Commit 82c47012 authored by Li RongQing's avatar Li RongQing Committed by Sean Christopherson
Browse files

KVM: x86: Use kvfree_rcu() to free old optimized APIC map



Use kvfree_rcu() to free the old optimized APIC instead of open coding a
rough equivalent via call_rcu() and a callback function.

Note, there is a subtle function change as rcu_barrier() doesn't wait on
kvfree_rcu(), but does wait on call_rcu().  Not forcing rcu_barrier() to
wait is safe and desirable in this case, as KVM doesn't care when an old
map is actually freed.  In fact, using kvfree_rcu() fixes a largely
theoretical use-after-free.  Because KVM _doesn't_ do rcu_barrier() to
wait for kvm_apic_map_free() to complete, if KVM-the-module is unloaded in
the RCU grace period before kvm_apic_map_free() is invoked, KVM's callback
could run after module unload.

Signed-off-by: default avatarLi RongQing <lirongqing@baidu.com>
Reviewed-by: default avatarNeeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Link: https://lore.kernel.org/r/20250122073456.2950-1-lirongqing@baidu.com


[sean: rework changelog, call out rcu_barrier() interaction]
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 4cad9f87
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -221,13 +221,6 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map,
	}
}

static void kvm_apic_map_free(struct rcu_head *rcu)
{
	struct kvm_apic_map *map = container_of(rcu, struct kvm_apic_map, rcu);

	kvfree(map);
}

static int kvm_recalculate_phys_map(struct kvm_apic_map *new,
				    struct kvm_vcpu *vcpu,
				    bool *xapic_id_mismatch)
@@ -489,7 +482,7 @@ static void kvm_recalculate_apic_map(struct kvm *kvm)
	mutex_unlock(&kvm->arch.apic_map_lock);

	if (old)
		call_rcu(&old->rcu, kvm_apic_map_free);
		kvfree_rcu(old, rcu);

	kvm_make_scan_ioapic_request(kvm);
}