@@ -3628,11 +3628,22 @@ static void s2_mmu_tlbi_s1e1(struct kvm_s2_mmu *mmu,
3628
3628
WARN_ON (__kvm_tlbi_s1e2 (mmu , info -> va .addr , info -> va .encoding ));
3629
3629
}
3630
3630
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
+
3631
3643
static bool handle_tlbi_el1 (struct kvm_vcpu * vcpu , struct sys_reg_params * p ,
3632
3644
const struct sys_reg_desc * r )
3633
3645
{
3634
3646
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 );
3636
3647
3637
3648
/*
3638
3649
* 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,
3643
3654
* - HCR_EL2.E2H == 0 : a non-VHE guest
3644
3655
* - HCR_EL2.{E2H,TGE} == { 1, 0 } : a VHE guest in guest mode
3645
3656
*
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
+ *
3646
3664
* We don't expect these helpers to ever be called when running
3647
3665
* in a vEL1 context.
3648
3666
*/
@@ -3652,7 +3670,13 @@ static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
3652
3670
if (!kvm_supported_tlbi_s1e1_op (vcpu , sys_encoding ))
3653
3671
return undef_access (vcpu , p , r );
3654
3672
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 )),
3656
3680
& (union tlbi_info ) {
3657
3681
.va = {
3658
3682
.addr = p -> regval ,
@@ -3774,16 +3798,21 @@ static struct sys_reg_desc sys_insn_descs[] = {
3774
3798
SYS_INSN (TLBI_IPAS2LE1IS , handle_ipas2e1is ),
3775
3799
SYS_INSN (TLBI_RIPAS2LE1IS , handle_ripas2e1is ),
3776
3800
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 ),
3779
3803
SYS_INSN (TLBI_ALLE1OS , handle_alle1is ),
3780
- SYS_INSN (TLBI_VALE2OS , undef_access ),
3804
+ SYS_INSN (TLBI_VALE2OS , handle_tlbi_el2 ),
3781
3805
SYS_INSN (TLBI_VMALLS12E1OS , handle_vmalls12e1is ),
3782
3806
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 ),
3785
3811
3786
3812
SYS_INSN (TLBI_ALLE1IS , handle_alle1is ),
3813
+
3814
+ SYS_INSN (TLBI_VALE2IS , handle_tlbi_el2 ),
3815
+
3787
3816
SYS_INSN (TLBI_VMALLS12E1IS , handle_vmalls12e1is ),
3788
3817
SYS_INSN (TLBI_IPAS2E1OS , handle_ipas2e1is ),
3789
3818
SYS_INSN (TLBI_IPAS2E1 , handle_ipas2e1is ),
@@ -3793,31 +3822,37 @@ static struct sys_reg_desc sys_insn_descs[] = {
3793
3822
SYS_INSN (TLBI_IPAS2LE1 , handle_ipas2e1is ),
3794
3823
SYS_INSN (TLBI_RIPAS2LE1 , handle_ripas2e1is ),
3795
3824
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
+
3800
3832
SYS_INSN (TLBI_ALLE1 , handle_alle1is ),
3833
+
3834
+ SYS_INSN (TLBI_VALE2 , handle_tlbi_el2 ),
3835
+
3801
3836
SYS_INSN (TLBI_VMALLS12E1 , handle_vmalls12e1is ),
3802
3837
3803
3838
SYS_INSN (TLBI_IPAS2E1ISNXS , handle_ipas2e1is ),
3804
3839
SYS_INSN (TLBI_RIPAS2E1ISNXS , handle_ripas2e1is ),
3805
3840
SYS_INSN (TLBI_IPAS2LE1ISNXS , handle_ipas2e1is ),
3806
3841
SYS_INSN (TLBI_RIPAS2LE1ISNXS , handle_ripas2e1is ),
3807
3842
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 ),
3810
3845
SYS_INSN (TLBI_ALLE1OSNXS , handle_alle1is ),
3811
- SYS_INSN (TLBI_VALE2OSNXS , undef_access ),
3846
+ SYS_INSN (TLBI_VALE2OSNXS , handle_tlbi_el2 ),
3812
3847
SYS_INSN (TLBI_VMALLS12E1OSNXS , handle_vmalls12e1is ),
3813
3848
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 ),
3818
3853
3819
3854
SYS_INSN (TLBI_ALLE1ISNXS , handle_alle1is ),
3820
- SYS_INSN (TLBI_VALE2ISNXS , undef_access ),
3855
+ SYS_INSN (TLBI_VALE2ISNXS , handle_tlbi_el2 ),
3821
3856
SYS_INSN (TLBI_VMALLS12E1ISNXS , handle_vmalls12e1is ),
3822
3857
SYS_INSN (TLBI_IPAS2E1OSNXS , handle_ipas2e1is ),
3823
3858
SYS_INSN (TLBI_IPAS2E1NXS , handle_ipas2e1is ),
@@ -3827,14 +3862,14 @@ static struct sys_reg_desc sys_insn_descs[] = {
3827
3862
SYS_INSN (TLBI_IPAS2LE1NXS , handle_ipas2e1is ),
3828
3863
SYS_INSN (TLBI_RIPAS2LE1NXS , handle_ripas2e1is ),
3829
3864
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 ),
3836
3871
SYS_INSN (TLBI_ALLE1NXS , handle_alle1is ),
3837
- SYS_INSN (TLBI_VALE2NXS , undef_access ),
3872
+ SYS_INSN (TLBI_VALE2NXS , handle_tlbi_el2 ),
3838
3873
SYS_INSN (TLBI_VMALLS12E1NXS , handle_vmalls12e1is ),
3839
3874
};
3840
3875
0 commit comments