summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>2020-10-15 19:44:32 +0300
committerAlex Bennée <alex.bennee@linaro.org>2020-10-23 16:06:19 +0100
commit7c714bd0d561dc5dac76ff2705e3c55104c73f1b (patch)
treedf2b55d50c52003e57384a12a6168bb836a809b6
parentb45368e1c8bd471025198b2f16bb279e672f762b (diff)
xen/arm: Add mapcache invalidation handling
We need to send mapcache invalidation request to qemu/demu everytime the page gets removed from a guest. At the moment, the Arm code doesn't explicitely remove the existing mapping before inserting the new mapping. Instead, this is done implicitely by __p2m_set_entry(). So the corresponding flag will be set in __p2m_set_entry() if old entry is a RAM page *and* the new MFN is different. And the invalidation request will be sent in do_trap_hypercall() later on. Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> CC: Julien Grall <julien.grall@arm.com> Message-Id: <1602780274-29141-22-git-send-email-olekstysh@gmail.com>
-rw-r--r--xen/arch/arm/p2m.c8
-rw-r--r--xen/arch/arm/traps.c13
2 files changed, 18 insertions, 3 deletions
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 370173c51b..2693b0c6c6 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -1,6 +1,7 @@
#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>
@@ -1067,7 +1068,14 @@ static int __p2m_set_entry(struct p2m_domain *p2m,
*/
if ( p2m_is_valid(orig_pte) &&
!mfn_eq(lpae_get_mfn(*entry), lpae_get_mfn(orig_pte)) )
+ {
+#ifdef CONFIG_IOREQ_SERVER
+ if ( domain_has_ioreq_server(p2m->domain) &&
+ (p2m->domain == current->domain) && p2m_is_ram(orig_pte.p2m.type) )
+ p2m->domain->qemu_mapcache_invalidate = true;
+#endif
p2m_free_entry(p2m, orig_pte, level);
+ }
out:
unmap_domain_page(table);
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index a8f5fdfeae..9eaa3420ef 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1442,6 +1442,7 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
const union hsr hsr)
{
arm_hypercall_fn_t call = NULL;
+ struct vcpu *v = current;
BUILD_BUG_ON(NR_hypercalls < ARRAY_SIZE(arm_hypercall_table) );
@@ -1458,7 +1459,7 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
return;
}
- current->hcall_preempted = false;
+ v->hcall_preempted = false;
perfc_incra(hypercalls, *nr);
call = arm_hypercall_table[*nr].fn;
@@ -1471,7 +1472,7 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
HYPERCALL_RESULT_REG(regs) = call(HYPERCALL_ARGS(regs));
#ifndef NDEBUG
- if ( !current->hcall_preempted )
+ if ( !v->hcall_preempted )
{
/* Deliberately corrupt parameter regs used by this hypercall. */
switch ( arm_hypercall_table[*nr].nr_args ) {
@@ -1488,8 +1489,14 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
#endif
/* Ensure the hypercall trap instruction is re-executed. */
- if ( current->hcall_preempted )
+ if ( v->hcall_preempted )
regs->pc -= 4; /* re-execute 'hvc #XEN_HYPERCALL_TAG' */
+
+#ifdef CONFIG_IOREQ_SERVER
+ if ( unlikely(v->domain->qemu_mapcache_invalidate) &&
+ test_and_clear_bool(v->domain->qemu_mapcache_invalidate) )
+ send_invalidate_ioreq();
+#endif
}
void arch_hypercall_tasklet_result(struct vcpu *v, long res)