xen-devel
[Xen-devel] [PATCH 13 of 20] Emulation of VMRESUME/VMLAUNCH
# HG changeset patch
# User Eddie Dong <eddie.dong@xxxxxxxxx>
# Date 1307003601 -28800
# Node ID 279a27a3b1a90380c8fa579e87835cb58a8f4aac
# Parent 62cc6c7516e010ef673c75bba83f901785b063d5
Emulation of VMRESUME/VMLAUNCH
Signed-off-by: Qing He <qing.he@xxxxxxxxx>
Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>
diff -r 62cc6c7516e0 -r 279a27a3b1a9 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 02 16:33:21 2011 +0800
+++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 02 16:33:21 2011 +0800
@@ -2175,6 +2175,11 @@ asmlinkage void vmx_vmexit_handler(struc
/* Now enable interrupts so it's safe to take locks. */
local_irq_enable();
+ /* XXX: This looks ugly, but we need a mechanism to ensure
+ * any pending vmresume has really happened
+ */
+ vcpu_nestedhvm(v).nv_vmswitch_in_progress = 0;
+
if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) )
return vmx_failed_vmentry(exit_reason, regs);
@@ -2469,10 +2474,18 @@ asmlinkage void vmx_vmexit_handler(struc
update_guest_eip();
break;
+ case EXIT_REASON_VMLAUNCH:
+ if ( nvmx_handle_vmlaunch(regs) == X86EMUL_OKAY )
+ update_guest_eip();
+ break;
+
+ case EXIT_REASON_VMRESUME:
+ if ( nvmx_handle_vmresume(regs) == X86EMUL_OKAY )
+ update_guest_eip();
+ break;
+
case EXIT_REASON_MWAIT_INSTRUCTION:
case EXIT_REASON_MONITOR_INSTRUCTION:
- case EXIT_REASON_VMLAUNCH:
- case EXIT_REASON_VMRESUME:
case EXIT_REASON_GETSEC:
case EXIT_REASON_INVEPT:
case EXIT_REASON_INVVPID:
diff -r 62cc6c7516e0 -r 279a27a3b1a9 xen/arch/x86/hvm/vmx/vvmx.c
--- a/xen/arch/x86/hvm/vmx/vvmx.c Thu Jun 02 16:33:21 2011 +0800
+++ b/xen/arch/x86/hvm/vmx/vvmx.c Thu Jun 02 16:33:21 2011 +0800
@@ -261,6 +261,13 @@ static void reg_write(struct cpu_user_re
}
}
+static inline u32 __n2_exec_control(struct vcpu *v)
+{
+ struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
+
+ return __get_vvmcs(nvcpu->nv_vvmcx, CPU_BASED_VM_EXEC_CONTROL);
+}
+
static int vmx_inst_check_privilege(struct cpu_user_regs *regs, int
vmxop_check)
{
struct vcpu *v = current;
@@ -502,6 +509,34 @@ int nvmx_handle_vmxoff(struct cpu_user_r
return X86EMUL_OKAY;
}
+int nvmx_handle_vmresume(struct cpu_user_regs *regs)
+{
+ struct vcpu *v = current;
+ struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
+ struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v);
+ int rc;
+
+ rc = vmx_inst_check_privilege(regs, 0);
+ if ( rc != X86EMUL_OKAY )
+ return rc;
+
+ /* check VMCS is valid and IO BITMAP is set */
+ if ( (nvcpu->nv_vvmcxaddr != VMCX_EADDR) &&
+ ((nvmx->iobitmap[0] && nvmx->iobitmap[1]) ||
+ !(__n2_exec_control(v) & CPU_BASED_ACTIVATE_IO_BITMAP) ) )
+ nvcpu->nv_vmentry_pending = 1;
+ else
+ vmreturn(regs, VMFAIL_INVALID);
+
+ return X86EMUL_OKAY;
+}
+
+int nvmx_handle_vmlaunch(struct cpu_user_regs *regs)
+{
+ /* TODO: check for initial launch/resume */
+ return nvmx_handle_vmresume(regs);
+}
+
int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
{
struct vcpu *v = current;
diff -r 62cc6c7516e0 -r 279a27a3b1a9 xen/include/asm-x86/hvm/vmx/vvmx.h
--- a/xen/include/asm-x86/hvm/vmx/vvmx.h Thu Jun 02 16:33:21 2011 +0800
+++ b/xen/include/asm-x86/hvm/vmx/vvmx.h Thu Jun 02 16:33:21 2011 +0800
@@ -158,6 +158,8 @@ int nvmx_handle_vmptrst(struct cpu_user_
int nvmx_handle_vmclear(struct cpu_user_regs *regs);
int nvmx_handle_vmread(struct cpu_user_regs *regs);
int nvmx_handle_vmwrite(struct cpu_user_regs *regs);
+int nvmx_handle_vmresume(struct cpu_user_regs *regs);
+int nvmx_handle_vmlaunch(struct cpu_user_regs *regs);
#endif /* __ASM_X86_HVM_VVMX_H__ */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|
|
|