Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153807567
D56551.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D56551.diff
View Options
diff --git a/sys/arm64/include/hypervisor.h b/sys/arm64/include/hypervisor.h
--- a/sys/arm64/include/hypervisor.h
+++ b/sys/arm64/include/hypervisor.h
@@ -2159,6 +2159,8 @@
/* Assumed to be 0 by locore.S */
#define VTTBR_HOST 0x0000000000000000
+/* Size of the memory page pointed to by VNCR_EL2 */
+#define VNCR_PAGE_SIZE 4096
/*
* Memory offsets of registers redirected to memory by HCR_EL2.NV2
* relative to the base address stored in VNCR_EL2.
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
@@ -39,6 +39,133 @@
struct vgic_v3;
struct vgic_v3_cpu;
+/*
+ Encode the index of a given register within VNCR into the enum value.
+ We move the indices up by VNCR_START to not interfere with values for
+ non-VNCR registers.
+*/
+#define VNCR_REG(reg) reg = (VNCR_START + VNCR_##reg / 8)
+/* Retrieve the VNCR offset from the enum value */
+#define REG_VNCR_OFFSET(val) ((val - VNCR_START) * 8)
+
+enum hypctx_sysreg {
+ /*
+ * EL1 & EL0 registers.
+ */
+ SP_EL0, /* Stack pointer */
+ TPIDR_EL0, /* EL0 Software ID Register */
+ TPIDRRO_EL0, /* Read-only Thread ID Register */
+ TPIDR_EL1, /* EL1 Software ID Register */
+ CSSELR_EL1, /* Cache Size Selection Register */
+ MDCCINT_EL1, /* Monitor DCC Interrupt Enable Register */
+ PAR_EL1, /* Physical Address Register */
+
+ PMCR_EL0, /* Performance Monitors Control Register */
+ PMCCNTR_EL0,
+ PMCCFILTR_EL0,
+ PMUSERENR_EL0,
+ PMSELR_EL0,
+ PMXEVCNTR_EL0,
+ PMCNTENSET_EL0,
+ PMINTENSET_EL1,
+ PMOVSSET_EL0,
+ DBGCLAIMSET_EL1,
+
+ NR_NON_VNCR_REGS,
+
+ /* VNCR Registers */
+ VNCR_START,
+
+ VNCR_REG(VTTBR_EL2),
+ VNCR_REG(VSTTBR_EL2),
+ VNCR_REG(VTCR_EL2),
+ VNCR_REG(VSTCR_EL2),
+ VNCR_REG(VMPIDR_EL2), /* Virtualization Multiprocessor ID Register */
+ VNCR_REG(CNTVOFF_EL2),
+ VNCR_REG(HCR_EL2), /* Hypervisor Configuration Register */
+ VNCR_REG(HSTR_EL2),
+ VNCR_REG(VPIDR_EL2), /* Virtualization Processor ID Register */
+ VNCR_REG(TPIDR_EL2),
+ VNCR_REG(HCRX_EL2), /* Extended Hypervisor Configuration Register */
+ VNCR_REG(VNCR_EL2),
+ VNCR_REG(CPACR_EL1), /* Architectural Feature Access Control Register */
+ VNCR_REG(CONTEXTIDR_EL1), /* Current Process Identifier */
+ VNCR_REG(SCTLR_EL1), /* System Control Register */
+ VNCR_REG(ACTLR_EL1), /* Auxiliary Control Register */
+ VNCR_REG(TCR_EL1), /* Translation Control Register */
+ VNCR_REG(AFSR0_EL1), /* Auxiliary Fault Status Register 0 */
+ VNCR_REG(AFSR1_EL1), /* Auxiliary Fault Status Register 1 */
+ VNCR_REG(ESR_EL1), /* Exception Syndrome Register */
+ VNCR_REG(MAIR_EL1), /* Memory Attribute Indirection Register */
+ VNCR_REG(AMAIR_EL1), /* Auxiliary Memory Attribute Indirection Register */
+ VNCR_REG(MDSCR_EL1), /* Monitor Debug System Control Register */
+ VNCR_REG(SPSR_EL1), /* Saved Program Status Register */
+ VNCR_REG(CNTV_CVAL_EL0),
+ VNCR_REG(CNTV_CTL_EL0),
+ VNCR_REG(CNTP_CVAL_EL0),
+ VNCR_REG(CNTP_CTL_EL0),
+ VNCR_REG(SCXTNUM_EL1),
+ VNCR_REG(TFSR_EL1),
+ VNCR_REG(HDFGRTR2_EL2),
+ VNCR_REG(CNTPOFF_EL2),
+ VNCR_REG(HDFGWTR2_EL2),
+ VNCR_REG(HFGRTR_EL2),
+ VNCR_REG(HFGWTR_EL2),
+ VNCR_REG(HFGITR_EL2),
+ VNCR_REG(HDFGRTR_EL2),
+ VNCR_REG(HDFGWTR_EL2),
+ VNCR_REG(ZCR_EL1),
+ VNCR_REG(HAFGRTR_EL2),
+ VNCR_REG(SMCR_EL1),
+ VNCR_REG(SMPRIMAP_EL2),
+ VNCR_REG(TTBR0_EL1), /* Translation Table Base Register 0 */
+ VNCR_REG(TTBR1_EL1), /* Translation Table Base Register 1 */
+ VNCR_REG(FAR_EL1), /* Fault Address Register */
+ VNCR_REG(ELR_EL1), /* Exception Link Register */
+ VNCR_REG(SP_EL1),
+ VNCR_REG(VBAR_EL1), /* Vector Base Address Register */
+ VNCR_REG(TCR2_EL1), /* Translation Control Register 2 */
+ VNCR_REG(SCTLR2_EL1),
+ VNCR_REG(MAIR2_EL1),
+ VNCR_REG(AMAIR2_EL1),
+ VNCR_REG(PIRE0_EL1),
+ VNCR_REG(PIRE0_EL2),
+ VNCR_REG(PIR_EL1),
+ VNCR_REG(POR_EL1),
+ VNCR_REG(S2PIR_EL2),
+ VNCR_REG(S2POR_EL1),
+ VNCR_REG(HFGRTR2_EL2),
+ VNCR_REG(HFGWTR2_EL2),
+ VNCR_REG(PFAR_EL1),
+ VNCR_REG(HFGITR2_EL2),
+ VNCR_REG(SCTLRMASK_EL1),
+ VNCR_REG(CPACRMASK_EL1),
+ VNCR_REG(SCTLR2MASK_EL1),
+ VNCR_REG(TCRMASK_EL1),
+ VNCR_REG(TCR2MASK_EL1),
+ VNCR_REG(ACTLRMASK_EL1),
+ VNCR_REG(ICH_HCR_EL2),
+ VNCR_REG(ICH_VMCR_EL2),
+ VNCR_REG(VDISR_EL2),
+ VNCR_REG(VSESR_EL2),
+ VNCR_REG(PMBLIMITR_EL1),
+ VNCR_REG(PMBPTR_EL1),
+ VNCR_REG(PMBSR_EL1),
+ VNCR_REG(PMSCR_EL1),
+ VNCR_REG(PMSEVFR_EL1),
+ VNCR_REG(PMSICR_EL1),
+ VNCR_REG(PMSIRR_EL1),
+ VNCR_REG(PMSLATFR_EL1),
+ VNCR_REG(PMSNEVFR_EL1),
+ VNCR_REG(PMSDSFR_EL1),
+ VNCR_REG(TRFCR_EL1),
+ VNCR_REG(TRCITECR_EL1),
+ VNCR_REG(GCSPR_EL1),
+ VNCR_REG(GCSCR_EL1),
+ VNCR_REG(BRBCR_EL1),
+ VNCR_REG(SPMACCESSR_EL1),
+};
+
/*
* Per-vCPU hypervisor state.
*/
@@ -46,34 +173,15 @@
struct trapframe tf;
/*
- * EL1 control registers.
+ * EL1 & EL0 registers.
*/
- uint64_t elr_el1; /* Exception Link Register */
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 vbar_el1; /* Vector Base Address Register */
-
- uint64_t actlr_el1; /* Auxiliary Control Register */
- uint64_t afsr0_el1; /* Auxiliary Fault Status Register 0 */
- uint64_t afsr1_el1; /* Auxiliary Fault Status Register 1 */
- uint64_t amair_el1; /* Auxiliary Memory Attribute Indirection Register */
- uint64_t contextidr_el1; /* Current Process Identifier */
- uint64_t cpacr_el1; /* Architectural Feature Access Control Register */
uint64_t csselr_el1; /* Cache Size Selection Register */
- uint64_t esr_el1; /* Exception Syndrome Register */
- uint64_t far_el1; /* Fault Address Register */
- uint64_t mair_el1; /* Memory Attribute Indirection Register */
uint64_t mdccint_el1; /* Monitor DCC Interrupt Enable Register */
- uint64_t mdscr_el1; /* Monitor Debug System Control Register */
uint64_t par_el1; /* Physical Address Register */
- uint64_t sctlr_el1; /* System Control Register */
- uint64_t tcr_el1; /* Translation Control Register */
- uint64_t tcr2_el1; /* Translation Control Register 2 */
- uint64_t ttbr0_el1; /* Translation Table Base Register 0 */
- uint64_t ttbr1_el1; /* Translation Table Base Register 1 */
- uint64_t spsr_el1; /* Saved Program Status Register */
uint64_t pmcr_el0; /* Performance Monitors Control Register */
uint64_t pmccntr_el0;
@@ -100,6 +208,8 @@
uint64_t mdcr_el2; /* Monitor Debug Configuration Register */
uint64_t vpidr_el2; /* Virtualization Processor ID Register */
uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
+ /* On systems without NV2 this still points to the register storage memory page */
+ uint64_t vncr_el2; /* Virtual Nested Control Register */
/* FEAT_FGT registers */
/*uint64_t hafgrtr_el2; *//* For FEAT_AMUv1 (not supported) */
@@ -116,7 +226,6 @@
uint64_t hfgrtr2_el2;
uint64_t hfgwtr2_el2;
- uint64_t el2_addr; /* The address of this in el2 space */
struct hyp *hyp;
struct vcpu *vcpu;
struct {
@@ -136,8 +245,48 @@
struct vgic_v3_cpu *vgic_cpu;
bool has_exception;
bool dbg_oslock;
+
+ /*
+ * Memory page pointed at by VNCR_EL2. Contains storage for registers
+ * the accesses to which are redirected to memory by FEAT_NV2.
+ * NOTE: The storage is still used even if FEAT_NV2 is not present.
+ */
+ void *vncr_regs;
+ /* Memory page used to store the host's values of VNCR registers. */
+ void *host_vncr_regs;
+
+ uint64_t el2_addr; /* The address of this in el2 space */
+ uint64_t el2_vncr_addr; /* The address of vncr_regs in el2 space */
+ uint64_t el2_host_vncr_addr;
};
+#ifndef __hypctx_vncr_sysreg
+#define __hypctx_vncr_sysreg(hypctx, reg) \
+ ((uint64_t*)((uint64_t)hypctx->vncr_regs + REG_VNCR_OFFSET(reg)))
+#endif
+
+static inline uint64_t *
+hypctx_sys_reg(struct hypctx *hypctx, int reg /* enum hypctx_sysreg */)
+{
+ if (reg > VNCR_START)
+ return __hypctx_vncr_sysreg(hypctx, reg);
+ /* TODO: uniform handling for non-VNCR registers */
+ return NULL;
+}
+
+static inline void
+hypctx_write_sys_reg(struct hypctx *hypctx, enum hypctx_sysreg reg,
+ uint64_t val)
+{
+ *hypctx_sys_reg(hypctx, reg) = val;
+}
+
+static inline uint64_t
+hypctx_read_sys_reg(struct hypctx *hypctx, enum hypctx_sysreg reg)
+{
+ return *hypctx_sys_reg(hypctx, reg);
+}
+
struct hyp {
struct vm *vm;
struct vtimer vtimer;
diff --git a/sys/arm64/vmm/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c
--- a/sys/arm64/vmm/vmm_arm64.c
+++ b/sys/arm64/vmm/vmm_arm64.c
@@ -488,7 +488,8 @@
static vm_size_t
el2_hypctx_size(void)
{
- return (round_page(sizeof(struct hypctx)));
+ /* Allocation for hypctx, one vncr page & one host state page */
+ return (round_page(sizeof(struct hypctx) + 2 * VNCR_PAGE_SIZE));
}
static vm_offset_t
@@ -557,7 +558,16 @@
vm_size_t size;
size = el2_hypctx_size();
+ /*
+ * Allocation memory layout:
+ 0x0000 - 0x0fff <- struct hypctx
+ 0x1000 - 0x1fff <- VNCR memory page
+ 0x2000 - 0x2fff <- host_ctx memory page
+ */
hypctx = malloc_aligned(size, PAGE_SIZE, M_HYP, M_WAITOK | M_ZERO);
+ /* NOTE: This assumes that sizeof(struct hypctx) < 4096, revise this if that changes */
+ hypctx->vncr_regs = (void*)((uint64_t)hypctx + VNCR_PAGE_SIZE);
+ hypctx->host_vncr_regs = (void*)((uint64_t)hypctx + 2 * VNCR_PAGE_SIZE);
KASSERT(vcpuid >= 0 && vcpuid < vm_get_maxcpus(hyp->vm),
("%s: Invalid vcpuid %d", __func__, vcpuid));
@@ -572,9 +582,12 @@
vtimer_cpuinit(hypctx);
vgic_cpuinit(hypctx);
- if (!in_vhe())
+ if (!in_vhe()) {
hypctx->el2_addr = el2_map_enter((vm_offset_t)hypctx, size,
VM_PROT_READ | VM_PROT_WRITE);
+ hypctx->el2_vncr_addr = hypctx->el2_addr + VNCR_PAGE_SIZE;
+ hypctx->el2_host_vncr_addr = hypctx->el2_addr + 2 * VNCR_PAGE_SIZE;
+ }
return (hypctx);
}
@@ -637,12 +650,12 @@
vie->reg = reg_num;
paging = &vme_ret->u.inst_emul.paging;
- paging->ttbr0_addr = hypctx->ttbr0_el1 & ~(TTBR_ASID_MASK | TTBR_CnP);
- paging->ttbr1_addr = hypctx->ttbr1_el1 & ~(TTBR_ASID_MASK | TTBR_CnP);
- paging->tcr_el1 = hypctx->tcr_el1;
- paging->tcr2_el1 = hypctx->tcr2_el1;
+ paging->ttbr0_addr = hypctx_read_sys_reg(hypctx, TTBR0_EL1) & ~(TTBR_ASID_MASK | TTBR_CnP);
+ paging->ttbr1_addr = hypctx_read_sys_reg(hypctx, TTBR1_EL1) & ~(TTBR_ASID_MASK | TTBR_CnP);
+ paging->tcr_el1 = hypctx_read_sys_reg(hypctx, TCR_EL1);
+ paging->tcr2_el1 = hypctx_read_sys_reg(hypctx, TCR2_EL1);
paging->flags = hypctx->tf.tf_spsr & (PSR_M_MASK | PSR_M_32);
- if ((hypctx->sctlr_el1 & SCTLR_M) != 0)
+ if ((hypctx_read_sys_reg(hypctx, SCTLR_EL1) & SCTLR_M) != 0)
paging->flags |= VM_GP_MMU_ENABLED;
}
@@ -1095,36 +1108,36 @@
for (;;) {
if (hypctx->has_exception) {
hypctx->has_exception = false;
- hypctx->elr_el1 = hypctx->tf.tf_elr;
+ hypctx_write_sys_reg(hypctx, ELR_EL1, hypctx->tf.tf_elr);
mode = hypctx->tf.tf_spsr & (PSR_M_MASK | PSR_M_32);
if (mode == PSR_M_EL1t) {
- hypctx->tf.tf_elr = hypctx->vbar_el1 + 0x0;
+ hypctx->tf.tf_elr = hypctx_read_sys_reg(hypctx, VBAR_EL1) + 0x0;
} else if (mode == PSR_M_EL1h) {
- hypctx->tf.tf_elr = hypctx->vbar_el1 + 0x200;
+ hypctx->tf.tf_elr = hypctx_read_sys_reg(hypctx, VBAR_EL1) + 0x200;
} else if ((mode & PSR_M_32) == PSR_M_64) {
/* 64-bit EL0 */
- hypctx->tf.tf_elr = hypctx->vbar_el1 + 0x400;
+ hypctx->tf.tf_elr = hypctx_read_sys_reg(hypctx, VBAR_EL1) + 0x400;
} else {
/* 32-bit EL0 */
- hypctx->tf.tf_elr = hypctx->vbar_el1 + 0x600;
+ hypctx->tf.tf_elr = hypctx_read_sys_reg(hypctx, VBAR_EL1) + 0x600;
}
/* Set the new spsr */
- hypctx->spsr_el1 = hypctx->tf.tf_spsr;
+ hypctx_write_sys_reg(hypctx, SPSR_EL1, hypctx->tf.tf_spsr);
/* Set the new cpsr */
- hypctx->tf.tf_spsr = hypctx->spsr_el1 & PSR_FLAGS;
+ hypctx->tf.tf_spsr = hypctx_read_sys_reg(hypctx, SPSR_EL1) & PSR_FLAGS;
hypctx->tf.tf_spsr |= PSR_DAIF | PSR_M_EL1h;
/*
* Update fields that may change on exeption entry
* based on how sctlr_el1 is configured.
*/
- if ((hypctx->sctlr_el1 & SCTLR_SPAN) == 0)
+ if ((hypctx_read_sys_reg(hypctx, SCTLR_EL1) & SCTLR_SPAN) == 0)
hypctx->tf.tf_spsr |= PSR_PAN;
- if ((hypctx->sctlr_el1 & SCTLR_DSSBS) == 0)
+ if ((hypctx_read_sys_reg(hypctx, SCTLR_EL1) & SCTLR_DSSBS) == 0)
hypctx->tf.tf_spsr &= ~PSR_SSBS;
else
hypctx->tf.tf_spsr |= PSR_SSBS;
@@ -1257,15 +1270,15 @@
case VM_REG_GUEST_PC:
return (&hypctx->tf.tf_elr);
case VM_REG_GUEST_SCTLR_EL1:
- return (&hypctx->sctlr_el1);
+ return hypctx_sys_reg(hypctx, SCTLR_EL1);
case VM_REG_GUEST_TTBR0_EL1:
- return (&hypctx->ttbr0_el1);
+ return hypctx_sys_reg(hypctx, TTBR0_EL1);
case VM_REG_GUEST_TTBR1_EL1:
- return (&hypctx->ttbr1_el1);
+ return hypctx_sys_reg(hypctx, TTBR1_EL1);
case VM_REG_GUEST_TCR_EL1:
- return (&hypctx->tcr_el1);
+ return hypctx_sys_reg(hypctx, TCR_EL1);
case VM_REG_GUEST_TCR2_EL1:
- return (&hypctx->tcr2_el1);
+ return hypctx_sys_reg(hypctx, TCR2_EL1);
case VM_REG_GUEST_MPIDR_EL1:
return (&hypctx->vmpidr_el2);
default:
@@ -1325,8 +1338,8 @@
panic("%s: %s%d is running", __func__, vm_name(hypctx->hyp->vm),
vcpu_vcpuid(hypctx->vcpu));
- hypctx->far_el1 = far;
- hypctx->esr_el1 = esr;
+ hypctx_write_sys_reg(hypctx, FAR_EL1, far);
+ hypctx_write_sys_reg(hypctx, ESR_EL1, esr);
hypctx->has_exception = true;
return (0);
@@ -1380,17 +1393,17 @@
if (val != 0) {
hypctx->debug_spsr |= (hypctx->tf.tf_spsr & PSR_SS);
- hypctx->debug_mdscr |= (hypctx->mdscr_el1 & MDSCR_SS);
+ hypctx->debug_mdscr |= (hypctx_read_sys_reg(hypctx, MDSCR_EL1) & MDSCR_SS);
hypctx->tf.tf_spsr |= PSR_SS;
- hypctx->mdscr_el1 |= MDSCR_SS;
+ *hypctx_sys_reg(hypctx, MDSCR_EL1) |= MDSCR_SS;
hypctx->mdcr_el2 |= MDCR_EL2_TDE;
} else {
hypctx->tf.tf_spsr &= ~PSR_SS;
hypctx->tf.tf_spsr |= hypctx->debug_spsr;
hypctx->debug_spsr &= ~PSR_SS;
- hypctx->mdscr_el1 &= ~MDSCR_SS;
- hypctx->mdscr_el1 |= hypctx->debug_mdscr;
+ *hypctx_sys_reg(hypctx, MDSCR_EL1) &= ~MDSCR_SS;
+ *hypctx_sys_reg(hypctx, MDSCR_EL1) |= hypctx->debug_mdscr;
hypctx->debug_mdscr &= ~MDSCR_SS;
if ((hypctx->setcaps & (1ul << VM_CAP_BRK_EXIT)) == 0)
hypctx->mdcr_el2 &= ~MDCR_EL2_TDE;
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
@@ -246,30 +246,30 @@
hypctx->tpidrro_el0 = READ_SPECIALREG(tpidrro_el0);
hypctx->tpidr_el1 = READ_SPECIALREG(tpidr_el1);
- hypctx->actlr_el1 = READ_SPECIALREG(actlr_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->mdscr_el1 = READ_SPECIALREG(mdscr_el1);
+ hypctx_write_sys_reg(hypctx, MDSCR_EL1, READ_SPECIALREG(mdscr_el1));
if (guest_or_nonvhe(guest)) {
- hypctx->elr_el1 = READ_SPECIALREG(EL1_REG(ELR));
- hypctx->vbar_el1 = READ_SPECIALREG(EL1_REG(VBAR));
-
- hypctx->afsr0_el1 = READ_SPECIALREG(EL1_REG(AFSR0));
- hypctx->afsr1_el1 = READ_SPECIALREG(EL1_REG(AFSR1));
- hypctx->amair_el1 = READ_SPECIALREG(EL1_REG(AMAIR));
- hypctx->contextidr_el1 = READ_SPECIALREG(EL1_REG(CONTEXTIDR));
- hypctx->cpacr_el1 = READ_SPECIALREG(EL1_REG(CPACR));
- hypctx->esr_el1 = READ_SPECIALREG(EL1_REG(ESR));
- hypctx->far_el1 = READ_SPECIALREG(EL1_REG(FAR));
- hypctx->mair_el1 = READ_SPECIALREG(EL1_REG(MAIR));
- hypctx->sctlr_el1 = READ_SPECIALREG(EL1_REG(SCTLR));
- hypctx->spsr_el1 = READ_SPECIALREG(EL1_REG(SPSR));
- hypctx->tcr_el1 = READ_SPECIALREG(EL1_REG(TCR));
+ hypctx_write_sys_reg(hypctx, ELR_EL1, READ_SPECIALREG(EL1_REG(ELR)));
+ hypctx_write_sys_reg(hypctx, VBAR_EL1, READ_SPECIALREG(EL1_REG(VBAR)));
+
+ hypctx_write_sys_reg(hypctx, AFSR0_EL1, READ_SPECIALREG(EL1_REG(AFSR0)));
+ hypctx_write_sys_reg(hypctx, AFSR1_EL1, READ_SPECIALREG(EL1_REG(AFSR1)));
+ hypctx_write_sys_reg(hypctx, AMAIR_EL1, READ_SPECIALREG(EL1_REG(AMAIR)));
+ hypctx_write_sys_reg(hypctx, CONTEXTIDR_EL1, READ_SPECIALREG(EL1_REG(CONTEXTIDR)));
+ hypctx_write_sys_reg(hypctx, CPACR_EL1, READ_SPECIALREG(EL1_REG(CPACR)));
+ hypctx_write_sys_reg(hypctx, ESR_EL1, READ_SPECIALREG(EL1_REG(ESR)));
+ hypctx_write_sys_reg(hypctx, FAR_EL1, READ_SPECIALREG(EL1_REG(FAR)));
+ hypctx_write_sys_reg(hypctx, MAIR_EL1, READ_SPECIALREG(EL1_REG(MAIR)));
+ hypctx_write_sys_reg(hypctx, SCTLR_EL1, READ_SPECIALREG(EL1_REG(SCTLR)));
+ hypctx_write_sys_reg(hypctx, SPSR_EL1, READ_SPECIALREG(EL1_REG(SPSR)));
+ hypctx_write_sys_reg(hypctx, TCR_EL1, READ_SPECIALREG(EL1_REG(TCR)));
/* TODO: Support when this is not res0 */
- hypctx->tcr2_el1 = 0;
- hypctx->ttbr0_el1 = READ_SPECIALREG(EL1_REG(TTBR0));
- hypctx->ttbr1_el1 = READ_SPECIALREG(EL1_REG(TTBR1));
+ hypctx_write_sys_reg(hypctx, TCR2_EL1, 0);
+ hypctx_write_sys_reg(hypctx, TTBR0_EL1, READ_SPECIALREG(EL1_REG(TTBR0)));
+ hypctx_write_sys_reg(hypctx, TTBR1_EL1, READ_SPECIALREG(EL1_REG(TTBR1)));
}
hypctx->cptr_el2 = READ_SPECIALREG(cptr_el2);
@@ -320,30 +320,30 @@
WRITE_SPECIALREG(tpidrro_el0, hypctx->tpidrro_el0);
WRITE_SPECIALREG(tpidr_el1, hypctx->tpidr_el1);
- WRITE_SPECIALREG(actlr_el1, hypctx->actlr_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(mdscr_el1, hypctx->mdscr_el1);
+ WRITE_SPECIALREG(mdscr_el1, hypctx_read_sys_reg(hypctx, MDSCR_EL1));
if (guest_or_nonvhe(guest)) {
- WRITE_SPECIALREG(EL1_REG(ELR), hypctx->elr_el1);
- WRITE_SPECIALREG(EL1_REG(VBAR), hypctx->vbar_el1);
-
- WRITE_SPECIALREG(EL1_REG(AFSR0), hypctx->afsr0_el1);
- WRITE_SPECIALREG(EL1_REG(AFSR1), hypctx->afsr1_el1);
- WRITE_SPECIALREG(EL1_REG(AMAIR), hypctx->amair_el1);
- WRITE_SPECIALREG(EL1_REG(CONTEXTIDR), hypctx->contextidr_el1);
- WRITE_SPECIALREG(EL1_REG(CPACR), hypctx->cpacr_el1);
- WRITE_SPECIALREG(EL1_REG(ESR), hypctx->esr_el1);
- WRITE_SPECIALREG(EL1_REG(FAR), hypctx->far_el1);
- WRITE_SPECIALREG(EL1_REG(MAIR), hypctx->mair_el1); //
-
- WRITE_SPECIALREG(EL1_REG(SCTLR), hypctx->sctlr_el1);
- WRITE_SPECIALREG(EL1_REG(SPSR), hypctx->spsr_el1);
- WRITE_SPECIALREG(EL1_REG(TCR), hypctx->tcr_el1);
+ WRITE_SPECIALREG(EL1_REG(ELR), hypctx_read_sys_reg(hypctx, ELR_EL1));
+ WRITE_SPECIALREG(EL1_REG(VBAR), hypctx_read_sys_reg(hypctx, VBAR_EL1));
+
+ WRITE_SPECIALREG(EL1_REG(AFSR0), hypctx_read_sys_reg(hypctx, AFSR0_EL1));
+ WRITE_SPECIALREG(EL1_REG(AFSR1), hypctx_read_sys_reg(hypctx, AFSR1_EL1));
+ WRITE_SPECIALREG(EL1_REG(AMAIR), hypctx_read_sys_reg(hypctx, AMAIR_EL1));
+ WRITE_SPECIALREG(EL1_REG(CONTEXTIDR), hypctx_read_sys_reg(hypctx, CONTEXTIDR_EL1));
+ WRITE_SPECIALREG(EL1_REG(CPACR), hypctx_read_sys_reg(hypctx, CPACR_EL1));
+ WRITE_SPECIALREG(EL1_REG(ESR), hypctx_read_sys_reg(hypctx, ESR_EL1));
+ WRITE_SPECIALREG(EL1_REG(FAR), hypctx_read_sys_reg(hypctx, FAR_EL1));
+ WRITE_SPECIALREG(EL1_REG(MAIR), hypctx_read_sys_reg(hypctx, MAIR_EL1));
+
+ WRITE_SPECIALREG(EL1_REG(SCTLR), hypctx_read_sys_reg(hypctx, SCTLR_EL1));
+ WRITE_SPECIALREG(EL1_REG(SPSR), hypctx_read_sys_reg(hypctx, SPSR_EL1));
+ WRITE_SPECIALREG(EL1_REG(TCR), hypctx_read_sys_reg(hypctx, TCR_EL1));
/* TODO: tcr2_el1 */
- WRITE_SPECIALREG(EL1_REG(TTBR0), hypctx->ttbr0_el1);
- WRITE_SPECIALREG(EL1_REG(TTBR1), hypctx->ttbr1_el1);
+ WRITE_SPECIALREG(EL1_REG(TTBR0), hypctx_read_sys_reg(hypctx, TTBR0_EL1));
+ WRITE_SPECIALREG(EL1_REG(TTBR1), hypctx_read_sys_reg(hypctx, TTBR1_EL1));
}
if (guest) {
@@ -568,6 +568,12 @@
uint64_t s1e1r, hpfar_el2;
bool ecv_poff, hpfar_valid;
+ /* Allows uniform implementation of guest and host register reloads */
+ host_hypctx.vncr_regs = hypctx->host_vncr_regs;
+#ifndef VMM_VHE
+ host_hypctx.el2_vncr_addr = hypctx->el2_host_vncr_addr;
+#endif
+
ecv_poff = (hyp->vtimer.cnthctl_el2 & CNTHCTL_ECV_EN) != 0;
vmm_hyp_reg_store(&host_hypctx, NULL, false, ecv_poff);
#ifndef VMM_VHE
diff --git a/sys/arm64/vmm/vmm_nvhe.c b/sys/arm64/vmm/vmm_nvhe.c
--- a/sys/arm64/vmm/vmm_nvhe.c
+++ b/sys/arm64/vmm/vmm_nvhe.c
@@ -36,6 +36,9 @@
#define EL1_REG(reg) MRS_REG_ALT_NAME(reg ## _EL1)
#define EL0_REG(reg) MRS_REG_ALT_NAME(reg ## _EL0)
+#define __hypctx_vncr_sysreg(hypctx, reg) \
+ ((uint64_t*)(hypctx->el2_vncr_addr + REG_VNCR_OFFSET(reg)))
+
#include "vmm_hyp.c"
uint64_t vmm_hyp_enter(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
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,19 +55,8 @@
set_arch_unknown(el2ctx->tf);
- set_arch_unknown(el2ctx->actlr_el1);
- set_arch_unknown(el2ctx->afsr0_el1);
- set_arch_unknown(el2ctx->afsr1_el1);
- set_arch_unknown(el2ctx->amair_el1);
- set_arch_unknown(el2ctx->contextidr_el1);
- set_arch_unknown(el2ctx->cpacr_el1);
set_arch_unknown(el2ctx->csselr_el1);
- set_arch_unknown(el2ctx->elr_el1);
- set_arch_unknown(el2ctx->esr_el1);
- set_arch_unknown(el2ctx->far_el1);
- set_arch_unknown(el2ctx->mair_el1);
set_arch_unknown(el2ctx->mdccint_el1);
- set_arch_unknown(el2ctx->mdscr_el1);
set_arch_unknown(el2ctx->par_el1);
/*
@@ -77,19 +66,14 @@
* SCTLR_CP15BEN: memory barrier instruction enable from EL0; RAO/WI
* ~SCTLR_I: instruction cache off
*/
- el2ctx->sctlr_el1 = SCTLR_RES1;
- el2ctx->sctlr_el1 &= ~SCTLR_M & ~SCTLR_C & ~SCTLR_I;
- el2ctx->sctlr_el1 |= SCTLR_CP15BEN;
+ *hypctx_sys_reg(el2ctx, SCTLR_EL1) = SCTLR_RES1;
+ *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->tcr_el1);
set_arch_unknown(el2ctx->tpidr_el0);
set_arch_unknown(el2ctx->tpidr_el1);
set_arch_unknown(el2ctx->tpidrro_el0);
- set_arch_unknown(el2ctx->ttbr0_el1);
- set_arch_unknown(el2ctx->ttbr1_el1);
- set_arch_unknown(el2ctx->vbar_el1);
- set_arch_unknown(el2ctx->spsr_el1);
set_arch_unknown(el2ctx->dbgbcr_el1);
set_arch_unknown(el2ctx->dbgbvr_el1);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 24, 10:12 PM (4 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32094026
Default Alt Text
D56551.diff (21 KB)
Attached To
Mode
D56551: arm64/vmm: Use the VNCR_EL2 memory page to store guest registers
Attached
Detach File
Event Timeline
Log In to Comment