Commit 4fdc3431 authored by Zheyun Shen's avatar Zheyun Shen Committed by Borislav Petkov (AMD)
Browse files

x86/lib: Add WBINVD and WBNOINVD helpers to target multiple CPUs



Extract KVM's open-coded calls to do writeback caches on multiple CPUs to
common library helpers for both WBINVD and WBNOINVD (KVM will use both).
Put the onus on the caller to check for a non-empty mask to simplify the
SMP=n implementation, e.g. so that it doesn't need to check that the one
and only CPU in the system is present in the mask.

  [sean: move to lib, add SMP=n helpers, clarify usage]

Signed-off-by: default avatarZheyun Shen <szy0127@sjtu.edu.cn>
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Acked-by: default avatarKai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/r/20250128015345.7929-2-szy0127@sjtu.edu.cn
Link: https://lore.kernel.org/20250522233733.3176144-5-seanjc@google.com
parent 07f99c3f
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -113,7 +113,9 @@ void native_play_dead(void);
void play_dead_common(void);
void wbinvd_on_cpu(int cpu);
void wbinvd_on_all_cpus(void);
void wbinvd_on_cpus_mask(struct cpumask *cpus);
void wbnoinvd_on_all_cpus(void);
void wbnoinvd_on_cpus_mask(struct cpumask *cpus);

void smp_kick_mwait_play_dead(void);
void __noreturn mwait_play_dead(unsigned int eax_hint);
@@ -154,11 +156,21 @@ static inline void wbinvd_on_all_cpus(void)
	wbinvd();
}

static inline void wbinvd_on_cpus_mask(struct cpumask *cpus)
{
	wbinvd();
}

static inline void wbnoinvd_on_all_cpus(void)
{
	wbnoinvd();
}

static inline void wbnoinvd_on_cpus_mask(struct cpumask *cpus)
{
	wbnoinvd();
}

static inline struct cpumask *cpu_llc_shared_mask(int cpu)
{
	return (struct cpumask *)cpumask_of(0);
+1 −2
Original line number Diff line number Diff line
@@ -8289,8 +8289,7 @@ static int kvm_emulate_wbinvd_noskip(struct kvm_vcpu *vcpu)
		int cpu = get_cpu();

		cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);
		on_each_cpu_mask(vcpu->arch.wbinvd_dirty_mask,
				wbinvd_ipi, NULL, 1);
		wbinvd_on_cpus_mask(vcpu->arch.wbinvd_dirty_mask);
		put_cpu();
		cpumask_clear(vcpu->arch.wbinvd_dirty_mask);
	} else
+12 −0
Original line number Diff line number Diff line
@@ -20,6 +20,12 @@ void wbinvd_on_all_cpus(void)
}
EXPORT_SYMBOL(wbinvd_on_all_cpus);

void wbinvd_on_cpus_mask(struct cpumask *cpus)
{
	on_each_cpu_mask(cpus, __wbinvd, NULL, 1);
}
EXPORT_SYMBOL_GPL(wbinvd_on_cpus_mask);

static void __wbnoinvd(void *dummy)
{
	wbnoinvd();
@@ -30,3 +36,9 @@ void wbnoinvd_on_all_cpus(void)
	on_each_cpu(__wbnoinvd, NULL, 1);
}
EXPORT_SYMBOL_GPL(wbnoinvd_on_all_cpus);

void wbnoinvd_on_cpus_mask(struct cpumask *cpus)
{
	on_each_cpu_mask(cpus, __wbnoinvd, NULL, 1);
}
EXPORT_SYMBOL_GPL(wbnoinvd_on_cpus_mask);