]> xenbits.xensource.com Git - people/andrewcoop/xen.git/commitdiff
x86: refactor psr: L3 CAT: implement get value flow.
authorYi Sun <yi.y.sun@linux.intel.com>
Tue, 1 Aug 2017 09:04:00 +0000 (11:04 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 3 Aug 2017 10:33:24 +0000 (12:33 +0200)
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 <yi.y.sun@linux.intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/domctl.c
xen/arch/x86/psr.c
xen/include/asm-x86/psr.h

index c1d016be20029a6e22ddd96360c5779cc2162c53..e9a72c8283cee59f67a83141fffbe359da933fc1 100644 (file)
@@ -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;
 
index 20d083e6d7f3eb506cdc459cc646917f03b5df58..0fe63dda9df682adfee648abc77f4e4b91b4de63 100644 (file)
@@ -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,
index 8d15328faab75ff70db17144ee8b8526c60ec6ab..0e960bf76a1264a796e618e121d0f61493ca42e7 100644 (file)
@@ -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);