On 11/27/23 22:56, Marc Zyngier wrote: > We have some special handling for VPIPT I-cache in critical parts > of the cache and TLB maintenance. Remove it. Reviewed-by: Anshuman Khandual <anshuman.khandual@xxxxxxx> > > Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx> > --- > arch/arm64/include/asm/kvm_mmu.h | 7 ---- > arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +- > arch/arm64/kvm/hyp/nvhe/tlb.c | 61 -------------------------------- > arch/arm64/kvm/hyp/vhe/tlb.c | 13 ------- > 4 files changed, 1 insertion(+), 82 deletions(-) > > diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h > index 49e0d4b36bd0..e3e793d0ec30 100644 > --- a/arch/arm64/include/asm/kvm_mmu.h > +++ b/arch/arm64/include/asm/kvm_mmu.h > @@ -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 > diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c > index 9d23a51d7f75..b29f15418c0a 100644 > --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c > +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c > @@ -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(). */ > diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c > index 1b265713d6be..a60fb13e2192 100644 > --- a/arch/arm64/kvm/hyp/nvhe/tlb.c > +++ b/arch/arm64/kvm/hyp/nvhe/tlb.c > @@ -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); > } > diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c > index b636b4111dbf..b32e2940df7d 100644 > --- a/arch/arm64/kvm/hyp/vhe/tlb.c > +++ b/arch/arm64/kvm/hyp/vhe/tlb.c > @@ -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); > }