[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/1 V3] x86/AMD: Fix nested svm crash due to assertion in __virt_to_maddr
From: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> Fix assertion in __virt_to_maddr when starting nested SVM guest in debug mode. Investigation has shown that svm_vmsave/svm_vmload make use of __pa() with invalid address. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> --- Changes in V3: - Map L1-GPA to MPA before calling svm_vmload/svm_vmsave Changes in V2: - Uses paddr_t instead of uint64_t (suggested by Tim). - Rename the nestedsvm_vmxxxx() to svm_vmxxxx_by_paddr() (suggested by Tim). - Wrapped svm_vmxxxx_by_paddr() with svm_vmxxxx() (suggested by Jan). xen/arch/x86/hvm/svm/svm.c | 27 +++++++++++++++++++++++++-- xen/arch/x86/mm/hap/nested_hap.c | 13 +++++++++++++ xen/include/asm-x86/hvm/nestedhvm.h | 3 +++ xen/include/asm-x86/hvm/svm/svm.h | 11 +++++++---- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 4a7aeee..efc821e 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1798,6 +1798,7 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb, struct vcpu *v, uint64_t vmcbaddr) { int ret; + paddr_t mpa; unsigned int inst_len; struct nestedvcpu *nv = &vcpu_nestedhvm(v); @@ -1816,7 +1817,18 @@ svm_vmexit_do_vmload(struct vmcb_struct *vmcb, goto inject; } - svm_vmload(nv->nv_vvmcx); + /* Need to translate L1-GPA to MPA */ + if ( NESTEDHVM_PAGEFAULT_DONE != nestedhvm_walk_L0_p2m( + v, nv->nv_vvmcxaddr, &mpa) ) + { + gdprintk(XENLOG_ERR, + "VMLOAD: mapping vmcb L1-GPA to MPA failed, injecting #UD\n"); + ret = TRAP_invalid_op; + goto inject; + } + + svm_vmload_pa(mpa); + /* State in L1 VMCB is stale now */ v->arch.hvm_svm.vmcb_in_sync = 0; @@ -1834,6 +1846,7 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb, struct vcpu *v, uint64_t vmcbaddr) { int ret; + paddr_t mpa; unsigned int inst_len; struct nestedvcpu *nv = &vcpu_nestedhvm(v); @@ -1852,7 +1865,17 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb, goto inject; } - svm_vmsave(nv->nv_vvmcx); + /* Need to translate L1-GPA to MPA */ + if ( NESTEDHVM_PAGEFAULT_DONE != nestedhvm_walk_L0_p2m( + v, nv->nv_vvmcxaddr, &mpa) ) + { + gdprintk(XENLOG_ERR, + "VMSAVE: mapping vmcb L1-GPA to MPA failed, injecting #UD\n"); + ret = TRAP_invalid_op; + goto inject; + } + + svm_vmsave_pa(mpa); __update_guest_eip(regs, inst_len); return; diff --git a/xen/arch/x86/mm/hap/nested_hap.c b/xen/arch/x86/mm/hap/nested_hap.c index c2ef1d1..af557d5 100644 --- a/xen/arch/x86/mm/hap/nested_hap.c +++ b/xen/arch/x86/mm/hap/nested_hap.c @@ -191,6 +191,19 @@ out: return rc; } +int +nestedhvm_walk_L0_p2m(struct vcpu *v, paddr_t L1_gpa, paddr_t *L0_gpa) +{ + p2m_type_t p2mt_10; + unsigned int page_order_10; + p2m_access_t p2ma_10 = p2m_access_rwx; + + return nestedhap_walk_L0_p2m ( p2m_get_hostp2m(v->domain), + L1_gpa, L0_gpa, + &p2mt_10, &p2ma_10, &page_order_10, + 0, 0, 0); +} + /* * The following function, nestedhap_page_fault(), is for steps (3)--(10). * diff --git a/xen/include/asm-x86/hvm/nestedhvm.h b/xen/include/asm-x86/hvm/nestedhvm.h index 649c511..228b6eb 100644 --- a/xen/include/asm-x86/hvm/nestedhvm.h +++ b/xen/include/asm-x86/hvm/nestedhvm.h @@ -56,6 +56,9 @@ bool_t nestedhvm_vcpu_in_guestmode(struct vcpu *v); int nestedhvm_hap_nested_page_fault(struct vcpu *v, paddr_t *L2_gpa, bool_t access_r, bool_t access_w, bool_t access_x); +int nestedhvm_walk_L0_p2m(struct vcpu *v, + paddr_t L1_gpa, paddr_t *L0_gpa); + /* IO permission map */ unsigned long *nestedhvm_vcpu_iomap_get(bool_t ioport_80, bool_t ioport_ed); diff --git a/xen/include/asm-x86/hvm/svm/svm.h b/xen/include/asm-x86/hvm/svm/svm.h index 64e7e25..1ffe6d6 100644 --- a/xen/include/asm-x86/hvm/svm/svm.h +++ b/xen/include/asm-x86/hvm/svm/svm.h @@ -41,18 +41,21 @@ #define SVM_REG_R14 (14) #define SVM_REG_R15 (15) -static inline void svm_vmload(void *vmcb) +#define svm_vmload(x) svm_vmload_pa(__pa(x)) +#define svm_vmsave(x) svm_vmsave_pa(__pa(x)) + +static inline void svm_vmload_pa(paddr_t vmcb) { asm volatile ( ".byte 0x0f,0x01,0xda" /* vmload */ - : : "a" (__pa(vmcb)) : "memory" ); + : : "a" (vmcb) : "memory" ); } -static inline void svm_vmsave(void *vmcb) +static inline void svm_vmsave_pa(paddr_t vmcb) { asm volatile ( ".byte 0x0f,0x01,0xdb" /* vmsave */ - : : "a" (__pa(vmcb)) : "memory" ); + : : "a" (vmcb) : "memory" ); } static inline void svm_invlpga(unsigned long vaddr, uint32_t asid) -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |