* [PATCH v2 0/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY
@ 2026-05-21 13:05 Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 1/5] KVM: s390: Track page size in struct guest_fault Claudio Imbrenda
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Claudio Imbrenda @ 2026-05-21 13:05 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra, pbonzini, seanjc, yan.y.zhao, isaku.yamahata
Implement KVM_PRE_FAULT_MEMORY on s390, and update documentation and
selftests accordingly.
Faulted-in pages will be marked as accessed, unlike x86, otherwise they
will trigger a minor fault when accessed. Avoiding such faults is one of
the points of KVM_PRE_FAULT_MEMORY.
CCing x86 people due to changes in the documentation and the selftests
v1->v2:
* Add the crste_region3 flag in struct guest_fault to keep track of the
page size used to solve a fault.
* Rewrite the s390 version of kvm_arch_vcpu_pre_fault_memory() so it
looks and behaves similarly to the x86 version. No more loops, better
handling of hugepage mappings, and more correct error handling.
* Remove the assertion vcpu->run->exit_reason == KVM_EXIT_IO from the
selftest, as it is redundant and x86-specific.
Claudio Imbrenda (5):
KVM: s390: Track page size in struct guest_fault
KVM: s390: Implement KVM_PRE_FAULT_MEMORY
KVM: s390: Update KVM_PRE_FAULT_MEMORY API documentation
KVM: selftests: Fix pre_fault_memory_test to run on s390
KVM: selftests: Enable pre_fault_memory_test for s390
Documentation/virt/kvm/api.rst | 5 ++-
arch/s390/kvm/Kconfig | 1 +
arch/s390/kvm/dat.h | 1 +
arch/s390/kvm/gmap.c | 2 +
arch/s390/kvm/kvm-s390.c | 45 +++++++++++++++++++
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../selftests/kvm/pre_fault_memory_test.c | 7 +--
7 files changed, 54 insertions(+), 8 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/5] KVM: s390: Track page size in struct guest_fault
2026-05-21 13:05 [PATCH v2 0/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
@ 2026-05-21 13:05 ` Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 2/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Claudio Imbrenda @ 2026-05-21 13:05 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra, pbonzini, seanjc, yan.y.zhao, isaku.yamahata
Until now, the members of struct guest_fault are always accessed while
holding the required locks, and thus the ptep and crstep pointers can
be dereferenced safely.
There will be some new cases where callers of kvm_s390_faultin_gfn()
need to know the size of the page used to solve the fault, at which
point no locks are held anymore, and dereferencing the crstep field
is not possible.
Introduce a new crste_region3 flag for struct guest_fault to indicate
whether the crstep used to solve the fault was a region 3 entry with FC=1
(large pud).
This allows to disambiguate all three possible scenarios:
* If ptep is not NULL, the fault was solved with a pte.
* If ptep is NULL and crste_region3 is 0, a segment entry with FC=1
(large pmd) was used.
* If ptep is NULL and crste_region3 is 1, a region 3 entry with FC=1
(large pud) was used.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/dat.h | 1 +
arch/s390/kvm/gmap.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/arch/s390/kvm/dat.h b/arch/s390/kvm/dat.h
index 8f8278c44879..db09b8fc34d6 100644
--- a/arch/s390/kvm/dat.h
+++ b/arch/s390/kvm/dat.h
@@ -500,6 +500,7 @@ struct guest_fault {
bool write_attempt; /* Write access attempted */
bool attempt_pfault; /* Attempt a pfault first */
bool valid; /* This entry contains valid data */
+ bool crste_region3; /* Whether crstep referst to a region3 entry */
void (*callback)(struct guest_fault *f);
void *priv;
};
diff --git a/arch/s390/kvm/gmap.c b/arch/s390/kvm/gmap.c
index 3c26e35af0ef..6f4143092871 100644
--- a/arch/s390/kvm/gmap.c
+++ b/arch/s390/kvm/gmap.c
@@ -545,6 +545,7 @@ static int gmap_handle_minor_crste_fault(struct gmap *gmap, struct guest_fault *
newcrste.s.fc1.d = 1;
newcrste.s.fc1.sd = 1;
}
+ f->crste_region3 = is_pud(newcrste);
/* In case of races, let the slow path deal with it. */
return !gmap_crstep_xchg_atomic(gmap, f->crstep, oldcrste, newcrste, f->gfn);
}
@@ -690,6 +691,7 @@ static int _gmap_link(struct kvm_s390_mmu_cache *mc, struct gmap *gmap, int leve
if (oldval.val != _CRSTE_EMPTY(oldval.h.tt).val &&
crste_origin_large(oldval) != crste_origin_large(newval))
return -EAGAIN;
+ f->crste_region3 = is_pud(newval);
} while (!gmap_crstep_xchg_atomic(gmap, f->crstep, oldval, newval, f->gfn));
if (f->callback)
f->callback(f);
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY
2026-05-21 13:05 [PATCH v2 0/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 1/5] KVM: s390: Track page size in struct guest_fault Claudio Imbrenda
@ 2026-05-21 13:05 ` Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 3/5] KVM: s390: Update KVM_PRE_FAULT_MEMORY API documentation Claudio Imbrenda
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Claudio Imbrenda @ 2026-05-21 13:05 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra, pbonzini, seanjc, yan.y.zhao, isaku.yamahata
Implement and enable the KVM_PRE_FAULT_MEMORY ioctl for s390.
Faulted-in pages will be marked as accessed, unlike x86, otherwise they
will trigger a minor fault when accessed. Avoiding such faults is one of
the points of KVM_PRE_FAULT_MEMORY.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/Kconfig | 1 +
arch/s390/kvm/kvm-s390.c | 45 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 5b835bc6a194..8d3ee17a1bcb 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -30,6 +30,7 @@ config KVM
select KVM_VFIO
select VIRT_XFER_TO_GUEST_WORK
select KVM_MMU_LOCKLESS_AGING
+ select KVM_GENERIC_PRE_FAULT_MEMORY
help
Support hosting paravirtualized guest machines using the SIE
virtualization capability on the mainframe. This should work
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index e09960c2e6ed..f6521f16532a 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -630,6 +630,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_S390_USER_OPEREXEC:
case KVM_CAP_S390_KEYOP:
case KVM_CAP_S390_VSIE_ESAMODE:
+ case KVM_CAP_PRE_FAULT_MEMORY:
r = 1;
break;
case KVM_CAP_SET_GUEST_DEBUG2:
@@ -5736,6 +5737,50 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
return;
}
+/**
+ * kvm_arch_vcpu_pre_fault_memory() -- pre-fault and link gmap dat tables
+ * @vcpu: the vcpu that shall appear to have generated the fault-in.
+ * @range: the range that needs to be faulted in.
+ *
+ * The first page of the given range is faulted in and the corresponding gmap
+ * page tables are created, as if the given vCPU had performed a read
+ * operation.
+ * If the range starts outside any memslots, an error is returned. An error is
+ * also returned for UCONTROL VMs, which should instead use the
+ * KVM_S390_VCPU_FAULT ioctl.
+ *
+ * Return:
+ * * %-ENOENT if the range lies outside of a memslot.
+ * * %-EINVAL in case of invalid state (for example if the VM is UCONTROL).
+ * * %-EIO if errors happen while faulting-in the page (will trigger a warning
+ * in the caller).
+ * * other error codes < 0 in case of other errors.
+ * * otherwise a number > 0 of bytes that have been faulted in successfully.
+ */
+long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, struct kvm_pre_fault_memory *range)
+{
+ struct guest_fault f = { .gfn = gpa_to_gfn(range->gpa), };
+ gpa_t end;
+ int rc;
+
+ if (kvm_is_ucontrol(vcpu->kvm))
+ return -EINVAL;
+
+ rc = kvm_s390_faultin_gfn(vcpu, NULL, &f);
+ if (rc == PGM_ADDRESSING)
+ return -ENOENT;
+ if (rc > 0)
+ return -EIO;
+ if (rc < 0)
+ return rc;
+
+ if (f.ptep)
+ return PAGE_SIZE;
+
+ end = ALIGN(range->gpa + PAGE_SIZE, f.crste_region3 ? _REGION3_SIZE : HPAGE_SIZE);
+ return min(range->size, end - range->gpa);
+}
+
/**
* kvm_test_age_gfn() - test young
* @kvm: the kvm instance
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/5] KVM: s390: Update KVM_PRE_FAULT_MEMORY API documentation
2026-05-21 13:05 [PATCH v2 0/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 1/5] KVM: s390: Track page size in struct guest_fault Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 2/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
@ 2026-05-21 13:05 ` Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 4/5] KVM: selftests: Fix pre_fault_memory_test to run on s390 Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 5/5] KVM: selftests: Enable pre_fault_memory_test for s390 Claudio Imbrenda
4 siblings, 0 replies; 7+ messages in thread
From: Claudio Imbrenda @ 2026-05-21 13:05 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra, pbonzini, seanjc, yan.y.zhao, isaku.yamahata
Update the API documentation for KVM_PRE_FAULT_MEMORY to account for
its s390 implementation.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
Documentation/virt/kvm/api.rst | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 52bbbb553ce1..e7998feaa940 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6471,7 +6471,8 @@ Errors:
========== ===============================================================
EINVAL The specified `gpa` and `size` were invalid (e.g. not
- page aligned, causes an overflow, or size is zero).
+ page aligned, causes an overflow, or size is zero), or the VM
+ is UCONTROL (s390).
ENOENT The specified `gpa` is outside defined memslots.
EINTR An unmasked signal is pending and no page was processed.
EFAULT The parameter address was invalid.
@@ -6494,7 +6495,7 @@ Errors:
KVM_PRE_FAULT_MEMORY populates KVM's stage-2 page tables used to map memory
for the current vCPU state. KVM maps memory as if the vCPU generated a
stage-2 read page fault, e.g. faults in memory as needed, but doesn't break
-CoW. However, KVM does not mark any newly created stage-2 PTE as Accessed.
+CoW. On x86, KVM does not mark any newly created stage-2 PTE as Accessed.
In the case of confidential VM types where there is an initial set up of
private guest memory before the guest is 'finalized'/measured, this ioctl
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 4/5] KVM: selftests: Fix pre_fault_memory_test to run on s390
2026-05-21 13:05 [PATCH v2 0/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
` (2 preceding siblings ...)
2026-05-21 13:05 ` [PATCH v2 3/5] KVM: s390: Update KVM_PRE_FAULT_MEMORY API documentation Claudio Imbrenda
@ 2026-05-21 13:05 ` Claudio Imbrenda
2026-05-21 13:22 ` Sean Christopherson
2026-05-21 13:05 ` [PATCH v2 5/5] KVM: selftests: Enable pre_fault_memory_test for s390 Claudio Imbrenda
4 siblings, 1 reply; 7+ messages in thread
From: Claudio Imbrenda @ 2026-05-21 13:05 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra, pbonzini, seanjc, yan.y.zhao, isaku.yamahata
Add a missing #include <ucall_common.h> which is needed and otherwise
not included on s390.
Remove the assertion vcpu->run->exit_reason == KVM_EXIT_IO since it
is x86-specific and redundant anyway.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
tools/testing/selftests/kvm/pre_fault_memory_test.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/tools/testing/selftests/kvm/pre_fault_memory_test.c b/tools/testing/selftests/kvm/pre_fault_memory_test.c
index fcb57fd034e6..a0fcae3cb7a8 100644
--- a/tools/testing/selftests/kvm/pre_fault_memory_test.c
+++ b/tools/testing/selftests/kvm/pre_fault_memory_test.c
@@ -11,6 +11,7 @@
#include <kvm_util.h>
#include <processor.h>
#include <pthread.h>
+#include <ucall_common.h>
/* Arbitrarily chosen values */
#define TEST_SIZE (SZ_2M + PAGE_SIZE)
@@ -167,7 +168,6 @@ static void __test_pre_fault_memory(unsigned long vm_type, bool private)
.type = vm_type,
};
struct kvm_vcpu *vcpu;
- struct kvm_run *run;
struct kvm_vm *vm;
struct ucall uc;
@@ -193,11 +193,6 @@ static void __test_pre_fault_memory(unsigned long vm_type, bool private)
vcpu_args_set(vcpu, 1, gva);
vcpu_run(vcpu);
- run = vcpu->run;
- TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
- "Wanted KVM_EXIT_IO, got exit reason: %u (%s)",
- run->exit_reason, exit_reason_str(run->exit_reason));
-
switch (get_ucall(vcpu, &uc)) {
case UCALL_ABORT:
REPORT_GUEST_ASSERT(uc);
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 5/5] KVM: selftests: Enable pre_fault_memory_test for s390
2026-05-21 13:05 [PATCH v2 0/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
` (3 preceding siblings ...)
2026-05-21 13:05 ` [PATCH v2 4/5] KVM: selftests: Fix pre_fault_memory_test to run on s390 Claudio Imbrenda
@ 2026-05-21 13:05 ` Claudio Imbrenda
4 siblings, 0 replies; 7+ messages in thread
From: Claudio Imbrenda @ 2026-05-21 13:05 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, linux-s390, borntraeger, frankja, david, seiden, nrb,
schlameuss, gra, pbonzini, seanjc, yan.y.zhao, isaku.yamahata
Enable the pre_fault_memory_test to run on s390.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 9118a5a51b89..fff939db89cd 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -210,6 +210,7 @@ TEST_GEN_PROGS_s390 += s390/keyop
TEST_GEN_PROGS_s390 += rseq_test
TEST_GEN_PROGS_s390 += s390/irq_routing
TEST_GEN_PROGS_s390 += mmu_stress_test
+TEST_GEN_PROGS_s390 += pre_fault_memory_test
TEST_GEN_PROGS_riscv = $(TEST_GEN_PROGS_COMMON)
TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 4/5] KVM: selftests: Fix pre_fault_memory_test to run on s390
2026-05-21 13:05 ` [PATCH v2 4/5] KVM: selftests: Fix pre_fault_memory_test to run on s390 Claudio Imbrenda
@ 2026-05-21 13:22 ` Sean Christopherson
0 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2026-05-21 13:22 UTC (permalink / raw)
To: Claudio Imbrenda
Cc: linux-kernel, kvm, linux-s390, borntraeger, frankja, david,
seiden, nrb, schlameuss, gra, pbonzini, yan.y.zhao,
isaku.yamahata
On Thu, May 21, 2026, Claudio Imbrenda wrote:
> Add a missing #include <ucall_common.h> which is needed and otherwise
> not included on s390.
>
> Remove the assertion vcpu->run->exit_reason == KVM_EXIT_IO since it
> is x86-specific and redundant anyway.
>
> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
> ---
Acked-by: Sean Christopherson <seanjc@google.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-21 13:22 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-21 13:05 [PATCH v2 0/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 1/5] KVM: s390: Track page size in struct guest_fault Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 2/5] KVM: s390: Implement KVM_PRE_FAULT_MEMORY Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 3/5] KVM: s390: Update KVM_PRE_FAULT_MEMORY API documentation Claudio Imbrenda
2026-05-21 13:05 ` [PATCH v2 4/5] KVM: selftests: Fix pre_fault_memory_test to run on s390 Claudio Imbrenda
2026-05-21 13:22 ` Sean Christopherson
2026-05-21 13:05 ` [PATCH v2 5/5] KVM: selftests: Enable pre_fault_memory_test for s390 Claudio Imbrenda
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox