Skip to content

Commit 03fb54d

Browse files
author
Marc Zyngier
committed
KVM: arm64: nv: Add support for HCRX_EL2
HCRX_EL2 has an interesting effect on HFGITR_EL2, as it conditions the traps of TLBI*nXS. Expand the FGT support to add a new Fine Grained Filter that will get checked when the instruction gets trapped, allowing the shadow register to override the trap as needed. Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Jing Zhang <jingzhangos@google.com> Link: https://lore.kernel.org/r/20230815183903.2735724-29-maz@kernel.org
1 parent a63cf31 commit 03fb54d

File tree

6 files changed

+83
-37
lines changed

6 files changed

+83
-37
lines changed

arch/arm64/include/asm/kvm_arm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@
369369
#define __HDFGWTR_EL2_MASK ~__HDFGWTR_EL2_nMASK
370370
#define __HDFGWTR_EL2_nMASK GENMASK(62, 60)
371371

372+
/* Similar definitions for HCRX_EL2 */
373+
#define __HCRX_EL2_RES0 (GENMASK(63, 16) | GENMASK(13, 12))
374+
#define __HCRX_EL2_MASK (0)
375+
#define __HCRX_EL2_nMASK (GENMASK(15, 14) | GENMASK(4, 0))
376+
372377
/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
373378
#define HPFAR_MASK (~UL(0xf))
374379
/*

arch/arm64/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ enum vcpu_sysreg {
380380
CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
381381
HSTR_EL2, /* Hypervisor System Trap Register */
382382
HACR_EL2, /* Hypervisor Auxiliary Control Register */
383+
HCRX_EL2, /* Extended Hypervisor Configuration Register */
383384
TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
384385
TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
385386
TCR_EL2, /* Translation Control Register (EL2) */

