All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steffen Eiden <seiden@linux.ibm.com>
To: Marc Zyngier <maz@kernel.org>, Oliver Upton <oupton@kernel.org>,
	Fuad Tabba <fuad.tabba@linux.dev>,
	Joey Gouly <joey.gouly@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Zenghui Yu <yuzenghui@huawei.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Andreas Grapentin <gra@linux.ibm.com>,
	Christian Borntraeger <borntraeger@linux.ibm.com>,
	Janosch Frank <frankja@linux.ibm.com>,
	Claudio Imbrenda <imbrenda@linux.ibm.com>,
	David Hildenbrand <david@kernel.org>,
	Heiko Carstens <hca@linux.ibm.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	Alexander Gordeev <agordeev@linux.ibm.com>,
	Sven Schnelle <svens@linux.ibm.com>,
	Friedrich Welter <fritz@linux.ibm.com>,
	Gautam Gala <ggala@linux.ibm.com>,
	Hariharan Mari <hari55@linux.ibm.com>,
	Hendrik Brueckner <brueckner@linux.ibm.com>,
	Nico Boehr <nrb@linux.ibm.com>,
	Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
	Arnd Bergmann <arnd@arndb.de>,
	Paolo Bonzini <pbonzini@redhat.com>
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	linux-s390@vger.kernel.org, Steffen Eiden <seiden@linux.ibm.com>
Subject: [PATCH v3 20/23] KVM: s390: arm64: Finalize page fault handling
Date: Fri, 06 Nov 2026 17:07:53 +0100	[thread overview]
Message-ID: <20261106-sysreg-v3-20-75e95980fb10@linux.ibm.com> (raw)
In-Reply-To: <20261106-sysreg-v3-0-75e95980fb10@linux.ibm.com>

Replace the temporary -ENOEXEC returns of the arm64-on-s390 page fault
handling with exception injection into the guest, mirroring arm64's
kvm_handle_guest_abort().

Translation faults beyond the physical address range  are injected as an
address size fault, while faults falling between the VM's IPA size and
that range are injected as a synchronous external abort. Instruction
aborts and stage-1 walk faults on host addresses that back no guest page
are injected as synchronous external aborts as well, and a
PGM-addressing from the fault-in path is injected as an address size
fault, the closest arm64 equivalent. Injected faults return 1 so the
vCPU re-enters the guest with the pending exception instead of exiting
to userspace.

Co-developed-by: Andreas Grapentin <gra@linux.ibm.com>
Signed-off-by: Andreas Grapentin <gra@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 arch/s390/include/asm/kvm_host_arm64.h |  1 +
 arch/s390/kvm/arm64/arm.c              |  6 +++
 arch/s390/kvm/arm64/mmu.c              | 74 +++++++++++++++++++++++-----------
 arch/s390/kvm/arm64/sys_regs.c         |  4 ++
 4 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/arch/s390/include/asm/kvm_host_arm64.h b/arch/s390/include/asm/kvm_host_arm64.h
index 79549434a1d6..20f51cf9ce37 100644
--- a/arch/s390/include/asm/kvm_host_arm64.h
+++ b/arch/s390/include/asm/kvm_host_arm64.h
@@ -426,5 +426,6 @@ static inline bool vgic_host_has_gicv5(void)
 }
 
 void kvm_adjust_pc(struct kvm_vcpu *vcpu);
+size_t kvm_parange_to_address_sanitized(u32 id_parange);
 
 #endif /* ASM_KVM_HOST_ARM64_H */
diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c
index 91e9f4a75ce7..b5a0f8c1e9a4 100644
--- a/arch/s390/kvm/arm64/arm.c
+++ b/arch/s390/kvm/arm64/arm.c
@@ -63,9 +63,15 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 
 static u64 kvm_max_guest_address(void)
 {
+	u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
+	u64 id_pa_addr;
 	u64 max_addr;
 
+	id_pa_addr = kvm_parange_to_address_sanitized(
+		SYS_FIELD_GET(ID_AA64MMFR0_EL1, PARANGE, mmfr0));
+
 	max_addr = min_t(u64, TASK_SIZE_MAX, sclp.hamax);
+	max_addr = min_t(u64, max_addr, id_pa_addr);
 	max_addr = max_t(u64, max_addr, SZ_1G - 1);
 	return ALIGN_DOWN(max_addr + 1, SZ_1G) - 1;
 }
