|
|
218e99 |
From 99ce2407227bd5474e69c93ab0f061f2a3438eac Mon Sep 17 00:00:00 2001
|
|
|
218e99 |
From: Eduardo Habkost <ehabkost@redhat.com>
|
|
|
218e99 |
Date: Fri, 2 Aug 2013 14:08:52 +0200
|
|
|
218e99 |
Subject: target-i386: Disable PMU CPUID leaf by default
|
|
|
218e99 |
|
|
|
218e99 |
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
|
|
|
218e99 |
Message-id: <1375452533-12507-3-git-send-email-ehabkost@redhat.com>
|
|
|
218e99 |
Patchwork-id: 52933
|
|
|
218e99 |
O-Subject: [RHEL-7 PATCH 2/3] target-i386: Disable PMU CPUID leaf by default
|
|
|
218e99 |
Bugzilla: 853101
|
|
|
218e99 |
RH-Acked-by: Bandan Das <bsd@redhat.com>
|
|
|
218e99 |
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
|
|
|
218e99 |
RH-Acked-by: Gleb Natapov <gleb@redhat.com>
|
|
|
218e99 |
|
|
|
218e99 |
Bugzilla: 853101
|
|
|
218e99 |
|
|
|
218e99 |
Bug description: QEMU currently gets all bits from GET_SUPPORTED_CPUID
|
|
|
218e99 |
for CPUID leaf 0xA and passes them directly to the guest. This makes
|
|
|
218e99 |
the guest ABI depend on host kernel and host CPU capabilities, and
|
|
|
218e99 |
breaks live migration if we migrate between hosts with different
|
|
|
218e99 |
capabilities (e.g., different number of PMU counters).
|
|
|
218e99 |
|
|
|
218e99 |
Add a "pmu" property to X86CPU, and set it to true only on "-cpu host",
|
|
|
218e99 |
or on pc-*-1.5 and older machine-types.
|
|
|
218e99 |
|
|
|
218e99 |
For now, setting pmu=on will enable the current passthrough mode that
|
|
|
218e99 |
doesn't have any ABI stability guarantees, but in the future we may
|
|
|
218e99 |
implement a mode where the PMU CPUID bits are stable and configurable.
|
|
|
218e99 |
|
|
|
218e99 |
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
|
|
218e99 |
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
218e99 |
Signed-off-by: Andreas Färber <afaerber@suse.de>
|
|
|
218e99 |
(cherry picked from commit 9337e3b6e1d779215423d9b419d42200506deaab)
|
|
|
218e99 |
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
|
|
218e99 |
|
|
|
218e99 |
Conflicts:
|
|
|
218e99 |
include/hw/i386/pc.h
|
|
|
218e99 |
target-i386/cpu.c
|
|
|
218e99 |
|
|
|
218e99 |
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
|
|
|
218e99 |
index 6692728..45487ba 100644
|
|
|
218e99 |
--- a/include/hw/i386/pc.h
|
|
|
218e99 |
+++ b/include/hw/i386/pc.h
|
|
|
218e99 |
@@ -211,6 +211,10 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
|
|
|
218e99 |
.driver = "Nehalem-" TYPE_X86_CPU,\
|
|
|
218e99 |
.property = "level",\
|
|
|
218e99 |
.value = stringify(2),\
|
|
|
218e99 |
+ },{\
|
|
|
218e99 |
+ .driver = TYPE_X86_CPU,\
|
|
|
218e99 |
+ .property = "pmu",\
|
|
|
218e99 |
+ .value = "on",\
|
|
|
218e99 |
}
|
|
|
218e99 |
|
|
|
218e99 |
#define PC_COMPAT_1_4 \
|
|
|
218e99 |
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
|
|
|
218e99 |
index 849cedf..5231005 100644
|
|
|
218e99 |
--- a/target-i386/cpu-qom.h
|
|
|
218e99 |
+++ b/target-i386/cpu-qom.h
|
|
|
218e99 |
@@ -68,6 +68,13 @@ typedef struct X86CPU {
|
|
|
218e99 |
|
|
|
218e99 |
/* Features that were filtered out because of missing host capabilities */
|
|
|
218e99 |
uint32_t filtered_features[FEATURE_WORDS];
|
|
|
218e99 |
+
|
|
|
218e99 |
+ /* Enable PMU CPUID bits. This can't be enabled by default yet because
|
|
|
218e99 |
+ * it doesn't have ABI stability guarantees, as it passes all PMU CPUID
|
|
|
218e99 |
+ * bits returned by GET_SUPPORTED_CPUID (that depend on host CPU and kernel
|
|
|
218e99 |
+ * capabilities) directly to the guest.
|
|
|
218e99 |
+ */
|
|
|
218e99 |
+ bool enable_pmu;
|
|
|
218e99 |
} X86CPU;
|
|
|
218e99 |
|
|
|
218e99 |
static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
|
|
|
218e99 |
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
|
|
|
218e99 |
index 0c9a99a..2bcc21e 100644
|
|
|
218e99 |
--- a/target-i386/cpu.c
|
|
|
218e99 |
+++ b/target-i386/cpu.c
|
|
|
218e99 |
@@ -1479,6 +1479,7 @@ static int cpu_x86_find_by_name(X86CPU *cpu, x86_def_t *x86_cpu_def,
|
|
|
218e99 |
const char *name)
|
|
|
218e99 |
{
|
|
|
218e99 |
x86_def_t *def;
|
|
|
218e99 |
+ Error *err = NULL;
|
|
|
218e99 |
int i;
|
|
|
218e99 |
|
|
|
218e99 |
if (name == NULL) {
|
|
|
218e99 |
@@ -1486,6 +1487,8 @@ static int cpu_x86_find_by_name(X86CPU *cpu, x86_def_t *x86_cpu_def,
|
|
|
218e99 |
}
|
|
|
218e99 |
if (kvm_enabled() && strcmp(name, "host") == 0) {
|
|
|
218e99 |
kvm_cpu_fill_host(x86_cpu_def);
|
|
|
218e99 |
+ object_property_set_bool(OBJECT(cpu), true, "pmu", &err;;
|
|
|
218e99 |
+ assert_no_error(err);
|
|
|
218e99 |
return 0;
|
|
|
218e99 |
}
|
|
|
218e99 |
|
|
|
218e99 |
@@ -2017,7 +2020,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|
|
218e99 |
break;
|
|
|
218e99 |
case 0xA:
|
|
|
218e99 |
/* Architectural Performance Monitoring Leaf */
|
|
|
218e99 |
- if (kvm_enabled()) {
|
|
|
218e99 |
+ if (kvm_enabled() && cpu->enable_pmu) {
|
|
|
218e99 |
KVMState *s = cs->kvm_state;
|
|
|
218e99 |
|
|
|
218e99 |
*eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
|
|
|
218e99 |
@@ -2506,6 +2509,11 @@ static int64_t x86_cpu_get_arch_id(CPUState *cs)
|
|
|
218e99 |
return env->cpuid_apic_id;
|
|
|
218e99 |
}
|
|
|
218e99 |
|
|
|
218e99 |
+static Property x86_cpu_properties[] = {
|
|
|
218e99 |
+ DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
|
|
|
218e99 |
+ DEFINE_PROP_END_OF_LIST()
|
|
|
218e99 |
+};
|
|
|
218e99 |
+
|
|
|
218e99 |
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
|
|
218e99 |
{
|
|
|
218e99 |
X86CPUClass *xcc = X86_CPU_CLASS(oc);
|
|
|
218e99 |
@@ -2515,6 +2523,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
|
|
218e99 |
xcc->parent_realize = dc->realize;
|
|
|
218e99 |
dc->realize = x86_cpu_realizefn;
|
|
|
218e99 |
dc->bus_type = TYPE_ICC_BUS;
|
|
|
218e99 |
+ dc->props = x86_cpu_properties;
|
|
|
218e99 |
|
|
|
218e99 |
xcc->parent_reset = cc->reset;
|
|
|
218e99 |
cc->reset = x86_cpu_reset;
|