[xen master] x86: refactor psr: L3 CAT: implement get value flow.

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

[xen master] x86: refactor psr: L3 CAT: implement get value flow.

patchbot
commit 03f30dc193c8847a1f8bdef15661d7fd00fbba86
Author:     Yi Sun <[hidden email]>
AuthorDate: Tue Aug 1 11:04:00 2017 +0200
Commit:     Jan Beulich <[hidden email]>
CommitDate: Thu Aug 3 12:33:24 2017 +0200

    x86: refactor psr: L3 CAT: implement get value flow.
   
    There is an interface in user space to show feature value of
    domains.
   
    This patch implements get value flow in hypervisor.
   
    It also changes domctl interface to make it more general.
   
    With this patch, 'psr-cat-show' can work for L3 CAT but not for
    L3 code/data which is implemented in CDP related patches.
   
    Signed-off-by: Yi Sun <[hidden email]>
    Reviewed-by: Jan Beulich <[hidden email]>
---
 xen/arch/x86/domctl.c     | 20 ++++++++++---------
 xen/arch/x86/psr.c        | 51 ++++++++++++++++++++++++++++++++++++++++++++---
 xen/include/asm-x86/psr.h |  4 ++--
 3 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index c1d016b..e9a72c8 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1442,6 +1442,8 @@ long arch_do_domctl(
     case XEN_DOMCTL_psr_cat_op:
         switch ( domctl->u.psr_cat_op.cmd )
         {
+            uint32_t val32;
+
         case XEN_DOMCTL_PSR_CAT_OP_SET_L3_CBM:
             ret = psr_set_l3_cbm(d, domctl->u.psr_cat_op.target,
                                  domctl->u.psr_cat_op.data,
@@ -1461,23 +1463,23 @@ long arch_do_domctl(
             break;
 
         case XEN_DOMCTL_PSR_CAT_OP_GET_L3_CBM:
-            ret = psr_get_l3_cbm(d, domctl->u.psr_cat_op.target,
-                                 &domctl->u.psr_cat_op.data,
-                                 PSR_CBM_TYPE_L3);
+            ret = psr_get_val(d, domctl->u.psr_cat_op.target,
+                              &val32, PSR_CBM_TYPE_L3);
+            domctl->u.psr_cat_op.data = val32;
             copyback = true;
             break;
 
         case XEN_DOMCTL_PSR_CAT_OP_GET_L3_CODE:
-            ret = psr_get_l3_cbm(d, domctl->u.psr_cat_op.target,
-                                 &domctl->u.psr_cat_op.data,
-                                 PSR_CBM_TYPE_L3_CODE);
+            ret = psr_get_val(d, domctl->u.psr_cat_op.target,
+                              &val32, PSR_CBM_TYPE_L3_CODE);
+            domctl->u.psr_cat_op.data = val32;
             copyback = true;
             break;
 
         case XEN_DOMCTL_PSR_CAT_OP_GET_L3_DATA:
-            ret = psr_get_l3_cbm(d, domctl->u.psr_cat_op.target,
-                                 &domctl->u.psr_cat_op.data,
-                                 PSR_CBM_TYPE_L3_DATA);
+            ret = psr_get_val(d, domctl->u.psr_cat_op.target,
+                              &val32, PSR_CBM_TYPE_L3_DATA);
+            domctl->u.psr_cat_op.data = val32;
             copyback = true;
             break;
 
diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c
index 20d083e..0fe63dd 100644
--- a/xen/arch/x86/psr.c
+++ b/xen/arch/x86/psr.c
@@ -524,10 +524,55 @@ int psr_get_info(unsigned int socket, enum cbm_type type,
     return -EINVAL;
 }
 
-int psr_get_l3_cbm(struct domain *d, unsigned int socket,
-                   uint64_t *cbm, enum cbm_type type)
+int psr_get_val(struct domain *d, unsigned int socket,
+                uint32_t *val, enum cbm_type type)
 {
-    return 0;
+    const struct psr_socket_info *info = get_socket_info(socket);
+    const struct feat_node *feat;
+    enum psr_feat_type feat_type;
+    unsigned int cos, i;
+
+    ASSERT(val);
+
+    if ( IS_ERR(info) )
+        return PTR_ERR(info);
+
+    feat_type = psr_cbm_type_to_feat_type(type);
+    if ( feat_type >= ARRAY_SIZE(info->features) )
+        return -ENOENT;
+
+    feat = info->features[feat_type];
+    if ( !feat )
+        return -ENOENT;
+
+    if ( !feat_props[feat_type] )
+    {
+        ASSERT_UNREACHABLE();
+        return -ENOENT;
+    }
+
+    cos = d->arch.psr_cos_ids[socket];
+    /*
+     * If input cos exceeds current feature's cos_max, we should return its
+     * default value which is stored in cos 0. This case only happens
+     * when more than two features enabled concurrently and at least one
+     * features's cos_max is bigger than others. When a domain's working cos
+     * id is bigger than some features' cos_max, HW automatically works as
+     * default value for those features which cos_max is smaller.
+     */
+    if ( cos > feat->cos_max )
+        cos = 0;
+
+    for ( i = 0; i < feat_props[feat_type]->cos_num; i++ )
+    {
+        if ( type == feat_props[feat_type]->type[i] )
+        {
+            *val = feat->cos_reg_val[cos * feat_props[feat_type]->cos_num + i];
+            return 0;
+        }
+    }
+
+    return -EINVAL;
 }
 
 int psr_set_l3_cbm(struct domain *d, unsigned int socket,
diff --git a/xen/include/asm-x86/psr.h b/xen/include/asm-x86/psr.h
index 8d15328..0e960bf 100644
--- a/xen/include/asm-x86/psr.h
+++ b/xen/include/asm-x86/psr.h
@@ -72,8 +72,8 @@ void psr_ctxt_switch_to(struct domain *d);
 
 int psr_get_info(unsigned int socket, enum cbm_type type,
                  uint32_t data[], unsigned int array_len);
-int psr_get_l3_cbm(struct domain *d, unsigned int socket,
-                   uint64_t *cbm, enum cbm_type type);
+int psr_get_val(struct domain *d, unsigned int socket,
+                uint32_t *val, enum cbm_type type);
 int psr_set_l3_cbm(struct domain *d, unsigned int socket,
                    uint64_t cbm, enum cbm_type type);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master

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