diff options
| author | Keir Fraser <keirf@google.com> | 2025-09-09 13:00:06 +0300 |
|---|---|---|
| committer | Marc Zyngier <maz@kernel.org> | 2025-09-15 12:55:23 +0300 |
| commit | 7788255aba6545a27b8d143c5256536f8dfb2c0a (patch) | |
| tree | 30be9801ea7217fb6c5e210cba1c888155efc1f1 /include/linux | |
| parent | 11490b5ec6bc4fe3a36f90817bbc8021ba8b05cd (diff) | |
| download | linux-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.h | 10 |
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) |
