]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/xen/setup.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / arch / x86 / xen / setup.c
index bea3d4f779dbbd4ad484a575e716a41a8270e9e2..b6acc3a0af46d0adeb44a99a8b8d78e1ef8c5140 100644 (file)
@@ -83,12 +83,18 @@ static void xen_idle(void)
 
 /*
  * Set the bit indicating "nosegneg" library variants should be used.
+ * We only need to bother in pure 32-bit mode; compat 32-bit processes
+ * can have un-truncated segments, so wrapping around is allowed.
  */
 static void __init fiddle_vdso(void)
 {
-       extern const char vdso32_default_start;
-       u32 *mask = VDSO32_SYMBOL(&vdso32_default_start, NOTE_MASK);
+#ifdef CONFIG_X86_32
+       u32 *mask;
+       mask = VDSO32_SYMBOL(&vdso32_int80_start, NOTE_MASK);
        *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
+       mask = VDSO32_SYMBOL(&vdso32_sysenter_start, NOTE_MASK);
+       *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
+#endif
 }
 
 static __cpuinit int register_callback(unsigned type, const void *func)
@@ -104,15 +110,45 @@ static __cpuinit int register_callback(unsigned type, const void *func)
 
 void __cpuinit xen_enable_sysenter(void)
 {
-       int cpu = smp_processor_id();
        extern void xen_sysenter_target(void);
+       int ret;
+       unsigned sysenter_feature;
+
+#ifdef CONFIG_X86_32
+       sysenter_feature = X86_FEATURE_SEP;
+#else
+       sysenter_feature = X86_FEATURE_SYSENTER32;
+#endif
+
+       if (!boot_cpu_has(sysenter_feature))
+               return;
+
+       ret = register_callback(CALLBACKTYPE_sysenter, xen_sysenter_target);
+       if(ret != 0)
+               setup_clear_cpu_cap(sysenter_feature);
+}
+
+void __cpuinit xen_enable_syscall(void)
+{
+#ifdef CONFIG_X86_64
+       int ret;
+       extern void xen_syscall_target(void);
+       extern void xen_syscall32_target(void);
+
+       ret = register_callback(CALLBACKTYPE_syscall, xen_syscall_target);
+       if (ret != 0) {
+               printk(KERN_ERR "Failed to set syscall callback: %d\n", ret);
+               /* Pretty fatal; 64-bit userspace has no other
+                  mechanism for syscalls. */
+       }
 
-       if (!boot_cpu_has(X86_FEATURE_SEP) ||
-           register_callback(CALLBACKTYPE_sysenter,
-                             xen_sysenter_target) != 0) {
-               clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SEP);
-               clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP);
+       if (boot_cpu_has(X86_FEATURE_SYSCALL32)) {
+               ret = register_callback(CALLBACKTYPE_syscall32,
+                                       xen_syscall32_target);
+               if (ret != 0)
+                       setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
        }
+#endif /* CONFIG_X86_64 */
 }
 
 void __init xen_arch_setup(void)
@@ -131,6 +167,7 @@ void __init xen_arch_setup(void)
                BUG();
 
        xen_enable_sysenter();
+       xen_enable_syscall();
 
        set_iopl.iopl = 1;
        rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);