git: ee2642678a2c - main - arm64/vmm: Move host-side EL2 regs into sys_regs

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Mon, 06 Jul 2026 15:24:43 UTC
The branch main has been updated by andrew:

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

commit ee2642678a2ca1cb968fcb2795496bc56eacbe7b
Author:     Kajetan Puchalski <kajetan.puchalski@arm.com>
AuthorDate: 2026-07-06 14:18:19 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-07-06 15:18:30 +0000

    arm64/vmm: Move host-side EL2 regs into sys_regs
    
    Move EL2 host registers that are not visible to the guest into
    hypctx->sys_regs. Prefix them with HOST_ to distinguish from EL2
    registers which are part of the guest's own state (e.g. in VNCR).
    
    Signed-off-by:  Kajetan Puchalski <kajetan.puchalski@arm.com>
    Reviewed by:    andrew
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D56555
---
 sys/arm64/vmm/arm64.h      |  70 +++---
 sys/arm64/vmm/io/vgic_v3.c |   6 +-
 sys/arm64/vmm/vmm_arm64.c  |  26 +-
 sys/arm64/vmm/vmm_hyp.c    |  82 ++++---
 sys/arm64/vmm/vmm_reset.c  | 582 ++++++++++++++++++++++++---------------------
 5 files changed, 410 insertions(+), 356 deletions(-)

diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h
index c43034454808..48ac3fe83ad7 100644
--- a/sys/arm64/vmm/arm64.h
+++ b/sys/arm64/vmm/arm64.h
@@ -89,6 +89,37 @@ enum hypctx_sysreg {
 	DBGWVR0_EL1,	/* Debug Watchpoint Value Registers */
 	DBGWVR15_EL1 = DBGWVR0_EL1 + 15,
 
+	/* EL2 registers used to control the guest, but not exposed to it */
+	HOST_CPTR_EL2,	 /* Architectural Feature Trap Register */
+	HOST_HCR_EL2,	 /* Hypervisor Configuration Register */
+	HOST_HCRX_EL2,	 /* Extended Hypervisor Configuration Register */
+	HOST_MDCR_EL2,	 /* Monitor Debug Configuration Register */
+	HOST_VPIDR_EL2,	 /* Virtualization Processor ID Register */
+	HOST_VMPIDR_EL2, /* Virtualization Multiprocessor ID Register */
+	/* On systems without NV2 this still points to the register storage
+	   memory page */
+	HOST_VNCR_EL2, /* Virtual Nested Control Register */
+	HOST_VTTBR_EL2,
+
+	/* FEAT_FGT registers */
+	/*HOST_HAFGRTR_EL2; */ /* For FEAT_AMUv1 (not supported) */
+	HOST_HDFGRTR_EL2,
+	HOST_HDFGWTR_EL2,
+	HOST_HFGITR_EL2,
+	HOST_HFGRTR_EL2,
+	HOST_HFGWTR_EL2,
+
+	/* FEAT_FGT2 registers */
+	HOST_HDFGRTR2_EL2,
+	HOST_HDFGWTR2_EL2,
+	HOST_HFGITR2_EL2,
+	HOST_HFGRTR2_EL2,
+	HOST_HFGWTR2_EL2,
+
+	/* Exit info registers */
+	HOST_FAR_EL2,	/* Fault Address Register */
+	HOST_HPFAR_EL2,	/* Hypervisor IPA Fault Address Register */
+
 	NR_NON_VNCR_REGS,
 
 	/* VNCR Registers */
@@ -201,48 +232,11 @@ 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 */
+	/* Non-VNCR register state */
 	uint64_t sys_regs[NR_NON_VNCR_REGS];
 
-	/* 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 */
-	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) */
-	uint64_t	hdfgrtr_el2;
-	uint64_t	hdfgwtr_el2;
-	uint64_t	hfgitr_el2;
-	uint64_t	hfgrtr_el2;
-	uint64_t	hfgwtr_el2;
-
-	/* FEAT_FGT2 registers */
-	uint64_t	hdfgrtr2_el2;
-	uint64_t	hdfgwtr2_el2;
-	uint64_t	hfgitr2_el2;
-	uint64_t	hfgrtr2_el2;
-	uint64_t	hfgwtr2_el2;
-
-	uint64_t	vttbr_el2;
-
-	/* Storage for *host* timer registers */
-	struct {
-		uint64_t cnthctl_el2;
-		uint64_t cntvoff_el2;
-	} host_timer_regs;
-
 	struct hyp	*hyp;
 	struct vcpu	*vcpu;
-	struct {
-		uint64_t	far_el2;	/* Fault Address Register */
-		uint64_t	hpfar_el2;	/* Hypervisor IPA Fault Address Register */
-	} exit_info;
 
 	struct vtimer	vtimer;
 	struct vtimer_cpu 	vtimer_cpu;
