diff options
| author | Michael S. Tsirkin <mst@redhat.com> | 2018-06-22 22:22:05 +0300 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-06-29 13:02:47 +0200 |
| commit | 2266d44311321a833d569cd4deb46cca6021d0e7 (patch) | |
| tree | 954cac47b13360c4ebafbc3f7cb2c4c2c31f9672 /target/i386/cpu.c | |
| parent | 6f131f13e68d648a8e4f083c667ab1acd88ce4cd (diff) | |
| download | focaccia-qemu-2266d44311321a833d569cd4deb46cca6021d0e7.tar.gz focaccia-qemu-2266d44311321a833d569cd4deb46cca6021d0e7.zip | |
i386/cpu: make -cpu host support monitor/mwait
When guest CPU PM is enabled, and with -cpu host, expose the host CPU MWAIT leaf in the CPUID so guest can make good PM decisions. Note: the result is 100% CPU utilization reported by host as host no longer knows that the CPU is halted. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Message-Id: <20180622192148.178309-3-mst@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target/i386/cpu.c')
| -rw-r--r-- | target/i386/cpu.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c index e6c2f8a22a..1e6a7d0a75 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -3959,11 +3959,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, } break; case 5: - /* mwait info: needed for Core compatibility */ - *eax = 0; /* Smallest monitor-line size in bytes */ - *ebx = 0; /* Largest monitor-line size in bytes */ - *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE; - *edx = 0; + /* MONITOR/MWAIT Leaf */ + *eax = cpu->mwait.eax; /* Smallest monitor-line size in bytes */ + *ebx = cpu->mwait.ebx; /* Largest monitor-line size in bytes */ + *ecx = cpu->mwait.ecx; /* flags */ + *edx = cpu->mwait.edx; /* mwait substates */ break; case 6: /* Thermal and Power Leaf */ @@ -4804,13 +4804,25 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) Error *local_err = NULL; static bool ht_warned; - if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) { - char *name = x86_cpu_class_get_model_name(xcc); - error_setg(&local_err, "CPU model '%s' requires KVM", name); - g_free(name); - goto out; + if (xcc->host_cpuid_required) { + if (!accel_uses_host_cpuid()) { + char *name = x86_cpu_class_get_model_name(xcc); + error_setg(&local_err, "CPU model '%s' requires KVM", name); + g_free(name); + goto out; + } + + if (enable_cpu_pm) { + host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx, + &cpu->mwait.ecx, &cpu->mwait.edx); + env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR; + } } + /* mwait extended info: needed for Core compatibility */ + /* We always wake on interrupt even if host does not have the capability */ + cpu->mwait.ecx |= CPUID_MWAIT_EMX | CPUID_MWAIT_IBE; + if (cpu->apic_id == UNASSIGNED_APIC_ID) { error_setg(errp, "apic-id property was not initialized properly"); return; |