Skip to content

Commit aa98df3

Browse files
author
Marc Zyngier
committed
KVM: arm64: nv: Plumb TLBI S1E2 into system instruction dispatch
Now that we have to handle TLBI S1E2 in the core code, plumb the sysinsn dispatch code into it, so that these instructions don't just UNDEF anymore. Reviewed-by: Oliver Upton <oliver.upton@linux.dev> Link: https://lore.kernel.org/r/20250514103501.2225951-15-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 4ffa72a commit aa98df3

File tree

1 file changed

+61
-26
lines changed

1 file changed

+61
-26
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3628,11 +3628,22 @@ static void s2_mmu_tlbi_s1e1(struct kvm_s2_mmu *mmu,
36283628
WARN_ON(__kvm_tlbi_s1e2(mmu, info->va.addr, info->va.encoding));
36293629
}
36303630

3631+
static bool handle_tlbi_el2(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
3632+
const struct sys_reg_desc *r)
3633+
{
3634+
u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
3635+
3636+
if (!kvm_supported_tlbi_s1e2_op(vcpu, sys_encoding))
3637+
return undef_access(vcpu, p, r);
3638+
3639+
kvm_handle_s1e2_tlbi(vcpu, sys_encoding, p->regval);
3640+
return true;
3641+
}
3642+
36313643
static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
36323644
const struct sys_reg_desc *r)
36333645
{
36343646
u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
3635-
u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
36363647

36373648
/*
36383649
* If we're here, this is because we've trapped on a EL1 TLBI
@@ -3643,6 +3654,13 @@ static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
36433654
* - HCR_EL2.E2H == 0 : a non-VHE guest
36443655
* - HCR_EL2.{E2H,TGE} == { 1, 0 } : a VHE guest in guest mode
36453656
*
3657+
* Another possibility is that we are invalidating the EL2 context
3658+
* using EL1 instructions, but that we landed here because we need
3659+
* additional invalidation for structures that are not held in the
3660+
* CPU TLBs (such as the VNCR pseudo-TLB and its EL2 mapping). In
3661+
* that case, we are guaranteed that HCR_EL2.{E2H,TGE} == { 1, 1 }
3662+
* as we don't allow an NV-capable L1 in a nVHE configuration.
3663+
*
36463664
* We don't expect these helpers to ever be called when running
36473665
* in a vEL1 context.
36483666
*/
@@ -3652,7 +3670,13 @@ static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
36523670
if (!kvm_supported_tlbi_s1e1_op(vcpu, sys_encoding))
36533671
return undef_access(vcpu, p, r);
36543672

3655-
kvm_s2_mmu_iterate_by_vmid(vcpu->kvm, get_vmid(vttbr),
3673+
if (vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu)) {
3674+
kvm_handle_s1e2_tlbi(vcpu, sys_encoding, p->regval);
3675+
return true;
3676+
}
3677+
3678+
kvm_s2_mmu_iterate_by_vmid(vcpu->kvm,
3679+
get_vmid(__vcpu_sys_reg(vcpu, VTTBR_EL2)),
36563680
&(union tlbi_info) {
36573681
.va = {
36583682
.addr = p->regval,
@@ -3774,16 +3798,21 @@ static struct sys_reg_desc sys_insn_descs[] = {
37743798
SYS_INSN(TLBI_IPAS2LE1IS, handle_ipas2e1is),
37753799
SYS_INSN(TLBI_RIPAS2LE1IS, handle_ripas2e1is),
37763800

3777-
SYS_INSN(TLBI_ALLE2OS, undef_access),
3778-
SYS_INSN(TLBI_VAE2OS, undef_access),
3801+
SYS_INSN(TLBI_ALLE2OS, handle_tlbi_el2),
3802+
SYS_INSN(TLBI_VAE2OS, handle_tlbi_el2),
37793803
SYS_INSN(TLBI_ALLE1OS, handle_alle1is),
3780-
SYS_INSN(TLBI_VALE2OS, undef_access),
3804+
SYS_INSN(TLBI_VALE2OS, handle_tlbi_el2),
37813805
SYS_INSN(TLBI_VMALLS12E1OS, handle_vmalls12e1is),
37823806

3783-
SYS_INSN(TLBI_RVAE2IS, undef_access),
3784-
SYS_INSN(TLBI_RVALE2IS, undef_access),
3807+
SYS_INSN(TLBI_RVAE2IS, handle_tlbi_el2),
3808+
SYS_INSN(TLBI_RVALE2IS, handle_tlbi_el2),
3809+
SYS_INSN(TLBI_ALLE2IS, handle_tlbi_el2),
3810+
SYS_INSN(TLBI_VAE2IS, handle_tlbi_el2),
37853811

37863812
SYS_INSN(TLBI_ALLE1IS, handle_alle1is),
3813+
3814+
SYS_INSN(TLBI_VALE2IS, handle_tlbi_el2),
3815+
37873816
SYS_INSN(TLBI_VMALLS12E1IS, handle_vmalls12e1is),
37883817
SYS_INSN(TLBI_IPAS2E1OS, handle_ipas2e1is),
37893818
SYS_INSN(TLBI_IPAS2E1, handle_ipas2e1is),
@@ -3793,31 +3822,37 @@ static struct sys_reg_desc sys_insn_descs[] = {
37933822
SYS_INSN(TLBI_IPAS2LE1, handle_ipas2e1is),
37943823
SYS_INSN(TLBI_RIPAS2LE1, handle_ripas2e1is),
37953824
SYS_INSN(TLBI_RIPAS2LE1OS, handle_ripas2e1is),
3796-
SYS_INSN(TLBI_RVAE2OS, undef_access),
3797-
SYS_INSN(TLBI_RVALE2OS, undef_access),
3798-
SYS_INSN(TLBI_RVAE2, undef_access),
3799-
SYS_INSN(TLBI_RVALE2, undef_access),
3825+
SYS_INSN(TLBI_RVAE2OS, handle_tlbi_el2),
3826+
SYS_INSN(TLBI_RVALE2OS, handle_tlbi_el2),
3827+
SYS_INSN(TLBI_RVAE2, handle_tlbi_el2),
3828+
SYS_INSN(TLBI_RVALE2, handle_tlbi_el2),
3829+
SYS_INSN(TLBI_ALLE2, handle_tlbi_el2),
3830+
SYS_INSN(TLBI_VAE2, handle_tlbi_el2),
3831+
38003832
SYS_INSN(TLBI_ALLE1, handle_alle1is),
3833+
3834+
SYS_INSN(TLBI_VALE2, handle_tlbi_el2),
3835+
38013836
SYS_INSN(TLBI_VMALLS12E1, handle_vmalls12e1is),
38023837

38033838
SYS_INSN(TLBI_IPAS2E1ISNXS, handle_ipas2e1is),
38043839
SYS_INSN(TLBI_RIPAS2E1ISNXS, handle_ripas2e1is),
38053840
SYS_INSN(TLBI_IPAS2LE1ISNXS, handle_ipas2e1is),
38063841
SYS_INSN(TLBI_RIPAS2LE1ISNXS, handle_ripas2e1is),
38073842

3808-
SYS_INSN(TLBI_ALLE2OSNXS, undef_access),
3809-
SYS_INSN(TLBI_VAE2OSNXS, undef_access),
3843+
SYS_INSN(TLBI_ALLE2OSNXS, handle_tlbi_el2),
3844+
SYS_INSN(TLBI_VAE2OSNXS, handle_tlbi_el2),
38103845
SYS_INSN(TLBI_ALLE1OSNXS, handle_alle1is),
3811-
SYS_INSN(TLBI_VALE2OSNXS, undef_access),
3846+
SYS_INSN(TLBI_VALE2OSNXS, handle_tlbi_el2),
38123847
SYS_INSN(TLBI_VMALLS12E1OSNXS, handle_vmalls12e1is),
38133848

3814-
SYS_INSN(TLBI_RVAE2ISNXS, undef_access),
3815-
SYS_INSN(TLBI_RVALE2ISNXS, undef_access),
3816-
SYS_INSN(TLBI_ALLE2ISNXS, undef_access),
3817-
SYS_INSN(TLBI_VAE2ISNXS, undef_access),
3849+
SYS_INSN(TLBI_RVAE2ISNXS, handle_tlbi_el2),
3850+
SYS_INSN(TLBI_RVALE2ISNXS, handle_tlbi_el2),
3851+
SYS_INSN(TLBI_ALLE2ISNXS, handle_tlbi_el2),
3852+
SYS_INSN(TLBI_VAE2ISNXS, handle_tlbi_el2),
38183853

38193854
SYS_INSN(TLBI_ALLE1ISNXS, handle_alle1is),
3820-
SYS_INSN(TLBI_VALE2ISNXS, undef_access),
3855+
SYS_INSN(TLBI_VALE2ISNXS, handle_tlbi_el2),
38213856
SYS_INSN(TLBI_VMALLS12E1ISNXS, handle_vmalls12e1is),
38223857
SYS_INSN(TLBI_IPAS2E1OSNXS, handle_ipas2e1is),
38233858
SYS_INSN(TLBI_IPAS2E1NXS, handle_ipas2e1is),
@@ -3827,14 +3862,14 @@ static struct sys_reg_desc sys_insn_descs[] = {
38273862
SYS_INSN(TLBI_IPAS2LE1NXS, handle_ipas2e1is),
38283863
SYS_INSN(TLBI_RIPAS2LE1NXS, handle_ripas2e1is),
38293864
SYS_INSN(TLBI_RIPAS2LE1OSNXS, handle_ripas2e1is),
3830-
SYS_INSN(TLBI_RVAE2OSNXS, undef_access),
3831-
SYS_INSN(TLBI_RVALE2OSNXS, undef_access),
3832-
SYS_INSN(TLBI_RVAE2NXS, undef_access),
3833-
SYS_INSN(TLBI_RVALE2NXS, undef_access),
3834-
SYS_INSN(TLBI_ALLE2NXS, undef_access),
3835-
SYS_INSN(TLBI_VAE2NXS, undef_access),
3865+
SYS_INSN(TLBI_RVAE2OSNXS, handle_tlbi_el2),
3866+
SYS_INSN(TLBI_RVALE2OSNXS, handle_tlbi_el2),
3867+
SYS_INSN(TLBI_RVAE2NXS, handle_tlbi_el2),
3868+
SYS_INSN(TLBI_RVALE2NXS, handle_tlbi_el2),
3869+
SYS_INSN(TLBI_ALLE2NXS, handle_tlbi_el2),
3870+
SYS_INSN(TLBI_VAE2NXS, handle_tlbi_el2),
38363871
SYS_INSN(TLBI_ALLE1NXS, handle_alle1is),
3837-
SYS_INSN(TLBI_VALE2NXS, undef_access),
3872+
SYS_INSN(TLBI_VALE2NXS, handle_tlbi_el2),
38383873
SYS_INSN(TLBI_VMALLS12E1NXS, handle_vmalls12e1is),
38393874
};
38403875

0 commit comments

Comments
 (0)