aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Bärwolf <stephan.baerwolf@tu-ilmenau.de>2012-01-12 10:43:03 -0500
committerAvi Kivity <avi@redhat.com>2012-02-01 04:43:33 -0500
commitbdb42f5afebe208eae90406959383856ae2caf2b (patch)
treee58d3b8aedf30b9f42689a7d0ee752600be3f938
parent50e92b3c971129c96a5fffb51dd42691e2ee4004 (diff)
KVM: x86: extend "struct x86_emulate_ops" with "get_cpuid"
In order to be able to proceed checks on CPU-specific properties within the emulator, function "get_cpuid" is introduced. With "get_cpuid" it is possible to virtually call the guests "cpuid"-opcode without changing the VM's context. [mtosatti: cleanup/beautify code] Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_emulate.h3
-rw-r--r--arch/x86/kvm/x86.c23
2 files changed, 26 insertions, 0 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index ab4092e3214e..c8b28689eeeb 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -190,6 +190,9 @@ struct x86_emulate_ops {
190 int (*intercept)(struct x86_emulate_ctxt *ctxt, 190 int (*intercept)(struct x86_emulate_ctxt *ctxt,
191 struct x86_instruction_info *info, 191 struct x86_instruction_info *info,
192 enum x86_intercept_stage stage); 192 enum x86_intercept_stage stage);
193
194 bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
195 u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
193}; 196};
194 197
195typedef u32 __attribute__((vector_size(16))) sse128_t; 198typedef u32 __attribute__((vector_size(16))) sse128_t;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 14d6cadc4ba6..8c890e2fa6b6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4180,6 +4180,28 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
4180 return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage); 4180 return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
4181} 4181}
4182 4182
4183static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
4184 u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
4185{
4186 struct kvm_cpuid_entry2 *cpuid = NULL;
4187
4188 if (eax && ecx)
4189 cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt),
4190 *eax, *ecx);
4191
4192 if (cpuid) {
4193 *eax = cpuid->eax;
4194 *ecx = cpuid->ecx;
4195 if (ebx)
4196 *ebx = cpuid->ebx;
4197 if (edx)
4198 *edx = cpuid->edx;
4199 return true;
4200 }
4201
4202 return false;
4203}
4204
4183static struct x86_emulate_ops emulate_ops = { 4205static struct x86_emulate_ops emulate_ops = {
4184 .read_std = kvm_read_guest_virt_system, 4206 .read_std = kvm_read_guest_virt_system,
4185 .write_std = kvm_write_guest_virt_system, 4207 .write_std = kvm_write_guest_virt_system,
@@ -4211,6 +4233,7 @@ static struct x86_emulate_ops emulate_ops = {
4211 .get_fpu = emulator_get_fpu, 4233 .get_fpu = emulator_get_fpu,
4212 .put_fpu = emulator_put_fpu, 4234 .put_fpu = emulator_put_fpu,
4213 .intercept = emulator_intercept, 4235 .intercept = emulator_intercept,
4236 .get_cpuid = emulator_get_cpuid,
4214}; 4237};
4215 4238
4216static void cache_all_regs(struct kvm_vcpu *vcpu) 4239static void cache_all_regs(struct kvm_vcpu *vcpu)