arch/arm64/kvm/emulate-nested.c

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -426,11 +426,13 @@ static const complex_condition_check ccc[] = {
426426
* [13:10] enum fgt_group_id (4 bits)
427427
* [19:14] bit number in the FGT register (6 bits)
428428
* [20] trap polarity (1 bit)
429-
* [62:21] Unused (42 bits)
429+
* [25:21] FG filter (5 bits)
430+
* [62:26] Unused (37 bits)
430431
* [63] RES0 - Must be zero, as lost on insertion in the xarray
431432
*/
432433
#define TC_CGT_BITS 10
433434
#define TC_FGT_BITS 4
435+
#define TC_FGF_BITS 5
434436

435437
union trap_config {
436438
u64 val;
@@ -439,7 +441,8 @@ union trap_config {
439441
unsigned long fgt:TC_FGT_BITS; /* Fine Grained Trap id */
440442
unsigned long bit:6; /* Bit number */
441443
unsigned long pol:1; /* Polarity */
442-
unsigned long unused:42; /* Unused, should be zero */
444+
unsigned long fgf:TC_FGF_BITS; /* Fine Grained Filter */
445+
unsigned long unused:37; /* Unused, should be zero */
443446
unsigned long mbz:1; /* Must Be Zero */
444447
};
445448
};
@@ -947,18 +950,29 @@ enum fgt_group_id {
947950
__NR_FGT_GROUP_IDS__
948951
};
949952

950-
#define SR_FGT(sr, g, b, p) \
953+
enum fg_filter_id {
954+
__NO_FGF__,
955+
HCRX_FGTnXS,
956+
957+
/* Must be last */
958+
__NR_FG_FILTER_IDS__
959+
};
960+
961+
#define SR_FGF(sr, g, b, p, f) \
951962
{ \
952963
.encoding = sr, \
953964
.end = sr, \
954965
.tc = { \
955966
.fgt = g ## _GROUP, \
956967
.bit = g ## _EL2_ ## b ## _SHIFT, \
957968
.pol = p, \
969+
.fgf = f, \
958970
}, \
959971
.line = __LINE__, \
960972
}
961973

974+
#define SR_FGT(sr, g, b, p) SR_FGF(sr, g, b, p, __NO_FGF__)
975+
962976
static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
963977
/* HFGRTR_EL2, HFGWTR_EL2 */
964978
SR_FGT(SYS_TPIDR2_EL0, HFGxTR, nTPIDR2_EL0, 0),
@@ -1062,37 +1076,37 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
10621076
SR_FGT(OP_TLBI_ASIDE1OS, HFGITR, TLBIASIDE1OS, 1),
10631077
SR_FGT(OP_TLBI_VAE1OS, HFGITR, TLBIVAE1OS, 1),
10641078
SR_FGT(OP_TLBI_VMALLE1OS, HFGITR, TLBIVMALLE1OS, 1),
1065-
/* FIXME: nXS variants must be checked against HCRX_EL2.FGTnXS */
1066-
SR_FGT(OP_TLBI_VAALE1NXS, HFGITR, TLBIVAALE1, 1),
1067-
SR_FGT(OP_TLBI_VALE1NXS, HFGITR, TLBIVALE1, 1),
1068-
SR_FGT(OP_TLBI_VAAE1NXS, HFGITR, TLBIVAAE1, 1),
1069-
SR_FGT(OP_TLBI_ASIDE1NXS, HFGITR, TLBIASIDE1, 1),
1070-
SR_FGT(OP_TLBI_VAE1NXS, HFGITR, TLBIVAE1, 1),
1071-
SR_FGT(OP_TLBI_VMALLE1NXS, HFGITR, TLBIVMALLE1, 1),
1072-
SR_FGT(OP_TLBI_RVAALE1NXS, HFGITR, TLBIRVAALE1, 1),
1073-
SR_FGT(OP_TLBI_RVALE1NXS, HFGITR, TLBIRVALE1, 1),
1074-
SR_FGT(OP_TLBI_RVAAE1NXS, HFGITR, TLBIRVAAE1, 1),
1075-
SR_FGT(OP_TLBI_RVAE1NXS, HFGITR, TLBIRVAE1, 1),
1076-
SR_FGT(OP_TLBI_RVAALE1ISNXS, HFGITR, TLBIRVAALE1IS, 1),
1077-
SR_FGT(OP_TLBI_RVALE1ISNXS, HFGITR, TLBIRVALE1IS, 1),
1078-
SR_FGT(OP_TLBI_RVAAE1ISNXS, HFGITR, TLBIRVAAE1IS, 1),
1079-
SR_FGT(OP_TLBI_RVAE1ISNXS, HFGITR, TLBIRVAE1IS, 1),
1080-
SR_FGT(OP_TLBI_VAALE1ISNXS, HFGITR, TLBIVAALE1IS, 1),
1081-
SR_FGT(OP_TLBI_VALE1ISNXS, HFGITR, TLBIVALE1IS, 1),
1082-
SR_FGT(OP_TLBI_VAAE1ISNXS, HFGITR, TLBIVAAE1IS, 1),
1083-
SR_FGT(OP_TLBI_ASIDE1ISNXS, HFGITR, TLBIASIDE1IS, 1),
1084-
SR_FGT(OP_TLBI_VAE1ISNXS, HFGITR, TLBIVAE1IS, 1),
1085-
SR_FGT(OP_TLBI_VMALLE1ISNXS, HFGITR, TLBIVMALLE1IS, 1),
1086-
SR_FGT(OP_TLBI_RVAALE1OSNXS, HFGITR, TLBIRVAALE1OS, 1),
1087-
SR_FGT(OP_TLBI_RVALE1OSNXS, HFGITR, TLBIRVALE1OS, 1),
1088-
SR_FGT(OP_TLBI_RVAAE1OSNXS, HFGITR, TLBIRVAAE1OS, 1),
1089-
SR_FGT(OP_TLBI_RVAE1OSNXS, HFGITR, TLBIRVAE1OS, 1),
1090-
SR_FGT(OP_TLBI_VAALE1OSNXS, HFGITR, TLBIVAALE1OS, 1),
1091-
SR_FGT(OP_TLBI_VALE1OSNXS, HFGITR, TLBIVALE1OS, 1),
1092-
SR_FGT(OP_TLBI_VAAE1OSNXS, HFGITR, TLBIVAAE1OS, 1),
1093-
SR_FGT(OP_TLBI_ASIDE1OSNXS, HFGITR, TLBIASIDE1OS, 1),
1094-
SR_FGT(OP_TLBI_VAE1OSNXS, HFGITR, TLBIVAE1OS, 1),
1095-
SR_FGT(OP_TLBI_VMALLE1OSNXS, HFGITR, TLBIVMALLE1OS, 1),
1079+
/* nXS variants must be checked against HCRX_EL2.FGTnXS */
1080+
SR_FGF(OP_TLBI_VAALE1NXS, HFGITR, TLBIVAALE1, 1, HCRX_FGTnXS),
1081+
SR_FGF(OP_TLBI_VALE1NXS, HFGITR, TLBIVALE1, 1, HCRX_FGTnXS),
1082+
SR_FGF(OP_TLBI_VAAE1NXS, HFGITR, TLBIVAAE1, 1, HCRX_FGTnXS),
1083+
SR_FGF(OP_TLBI_ASIDE1NXS, HFGITR, TLBIASIDE1, 1, HCRX_FGTnXS),
1084+
SR_FGF(OP_TLBI_VAE1NXS, HFGITR, TLBIVAE1, 1, HCRX_FGTnXS),
1085+
SR_FGF(OP_TLBI_VMALLE1NXS, HFGITR, TLBIVMALLE1, 1, HCRX_FGTnXS),
1086+
SR_FGF(OP_TLBI_RVAALE1NXS, HFGITR, TLBIRVAALE1, 1, HCRX_FGTnXS),
1087+
SR_FGF(OP_TLBI_RVALE1NXS, HFGITR, TLBIRVALE1, 1, HCRX_FGTnXS),
1088+
SR_FGF(OP_TLBI_RVAAE1NXS, HFGITR, TLBIRVAAE1, 1, HCRX_FGTnXS),
1089+
SR_FGF(OP_TLBI_RVAE1NXS, HFGITR, TLBIRVAE1, 1, HCRX_FGTnXS),
1090+
SR_FGF(OP_TLBI_RVAALE1ISNXS, HFGITR, TLBIRVAALE1IS, 1, HCRX_FGTnXS),
1091+
SR_FGF(OP_TLBI_RVALE1ISNXS, HFGITR, TLBIRVALE1IS, 1, HCRX_FGTnXS),
1092+
SR_FGF(OP_TLBI_RVAAE1ISNXS, HFGITR, TLBIRVAAE1IS, 1, HCRX_FGTnXS),
1093+
SR_FGF(OP_TLBI_RVAE1ISNXS, HFGITR, TLBIRVAE1IS, 1, HCRX_FGTnXS),
1094+
SR_FGF(OP_TLBI_VAALE1ISNXS, HFGITR, TLBIVAALE1IS, 1, HCRX_FGTnXS),
1095+
SR_FGF(OP_TLBI_VALE1ISNXS, HFGITR, TLBIVALE1IS, 1, HCRX_FGTnXS),
1096+
SR_FGF(OP_TLBI_VAAE1ISNXS, HFGITR, TLBIVAAE1IS, 1, HCRX_FGTnXS),
1097+
SR_FGF(OP_TLBI_ASIDE1ISNXS, HFGITR, TLBIASIDE1IS, 1, HCRX_FGTnXS),
1098+
SR_FGF(OP_TLBI_VAE1ISNXS, HFGITR, TLBIVAE1IS, 1, HCRX_FGTnXS),
1099+
SR_FGF(OP_TLBI_VMALLE1ISNXS, HFGITR, TLBIVMALLE1IS, 1, HCRX_FGTnXS),
1100+
SR_FGF(OP_TLBI_RVAALE1OSNXS, HFGITR, TLBIRVAALE1OS, 1, HCRX_FGTnXS),
1101+
SR_FGF(OP_TLBI_RVALE1OSNXS, HFGITR, TLBIRVALE1OS, 1, HCRX_FGTnXS),
1102+
SR_FGF(OP_TLBI_RVAAE1OSNXS, HFGITR, TLBIRVAAE1OS, 1, HCRX_FGTnXS),
1103+
SR_FGF(OP_TLBI_RVAE1OSNXS, HFGITR, TLBIRVAE1OS, 1, HCRX_FGTnXS),
1104+
SR_FGF(OP_TLBI_VAALE1OSNXS, HFGITR, TLBIVAALE1OS, 1, HCRX_FGTnXS),
1105+
SR_FGF(OP_TLBI_VALE1OSNXS, HFGITR, TLBIVALE1OS, 1, HCRX_FGTnXS),
1106+
SR_FGF(OP_TLBI_VAAE1OSNXS, HFGITR, TLBIVAAE1OS, 1, HCRX_FGTnXS),
1107+
SR_FGF(OP_TLBI_ASIDE1OSNXS, HFGITR, TLBIASIDE1OS, 1, HCRX_FGTnXS),
1108+
SR_FGF(OP_TLBI_VAE1OSNXS, HFGITR, TLBIVAE1OS, 1, HCRX_FGTnXS),
1109+
SR_FGF(OP_TLBI_VMALLE1OSNXS, HFGITR, TLBIVMALLE1OS, 1, HCRX_FGTnXS),
10961110
SR_FGT(OP_AT_S1E1WP, HFGITR, ATS1E1WP, 1),
10971111
SR_FGT(OP_AT_S1E1RP, HFGITR, ATS1E1RP, 1),
10981112
SR_FGT(OP_AT_S1E0W, HFGITR, ATS1E0W, 1),
@@ -1622,6 +1636,7 @@ int __init populate_nv_trap_config(void)
16221636
BUILD_BUG_ON(sizeof(union trap_config) != sizeof(void *));
16231637
BUILD_BUG_ON(__NR_CGT_GROUP_IDS__ > BIT(TC_CGT_BITS));
16241638
BUILD_BUG_ON(__NR_FGT_GROUP_IDS__ > BIT(TC_FGT_BITS));
1639+
BUILD_BUG_ON(__NR_FG_FILTER_IDS__ > BIT(TC_FGF_BITS));
16251640

16261641
for (int i = 0; i < ARRAY_SIZE(encoding_to_cgt); i++) {
16271642
const struct encoding_to_trap_config *cgt = &encoding_to_cgt[i];
@@ -1812,6 +1827,17 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
18121827

18131828
case HFGITR_GROUP:
18141829
val = sanitised_sys_reg(vcpu, HFGITR_EL2);
1830+
switch (tc.fgf) {
1831+
u64 tmp;
1832+
1833+
case __NO_FGF__:
1834+
break;
1835+
1836+
case HCRX_FGTnXS:
1837+
tmp = sanitised_sys_reg(vcpu, HCRX_EL2);
1838+
if (tmp & HCRX_EL2_FGTnXS)
1839+
tc.fgt = __NO_FGT_GROUP__;
1840+
}
18151841
break;
18161842

18171843
case __NR_FGT_GROUP_IDS__:

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,19 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
197197
vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2);
198198
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
199199

200-
if (cpus_have_final_cap(ARM64_HAS_HCX))
201-
write_sysreg_s(HCRX_GUEST_FLAGS, SYS_HCRX_EL2);
200+
if (cpus_have_final_cap(ARM64_HAS_HCX)) {
201+
u64 hcrx = HCRX_GUEST_FLAGS;
202+
if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
203+
u64 clr = 0, set = 0;
204+
205+
compute_clr_set(vcpu, HCRX_EL2, clr, set);
206+
207+
hcrx |= set;
208+
hcrx &= ~clr;
209+
}
210+
211+
write_sysreg_s(hcrx, SYS_HCRX_EL2);
212+
}
202213

203214
__activate_traps_hfgxtr(vcpu);
204215
}

arch/arm64/kvm/nested.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
117117
break;
118118

119119
case SYS_ID_AA64MMFR1_EL1:
120-
val &= (NV_FTR(MMFR1, PAN) |
120+
val &= (NV_FTR(MMFR1, HCX) |
121+
NV_FTR(MMFR1, PAN) |
121122
NV_FTR(MMFR1, LO) |
122123
NV_FTR(MMFR1, HPDS) |
123124
NV_FTR(MMFR1, VH) |

arch/arm64/kvm/sys_regs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,6 +2372,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
23722372
EL2_REG(HFGITR_EL2, access_rw, reset_val, 0),
23732373
EL2_REG(HACR_EL2, access_rw, reset_val, 0),
23742374

2375+
EL2_REG(HCRX_EL2, access_rw, reset_val, 0),
2376+
23752377
EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
23762378
EL2_REG(TTBR1_EL2, access_rw, reset_val, 0),
23772379
EL2_REG(TCR_EL2, access_rw, reset_val, TCR_EL2_RES1),

0 commit comments

Comments
 (0)