x86/cpuid: leak OSXSAVE only when XSAVE is not clear in policy
authorIgor Druzhinin <igor.druzhinin@citrix.com>
Thu, 27 Jun 2019 19:41:54 +0000 (20:41 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 28 Jun 2019 12:17:53 +0000 (13:17 +0100)
This fixes booting of old non-PV-OPS kernels which historically
looked for OSXSAVE instead of XSAVE bit in CPUID to check whether
XSAVE feature is enabled. If such a guest appears to be started on
an XSAVE enabled CPU and the feature is explicitly cleared in
policy, leaked OSXSAVE bit from Xen will lead to guest crash early in
boot.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/cpuid.c

index ea9bfc51b649abef84b8c4eceedf2e5fe571a745..ab1a48ff90f2b64baf2df6530a5bfdb667f90405 100644 (file)
@@ -770,7 +770,8 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
              *    damage itself.
              *
              * - Enlightened CPUID or CPUID faulting available:
-             *    Xen can fully control what is seen here.  Guest kernels need
+             *    Xen can fully control what is seen here.  When the guest has
+             *    been configured to have XSAVE available, guest kernels need
              *    to see the leaked OSXSAVE via the enlightened path, but
              *    guest userspace and the native is given architectural
              *    behaviour.
@@ -780,7 +781,8 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
              */
             /* OSXSAVE clear in policy.  Fast-forward CR4 back in. */
             if ( (v->arch.pv.ctrlreg[4] & X86_CR4_OSXSAVE) ||
-                 (regs->entry_vector == TRAP_invalid_op &&
+                 (p->basic.xsave &&
+                  regs->entry_vector == TRAP_invalid_op &&
                   guest_kernel_mode(v, regs) &&
                   (read_cr4() & X86_CR4_OSXSAVE)) )
                 res->c |= cpufeat_mask(X86_FEATURE_OSXSAVE);