[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] vvmx: replace vmreturn() by vmsucceed() and vmfail*()
commit 44d3196903f3ae5ac3d27da626107131e3e35603 Author: Haozhong Zhang <haozhong.zhang@xxxxxxxxx> AuthorDate: Tue Dec 20 09:53:39 2016 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Dec 20 09:53:39 2016 +0100 vvmx: replace vmreturn() by vmsucceed() and vmfail*() Replace vmreturn() by vmsucceed(), vmfail(), vmfail_valid() and vmfail_invalid(), which are consistent to the pseudo code on Intel SDM, and allow to return VM instruction error numbers to L1 hypervisor. Signed-off-by: Haozhong Zhang <haozhong.zhang@xxxxxxxxx> Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Acked-by: Kevin Tian <kevin.tian@xxxxxxxxx> --- xen/arch/x86/hvm/vmx/vvmx.c | 103 +++++++++++++++++++++---------------- xen/include/asm-x86/hvm/vmx/vmcs.h | 15 ++++-- xen/include/asm-x86/processor.h | 4 ++ 3 files changed, 74 insertions(+), 48 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index 9e37d22..6c7e92b 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -469,28 +469,33 @@ gp_fault: return X86EMUL_EXCEPTION; } -static void vmreturn(struct cpu_user_regs *regs, enum vmx_ops_result ops_res) +static void vmsucceed(struct cpu_user_regs *regs) { + regs->eflags &= ~X86_EFLAGS_ARITH_MASK; +} + +static void vmfail_valid(struct cpu_user_regs *regs, enum vmx_insn_errno errno) +{ + struct vcpu *v = current; unsigned long eflags = regs->eflags; - unsigned long mask = X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | - X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF; - eflags &= ~mask; + regs->eflags = (eflags & ~X86_EFLAGS_ARITH_MASK) | X86_EFLAGS_ZF; + set_vvmcs(v, VM_INSTRUCTION_ERROR, errno); +} - switch ( ops_res ) { - case VMSUCCEED: - break; - case VMFAIL_VALID: - /* TODO: error number, useful for guest VMM debugging */ - eflags |= X86_EFLAGS_ZF; - break; - case VMFAIL_INVALID: - default: - eflags |= X86_EFLAGS_CF; - break; - } +static void vmfail_invalid(struct cpu_user_regs *regs) +{ + unsigned long eflags = regs->eflags; + + regs->eflags = (eflags & ~X86_EFLAGS_ARITH_MASK) | X86_EFLAGS_CF; +} - regs->eflags = eflags; +static void vmfail(struct cpu_user_regs *regs, enum vmx_insn_errno errno) +{ + if ( vcpu_nestedhvm(current).nv_vvmcxaddr != INVALID_PADDR ) + vmfail_valid(regs, errno); + else + vmfail_invalid(regs); } bool_t nvmx_intercepts_exception( @@ -1328,7 +1333,7 @@ static void virtual_vmexit(struct cpu_user_regs *regs) nvmx_update_apicv(v); nvcpu->nv_vmswitch_in_progress = 0; - vmreturn(regs, VMSUCCEED); + vmsucceed(regs); } void nvmx_switch_guest(void) @@ -1382,16 +1387,14 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs) if ( nvmx_vcpu_in_vmx(v) ) { - vmreturn(regs, - nvcpu->nv_vvmcxaddr != INVALID_PADDR ? - VMFAIL_VALID : VMFAIL_INVALID); + vmfail(regs, VMX_INSN_VMXON_IN_VMX_ROOT); return X86EMUL_OKAY; } if ( (gpa & ~PAGE_MASK) || (gpa >> (v->domain->arch.paging.gfn_bits + PAGE_SHIFT)) ) { - vmreturn(regs, VMFAIL_INVALID); + vmfail_invalid(regs); return X86EMUL_OKAY; } @@ -1400,7 +1403,7 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs) (nvmcs_revid & ~VMX_BASIC_REVISION_MASK) || ((nvmcs_revid ^ vmx_basic_msr) & VMX_BASIC_REVISION_MASK) ) { - vmreturn(regs, VMFAIL_INVALID); + vmfail_invalid(regs); return X86EMUL_OKAY; } @@ -1416,7 +1419,7 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs) _mfn(PFN_DOWN(v->arch.hvm_vmx.vmcs_pa))); __vmptrld(v->arch.hvm_vmx.vmcs_pa); v->arch.hvm_vmx.launched = 0; - vmreturn(regs, VMSUCCEED); + vmsucceed(regs); return X86EMUL_OKAY; } @@ -1434,7 +1437,7 @@ int nvmx_handle_vmxoff(struct cpu_user_regs *regs) nvmx_purge_vvmcs(v); nvmx->vmxon_region_pa = INVALID_PADDR; - vmreturn(regs, VMSUCCEED); + vmsucceed(regs); return X86EMUL_OKAY; } @@ -1505,7 +1508,7 @@ static int nvmx_vmresume(struct vcpu *v, struct cpu_user_regs *regs) !(__n2_exec_control(v) & CPU_BASED_ACTIVATE_IO_BITMAP) ) ) nvcpu->nv_vmentry_pending = 1; else - vmreturn(regs, VMFAIL_INVALID); + vmfail_invalid(regs); return X86EMUL_OKAY; } @@ -1522,15 +1525,16 @@ int nvmx_handle_vmresume(struct cpu_user_regs *regs) if ( vcpu_nestedhvm(v).nv_vvmcxaddr == INVALID_PADDR ) { - vmreturn (regs, VMFAIL_INVALID); + vmfail_invalid(regs); return X86EMUL_OKAY; } launched = vvmcs_launched(&nvmx->launched_list, PFN_DOWN(v->arch.hvm_vmx.vmcs_shadow_maddr)); - if ( !launched ) { - vmreturn (regs, VMFAIL_VALID); - return X86EMUL_OKAY; + if ( !launched ) + { + vmfail_valid(regs, VMX_INSN_VMRESUME_NONLAUNCHED_VMCS); + return X86EMUL_OKAY; } return nvmx_vmresume(v,regs); } @@ -1547,15 +1551,16 @@ int nvmx_handle_vmlaunch(struct cpu_user_regs *regs) if ( vcpu_nestedhvm(v).nv_vvmcxaddr == INVALID_PADDR ) { - vmreturn (regs, VMFAIL_INVALID); + vmfail_invalid(regs); return X86EMUL_OKAY; } launched = vvmcs_launched(&nvmx->launched_list, PFN_DOWN(v->arch.hvm_vmx.vmcs_shadow_maddr)); - if ( launched ) { - vmreturn (regs, VMFAIL_VALID); - return X86EMUL_OKAY; + if ( launched ) + { + vmfail_valid(regs, VMX_INSN_VMLAUNCH_NONCLEAR_VMCS); + return X86EMUL_OKAY; } else { rc = nvmx_vmresume(v,regs); @@ -1583,7 +1588,7 @@ int nvmx_handle_vmptrld(struct cpu_user_regs *regs) if ( gpa == vcpu_2_nvmx(v).vmxon_region_pa || gpa & 0xfff ) { - vmreturn(regs, VMFAIL_INVALID); + vmfail_invalid(regs); goto out; } @@ -1614,7 +1619,7 @@ int nvmx_handle_vmptrld(struct cpu_user_regs *regs) !map_io_bitmap_all(v) || !_map_msr_bitmap(v) ) { - vmreturn(regs, VMFAIL_VALID); + vmfail_valid(regs, VMX_INSN_VMPTRLD_INVALID_PHYADDR); goto out; } } @@ -1622,7 +1627,7 @@ int nvmx_handle_vmptrld(struct cpu_user_regs *regs) if ( cpu_has_vmx_vmcs_shadowing ) nvmx_set_vmcs_pointer(v, nvcpu->nv_vvmcx); - vmreturn(regs, VMSUCCEED); + vmsucceed(regs); out: return X86EMUL_OKAY; @@ -1649,7 +1654,7 @@ int nvmx_handle_vmptrst(struct cpu_user_regs *regs) if ( rc != HVMCOPY_okay ) return X86EMUL_EXCEPTION; - vmreturn(regs, VMSUCCEED); + vmsucceed(regs); return X86EMUL_OKAY; } @@ -1695,7 +1700,12 @@ int nvmx_handle_vmclear(struct cpu_user_regs *regs) } } - vmreturn(regs, rc); + if ( rc == VMSUCCEED ) + vmsucceed(regs); + else if ( rc == VMFAIL_VALID ) + vmfail_valid(regs, VMX_INSN_VMCLEAR_INVALID_PHYADDR); + else + vmfail_invalid(regs); return X86EMUL_OKAY; } @@ -1727,7 +1737,7 @@ int nvmx_handle_vmread(struct cpu_user_regs *regs) break; } - vmreturn(regs, VMSUCCEED); + vmsucceed(regs); return X86EMUL_OKAY; } @@ -1759,7 +1769,10 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs) break; } - vmreturn(regs, okay ? VMSUCCEED : VMFAIL_VALID); + if ( okay ) + vmsucceed(regs); + else + vmfail_valid(regs, VMX_INSN_UNSUPPORTED_VMCS_COMPONENT); return X86EMUL_OKAY; } @@ -1790,10 +1803,10 @@ int nvmx_handle_invept(struct cpu_user_regs *regs) __invept(INVEPT_ALL_CONTEXT, 0, 0); break; default: - vmreturn(regs, VMFAIL_INVALID); + vmfail_invalid(regs); return X86EMUL_OKAY; } - vmreturn(regs, VMSUCCEED); + vmsucceed(regs); return X86EMUL_OKAY; } @@ -1815,11 +1828,11 @@ int nvmx_handle_invvpid(struct cpu_user_regs *regs) hvm_asid_flush_vcpu_asid(&vcpu_nestedhvm(current).nv_n2asid); break; default: - vmreturn(regs, VMFAIL_INVALID); + vmfail_invalid(regs); return X86EMUL_OKAY; } - vmreturn(regs, VMSUCCEED); + vmsucceed(regs); return X86EMUL_OKAY; } diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index 894093d..6c3d7ba 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -574,9 +574,18 @@ enum vmcs_field { #define VMX_GUEST_MSR 0 #define VMX_HOST_MSR 1 -/* VM Instruction error numbers. */ -#define VMX_INSN_INVALID_CONTROL_STATE 7 -#define VMX_INSN_INVALID_HOST_STATE 8 +/* VM Instruction error numbers */ +enum vmx_insn_errno +{ + VMX_INSN_VMCLEAR_INVALID_PHYADDR = 2, + VMX_INSN_VMLAUNCH_NONCLEAR_VMCS = 4, + VMX_INSN_VMRESUME_NONLAUNCHED_VMCS = 5, + VMX_INSN_INVALID_CONTROL_STATE = 7, + VMX_INSN_INVALID_HOST_STATE = 8, + VMX_INSN_VMPTRLD_INVALID_PHYADDR = 9, + VMX_INSN_UNSUPPORTED_VMCS_COMPONENT = 12, + VMX_INSN_VMXON_IN_VMX_ROOT = 15, +}; void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr, int type); void vmx_enable_intercept_for_msr(struct vcpu *v, u32 msr, int type); diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index eae4af2..9870589 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -53,6 +53,10 @@ #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ +#define X86_EFLAGS_ARITH_MASK \ + (X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | \ + X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF) + /* * Intel CPU flags in CR0 */ -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |