From: Steffen Eiden <seiden@linux.ibm.com>
To: kvm@vger.kernel.org, kvmarm@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Cc: Andreas Grapentin <gra@linux.ibm.com>,
Arnd Bergmann <arnd@arndb.de>,
Catalin Marinas <catalin.marinas@arm.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Claudio Imbrenda <imbrenda@linux.ibm.com>,
David Hildenbrand <david@kernel.org>,
Gautam Gala <ggala@linux.ibm.com>,
Hendrik Brueckner <brueckner@linux.ibm.com>,
Janosch Frank <frankja@linux.ibm.com>,
Joey Gouly <joey.gouly@arm.com>, Marc Zyngier <maz@kernel.org>,
Nina Schoetterl-Glausch <oss@nina.schoetterlglausch.eu>,
Oliver Upton <oupton@kernel.org>,
Paolo Bonzini <pbonzini@redhat.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
Will Deacon <will@kernel.org>, Zenghui Yu <yuzenghui@huawei.com>
Subject: [PATCH v2 02/28] KVM, vfio: remove symbol_get(kvm_get_kvm_safe) from vfio
Date: Tue, 28 Apr 2026 17:55:54 +0200 [thread overview]
Message-ID: <20260428155622.1361364-3-seiden@linux.ibm.com> (raw)
In-Reply-To: <20260428155622.1361364-1-seiden@linux.ibm.com>
From: Paolo Bonzini <pbonzini@redhat.com>
Right now, KVM and VFIO are using symbol_get to access each other's
symbols because of a circular reference between the modules, as well
as to avoid loading them unnecessarily.
However, usage of symbol_get is mostly deprecated and there are just a
handful of users left. In the case of VFIO, in particular, the
functions it calls can be made inline. Start with kvm_get_kvm_safe,
for which it is trivial to do so.
While at it, move the function from kvm_host.h to kvm_types.h.
Unlike e.g. drivers/s390/crypto/vfio_ap_ops.c, there's no need for
VFIO to know any implementation details of KVM, and struct kvm
can be treated as an opaque type.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Acked-by: Alex Williamson <alex@shazbot.org>
---
arch/x86/kvm/mmu/tdp_mmu.c | 2 +-
arch/x86/kvm/vmx/nested.h | 4 ++--
drivers/vfio/vfio_main.c | 8 +-------
include/linux/kvm_host.h | 8 ++++----
include/linux/kvm_types.h | 22 ++++++++++++++++++++++
virt/kvm/kvm_main.c | 27 ++++++---------------------
6 files changed, 36 insertions(+), 35 deletions(-)
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 9c26038f6b77..a88686b5db24 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -1136,7 +1136,7 @@ void kvm_tdp_mmu_invalidate_roots(struct kvm *kvm,
* being destroyed in an error path of KVM_CREATE_VM.
*/
if (IS_ENABLED(CONFIG_PROVE_LOCKING) &&
- refcount_read(&kvm->users_count) && kvm->created_vcpus)
+ refcount_read(&kvm->rc.users_count) && kvm->created_vcpus)
lockdep_assert_held_write(&kvm->mmu_lock);
/*
diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
index 213a448104af..2c83fc905698 100644
--- a/arch/x86/kvm/vmx/nested.h
+++ b/arch/x86/kvm/vmx/nested.h
@@ -58,7 +58,7 @@ bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port,
static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
{
lockdep_assert_once(lockdep_is_held(&vcpu->mutex) ||
- !refcount_read(&vcpu->kvm->users_count));
+ !refcount_read(&vcpu->kvm->rc.users_count));
return to_vmx(vcpu)->nested.cached_vmcs12;
}
@@ -66,7 +66,7 @@ static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
static inline struct vmcs12 *get_shadow_vmcs12(struct kvm_vcpu *vcpu)
{
lockdep_assert_once(lockdep_is_held(&vcpu->mutex) ||
- !refcount_read(&vcpu->kvm->users_count));
+ !refcount_read(&vcpu->kvm->rc.users_count));
return to_vmx(vcpu)->nested.cached_shadow_vmcs12;
}
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index d1bbc42d484a..cb6eaabd64ce 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -436,7 +436,6 @@ EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm, struct module *kvm_module)
{
void (*pfn)(struct kvm *kvm);
- bool (*fn)(struct kvm *kvm);
bool ret;
lockdep_assert_held(&device->dev_set->lock);
@@ -451,12 +450,7 @@ void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm, struc
if (WARN_ON(!pfn))
goto out_put_mod;
- fn = symbol_get(kvm_get_kvm_safe);
- if (WARN_ON(!fn))
- goto out_put_sym;
-
- ret = fn(kvm);
- symbol_put(kvm_get_kvm_safe);
+ ret = kvm_get_kvm_safe(kvm);
if (!ret)
goto out_put_sym;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 6b76e7a6f4c2..5163b541c82d 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -767,6 +767,9 @@ struct kvm_memslots {
};
struct kvm {
+ /* Must be the first field, see function definitions in kvm_types.h. */
+ struct kvm_refcount rc;
+
#ifdef KVM_HAVE_MMU_RWLOCK
rwlock_t mmu_lock;
#else
@@ -830,7 +833,6 @@ struct kvm {
struct list_head ioeventfds;
struct kvm_vm_stat stat;
struct kvm_arch arch;
- refcount_t users_count;
#ifdef CONFIG_KVM_MMIO
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
spinlock_t ring_lock;
@@ -1062,8 +1064,6 @@ static inline void kvm_irqfd_exit(void)
int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module);
void kvm_exit(void);
-void kvm_get_kvm(struct kvm *kvm);
-bool kvm_get_kvm_safe(struct kvm *kvm);
void kvm_put_kvm(struct kvm *kvm);
bool file_is_kvm(struct file *file);
void kvm_put_kvm_no_destroy(struct kvm *kvm);
@@ -1073,7 +1073,7 @@ static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)
as_id = array_index_nospec(as_id, KVM_MAX_NR_ADDRESS_SPACES);
return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu,
lockdep_is_held(&kvm->slots_lock) ||
- !refcount_read(&kvm->users_count));
+ !refcount_read(&kvm->rc.users_count));
}
static inline struct kvm_memslots *kvm_memslots(struct kvm *kvm)
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index a568d8e6f4e8..4cb68c71a13c 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -33,6 +33,7 @@
#include <linux/mutex.h>
#include <linux/spinlock_types.h>
+#include <linux/refcount.h>
struct kvm;
struct kvm_async_pf;
@@ -140,6 +141,27 @@ struct kvm_vcpu_stat_generic {
};
#define KVM_STATS_NAME_SIZE 48
+
+struct kvm_refcount {
+ refcount_t users_count;
+};
+
+static inline void kvm_get_kvm(struct kvm *kvm)
+{
+ struct kvm_refcount *rc = (struct kvm_refcount *)kvm;
+ refcount_inc(&rc->users_count);
+}
+
+/*
+ * A safe version of kvm_get_kvm(), making sure the vm is not being destroyed.
+ * Return true if kvm referenced successfully, false otherwise.
+ */
+static inline bool kvm_get_kvm_safe(struct kvm *kvm)
+{
+ struct kvm_refcount *rc = (struct kvm_refcount *)kvm;
+ return refcount_inc_not_zero(&rc->users_count);
+}
+
#endif /* !__ASSEMBLER__ */
#endif /* __KVM_TYPES_H__ */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9093251beb39..6e3796814da7 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1099,7 +1099,7 @@ static inline struct kvm_io_bus *kvm_get_bus_for_destruction(struct kvm *kvm,
enum kvm_bus idx)
{
return rcu_dereference_protected(kvm->buses[idx],
- !refcount_read(&kvm->users_count));
+ !refcount_read(&kvm->rc.users_count));
}
static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
@@ -1153,7 +1153,8 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
if (r)
goto out_err_no_irq_routing;
- refcount_set(&kvm->users_count, 1);
+ BUILD_BUG_ON(offsetof(struct kvm, rc) != 0);
+ refcount_set(&kvm->rc.users_count, 1);
for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
for (j = 0; j < 2; j++) {
@@ -1223,7 +1224,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
out_err_no_disable:
kvm_arch_destroy_vm(kvm);
out_err_no_arch_destroy_vm:
- WARN_ON_ONCE(!refcount_dec_and_test(&kvm->users_count));
+ WARN_ON_ONCE(!refcount_dec_and_test(&kvm->rc.users_count));
for (i = 0; i < KVM_NR_BUSES; i++)
kfree(kvm_get_bus_for_destruction(kvm, i));
kvm_free_irq_routing(kvm);
@@ -1316,25 +1317,9 @@ static void kvm_destroy_vm(struct kvm *kvm)
mmdrop(mm);
}
-void kvm_get_kvm(struct kvm *kvm)
-{
- refcount_inc(&kvm->users_count);
-}
-EXPORT_SYMBOL_GPL(kvm_get_kvm);
-
-/*
- * Make sure the vm is not during destruction, which is a safe version of
- * kvm_get_kvm(). Return true if kvm referenced successfully, false otherwise.
- */
-bool kvm_get_kvm_safe(struct kvm *kvm)
-{
- return refcount_inc_not_zero(&kvm->users_count);
-}
-EXPORT_SYMBOL_GPL(kvm_get_kvm_safe);
-
void kvm_put_kvm(struct kvm *kvm)
{
- if (refcount_dec_and_test(&kvm->users_count))
+ if (refcount_dec_and_test(&kvm->rc.users_count))
kvm_destroy_vm(kvm);
}
EXPORT_SYMBOL_GPL(kvm_put_kvm);
@@ -1348,7 +1333,7 @@ EXPORT_SYMBOL_GPL(kvm_put_kvm);
*/
void kvm_put_kvm_no_destroy(struct kvm *kvm)
{
- WARN_ON(refcount_dec_and_test(&kvm->users_count));
+ WARN_ON(refcount_dec_and_test(&kvm->rc.users_count));
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_put_kvm_no_destroy);
--
2.51.0
next prev parent reply other threads:[~2026-04-28 16:02 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-28 15:55 [PATCH v2 00/28] KVM: s390: Introduce arm64 KVM Steffen Eiden
2026-04-28 15:55 ` [PATCH v2 01/28] VFIO: take reference to the KVM module Steffen Eiden
2026-04-28 15:55 ` Steffen Eiden [this message]
2026-04-28 15:55 ` [PATCH v2 03/28] KVM, vfio: remove symbol_get(kvm_put_kvm) from vfio Steffen Eiden
2026-04-28 15:55 ` [PATCH v2 04/28] arm64: Provide arm64 UAPI for other host architectures Steffen Eiden
2026-04-29 8:04 ` Steffen Eiden
2026-04-28 15:55 ` [PATCH v2 05/28] arm64: Extract sysreg definitions Steffen Eiden
2026-04-28 15:55 ` [PATCH v2 06/28] arm64: Provide arm64 API for non-native architectures Steffen Eiden
2026-04-28 15:55 ` [PATCH v2 07/28] KVM: arm64: Provide arm64 KVM " Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 08/28] arm64: Extract pstate definitions from ptrace Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 09/28] KVM: arm64: Share kvm_emulate definitions Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 10/28] KVM: arm64: Make some arm64 KVM code shareable Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 11/28] KVM: arm64: Access elements of vcpu_gp_regs individually Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 12/28] KVM: arm64: Share reset general register code Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 13/28] KVM: arm64: Extract & share ipa size shift calculation Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 14/28] MAINTAINERS: Add Steffen as reviewer for KVM/arm64 Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 15/28] KVM: s390: Move s390 kvm code into a subdirectory Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 16/28] KVM: S390: Refactor gmap Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 17/28] KVM: Make device name configurable Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 18/28] KVM: Remove KVM_MMIO as config option Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 19/28] KVM: s390: Prepare kvm-s390 for a second kvm module Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 20/28] s390: Introduce Start Arm Execution instruction Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 21/28] KVM: s390: arm64: Introduce host definitions Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 22/28] s390/hwcaps: Report SAE support as hwcap Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 23/28] KVM: s390: Add basic arm64 kvm module Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 24/28] KVM: s390: arm64: Implement required functions Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 25/28] KVM: s390: arm64: Implement vm/vcpu create destroy Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 26/28] KVM: s390: arm64: Implement vCPU IOCTLs Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 27/28] KVM: s390: arm64: Implement basic page fault handler Steffen Eiden
2026-04-28 15:56 ` [PATCH v2 28/28] KVM: s390: arm64: Enable KVM_ARM64 config and Kbuild Steffen Eiden
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=20260428155622.1361364-3-seiden@linux.ibm.com \
--to=seiden@linux.ibm.com \
--cc=Ulrich.Weigand@de.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=ggala@linux.ibm.com \
--cc=gra@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=maz@kernel.org \
--cc=oss@nina.schoetterlglausch.eu \
--cc=oupton@kernel.org \
--cc=pbonzini@redhat.com \
--cc=suzuki.poulose@arm.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.