* [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
@ 2010-01-07 12:44 Gleb Natapov
2010-01-07 16:09 ` Anthony Liguori
2010-01-07 16:24 ` [Qemu-devel] [PATCHv2] " Gleb Natapov
0 siblings, 2 replies; 24+ messages in thread
From: Gleb Natapov @ 2010-01-07 12:44 UTC (permalink / raw)
To: qemu-devel
Initialize KVM paravirt cpuid leaf and allow user to control guest
visible PV features through -cpu flag.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index f3834b3..216b00e 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -701,7 +701,8 @@ typedef struct CPUX86State {
uint8_t nmi_pending;
uint8_t has_error_code;
uint32_t sipi_vector;
-
+ uint32_t cpuid_kvm_features;
+
/* in order to simplify APIC support, we leave this pointer to the
user */
struct APICState *apic_state;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index c39a993..20ec4b6 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -58,10 +58,18 @@ static const char *ext3_feature_name[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
+static const char *kvm_feature_name[] = {
+ "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL, NULL, NULL, NULL,
+};
+
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
uint32_t *ext_features,
uint32_t *ext2_features,
- uint32_t *ext3_features)
+ uint32_t *ext3_features,
+ uint32_t *kvm_features)
{
int i;
int found = 0;
@@ -86,6 +94,12 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
*ext3_features |= 1 << i;
found = 1;
}
+ for ( i = 0 ; i < 32 ; i++ )
+ if (kvm_feature_name[i] && !strcmp (flagname, kvm_feature_name[i])) {
+ *kvm_features |= 1 << i;
+ found = 1;
+ }
+
if (!found) {
fprintf(stderr, "CPU feature %s not found\n", flagname);
}
@@ -98,7 +112,7 @@ typedef struct x86_def_t {
int family;
int model;
int stepping;
- uint32_t features, ext_features, ext2_features, ext3_features;
+ uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
uint32_t xlevel;
char model_id[48];
int vendor_override;
@@ -375,8 +389,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
char *s = strdup(cpu_model);
char *featurestr, *name = strtok(s, ",");
- uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
- uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
+ uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
+ uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
uint32_t numvalue;
def = NULL;
@@ -394,17 +408,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
memcpy(x86_cpu_def, def, sizeof(*def));
}
+ plus_kvm_features = ~0; /* not supported bits will be filtered out later */
+
add_flagname_to_bitmaps("hypervisor", &plus_features,
- &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+ &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
+ &plus_kvm_features);
featurestr = strtok(NULL, ",");
while (featurestr) {
char *val;
if (featurestr[0] == '+') {
- add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+ add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features);
} else if (featurestr[0] == '-') {
- add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
+ add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features, &minus_kvm_features);
} else if ((val = strchr(featurestr, '='))) {
*val = 0; val++;
if (!strcmp(featurestr, "family")) {
@@ -481,10 +498,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
x86_cpu_def->ext_features |= plus_ext_features;
x86_cpu_def->ext2_features |= plus_ext2_features;
x86_cpu_def->ext3_features |= plus_ext3_features;
+ x86_cpu_def->kvm_features |= plus_kvm_features;
x86_cpu_def->features &= ~minus_features;
x86_cpu_def->ext_features &= ~minus_ext_features;
x86_cpu_def->ext2_features &= ~minus_ext2_features;
x86_cpu_def->ext3_features &= ~minus_ext3_features;
+ x86_cpu_def->kvm_features &= ~minus_kvm_features;
free(s);
return 0;
@@ -529,7 +548,7 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
env->cpuid_ext_features = def->ext_features;
env->cpuid_ext2_features = def->ext2_features;
env->cpuid_xlevel = def->xlevel;
- env->cpuid_ext3_features = def->ext3_features;
+ env->cpuid_kvm_features = def->kvm_features;
{
const char *model_id = def->model_id;
int c, len, i;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index de79eb7..1d93e63 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -17,6 +17,7 @@
#include <sys/mman.h>
#include <linux/kvm.h>
+#include <linux/kvm_para.h>
#include "qemu-common.h"
#include "sysemu.h"
@@ -134,6 +135,37 @@ static void kvm_trim_features(uint32_t *features, uint32_t supported)
}
}
+struct kvm_para_features {
+ int cap;
+ int feature;
+} para_features[] = {
+#ifdef KVM_CAP_CLOCKSOURCE
+ { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
+#endif
+#ifdef KVM_CAP_NOP_IO_DELAY
+ { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
+#endif
+#ifdef KVM_CAP_PV_MMU
+ { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
+#endif
+#ifdef KVM_CAP_CR3_CACHE
+ { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
+#endif
+ { -1, -1 }
+};
+
+static int get_para_features(CPUState *env)
+{
+ int i, features = 0;
+
+ for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
+ if (kvm_check_extension(env->kvm_state, para_features[i].cap))
+ features |= (1 << para_features[i].feature);
+ }
+
+ return features;
+}
+
int kvm_arch_init_vcpu(CPUState *env)
{
struct {
@@ -142,6 +174,10 @@ int kvm_arch_init_vcpu(CPUState *env)
} __attribute__((packed)) cpuid_data;
uint32_t limit, i, j, cpuid_i;
uint32_t unused;
+ struct kvm_cpuid_entry2 *c;
+#ifdef KVM_CPUID_SIGNATURE
+ uint32_t signature[3];
+#endif
env->mp_state = KVM_MP_STATE_RUNNABLE;
@@ -160,10 +196,27 @@ int kvm_arch_init_vcpu(CPUState *env)
cpuid_i = 0;
+#ifdef KVM_CPUID_SIGNATURE
+ /* Paravirtualization CPUIDs */
+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_SIGNATURE;
+ c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
+
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_FEATURES;
+ c->eax = env->cpuid_kvm_features & get_para_features(env);
+#endif
+
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
for (i = 0; i <= limit; i++) {
- struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
+ c = &cpuid_data.entries[cpuid_i++];
switch (i) {
case 2: {
@@ -213,7 +266,7 @@ int kvm_arch_init_vcpu(CPUState *env)
cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused);
for (i = 0x80000000; i <= limit; i++) {
- struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
+ c = &cpuid_data.entries[cpuid_i++];
c->function = i;
c->flags = 0;
--
Gleb.
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
2010-01-07 12:44 [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf Gleb Natapov
@ 2010-01-07 16:09 ` Anthony Liguori
2010-01-07 16:15 ` Gleb Natapov
2010-01-07 16:24 ` [Qemu-devel] [PATCHv2] " Gleb Natapov
1 sibling, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2010-01-07 16:09 UTC (permalink / raw)
To: Gleb Natapov; +Cc: qemu-devel
On 01/07/2010 06:44 AM, Gleb Natapov wrote:
> Initialize KVM paravirt cpuid leaf and allow user to control guest
> visible PV features through -cpu flag.
>
> Signed-off-by: Gleb Natapov<gleb@redhat.com>
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index f3834b3..216b00e 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -701,7 +701,8 @@ typedef struct CPUX86State {
> uint8_t nmi_pending;
> uint8_t has_error_code;
> uint32_t sipi_vector;
> -
> + uint32_t cpuid_kvm_features;
> +
> /* in order to simplify APIC support, we leave this pointer to the
> user */
> struct APICState *apic_state;
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index c39a993..20ec4b6 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -58,10 +58,18 @@ static const char *ext3_feature_name[] = {
> NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> };
>
> +static const char *kvm_feature_name[] = {
> + "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL, NULL, NULL, NULL,
> +};
> +
> static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> uint32_t *ext_features,
> uint32_t *ext2_features,
> - uint32_t *ext3_features)
> + uint32_t *ext3_features,
> + uint32_t *kvm_features)
> {
> int i;
> int found = 0;
> @@ -86,6 +94,12 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> *ext3_features |= 1<< i;
> found = 1;
> }
> + for ( i = 0 ; i< 32 ; i++ )
> + if (kvm_feature_name[i]&& !strcmp (flagname, kvm_feature_name[i])) {
> + *kvm_features |= 1<< i;
> + found = 1;
> + }
> +
> if (!found) {
> fprintf(stderr, "CPU feature %s not found\n", flagname);
> }
> @@ -98,7 +112,7 @@ typedef struct x86_def_t {
> int family;
> int model;
> int stepping;
> - uint32_t features, ext_features, ext2_features, ext3_features;
> + uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
> uint32_t xlevel;
> char model_id[48];
> int vendor_override;
> @@ -375,8 +389,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>
> char *s = strdup(cpu_model);
> char *featurestr, *name = strtok(s, ",");
> - uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
> - uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
> + uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
> + uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
> uint32_t numvalue;
>
> def = NULL;
> @@ -394,17 +408,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> memcpy(x86_cpu_def, def, sizeof(*def));
> }
>
> + plus_kvm_features = ~0; /* not supported bits will be filtered out later */
> +
> add_flagname_to_bitmaps("hypervisor",&plus_features,
> -&plus_ext_features,&plus_ext2_features,&plus_ext3_features);
> +&plus_ext_features,&plus_ext2_features,&plus_ext3_features,
> +&plus_kvm_features);
>
> featurestr = strtok(NULL, ",");
>
> while (featurestr) {
> char *val;
> if (featurestr[0] == '+') {
> - add_flagname_to_bitmaps(featurestr + 1,&plus_features,&plus_ext_features,&plus_ext2_features,&plus_ext3_features);
> + add_flagname_to_bitmaps(featurestr + 1,&plus_features,&plus_ext_features,&plus_ext2_features,&plus_ext3_features,&plus_kvm_features);
> } else if (featurestr[0] == '-') {
> - add_flagname_to_bitmaps(featurestr + 1,&minus_features,&minus_ext_features,&minus_ext2_features,&minus_ext3_features);
> + add_flagname_to_bitmaps(featurestr + 1,&minus_features,&minus_ext_features,&minus_ext2_features,&minus_ext3_features,&minus_kvm_features);
> } else if ((val = strchr(featurestr, '='))) {
> *val = 0; val++;
> if (!strcmp(featurestr, "family")) {
> @@ -481,10 +498,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> x86_cpu_def->ext_features |= plus_ext_features;
> x86_cpu_def->ext2_features |= plus_ext2_features;
> x86_cpu_def->ext3_features |= plus_ext3_features;
> + x86_cpu_def->kvm_features |= plus_kvm_features;
> x86_cpu_def->features&= ~minus_features;
> x86_cpu_def->ext_features&= ~minus_ext_features;
> x86_cpu_def->ext2_features&= ~minus_ext2_features;
> x86_cpu_def->ext3_features&= ~minus_ext3_features;
> + x86_cpu_def->kvm_features&= ~minus_kvm_features;
> free(s);
> return 0;
>
> @@ -529,7 +548,7 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
> env->cpuid_ext_features = def->ext_features;
> env->cpuid_ext2_features = def->ext2_features;
> env->cpuid_xlevel = def->xlevel;
> - env->cpuid_ext3_features = def->ext3_features;
> + env->cpuid_kvm_features = def->kvm_features;
> {
> const char *model_id = def->model_id;
> int c, len, i;
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index de79eb7..1d93e63 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -17,6 +17,7 @@
> #include<sys/mman.h>
>
> #include<linux/kvm.h>
> +#include<linux/kvm_para.h>
>
> #include "qemu-common.h"
> #include "sysemu.h"
> @@ -134,6 +135,37 @@ static void kvm_trim_features(uint32_t *features, uint32_t supported)
> }
> }
>
> +struct kvm_para_features {
> + int cap;
> + int feature;
> +} para_features[] = {
> +#ifdef KVM_CAP_CLOCKSOURCE
> + { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
> +#endif
> +#ifdef KVM_CAP_NOP_IO_DELAY
> + { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
> +#endif
> +#ifdef KVM_CAP_PV_MMU
> + { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
> +#endif
> +#ifdef KVM_CAP_CR3_CACHE
> + { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
> +#endif
> + { -1, -1 }
> +};
> +
> +static int get_para_features(CPUState *env)
> +{
> + int i, features = 0;
> +
> + for (i = 0; i< ARRAY_SIZE(para_features) - 1; i++) {
> + if (kvm_check_extension(env->kvm_state, para_features[i].cap))
> + features |= (1<< para_features[i].feature);
> + }
> +
> + return features;
> +}
> +
> int kvm_arch_init_vcpu(CPUState *env)
> {
> struct {
> @@ -142,6 +174,10 @@ int kvm_arch_init_vcpu(CPUState *env)
> } __attribute__((packed)) cpuid_data;
> uint32_t limit, i, j, cpuid_i;
> uint32_t unused;
> + struct kvm_cpuid_entry2 *c;
> +#ifdef KVM_CPUID_SIGNATURE
>
KVM_CPUID_SIGNATURE is unnecessary as a guard because it's always been
present in kvm_para.h. Since we include kvm_para.h unconditionally,
there's no way we wouldn't have KVM_CPUID_SIGNATURE.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
2010-01-07 16:09 ` Anthony Liguori
@ 2010-01-07 16:15 ` Gleb Natapov
2010-01-07 16:53 ` Anthony Liguori
0 siblings, 1 reply; 24+ messages in thread
From: Gleb Natapov @ 2010-01-07 16:15 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On Thu, Jan 07, 2010 at 10:09:16AM -0600, Anthony Liguori wrote:
> On 01/07/2010 06:44 AM, Gleb Natapov wrote:
> >Initialize KVM paravirt cpuid leaf and allow user to control guest
> >visible PV features through -cpu flag.
> >
> >Signed-off-by: Gleb Natapov<gleb@redhat.com>
> >diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> >index f3834b3..216b00e 100644
> >--- a/target-i386/cpu.h
> >+++ b/target-i386/cpu.h
> >@@ -701,7 +701,8 @@ typedef struct CPUX86State {
> > uint8_t nmi_pending;
> > uint8_t has_error_code;
> > uint32_t sipi_vector;
> >-
> >+ uint32_t cpuid_kvm_features;
> >+
> > /* in order to simplify APIC support, we leave this pointer to the
> > user */
> > struct APICState *apic_state;
> >diff --git a/target-i386/helper.c b/target-i386/helper.c
> >index c39a993..20ec4b6 100644
> >--- a/target-i386/helper.c
> >+++ b/target-i386/helper.c
> >@@ -58,10 +58,18 @@ static const char *ext3_feature_name[] = {
> > NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> > };
> >
> >+static const char *kvm_feature_name[] = {
> >+ "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL, NULL, NULL, NULL,
> >+};
> >+
> > static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> > uint32_t *ext_features,
> > uint32_t *ext2_features,
> >- uint32_t *ext3_features)
> >+ uint32_t *ext3_features,
> >+ uint32_t *kvm_features)
> > {
> > int i;
> > int found = 0;
> >@@ -86,6 +94,12 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> > *ext3_features |= 1<< i;
> > found = 1;
> > }
> >+ for ( i = 0 ; i< 32 ; i++ )
> >+ if (kvm_feature_name[i]&& !strcmp (flagname, kvm_feature_name[i])) {
> >+ *kvm_features |= 1<< i;
> >+ found = 1;
> >+ }
> >+
> > if (!found) {
> > fprintf(stderr, "CPU feature %s not found\n", flagname);
> > }
> >@@ -98,7 +112,7 @@ typedef struct x86_def_t {
> > int family;
> > int model;
> > int stepping;
> >- uint32_t features, ext_features, ext2_features, ext3_features;
> >+ uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
> > uint32_t xlevel;
> > char model_id[48];
> > int vendor_override;
> >@@ -375,8 +389,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> >
> > char *s = strdup(cpu_model);
> > char *featurestr, *name = strtok(s, ",");
> >- uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
> >- uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
> >+ uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
> >+ uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
> > uint32_t numvalue;
> >
> > def = NULL;
> >@@ -394,17 +408,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> > memcpy(x86_cpu_def, def, sizeof(*def));
> > }
> >
> >+ plus_kvm_features = ~0; /* not supported bits will be filtered out later */
> >+
> > add_flagname_to_bitmaps("hypervisor",&plus_features,
> >-&plus_ext_features,&plus_ext2_features,&plus_ext3_features);
> >+&plus_ext_features,&plus_ext2_features,&plus_ext3_features,
> >+&plus_kvm_features);
> >
> > featurestr = strtok(NULL, ",");
> >
> > while (featurestr) {
> > char *val;
> > if (featurestr[0] == '+') {
> >- add_flagname_to_bitmaps(featurestr + 1,&plus_features,&plus_ext_features,&plus_ext2_features,&plus_ext3_features);
> >+ add_flagname_to_bitmaps(featurestr + 1,&plus_features,&plus_ext_features,&plus_ext2_features,&plus_ext3_features,&plus_kvm_features);
> > } else if (featurestr[0] == '-') {
> >- add_flagname_to_bitmaps(featurestr + 1,&minus_features,&minus_ext_features,&minus_ext2_features,&minus_ext3_features);
> >+ add_flagname_to_bitmaps(featurestr + 1,&minus_features,&minus_ext_features,&minus_ext2_features,&minus_ext3_features,&minus_kvm_features);
> > } else if ((val = strchr(featurestr, '='))) {
> > *val = 0; val++;
> > if (!strcmp(featurestr, "family")) {
> >@@ -481,10 +498,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> > x86_cpu_def->ext_features |= plus_ext_features;
> > x86_cpu_def->ext2_features |= plus_ext2_features;
> > x86_cpu_def->ext3_features |= plus_ext3_features;
> >+ x86_cpu_def->kvm_features |= plus_kvm_features;
> > x86_cpu_def->features&= ~minus_features;
> > x86_cpu_def->ext_features&= ~minus_ext_features;
> > x86_cpu_def->ext2_features&= ~minus_ext2_features;
> > x86_cpu_def->ext3_features&= ~minus_ext3_features;
> >+ x86_cpu_def->kvm_features&= ~minus_kvm_features;
> > free(s);
> > return 0;
> >
> >@@ -529,7 +548,7 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
> > env->cpuid_ext_features = def->ext_features;
> > env->cpuid_ext2_features = def->ext2_features;
> > env->cpuid_xlevel = def->xlevel;
> >- env->cpuid_ext3_features = def->ext3_features;
> >+ env->cpuid_kvm_features = def->kvm_features;
> > {
> > const char *model_id = def->model_id;
> > int c, len, i;
> >diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> >index de79eb7..1d93e63 100644
> >--- a/target-i386/kvm.c
> >+++ b/target-i386/kvm.c
> >@@ -17,6 +17,7 @@
> > #include<sys/mman.h>
> >
> > #include<linux/kvm.h>
> >+#include<linux/kvm_para.h>
> >
> > #include "qemu-common.h"
> > #include "sysemu.h"
> >@@ -134,6 +135,37 @@ static void kvm_trim_features(uint32_t *features, uint32_t supported)
> > }
> > }
> >
> >+struct kvm_para_features {
> >+ int cap;
> >+ int feature;
> >+} para_features[] = {
> >+#ifdef KVM_CAP_CLOCKSOURCE
> >+ { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
> >+#endif
> >+#ifdef KVM_CAP_NOP_IO_DELAY
> >+ { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
> >+#endif
> >+#ifdef KVM_CAP_PV_MMU
> >+ { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
> >+#endif
> >+#ifdef KVM_CAP_CR3_CACHE
> >+ { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
> >+#endif
> >+ { -1, -1 }
> >+};
> >+
> >+static int get_para_features(CPUState *env)
> >+{
> >+ int i, features = 0;
> >+
> >+ for (i = 0; i< ARRAY_SIZE(para_features) - 1; i++) {
> >+ if (kvm_check_extension(env->kvm_state, para_features[i].cap))
> >+ features |= (1<< para_features[i].feature);
> >+ }
> >+
> >+ return features;
> >+}
> >+
> > int kvm_arch_init_vcpu(CPUState *env)
> > {
> > struct {
> >@@ -142,6 +174,10 @@ int kvm_arch_init_vcpu(CPUState *env)
> > } __attribute__((packed)) cpuid_data;
> > uint32_t limit, i, j, cpuid_i;
> > uint32_t unused;
> >+ struct kvm_cpuid_entry2 *c;
> >+#ifdef KVM_CPUID_SIGNATURE
>
> KVM_CPUID_SIGNATURE is unnecessary as a guard because it's always
> been present in kvm_para.h. Since we include kvm_para.h
> unconditionally, there's no way we wouldn't have
> KVM_CPUID_SIGNATURE.
>
It is there in qemu-kvm and we suppose to bring knowledge from there :)
But I can drop it if you like.
--
Gleb.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
2010-01-07 16:15 ` Gleb Natapov
@ 2010-01-07 16:53 ` Anthony Liguori
2010-01-07 16:56 ` Avi Kivity
2010-01-07 16:59 ` Gleb Natapov
0 siblings, 2 replies; 24+ messages in thread
From: Anthony Liguori @ 2010-01-07 16:53 UTC (permalink / raw)
To: Gleb Natapov; +Cc: qemu-devel, Avi Kivity
On 01/07/2010 10:15 AM, Gleb Natapov wrote:
>> KVM_CPUID_SIGNATURE is unnecessary as a guard because it's always
>> been present in kvm_para.h. Since we include kvm_para.h
>> unconditionally, there's no way we wouldn't have
>> KVM_CPUID_SIGNATURE.
>>
>>
> It is there in qemu-kvm and we suppose to bring knowledge from there :)
>
Hopefully just the good bits.
> But I can drop it if you like.
>
I don't want to deviate unnecessarily from qemu-kvm so we can approach
this in one of two ways. We can remove the guard in qemu-kvm and Avi
can send me a pull request with this feature. I can also just pull in
the patch as-is and we can fix this in both places later. I'm happy
either way.
Regards,
Anthony Liguori
> --
> Gleb.
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
2010-01-07 16:53 ` Anthony Liguori
@ 2010-01-07 16:56 ` Avi Kivity
2010-01-07 17:08 ` Gleb Natapov
2010-01-07 16:59 ` Gleb Natapov
1 sibling, 1 reply; 24+ messages in thread
From: Avi Kivity @ 2010-01-07 16:56 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, Gleb Natapov
On 01/07/2010 06:53 PM, Anthony Liguori wrote:
>
> I don't want to deviate unnecessarily from qemu-kvm so we can approach
> this in one of two ways. We can remove the guard in qemu-kvm and Avi
> can send me a pull request with this feature. I can also just pull in
> the patch as-is and we can fix this in both places later. I'm happy
> either way.
Let's go through qemu-kvm.git. I'll post information about the queue
policy soon.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
2010-01-07 16:56 ` Avi Kivity
@ 2010-01-07 17:08 ` Gleb Natapov
2010-01-07 18:02 ` Anthony Liguori
0 siblings, 1 reply; 24+ messages in thread
From: Gleb Natapov @ 2010-01-07 17:08 UTC (permalink / raw)
To: Avi Kivity; +Cc: qemu-devel
On Thu, Jan 07, 2010 at 06:56:31PM +0200, Avi Kivity wrote:
> On 01/07/2010 06:53 PM, Anthony Liguori wrote:
> >
> >I don't want to deviate unnecessarily from qemu-kvm so we can
> >approach this in one of two ways. We can remove the guard in
> >qemu-kvm and Avi can send me a pull request with this feature. I
> >can also just pull in the patch as-is and we can fix this in both
> >places later. I'm happy either way.
>
> Let's go through qemu-kvm.git. I'll post information about the
> queue policy soon.
>
Till yesterday it was other way around. May be switch rules after
applying the patch?
--
Gleb.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
2010-01-07 17:08 ` Gleb Natapov
@ 2010-01-07 18:02 ` Anthony Liguori
2010-01-07 18:10 ` Gleb Natapov
0 siblings, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2010-01-07 18:02 UTC (permalink / raw)
To: Gleb Natapov; +Cc: Avi Kivity, qemu-devel
On 01/07/2010 11:08 AM, Gleb Natapov wrote:
> On Thu, Jan 07, 2010 at 06:56:31PM +0200, Avi Kivity wrote:
>
>> On 01/07/2010 06:53 PM, Anthony Liguori wrote:
>>
>>> I don't want to deviate unnecessarily from qemu-kvm so we can
>>> approach this in one of two ways. We can remove the guard in
>>> qemu-kvm and Avi can send me a pull request with this feature. I
>>> can also just pull in the patch as-is and we can fix this in both
>>> places later. I'm happy either way.
>>>
>> Let's go through qemu-kvm.git. I'll post information about the
>> queue policy soon.
>>
>>
> Till yesterday it was other way around.
Not qemu-kvm.git master, but a for_upstream branch that actually tracks
qemu.git. The point is to get Avi involved in shaping the way kvm
support in qemu.git evolves so that we can converge.
> May be switch rules after
> applying the patch?
>
Let's give Avi a chance to get his tree setup. We can revisit in a
couple days if necessary.
Regards,
Anthony Liguori
> --
> Gleb.
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
2010-01-07 18:02 ` Anthony Liguori
@ 2010-01-07 18:10 ` Gleb Natapov
0 siblings, 0 replies; 24+ messages in thread
From: Gleb Natapov @ 2010-01-07 18:10 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Avi Kivity, qemu-devel
On Thu, Jan 07, 2010 at 12:02:01PM -0600, Anthony Liguori wrote:
> On 01/07/2010 11:08 AM, Gleb Natapov wrote:
> >On Thu, Jan 07, 2010 at 06:56:31PM +0200, Avi Kivity wrote:
> >>On 01/07/2010 06:53 PM, Anthony Liguori wrote:
> >>>I don't want to deviate unnecessarily from qemu-kvm so we can
> >>>approach this in one of two ways. We can remove the guard in
> >>>qemu-kvm and Avi can send me a pull request with this feature. I
> >>>can also just pull in the patch as-is and we can fix this in both
> >>>places later. I'm happy either way.
> >>Let's go through qemu-kvm.git. I'll post information about the
> >>queue policy soon.
> >>
> >Till yesterday it was other way around.
>
>
> Not qemu-kvm.git master, but a for_upstream branch that actually
> tracks qemu.git. The point is to get Avi involved in shaping the
> way kvm support in qemu.git evolves so that we can converge.
>
Ah, that's OK then.
> > May be switch rules after
> >applying the patch?
>
> Let's give Avi a chance to get his tree setup. We can revisit in a
> couple days if necessary.
>
> Regards,
>
> Anthony Liguori
> >--
> > Gleb.
--
Gleb.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf
2010-01-07 16:53 ` Anthony Liguori
2010-01-07 16:56 ` Avi Kivity
@ 2010-01-07 16:59 ` Gleb Natapov
1 sibling, 0 replies; 24+ messages in thread
From: Gleb Natapov @ 2010-01-07 16:59 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, Avi Kivity
On Thu, Jan 07, 2010 at 10:53:30AM -0600, Anthony Liguori wrote:
> On 01/07/2010 10:15 AM, Gleb Natapov wrote:
> >>KVM_CPUID_SIGNATURE is unnecessary as a guard because it's always
> >>been present in kvm_para.h. Since we include kvm_para.h
> >>unconditionally, there's no way we wouldn't have
> >>KVM_CPUID_SIGNATURE.
> >>
> >It is there in qemu-kvm and we suppose to bring knowledge from there :)
>
> Hopefully just the good bits.
>
> >But I can drop it if you like.
>
> I don't want to deviate unnecessarily from qemu-kvm so we can
> approach this in one of two ways. We can remove the guard in
> qemu-kvm and Avi can send me a pull request with this feature. I
> can also just pull in the patch as-is and we can fix this in both
> places later. I'm happy either way.
>
Actually qemu-kvm doesn't uses this function right now. It has it's own
version in qemu-kvm-x86.c. The idea was to teach qemu-kvm to use
upstream function instead.
--
Gleb.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
2010-01-07 12:44 [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf Gleb Natapov
2010-01-07 16:09 ` Anthony Liguori
@ 2010-01-07 16:24 ` Gleb Natapov
2010-01-11 19:18 ` Anthony Liguori
2010-01-13 13:25 ` [Qemu-devel] [PATCHv3] " Gleb Natapov
1 sibling, 2 replies; 24+ messages in thread
From: Gleb Natapov @ 2010-01-07 16:24 UTC (permalink / raw)
To: qemu-devel
Initialize KVM paravirt cpuid leaf and allow user to control guest
visible PV features through -cpu flag.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
v1->v2
fix indentation
remove unneeded ifdefs
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index f3834b3..fbe11b8 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -701,6 +701,7 @@ typedef struct CPUX86State {
uint8_t nmi_pending;
uint8_t has_error_code;
uint32_t sipi_vector;
+ uint32_t cpuid_kvm_features;
/* in order to simplify APIC support, we leave this pointer to the
user */
diff --git a/target-i386/helper.c b/target-i386/helper.c
index c39a993..20ec4b6 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -58,10 +58,18 @@ static const char *ext3_feature_name[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
+static const char *kvm_feature_name[] = {
+ "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL, NULL, NULL, NULL,
+};
+
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
uint32_t *ext_features,
uint32_t *ext2_features,
- uint32_t *ext3_features)
+ uint32_t *ext3_features,
+ uint32_t *kvm_features)
{
int i;
int found = 0;
@@ -86,6 +94,12 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
*ext3_features |= 1 << i;
found = 1;
}
+ for ( i = 0 ; i < 32 ; i++ )
+ if (kvm_feature_name[i] && !strcmp (flagname, kvm_feature_name[i])) {
+ *kvm_features |= 1 << i;
+ found = 1;
+ }
+
if (!found) {
fprintf(stderr, "CPU feature %s not found\n", flagname);
}
@@ -98,7 +112,7 @@ typedef struct x86_def_t {
int family;
int model;
int stepping;
- uint32_t features, ext_features, ext2_features, ext3_features;
+ uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
uint32_t xlevel;
char model_id[48];
int vendor_override;
@@ -375,8 +389,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
char *s = strdup(cpu_model);
char *featurestr, *name = strtok(s, ",");
- uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
- uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
+ uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
+ uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
uint32_t numvalue;
def = NULL;
@@ -394,17 +408,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
memcpy(x86_cpu_def, def, sizeof(*def));
}
+ plus_kvm_features = ~0; /* not supported bits will be filtered out later */
+
add_flagname_to_bitmaps("hypervisor", &plus_features,
- &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+ &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
+ &plus_kvm_features);
featurestr = strtok(NULL, ",");
while (featurestr) {
char *val;
if (featurestr[0] == '+') {
- add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+ add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features);
} else if (featurestr[0] == '-') {
- add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
+ add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features, &minus_kvm_features);
} else if ((val = strchr(featurestr, '='))) {
*val = 0; val++;
if (!strcmp(featurestr, "family")) {
@@ -481,10 +498,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
x86_cpu_def->ext_features |= plus_ext_features;
x86_cpu_def->ext2_features |= plus_ext2_features;
x86_cpu_def->ext3_features |= plus_ext3_features;
+ x86_cpu_def->kvm_features |= plus_kvm_features;
x86_cpu_def->features &= ~minus_features;
x86_cpu_def->ext_features &= ~minus_ext_features;
x86_cpu_def->ext2_features &= ~minus_ext2_features;
x86_cpu_def->ext3_features &= ~minus_ext3_features;
+ x86_cpu_def->kvm_features &= ~minus_kvm_features;
free(s);
return 0;
@@ -529,7 +548,7 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
env->cpuid_ext_features = def->ext_features;
env->cpuid_ext2_features = def->ext2_features;
env->cpuid_xlevel = def->xlevel;
- env->cpuid_ext3_features = def->ext3_features;
+ env->cpuid_kvm_features = def->kvm_features;
{
const char *model_id = def->model_id;
int c, len, i;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 4084503..6a841de 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -17,6 +17,7 @@
#include <sys/mman.h>
#include <linux/kvm.h>
+#include <linux/kvm_para.h>
#include "qemu-common.h"
#include "sysemu.h"
@@ -134,6 +135,40 @@ static void kvm_trim_features(uint32_t *features, uint32_t supported)
}
}
+struct kvm_para_features {
+ int cap;
+ int feature;
+} para_features[] = {
+#ifdef KVM_CAP_CLOCKSOURCE
+ { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
+#endif
+#ifdef KVM_CAP_NOP_IO_DELAY
+ { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
+#endif
+#ifdef KVM_CAP_PV_MMU
+ { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
+#endif
+#ifdef KVM_CAP_CR3_CACHE
+ { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
+#endif
+#ifdef KVM_CAP_HYPERV
+ { KVM_CAP_HYPERV, KVM_FEATURE_HYPERV },
+#endif
+ { -1, -1 }
+};
+
+static int get_para_features(CPUState *env)
+{
+ int i, features = 0;
+
+ for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
+ if (kvm_check_extension(env->kvm_state, para_features[i].cap))
+ features |= (1 << para_features[i].feature);
+ }
+
+ return features;
+}
+
int kvm_arch_init_vcpu(CPUState *env)
{
struct {
@@ -142,6 +177,8 @@ int kvm_arch_init_vcpu(CPUState *env)
} __attribute__((packed)) cpuid_data;
uint32_t limit, i, j, cpuid_i;
uint32_t unused;
+ struct kvm_cpuid_entry2 *c;
+ uint32_t signature[3];
env->mp_state = KVM_MP_STATE_RUNNABLE;
@@ -160,10 +197,25 @@ int kvm_arch_init_vcpu(CPUState *env)
cpuid_i = 0;
+ /* Paravirtualization CPUIDs */
+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_SIGNATURE;
+ c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
+
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_FEATURES;
+ c->eax = env->cpuid_kvm_features & get_para_features(env);
+
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
for (i = 0; i <= limit; i++) {
- struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
+ c = &cpuid_data.entries[cpuid_i++];
switch (i) {
case 2: {
@@ -213,7 +265,7 @@ int kvm_arch_init_vcpu(CPUState *env)
cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused);
for (i = 0x80000000; i <= limit; i++) {
- struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
+ c = &cpuid_data.entries[cpuid_i++];
c->function = i;
c->flags = 0;
--
Gleb.
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
2010-01-07 16:24 ` [Qemu-devel] [PATCHv2] " Gleb Natapov
@ 2010-01-11 19:18 ` Anthony Liguori
2010-01-11 19:33 ` [Qemu-devel] Registering key events android (qemu based) emulator Anwar Ghani
` (3 more replies)
2010-01-13 13:25 ` [Qemu-devel] [PATCHv3] " Gleb Natapov
1 sibling, 4 replies; 24+ messages in thread
From: Anthony Liguori @ 2010-01-11 19:18 UTC (permalink / raw)
To: Gleb Natapov
Cc: Marcelo Tosatti, Jan Kiszka, qemu-devel, kvm-devel, Avi Kivity
On 01/07/2010 10:24 AM, Gleb Natapov wrote:
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 4084503..6a841de 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -17,6 +17,7 @@
> #include<sys/mman.h>
>
> #include<linux/kvm.h>
> +#include<linux/kvm_para.h>
This breaks the build on a default F12 install because while kvm.h is
present, kvm_para.h is not. This is a hard one to fix.
We can default the kvm search path to /lib/modules/$(uname -r)/build, we
can fix the glibc headers and live with it, or we can pull in the kvm
headers into qemu.
Avi/Marcelo/Jan, any thoughts from the qemu-kvm side?
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* [Qemu-devel] Registering key events android (qemu based) emulator
2010-01-11 19:18 ` Anthony Liguori
@ 2010-01-11 19:33 ` Anwar Ghani
2010-01-11 20:40 ` [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf Jan Kiszka
` (2 subsequent siblings)
3 siblings, 0 replies; 24+ messages in thread
From: Anwar Ghani @ 2010-01-11 19:33 UTC (permalink / raw)
To: Gleb Natapov, Anthony Liguori
Cc: Marcelo Tosatti, Jan Kiszka, qemu-devel, kvm-devel, Avi Kivity
[-- Attachment #1: Type: text/plain, Size: 1363 bytes --]
Hi All
guys I am a bit new to this stuff. I want to call a method after user presses a combination of keys lets say alt+s or whatever. How can I do it using which event handler.
Best Regards
Anwar Ghani
+31 647 344 773
--- On Mon, 1/11/10, Anthony Liguori <anthony@codemonkey.ws> wrote:
From: Anthony Liguori <anthony@codemonkey.ws>
Subject: Re: [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
To: "Gleb Natapov" <gleb@redhat.com>
Cc: "Marcelo Tosatti" <mtosatti@redhat.com>, "Jan Kiszka" <jan.kiszka@web.de>, qemu-devel@nongnu.org, "kvm-devel" <kvm@vger.kernel.org>, "Avi Kivity" <avi@redhat.com>
Date: Monday, January 11, 2010, 7:18 PM
On 01/07/2010 10:24 AM, Gleb Natapov wrote:
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 4084503..6a841de 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -17,6 +17,7 @@
> #include<sys/mman.h>
>
> #include<linux/kvm.h>
> +#include<linux/kvm_para.h>
This breaks the build on a default F12 install because while kvm.h is present, kvm_para.h is not. This is a hard one to fix.
We can default the kvm search path to /lib/modules/$(uname -r)/build, we can fix the glibc headers and live with it, or we can pull in the kvm headers into qemu.
Avi/Marcelo/Jan, any thoughts from the qemu-kvm side?
Regards,
Anthony Liguori
[-- Attachment #2: Type: text/html, Size: 1834 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
2010-01-11 19:18 ` Anthony Liguori
2010-01-11 19:33 ` [Qemu-devel] Registering key events android (qemu based) emulator Anwar Ghani
@ 2010-01-11 20:40 ` Jan Kiszka
2010-01-11 21:36 ` Anthony Liguori
2010-01-12 7:23 ` Gleb Natapov
2010-01-12 8:42 ` Avi Kivity
3 siblings, 1 reply; 24+ messages in thread
From: Jan Kiszka @ 2010-01-11 20:40 UTC (permalink / raw)
To: Anthony Liguori
Cc: Avi Kivity, Marcelo Tosatti, qemu-devel, Gleb Natapov, kvm-devel
[-- Attachment #1: Type: text/plain, Size: 1088 bytes --]
Anthony Liguori wrote:
> On 01/07/2010 10:24 AM, Gleb Natapov wrote:
>> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
>> index 4084503..6a841de 100644
>> --- a/target-i386/kvm.c
>> +++ b/target-i386/kvm.c
>> @@ -17,6 +17,7 @@
>> #include<sys/mman.h>
>>
>> #include<linux/kvm.h>
>> +#include<linux/kvm_para.h>
>
> This breaks the build on a default F12 install because while kvm.h is
> present, kvm_para.h is not. This is a hard one to fix.
>
> We can default the kvm search path to /lib/modules/$(uname -r)/build, we
> can fix the glibc headers and live with it, or we can pull in the kvm
> headers into qemu.
>
> Avi/Marcelo/Jan, any thoughts from the qemu-kvm side?
kvm-kmod-wise, I can include arch and generic kvm_para.h in the next
release (missed the need for it so far). I'm planning to write a qemu
patch to ask pkg-config for kvm-kmod headers.
If we can live with considering the cpuid leaf a feature that depends on
a recent kvm-kmod version and is disabled otherwise, we are done. If
not, tricks like the above are required.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
2010-01-11 20:40 ` [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf Jan Kiszka
@ 2010-01-11 21:36 ` Anthony Liguori
2010-01-11 23:22 ` Jan Kiszka
0 siblings, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2010-01-11 21:36 UTC (permalink / raw)
To: Jan Kiszka
Cc: Avi Kivity, Marcelo Tosatti, qemu-devel, Gleb Natapov, kvm-devel
On 01/11/2010 02:40 PM, Jan Kiszka wrote:
> Anthony Liguori wrote:
>
>> On 01/07/2010 10:24 AM, Gleb Natapov wrote:
>>
>>> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
>>> index 4084503..6a841de 100644
>>> --- a/target-i386/kvm.c
>>> +++ b/target-i386/kvm.c
>>> @@ -17,6 +17,7 @@
>>> #include<sys/mman.h>
>>>
>>> #include<linux/kvm.h>
>>> +#include<linux/kvm_para.h>
>>>
>> This breaks the build on a default F12 install because while kvm.h is
>> present, kvm_para.h is not. This is a hard one to fix.
>>
>> We can default the kvm search path to /lib/modules/$(uname -r)/build, we
>> can fix the glibc headers and live with it, or we can pull in the kvm
>> headers into qemu.
>>
>> Avi/Marcelo/Jan, any thoughts from the qemu-kvm side?
>>
> kvm-kmod-wise, I can include arch and generic kvm_para.h in the next
> release (missed the need for it so far). I'm planning to write a qemu
> patch to ask pkg-config for kvm-kmod headers.
>
That would be nice.
I assume a change has to be made in the kernel too so that the libc
headers are updated. IOW, I assume make headers_install doesn't
currently install kvm_para.h
> If we can live with considering the cpuid leaf a feature that depends on
> a recent kvm-kmod version and is disabled otherwise, we are done. If
> not, tricks like the above are required.
>
It's less than ideal, but I can live with it.
Regards,
Anthony Liguori
> Jan
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
2010-01-11 21:36 ` Anthony Liguori
@ 2010-01-11 23:22 ` Jan Kiszka
0 siblings, 0 replies; 24+ messages in thread
From: Jan Kiszka @ 2010-01-11 23:22 UTC (permalink / raw)
To: Anthony Liguori
Cc: Avi Kivity, Marcelo Tosatti, qemu-devel, Gleb Natapov, kvm-devel
[-- Attachment #1: Type: text/plain, Size: 1364 bytes --]
Anthony Liguori wrote:
> On 01/11/2010 02:40 PM, Jan Kiszka wrote:
>> Anthony Liguori wrote:
>>
>>> On 01/07/2010 10:24 AM, Gleb Natapov wrote:
>>>
>>>> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
>>>> index 4084503..6a841de 100644
>>>> --- a/target-i386/kvm.c
>>>> +++ b/target-i386/kvm.c
>>>> @@ -17,6 +17,7 @@
>>>> #include<sys/mman.h>
>>>>
>>>> #include<linux/kvm.h>
>>>> +#include<linux/kvm_para.h>
>>>>
>>> This breaks the build on a default F12 install because while kvm.h is
>>> present, kvm_para.h is not. This is a hard one to fix.
>>>
>>> We can default the kvm search path to /lib/modules/$(uname -r)/build, we
>>> can fix the glibc headers and live with it, or we can pull in the kvm
>>> headers into qemu.
>>>
>>> Avi/Marcelo/Jan, any thoughts from the qemu-kvm side?
>>>
>> kvm-kmod-wise, I can include arch and generic kvm_para.h in the next
>> release (missed the need for it so far). I'm planning to write a qemu
>> patch to ask pkg-config for kvm-kmod headers.
>>
>
> That would be nice.
>
> I assume a change has to be made in the kernel too so that the libc
> headers are updated. IOW, I assume make headers_install doesn't
> currently install kvm_para.h
I does, I just failed to cherry-pick them from the temporary tree it
creates during 'make sync'.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
2010-01-11 19:18 ` Anthony Liguori
2010-01-11 19:33 ` [Qemu-devel] Registering key events android (qemu based) emulator Anwar Ghani
2010-01-11 20:40 ` [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf Jan Kiszka
@ 2010-01-12 7:23 ` Gleb Natapov
2010-01-12 8:40 ` Avi Kivity
2010-01-12 8:42 ` Avi Kivity
3 siblings, 1 reply; 24+ messages in thread
From: Gleb Natapov @ 2010-01-12 7:23 UTC (permalink / raw)
To: Anthony Liguori
Cc: Marcelo Tosatti, Jan Kiszka, qemu-devel, kvm-devel, Avi Kivity
On Mon, Jan 11, 2010 at 01:18:32PM -0600, Anthony Liguori wrote:
> On 01/07/2010 10:24 AM, Gleb Natapov wrote:
> >diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> >index 4084503..6a841de 100644
> >--- a/target-i386/kvm.c
> >+++ b/target-i386/kvm.c
> >@@ -17,6 +17,7 @@
> > #include<sys/mman.h>
> >
> > #include<linux/kvm.h>
> >+#include<linux/kvm_para.h>
>
> This breaks the build on a default F12 install because while kvm.h
> is present, kvm_para.h is not. This is a hard one to fix.
>
Avi how qemu-kvm compiles there? Or it doesn't?
> We can default the kvm search path to /lib/modules/$(uname
> -r)/build, we can fix the glibc headers and live with it, or we can
> pull in the kvm headers into qemu.
>
> Avi/Marcelo/Jan, any thoughts from the qemu-kvm side?
>
> Regards,
>
> Anthony Liguori
--
Gleb.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
2010-01-12 7:23 ` Gleb Natapov
@ 2010-01-12 8:40 ` Avi Kivity
0 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-01-12 8:40 UTC (permalink / raw)
To: Gleb Natapov; +Cc: Marcelo Tosatti, Jan Kiszka, qemu-devel, kvm-devel
On 01/12/2010 09:23 AM, Gleb Natapov wrote:
> On Mon, Jan 11, 2010 at 01:18:32PM -0600, Anthony Liguori wrote:
>
>> On 01/07/2010 10:24 AM, Gleb Natapov wrote:
>>
>>> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
>>> index 4084503..6a841de 100644
>>> --- a/target-i386/kvm.c
>>> +++ b/target-i386/kvm.c
>>> @@ -17,6 +17,7 @@
>>> #include<sys/mman.h>
>>>
>>> #include<linux/kvm.h>
>>> +#include<linux/kvm_para.h>
>>>
>> This breaks the build on a default F12 install because while kvm.h
>> is present, kvm_para.h is not. This is a hard one to fix.
>>
>>
> Avi how qemu-kvm compiles there? Or it doesn't?
>
>
include/linux/Kbuild has:
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \
$(srctree)/include/asm-$(SRCARCH)/kvm.h),)
unifdef-y += kvm.h
endif
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \
$(srctree)/include/asm-$(SRCARCH)/kvm_para.h),)
unifdef-y += kvm_para.h
endif
So it should be installed. Unfortunately this is starting 2.6.32, so we
need to backport the patch (da18acffc3) to the F12 kernel.
qemu-kvm doesn't depend on installed headers.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf
2010-01-11 19:18 ` Anthony Liguori
` (2 preceding siblings ...)
2010-01-12 7:23 ` Gleb Natapov
@ 2010-01-12 8:42 ` Avi Kivity
3 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-01-12 8:42 UTC (permalink / raw)
To: Anthony Liguori
Cc: Marcelo Tosatti, Jan Kiszka, qemu-devel, Gleb Natapov, kvm-devel
On 01/11/2010 09:18 PM, Anthony Liguori wrote:
> On 01/07/2010 10:24 AM, Gleb Natapov wrote:
>> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
>> index 4084503..6a841de 100644
>> --- a/target-i386/kvm.c
>> +++ b/target-i386/kvm.c
>> @@ -17,6 +17,7 @@
>> #include<sys/mman.h>
>>
>> #include<linux/kvm.h>
>> +#include<linux/kvm_para.h>
>
> This breaks the build on a default F12 install because while kvm.h is
> present, kvm_para.h is not. This is a hard one to fix.
>
> We can default the kvm search path to /lib/modules/$(uname -r)/build,
> we can fix the glibc headers and live with it, or we can pull in the
> kvm headers into qemu.
>
> Avi/Marcelo/Jan, any thoughts from the qemu-kvm side?
>
Two options:
- make kvm detection depend on kvm_para.h being includable, fix all
relevant distro kernels to supply it, and live with the breakage
- add a new CONFIG_KVM_PARA, detect it at configure time, and only
include it if present
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCHv3] Add KVM paravirt cpuid leaf
2010-01-07 16:24 ` [Qemu-devel] [PATCHv2] " Gleb Natapov
2010-01-11 19:18 ` Anthony Liguori
@ 2010-01-13 13:25 ` Gleb Natapov
2010-01-13 16:05 ` Anthony Liguori
2010-01-13 23:28 ` Anthony Liguori
1 sibling, 2 replies; 24+ messages in thread
From: Gleb Natapov @ 2010-01-13 13:25 UTC (permalink / raw)
To: qemu-devel; +Cc: avi
Initialize KVM paravirt cpuid leaf and allow user to control guest
visible PV features through -cpu flag.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
v1->v2
fix indentation
remove unneeded ifdefs
v2->v3
added needed ifdefs (CONFIG_KVM_PARA)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index f3834b3..216b00e 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -701,7 +701,8 @@ typedef struct CPUX86State {
uint8_t nmi_pending;
uint8_t has_error_code;
uint32_t sipi_vector;
-
+ uint32_t cpuid_kvm_features;
+
/* in order to simplify APIC support, we leave this pointer to the
user */
struct APICState *apic_state;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 049fccf..70762bb 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -58,10 +58,18 @@ static const char *ext3_feature_name[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
+static const char *kvm_feature_name[] = {
+ "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL, NULL, NULL, NULL,
+};
+
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
uint32_t *ext_features,
uint32_t *ext2_features,
- uint32_t *ext3_features)
+ uint32_t *ext3_features,
+ uint32_t *kvm_features)
{
int i;
int found = 0;
@@ -86,6 +94,12 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
*ext3_features |= 1 << i;
found = 1;
}
+ for ( i = 0 ; i < 32 ; i++ )
+ if (kvm_feature_name[i] && !strcmp (flagname, kvm_feature_name[i])) {
+ *kvm_features |= 1 << i;
+ found = 1;
+ }
+
if (!found) {
fprintf(stderr, "CPU feature %s not found\n", flagname);
}
@@ -98,7 +112,7 @@ typedef struct x86_def_t {
int family;
int model;
int stepping;
- uint32_t features, ext_features, ext2_features, ext3_features;
+ uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
uint32_t xlevel;
char model_id[48];
int vendor_override;
@@ -375,8 +389,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
char *s = strdup(cpu_model);
char *featurestr, *name = strtok(s, ",");
- uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
- uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
+ uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
+ uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
uint32_t numvalue;
def = NULL;
@@ -394,17 +408,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
memcpy(x86_cpu_def, def, sizeof(*def));
}
+ plus_kvm_features = ~0; /* not supported bits will be filtered out later */
+
add_flagname_to_bitmaps("hypervisor", &plus_features,
- &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+ &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
+ &plus_kvm_features);
featurestr = strtok(NULL, ",");
while (featurestr) {
char *val;
if (featurestr[0] == '+') {
- add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
+ add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features);
} else if (featurestr[0] == '-') {
- add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
+ add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features, &minus_kvm_features);
} else if ((val = strchr(featurestr, '='))) {
*val = 0; val++;
if (!strcmp(featurestr, "family")) {
@@ -481,10 +498,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
x86_cpu_def->ext_features |= plus_ext_features;
x86_cpu_def->ext2_features |= plus_ext2_features;
x86_cpu_def->ext3_features |= plus_ext3_features;
+ x86_cpu_def->kvm_features |= plus_kvm_features;
x86_cpu_def->features &= ~minus_features;
x86_cpu_def->ext_features &= ~minus_ext_features;
x86_cpu_def->ext2_features &= ~minus_ext2_features;
x86_cpu_def->ext3_features &= ~minus_ext3_features;
+ x86_cpu_def->kvm_features &= ~minus_kvm_features;
free(s);
return 0;
@@ -529,7 +548,7 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
env->cpuid_ext_features = def->ext_features;
env->cpuid_ext2_features = def->ext2_features;
env->cpuid_xlevel = def->xlevel;
- env->cpuid_ext3_features = def->ext3_features;
+ env->cpuid_kvm_features = def->kvm_features;
{
const char *model_id = def->model_id;
int c, len, i;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 4084503..5b093ce 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -25,6 +25,10 @@
#include "gdbstub.h"
#include "host-utils.h"
+#ifdef CONFIG_KVM_PARA
+#include <linux/kvm_para.h>
+#endif
+//
//#define DEBUG_KVM
#ifdef DEBUG_KVM
@@ -134,6 +138,39 @@ static void kvm_trim_features(uint32_t *features, uint32_t supported)
}
}
+#ifdef CONFIG_KVM_PARA
+struct kvm_para_features {
+ int cap;
+ int feature;
+} para_features[] = {
+#ifdef KVM_CAP_CLOCKSOURCE
+ { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
+#endif
+#ifdef KVM_CAP_NOP_IO_DELAY
+ { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
+#endif
+#ifdef KVM_CAP_PV_MMU
+ { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
+#endif
+#ifdef KVM_CAP_CR3_CACHE
+ { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
+#endif
+ { -1, -1 }
+};
+
+static int get_para_features(CPUState *env)
+{
+ int i, features = 0;
+
+ for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
+ if (kvm_check_extension(env->kvm_state, para_features[i].cap))
+ features |= (1 << para_features[i].feature);
+ }
+
+ return features;
+}
+#endif
+
int kvm_arch_init_vcpu(CPUState *env)
{
struct {
@@ -142,6 +179,10 @@ int kvm_arch_init_vcpu(CPUState *env)
} __attribute__((packed)) cpuid_data;
uint32_t limit, i, j, cpuid_i;
uint32_t unused;
+ struct kvm_cpuid_entry2 *c;
+#ifdef KVM_CPUID_SIGNATURE
+ uint32_t signature[3];
+#endif
env->mp_state = KVM_MP_STATE_RUNNABLE;
@@ -160,10 +201,27 @@ int kvm_arch_init_vcpu(CPUState *env)
cpuid_i = 0;
+#ifdef CONFIG_KVM_PARA
+ /* Paravirtualization CPUIDs */
+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_SIGNATURE;
+ c->eax = 0;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
+
+ c = &cpuid_data.entries[cpuid_i++];
+ memset(c, 0, sizeof(*c));
+ c->function = KVM_CPUID_FEATURES;
+ c->eax = env->cpuid_kvm_features & get_para_features(env);
+#endif
+
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
for (i = 0; i <= limit; i++) {
- struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
+ c = &cpuid_data.entries[cpuid_i++];
switch (i) {
case 2: {
@@ -213,7 +271,7 @@ int kvm_arch_init_vcpu(CPUState *env)
cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused);
for (i = 0x80000000; i <= limit; i++) {
- struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];
+ c = &cpuid_data.entries[cpuid_i++];
c->function = i;
c->flags = 0;
--
Gleb.
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv3] Add KVM paravirt cpuid leaf
2010-01-13 13:25 ` [Qemu-devel] [PATCHv3] " Gleb Natapov
@ 2010-01-13 16:05 ` Anthony Liguori
2010-01-13 16:14 ` Gleb Natapov
2010-01-13 23:28 ` Anthony Liguori
1 sibling, 1 reply; 24+ messages in thread
From: Anthony Liguori @ 2010-01-13 16:05 UTC (permalink / raw)
To: Gleb Natapov; +Cc: qemu-devel, avi
On 01/13/2010 07:25 AM, Gleb Natapov wrote:
> Initialize KVM paravirt cpuid leaf and allow user to control guest
> visible PV features through -cpu flag.
>
> Signed-off-by: Gleb Natapov<gleb@redhat.com>
> ---
> v1->v2
> fix indentation
> remove unneeded ifdefs
> v2->v3
> added needed ifdefs (CONFIG_KVM_PARA)
>
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index f3834b3..216b00e 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -701,7 +701,8 @@ typedef struct CPUX86State {
> uint8_t nmi_pending;
> uint8_t has_error_code;
> uint32_t sipi_vector;
> -
> + uint32_t cpuid_kvm_features;
> +
> /* in order to simplify APIC support, we leave this pointer to the
> user */
> struct APICState *apic_state;
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 049fccf..70762bb 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -58,10 +58,18 @@ static const char *ext3_feature_name[] = {
> NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> };
>
> +static const char *kvm_feature_name[] = {
> + "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL, NULL, NULL, NULL,
> +};
> +
> static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> uint32_t *ext_features,
> uint32_t *ext2_features,
> - uint32_t *ext3_features)
> + uint32_t *ext3_features,
> + uint32_t *kvm_features)
> {
> int i;
> int found = 0;
> @@ -86,6 +94,12 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> *ext3_features |= 1<< i;
> found = 1;
> }
> + for ( i = 0 ; i< 32 ; i++ )
> + if (kvm_feature_name[i]&& !strcmp (flagname, kvm_feature_name[i])) {
> + *kvm_features |= 1<< i;
> + found = 1;
> + }
> +
> if (!found) {
> fprintf(stderr, "CPU feature %s not found\n", flagname);
> }
> @@ -98,7 +112,7 @@ typedef struct x86_def_t {
> int family;
> int model;
> int stepping;
> - uint32_t features, ext_features, ext2_features, ext3_features;
> + uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
> uint32_t xlevel;
> char model_id[48];
> int vendor_override;
> @@ -375,8 +389,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>
> char *s = strdup(cpu_model);
> char *featurestr, *name = strtok(s, ",");
> - uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
> - uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
> + uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
> + uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
> uint32_t numvalue;
>
> def = NULL;
> @@ -394,17 +408,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> memcpy(x86_cpu_def, def, sizeof(*def));
> }
>
> + plus_kvm_features = ~0; /* not supported bits will be filtered out later */
> +
> add_flagname_to_bitmaps("hypervisor",&plus_features,
> -&plus_ext_features,&plus_ext2_features,&plus_ext3_features);
> +&plus_ext_features,&plus_ext2_features,&plus_ext3_features,
> +&plus_kvm_features);
>
> featurestr = strtok(NULL, ",");
>
> while (featurestr) {
> char *val;
> if (featurestr[0] == '+') {
> - add_flagname_to_bitmaps(featurestr + 1,&plus_features,&plus_ext_features,&plus_ext2_features,&plus_ext3_features);
> + add_flagname_to_bitmaps(featurestr + 1,&plus_features,&plus_ext_features,&plus_ext2_features,&plus_ext3_features,&plus_kvm_features);
> } else if (featurestr[0] == '-') {
> - add_flagname_to_bitmaps(featurestr + 1,&minus_features,&minus_ext_features,&minus_ext2_features,&minus_ext3_features);
> + add_flagname_to_bitmaps(featurestr + 1,&minus_features,&minus_ext_features,&minus_ext2_features,&minus_ext3_features,&minus_kvm_features);
> } else if ((val = strchr(featurestr, '='))) {
> *val = 0; val++;
> if (!strcmp(featurestr, "family")) {
> @@ -481,10 +498,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> x86_cpu_def->ext_features |= plus_ext_features;
> x86_cpu_def->ext2_features |= plus_ext2_features;
> x86_cpu_def->ext3_features |= plus_ext3_features;
> + x86_cpu_def->kvm_features |= plus_kvm_features;
> x86_cpu_def->features&= ~minus_features;
> x86_cpu_def->ext_features&= ~minus_ext_features;
> x86_cpu_def->ext2_features&= ~minus_ext2_features;
> x86_cpu_def->ext3_features&= ~minus_ext3_features;
> + x86_cpu_def->kvm_features&= ~minus_kvm_features;
> free(s);
> return 0;
>
> @@ -529,7 +548,7 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
> env->cpuid_ext_features = def->ext_features;
> env->cpuid_ext2_features = def->ext2_features;
> env->cpuid_xlevel = def->xlevel;
> - env->cpuid_ext3_features = def->ext3_features;
> + env->cpuid_kvm_features = def->kvm_features;
> {
> const char *model_id = def->model_id;
> int c, len, i;
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 4084503..5b093ce 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -25,6 +25,10 @@
> #include "gdbstub.h"
> #include "host-utils.h"
>
> +#ifdef CONFIG_KVM_PARA
> +#include<linux/kvm_para.h>
> +#endif
> +//
> //#define DEBUG_KVM
>
> #ifdef DEBUG_KVM
> @@ -134,6 +138,39 @@ static void kvm_trim_features(uint32_t *features, uint32_t supported)
> }
> }
>
> +#ifdef CONFIG_KVM_PARA
> +struct kvm_para_features {
> + int cap;
> + int feature;
> +} para_features[] = {
> +#ifdef KVM_CAP_CLOCKSOURCE
> + { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
> +#endif
> +#ifdef KVM_CAP_NOP_IO_DELAY
> + { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
> +#endif
> +#ifdef KVM_CAP_PV_MMU
> + { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
> +#endif
> +#ifdef KVM_CAP_CR3_CACHE
> + { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
> +#endif
> + { -1, -1 }
> +};
> +
> +static int get_para_features(CPUState *env)
> +{
> + int i, features = 0;
> +
> + for (i = 0; i< ARRAY_SIZE(para_features) - 1; i++) {
> + if (kvm_check_extension(env->kvm_state, para_features[i].cap))
> + features |= (1<< para_features[i].feature);
> + }
> +
> + return features;
> +}
> +#endif
> +
> int kvm_arch_init_vcpu(CPUState *env)
> {
> struct {
> @@ -142,6 +179,10 @@ int kvm_arch_init_vcpu(CPUState *env)
> } __attribute__((packed)) cpuid_data;
> uint32_t limit, i, j, cpuid_i;
> uint32_t unused;
> + struct kvm_cpuid_entry2 *c;
> +#ifdef KVM_CPUID_SIGNATURE
> + uint32_t signature[3];
> +#endif
>
> env->mp_state = KVM_MP_STATE_RUNNABLE;
>
> @@ -160,10 +201,27 @@ int kvm_arch_init_vcpu(CPUState *env)
>
> cpuid_i = 0;
>
> +#ifdef CONFIG_KVM_PARA
> + /* Paravirtualization CPUIDs */
> + memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> + c =&cpuid_data.entries[cpuid_i++];
> + memset(c, 0, sizeof(*c));
> + c->function = KVM_CPUID_SIGNATURE;
> + c->eax = 0;
> + c->ebx = signature[0];
> + c->ecx = signature[1];
> + c->edx = signature[2];
> +
> + c =&cpuid_data.entries[cpuid_i++];
> + memset(c, 0, sizeof(*c));
> + c->function = KVM_CPUID_FEATURES;
> + c->eax = env->cpuid_kvm_features& get_para_features(env);
> +#endif
> +
> cpu_x86_cpuid(env, 0, 0,&limit,&unused,&unused,&unused);
Instead of hooking here, would it make more sense to tie into the
generic cpuid function in helper.c?
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv3] Add KVM paravirt cpuid leaf
2010-01-13 16:05 ` Anthony Liguori
@ 2010-01-13 16:14 ` Gleb Natapov
2010-01-13 16:23 ` Gleb Natapov
0 siblings, 1 reply; 24+ messages in thread
From: Gleb Natapov @ 2010-01-13 16:14 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, avi
On Wed, Jan 13, 2010 at 10:05:33AM -0600, Anthony Liguori wrote:
> >+#ifdef CONFIG_KVM_PARA
> >+ /* Paravirtualization CPUIDs */
> >+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> >+ c =&cpuid_data.entries[cpuid_i++];
> >+ memset(c, 0, sizeof(*c));
> >+ c->function = KVM_CPUID_SIGNATURE;
> >+ c->eax = 0;
> >+ c->ebx = signature[0];
> >+ c->ecx = signature[1];
> >+ c->edx = signature[2];
> >+
> >+ c =&cpuid_data.entries[cpuid_i++];
> >+ memset(c, 0, sizeof(*c));
> >+ c->function = KVM_CPUID_FEATURES;
> >+ c->eax = env->cpuid_kvm_features& get_para_features(env);
> >+#endif
> >+
> > cpu_x86_cpuid(env, 0, 0,&limit,&unused,&unused,&unused);
>
> Instead of hooking here, would it make more sense to tie into the
> generic cpuid function in helper.c?
>
What do you mean? This patch ties into generic cpuid function in
helper.c and pars kvm cpu flags there. Here we just configure
kernel.
--
Gleb.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv3] Add KVM paravirt cpuid leaf
2010-01-13 16:14 ` Gleb Natapov
@ 2010-01-13 16:23 ` Gleb Natapov
2010-01-13 16:57 ` Anthony Liguori
0 siblings, 1 reply; 24+ messages in thread
From: Gleb Natapov @ 2010-01-13 16:23 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, avi
On Wed, Jan 13, 2010 at 06:14:54PM +0200, Gleb Natapov wrote:
> On Wed, Jan 13, 2010 at 10:05:33AM -0600, Anthony Liguori wrote:
> > >+#ifdef CONFIG_KVM_PARA
> > >+ /* Paravirtualization CPUIDs */
> > >+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> > >+ c =&cpuid_data.entries[cpuid_i++];
> > >+ memset(c, 0, sizeof(*c));
> > >+ c->function = KVM_CPUID_SIGNATURE;
> > >+ c->eax = 0;
> > >+ c->ebx = signature[0];
> > >+ c->ecx = signature[1];
> > >+ c->edx = signature[2];
> > >+
> > >+ c =&cpuid_data.entries[cpuid_i++];
> > >+ memset(c, 0, sizeof(*c));
> > >+ c->function = KVM_CPUID_FEATURES;
> > >+ c->eax = env->cpuid_kvm_features& get_para_features(env);
> > >+#endif
> > >+
> > > cpu_x86_cpuid(env, 0, 0,&limit,&unused,&unused,&unused);
> >
> > Instead of hooking here, would it make more sense to tie into the
> > generic cpuid function in helper.c?
> >
> What do you mean? This patch ties into generic cpuid function in
> helper.c and pars kvm cpu flags there. Here we just configure
> kernel.
>
Or do you mean making so that PV leaf will be available via
cpu_x86_cpuid()? This make sense, but lets do it after merging this
code path with qemu-kvm and the proposed patch brings qemu and
qemu-kvm close together.
--
Gleb.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv3] Add KVM paravirt cpuid leaf
2010-01-13 16:23 ` Gleb Natapov
@ 2010-01-13 16:57 ` Anthony Liguori
0 siblings, 0 replies; 24+ messages in thread
From: Anthony Liguori @ 2010-01-13 16:57 UTC (permalink / raw)
To: Gleb Natapov; +Cc: qemu-devel, avi
On 01/13/2010 10:23 AM, Gleb Natapov wrote:
> Or do you mean making so that PV leaf will be available via
> cpu_x86_cpuid()? This make sense, but lets do it after merging this
> code path with qemu-kvm and the proposed patch brings qemu and
> qemu-kvm close together.
>
Yes, that's what I meant, and yes, I think that's a fine approach.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCHv3] Add KVM paravirt cpuid leaf
2010-01-13 13:25 ` [Qemu-devel] [PATCHv3] " Gleb Natapov
2010-01-13 16:05 ` Anthony Liguori
@ 2010-01-13 23:28 ` Anthony Liguori
1 sibling, 0 replies; 24+ messages in thread
From: Anthony Liguori @ 2010-01-13 23:28 UTC (permalink / raw)
To: Gleb Natapov; +Cc: qemu-devel, avi
On 01/13/2010 07:25 AM, Gleb Natapov wrote:
> Initialize KVM paravirt cpuid leaf and allow user to control guest
> visible PV features through -cpu flag.
>
> Signed-off-by: Gleb Natapov<gleb@redhat.com>
>
Applied. Thanks.
Regards,
Anthony Liguori
> ---
> v1->v2
> fix indentation
> remove unneeded ifdefs
> v2->v3
> added needed ifdefs (CONFIG_KVM_PARA)
>
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index f3834b3..216b00e 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -701,7 +701,8 @@ typedef struct CPUX86State {
> uint8_t nmi_pending;
> uint8_t has_error_code;
> uint32_t sipi_vector;
> -
> + uint32_t cpuid_kvm_features;
> +
> /* in order to simplify APIC support, we leave this pointer to the
> user */
> struct APICState *apic_state;
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 049fccf..70762bb 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -58,10 +58,18 @@ static const char *ext3_feature_name[] = {
> NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> };
>
> +static const char *kvm_feature_name[] = {
> + "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL, NULL, NULL, NULL,
> +};
> +
> static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> uint32_t *ext_features,
> uint32_t *ext2_features,
> - uint32_t *ext3_features)
> + uint32_t *ext3_features,
> + uint32_t *kvm_features)
> {
> int i;
> int found = 0;
> @@ -86,6 +94,12 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> *ext3_features |= 1<< i;
> found = 1;
> }
> + for ( i = 0 ; i< 32 ; i++ )
> + if (kvm_feature_name[i]&& !strcmp (flagname, kvm_feature_name[i])) {
> + *kvm_features |= 1<< i;
> + found = 1;
> + }
> +
> if (!found) {
> fprintf(stderr, "CPU feature %s not found\n", flagname);
> }
> @@ -98,7 +112,7 @@ typedef struct x86_def_t {
> int family;
> int model;
> int stepping;
> - uint32_t features, ext_features, ext2_features, ext3_features;
> + uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
> uint32_t xlevel;
> char model_id[48];
> int vendor_override;
> @@ -375,8 +389,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
>
> char *s = strdup(cpu_model);
> char *featurestr, *name = strtok(s, ",");
> - uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
> - uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
> + uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
> + uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
> uint32_t numvalue;
>
> def = NULL;
> @@ -394,17 +408,20 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> memcpy(x86_cpu_def, def, sizeof(*def));
> }
>
> + plus_kvm_features = ~0; /* not supported bits will be filtered out later */
> +
> add_flagname_to_bitmaps("hypervisor",&plus_features,
> -&plus_ext_features,&plus_ext2_features,&plus_ext3_features);
> +&plus_ext_features,&plus_ext2_features,&plus_ext3_features,
> +&plus_kvm_features);
>
> featurestr = strtok(NULL, ",");
>
> while (featurestr) {
> char *val;
> if (featurestr[0] == '+') {
> - add_flagname_to_bitmaps(featurestr + 1,&plus_features,&plus_ext_features,&plus_ext2_features,&plus_ext3_features);
> + add_flagname_to_bitmaps(featurestr + 1,&plus_features,&plus_ext_features,&plus_ext2_features,&plus_ext3_features,&plus_kvm_features);
> } else if (featurestr[0] == '-') {
> - add_flagname_to_bitmaps(featurestr + 1,&minus_features,&minus_ext_features,&minus_ext2_features,&minus_ext3_features);
> + add_flagname_to_bitmaps(featurestr + 1,&minus_features,&minus_ext_features,&minus_ext2_features,&minus_ext3_features,&minus_kvm_features);
> } else if ((val = strchr(featurestr, '='))) {
> *val = 0; val++;
> if (!strcmp(featurestr, "family")) {
> @@ -481,10 +498,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> x86_cpu_def->ext_features |= plus_ext_features;
> x86_cpu_def->ext2_features |= plus_ext2_features;
> x86_cpu_def->ext3_features |= plus_ext3_features;
> + x86_cpu_def->kvm_features |= plus_kvm_features;
> x86_cpu_def->features&= ~minus_features;
> x86_cpu_def->ext_features&= ~minus_ext_features;
> x86_cpu_def->ext2_features&= ~minus_ext2_features;
> x86_cpu_def->ext3_features&= ~minus_ext3_features;
> + x86_cpu_def->kvm_features&= ~minus_kvm_features;
> free(s);
> return 0;
>
> @@ -529,7 +548,7 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
> env->cpuid_ext_features = def->ext_features;
> env->cpuid_ext2_features = def->ext2_features;
> env->cpuid_xlevel = def->xlevel;
> - env->cpuid_ext3_features = def->ext3_features;
> + env->cpuid_kvm_features = def->kvm_features;
> {
> const char *model_id = def->model_id;
> int c, len, i;
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 4084503..5b093ce 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -25,6 +25,10 @@
> #include "gdbstub.h"
> #include "host-utils.h"
>
> +#ifdef CONFIG_KVM_PARA
> +#include<linux/kvm_para.h>
> +#endif
> +//
> //#define DEBUG_KVM
>
> #ifdef DEBUG_KVM
> @@ -134,6 +138,39 @@ static void kvm_trim_features(uint32_t *features, uint32_t supported)
> }
> }
>
> +#ifdef CONFIG_KVM_PARA
> +struct kvm_para_features {
> + int cap;
> + int feature;
> +} para_features[] = {
> +#ifdef KVM_CAP_CLOCKSOURCE
> + { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
> +#endif
> +#ifdef KVM_CAP_NOP_IO_DELAY
> + { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
> +#endif
> +#ifdef KVM_CAP_PV_MMU
> + { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
> +#endif
> +#ifdef KVM_CAP_CR3_CACHE
> + { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
> +#endif
> + { -1, -1 }
> +};
> +
> +static int get_para_features(CPUState *env)
> +{
> + int i, features = 0;
> +
> + for (i = 0; i< ARRAY_SIZE(para_features) - 1; i++) {
> + if (kvm_check_extension(env->kvm_state, para_features[i].cap))
> + features |= (1<< para_features[i].feature);
> + }
> +
> + return features;
> +}
> +#endif
> +
> int kvm_arch_init_vcpu(CPUState *env)
> {
> struct {
> @@ -142,6 +179,10 @@ int kvm_arch_init_vcpu(CPUState *env)
> } __attribute__((packed)) cpuid_data;
> uint32_t limit, i, j, cpuid_i;
> uint32_t unused;
> + struct kvm_cpuid_entry2 *c;
> +#ifdef KVM_CPUID_SIGNATURE
> + uint32_t signature[3];
> +#endif
>
> env->mp_state = KVM_MP_STATE_RUNNABLE;
>
> @@ -160,10 +201,27 @@ int kvm_arch_init_vcpu(CPUState *env)
>
> cpuid_i = 0;
>
> +#ifdef CONFIG_KVM_PARA
> + /* Paravirtualization CPUIDs */
> + memcpy(signature, "KVMKVMKVM\0\0\0", 12);
> + c =&cpuid_data.entries[cpuid_i++];
> + memset(c, 0, sizeof(*c));
> + c->function = KVM_CPUID_SIGNATURE;
> + c->eax = 0;
> + c->ebx = signature[0];
> + c->ecx = signature[1];
> + c->edx = signature[2];
> +
> + c =&cpuid_data.entries[cpuid_i++];
> + memset(c, 0, sizeof(*c));
> + c->function = KVM_CPUID_FEATURES;
> + c->eax = env->cpuid_kvm_features& get_para_features(env);
> +#endif
> +
> cpu_x86_cpuid(env, 0, 0,&limit,&unused,&unused,&unused);
>
> for (i = 0; i<= limit; i++) {
> - struct kvm_cpuid_entry2 *c =&cpuid_data.entries[cpuid_i++];
> + c =&cpuid_data.entries[cpuid_i++];
>
> switch (i) {
> case 2: {
> @@ -213,7 +271,7 @@ int kvm_arch_init_vcpu(CPUState *env)
> cpu_x86_cpuid(env, 0x80000000, 0,&limit,&unused,&unused,&unused);
>
> for (i = 0x80000000; i<= limit; i++) {
> - struct kvm_cpuid_entry2 *c =&cpuid_data.entries[cpuid_i++];
> + c =&cpuid_data.entries[cpuid_i++];
>
> c->function = i;
> c->flags = 0;
> --
> Gleb.
>
>
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2010-01-13 23:28 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-07 12:44 [Qemu-devel] [PATCH] Add KVM paravirt cpuid leaf Gleb Natapov
2010-01-07 16:09 ` Anthony Liguori
2010-01-07 16:15 ` Gleb Natapov
2010-01-07 16:53 ` Anthony Liguori
2010-01-07 16:56 ` Avi Kivity
2010-01-07 17:08 ` Gleb Natapov
2010-01-07 18:02 ` Anthony Liguori
2010-01-07 18:10 ` Gleb Natapov
2010-01-07 16:59 ` Gleb Natapov
2010-01-07 16:24 ` [Qemu-devel] [PATCHv2] " Gleb Natapov
2010-01-11 19:18 ` Anthony Liguori
2010-01-11 19:33 ` [Qemu-devel] Registering key events android (qemu based) emulator Anwar Ghani
2010-01-11 20:40 ` [Qemu-devel] [PATCHv2] Add KVM paravirt cpuid leaf Jan Kiszka
2010-01-11 21:36 ` Anthony Liguori
2010-01-11 23:22 ` Jan Kiszka
2010-01-12 7:23 ` Gleb Natapov
2010-01-12 8:40 ` Avi Kivity
2010-01-12 8:42 ` Avi Kivity
2010-01-13 13:25 ` [Qemu-devel] [PATCHv3] " Gleb Natapov
2010-01-13 16:05 ` Anthony Liguori
2010-01-13 16:14 ` Gleb Natapov
2010-01-13 16:23 ` Gleb Natapov
2010-01-13 16:57 ` Anthony Liguori
2010-01-13 23:28 ` Anthony Liguori
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).