Page MenuHomeFreeBSD

D56552.id175975.diff
No OneTemporary

D56552.id175975.diff

diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h
--- a/sys/arm64/vmm/arm64.h
+++ b/sys/arm64/vmm/arm64.h
@@ -48,6 +48,14 @@
/* Retrieve the VNCR offset from the enum value */
#define REG_VNCR_OFFSET(val) (val - VNCR_START)
+/* 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 {
/*
* EL1 & EL0 registers.
@@ -60,7 +68,8 @@
MDCCINT_EL1, /* Monitor DCC Interrupt Enable Register */
PAR_EL1, /* Physical Address Register */
- PMCR_EL0, /* Performance Monitors Control Register */
+ /* PMU Registers */
+ PMCR_EL0, /* Performance Monitors Control Register */
PMCCNTR_EL0,
PMCCFILTR_EL0,
PMUSERENR_EL0,
@@ -69,7 +78,23 @@
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,
@@ -171,37 +196,10 @@
*/
struct hypctx {
struct trapframe tf;
+ /* 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 */
@@ -262,8 +260,8 @@
{
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
--- a/sys/arm64/vmm/vmm_hyp.c
+++ b/sys/arm64/vmm/vmm_hyp.c
@@ -120,16 +120,16 @@
}
}
- 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) \
+#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)
+ 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 +151,12 @@
}
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 +178,23 @@
}
/* 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) {
-#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, 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_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,18 +237,18 @@
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)) {
@@ -315,14 +315,14 @@
}
#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)) {
@@ -347,7 +347,7 @@
}
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);
@@ -360,27 +360,27 @@
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);
-
- switch ((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]); \
- WRITE_SPECIALREG(pmevtyper ## x ## _el0, \
- hypctx->pmevtyper_el0[x])
+ WRITE_SPECIALREG(pmovsset_el0, hypctx_read_sys_reg(hypctx, PMOVSSET_EL0));
+
+ 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_read_sys_reg(hypctx, PMEVCNTR_EL0(x))); \
+ WRITE_SPECIALREG(pmevtyper ## x ## _el0, \
+ hypctx_read_sys_reg(hypctx, PMEVTYPER_EL0(x)))
LOAD_PMU(30);
LOAD_PMU(29);
LOAD_PMU(28);
@@ -418,16 +418,16 @@
}
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]); \
- WRITE_SPECIALREG(dbgbvr ## x ## _el1, \
- hypctx->dbgbvr_el1[x])
+#define LOAD_DBG_BRP(x) \
+ case x: \
+ WRITE_SPECIALREG(dbgbcr ## x ## _el1, \
+ hypctx_read_sys_reg(hypctx, DBGBCR_EL1(x))); \
+ WRITE_SPECIALREG(dbgbvr ## x ## _el1, \
+ hypctx_read_sys_reg(hypctx, DBGBVR_EL1(x)))
LOAD_DBG_BRP(15);
LOAD_DBG_BRP(14);
LOAD_DBG_BRP(13);
@@ -449,12 +449,12 @@
}
switch (ID_AA64DFR0_WRPs_VAL(dfr0) - 1) {
-#define LOAD_DBG_WRP(x) \
- case x: \
- WRITE_SPECIALREG(dbgwcr ## x ## _el1, \
- hypctx->dbgwcr_el1[x]); \
- WRITE_SPECIALREG(dbgwvr ## x ## _el1, \
- hypctx->dbgwvr_el1[x])
+#define LOAD_DBG_WRP(x) \
+ case x: \
+ WRITE_SPECIALREG(dbgwcr ## x ## _el1, \
+ hypctx_read_sys_reg(hypctx, DBGWCR_EL1(x))); \
+ WRITE_SPECIALREG(dbgwvr ## x ## _el1, \
+ 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
--- a/sys/arm64/vmm/vmm_reset.c
+++ b/sys/arm64/vmm/vmm_reset.c
@@ -55,10 +55,6 @@
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 @@
*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 @@
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 */

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 26, 6:34 AM (17 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32169703
Default Alt Text
D56552.id175975.diff (14 KB)

Event Timeline