|
@@ -277,31 +277,19 @@ static bool __init xen_check_mwait(void)
|
|
|
|
|
|
static bool __init xen_check_xsave(void)
|
|
|
{
|
|
|
- unsigned int err, eax, edx;
|
|
|
+ unsigned int cx, xsave_mask;
|
|
|
|
|
|
- /*
|
|
|
- * Xen 4.0 and older accidentally leaked the host XSAVE flag into guest
|
|
|
- * view, despite not being able to support guests using the
|
|
|
- * functionality. Probe for the actual availability of XSAVE by seeing
|
|
|
- * whether xgetbv executes successfully or raises #UD.
|
|
|
- */
|
|
|
- asm volatile("1: .byte 0x0f,0x01,0xd0\n\t" /* xgetbv */
|
|
|
- "xor %[err], %[err]\n"
|
|
|
- "2:\n\t"
|
|
|
- ".pushsection .fixup,\"ax\"\n\t"
|
|
|
- "3: movl $1,%[err]\n\t"
|
|
|
- "jmp 2b\n\t"
|
|
|
- ".popsection\n\t"
|
|
|
- _ASM_EXTABLE(1b, 3b)
|
|
|
- : [err] "=r" (err), "=a" (eax), "=d" (edx)
|
|
|
- : "c" (0));
|
|
|
-
|
|
|
- return err == 0;
|
|
|
+ cx = cpuid_ecx(1);
|
|
|
+
|
|
|
+ xsave_mask = (1 << (X86_FEATURE_XSAVE % 32)) |
|
|
|
+ (1 << (X86_FEATURE_OSXSAVE % 32));
|
|
|
+
|
|
|
+ /* Xen will set CR4.OSXSAVE if supported and not disabled by force */
|
|
|
+ return (cx & xsave_mask) == xsave_mask;
|
|
|
}
|
|
|
|
|
|
static void __init xen_init_capabilities(void)
|
|
|
{
|
|
|
- setup_clear_cpu_cap(X86_BUG_SYSRET_SS_ATTRS);
|
|
|
setup_force_cpu_cap(X86_FEATURE_XENPV);
|
|
|
setup_clear_cpu_cap(X86_FEATURE_DCA);
|
|
|
setup_clear_cpu_cap(X86_FEATURE_APERFMPERF);
|
|
@@ -317,10 +305,7 @@ static void __init xen_init_capabilities(void)
|
|
|
else
|
|
|
setup_clear_cpu_cap(X86_FEATURE_MWAIT);
|
|
|
|
|
|
- if (xen_check_xsave()) {
|
|
|
- setup_force_cpu_cap(X86_FEATURE_XSAVE);
|
|
|
- setup_force_cpu_cap(X86_FEATURE_OSXSAVE);
|
|
|
- } else {
|
|
|
+ if (!xen_check_xsave()) {
|
|
|
setup_clear_cpu_cap(X86_FEATURE_XSAVE);
|
|
|
setup_clear_cpu_cap(X86_FEATURE_OSXSAVE);
|
|
|
}
|
|
@@ -988,6 +973,13 @@ void xen_setup_shared_info(void)
|
|
|
#endif
|
|
|
|
|
|
xen_setup_mfn_list_list();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Now that shared info is set up we can start using routines that
|
|
|
+ * point to pvclock area.
|
|
|
+ */
|
|
|
+ if (system_state == SYSTEM_BOOTING)
|
|
|
+ xen_init_time_ops();
|
|
|
}
|
|
|
|
|
|
/* This is called once we have the cpu_possible_mask */
|
|
@@ -1286,8 +1278,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
|
|
|
x86_init.oem.arch_setup = xen_arch_setup;
|
|
|
x86_init.oem.banner = xen_banner;
|
|
|
|
|
|
- xen_init_time_ops();
|
|
|
-
|
|
|
/*
|
|
|
* Set up some pagetable state before starting to set any ptes.
|
|
|
*/
|