Skip to content

Commit

Permalink
🐞 fix(opensbi-1.2): Free memory
Browse files Browse the repository at this point in the history
Add a sbi call to reclaim memory and clear pmp settings when uninstalling the fluffy module
  • Loading branch information
Fly0307 committed Nov 17, 2023
1 parent 6640373 commit 2f7afa8
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 11 deletions.
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 mm_free_clear(void* paddr, unsigned long size);

void print_buddy_system();

#endif /* _ENCLAVE_MM_H */
2 changes: 1 addition & 1 deletion opensbi-1.2/include/sm/print.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define SM_PRINT_H

#include <sbi/sbi_console.h>
#define PENGLAI_DEBUG
// #define PENGLAI_DEBUG
#ifdef PENGLAI_DEBUG
#define printm(...) sbi_printf(__VA_ARGS__)
#else
Expand Down
8 changes: 8 additions & 0 deletions opensbi-1.2/include/sm/sm.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern uintptr_t _fw_start[], _fw_end[];
#define SBI_ALLOC_ENCLAVE_MM 93
#define SBI_MEMORY_EXTEND 92
#define SBI_MEMORY_RECLAIM 91
#define SBI_FREE_ENCLAVE_MEM 90
#define SBI_DEBUG_PRINT 88

//Enclave SBI numbers
Expand All @@ -52,6 +53,11 @@ extern uintptr_t _fw_start[], _fw_end[];
#define RESUME_FROM_STOP 2003
#define RESUME_FROM_OCALL 2

#define FLAG_DESTROY 0
#define DIRECT_DESTROY 1
#define FREE_MAX_MEMORY 2
#define FREE_SPEC_MEMORY 3

void sm_init();

uintptr_t sm_mm_init(uintptr_t paddr, unsigned long size);
Expand All @@ -60,6 +66,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_create_enclave(uintptr_t enclave_create_args);

uintptr_t sm_attest_enclave(uintptr_t enclave_id, uintptr_t report, uintptr_t nonce);
Expand Down
3 changes: 3 additions & 0 deletions opensbi-1.2/lib/sbi/sbi_ecall_penglai.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ static int sbi_ecall_penglai_host_handler(unsigned long extid, unsigned long fun
case SBI_DESTROY_ENCLAVE:
ret = sm_destroy_enclave((uintptr_t *)regs, regs->a0);
break;
case SBI_FREE_ENCLAVE_MEM:
ret= sm_free_enclave_mem(regs->a0, regs->a1);
break;
default:
sbi_printf("[Penglai@Monitor] host interface(funcid:%ld) not supported yet\n", funcid);
ret = SBI_ENOTSUPP;
Expand Down
30 changes: 20 additions & 10 deletions opensbi-1.2/lib/sbi/sm/enclave.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct link_mem_t* add_link_mem(struct link_mem_t** tail)
return new_link_mem;
}

int remove_link_mem(struct link_mem_t** head, struct link_mem_t* ptr)
int remove_link_mem(struct link_mem_t** head, struct link_mem_t* ptr,bool clear)
{
struct link_mem_t *cur_link_mem, *tmp_link_mem;
int retval =0;
Expand All @@ -122,7 +122,12 @@ int remove_link_mem(struct link_mem_t** head, struct link_mem_t* ptr)
if (cur_link_mem == ptr)
{
*head = cur_link_mem->next_link_mem;
mm_free(cur_link_mem, cur_link_mem->mem_size);
if (clear)
{
mm_free_clear(cur_link_mem, cur_link_mem->mem_size);
}else{
mm_free(cur_link_mem, cur_link_mem->mem_size);
}
return 1;
}

Expand All @@ -133,7 +138,12 @@ int remove_link_mem(struct link_mem_t** head, struct link_mem_t* ptr)
tmp_link_mem = cur_link_mem->next_link_mem;
cur_link_mem->next_link_mem = cur_link_mem->next_link_mem->next_link_mem;
//FIXME
mm_free(tmp_link_mem, tmp_link_mem->mem_size);
if (clear)
{
mm_free_clear(tmp_link_mem, tmp_link_mem->mem_size);
}else{
mm_free(tmp_link_mem, tmp_link_mem->mem_size);
}
return retval;
}
}
Expand Down Expand Up @@ -207,7 +217,7 @@ static struct enclave_t* alloc_enclave()
return enclave;
}

