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; cx = 0; 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 __init xen_init_cpuid_mask(void) { unsigned int ax, bx, cx, dx; unsigned int xsave_mask; cpuid_leaf1_edx_mask = ~((1 << X86_FEATURE_MCE) | /* disable MCE */ (1 << X86_FEATURE_MCA) | /* disable MCA */ (1 << X86_FEATURE_MTRR) | /* disable MTRR */ (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); xsave_mask = (1 << (X86_FEATURE_XSAVE % 32)) | (1 << (X86_FEATURE_OSXSAVE % 32)); /* Xen will set CR4.OSXSAVE if supported and not disabled by force */ if ((cx & xsave_mask) != xsave_mask) cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ }
static bool __init xen_check_mwait(void) { #if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \ !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) struct xen_platform_op op = { .cmd = XENPF_set_processor_pminfo, .u.set_pminfo.id = -1, .u.set_pminfo.type = XEN_PM_PDC, }; uint32_t buf[3]; unsigned int ax, bx, cx, dx; unsigned int mwait_mask; if (!xen_initial_domain()) return false; ax = 1; cx = 0; native_cpuid(&ax, &bx, &cx, &dx); mwait_mask = (1 << (X86_FEATURE_EST % 32)) | (1 << (X86_FEATURE_MWAIT % 32)); if ((cx & mwait_mask) != mwait_mask) return false; ax = CPUID_MWAIT_LEAF; bx = 0; cx = 0; dx = 0; native_cpuid(&ax, &bx, &cx, &dx); buf[0] = ACPI_PDC_REVISION_ID; buf[1] = 1; buf[2] = (ACPI_PDC_C_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_SWSMP); set_xen_guest_handle(op.u.set_pminfo.pdc, buf); if ((HYPERVISOR_dom0_op(&op) == 0) && (buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) { cpuid_leaf5_ecx_val = cx; cpuid_leaf5_edx_val = dx; } return true; #else return false; #endif } static void __init xen_init_cpuid_mask(void) { unsigned int ax, bx, cx, dx; unsigned int xsave_mask; cpuid_leaf1_edx_mask = ~((1 << X86_FEATURE_MCE) | (1 << X86_FEATURE_MCA) | (1 << X86_FEATURE_MTRR) | (1 << X86_FEATURE_ACC)); if (!xen_initial_domain()) cpuid_leaf1_edx_mask &= ~((1 << X86_FEATURE_APIC) | (1 << X86_FEATURE_ACPI)); ax = 1; cx = 0; xen_cpuid(&ax, &bx, &cx, &dx); xsave_mask = (1 << (X86_FEATURE_XSAVE % 32)) | (1 << (X86_FEATURE_OSXSAVE % 32)); if ((cx & xsave_mask) != xsave_mask) cpuid_leaf1_ecx_mask &= ~xsave_mask; if (xen_check_mwait()) cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32)); }
static bool __init xen_check_mwait(void) { #if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \ !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) struct xen_platform_op op = { .cmd = XENPF_set_processor_pminfo, .u.set_pminfo.id = -1, .u.set_pminfo.type = XEN_PM_PDC, }; uint32_t buf[3]; unsigned int ax, bx, cx, dx; unsigned int mwait_mask; /* We need to determine whether it is OK to expose the MWAIT * capability to the kernel to harvest deeper than C3 states from ACPI * _CST using the processor_harvest_xen.c module. For this to work, we * need to gather the MWAIT_LEAF values (which the cstate.c code * checks against). The hypervisor won't expose the MWAIT flag because * it would break backwards compatibility; so we will find out directly * from the hardware and hypercall. */ if (!xen_initial_domain()) return false; ax = 1; cx = 0; native_cpuid(&ax, &bx, &cx, &dx); mwait_mask = (1 << (X86_FEATURE_EST % 32)) | (1 << (X86_FEATURE_MWAIT % 32)); if ((cx & mwait_mask) != mwait_mask) return false; /* We need to emulate the MWAIT_LEAF and for that we need both * ecx and edx. The hypercall provides only partial information. */ ax = CPUID_MWAIT_LEAF; bx = 0; cx = 0; dx = 0; native_cpuid(&ax, &bx, &cx, &dx); /* Ask the Hypervisor whether to clear ACPI_PDC_C_C2C3_FFH. If so, * don't expose MWAIT_LEAF and let ACPI pick the IOPORT version of C3. */ buf[0] = ACPI_PDC_REVISION_ID; buf[1] = 1; buf[2] = (ACPI_PDC_C_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_SWSMP); set_xen_guest_handle(op.u.set_pminfo.pdc, buf); if ((HYPERVISOR_dom0_op(&op) == 0) && (buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) { cpuid_leaf5_ecx_val = cx; cpuid_leaf5_edx_val = dx; } return true; #else return false; #endif } static void __init xen_init_cpuid_mask(void) { unsigned int ax, bx, cx, dx; unsigned int xsave_mask; cpuid_leaf1_edx_mask = ~((1 << X86_FEATURE_MCE) | /* disable MCE */ (1 << X86_FEATURE_MCA) | /* disable MCA */ (1 << X86_FEATURE_MTRR) | /* disable MTRR */ (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; cx = 0; xen_cpuid(&ax, &bx, &cx, &dx); xsave_mask = (1 << (X86_FEATURE_XSAVE % 32)) | (1 << (X86_FEATURE_OSXSAVE % 32)); /* Xen will set CR4.OSXSAVE if supported and not disabled by force */ if ((cx & xsave_mask) != xsave_mask) cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ if (xen_check_mwait()) cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32)); }