|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] xen: handle paged gfn in wrmsr_hypervisor_regs
# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1367511750 -7200
# Node ID 19777301f89653c640de73c6319c9d386a28327f
# Parent 9df019eef776d129c2abb130d1458914fe1ecac4
xen: handle paged gfn in wrmsr_hypervisor_regs
If xenpaging is started very early for a guest the gfn for the hypercall
page may be paged-out already. This leads to a guest crash:
...
(XEN) HVM10: Allocated Xen hypercall page at 169ff000
(XEN) traps.c:654:d10 Bad GMFN 169ff (MFN 3e900000000) to MSR 40000000
(XEN) HVM10: Detected Xen v4.3
(XEN) io.c:201:d10 MMIO emulation failed @ 0008:c2c2c2c2: 18 7c 55 6d 03 83 ff
ff 10 7c
(XEN) hvm.c:1253:d10 Triple fault on VCPU0 - invoking HVM shutdown action 1.
(XEN) HVM11: HVM Loader
...
Handle paged gfns in wrmsr_hypervisor_regs and update callers to deal with the
new return code -EAGAIN.
Also update the gdprintk to handle a page value of NULL to avoid printing a
bogus MFN value.
Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
diff -r 9df019eef776 -r 19777301f896 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1569,7 +1569,7 @@ static int svm_msr_read_intercept(unsign
static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content)
{
- int ret;
+ int ret, retry = 0;
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
int sync = 0;
@@ -1682,14 +1682,15 @@ static int svm_msr_write_intercept(unsig
if ( wrmsr_viridian_regs(msr, msr_content) )
break;
- wrmsr_hypervisor_regs(msr, msr_content);
+ ret = wrmsr_hypervisor_regs(msr, msr_content);
+ retry = ret == -EAGAIN;
break;
}
if ( sync )
svm_vmload(vmcb);
- return X86EMUL_OKAY;
+ return retry ? X86EMUL_RETRY : X86EMUL_OKAY;
gpf:
hvm_inject_hw_exception(TRAP_gp_fault, 0);
diff -r 9df019eef776 -r 19777301f896 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2020,6 +2020,7 @@ void vmx_vlapic_msr_changed(struct vcpu
static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content)
{
+ int ret = 0;
struct vcpu *v = current;
HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%#x, msr_value=%#"PRIx64, msr, msr_content);
@@ -2088,7 +2089,9 @@ static int vmx_msr_write_intercept(unsig
case HNDL_unhandled:
if ( (vmx_write_guest_msr(msr, msr_content) != 0) &&
!is_last_branch_msr(msr) )
- wrmsr_hypervisor_regs(msr, msr_content);
+ ret = wrmsr_hypervisor_regs(msr, msr_content);
+ if ( ret == -EAGAIN )
+ return X86EMUL_RETRY;
break;
case HNDL_exception_raised:
return X86EMUL_EXCEPTION;
diff -r 9df019eef776 -r 19777301f896 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -634,6 +634,7 @@ int wrmsr_hypervisor_regs(uint32_t idx,
unsigned long gmfn = val >> 12;
unsigned int idx = val & 0xfff;
struct page_info *page;
+ p2m_type_t t;
if ( idx > 0 )
{
@@ -643,15 +644,21 @@ int wrmsr_hypervisor_regs(uint32_t idx,
return 0;
}
- page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC);
+ page = get_page_from_gfn(d, gmfn, &t, P2M_ALLOC);
if ( !page || !get_page_type(page, PGT_writable_page) )
{
if ( page )
put_page(page);
+ if ( p2m_is_paging(t) )
+ {
+ p2m_mem_paging_populate(d, gmfn);
+ return -EAGAIN;
+ }
+
gdprintk(XENLOG_WARNING,
"Bad GMFN %lx (MFN %lx) to MSR %08x\n",
- gmfn, page_to_mfn(page), base + idx);
+ gmfn, page ? page_to_mfn(page) : -1UL, base + idx);
return 0;
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |