at v206 2.4 kB view raw
1--- a/arch/x86/xen/enlighten.c 2+++ b/arch/x86/xen/enlighten.c 3@@ -168,21 +168,23 @@ static void __init xen_banner(void) 4 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); 5 } 6 7+static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; 8+static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; 9+ 10 static void xen_cpuid(unsigned int *ax, unsigned int *bx, 11 unsigned int *cx, unsigned int *dx) 12 { 13+ unsigned maskecx = ~0; 14 unsigned maskedx = ~0; 15 16 /* 17 * Mask out inconvenient features, to try and disable as many 18 * unsupported kernel subsystems as possible. 19 */ 20- if (*ax == 1) 21- maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ 22- (1 << X86_FEATURE_ACPI) | /* disable ACPI */ 23- (1 << X86_FEATURE_MCE) | /* disable MCE */ 24- (1 << X86_FEATURE_MCA) | /* disable MCA */ 25- (1 << X86_FEATURE_ACC)); /* thermal monitoring */ 26+ if (*ax == 1) { 27+ maskecx = cpuid_leaf1_ecx_mask; 28+ maskedx = cpuid_leaf1_edx_mask; 29+ } 30 31 asm(XEN_EMULATE_PREFIX "cpuid" 32 : "=a" (*ax), 33@@ -190,9 +192,43 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, 34 "=c" (*cx), 35 "=d" (*dx) 36 : "0" (*ax), "2" (*cx)); 37+ 38+ *cx &= maskecx; 39 *dx &= maskedx; 40 } 41 42+static __init void xen_init_cpuid_mask(void) 43+{ 44+ unsigned int ax, bx, cx, dx; 45+ 46+ cpuid_leaf1_edx_mask = 47+ ~((1 << X86_FEATURE_MCE) | /* disable MCE */ 48+ (1 << X86_FEATURE_MCA) | /* disable MCA */ 49+ (1 << X86_FEATURE_ACC)); /* thermal monitoring */ 50+ 51+ if (!xen_initial_domain()) 52+ cpuid_leaf1_edx_mask &= 53+ ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ 54+ (1 << X86_FEATURE_ACPI)); /* disable ACPI */ 55+ 56+ ax = 1; 57+ xen_cpuid(&ax, &bx, &cx, &dx); 58+ 59+ /* cpuid claims we support xsave; try enabling it to see what happens */ 60+ if (cx & (1 << (X86_FEATURE_XSAVE % 32))) { 61+ unsigned long cr4; 62+ 63+ set_in_cr4(X86_CR4_OSXSAVE); 64+ 65+ cr4 = read_cr4(); 66+ 67+ if ((cr4 & X86_CR4_OSXSAVE) == 0) 68+ cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32)); 69+ 70+ clear_in_cr4(X86_CR4_OSXSAVE); 71+ } 72+} 73+ 74 static void xen_set_debugreg(int reg, unsigned long val) 75 { 76 HYPERVISOR_set_debugreg(reg, val); 77@@ -903,6 +939,8 @@ asmlinkage void __init xen_start_kernel(void) 78 79 xen_init_irq_ops(); 80 81+ xen_init_cpuid_mask(); 82+ 83 #ifdef CONFIG_X86_LOCAL_APIC 84 /* 85 * set up the basic apic ops.