diff --git a/arch/s390/kvm/arm64/mmu.c b/arch/s390/kvm/arm64/mmu.c
index 31e0d036896f..7a6f6ba326c1 100644
--- a/arch/s390/kvm/arm64/mmu.c
+++ b/arch/s390/kvm/arm64/mmu.c
@@ -16,7 +16,8 @@ static inline bool kvm_s390_cur_gmap_fault_is_write(struct kvm_vcpu *vcpu)
 /*
  * user_mem_abort() - handle a dat fault for the gmap of a vcpu
  *
- * Return: 0 on success, < 0 in case of error.
+ * Return: 0 if the fault was resolved, 1 if an exception was injected into
+ * the guest; the caller resumes the vCPU in both cases. < 0 in case of error.
  * Context: The mm lock must not be held before calling. May sleep.
  */
 static int user_mem_abort(struct kvm_vcpu *vcpu, gpa_t fault_ipa,
@@ -32,12 +33,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, gpa_t fault_ipa,
 	ret = kvm_s390_faultin_gfn(vcpu, NULL, &f);
 	if (ret <= 0)
 		return ret;
-	if (ret == PGM_ADDRESSING)
+	if (ret == PGM_ADDRESSING) {
 		/*
-		 * Without the relevant sysregs we cannot do anything for now.
-		 * Go back to userspace with an error. TODO sysreg handling
+		 * There is no page with the requested address. Inject size fault
+		 * which is the closest arm match to PGM-addressing
 		 */
-		return -ENOEXEC;
+		kvm_inject_size_fault(vcpu);
+		return 1;
+	}
 	KVM_BUG_ON(ret, vcpu->kvm);
 	return -EINVAL;
 }
@@ -70,6 +73,35 @@ static int kvm_handle_pic(struct kvm_vcpu *vcpu, bool *translation)
 	return 0;
 }
 
+size_t kvm_parange_to_address_sanitized(u32 id_parange)
+{
+	static u32 ranges_map[8] = {
+		[ID_AA64MMFR0_EL1_PARANGE_32] = 32,
+		[ID_AA64MMFR0_EL1_PARANGE_36] = 36,
+		[ID_AA64MMFR0_EL1_PARANGE_40] = 40,
+		[ID_AA64MMFR0_EL1_PARANGE_42] = 42,
+		[ID_AA64MMFR0_EL1_PARANGE_44] = 44,
+		[ID_AA64MMFR0_EL1_PARANGE_48] = 48,
+		[ID_AA64MMFR0_EL1_PARANGE_52] = 52,
+		[ID_AA64MMFR0_EL1_PARANGE_56] = 56,
+	};
+	u32 parange;
+
+	/*
+	 * Future values must be higher than we know already.
+	 * See ARM DDI 0487C.a. Return a safe limit.
+	 */
+	parange = ranges_map[min(id_parange, ID_AA64MMFR0_EL1_PARANGE_56)];
+	return BIT_ULL(parange);
+}
+
+static size_t kvm_get_pa_address(struct kvm *kvm)
+{
+	u32 id_parange = get_idreg_field_enum(kvm, ID_AA64MMFR0_EL1, PARANGE);
+
+	return kvm_parange_to_address_sanitized(id_parange);
+}
+
 int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 {
 	struct kvm_memory_slot *memslot;
@@ -98,16 +130,17 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	}
 
 	if (translation) {
-		/*
-		 * For both cases:
-		 * Without the relevant sysregs we cannot do anything for now.
-		 * Go back to userspace with an error. TODO sysreg handling
-		 */
-		if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit()))
-			return -ENOEXEC;
+		/* Beyond the PA range programmed for the guest */
+		if (fault_ipa >= kvm_get_pa_address(vcpu->kvm)) {
+			kvm_inject_size_fault(vcpu);
+			return 1;
+		}
 
-		if (fault_ipa >= vcpu->kvm->arch.guest_phys_size)
-			return -ENOEXEC;
+		/* Falls between the IPA range and the PA range? */
+		if (fault_ipa >= vcpu->kvm->arch.guest_phys_size) {
+			fault_ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu));
+			return kvm_inject_sea(vcpu, is_iabt, fault_ipa);
+		}
 	}
 
 	trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu),
@@ -121,23 +154,18 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	hva = gfn_to_hva_memslot_prot(memslot, gfn, &writable);
 	write_fault = kvm_s390_cur_gmap_fault_is_write(vcpu);
 	if (kvm_is_error_hva(hva) || (write_fault && !writable)) {
-		ret = -ENOEXEC;
 		/*
 		 * The guest has put either its instructions or its page-tables
 		 * somewhere it shouldn't have. Userspace won't be able to do
 		 * anything about this (there's no syndrome for a start).
-		 *
-		 * Without the relevant sysregs we cannot do anything for now.
-		 * Go back to userspace with an error. TODO sysreg handling
 		 */
-		if (is_iabt)
+		if (is_iabt) {
+			ret = kvm_inject_sea_iabt(vcpu, kvm_vcpu_get_hfar(vcpu));
 			goto out_unlock;
+		}
 
 		if (kvm_vcpu_abt_iss1tw(vcpu)) {
-			/*
-			 * Without the relevant sysregs we cannot do anything for now.
-			 * Go back to userspace with an error. TODO sysreg handling
-			 */
+			ret = kvm_inject_sea_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
 			goto out_unlock;
 		}
 
diff --git a/arch/s390/kvm/arm64/sys_regs.c b/arch/s390/kvm/arm64/sys_regs.c
index 417a05ce9015..951a02d89fc5 100644
--- a/arch/s390/kvm/arm64/sys_regs.c
+++ b/arch/s390/kvm/arm64/sys_regs.c
@@ -317,6 +317,10 @@ static int arm64_check_features(struct kvm_vcpu *vcpu,
 		if (SYS_FIELD_GET(ID_AA64MMFR0_EL1, PARANGE, val) >
 		    SYS_FIELD_GET(ID_AA64MMFR0_EL1, PARANGE, host_val))
 			return -E2BIG;
+		if (kvm_parange_to_address_sanitized(
+			    SYS_FIELD_GET(ID_AA64MMFR0_EL1, PARANGE, val)) <
+		    vcpu->kvm->arch.guest_phys_size)
+			return -E2BIG;
 		break;
 	case SYS_CTR_EL0:
 		/* forbid upgrading from VIPT to PIPT */

-- 
2.56.0


  parent reply	other threads:[~2026-11-06 16:08 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-06 16:07 [PATCH v3 00/23] KVM: arm64 on s390 System Register Handling Steffen Eiden
2026-11-06 16:07 ` [PATCH v3 01/23] KVM: arm64: Refactor idreg caching into dedicated structure Steffen Eiden
2026-11-06 16:23   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 02/23] KVM: arm64: Extract number of sys_reg_desc into a constant Steffen Eiden
2026-11-06 16:25   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 03/23] arm64: sysreg: Convert OSLSR to automatic register generation Steffen Eiden
2026-11-06 16:34   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 04/23] arm64: Prepare headers for sysreg sharing with s390 Steffen Eiden
2026-11-06 16:38   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 05/23] arm64: Share system register related headers and functions " Steffen Eiden
2026-11-06 16:58   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 06/23] KVM: s390: arm64: Prepare for sharing arm64 SVE and ftr-reg code Steffen Eiden
2026-11-06 17:05   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 07/23] KVM: arm64: Prepare sys_regs.c for sharing with s390 Steffen Eiden
2026-11-06 17:06   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 08/23] KVM: arm64: Share system register code " Steffen Eiden
2026-11-06 17:18   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 09/23] s390: tools: Share arm64/kvm headers Steffen Eiden
2026-11-06 17:20   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 10/23] s390: Add range check asm macro Steffen Eiden
2026-11-06 17:23   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 11/23] s390: Read/write ARM system registers Steffen Eiden
2026-11-06 17:34   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 12/23] s390: Query arm guest time Steffen Eiden
2026-11-06 17:37   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 13/23] KVM: s390: arm64: Query Available Arm features Steffen Eiden
2026-11-06 17:45   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 14/23] KVM: s390: arm64: Verify machine feature set before loading Steffen Eiden
2026-11-06 17:49   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 15/23] KVM: s390: arm64: Implement feature sanitisation Steffen Eiden
2026-11-06 18:17   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 16/23] KVM: s390: arm64: Implement arm sysreg managing infrastructure Steffen Eiden
2026-11-06 18:45   ` sashiko-bot
2026-11-07 14:08   ` Andreas Grapentin
2026-11-06 16:07 ` [PATCH v3 17/23] KVM: s390: arm64: Integrate sysreg into the host Steffen Eiden
2026-11-06 19:18   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 18/23] KVM: s390: arm64: Use QAAF init save area Steffen Eiden
2026-11-06 19:23   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 19/23] KVM: s390: arm64: Implement exception injection Steffen Eiden
2026-11-06 19:50   ` sashiko-bot
2026-11-06 16:07 ` Steffen Eiden [this message]
2026-11-06 20:10   ` [PATCH v3 20/23] KVM: s390: arm64: Finalize page fault handling sashiko-bot
2026-11-06 16:07 ` [PATCH v3 21/23] KVM: s390: arm64: Implement SVE for arm guests Steffen Eiden
2026-11-06 20:24   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 22/23] KVM: s390: arm64: Promote PTRAUTH capability Steffen Eiden
2026-11-06 20:33   ` sashiko-bot
2026-11-06 16:07 ` [PATCH v3 23/23] s390: Report AEF features to sysfs Steffen Eiden
2026-11-06 20:43   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261106-sysreg-v3-20-75e95980fb10@linux.ibm.com \
    --to=seiden@linux.ibm.com \
    --cc=Ulrich.Weigand@de.ibm.com \
    --cc=agordeev@linux.ibm.com \
    --cc=arnd@arndb.de \
    --cc=borntraeger@linux.ibm.com \
    --cc=brueckner@linux.ibm.com \
    --cc=catalin.marinas@arm.com \
    --cc=david@kernel.org \
    --cc=frankja@linux.ibm.com \
    --cc=fritz@linux.ibm.com \
    --cc=fuad.tabba@linux.dev \
    --cc=ggala@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=gra@linux.ibm.com \
    --cc=hari55@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=nrb@linux.ibm.com \
    --cc=oupton@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=suzuki.poulose@arm.com \
    --cc=svens@linux.ibm.com \
    --cc=will@kernel.org \
    --cc=yuzenghui@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.