Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: add missing memory barrier in kvm_{make,check}_request

kvm_make_request and kvm_check_request imply a producer-consumer
relationship; add implicit memory barriers to them. There was indeed
already a place that was adding an explicit smp_mb() to order between
kvm_check_request and the processing of the request. That memory
barrier can be removed (as an added benefit, kvm_check_request can use
smp_mb__after_atomic which is free on x86).

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Paolo Bonzini and committed by
Radim Krčmář
2e4682ba 46971a2f

+11 -3
-3
arch/x86/kvm/irq_comm.c
··· 382 382 u32 i, nr_ioapic_pins; 383 383 int idx; 384 384 385 - /* kvm->irq_routing must be read after clearing 386 - * KVM_SCAN_IOAPIC. */ 387 - smp_mb(); 388 385 idx = srcu_read_lock(&kvm->irq_srcu); 389 386 table = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); 390 387 nr_ioapic_pins = min_t(u32, table->nr_rt_entries,
+11
include/linux/kvm_host.h
··· 1091 1091 1092 1092 static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu) 1093 1093 { 1094 + /* 1095 + * Ensure the rest of the request is published to kvm_check_request's 1096 + * caller. Paired with the smp_mb__after_atomic in kvm_check_request. 1097 + */ 1098 + smp_wmb(); 1094 1099 set_bit(req, &vcpu->requests); 1095 1100 } 1096 1101 ··· 1103 1098 { 1104 1099 if (test_bit(req, &vcpu->requests)) { 1105 1100 clear_bit(req, &vcpu->requests); 1101 + 1102 + /* 1103 + * Ensure the rest of the request is visible to kvm_check_request's 1104 + * caller. Paired with the smp_wmb in kvm_make_request. 1105 + */ 1106 + smp_mb__after_atomic(); 1106 1107 return true; 1107 1108 } else { 1108 1109 return false;