]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/xen/setup.c
Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-omap-h63xx.git] / arch / x86 / xen / setup.c
index 9d7a144028956cf518f6205b2e8e523ee8b94c69..b6acc3a0af46d0adeb44a99a8b8d78e1ef8c5140 100644 (file)
@@ -83,12 +83,16 @@ 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)
 {
-#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
-       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
 }
@@ -106,46 +110,43 @@ 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
-       if (!boot_cpu_has(X86_FEATURE_SEP)) {
-               return;
-       }
+       sysenter_feature = X86_FEATURE_SEP;
 #else
-       if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL &&
-           boot_cpu_data.x86_vendor != X86_VENDOR_CENTAUR) {
-               return;
-       }
+       sysenter_feature = X86_FEATURE_SYSENTER32;
 #endif
 
+       if (!boot_cpu_has(sysenter_feature))
+               return;
+
        ret = register_callback(CALLBACKTYPE_sysenter, xen_sysenter_target);
-       if(ret != 0) {
-               clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SEP);
-               clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP);
-       }
+       if(ret != 0)
+               setup_clear_cpu_cap(sysenter_feature);
 }
 
 void __cpuinit xen_enable_syscall(void)
 {
 #ifdef CONFIG_X86_64
-       int cpu = smp_processor_id();
        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("failed to set syscall: %d\n", ret);
-               clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SYSCALL);
-               clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SYSCALL);
-       } else {
+               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_SYSCALL32)) {
                ret = register_callback(CALLBACKTYPE_syscall32,
                                        xen_syscall32_target);
                if (ret != 0)
-                       printk("failed to set 32-bit syscall: %d\n", ret);
+                       setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
        }
 #endif /* CONFIG_X86_64 */
 }