Josh Boyer 3aa57a6
From 0769c5de24621141c953fbe1f943582d37cb4244 Mon Sep 17 00:00:00 2001
Josh Boyer 3aa57a6
From: =?UTF-8?q?Stephan=20B=C3=A4rwolf?= <stephan.baerwolf@tu-ilmenau.de>
Josh Boyer 3aa57a6
Date: Thu, 12 Jan 2012 16:43:03 +0100
Josh Boyer 3aa57a6
Subject: [PATCH 1/2] KVM: x86: extend "struct x86_emulate_ops" with
Josh Boyer 3aa57a6
 "get_cpuid"
Josh Boyer 3aa57a6
Josh Boyer 3aa57a6
In order to be able to proceed checks on CPU-specific properties
Josh Boyer 3aa57a6
within the emulator, function "get_cpuid" is introduced.
Josh Boyer 3aa57a6
With "get_cpuid" it is possible to virtually call the guests
Josh Boyer 3aa57a6
"cpuid"-opcode without changing the VM's context.
Josh Boyer 3aa57a6
Josh Boyer 3aa57a6
[mtosatti: cleanup/beautify code]
Josh Boyer 3aa57a6
Josh Boyer 3aa57a6
Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
Josh Boyer 3aa57a6
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Josh Boyer 3aa57a6
---
Josh Boyer 3aa57a6
 arch/x86/include/asm/kvm_emulate.h |    3 +++
Josh Boyer 3aa57a6
 arch/x86/kvm/x86.c                 |   23 +++++++++++++++++++++++
Josh Boyer 3aa57a6
 2 files changed, 26 insertions(+), 0 deletions(-)
Josh Boyer 3aa57a6
Josh Boyer 3aa57a6
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
Josh Boyer 3aa57a6
index ab4092e..c8b2868 100644
Josh Boyer 3aa57a6
--- a/arch/x86/include/asm/kvm_emulate.h
Josh Boyer 3aa57a6
+++ b/arch/x86/include/asm/kvm_emulate.h
Josh Boyer 3aa57a6
@@ -190,6 +190,9 @@ struct x86_emulate_ops {
Josh Boyer 3aa57a6
 	int (*intercept)(struct x86_emulate_ctxt *ctxt,
Josh Boyer 3aa57a6
 			 struct x86_instruction_info *info,
Josh Boyer 3aa57a6
 			 enum x86_intercept_stage stage);
Josh Boyer 3aa57a6
+
Josh Boyer 3aa57a6
+	bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
Josh Boyer 3aa57a6
+			 u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
Josh Boyer 3aa57a6
 };
Josh Boyer 3aa57a6
 
Josh Boyer 3aa57a6
 typedef u32 __attribute__((vector_size(16))) sse128_t;
Josh Boyer 3aa57a6
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
Josh Boyer 3aa57a6
index f0fa3fb..c95ca2d 100644
Josh Boyer 3aa57a6
--- a/arch/x86/kvm/x86.c
Josh Boyer 3aa57a6
+++ b/arch/x86/kvm/x86.c
Josh Boyer 3aa57a6
@@ -4205,6 +4205,28 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
Josh Boyer 3aa57a6
 	return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
Josh Boyer 3aa57a6
 }
Josh Boyer 3aa57a6
 
Josh Boyer 3aa57a6
+static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
Josh Boyer 3aa57a6
+			       u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
Josh Boyer 3aa57a6
+{
Josh Boyer 3aa57a6
+	struct kvm_cpuid_entry2 *cpuid = NULL;
Josh Boyer 3aa57a6
+
Josh Boyer 3aa57a6
+	if (eax && ecx)
Josh Boyer 3aa57a6
+		cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt),
Josh Boyer 3aa57a6
+					    *eax, *ecx);
Josh Boyer 3aa57a6
+
Josh Boyer 3aa57a6
+	if (cpuid) {
Josh Boyer 3aa57a6
+		*eax = cpuid->eax;
Josh Boyer 3aa57a6
+		*ecx = cpuid->ecx;
Josh Boyer 3aa57a6
+		if (ebx)
Josh Boyer 3aa57a6
+			*ebx = cpuid->ebx;
Josh Boyer 3aa57a6
+		if (edx)
Josh Boyer 3aa57a6
+			*edx = cpuid->edx;
Josh Boyer 3aa57a6
+		return true;
Josh Boyer 3aa57a6
+	}
Josh Boyer 3aa57a6
+
Josh Boyer 3aa57a6
+	return false;
Josh Boyer 3aa57a6
+}
Josh Boyer 3aa57a6
+
Josh Boyer 3aa57a6
 static struct x86_emulate_ops emulate_ops = {
Josh Boyer 3aa57a6
 	.read_std            = kvm_read_guest_virt_system,
Josh Boyer 3aa57a6
 	.write_std           = kvm_write_guest_virt_system,
Josh Boyer 3aa57a6
@@ -4236,6 +4258,7 @@ static struct x86_emulate_ops emulate_ops = {
Josh Boyer 3aa57a6
 	.get_fpu             = emulator_get_fpu,
Josh Boyer 3aa57a6
 	.put_fpu             = emulator_put_fpu,
Josh Boyer 3aa57a6
 	.intercept           = emulator_intercept,
Josh Boyer 3aa57a6
+	.get_cpuid           = emulator_get_cpuid,
Josh Boyer 3aa57a6
 };
Josh Boyer 3aa57a6
 
Josh Boyer 3aa57a6
 static void cache_all_regs(struct kvm_vcpu *vcpu)
Josh Boyer 3aa57a6
-- 
Josh Boyer 3aa57a6
1.7.7.5
Josh Boyer 3aa57a6