From: James Houghton <jthoughton@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>,
Oliver Upton <oliver.upton@linux.dev>
Cc: Jonathan Corbet <corbet@lwn.net>, Marc Zyngier <maz@kernel.org>,
Yan Zhao <yan.y.zhao@intel.com>,
James Houghton <jthoughton@google.com>,
Nikita Kalyazin <kalyazin@amazon.com>,
Anish Moorthy <amoorthy@google.com>,
Peter Gonda <pgonda@google.com>, Peter Xu <peterx@redhat.com>,
David Matlack <dmatlack@google.com>,
wei.w.wang@intel.com, kvm@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev
Subject: [PATCH v3 03/15] KVM: arm64: x86: Require "struct kvm_page_fault" for memory fault exits
Date: Wed, 18 Jun 2025 04:24:12 +0000 [thread overview]
Message-ID: <20250618042424.330664-4-jthoughton@google.com> (raw)
In-Reply-To: <20250618042424.330664-1-jthoughton@google.com>
From: Sean Christopherson <seanjc@google.com>
Now that both arm64 and x86 define "struct kvm_page_fault" with a base set
of fields, rework kvm_prepare_memory_fault_exit() to take a kvm_page_fault
structure instead of passing in a pile of parameters. Guard the related
code with CONFIG_KVM_GENERIC_PAGE_FAULT to play nice with architectures
that don't yet support kvm_page_fault.
Rather than define a common kvm_page_fault and kvm_arch_page_fault child,
simply assert that the handful of required fields are provided by the
arch-defined structure. Unlike vCPU and VMs, the number of common fields
is expected to be small, and letting arch code fully define the structure
allows for maximum flexibility with respect to const, layout, etc.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: James Houghton <jthoughton@google.com>
---
arch/arm64/kvm/Kconfig | 1 +
arch/x86/kvm/Kconfig | 1 +
arch/x86/kvm/mmu/mmu.c | 8 ++++----
arch/x86/kvm/mmu/mmu_internal.h | 10 +---------
include/linux/kvm_host.h | 26 ++++++++++++++++++++------
virt/kvm/Kconfig | 3 +++
6 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 713248f240e03..3c299735b1668 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -37,6 +37,7 @@ menuconfig KVM
select HAVE_KVM_VCPU_RUN_PID_CHANGE
select SCHED_INFO
select GUEST_PERF_EVENTS if PERF_EVENTS
+ select KVM_GENERIC_PAGE_FAULT
help
Support hosting virtualized guest machines.
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 2eeffcec53828..2d5966f15738d 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -48,6 +48,7 @@ config KVM_X86
select KVM_GENERIC_PRE_FAULT_MEMORY
select KVM_GENERIC_PRIVATE_MEM if KVM_SW_PROTECTED_VM
select KVM_WERROR if WERROR
+ select KVM_GENERIC_PAGE_FAULT
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index cbc84c6abc2e3..a4439e9e07268 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -3429,7 +3429,7 @@ static int kvm_handle_noslot_fault(struct kvm_vcpu *vcpu,
gva_t gva = fault->is_tdp ? 0 : fault->addr;
if (fault->is_private) {
- kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+ kvm_prepare_memory_fault_exit(vcpu, fault);
return -EFAULT;
}
@@ -4499,14 +4499,14 @@ static int kvm_mmu_faultin_pfn_private(struct kvm_vcpu *vcpu,
int max_order, r;
if (!kvm_slot_can_be_private(fault->slot)) {
- kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+ kvm_prepare_memory_fault_exit(vcpu, fault);
return -EFAULT;
}
r = kvm_gmem_get_pfn(vcpu->kvm, fault->slot, fault->gfn, &fault->pfn,
&fault->refcounted_page, &max_order);
if (r) {
- kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+ kvm_prepare_memory_fault_exit(vcpu, fault);
return r;
}
@@ -4586,7 +4586,7 @@ static int kvm_mmu_faultin_pfn(struct kvm_vcpu *vcpu,
* private vs. shared mismatch.
*/
if (fault->is_private != kvm_mem_is_private(kvm, fault->gfn)) {
- kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
+ kvm_prepare_memory_fault_exit(vcpu, fault);
return -EFAULT;
}
diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h
index 384fc4d0bfec0..c15060ed6e8be 100644
--- a/arch/x86/kvm/mmu/mmu_internal.h
+++ b/arch/x86/kvm/mmu/mmu_internal.h
@@ -269,14 +269,6 @@ enum {
*/
static_assert(RET_PF_CONTINUE == 0);
-static inline void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
- struct kvm_page_fault *fault)
-{
- kvm_prepare_memory_fault_exit(vcpu, fault->gfn << PAGE_SHIFT,
- PAGE_SIZE, fault->write, fault->exec,
- fault->is_private);
-}
-
static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
u64 err, bool prefetch,
int *emulation_type, u8 *level)
@@ -329,7 +321,7 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
*/
if (r == RET_PF_EMULATE && fault.is_private) {
pr_warn_ratelimited("kvm: unexpected emulation request on private memory\n");
- kvm_mmu_prepare_memory_fault_exit(vcpu, &fault);
+ kvm_prepare_memory_fault_exit(vcpu, &fault);
return -EFAULT;
}
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 3bde4fb5c6aa4..9a85500cd5c50 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -2497,20 +2497,34 @@ static inline void kvm_account_pgtable_pages(void *virt, int nr)
/* Max number of entries allowed for each kvm dirty ring */
#define KVM_DIRTY_RING_MAX_ENTRIES 65536
+#ifdef CONFIG_KVM_GENERIC_PAGE_FAULT
+
+#define KVM_ASSERT_TYPE_IS(type_t, x) \
+do { \
+ type_t __maybe_unused tmp; \
+ \
+ BUILD_BUG_ON(!__types_ok(tmp, x) || !__typecheck(tmp, x)); \
+} while (0)
+
static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
- gpa_t gpa, gpa_t size,
- bool is_write, bool is_exec,
- bool is_private)
+ struct kvm_page_fault *fault)
{
+ KVM_ASSERT_TYPE_IS(gfn_t, fault->gfn);
+ KVM_ASSERT_TYPE_IS(bool, fault->exec);
+ KVM_ASSERT_TYPE_IS(bool, fault->write);
+ KVM_ASSERT_TYPE_IS(bool, fault->is_private);
+ KVM_ASSERT_TYPE_IS(struct kvm_memory_slot *, fault->slot);
+
vcpu->run->exit_reason = KVM_EXIT_MEMORY_FAULT;
- vcpu->run->memory_fault.gpa = gpa;
- vcpu->run->memory_fault.size = size;
+ vcpu->run->memory_fault.gpa = fault->gfn << PAGE_SHIFT;
+ vcpu->run->memory_fault.size = PAGE_SIZE;
/* RWX flags are not (yet) defined or communicated to userspace. */
vcpu->run->memory_fault.flags = 0;
- if (is_private)
+ if (fault->is_private)
vcpu->run->memory_fault.flags |= KVM_MEMORY_EXIT_FLAG_PRIVATE;
}
+#endif
#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn_t gfn)
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 727b542074e7e..28ed6b241578b 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -128,3 +128,6 @@ config HAVE_KVM_ARCH_GMEM_PREPARE
config HAVE_KVM_ARCH_GMEM_INVALIDATE
bool
depends on KVM_PRIVATE_MEM
+
+config KVM_GENERIC_PAGE_FAULT
+ bool
--
2.50.0.rc2.692.g299adb8693-goog
next prev parent reply other threads:[~2025-06-18 4:24 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-18 4:24 [PATCH v3 00/15] KVM: Introduce KVM Userfault James Houghton
2025-06-18 4:24 ` [PATCH v3 01/15] KVM: x86/mmu: Move "struct kvm_page_fault" definition to asm/kvm_host.h James Houghton
2025-06-18 4:24 ` [PATCH v3 02/15] KVM: arm64: Add "struct kvm_page_fault" to gather common fault variables James Houghton
2025-06-18 19:26 ` Oliver Upton
2025-06-18 21:17 ` Sean Christopherson
2025-06-18 4:24 ` James Houghton [this message]
2025-06-18 20:00 ` [PATCH v3 03/15] KVM: arm64: x86: Require "struct kvm_page_fault" for memory fault exits Oliver Upton
2025-06-18 20:47 ` Sean Christopherson
2025-06-18 23:14 ` Oliver Upton
2025-06-19 1:22 ` Sean Christopherson
2025-06-18 4:24 ` [PATCH v3 04/15] KVM: Add common infrastructure for KVM Userfaults James Houghton
2025-06-18 19:40 ` Oliver Upton
2025-06-18 20:33 ` Sean Christopherson
2025-06-18 20:41 ` James Houghton
2025-06-18 22:43 ` Oliver Upton
2025-06-19 1:27 ` Sean Christopherson
2025-06-18 20:38 ` James Houghton
2025-06-18 4:24 ` [PATCH v3 05/15] KVM: x86: Add support for KVM userfault exits James Houghton
2025-07-30 21:11 ` James Houghton
2025-06-18 4:24 ` [PATCH v3 06/15] KVM: arm64: " James Houghton
2025-06-18 4:24 ` [PATCH v3 07/15] KVM: Enable and advertise " James Houghton
2025-06-18 4:24 ` [PATCH v3 08/15] KVM: selftests: Fix vm_mem_region_set_flags docstring James Houghton
2025-06-18 4:24 ` [PATCH v3 09/15] KVM: selftests: Fix prefault_mem logic James Houghton
2025-06-18 4:24 ` [PATCH v3 10/15] KVM: selftests: Add va_start/end into uffd_desc James Houghton
2025-06-18 4:24 ` [PATCH v3 11/15] KVM: selftests: Add KVM Userfault mode to demand_paging_test James Houghton
2025-06-18 4:24 ` [PATCH v3 12/15] KVM: selftests: Inform set_memory_region_test of KVM_MEM_USERFAULT James Houghton
2025-06-18 4:24 ` [PATCH v3 13/15] KVM: selftests: Add KVM_MEM_USERFAULT + guest_memfd toggle tests James Houghton
2025-06-18 4:24 ` [PATCH v3 14/15] KVM: Documentation: Fix section number for KVM_CAP_ARM_WRITABLE_IMP_ID_REGS James Houghton
2025-06-18 4:24 ` [PATCH v3 15/15] KVM: Documentation: Add KVM_CAP_USERFAULT and KVM_MEM_USERFAULT details James Houghton
2025-06-18 23:24 ` [PATCH v3 00/15] KVM: Introduce KVM Userfault Oliver Upton
2025-09-04 16:43 ` Nikita Kalyazin
2025-09-04 18:45 ` James Houghton
2025-09-05 12:27 ` Sean Christopherson
2025-09-23 12:13 ` Nikita Kalyazin
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=20250618042424.330664-4-jthoughton@google.com \
--to=jthoughton@google.com \
--cc=amoorthy@google.com \
--cc=corbet@lwn.net \
--cc=dmatlack@google.com \
--cc=kalyazin@amazon.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=pgonda@google.com \
--cc=seanjc@google.com \
--cc=wei.w.wang@intel.com \
--cc=yan.y.zhao@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox