diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 44ff9d0c6b..4eb41792e2 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2923,9 +2923,10 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) v->arch.hvm.svm.cached_insn_len = vmcb->guest_ins_len & 0xf; rc = vmcb->exitinfo1 & PFEC_page_present ? p2m_pt_handle_deferred_changes(vmcb->exitinfo2) : 0; - if ( rc >= 0 ) + if ( rc == 0 ) + /* If no recal adjustments were being made - handle this fault */ svm_do_nested_pgfault(v, regs, vmcb->exitinfo1, vmcb->exitinfo2); - else + else if ( rc < 0 ) { printk(XENLOG_G_ERR "%pv: Error %d handling NPF (gpa=%08lx ec=%04lx)\n", diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c index 5c0501794e..badb26bc34 100644 --- a/xen/arch/x86/mm/p2m-pt.c +++ b/xen/arch/x86/mm/p2m-pt.c @@ -341,6 +341,7 @@ static int do_recalc(struct p2m_domain *p2m, unsigned long gfn) unsigned int level = 4; l1_pgentry_t *pent; int err = 0; + bool recalc_done = false; table = map_domain_page(pagetable_get_mfn(p2m_get_pagetable(p2m))); while ( --level ) @@ -402,6 +403,8 @@ static int do_recalc(struct p2m_domain *p2m, unsigned long gfn) clear_recalc(l1, e); err = p2m->write_p2m_entry(p2m, gfn, pent, e, level + 1); ASSERT(!err); + + recalc_done = true; } } unmap_domain_page((void *)((unsigned long)pent & PAGE_MASK)); @@ -448,12 +451,14 @@ static int do_recalc(struct p2m_domain *p2m, unsigned long gfn) clear_recalc(l1, e); err = p2m->write_p2m_entry(p2m, gfn, pent, e, level + 1); ASSERT(!err); + + recalc_done = true; } out: unmap_domain_page(table); - return err; + return err ?: recalc_done; } int p2m_pt_handle_deferred_changes(uint64_t gpa) diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 17f320b624..db7bde0230 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1197,7 +1197,7 @@ static int finish_type_change(struct p2m_domain *p2m, rc = p2m->recalc(p2m, gfn); /* * ept->recalc could return 0/1/-ENOMEM. pt->recalc could return - * 0/-ENOMEM/-ENOENT, -ENOENT isn't an error as we are looping + * 0/1/-ENOMEM/-ENOENT, -ENOENT isn't an error as we are looping * gfn here. If rc is 1 we need to have it 0 for success. */ if ( rc == -ENOENT || rc > 0 )