Skip to content

Commit cd08d32

Browse files
author
Marc Zyngier
committed
KVM: arm64: Unify UNDEF injection helpers
We currently have two helpers (undef_access() and trap_undef()) that do exactly the same thing: inject an UNDEF and return 'false' (as an indication that PC should not be incremented). We definitely could do with one less. Given that undef_access() is used 80ish times, while trap_undef() is only used 30 times, the latter loses the battle and is immediately sacrificed. We also have a large number of instances where undef_access() is open-coded. Let's also convert those. Reviewed-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 4a999a1 commit cd08d32

File tree

1 file changed

+51
-81
lines changed

1 file changed

+51
-81
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 51 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ static bool bad_trap(struct kvm_vcpu *vcpu,
6161
{
6262
WARN_ONCE(1, "Unexpected %s\n", msg);
6363
print_sys_reg_instr(params);
64-
kvm_inject_undefined(vcpu);
65-
return false;
64+
return undef_access(vcpu, params, r);
6665
}
6766

6867
static bool read_from_write_only(struct kvm_vcpu *vcpu,
@@ -353,10 +352,8 @@ static bool access_dcgsw(struct kvm_vcpu *vcpu,
353352
struct sys_reg_params *p,
354353
const struct sys_reg_desc *r)
355354
{
356-
if (!kvm_has_mte(vcpu->kvm)) {
357-
kvm_inject_undefined(vcpu);
358-
return false;
359-
}
355+
if (!kvm_has_mte(vcpu->kvm))
356+
return undef_access(vcpu, p, r);
360357

361358
/* Treat MTE S/W ops as we treat the classic ones: with contempt */
362359
return access_dcsw(vcpu, p, r);
@@ -393,10 +390,8 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
393390
u64 val, mask, shift;
394391

395392
if (reg_to_encoding(r) == SYS_TCR2_EL1 &&
396-
!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, TCRX, IMP)) {
397-
kvm_inject_undefined(vcpu);
398-
return false;
399-
}
393+
!kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, TCRX, IMP))
394+
return undef_access(vcpu, p, r);
400395

401396
BUG_ON(!p->is_write);
402397

@@ -443,10 +438,8 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
443438
{
444439
bool g1;
445440

446-
if (!kvm_has_gicv3(vcpu->kvm)) {
447-
kvm_inject_undefined(vcpu);
448-
return false;
449-
}
441+
if (!kvm_has_gicv3(vcpu->kvm))
442+
return undef_access(vcpu, p, r);
450443

451444
if (!p->is_write)
452445
return read_from_write_only(vcpu, p, r);
@@ -511,14 +504,6 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
511504
return read_zero(vcpu, p);
512505
}
513506

