mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
target/i386: Add lbr-fmt vPMU option to support guest LBR
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> Message-Id: <20220215195258.29149-3-weijiang.yang@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
18c22d7112
commit
f06d8a18ab
2 changed files with 50 additions and 0 deletions
|
@ -6275,6 +6275,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
|
|||
CPUX86State *env = &cpu->env;
|
||||
Error *local_err = NULL;
|
||||
static bool ht_warned;
|
||||
unsigned requested_lbr_fmt;
|
||||
|
||||
if (cpu->apic_id == UNASSIGNED_APIC_ID) {
|
||||
error_setg(errp, "apic-id property was not initialized properly");
|
||||
|
@ -6292,6 +6293,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);
|
||||
unsigned 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%x) does not match "
|
||||
"the host value (0x%x).",
|
||||
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)) {
|
||||
|
@ -6644,6 +6681,8 @@ static void x86_cpu_initfn(Object *obj)
|
|||
object_property_add_alias(obj, "sse4_2", obj, "sse4.2");
|
||||
|
||||
object_property_add_alias(obj, "hv-apicv", obj, "hv-avic");
|
||||
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);
|
||||
|
@ -6798,6 +6837,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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue