All of lore.kernel.org
 help / color / mirror / Atom feed
* RE: [Patch] Enable SMEP CPU feature support for XEN itself
@ 2011-06-02 13:29 Jan Beulich
  2011-06-02 14:36 ` Li, Xin
  0 siblings, 1 reply; 20+ messages in thread
From: Jan Beulich @ 2011-06-02 13:29 UTC (permalink / raw)
  To: wei.y.yang, xin.li; +Cc: xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 2642 bytes --]

>>> "Li, Xin"  06/02/11 6:20 AM >>>
>> > +boolean_param("nosmep", disable_smep);
>> >
>> >  struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
>> >
>> > @@ -222,6 +225,17 @@
>> >      c->x86_capability[4] = cap4;
>> >  }
>> >
>> > +static void __cpuinit setup_smep(struct cpuinfo_x86 *c)
>> > +{
>> > +    if ( cpu_has(c, X86_FEATURE_SMEP) ) {
>> > +        if( unlikely(disable_smep) ) {
>> 
>> ... a __cpuinit function?
>
>If change disable_smep to __cpuinitdata, this should be ok.

You would be okay, but as I wrote further down both are really
only needed on the BP.

>> > +            setup_clear_cpu_cap(X86_FEATURE_SMEP);
>> > +            clear_in_cr4(X86_CR4_SMEP);
>> > +        } else
>> > +            set_in_cr4(X86_CR4_SMEP);
>> 
>> Anyway, the whole thing is overkill - {set,clear}_in_cr4() write
>> the updated bits to mmu_cr4_features, and these get loaded
>> on secondary CPUs *before* you have any chance of looking
>> at the CPUID bits. As with everything else, it's assumed that
>> APs don't have less features than the BP, and hence you only
>> need to set_in_cr4() once (on the BP). And then the function
>> can be __init.
>>
>
>Do you mean? 
>if ( cpu_has(c, X86_FEATURE_SMEP) )
>if( likely(!disable_smep) ) {
>mmu_cr4_features |= X86_CR4_SMEP;

Why?

>set_in_cr4(0);

set_in_cr4(X86_CR4_SMEP) does exactly what you need.

>} else
>setup_clear_cpu_cap(X86_FEATURE_SMEP);
>
>Sounds good ... but the code will be harder to read, as it implicitly set smep?
>Also where to put setup_smep thus it's only called in BP?

early_cpu_detect() would seem to be the most logical place, though
it doesn't have all the x86_capabilities[] fields set up yet. The BP-only
part at the end of identify_cpu() would also be a possible place.

trap_init() would be another possible (and reasonably logical) place.

>> The further down I get the uglier this looks. Can't you simply
>> accumulate the user bit into a separate variable? That way the
>> compiler also doesn't need to keep around all the l[1234]e
>> variables.
>
>At the beginning we did accumulate the user bit into a separate variable. However
>SMEP faults hardly happen while we keep accumulating user bit no matter it's a
>spurious fault or not, and even spurious faults are rare I guess.

Remember that we're going through this function for almost every page
fault happening in Xen, and also for the majority of those originating
from certain pv guests (when they have suppress_spurious_page_faults
set).

Also, my comment was to a large part aiming at better legibility of the
code you add.

Jan


[-- Attachment #1.2: HTML --]
[-- Type: text/html, Size: 3650 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread
* [Patch] Enable SMEP CPU feature support for XEN itself
@ 2011-06-01 13:20 Yang, Wei Y
  2011-06-01 14:34 ` Keir Fraser
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Yang, Wei Y @ 2011-06-01 13:20 UTC (permalink / raw)
  To: xen-devel


Intel new CPU supports SMEP (Supervisor Mode Execution Protection). SMEP prevents
kernel from executing code in user. Updated Intel SDM describes this CPU feature.
The document will be published soon.

This patch enables SMEP in Xen to protect Xen hypervisor from executing pv guest
code, and kills a pv guest triggering SMEP fault.

 Signed-off-by: Yang, Wei <wei.y.yang@intel.com>
 Signed-off-by: Shan, Haitao <haitao.shan@intel.com>
 Signed-off-by: Li, Xin <xin.li@intel.com>

