diff mbox

[v8,18/24] x86: L2 CAT: implement get hw info flow.

Message ID 1487148579-7243-19-git-send-email-yi.y.sun@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yi Sun Feb. 15, 2017, 8:49 a.m. UTC
This patch implements get HW info flow for L2 CAT including L2 CAT callback
function.

Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
---
 xen/arch/x86/psr.c          | 16 ++++++++++++++++
 xen/arch/x86/sysctl.c       | 15 +++++++++++++++
 xen/include/asm-x86/psr.h   |  1 +
 xen/include/public/sysctl.h |  6 ++++++
 4 files changed, 38 insertions(+)

Comments

Roger Pau Monné Feb. 28, 2017, 3:18 p.m. UTC | #1
On Wed, Feb 15, 2017 at 04:49:33PM +0800, Yi Sun wrote:
> This patch implements get HW info flow for L2 CAT including L2 CAT callback
> function.
> 
> Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
> ---
>  xen/arch/x86/psr.c          | 16 ++++++++++++++++
>  xen/arch/x86/sysctl.c       | 15 +++++++++++++++
>  xen/include/asm-x86/psr.h   |  1 +
>  xen/include/public/sysctl.h |  6 ++++++
>  4 files changed, 38 insertions(+)
> 
> diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c
> index 4489637..05100b4 100644
> --- a/xen/arch/x86/psr.c
> +++ b/xen/arch/x86/psr.c
> @@ -276,6 +276,9 @@ static enum psr_feat_type psr_cbm_type_to_feat_type(enum cbm_type type)
>      case PSR_CBM_TYPE_L3_CODE:
>          feat_type = PSR_SOCKET_L3_CDP;
>          break;
> +    case PSR_CBM_TYPE_L2:
> +        feat_type = PSR_SOCKET_L2_CAT;
> +        break;
>      default:
>          feat_type = PSR_SOCKET_UNKNOWN;
>          break;
> @@ -729,8 +732,21 @@ static unsigned int l2_cat_get_cos_max(const struct feat_node *feat)
>      return feat->info.l2_cat_info.cos_max;
>  }
>  
> +static bool l2_cat_get_feat_info(const struct feat_node *feat,
> +                                 uint32_t data[], uint32_t array_len)
> +{
> +    if ( !data || 2 > array_len )
> +        return false;
> +
> +    data[CBM_LEN] = feat->info.l2_cat_info.cbm_len;
> +    data[COS_MAX] = feat->info.l2_cat_info.cos_max;
> +
> +    return true;
> +}
> +
>  struct feat_ops l2_cat_ops = {
>      .get_cos_max = l2_cat_get_cos_max,
> +    .get_feat_info = l2_cat_get_feat_info,
>  };
>  
>  static void __init parse_psr_bool(char *s, char *value, char *feature,
> diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
> index 568bfe9..01cf3b7 100644
> --- a/xen/arch/x86/sysctl.c
> +++ b/xen/arch/x86/sysctl.c
> @@ -207,6 +207,21 @@ long arch_do_sysctl(
>                  ret = -EFAULT;
>              break;
>          }
> +        case XEN_SYSCTL_PSR_CAT_get_l2_info:
> +        {
> +            uint32_t dat[2];

Missing newline, and probalby you want "data" here to match with
XEN_SYSCTL_PSR_CAT_get_l3_info?

Also I think this 2 should be a constant, and it should be used both here and
in l2_cat_get_feat_info.

> +            ret = psr_get_info(sysctl->u.psr_cat_op.target,
> +                               PSR_CBM_TYPE_L2, dat, 2);

ARRAY_SIZE(data)

> +            if ( ret )
> +                break;
> +
> +            sysctl->u.psr_cat_op.u.l2_info.cbm_len = dat[CBM_LEN];
> +            sysctl->u.psr_cat_op.u.l2_info.cos_max = dat[COS_MAX];
> +
> +            if ( !ret && __copy_field_to_guest(u_sysctl, sysctl, u.psr_cat_op) )
> +                ret = -EFAULT;
> +            break;
> +        }
>          default:
>              ret = -EOPNOTSUPP;
>              break;
> diff --git a/xen/include/asm-x86/psr.h b/xen/include/asm-x86/psr.h
> index d7ed012..2e1b3d0 100644
> --- a/xen/include/asm-x86/psr.h
> +++ b/xen/include/asm-x86/psr.h
> @@ -56,6 +56,7 @@ enum cbm_type {
>      PSR_CBM_TYPE_L3,
>      PSR_CBM_TYPE_L3_CODE,
>      PSR_CBM_TYPE_L3_DATA,
> +    PSR_CBM_TYPE_L2,
>  };
>  
>  extern struct psr_cmt *psr_cmt;
> diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
> index 00f5e77..cbf5372 100644
> --- a/xen/include/public/sysctl.h
> +++ b/xen/include/public/sysctl.h
> @@ -744,6 +744,7 @@ typedef struct xen_sysctl_pcitopoinfo xen_sysctl_pcitopoinfo_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_sysctl_pcitopoinfo_t);
>  
>  #define XEN_SYSCTL_PSR_CAT_get_l3_info               0
> +#define XEN_SYSCTL_PSR_CAT_get_l2_info               1
>  struct xen_sysctl_psr_cat_op {
>      uint32_t cmd;       /* IN: XEN_SYSCTL_PSR_CAT_* */
>      uint32_t target;    /* IN */
> @@ -754,6 +755,11 @@ struct xen_sysctl_psr_cat_op {
>  #define XEN_SYSCTL_PSR_CAT_L3_CDP       (1u << 0)
>              uint32_t flags;     /* OUT: CAT flags */
>          } l3_info;
> +
> +        struct {
> +            uint32_t cbm_len;   /* OUT: CBM length */
> +            uint32_t cos_max;   /* OUT: Maximum COS */
> +        } l2_info;
>      } u;
>  };
>  typedef struct xen_sysctl_psr_cat_op xen_sysctl_psr_cat_op_t;
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel
Jan Beulich March 9, 2017, 3:13 p.m. UTC | #2
>>> On 15.02.17 at 09:49, <yi.y.sun@linux.intel.com> wrote:
> +static bool l2_cat_get_feat_info(const struct feat_node *feat,
> +                                 uint32_t data[], uint32_t array_len)
> +{
> +    if ( !data || 2 > array_len )
> +        return false;
> +
> +    data[CBM_LEN] = feat->info.l2_cat_info.cbm_len;
> +    data[COS_MAX] = feat->info.l2_cat_info.cos_max;

What about PSR_FLAG? Which puts under question the
array_len check at the start of this and its sibling functions: If
more array entries are provided, they'd all be left uninitialized
without the caller having a way to know. Coming back to the
data structures being the same for all features, there should
presumably be a structure instead of an array be used for
communication here, and ...

> @@ -754,6 +755,11 @@ struct xen_sysctl_psr_cat_op {
>  #define XEN_SYSCTL_PSR_CAT_L3_CDP       (1u << 0)
>              uint32_t flags;     /* OUT: CAT flags */
>          } l3_info;
> +
> +        struct {
> +            uint32_t cbm_len;   /* OUT: CBM length */
> +            uint32_t cos_max;   /* OUT: Maximum COS */
> +        } l2_info;

... this should use the same structure as l3_info (flags being
set to zero until a use arises). This would then also allow for
more code to be shared instead of duplicated.

Jan
Yi Sun March 10, 2017, 5:57 a.m. UTC | #3
On 17-03-09 08:13:59, Jan Beulich wrote:
> >>> On 15.02.17 at 09:49, <yi.y.sun@linux.intel.com> wrote:
> > +static bool l2_cat_get_feat_info(const struct feat_node *feat,
> > +                                 uint32_t data[], uint32_t array_len)
> > +{
> > +    if ( !data || 2 > array_len )
> > +        return false;
> > +
> > +    data[CBM_LEN] = feat->info.l2_cat_info.cbm_len;
> > +    data[COS_MAX] = feat->info.l2_cat_info.cos_max;
> 
> What about PSR_FLAG? Which puts under question the
> array_len check at the start of this and its sibling functions: If
> more array entries are provided, they'd all be left uninitialized
> without the caller having a way to know. Coming back to the
> data structures being the same for all features, there should
> presumably be a structure instead of an array be used for
> communication here, and ...
> 
> > @@ -754,6 +755,11 @@ struct xen_sysctl_psr_cat_op {
> >  #define XEN_SYSCTL_PSR_CAT_L3_CDP       (1u << 0)
> >              uint32_t flags;     /* OUT: CAT flags */
> >          } l3_info;
> > +
> > +        struct {
> > +            uint32_t cbm_len;   /* OUT: CBM length */
> > +            uint32_t cos_max;   /* OUT: Maximum COS */
> > +        } l2_info;
> 
> ... this should use the same structure as l3_info (flags being
> set to zero until a use arises). This would then also allow for
> more code to be shared instead of duplicated.
> 
Ok, will reuse l3_info for L2 CAT. May modify its name to cat_info.

But for MBA or future feature, its info is different with CAT. So, it may
not be approriate to use a structure as parameter for 'psr_get_info'.
So I would prefer to keep data[]. Of course, I will correct array_len check
per Roger's suggestion, like "array_len != PSR_INFO_SIZE". Is that good to
you?

> Jan
Jan Beulich March 10, 2017, 9:26 a.m. UTC | #4
>>> On 10.03.17 at 06:57, <yi.y.sun@linux.intel.com> wrote:
> On 17-03-09 08:13:59, Jan Beulich wrote:
>> >>> On 15.02.17 at 09:49, <yi.y.sun@linux.intel.com> wrote:
>> > +static bool l2_cat_get_feat_info(const struct feat_node *feat,
>> > +                                 uint32_t data[], uint32_t array_len)
>> > +{
>> > +    if ( !data || 2 > array_len )
>> > +        return false;
>> > +
>> > +    data[CBM_LEN] = feat->info.l2_cat_info.cbm_len;
>> > +    data[COS_MAX] = feat->info.l2_cat_info.cos_max;
>> 
>> What about PSR_FLAG? Which puts under question the
>> array_len check at the start of this and its sibling functions: If
>> more array entries are provided, they'd all be left uninitialized
>> without the caller having a way to know. Coming back to the
>> data structures being the same for all features, there should
>> presumably be a structure instead of an array be used for
>> communication here, and ...
>> 
>> > @@ -754,6 +755,11 @@ struct xen_sysctl_psr_cat_op {
>> >  #define XEN_SYSCTL_PSR_CAT_L3_CDP       (1u << 0)
>> >              uint32_t flags;     /* OUT: CAT flags */
>> >          } l3_info;
>> > +
>> > +        struct {
>> > +            uint32_t cbm_len;   /* OUT: CBM length */
>> > +            uint32_t cos_max;   /* OUT: Maximum COS */
>> > +        } l2_info;
>> 
>> ... this should use the same structure as l3_info (flags being
>> set to zero until a use arises). This would then also allow for
>> more code to be shared instead of duplicated.
>> 
> Ok, will reuse l3_info for L2 CAT. May modify its name to cat_info.

Of course.

> But for MBA or future feature, its info is different with CAT. So, it may
> not be approriate to use a structure as parameter for 'psr_get_info'.
> So I would prefer to keep data[]. Of course, I will correct array_len check
> per Roger's suggestion, like "array_len != PSR_INFO_SIZE". Is that good to
> you?

Yes, if there is a need for it to be that way down the road, then I'm
fine as long as both the risk of array overrun and that of using
uninitialized data are minimized as much as possible.

Jan
diff mbox

Patch

diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c
index 4489637..05100b4 100644
--- a/xen/arch/x86/psr.c
+++ b/xen/arch/x86/psr.c
@@ -276,6 +276,9 @@  static enum psr_feat_type psr_cbm_type_to_feat_type(enum cbm_type type)
     case PSR_CBM_TYPE_L3_CODE:
         feat_type = PSR_SOCKET_L3_CDP;
         break;
+    case PSR_CBM_TYPE_L2:
+        feat_type = PSR_SOCKET_L2_CAT;
+        break;
     default:
         feat_type = PSR_SOCKET_UNKNOWN;
         break;
@@ -729,8 +732,21 @@  static unsigned int l2_cat_get_cos_max(const struct feat_node *feat)
     return feat->info.l2_cat_info.cos_max;
 }
 
+static bool l2_cat_get_feat_info(const struct feat_node *feat,
+                                 uint32_t data[], uint32_t array_len)
+{
+    if ( !data || 2 > array_len )
+        return false;
+
+    data[CBM_LEN] = feat->info.l2_cat_info.cbm_len;
+    data[COS_MAX] = feat->info.l2_cat_info.cos_max;
+
+    return true;
+}
+
 struct feat_ops l2_cat_ops = {
     .get_cos_max = l2_cat_get_cos_max,
+    .get_feat_info = l2_cat_get_feat_info,
 };
 
 static void __init parse_psr_bool(char *s, char *value, char *feature,
diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
index 568bfe9..01cf3b7 100644
--- a/xen/arch/x86/sysctl.c
+++ b/xen/arch/x86/sysctl.c
@@ -207,6 +207,21 @@  long arch_do_sysctl(
                 ret = -EFAULT;
             break;
         }
+        case XEN_SYSCTL_PSR_CAT_get_l2_info:
+        {
+            uint32_t dat[2];
+            ret = psr_get_info(sysctl->u.psr_cat_op.target,
+                               PSR_CBM_TYPE_L2, dat, 2);
+            if ( ret )
+                break;
+
+            sysctl->u.psr_cat_op.u.l2_info.cbm_len = dat[CBM_LEN];
+            sysctl->u.psr_cat_op.u.l2_info.cos_max = dat[COS_MAX];
+
+            if ( !ret && __copy_field_to_guest(u_sysctl, sysctl, u.psr_cat_op) )
+                ret = -EFAULT;
+            break;
+        }
         default:
             ret = -EOPNOTSUPP;
             break;
diff --git a/xen/include/asm-x86/psr.h b/xen/include/asm-x86/psr.h
index d7ed012..2e1b3d0 100644
--- a/xen/include/asm-x86/psr.h
+++ b/xen/include/asm-x86/psr.h
@@ -56,6 +56,7 @@  enum cbm_type {
     PSR_CBM_TYPE_L3,
     PSR_CBM_TYPE_L3_CODE,
     PSR_CBM_TYPE_L3_DATA,
+    PSR_CBM_TYPE_L2,
 };
 
 extern struct psr_cmt *psr_cmt;
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 00f5e77..cbf5372 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -744,6 +744,7 @@  typedef struct xen_sysctl_pcitopoinfo xen_sysctl_pcitopoinfo_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_pcitopoinfo_t);
 
 #define XEN_SYSCTL_PSR_CAT_get_l3_info               0
+#define XEN_SYSCTL_PSR_CAT_get_l2_info               1
 struct xen_sysctl_psr_cat_op {
     uint32_t cmd;       /* IN: XEN_SYSCTL_PSR_CAT_* */
     uint32_t target;    /* IN */
@@ -754,6 +755,11 @@  struct xen_sysctl_psr_cat_op {
 #define XEN_SYSCTL_PSR_CAT_L3_CDP       (1u << 0)
             uint32_t flags;     /* OUT: CAT flags */
         } l3_info;
+
+        struct {
+            uint32_t cbm_len;   /* OUT: CBM length */
+            uint32_t cos_max;   /* OUT: Maximum COS */
+        } l2_info;
     } u;
 };
 typedef struct xen_sysctl_psr_cat_op xen_sysctl_psr_cat_op_t;