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",
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 )
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));
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)
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 )