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