diff --git a/opensbi-1.2/include/sm/platform/pmp/enclave_mm.h b/opensbi-1.2/include/sm/platform/pmp/enclave_mm.h index c563f9fc0..9a6d75d8b 100644 --- a/opensbi-1.2/include/sm/platform/pmp/enclave_mm.h +++ b/opensbi-1.2/include/sm/platform/pmp/enclave_mm.h @@ -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 */ diff --git a/opensbi-1.2/include/sm/print.h b/opensbi-1.2/include/sm/print.h index 0c31c278a..18568ddf1 100644 --- a/opensbi-1.2/include/sm/print.h +++ b/opensbi-1.2/include/sm/print.h @@ -2,7 +2,7 @@ #define SM_PRINT_H #include -#define PENGLAI_DEBUG +// #define PENGLAI_DEBUG #ifdef PENGLAI_DEBUG #define printm(...) sbi_printf(__VA_ARGS__) #else diff --git a/opensbi-1.2/include/sm/sm.h b/opensbi-1.2/include/sm/sm.h index 17156b67b..2753bd59e 100644 --- a/opensbi-1.2/include/sm/sm.h +++ b/opensbi-1.2/include/sm/sm.h @@ -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 @@ -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); @@ -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); diff --git a/opensbi-1.2/lib/sbi/sbi_ecall_penglai.c b/opensbi-1.2/lib/sbi/sbi_ecall_penglai.c index 74628f1b7..3539c90e5 100644 --- a/opensbi-1.2/lib/sbi/sbi_ecall_penglai.c +++ b/opensbi-1.2/lib/sbi/sbi_ecall_penglai.c @@ -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; diff --git a/opensbi-1.2/lib/sbi/sm/enclave.c b/opensbi-1.2/lib/sbi/sm/enclave.c index abc862d1b..1eb31e35f 100644 --- a/opensbi-1.2/lib/sbi/sm/enclave.c +++ b/opensbi-1.2/lib/sbi/sm/enclave.c @@ -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; @@ -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; } @@ -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; } } @@ -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; @@ -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; @@ -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; } @@ -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? @@ -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 } @@ -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; } @@ -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; diff --git a/opensbi-1.2/lib/sbi/sm/platform/pmp/enclave_mm.c b/opensbi-1.2/lib/sbi/sm/platform/pmp/enclave_mm.c index 3db174150..232f79903 100644 --- a/opensbi-1.2/lib/sbi/sm/platform/pmp/enclave_mm.c +++ b/opensbi-1.2/lib/sbi/sm/platform/pmp/enclave_mm.c @@ -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<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; diff --git a/opensbi-1.2/lib/sbi/sm/sm.c b/opensbi-1.2/lib/sbi/sm/sm.c index 3d4e45149..781743f9b 100644 --- a/opensbi-1.2/lib/sbi/sm/sm.c +++ b/opensbi-1.2/lib/sbi/sm/sm.c @@ -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; +} \ No newline at end of file