diff options
Diffstat (limited to 'pkgs/os-specific/linux/kernel/no-xsave.patch')
-rw-r--r-- | pkgs/os-specific/linux/kernel/no-xsave.patch | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/kernel/no-xsave.patch b/pkgs/os-specific/linux/kernel/no-xsave.patch new file mode 100644 index 000000000000..dde96d7dccd4 --- /dev/null +++ b/pkgs/os-specific/linux/kernel/no-xsave.patch @@ -0,0 +1,85 @@ +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -168,21 +168,23 @@ static void __init xen_banner(void) + xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); + } + ++static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; ++static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; ++ + static void xen_cpuid(unsigned int *ax, unsigned int *bx, + unsigned int *cx, unsigned int *dx) + { ++ unsigned maskecx = ~0; + unsigned maskedx = ~0; + + /* + * Mask out inconvenient features, to try and disable as many + * unsupported kernel subsystems as possible. + */ +- if (*ax == 1) +- maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ +- (1 << X86_FEATURE_ACPI) | /* disable ACPI */ +- (1 << X86_FEATURE_MCE) | /* disable MCE */ +- (1 << X86_FEATURE_MCA) | /* disable MCA */ +- (1 << X86_FEATURE_ACC)); /* thermal monitoring */ ++ if (*ax == 1) { ++ maskecx = cpuid_leaf1_ecx_mask; ++ maskedx = cpuid_leaf1_edx_mask; ++ } + + asm(XEN_EMULATE_PREFIX "cpuid" + : "=a" (*ax), +@@ -190,9 +192,43 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, + "=c" (*cx), + "=d" (*dx) + : "0" (*ax), "2" (*cx)); ++ ++ *cx &= maskecx; + *dx &= maskedx; + } + ++static __init void xen_init_cpuid_mask(void) ++{ ++ unsigned int ax, bx, cx, dx; ++ ++ cpuid_leaf1_edx_mask = ++ ~((1 << X86_FEATURE_MCE) | /* disable MCE */ ++ (1 << X86_FEATURE_MCA) | /* disable MCA */ ++ (1 << X86_FEATURE_ACC)); /* thermal monitoring */ ++ ++ if (!xen_initial_domain()) ++ cpuid_leaf1_edx_mask &= ++ ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ ++ (1 << X86_FEATURE_ACPI)); /* disable ACPI */ ++ ++ ax = 1; ++ xen_cpuid(&ax, &bx, &cx, &dx); ++ ++ /* cpuid claims we support xsave; try enabling it to see what happens */ ++ if (cx & (1 << (X86_FEATURE_XSAVE % 32))) { ++ unsigned long cr4; ++ ++ set_in_cr4(X86_CR4_OSXSAVE); ++ ++ cr4 = read_cr4(); ++ ++ if ((cr4 & X86_CR4_OSXSAVE) == 0) ++ cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32)); ++ ++ clear_in_cr4(X86_CR4_OSXSAVE); ++ } ++} ++ + static void xen_set_debugreg(int reg, unsigned long val) + { + HYPERVISOR_set_debugreg(reg, val); +@@ -903,6 +939,8 @@ asmlinkage void __init xen_start_kernel(void) + + xen_init_irq_ops(); + ++ xen_init_cpuid_mask(); ++ + #ifdef CONFIG_X86_LOCAL_APIC + /* + * set up the basic apic ops. |