514-
static bool trap_undef(struct kvm_vcpu *vcpu,
515-
struct sys_reg_params *p,
516-
const struct sys_reg_desc *r)
517-
{
518-
kvm_inject_undefined(vcpu);
519-
return false;
520-
}
521-
522507
/*
523508
* ARMv8.1 mandates at least a trivial LORegion implementation, where all the
524509
* RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
@@ -531,10 +516,8 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
531516
{
532517
u32 sr = reg_to_encoding(r);
533518

534-
if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, LO, IMP)) {
535-
kvm_inject_undefined(vcpu);
536-
return false;
537-
}
519+
if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, LO, IMP))
520+
return undef_access(vcpu, p, r);
538521

539522
if (p->is_write && sr == SYS_LORID_EL1)
540523
return write_to_read_only(vcpu, p, r);
@@ -1267,10 +1250,8 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
12671250
const struct sys_reg_desc *r)
12681251
{
12691252
if (p->is_write) {
1270-
if (!vcpu_mode_priv(vcpu)) {
1271-
kvm_inject_undefined(vcpu);
1272-
return false;
1273-
}
1253+
if (!vcpu_mode_priv(vcpu))
1254+
return undef_access(vcpu, p, r);
12741255

12751256
__vcpu_sys_reg(vcpu, PMUSERENR_EL0) =
12761257
p->regval & ARMV8_PMU_USERENR_MASK;
@@ -1412,8 +1393,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
14121393
break;
14131394
default:
14141395
print_sys_reg_msg(p, "%s", "Unhandled trapped timer register");
1415-
kvm_inject_undefined(vcpu);
1416-
return false;
1396+
return undef_access(vcpu, p, r);
14171397
}
14181398

14191399
if (p->is_write)
@@ -2309,7 +2289,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
23092289
// DBGDTR[TR]X_EL0 share the same encoding
23102290
{ SYS_DESC(SYS_DBGDTRTX_EL0), trap_raz_wi },
23112291

2312-
{ SYS_DESC(SYS_DBGVCR32_EL2), trap_undef, reset_val, DBGVCR32_EL2, 0 },
2292+
{ SYS_DESC(SYS_DBGVCR32_EL2), undef_access, reset_val, DBGVCR32_EL2, 0 },
23132293

23142294
{ SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1 },
23152295

@@ -2780,7 +2760,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
27802760
EL2_REG_VNCR(VTTBR_EL2, reset_val, 0),
27812761
EL2_REG_VNCR(VTCR_EL2, reset_val, 0),
27822762

2783-
{ SYS_DESC(SYS_DACR32_EL2), trap_undef, reset_unknown, DACR32_EL2 },
2763+
{ SYS_DESC(SYS_DACR32_EL2), undef_access, reset_unknown, DACR32_EL2 },
27842764
EL2_REG_VNCR(HDFGRTR_EL2, reset_val, 0),
27852765
EL2_REG_VNCR(HDFGWTR_EL2, reset_val, 0),
27862766
EL2_REG_VNCR(HAFGRTR_EL2, reset_val, 0),
@@ -2798,11 +2778,11 @@ static const struct sys_reg_desc sys_reg_descs[] = {
27982778
{ SYS_DESC(SYS_SPSR_fiq), .access = trap_raz_wi,
27992779
.visibility = hidden_user_visibility },
28002780

2801-
{ SYS_DESC(SYS_IFSR32_EL2), trap_undef, reset_unknown, IFSR32_EL2 },
2781+
{ SYS_DESC(SYS_IFSR32_EL2), undef_access, reset_unknown, IFSR32_EL2 },
28022782
EL2_REG(AFSR0_EL2, access_rw, reset_val, 0),
28032783
EL2_REG(AFSR1_EL2, access_rw, reset_val, 0),
28042784
EL2_REG_REDIR(ESR_EL2, reset_val, 0),
2805-
{ SYS_DESC(SYS_FPEXC32_EL2), trap_undef, reset_val, FPEXC32_EL2, 0x700 },
2785+
{ SYS_DESC(SYS_FPEXC32_EL2), undef_access, reset_val, FPEXC32_EL2, 0x700 },
28062786

28072787
EL2_REG_REDIR(FAR_EL2, reset_val, 0),
28082788
EL2_REG(HPFAR_EL2, access_rw, reset_val, 0),
@@ -2812,7 +2792,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
28122792

28132793
EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
28142794
EL2_REG(RVBAR_EL2, access_rw, reset_val, 0),
2815-
{ SYS_DESC(SYS_RMR_EL2), trap_undef },
2795+
{ SYS_DESC(SYS_RMR_EL2), undef_access },
28162796

28172797
EL2_REG_VNCR(ICH_HCR_EL2, reset_val, 0),
28182798

@@ -2848,10 +2828,8 @@ static bool handle_alle1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
28482828
{
28492829
u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
28502830

2851-
if (!kvm_supported_tlbi_s12_op(vcpu, sys_encoding)) {
2852-
kvm_inject_undefined(vcpu);
2853-
return false;
2854-
}
2831+
if (!kvm_supported_tlbi_s12_op(vcpu, sys_encoding))
2832+
return undef_access(vcpu, p, r);
28552833

28562834
write_lock(&vcpu->kvm->mmu_lock);
28572835

@@ -2920,10 +2898,8 @@ static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
29202898
u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
29212899
u64 limit, vttbr;
29222900

2923-
if (!kvm_supported_tlbi_s12_op(vcpu, sys_encoding)) {
2924-
kvm_inject_undefined(vcpu);
2925-
return false;
2926-
}
2901+
if (!kvm_supported_tlbi_s12_op(vcpu, sys_encoding))
2902+
return undef_access(vcpu, p, r);
29272903

29282904
vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
29292905
limit = BIT_ULL(kvm_get_pa_bits(vcpu->kvm));
@@ -2948,10 +2924,8 @@ static bool handle_ripas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
29482924
u64 base, range, tg, num, scale;
29492925
int shift;
29502926

2951-
if (!kvm_supported_tlbi_ipas2_op(vcpu, sys_encoding)) {
2952-
kvm_inject_undefined(vcpu);
2953-
return false;
2954-
}
2927+
if (!kvm_supported_tlbi_ipas2_op(vcpu, sys_encoding))
2928+
return undef_access(vcpu, p, r);
29552929

29562930
/*
29572931
* Because the shadow S2 structure doesn't necessarily reflect that
@@ -3019,10 +2993,8 @@ static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
30192993
u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
30202994
u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
30212995

3022-
if (!kvm_supported_tlbi_ipas2_op(vcpu, sys_encoding)) {
3023-
kvm_inject_undefined(vcpu);
3024-
return false;
3025-
}
2996+
if (!kvm_supported_tlbi_ipas2_op(vcpu, sys_encoding))
2997+
return undef_access(vcpu, p, r);
30262998

30272999
kvm_s2_mmu_iterate_by_vmid(vcpu->kvm, get_vmid(vttbr),
30283000
&(union tlbi_info) {
@@ -3062,10 +3034,8 @@ static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
30623034

30633035
WARN_ON(!vcpu_is_el2(vcpu));
30643036

3065-
if (!kvm_supported_tlbi_s1e1_op(vcpu, sys_encoding)) {
3066-
kvm_inject_undefined(vcpu);
3067-
return false;
3068-
}
3037+
if (!kvm_supported_tlbi_s1e1_op(vcpu, sys_encoding))
3038+
return undef_access(vcpu, p, r);
30693039

30703040
kvm_s2_mmu_iterate_by_vmid(vcpu->kvm, get_vmid(vttbr),
30713041
&(union tlbi_info) {
@@ -3173,14 +3143,14 @@ static struct sys_reg_desc sys_insn_descs[] = {
31733143
SYS_INSN(TLBI_IPAS2LE1IS, handle_ipas2e1is),
31743144
SYS_INSN(TLBI_RIPAS2LE1IS, handle_ripas2e1is),
31753145

3176-
SYS_INSN(TLBI_ALLE2OS, trap_undef),
3177-
SYS_INSN(TLBI_VAE2OS, trap_undef),
3146+
SYS_INSN(TLBI_ALLE2OS, undef_access),
3147+
SYS_INSN(TLBI_VAE2OS, undef_access),
31783148
SYS_INSN(TLBI_ALLE1OS, handle_alle1is),
3179-
SYS_INSN(TLBI_VALE2OS, trap_undef),
3149+
SYS_INSN(TLBI_VALE2OS, undef_access),
31803150
SYS_INSN(TLBI_VMALLS12E1OS, handle_vmalls12e1is),
31813151

3182-
SYS_INSN(TLBI_RVAE2IS, trap_undef),
3183-
SYS_INSN(TLBI_RVALE2IS, trap_undef),
3152+
SYS_INSN(TLBI_RVAE2IS, undef_access),
3153+
SYS_INSN(TLBI_RVALE2IS, undef_access),
31843154

31853155
SYS_INSN(TLBI_ALLE1IS, handle_alle1is),
31863156
SYS_INSN(TLBI_VMALLS12E1IS, handle_vmalls12e1is),
@@ -3192,10 +3162,10 @@ static struct sys_reg_desc sys_insn_descs[] = {
31923162
SYS_INSN(TLBI_IPAS2LE1, handle_ipas2e1is),
31933163
SYS_INSN(TLBI_RIPAS2LE1, handle_ripas2e1is),
31943164
SYS_INSN(TLBI_RIPAS2LE1OS, handle_ripas2e1is),
3195-
SYS_INSN(TLBI_RVAE2OS, trap_undef),
3196-
SYS_INSN(TLBI_RVALE2OS, trap_undef),
3197-
SYS_INSN(TLBI_RVAE2, trap_undef),
3198-
SYS_INSN(TLBI_RVALE2, trap_undef),
3165+
SYS_INSN(TLBI_RVAE2OS, undef_access),
3166+
SYS_INSN(TLBI_RVALE2OS, undef_access),
3167+
SYS_INSN(TLBI_RVAE2, undef_access),
3168+
SYS_INSN(TLBI_RVALE2, undef_access),
31993169
SYS_INSN(TLBI_ALLE1, handle_alle1is),
32003170
SYS_INSN(TLBI_VMALLS12E1, handle_vmalls12e1is),
32013171

@@ -3204,19 +3174,19 @@ static struct sys_reg_desc sys_insn_descs[] = {
32043174
SYS_INSN(TLBI_IPAS2LE1ISNXS, handle_ipas2e1is),
32053175
SYS_INSN(TLBI_RIPAS2LE1ISNXS, handle_ripas2e1is),
32063176

3207-
SYS_INSN(TLBI_ALLE2OSNXS, trap_undef),
3208-
SYS_INSN(TLBI_VAE2OSNXS, trap_undef),
3177+
SYS_INSN(TLBI_ALLE2OSNXS, undef_access),
3178+
SYS_INSN(TLBI_VAE2OSNXS, undef_access),
32093179
SYS_INSN(TLBI_ALLE1OSNXS, handle_alle1is),
3210-
SYS_INSN(TLBI_VALE2OSNXS, trap_undef),
3180+
SYS_INSN(TLBI_VALE2OSNXS, undef_access),
32113181
SYS_INSN(TLBI_VMALLS12E1OSNXS, handle_vmalls12e1is),
32123182

3213-
SYS_INSN(TLBI_RVAE2ISNXS, trap_undef),
3214-
SYS_INSN(TLBI_RVALE2ISNXS, trap_undef),
3215-
SYS_INSN(TLBI_ALLE2ISNXS, trap_undef),
3216-
SYS_INSN(TLBI_VAE2ISNXS, trap_undef),
3183+
SYS_INSN(TLBI_RVAE2ISNXS, undef_access),
3184+
SYS_INSN(TLBI_RVALE2ISNXS, undef_access),
3185+
SYS_INSN(TLBI_ALLE2ISNXS, undef_access),
3186+
SYS_INSN(TLBI_VAE2ISNXS, undef_access),
32173187

32183188
SYS_INSN(TLBI_ALLE1ISNXS, handle_alle1is),
3219-
SYS_INSN(TLBI_VALE2ISNXS, trap_undef),
3189+
SYS_INSN(TLBI_VALE2ISNXS, undef_access),
32203190
SYS_INSN(TLBI_VMALLS12E1ISNXS, handle_vmalls12e1is),
32213191
SYS_INSN(TLBI_IPAS2E1OSNXS, handle_ipas2e1is),
32223192
SYS_INSN(TLBI_IPAS2E1NXS, handle_ipas2e1is),
@@ -3226,14 +3196,14 @@ static struct sys_reg_desc sys_insn_descs[] = {
32263196
SYS_INSN(TLBI_IPAS2LE1NXS, handle_ipas2e1is),
32273197
SYS_INSN(TLBI_RIPAS2LE1NXS, handle_ripas2e1is),
32283198
SYS_INSN(TLBI_RIPAS2LE1OSNXS, handle_ripas2e1is),
3229-
SYS_INSN(TLBI_RVAE2OSNXS, trap_undef),
3230-
SYS_INSN(TLBI_RVALE2OSNXS, trap_undef),
3231-
SYS_INSN(TLBI_RVAE2NXS, trap_undef),
3232-
SYS_INSN(TLBI_RVALE2NXS, trap_undef),
3233-
SYS_INSN(TLBI_ALLE2NXS, trap_undef),
3234-
SYS_INSN(TLBI_VAE2NXS, trap_undef),
3199+
SYS_INSN(TLBI_RVAE2OSNXS, undef_access),
3200+
SYS_INSN(TLBI_RVALE2OSNXS, undef_access),
3201+
SYS_INSN(TLBI_RVAE2NXS, undef_access),
3202+
SYS_INSN(TLBI_RVALE2NXS, undef_access),
3203+
SYS_INSN(TLBI_ALLE2NXS, undef_access),
3204+
SYS_INSN(TLBI_VAE2NXS, undef_access),
32353205
SYS_INSN(TLBI_ALLE1NXS, handle_alle1is),
3236-
SYS_INSN(TLBI_VALE2NXS, trap_undef),
3206+
SYS_INSN(TLBI_VALE2NXS, undef_access),
32373207
SYS_INSN(TLBI_VMALLS12E1NXS, handle_vmalls12e1is),
32383208
};
32393209

0 commit comments

Comments
 (0)