Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Apr 2026 17:43:07 +0000
From:      Jessica Clarke <jrtc27@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 04f744ce91ef - stable/15 - arm64/vmm: Enable 16-bit VMIDs when in use by pmap
Message-ID:  <69f394ab.31318.667bd2ec@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch stable/15 has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=04f744ce91efbb37f89b8e6d04f24af111e8bd8f

commit 04f744ce91efbb37f89b8e6d04f24af111e8bd8f
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2026-04-23 15:40:33 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2026-04-30 17:42:29 +0000

    arm64/vmm: Enable 16-bit VMIDs when in use by pmap
    
    pmap_init always uses 16-bit VMIDs when supported, but we never enable
    them in VTCR_EL2 (for ASIDs, locore enables them in TCR_EL1 and
    pmap_init keys off whether they've been enabled, but the order in which
    pmap_init and vmmops_modinit run is reversed). As a result, although the
    full 16-bit value can be stored to VTTBR_EL2 and read back, the upper 8
    bits are treated as 0, and so VMIDs that our VMID allocation believes
    are distinct end up aliasing.
    
    In future this interface may change such that vmm decides on the VMID
    width and tells the pmap to use that, with appropriate support for
    unloading and reloading vmm, but that can come as a follow-up change, as
    this is a more minimal bug fix.
    
    Reviewed by:    markj
    Obtained from:  CheriBSD
    Fixes:          47e073941f4e ("Import the kernel parts of bhyve/arm64")
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D55860
    
    (cherry picked from commit 44e4f45aec4469440af434098e61bd13982bbbc0)
---
 sys/arm64/arm64/pmap.c         | 11 +++++++++++
 sys/arm64/include/hypervisor.h |  2 ++
 sys/arm64/include/pmap.h       |  1 +
 sys/arm64/vmm/vmm_arm64.c      |  2 ++
 4 files changed, 16 insertions(+)

diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index 678030f827dd..aa0b0e829f7a 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -797,6 +797,17 @@ pmap_ps_enabled(pmap_t pmap)
 	return (superpages_enabled != 0);
 }
 
+bool
+pmap_vs_enabled(void)
+{
+	/*
+	 * 8 and 16 are the only values hardware can support, but allow for the
+	 * possibility of artificially restricting the bits, e.g. for testing.
+	 */
+	KASSERT(vmids.asid_bits <= 16, ("VMID bits %d > 16", vmids.asid_bits));
+	return (vmids.asid_bits > 8);
+}
+
 bool
 pmap_get_tables(pmap_t pmap, vm_offset_t va, pd_entry_t **l0, pd_entry_t **l1,
     pd_entry_t **l2, pt_entry_t **l3)
diff --git a/sys/arm64/include/hypervisor.h b/sys/arm64/include/hypervisor.h
index 3ee5c12f2265..879cd229a2bd 100644
--- a/sys/arm64/include/hypervisor.h
+++ b/sys/arm64/include/hypervisor.h
@@ -2142,6 +2142,8 @@
 #define	 VTCR_EL2_PS_44BIT	(0x4UL << VTCR_EL2_PS_SHIFT)
 #define	 VTCR_EL2_PS_48BIT	(0x5UL << VTCR_EL2_PS_SHIFT)
 #define	 VTCR_EL2_PS_52BIT	(0x6UL << VTCR_EL2_PS_SHIFT)
+#define	VTCR_EL2_VS_SHIFT	19
+#define	 VTCR_EL2_VS		(1UL << VTCR_EL2_VS_SHIFT)
 #define	VTCR_EL2_DS_SHIFT	32
 #define	VTCR_EL2_DS		(0x1UL << VTCR_EL2_DS_SHIFT)
 
diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h
index 406b6e2c5e0a..f5812893fcfa 100644
--- a/sys/arm64/include/pmap.h
+++ b/sys/arm64/include/pmap.h
@@ -156,6 +156,7 @@ void	*pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, vm_memattr_t ma);
 bool	pmap_page_is_mapped(vm_page_t m);
 int	pmap_pinit_stage(pmap_t, enum pmap_stage, int);
 bool	pmap_ps_enabled(pmap_t pmap);
+bool	pmap_vs_enabled(void);
 uint64_t pmap_to_ttbr0(pmap_t pmap);
 void	pmap_disable_promotion(vm_offset_t sva, vm_size_t size);
 void	pmap_map_delete(pmap_t, vm_offset_t, vm_offset_t);
diff --git a/sys/arm64/vmm/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c
index 712783338214..8fe0bf62bf8b 100644
--- a/sys/arm64/vmm/vmm_arm64.c
+++ b/sys/arm64/vmm/vmm_arm64.c
@@ -391,6 +391,8 @@ vmmops_modinit(int ipinum)
 #ifdef SMP
 	el2_regs.vtcr_el2 |= VTCR_EL2_SH0_IS;
 #endif
+	if (pmap_vs_enabled())
+		el2_regs.vtcr_el2 |= VTCR_EL2_VS;
 	/*
 	 * If FEAT_LPA2 is enabled in the host then we need to enable it here
 	 * so the page tables created by pmap.c are correct. The meaning of


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f394ab.31318.667bd2ec>