diff --git a/sys/arm64/vmm/io/vgic_v3.c b/sys/arm64/vmm/io/vgic_v3.c
index 199749c12b9f..f38fb4b74693 100644
--- a/sys/arm64/vmm/io/vgic_v3.c
+++ b/sys/arm64/vmm/io/vgic_v3.c
@@ -431,7 +431,7 @@ mpidr_to_vcpu(struct hyp *hyp, uint64_t mpidr)
 	vm = hyp->vm;
 	for (int i = 0; i < vm_get_maxcpus(vm); i++) {
 		hypctx = hyp->ctx[i];
-		if (hypctx != NULL && (hypctx->vmpidr_el2 & GICD_AFF) == mpidr)
+		if (hypctx != NULL && (hypctx_read_sys_reg(hypctx, HOST_VMPIDR_EL2) & GICD_AFF) == mpidr)
 			return (i);
 	}
 	return (-1);
@@ -481,7 +481,7 @@ vgic_v3_cpuinit(device_t dev, struct hypctx *hypctx)
 		mtx_init(&irq->irq_spinmtx, "VGIC IRQ spinlock", NULL,
 		    MTX_SPIN);
 		irq->irq = irqid;
-		irq->mpidr = hypctx->vmpidr_el2 & GICD_AFF;
+		irq->mpidr = hypctx_read_sys_reg(hypctx, HOST_VMPIDR_EL2) & GICD_AFF;
 		irq->target_vcpu = vcpu_vcpuid(hypctx->vcpu);
 		MPASS(irq->target_vcpu >= 0);
 
@@ -1470,7 +1470,7 @@ redist_typer_read(struct hypctx *hypctx, u_int reg, uint64_t *rval, void *arg)
 	if (vcpu_vcpuid(hypctx->vcpu) == (vgic_max_cpu_count(hypctx->hyp) - 1))
 		last_vcpu = true;
 
-	vmpidr_el2 = hypctx->vmpidr_el2;
+	vmpidr_el2 = hypctx_read_sys_reg(hypctx, HOST_VMPIDR_EL2);
 	MPASS(vmpidr_el2 != 0);
 	/*
 	 * Get affinity for the current CPU. The guest CPU affinity is taken
diff --git a/sys/arm64/vmm/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c
index 43f45dc596c9..ba826649092c 100644
--- a/sys/arm64/vmm/vmm_arm64.c
+++ b/sys/arm64/vmm/vmm_arm64.c
@@ -638,9 +638,9 @@ arm64_gen_inst_emul_data(struct hypctx *hypctx, uint32_t esr_iss,
 	 * Get the page address from HPFAR_EL2.
 	 */
 	vme_ret->u.inst_emul.gpa =
-	    HPFAR_EL2_FIPA_ADDR(hypctx->exit_info.hpfar_el2);
+	    HPFAR_EL2_FIPA_ADDR(hypctx_read_sys_reg(hypctx, HOST_HPFAR_EL2));
 	/* Bits [11:0] are the same as bits [11:0] from the virtual address. */
-	vme_ret->u.inst_emul.gpa += hypctx->exit_info.far_el2 &
+	vme_ret->u.inst_emul.gpa += hypctx_read_sys_reg(hypctx, HOST_FAR_EL2) &
 	    FAR_EL2_HPFAR_PAGE_MASK;
 
 	esr_sas = (esr_iss & ISS_DATA_SAS_MASK) >> ISS_DATA_SAS_SHIFT;
