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: %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);
+ if (ret != 0) {
+ printk(KERN_INFO "Xen: 32-bit syscall not supported: disabling vdso\n");
+ setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
+ sysctl_vsyscall32 = 0;
+ }
}
#endif /* CONFIG_X86_64 */
}