static int free_enclave(int eid)
static int free_enclave(int eid, bool clear)
{
struct link_mem_t *cur;
struct enclave_t *enclave = NULL;
Expand All @@ -226,6 +236,7 @@ static int free_enclave(int eid)
enclave->state = INVALID;
found = 1;
ret_val = 0;
remove_link_mem(&enclave_metadata_head,cur,clear);
break;
}
count += cur->slab_num;
Expand Down Expand Up @@ -462,7 +473,7 @@ uintptr_t create_enclave(struct enclave_sbi_param_t create_args)
spin_unlock(&enclave_metadata_lock);

//free enclave struct
free_enclave(eid); //the enclave state will be set INVALID here
free_enclave(eid,0); //the enclave state will be set INVALID here
return ENCLAVE_ERROR;
}

Expand Down Expand Up @@ -602,7 +613,7 @@ uintptr_t destroy_enclave(uintptr_t* regs, unsigned int eid)
spin_unlock(&enclave_metadata_lock);

//free enclave struct
retval = free_enclave(eid); //the enclave state will be set INVALID here
retval = free_enclave(eid,0); //the enclave state will be set INVALID here
return retval;
}
//FIXME: what if the enclave->state is RUNNABLE now?
Expand Down Expand Up @@ -680,7 +691,7 @@ uintptr_t resume_enclave(uintptr_t* regs, unsigned int eid)
spin_unlock(&enclave_metadata_lock);

//free enclave struct
free_enclave(eid); //the enclave state will be set INVALID here
free_enclave(eid,0); //the enclave state will be set INVALID here
return ENCLAVE_SUCCESS; //this will break the infinite loop in the enclave-driver
}

Expand Down Expand Up @@ -771,8 +782,7 @@ uintptr_t exit_enclave(uintptr_t* regs, unsigned long retval)
spin_unlock(&enclave_metadata_lock);

//free enclave struct
free_enclave(eid);

free_enclave(eid, 0);
return 0;
}

Expand Down Expand Up @@ -947,7 +957,7 @@ uintptr_t do_timer_irq(uintptr_t *regs, uintptr_t mcause, uintptr_t mepc)
spin_unlock(&enclave_metadata_lock);

//free enclave struct
retval = free_enclave(eid); //the enclave state will be set INVALID here
retval = free_enclave(eid,0); //the enclave state will be set INVALID here

retval = ENCLAVE_SUCCESS; //this means we will not run any more
goto timer_irq_out;
Expand Down
98 changes: 98 additions & 0 deletions opensbi-1.2/lib/sbi/sm/platform/pmp/enclave_mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,104 @@ int mm_free(void* req_paddr, unsigned long free_size)
//printm("after mm_free\r\n");
//print_buddy_system();

