From nobody Tue May 5 08:59:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776695155; cv=none; d=zohomail.com; s=zohoarc; b=Qwm1CoskINGolF5SOX/25gmYN2TRX9jIbSZepN6E/GA80bwjCFVS3vwcbvbEgrjXxA9B36Fsr0KS0/vmS/p5vuAjl3Oa77O509v4nOUMBi7LK+i6XdDkwNA+m816eBhbekBeDqomFGpYd3hzkmWUgoe9CbDFjG4MZIE1PJyHuNc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776695155; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=0IxAB4NwvT3mQfHcGAEy33LPD3hSzQBY9sh7394XBHU=; b=eferVQlgEfeVAmFzX2vCS5yJcPlTIOPIzYZOHgVv7+H0ZJyfJIDau/KcBT7hvjsPSnM02fZsPVtOMfdMK/QPzTBFhcz2fsoQE55Gzw8QDTxl5kC+j4cMcZIkXrJ0AciLCdD/7qeXGMK7OJK6yXXFJUXq6MyqtH06XnD4WlLIXKQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 177669515499772.83445422448642; Mon, 20 Apr 2026 07:25:54 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1286086.1567203 (Exim 4.92) (envelope-from ) id 1wEpZC-0004RK-0C; Mon, 20 Apr 2026 14:25:38 +0000 Received: by outflank-mailman (output) from mailman id 1286086.1567203; Mon, 20 Apr 2026 14:25:37 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZB-0004RD-TT; Mon, 20 Apr 2026 14:25:37 +0000 Received: by outflank-mailman (input) for mailman id 1286086; Mon, 20 Apr 2026 14:25:36 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZ9-0004DT-V4 for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 14:25:36 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wEpZ9-00DjKj-BW for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 16:25:35 +0200 Received: from [10.42.69.10] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e63750-bab6-0a2a0a5309dd-0a2a450a9acc-16 for ; Mon, 20 Apr 2026 16:25:35 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-4011c0.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e6375e-56b3-0a2a450a0019-d98c6eaccd08-1 for ; Mon, 20 Apr 2026 16:25:35 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5E7A316F2; Mon, 20 Apr 2026 07:25:28 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 769003F7B4; Mon, 20 Apr 2026 07:25:32 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776695133; bh=J3CyMkSY0KMV9Fw732pi6w6qLPzHaJTo8ZwxErzPiWc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e9xVvGHL8pn8PbTX3/4XMRA1Ddaaa52XlXWInaCUNZoMlcG0PmKjboXUKjXZsIevC ktjQHQGMMSq7GJgB5qJXYwJN0p+niIbVJn8mqTLdQM2aa5NLKSekU6SmyqZY3f0fXQ bGDcDjkoQtI2ahVJuxUKu1KR2fvLaAYUgAlQ0Ni4= From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen , Hari Limaye , Harry Ramsey Subject: [PATCH 1/8] xen/arm: Implement p2m_set_entry for MPU systems Date: Mon, 20 Apr 2026 15:25:17 +0100 Message-Id: <20260420142524.1804073-2-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260420142524.1804073-1-luca.fancellu@arm.com> References: <20260420142524.1804073-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-4011c0/1776695135-CE36B8B7-645A68D7/0/0 X-purgate-type: clean X-purgate-size: 12640 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776695155799158500 Content-Type: text/plain; charset="utf-8" From: Penny Zheng Implement the function `p2m_set_entry`, which is responsible for inserting a new entry into the p2m tables, for MPU systems. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye Signed-off-by: Harry Ramsey --- xen/arch/arm/include/asm/arm32/mpu.h | 3 +- xen/arch/arm/include/asm/arm64/mpu.h | 3 +- xen/arch/arm/include/asm/mpu/mm.h | 3 +- xen/arch/arm/include/asm/mpu/p2m.h | 10 +++ xen/arch/arm/include/asm/p2m.h | 3 + xen/arch/arm/mpu/mm.c | 43 ++++++---- xen/arch/arm/mpu/p2m.c | 123 ++++++++++++++++++++++++++- 7 files changed, 167 insertions(+), 21 deletions(-) diff --git a/xen/arch/arm/include/asm/arm32/mpu.h b/xen/arch/arm/include/as= m/arm32/mpu.h index d565230f84ee..ab58df079920 100644 --- a/xen/arch/arm/include/asm/arm32/mpu.h +++ b/xen/arch/arm/include/asm/arm32/mpu.h @@ -42,7 +42,8 @@ typedef struct { prbar_t prbar; prlar_t prlar; uint8_t refcount; - uint8_t pad[7]; /* Pad structure to 16 Bytes */ + uint8_t p2m_type; + uint8_t pad[6]; /* Pad structure to 16 Bytes */ } pr_t; =20 #endif /* __ASSEMBLER__ */ diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/as= m/arm64/mpu.h index 8b86a03fee44..c82624f0f2cf 100644 --- a/xen/arch/arm/include/asm/arm64/mpu.h +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -41,7 +41,8 @@ typedef struct { prbar_t prbar; prlar_t prlar; uint8_t refcount; - uint8_t pad[15]; /* Pad structure to 32 Bytes */ + uint8_t p2m_type; + uint8_t pad[14]; /* Pad structure to 32 Bytes */ } pr_t; =20 #endif /* __ASSEMBLER__ */ diff --git a/xen/arch/arm/include/asm/mpu/mm.h b/xen/arch/arm/include/asm/m= pu/mm.h index 1b5ffa5b644d..24bffdee4fb6 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -75,9 +75,10 @@ void write_protection_region(const pr_t *pr_write, uint8= _t sel); * @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. + * @param p2m True for a stage 2 mapping, otherwise False. * @return 0 on success, negative on error. */ -int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags); +int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags, boo= l p2m); =20 /* * Creates a pr_t structure describing a protection region. diff --git a/xen/arch/arm/include/asm/mpu/p2m.h b/xen/arch/arm/include/asm/= mpu/p2m.h index 39fc0c944916..b9c7be2d9dcc 100644 --- a/xen/arch/arm/include/asm/mpu/p2m.h +++ b/xen/arch/arm/include/asm/mpu/p2m.h @@ -21,6 +21,16 @@ static inline void p2m_clear_root_pages(struct p2m_domai= n *p2m) {} =20 static inline void p2m_tlb_flush_sync(struct p2m_domain *p2m) {} =20 +static inline void region_set_p2m(pr_t *pr, p2m_type_t p2m_type) +{ + pr->p2m_type =3D p2m_type; +} + +static inline p2m_type_t region_get_p2m(pr_t *pr) +{ + return pr->p2m_type; +} + #endif /* __ARM_MPU_P2M_H__ */ =20 /* diff --git a/xen/arch/arm/include/asm/p2m.h b/xen/arch/arm/include/asm/p2m.h index ed1b6dd40f40..43b383885da0 100644 --- a/xen/arch/arm/include/asm/p2m.h +++ b/xen/arch/arm/include/asm/p2m.h @@ -54,6 +54,9 @@ struct p2m_domain { #else /* Current Virtualization System Control Register for the p2m */ register_t vsctlr; + + /* Number of MPU memory regions in P2M MPU memory mapping table. */ + uint8_t nr_regions; #endif =20 /* Highest guest frame that's ever been mapped in the p2m */ diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index aff88bd3a9c1..4ee58ded5ad6 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -317,13 +317,14 @@ static int xen_mpumap_free_entry(uint8_t idx, int reg= ion_found_type) * Update the entry in the MPU memory region mapping table (xen_mpumap) fo= r 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) + * @param base Base address (inclusive). + * @param limit Limit address (exclusive). + * @param flags Region attributes (a combination of PAGE_HYPERVISOR_XX= X) + * @param p2m True for a stage 2 mapping, otherwise False. * @return 0 on success, otherwise negative on error. */ static int xen_mpumap_update_entry(paddr_t base, paddr_t limit, - unsigned int flags) + unsigned int flags, bool p2m) { bool flags_has_page_present; uint8_t idx; @@ -399,6 +400,8 @@ static int xen_mpumap_update_entry(paddr_t base, paddr_= t limit, return -ENOENT; =20 xen_mpumap[idx] =3D pr_of_addr(base, limit, flags); + /* AP[0] always 1 for stage 2 */ + xen_mpumap[idx].prbar.reg.ap_0 =3D (p2m ? 1 : 0); =20 write_protection_region(&xen_mpumap[idx], idx); } @@ -418,33 +421,41 @@ static int xen_mpumap_update_entry(paddr_t base, padd= r_t limit, return 0; } =20 -int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags) +int check_mpu_mapping(paddr_t base, paddr_t limit, unsigned int flags) { - int rc; - if ( flags_has_rwx(flags) ) { printk("Mappings should not be both Writeable and Executable\n"); - return -EINVAL; + return false; } =20 if ( base >=3D limit ) { printk("Base address %#"PRIpaddr" must be smaller than limit addre= ss %#"PRIpaddr"\n", base, limit); - return -EINVAL; + return false; } =20 if ( !IS_ALIGNED(base, PAGE_SIZE) || !IS_ALIGNED(limit, PAGE_SIZE) ) { printk("base address %#"PRIpaddr", or limit address %#"PRIpaddr" i= s not page aligned\n", base, limit); - return -EINVAL; + return false; } =20 + return true; +} + +int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags, boo= l p2m) +{ + int rc; + + if ( !check_mpu_mapping(base, limit, flags) ) + return -EINVAL; + spin_lock(&xen_mpumap_lock); =20 - rc =3D xen_mpumap_update_entry(base, limit, flags); + rc =3D xen_mpumap_update_entry(base, limit, flags, p2m); if ( !rc ) context_sync_mpu(); =20 @@ -459,7 +470,7 @@ int destroy_xen_mappings(unsigned long s, unsigned long= e) ASSERT(IS_ALIGNED(e, PAGE_SIZE)); ASSERT(s < e); =20 - return xen_mpumap_update(s, e, 0); + return xen_mpumap_update(s, e, 0, false); } =20 int destroy_xen_mapping_containing(paddr_t s) @@ -499,7 +510,7 @@ int map_pages_to_xen(unsigned long virt, mfn_t mfn, uns= igned long nr_mfns, unsigned int flags) { /* MPU systems have no translation, ma =3D=3D va, so pass virt directl= y */ - return xen_mpumap_update(virt, mfn_to_maddr(mfn_add(mfn, nr_mfns)), fl= ags); + return xen_mpumap_update(virt, mfn_to_maddr(mfn_add(mfn, nr_mfns)), fl= ags, false); } =20 /* @@ -520,7 +531,7 @@ void __init setup_mm_helper(void) paddr_t bank_end =3D bank_start + bank_size; =20 /* Map static heap with one MPU protection region */ - if ( xen_mpumap_update(bank_start, bank_end, PAGE_HYPERVISOR) ) + if ( xen_mpumap_update(bank_start, bank_end, PAGE_HYPERVISOR, = false) ) panic("Failed to map static heap\n"); =20 break; @@ -533,7 +544,7 @@ void __init setup_mm_helper(void) =20 int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int nf) { - return xen_mpumap_update(s, e, nf); + return xen_mpumap_update(s, e, nf, false); } =20 void dump_hyp_walk(vaddr_t addr) @@ -598,7 +609,7 @@ void __iomem *ioremap_attr(paddr_t start, size_t len, u= nsigned int flags) paddr_t start_pg =3D round_pgdown(start); paddr_t end_pg =3D round_pgup(start + len); =20 - if ( xen_mpumap_update(start_pg, end_pg, flags) ) + if ( xen_mpumap_update(start_pg, end_pg, flags, false) ) return NULL; =20 /* Mapped or already mapped */ diff --git a/xen/arch/arm/mpu/p2m.c b/xen/arch/arm/mpu/p2m.c index ec8f630acd90..4a8595b1b25e 100644 --- a/xen/arch/arm/mpu/p2m.c +++ b/xen/arch/arm/mpu/p2m.c @@ -8,12 +8,131 @@ #include #include #include +#include + +static inline unsigned int build_p2m_flags(p2m_type_t t) +{ + unsigned int flags =3D 0; + + BUILD_BUG_ON(p2m_max_real_type > (1 << 4)); + + switch ( t ) + { + case p2m_ram_rw: + /* Nothing to do, XN=3D0, RO=3D0 */ + break; + + case p2m_ram_ro: + flags |=3D _PAGE_RO; + break; + + case p2m_invalid: + flags |=3D _PAGE_XN | _PAGE_RO; + break; + + case p2m_max_real_type: + BUG(); + break; + + case p2m_mmio_direct_dev: + case p2m_mmio_direct_nc: + case p2m_mmio_direct_c: + case p2m_iommu_map_ro: + case p2m_iommu_map_rw: + case p2m_map_foreign_ro: + case p2m_map_foreign_rw: + case p2m_grant_map_ro: + case p2m_grant_map_rw: + panic(XENLOG_G_ERR "p2m: UNIMPLEMENTED p2m permission in MPU syste= m\n"); + break; + } + + flags |=3D MT_NORMAL; + + return flags; +} + +/* + * Check whether guest memory region [`sgfn`, `sgfn` + `nr_gfns`) is mappe= d in + * mpumap `table`. + * + * If the memory region is mapped, `idx` is set to the index of the associ= ated + * MPU memory region and 0 is returned. + * If the memory region is not mapped, -ENOENT is returned. + */ +static int is_gfns_mapped(pr_t *table, uint8_t nr_regions, gfn_t sgfn, + unsigned long nr_gfns, uint8_t *idx) +{ + paddr_t gbase =3D gfn_to_gaddr(sgfn); + paddr_t glimit =3D gfn_to_gaddr(gfn_add(sgfn, nr_gfns)); + int rc; + + rc =3D mpumap_contains_region(table, nr_regions, gbase, glimit, idx); + if ( MPUMAP_REGION_OVERLAP =3D=3D rc ) + return -EINVAL; + + if ( MPUMAP_REGION_NOTFOUND =3D=3D rc ) + return -ENOENT; + + return 0; +} + +static int __p2m_set_entry(struct p2m_domain *p2m, gfn_t sgfn, unsigned in= t nr, + mfn_t smfn, p2m_type_t t, p2m_access_t a) +{ + pr_t *table; + mfn_t emfn =3D mfn_add(smfn, nr); + unsigned int flags; + uint8_t idx =3D INVALID_REGION_IDX; + + /* + * In all cases other than when removing a mapping (mfn =3D=3D MFN_INV= ALID), + * gfn =3D=3D mfn on MPU systems. + */ + if ( !mfn_eq(smfn, INVALID_MFN) && gfn_x(sgfn) !=3D mfn_x(smfn) ) + { + printk(XENLOG_G_ERR "Unable to map MFN %#"PRI_mfn" at %#"PRI_mfn"\= n", + mfn_x(smfn), gfn_x(sgfn)); + return -EINVAL; + } + + table =3D (pr_t *)page_to_virt(p2m->root); + if ( !table ) + return -EINVAL; + + /* Already mapped */ + if ( is_gfns_mapped(table, p2m->nr_regions, sgfn, nr, &idx) !=3D -ENOE= NT ) + { + printk(XENLOG_G_ERR "Unable to insert P2M MPU memory region %#"PRI= paddr"-%#"PRIpaddr"\n", + gfn_to_gaddr(sgfn), gfn_to_gaddr(gfn_add(sgfn, nr))); + return -EINVAL; + } + + flags =3D build_p2m_flags(t); + table[p2m->nr_regions] =3D pr_of_addr(mfn_to_maddr(smfn), + mfn_to_maddr(mfn_add(smfn, nr)), f= lags); + region_set_p2m(&table[p2m->nr_regions], t); + p2m->nr_regions++; + + p2m->max_mapped_gfn =3D gfn_max(p2m->max_mapped_gfn, _gfn(mfn_x(emfn))= ); + p2m->lowest_mapped_gfn =3D gfn_min(p2m->lowest_mapped_gfn, _gfn(mfn_x(= smfn))); + + return 0; +} =20 int p2m_set_entry(struct p2m_domain *p2m, gfn_t sgfn, unsigned long nr, mfn_t smfn, p2m_type_t t, p2m_access_t a) { - BUG_ON("unimplemented"); - return -EINVAL; + /* + * Any reference taken by the P2M mappings (e.g. foreign mapping) will + * be dropped in relinquish_p2m_mapping(). As the P2M will still + * be accessible after, we need to prevent mapping to be added when the + * domain is dying. + */ + if ( unlikely(p2m->domain->is_dying) ) + return -ENOMEM; + + return __p2m_set_entry(p2m, sgfn, nr, smfn, t, a); } =20 mfn_t p2m_get_entry(struct p2m_domain *p2m, gfn_t gfn, p2m_type_t *t, --=20 2.34.1 From nobody Tue May 5 08:59:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776695157; cv=none; d=zohomail.com; s=zohoarc; b=PTYsB2J0uc9RFdyB+hPgiv6snlhI2M2UqG8DKMd3k9MmZvA32cgUo+fCDMoSDjpaYfmID6N8zksS8sBMFnSG+mqfdsqumKkVI1HoaiTB5N2NoJfEvurGMUwx+yrHzaQhIyT+avQRwnog33V+Ez7cluTgvtkWe7UPrQLsBnF0GgQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776695157; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=IJkP5OsqCpDOeABbQKKlHOeA24tGEgfkWFRl4zkb6qY=; b=awqnCgGdOaOcgVvByvXeqec2nSUFQ8HwBpSiYC2CsMW0hXDiAnpMaACA8Ry4hA6+69vP3eqq6zSb34NUoDlDA8174fpWQgaREgETWmXkKLt0I0FpdeQSnrsjxd6ecU/MafbVF7okCfxg3WMagk8uYJrVjZZHfX/RnRroIsJwxlQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1776695157034831.1519071374723; Mon, 20 Apr 2026 07:25:57 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1286087.1567212 (Exim 4.92) (envelope-from ) id 1wEpZD-0004fK-6Q; Mon, 20 Apr 2026 14:25:39 +0000 Received: by outflank-mailman (output) from mailman id 1286087.1567212; Mon, 20 Apr 2026 14:25:39 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZD-0004fB-3n; Mon, 20 Apr 2026 14:25:39 +0000 Received: by outflank-mailman (input) for mailman id 1286087; Mon, 20 Apr 2026 14:25:37 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZB-0004QW-9t for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 14:25:37 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wEpZA-00DjKj-Mp for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 16:25:36 +0200 Received: from [10.42.69.3] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e6375d-bab6-0a2a0a5309dd-0a2a45039354-10 for ; Mon, 20 Apr 2026 16:25:36 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-33051d.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e6375f-672d-0a2a45030019-d98c6eac8c36-1 for ; Mon, 20 Apr 2026 16:25:36 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E2A321516; Mon, 20 Apr 2026 07:25:29 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 373183F7B4; Mon, 20 Apr 2026 07:25:34 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776695135; bh=iv//vNmwKiPVjQpsnbCcSAu2c4KT7uRXnN6HNwH7kRM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C60P+blvO8zZ4OFaL3RS+PmAMBSRQ+8U/4URgbc7Ivw8aJfCG320v+cCN1h5wellN WH7EO3gbwuZ+/QAQRjQHbjkbxWgtfOdVToEJ5q+WlVQ09epfIhQTsnDiIT/hA9rTqi lS7LsTqjA7xVIZfOOQtxPtfidMEcipMIaXbeHYUE= From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen , Hari Limaye Subject: [PATCH 2/8] xen/arm: Implement p2m_get_entry for MPU systems Date: Mon, 20 Apr 2026 15:25:18 +0100 Message-Id: <20260420142524.1804073-3-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260420142524.1804073-1-luca.fancellu@arm.com> References: <20260420142524.1804073-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-33051d/1776695136-485AB938-8FD3651C/0/0 X-purgate-type: clean X-purgate-size: 3903 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776695157626158500 Content-Type: text/plain; charset="utf-8" From: Penny Zheng Implement the function p2m_get_entry for MPU systems, which is responsible for looking up an entry in the p2m table. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye --- xen/arch/arm/include/asm/mpu/p2m.h | 5 ++ xen/arch/arm/mpu/p2m.c | 76 ++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/xen/arch/arm/include/asm/mpu/p2m.h b/xen/arch/arm/include/asm/= mpu/p2m.h index b9c7be2d9dcc..d0ec8a77a15a 100644 --- a/xen/arch/arm/include/asm/mpu/p2m.h +++ b/xen/arch/arm/include/asm/mpu/p2m.h @@ -31,6 +31,11 @@ static inline p2m_type_t region_get_p2m(pr_t *pr) return pr->p2m_type; } =20 +static inline bool region_is_p2m_valid(pr_t *pr) +{ + return (pr->p2m_type !=3D p2m_invalid); +} + #endif /* __ARM_MPU_P2M_H__ */ =20 /* diff --git a/xen/arch/arm/mpu/p2m.c b/xen/arch/arm/mpu/p2m.c index 4a8595b1b25e..681717eacf37 100644 --- a/xen/arch/arm/mpu/p2m.c +++ b/xen/arch/arm/mpu/p2m.c @@ -135,11 +135,79 @@ int p2m_set_entry(struct p2m_domain *p2m, gfn_t sgfn,= unsigned long nr, return __p2m_set_entry(p2m, sgfn, nr, smfn, t, a); } =20 -mfn_t p2m_get_entry(struct p2m_domain *p2m, gfn_t gfn, p2m_type_t *t, - p2m_access_t *a, unsigned int *page_order, bool *valid) +/* + * Get the details of guest MPU memory region [gfn, gfn + nr_gfns). + * + * If the region is mapped, `t` is set to the p2m_type of the region and t= he + * starting MFN is returned. + * If the region is not mapped, INVALID_MFN is returned. + */ +static mfn_t p2m_get_mpu_region(struct p2m_domain *p2m, gfn_t gfn, + unsigned long nr_gfns, p2m_type_t *type, + bool *valid) { - BUG_ON("unimplemented"); - return INVALID_MFN; + pr_t *table =3D NULL; + pr_t *region =3D NULL; + uint8_t idx =3D INVALID_REGION_IDX; + gfn_t egfn =3D gfn_add(gfn, nr_gfns); + p2m_type_t optional_type =3D p2m_invalid; + bool optional_valid =3D false; + mfn_t ret =3D INVALID_MFN; + + ASSERT(p2m_is_locked(p2m)); + + /* + * Check if the ending gfn is higher than the highest the p2m map + * currently holds, or the starting gfn lower than the lowest it holds. + */ + if ( (gfn_x(egfn) > gfn_x(p2m->max_mapped_gfn)) || + (gfn_x(gfn) < gfn_x(p2m->lowest_mapped_gfn)) ) + goto out; + + table =3D (pr_t *)page_to_virt(p2m->root); + /* The table should always be non-NULL and is always present. */ + if ( !table ) + ASSERT_UNREACHABLE(); + + if ( is_gfns_mapped(table, p2m->nr_regions, gfn, nr_gfns, &idx) ) + goto out; + + region =3D &table[idx]; + if ( region_is_p2m_valid(region) ) + { + optional_type =3D region_get_p2m(region); + optional_valid =3D region_is_valid(region); + } + + /* Always GFN =3D=3D MFN on MPU systems. */ + ret =3D _mfn(gfn_x(gfn)); + +out: + if ( type ) + *type =3D optional_type; + + if ( valid ) + *valid =3D optional_valid; + + return ret; +} + +/* + * Get the details of a given gfn. + * + * If the entry is present, the associated MFN will be returned and the + * p2m type gets filled up. + * If the entry is not present, INVALID_MFN will be returned + * + * The page_order is meaningless in MPU system, and we keep it here + * to be compatible with MMU system. + */ +mfn_t p2m_get_entry(struct p2m_domain *p2m, gfn_t gfn, + p2m_type_t *t, p2m_access_t *a, + unsigned int *page_order, + bool *valid) +{ + return p2m_get_mpu_region(p2m, gfn, 1, t, valid); } =20 void p2m_dump_info(struct domain *d) --=20 2.34.1 From nobody Tue May 5 08:59:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776695157; cv=none; d=zohomail.com; s=zohoarc; b=n3sgEoBc8YkjwrTUidQaKp0SCLeyS2ruxnZthMjPTfY7deOGh9ilMHAlGZhcHHooQEsqQ1B/kLqBqr43P+isEr79FzJJt/4l0GMCrqR5TWwnRS173SJDzuDNtsM7v281ZSwtRMj2Mx6zZA6KZjoX7Z/w5GH4qTU042RWbMQeRUE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776695157; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vm8RGc78m0Lwq1DMkp1+U4Xe4cb1/zMreDiHtARtiRg=; b=jtYU15IcnIA1/UwvQV5bzcRYLyh43NBOjV5c7PymaAJtBQyYRrLOLl43aZNUCdFel1171K5sPZQ45NVj7+66HJ4f6+SI36gRcbZU4e3E/8/+gSULw2tW5wRI3BQ8gQP4xALdSVXzUTS5id4t76VFrhME/U+bQ80khAyQKGCaAl8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1776695157542184.96523542977945; Mon, 20 Apr 2026 07:25:57 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1286088.1567218 (Exim 4.92) (envelope-from ) id 1wEpZD-0004kf-IJ; Mon, 20 Apr 2026 14:25:39 +0000 Received: by outflank-mailman (output) from mailman id 1286088.1567218; Mon, 20 Apr 2026 14:25:39 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZD-0004jM-ES; Mon, 20 Apr 2026 14:25:39 +0000 Received: by outflank-mailman (input) for mailman id 1286088; Mon, 20 Apr 2026 14:25:38 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZC-0004bZ-Td for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 14:25:38 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wEpZC-00BFc6-9u for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 16:25:38 +0200 Received: from [10.42.69.8] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e63760-2eae-0a2a0a5409dd-0a2a450882fc-8 for ; Mon, 20 Apr 2026 16:25:37 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-c1860d.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e63761-63b5-0a2a45080019-d98c6eac96be-1 for ; Mon, 20 Apr 2026 16:25:37 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5300916F2; Mon, 20 Apr 2026 07:25:31 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B9A5C3F7B4; Mon, 20 Apr 2026 07:25:35 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776695136; bh=zydSLBd6tN5qexvU/dn56PdspdQkRiPjvNZz/rLJDIo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S8XRPHeMliAOMeBJjotCrRwclZtbZiPa/8onyrk1Y/8K4Rnnxfk2/nqWtrOyPljAD cAREu9wb91FmJFuKP8XtSqPxOMMvHdzI6CtOGP6jhbEBE3qfyF7GB45Vra1iAz3sG4 jdd8cmIyTM/X1GqKEe6Q95TxRQ3zw1665byMvIoA= From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen Subject: [PATCH 3/8] xen/mpu: enable device passthrough in MPU system Date: Mon, 20 Apr 2026 15:25:19 +0100 Message-Id: <20260420142524.1804073-4-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260420142524.1804073-1-luca.fancellu@arm.com> References: <20260420142524.1804073-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-c1860d/1776695137-C1F6ADB1-76E20B7C/0/0 X-purgate-type: clean X-purgate-size: 1422 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776695159625158500 Content-Type: text/plain; charset="utf-8" From: Penny Zheng In order to enable device passthrough in MPU system, we only need to provide p2m_mmio_direct_dev permission set up. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu --- xen/arch/arm/mpu/p2m.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/mpu/p2m.c b/xen/arch/arm/mpu/p2m.c index 681717eacf37..f2482237412b 100644 --- a/xen/arch/arm/mpu/p2m.c +++ b/xen/arch/arm/mpu/p2m.c @@ -13,6 +13,7 @@ static inline unsigned int build_p2m_flags(p2m_type_t t) { unsigned int flags =3D 0; + unsigned int attr_idx =3D MT_NORMAL; =20 BUILD_BUG_ON(p2m_max_real_type > (1 << 4)); =20 @@ -30,11 +31,15 @@ static inline unsigned int build_p2m_flags(p2m_type_t t) flags |=3D _PAGE_XN | _PAGE_RO; break; =20 + case p2m_mmio_direct_dev: + flags |=3D _PAGE_XN; + attr_idx =3D MT_DEVICE_nGnRE; + break; + case p2m_max_real_type: BUG(); break; =20 - case p2m_mmio_direct_dev: case p2m_mmio_direct_nc: case p2m_mmio_direct_c: case p2m_iommu_map_ro: @@ -47,7 +52,7 @@ static inline unsigned int build_p2m_flags(p2m_type_t t) break; } =20 - flags |=3D MT_NORMAL; + flags |=3D attr_idx; =20 return flags; } --=20 2.34.1 From nobody Tue May 5 08:59:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776695157; cv=none; d=zohomail.com; s=zohoarc; b=cPcnbZUHOC7KKdp46a7MAlzIBQp+UkYYrKnm/3gdUXBpi/NzUokfOncMxPFsqRAh88v+AYeHMNlRG+0bH+yA7E3PfDTSvor5sjjnCM5dBxufDhvgiIWdL/6pqT6yr6tFW2NQXLWKR/8zQZNnDFkIz49GkVCKVVPOPupme1sDzns= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776695157; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=tO9XQNWajO8wfjDdxhaO6pXXrLRcB9rBlj0a7rAi0Bs=; b=OJoB4niW3b1g4lZsOKJLWHvx9MuJmQO6OiBUi/twJJgfHto1ILK+ml6328K2p9HuhpZCR6RQL7E4P+R//TRop0eXF7fHammOEqJE+QxVMViX/CNxi+6myTU5xTpP1hHaKiqaFuOo0TJHjjEki6Xcr6wktwynliaUBX0u9f6VyCI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 17766951571061017.3473425095171; Mon, 20 Apr 2026 07:25:57 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1286089.1567231 (Exim 4.92) (envelope-from ) id 1wEpZF-0005Aa-Tb; Mon, 20 Apr 2026 14:25:41 +0000 Received: by outflank-mailman (output) from mailman id 1286089.1567231; Mon, 20 Apr 2026 14:25:41 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZF-0005AN-PF; Mon, 20 Apr 2026 14:25:41 +0000 Received: by outflank-mailman (input) for mailman id 1286089; Mon, 20 Apr 2026 14:25:40 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZE-00050r-Ee for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 14:25:40 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wEpZD-00DjKj-RW for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 16:25:39 +0200 Received: from [10.42.69.3] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e6375d-bab6-0a2a0a5309dd-0a2a45039354-22 for ; Mon, 20 Apr 2026 16:25:39 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-33051d.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e63762-672d-0a2a45030019-d98c6eacb926-1 for ; Mon, 20 Apr 2026 16:25:39 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EE7721758; Mon, 20 Apr 2026 07:25:32 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2C8DB3F7B4; Mon, 20 Apr 2026 07:25:37 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776695138; bh=qbZ9gSgQc0geGpYjPZJQGW1qcpmolTJxT0noQsC0zDg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A1kcUv112S14tZVWxdUhhSO4oRu3GAcs+kbCy1eOQNVfFvzWDYuiJ8OsPJHqMoWTY Qo+c22nZFCkqQ1EuoRA2VDf2weuePmyPvw1Z/Cee4sYHMbfqN1i1L+fM+Uk2JVgmjZ 2txr7iS7VplQUEYS5PD2NC86sqk6OIbs41R6HeOQ= From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen , Hari Limaye , Harry Ramsey Subject: [PATCH 4/8] arm/mpu: Support vCPU context switch on MPU systems Date: Mon, 20 Apr 2026 15:25:20 +0100 Message-Id: <20260420142524.1804073-5-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260420142524.1804073-1-luca.fancellu@arm.com> References: <20260420142524.1804073-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-33051d/1776695139-29D7B938-47532FEC/0/0 X-purgate-type: clean X-purgate-size: 4660 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776695157652158500 Content-Type: text/plain; charset="utf-8" From: Penny Zheng Implement the functions p2m_save_state and p2m_restore_state for MPU systems. Unlike on MMU systems, where we simply update VTTBR_EL2 with the incoming guest's p2m table on context switch, we have to disable the outgoing guest's p2m memory regions and enable the incoming guest's p2m memory regions. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu Signed-off-by: Hari Limaye Signed-off-by: Harry Ramsey --- xen/arch/arm/include/asm/mpu/cpregs.h | 4 +++ xen/arch/arm/mpu/mm.c | 11 +++++-- xen/arch/arm/mpu/p2m.c | 47 +++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/xen/arch/arm/include/asm/mpu/cpregs.h b/xen/arch/arm/include/a= sm/mpu/cpregs.h index 9f3b32acd79f..5a3d92cf5389 100644 --- a/xen/arch/arm/include/asm/mpu/cpregs.h +++ b/xen/arch/arm/include/asm/mpu/cpregs.h @@ -6,6 +6,9 @@ /* CP15 CR0: MPU Type Register */ #define HMPUIR p15,4,c0,c0,4 =20 +/* CP15 CR2: Virtualization System Control register */ +#define VSCTLR p15,4,c2,c0,1 + /* CP15 CR6: Protection Region Enable Register */ #define HPRENR p15,4,c6,c1,1 =20 @@ -88,6 +91,7 @@ #define PRENR_EL2 HPRENR #define PRLAR_EL2 HPRLAR #define PRSELR_EL2 HPRSELR +#define VSCTLR_EL2 VSCTLR #endif /* CONFIG_ARM_32 */ =20 #endif /* __ARM_MPU_CPREGS_H */ diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 4ee58ded5ad6..5ed77355a5f9 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -421,9 +421,14 @@ static int xen_mpumap_update_entry(paddr_t base, paddr= _t limit, return 0; } =20 -int check_mpu_mapping(paddr_t base, paddr_t limit, unsigned int flags) +static bool check_mpu_mapping(paddr_t base, paddr_t limit, unsigned int fl= ags, + bool p2m) { - if ( flags_has_rwx(flags) ) + /* + * Mappings should not be both Writeable and Executable, unless + * it is for guest P2M mapping. + */ + if ( flags_has_rwx(flags) && !p2m ) { printk("Mappings should not be both Writeable and Executable\n"); return false; @@ -450,7 +455,7 @@ int xen_mpumap_update(paddr_t base, paddr_t limit, unsi= gned int flags, bool p2m) { int rc; =20 - if ( !check_mpu_mapping(base, limit, flags) ) + if ( !check_mpu_mapping(base, limit, flags, p2m) ) return -EINVAL; =20 spin_lock(&xen_mpumap_lock); diff --git a/xen/arch/arm/mpu/p2m.c b/xen/arch/arm/mpu/p2m.c index f2482237412b..bf87c65c106c 100644 --- a/xen/arch/arm/mpu/p2m.c +++ b/xen/arch/arm/mpu/p2m.c @@ -285,14 +285,57 @@ int p2m_init(struct domain *d) return 0; } =20 +static int p2m_xenmpu_update(struct p2m_domain *p2m, bool online) +{ + pr_t *p2m_table; + unsigned int flags =3D online ? _PAGE_PRESENT : 0; + + p2m_table =3D (pr_t *)page_to_virt(p2m->root); + if ( !p2m_table ) + return -EINVAL; + + for ( unsigned int i =3D 0; i < p2m->nr_regions; i++ ) + { + paddr_t base =3D pr_get_base(&p2m_table[i]); + paddr_t limit =3D pr_get_limit(&p2m_table[i]) + 1; + unsigned int region_flags; + + region_flags =3D build_p2m_flags(region_get_p2m(&p2m_table[i])) | = flags; + if ( xen_mpumap_update(base, limit, region_flags, true) ) + { + printk(XENLOG_G_ERR "Unable to update MPU memory mapping with = P2M region %#"PRIpaddr"-%#"PRIpaddr"\n", + base, limit); + return -EINVAL; + } + } + + return 0; +} + +/* p2m_save_state and p2m_restore_state work in pair. */ void p2m_save_state(struct vcpu *p) { - BUG_ON("unimplemented"); + struct p2m_domain *p2m =3D p2m_get_hostp2m(p->domain); + + p->arch.sctlr =3D READ_SYSREG(SCTLR_EL1); + + if ( p2m_xenmpu_update(p2m, false) ) + panic("Failed to offline P2M MPU memory mapping\n"); } =20 void p2m_restore_state(struct vcpu *n) { - BUG_ON("unimplemented"); + struct p2m_domain *p2m =3D p2m_get_hostp2m(n->domain); + uint8_t *last_vcpu_ran =3D &p2m->last_vcpu_ran[smp_processor_id()]; + + WRITE_SYSREG(n->arch.sctlr, SCTLR_EL1); + WRITE_SYSREG(n->arch.hcr_el2, HCR_EL2); + + WRITE_SYSREG(p2m->vsctlr, VSCTLR_EL2); + if ( p2m_xenmpu_update(p2m, true) ) + panic("Failed to online P2M MPU memory mapping\n"); + + *last_vcpu_ran =3D n->vcpu_id; } =20 void p2m_final_teardown(struct domain *d) --=20 2.34.1 From nobody Tue May 5 08:59:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776695166; cv=none; d=zohomail.com; s=zohoarc; b=WSbkNv3fpZMfknrXmfu4RPvE37IB1tfsQvlq0xqgLt4q5YUgE7FBql+cDooX9Jpna4+pUloP7OC+FOrOnkSRFpQqtxj9csbDp/e/bPO7REmsLvk8JWDyJDfjHy/oOXgXLmakzyD8tGSrGK7kstypROmIhm/Ay4j1oa5x0Sogck0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776695166; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=MlecKU7j672IGTeDougCycfftnAjgjyQoQStUPOS8ts=; b=hQOkSThMP70mjnQIltdBEqvC+Ro/KZnaqVsYnJSAY3UuWh+pUaCWAHWoQaCW2n1NlfqEGKLwgbJZY6fM2X5cQeDRHjreYugA6QBKMcIDPqlIWhB8VaK5ngnJi/vgYrLoTQfvarOzpquL2iACshA5c4Z2C0/mvEdNppAzid7Zy1o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1776695166620635.1367881358444; Mon, 20 Apr 2026 07:26:06 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1286091.1567240 (Exim 4.92) (envelope-from ) id 1wEpZH-0005Q6-6O; Mon, 20 Apr 2026 14:25:43 +0000 Received: by outflank-mailman (output) from mailman id 1286091.1567240; Mon, 20 Apr 2026 14:25:43 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZH-0005Px-27; Mon, 20 Apr 2026 14:25:43 +0000 Received: by outflank-mailman (input) for mailman id 1286091; Mon, 20 Apr 2026 14:25:41 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZF-0005A0-PH for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 14:25:41 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wEpZF-00BFc6-3z for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 16:25:41 +0200 Received: from [10.42.69.6] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e63753-2eae-0a2a0a5409dd-0a2a4506d4a6-46 for ; Mon, 20 Apr 2026 16:25:41 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-16d1c6.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e63764-7371-0a2a45060019-d98c6eacd072-1 for ; Mon, 20 Apr 2026 16:25:40 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5E45E16F2; Mon, 20 Apr 2026 07:25:34 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id C672D3F7B4; Mon, 20 Apr 2026 07:25:38 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776695139; bh=7NVH7QgOJjbAjD26LtB1wsu/7pirLzYhzd1KxWkCV3U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uvOv0+BNiAmystHk22rMykjakgdlygV7SrTPltD8ab7waAmmUa31WhoZzlpJdGt7F I8PWWqtYNrHctgT7lPpZHHx7UG+2XfDVBJIeUy70KVcrhA/I/BTbpGJ8gIj67YRj4a b3CJU/1qMHWc1ZUjO2n+mciwDDplK3Y1c3rX3Rwo= From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen Subject: [PATCH 5/8] xen/arm: enable MMIO region trap in MPU system Date: Mon, 20 Apr 2026 15:25:21 +0100 Message-Id: <20260420142524.1804073-6-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260420142524.1804073-1-luca.fancellu@arm.com> References: <20260420142524.1804073-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-16d1c6/1776695141-91985D75-F6D49A57/0/0 X-purgate-type: clean X-purgate-size: 5352 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776695167729158500 Content-Type: text/plain; charset="utf-8" From: Penny Zheng MMIO region traps, generating from insufficient access permissions, will lead to data abort with Permission Fault in MPU system. It is different with MMU system, which generates Translation Fault instead. We extract common codes for dealing with MMIO trap into a new helper do_mmio_trap_stage2_abort_guest(). Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu --- xen/arch/arm/traps.c | 83 ++++++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 0c01f37ad6b4..081bd2e51979 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1815,6 +1815,47 @@ static inline bool check_p2m(bool is_data, paddr_t g= pa) return false; } =20 +static int do_mmio_trap_stage2_abort_guest(struct cpu_user_regs *regs, + const union hsr hsr, + mmio_info_t *info, + vaddr_t gva, paddr_t gpa) +{ + enum io_state state; + + state =3D try_handle_mmio(regs, info); + + switch ( state ) + { + case IO_ABORT: + gdprintk(XENLOG_DEBUG, + "HSR=3D%#"PRIregister" pc=3D%#"PRIregister" gva=3D%#"P= RIvaddr" gpa=3D%#"PRIpaddr"\n", + hsr.bits, regs->pc, gva, gpa); + inject_dabt_exception(regs, gva); + break; + case IO_HANDLED: + /* + * If the instruction was decoded and has executed successfully + * on the MMIO region, then Xen should execute the next part of + * the instruction. (for eg increment the rn if it is a + * post-indexing instruction. + */ + finalize_instr_emulation(&info->dabt_instr); + advance_pc(regs, hsr); + break; + case IO_RETRY: + /* finish later */ + break; + case IO_UNHANDLED: + /* IO unhandled, try another way to handle it. */ + return -EFAULT; + default: + ASSERT_UNREACHABLE(); + return -EFAULT; + } + + return 0; +} + static void do_trap_stage2_abort_guest(struct cpu_user_regs *regs, const union hsr hsr) { @@ -1829,7 +1870,6 @@ static void do_trap_stage2_abort_guest(struct cpu_use= r_regs *regs, uint8_t fsc =3D xabt.fsc & ~FSC_LL_MASK; bool is_data =3D (hsr.ec =3D=3D HSR_EC_DATA_ABORT_LOWER_EL); mmio_info_t info; - enum io_state state; =20 /* * If this bit has been set, it means that this stage-2 abort is caused @@ -1863,6 +1903,8 @@ static void do_trap_stage2_abort_guest(struct cpu_use= r_regs *regs, return; /* Try again */ } =20 + info.gpa =3D gpa; + info.dabt =3D hsr.dabt; switch ( fsc ) { case FSC_FLT_PERM: @@ -1876,6 +1918,17 @@ static void do_trap_stage2_abort_guest(struct cpu_us= er_regs *regs, }; =20 p2m_mem_access_check(gpa, gva, npfec); + +#if !defined(CONFIG_MMU) + /* + * MMIO region traps, generating from insufficient access permissi= ons, + * will lead to data abort with Permission fault. + */ + if ( is_data && (do_mmio_trap_stage2_abort_guest(regs, hsr, &info,= gva, + gpa) =3D=3D 0) ) + return; +#endif + /* * The only way to get here right now is because of mem_access, * thus reinjecting the exception to the guest is never required. @@ -1884,9 +1937,6 @@ static void do_trap_stage2_abort_guest(struct cpu_use= r_regs *regs, } case FSC_FLT_TRANS: { - info.gpa =3D gpa; - info.dabt =3D hsr.dabt; - /* * Assumption :- Most of the times when we get a data abort and th= e ISS * is invalid or an instruction abort, the underlying cause is tha= t the @@ -1923,29 +1973,8 @@ static void do_trap_stage2_abort_guest(struct cpu_us= er_regs *regs, if ( (info.dabt_instr.state =3D=3D INSTR_VALID) && check_p2m(is_da= ta, gpa) ) return; =20 - state =3D try_handle_mmio(regs, &info); - - switch ( state ) - { - case IO_ABORT: - goto inject_abt; - case IO_HANDLED: - /* - * If the instruction was decoded and has executed success= fully - * on the MMIO region, then Xen should execute the next pa= rt of - * the instruction. (for eg increment the rn if it is a - * post-indexing instruction. - */ - finalize_instr_emulation(&info.dabt_instr); - advance_pc(regs, hsr); - return; - case IO_RETRY: - /* finish later */ - return; - case IO_UNHANDLED: - /* IO unhandled, try another way to handle it. */ - break; - } + if ( do_mmio_trap_stage2_abort_guest(regs, hsr, &info, gva, gpa) = =3D=3D 0 ) + return; =20 break; } --=20 2.34.1 From nobody Tue May 5 08:59:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776695160; cv=none; d=zohomail.com; s=zohoarc; b=XkvV3cQc6DuJvBTPGfOzc+OnznVcs6zuWsF6aHf6skHt/OWnbCVxadLIHT1aH8/ZRcrodeJvUsNsePWxXyIESwrycokgYlmk3D2rZm6qIMngBmnitvecjBvFaOmrdHHv3VhLCDcuSymlCib2BaxBolYuM4eGtcveoA0TtQTlwFo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776695160; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Le8tGI1symSaCwtwwqowKDSGLELpNhLjhxT4qN2rtY8=; b=mL4p0M5NcxOt2Stq1nlOrZu9+TgIWyUI1UjLgqjOsC0esAsrCRYX4p64cD4eQ+DhGmoYDpKlstnC9k0koC/S3m34s+xMq3dsRZ9P6S0jgNJ75+J/A4KPysfJAf31cwjgc6X8v7buYkAXi/5d1EAw5xSZ6h9TDBz+Kkcg6ihi6ZY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1776695160567741.245499899836; Mon, 20 Apr 2026 07:26:00 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1286092.1567249 (Exim 4.92) (envelope-from ) id 1wEpZJ-0005ic-Hu; Mon, 20 Apr 2026 14:25:45 +0000 Received: by outflank-mailman (output) from mailman id 1286092.1567249; Mon, 20 Apr 2026 14:25:45 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZJ-0005iF-AZ; Mon, 20 Apr 2026 14:25:45 +0000 Received: by outflank-mailman (input) for mailman id 1286092; Mon, 20 Apr 2026 14:25:43 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZH-0005QG-Bq for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 14:25:43 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wEpZG-007oXE-P0 for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 16:25:42 +0200 Received: from [10.42.69.12] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e63758-5cb7-0a2a0a5109dd-0a2a450cba0e-44 for ; Mon, 20 Apr 2026 16:25:42 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-d25034.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e63765-62f1-0a2a450c0019-d98c6eacb948-1 for ; Mon, 20 Apr 2026 16:25:42 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C8F921516; Mon, 20 Apr 2026 07:25:35 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 38E6D3F7B4; Mon, 20 Apr 2026 07:25:40 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776695141; bh=Al7AOCud4lNxulX4r/nJBRzdtBBDHwwUvlyzIFQQIKY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X9UfO1TxDU5WDQ4XOfEZVuqUA7Cxo97hg/3n6y2wcT9I8yPJMNwz+5dgCMK66TUJZ rkc2y93ONuRunueaVzcWPnz0v1koP+p3ws8Dlg86Oe79Nld4MwWdwHx0SLcvf1121n yBzfkKc94C+c3O/uRbURDIbCVDXr65wqAelBMRSo= From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen Subject: [PATCH 6/8] xen/arm: dump debug message in MPU system Date: Mon, 20 Apr 2026 15:25:22 +0100 Message-Id: <20260420142524.1804073-7-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260420142524.1804073-1-luca.fancellu@arm.com> References: <20260420142524.1804073-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-d25034/1776695142-F4C07CF5-F184B584/0/0 X-purgate-type: clean X-purgate-size: 4208 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776695163266154100 Content-Type: text/plain; charset="utf-8" From: Penny Zheng A set of helpers dump_xxx and show_registers are responsible for dumping memory mapping info and register info when debugging. In this commit, we implement them all in MPU system too. Signed-off-by: Penny Zheng Signed-off-by: Wei Chen Signed-off-by: Luca Fancellu --- xen/arch/arm/mpu/mm.c | 12 +++++++++++- xen/arch/arm/mpu/p2m.c | 40 +++++++++++++++++++++++++++++++++++++++- xen/arch/arm/traps.c | 8 ++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 5ed77355a5f9..459fb952d125 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -554,7 +554,17 @@ int modify_xen_mappings(unsigned long s, unsigned long= e, unsigned int nf) =20 void dump_hyp_walk(vaddr_t addr) { - BUG_ON("unimplemented"); + uint8_t i =3D 0; + pr_t region; + + for ( i =3D 0; i < max_mpu_regions; i++ ) + { + read_protection_region(®ion, i); + if ( region_is_valid(®ion) ) + printk(XENLOG_INFO + "Walking hypervisor MPU memory region [%u]: 0x%"PRIpadd= r"-0x%"PRIpaddr"\n", + i, pr_get_base(®ion), pr_get_limit(®ion)); + } } =20 /* Release all __init and __initdata ranges to be reused */ diff --git a/xen/arch/arm/mpu/p2m.c b/xen/arch/arm/mpu/p2m.c index bf87c65c106c..06c92a3ef41b 100644 --- a/xen/arch/arm/mpu/p2m.c +++ b/xen/arch/arm/mpu/p2m.c @@ -215,9 +215,47 @@ mfn_t p2m_get_entry(struct p2m_domain *p2m, gfn_t gfn, return p2m_get_mpu_region(p2m, gfn, 1, t, valid); } =20 +static void dump_mpu_walk(pr_t *table, uint8_t nr_regions) +{ + uint8_t i =3D 0; + + for ( ; i < nr_regions; i++ ) + { + paddr_t base, limit; + + if ( region_is_valid(&table[i]) ) + { + base =3D pr_get_base(&table[i]); + limit =3D pr_get_limit(&table[i]); + + printk(XENLOG_INFO + "Walking MPU memory mapping table: Region[%u]: 0x%"PRIp= addr"-0x%"PRIpaddr"\n", + i, base, limit); + } + } +} + +void dump_p2m_lookup(struct domain *d, paddr_t addr) +{ + struct p2m_domain *p2m =3D p2m_get_hostp2m(d); + + printk("dom%d IPA 0x%"PRIpaddr"\n", d->domain_id, addr); + + printk("P2M @ %p mfn:%#"PRI_mfn"\n", + p2m->root, mfn_x(page_to_mfn(p2m->root))); + + dump_mpu_walk((pr_t *)page_to_virt(p2m->root), p2m->nr_regions); +} + void p2m_dump_info(struct domain *d) { - BUG_ON("unimplemented"); + struct p2m_domain *p2m =3D p2m_get_hostp2m(d); + + p2m_read_lock(p2m); + printk("p2m mappings for domain %d (vmid %d):\n", + d->domain_id, p2m->vmid); + printk(" Number of P2M Memory Region: %u \n", p2m->nr_regions); + p2m_read_unlock(p2m); } =20 static int p2m_alloc_table(struct domain *d) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 081bd2e51979..fba7d6c00e37 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -718,6 +718,8 @@ struct reg_ctxt { #ifdef CONFIG_MMU /* Hypervisor-side state */ uint64_t vttbr_el2; +#else + uint64_t vsctlr_el2; #endif }; =20 @@ -918,6 +920,8 @@ static void _show_registers(const struct cpu_user_regs = *regs, printk(" VTCR_EL2: %"PRIregister"\n", READ_SYSREG(VTCR_EL2)); #ifdef CONFIG_MMU printk(" VTTBR_EL2: %016"PRIx64"\n", ctxt->vttbr_el2); +#else + printk(" VSCTLR_EL2: %016"PRIx64"\n", ctxt->vsctlr_el2); #endif printk("\n"); =20 @@ -959,6 +963,8 @@ void show_registers(const struct cpu_user_regs *regs) #endif #ifdef CONFIG_MMU ctxt.vttbr_el2 =3D READ_SYSREG64(VTTBR_EL2); +#else + ctxt.vsctlr_el2 =3D READ_SYSREG(VSCTLR_EL2); #endif =20 _show_registers(regs, &ctxt, guest_mode(regs), current); @@ -985,6 +991,8 @@ void vcpu_show_registers(struct vcpu *v) =20 #ifdef CONFIG_MMU ctxt.vttbr_el2 =3D v->domain->arch.p2m.vttbr; +#else + ctxt.vsctlr_el2 =3D v->domain->arch.p2m.vsctlr; #endif =20 _show_registers(&v->arch.cpu_info->guest_cpu_user_regs, &ctxt, 1, v); --=20 2.34.1 From nobody Tue May 5 08:59:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776695175; cv=none; d=zohomail.com; s=zohoarc; b=dGC40Qu75wZVcV7K6FYW6JLATN6M0xrgC8+LcINUM6TIL4BHtEUMAKEG9XpnPQ5gS+LvCC9/BaaJjeGKA0epOS/hD1gFgi9LK+mnPYp3Wc4LXNqFKyG+kN7WVbM9+6mQjfMlWs2uoNabpY2zK+81X8waJrMTbh/PNP1sCNhKKwI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776695175; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=WzQkLDM2kpgevwCSwsO1tG0vNnKSQFWR5y+PZnINh5M=; b=YHDfVg4NWFMiujkN2H49n2svJ2UvwRnvm0jrRO+KeIjSuTk8frrcvtQCRYQMDwFGE+2LZ4cVkTcEdboX2rdGxRPqINqo05oOkjddQGSYEYPMeThXjr3lX0pZk4Sn3krPcninEeAUuWIBIhTK+JaifG0aFfxTiWiINu3imAylZT4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1776695175442716.325843656101; Mon, 20 Apr 2026 07:26:15 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1286094.1567254 (Exim 4.92) (envelope-from ) id 1wEpZK-0005lI-9c; Mon, 20 Apr 2026 14:25:46 +0000 Received: by outflank-mailman (output) from mailman id 1286094.1567254; Mon, 20 Apr 2026 14:25:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZJ-0005kb-OQ; Mon, 20 Apr 2026 14:25:45 +0000 Received: by outflank-mailman (input) for mailman id 1286094; Mon, 20 Apr 2026 14:25:44 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZI-0005fl-FR for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 14:25:44 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wEpZH-00BFc6-Ru for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 16:25:43 +0200 Received: from [10.42.69.8] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e63760-2eae-0a2a0a5409dd-0a2a450882fc-36 for ; Mon, 20 Apr 2026 16:25:43 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-c1860d.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e63767-63b5-0a2a45080019-d98c6eacb956-1 for ; Mon, 20 Apr 2026 16:25:43 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 05BCE1758; Mon, 20 Apr 2026 07:25:37 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9F9473F7B4; Mon, 20 Apr 2026 07:25:41 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776695142; bh=POwMy0a+mxqsay/MzYgDqyjsTTEYght2gW9VVJxJBz4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iFLQu4L1MjrxmtfYHsLxLuv0UPDZvOLH4psmVR7VcRh6has4yzl+fjB3TwnUR1kUs Wn8C0hKN1198xG8cQSM59wpSjmtbDzp1I1Zh2I1oxOXVjR4jSMTc+41zZRkclWcLuD VrrXQVwZBJ1vM6AH9BCHpMyjFQEPmDHTLgkuk+Ko= From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH 7/8] arm/mpu: Save/restore guest EL1 MPU-related context Date: Mon, 20 Apr 2026 15:25:23 +0100 Message-Id: <20260420142524.1804073-8-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260420142524.1804073-1-luca.fancellu@arm.com> References: <20260420142524.1804073-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-c1860d/1776695143-3AD73DB1-0CCEDBC0/0/0 X-purgate-type: clean X-purgate-size: 18418 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776695175736158500 Content-Type: text/plain; charset="utf-8" Implement save/restore of guest MPU-related context, as all MPU memory regions must be saved/restored on vCPU context switch when domain is using PMSAv8-64 translation regime. Introduce is_mpu_domain() helper function that is always false on MMU and it checks if PMSA is selected at EL1 for MPU domains. Split the save/restore functions into MPU arm64 and arm32, the latter is currently not implemented, the former is fully implemented and uses the PR{B,L}AR_EL1 register access in order to issue the minimum amount of ISB as possible while changing the selector and writing/reading the registers. struct arch_vcpu now includes a pointer to the allocated storage for the additional MPU regions to be saved on context switch. Signed-off-by: Luca Fancellu --- xen/arch/arm/arm64/mpu/p2m.c | 2 + xen/arch/arm/domain.c | 49 +++++++--- xen/arch/arm/include/asm/domain.h | 5 + xen/arch/arm/include/asm/mm.h | 3 + xen/arch/arm/include/asm/mmu/mm.h | 12 +++ xen/arch/arm/include/asm/mpu.h | 3 + xen/arch/arm/include/asm/mpu/cpregs.h | 3 + xen/arch/arm/include/asm/mpu/mm.h | 10 ++ xen/arch/arm/mpu/arm32/mm.c | 10 ++ xen/arch/arm/mpu/arm64/mm.c | 136 ++++++++++++++++++++++++++ xen/arch/arm/mpu/mm.c | 39 ++++++++ 11 files changed, 260 insertions(+), 12 deletions(-) diff --git a/xen/arch/arm/arm64/mpu/p2m.c b/xen/arch/arm/arm64/mpu/p2m.c index a39a1fc38946..a1ec9fcd6195 100644 --- a/xen/arch/arm/arm64/mpu/p2m.c +++ b/xen/arch/arm/arm64/mpu/p2m.c @@ -62,6 +62,8 @@ void __init setup_virt_paging(void) =20 p2m_vmid_allocator_init(); =20 + load_nr_mpu_regions_el1(); + /* * VSTCR_EL2.SA defines secure stage 2 translation output address spac= e. * To make sure that all stage 2 translations for the Secure PA space = access diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index dfa7ace1141b..221b1f8a7f9d 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -123,11 +123,23 @@ static void ctxt_switch_from(struct vcpu *p) =20 isb(); =20 - /* MMU */ + /* MMU/MPU */ + if ( is_mpu_domain(p->domain) ) + { + /* + * Domain is using PMSAv8-64 translation regime at EL1, so we need= to + * save EL1 MPU memory regions. + */ + save_el1_mpu_regions(p); + } + else + { + /* Domain is using VMSAv8-64 translation regime via MMU. */ + p->arch.ttbcr =3D READ_SYSREG(TCR_EL1); + p->arch.ttbr0 =3D READ_SYSREG64(TTBR0_EL1); + p->arch.ttbr1 =3D READ_SYSREG64(TTBR1_EL1); + } p->arch.vbar =3D READ_SYSREG(VBAR_EL1); - p->arch.ttbcr =3D READ_SYSREG(TCR_EL1); - p->arch.ttbr0 =3D READ_SYSREG64(TTBR0_EL1); - p->arch.ttbr1 =3D READ_SYSREG64(TTBR1_EL1); if ( is_32bit_domain(p->domain) ) p->arch.dacr =3D READ_SYSREG(DACR32_EL2); p->arch.par =3D read_sysreg_par(); @@ -156,8 +168,6 @@ static void ctxt_switch_from(struct vcpu *p) p->arch.afsr0 =3D READ_SYSREG(AFSR0_EL1); p->arch.afsr1 =3D READ_SYSREG(AFSR1_EL1); =20 - /* XXX MPU */ - /* VGIC */ gic_save_state(p); =20 @@ -181,8 +191,6 @@ static void ctxt_switch_to(struct vcpu *n) /* VGIC */ gic_restore_state(n); =20 - /* XXX MPU */ - /* Fault Status */ #if defined(CONFIG_ARM_32) WRITE_CP32(n->arch.dfar, DFAR); @@ -198,11 +206,23 @@ static void ctxt_switch_to(struct vcpu *n) WRITE_SYSREG(n->arch.afsr0, AFSR0_EL1); WRITE_SYSREG(n->arch.afsr1, AFSR1_EL1); =20 - /* MMU */ + /* MMU/MPU */ + if ( is_mpu_domain(n->domain) ) + { + /* + * Domain is using PMSAv8-64 translation regime at EL1, so we need= to + * restore EL1 MPU memory regions. + */ + restore_el1_mpu_regions(n); + } + else + { + /* Domain is using VMSAv8-64 translation regime via MMU. */ + WRITE_SYSREG(n->arch.ttbcr, TCR_EL1); + WRITE_SYSREG64(n->arch.ttbr0, TTBR0_EL1); + WRITE_SYSREG64(n->arch.ttbr1, TTBR1_EL1); + } WRITE_SYSREG(n->arch.vbar, VBAR_EL1); - WRITE_SYSREG(n->arch.ttbcr, TCR_EL1); - WRITE_SYSREG64(n->arch.ttbr0, TTBR0_EL1); - WRITE_SYSREG64(n->arch.ttbr1, TTBR1_EL1); =20 /* * Erratum #852523 (Cortex-A57) or erratum #853709 (Cortex-A72): @@ -518,6 +538,9 @@ int arch_vcpu_create(struct vcpu *v) if ( get_ssbd_state() =3D=3D ARM_SSBD_RUNTIME ) v->arch.cpu_info->flags |=3D CPUINFO_WORKAROUND_2_FLAG; =20 + if ( is_mpu_domain(v->domain) ) + allocate_el1_mpu_regions(v); + return rc; =20 fail: @@ -532,6 +555,8 @@ void arch_vcpu_destroy(struct vcpu *v) vcpu_timer_destroy(v); vcpu_vgic_free(v); free_xenheap_pages(v->arch.stack, STACK_ORDER); + if ( is_mpu_domain(v->domain) ) + free_el1_mpu_regions(v); } =20 void vcpu_switch_to_aarch64_mode(struct vcpu *v) diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/d= omain.h index 4a3fb825962b..44c304ef8aa9 100644 --- a/xen/arch/arm/include/asm/domain.h +++ b/xen/arch/arm/include/asm/domain.h @@ -202,6 +202,11 @@ struct arch_vcpu register_t actlr; uint32_t cpacr; =20 +#ifdef CONFIG_MPU + /* EL1 MPU memory regions */ + pr_t *mpu_regions; +#endif + uint32_t contextidr; register_t tpidr_el0; register_t tpidr_el1; diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h index 72a692862420..9e35800aba5e 100644 --- a/xen/arch/arm/include/asm/mm.h +++ b/xen/arch/arm/include/asm/mm.h @@ -202,6 +202,9 @@ extern void setup_frametable_mappings(paddr_t ps, paddr= _t pe); void setup_mm_helper(void); /* map a physical range in virtual memory */ void __iomem *ioremap_attr(paddr_t start, size_t len, unsigned int attribu= tes); +/* Allocate space for EL1 MPU region info */ +void allocate_el1_mpu_regions(struct vcpu *v); +void free_el1_mpu_regions(struct vcpu *v); =20 static inline void __iomem *ioremap_nocache(paddr_t start, size_t len) { diff --git a/xen/arch/arm/include/asm/mmu/mm.h b/xen/arch/arm/include/asm/m= mu/mm.h index 7f4d59137d0d..c441af50c3a9 100644 --- a/xen/arch/arm/include/asm/mmu/mm.h +++ b/xen/arch/arm/include/asm/mmu/mm.h @@ -9,6 +9,8 @@ #include #include =20 +struct domain; + /* Non-boot CPUs use this to find the correct pagetables. */ extern uint64_t init_ttbr; =20 @@ -91,6 +93,16 @@ static inline struct page_info *virt_to_page(const void = *v) return frame_table + pdx - frametable_base_pdx; } =20 +/* If this domain should use PMSAv8-64 translation regime (MPU) at EL1. */ +static inline bool is_mpu_domain(struct domain *d) +{ + return false; +} + +/* Stub for MPU EL1 region save/restore */ +static inline void save_el1_mpu_regions(struct vcpu *p) { } +static inline void restore_el1_mpu_regions(struct vcpu *n) { } + /* * Print a walk of a page table or p2m * diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 8a8c01086206..525944987713 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -27,6 +27,9 @@ =20 #ifndef __ASSEMBLER__ =20 +/* Load the number of regions supported by the EL1 MPU from MPUIR_EL1. */ +void load_nr_mpu_regions_el1(void); + /* * Utility function to determine if an Armv8-R processor supports VMSA. */ diff --git a/xen/arch/arm/include/asm/mpu/cpregs.h b/xen/arch/arm/include/a= sm/mpu/cpregs.h index 5a3d92cf5389..f6fb3c93c032 100644 --- a/xen/arch/arm/include/asm/mpu/cpregs.h +++ b/xen/arch/arm/include/asm/mpu/cpregs.h @@ -5,6 +5,7 @@ =20 /* CP15 CR0: MPU Type Register */ #define HMPUIR p15,4,c0,c0,4 +#define MPUIR p15,0,c0,c0,4 =20 /* CP15 CR2: Virtualization System Control register */ #define VSCTLR p15,4,c2,c0,1 @@ -16,6 +17,7 @@ #define HPRSELR p15,4,c6,c2,1 #define HPRBAR p15,4,c6,c3,0 #define HPRLAR p15,4,c6,c3,1 +#define PRSELR p15,0,c6,c2,1 =20 /* CP15 CR6: MPU Protection Region Base/Limit Address Register */ #define HPRBAR0 p15,4,c6,c8,0 @@ -86,6 +88,7 @@ /* Aliases of AArch64 names for use in common code */ #ifdef CONFIG_ARM_32 /* Alphabetically... */ +#define MPUIR_EL1 MPUIR #define MPUIR_EL2 HMPUIR #define PRBAR_EL2 HPRBAR #define PRENR_EL2 HPRENR diff --git a/xen/arch/arm/include/asm/mpu/mm.h b/xen/arch/arm/include/asm/m= pu/mm.h index 24bffdee4fb6..a536ec4431df 100644 --- a/xen/arch/arm/include/asm/mpu/mm.h +++ b/xen/arch/arm/include/asm/mpu/mm.h @@ -20,6 +20,7 @@ extern struct page_info *frame_table; =20 extern uint8_t max_mpu_regions; +extern uint8_t max_mpu_regions_el1; =20 extern DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR); =20 @@ -55,6 +56,15 @@ static inline void context_sync_mpu(void) isb(); } =20 +/* If this domain should use PMSAv8-64 translation regime (MPU) at EL1. */ +bool is_mpu_domain(struct domain *d); + +/* Save EL1 MPU base and limit registers. */ +void save_el1_mpu_regions(struct vcpu *p); + +/* Restore EL1 MPU base and limit registers. */ +void restore_el1_mpu_regions(struct vcpu *n); + /* * The following API requires context_sync_mpu() after being used to modif= y MPU * regions: diff --git a/xen/arch/arm/mpu/arm32/mm.c b/xen/arch/arm/mpu/arm32/mm.c index 5eaeb3400e6c..3dd71228b4ed 100644 --- a/xen/arch/arm/mpu/arm32/mm.c +++ b/xen/arch/arm/mpu/arm32/mm.c @@ -159,6 +159,16 @@ void write_protection_region(const pr_t *pr_write, uin= t8_t sel) } } =20 +void save_el1_mpu_regions(struct vcpu *p) +{ + BUG_ON("unimplemented"); +} + +void restore_el1_mpu_regions(struct vcpu *n) +{ + BUG_ON("unimplemented"); +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/mpu/arm64/mm.c b/xen/arch/arm/mpu/arm64/mm.c index b07e729a7d05..ce9947851173 100644 --- a/xen/arch/arm/mpu/arm64/mm.c +++ b/xen/arch/arm/mpu/arm64/mm.c @@ -1,8 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ =20 #include +#include #include #include +#include #include #include =20 @@ -10,9 +12,13 @@ * The following are needed for the cases: GENERATE_WRITE_PR_REG_CASE * and GENERATE_READ_PR_REG_CASE with num=3D=3D0 */ +#define PRBAR0_EL1 PRBAR_EL1 +#define PRLAR0_EL1 PRLAR_EL1 #define PRBAR0_EL2 PRBAR_EL2 #define PRLAR0_EL2 PRLAR_EL2 =20 +#define PRBAR_EL1_(n) PRBAR##n##_EL1 +#define PRLAR_EL1_(n) PRLAR##n##_EL1 #define PRBAR_EL2_(n) PRBAR##n##_EL2 #define PRLAR_EL2_(n) PRLAR##n##_EL2 =20 @@ -32,6 +38,22 @@ break; \ } =20 +#define GENERATE_SAVE_EL1_PR_REG_CASE(num, pr, sel) \ + case num: \ + { \ + pr->prbar.bits =3D READ_SYSREG(PRBAR_EL1_(num)); \ + pr->prlar.bits =3D READ_SYSREG(PRLAR_EL1_(num)); \ + sel--; \ + } + +#define GENERATE_RESTORE_EL1_PR_REG_CASE(num, pr, sel) = \ + case num: = \ + { = \ + WRITE_SYSREG(pr->prbar.bits & ~MPU_REGION_RES0, PRBAR_EL1_(num)); = \ + WRITE_SYSREG(pr->prlar.bits & ~MPU_REGION_RES0, PRLAR_EL1_(num)); = \ + sel--; = \ + } + bool has_v8r_vmsa_support(void) { return system_cpuinfo.mm64.msa_frac =3D=3D MM64_MSA_FRAC_VMSA_SUPPORT; @@ -125,6 +147,120 @@ void write_protection_region(const pr_t *pr_write, ui= nt8_t sel) } } =20 +void save_el1_mpu_regions(struct vcpu *p) +{ + int sel =3D max_mpu_regions_el1 - 1; + pr_t *table; + + if ( max_mpu_regions_el1 =3D=3D 0 ) + return; + + if ( p->arch.mpu_regions =3D=3D NULL ) + return; + table =3D p->arch.mpu_regions; + + while ( sel >=3D 0 ) + { + WRITE_SYSREG( (sel & 0xF0), PRSELR_EL1); + isb(); + switch ( sel & 0xF ) { + GENERATE_SAVE_EL1_PR_REG_CASE(15, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(14, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(13, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(12, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(11, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(10, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(9, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(8, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(7, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(6, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(5, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(4, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(3, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(2, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(1, (&table[sel]), sel); + fallthrough; + GENERATE_SAVE_EL1_PR_REG_CASE(0, (&table[sel]), sel); + break; + default: + BUG(); /* Can't happen */ + break; + } + } +} + +void restore_el1_mpu_regions(struct vcpu *n) +{ + int sel =3D max_mpu_regions_el1 - 1; + pr_t *table; + + if ( max_mpu_regions_el1 =3D=3D 0 ) + return; + + if ( !n->arch.mpu_regions ) + return; + table =3D n->arch.mpu_regions; + + while ( sel >=3D 0 ) + { + WRITE_SYSREG( (sel & 0xF0), PRSELR_EL1); + isb(); + switch ( sel & 0xF ) { + GENERATE_RESTORE_EL1_PR_REG_CASE(15, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(14, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(13, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(12, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(11, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(10, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(9, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(8, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(7, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(6, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(5, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(4, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(3, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(2, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(1, (&table[sel]), sel); + fallthrough; + GENERATE_RESTORE_EL1_PR_REG_CASE(0, (&table[sel]), sel); + break; + default: + BUG(); /* Can't happen */ + break; + } + } + + context_sync_mpu(); +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c index 459fb952d125..d6703bf0c005 100644 --- a/xen/arch/arm/mpu/mm.c +++ b/xen/arch/arm/mpu/mm.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include =20 #define MPU_ATTR_XN_RO_MISMATCH -1 #define MPU_ATTR_AI_MISMATCH -2 @@ -23,6 +25,9 @@ struct page_info *frame_table; /* Maximum number of supported MPU memory regions by the EL2 MPU. */ uint8_t __ro_after_init max_mpu_regions; =20 +/* Maximum number of supported MPU memory regions by the EL1 MPU. */ +uint8_t __read_mostly max_mpu_regions_el1; + /* * Bitmap xen_mpumap_mask is to record the usage of EL2 MPU memory regions. * Bit 0 represents MPU memory region 0, bit 1 represents MPU memory @@ -631,6 +636,40 @@ void __iomem *ioremap_attr(paddr_t start, size_t len, = unsigned int flags) return maddr_to_virt(start); } =20 +bool is_mpu_domain(struct domain *d) +{ + return (d->arch.v8r_el1_msa =3D=3D XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_N= ONE) || + (d->arch.v8r_el1_msa =3D=3D XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_P= MSA); +} + +void load_nr_mpu_regions_el1(void) +{ + max_mpu_regions_el1 =3D (uint8_t)(READ_SYSREG(MPUIR_EL1) & + NUM_MPU_REGIONS_MASK); +} + +void allocate_el1_mpu_regions(struct vcpu *v) +{ + if ( max_mpu_regions_el1 =3D=3D 0 ) + return; + + if ( v->arch.mpu_regions ) + return; + + v->arch.mpu_regions =3D (pr_t *)_xzalloc(sizeof(pr_t) * max_mpu_region= s_el1, + SMP_CACHE_BYTES); + if ( !v->arch.mpu_regions ) + panic("DOM%pd: mpu: no memory to store EL1 MPU memory region info\= n", + v->domain); + memset(v->arch.mpu_regions, 0, sizeof(pr_t) * max_mpu_regions_el1); +} + +void free_el1_mpu_regions(struct vcpu *v) +{ + if ( v->arch.mpu_regions ) + xfree(v->arch.mpu_regions); +} + /* * Local variables: * mode: C --=20 2.34.1 From nobody Tue May 5 08:59:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776695165; cv=none; d=zohomail.com; s=zohoarc; b=PI57UHENQl19aJ3rI4TGNn2Fiue8/N8m+nJFFDWYM/MxdGl0sDsVXMvOKGoAB7iZlad/u0Qj7ShZ/wCDNfgPH1vcMkRhmg8OJKvbktzy2WA252uWxm+/pvD6ycRsVq8I74+9boZSFf8ewPmcS049vxBO2gcvdzSg/EtE3kThllw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776695165; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=IUIbVYjxPNpMAi+HaRYNzvHnukTbi32xYMuiIayhWho=; b=oC9HLQQwuYe36xb/ChH8u6zHybYpAWIUMEGYW5rlSqCO8kCVvNsIWoglFPjTb13sAW5zx5KDe32mFPFt2XBbrVHRkKucuYOkKeIaEN8Qx+rtsN4Tf/L8NwOSKBbJUwY8srz94u90SfUNxFnOi7WHdZAIjseIcxXZrckSPd6kcj8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1776695165464125.23989556435049; Mon, 20 Apr 2026 07:26:05 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1286099.1567266 (Exim 4.92) (envelope-from ) id 1wEpZL-0006Dj-P8; Mon, 20 Apr 2026 14:25:47 +0000 Received: by outflank-mailman (output) from mailman id 1286099.1567266; Mon, 20 Apr 2026 14:25:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZL-0006CB-Gj; Mon, 20 Apr 2026 14:25:47 +0000 Received: by outflank-mailman (input) for mailman id 1286099; Mon, 20 Apr 2026 14:25:45 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wEpZJ-0005ik-Ko for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 14:25:45 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wEpZJ-00BFc6-0S for xen-devel@lists.xenproject.org; Mon, 20 Apr 2026 16:25:45 +0200 Received: from [10.42.69.11] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e63765-2eae-0a2a0a5409dd-0a2a450bd768-6 for ; Mon, 20 Apr 2026 16:25:44 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-42698a.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e63768-212f-0a2a450b0019-d98c6eac8d8e-1 for ; Mon, 20 Apr 2026 16:25:44 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 201F516F2; Mon, 20 Apr 2026 07:25:38 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.arm.com [10.1.199.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D29A03F7B4; Mon, 20 Apr 2026 07:25:42 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776695143; bh=DZDq1tuHld+v7+buygc/it5ATvErstw+AN1u/SO6z5U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cql5dYQz5MqXn40DAJLyQby//2LqjdikrSawBIJejgCAbGxmXoVzAGseR2UGeHvbm gOtdH0DPaOpL14OXm1RP8KkKqSOHumxoIkkiYgzykkflW4Uzrj5x+AWc/OP7I1HTLB IVlR7QhPN849+MJ1RVjZ+lbPaK7UdkKLaE78rBgo= From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH 8/8] arm/mpu: Save/restore VTCR_EL2 on vCPU context switch Date: Mon, 20 Apr 2026 15:25:24 +0100 Message-Id: <20260420142524.1804073-9-luca.fancellu@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260420142524.1804073-1-luca.fancellu@arm.com> References: <20260420142524.1804073-1-luca.fancellu@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-42698a/1776695144-05969F3B-B9F5DBF5/0/0 X-purgate-type: clean X-purgate-size: 6845 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776695167408154100 Content-Type: text/plain; charset="utf-8" On AArch64 MPU systems, the VTCR register contains the MSA bit that determi= nes if the guest is using MPU or MMU at EL1, which is required to be saved/restored on vCPU context switch. On AArch64 MPU systems the VTCR_EL2 register configuration will be saved during setup_virt_paging and will be placed in a new member of 'struct arch_vcpu' named vtcr_el2, to be retrieved by context switch. AArch32 MPU systems and MMU systems don't need to save/restore this register because they don't have any MSA bit and related functionality, so for these architecture a stub is provided. Signed-off-by: Luca Fancellu --- xen/arch/arm/arm64/mpu/p2m.c | 15 +++++++++++++++ xen/arch/arm/domain.c | 2 ++ xen/arch/arm/include/asm/domain.h | 5 +++++ xen/arch/arm/include/asm/mmu/domain-build.h | 2 ++ xen/arch/arm/include/asm/mpu/domain-build.h | 6 ++++++ xen/arch/arm/include/asm/mpu/p2m.h | 10 ++++++++++ xen/arch/arm/mpu/domain-build.c | 17 +++++++++++++++++ xen/arch/arm/mpu/p2m.c | 4 ++++ 8 files changed, 61 insertions(+) diff --git a/xen/arch/arm/arm64/mpu/p2m.c b/xen/arch/arm/arm64/mpu/p2m.c index a1ec9fcd6195..350cbd7ae94c 100644 --- a/xen/arch/arm/arm64/mpu/p2m.c +++ b/xen/arch/arm/arm64/mpu/p2m.c @@ -3,8 +3,12 @@ #include #include #include +#include #include =20 +/* VTCR_EL2 value to be configured for the boot CPU. */ +register_t __read_mostly vtcr; + void __init setup_virt_paging(void) { register_t vtcr_el2 =3D READ_SYSREG(VTCR_EL2); @@ -58,6 +62,7 @@ void __init setup_virt_paging(void) else vtcr_el2 &=3D ~VTCR_VS; =20 + vtcr =3D vtcr_el2; WRITE_SYSREG(vtcr_el2, VTCR_EL2); =20 p2m_vmid_allocator_init(); @@ -89,6 +94,16 @@ void __init setup_virt_paging(void) panic("Hardware with no PMSAv8-64 support in any translation regime\n"= ); } =20 +void p2m_save_vtcr(struct vcpu *p) +{ + p->arch.vtcr_el2 =3D READ_SYSREG(VTCR_EL2); +} + +void p2m_restore_vtcr(struct vcpu *n) +{ + WRITE_SYSREG(n->arch.vtcr_el2, VTCR_EL2); +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 221b1f8a7f9d..e928301d7cb0 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -538,6 +538,8 @@ int arch_vcpu_create(struct vcpu *v) if ( get_ssbd_state() =3D=3D ARM_SSBD_RUNTIME ) v->arch.cpu_info->flags |=3D CPUINFO_WORKAROUND_2_FLAG; =20 + arch_set_vtcr_msa(v); + if ( is_mpu_domain(v->domain) ) allocate_el1_mpu_regions(v); =20 diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/d= omain.h index 44c304ef8aa9..3ab004518427 100644 --- a/xen/arch/arm/include/asm/domain.h +++ b/xen/arch/arm/include/asm/domain.h @@ -203,6 +203,11 @@ struct arch_vcpu uint32_t cpacr; =20 #ifdef CONFIG_MPU +#ifdef CONFIG_ARM_64 + /* Virtualization Translation Control Register */ + uint64_t vtcr_el2; +#endif + /* EL1 MPU memory regions */ pr_t *mpu_regions; #endif diff --git a/xen/arch/arm/include/asm/mmu/domain-build.h b/xen/arch/arm/inc= lude/asm/mmu/domain-build.h index 3e0d9a6a2a08..0919c0097da9 100644 --- a/xen/arch/arm/include/asm/mmu/domain-build.h +++ b/xen/arch/arm/include/asm/mmu/domain-build.h @@ -34,6 +34,8 @@ int arch_set_v8r_el1_msa(struct domain *d, return 0; } =20 +static inline void arch_set_vtcr_msa(struct vcpu *v) {} + #endif /* __ARM_MMU_DOMAIN_BUILD_H__ */ =20 /* diff --git a/xen/arch/arm/include/asm/mpu/domain-build.h b/xen/arch/arm/inc= lude/asm/mpu/domain-build.h index 463cd85b5b7e..8d3a743219ce 100644 --- a/xen/arch/arm/include/asm/mpu/domain-build.h +++ b/xen/arch/arm/include/asm/mpu/domain-build.h @@ -15,6 +15,12 @@ int arch_set_v8r_el1_msa(struct domain *d, const struct xen_domctl_createdomain *config, unsigned int flags); =20 +#ifdef CONFIG_ARM_64 +void arch_set_vtcr_msa(struct vcpu *v); +#else +static inline void arch_set_vtcr_msa(struct vcpu *v) {} +#endif + #endif /* __ARM_MPU_DOMAIN_BUILD_H__ */ =20 /* diff --git a/xen/arch/arm/include/asm/mpu/p2m.h b/xen/arch/arm/include/asm/= mpu/p2m.h index d0ec8a77a15a..1628148ba578 100644 --- a/xen/arch/arm/include/asm/mpu/p2m.h +++ b/xen/arch/arm/include/asm/mpu/p2m.h @@ -9,6 +9,8 @@ =20 struct p2m_domain; =20 +extern register_t vtcr; + /* * The architecture allows at most 255 EL2 MPU memory regions. The size of= the * MPU structure entry (pr_t) is 32 Bytes on AArch64 (requiring two 4KB pa= ges) @@ -36,6 +38,14 @@ static inline bool region_is_p2m_valid(pr_t *pr) return (pr->p2m_type !=3D p2m_invalid); } =20 +#ifdef CONFIG_ARM_64 +void p2m_save_vtcr(struct vcpu *p); +void p2m_restore_vtcr(struct vcpu *n); +#else +static inline void p2m_save_vtcr(struct vcpu *p) {} +static inline void p2m_restore_vtcr(struct vcpu *n) {} +#endif + #endif /* __ARM_MPU_P2M_H__ */ =20 /* diff --git a/xen/arch/arm/mpu/domain-build.c b/xen/arch/arm/mpu/domain-buil= d.c index 1bdd0ffedebb..19e504f7149e 100644 --- a/xen/arch/arm/mpu/domain-build.c +++ b/xen/arch/arm/mpu/domain-build.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include =20 @@ -66,6 +67,22 @@ int arch_set_v8r_el1_msa(struct domain *d, return 0; } =20 +#ifdef CONFIG_ARM_64 +void arch_set_vtcr_msa(struct vcpu *v) +{ + /* + * When ID_AA64MMFR0_EL1.MSA_frac is 0b0010 (MM64_MSA_FRAC_VMSA_SUPPOR= T), + * then VTCR_EL2.MSA determines the memory system architecture enabled + * at stage 1 of the Secure EL1&0 translation regime. + */ + v->arch.vtcr_el2 =3D vtcr; + if ( is_mpu_domain(v->domain) ) + v->arch.vtcr_el2 &=3D ~VTCR_MSA; + else + v->arch.vtcr_el2 |=3D VTCR_MSA; +} +#endif + /* * Local variables: * mode: C diff --git a/xen/arch/arm/mpu/p2m.c b/xen/arch/arm/mpu/p2m.c index 06c92a3ef41b..b41abd8f2d37 100644 --- a/xen/arch/arm/mpu/p2m.c +++ b/xen/arch/arm/mpu/p2m.c @@ -357,6 +357,8 @@ void p2m_save_state(struct vcpu *p) =20 p->arch.sctlr =3D READ_SYSREG(SCTLR_EL1); =20 + p2m_save_vtcr(p); + if ( p2m_xenmpu_update(p2m, false) ) panic("Failed to offline P2M MPU memory mapping\n"); } @@ -369,6 +371,8 @@ void p2m_restore_state(struct vcpu *n) WRITE_SYSREG(n->arch.sctlr, SCTLR_EL1); WRITE_SYSREG(n->arch.hcr_el2, HCR_EL2); =20 + p2m_restore_vtcr(n); + WRITE_SYSREG(p2m->vsctlr, VSCTLR_EL2); if ( p2m_xenmpu_update(p2m, true) ) panic("Failed to online P2M MPU memory mapping\n"); --=20 2.34.1