At present, QEMU determines if the user has set the "lbr-fmt" property
by checking if its value differs from a special value,
`~PERF_CAP_LBR_FMT` (`~0x3f`).
Relying on such a magic number to distinguish user input from the
default state is implicit and fragile. It also prevents the helper macro
`DEFINE_PROP_UINT64_CHECKMASK` from supporting a *valid* default value,
as initializing the property with a valid default would make it
impossible to distinguish from a user-provided value.
With the introduction of `OBJ_PROP_FLAG_USER_SET`, it's possible to
directly check this flag to determine whether the user has modified the
property, which can help get rid of invalid "sentinel" value.
Therefore, detect user-provided value by checking the USER_SET property
flag in x86_cpu_realizefn(). The invalid initialization value will be
dropped in subsequent work.
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
target/i386/cpu.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a594747f0030..a6d943c53a3f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -9779,6 +9779,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
CPUX86State *env = &cpu->env;
Error *local_err = NULL;
unsigned requested_lbr_fmt;
+ int lbr_fmt_set;
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
/* Use pc-relative instructions in system-mode */
@@ -9815,7 +9816,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
* Override env->features[FEAT_PERF_CAPABILITIES].LBR_FMT
* with user-provided setting.
*/
- if (cpu->lbr_fmt != ~PERF_CAP_LBR_FMT) {
+ lbr_fmt_set = object_property_check_flags(OBJECT(dev), "lbr-fmt",
+ OBJ_PROP_FLAG_USER_SET, errp);
+ if (lbr_fmt_set < 0) {
+ return;
+ } else if (lbr_fmt_set > 0) {
env->features[FEAT_PERF_CAPABILITIES] &= ~PERF_CAP_LBR_FMT;
env->features[FEAT_PERF_CAPABILITIES] |= cpu->lbr_fmt;
}
--
2.34.1