KVM: arm64: Remove VPIPT I-cache handling
authorMarc Zyngier <maz@kernel.org>
Mon, 4 Dec 2023 14:36:04 +0000 (14:36 +0000)
committerWill Deacon <will@kernel.org>
Tue, 5 Dec 2023 11:38:03 +0000 (11:38 +0000)
We have some special handling for VPIPT I-cache in critical parts
of the cache and TLB maintenance. Remove it.

Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20231204143606.1806432-2-maz@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/kvm/hyp/nvhe/pkvm.c
arch/arm64/kvm/hyp/nvhe/tlb.c
arch/arm64/kvm/hyp/vhe/tlb.c

index 49e0d4b36bd009032cd2b22d2e50781214249d88..e3e793d0ec30413491839f9e060bd9e27deff227 100644 (file)
@@ -243,13 +243,6 @@ static inline size_t __invalidate_icache_max_range(void)
 
 static inline void __invalidate_icache_guest_page(void *va, size_t size)
 {
-       /*
-        * VPIPT I-cache maintenance must be done from EL2. See comment in the
-        * nVHE flavor of __kvm_tlb_flush_vmid_ipa().
-        */
-       if (icache_is_vpipt() && read_sysreg(CurrentEL) != CurrentEL_EL2)
-               return;
-
        /*
         * Blow the whole I-cache if it is aliasing (i.e. VIPT) or the
         * invalidation range exceeds our arbitrary limit on invadations by
index 9d23a51d7f7525d50558adefdc402c906ea2b82a..b29f15418c0aff6fca086747c0a7333ec78048ac 100644 (file)
@@ -12,7 +12,7 @@
 #include <nvhe/pkvm.h>
 #include <nvhe/trap_handler.h>
 
-/* Used by icache_is_vpipt(). */
+/* Used by icache_is_aliasing(). */
 unsigned long __icache_flags;
 
 /* Used by kvm_get_vttbr(). */
index 1b265713d6bede228b47a423d0f1d81a83070a5c..a60fb13e21924f4af56162687231251d8655ba04 100644 (file)
@@ -105,28 +105,6 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
        dsb(ish);
        isb();
 
-       /*
-        * If the host is running at EL1 and we have a VPIPT I-cache,
-        * then we must perform I-cache maintenance at EL2 in order for
-        * it to have an effect on the guest. Since the guest cannot hit
-        * I-cache lines allocated with a different VMID, we don't need
-        * to worry about junk out of guest reset (we nuke the I-cache on
-        * VMID rollover), but we do need to be careful when remapping
-        * executable pages for the same guest. This can happen when KSM
-        * takes a CoW fault on an executable page, copies the page into
-        * a page that was previously mapped in the guest and then needs
-        * to invalidate the guest view of the I-cache for that page
-        * from EL1. To solve this, we invalidate the entire I-cache when
-        * unmapping a page from a guest if we have a VPIPT I-cache but
-        * the host is running at EL1. As above, we could do better if
-        * we had the VA.
-        *
-        * The moral of this story is: if you have a VPIPT I-cache, then
-        * you should be running with VHE enabled.
-        */
-       if (icache_is_vpipt())
-               icache_inval_all_pou();
-
        __tlb_switch_to_host(&cxt);
 }
 
@@ -157,28 +135,6 @@ void __kvm_tlb_flush_vmid_ipa_nsh(struct kvm_s2_mmu *mmu,
        dsb(nsh);
        isb();
 
-       /*
-        * If the host is running at EL1 and we have a VPIPT I-cache,
-        * then we must perform I-cache maintenance at EL2 in order for
-        * it to have an effect on the guest. Since the guest cannot hit
-        * I-cache lines allocated with a different VMID, we don't need
-        * to worry about junk out of guest reset (we nuke the I-cache on
-        * VMID rollover), but we do need to be careful when remapping
-        * executable pages for the same guest. This can happen when KSM
-        * takes a CoW fault on an executable page, copies the page into
-        * a page that was previously mapped in the guest and then needs
-        * to invalidate the guest view of the I-cache for that page
-        * from EL1. To solve this, we invalidate the entire I-cache when
-        * unmapping a page from a guest if we have a VPIPT I-cache but
-        * the host is running at EL1. As above, we could do better if
-        * we had the VA.
-        *
-        * The moral of this story is: if you have a VPIPT I-cache, then
-        * you should be running with VHE enabled.
-        */
-       if (icache_is_vpipt())
-               icache_inval_all_pou();
-
        __tlb_switch_to_host(&cxt);
 }
 
@@ -205,10 +161,6 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
        dsb(ish);
        isb();
 
-       /* See the comment in __kvm_tlb_flush_vmid_ipa() */
-       if (icache_is_vpipt())
-               icache_inval_all_pou();
-
        __tlb_switch_to_host(&cxt);
 }
 
@@ -246,18 +198,5 @@ void __kvm_flush_vm_context(void)
        /* Same remark as in __tlb_switch_to_guest() */
        dsb(ish);
        __tlbi(alle1is);
-
-       /*
-        * VIPT and PIPT caches are not affected by VMID, so no maintenance
-        * is necessary across a VMID rollover.
-        *
-        * VPIPT caches constrain lookup and maintenance to the active VMID,
-        * so we need to invalidate lines with a stale VMID to avoid an ABA
-        * race after multiple rollovers.
-        *
-        */
-       if (icache_is_vpipt())
-               asm volatile("ic ialluis");
-
        dsb(ish);
 }
index b636b4111dbf504e18b68ef6bacd2c5f3418ef40..b32e2940df7dc83418fe39c4095998033326262e 100644 (file)
@@ -216,18 +216,5 @@ void __kvm_flush_vm_context(void)
 {
        dsb(ishst);
        __tlbi(alle1is);
-
-       /*
-        * VIPT and PIPT caches are not affected by VMID, so no maintenance
-        * is necessary across a VMID rollover.
-        *
-        * VPIPT caches constrain lookup and maintenance to the active VMID,
-        * so we need to invalidate lines with a stale VMID to avoid an ABA
-        * race after multiple rollovers.
-        *
-        */
-       if (icache_is_vpipt())
-               asm volatile("ic ialluis");
-
        dsb(ish);
 }