diff options
| author | Andrew Turner <andrew@FreeBSD.org> | 2026-02-03 17:14:44 +0000 |
|---|---|---|
| committer | Andrew Turner <andrew@FreeBSD.org> | 2026-02-03 17:14:44 +0000 |
| commit | a4f0e93c514280bfd0ff3897e5171ec7bbe4796b (patch) | |
| tree | a726e2e02890137a3c15a8a954d32e00008defeb | |
| parent | 095a7871f4320e7667a644e6e34a27e1f526b053 (diff) | |
arm64/vmm: Set and use the fine-grained traps
Set the Fine-grained trap registers to trap any features we don't
support. These are expected to be more useful when we support nested
virtualisation, so for now just the base features and GICv3 are not
trapped.
As nested virtualisation will require VHE we only set the fine-grained
trap registers when VHE is used.
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D54687
| -rw-r--r-- | sys/arm64/vmm/arm64.h | 16 | ||||
| -rw-r--r-- | sys/arm64/vmm/vmm_hyp.c | 22 | ||||
| -rw-r--r-- | sys/arm64/vmm/vmm_reset.c | 405 |
3 files changed, 443 insertions, 0 deletions
diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h index 1b8762545925..6062d1c07ae4 100644 --- a/sys/arm64/vmm/arm64.h +++ b/sys/arm64/vmm/arm64.h @@ -100,6 +100,22 @@ struct hypctx { uint64_t mdcr_el2; /* Monitor Debug Configuration Register */ uint64_t vpidr_el2; /* Virtualization Processor ID Register */ uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID 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 el2_addr; /* The address of this in el2 space */ struct hyp *hyp; struct vcpu *vcpu; diff --git a/sys/arm64/vmm/vmm_hyp.c b/sys/arm64/vmm/vmm_hyp.c index 0ad7930e9a87..75c15f06dd08 100644 --- a/sys/arm64/vmm/vmm_hyp.c +++ b/sys/arm64/vmm/vmm_hyp.c @@ -293,6 +293,28 @@ vmm_hyp_reg_restore(struct hypctx *hypctx, struct hyp *hyp, bool guest, } isb(); +#ifdef VMM_VHE + 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); + } + + if ((hyp->feats & HYP_FEAT_FGT2) != 0) { + WRITE_SPECIALREG(HDFGRTR2_EL2_REG, + hypctx->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); + } + } +#endif + WRITE_SPECIALREG(sp_el0, hypctx->sp_el0); WRITE_SPECIALREG(tpidr_el0, hypctx->tpidr_el0); WRITE_SPECIALREG(tpidrro_el0, hypctx->tpidrro_el0); diff --git a/sys/arm64/vmm/vmm_reset.c b/sys/arm64/vmm/vmm_reset.c index 06ac6dec5af8..fd3414ecd066 100644 --- a/sys/arm64/vmm/vmm_reset.c +++ b/sys/arm64/vmm/vmm_reset.c @@ -187,4 +187,409 @@ reset_vm_el2_regs(void *vcpu) el2ctx->tf.tf_spsr = PSR_D | PSR_A | PSR_I | PSR_F; /* Use the EL1 stack when taking exceptions to EL1 */ el2ctx->tf.tf_spsr |= PSR_M_EL1h; + + /* 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) + + + /* + * Traps for special registers + */ + + /* Debug registers */ + el2ctx->hdfgrtr_el2 = 0; + el2ctx->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; + + /* 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); + + /* FEAT_TRF */ + el2ctx->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); + + /* 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); + + /* FEAT_SPE_FnE */ + HFGT_TRAP_FIELDS(hdfgrtr_el2, 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); + + /* FEAT_DoubleLock */ + HFGT_TRAP_FIELDS(hdfgrtr_el2, 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); + + + /* Non-debug special registers */ + el2ctx->hfgrtr_el2 = 0; + el2ctx->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); + + /* FEAT_S2POE */ + HFGT_TRAP_FIELDS(hfgrtr_el2, 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); + + /* 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); + + /* FEAT_THE */ + HFGT_TRAP_FIELDS(hfgrtr_el2, 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); + + /* 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); + + /* FEAT_LS64_ACCDATA */ + HFGT_TRAP_FIELDS(hfgrtr_el2, 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; + + /* 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; + + /* GICv3 */ + HFGT_TRAP_FIELDS(hfgrtr_el2, 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); + + /* 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); + + /* 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); + + /* + * Traps for instructions + */ + + /* Enable all TLBI, cache and AT variants */ + el2ctx->hfgitr_el2 = 0; + + /* FEAT_ATS1A */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_ATS1E1A_TRAP; + + /* FEAT_SPECRES2 */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_COSPRCTX_TRAP; + + /* FEAT_GCS */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_nGCSEPP_TRAP | + HFGITR_EL2_nGCSSTR_EL1_TRAP | + HFGITR_EL2_nGCSPUSHM_EL1_TRAP; + + /* FEAT_BRBE */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_nBRBIALL_TRAP | + HFGITR_EL2_nBRBINJ_TRAP; + + /* FEAT_SPECRES */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_CPPRCTX_TRAP | + HFGITR_EL2_DVPRCTX_TRAP | + HFGITR_EL2_CFPRCTX_TRAP; + + /* FEAT_TLBIRANGE */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_TLBIRVAALE1_TRAP | + HFGITR_EL2_TLBIRVALE1_TRAP | + HFGITR_EL2_TLBIRVAAE1_TRAP | + HFGITR_EL2_TLBIRVAE1_TRAP | + HFGITR_EL2_TLBIRVAALE1IS_TRAP | + HFGITR_EL2_TLBIRVALE1IS_TRAP | + HFGITR_EL2_TLBIRVAAE1IS_TRAP | + HFGITR_EL2_TLBIRVAE1IS_TRAP; + + /* FEAT_TLBIRANGE && FEAT_TLBIOS */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_TLBIRVAALE1OS_TRAP | + HFGITR_EL2_TLBIRVALE1OS_TRAP | + HFGITR_EL2_TLBIRVAAE1OS_TRAP | + HFGITR_EL2_TLBIRVAE1OS_TRAP; + + /* FEAT_TLBIOS */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_TLBIVAALE1OS_TRAP | + HFGITR_EL2_TLBIVALE1OS_TRAP | + HFGITR_EL2_TLBIVAAE1OS_TRAP | + HFGITR_EL2_TLBIASIDE1OS_TRAP | + HFGITR_EL2_TLBIVAE1OS_TRAP | + HFGITR_EL2_TLBIVMALLE1OS_TRAP; + + /* FEAT_PAN2 */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_ATS1E1WP_TRAP | + HFGITR_EL2_ATS1E1RP_TRAP; + + /* FEAT_DPB2 */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_DCCVADP_TRAP; + + /* Base architecture */ + el2ctx->hfgitr_el2 |= + HFGITR_EL2_DCCVAC_NOTRAP | + HFGITR_EL2_SVC_EL1_NOTRAP | + HFGITR_EL2_SVC_EL0_NOTRAP | + HFGITR_EL2_ERET_NOTRAP; + + el2ctx->hfgitr_el2 |= + HFGITR_EL2_TLBIVAALE1_NOTRAP | + HFGITR_EL2_TLBIVALE1_NOTRAP | + HFGITR_EL2_TLBIVAAE1_NOTRAP | + HFGITR_EL2_TLBIASIDE1_NOTRAP | + HFGITR_EL2_TLBIVAE1_NOTRAP | + HFGITR_EL2_TLBIVMALLE1_NOTRAP | + HFGITR_EL2_TLBIVAALE1IS_NOTRAP | + HFGITR_EL2_TLBIVALE1IS_NOTRAP | + HFGITR_EL2_TLBIVAAE1IS_NOTRAP | + HFGITR_EL2_TLBIASIDE1IS_NOTRAP | + HFGITR_EL2_TLBIVAE1IS_NOTRAP | + HFGITR_EL2_TLBIVMALLE1IS_NOTRAP; + + el2ctx->hfgitr_el2 |= + HFGITR_EL2_ATS1E0W_NOTRAP | + HFGITR_EL2_ATS1E0R_NOTRAP | + HFGITR_EL2_ATS1E1W_NOTRAP | + HFGITR_EL2_ATS1E1R_NOTRAP | + HFGITR_EL2_DCZVA_NOTRAP | + HFGITR_EL2_DCCIVAC_NOTRAP | + HFGITR_EL2_DCCVAP_NOTRAP | + HFGITR_EL2_DCCVAU_NOTRAP | + HFGITR_EL2_DCCISW_NOTRAP | + HFGITR_EL2_DCCSW_NOTRAP | + HFGITR_EL2_DCISW_NOTRAP | + HFGITR_EL2_DCIVAC_NOTRAP | + HFGITR_EL2_ICIVAU_NOTRAP | + HFGITR_EL2_ICIALLU_NOTRAP | + HFGITR_EL2_ICIALLUIS_NOTRAP; + + } + + /* 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; + } } |
