git: dcfe2e687e71 - stable/15 - arm64/vmm: Save more PMU registers

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Thu, 09 Oct 2025 16:32:21 UTC
The branch stable/15 has been updated by andrew:

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

commit dcfe2e687e712d7915cd227bc1f9584502c430fa
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-10-02 15:34:35 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-10-09 16:31:49 +0000

    arm64/vmm: Save more PMU registers
    
    These were missed in the initial vmm.ko change.
    
    While here keep the order the same in all locations we handle these.
    
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D52802
    
    (cherry picked from commit 35d0c9efb17a9a7fea57c3a4a056141b21dad18f)
---
 sys/arm64/vmm/arm64.h     | 5 +++--
 sys/arm64/vmm/vmm_hyp.c   | 8 +++++++-
 sys/arm64/vmm/vmm_reset.c | 4 +++-
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h
index 6a0c4c78e568..f6b14e10c51b 100644
--- a/sys/arm64/vmm/arm64.h
+++ b/sys/arm64/vmm/arm64.h
@@ -78,11 +78,12 @@ struct hypctx {
 	uint64_t	pmcr_el0;	/* Performance Monitors Control Register */
 	uint64_t	pmccntr_el0;
 	uint64_t	pmccfiltr_el0;
+	uint64_t	pmuserenr_el0;
+	uint64_t	pmselr_el0;
+	uint64_t	pmxevcntr_el0;
 	uint64_t	pmcntenset_el0;
 	uint64_t	pmintenset_el1;
 	uint64_t	pmovsset_el0;
-	uint64_t	pmselr_el0;
-	uint64_t	pmuserenr_el0;
 	uint64_t	pmevcntr_el0[31];
 	uint64_t	pmevtyper_el0[31];
 
diff --git a/sys/arm64/vmm/vmm_hyp.c b/sys/arm64/vmm/vmm_hyp.c
index 3b3ed20f0e41..34402d7a4f05 100644
--- a/sys/arm64/vmm/vmm_hyp.c
+++ b/sys/arm64/vmm/vmm_hyp.c
@@ -167,10 +167,13 @@ vmm_hyp_reg_store(struct hypctx *hypctx, struct hyp *hyp, bool guest)
 	hypctx->pmcr_el0 = READ_SPECIALREG(pmcr_el0);
 	hypctx->pmccntr_el0 = READ_SPECIALREG(pmccntr_el0);
 	hypctx->pmccfiltr_el0 = READ_SPECIALREG(pmccfiltr_el0);
+	hypctx->pmuserenr_el0 = READ_SPECIALREG(pmuserenr_el0);
+	hypctx->pmselr_el0 = READ_SPECIALREG(pmselr_el0);
+	hypctx->pmxevcntr_el0 = READ_SPECIALREG(pmxevcntr_el0);
 	hypctx->pmcntenset_el0 = READ_SPECIALREG(pmcntenset_el0);
 	hypctx->pmintenset_el1 = READ_SPECIALREG(pmintenset_el1);
 	hypctx->pmovsset_el0 = READ_SPECIALREG(pmovsset_el0);
-	hypctx->pmuserenr_el0 = READ_SPECIALREG(pmuserenr_el0);
+
 	switch ((hypctx->pmcr_el0 & PMCR_N_MASK) >> PMCR_N_SHIFT) {
 #define	STORE_PMU(x)							\
 	case (x + 1):							\
@@ -333,6 +336,9 @@ vmm_hyp_reg_restore(struct hypctx *hypctx, struct hyp *hyp, bool guest)
 	WRITE_SPECIALREG(pmcr_el0, hypctx->pmcr_el0);
 	WRITE_SPECIALREG(pmccntr_el0, hypctx->pmccntr_el0);
 	WRITE_SPECIALREG(pmccfiltr_el0, hypctx->pmccfiltr_el0);
+	WRITE_SPECIALREG(pmuserenr_el0, hypctx->pmuserenr_el0);
+	WRITE_SPECIALREG(pmselr_el0, hypctx->pmselr_el0);
+	WRITE_SPECIALREG(pmxevcntr_el0, hypctx->pmxevcntr_el0);
 	/* Clear all events/interrupts then enable them */
 	WRITE_SPECIALREG(pmcntenclr_el0, ~0ul);
 	WRITE_SPECIALREG(pmcntenset_el0, hypctx->pmcntenset_el0);
diff --git a/sys/arm64/vmm/vmm_reset.c b/sys/arm64/vmm/vmm_reset.c
index 79d022cf33e8..c4102277131d 100644
--- a/sys/arm64/vmm/vmm_reset.c
+++ b/sys/arm64/vmm/vmm_reset.c
@@ -100,10 +100,12 @@ reset_vm_el01_regs(void *vcpu)
 	el2ctx->pmcr_el0 |= PMCR_LC;
 	set_arch_unknown(el2ctx->pmccntr_el0);
 	set_arch_unknown(el2ctx->pmccfiltr_el0);
+	set_arch_unknown(el2ctx->pmuserenr_el0);
+	set_arch_unknown(el2ctx->pmselr_el0);
+	set_arch_unknown(el2ctx->pmxevcntr_el0);
 	set_arch_unknown(el2ctx->pmcntenset_el0);
 	set_arch_unknown(el2ctx->pmintenset_el1);
 	set_arch_unknown(el2ctx->pmovsset_el0);
-	set_arch_unknown(el2ctx->pmuserenr_el0);
 	memset(el2ctx->pmevcntr_el0, 0, sizeof(el2ctx->pmevcntr_el0));
 	memset(el2ctx->pmevtyper_el0, 0, sizeof(el2ctx->pmevtyper_el0));
 }