Skip to content

Commit

Permalink
🐞 fix(opensbi-1.2): free metadata & pmp
Browse files Browse the repository at this point in the history
Fix the problem that metadata memory is not fully freed when clearing pmp

issues#100
  • Loading branch information
Fly0307 committed Dec 21, 2023
1 parent 6c586ed commit a868f53
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 222 deletions.
3 changes: 3 additions & 0 deletions opensbi-1.2/include/sm/enclave.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct enclave_t

//shared mem with kernel
unsigned long kbuffer;
unsigned long kbuffer_paddr;
unsigned long kbuffer_size;

unsigned long* ocall_func_id;
Expand All @@ -74,6 +75,7 @@ struct enclave_t

//shared memory with host
unsigned long untrusted_ptr;
unsigned long untrusted_ptr_paddr;
unsigned long untrusted_size;
// enclave measurement
unsigned char hash[HASH_SIZE];
Expand All @@ -100,6 +102,7 @@ uintptr_t resume_from_stop(uintptr_t* regs, unsigned int eid);
uintptr_t attest_enclave(uintptr_t eid, uintptr_t report_ptr, uintptr_t nonce);
uintptr_t exit_enclave(uintptr_t* regs, unsigned long retval);
uintptr_t do_timer_irq(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc);
uintptr_t free_enclave_metadata();

uintptr_t resume_from_ocall(uintptr_t* regs, unsigned int eid);
uintptr_t enclave_sys_write(uintptr_t *regs);
Expand Down
30 changes: 16 additions & 14 deletions opensbi-1.2/include/sm/enclave_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,22 @@ struct signature_t
*/
struct enclave_sbi_param_t
{
unsigned int *eid_ptr;
unsigned long paddr;
unsigned long size;
unsigned long entry_point;
unsigned long untrusted_ptr;
unsigned long untrusted_size;
unsigned long free_mem;
//enclave shared mem with kernel
unsigned long kbuffer;
unsigned long kbuffer_size;
unsigned long *ecall_arg0;
unsigned long *ecall_arg1;
unsigned long *ecall_arg2;
unsigned long *ecall_arg3;
unsigned int * eid_ptr;
unsigned long paddr;
unsigned long size;
unsigned long entry_point;
unsigned long untrusted_ptr;
unsigned long untrusted_paddr;
unsigned long untrusted_size;
unsigned long free_mem;
//enclave shared mem with kernel
unsigned long kbuffer;
unsigned long kbuffer_paddr;
unsigned long kbuffer_size;
unsigned long *ecall_arg0;
unsigned long *ecall_arg1;
unsigned long *ecall_arg2;
unsigned long *ecall_arg3;
};

#endif /* _ENCLAVE_ARGS_H */
2 changes: 2 additions & 0 deletions opensbi-1.2/include/sm/platform/pmp/enclave_mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ void* mm_alloc(unsigned long req_size, unsigned long* resp_size);

int mm_free(void* paddr, unsigned long size);

int memory_reclaim(unsigned long* resp_size);

int mm_free_clear(void* paddr, unsigned long size);

void print_buddy_system();
Expand Down
6 changes: 5 additions & 1 deletion opensbi-1.2/include/sm/sm.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ extern uintptr_t _fw_start[], _fw_end[];
#define SBI_GET_KEY 88

//Error code of SBI_ALLOC_ENCLAVE_MEM
#define RETRY_SPIN_LOCK -3
#define ENCLAVE_NO_MEMORY -2
#define ENCLAVE_ERROR -1
#define ENCLAVE_SUCCESS 0
Expand All @@ -58,6 +59,8 @@ extern uintptr_t _fw_start[], _fw_end[];
#define FREE_MAX_MEMORY 2
#define FREE_SPEC_MEMORY 3

#define RETRY_TIMES 5

void sm_init();

uintptr_t sm_mm_init(uintptr_t paddr, unsigned long size);
Expand All @@ -67,7 +70,8 @@ uintptr_t sm_mm_extend(uintptr_t paddr, unsigned long size);
uintptr_t sm_alloc_enclave_mem(uintptr_t mm_alloc_arg);

uintptr_t sm_free_enclave_mem(uintptr_t size_ptr,unsigned long flag);
uintptr_t sm_memory_reclaim(uintptr_t enclave_id);

