target-i386: Re-Enable PMU for Android if supported by host

This is a re-implementation of the following CLs lost after rebasing to QEMU 2.7:

81245f6 target-i386: Enable PMU for Android if supported by host
1801057 Revert "Revert "target-i386: Enable PMU for Android if supported by host""

BUG:
https://code.google.com/p/android/issues/detail?id=223377

Change-Id: I419716d803abd6344af06a55d2d721e91cb35bb8
diff --git a/android-qemu2-glue/main.cpp b/android-qemu2-glue/main.cpp
index 96f8374..8dc27b5 100755
--- a/android-qemu2-glue/main.cpp
+++ b/android-qemu2-glue/main.cpp
@@ -712,6 +712,12 @@
     args[n++] = "-cpu";
     args[n++] = kTarget.qemuCpu;
 
+    // Set env var to "on" for Intel PMU if the feature is enabled.
+    // cpu.c will then read that.
+    if (android::featurecontrol::isEnabled(android::featurecontrol::IntelPerformanceMonitoringUnit)) {
+        setenv("ANDROID_EMU_FEATURE_IntelPerformanceMonitoringUnit", "on", 1);
+    }
+
 #if defined(TARGET_X86_64) || defined(TARGET_I386)
     char* accel_status = NULL;
     CpuAccelMode accel_mode = ACCEL_AUTO;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 14f2dbd..ea6aefa 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3293,6 +3293,31 @@
     g_strfreev(names);
 }
 
+static void android_emulator_set_pmu_feature(X86CPU *cpu)
+{
+    char* intel_pmu_enabled =
+        getenv("ANDROID_EMU_FEATURE_IntelPerformanceMonitoringUnit");
+    if (kvm_enabled() &&
+        intel_pmu_enabled &&
+        !strcmp("on", intel_pmu_enabled)) {
+
+        CPUX86State *env = &cpu->env;
+        KVMState *s = kvm_state;
+
+        /* Use the host/KVM CPUID level in order to enable additional features
+         * supported by the host CPU, such as PMU. Cf. host_x86_cpu_initfn().
+         */
+        env->cpuid_level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
+        env->cpuid_xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0,
+                                                         R_EAX);
+        env->cpuid_xlevel2 = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0,
+                                                          R_EAX);
+
+        /* Enable PMU (this has no effect if env->cpuid_level < 0xA) */
+        object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
+    }
+}
+
 static void x86_cpu_initfn(Object *obj)
 {
     CPUState *cs = CPU(obj);
@@ -3339,6 +3364,8 @@
     }
 
     x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
+
+    android_emulator_set_pmu_feature(cpu);
 }
 
 static int64_t x86_cpu_get_arch_id(CPUState *cs)