On Mon, Sep 28, 2020 at 10:51:03PM +0800, Xu, Like wrote:Thanks, I'll apply it and enable "-cpu,lbr-fmt=*" from command line.
Hi Eduardo,You can add a regular uint8_t field to X86CPU, use
Thanks for your detailed review.
On 2020/9/25 6:05, Eduardo Habkost wrote:
I've just noticed this on my review queue (apologies for the longI'll remove it.
delay). Comments below:
On Sun, Jul 26, 2020 at 11:32:20PM +0800, Like Xu wrote:
The LBR feature would be enabled on the guest if:Why is this line here?
- the KVM is enabled and the PMU is enabled and,
- the msr-based-feature IA32_PERF_CAPABILITIES is supporterd and,
- the supported returned value for lbr_fmt from this msr is not zero.
The LBR feature would be disabled on the guest if:
- the msr-based-feature IA32_PERF_CAPABILITIES is unsupporterd OR,
- qemu set the IA32_PERF_CAPABILITIES msr feature without lbr_fmt values OR,
- the requested guest vcpu model doesn't support PDCM.
Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Cc: Richard Henderson <rth@xxxxxxxxxxx>
Cc: Eduardo Habkost <ehabkost@xxxxxxxxxx>
Cc: "Michael S. Tsirkin" <mst@xxxxxxxxxx>
Cc: Marcel Apfelbaum <marcel.apfelbaum@xxxxxxxxx>
Cc: Marcelo Tosatti <mtosatti@xxxxxxxxxx>
Cc: qemu-devel@xxxxxxxxxx
Signed-off-by: Like Xu <like.xu@xxxxxxxxxxxxxxx>
---
hw/i386/pc.c | 1 +
target/i386/cpu.c | 24 ++++++++++++++++++++++--
target/i386/cpu.h | 2 ++
target/i386/kvm.c | 7 ++++++-
4 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3d419d5991..857aff75bb 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -318,6 +318,7 @@ GlobalProperty pc_compat_1_5[] = {
{ "Nehalem-" TYPE_X86_CPU, "min-level", "2" },
{ "virtio-net-pci", "any_layout", "off" },
{ TYPE_X86_CPU, "pmu", "on" },
+ { TYPE_X86_CPU, "lbr", "on" },
I'm not sure if you mean adding a "separate lbr-fmt int property"{ "i440FX-pcihost", "short_root_bus", "0" },What about a separate "lbr-fmt" int property instead of
{ "q35-pcihost", "short_root_bus", "0" },
};
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 588f32e136..c803994887 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1142,8 +1142,8 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
[FEAT_PERF_CAPABILITIES] = {
.type = MSR_FEATURE_WORD,
.feat_names = {
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
+ "lbr-fmt-bit-0", "lbr-fmt-bit-1", "lbr-fmt-bit-2", "lbr-fmt-bit-3",
+ "lbr-fmt-bit-4", "lbr-fmt-bit-5", NULL, NULL,
individual bit properties?
like "uint64_t tcg_features" to 'struct FeatureWordInfo'.
Would you mind providing more implementation hints,
considering the PEBS_FMT will be added later ?
DEFINE_PROP_UINT8 at x86_cpu_properties[], and just validate/copy
the bits to cpu->features[FEAT_PERF_CAPABILITIES][bits 0:5] on
x86_cpu_realizefn().
I assume you meanOK, this means the value set in cpu->features[] need to beWhat happens if LBR_FMT on the host (returned byTo enable guest LBR, guest LBR_FMT must be the same as host LBR_FMT.
kvm_arch_get_supported_msr_feature(MSR_IA32_PERF_CAPABILITIES) is
different than the one configured for the guest?
Can KVM emulateIt must match the host since the LBR registers are model specified.
a CPU with different LBR_FMT, or it must match the host?
validated against the host in x86_cpu_filter_features().
It can be similar to what's done for intel-pt bits, but instead
of comparing to constants (the intel-pt bits in CPUID are
constant today), you can compare the host value with
cpu->features[FEAT_PERF_CAPABILITIES].
Sure, let me see if there is extra value in adding separate
Maybe a FeatureWordInfo.validate_feature(X86CPU *, FeatureWord)
callback could be added, so we could just define separate
validation functions for each feature word, to be called
automatically by x86_cpu_filter_features(). This could be done
as a follow-up patch, though.
Thanks.
As long as the requirements are validated insideIf LBR_FMT must always match the host, the feature needs to blockIt's migrable enough of the perf cap LBR version matches,
live migration.
don't need full model number match.
x86_cpu_filter_features(), it should be OK to make it migratable.
Thanks for clarification.
For example it's fine to migrate from SKY to CLX.OK, in this case forget what I said about setting it on
I guess this is already the case because PDCM isI'm trying to make LBR migration-friendly as much as possible w/ your help.
cleared if !cpu->enable_pmu. Adding PDCM to .unmigratable_flags
is probably a good idea, though.
If Arch LBR is enabled for SPR guest, the situation will be different
hence adding PDCM to .unmigratable_flags may not help it.
.unmigratable_flags. The constraints for making the feature
migratable should be same ones mentioned for intel-pt at:
https://lore.kernel.org/qemu-devel/20200923141502.GO2044576@xxxxxxxxxxx/
Real hardware may always has PDCM and non-zero LBR_FMT.
Don't we want to support hosts that have PDCMThanks, I'll apply it.
NULL, NULL, NULL, NULL,You can rewrite this is an accelerator-independent way as:
NULL, "full-width-write", NULL, NULL,
NULL, NULL, NULL, NULL,
@@ -4224,6 +4224,12 @@ static bool lmce_supported(void)
return !!(mce_cap & MCG_LMCE_P);
}
+static inline bool lbr_supported(void)
+{
+ return kvm_enabled() && (kvm_arch_get_supported_msr_feature(kvm_state,
+ MSR_IA32_PERF_CAPABILITIES) & PERF_CAP_LBR_FMT);
+}
(x86_cpu_get_supported_feature_word(FEAT_PERF_CAPABILITIES) & PERF_CAP_LBR_FMT)
However, is this really supposed to return false if LBR_FMT is 000000?I think it's fine to return false if LBR_FMT is 000000.
(CPUID[1].ECX[bit 15]) = 1 and
IA32_PERF_CAPABILITIES.LBR_FMT[bits 5:0] = 000000 ?
For model-specified LBR, please refer to:
How are those registers enumerated? Maybe I'm looking at anThanks, I'll remove it.+Why is this necessary?
#define CPUID_MODEL_ID_SZ 48
/**
@@ -4327,6 +4333,9 @@ static void max_x86_cpu_initfn(Object *obj)
}
object_property_set_bool(OBJECT(cpu), "pmu", true, &error_abort);
+ if (lbr_supported()) {
+ object_property_set_bool(OBJECT(cpu), "lbr", true, &error_abort);
If kvm_arch_get_supported_msr_feature(MSR_IA32_PERF_CAPABILITIES)
return the PERF_CAP_LBR_FMT bits set,
x86_cpu_get_supported_feature_word() will return those bits, and
they will be automatically set at
env->features[FEAT_PERF_CAPABILITIES].
I'll remove it.+ }Why do we need to check for !cpu->max_features here?
}
static const TypeInfo max_x86_cpu_type_info = {
@@ -5535,6 +5544,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
if (!cpu->enable_pmu) {
*ecx &= ~CPUID_EXT_PDCM;
+ if (cpu->enable_lbr) {
+ warn_report("LBR is unsupported since guest PMU is disabled.");
+ exit(1);
+ }
}
break;
case 2:
@@ -6553,6 +6566,12 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
}
}
+ if (!cpu->max_features && cpu->enable_lbr &&
I'll apply it.+ !(env->features[FEAT_1_ECX] & CPUID_EXT_PDCM)) {Please report errors using error_setg(errp, ...) instead.
+ warn_report("requested vcpu model doesn't support PDCM for LBR.");
+ exit(1);
We set pmu=off explicitly, so does lbr=off.+ }When exactly do we want to set lbr=off explicitly? What's the
+
if (cpu->ucode_rev == 0) {
/* The default is the same as KVM's. */
if (IS_AMD_CPU(env)) {
@@ -7187,6 +7206,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_BOOL("lbr", X86CPU, enable_lbr, false),
expected outcome when lbr=off?
When set lbr=off, the LBR-related registers accesses from guest bring #GP
and expected outcome is just like pmu=off.
outdated version of the Intel SDM or I couldn't find the right
section.
I'll document it here.DEFINE_PROP_UINT32("hv-spinlocks", X86CPU, hyperv_spinlock_attempts,This is a good place to document what enable_lbr=true|false
HYPERV_SPINLOCK_NEVER_RETRY),
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e1a5c174dc..a059913e26 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -357,6 +357,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
@@ -1702,6 +1703,7 @@ struct X86CPU {
* capabilities) directly to the guest.
*/
bool enable_pmu;
+ bool enable_lbr;
means (see questions above).
I'll remove it./* LMCE support can be enabled/disabled via cpu option 'lmce=on/off'. It isWhy is this necessary? If enable_lbr is false,
* disabled by default to avoid breaking migration between QEMU with
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index b8455c89ed..feb33d5472 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -2690,8 +2690,10 @@ static void kvm_msr_entry_add_perf(X86CPU *cpu, FeatureWordArray f)
uint64_t kvm_perf_cap =
kvm_arch_get_supported_msr_feature(kvm_state,
MSR_IA32_PERF_CAPABILITIES);
-
if (kvm_perf_cap) {
+ if (!cpu->enable_lbr) {
+ kvm_perf_cap &= ~PERF_CAP_LBR_FMT;
+ }
f[FEAT_PERF_CAPABILITIES] should not have those bits set at all.
Thanks, I'll apply it in the x86_cpu_filter_features().kvm_msr_entry_add(cpu, MSR_IA32_PERF_CAPABILITIES,This is not the appropriate place to check for unsupported
kvm_perf_cap & f[FEAT_PERF_CAPABILITIES]);
}
@@ -2731,6 +2733,9 @@ static void kvm_init_msrs(X86CPU *cpu)
if (has_msr_perf_capabs && cpu->enable_pmu) {
kvm_msr_entry_add_perf(cpu, env->features);
+ } else if (!has_msr_perf_capabs && cpu->enable_lbr) {
+ warn_report("KVM doesn't support MSR_IA32_PERF_CAPABILITIES for LBR.");
+ exit(1);
features. x86_cpu_realizefn() and/or x86_cpu_filter_features()
is.
Please let me if you have more comments.
Thanks,
Like Xu
}
if (has_msr_ucode_rev) {
--
2.21.3