All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property
@ 2021-06-20  2:42 Yang Weijiang
  2021-06-20  2:42 ` [PATCH v4 2/2] target/i386: Add lbr-fmt vPMU option to support guest LBR Yang Weijiang
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Yang Weijiang @ 2021-06-20  2:42 UTC (permalink / raw)
  To: pbonzini, qemu-devel, kvm, richard.henderson, armbru, wei.w.wang
  Cc: Yang Weijiang

The DEFINE_PROP_UINT64_CHECKMASK maro applies certain mask check agaist
user-supplied property value, reject the value if it violates the bitmask.

Co-developed-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 hw/core/qdev-properties.c    | 19 +++++++++++++++++++
 include/hw/qdev-properties.h | 12 ++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 50f40949f5..343a200784 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -428,6 +428,25 @@ const PropertyInfo qdev_prop_int64 = {
     .set_default_value = qdev_propinfo_set_default_value_int,
 };
 
+static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint64(v, name, ptr, errp);
+    if (*ptr & ~prop->bitmask) {
+        error_setg(errp, "Property value for '%s' violates bitmask '0x%lx'",
+                   name, prop->bitmask);
+    }
+}
+
+const PropertyInfo qdev_prop_uint64_checkmask = {
+    .name  = "uint64",
+    .get   = get_uint64,
+    .set   = set_uint64_checkmask,
+};
+
 /* --- string --- */
 
 static void release_string(Object *obj, const char *name, void *opaque)
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 0ef97d60ce..075882e8c1 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -17,6 +17,7 @@ struct Property {
     const PropertyInfo *info;
     ptrdiff_t    offset;
     uint8_t      bitnr;
+    uint64_t     bitmask;
     bool         set_default;
     union {
         int64_t i;
@@ -53,6 +54,7 @@ extern const PropertyInfo qdev_prop_uint16;
 extern const PropertyInfo qdev_prop_uint32;
 extern const PropertyInfo qdev_prop_int32;
 extern const PropertyInfo qdev_prop_uint64;
+extern const PropertyInfo qdev_prop_uint64_checkmask;
 extern const PropertyInfo qdev_prop_int64;
 extern const PropertyInfo qdev_prop_size;
 extern const PropertyInfo qdev_prop_string;
@@ -102,6 +104,16 @@ extern const PropertyInfo qdev_prop_link;
                 .set_default = true,                         \
                 .defval.u    = (bool)_defval)
 
+/**
+ * The DEFINE_PROP_UINT64_CHECKMASK macro checks a user-supplied value
+ * against corresponding bitmask, rejects the value if it violates.
+ * The default value is set in instance_init().
+ */
+#define DEFINE_PROP_UINT64_CHECKMASK(_name, _state, _field, _bitmask)   \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_uint64_checkmask, uint64_t, \
+                .bitmask    = (_bitmask),                     \
+                .set_default = false)
+
 #define PROP_ARRAY_LEN_PREFIX "len-"
 
 /**
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v4 2/2] target/i386: Add lbr-fmt vPMU option to support guest LBR
  2021-06-20  2:42 [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property Yang Weijiang
@ 2021-06-20  2:42 ` Yang Weijiang
  2021-07-19  7:35 ` [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property Yang Weijiang
  2021-08-26  9:19 ` Yang Weijiang
  2 siblings, 0 replies; 4+ messages in thread
From: Yang Weijiang @ 2021-06-20  2:42 UTC (permalink / raw)
  To: pbonzini, qemu-devel, kvm, richard.henderson, armbru, wei.w.wang
  Cc: Yang Weijiang

The Last Branch Recording (LBR) is a performance monitor unit (PMU)
feature on Intel processors which records a running trace of the most
recent branches taken by the processor in the LBR stack. This option
indicates the LBR format to enable for guest perf.

The LBR feature is enabled if below conditions are met:
1) KVM is enabled and the PMU is enabled.
2) msr-based-feature IA32_PERF_CAPABILITIES is supporterd on KVM.
3) Supported returned value for lbr_fmt from above msr is non-zero.
4) Guest vcpu model does support FEAT_1_ECX.CPUID_EXT_PDCM.
5) User-provided lbr-fmt value doesn't violate its bitmask (0x3f).
6) Target guest LBR format matches that of host.

Co-developed-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Like Xu <like.xu@linux.intel.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
---
 target/i386/cpu.c | 41 +++++++++++++++++++++++++++++++++++++++++
 target/i386/cpu.h | 10 ++++++++++
 2 files changed, 51 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ad99cad0e7..c80b8b7fe2 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6701,6 +6701,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
     CPUX86State *env = &cpu->env;
     Error *local_err = NULL;
     static bool ht_warned;
+    uint64_t requested_lbr_fmt;
 
     if (xcc->host_cpuid_required) {
         if (!accel_uses_host_cpuid()) {
@@ -6748,6 +6749,42 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
         goto out;
     }
 
+    /*
+     * Override env->features[FEAT_PERF_CAPABILITIES].LBR_FMT
+     * with user-provided setting.
+     */
+    if (cpu->lbr_fmt != ~PERF_CAP_LBR_FMT) {
+        if ((cpu->lbr_fmt & PERF_CAP_LBR_FMT) != cpu->lbr_fmt) {
+            error_setg(errp, "invalid lbr-fmt");
+            return;
+        }
+        env->features[FEAT_PERF_CAPABILITIES] &= ~PERF_CAP_LBR_FMT;
+        env->features[FEAT_PERF_CAPABILITIES] |= cpu->lbr_fmt;
+    }
+
+    /*
+     * vPMU LBR is supported when 1) KVM is enabled 2) Option pmu=on and
+     * 3)vPMU LBR format matches that of host setting.
+     */
+    requested_lbr_fmt =
+        env->features[FEAT_PERF_CAPABILITIES] & PERF_CAP_LBR_FMT;
+    if (requested_lbr_fmt && kvm_enabled()) {
+        uint64_t host_perf_cap =
+            x86_cpu_get_supported_feature_word(FEAT_PERF_CAPABILITIES, false);
+        uint64_t host_lbr_fmt = host_perf_cap & PERF_CAP_LBR_FMT;
+
+        if (!cpu->enable_pmu) {
+            error_setg(errp, "vPMU: LBR is unsupported without pmu=on");
+            return;
+        }
+        if (requested_lbr_fmt != host_lbr_fmt) {
+            error_setg(errp, "vPMU: the lbr-fmt value (0x%lx) mismatches "
+                        "the host supported value (0x%lx).",
+                        requested_lbr_fmt, host_lbr_fmt);
+            return;
+        }
+    }
+
     x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid);
 
     if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) {
@@ -7150,6 +7187,9 @@ static void x86_cpu_initfn(Object *obj)
     object_property_add_alias(obj, "sse4_1", obj, "sse4.1");
     object_property_add_alias(obj, "sse4_2", obj, "sse4.2");
 
+    cpu->lbr_fmt = ~PERF_CAP_LBR_FMT;
+    object_property_add_alias(obj, "lbr_fmt", obj, "lbr-fmt");
+
     if (xcc->model) {
         x86_cpu_load_model(cpu, xcc->model);
     }
@@ -7300,6 +7340,7 @@ static Property x86_cpu_properties[] = {
 #endif
     DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID),
     DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
+    DEFINE_PROP_UINT64_CHECKMASK("lbr-fmt", X86CPU, lbr_fmt, PERF_CAP_LBR_FMT),
 
     DEFINE_PROP_UINT32("hv-spinlocks", X86CPU, hyperv_spinlock_attempts,
                        HYPERV_SPINLOCK_NEVER_NOTIFY),
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 1bc300ce85..50e6d66791 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -354,6 +354,7 @@ typedef enum X86Seg {
 #define ARCH_CAP_TSX_CTRL_MSR		(1<<7)
 
 #define MSR_IA32_PERF_CAPABILITIES      0x345
+#define PERF_CAP_LBR_FMT                0x3f
 
 #define MSR_IA32_TSX_CTRL		0x122
 #define MSR_IA32_TSCDEADLINE            0x6e0
@@ -1726,6 +1727,15 @@ struct X86CPU {
      */
     bool enable_pmu;
 
+    /*
+     * Enable LBR_FMT bits of IA32_PERF_CAPABILITIES MSR.
+     * This can't be initialized with a default because it doesn't have
+     * stable ABI support yet. It is only allowed to pass all LBR_FMT bits
+     * returned by kvm_arch_get_supported_msr_feature()(which depends on both
+     * host CPU and kernel capabilities) to the guest.
+     */
+    uint64_t lbr_fmt;
+
     /* LMCE support can be enabled/disabled via cpu option 'lmce=on/off'. It is
      * disabled by default to avoid breaking migration between QEMU with
      * different LMCE configurations.
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property
  2021-06-20  2:42 [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property Yang Weijiang
  2021-06-20  2:42 ` [PATCH v4 2/2] target/i386: Add lbr-fmt vPMU option to support guest LBR Yang Weijiang
@ 2021-07-19  7:35 ` Yang Weijiang
  2021-08-26  9:19 ` Yang Weijiang
  2 siblings, 0 replies; 4+ messages in thread
From: Yang Weijiang @ 2021-07-19  7:35 UTC (permalink / raw)
  To: pbonzini, qemu-devel, kvm; +Cc: Yang, Weijiang

Hello, maintainers,

Could you review this patch series kindly since the legacy LBR patches
have been merged in 5.12 kernel tree?

Thanks!

On Sun, Jun 20, 2021 at 10:42:36AM +0800, Yang, Weijiang wrote:
> The DEFINE_PROP_UINT64_CHECKMASK maro applies certain mask check agaist
> user-supplied property value, reject the value if it violates the bitmask.
> 
> Co-developed-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  hw/core/qdev-properties.c    | 19 +++++++++++++++++++
>  include/hw/qdev-properties.h | 12 ++++++++++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 50f40949f5..343a200784 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -428,6 +428,25 @@ const PropertyInfo qdev_prop_int64 = {
>      .set_default_value = qdev_propinfo_set_default_value_int,
>  };
>  
> +static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name,
> +                      void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint64(v, name, ptr, errp);
> +    if (*ptr & ~prop->bitmask) {
> +        error_setg(errp, "Property value for '%s' violates bitmask '0x%lx'",
> +                   name, prop->bitmask);
> +    }
> +}
> +
> +const PropertyInfo qdev_prop_uint64_checkmask = {
> +    .name  = "uint64",
> +    .get   = get_uint64,
> +    .set   = set_uint64_checkmask,
> +};
> +
>  /* --- string --- */
>  
>  static void release_string(Object *obj, const char *name, void *opaque)
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 0ef97d60ce..075882e8c1 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -17,6 +17,7 @@ struct Property {
>      const PropertyInfo *info;
>      ptrdiff_t    offset;
>      uint8_t      bitnr;
> +    uint64_t     bitmask;
>      bool         set_default;
>      union {
>          int64_t i;
> @@ -53,6 +54,7 @@ extern const PropertyInfo qdev_prop_uint16;
>  extern const PropertyInfo qdev_prop_uint32;
>  extern const PropertyInfo qdev_prop_int32;
>  extern const PropertyInfo qdev_prop_uint64;
> +extern const PropertyInfo qdev_prop_uint64_checkmask;
>  extern const PropertyInfo qdev_prop_int64;
>  extern const PropertyInfo qdev_prop_size;
>  extern const PropertyInfo qdev_prop_string;
> @@ -102,6 +104,16 @@ extern const PropertyInfo qdev_prop_link;
>                  .set_default = true,                         \
>                  .defval.u    = (bool)_defval)
>  
> +/**
> + * The DEFINE_PROP_UINT64_CHECKMASK macro checks a user-supplied value
> + * against corresponding bitmask, rejects the value if it violates.
> + * The default value is set in instance_init().
> + */
> +#define DEFINE_PROP_UINT64_CHECKMASK(_name, _state, _field, _bitmask)   \
> +    DEFINE_PROP(_name, _state, _field, qdev_prop_uint64_checkmask, uint64_t, \
> +                .bitmask    = (_bitmask),                     \
> +                .set_default = false)
> +
>  #define PROP_ARRAY_LEN_PREFIX "len-"
>  
>  /**
> -- 
> 2.21.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property
  2021-06-20  2:42 [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property Yang Weijiang
  2021-06-20  2:42 ` [PATCH v4 2/2] target/i386: Add lbr-fmt vPMU option to support guest LBR Yang Weijiang
  2021-07-19  7:35 ` [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property Yang Weijiang
@ 2021-08-26  9:19 ` Yang Weijiang
  2 siblings, 0 replies; 4+ messages in thread
From: Yang Weijiang @ 2021-08-26  9:19 UTC (permalink / raw)
  To: pbonzini, Eduardo Habkost, qemu-devel, kvm; +Cc: Yang, Weijiang

On Sun, Jun 20, 2021 at 10:42:36AM +0800, Yang, Weijiang wrote:

Hi, Paolo and Eduardo,

Legacy Arch LBR patches have been merged in 5.12 kernel tree, these patches
are corresponding change from QEMU side, without these patches,legacy Arch LBR
cannot work, could you review them at your convenience?

Thanks a lot!

> The DEFINE_PROP_UINT64_CHECKMASK maro applies certain mask check agaist
> user-supplied property value, reject the value if it violates the bitmask.
> 
> Co-developed-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Like Xu <like.xu@linux.intel.com>
> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
> ---
>  hw/core/qdev-properties.c    | 19 +++++++++++++++++++
>  include/hw/qdev-properties.h | 12 ++++++++++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 50f40949f5..343a200784 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -428,6 +428,25 @@ const PropertyInfo qdev_prop_int64 = {
>      .set_default_value = qdev_propinfo_set_default_value_int,
>  };
>  
> +static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name,
> +                      void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint64(v, name, ptr, errp);
> +    if (*ptr & ~prop->bitmask) {
> +        error_setg(errp, "Property value for '%s' violates bitmask '0x%lx'",
> +                   name, prop->bitmask);
> +    }
> +}
> +
> +const PropertyInfo qdev_prop_uint64_checkmask = {
> +    .name  = "uint64",
> +    .get   = get_uint64,
> +    .set   = set_uint64_checkmask,
> +};
> +
>  /* --- string --- */
>  
>  static void release_string(Object *obj, const char *name, void *opaque)
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 0ef97d60ce..075882e8c1 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -17,6 +17,7 @@ struct Property {
>      const PropertyInfo *info;
>      ptrdiff_t    offset;
>      uint8_t      bitnr;
> +    uint64_t     bitmask;
>      bool         set_default;
>      union {
>          int64_t i;
> @@ -53,6 +54,7 @@ extern const PropertyInfo qdev_prop_uint16;
>  extern const PropertyInfo qdev_prop_uint32;
>  extern const PropertyInfo qdev_prop_int32;
>  extern const PropertyInfo qdev_prop_uint64;
> +extern const PropertyInfo qdev_prop_uint64_checkmask;
>  extern const PropertyInfo qdev_prop_int64;
>  extern const PropertyInfo qdev_prop_size;
>  extern const PropertyInfo qdev_prop_string;
> @@ -102,6 +104,16 @@ extern const PropertyInfo qdev_prop_link;
>                  .set_default = true,                         \
>                  .defval.u    = (bool)_defval)
>  
> +/**
> + * The DEFINE_PROP_UINT64_CHECKMASK macro checks a user-supplied value
> + * against corresponding bitmask, rejects the value if it violates.
> + * The default value is set in instance_init().
> + */
> +#define DEFINE_PROP_UINT64_CHECKMASK(_name, _state, _field, _bitmask)   \
> +    DEFINE_PROP(_name, _state, _field, qdev_prop_uint64_checkmask, uint64_t, \
> +                .bitmask    = (_bitmask),                     \
> +                .set_default = false)
> +
>  #define PROP_ARRAY_LEN_PREFIX "len-"
>  
>  /**
> -- 
> 2.21.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-08-26  9:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-20  2:42 [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property Yang Weijiang
2021-06-20  2:42 ` [PATCH v4 2/2] target/i386: Add lbr-fmt vPMU option to support guest LBR Yang Weijiang
2021-07-19  7:35 ` [PATCH v4 1/2] qdev-properties: Add a new macro with bitmask check for uint64_t property Yang Weijiang
2021-08-26  9:19 ` Yang Weijiang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.