Merge remote-tracking branch 'qemu-kvm/uq/master' into staging

* qemu-kvm/uq/master:
  target-i386: kvm: prevent buffer overflow if -cpu foo, [x]level is too big
  vmxcap: bit 9 of VMX_PROCBASED_CTLS2 is 'virtual interrupt delivery'

Conflicts:
	target-i386/kvm.c

Trivial merge resolution due to lack of context.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori 2013-01-29 16:57:41 -06:00
commit 0893d46014
2 changed files with 26 additions and 1 deletions

View File

@ -147,6 +147,7 @@ controls = [
5: 'Enable VPID', 5: 'Enable VPID',
6: 'WBINVD exiting', 6: 'WBINVD exiting',
7: 'Unrestricted guest', 7: 'Unrestricted guest',
9: 'Virtual interrupt delivery',
10: 'PAUSE-loop exiting', 10: 'PAUSE-loop exiting',
11: 'RDRAND exiting', 11: 'RDRAND exiting',
12: 'Enable INVPCID', 12: 'Enable INVPCID',

View File

@ -417,11 +417,13 @@ unsigned long kvm_arch_vcpu_id(CPUState *cs)
return cpu->env.cpuid_apic_id; return cpu->env.cpuid_apic_id;
} }
#define KVM_MAX_CPUID_ENTRIES 100
int kvm_arch_init_vcpu(CPUState *cs) int kvm_arch_init_vcpu(CPUState *cs)
{ {
struct { struct {
struct kvm_cpuid2 cpuid; struct kvm_cpuid2 cpuid;
struct kvm_cpuid_entry2 entries[100]; struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES];
} QEMU_PACKED cpuid_data; } QEMU_PACKED cpuid_data;
X86CPU *cpu = X86_CPU(cs); X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
@ -508,6 +510,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
for (i = 0; i <= limit; i++) { for (i = 0; i <= limit; i++) {
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
fprintf(stderr, "unsupported level value: 0x%x\n", limit);
abort();
}
c = &cpuid_data.entries[cpuid_i++]; c = &cpuid_data.entries[cpuid_i++];
switch (i) { switch (i) {
@ -522,6 +528,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
times = c->eax & 0xff; times = c->eax & 0xff;
for (j = 1; j < times; ++j) { for (j = 1; j < times; ++j) {
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
fprintf(stderr, "cpuid_data is full, no space for "
"cpuid(eax:2):eax & 0xf = 0x%x\n", times);
abort();
}
c = &cpuid_data.entries[cpuid_i++]; c = &cpuid_data.entries[cpuid_i++];
c->function = i; c->function = i;
c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC; c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC;
@ -550,6 +561,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (i == 0xd && c->eax == 0) { if (i == 0xd && c->eax == 0) {
continue; continue;
} }
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
fprintf(stderr, "cpuid_data is full, no space for "
"cpuid(eax:0x%x,ecx:0x%x)\n", i, j);
abort();
}
c = &cpuid_data.entries[cpuid_i++]; c = &cpuid_data.entries[cpuid_i++];
} }
break; break;
@ -563,6 +579,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused); cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused);
for (i = 0x80000000; i <= limit; i++) { for (i = 0x80000000; i <= limit; i++) {
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
fprintf(stderr, "unsupported xlevel value: 0x%x\n", limit);
abort();
}
c = &cpuid_data.entries[cpuid_i++]; c = &cpuid_data.entries[cpuid_i++];
c->function = i; c->function = i;
@ -575,6 +595,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unused); cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unused);
for (i = 0xC0000000; i <= limit; i++) { for (i = 0xC0000000; i <= limit; i++) {
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
fprintf(stderr, "unsupported xlevel2 value: 0x%x\n", limit);
abort();
}
c = &cpuid_data.entries[cpuid_i++]; c = &cpuid_data.entries[cpuid_i++];
c->function = i; c->function = i;