| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (C) 2025 Google LLC
- * Author: Marc Zyngier <maz@kernel.org>
- */
- #include <linux/kvm_host.h>
- #include <asm/kvm_emulate.h>
- #include <asm/kvm_nested.h>
- #include <asm/sysreg.h>
- /*
- * Describes the dependencies between a set of bits (or the negation
- * of a set of RES0 bits) and a feature. The flags indicate how the
- * data is interpreted.
- */
- struct reg_bits_to_feat_map {
- union {
- u64 bits;
- struct fgt_masks *masks;
- };
- #define NEVER_FGU BIT(0) /* Can trap, but never UNDEF */
- #define CALL_FUNC BIT(1) /* Needs to evaluate tons of crap */
- #define FORCE_RESx BIT(2) /* Unconditional RESx */
- #define MASKS_POINTER BIT(3) /* Pointer to fgt_masks struct instead of bits */
- #define AS_RES1 BIT(4) /* RES1 when not supported */
- #define REQUIRES_E2H1 BIT(5) /* Add HCR_EL2.E2H RES1 as a pre-condition */
- #define RES1_WHEN_E2H0 BIT(6) /* RES1 when E2H=0 and not supported */
- #define RES1_WHEN_E2H1 BIT(7) /* RES1 when E2H=1 and not supported */
- unsigned long flags;
- union {
- struct {
- u8 regidx;
- u8 shift;
- u8 width;
- bool sign;
- s8 lo_lim;
- };
- bool (*match)(struct kvm *);
- };
- };
- /*
- * Describes the dependencies for a given register:
- *
- * @feat_map describes the dependency for the whole register. If the
- * features the register depends on are not present, the whole
- * register is effectively RES0.
- *
- * @bit_feat_map describes the dependencies for a set of bits in that
- * register. If the features these bits depend on are not present, the
- * bits are effectively RES0.
- */
- struct reg_feat_map_desc {
- const char *name;
- const struct reg_bits_to_feat_map feat_map;
- const struct reg_bits_to_feat_map *bit_feat_map;
- const unsigned int bit_feat_map_sz;
- };
- #define __NEEDS_FEAT_3(m, f, w, id, fld, lim) \
- { \
- .w = (m), \
- .flags = (f), \
- .regidx = IDREG_IDX(SYS_ ## id), \
- .shift = id ##_## fld ## _SHIFT, \
- .width = id ##_## fld ## _WIDTH, \
- .sign = id ##_## fld ## _SIGNED, \
- .lo_lim = id ##_## fld ##_## lim \
- }
- #define __NEEDS_FEAT_1(m, f, w, fun) \
- { \
- .w = (m), \
- .flags = (f) | CALL_FUNC, \
- .match = (fun), \
- }
- #define __NEEDS_FEAT_0(m, f, w, ...) \
- { \
- .w = (m), \
- .flags = (f), \
- }
- #define __NEEDS_FEAT_FLAG(m, f, w, ...) \
- CONCATENATE(__NEEDS_FEAT_, COUNT_ARGS(__VA_ARGS__))(m, f, w, __VA_ARGS__)
- #define NEEDS_FEAT_FLAG(m, f, ...) \
- __NEEDS_FEAT_FLAG(m, f, bits, __VA_ARGS__)
- #define NEEDS_FEAT_MASKS(p, ...) \
- __NEEDS_FEAT_FLAG(p, MASKS_POINTER, masks, __VA_ARGS__)
- /*
- * Declare the dependency between a set of bits and a set of features,
- * generating a struct reg_bit_to_feat_map.
- */
- #define NEEDS_FEAT(m, ...) NEEDS_FEAT_FLAG(m, 0, __VA_ARGS__)
- /* Declare fixed RESx bits */
- #define FORCE_RES0(m) NEEDS_FEAT_FLAG(m, FORCE_RESx)
- #define FORCE_RES1(m) NEEDS_FEAT_FLAG(m, FORCE_RESx | AS_RES1)
- /*
- * Declare the dependency between a non-FGT register, a set of features,
- * and the set of individual bits it contains. This generates a struct
- * reg_feat_map_desc.
- */
- #define DECLARE_FEAT_MAP(n, r, m, f) \
- struct reg_feat_map_desc n = { \
- .name = #r, \
- .feat_map = NEEDS_FEAT(~(r##_RES0 | \
- r##_RES1), f), \
- .bit_feat_map = m, \
- .bit_feat_map_sz = ARRAY_SIZE(m), \
- }
- /*
- * Specialised version of the above for FGT registers that have their
- * RESx masks described as struct fgt_masks.
- */
- #define DECLARE_FEAT_MAP_FGT(n, msk, m, f) \
- struct reg_feat_map_desc n = { \
- .name = #msk, \
- .feat_map = NEEDS_FEAT_MASKS(&msk, f), \
- .bit_feat_map = m, \
- .bit_feat_map_sz = ARRAY_SIZE(m), \
- }
- #define FEAT_SPE ID_AA64DFR0_EL1, PMSVer, IMP
- #define FEAT_SPE_FnE ID_AA64DFR0_EL1, PMSVer, V1P2
- #define FEAT_BRBE ID_AA64DFR0_EL1, BRBE, IMP
- #define FEAT_TRC_SR ID_AA64DFR0_EL1, TraceVer, IMP
- #define FEAT_PMUv3 ID_AA64DFR0_EL1, PMUVer, IMP
- #define FEAT_TRBE ID_AA64DFR0_EL1, TraceBuffer, IMP
- #define FEAT_TRBEv1p1 ID_AA64DFR0_EL1, TraceBuffer, TRBE_V1P1
- #define FEAT_DoubleLock ID_AA64DFR0_EL1, DoubleLock, IMP
- #define FEAT_TRF ID_AA64DFR0_EL1, TraceFilt, IMP
- #define FEAT_AA32EL0 ID_AA64PFR0_EL1, EL0, AARCH32
- #define FEAT_AA32EL1 ID_AA64PFR0_EL1, EL1, AARCH32
- #define FEAT_AA64EL1 ID_AA64PFR0_EL1, EL1, IMP
- #define FEAT_AA64EL2 ID_AA64PFR0_EL1, EL2, IMP
- #define FEAT_AA64EL3 ID_AA64PFR0_EL1, EL3, IMP
- #define FEAT_SEL2 ID_AA64PFR0_EL1, SEL2, IMP
- #define FEAT_AIE ID_AA64MMFR3_EL1, AIE, IMP
- #define FEAT_S2POE ID_AA64MMFR3_EL1, S2POE, IMP
- #define FEAT_S1POE ID_AA64MMFR3_EL1, S1POE, IMP
- #define FEAT_S1PIE ID_AA64MMFR3_EL1, S1PIE, IMP
- #define FEAT_THE ID_AA64PFR1_EL1, THE, IMP
- #define FEAT_SME ID_AA64PFR1_EL1, SME, IMP
- #define FEAT_GCS ID_AA64PFR1_EL1, GCS, IMP
- #define FEAT_LS64 ID_AA64ISAR1_EL1, LS64, LS64
- #define FEAT_LS64_V ID_AA64ISAR1_EL1, LS64, LS64_V
- #define FEAT_LS64_ACCDATA ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA
- #define FEAT_RAS ID_AA64PFR0_EL1, RAS, IMP
- #define FEAT_RASv2 ID_AA64PFR0_EL1, RAS, V2
- #define FEAT_GICv3 ID_AA64PFR0_EL1, GIC, IMP
- #define FEAT_LOR ID_AA64MMFR1_EL1, LO, IMP
- #define FEAT_SPEv1p2 ID_AA64DFR0_EL1, PMSVer, V1P2
- #define FEAT_SPEv1p4 ID_AA64DFR0_EL1, PMSVer, V1P4
- #define FEAT_SPEv1p5 ID_AA64DFR0_EL1, PMSVer, V1P5
- #define FEAT_ATS1A ID_AA64ISAR2_EL1, ATS1A, IMP
- #define FEAT_SPECRES2 ID_AA64ISAR1_EL1, SPECRES, COSP_RCTX
- #define FEAT_SPECRES ID_AA64ISAR1_EL1, SPECRES, IMP
- #define FEAT_TLBIRANGE ID_AA64ISAR0_EL1, TLB, RANGE
- #define FEAT_TLBIOS ID_AA64ISAR0_EL1, TLB, OS
- #define FEAT_PAN2 ID_AA64MMFR1_EL1, PAN, PAN2
- #define FEAT_DPB2 ID_AA64ISAR1_EL1, DPB, DPB2
- #define FEAT_AMUv1 ID_AA64PFR0_EL1, AMU, IMP
- #define FEAT_AMUv1p1 ID_AA64PFR0_EL1, AMU, V1P1
- #define FEAT_CMOW ID_AA64MMFR1_EL1, CMOW, IMP
- #define FEAT_D128 ID_AA64MMFR3_EL1, D128, IMP
- #define FEAT_DoubleFault2 ID_AA64PFR1_EL1, DF2, IMP
- #define FEAT_FPMR ID_AA64PFR2_EL1, FPMR, IMP
- #define FEAT_MOPS ID_AA64ISAR2_EL1, MOPS, IMP
- #define FEAT_NMI ID_AA64PFR1_EL1, NMI, IMP
- #define FEAT_SCTLR2 ID_AA64MMFR3_EL1, SCTLRX, IMP
- #define FEAT_SYSREG128 ID_AA64ISAR2_EL1, SYSREG_128, IMP
- #define FEAT_TCR2 ID_AA64MMFR3_EL1, TCRX, IMP
- #define FEAT_XS ID_AA64ISAR1_EL1, XS, IMP
- #define FEAT_EVT ID_AA64MMFR2_EL1, EVT, IMP
- #define FEAT_EVT_TTLBxS ID_AA64MMFR2_EL1, EVT, TTLBxS
- #define FEAT_MTE2 ID_AA64PFR1_EL1, MTE, MTE2
- #define FEAT_RME ID_AA64PFR0_EL1, RME, IMP
- #define FEAT_MPAM ID_AA64PFR0_EL1, MPAM, 1
- #define FEAT_S2FWB ID_AA64MMFR2_EL1, FWB, IMP
- #define FEAT_TWED ID_AA64MMFR1_EL1, TWED, IMP
- #define FEAT_E2H0 ID_AA64MMFR4_EL1, E2H0, IMP
- #define FEAT_SRMASK ID_AA64MMFR4_EL1, SRMASK, IMP
- #define FEAT_PoPS ID_AA64MMFR4_EL1, PoPS, IMP
- #define FEAT_PFAR ID_AA64PFR1_EL1, PFAR, IMP
- #define FEAT_Debugv8p9 ID_AA64DFR0_EL1, PMUVer, V3P9
- #define FEAT_PMUv3_SS ID_AA64DFR0_EL1, PMSS, IMP
- #define FEAT_SEBEP ID_AA64DFR0_EL1, SEBEP, IMP
- #define FEAT_EBEP ID_AA64DFR1_EL1, EBEP, IMP
- #define FEAT_ITE ID_AA64DFR1_EL1, ITE, IMP
- #define FEAT_PMUv3_ICNTR ID_AA64DFR1_EL1, PMICNTR, IMP
- #define FEAT_SPMU ID_AA64DFR1_EL1, SPMU, IMP
- #define FEAT_SPE_nVM ID_AA64DFR2_EL1, SPE_nVM, IMP
- #define FEAT_STEP2 ID_AA64DFR2_EL1, STEP, IMP
- #define FEAT_CPA2 ID_AA64ISAR3_EL1, CPA, CPA2
- #define FEAT_ASID2 ID_AA64MMFR4_EL1, ASID2, IMP
- #define FEAT_MEC ID_AA64MMFR3_EL1, MEC, IMP
- #define FEAT_HAFT ID_AA64MMFR1_EL1, HAFDBS, HAFT
- #define FEAT_HDBSS ID_AA64MMFR1_EL1, HAFDBS, HDBSS
- #define FEAT_HPDS2 ID_AA64MMFR1_EL1, HPDS, HPDS2
- #define FEAT_BTI ID_AA64PFR1_EL1, BT, IMP
- #define FEAT_ExS ID_AA64MMFR0_EL1, EXS, IMP
- #define FEAT_IESB ID_AA64MMFR2_EL1, IESB, IMP
- #define FEAT_LSE2 ID_AA64MMFR2_EL1, AT, IMP
- #define FEAT_LSMAOC ID_AA64MMFR2_EL1, LSM, IMP
- #define FEAT_MixedEnd ID_AA64MMFR0_EL1, BIGEND, IMP
- #define FEAT_MixedEndEL0 ID_AA64MMFR0_EL1, BIGENDEL0, IMP
- #define FEAT_MTE_ASYNC ID_AA64PFR1_EL1, MTE_frac, ASYNC
- #define FEAT_MTE_STORE_ONLY ID_AA64PFR2_EL1, MTESTOREONLY, IMP
- #define FEAT_PAN ID_AA64MMFR1_EL1, PAN, IMP
- #define FEAT_PAN3 ID_AA64MMFR1_EL1, PAN, PAN3
- #define FEAT_SSBS ID_AA64PFR1_EL1, SSBS, IMP
- #define FEAT_TIDCP1 ID_AA64MMFR1_EL1, TIDCP1, IMP
- #define FEAT_FGT ID_AA64MMFR0_EL1, FGT, IMP
- #define FEAT_FGT2 ID_AA64MMFR0_EL1, FGT, FGT2
- #define FEAT_MTPMU ID_AA64DFR0_EL1, MTPMU, IMP
- #define FEAT_HCX ID_AA64MMFR1_EL1, HCX, IMP
- #define FEAT_S2PIE ID_AA64MMFR3_EL1, S2PIE, IMP
- static bool not_feat_aa64el3(struct kvm *kvm)
- {
- return !kvm_has_feat(kvm, FEAT_AA64EL3);
- }
- static bool feat_nv2(struct kvm *kvm)
- {
- return ((kvm_has_feat(kvm, ID_AA64MMFR4_EL1, NV_frac, NV2_ONLY) &&
- kvm_has_feat_enum(kvm, ID_AA64MMFR2_EL1, NV, NI)) ||
- kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, NV2));
- }
- static bool feat_nv2_e2h0_ni(struct kvm *kvm)
- {
- return feat_nv2(kvm) && !kvm_has_feat(kvm, FEAT_E2H0);
- }
- static bool feat_rasv1p1(struct kvm *kvm)
- {
- return (kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1) ||
- (kvm_has_feat_enum(kvm, ID_AA64PFR0_EL1, RAS, IMP) &&
- kvm_has_feat(kvm, ID_AA64PFR1_EL1, RAS_frac, RASv1p1)));
- }
- static bool feat_csv2_2_csv2_1p2(struct kvm *kvm)
- {
- return (kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) ||
- (kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2) &&
- kvm_has_feat_enum(kvm, ID_AA64PFR0_EL1, CSV2, IMP)));
- }
- static bool feat_pauth(struct kvm *kvm)
- {
- return kvm_has_pauth(kvm, PAuth);
- }
- static bool feat_pauth_lr(struct kvm *kvm)
- {
- return kvm_has_pauth(kvm, PAuth_LR);
- }
- static bool feat_aderr(struct kvm *kvm)
- {
- return (kvm_has_feat(kvm, ID_AA64MMFR3_EL1, ADERR, FEAT_ADERR) &&
- kvm_has_feat(kvm, ID_AA64MMFR3_EL1, SDERR, FEAT_ADERR));
- }
- static bool feat_anerr(struct kvm *kvm)
- {
- return (kvm_has_feat(kvm, ID_AA64MMFR3_EL1, ANERR, FEAT_ANERR) &&
- kvm_has_feat(kvm, ID_AA64MMFR3_EL1, SNERR, FEAT_ANERR));
- }
- static bool feat_sme_smps(struct kvm *kvm)
- {
- /*
- * Revists this if KVM ever supports SME -- this really should
- * look at the guest's view of SMIDR_EL1. Funnily enough, this
- * is not captured in the JSON file, but only as a note in the
- * ARM ARM.
- */
- return (kvm_has_feat(kvm, FEAT_SME) &&
- (read_sysreg_s(SYS_SMIDR_EL1) & SMIDR_EL1_SMPS));
- }
- static bool feat_spe_fds(struct kvm *kvm)
- {
- /*
- * Revists this if KVM ever supports SPE -- this really should
- * look at the guest's view of PMSIDR_EL1.
- */
- return (kvm_has_feat(kvm, FEAT_SPEv1p4) &&
- (read_sysreg_s(SYS_PMSIDR_EL1) & PMSIDR_EL1_FDS));
- }
- static bool feat_trbe_mpam(struct kvm *kvm)
- {
- /*
- * Revists this if KVM ever supports both MPAM and TRBE --
- * this really should look at the guest's view of TRBIDR_EL1.
- */
- return (kvm_has_feat(kvm, FEAT_TRBE) &&
- kvm_has_feat(kvm, FEAT_MPAM) &&
- (read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_MPAM));
- }
- static bool feat_ebep_pmuv3_ss(struct kvm *kvm)
- {
- return kvm_has_feat(kvm, FEAT_EBEP) || kvm_has_feat(kvm, FEAT_PMUv3_SS);
- }
- static bool feat_mixedendel0(struct kvm *kvm)
- {
- return kvm_has_feat(kvm, FEAT_MixedEnd) || kvm_has_feat(kvm, FEAT_MixedEndEL0);
- }
- static bool feat_mte_async(struct kvm *kvm)
- {
- return kvm_has_feat(kvm, FEAT_MTE2) && kvm_has_feat_enum(kvm, FEAT_MTE_ASYNC);
- }
- #define check_pmu_revision(k, r) \
- ({ \
- (kvm_has_feat((k), ID_AA64DFR0_EL1, PMUVer, r) && \
- !kvm_has_feat((k), ID_AA64DFR0_EL1, PMUVer, IMP_DEF)); \
- })
- static bool feat_pmuv3p1(struct kvm *kvm)
- {
- return check_pmu_revision(kvm, V3P1);
- }
- static bool feat_pmuv3p5(struct kvm *kvm)
- {
- return check_pmu_revision(kvm, V3P5);
- }
- static bool feat_pmuv3p7(struct kvm *kvm)
- {
- return check_pmu_revision(kvm, V3P7);
- }
- static bool feat_pmuv3p9(struct kvm *kvm)
- {
- return check_pmu_revision(kvm, V3P9);
- }
- #define has_feat_s2tgran(k, s) \
- ((kvm_has_feat_enum(kvm, ID_AA64MMFR0_EL1, TGRAN##s##_2, TGRAN##s) && \
- kvm_has_feat(kvm, ID_AA64MMFR0_EL1, TGRAN##s, IMP)) || \
- kvm_has_feat(kvm, ID_AA64MMFR0_EL1, TGRAN##s##_2, IMP))
- static bool feat_lpa2(struct kvm *kvm)
- {
- return ((kvm_has_feat(kvm, ID_AA64MMFR0_EL1, TGRAN4, 52_BIT) ||
- !kvm_has_feat(kvm, ID_AA64MMFR0_EL1, TGRAN4, IMP)) &&
- (kvm_has_feat(kvm, ID_AA64MMFR0_EL1, TGRAN16, 52_BIT) ||
- !kvm_has_feat(kvm, ID_AA64MMFR0_EL1, TGRAN16, IMP)) &&
- (kvm_has_feat(kvm, ID_AA64MMFR0_EL1, TGRAN4_2, 52_BIT) ||
- !has_feat_s2tgran(kvm, 4)) &&
- (kvm_has_feat(kvm, ID_AA64MMFR0_EL1, TGRAN16_2, 52_BIT) ||
- !has_feat_s2tgran(kvm, 16)));
- }
- static bool feat_vmid16(struct kvm *kvm)
- {
- return kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16);
- }
- static const struct reg_bits_to_feat_map hfgrtr_feat_map[] = {
- NEEDS_FEAT(HFGRTR_EL2_nAMAIR2_EL1 |
- HFGRTR_EL2_nMAIR2_EL1,
- FEAT_AIE),
- NEEDS_FEAT(HFGRTR_EL2_nS2POR_EL1, FEAT_S2POE),
- NEEDS_FEAT(HFGRTR_EL2_nPOR_EL1 |
- HFGRTR_EL2_nPOR_EL0,
- FEAT_S1POE),
- NEEDS_FEAT(HFGRTR_EL2_nPIR_EL1 |
- HFGRTR_EL2_nPIRE0_EL1,
- FEAT_S1PIE),
- NEEDS_FEAT(HFGRTR_EL2_nRCWMASK_EL1, FEAT_THE),
- NEEDS_FEAT(HFGRTR_EL2_nTPIDR2_EL0 |
- HFGRTR_EL2_nSMPRI_EL1,
- FEAT_SME),
- NEEDS_FEAT(HFGRTR_EL2_nGCS_EL1 |
- HFGRTR_EL2_nGCS_EL0,
- FEAT_GCS),
- NEEDS_FEAT(HFGRTR_EL2_nACCDATA_EL1, FEAT_LS64_ACCDATA),
- NEEDS_FEAT(HFGRTR_EL2_ERXADDR_EL1 |
- HFGRTR_EL2_ERXMISCn_EL1 |
- HFGRTR_EL2_ERXSTATUS_EL1 |
- HFGRTR_EL2_ERXCTLR_EL1 |
- HFGRTR_EL2_ERXFR_EL1 |
- HFGRTR_EL2_ERRSELR_EL1 |
- HFGRTR_EL2_ERRIDR_EL1,
- FEAT_RAS),
- NEEDS_FEAT(HFGRTR_EL2_ERXPFGCDN_EL1 |
- HFGRTR_EL2_ERXPFGCTL_EL1 |
- HFGRTR_EL2_ERXPFGF_EL1,
- feat_rasv1p1),
- NEEDS_FEAT(HFGRTR_EL2_ICC_IGRPENn_EL1, FEAT_GICv3),
- NEEDS_FEAT(HFGRTR_EL2_SCXTNUM_EL0 |
- HFGRTR_EL2_SCXTNUM_EL1,
- feat_csv2_2_csv2_1p2),
- NEEDS_FEAT(HFGRTR_EL2_LORSA_EL1 |
- HFGRTR_EL2_LORN_EL1 |
- HFGRTR_EL2_LORID_EL1 |
- HFGRTR_EL2_LOREA_EL1 |
- HFGRTR_EL2_LORC_EL1,
- FEAT_LOR),
- NEEDS_FEAT(HFGRTR_EL2_APIBKey |
- HFGRTR_EL2_APIAKey |
- HFGRTR_EL2_APGAKey |
- HFGRTR_EL2_APDBKey |
- HFGRTR_EL2_APDAKey,
- feat_pauth),
- NEEDS_FEAT_FLAG(HFGRTR_EL2_VBAR_EL1 |
- HFGRTR_EL2_TTBR1_EL1 |
- HFGRTR_EL2_TTBR0_EL1 |
- HFGRTR_EL2_TPIDR_EL0 |
- HFGRTR_EL2_TPIDRRO_EL0 |
- HFGRTR_EL2_TPIDR_EL1 |
- HFGRTR_EL2_TCR_EL1 |
- HFGRTR_EL2_SCTLR_EL1 |
- HFGRTR_EL2_REVIDR_EL1 |
- HFGRTR_EL2_PAR_EL1 |
- HFGRTR_EL2_MPIDR_EL1 |
- HFGRTR_EL2_MIDR_EL1 |
- HFGRTR_EL2_MAIR_EL1 |
- HFGRTR_EL2_ISR_EL1 |
- HFGRTR_EL2_FAR_EL1 |
- HFGRTR_EL2_ESR_EL1 |
- HFGRTR_EL2_DCZID_EL0 |
- HFGRTR_EL2_CTR_EL0 |
- HFGRTR_EL2_CSSELR_EL1 |
- HFGRTR_EL2_CPACR_EL1 |
- HFGRTR_EL2_CONTEXTIDR_EL1|
- HFGRTR_EL2_CLIDR_EL1 |
- HFGRTR_EL2_CCSIDR_EL1 |
- HFGRTR_EL2_AMAIR_EL1 |
- HFGRTR_EL2_AIDR_EL1 |
- HFGRTR_EL2_AFSR1_EL1 |
- HFGRTR_EL2_AFSR0_EL1,
- NEVER_FGU, FEAT_AA64EL1),
- };
- static const DECLARE_FEAT_MAP_FGT(hfgrtr_desc, hfgrtr_masks,
- hfgrtr_feat_map, FEAT_FGT);
- static const struct reg_bits_to_feat_map hfgwtr_feat_map[] = {
- NEEDS_FEAT(HFGWTR_EL2_nAMAIR2_EL1 |
- HFGWTR_EL2_nMAIR2_EL1,
- FEAT_AIE),
- NEEDS_FEAT(HFGWTR_EL2_nS2POR_EL1, FEAT_S2POE),
- NEEDS_FEAT(HFGWTR_EL2_nPOR_EL1 |
- HFGWTR_EL2_nPOR_EL0,
- FEAT_S1POE),
- NEEDS_FEAT(HFGWTR_EL2_nPIR_EL1 |
- HFGWTR_EL2_nPIRE0_EL1,
- FEAT_S1PIE),
- NEEDS_FEAT(HFGWTR_EL2_nRCWMASK_EL1, FEAT_THE),
- NEEDS_FEAT(HFGWTR_EL2_nTPIDR2_EL0 |
- HFGWTR_EL2_nSMPRI_EL1,
- FEAT_SME),
- NEEDS_FEAT(HFGWTR_EL2_nGCS_EL1 |
- HFGWTR_EL2_nGCS_EL0,
- FEAT_GCS),
- NEEDS_FEAT(HFGWTR_EL2_nACCDATA_EL1, FEAT_LS64_ACCDATA),
- NEEDS_FEAT(HFGWTR_EL2_ERXADDR_EL1 |
- HFGWTR_EL2_ERXMISCn_EL1 |
- HFGWTR_EL2_ERXSTATUS_EL1 |
- HFGWTR_EL2_ERXCTLR_EL1 |
- HFGWTR_EL2_ERRSELR_EL1,
- FEAT_RAS),
- NEEDS_FEAT(HFGWTR_EL2_ERXPFGCDN_EL1 |
- HFGWTR_EL2_ERXPFGCTL_EL1,
- feat_rasv1p1),
- NEEDS_FEAT(HFGWTR_EL2_ICC_IGRPENn_EL1, FEAT_GICv3),
- NEEDS_FEAT(HFGWTR_EL2_SCXTNUM_EL0 |
- HFGWTR_EL2_SCXTNUM_EL1,
- feat_csv2_2_csv2_1p2),
- NEEDS_FEAT(HFGWTR_EL2_LORSA_EL1 |
- HFGWTR_EL2_LORN_EL1 |
- HFGWTR_EL2_LOREA_EL1 |
- HFGWTR_EL2_LORC_EL1,
- FEAT_LOR),
- NEEDS_FEAT(HFGWTR_EL2_APIBKey |
- HFGWTR_EL2_APIAKey |
- HFGWTR_EL2_APGAKey |
- HFGWTR_EL2_APDBKey |
- HFGWTR_EL2_APDAKey,
- feat_pauth),
- NEEDS_FEAT_FLAG(HFGWTR_EL2_VBAR_EL1 |
- HFGWTR_EL2_TTBR1_EL1 |
- HFGWTR_EL2_TTBR0_EL1 |
- HFGWTR_EL2_TPIDR_EL0 |
- HFGWTR_EL2_TPIDRRO_EL0 |
- HFGWTR_EL2_TPIDR_EL1 |
- HFGWTR_EL2_TCR_EL1 |
- HFGWTR_EL2_SCTLR_EL1 |
- HFGWTR_EL2_PAR_EL1 |
- HFGWTR_EL2_MAIR_EL1 |
- HFGWTR_EL2_FAR_EL1 |
- HFGWTR_EL2_ESR_EL1 |
- HFGWTR_EL2_CSSELR_EL1 |
- HFGWTR_EL2_CPACR_EL1 |
- HFGWTR_EL2_CONTEXTIDR_EL1|
- HFGWTR_EL2_AMAIR_EL1 |
- HFGWTR_EL2_AFSR1_EL1 |
- HFGWTR_EL2_AFSR0_EL1,
- NEVER_FGU, FEAT_AA64EL1),
- };
- static const DECLARE_FEAT_MAP_FGT(hfgwtr_desc, hfgwtr_masks,
- hfgwtr_feat_map, FEAT_FGT);
- static const struct reg_bits_to_feat_map hdfgrtr_feat_map[] = {
- NEEDS_FEAT(HDFGRTR_EL2_PMBIDR_EL1 |
- HDFGRTR_EL2_PMSLATFR_EL1 |
- HDFGRTR_EL2_PMSIRR_EL1 |
- HDFGRTR_EL2_PMSIDR_EL1 |
- HDFGRTR_EL2_PMSICR_EL1 |
- HDFGRTR_EL2_PMSFCR_EL1 |
- HDFGRTR_EL2_PMSEVFR_EL1 |
- HDFGRTR_EL2_PMSCR_EL1 |
- HDFGRTR_EL2_PMBSR_EL1 |
- HDFGRTR_EL2_PMBPTR_EL1 |
- HDFGRTR_EL2_PMBLIMITR_EL1,
- FEAT_SPE),
- NEEDS_FEAT(HDFGRTR_EL2_nPMSNEVFR_EL1, FEAT_SPE_FnE),
- NEEDS_FEAT(HDFGRTR_EL2_nBRBDATA |
- HDFGRTR_EL2_nBRBCTL |
- HDFGRTR_EL2_nBRBIDR,
- FEAT_BRBE),
- NEEDS_FEAT(HDFGRTR_EL2_TRCVICTLR |
- HDFGRTR_EL2_TRCSTATR |
- HDFGRTR_EL2_TRCSSCSRn |
- HDFGRTR_EL2_TRCSEQSTR |
- HDFGRTR_EL2_TRCPRGCTLR |
- HDFGRTR_EL2_TRCOSLSR |
- HDFGRTR_EL2_TRCIMSPECn |
- HDFGRTR_EL2_TRCID |
- HDFGRTR_EL2_TRCCNTVRn |
- HDFGRTR_EL2_TRCCLAIM |
- HDFGRTR_EL2_TRCAUXCTLR |
- HDFGRTR_EL2_TRCAUTHSTATUS |
- HDFGRTR_EL2_TRC,
- FEAT_TRC_SR),
- NEEDS_FEAT(HDFGRTR_EL2_PMCEIDn_EL0 |
- HDFGRTR_EL2_PMUSERENR_EL0 |
- HDFGRTR_EL2_PMMIR_EL1 |
- HDFGRTR_EL2_PMSELR_EL0 |
- HDFGRTR_EL2_PMOVS |
- HDFGRTR_EL2_PMINTEN |
- HDFGRTR_EL2_PMCNTEN |
- HDFGRTR_EL2_PMCCNTR_EL0 |
- HDFGRTR_EL2_PMCCFILTR_EL0 |
- HDFGRTR_EL2_PMEVTYPERn_EL0 |
- HDFGRTR_EL2_PMEVCNTRn_EL0,
- FEAT_PMUv3),
- NEEDS_FEAT(HDFGRTR_EL2_TRBTRG_EL1 |
- HDFGRTR_EL2_TRBSR_EL1 |
- HDFGRTR_EL2_TRBPTR_EL1 |
- HDFGRTR_EL2_TRBMAR_EL1 |
- HDFGRTR_EL2_TRBLIMITR_EL1 |
- HDFGRTR_EL2_TRBIDR_EL1 |
- HDFGRTR_EL2_TRBBASER_EL1,
- FEAT_TRBE),
- NEEDS_FEAT_FLAG(HDFGRTR_EL2_OSDLR_EL1, NEVER_FGU,
- FEAT_DoubleLock),
- NEEDS_FEAT_FLAG(HDFGRTR_EL2_OSECCR_EL1 |
- HDFGRTR_EL2_OSLSR_EL1 |
- HDFGRTR_EL2_DBGPRCR_EL1 |
- HDFGRTR_EL2_DBGAUTHSTATUS_EL1|
- HDFGRTR_EL2_DBGCLAIM |
- HDFGRTR_EL2_MDSCR_EL1 |
- HDFGRTR_EL2_DBGWVRn_EL1 |
- HDFGRTR_EL2_DBGWCRn_EL1 |
- HDFGRTR_EL2_DBGBVRn_EL1 |
- HDFGRTR_EL2_DBGBCRn_EL1,
- NEVER_FGU, FEAT_AA64EL1)
- };
- static const DECLARE_FEAT_MAP_FGT(hdfgrtr_desc, hdfgrtr_masks,
- hdfgrtr_feat_map, FEAT_FGT);
- static const struct reg_bits_to_feat_map hdfgwtr_feat_map[] = {
- NEEDS_FEAT(HDFGWTR_EL2_PMSLATFR_EL1 |
- HDFGWTR_EL2_PMSIRR_EL1 |
- HDFGWTR_EL2_PMSICR_EL1 |
- HDFGWTR_EL2_PMSFCR_EL1 |
- HDFGWTR_EL2_PMSEVFR_EL1 |
- HDFGWTR_EL2_PMSCR_EL1 |
- HDFGWTR_EL2_PMBSR_EL1 |
- HDFGWTR_EL2_PMBPTR_EL1 |
- HDFGWTR_EL2_PMBLIMITR_EL1,
- FEAT_SPE),
- NEEDS_FEAT(HDFGWTR_EL2_nPMSNEVFR_EL1, FEAT_SPE_FnE),
- NEEDS_FEAT(HDFGWTR_EL2_nBRBDATA |
- HDFGWTR_EL2_nBRBCTL,
- FEAT_BRBE),
- NEEDS_FEAT(HDFGWTR_EL2_TRCVICTLR |
- HDFGWTR_EL2_TRCSSCSRn |
- HDFGWTR_EL2_TRCSEQSTR |
- HDFGWTR_EL2_TRCPRGCTLR |
- HDFGWTR_EL2_TRCOSLAR |
- HDFGWTR_EL2_TRCIMSPECn |
- HDFGWTR_EL2_TRCCNTVRn |
- HDFGWTR_EL2_TRCCLAIM |
- HDFGWTR_EL2_TRCAUXCTLR |
- HDFGWTR_EL2_TRC,
- FEAT_TRC_SR),
- NEEDS_FEAT(HDFGWTR_EL2_PMUSERENR_EL0 |
- HDFGWTR_EL2_PMCR_EL0 |
- HDFGWTR_EL2_PMSWINC_EL0 |
- HDFGWTR_EL2_PMSELR_EL0 |
- HDFGWTR_EL2_PMOVS |
- HDFGWTR_EL2_PMINTEN |
- HDFGWTR_EL2_PMCNTEN |
- HDFGWTR_EL2_PMCCNTR_EL0 |
- HDFGWTR_EL2_PMCCFILTR_EL0 |
- HDFGWTR_EL2_PMEVTYPERn_EL0 |
- HDFGWTR_EL2_PMEVCNTRn_EL0,
- FEAT_PMUv3),
- NEEDS_FEAT(HDFGWTR_EL2_TRBTRG_EL1 |
- HDFGWTR_EL2_TRBSR_EL1 |
- HDFGWTR_EL2_TRBPTR_EL1 |
- HDFGWTR_EL2_TRBMAR_EL1 |
- HDFGWTR_EL2_TRBLIMITR_EL1 |
- HDFGWTR_EL2_TRBBASER_EL1,
- FEAT_TRBE),
- NEEDS_FEAT_FLAG(HDFGWTR_EL2_OSDLR_EL1,
- NEVER_FGU, FEAT_DoubleLock),
- NEEDS_FEAT_FLAG(HDFGWTR_EL2_OSECCR_EL1 |
- HDFGWTR_EL2_OSLAR_EL1 |
- HDFGWTR_EL2_DBGPRCR_EL1 |
- HDFGWTR_EL2_DBGCLAIM |
- HDFGWTR_EL2_MDSCR_EL1 |
- HDFGWTR_EL2_DBGWVRn_EL1 |
- HDFGWTR_EL2_DBGWCRn_EL1 |
- HDFGWTR_EL2_DBGBVRn_EL1 |
- HDFGWTR_EL2_DBGBCRn_EL1,
- NEVER_FGU, FEAT_AA64EL1),
- NEEDS_FEAT(HDFGWTR_EL2_TRFCR_EL1, FEAT_TRF),
- };
- static const DECLARE_FEAT_MAP_FGT(hdfgwtr_desc, hdfgwtr_masks,
- hdfgwtr_feat_map, FEAT_FGT);
- static const struct reg_bits_to_feat_map hfgitr_feat_map[] = {
- NEEDS_FEAT(HFGITR_EL2_PSBCSYNC, FEAT_SPEv1p5),
- NEEDS_FEAT(HFGITR_EL2_ATS1E1A, FEAT_ATS1A),
- NEEDS_FEAT(HFGITR_EL2_COSPRCTX, FEAT_SPECRES2),
- NEEDS_FEAT(HFGITR_EL2_nGCSEPP |
- HFGITR_EL2_nGCSSTR_EL1 |
- HFGITR_EL2_nGCSPUSHM_EL1,
- FEAT_GCS),
- NEEDS_FEAT(HFGITR_EL2_nBRBIALL |
- HFGITR_EL2_nBRBINJ,
- FEAT_BRBE),
- NEEDS_FEAT(HFGITR_EL2_CPPRCTX |
- HFGITR_EL2_DVPRCTX |
- HFGITR_EL2_CFPRCTX,
- FEAT_SPECRES),
- NEEDS_FEAT(HFGITR_EL2_TLBIRVAALE1 |
- HFGITR_EL2_TLBIRVALE1 |
- HFGITR_EL2_TLBIRVAAE1 |
- HFGITR_EL2_TLBIRVAE1 |
- HFGITR_EL2_TLBIRVAALE1IS |
- HFGITR_EL2_TLBIRVALE1IS |
- HFGITR_EL2_TLBIRVAAE1IS |
- HFGITR_EL2_TLBIRVAE1IS |
- HFGITR_EL2_TLBIRVAALE1OS |
- HFGITR_EL2_TLBIRVALE1OS |
- HFGITR_EL2_TLBIRVAAE1OS |
- HFGITR_EL2_TLBIRVAE1OS,
- FEAT_TLBIRANGE),
- NEEDS_FEAT(HFGITR_EL2_TLBIVAALE1OS |
- HFGITR_EL2_TLBIVALE1OS |
- HFGITR_EL2_TLBIVAAE1OS |
- HFGITR_EL2_TLBIASIDE1OS |
- HFGITR_EL2_TLBIVAE1OS |
- HFGITR_EL2_TLBIVMALLE1OS,
- FEAT_TLBIOS),
- NEEDS_FEAT(HFGITR_EL2_ATS1E1WP |
- HFGITR_EL2_ATS1E1RP,
- FEAT_PAN2),
- NEEDS_FEAT(HFGITR_EL2_DCCVADP, FEAT_DPB2),
- NEEDS_FEAT_FLAG(HFGITR_EL2_DCCVAC |
- HFGITR_EL2_SVC_EL1 |
- HFGITR_EL2_SVC_EL0 |
- HFGITR_EL2_ERET |
- HFGITR_EL2_TLBIVAALE1 |
- HFGITR_EL2_TLBIVALE1 |
- HFGITR_EL2_TLBIVAAE1 |
- HFGITR_EL2_TLBIASIDE1 |
- HFGITR_EL2_TLBIVAE1 |
- HFGITR_EL2_TLBIVMALLE1 |
- HFGITR_EL2_TLBIVAALE1IS |
- HFGITR_EL2_TLBIVALE1IS |
- HFGITR_EL2_TLBIVAAE1IS |
- HFGITR_EL2_TLBIASIDE1IS |
- HFGITR_EL2_TLBIVAE1IS |
- HFGITR_EL2_TLBIVMALLE1IS|
- HFGITR_EL2_ATS1E0W |
- HFGITR_EL2_ATS1E0R |
- HFGITR_EL2_ATS1E1W |
- HFGITR_EL2_ATS1E1R |
- HFGITR_EL2_DCZVA |
- HFGITR_EL2_DCCIVAC |
- HFGITR_EL2_DCCVAP |
- HFGITR_EL2_DCCVAU |
- HFGITR_EL2_DCCISW |
- HFGITR_EL2_DCCSW |
- HFGITR_EL2_DCISW |
- HFGITR_EL2_DCIVAC |
- HFGITR_EL2_ICIVAU |
- HFGITR_EL2_ICIALLU |
- HFGITR_EL2_ICIALLUIS,
- NEVER_FGU, FEAT_AA64EL1),
- };
- static const DECLARE_FEAT_MAP_FGT(hfgitr_desc, hfgitr_masks,
- hfgitr_feat_map, FEAT_FGT);
- static const struct reg_bits_to_feat_map hafgrtr_feat_map[] = {
- NEEDS_FEAT(HAFGRTR_EL2_AMEVTYPER115_EL0 |
- HAFGRTR_EL2_AMEVTYPER114_EL0 |
- HAFGRTR_EL2_AMEVTYPER113_EL0 |
- HAFGRTR_EL2_AMEVTYPER112_EL0 |
- HAFGRTR_EL2_AMEVTYPER111_EL0 |
- HAFGRTR_EL2_AMEVTYPER110_EL0 |
- HAFGRTR_EL2_AMEVTYPER19_EL0 |
- HAFGRTR_EL2_AMEVTYPER18_EL0 |
- HAFGRTR_EL2_AMEVTYPER17_EL0 |
- HAFGRTR_EL2_AMEVTYPER16_EL0 |
- HAFGRTR_EL2_AMEVTYPER15_EL0 |
- HAFGRTR_EL2_AMEVTYPER14_EL0 |
- HAFGRTR_EL2_AMEVTYPER13_EL0 |
- HAFGRTR_EL2_AMEVTYPER12_EL0 |
- HAFGRTR_EL2_AMEVTYPER11_EL0 |
- HAFGRTR_EL2_AMEVTYPER10_EL0 |
- HAFGRTR_EL2_AMEVCNTR115_EL0 |
- HAFGRTR_EL2_AMEVCNTR114_EL0 |
- HAFGRTR_EL2_AMEVCNTR113_EL0 |
- HAFGRTR_EL2_AMEVCNTR112_EL0 |
- HAFGRTR_EL2_AMEVCNTR111_EL0 |
- HAFGRTR_EL2_AMEVCNTR110_EL0 |
- HAFGRTR_EL2_AMEVCNTR19_EL0 |
- HAFGRTR_EL2_AMEVCNTR18_EL0 |
- HAFGRTR_EL2_AMEVCNTR17_EL0 |
- HAFGRTR_EL2_AMEVCNTR16_EL0 |
- HAFGRTR_EL2_AMEVCNTR15_EL0 |
- HAFGRTR_EL2_AMEVCNTR14_EL0 |
- HAFGRTR_EL2_AMEVCNTR13_EL0 |
- HAFGRTR_EL2_AMEVCNTR12_EL0 |
- HAFGRTR_EL2_AMEVCNTR11_EL0 |
- HAFGRTR_EL2_AMEVCNTR10_EL0 |
- HAFGRTR_EL2_AMCNTEN1 |
- HAFGRTR_EL2_AMCNTEN0 |
- HAFGRTR_EL2_AMEVCNTR03_EL0 |
- HAFGRTR_EL2_AMEVCNTR02_EL0 |
- HAFGRTR_EL2_AMEVCNTR01_EL0 |
- HAFGRTR_EL2_AMEVCNTR00_EL0,
- FEAT_AMUv1),
- };
- static const DECLARE_FEAT_MAP_FGT(hafgrtr_desc, hafgrtr_masks,
- hafgrtr_feat_map, FEAT_FGT);
- static const struct reg_bits_to_feat_map hfgitr2_feat_map[] = {
- NEEDS_FEAT(HFGITR2_EL2_nDCCIVAPS, FEAT_PoPS),
- NEEDS_FEAT(HFGITR2_EL2_TSBCSYNC, FEAT_TRBEv1p1)
- };
- static const DECLARE_FEAT_MAP_FGT(hfgitr2_desc, hfgitr2_masks,
- hfgitr2_feat_map, FEAT_FGT2);
- static const struct reg_bits_to_feat_map hfgrtr2_feat_map[] = {
- NEEDS_FEAT(HFGRTR2_EL2_nPFAR_EL1, FEAT_PFAR),
- NEEDS_FEAT(HFGRTR2_EL2_nERXGSR_EL1, FEAT_RASv2),
- NEEDS_FEAT(HFGRTR2_EL2_nACTLRALIAS_EL1 |
- HFGRTR2_EL2_nACTLRMASK_EL1 |
- HFGRTR2_EL2_nCPACRALIAS_EL1 |
- HFGRTR2_EL2_nCPACRMASK_EL1 |
- HFGRTR2_EL2_nSCTLR2MASK_EL1 |
- HFGRTR2_EL2_nSCTLRALIAS2_EL1 |
- HFGRTR2_EL2_nSCTLRALIAS_EL1 |
- HFGRTR2_EL2_nSCTLRMASK_EL1 |
- HFGRTR2_EL2_nTCR2ALIAS_EL1 |
- HFGRTR2_EL2_nTCR2MASK_EL1 |
- HFGRTR2_EL2_nTCRALIAS_EL1 |
- HFGRTR2_EL2_nTCRMASK_EL1,
- FEAT_SRMASK),
- NEEDS_FEAT(HFGRTR2_EL2_nRCWSMASK_EL1, FEAT_THE),
- };
- static const DECLARE_FEAT_MAP_FGT(hfgrtr2_desc, hfgrtr2_masks,
- hfgrtr2_feat_map, FEAT_FGT2);
- static const struct reg_bits_to_feat_map hfgwtr2_feat_map[] = {
- NEEDS_FEAT(HFGWTR2_EL2_nPFAR_EL1, FEAT_PFAR),
- NEEDS_FEAT(HFGWTR2_EL2_nACTLRALIAS_EL1 |
- HFGWTR2_EL2_nACTLRMASK_EL1 |
- HFGWTR2_EL2_nCPACRALIAS_EL1 |
- HFGWTR2_EL2_nCPACRMASK_EL1 |
- HFGWTR2_EL2_nSCTLR2MASK_EL1 |
- HFGWTR2_EL2_nSCTLRALIAS2_EL1 |
- HFGWTR2_EL2_nSCTLRALIAS_EL1 |
- HFGWTR2_EL2_nSCTLRMASK_EL1 |
- HFGWTR2_EL2_nTCR2ALIAS_EL1 |
- HFGWTR2_EL2_nTCR2MASK_EL1 |
- HFGWTR2_EL2_nTCRALIAS_EL1 |
- HFGWTR2_EL2_nTCRMASK_EL1,
- FEAT_SRMASK),
- NEEDS_FEAT(HFGWTR2_EL2_nRCWSMASK_EL1, FEAT_THE),
- };
- static const DECLARE_FEAT_MAP_FGT(hfgwtr2_desc, hfgwtr2_masks,
- hfgwtr2_feat_map, FEAT_FGT2);
- static const struct reg_bits_to_feat_map hdfgrtr2_feat_map[] = {
- NEEDS_FEAT(HDFGRTR2_EL2_nMDSELR_EL1, FEAT_Debugv8p9),
- NEEDS_FEAT(HDFGRTR2_EL2_nPMECR_EL1, feat_ebep_pmuv3_ss),
- NEEDS_FEAT(HDFGRTR2_EL2_nTRCITECR_EL1, FEAT_ITE),
- NEEDS_FEAT(HDFGRTR2_EL2_nPMICFILTR_EL0 |
- HDFGRTR2_EL2_nPMICNTR_EL0,
- FEAT_PMUv3_ICNTR),
- NEEDS_FEAT(HDFGRTR2_EL2_nPMUACR_EL1, feat_pmuv3p9),
- NEEDS_FEAT(HDFGRTR2_EL2_nPMSSCR_EL1 |
- HDFGRTR2_EL2_nPMSSDATA,
- FEAT_PMUv3_SS),
- NEEDS_FEAT(HDFGRTR2_EL2_nPMIAR_EL1, FEAT_SEBEP),
- NEEDS_FEAT(HDFGRTR2_EL2_nPMSDSFR_EL1, feat_spe_fds),
- NEEDS_FEAT(HDFGRTR2_EL2_nPMBMAR_EL1, FEAT_SPE_nVM),
- NEEDS_FEAT(HDFGRTR2_EL2_nSPMACCESSR_EL1 |
- HDFGRTR2_EL2_nSPMCNTEN |
- HDFGRTR2_EL2_nSPMCR_EL0 |
- HDFGRTR2_EL2_nSPMDEVAFF_EL1 |
- HDFGRTR2_EL2_nSPMEVCNTRn_EL0 |
- HDFGRTR2_EL2_nSPMEVTYPERn_EL0|
- HDFGRTR2_EL2_nSPMID |
- HDFGRTR2_EL2_nSPMINTEN |
- HDFGRTR2_EL2_nSPMOVS |
- HDFGRTR2_EL2_nSPMSCR_EL1 |
- HDFGRTR2_EL2_nSPMSELR_EL0,
- FEAT_SPMU),
- NEEDS_FEAT(HDFGRTR2_EL2_nMDSTEPOP_EL1, FEAT_STEP2),
- NEEDS_FEAT(HDFGRTR2_EL2_nTRBMPAM_EL1, feat_trbe_mpam),
- };
- static const DECLARE_FEAT_MAP_FGT(hdfgrtr2_desc, hdfgrtr2_masks,
- hdfgrtr2_feat_map, FEAT_FGT2);
- static const struct reg_bits_to_feat_map hdfgwtr2_feat_map[] = {
- NEEDS_FEAT(HDFGWTR2_EL2_nMDSELR_EL1, FEAT_Debugv8p9),
- NEEDS_FEAT(HDFGWTR2_EL2_nPMECR_EL1, feat_ebep_pmuv3_ss),
- NEEDS_FEAT(HDFGWTR2_EL2_nTRCITECR_EL1, FEAT_ITE),
- NEEDS_FEAT(HDFGWTR2_EL2_nPMICFILTR_EL0 |
- HDFGWTR2_EL2_nPMICNTR_EL0,
- FEAT_PMUv3_ICNTR),
- NEEDS_FEAT(HDFGWTR2_EL2_nPMUACR_EL1 |
- HDFGWTR2_EL2_nPMZR_EL0,
- feat_pmuv3p9),
- NEEDS_FEAT(HDFGWTR2_EL2_nPMSSCR_EL1, FEAT_PMUv3_SS),
- NEEDS_FEAT(HDFGWTR2_EL2_nPMIAR_EL1, FEAT_SEBEP),
- NEEDS_FEAT(HDFGWTR2_EL2_nPMSDSFR_EL1, feat_spe_fds),
- NEEDS_FEAT(HDFGWTR2_EL2_nPMBMAR_EL1, FEAT_SPE_nVM),
- NEEDS_FEAT(HDFGWTR2_EL2_nSPMACCESSR_EL1 |
- HDFGWTR2_EL2_nSPMCNTEN |
- HDFGWTR2_EL2_nSPMCR_EL0 |
- HDFGWTR2_EL2_nSPMEVCNTRn_EL0 |
- HDFGWTR2_EL2_nSPMEVTYPERn_EL0|
- HDFGWTR2_EL2_nSPMINTEN |
- HDFGWTR2_EL2_nSPMOVS |
- HDFGWTR2_EL2_nSPMSCR_EL1 |
- HDFGWTR2_EL2_nSPMSELR_EL0,
- FEAT_SPMU),
- NEEDS_FEAT(HDFGWTR2_EL2_nMDSTEPOP_EL1, FEAT_STEP2),
- NEEDS_FEAT(HDFGWTR2_EL2_nTRBMPAM_EL1, feat_trbe_mpam),
- };
- static const DECLARE_FEAT_MAP_FGT(hdfgwtr2_desc, hdfgwtr2_masks,
- hdfgwtr2_feat_map, FEAT_FGT2);
- static const struct reg_bits_to_feat_map hcrx_feat_map[] = {
- NEEDS_FEAT(HCRX_EL2_PACMEn, feat_pauth_lr),
- NEEDS_FEAT(HCRX_EL2_EnFPM, FEAT_FPMR),
- NEEDS_FEAT(HCRX_EL2_GCSEn, FEAT_GCS),
- NEEDS_FEAT(HCRX_EL2_EnIDCP128, FEAT_SYSREG128),
- NEEDS_FEAT(HCRX_EL2_EnSDERR, feat_aderr),
- NEEDS_FEAT(HCRX_EL2_TMEA, FEAT_DoubleFault2),
- NEEDS_FEAT(HCRX_EL2_EnSNERR, feat_anerr),
- NEEDS_FEAT(HCRX_EL2_D128En, FEAT_D128),
- NEEDS_FEAT(HCRX_EL2_PTTWI, FEAT_THE),
- NEEDS_FEAT(HCRX_EL2_SCTLR2En, FEAT_SCTLR2),
- NEEDS_FEAT(HCRX_EL2_TCR2En, FEAT_TCR2),
- NEEDS_FEAT(HCRX_EL2_MSCEn |
- HCRX_EL2_MCE2,
- FEAT_MOPS),
- NEEDS_FEAT(HCRX_EL2_CMOW, FEAT_CMOW),
- NEEDS_FEAT(HCRX_EL2_VFNMI |
- HCRX_EL2_VINMI |
- HCRX_EL2_TALLINT,
- FEAT_NMI),
- NEEDS_FEAT(HCRX_EL2_SMPME, feat_sme_smps),
- NEEDS_FEAT(HCRX_EL2_FGTnXS |
- HCRX_EL2_FnXS,
- FEAT_XS),
- NEEDS_FEAT(HCRX_EL2_EnASR, FEAT_LS64_V),
- NEEDS_FEAT(HCRX_EL2_EnALS, FEAT_LS64),
- NEEDS_FEAT(HCRX_EL2_EnAS0, FEAT_LS64_ACCDATA),
- };
- static const DECLARE_FEAT_MAP(hcrx_desc, __HCRX_EL2,
- hcrx_feat_map, FEAT_HCX);
- static const struct reg_bits_to_feat_map hcr_feat_map[] = {
- NEEDS_FEAT(HCR_EL2_TID0, FEAT_AA32EL0),
- NEEDS_FEAT_FLAG(HCR_EL2_RW, AS_RES1, FEAT_AA32EL1),
- NEEDS_FEAT(HCR_EL2_HCD, not_feat_aa64el3),
- NEEDS_FEAT(HCR_EL2_AMO |
- HCR_EL2_BSU |
- HCR_EL2_CD |
- HCR_EL2_DC |
- HCR_EL2_FB |
- HCR_EL2_FMO |
- HCR_EL2_ID |
- HCR_EL2_IMO |
- HCR_EL2_PTW |
- HCR_EL2_SWIO |
- HCR_EL2_TACR |
- HCR_EL2_TDZ |
- HCR_EL2_TGE |
- HCR_EL2_TID1 |
- HCR_EL2_TID2 |
- HCR_EL2_TID3 |
- HCR_EL2_TIDCP |
- HCR_EL2_TPCP |
- HCR_EL2_TPU |
- HCR_EL2_TRVM |
- HCR_EL2_TSC |
- HCR_EL2_TSW |
- HCR_EL2_TTLB |
- HCR_EL2_TVM |
- HCR_EL2_TWE |
- HCR_EL2_TWI |
- HCR_EL2_VF |
- HCR_EL2_VI |
- HCR_EL2_VM |
- HCR_EL2_VSE,
- FEAT_AA64EL1),
- NEEDS_FEAT(HCR_EL2_AMVOFFEN, FEAT_AMUv1p1),
- NEEDS_FEAT(HCR_EL2_EnSCXT, feat_csv2_2_csv2_1p2),
- NEEDS_FEAT(HCR_EL2_TICAB |
- HCR_EL2_TID4 |
- HCR_EL2_TOCU,
- FEAT_EVT),
- NEEDS_FEAT(HCR_EL2_TTLBIS |
- HCR_EL2_TTLBOS,
- FEAT_EVT_TTLBxS),
- NEEDS_FEAT(HCR_EL2_TLOR, FEAT_LOR),
- NEEDS_FEAT(HCR_EL2_ATA |
- HCR_EL2_DCT |
- HCR_EL2_TID5,
- FEAT_MTE2),
- NEEDS_FEAT(HCR_EL2_AT | /* Ignore the original FEAT_NV */
- HCR_EL2_NV2 |
- HCR_EL2_NV,
- feat_nv2),
- NEEDS_FEAT(HCR_EL2_NV1, feat_nv2_e2h0_ni), /* Missing from JSON */
- NEEDS_FEAT(HCR_EL2_API |
- HCR_EL2_APK,
- feat_pauth),
- NEEDS_FEAT(HCR_EL2_TEA |
- HCR_EL2_TERR,
- FEAT_RAS),
- NEEDS_FEAT(HCR_EL2_FIEN, feat_rasv1p1),
- NEEDS_FEAT(HCR_EL2_GPF, FEAT_RME),
- NEEDS_FEAT(HCR_EL2_FWB, FEAT_S2FWB),
- NEEDS_FEAT(HCR_EL2_TWEDEL |
- HCR_EL2_TWEDEn,
- FEAT_TWED),
- NEEDS_FEAT_FLAG(HCR_EL2_E2H, RES1_WHEN_E2H1 | FORCE_RESx),
- FORCE_RES0(HCR_EL2_RES0),
- FORCE_RES1(HCR_EL2_RES1),
- };
- static const DECLARE_FEAT_MAP(hcr_desc, HCR_EL2,
- hcr_feat_map, FEAT_AA64EL2);
- static const struct reg_bits_to_feat_map sctlr2_feat_map[] = {
- NEEDS_FEAT(SCTLR2_EL1_NMEA |
- SCTLR2_EL1_EASE,
- FEAT_DoubleFault2),
- NEEDS_FEAT(SCTLR2_EL1_EnADERR, feat_aderr),
- NEEDS_FEAT(SCTLR2_EL1_EnANERR, feat_anerr),
- NEEDS_FEAT(SCTLR2_EL1_EnIDCP128, FEAT_SYSREG128),
- NEEDS_FEAT(SCTLR2_EL1_EnPACM |
- SCTLR2_EL1_EnPACM0,
- feat_pauth_lr),
- NEEDS_FEAT(SCTLR2_EL1_CPTA |
- SCTLR2_EL1_CPTA0 |
- SCTLR2_EL1_CPTM |
- SCTLR2_EL1_CPTM0,
- FEAT_CPA2),
- FORCE_RES0(SCTLR2_EL1_RES0),
- FORCE_RES1(SCTLR2_EL1_RES1),
- };
- static const DECLARE_FEAT_MAP(sctlr2_desc, SCTLR2_EL1,
- sctlr2_feat_map, FEAT_SCTLR2);
- static const struct reg_bits_to_feat_map tcr2_el2_feat_map[] = {
- NEEDS_FEAT_FLAG(TCR2_EL2_FNG1 |
- TCR2_EL2_FNG0 |
- TCR2_EL2_A2,
- REQUIRES_E2H1, FEAT_ASID2),
- NEEDS_FEAT_FLAG(TCR2_EL2_DisCH1 |
- TCR2_EL2_DisCH0 |
- TCR2_EL2_D128,
- REQUIRES_E2H1, FEAT_D128),
- NEEDS_FEAT_FLAG(TCR2_EL2_AMEC1, REQUIRES_E2H1, FEAT_MEC),
- NEEDS_FEAT(TCR2_EL2_AMEC0, FEAT_MEC),
- NEEDS_FEAT(TCR2_EL2_HAFT, FEAT_HAFT),
- NEEDS_FEAT(TCR2_EL2_PTTWI |
- TCR2_EL2_PnCH,
- FEAT_THE),
- NEEDS_FEAT(TCR2_EL2_AIE, FEAT_AIE),
- NEEDS_FEAT(TCR2_EL2_POE |
- TCR2_EL2_E0POE,
- FEAT_S1POE),
- NEEDS_FEAT(TCR2_EL2_PIE, FEAT_S1PIE),
- FORCE_RES0(TCR2_EL2_RES0),
- FORCE_RES1(TCR2_EL2_RES1),
- };
- static const DECLARE_FEAT_MAP(tcr2_el2_desc, TCR2_EL2,
- tcr2_el2_feat_map, FEAT_TCR2);
- static const struct reg_bits_to_feat_map sctlr_el1_feat_map[] = {
- NEEDS_FEAT(SCTLR_EL1_CP15BEN, FEAT_AA32EL0),
- NEEDS_FEAT_FLAG(SCTLR_EL1_ITD |
- SCTLR_EL1_SED,
- AS_RES1, FEAT_AA32EL0),
- NEEDS_FEAT(SCTLR_EL1_BT0 |
- SCTLR_EL1_BT1,
- FEAT_BTI),
- NEEDS_FEAT(SCTLR_EL1_CMOW, FEAT_CMOW),
- NEEDS_FEAT_FLAG(SCTLR_EL1_TSCXT,
- AS_RES1, feat_csv2_2_csv2_1p2),
- NEEDS_FEAT_FLAG(SCTLR_EL1_EIS |
- SCTLR_EL1_EOS,
- AS_RES1, FEAT_ExS),
- NEEDS_FEAT(SCTLR_EL1_EnFPM, FEAT_FPMR),
- NEEDS_FEAT(SCTLR_EL1_IESB, FEAT_IESB),
- NEEDS_FEAT(SCTLR_EL1_EnALS, FEAT_LS64),
- NEEDS_FEAT(SCTLR_EL1_EnAS0, FEAT_LS64_ACCDATA),
- NEEDS_FEAT(SCTLR_EL1_EnASR, FEAT_LS64_V),
- NEEDS_FEAT(SCTLR_EL1_nAA, FEAT_LSE2),
- NEEDS_FEAT_FLAG(SCTLR_EL1_LSMAOE |
- SCTLR_EL1_nTLSMD,
- AS_RES1, FEAT_LSMAOC),
- NEEDS_FEAT(SCTLR_EL1_EE, FEAT_MixedEnd),
- NEEDS_FEAT(SCTLR_EL1_E0E, feat_mixedendel0),
- NEEDS_FEAT(SCTLR_EL1_MSCEn, FEAT_MOPS),
- NEEDS_FEAT(SCTLR_EL1_ATA0 |
- SCTLR_EL1_ATA |
- SCTLR_EL1_TCF0 |
- SCTLR_EL1_TCF,
- FEAT_MTE2),
- NEEDS_FEAT(SCTLR_EL1_ITFSB, feat_mte_async),
- NEEDS_FEAT(SCTLR_EL1_TCSO0 |
- SCTLR_EL1_TCSO,
- FEAT_MTE_STORE_ONLY),
- NEEDS_FEAT(SCTLR_EL1_NMI |
- SCTLR_EL1_SPINTMASK,
- FEAT_NMI),
- NEEDS_FEAT_FLAG(SCTLR_EL1_SPAN,
- AS_RES1, FEAT_PAN),
- NEEDS_FEAT(SCTLR_EL1_EPAN, FEAT_PAN3),
- NEEDS_FEAT(SCTLR_EL1_EnDA |
- SCTLR_EL1_EnDB |
- SCTLR_EL1_EnIA |
- SCTLR_EL1_EnIB,
- feat_pauth),
- NEEDS_FEAT(SCTLR_EL1_EnTP2, FEAT_SME),
- NEEDS_FEAT(SCTLR_EL1_EnRCTX, FEAT_SPECRES),
- NEEDS_FEAT(SCTLR_EL1_DSSBS, FEAT_SSBS),
- NEEDS_FEAT(SCTLR_EL1_TIDCP, FEAT_TIDCP1),
- NEEDS_FEAT(SCTLR_EL1_TWEDEL |
- SCTLR_EL1_TWEDEn,
- FEAT_TWED),
- NEEDS_FEAT(SCTLR_EL1_UCI |
- SCTLR_EL1_WXN |
- SCTLR_EL1_nTWE |
- SCTLR_EL1_nTWI |
- SCTLR_EL1_UCT |
- SCTLR_EL1_DZE |
- SCTLR_EL1_I |
- SCTLR_EL1_UMA |
- SCTLR_EL1_SA0 |
- SCTLR_EL1_SA |
- SCTLR_EL1_C |
- SCTLR_EL1_A |
- SCTLR_EL1_M,
- FEAT_AA64EL1),
- FORCE_RES0(SCTLR_EL1_RES0),
- FORCE_RES1(SCTLR_EL1_RES1),
- };
- static const DECLARE_FEAT_MAP(sctlr_el1_desc, SCTLR_EL1,
- sctlr_el1_feat_map, FEAT_AA64EL1);
- static const struct reg_bits_to_feat_map sctlr_el2_feat_map[] = {
- NEEDS_FEAT_FLAG(SCTLR_EL2_CP15BEN,
- RES1_WHEN_E2H0 | REQUIRES_E2H1,
- FEAT_AA32EL0),
- NEEDS_FEAT_FLAG(SCTLR_EL2_ITD |
- SCTLR_EL2_SED,
- RES1_WHEN_E2H1 | REQUIRES_E2H1,
- FEAT_AA32EL0),
- NEEDS_FEAT_FLAG(SCTLR_EL2_BT0, REQUIRES_E2H1, FEAT_BTI),
- NEEDS_FEAT(SCTLR_EL2_BT, FEAT_BTI),
- NEEDS_FEAT_FLAG(SCTLR_EL2_CMOW, REQUIRES_E2H1, FEAT_CMOW),
- NEEDS_FEAT_FLAG(SCTLR_EL2_TSCXT,
- RES1_WHEN_E2H1 | REQUIRES_E2H1,
- feat_csv2_2_csv2_1p2),
- NEEDS_FEAT_FLAG(SCTLR_EL2_EIS |
- SCTLR_EL2_EOS,
- AS_RES1, FEAT_ExS),
- NEEDS_FEAT(SCTLR_EL2_EnFPM, FEAT_FPMR),
- NEEDS_FEAT(SCTLR_EL2_IESB, FEAT_IESB),
- NEEDS_FEAT_FLAG(SCTLR_EL2_EnALS, REQUIRES_E2H1, FEAT_LS64),
- NEEDS_FEAT_FLAG(SCTLR_EL2_EnAS0, REQUIRES_E2H1, FEAT_LS64_ACCDATA),
- NEEDS_FEAT_FLAG(SCTLR_EL2_EnASR, REQUIRES_E2H1, FEAT_LS64_V),
- NEEDS_FEAT(SCTLR_EL2_nAA, FEAT_LSE2),
- NEEDS_FEAT_FLAG(SCTLR_EL2_LSMAOE |
- SCTLR_EL2_nTLSMD,
- AS_RES1 | REQUIRES_E2H1, FEAT_LSMAOC),
- NEEDS_FEAT(SCTLR_EL2_EE, FEAT_MixedEnd),
- NEEDS_FEAT_FLAG(SCTLR_EL2_E0E, REQUIRES_E2H1, feat_mixedendel0),
- NEEDS_FEAT_FLAG(SCTLR_EL2_MSCEn, REQUIRES_E2H1, FEAT_MOPS),
- NEEDS_FEAT_FLAG(SCTLR_EL2_ATA0 |
- SCTLR_EL2_TCF0,
- REQUIRES_E2H1, FEAT_MTE2),
- NEEDS_FEAT(SCTLR_EL2_ATA |
- SCTLR_EL2_TCF,
- FEAT_MTE2),
- NEEDS_FEAT(SCTLR_EL2_ITFSB, feat_mte_async),
- NEEDS_FEAT_FLAG(SCTLR_EL2_TCSO0, REQUIRES_E2H1, FEAT_MTE_STORE_ONLY),
- NEEDS_FEAT(SCTLR_EL2_TCSO,
- FEAT_MTE_STORE_ONLY),
- NEEDS_FEAT(SCTLR_EL2_NMI |
- SCTLR_EL2_SPINTMASK,
- FEAT_NMI),
- NEEDS_FEAT_FLAG(SCTLR_EL2_SPAN, AS_RES1 | REQUIRES_E2H1, FEAT_PAN),
- NEEDS_FEAT_FLAG(SCTLR_EL2_EPAN, REQUIRES_E2H1, FEAT_PAN3),
- NEEDS_FEAT(SCTLR_EL2_EnDA |
- SCTLR_EL2_EnDB |
- SCTLR_EL2_EnIA |
- SCTLR_EL2_EnIB,
- feat_pauth),
- NEEDS_FEAT_FLAG(SCTLR_EL2_EnTP2, REQUIRES_E2H1, FEAT_SME),
- NEEDS_FEAT(SCTLR_EL2_EnRCTX, FEAT_SPECRES),
- NEEDS_FEAT(SCTLR_EL2_DSSBS, FEAT_SSBS),
- NEEDS_FEAT_FLAG(SCTLR_EL2_TIDCP, REQUIRES_E2H1, FEAT_TIDCP1),
- NEEDS_FEAT_FLAG(SCTLR_EL2_TWEDEL |
- SCTLR_EL2_TWEDEn,
- REQUIRES_E2H1, FEAT_TWED),
- NEEDS_FEAT_FLAG(SCTLR_EL2_nTWE |
- SCTLR_EL2_nTWI,
- AS_RES1 | REQUIRES_E2H1, FEAT_AA64EL2),
- NEEDS_FEAT_FLAG(SCTLR_EL2_UCI |
- SCTLR_EL2_UCT |
- SCTLR_EL2_DZE |
- SCTLR_EL2_SA0,
- REQUIRES_E2H1, FEAT_AA64EL2),
- NEEDS_FEAT(SCTLR_EL2_WXN |
- SCTLR_EL2_I |
- SCTLR_EL2_SA |
- SCTLR_EL2_C |
- SCTLR_EL2_A |
- SCTLR_EL2_M,
- FEAT_AA64EL2),
- FORCE_RES0(SCTLR_EL2_RES0),
- FORCE_RES1(SCTLR_EL2_RES1),
- };
- static const DECLARE_FEAT_MAP(sctlr_el2_desc, SCTLR_EL2,
- sctlr_el2_feat_map, FEAT_AA64EL2);
- static const struct reg_bits_to_feat_map mdcr_el2_feat_map[] = {
- NEEDS_FEAT(MDCR_EL2_EBWE, FEAT_Debugv8p9),
- NEEDS_FEAT(MDCR_EL2_TDOSA, FEAT_DoubleLock),
- NEEDS_FEAT(MDCR_EL2_PMEE, FEAT_EBEP),
- NEEDS_FEAT(MDCR_EL2_TDCC, FEAT_FGT),
- NEEDS_FEAT(MDCR_EL2_MTPME, FEAT_MTPMU),
- NEEDS_FEAT(MDCR_EL2_HPME |
- MDCR_EL2_HPMN |
- MDCR_EL2_TPMCR |
- MDCR_EL2_TPM,
- FEAT_PMUv3),
- NEEDS_FEAT(MDCR_EL2_HPMD, feat_pmuv3p1),
- NEEDS_FEAT(MDCR_EL2_HCCD |
- MDCR_EL2_HLP,
- feat_pmuv3p5),
- NEEDS_FEAT(MDCR_EL2_HPMFZO, feat_pmuv3p7),
- NEEDS_FEAT(MDCR_EL2_PMSSE, FEAT_PMUv3_SS),
- NEEDS_FEAT(MDCR_EL2_E2PB |
- MDCR_EL2_TPMS,
- FEAT_SPE),
- NEEDS_FEAT(MDCR_EL2_HPMFZS, FEAT_SPEv1p2),
- NEEDS_FEAT(MDCR_EL2_EnSPM, FEAT_SPMU),
- NEEDS_FEAT(MDCR_EL2_EnSTEPOP, FEAT_STEP2),
- NEEDS_FEAT(MDCR_EL2_E2TB, FEAT_TRBE),
- NEEDS_FEAT(MDCR_EL2_TTRF, FEAT_TRF),
- NEEDS_FEAT(MDCR_EL2_TDA |
- MDCR_EL2_TDE |
- MDCR_EL2_TDRA,
- FEAT_AA64EL1),
- FORCE_RES0(MDCR_EL2_RES0),
- FORCE_RES1(MDCR_EL2_RES1),
- };
- static const DECLARE_FEAT_MAP(mdcr_el2_desc, MDCR_EL2,
- mdcr_el2_feat_map, FEAT_AA64EL2);
- static const struct reg_bits_to_feat_map vtcr_el2_feat_map[] = {
- NEEDS_FEAT(VTCR_EL2_HDBSS, FEAT_HDBSS),
- NEEDS_FEAT(VTCR_EL2_HAFT, FEAT_HAFT),
- NEEDS_FEAT(VTCR_EL2_TL0 |
- VTCR_EL2_TL1 |
- VTCR_EL2_AssuredOnly |
- VTCR_EL2_GCSH,
- FEAT_THE),
- NEEDS_FEAT(VTCR_EL2_D128, FEAT_D128),
- NEEDS_FEAT(VTCR_EL2_S2POE, FEAT_S2POE),
- NEEDS_FEAT(VTCR_EL2_S2PIE, FEAT_S2PIE),
- NEEDS_FEAT(VTCR_EL2_SL2 |
- VTCR_EL2_DS,
- feat_lpa2),
- NEEDS_FEAT(VTCR_EL2_NSA |
- VTCR_EL2_NSW,
- FEAT_SEL2),
- NEEDS_FEAT(VTCR_EL2_HWU62 |
- VTCR_EL2_HWU61 |
- VTCR_EL2_HWU60 |
- VTCR_EL2_HWU59,
- FEAT_HPDS2),
- NEEDS_FEAT(VTCR_EL2_HD, ID_AA64MMFR1_EL1, HAFDBS, DBM),
- NEEDS_FEAT(VTCR_EL2_HA, ID_AA64MMFR1_EL1, HAFDBS, AF),
- NEEDS_FEAT(VTCR_EL2_VS, feat_vmid16),
- NEEDS_FEAT(VTCR_EL2_PS |
- VTCR_EL2_TG0 |
- VTCR_EL2_SH0 |
- VTCR_EL2_ORGN0 |
- VTCR_EL2_IRGN0 |
- VTCR_EL2_SL0 |
- VTCR_EL2_T0SZ,
- FEAT_AA64EL1),
- FORCE_RES0(VTCR_EL2_RES0),
- FORCE_RES1(VTCR_EL2_RES1),
- };
- static const DECLARE_FEAT_MAP(vtcr_el2_desc, VTCR_EL2,
- vtcr_el2_feat_map, FEAT_AA64EL2);
- static void __init check_feat_map(const struct reg_bits_to_feat_map *map,
- int map_size, u64 resx, const char *str)
- {
- u64 mask = 0;
- /*
- * Don't account for FORCE_RESx that are architectural, and
- * therefore part of the resx parameter. Other FORCE_RESx bits
- * are implementation choices, and therefore accounted for.
- */
- for (int i = 0; i < map_size; i++)
- if (!((map[i].flags & FORCE_RESx) && (map[i].bits & resx)))
- mask |= map[i].bits;
- if (mask != ~resx)
- kvm_err("Undefined %s behaviour, bits %016llx\n",
- str, mask ^ ~resx);
- }
- static u64 reg_feat_map_bits(const struct reg_bits_to_feat_map *map)
- {
- return map->flags & MASKS_POINTER ? (map->masks->mask | map->masks->nmask) : map->bits;
- }
- static void __init check_reg_desc(const struct reg_feat_map_desc *r)
- {
- check_feat_map(r->bit_feat_map, r->bit_feat_map_sz,
- ~reg_feat_map_bits(&r->feat_map), r->name);
- }
- void __init check_feature_map(void)
- {
- check_reg_desc(&hfgrtr_desc);
- check_reg_desc(&hfgwtr_desc);
- check_reg_desc(&hfgitr_desc);
- check_reg_desc(&hdfgrtr_desc);
- check_reg_desc(&hdfgwtr_desc);
- check_reg_desc(&hafgrtr_desc);
- check_reg_desc(&hfgrtr2_desc);
- check_reg_desc(&hfgwtr2_desc);
- check_reg_desc(&hfgitr2_desc);
- check_reg_desc(&hdfgrtr2_desc);
- check_reg_desc(&hdfgwtr2_desc);
- check_reg_desc(&hcrx_desc);
- check_reg_desc(&hcr_desc);
- check_reg_desc(&sctlr2_desc);
- check_reg_desc(&tcr2_el2_desc);
- check_reg_desc(&sctlr_el1_desc);
- check_reg_desc(&sctlr_el2_desc);
- check_reg_desc(&mdcr_el2_desc);
- check_reg_desc(&vtcr_el2_desc);
- }
- static bool idreg_feat_match(struct kvm *kvm, const struct reg_bits_to_feat_map *map)
- {
- u64 regval = kvm->arch.id_regs[map->regidx];
- u64 regfld = (regval >> map->shift) & GENMASK(map->width - 1, 0);
- if (map->sign) {
- s64 sfld = sign_extend64(regfld, map->width - 1);
- s64 slim = sign_extend64(map->lo_lim, map->width - 1);
- return sfld >= slim;
- } else {
- return regfld >= map->lo_lim;
- }
- }
- static struct resx compute_resx_bits(struct kvm *kvm,
- const struct reg_bits_to_feat_map *map,
- int map_size,
- unsigned long require,
- unsigned long exclude)
- {
- bool e2h0 = kvm_has_feat(kvm, FEAT_E2H0);
- struct resx resx = {};
- for (int i = 0; i < map_size; i++) {
- bool match;
- if ((map[i].flags & require) != require)
- continue;
- if (map[i].flags & exclude)
- continue;
- if (map[i].flags & FORCE_RESx)
- match = false;
- else if (map[i].flags & CALL_FUNC)
- match = map[i].match(kvm);
- else
- match = idreg_feat_match(kvm, &map[i]);
- if (map[i].flags & REQUIRES_E2H1)
- match &= !e2h0;
- if (!match) {
- u64 bits = reg_feat_map_bits(&map[i]);
- if ((map[i].flags & AS_RES1) ||
- (e2h0 && (map[i].flags & RES1_WHEN_E2H0)) ||
- (!e2h0 && (map[i].flags & RES1_WHEN_E2H1)))
- resx.res1 |= bits;
- else
- resx.res0 |= bits;
- }
- }
- return resx;
- }
- static struct resx compute_reg_resx_bits(struct kvm *kvm,
- const struct reg_feat_map_desc *r,
- unsigned long require,
- unsigned long exclude)
- {
- struct resx resx;
- resx = compute_resx_bits(kvm, r->bit_feat_map, r->bit_feat_map_sz,
- require, exclude);
- if (r->feat_map.flags & MASKS_POINTER) {
- resx.res0 |= r->feat_map.masks->res0;
- resx.res1 |= r->feat_map.masks->res1;
- }
- /*
- * If the register itself was not valid, all the non-RESx bits are
- * now considered RES0 (this matches the behaviour of registers such
- * as SCTLR2 and TCR2). Weed out any potential (though unlikely)
- * overlap with RES1 bits coming from the previous computation.
- */
- resx.res0 |= compute_resx_bits(kvm, &r->feat_map, 1, require, exclude).res0;
- resx.res1 &= ~resx.res0;
- return resx;
- }
- static u64 compute_fgu_bits(struct kvm *kvm, const struct reg_feat_map_desc *r)
- {
- struct resx resx;
- /*
- * If computing FGUs, we collect the unsupported feature bits as
- * RESx bits, but don't take the actual RESx bits or register
- * existence into account -- we're not computing bits for the
- * register itself.
- */
- resx = compute_resx_bits(kvm, r->bit_feat_map, r->bit_feat_map_sz,
- 0, NEVER_FGU);
- return resx.res0 | resx.res1;
- }
- void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt)
- {
- u64 val = 0;
- switch (fgt) {
- case HFGRTR_GROUP:
- val |= compute_fgu_bits(kvm, &hfgrtr_desc);
- val |= compute_fgu_bits(kvm, &hfgwtr_desc);
- break;
- case HFGITR_GROUP:
- val |= compute_fgu_bits(kvm, &hfgitr_desc);
- break;
- case HDFGRTR_GROUP:
- val |= compute_fgu_bits(kvm, &hdfgrtr_desc);
- val |= compute_fgu_bits(kvm, &hdfgwtr_desc);
- break;
- case HAFGRTR_GROUP:
- val |= compute_fgu_bits(kvm, &hafgrtr_desc);
- break;
- case HFGRTR2_GROUP:
- val |= compute_fgu_bits(kvm, &hfgrtr2_desc);
- val |= compute_fgu_bits(kvm, &hfgwtr2_desc);
- break;
- case HFGITR2_GROUP:
- val |= compute_fgu_bits(kvm, &hfgitr2_desc);
- break;
- case HDFGRTR2_GROUP:
- val |= compute_fgu_bits(kvm, &hdfgrtr2_desc);
- val |= compute_fgu_bits(kvm, &hdfgwtr2_desc);
- break;
- default:
- BUG();
- }
- kvm->arch.fgu[fgt] = val;
- }
- struct resx get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg)
- {
- struct resx resx;
- switch (reg) {
- case HFGRTR_EL2:
- resx = compute_reg_resx_bits(kvm, &hfgrtr_desc, 0, 0);
- break;
- case HFGWTR_EL2:
- resx = compute_reg_resx_bits(kvm, &hfgwtr_desc, 0, 0);
- break;
- case HFGITR_EL2:
- resx = compute_reg_resx_bits(kvm, &hfgitr_desc, 0, 0);
- break;
- case HDFGRTR_EL2:
- resx = compute_reg_resx_bits(kvm, &hdfgrtr_desc, 0, 0);
- break;
- case HDFGWTR_EL2:
- resx = compute_reg_resx_bits(kvm, &hdfgwtr_desc, 0, 0);
- break;
- case HAFGRTR_EL2:
- resx = compute_reg_resx_bits(kvm, &hafgrtr_desc, 0, 0);
- break;
- case HFGRTR2_EL2:
- resx = compute_reg_resx_bits(kvm, &hfgrtr2_desc, 0, 0);
- break;
- case HFGWTR2_EL2:
- resx = compute_reg_resx_bits(kvm, &hfgwtr2_desc, 0, 0);
- break;
- case HFGITR2_EL2:
- resx = compute_reg_resx_bits(kvm, &hfgitr2_desc, 0, 0);
- break;
- case HDFGRTR2_EL2:
- resx = compute_reg_resx_bits(kvm, &hdfgrtr2_desc, 0, 0);
- break;
- case HDFGWTR2_EL2:
- resx = compute_reg_resx_bits(kvm, &hdfgwtr2_desc, 0, 0);
- break;
- case HCRX_EL2:
- resx = compute_reg_resx_bits(kvm, &hcrx_desc, 0, 0);
- resx.res1 |= __HCRX_EL2_RES1;
- break;
- case HCR_EL2:
- resx = compute_reg_resx_bits(kvm, &hcr_desc, 0, 0);
- break;
- case SCTLR2_EL1:
- case SCTLR2_EL2:
- resx = compute_reg_resx_bits(kvm, &sctlr2_desc, 0, 0);
- break;
- case TCR2_EL2:
- resx = compute_reg_resx_bits(kvm, &tcr2_el2_desc, 0, 0);
- break;
- case SCTLR_EL1:
- resx = compute_reg_resx_bits(kvm, &sctlr_el1_desc, 0, 0);
- break;
- case SCTLR_EL2:
- resx = compute_reg_resx_bits(kvm, &sctlr_el2_desc, 0, 0);
- break;
- case MDCR_EL2:
- resx = compute_reg_resx_bits(kvm, &mdcr_el2_desc, 0, 0);
- break;
- case VTCR_EL2:
- resx = compute_reg_resx_bits(kvm, &vtcr_el2_desc, 0, 0);
- break;
- default:
- WARN_ON_ONCE(1);
- resx = (typeof(resx)){};
- break;
- }
- return resx;
- }
- static __always_inline struct fgt_masks *__fgt_reg_to_masks(enum vcpu_sysreg reg)
- {
- switch (reg) {
- case HFGRTR_EL2:
- return &hfgrtr_masks;
- case HFGWTR_EL2:
- return &hfgwtr_masks;
- case HFGITR_EL2:
- return &hfgitr_masks;
- case HDFGRTR_EL2:
- return &hdfgrtr_masks;
- case HDFGWTR_EL2:
- return &hdfgwtr_masks;
- case HAFGRTR_EL2:
- return &hafgrtr_masks;
- case HFGRTR2_EL2:
- return &hfgrtr2_masks;
- case HFGWTR2_EL2:
- return &hfgwtr2_masks;
- case HFGITR2_EL2:
- return &hfgitr2_masks;
- case HDFGRTR2_EL2:
- return &hdfgrtr2_masks;
- case HDFGWTR2_EL2:
- return &hdfgwtr2_masks;
- default:
- BUILD_BUG_ON(1);
- }
- }
- static __always_inline void __compute_fgt(struct kvm_vcpu *vcpu, enum vcpu_sysreg reg)
- {
- u64 fgu = vcpu->kvm->arch.fgu[__fgt_reg_to_group_id(reg)];
- struct fgt_masks *m = __fgt_reg_to_masks(reg);
- u64 clear = 0, set = 0, val = m->nmask;
- set |= fgu & m->mask;
- clear |= fgu & m->nmask;
- if (is_nested_ctxt(vcpu)) {
- u64 nested = __vcpu_sys_reg(vcpu, reg);
- set |= nested & m->mask;
- clear |= ~nested & m->nmask;
- }
- val |= set;
- val &= ~clear;
- *vcpu_fgt(vcpu, reg) = val;
- }
- static void __compute_hfgwtr(struct kvm_vcpu *vcpu)
- {
- __compute_fgt(vcpu, HFGWTR_EL2);
- if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
- *vcpu_fgt(vcpu, HFGWTR_EL2) |= HFGWTR_EL2_TCR_EL1;
- }
- static void __compute_hdfgwtr(struct kvm_vcpu *vcpu)
- {
- __compute_fgt(vcpu, HDFGWTR_EL2);
- if (is_hyp_ctxt(vcpu))
- *vcpu_fgt(vcpu, HDFGWTR_EL2) |= HDFGWTR_EL2_MDSCR_EL1;
- }
- void kvm_vcpu_load_fgt(struct kvm_vcpu *vcpu)
- {
- if (!cpus_have_final_cap(ARM64_HAS_FGT))
- return;
- __compute_fgt(vcpu, HFGRTR_EL2);
- __compute_hfgwtr(vcpu);
- __compute_fgt(vcpu, HFGITR_EL2);
- __compute_fgt(vcpu, HDFGRTR_EL2);
- __compute_hdfgwtr(vcpu);
- __compute_fgt(vcpu, HAFGRTR_EL2);
- if (!cpus_have_final_cap(ARM64_HAS_FGT2))
- return;
- __compute_fgt(vcpu, HFGRTR2_EL2);
- __compute_fgt(vcpu, HFGWTR2_EL2);
- __compute_fgt(vcpu, HFGITR2_EL2);
- __compute_fgt(vcpu, HDFGRTR2_EL2);
- __compute_fgt(vcpu, HDFGWTR2_EL2);
- }
|