summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-12-14 16:54:46 +0200
committerAvi Kivity <avi@redhat.com>2009-12-14 16:54:46 +0200
commit4c15e26323b38f4b5688eb3cb5b3b27e792c1f0d (patch)
tree7cc9bb0c932c159bf60275e762bfaed231b50077 /target-i386
parentRevert "Temporarily avoid loading pxe option roms" (diff)
parentmsix: function mask support (diff)
downloadqemu-kvm-4c15e26323b38f4b5688eb3cb5b3b27e792c1f0d.tar.gz
qemu-kvm-4c15e26323b38f4b5688eb3cb5b3b27e792c1f0d.tar.bz2
qemu-kvm-4c15e26323b38f4b5688eb3cb5b3b27e792c1f0d.zip
Merge commit 'c99d32efe6970493c44fe410ee4a4aafc1a35428' into stable-0.12-merge
* commit 'c99d32efe6970493c44fe410ee4a4aafc1a35428': msix: function mask support msix: macro rename for function mask support cpuid: Fix multicore setup on Intel kvm: x86: Fix initial kvm_has_msr_star Update OpenBIOS images to r640 Update version to -rc1 Conflicts: hw/msix.c Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/helper.c46
-rw-r--r--target-i386/kvm.c4
2 files changed, 33 insertions, 17 deletions
diff --git a/target-i386/helper.c b/target-i386/helper.c
index fd32b2ee9..09ba5e9cf 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1645,6 +1645,24 @@ static void host_cpuid(uint32_t function, uint32_t count,
#endif
}
+static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ *ebx = env->cpuid_vendor1;
+ *edx = env->cpuid_vendor2;
+ *ecx = env->cpuid_vendor3;
+
+ /* sysenter isn't supported on compatibility mode on AMD, syscall
+ * isn't supported in compatibility mode on Intel.
+ * Normally we advertise the actual cpu vendor, but you can override
+ * this if you want to use KVM's sysenter/syscall emulation
+ * in compatibility mode and when doing cross vendor migration
+ */
+ if (kvm_enabled() && env->cpuid_vendor_override) {
+ host_cpuid(0, 0, NULL, ebx, ecx, edx);
+ }
+}
+
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
@@ -1661,16 +1679,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
switch(index) {
case 0:
*eax = env->cpuid_level;
- *ebx = env->cpuid_vendor1;
- *edx = env->cpuid_vendor2;
- *ecx = env->cpuid_vendor3;
-
- /* sysenter isn't supported on compatibility mode on AMD. and syscall
- * isn't supported in compatibility mode on Intel. so advertise the
- * actuall cpu, and say goodbye to migration between different vendors
- * is you use compatibility mode. */
- if (kvm_enabled() && !env->cpuid_vendor_override)
- host_cpuid(0, 0, NULL, ebx, ecx, edx);
+ get_cpuid_vendor(env, ebx, ecx, edx);
break;
case 1:
*eax = env->cpuid_version;
@@ -1766,11 +1775,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ecx = env->cpuid_ext3_features;
*edx = env->cpuid_ext2_features;
- if (env->nr_cores * env->nr_threads > 1 &&
- env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
- env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
- env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
- *ecx |= 1 << 1; /* CmpLegacy bit */
+ /* The Linux kernel checks for the CMPLegacy bit and
+ * discards multiple thread information if it is set.
+ * So dont set it here for Intel to make Linux guests happy.
+ */
+ if (env->nr_cores * env->nr_threads > 1) {
+ uint32_t tebx, tecx, tedx;
+ get_cpuid_vendor(env, &tebx, &tecx, &tedx);
+ if (tebx != CPUID_VENDOR_INTEL_1 ||
+ tedx != CPUID_VENDOR_INTEL_2 ||
+ tecx != CPUID_VENDOR_INTEL_3) {
+ *ecx |= 1 << 1; /* CmpLegacy bit */
+ }
}
if (kvm_enabled()) {
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 568e2117b..6926cc959 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -245,9 +245,9 @@ static int kvm_has_msr_star(CPUState *env)
* save/restore */
msr_list.nmsrs = 0;
ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
- if (ret < 0)
+ if (ret < 0 && ret != -E2BIG) {
return 0;
-
+ }
/* Old kernel modules had a bug and could write beyond the provided
memory. Allocate at least a safe amount of 1K. */
kvm_msr_list = qemu_mallocz(MAX(1024, sizeof(msr_list) +