]> xenbits.xensource.com Git - xen.git/commitdiff
x86/msr: introduce struct msr_vcpu_policy
authorSergey Dyasli <sergey.dyasli@citrix.com>
Mon, 25 Sep 2017 08:54:09 +0000 (10:54 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 25 Sep 2017 08:54:09 +0000 (10:54 +0200)
The new structure contains information about guest's MSRs that are
unique to each vCPU. It starts with only 1 MSR:

    MSR_INTEL_MISC_FEATURES_ENABLES

Which currently has only 1 usable bit: cpuid_faulting.

Add 2 global policy objects: hvm_max and pv_max that are inited during
boot up. Availability of MSR_INTEL_MISC_FEATURES_ENABLES depends on
availability of MSR_INTEL_PLATFORM_INFO.

Add init_vcpu_msr_policy() which sets initial MSR policy for every vCPU
during domain creation with a special case for Dom0.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
xen/arch/x86/domain.c
xen/arch/x86/msr.c
xen/include/asm-x86/domain.h
xen/include/asm-x86/msr.h

index ca64903132af66e8bae42425216764ae17a599df..466a1a2facc36878fda4d374b1728a96d8996fe9 100644 (file)
@@ -351,13 +351,27 @@ int vcpu_initialise(struct vcpu *v)
         /* Idle domain */
         v->arch.cr3 = __pa(idle_pg_table);
         rc = 0;
+        v->arch.msr = ZERO_BLOCK_PTR; /* Catch stray misuses */
     }
 
     if ( rc )
-        vcpu_destroy_fpu(v);
-    else if ( !is_idle_domain(v->domain) )
+        goto fail;
+
+    if ( !is_idle_domain(v->domain) )
+    {
         vpmu_initialise(v);
 
+        if ( (rc = init_vcpu_msr_policy(v)) )
+            goto fail;
+    }
+
+    return rc;
+
+ fail:
+    vcpu_destroy_fpu(v);
+    xfree(v->arch.msr);
+    v->arch.msr = NULL;
+
     return rc;
 }
 
index eac50ec897b2b526bacac2956b548de101c7fad5..b5ad97d3c813157c4acce352c65808be2869d6ac 100644 (file)
 struct msr_domain_policy __read_mostly hvm_max_msr_domain_policy,
                          __read_mostly  pv_max_msr_domain_policy;
 
+struct msr_vcpu_policy __read_mostly hvm_max_msr_vcpu_policy,
+                       __read_mostly  pv_max_msr_vcpu_policy;
+
 static void __init calculate_hvm_max_policy(void)
 {
     struct msr_domain_policy *dp = &hvm_max_msr_domain_policy;
+    struct msr_vcpu_policy *vp = &hvm_max_msr_vcpu_policy;
 
     if ( !hvm_enabled )
         return;
@@ -40,11 +44,15 @@ static void __init calculate_hvm_max_policy(void)
         dp->plaform_info.available = true;
         dp->plaform_info.cpuid_faulting = true;
     }
+
+    /* 0x00000140  MSR_INTEL_MISC_FEATURES_ENABLES */
+    vp->misc_features_enables.available = dp->plaform_info.available;
 }
 
 static void __init calculate_pv_max_policy(void)
 {
     struct msr_domain_policy *dp = &pv_max_msr_domain_policy;
+    struct msr_vcpu_policy *vp = &pv_max_msr_vcpu_policy;
 
     /* 0x000000ce  MSR_INTEL_PLATFORM_INFO */
     if ( cpu_has_cpuid_faulting )
@@ -52,6 +60,9 @@ static void __init calculate_pv_max_policy(void)
         dp->plaform_info.available = true;
         dp->plaform_info.cpuid_faulting = true;
     }
+
+    /* 0x00000140  MSR_INTEL_MISC_FEATURES_ENABLES */
+    vp->misc_features_enables.available = dp->plaform_info.available;
 }
 
 void __init init_guest_msr_policy(void)
@@ -84,6 +95,28 @@ int init_domain_msr_policy(struct domain *d)
     return 0;
 }
 
+int init_vcpu_msr_policy(struct vcpu *v)
+{
+    struct domain *d = v->domain;
+    struct msr_vcpu_policy *vp;
+
+    vp = xmalloc(struct msr_vcpu_policy);
+
+    if ( !vp )
+        return -ENOMEM;
+
+    *vp = is_pv_domain(d) ? pv_max_msr_vcpu_policy :
+                            hvm_max_msr_vcpu_policy;
+
+    /* See comment in intel_ctxt_switch_levelling() */
+    if ( is_control_domain(d) )
+        vp->misc_features_enables.available = false;
+
+    v->arch.msr = vp;
+
+    return 0;
+}
+
 /*
  * Local variables:
  * mode: C
index 1734eb0e257d436f1f065a76c1bcd0712d9c84c2..028bbd2ed3b719ffb209bf23c8ee8fc541732940 100644 (file)
@@ -577,6 +577,8 @@ struct arch_vcpu
 
     struct arch_vm_event *vm_event;
 
+    struct msr_vcpu_policy *msr;
+
     struct {
         bool next_interrupt_enabled;
     } monitor;
index 5cf7be1821ebf459c62f55ce9bdd06c3b91e3917..7c8395b9b30e103f5b73aade94a0c138aa65bec3 100644 (file)
@@ -212,8 +212,19 @@ struct msr_domain_policy
     } plaform_info;
 };
 
+/* MSR policy object for per-vCPU MSRs */
+struct msr_vcpu_policy
+{
+    /* 0x00000140  MSR_INTEL_MISC_FEATURES_ENABLES */
+    struct {
+        bool available; /* This MSR is non-architectural */
+        bool cpuid_faulting;
+    } misc_features_enables;
+};
+
 void init_guest_msr_policy(void);
 int init_domain_msr_policy(struct domain *d);
+int init_vcpu_msr_policy(struct vcpu *v);
 
 #endif /* !__ASSEMBLY__ */