diff --git a/arch/x86/kernel/include/arch-memory.h b/arch/x86/kernel/include/arch-memory.h index fb523be6..035ea621 100644 --- a/arch/x86/kernel/include/arch-memory.h +++ b/arch/x86/kernel/include/arch-memory.h @@ -114,6 +114,7 @@ enum ihk_mc_pt_attribute { PTATTR_WRITABLE = 0x02, PTATTR_USER = 0x04, PTATTR_LARGEPAGE = 0x80, + PTATTR_NO_EXECUTE = 0x8000000000000000, PTATTR_UNCACHABLE = 0x10000, PTATTR_FOR_USER = 0x20000, }; @@ -156,5 +157,5 @@ void *map_fixed_area(unsigned long phys, unsigned long size, int uncachable); #define AP_TRAMPOLINE_SIZE 0x4000 /* Local is cachable */ -#define IHK_IKC_QUEUE_PT_ATTR (PTATTR_WRITABLE | PTATTR_UNCACHABLE) +#define IHK_IKC_QUEUE_PT_ATTR (PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_UNCACHABLE) #endif diff --git a/arch/x86/kernel/memory.c b/arch/x86/kernel/memory.c index e7659c40..32181fd2 100644 --- a/arch/x86/kernel/memory.c +++ b/arch/x86/kernel/memory.c @@ -1666,21 +1666,25 @@ void *map_fixed_area(unsigned long phys, unsigned long size, int uncachable) { unsigned long poffset, paligned; int i, npages; - int flag = PTATTR_WRITABLE | PTATTR_ACTIVE; void *v = (void *)fixed_virt; + enum ihk_mc_pt_attribute attr; poffset = phys & (PAGE_SIZE - 1); paligned = phys & PAGE_MASK; npages = (poffset + size + PAGE_SIZE - 1) >> PAGE_SHIFT; + attr = PTATTR_WRITABLE | PTATTR_ACTIVE; +#if 0 /* In the case of LAPIC MMIO, something will happen */ + attr |= PTATTR_NO_EXECUTE; +#endif if (uncachable) { - flag |= PTATTR_UNCACHABLE; + attr |= PTATTR_UNCACHABLE; } kprintf("map_fixed: %lx => %p (%d pages)\n", paligned, v, npages); for (i = 0; i < npages; i++) { - if(__set_pt_page(init_pt, (void *)fixed_virt, paligned, flag)){ + if(__set_pt_page(init_pt, (void *)fixed_virt, paligned, attr)){ return NULL; } @@ -1695,7 +1699,7 @@ void *map_fixed_area(unsigned long phys, unsigned long size, int uncachable) void init_low_area(struct page_table *pt) { - set_pt_large_page(pt, 0, 0, PTATTR_WRITABLE); + set_pt_large_page(pt, 0, 0, PTATTR_NO_EXECUTE|PTATTR_WRITABLE); } static void init_vsyscall_area(struct page_table *pt) diff --git a/kernel/host.c b/kernel/host.c index a130e17b..c357cb3d 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -69,13 +69,16 @@ static int process_msg_prepare_process(unsigned long rphys) unsigned long flags; uintptr_t interp_obase = -1; uintptr_t interp_nbase = -1; + enum ihk_mc_pt_attribute attr; + + attr = PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER; sz = sizeof(struct program_load_desc) + sizeof(struct program_image_section) * 16; npages = ((rphys + sz - 1) >> PAGE_SHIFT) - (rphys >> PAGE_SHIFT) + 1; phys = ihk_mc_map_memory(NULL, rphys, sz); - if((p = ihk_mc_map_virtual(phys, npages, PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){ + if((p = ihk_mc_map_virtual(phys, npages, attr)) == NULL){ ihk_mc_unmap_memory(NULL, phys, sz); return -ENOMEM; } @@ -264,7 +267,7 @@ static int process_msg_prepare_process(unsigned long rphys) args_envs_rp = ihk_mc_map_memory(NULL, (unsigned long)p->args, p->args_len); dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp); if((args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages, - PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){ + attr)) == NULL){ goto err; } dkprintf("args_envs_r: 0x%lX\n", args_envs_r); @@ -285,7 +288,7 @@ static int process_msg_prepare_process(unsigned long rphys) args_envs_rp = ihk_mc_map_memory(NULL, (unsigned long)p->envs, p->envs_len); dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp); if((args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages, - PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){ + attr)) == NULL){ goto err; } dkprintf("args_envs_r: 0x%lX\n", args_envs_r); @@ -363,6 +366,9 @@ static void process_msg_init_acked(struct ihk_ikc_channel_desc *c, unsigned long { struct ikc_scd_init_param *param = (void *)pphys; struct syscall_params *lparam; + enum ihk_mc_pt_attribute attr; + + attr = PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER; lparam = &cpu_local_var(scp); if(cpu_local_var(syscall_channel2) == c) @@ -372,7 +378,7 @@ static void process_msg_init_acked(struct ihk_ikc_channel_desc *c, unsigned long REQUEST_PAGE_COUNT * PAGE_SIZE); if((lparam->request_va = ihk_mc_map_virtual(lparam->request_pa, REQUEST_PAGE_COUNT, - PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){ + attr)) == NULL){ // TODO: panic("ENOMEM"); } @@ -383,7 +389,7 @@ static void process_msg_init_acked(struct ihk_ikc_channel_desc *c, unsigned long PAGE_SIZE); if((lparam->doorbell_va = ihk_mc_map_virtual(lparam->doorbell_pa, DOORBELL_PAGE_COUNT, - PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){ + attr)) == NULL){ // TODO: panic("ENOMEM"); } @@ -392,7 +398,7 @@ static void process_msg_init_acked(struct ihk_ikc_channel_desc *c, unsigned long lparam->post_pa = ihk_mc_map_memory(NULL, param->post_page, PAGE_SIZE); if((lparam->post_va = ihk_mc_map_virtual(lparam->post_pa, 1, - PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){ + attr)) == NULL){ // TODO: panic("ENOMEM"); } diff --git a/kernel/process.c b/kernel/process.c index c128d4da..d0b194d0 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -348,6 +348,7 @@ int update_process_page_table(struct process *process, attr = flag | PTATTR_USER | PTATTR_FOR_USER; attr |= (range->flag & VR_PROT_WRITE)? PTATTR_WRITABLE: 0; + attr |= (range->flag & VR_PROT_EXEC)? 0: PTATTR_NO_EXECUTE; p = range->start; while (p < range->end) { @@ -690,6 +691,10 @@ enum ihk_mc_pt_attribute vrflag_to_ptattr(unsigned long flag) attr |= PTATTR_WRITABLE; } + if (!(flag & VR_PROT_EXEC)) { + attr |= PTATTR_NO_EXECUTE; + } + return attr; } @@ -1198,7 +1203,9 @@ static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64 if (((range->flag & VR_PROT_MASK) == VR_PROT_NONE) || ((reason & PF_WRITE) - && !(range->flag & VR_PROT_WRITE))) { + && !(range->flag & VR_PROT_WRITE)) + || ((reason & PF_INSTR) + && !(range->flag & VR_PROT_EXEC))) { error = -EFAULT; kprintf("[%d]do_page_fault_process(%p,%lx,%lx):" "access denied. %d\n",