#include <xen/cpu.h>
#include <xen/domain_page.h>
#include <xen/iocap.h>
+#include <xen/ioreq.h>
#include <xen/lib.h>
#include <xen/sched.h>
#include <xen/softirq.h>
if ( !p2m_is_valid(entry) )
return;
- /* Nothing to do but updating the stats if the entry is a super-page. */
- if ( p2m_is_superpage(entry, level) )
+ if ( p2m_is_superpage(entry, level) || (level == 3) )
{
- p2m->stats.mappings[level]--;
- return;
- }
+#ifdef CONFIG_IOREQ_SERVER
+ /*
+ * If this gets called then either the entry was replaced by an entry
+ * with a different base (valid case) or the shattering of a superpage
+ * has failed (error case).
+ * So, at worst, the spurious mapcache invalidation might be sent.
+ */
+ if ( (p2m->domain == current->domain) &&
+ domain_has_ioreq_server(p2m->domain) &&
+ p2m_is_ram(entry.p2m.type) )
+ p2m->domain->mapcache_invalidate = true;
+#endif
- if ( level == 3 )
- {
p2m->stats.mappings[level]--;
- p2m_put_l3_page(entry);
+ /* Nothing to do if the entry is a super-page. */
+ if ( level == 3 )
+ p2m_put_l3_page(entry);
return;
}
const union hsr hsr)
{
arm_hypercall_fn_t call = NULL;
+ struct vcpu *curr = current;
BUILD_BUG_ON(NR_hypercalls < ARRAY_SIZE(arm_hypercall_table) );
return;
}
- current->hcall_preempted = false;
+ curr->hcall_preempted = false;
perfc_incra(hypercalls, *nr);
call = arm_hypercall_table[*nr].fn;
HYPERCALL_RESULT_REG(regs) = call(HYPERCALL_ARGS(regs));
#ifndef NDEBUG
- if ( !current->hcall_preempted )
+ if ( !curr->hcall_preempted )
{
/* Deliberately corrupt parameter regs used by this hypercall. */
switch ( arm_hypercall_table[*nr].nr_args ) {
#endif
/* Ensure the hypercall trap instruction is re-executed. */
- if ( current->hcall_preempted )
+ if ( curr->hcall_preempted )
regs->pc -= 4; /* re-execute 'hvc #XEN_HYPERCALL_TAG' */
+
+#ifdef CONFIG_IOREQ_SERVER
+ /*
+ * We call ioreq_signal_mapcache_invalidate from do_trap_hypercall()
+ * because the only way a guest can modify its P2M on Arm is via an
+ * hypercall.
+ * Note that sending the invalidation request causes the vCPU to block
+ * until all the IOREQ servers have acknowledged the invalidation.
+ */
+ if ( unlikely(curr->domain->mapcache_invalidate) &&
+ test_and_clear_bool(curr->domain->mapcache_invalidate) )
+ ioreq_signal_mapcache_invalidate();
+#endif
}
void arch_hypercall_tasklet_result(struct vcpu *v, long res)