uintptr_t sm_memory_reclaim(uintptr_t enclave_id, unsigned long eid);

uintptr_t sm_create_enclave(uintptr_t enclave_create_args, bool retry);

Expand Down
2 changes: 0 additions & 2 deletions opensbi-1.2/lib/sbi/riscv_locks.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ bool spin_trylock(spinlock_t *lock)
void spin_lock(spinlock_t *lock)
{
//for lock debug
// u32 source_hart = current_hartid();
// printm_nolock("[spin_lock@%u]try getlock\n",source_hart);
unsigned long inc = 1u << TICKET_SHIFT;
unsigned long mask = 0xffffu;
u32 l0, tmp1, tmp2;
Expand Down
8 changes: 4 additions & 4 deletions opensbi-1.2/lib/sbi/sbi_ecall_penglai.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static int sbi_ecall_penglai_host_handler(unsigned long extid, unsigned long fun
ret = sm_destroy_enclave((uintptr_t *)regs, regs->a0);
break;
case SBI_MEMORY_RECLAIM: //91
ret=sm_memory_reclaim(regs->a0);
ret=sm_memory_reclaim(regs->a0, regs->a1);
break;
case SBI_FREE_ENCLAVE_MEM://90
ret= sm_free_enclave_mem(regs->a0, regs->a1);
Expand All @@ -69,8 +69,8 @@ static int sbi_ecall_penglai_host_handler(unsigned long extid, unsigned long fun
//((struct sbi_trap_regs *)regs)->mstatus = csr_read(CSR_MSTATUS);
*out_val = ret;
// spin_unlock(&sm_big_lock);
printm("[Penglai KModule@%u] %s return, funcid=%ld\r\n",
current_hartid(), __func__, funcid);
printm("[Penglai KModule@%u] %s return %ld, funcid=%ld\r\n",
current_hartid(), __func__, ret, funcid);
return ret;
}

Expand Down Expand Up @@ -105,7 +105,7 @@ static int sbi_ecall_penglai_enclave_handler(unsigned long extid, unsigned long
sbi_printf("[Penglai@Monitor] enclave interface(funcid:%ld) not supported yet\n", funcid);
ret = SBI_ENOTSUPP;
}
printm("[Penglai KModule@%u] %s return,funcid=%ld\r\n", current_hartid(), __func__,funcid);
printm("[Penglai KModule@%u] %s return %ld,funcid=%ld\r\n", current_hartid(), __func__,ret , funcid);
// spin_unlock(&sm_big_lock);
*out_val = ret;
return ret;
Expand Down
13 changes: 4 additions & 9 deletions opensbi-1.2/lib/sbi/sbi_ipi.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
#include <sbi/sbi_tlb.h>

volatile unsigned long wait_for_sync[MAX_HARTS] = { IPI_NONE };
volatile unsigned long skip_for_wait[MAX_HARTS] = { [0 ... MAX_HARTS - 1] =
-1UL };
volatile unsigned long skip_for_wait[MAX_HARTS][MAX_HARTS] = {{0}};

struct sbi_ipi_data {
unsigned long ipi_type;
Expand Down Expand Up @@ -69,19 +68,15 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 remote_hartid,
smp_wmb();

if (ipi_dev && ipi_dev->ipi_send) {
// while (!waiting_for_sync[remote_hartid])
// {
// /* code */
// }

ipi_dev->ipi_send(remote_hartid);
}

sbi_pmu_ctr_incr_fw(SBI_PMU_FW_IPI_SENT);
// if (!waiting_for_sync[remote_hartid] && !sbi_strcmp(ipi_ops->name, "IPI_PMP"))
// {

if (ipi_ops->sync)
ipi_ops->sync(scratch);
// }


return 0;
}
Expand Down
91 changes: 51 additions & 40 deletions opensbi-1.2/lib/sbi/sbi_pmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@
#include <sbi/sbi_platform.h>
#include <sbi/sbi_hartmask.h>

extern unsigned long waiting_for_spinlock[MAX_HARTS];
#define MAGIC_NUM 30;
extern volatile unsigned long waiting_for_spinlock[MAX_HARTS];
extern volatile unsigned long wait_for_sync[MAX_HARTS];
extern volatile unsigned long
skip_for_wait[MAX_HARTS]; //slot: mark which rhart no reply
extern volatile int skip_for_wait[MAX_HARTS][MAX_HARTS]; //slot: mark which rhart no reply
extern volatile int print_m_mode;
static unsigned long pmp_data_offset;
static unsigned long pmp_sync_offset;
static unsigned long curr_skip_hartid[2] = {
-1UL
}; //0:cur_remotehartid, 1:skip_hartid
static volatile u32 curr_skip_hartid =-1; //0:cur_remotehartid, 1:skip_hartid


static void sbi_process_pmp(struct sbi_scratch *scratch)
{
Expand All @@ -43,12 +42,13 @@ static void sbi_process_pmp(struct sbi_scratch *scratch)
continue;
if(print_m_mode && SYNC_DEBUG) sbi_printf("hart %ld process sync pmp\n", hartid);
pmp_sync = sbi_scratch_offset_ptr(rscratch, pmp_sync_offset);
if (skip_for_wait[rhartid] == hartid)
if (skip_for_wait[rhartid][hartid] == 1)
{
if(print_m_mode && SYNC_DEBUG) sbi_printf("hart %ld no reply syncpmp to %d\n", hartid, rhartid);
skip_for_wait[rhartid] = -1UL;
curr_skip_hartid[1] = -1UL;
curr_skip_hartid[0] = -1UL;
*pmp_sync = 0;
if (SYNC_DEBUG)
sbi_printf("hart %ld no reply sync_pmp to %d\n",
hartid, rhartid);
skip_for_wait[rhartid][hartid] = 0;
continue;
}

Expand All @@ -73,11 +73,7 @@ static int sbi_update_pmp(struct sbi_scratch *scratch,
}

wait_for_sync[curr_hartid] = IPI_PMP;
if (wait_for_sync[remote_hartid] == IPI_TLB)
{
curr_skip_hartid[1]= remote_hartid;
}
curr_skip_hartid[0] = remote_hartid;
curr_skip_hartid = remote_hartid;
pmp_data = sbi_scratch_offset_ptr(remote_scratch, pmp_data_offset);
//update the remote hart pmp data
sbi_memcpy(pmp_data, data, sizeof(struct pmp_data_t));
Expand All @@ -91,36 +87,51 @@ static void sbi_pmp_sync(struct sbi_scratch *scratch)
sbi_scratch_offset_ptr(scratch, pmp_sync_offset);
ulong hartid = csr_read(CSR_MHARTID);
wait_for_sync[hartid] = IPI_PMP;
// for (size_t i = 0; i < MAX_HARTS; i++) {
// struct sbi_scratch *rscratch = NULL;
// rscratch = sbi_hartid_to_scratch(i);
// if (!rscratch)
// continue;
// if (rscratch == scratch)
// {
// }
// }
// if (curr_skip_hartid[0] == curr_skip_hartid[1])
ulong remote_hartid = curr_skip_hartid[0];
// if (remote_hartid == -1UL)
// {
// sbi_printf("sync_pmp remote_hartid %lu error!\n", remote_hartid);
// return;
// }

if (remote_hartid != -1UL && wait_for_sync[remote_hartid] == IPI_TLB){

u32 remote_hartid = curr_skip_hartid;

if (remote_hartid != -1 && (wait_for_sync[remote_hartid] == IPI_TLB || waiting_for_spinlock[remote_hartid] == 1)){
if (SYNC_DEBUG)
sbi_printf("hart %ld skip wait %lu sync pmp\n", hartid,
curr_skip_hartid[1]);
sbi_printf("hart %ld skip wait %u sync pmp\n", hartid,
remote_hartid);
curr_skip_hartid = -1;
atomic_raw_xchg_ulong(pmp_sync, 0);
// skip_for_wait[hartid] = IPI_PMP;
skip_for_wait[hartid] = remote_hartid;
skip_for_wait[hartid][remote_hartid] = 1;
} else {
if (SYNC_DEBUG)
sbi_printf("hart %ld wait %d sync pmp\n", hartid,
curr_skip_hartid);
//wait the remote hart process the pmp signal
while (!atomic_raw_xchg_ulong(pmp_sync, 0));
int retry = MAGIC_NUM;
while (!atomic_raw_xchg_ulong(pmp_sync, 0)) {
/**
* This is used to handle the situation
* where the remote enters m mode before
* sending pmp sync, and the remote is in spin
* lock after sending ipi.
*/
retry--;
if (retry == 0) {
retry = MAGIC_NUM;
if (remote_hartid != -1 &&
(wait_for_sync[remote_hartid] == IPI_TLB ||
waiting_for_spinlock[remote_hartid] == 1)) {
if (SYNC_DEBUG)
sbi_printf(
"hart %ld skip wait %u sync pmp\n",
hartid, remote_hartid);
curr_skip_hartid = -1;
atomic_raw_xchg_ulong(pmp_sync, 0);
skip_for_wait[hartid][remote_hartid] = 1;
break;
}
}
if (SYNC_DEBUG)
sbi_printf("hart %ld wait %u sync pmp\n",
hartid, remote_hartid);
};
}
wait_for_sync[hartid] = IPI_NONE;
// curr_skip_hartid[1] = -1UL;
return;
}

Expand Down
11 changes: 3 additions & 8 deletions opensbi-1.2/lib/sbi/sbi_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,7 @@ static void tlb_sync(struct sbi_scratch *scratch)

ulong hartid = csr_read(CSR_MHARTID);
wait_for_sync[hartid] = IPI_TLB;
if(print_m_mode && SYNC_DEBUG) sbi_printf("hart %ld begin wait sync_tlb\n", hartid);
// for (size_t i = 0; i < MAX_HARTS; i++) {
// if (waiting_for_sync[i] && hartid != i) {
// goto no_wait;
// }
// }


while (!atomic_raw_xchg_ulong(tlb_sync, 0)) {
/*
Expand Down Expand Up @@ -388,7 +383,8 @@ static int tlb_update(struct sbi_scratch *scratch,
if (ret != SBI_FIFO_UNCHANGED) {
return 1;
}

ulong hartid = csr_read(CSR_MHARTID);
if(SYNC_DEBUG) sbi_printf("hart %ld begin wait %d sync_tlb\n", hartid, remote_hartid);
while (sbi_fifo_enqueue(tlb_fifo_r, data) < 0) {
/**
* For now, Busy loop until there is space in the fifo.
Expand Down Expand Up @@ -423,7 +419,6 @@ int sbi_tlb_request(ulong hmask, ulong hbase, struct sbi_tlb_info *tinfo)
tlb_pmu_incr_fw_ctr(tinfo);
ulong hartid = csr_read(CSR_MHARTID);
if(print_m_mode && SYNC_DEBUG) sbi_printf("hart %ld begin sync tlb\n", hartid);
// if(SYNC_DEBUG) sbi_printf("hart %ld begin sync tlb\n", hartid);
wait_for_sync[hartid] = IPI_TLB;
return sbi_ipi_send_many(hmask, hbase, tlb_event, tinfo);
}
Expand Down
3 changes: 0 additions & 3 deletions opensbi-1.2/lib/sbi/sbi_trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
*/
struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs)
{
if(print_m_mode && SYNC_DEBUG) sbi_printf("hart %ld enter into m_mode\n", csr_read(CSR_MHARTID));
int rc = SBI_ENOTSUPP;
const char *msg = "trap handler failed";
ulong mcause = csr_read(CSR_MCAUSE);
Expand Down Expand Up @@ -304,7 +303,6 @@ struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs)
};
hartid = csr_read(CSR_MHARTID);
m_mode_status[hartid] = 0;
if(print_m_mode && SYNC_DEBUG) sbi_printf("hart %ld return from m_mode\n", csr_read(CSR_MHARTID));
return regs;
}

Expand Down Expand Up @@ -359,7 +357,6 @@ struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs)
sbi_trap_error(msg, rc, mcause, mtval, mtval2, mtinst, regs);
hartid = csr_read(CSR_MHARTID);
m_mode_status[hartid] = 0;
if(print_m_mode && SYNC_DEBUG) sbi_printf("hart %ld return from m_mode\n", csr_read(CSR_MHARTID));
return regs;
}

Expand Down
Loading

0 comments on commit a868f53

Please sign in to comment.