|
[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 |