Date: Mon, 06 Jul 2026 15:24:40 +0000 From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Kajetan Puchalski <kajetan.puchalski@arm.com> Subject: git: d2e3e76ab902 - main - arm64/vmm: Store non-VNCR registers in an array Message-ID: <6a4bc8b8.1cdc2.75cd5be8@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=d2e3e76ab902001c62e8c9a6286d2979b0f2a0de commit d2e3e76ab902001c62e8c9a6286d2979b0f2a0de Author: Kajetan Puchalski <kajetan.puchalski@arm.com> AuthorDate: 2026-07-06 14:17:03 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2026-07-06 15:18:30 +0000 arm64/vmm: Store non-VNCR registers in an array Move non-VNCR EL0 and EL1 registers into a dedicated array inside of hypctx. This enables uniform accesses to both VNCR and non-VNCR guest register state through hypctx_[read|write]_sys_reg(). The accessors are _not_ used for non-VNCR EL2 registers in order to create a clear separation between guest-visible and guest-invisible register state. Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com> Reviewed by: andrew Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D56552 --- sys/arm64/vmm/arm64.h | 99 +++++++++++++++-------- sys/arm64/vmm/vmm_hyp.c | 199 +++++++++++++++++++++++++--------------------- sys/arm64/vmm/vmm_reset.c | 32 +------- 3 files changed, 181 insertions(+), 149 deletions(-) diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h index 4db26709f21e..b90cc9d8d15f 100644 --- a/sys/arm64/vmm/arm64.h +++ b/sys/arm64/vmm/arm64.h @@ -48,7 +48,49 @@ struct vgic_v3_cpu; /* Retrieve the VNCR offset from the enum value */ #define REG_VNCR_OFFSET(val) ((val - VNCR_START) * 8) +/* Accessors for indices of PME and DBG registers */ +#define PMEVCNTR_EL0(n) (PMEVCNTR0_EL0 + MIN(n, 30)) +#define PMEVTYPER_EL0(n) (PMEVTYPER0_EL0 + MIN(n, 30)) +#define DBGBCR_EL1(n) (DBGBCR0_EL1 + MIN(n, 15)) +#define DBGBVR_EL1(n) (DBGBVR0_EL1 + MIN(n, 15)) +#define DBGWCR_EL1(n) (DBGWCR0_EL1 + MIN(n, 15)) +#define DBGWVR_EL1(n) (DBGWVR0_EL1 + MIN(n, 15)) + enum hypctx_sysreg { + CSSELR_EL1, /* Cache Size Selection Register */ + MDCCINT_EL1, /* Monitor DCC Interrupt Enable Register */ + PAR_EL1, /* Physical Address Register */ + + /* PMU Registers */ + PMCR_EL0, /* Performance Monitors Control Register */ + PMCCNTR_EL0, + PMCCFILTR_EL0, + PMUSERENR_EL0, + PMSELR_EL0, + PMXEVCNTR_EL0, + PMCNTENSET_EL0, + PMINTENSET_EL1, + PMOVSSET_EL0, + /* Access these through macros defined above, e.g. PMEVCNTR_EL0(5) */ + PMEVCNTR0_EL0, + PMEVCNTR30_EL0 = PMEVCNTR0_EL0 + 30, + PMEVTYPER0_EL0, + PMEVTYPER30_EL0 = PMEVTYPER0_EL0 + 30, + + /* DBG Registers */ + DBGCLAIMSET_EL1, + /* Access these through macros defined above, e.g. DBGBCR_EL1(5) */ + DBGBCR0_EL1, /* Debug Breakpoint Control Registers */ + DBGBCR15_EL1 = DBGBCR0_EL1 + 15, + DBGBVR0_EL1, /* Debug Breakpoint Value Registers */ + DBGBVR15_EL1 = DBGBVR0_EL1 + 15, + DBGWCR0_EL1, /* Debug Watchpoint Control Registers */ + DBGWCR15_EL1 = DBGWCR0_EL1 + 15, + DBGWVR0_EL1, /* Debug Watchpoint Value Registers */ + DBGWVR15_EL1 = DBGWVR0_EL1 + 15, + + NR_NON_VNCR_REGS, + /* VNCR Registers */ VNCR_START, @@ -140,6 +182,16 @@ enum hypctx_sysreg { VNCR_REG(GCSCR_EL1), VNCR_REG(BRBCR_EL1), VNCR_REG(SPMACCESSR_EL1), + + /* Virtual-address-sized registers */ + VA_REGS_START, + + SP_EL0, /* Stack pointer */ + TPIDR_EL0, /* EL0 Software ID Register */ + TPIDRRO_EL0, /* Read-only Thread ID Register */ + TPIDR_EL1, /* EL1 Software ID Register */ + + VA_REGS_END, }; /* @@ -147,37 +199,12 @@ enum hypctx_sysreg { */ struct hypctx { struct trapframe tf; + /* Virtual-address-sized registers */ + uint64_t va_regs[VA_REGS_END - VA_REGS_START - 1]; + /* Non-VNCR guest register state */ + uint64_t sys_regs[NR_NON_VNCR_REGS]; - /* - * EL1 & EL0 registers. - */ - uint64_t sp_el0; /* Stack pointer */ - uint64_t tpidr_el0; /* EL0 Software ID Register */ - uint64_t tpidrro_el0; /* Read-only Thread ID Register */ - uint64_t tpidr_el1; /* EL1 Software ID Register */ - uint64_t csselr_el1; /* Cache Size Selection Register */ - uint64_t mdccint_el1; /* Monitor DCC Interrupt Enable Register */ - uint64_t par_el1; /* Physical Address Register */ - - 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 pmevcntr_el0[31]; - uint64_t pmevtyper_el0[31]; - - uint64_t dbgclaimset_el1; - uint64_t dbgbcr_el1[16]; /* Debug Breakpoint Control Registers */ - uint64_t dbgbvr_el1[16]; /* Debug Breakpoint Value Registers */ - uint64_t dbgwcr_el1[16]; /* Debug Watchpoint Control Registers */ - uint64_t dbgwvr_el1[16]; /* Debug Watchpoint Value Registers */ - - /* EL2 control registers */ + /* EL2 registers which we use to control the guest but do not expose to it */ uint64_t cptr_el2; /* Architectural Feature Trap Register */ uint64_t hcr_el2; /* Hypervisor Configuration Register */ uint64_t hcrx_el2; /* Extended Hypervisor Configuration Register */ @@ -242,13 +269,21 @@ struct hypctx { ((uint64_t *)((char *)hypctx->vncr_regs + REG_VNCR_OFFSET(reg))) #endif +#ifndef __hypctx_va_sysreg +#define __hypctx_va_sysreg(hypctx, reg) \ + (&hypctx->va_regs[reg - VA_REGS_START - 1]) +#endif + static inline uint64_t * hypctx_sys_reg(struct hypctx *hypctx, int reg /* enum hypctx_sysreg */) { + /* Extract this into a separate helper when we actually support 128-bit regs */ + if (reg > VA_REGS_START) + return (__hypctx_va_sysreg(hypctx, reg)); if (reg > VNCR_START) return (__hypctx_vncr_sysreg(hypctx, reg)); - /* TODO: uniform handling for non-VNCR registers */ - return (NULL); + /* Calling this with reg=VNCR_START or reg=NR_NON_VNCR_REGS is a bad idea */ + return (&hypctx->sys_regs[reg]); } static inline void diff --git a/sys/arm64/vmm/vmm_hyp.c b/sys/arm64/vmm/vmm_hyp.c index bde283a077c8..469ae8b90d9e 100644 --- a/sys/arm64/vmm/vmm_hyp.c +++ b/sys/arm64/vmm/vmm_hyp.c @@ -120,16 +120,17 @@ vmm_hyp_reg_store(struct hypctx *hypctx, struct hyp *hyp, bool guest, } } - hypctx->dbgclaimset_el1 = READ_SPECIALREG(dbgclaimset_el1); + hypctx_write_sys_reg(hypctx, DBGCLAIMSET_EL1, + READ_SPECIALREG(dbgclaimset_el1)); dfr0 = READ_SPECIALREG(id_aa64dfr0_el1); switch (ID_AA64DFR0_BRPs_VAL(dfr0) - 1) { -#define STORE_DBG_BRP(x) \ - case x: \ - hypctx->dbgbcr_el1[x] = \ - READ_SPECIALREG(dbgbcr ## x ## _el1); \ - hypctx->dbgbvr_el1[x] = \ - READ_SPECIALREG(dbgbvr ## x ## _el1) +#define STORE_DBG_BRP(x) \ + case x: \ + hypctx_write_sys_reg(hypctx, DBGBCR_EL1(x), \ + READ_SPECIALREG(dbgbcr ## x ## _el1)); \ + hypctx_write_sys_reg(hypctx, DBGBVR_EL1(x), \ + READ_SPECIALREG(dbgbvr ## x ## _el1)) STORE_DBG_BRP(15); STORE_DBG_BRP(14); STORE_DBG_BRP(13); @@ -151,12 +152,12 @@ vmm_hyp_reg_store(struct hypctx *hypctx, struct hyp *hyp, bool guest, } switch (ID_AA64DFR0_WRPs_VAL(dfr0) - 1) { -#define STORE_DBG_WRP(x) \ - case x: \ - hypctx->dbgwcr_el1[x] = \ - READ_SPECIALREG(dbgwcr ## x ## _el1); \ - hypctx->dbgwvr_el1[x] = \ - READ_SPECIALREG(dbgwvr ## x ## _el1) +#define STORE_DBG_WRP(x) \ + case x: \ + hypctx_write_sys_reg(hypctx, DBGWCR_EL1(x), \ + READ_SPECIALREG(dbgwcr ## x ## _el1)); \ + hypctx_write_sys_reg(hypctx, DBGWVR_EL1(x), \ + READ_SPECIALREG(dbgwvr ## x ## _el1)) STORE_DBG_WRP(15); STORE_DBG_WRP(14); STORE_DBG_WRP(13); @@ -178,23 +179,33 @@ vmm_hyp_reg_store(struct hypctx *hypctx, struct hyp *hyp, bool guest, } /* Store the PMU registers */ - 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); - - switch ((hypctx->pmcr_el0 & PMCR_N_MASK) >> PMCR_N_SHIFT) { + hypctx_write_sys_reg(hypctx, PMCR_EL0, + READ_SPECIALREG(pmcr_el0)); + hypctx_write_sys_reg(hypctx, PMCCNTR_EL0, + READ_SPECIALREG(pmccntr_el0)); + hypctx_write_sys_reg(hypctx, PMCCFILTR_EL0, + READ_SPECIALREG(pmccfiltr_el0)); + hypctx_write_sys_reg(hypctx, PMUSERENR_EL0, + READ_SPECIALREG(pmuserenr_el0)); + hypctx_write_sys_reg(hypctx, PMSELR_EL0, + READ_SPECIALREG(pmselr_el0)); + hypctx_write_sys_reg(hypctx, PMXEVCNTR_EL0, + READ_SPECIALREG(pmxevcntr_el0)); + hypctx_write_sys_reg(hypctx, PMCNTENSET_EL0, + READ_SPECIALREG(pmcntenset_el0)); + hypctx_write_sys_reg(hypctx, PMINTENSET_EL1, + READ_SPECIALREG(pmintenset_el1)); + hypctx_write_sys_reg(hypctx, PMOVSSET_EL0, + READ_SPECIALREG(pmovsset_el0)); + + switch ((hypctx_read_sys_reg(hypctx, PMCR_EL0) & PMCR_N_MASK) >> + PMCR_N_SHIFT) { #define STORE_PMU(x) \ case (x + 1): \ - hypctx->pmevcntr_el0[x] = \ - READ_SPECIALREG(pmevcntr ## x ## _el0); \ - hypctx->pmevtyper_el0[x] = \ - READ_SPECIALREG(pmevtyper ## x ## _el0) + hypctx_write_sys_reg(hypctx, PMEVCNTR_EL0(x), \ + READ_SPECIALREG(pmevcntr ## x ## _el0)); \ + hypctx_write_sys_reg(hypctx, PMEVTYPER_EL0(x), \ + READ_SPECIALREG(pmevtyper ## x ## _el0)) STORE_PMU(30); STORE_PMU(29); STORE_PMU(28); @@ -237,53 +248,53 @@ vmm_hyp_reg_store(struct hypctx *hypctx, struct hyp *hyp, bool guest, hypctx->tf.tf_spsr = READ_SPECIALREG(spsr_el2); if (guest) { hypctx->tf.tf_esr = READ_SPECIALREG(esr_el2); - hypctx->par_el1 = READ_SPECIALREG(par_el1); + hypctx_write_sys_reg(hypctx, PAR_EL1, READ_SPECIALREG(par_el1)); } /* Store the guest special registers */ - hypctx->sp_el0 = READ_SPECIALREG(sp_el0); - hypctx->tpidr_el0 = READ_SPECIALREG(tpidr_el0); - hypctx->tpidrro_el0 = READ_SPECIALREG(tpidrro_el0); - hypctx->tpidr_el1 = READ_SPECIALREG(tpidr_el1); + hypctx_write_sys_reg(hypctx, SP_EL0, READ_SPECIALREG(sp_el0)); + hypctx_write_sys_reg(hypctx, TPIDR_EL0, READ_SPECIALREG(tpidr_el0)); + hypctx_write_sys_reg(hypctx, TPIDRRO_EL0, READ_SPECIALREG(tpidrro_el0)); + hypctx_write_sys_reg(hypctx, TPIDR_EL1, READ_SPECIALREG(tpidr_el1)); hypctx_write_sys_reg(hypctx, ACTLR_EL1, READ_SPECIALREG(actlr_el1)); - hypctx->csselr_el1 = READ_SPECIALREG(csselr_el1); - hypctx->mdccint_el1 = READ_SPECIALREG(mdccint_el1); + hypctx_write_sys_reg(hypctx, CSSELR_EL1, READ_SPECIALREG(csselr_el1)); + hypctx_write_sys_reg(hypctx, MDCCINT_EL1, READ_SPECIALREG(mdccint_el1)); hypctx_write_sys_reg(hypctx, MDSCR_EL1, READ_SPECIALREG(mdscr_el1)); if (guest_or_nonvhe(guest)) { hypctx_write_sys_reg(hypctx, ELR_EL1, - READ_SPECIALREG(EL1_REG(ELR))); + READ_SPECIALREG(EL1_REG(ELR))); hypctx_write_sys_reg(hypctx, VBAR_EL1, - READ_SPECIALREG(EL1_REG(VBAR))); + READ_SPECIALREG(EL1_REG(VBAR))); hypctx_write_sys_reg(hypctx, AFSR0_EL1, - READ_SPECIALREG(EL1_REG(AFSR0))); + READ_SPECIALREG(EL1_REG(AFSR0))); hypctx_write_sys_reg(hypctx, AFSR1_EL1, - READ_SPECIALREG(EL1_REG(AFSR1))); + READ_SPECIALREG(EL1_REG(AFSR1))); hypctx_write_sys_reg(hypctx, AMAIR_EL1, - READ_SPECIALREG(EL1_REG(AMAIR))); + READ_SPECIALREG(EL1_REG(AMAIR))); hypctx_write_sys_reg(hypctx, CONTEXTIDR_EL1, - READ_SPECIALREG(EL1_REG(CONTEXTIDR))); + READ_SPECIALREG(EL1_REG(CONTEXTIDR))); hypctx_write_sys_reg(hypctx, CPACR_EL1, - READ_SPECIALREG(EL1_REG(CPACR))); + READ_SPECIALREG(EL1_REG(CPACR))); hypctx_write_sys_reg(hypctx, ESR_EL1, - READ_SPECIALREG(EL1_REG(ESR))); + READ_SPECIALREG(EL1_REG(ESR))); hypctx_write_sys_reg(hypctx, FAR_EL1, - READ_SPECIALREG(EL1_REG(FAR))); + READ_SPECIALREG(EL1_REG(FAR))); hypctx_write_sys_reg(hypctx, MAIR_EL1, - READ_SPECIALREG(EL1_REG(MAIR))); + READ_SPECIALREG(EL1_REG(MAIR))); hypctx_write_sys_reg(hypctx, SCTLR_EL1, - READ_SPECIALREG(EL1_REG(SCTLR))); + READ_SPECIALREG(EL1_REG(SCTLR))); hypctx_write_sys_reg(hypctx, SPSR_EL1, - READ_SPECIALREG(EL1_REG(SPSR))); + READ_SPECIALREG(EL1_REG(SPSR))); hypctx_write_sys_reg(hypctx, TCR_EL1, - READ_SPECIALREG(EL1_REG(TCR))); + READ_SPECIALREG(EL1_REG(TCR))); /* TODO: Support when this is not res0 */ hypctx_write_sys_reg(hypctx, TCR2_EL1, 0); hypctx_write_sys_reg(hypctx, TTBR0_EL1, - READ_SPECIALREG(EL1_REG(TTBR0))); + READ_SPECIALREG(EL1_REG(TTBR0))); hypctx_write_sys_reg(hypctx, TTBR1_EL1, - READ_SPECIALREG(EL1_REG(TTBR1))); + READ_SPECIALREG(EL1_REG(TTBR1))); } hypctx->cptr_el2 = READ_SPECIALREG(cptr_el2); @@ -329,52 +340,52 @@ vmm_hyp_reg_restore(struct hypctx *hypctx, struct hyp *hyp, bool guest, } #endif - WRITE_SPECIALREG(sp_el0, hypctx->sp_el0); - WRITE_SPECIALREG(tpidr_el0, hypctx->tpidr_el0); - WRITE_SPECIALREG(tpidrro_el0, hypctx->tpidrro_el0); - WRITE_SPECIALREG(tpidr_el1, hypctx->tpidr_el1); + WRITE_SPECIALREG(sp_el0, hypctx_read_sys_reg(hypctx, SP_EL0)); + WRITE_SPECIALREG(tpidr_el0, hypctx_read_sys_reg(hypctx, TPIDR_EL0)); + WRITE_SPECIALREG(tpidrro_el0, hypctx_read_sys_reg(hypctx, TPIDRRO_EL0)); + WRITE_SPECIALREG(tpidr_el1, hypctx_read_sys_reg(hypctx, TPIDR_EL1)); WRITE_SPECIALREG(actlr_el1, hypctx_read_sys_reg(hypctx, ACTLR_EL1)); - WRITE_SPECIALREG(csselr_el1, hypctx->csselr_el1); - WRITE_SPECIALREG(mdccint_el1, hypctx->mdccint_el1); + WRITE_SPECIALREG(csselr_el1, hypctx_read_sys_reg(hypctx, CSSELR_EL1)); + WRITE_SPECIALREG(mdccint_el1, hypctx_read_sys_reg(hypctx, MDCCINT_EL1)); WRITE_SPECIALREG(mdscr_el1, hypctx_read_sys_reg(hypctx, MDSCR_EL1)); if (guest_or_nonvhe(guest)) { WRITE_SPECIALREG(EL1_REG(ELR), - hypctx_read_sys_reg(hypctx, ELR_EL1)); + hypctx_read_sys_reg(hypctx, ELR_EL1)); WRITE_SPECIALREG(EL1_REG(VBAR), - hypctx_read_sys_reg(hypctx, VBAR_EL1)); + hypctx_read_sys_reg(hypctx, VBAR_EL1)); WRITE_SPECIALREG(EL1_REG(AFSR0), - hypctx_read_sys_reg(hypctx, AFSR0_EL1)); + hypctx_read_sys_reg(hypctx, AFSR0_EL1)); WRITE_SPECIALREG(EL1_REG(AFSR1), - hypctx_read_sys_reg(hypctx, AFSR1_EL1)); + hypctx_read_sys_reg(hypctx, AFSR1_EL1)); WRITE_SPECIALREG(EL1_REG(AMAIR), - hypctx_read_sys_reg(hypctx, AMAIR_EL1)); + hypctx_read_sys_reg(hypctx, AMAIR_EL1)); WRITE_SPECIALREG(EL1_REG(CONTEXTIDR), - hypctx_read_sys_reg(hypctx, CONTEXTIDR_EL1)); + hypctx_read_sys_reg(hypctx, CONTEXTIDR_EL1)); WRITE_SPECIALREG(EL1_REG(CPACR), - hypctx_read_sys_reg(hypctx, CPACR_EL1)); + hypctx_read_sys_reg(hypctx, CPACR_EL1)); WRITE_SPECIALREG(EL1_REG(ESR), - hypctx_read_sys_reg(hypctx, ESR_EL1)); + hypctx_read_sys_reg(hypctx, ESR_EL1)); WRITE_SPECIALREG(EL1_REG(FAR), - hypctx_read_sys_reg(hypctx, FAR_EL1)); + hypctx_read_sys_reg(hypctx, FAR_EL1)); WRITE_SPECIALREG(EL1_REG(MAIR), - hypctx_read_sys_reg(hypctx, MAIR_EL1)); + hypctx_read_sys_reg(hypctx, MAIR_EL1)); WRITE_SPECIALREG(EL1_REG(SCTLR), - hypctx_read_sys_reg(hypctx, SCTLR_EL1)); + hypctx_read_sys_reg(hypctx, SCTLR_EL1)); WRITE_SPECIALREG(EL1_REG(SPSR), - hypctx_read_sys_reg(hypctx, SPSR_EL1)); + hypctx_read_sys_reg(hypctx, SPSR_EL1)); WRITE_SPECIALREG(EL1_REG(TCR), - hypctx_read_sys_reg(hypctx, TCR_EL1)); + hypctx_read_sys_reg(hypctx, TCR_EL1)); /* TODO: tcr2_el1 */ WRITE_SPECIALREG(EL1_REG(TTBR0), - hypctx_read_sys_reg(hypctx, TTBR0_EL1)); + hypctx_read_sys_reg(hypctx, TTBR0_EL1)); WRITE_SPECIALREG(EL1_REG(TTBR1), - hypctx_read_sys_reg(hypctx, TTBR1_EL1)); + hypctx_read_sys_reg(hypctx, TTBR1_EL1)); } if (guest) { - WRITE_SPECIALREG(par_el1, hypctx->par_el1); + WRITE_SPECIALREG(par_el1, hypctx_read_sys_reg(hypctx, PAR_EL1)); } WRITE_SPECIALREG(cptr_el2, hypctx->cptr_el2); @@ -387,27 +398,36 @@ vmm_hyp_reg_restore(struct hypctx *hypctx, struct hyp *hyp, bool guest, WRITE_SPECIALREG(spsr_el2, hypctx->tf.tf_spsr); /* Restore the PMU registers */ - 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); + WRITE_SPECIALREG(pmcr_el0, + hypctx_read_sys_reg(hypctx, PMCR_EL0)); + WRITE_SPECIALREG(pmccntr_el0, + hypctx_read_sys_reg(hypctx, PMCCNTR_EL0)); + WRITE_SPECIALREG(pmccfiltr_el0, + hypctx_read_sys_reg(hypctx, PMCCFILTR_EL0)); + WRITE_SPECIALREG(pmuserenr_el0, + hypctx_read_sys_reg(hypctx, PMUSERENR_EL0)); + WRITE_SPECIALREG(pmselr_el0, + hypctx_read_sys_reg(hypctx, PMSELR_EL0)); + WRITE_SPECIALREG(pmxevcntr_el0, + hypctx_read_sys_reg(hypctx, PMXEVCNTR_EL0)); /* Clear all events/interrupts then enable them */ WRITE_SPECIALREG(pmcntenclr_el0, ~0ul); - WRITE_SPECIALREG(pmcntenset_el0, hypctx->pmcntenset_el0); + WRITE_SPECIALREG(pmcntenset_el0, + hypctx_read_sys_reg(hypctx, PMCNTENSET_EL0)); WRITE_SPECIALREG(pmintenclr_el1, ~0ul); - WRITE_SPECIALREG(pmintenset_el1, hypctx->pmintenset_el1); + WRITE_SPECIALREG(pmintenset_el1, + hypctx_read_sys_reg(hypctx, PMINTENSET_EL1)); WRITE_SPECIALREG(pmovsclr_el0, ~0ul); - WRITE_SPECIALREG(pmovsset_el0, hypctx->pmovsset_el0); + WRITE_SPECIALREG(pmovsset_el0, + hypctx_read_sys_reg(hypctx, PMOVSSET_EL0)); - switch ((hypctx->pmcr_el0 & PMCR_N_MASK) >> PMCR_N_SHIFT) { + switch ((hypctx_read_sys_reg(hypctx, PMCR_EL0) & PMCR_N_MASK) >> PMCR_N_SHIFT) { #define LOAD_PMU(x) \ case (x + 1): \ WRITE_SPECIALREG(pmevcntr ## x ## _el0, \ - hypctx->pmevcntr_el0[x]); \ + hypctx_read_sys_reg(hypctx, PMEVCNTR_EL0(x))); \ WRITE_SPECIALREG(pmevtyper ## x ## _el0, \ - hypctx->pmevtyper_el0[x]) + hypctx_read_sys_reg(hypctx, PMEVTYPER_EL0(x))) LOAD_PMU(30); LOAD_PMU(29); LOAD_PMU(28); @@ -445,16 +465,17 @@ vmm_hyp_reg_restore(struct hypctx *hypctx, struct hyp *hyp, bool guest, } WRITE_SPECIALREG(dbgclaimclr_el1, ~0ul); - WRITE_SPECIALREG(dbgclaimclr_el1, hypctx->dbgclaimset_el1); + WRITE_SPECIALREG(dbgclaimclr_el1, + hypctx_read_sys_reg(hypctx, DBGCLAIMSET_EL1)); dfr0 = READ_SPECIALREG(id_aa64dfr0_el1); switch (ID_AA64DFR0_BRPs_VAL(dfr0) - 1) { #define LOAD_DBG_BRP(x) \ case x: \ WRITE_SPECIALREG(dbgbcr ## x ## _el1, \ - hypctx->dbgbcr_el1[x]); \ + hypctx_read_sys_reg(hypctx, DBGBCR_EL1(x))); \ WRITE_SPECIALREG(dbgbvr ## x ## _el1, \ - hypctx->dbgbvr_el1[x]) + hypctx_read_sys_reg(hypctx, DBGBVR_EL1(x))) LOAD_DBG_BRP(15); LOAD_DBG_BRP(14); LOAD_DBG_BRP(13); @@ -479,9 +500,9 @@ vmm_hyp_reg_restore(struct hypctx *hypctx, struct hyp *hyp, bool guest, #define LOAD_DBG_WRP(x) \ case x: \ WRITE_SPECIALREG(dbgwcr ## x ## _el1, \ - hypctx->dbgwcr_el1[x]); \ + hypctx_read_sys_reg(hypctx, DBGWCR_EL1(x))); \ WRITE_SPECIALREG(dbgwvr ## x ## _el1, \ - hypctx->dbgwvr_el1[x]) + hypctx_read_sys_reg(hypctx, DBGWVR_EL1(x))) LOAD_DBG_WRP(15); LOAD_DBG_WRP(14); LOAD_DBG_WRP(13); diff --git a/sys/arm64/vmm/vmm_reset.c b/sys/arm64/vmm/vmm_reset.c index 4966de5c8fa5..1280fe64277a 100644 --- a/sys/arm64/vmm/vmm_reset.c +++ b/sys/arm64/vmm/vmm_reset.c @@ -55,10 +55,6 @@ reset_vm_el01_regs(void *vcpu) set_arch_unknown(el2ctx->tf); - set_arch_unknown(el2ctx->csselr_el1); - set_arch_unknown(el2ctx->mdccint_el1); - set_arch_unknown(el2ctx->par_el1); - /* * Guest starts with: * ~SCTLR_M: MMU off @@ -70,29 +66,9 @@ reset_vm_el01_regs(void *vcpu) *hypctx_sys_reg(el2ctx, SCTLR_EL1) &= ~SCTLR_M & ~SCTLR_C & ~SCTLR_I; *hypctx_sys_reg(el2ctx, SCTLR_EL1) |= SCTLR_CP15BEN; - set_arch_unknown(el2ctx->sp_el0); - set_arch_unknown(el2ctx->tpidr_el0); - set_arch_unknown(el2ctx->tpidr_el1); - set_arch_unknown(el2ctx->tpidrro_el0); - - set_arch_unknown(el2ctx->dbgbcr_el1); - set_arch_unknown(el2ctx->dbgbvr_el1); - set_arch_unknown(el2ctx->dbgwcr_el1); - set_arch_unknown(el2ctx->dbgwvr_el1); - - el2ctx->pmcr_el0 = READ_SPECIALREG(pmcr_el0) & PMCR_N_MASK; - /* PMCR_LC is unknown when AArch32 is supported or RES1 otherwise */ - 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); - memset(el2ctx->pmevcntr_el0, 0, sizeof(el2ctx->pmevcntr_el0)); - memset(el2ctx->pmevtyper_el0, 0, sizeof(el2ctx->pmevtyper_el0)); + hypctx_write_sys_reg(el2ctx, PMCR_EL0, + /* PMCR_LC is unknown when AArch32 is supported or RES1 otherwise */ + (READ_SPECIALREG(pmcr_el0) & PMCR_N_MASK) | PMCR_LC); } void @@ -133,7 +109,7 @@ reset_vm_el2_regs(void *vcpu) el2ctx->mdcr_el2 = MDCR_EL2_TDOSA | MDCR_EL2_TDRA | MDCR_EL2_TPMS | MDCR_EL2_TTRF; /* PMCR_EL0.N is read from MDCR_EL2.HPMN */ - el2ctx->mdcr_el2 |= (el2ctx->pmcr_el0 & PMCR_N_MASK) >> PMCR_N_SHIFT; + el2ctx->mdcr_el2 |= (hypctx_read_sys_reg(el2ctx, PMCR_EL0) & PMCR_N_MASK) >> PMCR_N_SHIFT; el2ctx->vmpidr_el2 = VMPIDR_EL2_RES1; /* The guest will detect a multi-core, single-threaded CPU */home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a4bc8b8.1cdc2.75cd5be8>
