The branch main has been updated by andrew:

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

commit a4f0e93c514280bfd0ff3897e5171ec7bbe4796b
Author:     Andrew Turner <[email protected]>
AuthorDate: 2026-02-03 17:14:44 +0000
Commit:     Andrew Turner <[email protected]>
CommitDate: 2026-02-03 17:14:44 +0000

    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
---
 sys/arm64/vmm/arm64.h     |  16 ++
 sys/arm64/vmm/vmm_hyp.c   |  22 +++
 sys/arm64/vmm/vmm_reset.c | 405 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 443 insertions(+)

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;
+       }
 }

Reply via email to