@@ -755,11 +755,11 @@ handle_el1_sync_excp(struct hypctx *hypctx, struct vm_exit *vme_ret,
 		case ISS_DATA_DFSC_PF_L1:
 		case ISS_DATA_DFSC_PF_L2:
 		case ISS_DATA_DFSC_PF_L3:
-			gpa = HPFAR_EL2_FIPA_ADDR(hypctx->exit_info.hpfar_el2);
+			gpa = HPFAR_EL2_FIPA_ADDR(hypctx_read_sys_reg(hypctx, HOST_HPFAR_EL2));
 			/* Check the IPA is valid */
 			if (gpa >= (1ul << vmm_max_ipa_bits)) {
 				raise_data_insn_abort(hypctx,
-				    hypctx->exit_info.far_el2,
+				    hypctx_read_sys_reg(hypctx, HOST_FAR_EL2),
 				    esr_ec == EXCP_DATA_ABORT_L,
 				    ISS_DATA_DFSC_ASF_L0);
 				vme_ret->inst_length = 0;
@@ -777,7 +777,7 @@ handle_el1_sync_excp(struct hypctx *hypctx, struct vm_exit *vme_ret,
 				 * not executable
 				 */
 				raise_data_insn_abort(hypctx,
-				    hypctx->exit_info.far_el2, false,
+				    hypctx_read_sys_reg(hypctx, HOST_FAR_EL2), false,
 				    ISS_DATA_DFSC_EXT);
 				vme_ret->inst_length = 0;
 				return (HANDLED);
@@ -1170,7 +1170,7 @@ vmmops_run(void *vcpui, register_t pc, pmap_t pmap, struct vm_eventinfo *evinfo)
 
 		/* Activate the stage2 pmap so the vmid is valid */
 		pmap_activate_vm(pmap);
-		hypctx->vttbr_el2 = pmap_to_ttbr0(pmap);
+		hypctx_write_sys_reg(hypctx, HOST_VTTBR_EL2, pmap_to_ttbr0(pmap));
 
 		/*
 		 * TODO: What happens if a timer interrupt is asserted exactly
@@ -1199,8 +1199,8 @@ vmmops_run(void *vcpui, register_t pc, pmap_t pmap, struct vm_eventinfo *evinfo)
 		vme->inst_length = INSN_SIZE;
 		vme->u.hyp.exception_nr = excp_type;
 		vme->u.hyp.esr_el2 = hypctx->tf.tf_esr;
-		vme->u.hyp.far_el2 = hypctx->exit_info.far_el2;
-		vme->u.hyp.hpfar_el2 = hypctx->exit_info.hpfar_el2;
+		vme->u.hyp.far_el2 = hypctx_read_sys_reg(hypctx, HOST_FAR_EL2);
+		vme->u.hyp.hpfar_el2 = hypctx_read_sys_reg(hypctx, HOST_HPFAR_EL2);
 
 		handled = arm64_handle_world_switch(hypctx, excp_type, vme,
 		    pmap);
@@ -1290,7 +1290,7 @@ hypctx_regptr(struct hypctx *hypctx, int reg)
 	case VM_REG_GUEST_TCR2_EL1:
 		return hypctx_sys_reg(hypctx, TCR2_EL1);
 	case VM_REG_GUEST_MPIDR_EL1:
-		return (&hypctx->vmpidr_el2);
+		return hypctx_sys_reg(hypctx, HOST_VMPIDR_EL2);
 	default:
 		break;
 	}
@@ -1393,9 +1393,9 @@ vmmops_setcap(void *vcpui, int num, int val)
 		if ((val != 0) == ((hypctx->setcaps & (1ul << num)) != 0))
 			break;
 		if (val != 0)
-			hypctx->mdcr_el2 |= MDCR_EL2_TDE;
+			*hypctx_sys_reg(hypctx, HOST_MDCR_EL2) |= MDCR_EL2_TDE;
 		else if ((hypctx->setcaps & (1ul << VM_CAP_SS_EXIT)) == 0)
-			hypctx->mdcr_el2 &= ~MDCR_EL2_TDE;
+			*hypctx_sys_reg(hypctx, HOST_MDCR_EL2) &= ~MDCR_EL2_TDE;
 		break;
 	case VM_CAP_SS_EXIT:
 		if ((val != 0) == ((hypctx->setcaps & (1ul << num)) != 0))
@@ -1408,7 +1408,7 @@ vmmops_setcap(void *vcpui, int num, int val)
 
 			hypctx->tf.tf_spsr |= PSR_SS;
 			*hypctx_sys_reg(hypctx, MDSCR_EL1) |= MDSCR_SS;
-			hypctx->mdcr_el2 |= MDCR_EL2_TDE;
+			*hypctx_sys_reg(hypctx, HOST_MDCR_EL2) |= MDCR_EL2_TDE;
 		} else {
 			hypctx->tf.tf_spsr &= ~PSR_SS;
 			hypctx->tf.tf_spsr |= hypctx->debug_spsr;
@@ -1417,7 +1417,7 @@ vmmops_setcap(void *vcpui, int num, int val)
 			*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;
+				*hypctx_sys_reg(hypctx, HOST_MDCR_EL2) &= ~MDCR_EL2_TDE;
 		}
 		break;
 	case VM_CAP_MASK_HWINTR:
diff --git a/sys/arm64/vmm/vmm_hyp.c b/sys/arm64/vmm/vmm_hyp.c
index 070142199c44..ffc51f243dcd 100644
--- a/sys/arm64/vmm/vmm_hyp.c
+++ b/sys/arm64/vmm/vmm_hyp.c
@@ -167,7 +167,8 @@ vmm_hyp_reg_store_pmu_debug(struct hypctx *hypctx, bool guest)
 	}
 
 	if (!guest)
-		hypctx->mdcr_el2 = READ_SPECIALREG(mdcr_el2);
+		hypctx_write_sys_reg(hypctx, HOST_MDCR_EL2,
+		    READ_SPECIALREG(mdcr_el2));
 }
 
 static void
@@ -272,8 +273,10 @@ vmm_hyp_reg_store_special(struct hypctx *hypctx, struct hyp *hyp, bool guest)
 
 	if (guest) {
 		hypctx->tf.tf_esr = READ_SPECIALREG(esr_el2);
-		hypctx->exit_info.far_el2 = READ_SPECIALREG(far_el2);
-		hypctx_write_sys_reg(hypctx, PAR_EL1, READ_SPECIALREG(par_el1));
+		hypctx_write_sys_reg(hypctx, HOST_FAR_EL2,
+		    READ_SPECIALREG(far_el2));
+		hypctx_write_sys_reg(hypctx,
+		    PAR_EL1, READ_SPECIALREG(par_el1));
 	}
 
 	/* Store the guest special registers */
@@ -322,16 +325,19 @@ vmm_hyp_reg_store_special(struct hypctx *hypctx, struct hyp *hyp, bool guest)
 		    READ_SPECIALREG(EL1_REG(TTBR1)));
 	}
 
-	hypctx->cptr_el2 = READ_SPECIALREG(cptr_el2);
-	hypctx->hcr_el2 = READ_SPECIALREG(hcr_el2);
-	hypctx->vpidr_el2 = READ_SPECIALREG(vpidr_el2);
-	hypctx->vmpidr_el2 = READ_SPECIALREG(vmpidr_el2);
+	hypctx_write_sys_reg(hypctx, HOST_CPTR_EL2,
+	    READ_SPECIALREG(cptr_el2));
+	hypctx_write_sys_reg(hypctx, HOST_HCR_EL2,
+	    READ_SPECIALREG(hcr_el2));
+	hypctx_write_sys_reg(hypctx, HOST_VPIDR_EL2,
+	    READ_SPECIALREG(vpidr_el2));
+	hypctx_write_sys_reg(hypctx, HOST_VMPIDR_EL2,
+	    READ_SPECIALREG(vmpidr_el2));
 
 #ifndef VMM_VHE
-	if (!guest) {
-		if ((hyp->feats & HYP_FEAT_HCX) != 0)
-			hypctx->hcrx_el2 =
-				READ_SPECIALREG(MRS_REG_ALT_NAME(HCRX_EL2));
+	if (!guest && ((hyp->feats & HYP_FEAT_HCX) != 0)) {
+		hypctx_write_sys_reg(hypctx, HOST_HCRX_EL2,
+		    READ_SPECIALREG(MRS_REG_ALT_NAME(HCRX_EL2)));
 	}
 #endif
 }
@@ -339,11 +345,11 @@ vmm_hyp_reg_store_special(struct hypctx *hypctx, struct hyp *hyp, bool guest)
 static void
 vmm_hyp_reg_restore_special(struct hypctx *hypctx, struct hyp *hyp, bool guest)
 {
-	WRITE_SPECIALREG(hcr_el2, hypctx->hcr_el2);
+	WRITE_SPECIALREG(hcr_el2, hypctx_read_sys_reg(hypctx, HOST_HCR_EL2));
 
-	if (guest_or_nonvhe(guest)) {
-		if ((hyp->feats & HYP_FEAT_HCX) != 0)
-			WRITE_SPECIALREG(HCRX_EL2_REG, hypctx->hcrx_el2);
+	if (guest_or_nonvhe(guest) && ((hyp->feats & HYP_FEAT_HCX) != 0)) {
+		WRITE_SPECIALREG(HCRX_EL2_REG,
+		    hypctx_read_sys_reg(hypctx, HOST_HCRX_EL2));
 	}
 
 	isb();
@@ -352,20 +358,27 @@ vmm_hyp_reg_restore_special(struct hypctx *hypctx, struct hyp *hyp, bool guest)
 	if (guest) {
 		/* Fine-grained trap controls */
 		if ((hyp->feats & HYP_FEAT_FGT) != 0) {
-			WRITE_SPECIALREG(HDFGWTR_EL2_REG, hypctx->hdfgwtr_el2);
-			WRITE_SPECIALREG(HFGITR_EL2_REG, hypctx->hfgitr_el2);
-			WRITE_SPECIALREG(HFGRTR_EL2_REG, hypctx->hfgrtr_el2);
-			WRITE_SPECIALREG(HFGWTR_EL2_REG, hypctx->hfgwtr_el2);
+			WRITE_SPECIALREG(HDFGWTR_EL2_REG,
+			    hypctx_read_sys_reg(hypctx, HOST_HDFGWTR_EL2));
+			WRITE_SPECIALREG(HFGITR_EL2_REG,
+			    hypctx_read_sys_reg(hypctx, HOST_HFGITR_EL2));
+			WRITE_SPECIALREG(HFGRTR_EL2_REG,
+			    hypctx_read_sys_reg(hypctx, HOST_HFGRTR_EL2));
+			WRITE_SPECIALREG(HFGWTR_EL2_REG,
+			    hypctx_read_sys_reg(hypctx, HOST_HFGWTR_EL2));
 		}
 
 		if ((hyp->feats & HYP_FEAT_FGT2) != 0) {
 			WRITE_SPECIALREG(HDFGRTR2_EL2_REG,
-			    hypctx->hdfgrtr2_el2);
+			    hypctx_read_sys_reg(hypctx, HOST_HDFGRTR2_EL2));
 			WRITE_SPECIALREG(HDFGWTR2_EL2_REG,
-			    hypctx->hdfgwtr2_el2);
-			WRITE_SPECIALREG(HFGITR2_EL2_REG, hypctx->hfgitr2_el2);
-			WRITE_SPECIALREG(HFGRTR2_EL2_REG, hypctx->hfgrtr2_el2);
-			WRITE_SPECIALREG(HFGWTR2_EL2_REG, hypctx->hfgwtr2_el2);
+			    hypctx_read_sys_reg(hypctx, HOST_HDFGWTR2_EL2));
+			WRITE_SPECIALREG(HFGITR2_EL2_REG,
+			    hypctx_read_sys_reg(hypctx, HOST_HFGITR2_EL2));
+			WRITE_SPECIALREG(HFGRTR2_EL2_REG,
+			    hypctx_read_sys_reg(hypctx, HOST_HFGRTR2_EL2));
+			WRITE_SPECIALREG(HFGWTR2_EL2_REG,
+			    hypctx_read_sys_reg(hypctx, HOST_HFGWTR2_EL2));
 		}
 	}
 #endif
@@ -418,9 +431,12 @@ vmm_hyp_reg_restore_special(struct hypctx *hypctx, struct hyp *hyp, bool guest)
 		WRITE_SPECIALREG(par_el1, hypctx_read_sys_reg(hypctx, PAR_EL1));
 	}
 
