summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorKeir Fraser <keirf@google.com>2025-09-09 13:00:06 +0300
committerMarc Zyngier <maz@kernel.org>2025-09-15 12:55:23 +0300
commit7788255aba6545a27b8d143c5256536f8dfb2c0a (patch)
tree30be9801ea7217fb6c5e210cba1c888155efc1f1 /include/linux
parent11490b5ec6bc4fe3a36f90817bbc8021ba8b05cd (diff)
downloadlinux-7788255aba6545a27b8d143c5256536f8dfb2c0a.tar.xz
KVM: Implement barriers before accessing kvm->buses[] on SRCU read paths
This ensures that, if a VCPU has "observed" that an IO registration has occurred, the instruction currently being trapped or emulated will also observe the IO registration. At the same time, enforce that kvm_get_bus() is used only on the update side, ensuring that a long-term reference cannot be obtained by an SRCU reader. Signed-off-by: Keir Fraser <keirf@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/kvm_host.h10
1 files changed, 7 insertions, 3 deletions
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 15656b7fba6c..e7d6111cf254 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -966,11 +966,15 @@ static inline bool kvm_dirty_log_manual_protect_and_init_set(struct kvm *kvm)
return !!(kvm->manual_dirty_log_protect & KVM_DIRTY_LOG_INITIALLY_SET);
}
+/*
+ * Get a bus reference under the update-side lock. No long-term SRCU reader
+ * references are permitted, to avoid stale reads vs concurrent IO
+ * registrations.
+ */
static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx)
{
- return srcu_dereference_check(kvm->buses[idx], &kvm->srcu,
- lockdep_is_held(&kvm->slots_lock) ||
- !refcount_read(&kvm->users_count));
+ return rcu_dereference_protected(kvm->buses[idx],
+ lockdep_is_held(&kvm->slots_lock));
}
static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)