From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Borrow x86's logic to invalidate qemu mapcache.
TODO: Move send_invalidate_req() to common code (ioreq.c?).
Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
---
xen/arch/arm/ioreq.c | 14 ++++++++++++++
xen/arch/arm/traps.c | 6 ++++++
xen/common/memory.c | 6 ++++++
xen/include/asm-arm/domain.h | 2 ++
xen/include/asm-arm/hvm/ioreq.h | 2 ++
5 files changed, 30 insertions(+)
diff --git a/xen/arch/arm/ioreq.c b/xen/arch/arm/ioreq.c
index a9cc839..8f60c41 100644
--- a/xen/arch/arm/ioreq.c
+++ b/xen/arch/arm/ioreq.c
@@ -75,6 +75,20 @@ bool handle_mmio(void)
return true;
}
+/* Ask ioemu mapcache to invalidate mappings. */
+void send_invalidate_req(void)
+{
+ ioreq_t p = {
+ .type = IOREQ_TYPE_INVALIDATE,
+ .size = 4,
+ .dir = IOREQ_WRITE,
+ .data = ~0UL, /* flush all */
+ };
+
+ if ( hvm_broadcast_ioreq(&p, false) != 0 )
+ gprintk(XENLOG_ERR, "Unsuccessful map-cache invalidate\n");
+}
+
/*
* Local variables:
* mode: C
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 4cdf098..ea472d1 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1490,6 +1490,12 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
/* Ensure the hypercall trap instruction is re-executed. */
if ( current->hcall_preempted )
regs->pc -= 4; /* re-execute 'hvc #XEN_HYPERCALL_TAG' */
+
+#ifdef CONFIG_IOREQ_SERVER
+ if ( unlikely(current->domain->arch.hvm.qemu_mapcache_invalidate) &&
+ test_and_clear_bool(current->domain->arch.hvm.qemu_mapcache_invalidate) )
+ send_invalidate_req();
+#endif
}
void arch_hypercall_tasklet_result(struct vcpu *v, long res)
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 8b306f6..8d9f0a8 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -1652,6 +1652,12 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
break;
}
+ /* x86 already sets the flag in hvm_memory_op() */
+#if defined(CONFIG_ARM64) && defined(CONFIG_IOREQ_SERVER)
+ if ( op == XENMEM_decrease_reservation )
+ curr_d->arch.hvm.qemu_mapcache_invalidate = true;
+#endif
+
return rc;
}
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index e060b0a..0db8bb4 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -69,6 +69,8 @@ struct hvm_domain
spinlock_t lock;
struct hvm_ioreq_server *server[MAX_NR_IOREQ_SERVERS];
} ioreq_server;
+
+ bool_t qemu_mapcache_invalidate;
};
#ifdef CONFIG_ARM_64
diff --git a/xen/include/asm-arm/hvm/ioreq.h b/xen/include/asm-arm/hvm/ioreq.h
index 83a560c..392ce64 100644
--- a/xen/include/asm-arm/hvm/ioreq.h
+++ b/xen/include/asm-arm/hvm/ioreq.h
@@ -90,6 +90,8 @@ static inline void arch_hvm_ioreq_destroy(struct domain *d)
#define IOREQ_IO_UNHANDLED IO_UNHANDLED
#define IOREQ_IO_RETRY IO_RETRY
+void send_invalidate_req(void);
+
#endif /* __ASM_X86_HVM_IOREQ_H__ */
/*
--
2.7.4
Borrow x86's logic to invalidate qemu mapcache.
TODO: Move send_invalidate_req() to common code (ioreq.c?).
Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
---
xen/arch/arm/ioreq.c | 14 ++++++++++++++
xen/arch/arm/traps.c | 6 ++++++
xen/common/memory.c | 6 ++++++
xen/include/asm-arm/domain.h | 2 ++
xen/include/asm-arm/hvm/ioreq.h | 2 ++
5 files changed, 30 insertions(+)
diff --git a/xen/arch/arm/ioreq.c b/xen/arch/arm/ioreq.c
index a9cc839..8f60c41 100644
--- a/xen/arch/arm/ioreq.c
+++ b/xen/arch/arm/ioreq.c
@@ -75,6 +75,20 @@ bool handle_mmio(void)
return true;
}
+/* Ask ioemu mapcache to invalidate mappings. */
+void send_invalidate_req(void)
+{
+ ioreq_t p = {
+ .type = IOREQ_TYPE_INVALIDATE,
+ .size = 4,
+ .dir = IOREQ_WRITE,
+ .data = ~0UL, /* flush all */
+ };
+
+ if ( hvm_broadcast_ioreq(&p, false) != 0 )
+ gprintk(XENLOG_ERR, "Unsuccessful map-cache invalidate\n");
+}
+
/*
* Local variables:
* mode: C
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 4cdf098..ea472d1 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -1490,6 +1490,12 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
/* Ensure the hypercall trap instruction is re-executed. */
if ( current->hcall_preempted )
regs->pc -= 4; /* re-execute 'hvc #XEN_HYPERCALL_TAG' */
+
+#ifdef CONFIG_IOREQ_SERVER
+ if ( unlikely(current->domain->arch.hvm.qemu_mapcache_invalidate) &&
+ test_and_clear_bool(current->domain->arch.hvm.qemu_mapcache_invalidate) )
+ send_invalidate_req();
+#endif
}
void arch_hypercall_tasklet_result(struct vcpu *v, long res)
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 8b306f6..8d9f0a8 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -1652,6 +1652,12 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
break;
}
+ /* x86 already sets the flag in hvm_memory_op() */
+#if defined(CONFIG_ARM64) && defined(CONFIG_IOREQ_SERVER)
+ if ( op == XENMEM_decrease_reservation )
+ curr_d->arch.hvm.qemu_mapcache_invalidate = true;
+#endif
+
return rc;
}
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index e060b0a..0db8bb4 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -69,6 +69,8 @@ struct hvm_domain
spinlock_t lock;
struct hvm_ioreq_server *server[MAX_NR_IOREQ_SERVERS];
} ioreq_server;
+
+ bool_t qemu_mapcache_invalidate;
};
#ifdef CONFIG_ARM_64
diff --git a/xen/include/asm-arm/hvm/ioreq.h b/xen/include/asm-arm/hvm/ioreq.h
index 83a560c..392ce64 100644
--- a/xen/include/asm-arm/hvm/ioreq.h
+++ b/xen/include/asm-arm/hvm/ioreq.h
@@ -90,6 +90,8 @@ static inline void arch_hvm_ioreq_destroy(struct domain *d)
#define IOREQ_IO_UNHANDLED IO_UNHANDLED
#define IOREQ_IO_RETRY IO_RETRY
+void send_invalidate_req(void);
+
#endif /* __ASM_X86_HVM_IOREQ_H__ */
/*
--
2.7.4