[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 08/16] vmx: nest: vmresume/vmlaunch
vmresume and vmlaunch instructions and transitional states Signed-off-by: Qing He <qing.he@xxxxxxxxx> Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> --- diff -r e828d55c10bb xen/arch/x86/hvm/vmx/nest.c --- a/xen/arch/x86/hvm/vmx/nest.c Wed Sep 08 21:42:10 2010 +0800 +++ b/xen/arch/x86/hvm/vmx/nest.c Wed Sep 08 22:04:16 2010 +0800 @@ -633,3 +633,33 @@ hvm_inject_exception(TRAP_invalid_op, 0, 0); return X86EMUL_EXCEPTION; } + +int vmx_nest_handle_vmresume(struct cpu_user_regs *regs) +{ + struct vcpu *v = current; + struct vmx_nest_struct *nest = &v->arch.hvm_vmx.nest; + int rc; + + if ( unlikely(!nest->guest_vmxon_pa) ) + goto invalid_op; + + rc = vmx_inst_check_privilege(regs); + if ( rc != X86EMUL_OKAY ) + return rc; + + if ( nest->vmcs_valid == 1 ) + nest->vmresume_pending = 1; + else + vmreturn(regs, VMFAIL_INVALID); + + return X86EMUL_OKAY; + +invalid_op: + hvm_inject_exception(TRAP_invalid_op, 0, 0); + return X86EMUL_EXCEPTION; +} + +int vmx_nest_handle_vmlaunch(struct cpu_user_regs *regs) +{ + return vmx_nest_handle_vmresume(regs); +} diff -r e828d55c10bb xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Wed Sep 08 21:42:10 2010 +0800 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Sep 08 22:04:16 2010 +0800 @@ -2321,6 +2321,11 @@ /* 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 + */ + v->arch.hvm_vmx.nest.vmresume_in_progress = 0; + if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) ) return vmx_failed_vmentry(exit_reason, regs); @@ -2592,6 +2597,11 @@ if ( vmx_nest_handle_vmclear(regs) == X86EMUL_OKAY ) __update_guest_eip(inst_len); break; + case EXIT_REASON_VMLAUNCH: + inst_len = __get_instruction_length(); + if ( vmx_nest_handle_vmlaunch(regs) == X86EMUL_OKAY ) + __update_guest_eip(inst_len); + break; case EXIT_REASON_VMPTRLD: inst_len = __get_instruction_length(); if ( vmx_nest_handle_vmptrld(regs) == X86EMUL_OKAY ) @@ -2607,6 +2617,11 @@ if ( vmx_nest_handle_vmread(regs) == X86EMUL_OKAY ) __update_guest_eip(inst_len); break; + case EXIT_REASON_VMRESUME: + inst_len = __get_instruction_length(); + if ( vmx_nest_handle_vmresume(regs) == X86EMUL_OKAY ) + __update_guest_eip(inst_len); + break; case EXIT_REASON_VMWRITE: inst_len = __get_instruction_length(); if ( vmx_nest_handle_vmwrite(regs) == X86EMUL_OKAY ) @@ -2625,8 +2640,6 @@ case EXIT_REASON_MWAIT_INSTRUCTION: case EXIT_REASON_MONITOR_INSTRUCTION: - case EXIT_REASON_VMLAUNCH: - case EXIT_REASON_VMRESUME: vmx_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE); break; diff -r e828d55c10bb xen/include/asm-x86/hvm/vmx/nest.h --- a/xen/include/asm-x86/hvm/vmx/nest.h Wed Sep 08 21:42:10 2010 +0800 +++ b/xen/include/asm-x86/hvm/vmx/nest.h Wed Sep 08 22:04:16 2010 +0800 @@ -40,6 +40,20 @@ void *vvmcs; struct vmcs_struct *svmcs; int vmcs_valid; + + /* + * vmexit_pending and vmresume_pending is to mark pending + * switches, they are cleared when physical vmcs is changed. + */ + int vmexit_pending; + int vmresume_pending; + + /* + * upon L1->L2, there is a window between context switch and + * the physical vmentry of the shadow vmcs, protect against it + * with vmresume_in_progress + */ + int vmresume_in_progress; }; int vmx_nest_handle_vmxon(struct cpu_user_regs *regs); @@ -52,4 +66,7 @@ int vmx_nest_handle_vmread(struct cpu_user_regs *regs); int vmx_nest_handle_vmwrite(struct cpu_user_regs *regs); +int vmx_nest_handle_vmresume(struct cpu_user_regs *regs); +int vmx_nest_handle_vmlaunch(struct cpu_user_regs *regs); + #endif /* __ASM_X86_HVM_NEST_H__ */ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |