[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 3/6] arm/mpu: Populate a new region in Xen MPU mapping table
- To: Hari Limaye <hari.limaye@xxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
- From: Ayan Kumar Halder <ayankuma@xxxxxxx>
- Date: Wed, 25 Jun 2025 15:15:37 +0100
- Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=CYgPdWRnj0mClzlnmlH/ZXSxxYpCMH3YEgd7+AiGMKI=; b=IggMYjkk7fRiKdeQ9IJZR/S6gclS1UrT+G/7VD5KB+IDsbW0JccFfwxOASmhyN/pfJhG6revEAYVnE03Xffm3g+ibrG1wtfb+VAkuaPiHOZtEfZEz3mhH5B34x7Gu+MOROw7pOh44jwpXwYig0TxlQyPS5eTf7/WS+bshRuUyC+LX2XFQbuC6i9DrrYbdguLCegfIbn7azkmyqhEkoAjnmzVK8tbgKxzbKrmg9uNrPjPWi4xfRZSBB7pXi49gYQFDE685JaIBvLp3CTK9JZM/ZqZc91rC/Jq43G/l+5988okQUZi6rbAOwFWzXpreLTISroGlC5hZDNEZKaEmsa5mw==
- Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=t/jtHwp2ltemq7fKVS9aCx3NakRwA8j/mAgTQQlRunvX41vX9eIS6JSQzYwyKkHTAfQo6EUgzKFY4lArKYMjYv+LU2eJRP13kmfnc6OeB39bpEC3/0PTCRyZ2A+VSlSaPDrkRzDWKLl7w2UD23XKv6HtFc3FGwejKCvJo0Cel6aA7DPQv4B9fOhlKqc2N+zz0L1QWR3VwqhPNykstv2X70UmTYn4j2cTm28pp2VXRw1jhD7yxg2qzcK1luEo/qbrt5H/Kj9ayguJUlr8QNNl1gt6QGvhtWrlRBLNEFPPNA7p4jLSASzKrpKOk9ZilJvsVN+30lD0DBqnr7LeFjLwnw==
- Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com;
- Cc: luca.fancellu@xxxxxxx, Penny Zheng <Penny.Zheng@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Wei Chen <wei.chen@xxxxxxx>
- Delivery-date: Wed, 25 Jun 2025 14:15:52 +0000
- List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
Hi Hari,
Some questions.
On 20/06/2025 10:49, Hari Limaye wrote:
CAUTION: This message has originated from an External Source. Please use proper
judgment and caution when opening attachments, clicking links, or responding to
this email.
From: Penny Zheng <Penny.Zheng@xxxxxxx>
Introduce map_pages_to_xen() that is implemented using a new helper,
xen_mpumap_update(), which is responsible for updating Xen MPU memory
mapping table(xen_mpumap), including creating a new entry, updating
or destroying an existing one, it is equivalent to xen_pt_update in MMU.
This commit only implements populating a new entry in Xen MPU memory mapping
table(xen_mpumap).
Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
Signed-off-by: Wei Chen <wei.chen@xxxxxxx>
Signed-off-by: Luca Fancellu <luca.fancellu@xxxxxxx>
Signed-off-by: Hari Limaye <hari.limaye@xxxxxxx>
---
xen/arch/arm/include/asm/mpu/mm.h | 12 ++++
xen/arch/arm/mpu/mm.c | 96 +++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+)
diff --git a/xen/arch/arm/include/asm/mpu/mm.h
b/xen/arch/arm/include/asm/mpu/mm.h
index a0f0d86d4a..f0f41db210 100644
--- a/xen/arch/arm/include/asm/mpu/mm.h
+++ b/xen/arch/arm/include/asm/mpu/mm.h
@@ -64,6 +64,7 @@ static inline void context_sync_mpu(void)
* The following API requires context_sync_mpu() after being used to modify
MPU
* regions:
* - write_protection_region
+ * - xen_mpumap_update
*/
/* Reads the MPU region (into @pr_read) with index @sel from the HW */
@@ -72,6 +73,17 @@ void read_protection_region(pr_t *pr_read, uint8_t sel);
/* Writes the MPU region (from @pr_write) with index @sel to the HW */
void write_protection_region(const pr_t *pr_write, uint8_t sel);
+/*
+ * Maps an address range into the MPU data structure and updates the HW.
+ * Equivalent to xen_pt_update in an MMU system.
+ *
+ * @param base Base address of the range to map (inclusive).
+ * @param limit Limit address of the range to map (exclusive).
+ * @param flags Flags for the memory range to map.
+ * @return 0 on success, negative on error.
+ */
+int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags);
+
/*
* Creates a pr_t structure describing a protection region.
*
diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
index 15197339b1..1de28d2120 100644
--- a/xen/arch/arm/mpu/mm.c
+++ b/xen/arch/arm/mpu/mm.c
@@ -6,6 +6,7 @@
#include <xen/lib.h>
#include <xen/mm.h>
#include <xen/sizes.h>
+#include <xen/spinlock.h>
#include <xen/types.h>
#include <asm/mpu.h>
#include <asm/mpu/mm.h>
@@ -41,6 +42,8 @@ DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR) \
/* EL2 Xen MPU memory region mapping table. */
pr_t __cacheline_aligned __section(".data") xen_mpumap[MAX_MPU_REGION_NR];
+static DEFINE_SPINLOCK(xen_mpumap_lock);
+
static void __init __maybe_unused build_assertions(void)
{
/*
@@ -176,6 +179,99 @@ int mpumap_contain_region(pr_t *table, uint8_t nr_regions,
paddr_t base,
return MPUMAP_REGION_NOTFOUND;
}
+/*
+ * Allocate a new free EL2 MPU memory region, based on bitmap xen_mpumap_mask.
+ * @param idx Set to the index of the allocated EL2 MPU region on success.
+ * @return 0 on success, otherwise -ENOENT on failure.
+ */
+static int xen_mpumap_alloc_entry(uint8_t *idx)
+{
+ ASSERT(spin_is_locked(&xen_mpumap_lock));
+
+ *idx = find_first_zero_bit(xen_mpumap_mask, max_mpu_regions);
+ if ( *idx == max_mpu_regions )
+ {
+ printk(XENLOG_ERR "mpu: EL2 MPU memory region mapping pool
exhausted\n");
+ return -ENOENT;
+ }
+
+ set_bit(*idx, xen_mpumap_mask);
+ return 0;
+}
+
+/*
+ * Update the entry in the MPU memory region mapping table (xen_mpumap) for the
+ * given memory range and flags, creating one if none exists.
+ *
+ * @param base Base address (inclusive).
+ * @param limit Limit address (exclusive).
+ * @param flags Region attributes (a combination of PAGE_HYPERVISOR_XXX)
+ * @return 0 on success, otherwise negative on error.
+ */
+static int xen_mpumap_update_entry(paddr_t base, paddr_t limit,
+ unsigned int flags)
+{
+ uint8_t idx;
+ int rc;
+
+ ASSERT(spin_is_locked(&xen_mpumap_lock));
+
+ rc = mpumap_contain_region(xen_mpumap, max_mpu_regions, base, limit, &idx);
+ if ( (rc < 0) || (rc > MPUMAP_REGION_NOTFOUND) )
if ( !(rc == MPUMAP_REGION_NOTFOUND) ) <<-- Does it read better ?
+ return -EINVAL;
+
+ /* We are inserting a mapping => Create new region. */
+ if ( flags & _PAGE_PRESENT )
Why do we need to check for this flag ? Or where have we set it.
If we have reached here, doesn't it mean that the region does not exist.
So we need to create one.
+ {
+ rc = xen_mpumap_alloc_entry(&idx);
+ if ( rc )
+ return -ENOENT;
+
+ xen_mpumap[idx] = pr_of_addr(base, limit, flags);
+
+ write_protection_region(&xen_mpumap[idx], idx);
+ }
+
+ return 0;
+}
+
+int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags)
+{
+ int rc;
+
+ if ( flags_has_rwx(flags) )
+ {
+ region_printk("Mappings should not be both Writeable and
Executable\n");
+ return -EINVAL;
+ }
+
+ if ( !IS_ALIGNED(base, PAGE_SIZE) || !IS_ALIGNED(limit, PAGE_SIZE) )
+ {
+ region_printk("base address 0x%"PRIpaddr", or limit address 0x%"PRIpaddr"
is not page aligned\n",
+ base, limit);
+ return -EINVAL;
+ }
+
+ spin_lock(&xen_mpumap_lock);
+
+ rc = xen_mpumap_update_entry(base, limit, flags);
+
+ spin_unlock(&xen_mpumap_lock);
+
+ return rc;
+}
+
+int map_pages_to_xen(unsigned long virt, mfn_t mfn, unsigned long nr_mfns,
+ unsigned int flags)
+{
+ int rc = xen_mpumap_update(mfn_to_maddr(mfn),
+ mfn_to_maddr(mfn_add(mfn, nr_mfns)), flags);
+ if ( !rc )
+ context_sync_mpu();
+
+ return rc;
+}
+
void __init setup_mm(void)
{
BUG_ON("unimplemented");
Rest look good to me.
- Ayan
--
2.34.1
|