[2/3] KVM: arm64: Clear possible conflict aborts

Message ID 20230602170147.1541355-3-coltonlewis@google.com
State New
Headers
Series Relax break-before-make use with FEAT_BBM |

Commit Message

Colton Lewis June 2, 2023, 5:01 p.m. UTC
  Clear possible conflict aborts by TLB invalidation targeted to the
address that caused the abort.

Making use of FEAT_BBM Level 2 creates the possibility of a conflict
abort when translating addresses, where multiple entries exist in the
TLB for a single input address.

Signed-off-by: Colton Lewis <coltonlewis@google.com>
---
 arch/arm64/include/asm/esr.h | 1 +
 arch/arm64/kvm/mmu.c         | 6 ++++++
 2 files changed, 7 insertions(+)

--
2.41.0.rc0.172.g3f132b7071-goog
  

Comments

Oliver Upton June 9, 2023, 3:44 p.m. UTC | #1
On Fri, Jun 02, 2023 at 05:01:46PM +0000, Colton Lewis wrote:
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 7a68398517c95..96b950f20c8d0 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1591,6 +1591,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>  		return 1;
>  	}
> 
> +	if (fault_status == ESR_ELx_FSC_CONFLICT) {
> +		/* We could be at any level. 0 covers all levels. */
> +		__kvm_tlb_flush_vmid_ipa(vcpu->arch.hw_mmu, fault_ipa, 0);
> +		return 1;
> +	}
> +

This does not match the architecture. Please read DDI0487J D8.14.3
"TLB maintenance due to TLB conflict", which tells you exactly how to
resolve the conflict. TL; DR: TLBI by address is _not_ guaranteed to
invalidate duplicate TLB entries. vmalls12e1 is your friend.

The conflicting TLB entries are local to the CPU that took the abort, so
you don't need to do any broadcast.

--
Thanks,
Oliver
  

Patch

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 8487aec9b6587..41336cfa19ff3 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -123,6 +123,7 @@ 
 #define ESR_ELx_FSC_SECC_TTW1	(0x1d)
 #define ESR_ELx_FSC_SECC_TTW2	(0x1e)
 #define ESR_ELx_FSC_SECC_TTW3	(0x1f)
+#define ESR_ELx_FSC_CONFLICT	(0x30)

 /* ISS field definitions for Data Aborts */
 #define ESR_ELx_ISV_SHIFT	(24)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 7a68398517c95..96b950f20c8d0 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1591,6 +1591,12 @@  int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		return 1;
 	}

+	if (fault_status == ESR_ELx_FSC_CONFLICT) {
+		/* We could be at any level. 0 covers all levels. */
+		__kvm_tlb_flush_vmid_ipa(vcpu->arch.hw_mmu, fault_ipa, 0);
+		return 1;
+	}
+
 	trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu),
 			      kvm_vcpu_get_hfar(vcpu), fault_ipa);