mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
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 <[email protected]> Reviewed by: andrew Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D56555
This commit is contained in:
1 parent
f4c3458ab3
commit
ee2642678a
5 files changed
+410
-356
No files matched your search
+32
-38
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
+13
-13
@@ -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:
|
||||
|
||||
+49
-33
@@ -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();
|
||||
|
||||
|
||||
+313
-269
@@ -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,
|
||||
HFGWTR, VBAR_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, TTBR1_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, TTBR0_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, TPIDR_EL0, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, TPIDRRO_EL0, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, TPIDR_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, TCR_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, SCXTNUM_EL0, TRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, SCXTNUM_EL1, TRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, SCTLR_EL1, NOTRAP);
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_REVIDR_EL1_NOTRAP;
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, PAR_EL1, NOTRAP);
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_MPIDR_EL1_NOTRAP;
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_MIDR_EL1_NOTRAP;
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, MAIR_EL1, NOTRAP);
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_ISR_EL1_NOTRAP;
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, FAR_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, ESR_EL1, NOTRAP);
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_DCZID_EL0_NOTRAP;
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_CTR_EL0_NOTRAP;
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, CSSELR_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, CPACR_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, CONTEXTIDR_EL1, NOTRAP);
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_CLIDR_EL1_NOTRAP;
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_CCSIDR_EL1_NOTRAP;
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, AMAIR_EL1, NOTRAP);
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGRTR_EL2) |= HFGRTR_EL2_AIDR_EL1_NOTRAP;
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, AFSR1_EL1, NOTRAP);
|
||||
HFGT_TRAP_FIELDS(HOST_HFGRTR_EL2, HOST_HFGWTR_EL2, HFGRTR,
|
||||
HFGWTR, AFSR0_EL1, NOTRAP);
|
||||
|
||||
/*
|
||||
* Traps for instructions
|
||||
*/
|
||||
|
||||
/* Enable all TLBI, cache and AT variants */
|
||||
el2ctx->hfgitr_el2 = 0;
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) = 0;
|
||||
|
||||
/* FEAT_ATS1A */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
HFGITR_EL2_ATS1E1A_TRAP;
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGITR_EL2) |= HFGITR_EL2_ATS1E1A_TRAP;
|
||||
|
||||
/* FEAT_SPECRES2 */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
HFGITR_EL2_COSPRCTX_TRAP;
|
||||
*hypctx_sys_reg(el2ctx,
|
||||
HOST_HFGITR_EL2) |= HFGITR_EL2_COSPRCTX_TRAP;
|
||||
|
||||
/* FEAT_GCS */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_nGCSEPP_TRAP |
|
||||
HFGITR_EL2_nGCSSTR_EL1_TRAP |
|
||||
HFGITR_EL2_nGCSPUSHM_EL1_TRAP;
|
||||
|
||||
/* FEAT_BRBE */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_nBRBIALL_TRAP |
|
||||
HFGITR_EL2_nBRBINJ_TRAP;
|
||||
|
||||
/* FEAT_SPECRES */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_CPPRCTX_TRAP |
|
||||
HFGITR_EL2_DVPRCTX_TRAP |
|
||||
HFGITR_EL2_CFPRCTX_TRAP;
|
||||
|
||||
/* FEAT_TLBIRANGE */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_TLBIRVAALE1_TRAP |
|
||||
HFGITR_EL2_TLBIRVALE1_TRAP |
|
||||
HFGITR_EL2_TLBIRVAAE1_TRAP |
|
||||
@@ -479,14 +523,14 @@ do { \
|
||||
HFGITR_EL2_TLBIRVAE1IS_TRAP;
|
||||
|
||||
/* FEAT_TLBIRANGE && FEAT_TLBIOS */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_TLBIRVAALE1OS_TRAP |
|
||||
HFGITR_EL2_TLBIRVALE1OS_TRAP |
|
||||
HFGITR_EL2_TLBIRVAAE1OS_TRAP |
|
||||
HFGITR_EL2_TLBIRVAE1OS_TRAP;
|
||||
|
||||
/* FEAT_TLBIOS */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_TLBIVAALE1OS_TRAP |
|
||||
HFGITR_EL2_TLBIVALE1OS_TRAP |
|
||||
HFGITR_EL2_TLBIVAAE1OS_TRAP |
|
||||
@@ -495,22 +539,22 @@ do { \
|
||||
HFGITR_EL2_TLBIVMALLE1OS_TRAP;
|
||||
|
||||
/* FEAT_PAN2 */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_ATS1E1WP_TRAP |
|
||||
HFGITR_EL2_ATS1E1RP_TRAP;
|
||||
|
||||
/* FEAT_DPB2 */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_DCCVADP_TRAP;
|
||||
|
||||
/* Base architecture */
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_DCCVAC_NOTRAP |
|
||||
HFGITR_EL2_SVC_EL1_NOTRAP |
|
||||
HFGITR_EL2_SVC_EL0_NOTRAP |
|
||||
HFGITR_EL2_ERET_NOTRAP;
|
||||
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_TLBIVAALE1_NOTRAP |
|
||||
HFGITR_EL2_TLBIVALE1_NOTRAP |
|
||||
HFGITR_EL2_TLBIVAAE1_NOTRAP |
|
||||
@@ -524,7 +568,7 @@ do { \
|
||||
HFGITR_EL2_TLBIVAE1IS_NOTRAP |
|
||||
HFGITR_EL2_TLBIVMALLE1IS_NOTRAP;
|
||||
|
||||
el2ctx->hfgitr_el2 |=
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR_EL2) |=
|
||||
HFGITR_EL2_ATS1E0W_NOTRAP |
|
||||
HFGITR_EL2_ATS1E0R_NOTRAP |
|
||||
HFGITR_EL2_ATS1E1W_NOTRAP |
|
||||
@@ -546,10 +590,10 @@ do { \
|
||||
/* FEAT_FGT2 traps */
|
||||
if ((el2ctx->hyp->feats & HYP_FEAT_FGT2) != 0) {
|
||||
/* Trap everything here until we support the feature */
|
||||
el2ctx->hdfgrtr2_el2 = 0;
|
||||
el2ctx->hdfgwtr2_el2 = 0;
|
||||
el2ctx->hfgitr2_el2 = 0;
|
||||
el2ctx->hfgrtr2_el2 = 0;
|
||||
el2ctx->hfgwtr2_el2 = 0;
|
||||
*hypctx_sys_reg(el2ctx, HOST_HDFGRTR2_EL2) = 0;
|
||||
*hypctx_sys_reg(el2ctx, HOST_HDFGWTR2_EL2) = 0;
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGITR2_EL2) = 0;
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGRTR2_EL2) = 0;
|
||||
*hypctx_sys_reg(el2ctx, HOST_HFGWTR2_EL2) = 0;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user