[xen master] x86: refactor psr: L3 CAT: set value: implement write msr flow.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen master] x86: refactor psr: L3 CAT: set value: implement write msr flow.

patchbot
commit 200e8af4e51826b07c1694633a42e818a6465773
Author:     Yi Sun <[hidden email]>
AuthorDate: Tue Aug 1 11:04:00 2017 +0200
Commit:     Jan Beulich <[hidden email]>
CommitDate: Thu Aug 3 12:35:19 2017 +0200

    x86: refactor psr: L3 CAT: set value: implement write msr flow.
   
    Continue from previous patch:
    'x86: refactor psr: L3 CAT: set value: implement cos id picking flow.'
   
    We have got the feature value and COS ID to set. Then, we write MSRs of the
    designated feature.
   
    Till now, set value process is completed.
   
    Signed-off-by: Yi Sun <[hidden email]>
    Reviewed-by: Jan Beulich <[hidden email]>
---
 xen/arch/x86/psr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 78 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c
index b553112..6ea2e4e 100644
--- a/xen/arch/x86/psr.c
+++ b/xen/arch/x86/psr.c
@@ -113,6 +113,9 @@ static const struct feat_props {
     /* get_feat_info is used to return feature HW info through sysctl. */
     bool (*get_feat_info)(const struct feat_node *feat,
                           uint32_t data[], unsigned int array_len);
+
+    /* write_msr is used to write out feature MSR register. */
+    void (*write_msr)(unsigned int cos, uint32_t val, enum cbm_type type);
 } *feat_props[FEAT_TYPE_NUM];
 
 /*
@@ -289,11 +292,17 @@ static bool cat_get_feat_info(const struct feat_node *feat,
 }
 
 /* L3 CAT props */
+static void l3_cat_write_msr(unsigned int cos, uint32_t val, enum cbm_type type)
+{
+    wrmsrl(MSR_IA32_PSR_L3_MASK(cos), val);
+}
+
 static const struct feat_props l3_cat_props = {
     .cos_num = 1,
     .type[0] = PSR_CBM_TYPE_L3,
     .alt_type = PSR_CBM_TYPE_UNKNOWN,
     .get_feat_info = cat_get_feat_info,
+    .write_msr = l3_cat_write_msr,
 };
 
 static void __init parse_psr_bool(char *s, char *value, char *feature,
@@ -947,11 +956,79 @@ static int pick_avail_cos(const struct psr_socket_info *info,
     return -EOVERFLOW;
 }
 
+static unsigned int get_socket_cpu(unsigned int socket)
+{
+    if ( likely(socket < nr_sockets) )
+        return cpumask_any(socket_cpumask[socket]);
+
+    return nr_cpu_ids;
+}
+
+struct cos_write_info
+{
+    unsigned int cos;
+    struct feat_node *feature;
+    const uint32_t *val;
+    const struct feat_props *props;
+};
+
+static void do_write_psr_msrs(void *data)
+{
+    const struct cos_write_info *info = data;
+    struct feat_node *feat = info->feature;
+    const struct feat_props *props = info->props;
+    unsigned int i, cos = info->cos, cos_num = props->cos_num;
+
+    for ( i = 0; i < cos_num; i++ )
+    {
+        if ( feat->cos_reg_val[cos * cos_num + i] != info->val[i] )
+        {
+            feat->cos_reg_val[cos * cos_num + i] = info->val[i];
+            props->write_msr(cos, info->val[i], props->type[i]);
+        }
+    }
+}
+
 static int write_psr_msrs(unsigned int socket, unsigned int cos,
                           const uint32_t val[], unsigned int array_len,
                           enum psr_feat_type feat_type)
 {
-    return -ENOENT;
+    int ret;
+    struct psr_socket_info *info = get_socket_info(socket);
+    struct cos_write_info data =
+    {
+        .cos = cos,
+        .feature = info->features[feat_type],
+        .props = feat_props[feat_type],
+    };
+
+    if ( cos > info->features[feat_type]->cos_max )
+        return -EINVAL;
+
+    /* Skip to the feature's value head. */
+    ret = skip_prior_features(&array_len, feat_type);
+    if ( ret < 0 )
+        return ret;
+
+    val += ret;
+
+    if ( array_len < feat_props[feat_type]->cos_num )
+        return -ENOSPC;
+
+    data.val = val;
+
+    if ( socket == cpu_to_socket(smp_processor_id()) )
+        do_write_psr_msrs(&data);
+    else
+    {
+        unsigned int cpu = get_socket_cpu(socket);
+
+        if ( cpu >= nr_cpu_ids )
+            return -ENOTSOCK;
+        on_selected_cpus(cpumask_of(cpu), do_write_psr_msrs, &data, 1);
+    }
+
+    return 0;
 }
 
 int psr_set_val(struct domain *d, unsigned int socket,
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog