When userspace unmaps a VMA backing a memslot, the corresponding stage 2
address range gets unmapped via the MMU notifiers. This makes it possible
to get stage 2 faults on a locked memslot, which might not be what
userspace wants because the purpose of locking a memslot is to avoid stage
2 faults in the first place.
Addresses being unmapped from stage 2 can happen from other reasons too,
like bugs in the implementation of the lock memslot API, however unlikely
that might seem.
Let's try to make debugging easier by printing a warning when this happens.
Signed-off-by: Alexandru Elisei <[email protected]>
---
arch/arm64/kvm/mmu.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 3ab8eba808ae..d66d89c18045 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1298,6 +1298,27 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
/* Userspace should not be able to register out-of-bounds IPAs */
VM_BUG_ON(fault_ipa >= kvm_phys_size(vcpu->kvm));
+ if (memslot_is_locked(memslot)) {
+ const char *fault_type_str;
+
+ if (kvm_vcpu_trap_is_exec_fault(vcpu))
+ goto handle_fault;
+
+ if (fault_status == FSC_ACCESS)
+ fault_type_str = "access";
+ else if (write_fault && (memslot->arch.flags & KVM_MEMSLOT_LOCK_WRITE))
+ fault_type_str = "write";
+ else if (!write_fault)
+ fault_type_str = "read";
+ else
+ goto handle_fault;
+
+ kvm_warn_ratelimited("Unexpected L2 %s fault on locked memslot %d: IPA=%#llx, ESR_EL2=%#08x]\n",
+ fault_type_str, memslot->id, fault_ipa,
+ kvm_vcpu_get_esr(vcpu));
+ }
+
+handle_fault:
if (fault_status == FSC_ACCESS) {
handle_access_fault(vcpu, fault_ipa);
ret = 1;
--
2.33.0