Skip to content

Commit fef3acf

Browse files
author
Marc Zyngier
committed
Merge branch kvm-arm64/fgt-masks into kvmarm-master/next
* kvm-arm64/fgt-masks: (43 commits) : . : Large rework of the way KVM deals with trap bits in conjunction with : the CPU feature registers. It now draws a direct link between which : the feature set, the system registers that need to UNDEF to match : the configuration and bits that need to behave as RES0 or RES1 in : the trap registers that are visible to the guest. : : Best of all, these definitions are mostly automatically generated : from the JSON description published by ARM under a permissive : license. : . KVM: arm64: Handle TSB CSYNC traps KVM: arm64: Add FGT descriptors for FEAT_FGT2 KVM: arm64: Allow sysreg ranges for FGT descriptors KVM: arm64: Add context-switch for FEAT_FGT2 registers KVM: arm64: Add trap routing for FEAT_FGT2 registers KVM: arm64: Add sanitisation for FEAT_FGT2 registers KVM: arm64: Add FEAT_FGT2 registers to the VNCR page KVM: arm64: Use HCR_EL2 feature map to drive fixed-value bits KVM: arm64: Use HCRX_EL2 feature map to drive fixed-value bits KVM: arm64: Allow kvm_has_feat() to take variable arguments KVM: arm64: Use FGT feature maps to drive RES0 bits KVM: arm64: Validate FGT register descriptions against RES0 masks KVM: arm64: Switch to table-driven FGU configuration KVM: arm64: Handle PSB CSYNC traps KVM: arm64: Use KVM-specific HCRX_EL2 RES0 mask KVM: arm64: Remove hand-crafted masks for FGT registers KVM: arm64: Use computed FGT masks to setup FGT registers KVM: arm64: Propagate FGT masks to the nVHE hypervisor KVM: arm64: Unconditionally configure fine-grain traps KVM: arm64: Use computed masks as sanitisers for FGT registers ... Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents 6eb0ed9 + 98dbe56 commit fef3acf

File tree

20 files changed

+2895
-711
lines changed

20 files changed

+2895
-711
lines changed

arch/arm64/include/asm/el2_setup.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,25 +213,25 @@
213213
cbz x1, .Lskip_debug_fgt_\@
214214

215215
/* Disable nVHE traps of TPIDR2 and SMPRI */
216-
orr x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK
217-
orr x0, x0, #HFGxTR_EL2_nTPIDR2_EL0_MASK
216+
orr x0, x0, #HFGRTR_EL2_nSMPRI_EL1_MASK
217+
orr x0, x0, #HFGRTR_EL2_nTPIDR2_EL0_MASK
218218

219219
.Lskip_debug_fgt_\@:
220220
mrs_s x1, SYS_ID_AA64MMFR3_EL1
221221
ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
222222
cbz x1, .Lskip_pie_fgt_\@
223223

224224
/* Disable trapping of PIR_EL1 / PIRE0_EL1 */
225-
orr x0, x0, #HFGxTR_EL2_nPIR_EL1
226-
orr x0, x0, #HFGxTR_EL2_nPIRE0_EL1
225+
orr x0, x0, #HFGRTR_EL2_nPIR_EL1
226+
orr x0, x0, #HFGRTR_EL2_nPIRE0_EL1
227227

228228
.Lskip_pie_fgt_\@:
229229
mrs_s x1, SYS_ID_AA64MMFR3_EL1
230230
ubfx x1, x1, #ID_AA64MMFR3_EL1_S1POE_SHIFT, #4
231231
cbz x1, .Lskip_poe_fgt_\@
232232

233233
/* Disable trapping of POR_EL0 */
234-
orr x0, x0, #HFGxTR_EL2_nPOR_EL0
234+
orr x0, x0, #HFGRTR_EL2_nPOR_EL0
235235

236236
.Lskip_poe_fgt_\@:
237237
/* GCS depends on PIE so we don't check it if PIE is absent */
@@ -240,8 +240,8 @@
240240
cbz x1, .Lset_fgt_\@
241241

