|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] arm/mpu: Implement p2m tables
commit cd5fe09e50111b7c367335f2874b8c91b023e1cd
Author: Harry Ramsey <harry.ramsey@xxxxxxx>
AuthorDate: Wed May 13 13:41:38 2026 +0100
Commit: Michal Orzel <michal.orzel@xxxxxxx>
CommitDate: Fri May 15 09:08:19 2026 +0200
arm/mpu: Implement p2m tables
Implement `p2m_alloc_table`, `p2m_init` and `p2m_final_teardown` for MPU
systems.
Signed-off-by: Harry Ramsey <harry.ramsey@xxxxxxx>
Signed-off-by: Luca Fancellu <luca.fancellu@xxxxxxx>
Reviewed-by: Michal Orzel <michal.orzel@xxxxxxx>
---
xen/arch/arm/include/asm/arm32/mpu.h | 2 +
xen/arch/arm/include/asm/arm64/mpu.h | 2 +
xen/arch/arm/include/asm/mpu/p2m.h | 8 ++++
xen/arch/arm/include/asm/p2m.h | 5 +++
xen/arch/arm/mpu/p2m.c | 72 ++++++++++++++++++++++++++++++++++--
5 files changed, 86 insertions(+), 3 deletions(-)
diff --git a/xen/arch/arm/include/asm/arm32/mpu.h
b/xen/arch/arm/include/asm/arm32/mpu.h
index 2cf0f8cbac..d565230f84 100644
--- a/xen/arch/arm/include/asm/arm32/mpu.h
+++ b/xen/arch/arm/include/asm/arm32/mpu.h
@@ -11,6 +11,8 @@
*/
#define MPU_REGION_RES0 0x0
+#define VSCTLR_VMID_SHIFT 16
+
/* Hypervisor Protection Region Base Address Register */
typedef union {
struct {
diff --git a/xen/arch/arm/include/asm/arm64/mpu.h
b/xen/arch/arm/include/asm/arm64/mpu.h
index 4f694190a8..8b86a03fee 100644
--- a/xen/arch/arm/include/asm/arm64/mpu.h
+++ b/xen/arch/arm/include/asm/arm64/mpu.h
@@ -7,6 +7,8 @@
#define MPU_REGION_RES0 (0xFFFFULL << 48)
+#define VSCTLR_VMID_SHIFT 48
+
/* Protection Region Base Address Register */
typedef union {
struct __packed {
diff --git a/xen/arch/arm/include/asm/mpu/p2m.h
b/xen/arch/arm/include/asm/mpu/p2m.h
index e46d9e757a..1484c75b55 100644
--- a/xen/arch/arm/include/asm/mpu/p2m.h
+++ b/xen/arch/arm/include/asm/mpu/p2m.h
@@ -3,8 +3,16 @@
#ifndef __ARM_MPU_P2M_H__
#define __ARM_MPU_P2M_H__
+#include <xen/bitops.h>
+#include <xen/macros.h>
+#include <xen/page-size.h>
+#include <asm/mpu.h>
+
struct p2m_domain;
+#define P2M_ROOT_PAGES DIV_ROUND_UP(MAX_MPU_REGION_NR * sizeof(pr_t),
PAGE_SIZE)
+#define P2M_ROOT_ORDER get_count_order(P2M_ROOT_PAGES)
+
static inline void p2m_clear_root_pages(struct p2m_domain *p2m) {}
static inline void p2m_tlb_flush_sync(struct p2m_domain *p2m) {}
diff --git a/xen/arch/arm/include/asm/p2m.h b/xen/arch/arm/include/asm/p2m.h
index 23500713a1..4a4913716b 100644
--- a/xen/arch/arm/include/asm/p2m.h
+++ b/xen/arch/arm/include/asm/p2m.h
@@ -51,8 +51,13 @@ struct p2m_domain {
/* Current VMID in use */
uint16_t vmid;
+#ifdef CONFIG_MMU
/* Current Translation Table Base Register for the p2m */
uint64_t vttbr;
+#else
+ /* Current Virtualization System Control Register for the p2m */
+ register_t vsctlr;
+#endif
/* Highest guest frame that's ever been mapped in the p2m */
gfn_t max_mapped_gfn;
diff --git a/xen/arch/arm/mpu/p2m.c b/xen/arch/arm/mpu/p2m.c
index f7fb58ab6a..f3ca8a4ab3 100644
--- a/xen/arch/arm/mpu/p2m.c
+++ b/xen/arch/arm/mpu/p2m.c
@@ -28,10 +28,63 @@ void p2m_dump_info(struct domain *d)
BUG_ON("unimplemented");
}
+static int p2m_alloc_table(struct domain *d)
+{
+ struct p2m_domain *p2m = p2m_get_hostp2m(d);
+ void *table = alloc_xenheap_pages(P2M_ROOT_ORDER, 0);
+ unsigned int i;
+
+ if ( !table )
+ {
+ printk(XENLOG_G_ERR "%pd: p2m: unable to allocate P2M MPU mapping
table\n",
+ d);
+ return -ENOMEM;
+ }
+
+ p2m->root = virt_to_page(table);
+
+ for ( i = 0; i < P2M_ROOT_PAGES; i++ )
+ clear_page(table + (i * PAGE_SIZE));
+
+ return 0;
+}
+
int p2m_init(struct domain *d)
{
- BUG_ON("unimplemented");
- return -EINVAL;
+ struct p2m_domain *p2m = p2m_get_hostp2m(d);
+ int rc = 0;
+ unsigned int cpu;
+
+ rwlock_init(&p2m->lock);
+
+ p2m->vmid = INVALID_VMID;
+ p2m->max_mapped_gfn = _gfn(0);
+ p2m->lowest_mapped_gfn = _gfn(ULONG_MAX);
+
+ p2m->default_access = p2m_access_rwx;
+ /* mem_access is NOT supported on MPU system. */
+ p2m->mem_access_enabled = false;
+
+ /* Ensure that the type chosen is large enough for MAX_VIRT_CPUS. */
+ BUILD_BUG_ON((1 << (sizeof(p2m->last_vcpu_ran[0]) * 8)) < MAX_VIRT_CPUS);
+ BUILD_BUG_ON((1 << (sizeof(p2m->last_vcpu_ran[0]) * 8)) < INVALID_VCPU_ID);
+
+ for_each_possible_cpu(cpu)
+ p2m->last_vcpu_ran[cpu] = INVALID_VCPU_ID;
+
+ /*
+ * "Trivial" initialization is now complete. Set the backpointer so that
+ * p2m_teardown() and related functions know to do something.
+ */
+ p2m->domain = d;
+
+ rc = p2m_alloc_vmid(d);
+ if ( rc )
+ return rc;
+
+ p2m->vsctlr = ((register_t)p2m->vmid << VSCTLR_VMID_SHIFT);
+
+ return p2m_alloc_table(d);
}
void p2m_save_state(struct vcpu *p)
@@ -46,7 +99,20 @@ void p2m_restore_state(struct vcpu *n)
void p2m_final_teardown(struct domain *d)
{
- BUG_ON("unimplemented");
+ struct p2m_domain *p2m = p2m_get_hostp2m(d);
+
+ /* p2m not actually initialized */
+ if ( !p2m->domain )
+ return;
+
+ if ( p2m->root )
+ free_xenheap_pages(page_to_virt(p2m->root), P2M_ROOT_ORDER);
+
+ p2m->root = NULL;
+
+ p2m_free_vmid(d);
+
+ p2m->domain = NULL;
}
bool p2m_resolve_translation_fault(struct domain *d, gfn_t gfn)
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |