Il 02/09/2013 17:06, Benoît Canet ha scritto:
Some users running cpu intensive tasks checking the cache CPUID leaves at
startup and making decisions based on the result reported that the guest was
not reflecting the host CPUID leaves when -cpu host is used.
This patch fix this.
Signed-off-by: Benoit Canet ben...@irqsave.net
---
target-i386/cpu-qom.h |3 +++
target-i386/cpu.c | 19 +++
2 files changed, 22 insertions(+)
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index c4447c2..b1d1bd8 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -70,6 +70,9 @@ typedef struct X86CPU {
bool hyperv_relaxed_timing;
int hyperv_spinlock_attempts;
+/* if true the CPUID code directly forward host cache leaves to the
guest */
+bool fwd_host_cache_info;
+
/* Features that were filtered out because of missing host capabilities
*/
uint32_t filtered_features[FEATURE_WORDS];
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index c36345e..f0df4db 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -486,6 +486,7 @@ typedef struct x86_def_t {
int stepping;
FeatureWordArray features;
char model_id[48];
+bool fwd_host_cache_info;
} x86_def_t;
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
@@ -1139,6 +1140,7 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
assert(kvm_enabled());
x86_cpu_def-name = host;
+x86_cpu_def-fwd_host_cache_info = true;
host_cpuid(0x0, 0, eax, ebx, ecx, edx);
x86_cpu_vendor_words2str(x86_cpu_def-vendor, ebx, edx, ecx);
@@ -1888,6 +1890,7 @@ static void cpu_x86_register(X86CPU *cpu, const char
*name, Error **errp)
env-features[FEAT_C000_0001_EDX] = def-features[FEAT_C000_0001_EDX];
env-features[FEAT_7_0_EBX] = def-features[FEAT_7_0_EBX];
env-cpuid_xlevel2 = def-xlevel2;
+cpu-fwd_host_cache_info = def-fwd_host_cache_info;
object_property_set_str(OBJECT(cpu), def-model_id, model-id, errp);
}
@@ -2062,6 +2065,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
uint32_t count,
break;
case 2:
/* cache info: needed for Pentium Pro compatibility */
+if (cpu-fwd_host_cache_info) {
+host_cpuid(index, 0, eax, ebx, ecx, edx);
+break;
+}
*eax = 1; /* Number of CPUID[EAX=2] calls required */
*ebx = 0;
*ecx = 0;
@@ -2071,6 +2078,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
uint32_t count,
break;
case 4:
/* cache info: needed for Core compatibility */
+if (cpu-fwd_host_cache_info) {
+host_cpuid(index, count, eax, ebx, ecx, edx);
+break;
+}
if (cs-nr_cores 1) {
*eax = (cs-nr_cores - 1) 26;
} else {
@@ -2228,6 +2239,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
uint32_t count,
break;
case 0x8005:
/* cache info (L1 cache) */
+if (cpu-fwd_host_cache_info) {
+host_cpuid(index, 0, eax, ebx, ecx, edx);
+break;
+}
*eax = (L1_DTLB_2M_ASSOC 24) | (L1_DTLB_2M_ENTRIES 16) | \
(L1_ITLB_2M_ASSOC 8) | (L1_ITLB_2M_ENTRIES);
*ebx = (L1_DTLB_4K_ASSOC 24) | (L1_DTLB_4K_ENTRIES 16) | \
@@ -2239,6 +2254,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
uint32_t count,
break;
case 0x8006:
/* cache info (L2 cache) */
+if (cpu-fwd_host_cache_info) {
+host_cpuid(index, 0, eax, ebx, ecx, edx);
+break;
+}
*eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) 28) | \
(L2_DTLB_2M_ENTRIES 16) | \
(AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) 12) | \
I renamed the new field to cache_info_passthrough (Eduardo had a
pmu_passthrough patch a few weeks ago) and will push it tomorrow to
uq/master. Thanks,
Paolo