242242
/* Disable traps of access to GCS registers at EL0 and EL1 */
243-
orr x0, x0, #HFGxTR_EL2_nGCS_EL1_MASK
244-
orr x0, x0, #HFGxTR_EL2_nGCS_EL0_MASK
243+
orr x0, x0, #HFGRTR_EL2_nGCS_EL1_MASK
244+
orr x0, x0, #HFGRTR_EL2_nGCS_EL0_MASK
245245

246246
.Lset_fgt_\@:
247247
msr_s SYS_HFGRTR_EL2, x0

arch/arm64/include/asm/esr.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
#define ESR_ELx_EC_FP_ASIMD UL(0x07)
2121
#define ESR_ELx_EC_CP10_ID UL(0x08) /* EL2 only */
2222
#define ESR_ELx_EC_PAC UL(0x09) /* EL2 and above */
23-
/* Unallocated EC: 0x0A - 0x0B */
23+
#define ESR_ELx_EC_OTHER UL(0x0A)
24+
/* Unallocated EC: 0x0B */
2425
#define ESR_ELx_EC_CP14_64 UL(0x0C)
2526
#define ESR_ELx_EC_BTI UL(0x0D)
2627
#define ESR_ELx_EC_ILL UL(0x0E)
@@ -181,6 +182,13 @@
181182
#define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
182183
#define ESR_ELx_xVC_IMM_MASK ((UL(1) << 16) - 1)
183184

185+
/* ISS definitions for LD64B/ST64B/{T,P}SBCSYNC instructions */
186+
#define ESR_ELx_ISS_OTHER_ST64BV (0)
187+
#define ESR_ELx_ISS_OTHER_ST64BV0 (1)
188+
#define ESR_ELx_ISS_OTHER_LDST64B (2)
189+
#define ESR_ELx_ISS_OTHER_TSBCSYNC (3)
190+
#define ESR_ELx_ISS_OTHER_PSBCSYNC (4)
191+
184192
#define DISR_EL1_IDS (UL(1) << 24)
185193
/*
186194
* DISR_EL1 and ESR_ELx share the bottom 13 bits, but the RES0 bits may mean

arch/arm64/include/asm/kvm_arm.h

Lines changed: 76 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -12,67 +12,70 @@
1212
#include <asm/sysreg.h>
1313
#include <asm/types.h>
1414

15-
/* Hyp Configuration Register (HCR) bits */
16-
17-
#define HCR_TID5 (UL(1) << 58)
18-
#define HCR_DCT (UL(1) << 57)
19-
#define HCR_ATA_SHIFT 56
20-
#define HCR_ATA (UL(1) << HCR_ATA_SHIFT)
21-
#define HCR_TTLBOS (UL(1) << 55)
22-
#define HCR_TTLBIS (UL(1) << 54)
23-
#define HCR_ENSCXT (UL(1) << 53)
24-
#define HCR_TOCU (UL(1) << 52)
25-
#define HCR_AMVOFFEN (UL(1) << 51)
26-
#define HCR_TICAB (UL(1) << 50)
27-
#define HCR_TID4 (UL(1) << 49)
28-
#define HCR_FIEN (UL(1) << 47)
29-
#define HCR_FWB (UL(1) << 46)
30-
#define HCR_NV2 (UL(1) << 45)
31-
#define HCR_AT (UL(1) << 44)
32-
#define HCR_NV1 (UL(1) << 43)
33-
#define HCR_NV (UL(1) << 42)
34-
#define HCR_API (UL(1) << 41)
35-
#define HCR_APK (UL(1) << 40)
36-
#define HCR_TEA (UL(1) << 37)
37-
#define HCR_TERR (UL(1) << 36)
38-
#define HCR_TLOR (UL(1) << 35)
39-
#define HCR_E2H (UL(1) << 34)
40-
#define HCR_ID (UL(1) << 33)
41-
#define HCR_CD (UL(1) << 32)
42-
#define HCR_RW_SHIFT 31
43-
#define HCR_RW (UL(1) << HCR_RW_SHIFT)
44-
#define HCR_TRVM (UL(1) << 30)
45-
#define HCR_HCD (UL(1) << 29)
46-
#define HCR_TDZ (UL(1) << 28)
47-
#define HCR_TGE (UL(1) << 27)
48-
#define HCR_TVM (UL(1) << 26)
49-
#define HCR_TTLB (UL(1) << 25)
50-
#define HCR_TPU (UL(1) << 24)
51-
#define HCR_TPC (UL(1) << 23) /* HCR_TPCP if FEAT_DPB */
52-
#define HCR_TSW (UL(1) << 22)
53-
#define HCR_TACR (UL(1) << 21)
54-
#define HCR_TIDCP (UL(1) << 20)
55-
#define HCR_TSC (UL(1) << 19)
56-
#define HCR_TID3 (UL(1) << 18)
57-
#define HCR_TID2 (UL(1) << 17)
58-
#define HCR_TID1 (UL(1) << 16)
59-
#define HCR_TID0 (UL(1) << 15)
60-
#define HCR_TWE (UL(1) << 14)
61-
#define HCR_TWI (UL(1) << 13)
62-
#define HCR_DC (UL(1) << 12)
63-
#define HCR_BSU (3 << 10)
64-
#define HCR_BSU_IS (UL(1) << 10)
65-
#define HCR_FB (UL(1) << 9)
66-
#define HCR_VSE (UL(1) << 8)
67-
#define HCR_VI (UL(1) << 7)
68-
#define HCR_VF (UL(1) << 6)
69-
#define HCR_AMO (UL(1) << 5)
70-
#define HCR_IMO (UL(1) << 4)
71-
#define HCR_FMO (UL(1) << 3)
72-
#define HCR_PTW (UL(1) << 2)
73-
#define HCR_SWIO (UL(1) << 1)
74-
#define HCR_VM (UL(1) << 0)
75-
#define HCR_RES0 ((UL(1) << 48) | (UL(1) << 39))
15+
/*
16+
* Because I'm terribly lazy and that repainting the whole of the KVM
17+
* code with the proper names is a pain, use a helper to map the names
18+
* inherited from AArch32 with the new fancy nomenclature. One day...
19+
*/
20+
#define __HCR(x) HCR_EL2_##x
21+
22+
#define HCR_TID5 __HCR(TID5)
23+
#define HCR_DCT __HCR(DCT)
24+
#define HCR_ATA_SHIFT __HCR(ATA_SHIFT)
25+
#define HCR_ATA __HCR(ATA)
26+
#define HCR_TTLBOS __HCR(TTLBOS)
27+
#define HCR_TTLBIS __HCR(TTLBIS)
28+
#define HCR_ENSCXT __HCR(EnSCXT)
29+
#define HCR_TOCU __HCR(TOCU)
30+
#define HCR_AMVOFFEN __HCR(AMVOFFEN)
31+
#define HCR_TICAB __HCR(TICAB)
32+
#define HCR_TID4 __HCR(TID4)
33+
#define HCR_FIEN __HCR(FIEN)
34+
#define HCR_FWB __HCR(FWB)
35+
#define HCR_NV2 __HCR(NV2)
36+
#define HCR_AT __HCR(AT)
37+
#define HCR_NV1 __HCR(NV1)
38+
#define HCR_NV __HCR(NV)
39+
#define HCR_API __HCR(API)
40+
#define HCR_APK __HCR(APK)
41+
#define HCR_TEA __HCR(TEA)
42+
#define HCR_TERR __HCR(TERR)
43+
#define HCR_TLOR __HCR(TLOR)
44+
#define HCR_E2H __HCR(E2H)
45+
#define HCR_ID __HCR(ID)
46+
#define HCR_CD __HCR(CD)
47+
#define HCR_RW __HCR(RW)
48+
#define HCR_TRVM __HCR(TRVM)
49+
#define HCR_HCD __HCR(HCD)
50+
#define HCR_TDZ __HCR(TDZ)
51+
#define HCR_TGE __HCR(TGE)
52+
#define HCR_TVM __HCR(TVM)
53+
#define HCR_TTLB __HCR(TTLB)
54+
#define HCR_TPU __HCR(TPU)
55+
#define HCR_TPC __HCR(TPCP)
56+
#define HCR_TSW __HCR(TSW)
57+
#define HCR_TACR __HCR(TACR)
58+
#define HCR_TIDCP __HCR(TIDCP)
59+
#define HCR_TSC __HCR(TSC)
60+
#define HCR_TID3 __HCR(TID3)
61+
#define HCR_TID2 __HCR(TID2)
62+
#define HCR_TID1 __HCR(TID1)
63+
#define HCR_TID0 __HCR(TID0)
64+
#define HCR_TWE __HCR(TWE)
65+
#define HCR_TWI __HCR(TWI)
66+
#define HCR_DC __HCR(DC)
67+
#define HCR_BSU __HCR(BSU)
68+
#define HCR_BSU_IS __HCR(BSU_IS)
69+
#define HCR_FB __HCR(FB)
70+
#define HCR_VSE __HCR(VSE)
71+
#define HCR_VI __HCR(VI)
72+
#define HCR_VF __HCR(VF)
73+
#define HCR_AMO __HCR(AMO)
74+
#define HCR_IMO __HCR(IMO)
75+
#define HCR_FMO __HCR(FMO)
76+
#define HCR_PTW __HCR(PTW)
77+
#define HCR_SWIO __HCR(SWIO)
78+
#define HCR_VM __HCR(VM)
7679

7780
/*
7881
* The bits we set in HCR:
@@ -313,56 +316,19 @@
313316
GENMASK(15, 0))
314317

315318
/*
316-
* FGT register definitions
317-
*
318-
* RES0 and polarity masks as of DDI0487J.a, to be updated as needed.
319-
* We're not using the generated masks as they are usually ahead of
320-
* the published ARM ARM, which we use as a reference.
321-
*
322-
* Once we get to a point where the two describe the same thing, we'll
323-
* merge the definitions. One day.
324-
*/
325-
#define __HFGRTR_EL2_RES0 HFGxTR_EL2_RES0
326-
#define __HFGRTR_EL2_MASK GENMASK(49, 0)
327-
#define __HFGRTR_EL2_nMASK ~(__HFGRTR_EL2_RES0 | __HFGRTR_EL2_MASK)
328-
329-
/*
330-
* The HFGWTR bits are a subset of HFGRTR bits. To ensure we don't miss any
331-
* future additions, define __HFGWTR* macros relative to __HFGRTR* ones.
319+
* Polarity masks for HCRX_EL2, limited to the bits that we know about
320+
* at this point in time. It doesn't mean that we actually *handle*
321+
* them, but that at least those that are not advertised to a guest
322+
* will be RES0 for that guest.
332323
*/
333-
#define __HFGRTR_ONLY_MASK (BIT(46) | BIT(42) | BIT(40) | BIT(28) | \
334-
GENMASK(26, 25) | BIT(21) | BIT(18) | \
335-
GENMASK(15, 14) | GENMASK(10, 9) | BIT(2))
336-
#define __HFGWTR_EL2_RES0 (__HFGRTR_EL2_RES0 | __HFGRTR_ONLY_MASK)
337-
#define __HFGWTR_EL2_MASK (__HFGRTR_EL2_MASK & ~__HFGRTR_ONLY_MASK)
338-
#define __HFGWTR_EL2_nMASK ~(__HFGWTR_EL2_RES0 | __HFGWTR_EL2_MASK)
339-
340-
#define __HFGITR_EL2_RES0 HFGITR_EL2_RES0
341-
#define __HFGITR_EL2_MASK (BIT(62) | BIT(60) | GENMASK(54, 0))
342-
#define __HFGITR_EL2_nMASK ~(__HFGITR_EL2_RES0 | __HFGITR_EL2_MASK)
343-
344-
#define __HDFGRTR_EL2_RES0 HDFGRTR_EL2_RES0
345-
#define __HDFGRTR_EL2_MASK (BIT(63) | GENMASK(58, 50) | GENMASK(48, 43) | \
346-
GENMASK(41, 40) | GENMASK(37, 22) | \
347-
GENMASK(19, 9) | GENMASK(7, 0))
348-
#define __HDFGRTR_EL2_nMASK ~(__HDFGRTR_EL2_RES0 | __HDFGRTR_EL2_MASK)
349-
350-
#define __HDFGWTR_EL2_RES0 HDFGWTR_EL2_RES0
351-
#define __HDFGWTR_EL2_MASK (GENMASK(57, 52) | GENMASK(50, 48) | \
352-
GENMASK(46, 44) | GENMASK(42, 41) | \
353-
GENMASK(37, 35) | GENMASK(33, 31) | \
354-
GENMASK(29, 23) | GENMASK(21, 10) | \
355-
GENMASK(8, 7) | GENMASK(5, 0))
356-
#define __HDFGWTR_EL2_nMASK ~(__HDFGWTR_EL2_RES0 | __HDFGWTR_EL2_MASK)
357-
358-
#define __HAFGRTR_EL2_RES0 HAFGRTR_EL2_RES0
359-
#define __HAFGRTR_EL2_MASK (GENMASK(49, 17) | GENMASK(4, 0))
360-
#define __HAFGRTR_EL2_nMASK ~(__HAFGRTR_EL2_RES0 | __HAFGRTR_EL2_MASK)
361-
362-
/* Similar definitions for HCRX_EL2 */
363-
#define __HCRX_EL2_RES0 HCRX_EL2_RES0
364-
#define __HCRX_EL2_MASK (BIT(6))
365-
#define __HCRX_EL2_nMASK ~(__HCRX_EL2_RES0 | __HCRX_EL2_MASK)
324+
#define __HCRX_EL2_MASK (BIT_ULL(6))
325+
#define __HCRX_EL2_nMASK (GENMASK_ULL(24, 14) | \
326+
GENMASK_ULL(11, 7) | \
327+
GENMASK_ULL(5, 0))
328+
#define __HCRX_EL2_RES0 ~(__HCRX_EL2_nMASK | __HCRX_EL2_MASK)
329+
#define __HCRX_EL2_RES1 ~(__HCRX_EL2_nMASK | \
330+
__HCRX_EL2_MASK | \
331+
__HCRX_EL2_RES0)
366332

367333
/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
368334
#define HPFAR_MASK (~UL(0xf))

arch/arm64/include/asm/kvm_host.h

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,17 @@ struct kvm_sysreg_masks;
273273

274274
enum fgt_group_id {
275275
__NO_FGT_GROUP__,
276-
HFGxTR_GROUP,
276+
HFGRTR_GROUP,
277+
HFGWTR_GROUP = HFGRTR_GROUP,
277278
HDFGRTR_GROUP,
278279
HDFGWTR_GROUP = HDFGRTR_GROUP,
279280
HFGITR_GROUP,
280281
HAFGRTR_GROUP,
282+
HFGRTR2_GROUP,
283+
HFGWTR2_GROUP = HFGRTR2_GROUP,
284+
HDFGRTR2_GROUP,
285+
HDFGWTR2_GROUP = HDFGRTR2_GROUP,
286+
HFGITR2_GROUP,
281287

282288
/* Must be last */
283289
__NR_FGT_GROUP_IDS__
@@ -561,6 +567,11 @@ enum vcpu_sysreg {
561567
VNCR(HDFGRTR_EL2),
562568
VNCR(HDFGWTR_EL2),
563569
VNCR(HAFGRTR_EL2),
570+
VNCR(HFGRTR2_EL2),
571+
VNCR(HFGWTR2_EL2),
572+
VNCR(HFGITR2_EL2),
573+
VNCR(HDFGRTR2_EL2),
574+
VNCR(HDFGWTR2_EL2),
564575

565576
VNCR(CNTVOFF_EL2),
566577
VNCR(CNTV_CVAL_EL0),
@@ -606,6 +617,37 @@ struct kvm_sysreg_masks {
606617
} mask[NR_SYS_REGS - __SANITISED_REG_START__];
607618
};
608619

620+
struct fgt_masks {
621+
const char *str;
622+
u64 mask;
623+
u64 nmask;
624+
u64 res0;
625+
};
626+
627+
extern struct fgt_masks hfgrtr_masks;
628+
extern struct fgt_masks hfgwtr_masks;
629+
extern struct fgt_masks hfgitr_masks;
630+
extern struct fgt_masks hdfgrtr_masks;
631+
extern struct fgt_masks hdfgwtr_masks;
632+
extern struct fgt_masks hafgrtr_masks;
633+
extern struct fgt_masks hfgrtr2_masks;
634+
extern struct fgt_masks hfgwtr2_masks;
635+
extern struct fgt_masks hfgitr2_masks;
636+
extern struct fgt_masks hdfgrtr2_masks;
637+
extern struct fgt_masks hdfgwtr2_masks;
638+
639+
extern struct fgt_masks kvm_nvhe_sym(hfgrtr_masks);
640+
extern struct fgt_masks kvm_nvhe_sym(hfgwtr_masks);
641+
extern struct fgt_masks kvm_nvhe_sym(hfgitr_masks);
642+
extern struct fgt_masks kvm_nvhe_sym(hdfgrtr_masks);
643+
extern struct fgt_masks kvm_nvhe_sym(hdfgwtr_masks);
644+
extern struct fgt_masks kvm_nvhe_sym(hafgrtr_masks);
645+
extern struct fgt_masks kvm_nvhe_sym(hfgrtr2_masks);
646+
extern struct fgt_masks kvm_nvhe_sym(hfgwtr2_masks);
647+
extern struct fgt_masks kvm_nvhe_sym(hfgitr2_masks);
648+
extern struct fgt_masks kvm_nvhe_sym(hdfgrtr2_masks);
649+
extern struct fgt_masks kvm_nvhe_sym(hdfgwtr2_masks);
650+
609651
struct kvm_cpu_context {
610652
struct user_pt_regs regs; /* sp = sp_el0 */
611653

@@ -1552,12 +1594,16 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
15521594
kvm_cmp_feat_signed(kvm, id, fld, op, limit) : \
15531595
kvm_cmp_feat_unsigned(kvm, id, fld, op, limit))
15541596

1555-
#define kvm_has_feat(kvm, id, fld, limit) \
1597+
#define __kvm_has_feat(kvm, id, fld, limit) \
15561598
kvm_cmp_feat(kvm, id, fld, >=, limit)
15571599

1558-
#define kvm_has_feat_enum(kvm, id, fld, val) \
1600+
#define kvm_has_feat(kvm, ...) __kvm_has_feat(kvm, __VA_ARGS__)
1601+
1602+
#define __kvm_has_feat_enum(kvm, id, fld, val) \
15591603
kvm_cmp_feat_unsigned(kvm, id, fld, ==, val)
15601604

1605+
#define kvm_has_feat_enum(kvm, ...) __kvm_has_feat_enum(kvm, __VA_ARGS__)
1606+
15611607
#define kvm_has_feat_range(kvm, id, fld, min, max) \
15621608
(kvm_cmp_feat(kvm, id, fld, >=, min) && \
15631609
kvm_cmp_feat(kvm, id, fld, <=, max))
@@ -1595,4 +1641,9 @@ static inline bool kvm_arch_has_irq_bypass(void)
15951641
return true;
15961642
}
15971643

1644+
void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt);
1645+
void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *res1);
1646+
void check_feature_map(void);
1647+
1648+
15981649
#endif /* __ARM64_KVM_HOST_H__ */

0 commit comments

Comments
 (0)