Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153985046
D56552.id175975.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D56552.id175975.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D56552: arm64/vmm: Store non-VNCR registers in an array
Attached
Detach File
Event Timeline
Log In to Comment