From nobody Mon Feb 9 01:35:24 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770368551893997.7899988443411; Fri, 6 Feb 2026 01:02:31 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1222984.1530648 (Exim 4.92) (envelope-from ) id 1voHj9-00075R-SY; Fri, 06 Feb 2026 09:02:11 +0000 Received: by outflank-mailman (output) from mailman id 1222984.1530648; Fri, 06 Feb 2026 09:02:11 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1voHj9-00075E-Pf; Fri, 06 Feb 2026 09:02:11 +0000 Received: by outflank-mailman (input) for mailman id 1222984; Fri, 06 Feb 2026 09:02:10 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1voHj8-0006qi-LM for xen-devel@lists.xenproject.org; Fri, 06 Feb 2026 09:02:10 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 84bf41e6-033a-11f1-b161-2bf370ae4941; Fri, 06 Feb 2026 10:02:09 +0100 (CET) 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 B81BF1516; Fri, 6 Feb 2026 01:02:02 -0800 (PST) Received: from e134099.cambridge.arm.com (e134099.arm.com [10.1.198.34]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A5B333F778; Fri, 6 Feb 2026 01:02:07 -0800 (PST) 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" X-Inumbo-ID: 84bf41e6-033a-11f1-b161-2bf370ae4941 From: Harry Ramsey To: xen-devel@lists.xenproject.org Cc: Luca.Fancellu@arm.com, Penny Zheng , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Penny Zheng , Wei Chen , Luca Fancellu , Hari Limaye Subject: [PATCH 1/3] arm/mpu: implement setup_virt_paging for MPU system Date: Fri, 6 Feb 2026 09:01:53 +0000 Message-ID: <20260206090155.68466-2-harry.ramsey@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260206090155.68466-1-harry.ramsey@arm.com> References: <20260206090155.68466-1-harry.ramsey@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770368552388158500 Content-Type: text/plain; charset="utf-8" From: Penny Zheng For MMU system, setup_virt_paging is used to configure stage 2 address translation regime, like IPA bits, VMID allocator set up, etc. Some could be inherited in MPU system, like VMID allocator set up, etc. For MPU system, we could have the following memory translation regime: - PMSAv8-64 at both EL1/EL0 and EL2 (default) - VMSAv8-64 at EL1/EL0 and PMSAv8-64 at EL2 (enabled with device tree proprty v8r_el1_msa) 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/arm64/mpu/p2m.c | 67 +++++++++++++++++++++++- xen/arch/arm/include/asm/arm64/sysregs.h | 4 ++ xen/arch/arm/include/asm/cpufeature.h | 13 +++-- xen/arch/arm/include/asm/mpu/p2m.h | 12 +++++ xen/arch/arm/include/asm/p2m.h | 5 ++ xen/arch/arm/include/asm/processor.h | 11 ++++ 6 files changed, 108 insertions(+), 4 deletions(-) diff --git a/xen/arch/arm/arm64/mpu/p2m.c b/xen/arch/arm/arm64/mpu/p2m.c index b6d8b2777b..da8f0553c1 100644 --- a/xen/arch/arm/arm64/mpu/p2m.c +++ b/xen/arch/arm/arm64/mpu/p2m.c @@ -2,11 +2,76 @@ =20 #include #include +#include #include =20 void __init setup_virt_paging(void) { - BUG_ON("unimplemented"); + uint64_t vtcr_el2 =3D READ_SYSREG(VTCR_EL2), vstcr_el2 =3D READ_SYSREG= (VSTCR_EL2); + + /* PA size */ + const unsigned int pa_range_info[] =3D {32, 36, 40, 42, 44, 48, 52, 0, + /* Invalid */}; + + /* + * Restrict "p2m_ipa_bits" if needed. As P2M table is always configured + * with IPA bits =3D=3D PA bits, compare against "pabits". + */ + if ( pa_range_info[system_cpuinfo.mm64.pa_range] < p2m_ipa_bits ) + p2m_ipa_bits =3D pa_range_info[system_cpuinfo.mm64.pa_range]; + + /* + * Clear VTCR_EL2.NSA bit to configure non-secure stage 2 translation = output + * address space to access the Secure PA space as Armv8r only implemen= ts + * secure state. + */ + vtcr_el2 &=3D ~VTCR_NSA; + + /* + * The MSA and MSA_frac fields in the ID_AA64MMFR0_EL1 register identi= fy the + * memory system configurations supported. In Armv8-R AArch64, the + * only permitted value for ID_AA64MMFR0_EL1.MSA is 0b1111. + */ + if ( system_cpuinfo.mm64.msa !=3D MM64_MSA_PMSA_SUPPORT ) + goto fault; + + /* Permitted values for ID_AA64MMFR0_EL1.MSA_frac are 0b0001 and 0b001= 0. */ + if ( system_cpuinfo.mm64.msa_frac =3D=3D MM64_MSA_FRAC_NONE_SUPPORT ) + goto fault; + + /* + * cpuinfo sanitization makes sure we support 16bits VMID only if all = cores + * are supporting it. + */ + if ( system_cpuinfo.mm64.vmid_bits =3D=3D MM64_VMID_16_BITS_SUPPORT ) + max_vmid =3D MAX_VMID_16_BIT; + + /* Set the VS bit only if 16 bit VMID is supported. */ + if ( max_vmid =3D=3D MAX_VMID_16_BIT ) + vtcr_el2 |=3D VTCR_VS; + + p2m_vmid_allocator_init(); + + WRITE_SYSREG(vtcr_el2, VTCR_EL2); + + /* + * 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 + * the Secure PA space, we keep SA bit as 0. + * + * VSTCR_EL2.SC is NS check enable bit. To make sure that Stage 2 NS + * configuration is checked against stage 1 NS configuration in EL1&0 + * translation regime for the given address, and generates a fault if = they + * are different, we set SC bit 1. + */ + vstcr_el2 &=3D ~VSTCR_EL2_SA; + vstcr_el2 |=3D VSTCR_EL2_SC; + WRITE_SYSREG(vstcr_el2, VSTCR_EL2); + + return; + + fault: + panic("Hardware with no PMSAv8-64 support in any translation regime\n"= ); } =20 /* diff --git a/xen/arch/arm/include/asm/arm64/sysregs.h b/xen/arch/arm/includ= e/asm/arm64/sysregs.h index 19d409d3eb..a4b6eef181 100644 --- a/xen/arch/arm/include/asm/arm64/sysregs.h +++ b/xen/arch/arm/include/asm/arm64/sysregs.h @@ -462,6 +462,10 @@ #define ZCR_ELx_LEN_SIZE 9 #define ZCR_ELx_LEN_MASK 0x1ff =20 +/* Virtualization Secure Translation Control Register */ +#define VSTCR_EL2_SA (_AC(0x1,UL)<<30) +#define VSTCR_EL2_SC (_AC(0x1,UL)<<20) + #ifdef CONFIG_MPU /* * The Armv8-R AArch64 architecture always executes code in Secure diff --git a/xen/arch/arm/include/asm/cpufeature.h b/xen/arch/arm/include/a= sm/cpufeature.h index 13353c8e1a..bf902a3970 100644 --- a/xen/arch/arm/include/asm/cpufeature.h +++ b/xen/arch/arm/include/asm/cpufeature.h @@ -248,6 +248,12 @@ struct cpuinfo_arm { unsigned long tgranule_16K:4; unsigned long tgranule_64K:4; unsigned long tgranule_4K:4; +#ifdef CONFIG_MPU + unsigned long __res0:16; + unsigned long msa:4; + unsigned long msa_frac:4; + unsigned long __res1:8; +#else unsigned long tgranule_16k_2:4; unsigned long tgranule_64k_2:4; unsigned long tgranule_4k_2:4; @@ -255,6 +261,7 @@ struct cpuinfo_arm { unsigned long __res0:8; unsigned long fgt:4; unsigned long ecv:4; +#endif =20 /* MMFR1 */ unsigned long hafdbs:4; @@ -267,13 +274,13 @@ struct cpuinfo_arm { unsigned long xnx:4; unsigned long twed:4; unsigned long ets:4; - unsigned long __res1:4; + unsigned long __res2:4; unsigned long afp:4; - unsigned long __res2:12; + unsigned long __res3:12; unsigned long ecbhb:4; =20 /* MMFR2 */ - unsigned long __res3:64; + unsigned long __res4:64; }; } mm64; =20 diff --git a/xen/arch/arm/include/asm/mpu/p2m.h b/xen/arch/arm/include/asm/= mpu/p2m.h index e46d9e757a..d165585d4e 100644 --- a/xen/arch/arm/include/asm/mpu/p2m.h +++ b/xen/arch/arm/include/asm/mpu/p2m.h @@ -5,6 +5,18 @@ =20 struct p2m_domain; =20 +/* + * 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) + * and 16 bytes on AArch32 (requiring one 4KB page). + */ +#ifdef CONFIG_ARM_64 +#define P2M_ROOT_ORDER 1 +#else +#define P2M_ROOT_ORDER 0 +#endif + +/* Not used on MPU system */ static inline void p2m_clear_root_pages(struct p2m_domain *p2m) {} =20 static inline void p2m_tlb_flush_sync(struct p2m_domain *p2m) {} diff --git a/xen/arch/arm/include/asm/p2m.h b/xen/arch/arm/include/asm/p2m.h index 010ce8c9eb..ed1b6dd40f 100644 --- a/xen/arch/arm/include/asm/p2m.h +++ b/xen/arch/arm/include/asm/p2m.h @@ -48,8 +48,13 @@ struct p2m_domain { /* Current VMID in use */ uint16_t vmid; =20 +#ifdef CONFIG_MMU /* Current Translation Table Base Register for the p2m */ uint64_t vttbr; +#else + /* Current Virtualization System Control Register for the p2m */ + register_t vsctlr; +#endif =20 /* Highest guest frame that's ever been mapped in the p2m */ gfn_t max_mapped_gfn; diff --git a/xen/arch/arm/include/asm/processor.h b/xen/arch/arm/include/as= m/processor.h index 1a48c9ff3b..7344aa094b 100644 --- a/xen/arch/arm/include/asm/processor.h +++ b/xen/arch/arm/include/asm/processor.h @@ -403,6 +403,10 @@ =20 #define VTCR_RES1 (_AC(1,UL)<<31) =20 +#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) +#define VTCR_NSA (_AC(0x1,UL)<<30) +#endif + /* HCPTR Hyp. Coprocessor Trap Register */ #define HCPTR_TAM ((_AC(1,U)<<30)) #define HCPTR_TTA ((_AC(1,U)<<20)) /* Trap trace registers */ @@ -464,6 +468,13 @@ #define MM64_VMID_16_BITS_SUPPORT 0x2 #endif =20 +#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) +#define MM64_MSA_PMSA_SUPPORT 0xf +#define MM64_MSA_FRAC_NONE_SUPPORT 0x0 +#define MM64_MSA_FRAC_PMSA_SUPPORT 0x1 +#define MM64_MSA_FRAC_VMSA_SUPPORT 0x2 +#endif + #ifndef __ASSEMBLER__ =20 extern register_t __cpu_logical_map[]; --=20 2.43.0 From nobody Mon Feb 9 01:35:24 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770368565989708.636122431747; Fri, 6 Feb 2026 01:02:45 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1222988.1530668 (Exim 4.92) (envelope-from ) id 1voHjK-0007i1-Gm; Fri, 06 Feb 2026 09:02:22 +0000 Received: by outflank-mailman (output) from mailman id 1222988.1530668; Fri, 06 Feb 2026 09:02:22 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1voHjK-0007hm-Dh; Fri, 06 Feb 2026 09:02:22 +0000 Received: by outflank-mailman (input) for mailman id 1222988; Fri, 06 Feb 2026 09:02:21 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1voHjJ-0007ev-Dg for xen-devel@lists.xenproject.org; Fri, 06 Feb 2026 09:02:21 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 86559266-033a-11f1-9ccf-f158ae23cfc8; Fri, 06 Feb 2026 10:02:12 +0100 (CET) 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 6E9D8339; Fri, 6 Feb 2026 01:02:05 -0800 (PST) Received: from e134099.cambridge.arm.com (e134099.arm.com [10.1.198.34]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DC6DF3F778; Fri, 6 Feb 2026 01:02:10 -0800 (PST) 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" X-Inumbo-ID: 86559266-033a-11f1-9ccf-f158ae23cfc8 From: Harry Ramsey To: xen-devel@lists.xenproject.org Cc: Luca.Fancellu@arm.com, Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH 2/3] arm/mpu: Introduce `v8r_el1_msa` device tree property for domains Date: Fri, 6 Feb 2026 09:01:54 +0000 Message-ID: <20260206090155.68466-3-harry.ramsey@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260206090155.68466-1-harry.ramsey@arm.com> References: <20260206090155.68466-1-harry.ramsey@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770368566499158500 Content-Type: text/plain; charset="utf-8" Add a new device tree property `v8r_el1_msa` to enable/disable the PMSAv8-64 translation regime at EL1. Signed-off-by: Harry Ramsey --- docs/misc/arm/device-tree/booting.txt | 11 +++++++++++ xen/arch/arm/dom0less-build.c | 25 +++++++++++++++++++++++++ xen/arch/arm/domain.c | 16 ++++++++++++++++ xen/arch/arm/include/asm/domain.h | 9 +++++++++ xen/include/public/arch-arm.h | 4 ++++ 5 files changed, 65 insertions(+) diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-t= ree/booting.txt index 977b428608..431d285b6e 100644 --- a/docs/misc/arm/device-tree/booting.txt +++ b/docs/misc/arm/device-tree/booting.txt @@ -322,6 +322,17 @@ with the following properties: Should be used together with scmi-smc-passthrough Xen command line option. =20 +- v8r_el1_msa + + A string property specifying whether, on Armv8-R aarch64 systems, a do= main + should use PMSAv8-64 (MPU) at EL1 or VMSAv8-64 (MMU) at EL1. + + - "mmu" + Enables VMSAv8-64 at EL1. + + - "mpu" + Enables PMSAv8-64 at EL1. + Under the "xen,domain" compatible node, one or more sub-nodes are present for the DomU kernel and ramdisk. =20 diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c index 4181c10538..41f538fb50 100644 --- a/xen/arch/arm/dom0less-build.c +++ b/xen/arch/arm/dom0less-build.c @@ -315,6 +315,7 @@ int __init arch_parse_dom0less_node(struct dt_device_no= de *node, struct xen_domctl_createdomain *d_cfg =3D &bd->create_cfg; unsigned int flags =3D bd->create_flags; uint32_t val; + const char *v8r_el1_msa; =20 d_cfg->arch.gic_version =3D XEN_DOMCTL_CONFIG_GIC_NATIVE; d_cfg->flags |=3D XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap; @@ -322,6 +323,30 @@ int __init arch_parse_dom0less_node(struct dt_device_n= ode *node, if ( domu_dt_sci_parse(node, d_cfg) ) panic("Error getting SCI configuration\n"); =20 + if (!dt_property_read_string(node, "v8r_el1_msa", &v8r_el1_msa)) + { +#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) + if ( !strcmp(v8r_el1_msa, "mmu") ) + { + if ( system_cpuinfo.mm64.msa_frac !=3D MM64_MSA_FRAC_VMSA_SUPP= ORT ) + panic("Platform does not support VMSA at EL1 (v8r_el1_msa)= \n"); + d_cfg->arch.v8r_el1_msa =3D MPU_EL1_VMSA; + } + else if ( !strcmp(v8r_el1_msa, "mpu") ) + { + d_cfg->arch.v8r_el1_msa =3D MPU_EL1_PMSA; + if ( !(flags & CDF_staticmem) || !(flags & CDF_directmap) ) + panic("PMSA is not valid for domain without static allocat= ion" + " and direct map (v8r_el1_msa)\n"); + } + else + panic("Invalid device tree option for v8r_el1_msa\n"); +#else + panic("'v8r_el1_msa' property requires CONFIG_MPU and CONFIG_ARM_6= 4 to " + "be selected\n"); +#endif + } + if ( !dt_property_read_u32(node, "nr_spis", &d_cfg->arch.nr_spis) ) { int vpl011_virq =3D GUEST_VPL011_SPI; diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 2eca2b913d..fc4c7ae734 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -35,6 +35,18 @@ =20 DEFINE_PER_CPU(struct vcpu *, curr_vcpu); =20 +/* If this domain should use PMSAv8-64 translation regime (MPU) at EL1. */ +static inline bool is_mpu_domain(struct domain *d) +{ +#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) + return d->arch.v8r_el1_msa =3D=3D MPU_EL1_PMSA; +#elif defined(CONFIG_MPU) + return true; +#else + return false; +#endif +} + static void do_idle(void) { unsigned int cpu =3D smp_processor_id(); @@ -731,6 +743,10 @@ int arch_domain_create(struct domain *d, if ( (rc =3D sci_domain_init(d, config)) !=3D 0 ) goto fail; =20 +#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) + d->arch.v8r_el1_msa =3D config->arch.v8r_el1_msa; +#endif + return 0; =20 fail: diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/d= omain.h index 758ad807e4..1387adc0e9 100644 --- a/xen/arch/arm/include/asm/domain.h +++ b/xen/arch/arm/include/asm/domain.h @@ -29,6 +29,11 @@ enum domain_type { #define is_64bit_domain(d) (0) #endif =20 +#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) +#define MPU_EL1_PMSA 0 +#define MPU_EL1_VMSA 1 +#endif + /* * Is the domain using the host memory layout? * @@ -126,6 +131,10 @@ struct arch_domain void *sci_data; #endif =20 +#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) + uint8_t v8r_el1_msa; +#endif + } __cacheline_aligned; =20 struct arch_vcpu diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index cd563cf706..0ef445a273 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -355,6 +355,10 @@ struct xen_arch_domainconfig { uint32_t clock_frequency; /* IN */ uint8_t arm_sci_type; +#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) + /* IN */ + uint8_t v8r_el1_msa; +#endif }; #endif /* __XEN__ || __XEN_TOOLS__ */ =20 --=20 2.43.0 From nobody Mon Feb 9 01:35:24 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770368553676710.846045561886; Fri, 6 Feb 2026 01:02:33 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1222985.1530658 (Exim 4.92) (envelope-from ) id 1voHjF-0007MV-4p; Fri, 06 Feb 2026 09:02:17 +0000 Received: by outflank-mailman (output) from mailman id 1222985.1530658; Fri, 06 Feb 2026 09:02:17 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1voHjF-0007ML-13; Fri, 06 Feb 2026 09:02:17 +0000 Received: by outflank-mailman (input) for mailman id 1222985; Fri, 06 Feb 2026 09:02:15 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1voHjD-0006qi-RA for xen-devel@lists.xenproject.org; Fri, 06 Feb 2026 09:02:15 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 87e09567-033a-11f1-b161-2bf370ae4941; Fri, 06 Feb 2026 10:02:15 +0100 (CET) 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 089881516; Fri, 6 Feb 2026 01:02:08 -0800 (PST) Received: from e134099.cambridge.arm.com (e134099.arm.com [10.1.198.34]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 770163F778; Fri, 6 Feb 2026 01:02:13 -0800 (PST) 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" X-Inumbo-ID: 87e09567-033a-11f1-b161-2bf370ae4941 From: Harry Ramsey To: xen-devel@lists.xenproject.org Cc: Luca.Fancellu@arm.com, Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH 3/3] arm/mpu: Implement p2m tables Date: Fri, 6 Feb 2026 09:01:55 +0000 Message-ID: <20260206090155.68466-4-harry.ramsey@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260206090155.68466-1-harry.ramsey@arm.com> References: <20260206090155.68466-1-harry.ramsey@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770368554636154100 Content-Type: text/plain; charset="utf-8" Implement `p2m_alloc_table`, `p2m_init` and `p2m_final_teardown` for MPU systems. Additionally implement a helper function `generate_vsctlr` for p2m initalization. Signed-off-by: Harry Ramsey --- xen/arch/arm/include/asm/arm32/mpu.h | 2 + xen/arch/arm/include/asm/arm64/mpu.h | 2 + xen/arch/arm/include/asm/mpu.h | 5 ++ xen/arch/arm/mpu/p2m.c | 71 ++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/xen/arch/arm/include/asm/arm32/mpu.h b/xen/arch/arm/include/as= m/arm32/mpu.h index 2cf0f8cbac..d565230f84 100644 --- a/xen/arch/arm/include/asm/arm32/mpu.h +++ b/xen/arch/arm/include/asm/arm32/mpu.h @@ -11,6 +11,8 @@ */ #define MPU_REGION_RES0 0x0 =20 +#define VSCTLR_VMID_SHIFT 16 + /* Hypervisor Protection Region Base Address Register */ typedef union { struct { diff --git a/xen/arch/arm/include/asm/arm64/mpu.h b/xen/arch/arm/include/as= m/arm64/mpu.h index 4f694190a8..8b86a03fee 100644 --- a/xen/arch/arm/include/asm/arm64/mpu.h +++ b/xen/arch/arm/include/asm/arm64/mpu.h @@ -7,6 +7,8 @@ =20 #define MPU_REGION_RES0 (0xFFFFULL << 48) =20 +#define VSCTLR_VMID_SHIFT 48 + /* Protection Region Base Address Register */ typedef union { struct __packed { diff --git a/xen/arch/arm/include/asm/mpu.h b/xen/arch/arm/include/asm/mpu.h index 72fa5b00b8..4ae583a7e9 100644 --- a/xen/arch/arm/include/asm/mpu.h +++ b/xen/arch/arm/include/asm/mpu.h @@ -87,6 +87,11 @@ static inline bool region_is_valid(const pr_t *pr) return pr->prlar.reg.en; } =20 +static inline register_t generate_vsctlr(uint16_t vmid) +{ + return ((register_t)vmid << VSCTLR_VMID_SHIFT); +} + #endif /* __ASSEMBLER__ */ =20 #endif /* __ARM_MPU_H__ */ diff --git a/xen/arch/arm/mpu/p2m.c b/xen/arch/arm/mpu/p2m.c index f7fb58ab6a..1598f9ab64 100644 --- a/xen/arch/arm/mpu/p2m.c +++ b/xen/arch/arm/mpu/p2m.c @@ -28,10 +28,62 @@ void p2m_dump_info(struct domain *d) BUG_ON("unimplemented"); } =20 +static int __init p2m_alloc_table(struct domain *d) +{ + struct p2m_domain *p2m =3D p2m_get_hostp2m(d); + pr_t* p2m_map; + + p2m_map =3D alloc_xenheap_pages(P2M_ROOT_ORDER, 0); + if ( !p2m_map ) + { + printk(XENLOG_G_ERR "DOM%pd: p2m: unable to allocate P2M MPU mappi= ng table\n", d); + return -ENOMEM; + } + clear_page(p2m_map); + + p2m->root =3D virt_to_page((const void *)p2m_map); + + return 0; +} + int p2m_init(struct domain *d) { - BUG_ON("unimplemented"); - return -EINVAL; + struct p2m_domain *p2m =3D p2m_get_hostp2m(d); + int rc =3D 0; + unsigned int cpu; + + rwlock_init(&p2m->lock); + + p2m->vmid =3D INVALID_VMID; + p2m->max_mapped_gfn =3D _gfn(0); + p2m->lowest_mapped_gfn =3D _gfn(ULONG_MAX); + + p2m->default_access =3D p2m_access_rwx; + /* mem_access is NOT supported in MPU system. */ + p2m->mem_access_enabled =3D false; + + /* Ensure that the type chosen is large enough for MAX_VIRT_CPUS. */ + BUILD_BUG_ON((1 << (sizeof(p2m->last_vcpu_ran[0]) * 8)) < MAX_VIRT_CPU= S); + + for_each_possible_cpu(cpu) + p2m->last_vcpu_ran[cpu] =3D INVALID_VCPU_ID; + + /* + * "Trivial" initialization is now complete. Set the backpointer so th= at + * p2m_teardown() and related functions know to do something. + */ + p2m->domain =3D d; + + rc =3D p2m_alloc_vmid(d); + if ( rc ) + return rc; + p2m->vsctlr =3D generate_vsctlr(p2m->vmid); + + rc =3D p2m_alloc_table(d); + if ( rc ) + return rc; + + return rc; } =20 void p2m_save_state(struct vcpu *p) @@ -46,7 +98,20 @@ void p2m_restore_state(struct vcpu *n) =20 void p2m_final_teardown(struct domain *d) { - BUG_ON("unimplemented"); + struct p2m_domain *p2m =3D p2m_get_hostp2m(d); + + /* p2m not actually initialized */ + if ( !p2m->domain ) + return; + + if ( p2m->root ) + free_xenheap_pages(p2m->root, P2M_ROOT_ORDER); + + p2m->root =3D NULL; + + p2m_free_vmid(d); + + p2m->domain =3D NULL; } =20 bool p2m_resolve_translation_fault(struct domain *d, gfn_t gfn) --=20 2.43.0