[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3/4] x86/vvmx: correctly emulate VMWRITE
There is an issue with the original __vmwrite() in nested vmx mode: emulation of a guest's VMWRITE with invalid arguments leads to BUG(). Fix this by using __vmwrite_safe() and reporting any kind of VMfail back to the guest. Signed-off-by: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx> --- xen/arch/x86/hvm/vmx/vmcs.c | 9 +++++++-- xen/arch/x86/hvm/vmx/vvmx.c | 15 +++++++++++---- xen/include/asm-x86/hvm/vmx/vmcs.h | 2 +- xen/include/asm-x86/hvm/vmx/vvmx.h | 4 ++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 641e2ef..c1f09c6 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -943,11 +943,16 @@ u64 virtual_vmcs_vmread(const struct vcpu *v, u32 vmcs_encoding) return res; } -void virtual_vmcs_vmwrite(const struct vcpu *v, u32 vmcs_encoding, u64 val) +unsigned long virtual_vmcs_vmwrite(const struct vcpu *v, u32 vmcs_encoding, + u64 val) { + unsigned long ret; + virtual_vmcs_enter(v); - __vmwrite(vmcs_encoding, val); + ret = __vmwrite_safe(vmcs_encoding, val); virtual_vmcs_exit(v); + + return ret; } /* diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index e0cf0fb..c427a24 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -264,7 +264,7 @@ u64 get_vvmcs_real(const struct vcpu *v, u32 encoding) return virtual_vmcs_vmread(v, encoding); } -void set_vvmcs_virtual(void *vvmcs, u32 vmcs_encoding, u64 val) +unsigned long set_vvmcs_virtual(void *vvmcs, u32 vmcs_encoding, u64 val) { union vmcs_encoding enc; u64 *content = (u64 *) vvmcs; @@ -298,11 +298,13 @@ void set_vvmcs_virtual(void *vvmcs, u32 vmcs_encoding, u64 val) } content[offset] = res; + + return 0; } -void set_vvmcs_real(const struct vcpu *v, u32 encoding, u64 val) +unsigned long set_vvmcs_real(const struct vcpu *v, u32 encoding, u64 val) { - virtual_vmcs_vmwrite(v, encoding, val); + return virtual_vmcs_vmwrite(v, encoding, val); } static unsigned long reg_read(struct cpu_user_regs *regs, @@ -1740,13 +1742,18 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs) unsigned long operand; u64 vmcs_encoding; bool_t okay = 1; + unsigned long err; if ( decode_vmx_inst(regs, &decode, &operand, 0) != X86EMUL_OKAY ) return X86EMUL_EXCEPTION; vmcs_encoding = reg_read(regs, decode.reg2); - set_vvmcs(v, vmcs_encoding, operand); + if ( (err = set_vvmcs(v, vmcs_encoding, operand)) ) + { + vmfail(regs, err); + return X86EMUL_OKAY; + } switch ( vmcs_encoding & ~VMCS_HIGH(0) ) { diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index cb02d53..b30e0f7 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -541,7 +541,7 @@ int vmx_check_msr_bitmap(unsigned long *msr_bitmap, u32 msr, int access_type); void virtual_vmcs_enter(const struct vcpu *); void virtual_vmcs_exit(const struct vcpu *); u64 virtual_vmcs_vmread(const struct vcpu *, u32 encoding); -void virtual_vmcs_vmwrite(const struct vcpu *, u32 encoding, u64 val); +unsigned long virtual_vmcs_vmwrite(const struct vcpu *, u32 encoding, u64 val); static inline int vmx_add_guest_msr(u32 msr) { diff --git a/xen/include/asm-x86/hvm/vmx/vvmx.h b/xen/include/asm-x86/hvm/vmx/vvmx.h index 242e524..d60e0bb 100644 --- a/xen/include/asm-x86/hvm/vmx/vvmx.h +++ b/xen/include/asm-x86/hvm/vmx/vvmx.h @@ -181,8 +181,8 @@ enum vvmcs_encoding_type { u64 get_vvmcs_virtual(void *vvmcs, u32 encoding); u64 get_vvmcs_real(const struct vcpu *, u32 encoding); -void set_vvmcs_virtual(void *vvmcs, u32 encoding, u64 val); -void set_vvmcs_real(const struct vcpu *, u32 encoding, u64 val); +unsigned long set_vvmcs_virtual(void *vvmcs, u32 encoding, u64 val); +unsigned long set_vvmcs_real(const struct vcpu *, u32 encoding, u64 val); #define get_vvmcs(vcpu, encoding) \ (cpu_has_vmx_vmcs_shadowing ? \ -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |