Intercept the CPUID vmexit to possibly either set the hypervisor bit or to
return the KVM signature depending on the value in RAX.

Signed-off-by: Gan Shun <[email protected]>
Change-Id: Ic27e05eafa22b0a20a888397c8bae37ff0ea3267
---
 kern/arch/x86/trap.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/kern/arch/x86/trap.c b/kern/arch/x86/trap.c
index 72d0c64..9ebe5a6 100644
--- a/kern/arch/x86/trap.c
+++ b/kern/arch/x86/trap.c
@@ -685,7 +685,24 @@ static bool handle_vmexit_cpuid(struct vm_trapframe *tf)
 {
        uint32_t eax, ebx, ecx, edx;
 
-       cpuid(tf->tf_rax, tf->tf_rcx, &eax, &ebx, &ecx, &edx);
+       /* 0x4000000 is taken from Linux; it is not documented but it signals 
the
+        * use of KVM. */
+       if (tf->tf_rax == 0x40000000) {
+               /* Pretend to be KVM: Return the KVM signature by placing the 
following
+                * constants in RAX, RBX, RCX and RDX. RAX is set to 0, while 
RBX to
+                * RDX forms the string "KVMKVMKVMKVM\0\0\0". This can be 
placed in
+                * 0x100 offsets from 0x40000000 to 0x40010000. */
+               eax = 0;
+               ebx = 0x4b4d564b;
+               ecx = 0x564b4d56;
+               edx = 0x0000004d;
+       } else {
+               cpuid(tf->tf_rax, tf->tf_rcx, &eax, &ebx, &ecx, &edx);
+               if (tf->tf_rax == 1) {
+                       /* Set the hypervisor bit to let the guest know it is 
virtualized */
+                       ecx |= 1 << 31;
+               }
+       }
        tf->tf_rax = eax;
        tf->tf_rbx = ebx;
        tf->tf_rcx = ecx;
-- 
2.8.0.rc3.226.g39d4020

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to