---
 arch/x86/cpu/common.c        |   16 ++++++++++++++++
 arch/x86/traps.c             |   43 +++++++++++++++++++++++++++++++++++++++++--
 include/asm-x86/cpufeature.h |    5 ++++-
 include/asm-x86/processor.h  |    1 +
 4 files changed, 62 insertions(+), 3 deletions(-)

diff -r d4f6310f1ef5 xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c	Wed Jun 01 11:11:43 2011 +0100
+++ b/xen/arch/x86/cpu/common.c	Wed Jun 01 19:53:52 2011 +0800
@@ -28,6 +28,9 @@
 integer_param("cpuid_mask_ext_ecx", opt_cpuid_mask_ext_ecx);
 unsigned int __devinitdata opt_cpuid_mask_ext_edx = ~0u;
 integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
+/* nosmep: if true, Intel SMEP is disabled. */
+static bool_t __initdata disable_smep;
+boolean_param("nosmep", disable_smep);
 
 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
 
@@ -222,6 +225,17 @@
 	c->x86_capability[4] = cap4;
 }
 
+static void __cpuinit setup_smep(struct cpuinfo_x86 *c)
+{
+	if ( cpu_has(c, X86_FEATURE_SMEP) ) {
+		if( unlikely(disable_smep) ) {
+			setup_clear_cpu_cap(X86_FEATURE_SMEP);
+			clear_in_cr4(X86_CR4_SMEP);
+		} else
+			set_in_cr4(X86_CR4_SMEP);
+	}
+}
+
 void __cpuinit generic_identify(struct cpuinfo_x86 * c)
 {
 	u32 tfms, xlvl, capability, excap, ebx;
@@ -268,6 +282,8 @@
 		c->x86_capability[X86_FEATURE_FSGSBASE / 32] = ebx;
 	}
 
+	setup_smep(c);
+
 	early_intel_workaround(c);
 
 #ifdef CONFIG_X86_HT
diff -r d4f6310f1ef5 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c	Wed Jun 01 11:11:43 2011 +0100
+++ b/xen/arch/x86/traps.c	Wed Jun 01 19:53:52 2011 +0800
@@ -1195,8 +1195,16 @@
     if ( ((l3e_get_flags(l3e) & required_flags) != required_flags) ||
          (l3e_get_flags(l3e) & disallowed_flags) )
         return 0;
-    if ( l3e_get_flags(l3e) & _PAGE_PSE )
+    if ( l3e_get_flags(l3e) & _PAGE_PSE ) {
+        /* SMEP fault error code 10001b */
+        if ( (error_code & PFEC_insn_fetch) &&
+             !(error_code & PFEC_user_mode) &&
+             cpu_has_smep &&
+             (_PAGE_USER & l4e_get_flags(l4e) & l3e_get_flags(l3e)) )
+            return 2;
+
         return 1;
+    }
 #endif
 #endif
 
@@ -1207,8 +1215,21 @@
     if ( ((l2e_get_flags(l2e) & required_flags) != required_flags) ||
          (l2e_get_flags(l2e) & disallowed_flags) )
         return 0;
-    if ( l2e_get_flags(l2e) & _PAGE_PSE )
+    if ( l2e_get_flags(l2e) & _PAGE_PSE ) {
+        /* SMEP fault error code 10001b */
+        if ( (error_code & PFEC_insn_fetch) &&
+             !(error_code & PFEC_user_mode) &&
+             cpu_has_smep &&
+             (_PAGE_USER &
+#if CONFIG_PAGING_LEVELS >= 4
+              l4e_get_flags(l4e) &
+              l3e_get_flags(l3e) &
+#endif
+              l2e_get_flags(l2e)) )
+            return 2;
+
         return 1;
+    }
 
     l1t = map_domain_page(mfn);
     l1e = l1e_read_atomic(&l1t[l1_table_offset(addr)]);
@@ -1218,6 +1239,18 @@
          (l1e_get_flags(l1e) & disallowed_flags) )
         return 0;
 
