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.
