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. diff --git a/pkgs/os-specific/linux/kernel/patches.nix b/pkgs/os-specific/linux/kernel/patches.nix index 26a8bf55225d..65cd9b3d8301 100644 --- a/pkgs/os-specific/linux/kernel/patches.nix +++ b/pkgs/os-specific/linux/kernel/patches.nix @@ -203,11 +203,7 @@ rec { no_xsave = { name = "no-xsave"; - patch = fetchurl { - url = "http://kernel.ubuntu.com/git?p=rtg/ubuntu-maverick.git;a=blobdiff_plain;f=arch/x86/xen/enlighten.c;h=f7ff4c7d22954ab5eda464320241300bd5a32ee5;hp=1ea06f842a921557e958110e22941d53a2822f3c;hb=1a30f99;hpb=8f2ff69dce18ed856a8d1b93176f768b47eeed86"; - name = "no-xsave.patch"; - sha256 = "18732s3vmav5rpg6zqpiw2i0ll83pcc4gw266h6545pmbh9p7hky"; - }; + patch = ./no-xsave.patch; features.noXsave = true; };