In order to allow the elision of TLB maintenance operations on unmap, add a new flag (KVM_UNMAP_ELIDE_TBLI) that a caller can use to indicate that TLB invalidation is not required. Nobody is passing this flag yet, hence no functional change. Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx> --- virt/kvm/arm/mmu.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index ebf8c87cc007..4399866842dc 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c @@ -37,6 +37,7 @@ static unsigned long io_map_base; /* Flags controlling S2 unmapping */ #define KVM_UNMAP_ELIDE_CMO (1UL << 0) +#define KVM_UNMAP_ELIDE_TBLI (1UL << 1) #define KVM_S2PTE_FLAG_IS_IOMAP (1UL << 0) #define KVM_S2_FLAG_LOGGING_ACTIVE (1UL << 1) @@ -160,7 +161,8 @@ static void clear_stage2_pgd_entry(struct kvm *kvm, pgd_t *pgd, phys_addr_t addr { pud_t *pud_table __maybe_unused = stage2_pud_offset(kvm, pgd, 0UL); stage2_pgd_clear(kvm, pgd); - kvm_tlb_flush_vmid_ipa(kvm, addr); + if (!(flags & KVM_UNMAP_ELIDE_TBLI)) + kvm_tlb_flush_vmid_ipa(kvm, addr); stage2_pud_free(kvm, pud_table); put_page(virt_to_page(pgd)); } @@ -171,7 +173,8 @@ static void clear_stage2_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr pmd_t *pmd_table __maybe_unused = stage2_pmd_offset(kvm, pud, 0); VM_BUG_ON(stage2_pud_huge(kvm, *pud)); stage2_pud_clear(kvm, pud); - kvm_tlb_flush_vmid_ipa(kvm, addr); + if (!(flags & KVM_UNMAP_ELIDE_TBLI)) + kvm_tlb_flush_vmid_ipa(kvm, addr); stage2_pmd_free(kvm, pmd_table); put_page(virt_to_page(pud)); } @@ -182,7 +185,8 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr pte_t *pte_table = pte_offset_kernel(pmd, 0); VM_BUG_ON(pmd_thp_or_huge(*pmd)); pmd_clear(pmd); - kvm_tlb_flush_vmid_ipa(kvm, addr); + if (!(flags & KVM_UNMAP_ELIDE_TBLI)) + kvm_tlb_flush_vmid_ipa(kvm, addr); free_page((unsigned long)pte_table); put_page(virt_to_page(pmd)); } @@ -253,7 +257,8 @@ static void unmap_stage2_ptes(struct kvm *kvm, pmd_t *pmd, pte_t old_pte = *pte; kvm_set_pte(pte, __pte(0)); - kvm_tlb_flush_vmid_ipa(kvm, addr); + if (!(flags & KVM_UNMAP_ELIDE_TBLI)) + kvm_tlb_flush_vmid_ipa(kvm, addr); /* No need to invalidate the cache for device mappings */ if (!kvm_is_device_pfn(pte_pfn(old_pte)) && @@ -283,7 +288,8 @@ static void unmap_stage2_pmds(struct kvm *kvm, pud_t *pud, pmd_t old_pmd = *pmd; pmd_clear(pmd); - kvm_tlb_flush_vmid_ipa(kvm, addr); + if (!(flags & KVM_UNMAP_ELIDE_TBLI)) + kvm_tlb_flush_vmid_ipa(kvm, addr); if (!(flags & KVM_UNMAP_ELIDE_CMO)) kvm_flush_dcache_pmd(old_pmd); @@ -314,7 +320,8 @@ static void unmap_stage2_puds(struct kvm *kvm, pgd_t *pgd, pud_t old_pud = *pud; stage2_pud_clear(kvm, pud); - kvm_tlb_flush_vmid_ipa(kvm, addr); + if (!(flags & KVM_UNMAP_ELIDE_TBLI)) + kvm_tlb_flush_vmid_ipa(kvm, addr); if (!(flags & KVM_UNMAP_ELIDE_CMO)) kvm_flush_dcache_pud(old_pud); put_page(virt_to_page(pud)); -- 2.20.1