From: Ben Gras Date: Thu, 18 Dec 2008 14:30:55 +0000 (+0000) Subject: make kernel leave a page-sized gap in its code and data to not be X-Git-Tag: v3.1.4~166 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=f0000078c32898973f6f79f3f6c24a1fde59e0fd;p=minix.git make kernel leave a page-sized gap in its code and data to not be mapped in if so configured. --- diff --git a/include/minix/com.h b/include/minix/com.h index 5358c1784..4e93a76d4 100755 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -593,6 +593,7 @@ #define VMCTL_MEMREQ_REPLY 15 #define VMCTL_INCSP 16 #define VMCTL_STACKTRACE 17 +#define VMCTL_NOPAGEZERO 18 /*===========================================================================* * Messages for the Reincarnation Server * diff --git a/include/minix/config.h b/include/minix/config.h index 8bac14ba4..dcfeb4326 100755 --- a/include/minix/config.h +++ b/include/minix/config.h @@ -95,4 +95,7 @@ #define SPROFILE 1 /* statistical profiling */ #define CPROFILE 0 /* call profiling */ +/* Compile kernel so that first page of code and data can be unmapped. */ +#define VM_KERN_NOPAGEZERO 1 + #endif /* _CONFIG_H */ diff --git a/kernel/arch/i386/memory.c b/kernel/arch/i386/memory.c index e02008868..16c6cb294 100644 --- a/kernel/arch/i386/memory.c +++ b/kernel/arch/i386/memory.c @@ -45,6 +45,7 @@ PUBLIC void vm_init(void) u32_t entry; unsigned pages; struct proc* rp; + struct proc *sys = proc_addr(SYSTEM); if (!vm_size) minix_panic("i386_vm_init: no space for page tables", NO_NUM); @@ -77,6 +78,12 @@ PUBLIC void vm_init(void) I386_VM_PRESENT; if (phys_mem >= vm_mem_high) entry= 0; +#if VM_KERN_NOPAGEZERO + if (phys_mem == (sys->p_memmap[T].mem_phys << CLICK_SHIFT) || + phys_mem == (sys->p_memmap[D].mem_phys << CLICK_SHIFT)) { + entry = 0; + } +#endif phys_put32(vm_pt_base + p*I386_VM_PT_ENT_SIZE, entry); } @@ -471,6 +478,7 @@ PUBLIC int vm_checkrange(struct proc *caller, struct proc *target, vmassert(vm_running); + /* If caller has had a reply to this request, return it. */ if(RTS_ISSET(caller, VMREQUEST)) { if(caller->p_vmrequest.who == target->p_endpoint) { @@ -522,8 +530,9 @@ PUBLIC int vm_checkrange(struct proc *caller, struct proc *target, target->p_name, target->p_endpoint, v, wrfl, flags, phys); } - if(checkonly) + if(checkonly) { return VMSUSPEND; + } /* This range is not OK for this process. Set parameters * of the request and notify VM about the pending request. @@ -544,7 +553,19 @@ PUBLIC int vm_checkrange(struct proc *caller, struct proc *target, /* Connect caller on vmrequest wait queue. */ caller->p_vmrequest.nextrequestor = vmrequest; vmrequest = caller; - soft_notify(VM_PROC_NR); + if(!caller->p_vmrequest.nextrequestor) { + int n = 0; + struct proc *vmr; + for(vmr = vmrequest; vmr; vmr = vmr->p_vmrequest.nextrequestor) + n++; + soft_notify(VM_PROC_NR); +#if 0 + kprintf("(%d) ", n); + kprintf("%d/%d ", + caller->p_endpoint, target->p_endpoint); + util_stacktrace(); +#endif + } #if 0 kprintf("SYSTEM: vm_checkrange: range bad for " diff --git a/kernel/system/do_vmctl.c b/kernel/system/do_vmctl.c index bceeed639..2628f1e2a 100644 --- a/kernel/system/do_vmctl.c +++ b/kernel/system/do_vmctl.c @@ -11,6 +11,7 @@ #include "../vm.h" #include "../debug.h" #include +#include /*===========================================================================* * do_vmctl * @@ -92,6 +93,10 @@ kprintf("SYSTEM: request %d:0x%lx-0x%lx, wrflag %d, failed\n", } #endif return OK; +#if VM_KERN_NOPAGEZERO + case VMCTL_NOPAGEZERO: + return OK; +#endif case VMCTL_STACKTRACE: kprintf("vmctl stacktrace "); proc_stacktrace(p);