# HG changeset patch
# User Ian.Campbell@xxxxxxxxxxxxx
# Node ID 3ffb6cc6b8d2a42dd4f3c6399783a5f99458023b
# Parent d73eeceeae692cc08d68aece06b42fa7ce60edd7
Xen support for sysenter/exit on x86_32 when supervisor_mode_kernel is
enabled.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
diff -r d73eeceeae69 -r 3ffb6cc6b8d2 xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c Fri Apr 21 17:19:26 2006 +0100
+++ b/xen/arch/x86/cpu/common.c Fri Apr 21 17:19:29 2006 +0100
@@ -575,6 +575,8 @@ void __devinit cpu_init(void)
#if defined(CONFIG_X86_32)
t->ss0 = __HYPERVISOR_DS;
t->esp0 = get_stack_bottom();
+ if ( supervisor_mode_kernel && cpu_has_sep )
+ wrmsr(MSR_IA32_SYSENTER_ESP, &t->esp1, 0);
#elif defined(CONFIG_X86_64)
/* Bottom-of-stack must be 16-byte aligned! */
BUG_ON((get_stack_bottom() & 15) != 0);
diff -r d73eeceeae69 -r 3ffb6cc6b8d2 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Fri Apr 21 17:19:26 2006 +0100
+++ b/xen/arch/x86/traps.c Fri Apr 21 17:19:29 2006 +0100
@@ -425,7 +425,8 @@ static int emulate_forced_invalid_op(str
clear_bit(X86_FEATURE_DE, &d);
clear_bit(X86_FEATURE_PSE, &d);
clear_bit(X86_FEATURE_PGE, &d);
- clear_bit(X86_FEATURE_SEP, &d);
+ if ( !supervisor_mode_kernel )
+ clear_bit(X86_FEATURE_SEP, &d);
if ( !IS_PRIV(current->domain) )
clear_bit(X86_FEATURE_MTRR, &d);
}
diff -r d73eeceeae69 -r 3ffb6cc6b8d2 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Fri Apr 21 17:19:26 2006 +0100
+++ b/xen/arch/x86/x86_32/traps.c Fri Apr 21 17:19:29 2006 +0100
@@ -318,6 +318,16 @@ void init_int80_direct_trap(struct vcpu
set_int80_direct_trap(v);
}
+#ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL
+static void do_update_sysenter(void *info)
+{
+ xen_callback_t *address = info;
+
+ wrmsr(MSR_IA32_SYSENTER_CS, address->cs, 0);
+ wrmsr(MSR_IA32_SYSENTER_EIP, address->eip, 0);
+}
+#endif
+
static long register_guest_callback(struct callback_register *reg)
{
long ret = 0;
@@ -336,6 +346,15 @@ static long register_guest_callback(stru
v->arch.guest_context.failsafe_callback_cs = reg->address.cs;
v->arch.guest_context.failsafe_callback_eip = reg->address.eip;
break;
+
+#ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL
+ case CALLBACKTYPE_sysenter:
+ if ( ! cpu_has_sep )
+ ret = -EINVAL;
+ else if ( on_each_cpu(do_update_sysenter, ®->address, 1, 1) != 0 )
+ ret = -EIO;
+ break;
+#endif
case CALLBACKTYPE_nmi:
ret = register_guest_nmi_callback(reg->address.eip);
diff -r d73eeceeae69 -r 3ffb6cc6b8d2 xen/include/asm-x86/cpufeature.h
--- a/xen/include/asm-x86/cpufeature.h Fri Apr 21 17:19:26 2006 +0100
+++ b/xen/include/asm-x86/cpufeature.h Fri Apr 21 17:19:29 2006 +0100
@@ -104,6 +104,7 @@
#define cpu_has_pae boot_cpu_has(X86_FEATURE_PAE)
#define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE)
#define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC)
+#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP)
#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR)
#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX)
#define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR)
@@ -125,6 +126,7 @@
#define cpu_has_pae 1
#define cpu_has_pge 1
#define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC)
+#define cpu_has_sep 0
#define cpu_has_mtrr 1
#define cpu_has_mmx 1
#define cpu_has_fxsr 1
diff -r d73eeceeae69 -r 3ffb6cc6b8d2 xen/include/public/callback.h
--- a/xen/include/public/callback.h Fri Apr 21 17:19:26 2006 +0100
+++ b/xen/include/public/callback.h Fri Apr 21 17:19:29 2006 +0100
@@ -21,6 +21,11 @@
#define CALLBACKTYPE_event 0
#define CALLBACKTYPE_failsafe 1
#define CALLBACKTYPE_syscall 2 /* x86_64 only */
+/*
+ * sysenter is only available on x86_32 with the
+ * supervisor_mode_kernel option enabled.
+ */
+#define CALLBACKTYPE_sysenter 3
#define CALLBACKTYPE_nmi 4
/*
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|