diff mbox

[v1,2/5] x86/msr: introduce struct msr_vcpu_policy

Message ID 20170830103433.6605-3-sergey.dyasli@citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sergey Dyasli Aug. 30, 2017, 10:34 a.m. UTC
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>
---
 xen/arch/x86/domain.c        | 18 ++++++++++++++++--
 xen/arch/x86/msr.c           | 33 +++++++++++++++++++++++++++++++++
 xen/include/asm-x86/domain.h |  2 ++
 xen/include/asm-x86/msr.h    | 11 +++++++++++
 4 files changed, 62 insertions(+), 2 deletions(-)

Comments

Tian, Kevin Sept. 21, 2017, 1:45 a.m. UTC | #1
> From: Sergey Dyasli [mailto:sergey.dyasli@citrix.com]
> Sent: Wednesday, August 30, 2017 6:35 PM
> 
> 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>

with similar cosmetic comments:

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Jan Beulich Sept. 25, 2017, 8:32 a.m. UTC | #2
>>> On 30.08.17 at 12:34, <sergey.dyasli@citrix.com> wrote:
> @@ -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;
>  }

The similarity of the two changes makes me wonder whether
down the road it wouldn't be better to have a function doing
things which are uniform between HVM and PV.

> @@ -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;

It's CPUID faulting that's meant to be suppressed, not the MSR's
presence.

> --- a/xen/include/asm-x86/msr.h
> +++ b/xen/include/asm-x86/msr.h
> @@ -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;

Here as well as in patch 1 I think down the road we want these
to be single-bit bitfields, to limit the growth of the structure.

In any event, none of the comments are meant to prevent the
series from going in as-is - in fact I'm preparing to commit it as
I'm going over the patches. Follow-up changes for some of the
items pointed out would be nice post-4.10.

Jan
diff mbox

Patch

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 620666b33a..1667d2ad57 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -344,13 +344,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;
 }
 
diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
index eac50ec897..b5ad97d3c8 100644
--- a/xen/arch/x86/msr.c
+++ b/xen/arch/x86/msr.c
@@ -27,9 +27,13 @@ 
 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
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index f08ede3a05..866a03b508 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -575,6 +575,8 @@  struct arch_vcpu
 
     struct arch_vm_event *vm_event;
 
+    struct msr_vcpu_policy *msr;
+
     struct {
         bool next_interrupt_enabled;
     } monitor;
diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h
index 5cf7be1821..7c8395b9b3 100644
--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -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__ */