mm_free_out:
spin_unlock(&pmp_bitmap_lock);
return ret_val;
}
//TODO:Reserved interfaces for calls to reclaim unused memory
int mm_free_clear(void* req_paddr, unsigned long free_size)
{
//check this paddr is 2^power aligned
uintptr_t paddr = (uintptr_t)req_paddr;
unsigned long order = ilog2(free_size-1) + 1;
unsigned long size = 1 << order;
if(check_mem_size(paddr, size) < 0)
return -1;

int ret_val = 0;
int region_idx = 0;
struct mm_list_t* mm_region = PADDR_2_MM_LIST(paddr);
mm_region->order = order;
mm_region->prev_mm = NULL;
mm_region->next_mm = NULL;

spin_lock(&pmp_bitmap_lock);

//print_buddy_system();

for(region_idx=0; region_idx < N_PMP_REGIONS; ++region_idx)
{
if(mm_regions[region_idx].valid && region_contain(mm_regions[region_idx].paddr, mm_regions[region_idx].size, paddr, size))
{
break;
}
}
if(region_idx >= N_PMP_REGIONS)
{
printm("mm_free: buddy system doesn't contain memory(addr 0x%lx, order %ld)\r\n", paddr, order);
ret_val = -1;
goto mm_free_out;
}

//check whether this region overlap with existing free mm_lists
struct mm_list_head_t* mm_list_head = mm_regions[region_idx].mm_list_head;
while(mm_list_head)
{
struct mm_list_t* mm_region = mm_list_head->mm_list;
while(mm_region)
{
uintptr_t region_paddr = (uintptr_t)MM_LIST_2_PADDR(mm_region);
unsigned long region_size = 1 << mm_region->order;
if(region_overlap(paddr, size, region_paddr, region_size))
{
printm("mm_free: memory(addr 0x%lx order %ld) overlap with free memory(addr 0x%lx order %d)\r\n", paddr, order, region_paddr, mm_region->order);
ret_val = -1;
break;
}
mm_region = mm_region->next_mm;
}
if(mm_region)
break;

mm_list_head = mm_list_head->next_list_head;
}
if(mm_list_head)
{
goto mm_free_out;
}

//insert with merge
ret_val = insert_mm_region(region_idx, mm_region, 1);
if(ret_val < 0)
{
printm("mm_free: failed to insert mm(addr 0x%lx, order %ld)\r\n in mm_regions[%d]\r\n", paddr, order, region_idx);
}

//printm("after mm_free\r\n");
//print_buddy_system();
int pmp_idx;
struct pmp_config_t pmp_config;
pmp_idx = REGION_TO_PMP(region_idx);
pmp_config = get_pmp(pmp_idx);

struct mm_region_t mm_regiont = mm_regions[region_idx];
mm_list_head = mm_regiont.mm_list_head;
struct mm_list_t *mm_list = mm_list_head->mm_list;
if (((long int *)MM_LIST_2_PADDR(mm_list) == (long int *)pmp_config.paddr)&&((pmp_config.size) == (1<<mm_list->order)))
{
delete_certain_region(region_idx,&mm_list_head,mm_list);
mm_regions[region_idx].valid = 0;
mm_regions[region_idx].paddr = 0;
mm_regions[region_idx].mm_list_head = NULL;
// release_big_emem_lock(__func__);
clear_pmp_and_sync(pmp_idx);
// acquire_big_emem_lock(__func__);
}

printm("***after mm_free***\r\n");
print_buddy_system();
dump_pmps();

mm_free_out:
spin_unlock(&pmp_bitmap_lock);
return ret_val;
Expand Down
49 changes: 49 additions & 0 deletions opensbi-1.2/lib/sbi/sm/sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,52 @@ uintptr_t sm_do_timer_irq(uintptr_t *regs, uintptr_t mcause, uintptr_t mepc)
regs[11] = ret; //value
return ret;
}

uintptr_t sm_free_enclave_mem(uintptr_t size_ptr, unsigned long flag)
{
uintptr_t ret = 0;
unsigned long size = 0;
dump_pmps();
switch (flag) {
case FREE_MAX_MEMORY:
for (size_t i = NPMP - 2; i >= 0; i--) {
int pmp_idx = i;
struct pmp_config_t pmp_config = get_pmp(pmp_idx);

if (pmp_config.paddr == 0 || pmp_config.size == 0) {
continue;
}

if (pmp_idx == 0) {
printm("M mode: sm_memory_reclaim: There is no mem to reclaim\r\n");
dump_pmps();
size = 0;
ret = 0;
break;
}

clear_pmp_and_sync(pmp_idx);
ret = pmp_config.paddr;
size = pmp_config.size;

break;
}
break;
case FREE_SPEC_MEMORY:
/*free */
{ //TODO:Reserved interfaces for calls to reclaim unused memory
struct pmp_config_t pmp_config = get_pmp(15);
clear_pmp_and_sync(15);
ret = pmp_config.paddr;
size = 0;
}
break;
default:
ret = 0;
size = 0;
break;
}

copy_to_host((void *)size_ptr, (void *)(&size), sizeof(unsigned long));
return ret;
}

0 comments on commit 2f7afa8

Please sign in to comment.