+    /* SMEP fault error code 10001b */
+    if ( (error_code & PFEC_insn_fetch) &&
+         !(error_code & PFEC_user_mode) &&
+         cpu_has_smep &&
+         (_PAGE_USER &
+#if CONFIG_PAGING_LEVELS >= 4
+          l4e_get_flags(l4e) &
+          l3e_get_flags(l3e) &
+#endif
+          l2e_get_flags(l2e) & l1e_get_flags(l1e)) )
+        return 2;
+
     return 1;
 }
 
@@ -1235,6 +1268,12 @@
     is_spurious = __spurious_page_fault(addr, error_code);
     local_irq_restore(flags);
 
+    if ( is_spurious == 2 ) {
+        printk("SMEP fault at address %lx, crashing current domain %d\n",
+               addr, current->domain->domain_id);
+        domain_crash_synchronous();
+    }
+
     return is_spurious;
 }
 
diff -r d4f6310f1ef5 xen/include/asm-x86/cpufeature.h
--- a/xen/include/asm-x86/cpufeature.h	Wed Jun 01 11:11:43 2011 +0100
+++ b/xen/include/asm-x86/cpufeature.h	Wed Jun 01 19:53:52 2011 +0800
@@ -141,8 +141,9 @@
 #define X86_FEATURE_TBM         (6*32+21) /* trailing bit manipulations */
 #define X86_FEATURE_TOPOEXT     (6*32+22) /* topology extensions CPUID leafs */
 
-/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 7 */
 #define X86_FEATURE_FSGSBASE	(7*32+ 0) /* {RD,WR}{FS,GS}BASE instructions */
+#define X86_FEATURE_SMEP	(7*32+ 7) /* Supervisor Mode Execution Protection */
 
 #define cpu_has(c, bit)		test_bit(bit, (c)->x86_capability)
 #define boot_cpu_has(bit)	test_bit(bit, boot_cpu_data.x86_capability)
@@ -201,6 +202,8 @@
 #define cpu_has_fsgsbase	boot_cpu_has(X86_FEATURE_FSGSBASE)
 #endif
 
+#define cpu_has_smep            boot_cpu_has(X86_FEATURE_SMEP)
+
 #define cpu_has_ffxsr           ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) \
                                  && boot_cpu_has(X86_FEATURE_FFXSR))
 
diff -r d4f6310f1ef5 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h	Wed Jun 01 11:11:43 2011 +0100
+++ b/xen/include/asm-x86/processor.h	Wed Jun 01 19:53:52 2011 +0800
@@ -85,6 +85,7 @@
 #define X86_CR4_SMXE		0x4000  /* enable SMX */
 #define X86_CR4_FSGSBASE	0x10000 /* enable {rd,wr}{fs,gs}base */
 #define X86_CR4_OSXSAVE	0x40000 /* enable XSAVE/XRSTOR */
+#define X86_CR4_SMEP		0x100000/* enable SMEP */
 
 /*
  * Trap/fault mnemonics.
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2011-06-03 12:34 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-02 13:29 [Patch] Enable SMEP CPU feature support for XEN itself Jan Beulich
2011-06-02 14:36 ` Li, Xin
2011-06-02 15:05   ` Li, Xin
2011-06-02 19:24   ` Keir Fraser
2011-06-02 22:49     ` Li, Xin
2011-06-03 11:54       ` Li, Xin
2011-06-03 12:34         ` Keir Fraser
  -- strict thread matches above, loose matches on Subject: below --
2011-06-01 13:20 Yang, Wei Y
2011-06-01 14:34 ` Keir Fraser
2011-06-01 14:50   ` Li, Xin
2011-06-01 15:17 ` Jan Beulich
2011-06-01 15:23   ` Ian Campbell
2011-06-02  4:20   ` Li, Xin
2011-06-02  7:45   ` Li, Xin
2011-06-01 15:26 ` Keir Fraser
2011-06-01 16:15   ` Li, Xin
2011-06-01 20:43     ` Keir Fraser
2011-06-01 22:52       ` Li, Xin
2011-06-02  6:25         ` Keir Fraser
2011-06-02 10:07           ` Li, Xin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.