-	WRITE_SPECIALREG(cptr_el2, hypctx->cptr_el2);
-	WRITE_SPECIALREG(vpidr_el2, hypctx->vpidr_el2);
-	WRITE_SPECIALREG(vmpidr_el2, hypctx->vmpidr_el2);
+	WRITE_SPECIALREG(cptr_el2,
+	    hypctx_read_sys_reg(hypctx, HOST_CPTR_EL2));
+	WRITE_SPECIALREG(vpidr_el2,
+	    hypctx_read_sys_reg(hypctx, HOST_VPIDR_EL2));
+	WRITE_SPECIALREG(vmpidr_el2,
+	    hypctx_read_sys_reg(hypctx, HOST_VMPIDR_EL2));
 
 	/* Load the special regs from the trapframe */
 	WRITE_SPECIALREG(sp_el1, hypctx->tf.tf_sp);
@@ -710,18 +726,18 @@ vmm_hyp_handle_guest_exit(struct hypctx *hypctx, uint64_t *ret)
 		}
 	}
 	if (hpfar_valid) {
-		hypctx->exit_info.hpfar_el2 = READ_SPECIALREG(hpfar_el2);
+		hypctx_write_sys_reg(hypctx, HOST_HPFAR_EL2, READ_SPECIALREG(hpfar_el2));
 	} else {
 		/*
 		 * TODO: There is a risk the at instruction could cause an
 		 * exception here. We should handle it & return a failure.
 		 */
 		s1e1r =
-		    arm64_address_translate_s1e1r(hypctx->exit_info.far_el2);
+		    arm64_address_translate_s1e1r(hypctx_read_sys_reg(hypctx, HOST_FAR_EL2));
 		if (PAR_SUCCESS(s1e1r)) {
 			hpfar_el2 = (s1e1r & PAR_PA_MASK) >> PAR_PA_SHIFT;
 			hpfar_el2 <<= HPFAR_EL2_FIPA_SHIFT;
-			hypctx->exit_info.hpfar_el2 = hpfar_el2;
+			hypctx_write_sys_reg(hypctx, HOST_HPFAR_EL2, hpfar_el2);
 		} else {
 			*ret = EXCP_TYPE_REENTER;
 		}
@@ -733,11 +749,11 @@ static uint64_t
 __vmm_hyp_call_guest(struct hypctx *hypctx, struct hypctx *host_hypctx)
 {
 	uint64_t ret;
-	WRITE_SPECIALREG(vttbr_el2, hypctx->vttbr_el2);
-	WRITE_SPECIALREG(mdcr_el2, hypctx->mdcr_el2);
+	WRITE_SPECIALREG(vttbr_el2, hypctx_read_sys_reg(hypctx, HOST_VTTBR_EL2));
+	WRITE_SPECIALREG(mdcr_el2, hypctx_read_sys_reg(hypctx, HOST_MDCR_EL2));
 	/* Call into the guest */
 	ret = VMM_HYP_FUNC(do_call_guest)(hypctx);
-	WRITE_SPECIALREG(mdcr_el2, host_hypctx->mdcr_el2);
+	WRITE_SPECIALREG(mdcr_el2, hypctx_read_sys_reg(host_hypctx, HOST_MDCR_EL2));
 
 	isb();
 
diff --git a/sys/arm64/vmm/vmm_reset.c b/sys/arm64/vmm/vmm_reset.c
index 1280fe64277a..1beea0fdbc53 100644
--- a/sys/arm64/vmm/vmm_reset.c
+++ b/sys/arm64/vmm/vmm_reset.c
@@ -97,23 +97,27 @@ reset_vm_el2_regs(void *vcpu)
 	 * invalidate
 	 * HCR_VM: use stage 2 translation
 	 */
-	el2ctx->hcr_el2 = HCR_RW | HCR_TID3 | HCR_TWI | HCR_BSU_IS | HCR_FB |
-	    HCR_AMO | HCR_IMO | HCR_FMO | HCR_SWIO | HCR_VM;
+	hypctx_write_sys_reg(el2ctx, HOST_HCR_EL2,
+	    HCR_RW | HCR_TID3 | HCR_TWI | HCR_BSU_IS | HCR_FB | HCR_AMO |
+	    HCR_IMO | HCR_FMO | HCR_SWIO | HCR_VM);
+
 	if (in_vhe()) {
-		el2ctx->hcr_el2 |= HCR_E2H;
+		*hypctx_sys_reg(el2ctx, HOST_HCR_EL2) |= HCR_E2H;
 	}
 
 	/* Set the Extended Hypervisor Configuration Register */
-	el2ctx->hcrx_el2 = 0;
+	hypctx_write_sys_reg(el2ctx, HOST_HCRX_EL2, 0);
 	/* TODO: Trap all extensions we don't support */
-	el2ctx->mdcr_el2 = MDCR_EL2_TDOSA | MDCR_EL2_TDRA | MDCR_EL2_TPMS |
-	    MDCR_EL2_TTRF;
+	hypctx_write_sys_reg(el2ctx, HOST_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 |= (hypctx_read_sys_reg(el2ctx, PMCR_EL0) & PMCR_N_MASK) >> PMCR_N_SHIFT;
+	*hypctx_sys_reg(el2ctx, HOST_MDCR_EL2) |=
+	    (hypctx_read_sys_reg(el2ctx, PMCR_EL0) & PMCR_N_MASK) >> PMCR_N_SHIFT;
 
-	el2ctx->vmpidr_el2 = VMPIDR_EL2_RES1;
+	hypctx_write_sys_reg(el2ctx, HOST_VMPIDR_EL2, VMPIDR_EL2_RES1);
 	/* The guest will detect a multi-core, single-threaded CPU */
-	el2ctx->vmpidr_el2 &= ~VMPIDR_EL2_U & ~VMPIDR_EL2_MT;
+	*hypctx_sys_reg(el2ctx, HOST_VMPIDR_EL2) &=
+	    ~VMPIDR_EL2_U & ~VMPIDR_EL2_MT;
 	/*
 	 * Generate the guest MPIDR value. We only support 16 CPUs at affinity
 	 * level 0 to simplify the vgicv3 driver (see writing sgi1r_el1).
@@ -122,24 +126,28 @@ reset_vm_el2_regs(void *vcpu)
 	    ((vcpuid >> 4) & 0xff) << MPIDR_AFF1_SHIFT |
 	    ((vcpuid >> 12) & 0xff) << MPIDR_AFF2_SHIFT |
 	    ((vcpuid >> 20) & 0xff) << MPIDR_AFF3_SHIFT;
-	el2ctx->vmpidr_el2 |= cpu_aff;
+	*hypctx_sys_reg(el2ctx, HOST_VMPIDR_EL2) |= cpu_aff;
 
 	/* Use the same CPU identification information as the host */
-	el2ctx->vpidr_el2 = CPU_IMPL_TO_MIDR(CPU_IMPL_ARM);
-	el2ctx->vpidr_el2 |= CPU_VAR_TO_MIDR(0);
-	el2ctx->vpidr_el2 |= CPU_ARCH_TO_MIDR(0xf);
-	el2ctx->vpidr_el2 |= CPU_PART_TO_MIDR(CPU_PART_FOUNDATION);
-	el2ctx->vpidr_el2 |= CPU_REV_TO_MIDR(0);
+	hypctx_write_sys_reg(el2ctx, HOST_VPIDR_EL2,
+	    CPU_IMPL_TO_MIDR(CPU_IMPL_ARM));
+	*hypctx_sys_reg(el2ctx, HOST_VPIDR_EL2) |= CPU_VAR_TO_MIDR(0);
+	*hypctx_sys_reg(el2ctx, HOST_VPIDR_EL2) |= CPU_ARCH_TO_MIDR(0xf);
+	*hypctx_sys_reg(el2ctx, HOST_VPIDR_EL2) |= CPU_PART_TO_MIDR(
+	    CPU_PART_FOUNDATION);
+	*hypctx_sys_reg(el2ctx, HOST_VPIDR_EL2) |= CPU_REV_TO_MIDR(0);
 
 	/*
 	 * Don't trap accesses to CPACR_EL1, trace, SVE, Advanced SIMD
 	 * and floating point functionality to EL2.
 	 */
 	if (in_vhe())
-		el2ctx->cptr_el2 = CPTR_E2H_TRAP_ALL | CPTR_E2H_FPEN;
+		hypctx_write_sys_reg(el2ctx, HOST_CPTR_EL2,
+		    CPTR_E2H_TRAP_ALL | CPTR_E2H_FPEN);
 	else
-		el2ctx->cptr_el2 = CPTR_TRAP_ALL & ~CPTR_TFP;
-	el2ctx->cptr_el2 &= ~CPTR_TCPAC;
+		hypctx_write_sys_reg(el2ctx, HOST_CPTR_EL2,
+		    CPTR_TRAP_ALL & ~CPTR_TFP);
+	*hypctx_sys_reg(el2ctx, HOST_CPTR_EL2) &= ~CPTR_TCPAC;
 	/*
 	 * Disable interrupts in the guest. The guest OS will re-enable
 	 * them.
@@ -150,325 +158,361 @@ reset_vm_el2_regs(void *vcpu)
 
 	/* FEAT_FGT traps */
 	if ((el2ctx->hyp->feats & HYP_FEAT_FGT) != 0) {
-#define	HFGT_TRAP_FIELDS(read, write, read_pfx, write_pfx, name, trap)	\
-do {									\
-	el2ctx->read |= read_pfx ## _EL2_ ## name ## _ ## trap;		\
-	el2ctx->write |= write_pfx ## _EL2_ ## name ## _ ## trap;	\
-} while (0)
-
+#define HFGT_TRAP_FIELDS(read, write, read_pfx, write_pfx, name, trap)	\
+	do {								\
+		*hypctx_sys_reg(el2ctx,					\
+		    read) |= read_pfx##_EL2_##name##_##trap;		\
+		*hypctx_sys_reg(el2ctx,					\
+		    write) |= write_pfx##_EL2_##name##_##trap;		\
+	} while (0)
 
 		/*
 		 * Traps for special registers
 		 */
 
 		/* Debug registers */
-		el2ctx->hdfgrtr_el2 = 0;
-		el2ctx->hdfgwtr_el2 = 0;
+		hypctx_write_sys_reg(el2ctx, HOST_HDFGRTR_EL2, 0);
+		hypctx_write_sys_reg(el2ctx, HOST_HDFGWTR_EL2, 0);
 
 		/* FEAT_BRBE */
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    nBRBDATA, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    nBRBCTL, TRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_nBRBIDR_TRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, nBRBDATA, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, nBRBCTL, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_nBRBIDR_TRAP;
 
 		/* FEAT_TRBE */
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRBTRG_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRBSR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRBPTR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRBMAR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRBLIMITR_EL1, TRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_TRBIDR_EL1_TRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRBBASER_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRBTRG_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRBSR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRBPTR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRBMAR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRBLIMITR_EL1, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_TRBIDR_EL1_TRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRBBASER_EL1, TRAP);
 
 		/* FEAT_TRF */
-		el2ctx->hdfgwtr_el2 |= HDFGWTR_EL2_TRFCR_EL1_TRAP;
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGWTR_EL2) |= HDFGWTR_EL2_TRFCR_EL1_TRAP;
 
 		/* FEAT_ETE */
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRCVICTLR, TRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_TRCSTATR_TRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRCSSCSRn, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRCSEQSTR, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRCPRGCTLR, TRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_TRCOSLSR_TRAP;
-		el2ctx->hdfgwtr_el2 |= HDFGWTR_EL2_TRCOSLAR_TRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRCIMSPECn, TRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_TRCID_TRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRCCNTVRn, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRCCLAIM, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRCAUXCTLR, TRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_TRCAUTHSTATUS_TRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    TRC, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMSLATFR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMSIRR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRCVICTLR, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_TRCSTATR_TRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRCSSCSRn, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRCSEQSTR, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRCPRGCTLR, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_TRCOSLSR_TRAP;
+
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGWTR_EL2) |= HDFGWTR_EL2_TRCOSLAR_TRAP;
+
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRCIMSPECn, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_TRCID_TRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRCCNTVRn, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRCCLAIM, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRCAUXCTLR, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_TRCAUTHSTATUS_TRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, TRC, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMSLATFR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMSIRR_EL1, TRAP);
 
 		/* FEAT_SPE */
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_PMBIDR_EL1_TRAP;
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_PMSIDR_EL1_TRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMSICR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMSFCR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMSEVFR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMSCR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMBSR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMBPTR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMBLIMITR_EL1, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_PMBIDR_EL1_TRAP;
+
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_PMSIDR_EL1_TRAP;
+
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMSICR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMSFCR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMSEVFR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMSCR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMBSR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMBPTR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMBLIMITR_EL1, TRAP);
 
 		/* FEAT_SPE_FnE */
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    nPMSNEVFR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, nPMSNEVFR_EL1, TRAP);
 
 		/* FEAT_PMUv3 */
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_PMCEIDn_EL0_NOTRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMUSERENR_EL0, NOTRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_PMMIR_EL1_NOTRAP;
-		el2ctx->hdfgwtr_el2 |= HDFGWTR_EL2_PMCR_EL0_NOTRAP;
-		el2ctx->hdfgwtr_el2 |= HDFGWTR_EL2_PMSWINC_EL0_NOTRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMSELR_EL0, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMOVS, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMINTEN, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMCNTEN, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMCCNTR_EL0, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMCCFILTR_EL0, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMEVTYPERn_EL0, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    PMEVCNTRn_EL0, NOTRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_PMCEIDn_EL0_NOTRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMUSERENR_EL0, NOTRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_PMMIR_EL1_NOTRAP;
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGWTR_EL2) |= HDFGWTR_EL2_PMCR_EL0_NOTRAP;
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGWTR_EL2) |= HDFGWTR_EL2_PMSWINC_EL0_NOTRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMSELR_EL0, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMOVS, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMINTEN, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMCNTEN, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMCCNTR_EL0, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMCCFILTR_EL0, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMEVTYPERn_EL0, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, PMEVCNTRn_EL0, NOTRAP);
 
 		/* FEAT_DoubleLock */
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    OSDLR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, OSDLR_EL1, TRAP);
 
 		/* Base architecture */
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    OSECCR_EL1, NOTRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_OSLSR_EL1_NOTRAP;
-		el2ctx->hdfgwtr_el2 |= HDFGWTR_EL2_OSLAR_EL1_NOTRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    DBGPRCR_EL1, NOTRAP);
-		el2ctx->hdfgrtr_el2 |= HDFGRTR_EL2_DBGAUTHSTATUS_EL1_NOTRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    DBGCLAIM, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    MDSCR_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    DBGWVRn_EL1, NOTRAP);
-		el2ctx->hdfgwtr_el2 |= HDFGWTR_EL2_DBGWCRn_EL1_NOTRAP;
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    DBGBVRn_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hdfgrtr_el2, hdfgwtr_el2, HDFGRTR, HDFGWTR,
-		    DBGBCRn_EL1, NOTRAP);
-
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, OSECCR_EL1, NOTRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_OSLSR_EL1_NOTRAP;
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGWTR_EL2) |= HDFGWTR_EL2_OSLAR_EL1_NOTRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, DBGPRCR_EL1, NOTRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGRTR_EL2) |= HDFGRTR_EL2_DBGAUTHSTATUS_EL1_NOTRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, DBGCLAIM, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, MDSCR_EL1, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, DBGWVRn_EL1, NOTRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HDFGWTR_EL2) |= HDFGWTR_EL2_DBGWCRn_EL1_NOTRAP;
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, DBGBVRn_EL1, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HDFGRTR_EL2, HOST_HDFGWTR_EL2, HDFGRTR,
+		    HDFGWTR, DBGBCRn_EL1, NOTRAP);
 
 		/* Non-debug special registers */
