[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/6] introduce -cpu host target
From: |
Andre Przywara |
Subject: |
[Qemu-devel] [PATCH 2/6] introduce -cpu host target |
Date: |
Thu, 25 Jun 2009 00:08:00 +0200 |
Although the guest's CPUID bits can be controlled in a fine grained way
in QEMU, a simple way to inject the host CPU is missing. This is handy
for KVM desktop virtualization, where one wants the guest to support the
full host feature set.
Introduce another CPU type called 'host', which will propagate the host's
CPUID bits to the guest. Unwanted bits can still be turned off by using
the existing syntax (-cpu host,-skinit)
Signed-off-by: Andre Przywara <address@hidden>
---
target-i386/helper.c | 65 +++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index cb9113e..d7563f7 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -273,9 +273,9 @@ static x86_def_t x86_defs[] = {
{
.name = "athlon",
.level = 2,
- .vendor1 = 0x68747541, /* "Auth" */
- .vendor2 = 0x69746e65, /* "enti" */
- .vendor3 = 0x444d4163, /* "cAMD" */
+ .vendor1 = CPUID_VENDOR_AMD_1,
+ .vendor2 = CPUID_VENDOR_AMD_2,
+ .vendor3 = CPUID_VENDOR_AMD_3,
.family = 6,
.model = 2,
.stepping = 3,
@@ -308,6 +308,54 @@ static x86_def_t x86_defs[] = {
},
};
+static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
+ uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
+
+static int cpu_x86_fill_model_id(char *str)
+{
+ uint32_t eax, ebx, ecx, edx;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
+ memcpy(str + i * 16 + 0, &eax, 4);
+ memcpy(str + i * 16 + 4, &ebx, 4);
+ memcpy(str + i * 16 + 8, &ecx, 4);
+ memcpy(str + i * 16 + 12, &edx, 4);
+ }
+ return 0;
+}
+
+static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
+{
+ uint32_t eax, ebx, ecx, edx;
+
+ x86_cpu_def->name = "host";
+ host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
+ x86_cpu_def->level = eax;
+ x86_cpu_def->vendor1 = ebx;
+ x86_cpu_def->vendor2 = edx;
+ x86_cpu_def->vendor3 = ecx;
+
+ host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
+ x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
+ x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
+ x86_cpu_def->stepping = eax & 0x0F;
+ x86_cpu_def->ext_features = ecx;
+ x86_cpu_def->features = edx;
+
+ host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
+ x86_cpu_def->xlevel = eax;
+
+ host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
+ x86_cpu_def->ext2_features = edx;
+ x86_cpu_def->ext3_features = ecx;
+ cpu_x86_fill_model_id(x86_cpu_def->model_id);
+ x86_cpu_def->vendor_override = 0;
+
+ return 0;
+}
+
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
{
unsigned int i;
@@ -326,9 +374,14 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def,
const char *cpu_model)
break;
}
}
- if (!def)
- goto error;
- memcpy(x86_cpu_def, def, sizeof(*def));
+ if (!def) {
+ if (strcmp(name, "host") != 0) {
+ goto error;
+ }
+ cpu_x86_fill_host(x86_cpu_def);
+ } else {
+ memcpy(x86_cpu_def, def, sizeof(*def));
+ }
add_flagname_to_bitmaps("hypervisor", &plus_features,
&plus_ext_features, &plus_ext2_features, &plus_ext3_features);
--
1.6.1.3
- [Qemu-devel] [PATCH 0/6] Add -cpu host CPU type, Andre Przywara, 2009/06/24
- [Qemu-devel] [PATCH 1/6] allow hypervisor CPUID bit to be overriden, Andre Przywara, 2009/06/24
- [Qemu-devel] [PATCH 5/6] remove CPUID host hacks, Andre Przywara, 2009/06/24
- [Qemu-devel] [PATCH 4/6] fix KVMs GET_SUPPORTED_CPUID feature usage, Andre Przywara, 2009/06/24
- [Qemu-devel] [PATCH 3/6] CPUID Fn8000_0001.EAX is family/model/stepping, not features, Andre Przywara, 2009/06/24
- [Qemu-devel] [PATCH 6/6] preserve the hypervisor bit while KVM trims the CPUID bits, Andre Przywara, 2009/06/24
- [Qemu-devel] [PATCH 2/6] introduce -cpu host target,
Andre Przywara <=