* Re: [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
@ 2012-09-05 16:48 ` Marcelo Tosatti
2012-09-11 13:57 ` Don Slutz
2012-09-06 10:28 ` Andreas Färber
` (49 subsequent siblings)
50 siblings, 1 reply; 65+ messages in thread
From: Marcelo Tosatti @ 2012-09-05 16:48 UTC (permalink / raw)
To: Don Slutz; +Cc: Don Slutz, qemu-devel, kvm, Avi Kivity
On Thu, Aug 30, 2012 at 03:20:35PM -0400, Don Slutz wrote:
> This is primarily done so that the guest will think it is running
> under vmware when hypervisor=vmware is specified as a property of a
> cpu.
>
> Also allow this to work in accel=tcg mode.
>
> The new cpu properties hyper_level, hyper_extra, hyper_extra_a, and
> hyper_extra_b can be used to further adjust what the guest sees.
>
> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
For what purpose?
Is the VMWare interface documented somewhere?
> ---
> target-i386/cpu.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> target-i386/cpu.h | 9 +++
> target-i386/kvm.c | 33 ++++++++--
> 3 files changed, 214 insertions(+), 6 deletions(-)
>
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index f3cac49..a444b95 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -26,6 +26,7 @@
>
> #include "qemu-option.h"
> #include "qemu-config.h"
> +#include "qemu-timer.h"
>
> #include "qapi/qapi-visit-core.h"
> #include "arch_init.h"
> @@ -244,6 +245,15 @@ typedef struct x86_def_t {
> uint32_t xlevel2;
> /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
> uint32_t cpuid_7_0_ebx_features;
> + /* Hypervisor CPUIDs */
> + uint32_t cpuid_hv_level;
> + uint32_t cpuid_hv_vendor1;
> + uint32_t cpuid_hv_vendor2;
> + uint32_t cpuid_hv_vendor3;
> + /* VMware extra data */
> + uint32_t cpuid_hv_extra;
> + uint32_t cpuid_hv_extra_a;
> + uint32_t cpuid_hv_extra_b;
> } x86_def_t;
>
> #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
> @@ -860,6 +870,18 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
> cpu->env.tsc_khz = value / 1000;
> }
>
> +static void x86_cpuid_set_hv(x86_def_t *x86_cpu_def, uint32_t level,
> + const char *who)
> +{
> + uint32_t signature[3];
> +
> + memcpy(signature, who, 12);
> + x86_cpu_def->cpuid_hv_level = level;
> + x86_cpu_def->cpuid_hv_vendor1 = signature[0];
> + x86_cpu_def->cpuid_hv_vendor2 = signature[1];
> + x86_cpu_def->cpuid_hv_vendor3 = signature[2];
> +}
> +
> static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> {
> unsigned int i;
> @@ -867,6 +889,10 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>
> char *s = g_strdup(cpu_model);
> char *featurestr, *name = strtok(s, ",");
> + bool hyperv_enabled = false;
> + bool hv_enabled = false;
> + long hyper_level = -1;
> + long hyper_extra = -1;
> /* Features to be added*/
> uint32_t plus_features = 0, plus_ext_features = 0;
> uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
> @@ -993,12 +1019,84 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> x86_cpu_def->tsc_khz = tsc_freq / 1000;
> } else if (!strcmp(featurestr, "hv_spinlocks")) {
> char *err;
> +
> + if (hv_enabled) {
> + fprintf(stderr,
> + "Only one of hypervisor= or hv_* can be used at one time.\n");
> + goto error;
> + }
> numvalue = strtoul(val, &err, 0);
> if (!*val || *err) {
> fprintf(stderr, "bad numerical value %s\n", val);
> goto error;
> }
> + hyperv_enabled = true;
> hyperv_set_spinlock_retries(numvalue);
> + } else if (!strcmp(featurestr, "hyper_level")) {
> + char *err;
> + long longvalue = strtol(val, &err, 0);
> +
> + if (!*val || *err) {
> + fprintf(stderr, "bad numerical value for hyper_level=%s\n",
> + val);
> + goto error;
> + }
> + hyper_level = longvalue;
> + } else if (!strcmp(featurestr, "hyper_extra")) {
> + char *err;
> + long longvalue = strtol(val, &err, 0);
> +
> + if (!*val || *err) {
> + fprintf(stderr, "bad numerical value for hyper_extra=%s\n",
> + val);
> + goto error;
> + }
> + hyper_extra = longvalue;
> + } else if (!strcmp(featurestr, "hyper_extra_a")) {
> + char *err;
> +
> + numvalue = strtoul(val, &err, 0);
> + if (!*val || *err) {
> + fprintf(stderr,
> + "bad numerical value for hyper_extra_a=%s\n",
> + val);
> + goto error;
> + }
> + x86_cpu_def->cpuid_hv_extra_a = (uint32_t)numvalue;
> + } else if (!strcmp(featurestr, "hyper_extra_b")) {
> + char *err;
> +
> + numvalue = strtoul(val, &err, 0);
> + if (!*val || *err) {
> + fprintf(stderr,
> + "bad numerical value for hyper_extra_b=%s\n",
> + val);
> + goto error;
> + }
> + x86_cpu_def->cpuid_hv_extra_b = (uint32_t)numvalue;
> + } else if (!strcmp(featurestr, "hv") ||
> + !strcmp(featurestr, "hypervisor")) {
> + if (hyperv_enabled) {
> + fprintf(stderr,
> + "Only one of hypervisor= or hv_* can be used at one time.\n");
> + goto error;
> + }
> + hv_enabled = true;
> + if (!strcmp(val, "vmware")) {
> + x86_cpuid_set_hv(x86_cpu_def, 0x40000010, "VMwareVMware");
> + minus_kvm_features = ~0; /* Expected to be zero... */
> + } else if (!strcmp(val, "vmware3")) {
> + x86_cpuid_set_hv(x86_cpu_def, 0x40000002, "VMwareVMware");
> + minus_kvm_features = ~0; /* Expected to be zero... */
> + } else if (!strcmp(val, "xen")) {
> + x86_cpuid_set_hv(x86_cpu_def, 0x40000002, "XenVMMXenVMM");
> + } else if (!strcmp(val, "kvm")) {
> + x86_cpuid_set_hv(x86_cpu_def, 0, "KVMKVMKVM\0\0\0");
> + } else {
> + fprintf(stderr, "unknown hypervisor %s\n",
> + val);
> + goto error;
> + }
> } else {
> fprintf(stderr, "unrecognized feature %s\n", featurestr);
> goto error;
> @@ -1008,8 +1106,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> } else if (!strcmp(featurestr, "enforce")) {
> check_cpuid = enforce_cpuid = 1;
> } else if (!strcmp(featurestr, "hv_relaxed")) {
> + if (hv_enabled) {
> + fprintf(stderr,
> + "Only one of hypervisor= or hv_* can be used at one time.\n");
> + goto error;
> + }
> + hyperv_enabled = true;
> hyperv_enable_relaxed_timing(true);
> } else if (!strcmp(featurestr, "hv_vapic")) {
> + if (hv_enabled) {
> + fprintf(stderr,
> + "Only one of hypervisor= or hv_* can be used at one time.\n");
> + goto error;
> + }
> + hyperv_enabled = true;
> hyperv_enable_vapic_recommended(true);
> } else {
> fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
> @@ -1017,6 +1127,34 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> }
> featurestr = strtok(NULL, ",");
> }
> +#ifdef CONFIG_KVM
> + if (hyperv_enabled) {
> + x86_cpuid_set_hv(x86_cpu_def, HYPERV_CPUID_MIN, "Microsoft Hv");
> + }
> +#endif
> + if (hyper_extra >= 0) {
> + x86_cpu_def->cpuid_hv_extra = 0x40000000 + hyper_extra;
> + } else if (hv_enabled && x86_cpu_def->tsc_khz) {
> + /*
> + * From http://article.gmane.org/gmane.comp.emulators.kvm.devel/22643
> + *
> + * Leaf 0x40000010, Timing Information.
> + *
> + * VMware has defined the first generic leaf to provide timing
> + * information. This leaf returns the current TSC frequency and
> + * current Bus frequency in kHz.
> + *
> + * # EAX: (Virtual) TSC frequency in kHz.
> + * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
> + * # ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
> + */
> + x86_cpu_def->cpuid_hv_extra = 0x40000010;
> + x86_cpu_def->cpuid_hv_extra_a = (uint32_t)x86_cpu_def->tsc_khz;
> + x86_cpu_def->cpuid_hv_extra_b = (uint32_t)(get_ticks_per_sec() / 1000);
> + }
> + if (hyper_level >= 0) {
> + x86_cpu_def->cpuid_hv_level = 0x40000000 + hyper_level;
> + }
> x86_cpu_def->features |= plus_features;
> x86_cpu_def->ext_features |= plus_ext_features;
> x86_cpu_def->ext2_features |= plus_ext2_features;
> @@ -1192,6 +1330,13 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
> env->cpuid_ext4_features = def->ext4_features;
> env->cpuid_7_0_ebx = def->cpuid_7_0_ebx_features;
> env->cpuid_xlevel2 = def->xlevel2;
> + env->cpuid_hv_level = def->cpuid_hv_level;
> + env->cpuid_hv_vendor1 = def->cpuid_hv_vendor1;
> + env->cpuid_hv_vendor2 = def->cpuid_hv_vendor2;
> + env->cpuid_hv_vendor3 = def->cpuid_hv_vendor3;
> + env->cpuid_hv_extra = def->cpuid_hv_extra;
> + env->cpuid_hv_extra_a = def->cpuid_hv_extra_a;
> + env->cpuid_hv_extra_b = def->cpuid_hv_extra_b;
> object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
> "tsc-frequency", &error);
> if (!kvm_enabled()) {
> @@ -1390,6 +1535,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
> index = env->cpuid_xlevel;
> }
> }
> + } else if (index & 0x40000000) {
> + if (env->cpuid_hv_level > 0) {
> + /* Handle Paravirtualization CPUIDs */
> + if (index > env->cpuid_hv_level) {
> + index = env->cpuid_hv_level;
> + }
> + } else {
> + if (index > env->cpuid_level)
> + index = env->cpuid_level;
> + }
> } else {
> if (index > env->cpuid_level)
> index = env->cpuid_level;
> @@ -1528,6 +1683,29 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
> *edx = 0;
> }
> break;
> + case 0x40000000:
> + *eax = env->cpuid_hv_level;
> + *ebx = env->cpuid_hv_vendor1;
> + *ecx = env->cpuid_hv_vendor2;
> + *edx = env->cpuid_hv_vendor3;
> + break;
> + case 0x40000001:
> + *eax = env->cpuid_kvm_features;
> + *ebx = 0;
> + *ecx = 0;
> + *edx = 0;
> + break;
> + case 0x40000002 ... 0x400000FF:
> + if (index == env->cpuid_hv_extra) {
> + *eax = env->cpuid_hv_extra_a;
> + *ebx = env->cpuid_hv_extra_b;
> + } else {
> + *eax = 0;
> + *ebx = 0;
> + }
> + *ecx = 0;
> + *edx = 0;
> + break;
> case 0x80000000:
> *eax = env->cpuid_xlevel;
> *ebx = env->cpuid_vendor1;
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 0677502..dc2039a 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -746,6 +746,15 @@ typedef struct CPUX86State {
> uint32_t cpuid_ext4_features;
> /* Flags from CPUID[EAX=7,ECX=0].EBX */
> uint32_t cpuid_7_0_ebx;
> + /* Paravirtualization CPUIDs */
> + uint32_t cpuid_hv_level;
> + uint32_t cpuid_hv_vendor1;
> + uint32_t cpuid_hv_vendor2;
> + uint32_t cpuid_hv_vendor3;
> + /* VMware extra data */
> + uint32_t cpuid_hv_extra;
> + uint32_t cpuid_hv_extra_a;
> + uint32_t cpuid_hv_extra_b;
>
> /* MTRRs */
> uint64_t mtrr_fixed[11];
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index ffc294e..d01a5f8 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -389,16 +389,18 @@ int kvm_arch_init_vcpu(CPUX86State *env)
> c = &cpuid_data.entries[cpuid_i++];
> memset(c, 0, sizeof(*c));
> c->function = KVM_CPUID_SIGNATURE;
> - if (!hyperv_enabled()) {
> + if (env->cpuid_hv_level == 0) {
> memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> c->eax = 0;
> + c->ebx = signature[0];
> + c->ecx = signature[1];
> + c->edx = signature[2];
> } else {
> - memcpy(signature, "Microsoft Hv", 12);
> - c->eax = HYPERV_CPUID_MIN;
> + c->eax = env->cpuid_hv_level;
> + c->ebx = env->cpuid_hv_vendor1;
> + c->ecx = env->cpuid_hv_vendor2;
> + c->edx = env->cpuid_hv_vendor3;
> }
> - c->ebx = signature[0];
> - c->ecx = signature[1];
> - c->edx = signature[2];
>
> c = &cpuid_data.entries[cpuid_i++];
> memset(c, 0, sizeof(*c));
> @@ -452,6 +454,25 @@ int kvm_arch_init_vcpu(CPUX86State *env)
> c->ebx = signature[0];
> c->ecx = signature[1];
> c->edx = signature[2];
> + } else if (env->cpuid_hv_level > 0) {
> + for (i = KVM_CPUID_FEATURES + 1; i <= env->cpuid_hv_level; i++) {
> + c = &cpuid_data.entries[cpuid_i++];
> + memset(c, 0, sizeof(*c));
> + c->function = i;
> + if (i == env->cpuid_hv_extra) {
> + c->eax = env->cpuid_hv_extra_a;
> + c->ebx = env->cpuid_hv_extra_b;
> + }
> + }
> +
> + c = &cpuid_data.entries[cpuid_i++];
> + memset(c, 0, sizeof(*c));
> + c->function = KVM_CPUID_SIGNATURE_NEXT;
> + memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> + c->eax = 0;
> + c->ebx = signature[0];
> + c->ecx = signature[1];
> + c->edx = signature[2];
> }
>
> has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs.
2012-09-05 16:48 ` Marcelo Tosatti
@ 2012-09-11 13:57 ` Don Slutz
0 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-11 13:57 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: Avi Kivity, Don Slutz, kvm, qemu-devel
On 09/05/12 12:48, Marcelo Tosatti wrote:
> On Thu, Aug 30, 2012 at 03:20:35PM -0400, Don Slutz wrote:
>> This is primarily done so that the guest will think it is running
>> under vmware when hypervisor=vmware is specified as a property of a
>> cpu.
>>
>> Also allow this to work in accel=tcg mode.
>>
>> The new cpu properties hyper_level, hyper_extra, hyper_extra_a, and
>> hyper_extra_b can be used to further adjust what the guest sees.
>>
>> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> For what purpose?
To be able to run bits copied from a ESX(i) server with limited changes
to the bits.
>
> Is the VMWare interface documented somewhere?
Not that I know of. All of this change is taken from the Linux source
(2.6.18-194.32.1.el5 or later) that checks for running on a VMware
hypervisor.
>
>> ---
>> target-i386/cpu.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> target-i386/cpu.h | 9 +++
>> target-i386/kvm.c | 33 ++++++++--
>> 3 files changed, 214 insertions(+), 6 deletions(-)
>>
>> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
>> index f3cac49..a444b95 100644
>> --- a/target-i386/cpu.c
>> +++ b/target-i386/cpu.c
>> @@ -26,6 +26,7 @@
>>
>> #include "qemu-option.h"
>> #include "qemu-config.h"
>> +#include "qemu-timer.h"
>>
>> #include "qapi/qapi-visit-core.h"
>> #include "arch_init.h"
>> @@ -244,6 +245,15 @@ typedef struct x86_def_t {
>> uint32_t xlevel2;
>> /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
>> uint32_t cpuid_7_0_ebx_features;
>> + /* Hypervisor CPUIDs */
>> + uint32_t cpuid_hv_level;
>> + uint32_t cpuid_hv_vendor1;
>> + uint32_t cpuid_hv_vendor2;
>> + uint32_t cpuid_hv_vendor3;
>> + /* VMware extra data */
>> + uint32_t cpuid_hv_extra;
>> + uint32_t cpuid_hv_extra_a;
>> + uint32_t cpuid_hv_extra_b;
>> } x86_def_t;
>>
>> #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
>> @@ -860,6 +870,18 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
>> cpu->env.tsc_khz = value / 1000;
>> }
>>
>> +static void x86_cpuid_set_hv(x86_def_t *x86_cpu_def, uint32_t level,
>> + const char *who)
>> +{
>> + uint32_t signature[3];
>> +
>> + memcpy(signature, who, 12);
>> + x86_cpu_def->cpuid_hv_level = level;
>> + x86_cpu_def->cpuid_hv_vendor1 = signature[0];
>> + x86_cpu_def->cpuid_hv_vendor2 = signature[1];
>> + x86_cpu_def->cpuid_hv_vendor3 = signature[2];
>> +}
>> +
>> static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>> {
>> unsigned int i;
>> @@ -867,6 +889,10 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>>
>> char *s = g_strdup(cpu_model);
>> char *featurestr, *name = strtok(s, ",");
>> + bool hyperv_enabled = false;
>> + bool hv_enabled = false;
>> + long hyper_level = -1;
>> + long hyper_extra = -1;
>> /* Features to be added*/
>> uint32_t plus_features = 0, plus_ext_features = 0;
>> uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
>> @@ -993,12 +1019,84 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>> x86_cpu_def->tsc_khz = tsc_freq / 1000;
>> } else if (!strcmp(featurestr, "hv_spinlocks")) {
>> char *err;
>> +
>> + if (hv_enabled) {
>> + fprintf(stderr,
>> + "Only one of hypervisor= or hv_* can be used at one time.\n");
>> + goto error;
>> + }
>> numvalue = strtoul(val, &err, 0);
>> if (!*val || *err) {
>> fprintf(stderr, "bad numerical value %s\n", val);
>> goto error;
>> }
>> + hyperv_enabled = true;
>> hyperv_set_spinlock_retries(numvalue);
>> + } else if (!strcmp(featurestr, "hyper_level")) {
>> + char *err;
>> + long longvalue = strtol(val, &err, 0);
>> +
>> + if (!*val || *err) {
>> + fprintf(stderr, "bad numerical value for hyper_level=%s\n",
>> + val);
>> + goto error;
>> + }
>> + hyper_level = longvalue;
>> + } else if (!strcmp(featurestr, "hyper_extra")) {
>> + char *err;
>> + long longvalue = strtol(val, &err, 0);
>> +
>> + if (!*val || *err) {
>> + fprintf(stderr, "bad numerical value for hyper_extra=%s\n",
>> + val);
>> + goto error;
>> + }
>> + hyper_extra = longvalue;
>> + } else if (!strcmp(featurestr, "hyper_extra_a")) {
>> + char *err;
>> +
>> + numvalue = strtoul(val, &err, 0);
>> + if (!*val || *err) {
>> + fprintf(stderr,
>> + "bad numerical value for hyper_extra_a=%s\n",
>> + val);
>> + goto error;
>> + }
>> + x86_cpu_def->cpuid_hv_extra_a = (uint32_t)numvalue;
>> + } else if (!strcmp(featurestr, "hyper_extra_b")) {
>> + char *err;
>> +
>> + numvalue = strtoul(val, &err, 0);
>> + if (!*val || *err) {
>> + fprintf(stderr,
>> + "bad numerical value for hyper_extra_b=%s\n",
>> + val);
>> + goto error;
>> + }
>> + x86_cpu_def->cpuid_hv_extra_b = (uint32_t)numvalue;
>> + } else if (!strcmp(featurestr, "hv") ||
>> + !strcmp(featurestr, "hypervisor")) {
>> + if (hyperv_enabled) {
>> + fprintf(stderr,
>> + "Only one of hypervisor= or hv_* can be used at one time.\n");
>> + goto error;
>> + }
>> + hv_enabled = true;
>> + if (!strcmp(val, "vmware")) {
>> + x86_cpuid_set_hv(x86_cpu_def, 0x40000010, "VMwareVMware");
>> + minus_kvm_features = ~0; /* Expected to be zero... */
>> + } else if (!strcmp(val, "vmware3")) {
>> + x86_cpuid_set_hv(x86_cpu_def, 0x40000002, "VMwareVMware");
>> + minus_kvm_features = ~0; /* Expected to be zero... */
>> + } else if (!strcmp(val, "xen")) {
>> + x86_cpuid_set_hv(x86_cpu_def, 0x40000002, "XenVMMXenVMM");
>> + } else if (!strcmp(val, "kvm")) {
>> + x86_cpuid_set_hv(x86_cpu_def, 0, "KVMKVMKVM\0\0\0");
>> + } else {
>> + fprintf(stderr, "unknown hypervisor %s\n",
>> + val);
>> + goto error;
>> + }
>> } else {
>> fprintf(stderr, "unrecognized feature %s\n", featurestr);
>> goto error;
>> @@ -1008,8 +1106,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>> } else if (!strcmp(featurestr, "enforce")) {
>> check_cpuid = enforce_cpuid = 1;
>> } else if (!strcmp(featurestr, "hv_relaxed")) {
>> + if (hv_enabled) {
>> + fprintf(stderr,
>> + "Only one of hypervisor= or hv_* can be used at one time.\n");
>> + goto error;
>> + }
>> + hyperv_enabled = true;
>> hyperv_enable_relaxed_timing(true);
>> } else if (!strcmp(featurestr, "hv_vapic")) {
>> + if (hv_enabled) {
>> + fprintf(stderr,
>> + "Only one of hypervisor= or hv_* can be used at one time.\n");
>> + goto error;
>> + }
>> + hyperv_enabled = true;
>> hyperv_enable_vapic_recommended(true);
>> } else {
>> fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
>> @@ -1017,6 +1127,34 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>> }
>> featurestr = strtok(NULL, ",");
>> }
>> +#ifdef CONFIG_KVM
>> + if (hyperv_enabled) {
>> + x86_cpuid_set_hv(x86_cpu_def, HYPERV_CPUID_MIN, "Microsoft Hv");
>> + }
>> +#endif
>> + if (hyper_extra >= 0) {
>> + x86_cpu_def->cpuid_hv_extra = 0x40000000 + hyper_extra;
>> + } else if (hv_enabled && x86_cpu_def->tsc_khz) {
>> + /*
>> + * From http://article.gmane.org/gmane.comp.emulators.kvm.devel/22643
>> + *
>> + * Leaf 0x40000010, Timing Information.
>> + *
>> + * VMware has defined the first generic leaf to provide timing
>> + * information. This leaf returns the current TSC frequency and
>> + * current Bus frequency in kHz.
>> + *
>> + * # EAX: (Virtual) TSC frequency in kHz.
>> + * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
>> + * # ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
>> + */
>> + x86_cpu_def->cpuid_hv_extra = 0x40000010;
>> + x86_cpu_def->cpuid_hv_extra_a = (uint32_t)x86_cpu_def->tsc_khz;
>> + x86_cpu_def->cpuid_hv_extra_b = (uint32_t)(get_ticks_per_sec() / 1000);
>> + }
>> + if (hyper_level >= 0) {
>> + x86_cpu_def->cpuid_hv_level = 0x40000000 + hyper_level;
>> + }
>> x86_cpu_def->features |= plus_features;
>> x86_cpu_def->ext_features |= plus_ext_features;
>> x86_cpu_def->ext2_features |= plus_ext2_features;
>> @@ -1192,6 +1330,13 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
>> env->cpuid_ext4_features = def->ext4_features;
>> env->cpuid_7_0_ebx = def->cpuid_7_0_ebx_features;
>> env->cpuid_xlevel2 = def->xlevel2;
>> + env->cpuid_hv_level = def->cpuid_hv_level;
>> + env->cpuid_hv_vendor1 = def->cpuid_hv_vendor1;
>> + env->cpuid_hv_vendor2 = def->cpuid_hv_vendor2;
>> + env->cpuid_hv_vendor3 = def->cpuid_hv_vendor3;
>> + env->cpuid_hv_extra = def->cpuid_hv_extra;
>> + env->cpuid_hv_extra_a = def->cpuid_hv_extra_a;
>> + env->cpuid_hv_extra_b = def->cpuid_hv_extra_b;
>> object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
>> "tsc-frequency", &error);
>> if (!kvm_enabled()) {
>> @@ -1390,6 +1535,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
>> index = env->cpuid_xlevel;
>> }
>> }
>> + } else if (index & 0x40000000) {
>> + if (env->cpuid_hv_level > 0) {
>> + /* Handle Paravirtualization CPUIDs */
>> + if (index > env->cpuid_hv_level) {
>> + index = env->cpuid_hv_level;
>> + }
>> + } else {
>> + if (index > env->cpuid_level)
>> + index = env->cpuid_level;
>> + }
>> } else {
>> if (index > env->cpuid_level)
>> index = env->cpuid_level;
>> @@ -1528,6 +1683,29 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
>> *edx = 0;
>> }
>> break;
>> + case 0x40000000:
>> + *eax = env->cpuid_hv_level;
>> + *ebx = env->cpuid_hv_vendor1;
>> + *ecx = env->cpuid_hv_vendor2;
>> + *edx = env->cpuid_hv_vendor3;
>> + break;
>> + case 0x40000001:
>> + *eax = env->cpuid_kvm_features;
>> + *ebx = 0;
>> + *ecx = 0;
>> + *edx = 0;
>> + break;
>> + case 0x40000002 ... 0x400000FF:
>> + if (index == env->cpuid_hv_extra) {
>> + *eax = env->cpuid_hv_extra_a;
>> + *ebx = env->cpuid_hv_extra_b;
>> + } else {
>> + *eax = 0;
>> + *ebx = 0;
>> + }
>> + *ecx = 0;
>> + *edx = 0;
>> + break;
>> case 0x80000000:
>> *eax = env->cpuid_xlevel;
>> *ebx = env->cpuid_vendor1;
>> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
>> index 0677502..dc2039a 100644
>> --- a/target-i386/cpu.h
>> +++ b/target-i386/cpu.h
>> @@ -746,6 +746,15 @@ typedef struct CPUX86State {
>> uint32_t cpuid_ext4_features;
>> /* Flags from CPUID[EAX=7,ECX=0].EBX */
>> uint32_t cpuid_7_0_ebx;
>> + /* Paravirtualization CPUIDs */
>> + uint32_t cpuid_hv_level;
>> + uint32_t cpuid_hv_vendor1;
>> + uint32_t cpuid_hv_vendor2;
>> + uint32_t cpuid_hv_vendor3;
>> + /* VMware extra data */
>> + uint32_t cpuid_hv_extra;
>> + uint32_t cpuid_hv_extra_a;
>> + uint32_t cpuid_hv_extra_b;
>>
>> /* MTRRs */
>> uint64_t mtrr_fixed[11];
>> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
>> index ffc294e..d01a5f8 100644
>> --- a/target-i386/kvm.c
>> +++ b/target-i386/kvm.c
>> @@ -389,16 +389,18 @@ int kvm_arch_init_vcpu(CPUX86State *env)
>> c = &cpuid_data.entries[cpuid_i++];
>> memset(c, 0, sizeof(*c));
>> c->function = KVM_CPUID_SIGNATURE;
>> - if (!hyperv_enabled()) {
>> + if (env->cpuid_hv_level == 0) {
>> memcpy(signature, "KVMKVMKVM\0\0\0", 12);
>> c->eax = 0;
>> + c->ebx = signature[0];
>> + c->ecx = signature[1];
>> + c->edx = signature[2];
>> } else {
>> - memcpy(signature, "Microsoft Hv", 12);
>> - c->eax = HYPERV_CPUID_MIN;
>> + c->eax = env->cpuid_hv_level;
>> + c->ebx = env->cpuid_hv_vendor1;
>> + c->ecx = env->cpuid_hv_vendor2;
>> + c->edx = env->cpuid_hv_vendor3;
>> }
>> - c->ebx = signature[0];
>> - c->ecx = signature[1];
>> - c->edx = signature[2];
>>
>> c = &cpuid_data.entries[cpuid_i++];
>> memset(c, 0, sizeof(*c));
>> @@ -452,6 +454,25 @@ int kvm_arch_init_vcpu(CPUX86State *env)
>> c->ebx = signature[0];
>> c->ecx = signature[1];
>> c->edx = signature[2];
>> + } else if (env->cpuid_hv_level > 0) {
>> + for (i = KVM_CPUID_FEATURES + 1; i <= env->cpuid_hv_level; i++) {
>> + c = &cpuid_data.entries[cpuid_i++];
>> + memset(c, 0, sizeof(*c));
>> + c->function = i;
>> + if (i == env->cpuid_hv_extra) {
>> + c->eax = env->cpuid_hv_extra_a;
>> + c->ebx = env->cpuid_hv_extra_b;
>> + }
>> + }
>> +
>> + c = &cpuid_data.entries[cpuid_i++];
>> + memset(c, 0, sizeof(*c));
>> + c->function = KVM_CPUID_SIGNATURE_NEXT;
>> + memcpy(signature, "KVMKVMKVM\0\0\0", 12);
>> + c->eax = 0;
>> + c->ebx = signature[0];
>> + c->ecx = signature[1];
>> + c->edx = signature[2];
>> }
>>
>> has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
>> --
>> 1.7.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe kvm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
v2 is on it way now that QEMU 1.3 is open.
-Don
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
2012-09-05 16:48 ` Marcelo Tosatti
@ 2012-09-06 10:28 ` Andreas Färber
2012-09-06 18:40 ` Eduardo Habkost
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 0/4] " Don Slutz
` (48 subsequent siblings)
50 siblings, 1 reply; 65+ messages in thread
From: Andreas Färber @ 2012-09-06 10:28 UTC (permalink / raw)
To: Don Slutz
Cc: Eduardo Habkost, kvm, Don Slutz, Marcelo Tosatti, qemu-devel,
Avi Kivity, Igor Mammedov
Am 30.08.2012 21:20, schrieb Don Slutz:
> This is primarily done so that the guest will think it is running
> under vmware when hypervisor=vmware is specified as a property of a
> cpu.
>
> Also allow this to work in accel=tcg mode.
>
> The new cpu properties hyper_level, hyper_extra, hyper_extra_a, and
> hyper_extra_b can be used to further adjust what the guest sees.
>
> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> ---
> target-i386/cpu.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> target-i386/cpu.h | 9 +++
> target-i386/kvm.c | 33 ++++++++--
> 3 files changed, 214 insertions(+), 6 deletions(-)
Please don't add new CPU command line options without matching QOM
properties. There are patch series in the works that convert the CPU
definitions to QOM subclasses, the parameters then need to be set on the
X86CPU object instance.
Note that the convention for QOM properties is
descriptive-name-with-dashes rather than shortened_abbrev_with_underscore.
Regards,
Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs.
2012-09-06 10:28 ` Andreas Färber
@ 2012-09-06 18:40 ` Eduardo Habkost
2012-09-06 19:00 ` Don Slutz
0 siblings, 1 reply; 65+ messages in thread
From: Eduardo Habkost @ 2012-09-06 18:40 UTC (permalink / raw)
To: Andreas Färber
Cc: kvm, Don Slutz, Marcelo Tosatti, Don Slutz, qemu-devel,
Avi Kivity, Igor Mammedov
On Thu, Sep 06, 2012 at 12:28:05PM +0200, Andreas Färber wrote:
> Am 30.08.2012 21:20, schrieb Don Slutz:
> > This is primarily done so that the guest will think it is running
> > under vmware when hypervisor=vmware is specified as a property of a
> > cpu.
> >
> > Also allow this to work in accel=tcg mode.
> >
> > The new cpu properties hyper_level, hyper_extra, hyper_extra_a, and
> > hyper_extra_b can be used to further adjust what the guest sees.
> >
> > Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> > ---
> > target-i386/cpu.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > target-i386/cpu.h | 9 +++
> > target-i386/kvm.c | 33 ++++++++--
> > 3 files changed, 214 insertions(+), 6 deletions(-)
>
> Please don't add new CPU command line options without matching QOM
> properties. There are patch series in the works that convert the CPU
> definitions to QOM subclasses, the parameters then need to be set on the
> X86CPU object instance.
It seems to be a good idea to wait for the CPU properties series from
Igor to be applied, before implementing this. It should make the new
code much simpler.
>
> Note that the convention for QOM properties is
> descriptive-name-with-dashes rather than shortened_abbrev_with_underscore.
>
--
Eduardo
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs.
2012-09-06 18:40 ` Eduardo Habkost
@ 2012-09-06 19:00 ` Don Slutz
2012-09-06 19:36 ` Eduardo Habkost
0 siblings, 1 reply; 65+ messages in thread
From: Don Slutz @ 2012-09-06 19:00 UTC (permalink / raw)
To: Eduardo Habkost
Cc: kvm, Marcelo Tosatti, qemu-devel, Don Slutz, Avi Kivity,
Igor Mammedov, Andreas Färber
On 09/06/12 14:40, Eduardo Habkost wrote:
> On Thu, Sep 06, 2012 at 12:28:05PM +0200, Andreas Färber wrote:
>> Am 30.08.2012 21:20, schrieb Don Slutz:
>>> This is primarily done so that the guest will think it is running
>>> under vmware when hypervisor=vmware is specified as a property of a
>>> cpu.
>>>
>>> Also allow this to work in accel=tcg mode.
>>>
>>> The new cpu properties hyper_level, hyper_extra, hyper_extra_a, and
>>> hyper_extra_b can be used to further adjust what the guest sees.
>>>
>>> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
>>> ---
>>> target-i386/cpu.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> target-i386/cpu.h | 9 +++
>>> target-i386/kvm.c | 33 ++++++++--
>>> 3 files changed, 214 insertions(+), 6 deletions(-)
>> Please don't add new CPU command line options without matching QOM
>> properties. There are patch series in the works that convert the CPU
>> definitions to QOM subclasses, the parameters then need to be set on the
>> X86CPU object instance.
I found:
http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg00587.html
Is this the right set?
> It seems to be a good idea to wait for the CPU properties series from
> Igor to be applied, before implementing this. It should make the new
> code much simpler.
So Igor has a patch set that does a similar change like above. I so far
have not found it on QEMU-DEVEL. Please provide a pointer to this patch
set.
>
>> Note that the convention for QOM properties is
>> descriptive-name-with-dashes rather than shortened_abbrev_with_underscore.
>>
I will be re-working this change, and wait (for v2) until master has
changed to the new way.
-Don
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs.
2012-09-06 19:00 ` Don Slutz
@ 2012-09-06 19:36 ` Eduardo Habkost
0 siblings, 0 replies; 65+ messages in thread
From: Eduardo Habkost @ 2012-09-06 19:36 UTC (permalink / raw)
To: Don Slutz
Cc: kvm, Marcelo Tosatti, qemu-devel, Don Slutz, Avi Kivity,
Igor Mammedov, Andreas Färber
On Thu, Sep 06, 2012 at 03:00:47PM -0400, Don Slutz wrote:
> On 09/06/12 14:40, Eduardo Habkost wrote:
> >On Thu, Sep 06, 2012 at 12:28:05PM +0200, Andreas Färber wrote:
> >>Am 30.08.2012 21:20, schrieb Don Slutz:
> >>>This is primarily done so that the guest will think it is running
> >>>under vmware when hypervisor=vmware is specified as a property of a
> >>>cpu.
> >>>
> >>>Also allow this to work in accel=tcg mode.
> >>>
> >>>The new cpu properties hyper_level, hyper_extra, hyper_extra_a, and
> >>>hyper_extra_b can be used to further adjust what the guest sees.
> >>>
> >>>Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> >>>---
> >>> target-i386/cpu.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>> target-i386/cpu.h | 9 +++
> >>> target-i386/kvm.c | 33 ++++++++--
> >>> 3 files changed, 214 insertions(+), 6 deletions(-)
> >>Please don't add new CPU command line options without matching QOM
> >>properties. There are patch series in the works that convert the CPU
> >>definitions to QOM subclasses, the parameters then need to be set on the
> >>X86CPU object instance.
> I found:
> http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg00587.html
>
> Is this the right set?
Yes. But note that there are lots of work in progress in the list (and
work that we haven't submitted to the list yet). You don't necessarily
need to wait for the above to be applied, probably you can just rebase
on top of the "CPU properties" work (that affects your patch more
directly). See below.
> >It seems to be a good idea to wait for the CPU properties series from
> >Igor to be applied, before implementing this. It should make the new
> >code much simpler.
> So Igor has a patch set that does a similar change like above. I so
> far have not found it on QEMU-DEVEL. Please provide a pointer to
> this patch set.
I was talking specifically about the "CPU properties" series, at:
http://article.gmane.org/gmane.comp.emulators.qemu/165728
The "CPU model classes" series (URL you sent above) is an additional
series to be applied on top of the "CPU properties" series. But the "CPU
model classes" work probably don't impact your patch, so you can simply
be ready to rebase/resend your patch after Igor sends a new version of
the CPU properties series.
Note that the URLs above are old versions of the work in progress. You
may find newer versions at my github tree[1] or at Igor's tree[2].
Basically once we introduce CPU properties, you'll just need to define
the new properties on X86CPU, without the need to change the CPU model
string parsing code. It should make your patch simpler.
[1] An experimental rebase of Igor's CPU properties series (Igor's
latest version may look different):
https://github.com/ehabkost/qemu-hacks/tree/work/cpu-properties-igor-rebase-v4.3-2012-08-31
CPU model classes:
(may look different when I submit to qemu-devel again):
https://github.com/ehabkost/qemu-hacks/tree/work/cpu-model-classes-v2.8-2012-08-31
Lots of work in progress, including multiple branches/series:
(may look very different when I submit to qemu-devel):
https://github.com/ehabkost/qemu-hacks/tree/work/cpuid-refactor-v0.22-2012-08-31
[2] Igor's work in progress branch:
https://github.com/imammedo/qemu/tree/x86-cpu-properties.WIP
> >
> >>Note that the convention for QOM properties is
> >>descriptive-name-with-dashes rather than shortened_abbrev_with_underscore.
> >>
> I will be re-working this change, and wait (for v2) until master has
> changed to the new way.
> -Don
--
Eduardo
^ permalink raw reply [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v2 0/4] Allow changing of Hypervisor CPUIDs.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
2012-09-05 16:48 ` Marcelo Tosatti
2012-09-06 10:28 ` Andreas Färber
@ 2012-09-11 14:07 ` Don Slutz
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 1/4] target-i386: Allow tsc-frequency to be larger then 2.147G Don Slutz
` (47 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-11 14:07 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo
Cc: peter.maydell, kvm, Don Slutz, avi, anthony, afaerber
This depends on:
http://lists.gnu.org/archive/html/qemu-devel/2012-09/msg01400.html
As far as I know it is #4. It depends on (1) and (2) and (3).
Changes from v1 to v2:
1) Added 1/4 from http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg05153.html
Because Fred is changing jobs and so will not be pushing to get
this in. It needed to be rebased, And I needed it to complete the
testing of this change.
2) Added 2/4 because of the re-work I needed a way to clear all KVM bits,
3) The rework of v1. Make it fit into the object model re-work of cpu.c for x86.
4) Added 3/4 -- The split out of the code that is not needed for accel=kvm.
Don Slutz (4):
target-i386: Allow tsc-frequency to be larger then 2.147G
target-i386: Add missing kvm bits.
target-i386: Allow changing of Hypervisor CPUIDs.
target-i386: Add Hypervisor CPUIDs in accel=tcg mode.
target-i386/cpu.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
target-i386/cpu.h | 21 +++++
target-i386/kvm.c | 33 ++++++--
3 files changed, 304 insertions(+), 11 deletions(-)
^ permalink raw reply [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v2 1/4] target-i386: Allow tsc-frequency to be larger then 2.147G
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (2 preceding siblings ...)
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 0/4] " Don Slutz
@ 2012-09-11 14:07 ` Don Slutz
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 2/4] target-i386: Add missing kvm bits Don Slutz
` (46 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-11 14:07 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo
Cc: peter.maydell, kvm, Don Slutz, avi, anthony, Fred Oliveira,
afaerber
The check using INT_MAX (2147483647) is wrong in this case.
Signed-off-by: Fred Oliveira <foliveira@cloudswitch.com>
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index af50a8f..0313cf5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1146,7 +1146,7 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
{
X86CPU *cpu = X86_CPU(obj);
const int64_t min = 0;
- const int64_t max = INT_MAX;
+ const int64_t max = INT64_MAX;
int64_t value;
visit_type_freq(v, &value, name, errp);
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v2 2/4] target-i386: Add missing kvm bits.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (3 preceding siblings ...)
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 1/4] target-i386: Allow tsc-frequency to be larger then 2.147G Don Slutz
@ 2012-09-11 14:07 ` Don Slutz
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 3/4] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (45 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-11 14:07 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo
Cc: peter.maydell, kvm, Don Slutz, avi, anthony, afaerber
Fix duplicate name (kvmclock => kvm_clock2) also.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 0313cf5..5f9866a 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -87,10 +87,14 @@ static const char *ext3_feature_name[] = {
};
static const char *kvm_feature_name[] = {
- "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, "kvm_pv_eoi", NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvm_clock2",
+ "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ "kvm_clock_stable", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
};
static const char *svm_feature_name[] = {
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v2 3/4] target-i386: Allow changing of Hypervisor CPUIDs.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (4 preceding siblings ...)
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 2/4] target-i386: Add missing kvm bits Don Slutz
@ 2012-09-11 14:07 ` Don Slutz
2012-09-12 17:55 ` Marcelo Tosatti
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 4/4] target-i386: Add Hypervisor CPUIDs in accel=tcg mode Don Slutz
` (44 subsequent siblings)
50 siblings, 1 reply; 65+ messages in thread
From: Don Slutz @ 2012-09-11 14:07 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo
Cc: peter.maydell, kvm, Don Slutz, avi, anthony, afaerber
This is primarily done so that the guest will think it is running
under vmware when hypervisor-vendor=vmware is specified as a
property of a cpu.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++
target-i386/cpu.h | 21 +++++
target-i386/kvm.c | 33 +++++++--
3 files changed, 262 insertions(+), 6 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5f9866a..9f1f390 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1135,6 +1135,36 @@ static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
}
}
+static void x86_cpuid_set_vmware_extra(Object *obj)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ if ((cpu->env.tsc_khz != 0) &&
+ (cpu->env.cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) &&
+ (cpu->env.cpuid_hv_vendor1 == CPUID_HV_VENDOR_VMWARE_1) &&
+ (cpu->env.cpuid_hv_vendor2 == CPUID_HV_VENDOR_VMWARE_2) &&
+ (cpu->env.cpuid_hv_vendor3 == CPUID_HV_VENDOR_VMWARE_3)) {
+ const uint32_t apic_khz = 1000000L;
+
+ /*
+ * From article.gmane.org/gmane.comp.emulators.kvm.devel/22643
+ *
+ * Leaf 0x40000010, Timing Information.
+ *
+ * VMware has defined the first generic leaf to provide timing
+ * information. This leaf returns the current TSC frequency and
+ * current Bus frequency in kHz.
+ *
+ * # EAX: (Virtual) TSC frequency in kHz.
+ * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
+ * # ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
+ */
+ cpu->env.cpuid_hv_extra = 0x40000010;
+ cpu->env.cpuid_hv_extra_a = (uint32_t)cpu->env.tsc_khz;
+ cpu->env.cpuid_hv_extra_b = apic_khz;
+ }
+}
+
static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
@@ -1164,9 +1194,175 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
}
cpu->env.tsc_khz = value / 1000;
+ x86_cpuid_set_vmware_extra(obj);
+}
+
+static void x86_cpuid_get_hv_level(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_level, name, errp);
+}
+
+static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+
+ if ((value != 0) && (value < 0x40000000)) {
+ value += 0x40000000;
+ }
+ cpu->env.cpuid_hv_level = value;
+}
+
+static char *x86_cpuid_get_hv_vendor(Object *obj, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ char *value;
+ int i;
+
+ value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
+ for (i = 0; i < 4; i++) {
+ value[i + 0] = env->cpuid_hv_vendor1 >> (8 * i);
+ value[i + 4] = env->cpuid_hv_vendor2 >> (8 * i);
+ value[i + 8] = env->cpuid_hv_vendor3 >> (8 * i);
+ }
+ value[CPUID_VENDOR_SZ] = '\0';
+
+ /* Convert known names */
+ if (!strcmp(value, CPUID_HV_VENDOR_VMWARE)) {
+ if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) {
+ pstrcpy(value, sizeof(value), "vmware4");
+ } else if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_3) {
+ pstrcpy(value, sizeof(value), "vmware3");
+ }
+ } else if (!strcmp(value, CPUID_HV_VENDOR_XEN) &&
+ env->cpuid_hv_level == CPUID_HV_LEVEL_XEN) {
+ pstrcpy(value, sizeof(value), "xen");
+ } else if (!strcmp(value, CPUID_HV_VENDOR_KVM) &&
+ env->cpuid_hv_level == 0) {
+ pstrcpy(value, sizeof(value), "kvm");
+ }
+ return value;
+}
+
+static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
+ Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ int i;
+ char adj_value[CPUID_VENDOR_SZ + 1];
+
+ memset(adj_value, 0, sizeof(adj_value));
+
+ /* Convert known names */
+ if (!strcmp(value, "vmware") || !strcmp(value, "vmware4")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_4;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
+ } else if (!strcmp(value, "vmware3")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_3;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
+ } else if (!strcmp(value, "xen")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_XEN;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_XEN);
+ } else if (!strcmp(value, "kvm")) {
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_KVM);
+ } else {
+ pstrcpy(adj_value, sizeof(adj_value), value);
+ }
+
+ env->cpuid_hv_vendor1 = 0;
+ env->cpuid_hv_vendor2 = 0;
+ env->cpuid_hv_vendor3 = 0;
+ for (i = 0; i < 4; i++) {
+ env->cpuid_hv_vendor1 |= ((uint8_t)adj_value[i + 0]) << (8 * i);
+ env->cpuid_hv_vendor2 |= ((uint8_t)adj_value[i + 4]) << (8 * i);
+ env->cpuid_hv_vendor3 |= ((uint8_t)adj_value[i + 8]) << (8 * i);
+ }
+ x86_cpuid_set_vmware_extra(obj);
+}
+
+static void x86_cpuid_get_hv_extra(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+
+ if ((value != 0) && (value < 0x40000000)) {
+ value += 0x40000000;
+ }
+ cpu->env.cpuid_hv_extra = value;
+}
+
+static void x86_cpuid_get_hv_extra_a(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra_a(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
+}
+
+static void x86_cpuid_get_hv_extra_b(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra_b(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
}
#if !defined(CONFIG_USER_ONLY)
+static void x86_set_hyperv(Object *obj, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
+ x86_cpuid_set_hv_vendor(obj, "Microsoft Hv", errp);
+}
+
static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
@@ -1189,6 +1385,7 @@ static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_set_spinlock_retries(value);
+ x86_set_hyperv(obj, errp);
}
static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
@@ -1209,6 +1406,7 @@ static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_enable_relaxed_timing(value);
+ x86_set_hyperv(obj, errp);
}
static void x86_get_hv_vapic(Object *obj, Visitor *v, void *opaque,
@@ -1229,6 +1427,7 @@ static void x86_set_hv_vapic(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_enable_vapic_recommended(value);
+ x86_set_hyperv(obj, errp);
}
#endif
@@ -2061,6 +2260,21 @@ static void x86_cpu_initfn(Object *obj)
object_property_add(obj, "enforce", "bool",
x86_cpuid_get_enforce,
x86_cpuid_set_enforce, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-level", "int",
+ x86_cpuid_get_hv_level,
+ x86_cpuid_set_hv_level, NULL, NULL, NULL);
+ object_property_add_str(obj, "hypervisor-vendor",
+ x86_cpuid_get_hv_vendor,
+ x86_cpuid_set_hv_vendor, NULL);
+ object_property_add(obj, "hypervisor-extra", "int",
+ x86_cpuid_get_hv_extra,
+ x86_cpuid_set_hv_extra, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-extra-a", "int",
+ x86_cpuid_get_hv_extra_a,
+ x86_cpuid_set_hv_extra_a, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-extra-b", "int",
+ x86_cpuid_get_hv_extra_b,
+ x86_cpuid_set_hv_extra_b, NULL, NULL, NULL);
#if !defined(CONFIG_USER_ONLY)
object_property_add(obj, "hv_spinlocks", "int",
x86_get_hv_spinlocks,
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5265c5a..a2d3588 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -488,6 +488,18 @@
#define CPUID_VENDOR_VIA "CentaurHauls"
+#define CPUID_HV_VENDOR_VMWARE_1 0x61774d56 /* "VMwa" */
+#define CPUID_HV_VENDOR_VMWARE_2 0x4d566572 /* "reVM" */
+#define CPUID_HV_VENDOR_VMWARE_3 0x65726177 /* "ware" */
+#define CPUID_HV_VENDOR_VMWARE "VMwareVMware"
+#define CPUID_HV_LEVEL_VMARE_3 0x40000002
+#define CPUID_HV_LEVEL_VMARE_4 0x40000010
+
+#define CPUID_HV_VENDOR_XEN "XenVMMXenVMM"
+#define CPUID_HV_LEVEL_XEN 0x40000002
+
+#define CPUID_HV_VENDOR_KVM "KVMKVMKVM"
+
#define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
#define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
@@ -782,6 +794,15 @@ typedef struct CPUX86State {
uint32_t cpuid_ext4_features;
/* Flags from CPUID[EAX=7,ECX=0].EBX */
uint32_t cpuid_7_0_ebx;
+ /* Hypervisor CPUIDs */
+ uint32_t cpuid_hv_level;
+ uint32_t cpuid_hv_vendor1;
+ uint32_t cpuid_hv_vendor2;
+ uint32_t cpuid_hv_vendor3;
+ /* VMware extra data */
+ uint32_t cpuid_hv_extra;
+ uint32_t cpuid_hv_extra_a;
+ uint32_t cpuid_hv_extra_b;
/* MTRRs */
uint64_t mtrr_fixed[11];
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 895d848..17c72bc 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -389,16 +389,18 @@ int kvm_arch_init_vcpu(CPUX86State *env)
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
c->function = KVM_CPUID_SIGNATURE;
- if (!hyperv_enabled()) {
+ if (env->cpuid_hv_level == 0) {
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
} else {
- memcpy(signature, "Microsoft Hv", 12);
- c->eax = HYPERV_CPUID_MIN;
+ c->eax = env->cpuid_hv_level;
+ c->ebx = env->cpuid_hv_vendor1;
+ c->ecx = env->cpuid_hv_vendor2;
+ c->edx = env->cpuid_hv_vendor3;
}
- c->ebx = signature[0];
- c->ecx = signature[1];
- c->edx = signature[2];
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
@@ -452,6 +454,25 @@ int kvm_arch_init_vcpu(CPUX86State *env)
c->ebx = signature[0];
c->ecx = signature[1];
c->edx = signature[2];
+ } else if (env->cpuid_hv_level > 0) {
+ for (i = KVM_CPUID_FEATURES + 1; i <= env->cpuid_hv_level; i++) {
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = i;
+ if (i == env->cpuid_hv_extra) {
+ c->eax = env->cpuid_hv_extra_a;
+ c->ebx = env->cpuid_hv_extra_b;
+ }
+ }
+
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_SIGNATURE_NEXT;
+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
+ c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
}
has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v2 3/4] target-i386: Allow changing of Hypervisor CPUIDs.
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 3/4] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
@ 2012-09-12 17:55 ` Marcelo Tosatti
2012-09-13 18:43 ` Don Slutz
0 siblings, 1 reply; 65+ messages in thread
From: Marcelo Tosatti @ 2012-09-12 17:55 UTC (permalink / raw)
To: Don Slutz
Cc: peter.maydell, ehabkost, kvm, qemu-devel, avi, anthony, imammedo,
afaerber
The problem with integrating this is that it has little or
no assurance from documentation. The Linux kernel source is a good
source, then say "accordingly to VMWare guest support code in version xyz"
in the changelog.
Also extracting this information in a text file (or comment in the code)
would be better than just adding code.
On Tue, Sep 11, 2012 at 10:07:46AM -0400, Don Slutz wrote:
> This is primarily done so that the guest will think it is running
> under vmware when hypervisor-vendor=vmware is specified as a
> property of a cpu.
>
> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> ---
> target-i386/cpu.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> target-i386/cpu.h | 21 +++++
> target-i386/kvm.c | 33 +++++++--
> 3 files changed, 262 insertions(+), 6 deletions(-)
>
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 5f9866a..9f1f390 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -1135,6 +1135,36 @@ static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
> }
> }
>
> +static void x86_cpuid_set_vmware_extra(Object *obj)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> +
> + if ((cpu->env.tsc_khz != 0) &&
> + (cpu->env.cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) &&
> + (cpu->env.cpuid_hv_vendor1 == CPUID_HV_VENDOR_VMWARE_1) &&
> + (cpu->env.cpuid_hv_vendor2 == CPUID_HV_VENDOR_VMWARE_2) &&
> + (cpu->env.cpuid_hv_vendor3 == CPUID_HV_VENDOR_VMWARE_3)) {
> + const uint32_t apic_khz = 1000000L;
> +
> + /*
> + * From article.gmane.org/gmane.comp.emulators.kvm.devel/22643
> + *
> + * Leaf 0x40000010, Timing Information.
> + *
> + * VMware has defined the first generic leaf to provide timing
> + * information. This leaf returns the current TSC frequency and
> + * current Bus frequency in kHz.
> + *
> + * # EAX: (Virtual) TSC frequency in kHz.
> + * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
> + * # ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
> + */
> + cpu->env.cpuid_hv_extra = 0x40000010;
> + cpu->env.cpuid_hv_extra_a = (uint32_t)cpu->env.tsc_khz;
> + cpu->env.cpuid_hv_extra_b = apic_khz;
> + }
> +}
What happens in case you migrate the vmware guest to a host
with different frequency? How is that transmitted to the
vmware-guest-running-on-kvm ? Or is migration not supported?
> +static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> + uint32_t value;
> +
> + visit_type_uint32(v, &value, name, errp);
> + if (error_is_set(errp)) {
> + return;
> + }
> +
> + if ((value != 0) && (value < 0x40000000)) {
> + value += 0x40000000;
> + }
> + cpu->env.cpuid_hv_level = value;
> +}
> +
> +static char *x86_cpuid_get_hv_vendor(Object *obj, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> + CPUX86State *env = &cpu->env;
> + char *value;
> + int i;
> +
> + value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
> + for (i = 0; i < 4; i++) {
> + value[i + 0] = env->cpuid_hv_vendor1 >> (8 * i);
> + value[i + 4] = env->cpuid_hv_vendor2 >> (8 * i);
> + value[i + 8] = env->cpuid_hv_vendor3 >> (8 * i);
> + }
> + value[CPUID_VENDOR_SZ] = '\0';
> +
> + /* Convert known names */
> + if (!strcmp(value, CPUID_HV_VENDOR_VMWARE)) {
> + if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) {
> + pstrcpy(value, sizeof(value), "vmware4");
> + } else if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_3) {
> + pstrcpy(value, sizeof(value), "vmware3");
> + }
> + } else if (!strcmp(value, CPUID_HV_VENDOR_XEN) &&
> + env->cpuid_hv_level == CPUID_HV_LEVEL_XEN) {
> + pstrcpy(value, sizeof(value), "xen");
> + } else if (!strcmp(value, CPUID_HV_VENDOR_KVM) &&
> + env->cpuid_hv_level == 0) {
> + pstrcpy(value, sizeof(value), "kvm");
> + }
> + return value;
> +}
> +
> +static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
> + Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> + CPUX86State *env = &cpu->env;
> + int i;
> + char adj_value[CPUID_VENDOR_SZ + 1];
> +
> + memset(adj_value, 0, sizeof(adj_value));
> +
> + /* Convert known names */
> + if (!strcmp(value, "vmware") || !strcmp(value, "vmware4")) {
> + if (env->cpuid_hv_level == 0) {
> + env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_4;
> + }
> + pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
> + } else if (!strcmp(value, "vmware3")) {
> + if (env->cpuid_hv_level == 0) {
> + env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_3;
> + }
> + pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
> + } else if (!strcmp(value, "xen")) {
> + if (env->cpuid_hv_level == 0) {
> + env->cpuid_hv_level = CPUID_HV_LEVEL_XEN;
> + }
> + pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_XEN);
> + } else if (!strcmp(value, "kvm")) {
> + pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_KVM);
> + } else {
> + pstrcpy(adj_value, sizeof(adj_value), value);
> + }
> +
> + env->cpuid_hv_vendor1 = 0;
> + env->cpuid_hv_vendor2 = 0;
> + env->cpuid_hv_vendor3 = 0;
> + for (i = 0; i < 4; i++) {
> + env->cpuid_hv_vendor1 |= ((uint8_t)adj_value[i + 0]) << (8 * i);
> + env->cpuid_hv_vendor2 |= ((uint8_t)adj_value[i + 4]) << (8 * i);
> + env->cpuid_hv_vendor3 |= ((uint8_t)adj_value[i + 8]) << (8 * i);
> + }
> + x86_cpuid_set_vmware_extra(obj);
> +}
> +
> +static void x86_cpuid_get_hv_extra(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> +
> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra, name, errp);
> +}
> +
> +static void x86_cpuid_set_hv_extra(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> + uint32_t value;
> +
> + visit_type_uint32(v, &value, name, errp);
> + if (error_is_set(errp)) {
> + return;
> + }
> +
> + if ((value != 0) && (value < 0x40000000)) {
> + value += 0x40000000;
> + }
> + cpu->env.cpuid_hv_extra = value;
> +}
> +
> +static void x86_cpuid_get_hv_extra_a(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> +
> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
> +}
> +
> +static void x86_cpuid_set_hv_extra_a(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> +
> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
> +}
> +
> +static void x86_cpuid_get_hv_extra_b(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> +
> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
> +}
> +
> +static void x86_cpuid_set_hv_extra_b(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> +
> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
> }
>
> #if !defined(CONFIG_USER_ONLY)
> +static void x86_set_hyperv(Object *obj, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> +
> + cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
> + x86_cpuid_set_hv_vendor(obj, "Microsoft Hv", errp);
> +}
> +
> static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
> const char *name, Error **errp)
> {
> @@ -1189,6 +1385,7 @@ static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
> return;
> }
> hyperv_set_spinlock_retries(value);
> + x86_set_hyperv(obj, errp);
> }
>
> static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
> @@ -1209,6 +1406,7 @@ static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
> return;
> }
> hyperv_enable_relaxed_timing(value);
> + x86_set_hyperv(obj, errp);
> }
This seems unrelated to the rest of the patch?
> static void x86_get_hv_vapic(Object *obj, Visitor *v, void *opaque,
> @@ -1229,6 +1427,7 @@ static void x86_set_hv_vapic(Object *obj, Visitor *v, void *opaque,
> return;
> }
> hyperv_enable_vapic_recommended(value);
> + x86_set_hyperv(obj, errp);
> }
> #endif
>
> @@ -2061,6 +2260,21 @@ static void x86_cpu_initfn(Object *obj)
> object_property_add(obj, "enforce", "bool",
> x86_cpuid_get_enforce,
> x86_cpuid_set_enforce, NULL, NULL, NULL);
> + object_property_add(obj, "hypervisor-level", "int",
> + x86_cpuid_get_hv_level,
> + x86_cpuid_set_hv_level, NULL, NULL, NULL);
> + object_property_add_str(obj, "hypervisor-vendor",
> + x86_cpuid_get_hv_vendor,
> + x86_cpuid_set_hv_vendor, NULL);
> + object_property_add(obj, "hypervisor-extra", "int",
> + x86_cpuid_get_hv_extra,
> + x86_cpuid_set_hv_extra, NULL, NULL, NULL);
> + object_property_add(obj, "hypervisor-extra-a", "int",
> + x86_cpuid_get_hv_extra_a,
> + x86_cpuid_set_hv_extra_a, NULL, NULL, NULL);
> + object_property_add(obj, "hypervisor-extra-b", "int",
> + x86_cpuid_get_hv_extra_b,
> + x86_cpuid_set_hv_extra_b, NULL, NULL, NULL);
> #if !defined(CONFIG_USER_ONLY)
> object_property_add(obj, "hv_spinlocks", "int",
> x86_get_hv_spinlocks,
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 5265c5a..a2d3588 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -488,6 +488,18 @@
>
> #define CPUID_VENDOR_VIA "CentaurHauls"
>
> +#define CPUID_HV_VENDOR_VMWARE_1 0x61774d56 /* "VMwa" */
> +#define CPUID_HV_VENDOR_VMWARE_2 0x4d566572 /* "reVM" */
> +#define CPUID_HV_VENDOR_VMWARE_3 0x65726177 /* "ware" */
> +#define CPUID_HV_VENDOR_VMWARE "VMwareVMware"
> +#define CPUID_HV_LEVEL_VMARE_3 0x40000002
> +#define CPUID_HV_LEVEL_VMARE_4 0x40000010
> +
> +#define CPUID_HV_VENDOR_XEN "XenVMMXenVMM"
> +#define CPUID_HV_LEVEL_XEN 0x40000002
> +
> +#define CPUID_HV_VENDOR_KVM "KVMKVMKVM"
> +
> #define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
> #define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
>
> @@ -782,6 +794,15 @@ typedef struct CPUX86State {
> uint32_t cpuid_ext4_features;
> /* Flags from CPUID[EAX=7,ECX=0].EBX */
> uint32_t cpuid_7_0_ebx;
> + /* Hypervisor CPUIDs */
> + uint32_t cpuid_hv_level;
> + uint32_t cpuid_hv_vendor1;
> + uint32_t cpuid_hv_vendor2;
> + uint32_t cpuid_hv_vendor3;
> + /* VMware extra data */
> + uint32_t cpuid_hv_extra;
> + uint32_t cpuid_hv_extra_a;
> + uint32_t cpuid_hv_extra_b;
>
> /* MTRRs */
> uint64_t mtrr_fixed[11];
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 895d848..17c72bc 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -389,16 +389,18 @@ int kvm_arch_init_vcpu(CPUX86State *env)
> c = &cpuid_data.entries[cpuid_i++];
> memset(c, 0, sizeof(*c));
> c->function = KVM_CPUID_SIGNATURE;
> - if (!hyperv_enabled()) {
> + if (env->cpuid_hv_level == 0) {
> memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> c->eax = 0;
> + c->ebx = signature[0];
> + c->ecx = signature[1];
> + c->edx = signature[2];
> } else {
> - memcpy(signature, "Microsoft Hv", 12);
> - c->eax = HYPERV_CPUID_MIN;
> + c->eax = env->cpuid_hv_level;
> + c->ebx = env->cpuid_hv_vendor1;
> + c->ecx = env->cpuid_hv_vendor2;
> + c->edx = env->cpuid_hv_vendor3;
> }
> - c->ebx = signature[0];
> - c->ecx = signature[1];
> - c->edx = signature[2];
>
> c = &cpuid_data.entries[cpuid_i++];
> memset(c, 0, sizeof(*c));
> @@ -452,6 +454,25 @@ int kvm_arch_init_vcpu(CPUX86State *env)
> c->ebx = signature[0];
> c->ecx = signature[1];
> c->edx = signature[2];
> + } else if (env->cpuid_hv_level > 0) {
> + for (i = KVM_CPUID_FEATURES + 1; i <= env->cpuid_hv_level; i++) {
> + c = &cpuid_data.entries[cpuid_i++];
> + memset(c, 0, sizeof(*c));
> + c->function = i;
> + if (i == env->cpuid_hv_extra) {
> + c->eax = env->cpuid_hv_extra_a;
> + c->ebx = env->cpuid_hv_extra_b;
> + }
> + }
> +
> + c = &cpuid_data.entries[cpuid_i++];
> + memset(c, 0, sizeof(*c));
> + c->function = KVM_CPUID_SIGNATURE_NEXT;
> + memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> + c->eax = 0;
> + c->ebx = signature[0];
> + c->ecx = signature[1];
> + c->edx = signature[2];
> }
>
> has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
Its one big patch, better split in logically correlated patches
(with better changelog). This would help reviewers.
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v2 3/4] target-i386: Allow changing of Hypervisor CPUIDs.
2012-09-12 17:55 ` Marcelo Tosatti
@ 2012-09-13 18:43 ` Don Slutz
2012-09-14 10:01 ` Marcelo Tosatti
0 siblings, 1 reply; 65+ messages in thread
From: Don Slutz @ 2012-09-13 18:43 UTC (permalink / raw)
To: Marcelo Tosatti
Cc: peter.maydell, ehabkost, kvm, qemu-devel, avi, anthony, imammedo,
afaerber
On 09/12/12 13:55, Marcelo Tosatti wrote:
> The problem with integrating this is that it has little or
> no assurance from documentation. The Linux kernel source is a good
> source, then say "accordingly to VMWare guest support code in version xyz"
> in the changelog.
I will work on getting a list of the documentation and sources used to
generate this.
>
> Also extracting this information in a text file (or comment in the code)
> would be better than just adding code.
I am not sure what information you are talking about here. Are you
asking about the known "Hypervisor CPUIDs", or what a lot of Linux
version look at to determine the Hypervisor they are on, or something else?
>
> On Tue, Sep 11, 2012 at 10:07:46AM -0400, Don Slutz wrote:
>> This is primarily done so that the guest will think it is running
>> under vmware when hypervisor-vendor=vmware is specified as a
>> property of a cpu.
>>
>> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
>> ---
>> target-i386/cpu.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> target-i386/cpu.h | 21 +++++
>> target-i386/kvm.c | 33 +++++++--
>> 3 files changed, 262 insertions(+), 6 deletions(-)
>>
>> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
>> index 5f9866a..9f1f390 100644
>> --- a/target-i386/cpu.c
>> +++ b/target-i386/cpu.c
>> @@ -1135,6 +1135,36 @@ static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
>> }
>> }
>>
>> +static void x86_cpuid_set_vmware_extra(Object *obj)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> +
>> + if ((cpu->env.tsc_khz != 0) &&
>> + (cpu->env.cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) &&
>> + (cpu->env.cpuid_hv_vendor1 == CPUID_HV_VENDOR_VMWARE_1) &&
>> + (cpu->env.cpuid_hv_vendor2 == CPUID_HV_VENDOR_VMWARE_2) &&
>> + (cpu->env.cpuid_hv_vendor3 == CPUID_HV_VENDOR_VMWARE_3)) {
>> + const uint32_t apic_khz = 1000000L;
>> +
>> + /*
>> + * From article.gmane.org/gmane.comp.emulators.kvm.devel/22643
>> + *
>> + * Leaf 0x40000010, Timing Information.
>> + *
>> + * VMware has defined the first generic leaf to provide timing
>> + * information. This leaf returns the current TSC frequency and
>> + * current Bus frequency in kHz.
>> + *
>> + * # EAX: (Virtual) TSC frequency in kHz.
>> + * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
>> + * # ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
>> + */
>> + cpu->env.cpuid_hv_extra = 0x40000010;
>> + cpu->env.cpuid_hv_extra_a = (uint32_t)cpu->env.tsc_khz;
>> + cpu->env.cpuid_hv_extra_b = apic_khz;
>> + }
>> +}
> What happens in case you migrate the vmware guest to a host
> with different frequency? How is that transmitted to the
> vmware-guest-running-on-kvm ? Or is migration not supported?
As far as I know, it would be the same as for a non-vmware guest.
http://lists.nongnu.org/archive/html/qemu-devel/2011-07/msg01656.html is
related to this.
I did not look to see if this has been done since then.
All this change does is to allow the guest to "read" the tsc-frequency
instead of trying to calculate it.
I will look into the current state of migration when tsc_freq=X is
specified. The machine I have been doing most of the testing on (Intel
Xeon E3-1260L) when I add tsc_freq=2.0G or tsc_freq=2.4G, the guest does
not see any difference in accel=kvm.
>
>> +static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
>> + const char *name, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> + uint32_t value;
>> +
>> + visit_type_uint32(v, &value, name, errp);
>> + if (error_is_set(errp)) {
>> + return;
>> + }
>> +
>> + if ((value != 0) && (value < 0x40000000)) {
>> + value += 0x40000000;
>> + }
>> + cpu->env.cpuid_hv_level = value;
>> +}
>> +
>> +static char *x86_cpuid_get_hv_vendor(Object *obj, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> + CPUX86State *env = &cpu->env;
>> + char *value;
>> + int i;
>> +
>> + value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
>> + for (i = 0; i < 4; i++) {
>> + value[i + 0] = env->cpuid_hv_vendor1 >> (8 * i);
>> + value[i + 4] = env->cpuid_hv_vendor2 >> (8 * i);
>> + value[i + 8] = env->cpuid_hv_vendor3 >> (8 * i);
>> + }
>> + value[CPUID_VENDOR_SZ] = '\0';
>> +
>> + /* Convert known names */
>> + if (!strcmp(value, CPUID_HV_VENDOR_VMWARE)) {
>> + if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) {
>> + pstrcpy(value, sizeof(value), "vmware4");
>> + } else if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_3) {
>> + pstrcpy(value, sizeof(value), "vmware3");
>> + }
>> + } else if (!strcmp(value, CPUID_HV_VENDOR_XEN) &&
>> + env->cpuid_hv_level == CPUID_HV_LEVEL_XEN) {
>> + pstrcpy(value, sizeof(value), "xen");
>> + } else if (!strcmp(value, CPUID_HV_VENDOR_KVM) &&
>> + env->cpuid_hv_level == 0) {
>> + pstrcpy(value, sizeof(value), "kvm");
>> + }
>> + return value;
>> +}
>> +
>> +static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
>> + Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> + CPUX86State *env = &cpu->env;
>> + int i;
>> + char adj_value[CPUID_VENDOR_SZ + 1];
>> +
>> + memset(adj_value, 0, sizeof(adj_value));
>> +
>> + /* Convert known names */
>> + if (!strcmp(value, "vmware") || !strcmp(value, "vmware4")) {
>> + if (env->cpuid_hv_level == 0) {
>> + env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_4;
>> + }
>> + pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
>> + } else if (!strcmp(value, "vmware3")) {
>> + if (env->cpuid_hv_level == 0) {
>> + env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_3;
>> + }
>> + pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
>> + } else if (!strcmp(value, "xen")) {
>> + if (env->cpuid_hv_level == 0) {
>> + env->cpuid_hv_level = CPUID_HV_LEVEL_XEN;
>> + }
>> + pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_XEN);
>> + } else if (!strcmp(value, "kvm")) {
>> + pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_KVM);
>> + } else {
>> + pstrcpy(adj_value, sizeof(adj_value), value);
>> + }
>> +
>> + env->cpuid_hv_vendor1 = 0;
>> + env->cpuid_hv_vendor2 = 0;
>> + env->cpuid_hv_vendor3 = 0;
>> + for (i = 0; i < 4; i++) {
>> + env->cpuid_hv_vendor1 |= ((uint8_t)adj_value[i + 0]) << (8 * i);
>> + env->cpuid_hv_vendor2 |= ((uint8_t)adj_value[i + 4]) << (8 * i);
>> + env->cpuid_hv_vendor3 |= ((uint8_t)adj_value[i + 8]) << (8 * i);
>> + }
>> + x86_cpuid_set_vmware_extra(obj);
>> +}
>> +
>> +static void x86_cpuid_get_hv_extra(Object *obj, Visitor *v, void *opaque,
>> + const char *name, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> +
>> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra, name, errp);
>> +}
>> +
>> +static void x86_cpuid_set_hv_extra(Object *obj, Visitor *v, void *opaque,
>> + const char *name, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> + uint32_t value;
>> +
>> + visit_type_uint32(v, &value, name, errp);
>> + if (error_is_set(errp)) {
>> + return;
>> + }
>> +
>> + if ((value != 0) && (value < 0x40000000)) {
>> + value += 0x40000000;
>> + }
>> + cpu->env.cpuid_hv_extra = value;
>> +}
>> +
>> +static void x86_cpuid_get_hv_extra_a(Object *obj, Visitor *v, void *opaque,
>> + const char *name, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> +
>> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
>> +}
>> +
>> +static void x86_cpuid_set_hv_extra_a(Object *obj, Visitor *v, void *opaque,
>> + const char *name, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> +
>> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
>> +}
>> +
>> +static void x86_cpuid_get_hv_extra_b(Object *obj, Visitor *v, void *opaque,
>> + const char *name, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> +
>> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
>> +}
>> +
>> +static void x86_cpuid_set_hv_extra_b(Object *obj, Visitor *v, void *opaque,
>> + const char *name, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> +
>> + visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
>> }
>>
>> #if !defined(CONFIG_USER_ONLY)
>> +static void x86_set_hyperv(Object *obj, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> +
>> + cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
>> + x86_cpuid_set_hv_vendor(obj, "Microsoft Hv", errp);
>> +}
>> +
>> static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
>> const char *name, Error **errp)
>> {
>> @@ -1189,6 +1385,7 @@ static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
>> return;
>> }
>> hyperv_set_spinlock_retries(value);
>> + x86_set_hyperv(obj, errp);
>> }
>>
>> static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
>> @@ -1209,6 +1406,7 @@ static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
>> return;
>> }
>> hyperv_enable_relaxed_timing(value);
>> + x86_set_hyperv(obj, errp);
>> }
> This seems unrelated to the rest of the patch?
The new call to x86_set_hyperv() is how the 1st change to
target-i386/kvm.c still does the same thing as before.
>
>> static void x86_get_hv_vapic(Object *obj, Visitor *v, void *opaque,
>> @@ -1229,6 +1427,7 @@ static void x86_set_hv_vapic(Object *obj, Visitor *v, void *opaque,
>> return;
>> }
>> hyperv_enable_vapic_recommended(value);
>> + x86_set_hyperv(obj, errp);
>> }
>> #endif
>>
>> @@ -2061,6 +2260,21 @@ static void x86_cpu_initfn(Object *obj)
>> object_property_add(obj, "enforce", "bool",
>> x86_cpuid_get_enforce,
>> x86_cpuid_set_enforce, NULL, NULL, NULL);
>> + object_property_add(obj, "hypervisor-level", "int",
>> + x86_cpuid_get_hv_level,
>> + x86_cpuid_set_hv_level, NULL, NULL, NULL);
>> + object_property_add_str(obj, "hypervisor-vendor",
>> + x86_cpuid_get_hv_vendor,
>> + x86_cpuid_set_hv_vendor, NULL);
>> + object_property_add(obj, "hypervisor-extra", "int",
>> + x86_cpuid_get_hv_extra,
>> + x86_cpuid_set_hv_extra, NULL, NULL, NULL);
>> + object_property_add(obj, "hypervisor-extra-a", "int",
>> + x86_cpuid_get_hv_extra_a,
>> + x86_cpuid_set_hv_extra_a, NULL, NULL, NULL);
>> + object_property_add(obj, "hypervisor-extra-b", "int",
>> + x86_cpuid_get_hv_extra_b,
>> + x86_cpuid_set_hv_extra_b, NULL, NULL, NULL);
>> #if !defined(CONFIG_USER_ONLY)
>> object_property_add(obj, "hv_spinlocks", "int",
>> x86_get_hv_spinlocks,
>> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
>> index 5265c5a..a2d3588 100644
>> --- a/target-i386/cpu.h
>> +++ b/target-i386/cpu.h
>> @@ -488,6 +488,18 @@
>>
>> #define CPUID_VENDOR_VIA "CentaurHauls"
>>
>> +#define CPUID_HV_VENDOR_VMWARE_1 0x61774d56 /* "VMwa" */
>> +#define CPUID_HV_VENDOR_VMWARE_2 0x4d566572 /* "reVM" */
>> +#define CPUID_HV_VENDOR_VMWARE_3 0x65726177 /* "ware" */
>> +#define CPUID_HV_VENDOR_VMWARE "VMwareVMware"
>> +#define CPUID_HV_LEVEL_VMARE_3 0x40000002
>> +#define CPUID_HV_LEVEL_VMARE_4 0x40000010
>> +
>> +#define CPUID_HV_VENDOR_XEN "XenVMMXenVMM"
>> +#define CPUID_HV_LEVEL_XEN 0x40000002
>> +
>> +#define CPUID_HV_VENDOR_KVM "KVMKVMKVM"
>> +
>> #define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
>> #define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
>>
>> @@ -782,6 +794,15 @@ typedef struct CPUX86State {
>> uint32_t cpuid_ext4_features;
>> /* Flags from CPUID[EAX=7,ECX=0].EBX */
>> uint32_t cpuid_7_0_ebx;
>> + /* Hypervisor CPUIDs */
>> + uint32_t cpuid_hv_level;
>> + uint32_t cpuid_hv_vendor1;
>> + uint32_t cpuid_hv_vendor2;
>> + uint32_t cpuid_hv_vendor3;
>> + /* VMware extra data */
>> + uint32_t cpuid_hv_extra;
>> + uint32_t cpuid_hv_extra_a;
>> + uint32_t cpuid_hv_extra_b;
>>
>> /* MTRRs */
>> uint64_t mtrr_fixed[11];
>> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
>> index 895d848..17c72bc 100644
>> --- a/target-i386/kvm.c
>> +++ b/target-i386/kvm.c
>> @@ -389,16 +389,18 @@ int kvm_arch_init_vcpu(CPUX86State *env)
>> c = &cpuid_data.entries[cpuid_i++];
>> memset(c, 0, sizeof(*c));
>> c->function = KVM_CPUID_SIGNATURE;
>> - if (!hyperv_enabled()) {
>> + if (env->cpuid_hv_level == 0) {
>> memcpy(signature, "KVMKVMKVM\0\0\0", 12);
>> c->eax = 0;
>> + c->ebx = signature[0];
>> + c->ecx = signature[1];
>> + c->edx = signature[2];
>> } else {
>> - memcpy(signature, "Microsoft Hv", 12);
>> - c->eax = HYPERV_CPUID_MIN;
>> + c->eax = env->cpuid_hv_level;
>> + c->ebx = env->cpuid_hv_vendor1;
>> + c->ecx = env->cpuid_hv_vendor2;
>> + c->edx = env->cpuid_hv_vendor3;
>> }
>> - c->ebx = signature[0];
>> - c->ecx = signature[1];
>> - c->edx = signature[2];
>>
>> c = &cpuid_data.entries[cpuid_i++];
>> memset(c, 0, sizeof(*c));
>> @@ -452,6 +454,25 @@ int kvm_arch_init_vcpu(CPUX86State *env)
>> c->ebx = signature[0];
>> c->ecx = signature[1];
>> c->edx = signature[2];
>> + } else if (env->cpuid_hv_level > 0) {
>> + for (i = KVM_CPUID_FEATURES + 1; i <= env->cpuid_hv_level; i++) {
>> + c = &cpuid_data.entries[cpuid_i++];
>> + memset(c, 0, sizeof(*c));
>> + c->function = i;
>> + if (i == env->cpuid_hv_extra) {
>> + c->eax = env->cpuid_hv_extra_a;
>> + c->ebx = env->cpuid_hv_extra_b;
>> + }
>> + }
>> +
>> + c = &cpuid_data.entries[cpuid_i++];
>> + memset(c, 0, sizeof(*c));
>> + c->function = KVM_CPUID_SIGNATURE_NEXT;
>> + memcpy(signature, "KVMKVMKVM\0\0\0", 12);
>> + c->eax = 0;
>> + c->ebx = signature[0];
>> + c->ecx = signature[1];
>> + c->edx = signature[2];
>> }
>>
>> has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
>
> Its one big patch, better split in logically correlated patches
> (with better changelog). This would help reviewers.
Will re-work into a set of smaller changes.
-Don
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v2 3/4] target-i386: Allow changing of Hypervisor CPUIDs.
2012-09-13 18:43 ` Don Slutz
@ 2012-09-14 10:01 ` Marcelo Tosatti
0 siblings, 0 replies; 65+ messages in thread
From: Marcelo Tosatti @ 2012-09-14 10:01 UTC (permalink / raw)
To: Don Slutz
Cc: peter.maydell, ehabkost, kvm, qemu-devel, avi, anthony, imammedo,
afaerber
On Thu, Sep 13, 2012 at 02:43:55PM -0400, Don Slutz wrote:
> On 09/12/12 13:55, Marcelo Tosatti wrote:
> >The problem with integrating this is that it has little or
> >no assurance from documentation. The Linux kernel source is a good
> >source, then say "accordingly to VMWare guest support code in version xyz"
> >in the changelog.
> I will work on getting a list of the documentation and sources used
> to generate this.
> >
> >Also extracting this information in a text file (or comment in the code)
> >would be better than just adding code.
> I am not sure what information you are talking about here. Are you
> asking about the known "Hypervisor CPUIDs", or what a lot of Linux
> version look at to determine the Hypervisor they are on, or
> something else?
Just a summary of where you got the info from.
> >On Tue, Sep 11, 2012 at 10:07:46AM -0400, Don Slutz wrote:
> >>This is primarily done so that the guest will think it is running
> >>under vmware when hypervisor-vendor=vmware is specified as a
> >>property of a cpu.
> >>
> >>Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> >>---
> >> target-i386/cpu.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >> target-i386/cpu.h | 21 +++++
> >> target-i386/kvm.c | 33 +++++++--
> >> 3 files changed, 262 insertions(+), 6 deletions(-)
> >>
> >>diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> >>index 5f9866a..9f1f390 100644
> >>--- a/target-i386/cpu.c
> >>+++ b/target-i386/cpu.c
> >>@@ -1135,6 +1135,36 @@ static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
> >> }
> >> }
> >>+static void x86_cpuid_set_vmware_extra(Object *obj)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+
> >>+ if ((cpu->env.tsc_khz != 0) &&
> >>+ (cpu->env.cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) &&
> >>+ (cpu->env.cpuid_hv_vendor1 == CPUID_HV_VENDOR_VMWARE_1) &&
> >>+ (cpu->env.cpuid_hv_vendor2 == CPUID_HV_VENDOR_VMWARE_2) &&
> >>+ (cpu->env.cpuid_hv_vendor3 == CPUID_HV_VENDOR_VMWARE_3)) {
> >>+ const uint32_t apic_khz = 1000000L;
> >>+
> >>+ /*
> >>+ * From article.gmane.org/gmane.comp.emulators.kvm.devel/22643
> >>+ *
> >>+ * Leaf 0x40000010, Timing Information.
> >>+ *
> >>+ * VMware has defined the first generic leaf to provide timing
> >>+ * information. This leaf returns the current TSC frequency and
> >>+ * current Bus frequency in kHz.
> >>+ *
> >>+ * # EAX: (Virtual) TSC frequency in kHz.
> >>+ * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
> >>+ * # ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
> >>+ */
> >>+ cpu->env.cpuid_hv_extra = 0x40000010;
> >>+ cpu->env.cpuid_hv_extra_a = (uint32_t)cpu->env.tsc_khz;
> >>+ cpu->env.cpuid_hv_extra_b = apic_khz;
> >>+ }
> >>+}
> >What happens in case you migrate the vmware guest to a host
> >with different frequency? How is that transmitted to the
> >vmware-guest-running-on-kvm ? Or is migration not supported?
> As far as I know, it would be the same as for a non-vmware guest.
> http://lists.nongnu.org/archive/html/qemu-devel/2011-07/msg01656.html
> is related to this.
>
> I did not look to see if this has been done since then.
No it has not, but something similar will be, see:
http://www.spinics.net/lists/kvm/msg79719.html
Yeah alright.
> All this change does is to allow the guest to "read" the
> tsc-frequency instead of trying to calculate it.
>
> I will look into the current state of migration when tsc_freq=X is
> specified. The machine I have been doing most of the testing on
> (Intel Xeon E3-1260L) when I add tsc_freq=2.0G or tsc_freq=2.4G, the
> guest does not see any difference in accel=kvm.
Yeah i think you can ignore it.
> >>+static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
> >>+ const char *name, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+ uint32_t value;
> >>+
> >>+ visit_type_uint32(v, &value, name, errp);
> >>+ if (error_is_set(errp)) {
> >>+ return;
> >>+ }
> >>+
> >>+ if ((value != 0) && (value < 0x40000000)) {
> >>+ value += 0x40000000;
> >>+ }
> >>+ cpu->env.cpuid_hv_level = value;
> >>+}
> >>+
> >>+static char *x86_cpuid_get_hv_vendor(Object *obj, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+ CPUX86State *env = &cpu->env;
> >>+ char *value;
> >>+ int i;
> >>+
> >>+ value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
> >>+ for (i = 0; i < 4; i++) {
> >>+ value[i + 0] = env->cpuid_hv_vendor1 >> (8 * i);
> >>+ value[i + 4] = env->cpuid_hv_vendor2 >> (8 * i);
> >>+ value[i + 8] = env->cpuid_hv_vendor3 >> (8 * i);
> >>+ }
> >>+ value[CPUID_VENDOR_SZ] = '\0';
> >>+
> >>+ /* Convert known names */
> >>+ if (!strcmp(value, CPUID_HV_VENDOR_VMWARE)) {
> >>+ if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) {
> >>+ pstrcpy(value, sizeof(value), "vmware4");
> >>+ } else if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_3) {
> >>+ pstrcpy(value, sizeof(value), "vmware3");
> >>+ }
> >>+ } else if (!strcmp(value, CPUID_HV_VENDOR_XEN) &&
> >>+ env->cpuid_hv_level == CPUID_HV_LEVEL_XEN) {
> >>+ pstrcpy(value, sizeof(value), "xen");
> >>+ } else if (!strcmp(value, CPUID_HV_VENDOR_KVM) &&
> >>+ env->cpuid_hv_level == 0) {
> >>+ pstrcpy(value, sizeof(value), "kvm");
> >>+ }
> >>+ return value;
> >>+}
> >>+
> >>+static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
> >>+ Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+ CPUX86State *env = &cpu->env;
> >>+ int i;
> >>+ char adj_value[CPUID_VENDOR_SZ + 1];
> >>+
> >>+ memset(adj_value, 0, sizeof(adj_value));
> >>+
> >>+ /* Convert known names */
> >>+ if (!strcmp(value, "vmware") || !strcmp(value, "vmware4")) {
> >>+ if (env->cpuid_hv_level == 0) {
> >>+ env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_4;
> >>+ }
> >>+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
> >>+ } else if (!strcmp(value, "vmware3")) {
> >>+ if (env->cpuid_hv_level == 0) {
> >>+ env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_3;
> >>+ }
> >>+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
> >>+ } else if (!strcmp(value, "xen")) {
> >>+ if (env->cpuid_hv_level == 0) {
> >>+ env->cpuid_hv_level = CPUID_HV_LEVEL_XEN;
> >>+ }
> >>+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_XEN);
> >>+ } else if (!strcmp(value, "kvm")) {
> >>+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_KVM);
> >>+ } else {
> >>+ pstrcpy(adj_value, sizeof(adj_value), value);
> >>+ }
> >>+
> >>+ env->cpuid_hv_vendor1 = 0;
> >>+ env->cpuid_hv_vendor2 = 0;
> >>+ env->cpuid_hv_vendor3 = 0;
> >>+ for (i = 0; i < 4; i++) {
> >>+ env->cpuid_hv_vendor1 |= ((uint8_t)adj_value[i + 0]) << (8 * i);
> >>+ env->cpuid_hv_vendor2 |= ((uint8_t)adj_value[i + 4]) << (8 * i);
> >>+ env->cpuid_hv_vendor3 |= ((uint8_t)adj_value[i + 8]) << (8 * i);
> >>+ }
> >>+ x86_cpuid_set_vmware_extra(obj);
> >>+}
> >>+
> >>+static void x86_cpuid_get_hv_extra(Object *obj, Visitor *v, void *opaque,
> >>+ const char *name, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+
> >>+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra, name, errp);
> >>+}
> >>+
> >>+static void x86_cpuid_set_hv_extra(Object *obj, Visitor *v, void *opaque,
> >>+ const char *name, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+ uint32_t value;
> >>+
> >>+ visit_type_uint32(v, &value, name, errp);
> >>+ if (error_is_set(errp)) {
> >>+ return;
> >>+ }
> >>+
> >>+ if ((value != 0) && (value < 0x40000000)) {
> >>+ value += 0x40000000;
> >>+ }
> >>+ cpu->env.cpuid_hv_extra = value;
> >>+}
> >>+
> >>+static void x86_cpuid_get_hv_extra_a(Object *obj, Visitor *v, void *opaque,
> >>+ const char *name, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+
> >>+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
> >>+}
> >>+
> >>+static void x86_cpuid_set_hv_extra_a(Object *obj, Visitor *v, void *opaque,
> >>+ const char *name, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+
> >>+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
> >>+}
> >>+
> >>+static void x86_cpuid_get_hv_extra_b(Object *obj, Visitor *v, void *opaque,
> >>+ const char *name, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+
> >>+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
> >>+}
> >>+
> >>+static void x86_cpuid_set_hv_extra_b(Object *obj, Visitor *v, void *opaque,
> >>+ const char *name, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+
> >>+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
> >> }
> >> #if !defined(CONFIG_USER_ONLY)
> >>+static void x86_set_hyperv(Object *obj, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+
> >>+ cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
> >>+ x86_cpuid_set_hv_vendor(obj, "Microsoft Hv", errp);
> >>+}
> >>+
> >> static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
> >> const char *name, Error **errp)
> >> {
> >>@@ -1189,6 +1385,7 @@ static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
> >> return;
> >> }
> >> hyperv_set_spinlock_retries(value);
> >>+ x86_set_hyperv(obj, errp);
> >> }
> >> static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
> >>@@ -1209,6 +1406,7 @@ static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
> >> return;
> >> }
> >> hyperv_enable_relaxed_timing(value);
> >>+ x86_set_hyperv(obj, errp);
> >> }
> >This seems unrelated to the rest of the patch?
> The new call to x86_set_hyperv() is how the 1st change to
> target-i386/kvm.c still does the same thing as before.
> >
> >> static void x86_get_hv_vapic(Object *obj, Visitor *v, void *opaque,
> >>@@ -1229,6 +1427,7 @@ static void x86_set_hv_vapic(Object *obj, Visitor *v, void *opaque,
> >> return;
> >> }
> >> hyperv_enable_vapic_recommended(value);
> >>+ x86_set_hyperv(obj, errp);
> >> }
> >> #endif
> >>@@ -2061,6 +2260,21 @@ static void x86_cpu_initfn(Object *obj)
> >> object_property_add(obj, "enforce", "bool",
> >> x86_cpuid_get_enforce,
> >> x86_cpuid_set_enforce, NULL, NULL, NULL);
> >>+ object_property_add(obj, "hypervisor-level", "int",
> >>+ x86_cpuid_get_hv_level,
> >>+ x86_cpuid_set_hv_level, NULL, NULL, NULL);
> >>+ object_property_add_str(obj, "hypervisor-vendor",
> >>+ x86_cpuid_get_hv_vendor,
> >>+ x86_cpuid_set_hv_vendor, NULL);
> >>+ object_property_add(obj, "hypervisor-extra", "int",
> >>+ x86_cpuid_get_hv_extra,
> >>+ x86_cpuid_set_hv_extra, NULL, NULL, NULL);
> >>+ object_property_add(obj, "hypervisor-extra-a", "int",
> >>+ x86_cpuid_get_hv_extra_a,
> >>+ x86_cpuid_set_hv_extra_a, NULL, NULL, NULL);
> >>+ object_property_add(obj, "hypervisor-extra-b", "int",
> >>+ x86_cpuid_get_hv_extra_b,
> >>+ x86_cpuid_set_hv_extra_b, NULL, NULL, NULL);
> >> #if !defined(CONFIG_USER_ONLY)
> >> object_property_add(obj, "hv_spinlocks", "int",
> >> x86_get_hv_spinlocks,
> >>diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> >>index 5265c5a..a2d3588 100644
> >>--- a/target-i386/cpu.h
> >>+++ b/target-i386/cpu.h
> >>@@ -488,6 +488,18 @@
> >> #define CPUID_VENDOR_VIA "CentaurHauls"
> >>+#define CPUID_HV_VENDOR_VMWARE_1 0x61774d56 /* "VMwa" */
> >>+#define CPUID_HV_VENDOR_VMWARE_2 0x4d566572 /* "reVM" */
> >>+#define CPUID_HV_VENDOR_VMWARE_3 0x65726177 /* "ware" */
> >>+#define CPUID_HV_VENDOR_VMWARE "VMwareVMware"
> >>+#define CPUID_HV_LEVEL_VMARE_3 0x40000002
> >>+#define CPUID_HV_LEVEL_VMARE_4 0x40000010
> >>+
> >>+#define CPUID_HV_VENDOR_XEN "XenVMMXenVMM"
> >>+#define CPUID_HV_LEVEL_XEN 0x40000002
> >>+
> >>+#define CPUID_HV_VENDOR_KVM "KVMKVMKVM"
> >>+
> >> #define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
> >> #define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
> >>@@ -782,6 +794,15 @@ typedef struct CPUX86State {
> >> uint32_t cpuid_ext4_features;
> >> /* Flags from CPUID[EAX=7,ECX=0].EBX */
> >> uint32_t cpuid_7_0_ebx;
> >>+ /* Hypervisor CPUIDs */
> >>+ uint32_t cpuid_hv_level;
> >>+ uint32_t cpuid_hv_vendor1;
> >>+ uint32_t cpuid_hv_vendor2;
> >>+ uint32_t cpuid_hv_vendor3;
> >>+ /* VMware extra data */
> >>+ uint32_t cpuid_hv_extra;
> >>+ uint32_t cpuid_hv_extra_a;
> >>+ uint32_t cpuid_hv_extra_b;
> >> /* MTRRs */
> >> uint64_t mtrr_fixed[11];
> >>diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> >>index 895d848..17c72bc 100644
> >>--- a/target-i386/kvm.c
> >>+++ b/target-i386/kvm.c
> >>@@ -389,16 +389,18 @@ int kvm_arch_init_vcpu(CPUX86State *env)
> >> c = &cpuid_data.entries[cpuid_i++];
> >> memset(c, 0, sizeof(*c));
> >> c->function = KVM_CPUID_SIGNATURE;
> >>- if (!hyperv_enabled()) {
> >>+ if (env->cpuid_hv_level == 0) {
> >> memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> >> c->eax = 0;
> >>+ c->ebx = signature[0];
> >>+ c->ecx = signature[1];
> >>+ c->edx = signature[2];
> >> } else {
> >>- memcpy(signature, "Microsoft Hv", 12);
> >>- c->eax = HYPERV_CPUID_MIN;
> >>+ c->eax = env->cpuid_hv_level;
> >>+ c->ebx = env->cpuid_hv_vendor1;
> >>+ c->ecx = env->cpuid_hv_vendor2;
> >>+ c->edx = env->cpuid_hv_vendor3;
> >> }
> >>- c->ebx = signature[0];
> >>- c->ecx = signature[1];
> >>- c->edx = signature[2];
> >> c = &cpuid_data.entries[cpuid_i++];
> >> memset(c, 0, sizeof(*c));
> >>@@ -452,6 +454,25 @@ int kvm_arch_init_vcpu(CPUX86State *env)
> >> c->ebx = signature[0];
> >> c->ecx = signature[1];
> >> c->edx = signature[2];
> >>+ } else if (env->cpuid_hv_level > 0) {
> >>+ for (i = KVM_CPUID_FEATURES + 1; i <= env->cpuid_hv_level; i++) {
> >>+ c = &cpuid_data.entries[cpuid_i++];
> >>+ memset(c, 0, sizeof(*c));
> >>+ c->function = i;
> >>+ if (i == env->cpuid_hv_extra) {
> >>+ c->eax = env->cpuid_hv_extra_a;
> >>+ c->ebx = env->cpuid_hv_extra_b;
> >>+ }
> >>+ }
> >>+
> >>+ c = &cpuid_data.entries[cpuid_i++];
> >>+ memset(c, 0, sizeof(*c));
> >>+ c->function = KVM_CPUID_SIGNATURE_NEXT;
> >>+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> >>+ c->eax = 0;
> >>+ c->ebx = signature[0];
> >>+ c->ecx = signature[1];
> >>+ c->edx = signature[2];
> >> }
> >> has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
> >
> >Its one big patch, better split in logically correlated patches
> >(with better changelog). This would help reviewers.
> Will re-work into a set of smaller changes.
> -Don
OK then.
^ permalink raw reply [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v2 4/4] target-i386: Add Hypervisor CPUIDs in accel=tcg mode.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (5 preceding siblings ...)
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 3/4] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
@ 2012-09-11 14:07 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs Don Slutz
` (43 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-11 14:07 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo
Cc: peter.maydell, kvm, Don Slutz, avi, anthony, afaerber
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 33 +++++++++++++++++++++++++++++++++
1 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9f1f390..89a45b5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1815,6 +1815,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
index = env->cpuid_xlevel;
}
}
+ } else if (index & 0x40000000) {
+ if (env->cpuid_hv_level > 0) {
+ /* Handle Hypervisor CPUIDs */
+ if (index > env->cpuid_hv_level) {
+ index = env->cpuid_hv_level;
+ }
+ } else {
+ if (index > env->cpuid_level)
+ index = env->cpuid_level;
+ }
} else {
if (index > env->cpuid_level)
index = env->cpuid_level;
@@ -1953,6 +1963,29 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx = 0;
}
break;
+ case 0x40000000:
+ *eax = env->cpuid_hv_level;
+ *ebx = env->cpuid_hv_vendor1;
+ *ecx = env->cpuid_hv_vendor2;
+ *edx = env->cpuid_hv_vendor3;
+ break;
+ case 0x40000001:
+ *eax = env->cpuid_kvm_features;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 0x40000002 ... 0x400000FF:
+ if (index == env->cpuid_hv_extra) {
+ *eax = env->cpuid_hv_extra_a;
+ *ebx = env->cpuid_hv_extra_b;
+ } else {
+ *eax = 0;
+ *ebx = 0;
+ }
+ *ecx = 0;
+ *edx = 0;
+ break;
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (6 preceding siblings ...)
2012-09-11 14:07 ` [Qemu-devel] [PATCH v2 4/4] target-i386: Add Hypervisor CPUIDs in accel=tcg mode Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 00/17] *** SUBJECT HERE *** Don Slutz
` (42 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization CPUIDs.
This is primarily done so that the guest will think it is running
under vmware when hypervisor-vendor=vmware is specified as a
property of a cpu.
This depends on:
http://lists.gnu.org/archive/html/qemu-devel/2012-09/msg01400.html
As far as I know it is #4. It depends on (1) and (2) and (3).
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Changes from v1 to v2:
1) Added 1/4 from http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg05153.html
Because Fred is changing jobs and so will not be pushing to get
this in. It needed to be rebased, And I needed it to complete the
testing of this change.
2) Added 2/4 because of the re-work I needed a way to clear all KVM bits,
3) The rework of v1. Make it fit into the object model re-work of cpu.c for x86.
4) Added 3/4 -- The split out of the code that is not needed for accel=kvm.
Changes from v2 to v3:
Marcelo Tosatti:
Its one big patch, better split in logically correlated patches
(with better changelog). This would help reviewers.
So split 3 and 4 into 3 to 17. More info in change log.
No code change.
Don Slutz (17):
target-i386: Allow tsc-frequency to be larger then 2.147G
target-i386: Add missing kvm bits.
target-i386: Add Hypervisor level.
target-i386: Add cpu object access routines for Hypervisor level.
target-i386: Add x86_set_hyperv.
target-i386: Use Hypervisor level in -machine pc,accel=kvm.
target-i386: Use Hypervisor level in -machine pc,accel=tcg.
target-i386: Add Hypervisor vendor.
target-i386: Add cpu object access routines for Hypervisor vendor.
target-i386: Use Hypervisor vendor in -machine pc,accel=kvm.
target-i386: Use Hypervisor vendor in -machine pc,accel=tcg.
target-i386: Add some known names to Hypervisor vendor.
target-i386: Add optional Hypervisor leaf extra.
target-i386: Add cpu object access routines for Hypervisor leaf
extra.
target-i386: Add setting of Hypervisor leaf extra for known vmare4.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=kvm.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=tcg.
target-i386/cpu.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
target-i386/cpu.h | 21 +++++
target-i386/kvm.c | 33 ++++++--
3 files changed, 304 insertions(+), 11 deletions(-)
^ permalink raw reply [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 00/17] *** SUBJECT HERE ***
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (7 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:49 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs Don Slutz
` (41 subsequent siblings)
50 siblings, 1 reply; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
*** BLURB HERE ***
Don Slutz (17):
target-i386: Allow tsc-frequency to be larger then 2.147G
target-i386: Add missing kvm bits.
target-i386: Add Hypervisor level.
target-i386: Add cpu object access routines for Hypervisor level.
target-i386: Add x86_set_hyperv.
target-i386: Use Hypervisor level in -machine pc,accel=kvm.
target-i386: Use Hypervisor level in -machine pc,accel=tcg.
target-i386: Add Hypervisor vendor.
target-i386: Add cpu object access routines for Hypervisor vendor.
target-i386: Use Hypervisor vendor in -machine pc,accel=kvm.
target-i386: Use Hypervisor vendor in -machine pc,accel=tcg.
target-i386: Add some known names to Hypervisor vendor.
target-i386: Add optional Hypervisor leaf extra.
target-i386: Add cpu object access routines for Hypervisor leaf
extra.
target-i386: Add setting of Hypervisor leaf extra for known vmare4.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=kvm.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=tcg.
target-i386/cpu.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
target-i386/cpu.h | 21 +++++
target-i386/kvm.c | 33 ++++++--
3 files changed, 304 insertions(+), 11 deletions(-)
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/17] *** SUBJECT HERE ***
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 00/17] *** SUBJECT HERE *** Don Slutz
@ 2012-09-17 13:49 ` Don Slutz
2012-09-17 13:51 ` Don Slutz
0 siblings, 1 reply; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:49 UTC (permalink / raw)
To: Don Slutz
Cc: peter.maydell, ehabkost, kvm, mtosatti, qemu-devel, avi, anthony,
imammedo, afaerber
forgot to delete the backup versions. :(
-Don
On 09/17/12 09:39, Don Slutz wrote:
> *** BLURB HERE ***
>
> Don Slutz (17):
> target-i386: Allow tsc-frequency to be larger then 2.147G
> target-i386: Add missing kvm bits.
> target-i386: Add Hypervisor level.
> target-i386: Add cpu object access routines for Hypervisor level.
> target-i386: Add x86_set_hyperv.
> target-i386: Use Hypervisor level in -machine pc,accel=kvm.
> target-i386: Use Hypervisor level in -machine pc,accel=tcg.
> target-i386: Add Hypervisor vendor.
> target-i386: Add cpu object access routines for Hypervisor vendor.
> target-i386: Use Hypervisor vendor in -machine pc,accel=kvm.
> target-i386: Use Hypervisor vendor in -machine pc,accel=tcg.
> target-i386: Add some known names to Hypervisor vendor.
> target-i386: Add optional Hypervisor leaf extra.
> target-i386: Add cpu object access routines for Hypervisor leaf
> extra.
> target-i386: Add setting of Hypervisor leaf extra for known vmare4.
> target-i386: Use Hypervisor leaf extra in -machine pc,accel=kvm.
> target-i386: Use Hypervisor leaf extra in -machine pc,accel=tcg.
>
> target-i386/cpu.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> target-i386/cpu.h | 21 +++++
> target-i386/kvm.c | 33 ++++++--
> 3 files changed, 304 insertions(+), 11 deletions(-)
>
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/17] *** SUBJECT HERE ***
2012-09-17 13:49 ` Don Slutz
@ 2012-09-17 13:51 ` Don Slutz
0 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:51 UTC (permalink / raw)
To: Don Slutz
Cc: peter.maydell, ehabkost, kvm, mtosatti, qemu-devel, avi, anthony,
imammedo, afaerber
On 09/17/12 09:49, Don Slutz wrote:
> forgot to delete the backup versions. :(
> -Don
> On 09/17/12 09:39, Don Slutz wrote:
Here is the planned cover letter:
From 7c0a80d8e870da981786b7235d3a968024c89abb Mon Sep 17 00:00:00 2001
In-Reply-To: <1346354435-21685-1-git-send-email-Don@CloudSwitch.com>
References: <1346354435-21685-1-git-send-email-Don@CloudSwitch.com>
From: Don Slutz <Don@CloudSwitch.com>
Date: Mon, 17 Sep 2012 09:23:29 -0400
Subject: [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs.
Also known as Paravirtualization CPUIDs.
This is primarily done so that the guest will think it is running
under vmware when hypervisor-vendor=vmware is specified as a
property of a cpu.
This depends on:
http://lists.gnu.org/archive/html/qemu-devel/2012-09/msg01400.html
As far as I know it is #4. It depends on (1) and (2) and (3).
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Changes from v1 to v2:
1) Added 1/4 from
http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg05153.html
Because Fred is changing jobs and so will not be pushing to get
this in. It needed to be rebased, And I needed it to complete the
testing of this change.
2) Added 2/4 because of the re-work I needed a way to clear all KVM bits,
3) The rework of v1. Make it fit into the object model re-work of cpu.c
for x86.
4) Added 3/4 -- The split out of the code that is not needed for accel=kvm.
Changes from v2 to v3:
Marcelo Tosatti:
Its one big patch, better split in logically correlated patches
(with better changelog). This would help reviewers.
So split 3 and 4 into 3 to 17. More info in change log.
No code change.
Don Slutz (17):
target-i386: Allow tsc-frequency to be larger then 2.147G
target-i386: Add missing kvm bits.
target-i386: Add Hypervisor level.
target-i386: Add cpu object access routines for Hypervisor level.
target-i386: Add x86_set_hyperv.
target-i386: Use Hypervisor level in -machine pc,accel=kvm.
target-i386: Use Hypervisor level in -machine pc,accel=tcg.
target-i386: Add Hypervisor vendor.
target-i386: Add cpu object access routines for Hypervisor vendor.
target-i386: Use Hypervisor vendor in -machine pc,accel=kvm.
target-i386: Use Hypervisor vendor in -machine pc,accel=tcg.
target-i386: Add some known names to Hypervisor vendor.
target-i386: Add optional Hypervisor leaf extra.
target-i386: Add cpu object access routines for Hypervisor leaf
extra.
target-i386: Add setting of Hypervisor leaf extra for known vmare4.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=kvm.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=tcg.
target-i386/cpu.c | 261
++++++++++++++++++++++++++++++++++++++++++++++++++++-
target-i386/cpu.h | 21 +++++
target-i386/kvm.c | 33 ++++++--
3 files changed, 304 insertions(+), 11 deletions(-)
^ permalink raw reply [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (8 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 00/17] *** SUBJECT HERE *** Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 01/17] target-i386: Allow tsc-frequency to be larger then 2.147G Don Slutz
` (40 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization CPUIDs.
This is primarily done so that the guest will think it is running
under vmware when hypervisor-vendor=vmware is specified as a
property of a cpu.
This depends on:
http://lists.gnu.org/archive/html/qemu-devel/2012-09/msg01400.html
As far as I know it is #4. It depends on (1) and (2) and (3).
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Changes from v1 to v2:
1) Added 1/4 from http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg05153.html
Because Fred is changing jobs and so will not be pushing to get
this in. It needed to be rebased, And I needed it to complete the
testing of this change.
2) Added 2/4 because of the re-work I needed a way to clear all KVM bits,
3) The rework of v1. Make it fit into the object model re-work of cpu.c for x86.
4) Added 3/4 -- The split out of the code that is not needed for accel=kvm.
Changes from v2 to v3:
Marcelo Tosatti:
Its one big patch, better split in logically correlated patches
(with better changelog). This would help reviewers.
So split 3 and 4 into 3 to 17. More info in change log.
No code change.
Don Slutz (17):
target-i386: Allow tsc-frequency to be larger then 2.147G
target-i386: Add missing kvm bits.
target-i386: Add Hypervisor level.
target-i386: Add cpu object access routines for Hypervisor level.
target-i386: Add x86_set_hyperv.
target-i386: Use Hypervisor level in -machine pc,accel=kvm.
target-i386: Use Hypervisor level in -machine pc,accel=tcg.
target-i386: Add Hypervisor vendor.
target-i386: Add cpu object access routines for Hypervisor vendor.
target-i386: Use Hypervisor vendor in -machine pc,accel=kvm.
target-i386: Use Hypervisor vendor in -machine pc,accel=tcg.
target-i386: Add some known names to Hypervisor vendor.
target-i386: Add optional Hypervisor leaf extra.
target-i386: Add cpu object access routines for Hypervisor leaf
extra.
target-i386: Add setting of Hypervisor leaf extra for known vmare4.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=kvm.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=tcg.
target-i386/cpu.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
target-i386/cpu.h | 21 +++++
target-i386/kvm.c | 33 ++++++--
3 files changed, 304 insertions(+), 11 deletions(-)
^ permalink raw reply [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 01/17] target-i386: Allow tsc-frequency to be larger then 2.147G
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (9 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 02/17] target-i386: Add missing kvm bits Don Slutz
` (39 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz, Fred Oliveira
The check using INT_MAX (2147483647) is wrong in this case.
Signed-off-by: Fred Oliveira <foliveira@cloudswitch.com>
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index af50a8f..0313cf5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1146,7 +1146,7 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
{
X86CPU *cpu = X86_CPU(obj);
const int64_t min = 0;
- const int64_t max = INT_MAX;
+ const int64_t max = INT64_MAX;
int64_t value;
visit_type_freq(v, &value, name, errp);
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 02/17] target-i386: Add missing kvm bits.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (10 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 01/17] target-i386: Allow tsc-frequency to be larger then 2.147G Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 03/17] target-i386: Add Hypervisor level Don Slutz
` (38 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Fix duplicate name (kvmclock => kvm_clock2) also.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 0313cf5..5f9866a 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -87,10 +87,14 @@ static const char *ext3_feature_name[] = {
};
static const char *kvm_feature_name[] = {
- "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, "kvm_pv_eoi", NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvm_clock2",
+ "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ "kvm_clock_stable", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
};
static const char *svm_feature_name[] = {
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 03/17] target-i386: Add Hypervisor level.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (11 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 02/17] target-i386: Add missing kvm bits Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` Don Slutz
` (37 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization level or maximim cpuid function present in this leaf.
This is just the EAX value for 0x40000000.
QEMU knows this is KVM_CPUID_SIGNATURE (0x40000000).
This is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
QEMU has the value HYPERV_CPUID_MIN defined.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5265c5a..05c0848 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -782,6 +782,8 @@ typedef struct CPUX86State {
uint32_t cpuid_ext4_features;
/* Flags from CPUID[EAX=7,ECX=0].EBX */
uint32_t cpuid_7_0_ebx;
+ /* Hypervisor CPUIDs */
+ uint32_t cpuid_hv_level;
/* MTRRs */
uint64_t mtrr_fixed[11];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 03/17] target-i386: Add Hypervisor level.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (12 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 03/17] target-i386: Add Hypervisor level Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 04/17] target-i386: Add cpu object access routines for " Don Slutz
` (36 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
This is just the EAX value.
This is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
QEMU has the value HYPERV_CPUID_MIN defined.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5265c5a..05c0848 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -782,6 +782,8 @@ typedef struct CPUX86State {
uint32_t cpuid_ext4_features;
/* Flags from CPUID[EAX=7,ECX=0].EBX */
uint32_t cpuid_7_0_ebx;
+ /* Hypervisor CPUIDs */
+ uint32_t cpuid_hv_level;
/* MTRRs */
uint64_t mtrr_fixed[11];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 04/17] target-i386: Add cpu object access routines for Hypervisor level.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (13 preceding siblings ...)
2012-09-17 13:39 ` Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv Don Slutz
` (35 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
These are modeled after x86_cpuid_get_xlevel and x86_cpuid_set_xlevel.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5f9866a..0e4a18d 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1166,6 +1166,31 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
cpu->env.tsc_khz = value / 1000;
}
+static void x86_cpuid_get_hv_level(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_level, name, errp);
+}
+
+static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+
+ if ((value != 0) && (value < 0x40000000)) {
+ value += 0x40000000;
+ }
+ cpu->env.cpuid_hv_level = value;
+}
+
#if !defined(CONFIG_USER_ONLY)
static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
@@ -2061,6 +2086,9 @@ static void x86_cpu_initfn(Object *obj)
object_property_add(obj, "enforce", "bool",
x86_cpuid_get_enforce,
x86_cpuid_set_enforce, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-level", "int",
+ x86_cpuid_get_hv_level,
+ x86_cpuid_set_hv_level, NULL, NULL, NULL);
#if !defined(CONFIG_USER_ONLY)
object_property_add(obj, "hv_spinlocks", "int",
x86_get_hv_spinlocks,
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (14 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 04/17] target-i386: Add cpu object access routines for " Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 06/17] target-i386: Use Hypervisor level in -machine pc, accel=kvm Don Slutz
` (34 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
This is used to set the cpu object's hypervisor level to the default for Microsoft's Hypervisor.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 0e4a18d..4120393 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1192,6 +1192,13 @@ static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
}
#if !defined(CONFIG_USER_ONLY)
+static void x86_set_hyperv(Object *obj, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
+}
+
static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
@@ -1214,6 +1221,7 @@ static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_set_spinlock_retries(value);
+ x86_set_hyperv(obj, errp);
}
static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
@@ -1234,6 +1242,7 @@ static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_enable_relaxed_timing(value);
+ x86_set_hyperv(obj, errp);
}
static void x86_get_hv_vapic(Object *obj, Visitor *v, void *opaque,
@@ -1254,6 +1263,7 @@ static void x86_set_hv_vapic(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_enable_vapic_recommended(value);
+ x86_set_hyperv(obj, errp);
}
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 06/17] target-i386: Use Hypervisor level in -machine pc, accel=kvm.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (15 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` Don Slutz
` (33 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization level.
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
QEMU knows this is KVM_CPUID_SIGNATURE (0x40000000).
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/kvm.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 895d848..bf27793 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -389,12 +389,12 @@ int kvm_arch_init_vcpu(CPUX86State *env)
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
c->function = KVM_CPUID_SIGNATURE;
- if (!hyperv_enabled()) {
+ if (env->cpuid_hv_level == 0) {
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
c->eax = 0;
} else {
memcpy(signature, "Microsoft Hv", 12);
- c->eax = HYPERV_CPUID_MIN;
+ c->eax = env->cpuid_hv_level;
}
c->ebx = signature[0];
c->ecx = signature[1];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 06/17] target-i386: Use Hypervisor level in -machine pc, accel=kvm.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (16 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 06/17] target-i386: Use Hypervisor level in -machine pc, accel=kvm Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 07/17] target-i386: Use Hypervisor level in -machine pc, accel=tcg Don Slutz
` (32 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/kvm.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 895d848..bf27793 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -389,12 +389,12 @@ int kvm_arch_init_vcpu(CPUX86State *env)
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
c->function = KVM_CPUID_SIGNATURE;
- if (!hyperv_enabled()) {
+ if (env->cpuid_hv_level == 0) {
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
c->eax = 0;
} else {
memcpy(signature, "Microsoft Hv", 12);
- c->eax = HYPERV_CPUID_MIN;
+ c->eax = env->cpuid_hv_level;
}
c->ebx = signature[0];
c->ecx = signature[1];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 07/17] target-i386: Use Hypervisor level in -machine pc, accel=tcg.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (17 preceding siblings ...)
2012-09-17 13:39 ` Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` Don Slutz
` (31 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization level.
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
QEMU knows this is KVM_CPUID_SIGNATURE (0x40000000).
This does not provide vendor support in tcg yet.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 4120393..d3b9bd8 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1651,6 +1651,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
index = env->cpuid_xlevel;
}
}
+ } else if (index & 0x40000000) {
+ if (env->cpuid_hv_level > 0) {
+ /* Handle Hypervisor CPUIDs */
+ if (index > env->cpuid_hv_level) {
+ index = env->cpuid_hv_level;
+ }
+ } else {
+ if (index > env->cpuid_level)
+ index = env->cpuid_level;
+ }
} else {
if (index > env->cpuid_level)
index = env->cpuid_level;
@@ -1789,6 +1799,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx = 0;
}
break;
+ case 0x40000000:
+ *eax = env->cpuid_hv_level;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 0x40000001:
+ *eax = env->cpuid_kvm_features;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 07/17] target-i386: Use Hypervisor level in -machine pc, accel=tcg.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (18 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 07/17] target-i386: Use Hypervisor level in -machine pc, accel=tcg Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 08/17] target-i386: Add Hypervisor vendor Don Slutz
` (30 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
This does not provide vendor support in tcg yet.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 4120393..d3b9bd8 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1651,6 +1651,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
index = env->cpuid_xlevel;
}
}
+ } else if (index & 0x40000000) {
+ if (env->cpuid_hv_level > 0) {
+ /* Handle Hypervisor CPUIDs */
+ if (index > env->cpuid_hv_level) {
+ index = env->cpuid_hv_level;
+ }
+ } else {
+ if (index > env->cpuid_level)
+ index = env->cpuid_level;
+ }
} else {
if (index > env->cpuid_level)
index = env->cpuid_level;
@@ -1789,6 +1799,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx = 0;
}
break;
+ case 0x40000000:
+ *eax = env->cpuid_hv_level;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 0x40000001:
+ *eax = env->cpuid_kvm_features;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 08/17] target-i386: Add Hypervisor vendor.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (19 preceding siblings ...)
2012-09-17 13:39 ` Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` Don Slutz
` (29 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization vendor.
This is EBX, ECX, EDX data for 0x40000000.
QEMU knows this is KVM_CPUID_SIGNATURE (0x40000000).
This is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.h | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 05c0848..53ba4cf 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -784,6 +784,9 @@ typedef struct CPUX86State {
uint32_t cpuid_7_0_ebx;
/* Hypervisor CPUIDs */
uint32_t cpuid_hv_level;
+ uint32_t cpuid_hv_vendor1;
+ uint32_t cpuid_hv_vendor2;
+ uint32_t cpuid_hv_vendor3;
/* MTRRs */
uint64_t mtrr_fixed[11];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 08/17] target-i386: Add Hypervisor vendor.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (20 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 08/17] target-i386: Add Hypervisor vendor Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 09/17] target-i386: Add cpu object access routines for " Don Slutz
` (28 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
This is EBX, ECX, EDX data.
This is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.h | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 05c0848..53ba4cf 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -784,6 +784,9 @@ typedef struct CPUX86State {
uint32_t cpuid_7_0_ebx;
/* Hypervisor CPUIDs */
uint32_t cpuid_hv_level;
+ uint32_t cpuid_hv_vendor1;
+ uint32_t cpuid_hv_vendor2;
+ uint32_t cpuid_hv_vendor3;
/* MTRRs */
uint64_t mtrr_fixed[11];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 09/17] target-i386: Add cpu object access routines for Hypervisor vendor.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (21 preceding siblings ...)
2012-09-17 13:39 ` Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 10/17] target-i386: Use Hypervisor vendor in -machine pc, accel=kvm Don Slutz
` (27 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
These are modeled after x86_cpuid_set_vendor and x86_cpuid_get_vendor.
Since kvm's vendor is shorter, the test for correct size is removed and zero padding is added.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index d3b9bd8..5afb188 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1191,12 +1191,53 @@ static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
cpu->env.cpuid_hv_level = value;
}
+static char *x86_cpuid_get_hv_vendor(Object *obj, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ char *value;
+ int i;
+
+ value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
+ for (i = 0; i < 4; i++) {
+ value[i + 0] = env->cpuid_hv_vendor1 >> (8 * i);
+ value[i + 4] = env->cpuid_hv_vendor2 >> (8 * i);
+ value[i + 8] = env->cpuid_hv_vendor3 >> (8 * i);
+ }
+ value[CPUID_VENDOR_SZ] = '\0';
+
+ return value;
+}
+
+static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
+ Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ int i;
+ char adj_value[CPUID_VENDOR_SZ + 1];
+
+ memset(adj_value, 0, sizeof(adj_value));
+
+ pstrcpy(adj_value, sizeof(adj_value), value);
+
+ env->cpuid_hv_vendor1 = 0;
+ env->cpuid_hv_vendor2 = 0;
+ env->cpuid_hv_vendor3 = 0;
+ for (i = 0; i < 4; i++) {
+ env->cpuid_hv_vendor1 |= ((uint8_t)adj_value[i + 0]) << (8 * i);
+ env->cpuid_hv_vendor2 |= ((uint8_t)adj_value[i + 4]) << (8 * i);
+ env->cpuid_hv_vendor3 |= ((uint8_t)adj_value[i + 8]) << (8 * i);
+ }
+}
+
#if !defined(CONFIG_USER_ONLY)
static void x86_set_hyperv(Object *obj, Error **errp)
{
X86CPU *cpu = X86_CPU(obj);
cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
+ x86_cpuid_set_hv_vendor(obj, "Microsoft Hv", errp);
}
static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
@@ -2121,6 +2162,9 @@ static void x86_cpu_initfn(Object *obj)
object_property_add(obj, "hypervisor-level", "int",
x86_cpuid_get_hv_level,
x86_cpuid_set_hv_level, NULL, NULL, NULL);
+ object_property_add_str(obj, "hypervisor-vendor",
+ x86_cpuid_get_hv_vendor,
+ x86_cpuid_set_hv_vendor, NULL);
#if !defined(CONFIG_USER_ONLY)
object_property_add(obj, "hv_spinlocks", "int",
x86_get_hv_spinlocks,
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 10/17] target-i386: Use Hypervisor vendor in -machine pc, accel=kvm.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (22 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 09/17] target-i386: Add cpu object access routines for " Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` Don Slutz
` (26 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization vendor.
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/kvm.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index bf27793..b8789f2 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -392,13 +392,15 @@ int kvm_arch_init_vcpu(CPUX86State *env)
if (env->cpuid_hv_level == 0) {
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
} else {
- memcpy(signature, "Microsoft Hv", 12);
c->eax = env->cpuid_hv_level;
+ c->ebx = env->cpuid_hv_vendor1;
+ c->ecx = env->cpuid_hv_vendor2;
+ c->edx = env->cpuid_hv_vendor3;
}
- c->ebx = signature[0];
- c->ecx = signature[1];
- c->edx = signature[2];
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 10/17] target-i386: Use Hypervisor vendor in -machine pc, accel=kvm.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (23 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 10/17] target-i386: Use Hypervisor vendor in -machine pc, accel=kvm Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 11/17] target-i386: Use Hypervisor vendor in -machine pc, accel=tcg Don Slutz
` (25 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/kvm.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index bf27793..b8789f2 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -392,13 +392,15 @@ int kvm_arch_init_vcpu(CPUX86State *env)
if (env->cpuid_hv_level == 0) {
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
} else {
- memcpy(signature, "Microsoft Hv", 12);
c->eax = env->cpuid_hv_level;
+ c->ebx = env->cpuid_hv_vendor1;
+ c->ecx = env->cpuid_hv_vendor2;
+ c->edx = env->cpuid_hv_vendor3;
}
- c->ebx = signature[0];
- c->ecx = signature[1];
- c->edx = signature[2];
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 11/17] target-i386: Use Hypervisor vendor in -machine pc, accel=tcg.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (24 preceding siblings ...)
2012-09-17 13:39 ` Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` Don Slutz
` (24 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization vendor.
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5afb188..1b3a472 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1842,9 +1842,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 0x40000000:
*eax = env->cpuid_hv_level;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
+ *ebx = env->cpuid_hv_vendor1;
+ *ecx = env->cpuid_hv_vendor2;
+ *edx = env->cpuid_hv_vendor3;
break;
case 0x40000001:
*eax = env->cpuid_kvm_features;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 11/17] target-i386: Use Hypervisor vendor in -machine pc, accel=tcg.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (25 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 11/17] target-i386: Use Hypervisor vendor in -machine pc, accel=tcg Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 12/17] target-i386: Add some known names to Hypervisor vendor Don Slutz
` (23 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5afb188..1b3a472 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1842,9 +1842,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 0x40000000:
*eax = env->cpuid_hv_level;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
+ *ebx = env->cpuid_hv_vendor1;
+ *ecx = env->cpuid_hv_vendor2;
+ *edx = env->cpuid_hv_vendor3;
break;
case 0x40000001:
*eax = env->cpuid_kvm_features;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 12/17] target-i386: Add some known names to Hypervisor vendor.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (26 preceding siblings ...)
2012-09-17 13:39 ` Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 13/17] target-i386: Add optional Hypervisor leaf extra Don Slutz
` (22 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 36 +++++++++++++++++++++++++++++++++++-
target-i386/cpu.h | 12 ++++++++++++
2 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 1b3a472..9ac3076 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1206,6 +1206,20 @@ static char *x86_cpuid_get_hv_vendor(Object *obj, Error **errp)
}
value[CPUID_VENDOR_SZ] = '\0';
+ /* Convert known names */
+ if (!strcmp(value, CPUID_HV_VENDOR_VMWARE)) {
+ if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) {
+ pstrcpy(value, sizeof(value), "vmware4");
+ } else if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_3) {
+ pstrcpy(value, sizeof(value), "vmware3");
+ }
+ } else if (!strcmp(value, CPUID_HV_VENDOR_XEN) &&
+ env->cpuid_hv_level == CPUID_HV_LEVEL_XEN) {
+ pstrcpy(value, sizeof(value), "xen");
+ } else if (!strcmp(value, CPUID_HV_VENDOR_KVM) &&
+ env->cpuid_hv_level == 0) {
+ pstrcpy(value, sizeof(value), "kvm");
+ }
return value;
}
@@ -1219,7 +1233,27 @@ static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
memset(adj_value, 0, sizeof(adj_value));
- pstrcpy(adj_value, sizeof(adj_value), value);
+ /* Convert known names */
+ if (!strcmp(value, "vmware") || !strcmp(value, "vmware4")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_4;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
+ } else if (!strcmp(value, "vmware3")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_3;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
+ } else if (!strcmp(value, "xen")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_XEN;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_XEN);
+ } else if (!strcmp(value, "kvm")) {
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_KVM);
+ } else {
+ pstrcpy(adj_value, sizeof(adj_value), value);
+ }
env->cpuid_hv_vendor1 = 0;
env->cpuid_hv_vendor2 = 0;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 53ba4cf..47bc00c 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -488,6 +488,18 @@
#define CPUID_VENDOR_VIA "CentaurHauls"
+#define CPUID_HV_VENDOR_VMWARE_1 0x61774d56 /* "VMwa" */
+#define CPUID_HV_VENDOR_VMWARE_2 0x4d566572 /* "reVM" */
+#define CPUID_HV_VENDOR_VMWARE_3 0x65726177 /* "ware" */
+#define CPUID_HV_VENDOR_VMWARE "VMwareVMware"
+#define CPUID_HV_LEVEL_VMARE_3 0x40000002
+#define CPUID_HV_LEVEL_VMARE_4 0x40000010
+
+#define CPUID_HV_VENDOR_XEN "XenVMMXenVMM"
+#define CPUID_HV_LEVEL_XEN 0x40000002
+
+#define CPUID_HV_VENDOR_KVM "KVMKVMKVM"
+
#define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
#define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 13/17] target-i386: Add optional Hypervisor leaf extra.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (27 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 12/17] target-i386: Add some known names to Hypervisor vendor Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 14/17] target-i386: Add cpu object access routines for " Don Slutz
` (21 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.h | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 47bc00c..a2d3588 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -799,6 +799,10 @@ typedef struct CPUX86State {
uint32_t cpuid_hv_vendor1;
uint32_t cpuid_hv_vendor2;
uint32_t cpuid_hv_vendor3;
+ /* VMware extra data */
+ uint32_t cpuid_hv_extra;
+ uint32_t cpuid_hv_extra_a;
+ uint32_t cpuid_hv_extra_b;
/* MTRRs */
uint64_t mtrr_fixed[11];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 14/17] target-i386: Add cpu object access routines for Hypervisor leaf extra.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (28 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 13/17] target-i386: Add optional Hypervisor leaf extra Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 15/17] target-i386: Add setting of Hypervisor leaf extra for known vmare4 Don Slutz
` (20 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9ac3076..34d2291 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1265,6 +1265,63 @@ static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
}
}
+static void x86_cpuid_get_hv_extra(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+
+ if ((value != 0) && (value < 0x40000000)) {
+ value += 0x40000000;
+ }
+ cpu->env.cpuid_hv_extra = value;
+}
+
+static void x86_cpuid_get_hv_extra_a(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra_a(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
+}
+
+static void x86_cpuid_get_hv_extra_b(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra_b(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
+}
+
#if !defined(CONFIG_USER_ONLY)
static void x86_set_hyperv(Object *obj, Error **errp)
{
@@ -2199,6 +2256,15 @@ static void x86_cpu_initfn(Object *obj)
object_property_add_str(obj, "hypervisor-vendor",
x86_cpuid_get_hv_vendor,
x86_cpuid_set_hv_vendor, NULL);
+ object_property_add(obj, "hypervisor-extra", "int",
+ x86_cpuid_get_hv_extra,
+ x86_cpuid_set_hv_extra, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-extra-a", "int",
+ x86_cpuid_get_hv_extra_a,
+ x86_cpuid_set_hv_extra_a, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-extra-b", "int",
+ x86_cpuid_get_hv_extra_b,
+ x86_cpuid_set_hv_extra_b, NULL, NULL, NULL);
#if !defined(CONFIG_USER_ONLY)
object_property_add(obj, "hv_spinlocks", "int",
x86_get_hv_spinlocks,
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 15/17] target-i386: Add setting of Hypervisor leaf extra for known vmare4.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (29 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 14/17] target-i386: Add cpu object access routines for " Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 16/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=kvm Don Slutz
` (19 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
This was taken from:
http://article.gmane.org/gmane.comp.emulators.kvm.devel/22643
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 34d2291..bfaee02 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1135,6 +1135,36 @@ static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
}
}
+static void x86_cpuid_set_vmware_extra(Object *obj)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ if ((cpu->env.tsc_khz != 0) &&
+ (cpu->env.cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) &&
+ (cpu->env.cpuid_hv_vendor1 == CPUID_HV_VENDOR_VMWARE_1) &&
+ (cpu->env.cpuid_hv_vendor2 == CPUID_HV_VENDOR_VMWARE_2) &&
+ (cpu->env.cpuid_hv_vendor3 == CPUID_HV_VENDOR_VMWARE_3)) {
+ const uint32_t apic_khz = 1000000L;
+
+ /*
+ * From article.gmane.org/gmane.comp.emulators.kvm.devel/22643
+ *
+ * Leaf 0x40000010, Timing Information.
+ *
+ * VMware has defined the first generic leaf to provide timing
+ * information. This leaf returns the current TSC frequency and
+ * current Bus frequency in kHz.
+ *
+ * # EAX: (Virtual) TSC frequency in kHz.
+ * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
+ * # ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
+ */
+ cpu->env.cpuid_hv_extra = 0x40000010;
+ cpu->env.cpuid_hv_extra_a = (uint32_t)cpu->env.tsc_khz;
+ cpu->env.cpuid_hv_extra_b = apic_khz;
+ }
+}
+
static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
@@ -1164,6 +1194,7 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
}
cpu->env.tsc_khz = value / 1000;
+ x86_cpuid_set_vmware_extra(obj);
}
static void x86_cpuid_get_hv_level(Object *obj, Visitor *v, void *opaque,
@@ -1263,6 +1294,7 @@ static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
env->cpuid_hv_vendor2 |= ((uint8_t)adj_value[i + 4]) << (8 * i);
env->cpuid_hv_vendor3 |= ((uint8_t)adj_value[i + 8]) << (8 * i);
}
+ x86_cpuid_set_vmware_extra(obj);
}
static void x86_cpuid_get_hv_extra(Object *obj, Visitor *v, void *opaque,
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 16/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=kvm.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (30 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 15/17] target-i386: Add setting of Hypervisor leaf extra for known vmare4 Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 17/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=tcg Don Slutz
` (18 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/kvm.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index b8789f2..17c72bc 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -454,6 +454,25 @@ int kvm_arch_init_vcpu(CPUX86State *env)
c->ebx = signature[0];
c->ecx = signature[1];
c->edx = signature[2];
+ } else if (env->cpuid_hv_level > 0) {
+ for (i = KVM_CPUID_FEATURES + 1; i <= env->cpuid_hv_level; i++) {
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = i;
+ if (i == env->cpuid_hv_extra) {
+ c->eax = env->cpuid_hv_extra_a;
+ c->ebx = env->cpuid_hv_extra_b;
+ }
+ }
+
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_SIGNATURE_NEXT;
+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
+ c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
}
has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 17/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=tcg.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (31 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 16/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=kvm Don Slutz
@ 2012-09-17 13:39 ` Don Slutz
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs Don Slutz
` (17 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 13:39 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index bfaee02..89a45b5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1975,6 +1975,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ecx = 0;
*edx = 0;
break;
+ case 0x40000002 ... 0x400000FF:
+ if (index == env->cpuid_hv_extra) {
+ *eax = env->cpuid_hv_extra_a;
+ *ebx = env->cpuid_hv_extra_b;
+ } else {
+ *eax = 0;
+ *ebx = 0;
+ }
+ *ecx = 0;
+ *edx = 0;
+ break;
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (32 preceding siblings ...)
2012-09-17 13:39 ` [Qemu-devel] [PATCH v3 17/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=tcg Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 19:27 ` Eduardo Habkost
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 01/17] target-i386: Allow tsc-frequency to be larger then 2.147G Don Slutz
` (16 subsequent siblings)
50 siblings, 1 reply; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Resend with new id so the backup files are not included.
Also known as Paravirtualization CPUIDs.
This is primarily done so that the guest will think it is running
under vmware when hypervisor-vendor=vmware is specified as a
property of a cpu.
This depends on:
http://lists.gnu.org/archive/html/qemu-devel/2012-09/msg01400.html
As far as I know it is #4. It depends on (1) and (2) and (3).
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Changes from v1 to v2:
1) Added 1/4 from http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg05153.html
Because Fred is changing jobs and so will not be pushing to get
this in. It needed to be rebased, And I needed it to complete the
testing of this change.
2) Added 2/4 because of the re-work I needed a way to clear all KVM bits,
3) The rework of v1. Make it fit into the object model re-work of cpu.c for x86.
4) Added 3/4 -- The split out of the code that is not needed for accel=kvm.
Changes from v2 to v3:
Marcelo Tosatti:
Its one big patch, better split in logically correlated patches
(with better changelog). This would help reviewers.
So split 3 and 4 into 3 to 17. More info in change log.
No code change.
Don Slutz (17):
target-i386: Allow tsc-frequency to be larger then 2.147G
target-i386: Add missing kvm bits.
target-i386: Add Hypervisor level.
target-i386: Add cpu object access routines for Hypervisor level.
target-i386: Add x86_set_hyperv.
target-i386: Use Hypervisor level in -machine pc,accel=kvm.
target-i386: Use Hypervisor level in -machine pc,accel=tcg.
target-i386: Add Hypervisor vendor.
target-i386: Add cpu object access routines for Hypervisor vendor.
target-i386: Use Hypervisor vendor in -machine pc,accel=kvm.
target-i386: Use Hypervisor vendor in -machine pc,accel=tcg.
target-i386: Add some known names to Hypervisor vendor.
target-i386: Add optional Hypervisor leaf extra.
target-i386: Add cpu object access routines for Hypervisor leaf
extra.
target-i386: Add setting of Hypervisor leaf extra for known vmare4.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=kvm.
target-i386: Use Hypervisor leaf extra in -machine pc,accel=tcg.
target-i386/cpu.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
target-i386/cpu.h | 21 +++++
target-i386/kvm.c | 33 ++++++--
3 files changed, 304 insertions(+), 11 deletions(-)
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs.
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs Don Slutz
@ 2012-09-17 19:27 ` Eduardo Habkost
0 siblings, 0 replies; 65+ messages in thread
From: Eduardo Habkost @ 2012-09-17 19:27 UTC (permalink / raw)
To: Don Slutz
Cc: peter.maydell, kvm, mtosatti, qemu-devel, avi, anthony, imammedo,
afaerber
On Mon, Sep 17, 2012 at 10:00:50AM -0400, Don Slutz wrote:
> Resend with new id so the backup files are not included.
>
> Also known as Paravirtualization CPUIDs.
>
> This is primarily done so that the guest will think it is running
> under vmware when hypervisor-vendor=vmware is specified as a
> property of a cpu.
>
>
> This depends on:
>
> http://lists.gnu.org/archive/html/qemu-devel/2012-09/msg01400.html
>
> As far as I know it is #4. It depends on (1) and (2) and (3).
Correct.
I have removed v2 and added this version to my cpu-queue[1] branch.
[1] https://github.com/ehabkost/qemu/commits/cpu-queue
My branch is now based on Andreas's qom-cpu branch from
https://github.com/afaerber/qemu-cpu/commits/qom-cpu
>
> This change is based on:
>
> Microsoft Hypervisor CPUID Leaves:
> http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
>
> Linux kernel change starts with:
> http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
> Also:
> http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
>
> VMware documention on CPUIDs (Mechanisms to determine if software is
> running in a VMware virtual machine):
> http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
>
> Changes from v1 to v2:
>
> 1) Added 1/4 from http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg05153.html
>
> Because Fred is changing jobs and so will not be pushing to get
> this in. It needed to be rebased, And I needed it to complete the
> testing of this change.
>
> 2) Added 2/4 because of the re-work I needed a way to clear all KVM bits,
>
> 3) The rework of v1. Make it fit into the object model re-work of cpu.c for x86.
>
> 4) Added 3/4 -- The split out of the code that is not needed for accel=kvm.
>
> Changes from v2 to v3:
>
> Marcelo Tosatti:
> Its one big patch, better split in logically correlated patches
> (with better changelog). This would help reviewers.
>
> So split 3 and 4 into 3 to 17. More info in change log.
> No code change.
>
> Don Slutz (17):
> target-i386: Allow tsc-frequency to be larger then 2.147G
> target-i386: Add missing kvm bits.
> target-i386: Add Hypervisor level.
> target-i386: Add cpu object access routines for Hypervisor level.
> target-i386: Add x86_set_hyperv.
> target-i386: Use Hypervisor level in -machine pc,accel=kvm.
> target-i386: Use Hypervisor level in -machine pc,accel=tcg.
> target-i386: Add Hypervisor vendor.
> target-i386: Add cpu object access routines for Hypervisor vendor.
> target-i386: Use Hypervisor vendor in -machine pc,accel=kvm.
> target-i386: Use Hypervisor vendor in -machine pc,accel=tcg.
> target-i386: Add some known names to Hypervisor vendor.
> target-i386: Add optional Hypervisor leaf extra.
> target-i386: Add cpu object access routines for Hypervisor leaf
> extra.
> target-i386: Add setting of Hypervisor leaf extra for known vmare4.
> target-i386: Use Hypervisor leaf extra in -machine pc,accel=kvm.
> target-i386: Use Hypervisor leaf extra in -machine pc,accel=tcg.
>
> target-i386/cpu.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> target-i386/cpu.h | 21 +++++
> target-i386/kvm.c | 33 ++++++--
> 3 files changed, 304 insertions(+), 11 deletions(-)
>
>
--
Eduardo
^ permalink raw reply [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 01/17] target-i386: Allow tsc-frequency to be larger then 2.147G
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (33 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 00/17] Allow changing of Hypervisor CPUIDs Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 02/17] target-i386: Add missing kvm bits Don Slutz
` (15 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz, Fred Oliveira
The check using INT_MAX (2147483647) is wrong in this case.
Signed-off-by: Fred Oliveira <foliveira@cloudswitch.com>
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index af50a8f..0313cf5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1146,7 +1146,7 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
{
X86CPU *cpu = X86_CPU(obj);
const int64_t min = 0;
- const int64_t max = INT_MAX;
+ const int64_t max = INT64_MAX;
int64_t value;
visit_type_freq(v, &value, name, errp);
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 02/17] target-i386: Add missing kvm bits.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (34 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 01/17] target-i386: Allow tsc-frequency to be larger then 2.147G Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 03/17] target-i386: Add Hypervisor level Don Slutz
` (14 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Fix duplicate name (kvmclock => kvm_clock2) also.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 0313cf5..5f9866a 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -87,10 +87,14 @@ static const char *ext3_feature_name[] = {
};
static const char *kvm_feature_name[] = {
- "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, "kvm_pv_eoi", NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvm_clock2",
+ "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ "kvm_clock_stable", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
};
static const char *svm_feature_name[] = {
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 03/17] target-i386: Add Hypervisor level.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (35 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 02/17] target-i386: Add missing kvm bits Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 04/17] target-i386: Add cpu object access routines for " Don Slutz
` (13 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization level or maximim cpuid function present in this leaf.
This is just the EAX value for 0x40000000.
QEMU knows this is KVM_CPUID_SIGNATURE (0x40000000).
This is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
QEMU has the value HYPERV_CPUID_MIN defined.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5265c5a..05c0848 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -782,6 +782,8 @@ typedef struct CPUX86State {
uint32_t cpuid_ext4_features;
/* Flags from CPUID[EAX=7,ECX=0].EBX */
uint32_t cpuid_7_0_ebx;
+ /* Hypervisor CPUIDs */
+ uint32_t cpuid_hv_level;
/* MTRRs */
uint64_t mtrr_fixed[11];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 04/17] target-i386: Add cpu object access routines for Hypervisor level.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (36 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 03/17] target-i386: Add Hypervisor level Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv Don Slutz
` (12 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
These are modeled after x86_cpuid_get_xlevel and x86_cpuid_set_xlevel.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5f9866a..0e4a18d 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1166,6 +1166,31 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
cpu->env.tsc_khz = value / 1000;
}
+static void x86_cpuid_get_hv_level(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_level, name, errp);
+}
+
+static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+
+ if ((value != 0) && (value < 0x40000000)) {
+ value += 0x40000000;
+ }
+ cpu->env.cpuid_hv_level = value;
+}
+
#if !defined(CONFIG_USER_ONLY)
static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
@@ -2061,6 +2086,9 @@ static void x86_cpu_initfn(Object *obj)
object_property_add(obj, "enforce", "bool",
x86_cpuid_get_enforce,
x86_cpuid_set_enforce, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-level", "int",
+ x86_cpuid_get_hv_level,
+ x86_cpuid_set_hv_level, NULL, NULL, NULL);
#if !defined(CONFIG_USER_ONLY)
object_property_add(obj, "hv_spinlocks", "int",
x86_get_hv_spinlocks,
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (37 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 04/17] target-i386: Add cpu object access routines for " Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-19 19:32 ` Eduardo Habkost
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 06/17] target-i386: Use Hypervisor level in -machine pc, accel=kvm Don Slutz
` (11 subsequent siblings)
50 siblings, 1 reply; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
This is used to set the cpu object's hypervisor level to the default for Microsoft's Hypervisor.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 0e4a18d..4120393 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1192,6 +1192,13 @@ static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
}
#if !defined(CONFIG_USER_ONLY)
+static void x86_set_hyperv(Object *obj, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
+}
+
static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
@@ -1214,6 +1221,7 @@ static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_set_spinlock_retries(value);
+ x86_set_hyperv(obj, errp);
}
static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
@@ -1234,6 +1242,7 @@ static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_enable_relaxed_timing(value);
+ x86_set_hyperv(obj, errp);
}
static void x86_get_hv_vapic(Object *obj, Visitor *v, void *opaque,
@@ -1254,6 +1263,7 @@ static void x86_set_hv_vapic(Object *obj, Visitor *v, void *opaque,
return;
}
hyperv_enable_vapic_recommended(value);
+ x86_set_hyperv(obj, errp);
}
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv.
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv Don Slutz
@ 2012-09-19 19:32 ` Eduardo Habkost
2012-09-19 21:26 ` Don Slutz
0 siblings, 1 reply; 65+ messages in thread
From: Eduardo Habkost @ 2012-09-19 19:32 UTC (permalink / raw)
To: Don Slutz
Cc: peter.maydell, kvm, mtosatti, qemu-devel, avi, anthony, imammedo,
afaerber
On Mon, Sep 17, 2012 at 10:00:55AM -0400, Don Slutz wrote:
> This is used to set the cpu object's hypervisor level to the default for Microsoft's Hypervisor.
>
> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> ---
> target-i386/cpu.c | 10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 0e4a18d..4120393 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -1192,6 +1192,13 @@ static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
> }
>
> #if !defined(CONFIG_USER_ONLY)
> +static void x86_set_hyperv(Object *obj, Error **errp)
> +{
> + X86CPU *cpu = X86_CPU(obj);
> +
> + cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
HYPERV_CPUID_MIN is defined on linux-headers/asm-x86/hyperv.h, that is
included only if build host is linux-x86 and CONFIG_KVM is set.
> +}
> +
> static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
> const char *name, Error **errp)
> {
> @@ -1214,6 +1221,7 @@ static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
> return;
> }
> hyperv_set_spinlock_retries(value);
> + x86_set_hyperv(obj, errp);
> }
>
> static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
> @@ -1234,6 +1242,7 @@ static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
> return;
> }
> hyperv_enable_relaxed_timing(value);
> + x86_set_hyperv(obj, errp);
> }
>
> static void x86_get_hv_vapic(Object *obj, Visitor *v, void *opaque,
> @@ -1254,6 +1263,7 @@ static void x86_set_hv_vapic(Object *obj, Visitor *v, void *opaque,
> return;
> }
> hyperv_enable_vapic_recommended(value);
> + x86_set_hyperv(obj, errp);
> }
> #endif
>
> --
> 1.7.1
>
>
--
Eduardo
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv.
2012-09-19 19:32 ` Eduardo Habkost
@ 2012-09-19 21:26 ` Don Slutz
2012-09-20 16:20 ` Eduardo Habkost
0 siblings, 1 reply; 65+ messages in thread
From: Don Slutz @ 2012-09-19 21:26 UTC (permalink / raw)
To: Eduardo Habkost
Cc: peter.maydell, kvm, mtosatti, qemu-devel, avi, anthony, imammedo,
afaerber
On 09/19/12 15:32, Eduardo Habkost wrote:
> On Mon, Sep 17, 2012 at 10:00:55AM -0400, Don Slutz wrote:
>> This is used to set the cpu object's hypervisor level to the default for Microsoft's Hypervisor.
>>
>> Signed-off-by: Don Slutz <Don@CloudSwitch.com>
>> ---
>> target-i386/cpu.c | 10 ++++++++++
>> 1 files changed, 10 insertions(+), 0 deletions(-)
>>
>> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
>> index 0e4a18d..4120393 100644
>> --- a/target-i386/cpu.c
>> +++ b/target-i386/cpu.c
>> @@ -1192,6 +1192,13 @@ static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
>> }
>>
>> #if !defined(CONFIG_USER_ONLY)
>> +static void x86_set_hyperv(Object *obj, Error **errp)
>> +{
>> + X86CPU *cpu = X86_CPU(obj);
>> +
>> + cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
> HYPERV_CPUID_MIN is defined on linux-headers/asm-x86/hyperv.h, that is
> included only if build host is linux-x86 and CONFIG_KVM is set.
>
Will fix. I see 3 options:
1) Use the numbers like 0x40000005
2) Use QEMU defines like:
#define CPUID_HV_LEVEL_HYPERV 0x40000005
3) Use condtional define:
#ifndef HYPERV_CPUID_MIN
#define CPUID_HV_LEVEL_HYPERV 0x40000005
#else
#define CPUID_HV_LEVEL_HYPERV HYPERV_CPUID_MIN
#endif
I lean to #2 of #3 and both over #1. This is because if in the future
if HYPERV_CPUID_MIN ever changes then a patch to QEMU needs to be done
and considered before that change can be seen by a guest. Note: since
hypervisor-level=0x40000006 can be specified, this might be enough to do
some testing.
Please advise.
>> +}
>> +
>> static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
>> const char *name, Error **errp)
>> {
>> @@ -1214,6 +1221,7 @@ static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
>> return;
>> }
>> hyperv_set_spinlock_retries(value);
>> + x86_set_hyperv(obj, errp);
>> }
>>
>> static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
>> @@ -1234,6 +1242,7 @@ static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
>> return;
>> }
>> hyperv_enable_relaxed_timing(value);
>> + x86_set_hyperv(obj, errp);
>> }
>>
>> static void x86_get_hv_vapic(Object *obj, Visitor *v, void *opaque,
>> @@ -1254,6 +1263,7 @@ static void x86_set_hv_vapic(Object *obj, Visitor *v, void *opaque,
>> return;
>> }
>> hyperv_enable_vapic_recommended(value);
>> + x86_set_hyperv(obj, errp);
>> }
>> #endif
>>
>> --
>> 1.7.1
>>
>>
-Don Slutz
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv.
2012-09-19 21:26 ` Don Slutz
@ 2012-09-20 16:20 ` Eduardo Habkost
0 siblings, 0 replies; 65+ messages in thread
From: Eduardo Habkost @ 2012-09-20 16:20 UTC (permalink / raw)
To: Don Slutz
Cc: peter.maydell, kvm, mtosatti, qemu-devel, avi, anthony, imammedo,
afaerber
On Wed, Sep 19, 2012 at 05:26:01PM -0400, Don Slutz wrote:
> On 09/19/12 15:32, Eduardo Habkost wrote:
> >On Mon, Sep 17, 2012 at 10:00:55AM -0400, Don Slutz wrote:
> >>This is used to set the cpu object's hypervisor level to the default for Microsoft's Hypervisor.
> >>
> >>Signed-off-by: Don Slutz <Don@CloudSwitch.com>
> >>---
> >> target-i386/cpu.c | 10 ++++++++++
> >> 1 files changed, 10 insertions(+), 0 deletions(-)
> >>
> >>diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> >>index 0e4a18d..4120393 100644
> >>--- a/target-i386/cpu.c
> >>+++ b/target-i386/cpu.c
> >>@@ -1192,6 +1192,13 @@ static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
> >> }
> >>
> >> #if !defined(CONFIG_USER_ONLY)
> >>+static void x86_set_hyperv(Object *obj, Error **errp)
> >>+{
> >>+ X86CPU *cpu = X86_CPU(obj);
> >>+
> >>+ cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
> >HYPERV_CPUID_MIN is defined on linux-headers/asm-x86/hyperv.h, that is
> >included only if build host is linux-x86 and CONFIG_KVM is set.
> >
> Will fix. I see 3 options:
>
> 1) Use the numbers like 0x40000005
If we're going to use the number directly, it's better to have a define
for it (so #2 is better).
>
> 2) Use QEMU defines like:
> #define CPUID_HV_LEVEL_HYPERV 0x40000005
>
> 3) Use condtional define:
> #ifndef HYPERV_CPUID_MIN
> #define CPUID_HV_LEVEL_HYPERV 0x40000005
> #else
> #define CPUID_HV_LEVEL_HYPERV HYPERV_CPUID_MIN
> #endif
>
If QEMU is going to contain a "#define CPUID_HV_LEVEL_HYPERV 0x40000005"
in the code, I don't see a reason to try to use the definition from
asm-x86/hyperv.h if available.
So, #2 looks like the best option.
> I lean to #2 of #3 and both over #1. This is because if in the
> future if HYPERV_CPUID_MIN ever changes then a patch to QEMU needs to
> be done and considered before that change can be seen by a guest.
> Note: since hypervisor-level=0x40000006 can be specified, this might
> be enough to do some testing.
I don't think HYPERV_CPUID_MIN will ever change, but the meaning of the
constant is not clear to me. Anyway, if it ever changes, that's another
reason for QEMU to have its own constant. The resulting CPUID bits
exposed to the guest should be a function of the machine-type and
command-line/config parameters, and nothing else (otherwise the CPUID
bits would change under the guest's feet when live-migrating).
--
Eduardo
^ permalink raw reply [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 06/17] target-i386: Use Hypervisor level in -machine pc, accel=kvm.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (38 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 05/17] target-i386: Add x86_set_hyperv Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 07/17] target-i386: Use Hypervisor level in -machine pc, accel=tcg Don Slutz
` (10 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization level.
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
QEMU knows this is KVM_CPUID_SIGNATURE (0x40000000).
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/kvm.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 895d848..bf27793 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -389,12 +389,12 @@ int kvm_arch_init_vcpu(CPUX86State *env)
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
c->function = KVM_CPUID_SIGNATURE;
- if (!hyperv_enabled()) {
+ if (env->cpuid_hv_level == 0) {
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
c->eax = 0;
} else {
memcpy(signature, "Microsoft Hv", 12);
- c->eax = HYPERV_CPUID_MIN;
+ c->eax = env->cpuid_hv_level;
}
c->ebx = signature[0];
c->ecx = signature[1];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 07/17] target-i386: Use Hypervisor level in -machine pc, accel=tcg.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (39 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 06/17] target-i386: Use Hypervisor level in -machine pc, accel=kvm Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 08/17] target-i386: Add Hypervisor vendor Don Slutz
` (9 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization level.
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
QEMU knows this is KVM_CPUID_SIGNATURE (0x40000000).
This does not provide vendor support in tcg yet.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 4120393..d3b9bd8 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1651,6 +1651,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
index = env->cpuid_xlevel;
}
}
+ } else if (index & 0x40000000) {
+ if (env->cpuid_hv_level > 0) {
+ /* Handle Hypervisor CPUIDs */
+ if (index > env->cpuid_hv_level) {
+ index = env->cpuid_hv_level;
+ }
+ } else {
+ if (index > env->cpuid_level)
+ index = env->cpuid_level;
+ }
} else {
if (index > env->cpuid_level)
index = env->cpuid_level;
@@ -1789,6 +1799,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx = 0;
}
break;
+ case 0x40000000:
+ *eax = env->cpuid_hv_level;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 0x40000001:
+ *eax = env->cpuid_kvm_features;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 08/17] target-i386: Add Hypervisor vendor.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (40 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 07/17] target-i386: Use Hypervisor level in -machine pc, accel=tcg Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 09/17] target-i386: Add cpu object access routines for " Don Slutz
` (8 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization vendor.
This is EBX, ECX, EDX data for 0x40000000.
QEMU knows this is KVM_CPUID_SIGNATURE (0x40000000).
This is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.h | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 05c0848..53ba4cf 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -784,6 +784,9 @@ typedef struct CPUX86State {
uint32_t cpuid_7_0_ebx;
/* Hypervisor CPUIDs */
uint32_t cpuid_hv_level;
+ uint32_t cpuid_hv_vendor1;
+ uint32_t cpuid_hv_vendor2;
+ uint32_t cpuid_hv_vendor3;
/* MTRRs */
uint64_t mtrr_fixed[11];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 09/17] target-i386: Add cpu object access routines for Hypervisor vendor.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (41 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 08/17] target-i386: Add Hypervisor vendor Don Slutz
@ 2012-09-17 14:00 ` Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 10/17] target-i386: Use Hypervisor vendor in -machine pc, accel=kvm Don Slutz
` (7 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:00 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
These are modeled after x86_cpuid_set_vendor and x86_cpuid_get_vendor.
Since kvm's vendor is shorter, the test for correct size is removed and zero padding is added.
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index d3b9bd8..5afb188 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1191,12 +1191,53 @@ static void x86_cpuid_set_hv_level(Object *obj, Visitor *v, void *opaque,
cpu->env.cpuid_hv_level = value;
}
+static char *x86_cpuid_get_hv_vendor(Object *obj, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ char *value;
+ int i;
+
+ value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
+ for (i = 0; i < 4; i++) {
+ value[i + 0] = env->cpuid_hv_vendor1 >> (8 * i);
+ value[i + 4] = env->cpuid_hv_vendor2 >> (8 * i);
+ value[i + 8] = env->cpuid_hv_vendor3 >> (8 * i);
+ }
+ value[CPUID_VENDOR_SZ] = '\0';
+
+ return value;
+}
+
+static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
+ Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ CPUX86State *env = &cpu->env;
+ int i;
+ char adj_value[CPUID_VENDOR_SZ + 1];
+
+ memset(adj_value, 0, sizeof(adj_value));
+
+ pstrcpy(adj_value, sizeof(adj_value), value);
+
+ env->cpuid_hv_vendor1 = 0;
+ env->cpuid_hv_vendor2 = 0;
+ env->cpuid_hv_vendor3 = 0;
+ for (i = 0; i < 4; i++) {
+ env->cpuid_hv_vendor1 |= ((uint8_t)adj_value[i + 0]) << (8 * i);
+ env->cpuid_hv_vendor2 |= ((uint8_t)adj_value[i + 4]) << (8 * i);
+ env->cpuid_hv_vendor3 |= ((uint8_t)adj_value[i + 8]) << (8 * i);
+ }
+}
+
#if !defined(CONFIG_USER_ONLY)
static void x86_set_hyperv(Object *obj, Error **errp)
{
X86CPU *cpu = X86_CPU(obj);
cpu->env.cpuid_hv_level = HYPERV_CPUID_MIN;
+ x86_cpuid_set_hv_vendor(obj, "Microsoft Hv", errp);
}
static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
@@ -2121,6 +2162,9 @@ static void x86_cpu_initfn(Object *obj)
object_property_add(obj, "hypervisor-level", "int",
x86_cpuid_get_hv_level,
x86_cpuid_set_hv_level, NULL, NULL, NULL);
+ object_property_add_str(obj, "hypervisor-vendor",
+ x86_cpuid_get_hv_vendor,
+ x86_cpuid_set_hv_vendor, NULL);
#if !defined(CONFIG_USER_ONLY)
object_property_add(obj, "hv_spinlocks", "int",
x86_get_hv_spinlocks,
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 10/17] target-i386: Use Hypervisor vendor in -machine pc, accel=kvm.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (42 preceding siblings ...)
2012-09-17 14:00 ` [Qemu-devel] [PATCH v3 09/17] target-i386: Add cpu object access routines for " Don Slutz
@ 2012-09-17 14:01 ` Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 11/17] target-i386: Use Hypervisor vendor in -machine pc, accel=tcg Don Slutz
` (6 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:01 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization vendor.
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/kvm.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index bf27793..b8789f2 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -392,13 +392,15 @@ int kvm_arch_init_vcpu(CPUX86State *env)
if (env->cpuid_hv_level == 0) {
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
} else {
- memcpy(signature, "Microsoft Hv", 12);
c->eax = env->cpuid_hv_level;
+ c->ebx = env->cpuid_hv_vendor1;
+ c->ecx = env->cpuid_hv_vendor2;
+ c->edx = env->cpuid_hv_vendor3;
}
- c->ebx = signature[0];
- c->ecx = signature[1];
- c->edx = signature[2];
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 11/17] target-i386: Use Hypervisor vendor in -machine pc, accel=tcg.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (43 preceding siblings ...)
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 10/17] target-i386: Use Hypervisor vendor in -machine pc, accel=kvm Don Slutz
@ 2012-09-17 14:01 ` Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 12/17] target-i386: Add some known names to Hypervisor vendor Don Slutz
` (5 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:01 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Also known as Paravirtualization vendor.
This change is based on:
Microsoft Hypervisor CPUID Leaves:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542428%28v=vs.85%29.aspx
Linux kernel change starts with:
http://fixunix.com/kernel/538707-use-cpuid-communicate-hypervisor.html
Also:
http://lkml.indiana.edu/hypermail/linux/kernel/1205.0/00100.html
VMware documention on CPUIDs (Mechanisms to determine if software is
running in a VMware virtual machine):
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5afb188..1b3a472 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1842,9 +1842,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 0x40000000:
*eax = env->cpuid_hv_level;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
+ *ebx = env->cpuid_hv_vendor1;
+ *ecx = env->cpuid_hv_vendor2;
+ *edx = env->cpuid_hv_vendor3;
break;
case 0x40000001:
*eax = env->cpuid_kvm_features;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 12/17] target-i386: Add some known names to Hypervisor vendor.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (44 preceding siblings ...)
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 11/17] target-i386: Use Hypervisor vendor in -machine pc, accel=tcg Don Slutz
@ 2012-09-17 14:01 ` Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 13/17] target-i386: Add optional Hypervisor leaf extra Don Slutz
` (4 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:01 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 36 +++++++++++++++++++++++++++++++++++-
target-i386/cpu.h | 12 ++++++++++++
2 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 1b3a472..9ac3076 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1206,6 +1206,20 @@ static char *x86_cpuid_get_hv_vendor(Object *obj, Error **errp)
}
value[CPUID_VENDOR_SZ] = '\0';
+ /* Convert known names */
+ if (!strcmp(value, CPUID_HV_VENDOR_VMWARE)) {
+ if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) {
+ pstrcpy(value, sizeof(value), "vmware4");
+ } else if (env->cpuid_hv_level == CPUID_HV_LEVEL_VMARE_3) {
+ pstrcpy(value, sizeof(value), "vmware3");
+ }
+ } else if (!strcmp(value, CPUID_HV_VENDOR_XEN) &&
+ env->cpuid_hv_level == CPUID_HV_LEVEL_XEN) {
+ pstrcpy(value, sizeof(value), "xen");
+ } else if (!strcmp(value, CPUID_HV_VENDOR_KVM) &&
+ env->cpuid_hv_level == 0) {
+ pstrcpy(value, sizeof(value), "kvm");
+ }
return value;
}
@@ -1219,7 +1233,27 @@ static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
memset(adj_value, 0, sizeof(adj_value));
- pstrcpy(adj_value, sizeof(adj_value), value);
+ /* Convert known names */
+ if (!strcmp(value, "vmware") || !strcmp(value, "vmware4")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_4;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
+ } else if (!strcmp(value, "vmware3")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_VMARE_3;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_VMWARE);
+ } else if (!strcmp(value, "xen")) {
+ if (env->cpuid_hv_level == 0) {
+ env->cpuid_hv_level = CPUID_HV_LEVEL_XEN;
+ }
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_XEN);
+ } else if (!strcmp(value, "kvm")) {
+ pstrcpy(adj_value, sizeof(adj_value), CPUID_HV_VENDOR_KVM);
+ } else {
+ pstrcpy(adj_value, sizeof(adj_value), value);
+ }
env->cpuid_hv_vendor1 = 0;
env->cpuid_hv_vendor2 = 0;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 53ba4cf..47bc00c 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -488,6 +488,18 @@
#define CPUID_VENDOR_VIA "CentaurHauls"
+#define CPUID_HV_VENDOR_VMWARE_1 0x61774d56 /* "VMwa" */
+#define CPUID_HV_VENDOR_VMWARE_2 0x4d566572 /* "reVM" */
+#define CPUID_HV_VENDOR_VMWARE_3 0x65726177 /* "ware" */
+#define CPUID_HV_VENDOR_VMWARE "VMwareVMware"
+#define CPUID_HV_LEVEL_VMARE_3 0x40000002
+#define CPUID_HV_LEVEL_VMARE_4 0x40000010
+
+#define CPUID_HV_VENDOR_XEN "XenVMMXenVMM"
+#define CPUID_HV_LEVEL_XEN 0x40000002
+
+#define CPUID_HV_VENDOR_KVM "KVMKVMKVM"
+
#define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
#define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 13/17] target-i386: Add optional Hypervisor leaf extra.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (45 preceding siblings ...)
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 12/17] target-i386: Add some known names to Hypervisor vendor Don Slutz
@ 2012-09-17 14:01 ` Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 14/17] target-i386: Add cpu object access routines for " Don Slutz
` (3 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:01 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.h | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 47bc00c..a2d3588 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -799,6 +799,10 @@ typedef struct CPUX86State {
uint32_t cpuid_hv_vendor1;
uint32_t cpuid_hv_vendor2;
uint32_t cpuid_hv_vendor3;
+ /* VMware extra data */
+ uint32_t cpuid_hv_extra;
+ uint32_t cpuid_hv_extra_a;
+ uint32_t cpuid_hv_extra_b;
/* MTRRs */
uint64_t mtrr_fixed[11];
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 14/17] target-i386: Add cpu object access routines for Hypervisor leaf extra.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (46 preceding siblings ...)
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 13/17] target-i386: Add optional Hypervisor leaf extra Don Slutz
@ 2012-09-17 14:01 ` Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 15/17] target-i386: Add setting of Hypervisor leaf extra for known vmare4 Don Slutz
` (2 subsequent siblings)
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:01 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9ac3076..34d2291 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1265,6 +1265,63 @@ static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
}
}
+static void x86_cpuid_get_hv_extra(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, &value, name, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+
+ if ((value != 0) && (value < 0x40000000)) {
+ value += 0x40000000;
+ }
+ cpu->env.cpuid_hv_extra = value;
+}
+
+static void x86_cpuid_get_hv_extra_a(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra_a(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_a, name, errp);
+}
+
+static void x86_cpuid_get_hv_extra_b(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
+}
+
+static void x86_cpuid_set_hv_extra_b(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ visit_type_uint32(v, &cpu->env.cpuid_hv_extra_b, name, errp);
+}
+
#if !defined(CONFIG_USER_ONLY)
static void x86_set_hyperv(Object *obj, Error **errp)
{
@@ -2199,6 +2256,15 @@ static void x86_cpu_initfn(Object *obj)
object_property_add_str(obj, "hypervisor-vendor",
x86_cpuid_get_hv_vendor,
x86_cpuid_set_hv_vendor, NULL);
+ object_property_add(obj, "hypervisor-extra", "int",
+ x86_cpuid_get_hv_extra,
+ x86_cpuid_set_hv_extra, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-extra-a", "int",
+ x86_cpuid_get_hv_extra_a,
+ x86_cpuid_set_hv_extra_a, NULL, NULL, NULL);
+ object_property_add(obj, "hypervisor-extra-b", "int",
+ x86_cpuid_get_hv_extra_b,
+ x86_cpuid_set_hv_extra_b, NULL, NULL, NULL);
#if !defined(CONFIG_USER_ONLY)
object_property_add(obj, "hv_spinlocks", "int",
x86_get_hv_spinlocks,
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 15/17] target-i386: Add setting of Hypervisor leaf extra for known vmare4.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (47 preceding siblings ...)
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 14/17] target-i386: Add cpu object access routines for " Don Slutz
@ 2012-09-17 14:01 ` Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 16/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=kvm Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 17/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=tcg Don Slutz
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:01 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
This was taken from:
http://article.gmane.org/gmane.comp.emulators.kvm.devel/22643
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 34d2291..bfaee02 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1135,6 +1135,36 @@ static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
}
}
+static void x86_cpuid_set_vmware_extra(Object *obj)
+{
+ X86CPU *cpu = X86_CPU(obj);
+
+ if ((cpu->env.tsc_khz != 0) &&
+ (cpu->env.cpuid_hv_level == CPUID_HV_LEVEL_VMARE_4) &&
+ (cpu->env.cpuid_hv_vendor1 == CPUID_HV_VENDOR_VMWARE_1) &&
+ (cpu->env.cpuid_hv_vendor2 == CPUID_HV_VENDOR_VMWARE_2) &&
+ (cpu->env.cpuid_hv_vendor3 == CPUID_HV_VENDOR_VMWARE_3)) {
+ const uint32_t apic_khz = 1000000L;
+
+ /*
+ * From article.gmane.org/gmane.comp.emulators.kvm.devel/22643
+ *
+ * Leaf 0x40000010, Timing Information.
+ *
+ * VMware has defined the first generic leaf to provide timing
+ * information. This leaf returns the current TSC frequency and
+ * current Bus frequency in kHz.
+ *
+ * # EAX: (Virtual) TSC frequency in kHz.
+ * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
+ * # ECX, EDX: RESERVED (Per above, reserved fields are set to zero).
+ */
+ cpu->env.cpuid_hv_extra = 0x40000010;
+ cpu->env.cpuid_hv_extra_a = (uint32_t)cpu->env.tsc_khz;
+ cpu->env.cpuid_hv_extra_b = apic_khz;
+ }
+}
+
static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
@@ -1164,6 +1194,7 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
}
cpu->env.tsc_khz = value / 1000;
+ x86_cpuid_set_vmware_extra(obj);
}
static void x86_cpuid_get_hv_level(Object *obj, Visitor *v, void *opaque,
@@ -1263,6 +1294,7 @@ static void x86_cpuid_set_hv_vendor(Object *obj, const char *value,
env->cpuid_hv_vendor2 |= ((uint8_t)adj_value[i + 4]) << (8 * i);
env->cpuid_hv_vendor3 |= ((uint8_t)adj_value[i + 8]) << (8 * i);
}
+ x86_cpuid_set_vmware_extra(obj);
}
static void x86_cpuid_get_hv_extra(Object *obj, Visitor *v, void *opaque,
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 16/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=kvm.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (48 preceding siblings ...)
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 15/17] target-i386: Add setting of Hypervisor leaf extra for known vmare4 Don Slutz
@ 2012-09-17 14:01 ` Don Slutz
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 17/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=tcg Don Slutz
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:01 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/kvm.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index b8789f2..17c72bc 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -454,6 +454,25 @@ int kvm_arch_init_vcpu(CPUX86State *env)
c->ebx = signature[0];
c->ecx = signature[1];
c->edx = signature[2];
+ } else if (env->cpuid_hv_level > 0) {
+ for (i = KVM_CPUID_FEATURES + 1; i <= env->cpuid_hv_level; i++) {
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = i;
+ if (i == env->cpuid_hv_extra) {
+ c->eax = env->cpuid_hv_extra_a;
+ c->ebx = env->cpuid_hv_extra_b;
+ }
+ }
+
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_SIGNATURE_NEXT;
+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
+ c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
}
has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [Qemu-devel] [PATCH v3 17/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=tcg.
2012-08-30 19:20 [Qemu-devel] [PATCH] target-i386: Allow changing of Hypervisor CPUIDs Don Slutz
` (49 preceding siblings ...)
2012-09-17 14:01 ` [Qemu-devel] [PATCH v3 16/17] target-i386: Use Hypervisor leaf extra in -machine pc, accel=kvm Don Slutz
@ 2012-09-17 14:01 ` Don Slutz
50 siblings, 0 replies; 65+ messages in thread
From: Don Slutz @ 2012-09-17 14:01 UTC (permalink / raw)
To: qemu-devel, mtosatti, ehabkost, imammedo, avi, afaerber,
peter.maydell, kvm, anthony
Cc: Don Slutz
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
---
target-i386/cpu.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index bfaee02..89a45b5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1975,6 +1975,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ecx = 0;
*edx = 0;
break;
+ case 0x40000002 ... 0x400000FF:
+ if (index == env->cpuid_hv_extra) {
+ *eax = env->cpuid_hv_extra_a;
+ *ebx = env->cpuid_hv_extra_b;
+ } else {
+ *eax = 0;
+ *ebx = 0;
+ }
+ *ecx = 0;
+ *edx = 0;
+ break;
case 0x80000000:
*eax = env->cpuid_xlevel;
*ebx = env->cpuid_vendor1;
--
1.7.1
^ permalink raw reply related [flat|nested] 65+ messages in thread