-		el2ctx->hfgrtr_el2 = 0;
-		el2ctx->hfgwtr_el2 = 0;
+		*hypctx_sys_reg(el2ctx, HOST_HFGRTR_EL2) = 0;
+		*hypctx_sys_reg(el2ctx, HOST_HFGWTR_EL2) = 0;
 
 		/* FEAT_AIE */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nAMAIR2_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nMAIR2_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nAMAIR2_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nMAIR2_EL1, TRAP);
 
 		/* FEAT_S2POE */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nS2POR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nS2POR_EL1, TRAP);
 
 		/* FEAT_S1POE */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nPOR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nPOR_EL0, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nPOR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nPOR_EL0, TRAP);
 
 		/* FEAT_S1PIE */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nPIR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nPIRE0_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nPIR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nPIRE0_EL1, TRAP);
 
 		/* FEAT_THE */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nRCWMASK_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nRCWMASK_EL1, TRAP);
 
 		/* FEAT_SME */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nTPIDR2_EL0, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nSMPRI_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nTPIDR2_EL0, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nSMPRI_EL1, TRAP);
 
 		/* FEAT_GCS */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nGCS_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nGCS_EL0, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nGCS_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nGCS_EL0, TRAP);
 
 		/* FEAT_LS64_ACCDATA */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    nACCDATA_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, nACCDATA_EL1, TRAP);
 
 		/* FEAT_RASv1p1 */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ERXPFGCDN_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ERXPFGCTL_EL1, TRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_ERXPFGF_EL1_TRAP;
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, ERXPFGCDN_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, ERXPFGCTL_EL1, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HFGRTR_EL2) |= HFGRTR_EL2_ERXPFGF_EL1_TRAP;
 
 		/* FEAT_RAS */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ERXADDR_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ERXMISCn_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ERXSTATUS_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ERXCTLR_EL1, TRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_ERXFR_EL1_TRAP;
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ERRSELR_EL1, TRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_ERRIDR_EL1_TRAP;
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, ERXADDR_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, ERXMISCn_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, ERXSTATUS_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, ERXCTLR_EL1, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HFGRTR_EL2) |= HFGRTR_EL2_ERXFR_EL1_TRAP;
+
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, ERRSELR_EL1, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HFGRTR_EL2) |= HFGRTR_EL2_ERRIDR_EL1_TRAP;
 
 		/* GICv3 */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ICC_IGRPENn_EL1, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, ICC_IGRPENn_EL1, NOTRAP);
 
 		/* FEAT_LOR */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    LORSA_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    LORN_EL1, TRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_LORID_EL1_TRAP;
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    LOREA_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    LORC_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, LORSA_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, LORN_EL1, TRAP);
+		*hypctx_sys_reg(el2ctx,
+		    HOST_HFGRTR_EL2) |= HFGRTR_EL2_LORID_EL1_TRAP;
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, LOREA_EL1, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, LORC_EL1, TRAP);
 
 		/* FEAT_PAuth */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    APIBKey, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    APIAKey, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    APGAKey, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    APDBKey, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    APDAKey, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, APIBKey, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, APIAKey, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, APGAKey, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, APDBKey, TRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
