Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Enabling NX bit on Xen ports?



On 04/21/10 11:53, Jean-Yves Migeon wrote:

On Wed, 21 Apr 2010 10:44:43 +0200, Manuel 
Bouyer<bouyer%antioche.eu.org@localhost>
wrote:
On Wed, Apr 21, 2010 at 01:31:53AM +0200, Jean-Yves Migeon wrote:
Dear list,

As some of you have noticed, I passed some hours through x86 code
around the NXE feature (makes possible to mark specific memory pages
as not being executable).

I propose to enable the feature under Xen, by removing the mask
regarding CPUID_NOX (see patch attached).

Currently, the feature is disabled, for unknown reasons (at least by
me). I quickly tested it under i386 and amd64.

[...]
Opinions? Am I missing something?

Did you test with both Xen31 and Xen33 ?

The only part I did not test is PAE kernel over Xen31. Sadly, I can't
really say much on the Xen31 case; in QEMU, wd chokes and keeps logging
"lost interrupt" messages with Xen 3.1. As my laptop has no NX support, the
feature is disabled, with or without PAE :/

If there is a corner case I did not see, please tell me.

I tested both with Xen 3.1 and 3.3, dom0 and domU (through multiple build.sh distribution), never encountered a problem, except with X.org that randomly crashes the kernel.

It seems to be not related to NX, it happens with or without NX bit enabled, by just moving a window around the screen (I am using nv(4), so I guess that the driver is not entirely innocent here...)

--
Jean-Yves Migeon
jeanyves.migeon%free.fr@localhost
Index: sys/arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/machdep.c,v
retrieving revision 1.144
diff -u -u -r1.144 machdep.c
--- sys/arch/amd64/amd64/machdep.c      18 Apr 2010 23:47:50 -0000      1.144
+++ sys/arch/amd64/amd64/machdep.c      28 Apr 2010 20:19:56 -0000
@@ -1253,7 +1253,6 @@
 #endif /* XEN */
 
        cpu_feature[0] &= ~CPUID_FEAT_BLACKLIST;
-       cpu_feature[2] &= ~CPUID_EXT_FEAT_BLACKLIST;
 
        cpu_init_msrs(&cpu_info_primary, true);
 
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.686
diff -u -u -r1.686 machdep.c
--- sys/arch/i386/i386/machdep.c        23 Apr 2010 16:07:33 -0000      1.686
+++ sys/arch/i386/i386/machdep.c        28 Apr 2010 20:20:00 -0000
@@ -1299,7 +1299,6 @@
        pcb = lwp_getpcb(&lwp0);
 
        cpu_feature[0] &= ~CPUID_FEAT_BLACKLIST;
-       cpu_feature[2] &= ~CPUID_EXT_FEAT_BLACKLIST;
 
        cpu_init_msrs(&cpu_info_primary, true);
 
Index: sys/arch/i386/i386/trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/trap.c,v
retrieving revision 1.256
diff -u -u -r1.256 trap.c
--- sys/arch/i386/i386/trap.c   23 Apr 2010 19:18:09 -0000      1.256
+++ sys/arch/i386/i386/trap.c   28 Apr 2010 20:20:00 -0000
@@ -671,6 +671,8 @@
                        map = &vm->vm_map;
                if (frame->tf_err & PGEX_W)
                        ftype = VM_PROT_WRITE;
+               else if (frame->tf_err & PGEX_X)
+                       ftype = VM_PROT_EXECUTE;
                else
                        ftype = VM_PROT_READ;
 
Index: sys/arch/i386/include/pte.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/include/pte.h,v
retrieving revision 1.22
diff -u -u -r1.22 pte.h
--- sys/arch/i386/include/pte.h 6 Apr 2010 20:43:57 -0000       1.22
+++ sys/arch/i386/include/pte.h 28 Apr 2010 20:20:00 -0000
@@ -274,5 +274,6 @@
 #define PGEX_P         0x01    /* protection violation (vs. no mapping) */
 #define PGEX_W         0x02    /* exception during a write cycle */
 #define PGEX_U         0x04    /* exception while in user mode (upl) */
+#define PGEX_X         0x10    /* exception during instruction fetch */
 
 #endif /* _I386_PTE_H_ */
Index: sys/arch/x86/include/specialreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/specialreg.h,v
retrieving revision 1.40
diff -u -u -r1.40 specialreg.h
--- sys/arch/x86/include/specialreg.h   18 Apr 2010 23:47:51 -0000      1.40
+++ sys/arch/x86/include/specialreg.h   28 Apr 2010 20:20:06 -0000
@@ -262,10 +262,8 @@
 #ifdef XEN
 /* Not on Xen */
 #define CPUID_FEAT_BLACKLIST    (CPUID_PGE|CPUID_PSE|CPUID_MTRR|CPUID_FXSR)
-#define CPUID_EXT_FEAT_BLACKLIST (CPUID_NOX)
 #else
 #define CPUID_FEAT_BLACKLIST    0
-#define CPUID_EXT_FEAT_BLACKLIST 0
 #endif /* XEN */
 
 /*
Index: sys/arch/x86/x86/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/pmap.c,v
retrieving revision 1.107
diff -u -u -r1.107 pmap.c
--- sys/arch/x86/x86/pmap.c     18 Apr 2010 23:47:51 -0000      1.107
+++ sys/arch/x86/x86/pmap.c     28 Apr 2010 20:20:07 -0000
@@ -1146,10 +1146,9 @@
        if (flags & PMAP_NOCACHE)
                npte |= PG_N;
 
-#ifndef XEN
        if ((cpu_feature[2] & CPUID_NOX) && !(prot & VM_PROT_EXECUTE))
                npte |= PG_NX;
-#endif
+
        opte = pmap_pte_testset (pte, npte); /* zap! */
 
        if (pmap_valid_entry(opte)) {
@@ -1268,14 +1267,13 @@
        struct pcb *pcb;
        int i;
        vaddr_t kva;
-#ifdef XEN
-       pt_entry_t pg_nx = 0;
-#else
+#ifndef XEN
        unsigned long p1i;
        vaddr_t kva_end;
-       pt_entry_t pg_nx = (cpu_feature[2] & CPUID_NOX ? PG_NX : 0);
 #endif
 
+       pt_entry_t pg_nx = (cpu_feature[2] & CPUID_NOX ? PG_NX : 0);
+
        /*
         * set up our local static global vars that keep track of the
         * usage of KVM before kernel_map is set up
Index: sys/arch/xen/x86/cpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/x86/cpu.c,v
retrieving revision 1.43
diff -u -u -r1.43 cpu.c
--- sys/arch/xen/x86/cpu.c      18 Apr 2010 23:47:52 -0000      1.43
+++ sys/arch/xen/x86/cpu.c      28 Apr 2010 20:20:07 -0000
@@ -1005,6 +1005,9 @@
                HYPERVISOR_set_segment_base (SEGBASE_GS_USER, 0);
        }
 #endif /* __x86_64__ */
+
+       if (cpu_feature[2] & CPUID_NOX)
+               wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NXE);
 }
 
 void


Home | Main Index | Thread Index | Old Index