diff options
author | Stephan Bärwolf <stephan.baerwolf@tu-ilmenau.de> | 2012-01-12 10:43:03 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-02-01 04:43:33 -0500 |
commit | bdb42f5afebe208eae90406959383856ae2caf2b (patch) | |
tree | e58d3b8aedf30b9f42689a7d0ee752600be3f938 | |
parent | 50e92b3c971129c96a5fffb51dd42691e2ee4004 (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.h | 3 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 23 |
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 | ||
195 | typedef u32 __attribute__((vector_size(16))) sse128_t; | 198 | typedef 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 | ||
4183 | static 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 | |||
4183 | static struct x86_emulate_ops emulate_ops = { | 4205 | static 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 | ||
4216 | static void cache_all_regs(struct kvm_vcpu *vcpu) | 4239 | static void cache_all_regs(struct kvm_vcpu *vcpu) |