+		    HFGWTR, APDAKey, TRAP);
 
 		/* Base architecture */
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    VBAR_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    TTBR1_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    TTBR0_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    TPIDR_EL0, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    TPIDRRO_EL0, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    TPIDR_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    TCR_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    SCXTNUM_EL0, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    SCXTNUM_EL1, TRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    SCTLR_EL1, NOTRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_REVIDR_EL1_NOTRAP;
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    PAR_EL1, NOTRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_MPIDR_EL1_NOTRAP;
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_MIDR_EL1_NOTRAP;
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    MAIR_EL1, NOTRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_ISR_EL1_NOTRAP;
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    FAR_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    ESR_EL1, NOTRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_DCZID_EL0_NOTRAP;
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_CTR_EL0_NOTRAP;
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    CSSELR_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    CPACR_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    CONTEXTIDR_EL1, NOTRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_CLIDR_EL1_NOTRAP;
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_CCSIDR_EL1_NOTRAP;
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    AMAIR_EL1, NOTRAP);
-		el2ctx->hfgrtr_el2 |= HFGRTR_EL2_AIDR_EL1_NOTRAP;
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    AFSR1_EL1, NOTRAP);
-		HFGT_TRAP_FIELDS(hfgrtr_el2, hfgwtr_el2, HFGRTR, HFGWTR,
-		    AFSR0_EL1, NOTRAP);
+		HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
*** 173 LINES SKIPPED ***