[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen stable-4.13] x86/amd: Avoid cpu_has_hypervisor evaluating true on native hardware



commit 5e106996495d98b7c8629f07e99d780db8491ea4
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Thu Apr 9 08:59:55 2020 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Apr 9 08:59:55 2020 +0200

    x86/amd: Avoid cpu_has_hypervisor evaluating true on native hardware
    
    Currently when booting native on AMD hardware, cpuidmask_defaults._1cd gets
    configured with the HYPERVISOR bit before native CPUID is scanned for 
feature
    bits.
    
    This results in cpu_has_hypervisor becoming set as part of identify_cpu(), 
and
    ends up appearing in the raw and host CPU policies.
    
    A combination of this bug, and c/s bb502a8ca59 "x86: check feature flags 
after
    resume" which checks that feature bits don't go missing, results in broken 
S3
    on AMD hardware.
    
    Alter amd_init_levelling() to exclude the HYPERVISOR bit from
    cpumask_defaults, and update domain_cpu_policy_changed() to allow it to be
    explicitly forwarded.
    
    This also fixes a bug on kexec, where the hypervisor bit is left enabled for
    the new kernel to find.
    
    These changes highlight a further but - dom0 construction is asymetric with
    domU construction, by not having any calls to domain_cpu_policy_changed().
    Extend arch_domain_create() to always call domain_cpu_policy_changed().
    
    Reported-by: Igor Druzhinin <igor.druzhinin@xxxxxxxxxx>
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
    master commit: e2d1254f5af2a6ff24d009523639b80ccba2c089
    master date: 2020-02-14 18:01:52 +0000
---
 xen/arch/x86/cpu/amd.c       | 3 ---
 xen/arch/x86/domain.c        | 2 ++
 xen/arch/x86/domctl.c        | 9 ++++++++-
 xen/include/asm-x86/domain.h | 2 ++
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 8b5f0f2e4c..0906b23582 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -297,9 +297,6 @@ static void __init noinline amd_init_levelling(void)
                        ecx |= cpufeat_mask(X86_FEATURE_OSXSAVE);
                edx |= cpufeat_mask(X86_FEATURE_APIC);
 
-               /* Allow the HYPERVISOR bit to be set via guest policy. */
-               ecx |= cpufeat_mask(X86_FEATURE_HYPERVISOR);
-
                cpuidmask_defaults._1cd = ((uint64_t)ecx << 32) | edx;
        }
 
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 94531be05e..2ce00fb26f 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -665,6 +665,8 @@ int arch_domain_create(struct domain *d,
      */
     d->arch.x87_fip_width = cpu_has_fpu_sel ? 0 : 8;
 
+    domain_cpu_policy_changed(d);
+
     return 0;
 
  fail:
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 7aed545d2d..d73bc8f318 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -46,7 +46,7 @@ static int gdbsx_guest_mem_io(domid_t domid, struct 
xen_domctl_gdbsx_memio *iop)
     return iop->remain ? -EFAULT : 0;
 }
 
-static void domain_cpu_policy_changed(struct domain *d)
+void domain_cpu_policy_changed(struct domain *d)
 {
     const struct cpuid_policy *p = d->arch.cpuid;
     struct vcpu *v;
@@ -104,6 +104,13 @@ static void domain_cpu_policy_changed(struct domain *d)
                     ecx = 0;
                 edx = cpufeat_mask(X86_FEATURE_APIC);
 
+                /*
+                 * If the Hypervisor bit is set in the policy, we can also
+                 * forward it into real CPUID.
+                 */
+                if ( p->basic.hypervisor )
+                    ecx |= cpufeat_mask(X86_FEATURE_HYPERVISOR);
+
                 mask |= ((uint64_t)ecx << 32) | edx;
                 break;
             }
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 2c0940899b..9dc7556980 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -627,6 +627,8 @@ struct guest_memory_policy
 void update_guest_memory_policy(struct vcpu *v,
                                 struct guest_memory_policy *policy);
 
+void domain_cpu_policy_changed(struct domain *d);
+
 bool update_runstate_area(struct vcpu *);
 bool update_secondary_system_time(struct vcpu *,
                                   struct vcpu_time_info *);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.