@@ -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+
36313643static 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