vmm: vmexit speed tests There's a corresponding kernel module, vmexit_speed, in our linux-guest repo. Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/arch/x86/trap.c b/kern/arch/x86/trap.c index d21f0b2..4adc07b 100644 --- a/kern/arch/x86/trap.c +++ b/kern/arch/x86/trap.c
@@ -38,6 +38,8 @@ struct irq_handler *irq_handlers[NUM_IRQS]; spinlock_t irq_handler_wlock = SPINLOCK_INITIALIZER_IRQSAVE; +static void x86_finalize_vmtf(struct vm_trapframe *tf); + static bool try_handle_exception_fixup(struct hw_trapframe *hw_tf) { if (in_kernel(hw_tf)) { @@ -1052,6 +1054,17 @@ * do it for external IRQs - the irq_dispatch code will handle it. */ switch (tf->tf_exit_reason) { case EXIT_REASON_VMCALL: + if (tf->tf_rdi == 0x1338) { + tf->tf_rip += 3; + handled = TRUE; + break; + } + if (tf->tf_rdi == 0x1339) { + tf->tf_rip += 3; + x86_finalize_vmtf(tf); + handled = TRUE; + break; + } if (current->vmm.flags & VMM_VMCALL_PRINTF) { printk("%c", tf->tf_rdi); tf->tf_rip += 3;
diff --git a/kern/arch/x86/trapentry64.S b/kern/arch/x86/trapentry64.S index e7aa859..4d531c0 100644 --- a/kern/arch/x86/trapentry64.S +++ b/kern/arch/x86/trapentry64.S
@@ -914,6 +914,31 @@ .globl vmexit_handler; .type vmexit_handler, @function; vmexit_handler: + +# This is part of why i don't use enums. need #defines for asm. +#define VM_EXIT_REASON 0x00004402 +#define EXIT_REASON_VMCALL 18 +#define GUEST_RIP 0x0000681e + pushq %rdx + pushq %rax + movq $VM_EXIT_REASON, %rdx + vmread %rdx, %rax + cmp $EXIT_REASON_VMCALL, %rax + jne normal_vmexit + cmp $0x1337, %rdi + jne normal_vmexit + # advance RIP by 3 (sizeof vmcall) + movq $GUEST_RIP, %rdx + vmread %rdx, %rax + add $3, %rax + vmwrite %rax, %rdx + popq %rax + popq %rdx + vmresume +normal_vmexit: + popq %rax + popq %rdx + # rflags has all flags = 0, so cli and cld already. # HOST_GS_BASE and RSP is set by the hardware # Set default values. Most of these will be set in C later.
diff --git a/user/vmm/vmexit.c b/user/vmm/vmexit.c index 3e8700b..9d0bd65 100644 --- a/user/vmm/vmexit.c +++ b/user/vmm/vmexit.c
@@ -126,6 +126,10 @@ struct vm_trapframe *vm_tf = gth_to_vmtf(gth); uint8_t byte; + if (vm_tf->tf_rdi == 0x1340) { + vm_tf->tf_rip += 3; + return TRUE; + } if (gth->vmcall) return gth->vmcall(gth, vm_tf); byte = vm_tf->tf_rdi;