Commit a10accae authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'x86_core_for_kvm' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into HEAD

Immutable branch for KVM tree to put the KVM patches from

https://lore.kernel.org/r/20250522233733.3176144-1-seanjc@google.com



ontop.

Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
parents 0097f9df 4fdc3431
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -112,7 +112,10 @@ void __noreturn hlt_play_dead(void);
void native_play_dead(void);
void play_dead_common(void);
void wbinvd_on_cpu(int cpu);
int wbinvd_on_all_cpus(void);
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);
@@ -148,10 +151,24 @@ static inline struct cpumask *cpu_l2c_shared_mask(int cpu)

#else /* !CONFIG_SMP */
#define wbinvd_on_cpu(cpu)     wbinvd()
static inline int wbinvd_on_all_cpus(void)
static inline void wbinvd_on_all_cpus(void)
{
	wbinvd();
	return 0;
}

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)
+28 −1
Original line number Diff line number Diff line
@@ -104,11 +104,38 @@ static inline void wrpkru(u32 pkru)
}
#endif

/*
 * Write back all modified lines in all levels of cache associated with this
 * logical processor to main memory, and then invalidate all caches.  Depending
 * on the micro-architecture, WBINVD (and WBNOINVD below) may or may not affect
 * lower level caches associated with another logical processor that shares any
 * level of this processor's cache hierarchy.
 */
static __always_inline void wbinvd(void)
{
	asm volatile("wbinvd" : : : "memory");
}

/* Instruction encoding provided for binutils backwards compatibility. */
#define ASM_WBNOINVD _ASM_BYTES(0xf3,0x0f,0x09)

/*
 * Write back all modified lines in all levels of cache associated with this
 * logical processor to main memory, but do NOT explicitly invalidate caches,
 * i.e. leave all/most cache lines in the hierarchy in non-modified state.
 */
static __always_inline void wbnoinvd(void)
{
	/*
	 * Explicitly encode WBINVD if X86_FEATURE_WBNOINVD is unavailable even
	 * though WBNOINVD is backwards compatible (it's simply WBINVD with an
	 * ignored REP prefix), to guarantee that WBNOINVD isn't used if it
	 * needs to be avoided for any reason.  For all supported usage in the
	 * kernel, WBINVD is functionally a superset of WBNOINVD.
	 */
	alternative("wbinvd", ASM_WBNOINVD, X86_FEATURE_WBNOINVD);
}

static inline unsigned long __read_cr4(void)
{
	return native_read_cr4();
+1 −2
Original line number Diff line number Diff line
@@ -8159,8 +8159,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
+24 −2
Original line number Diff line number Diff line
@@ -14,9 +14,31 @@ void wbinvd_on_cpu(int cpu)
}
EXPORT_SYMBOL(wbinvd_on_cpu);

int wbinvd_on_all_cpus(void)
void wbinvd_on_all_cpus(void)
{
	on_each_cpu(__wbinvd, NULL, 1);
	return 0;
}
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();
}

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);
+3 −6
Original line number Diff line number Diff line
@@ -93,8 +93,7 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
		return;
	}

	if (wbinvd_on_all_cpus())
		pr_err("Timed out waiting for cache flush\n");
	wbinvd_on_all_cpus();

#elif defined(__powerpc__)
	unsigned long i;
@@ -139,8 +138,7 @@ drm_clflush_sg(struct sg_table *st)
		return;
	}

	if (wbinvd_on_all_cpus())
		pr_err("Timed out waiting for cache flush\n");
	wbinvd_on_all_cpus();
#else
	WARN_ONCE(1, "Architecture has no drm_cache.c support\n");
#endif
@@ -172,8 +170,7 @@ drm_clflush_virt_range(void *addr, unsigned long length)
		return;
	}

	if (wbinvd_on_all_cpus())
		pr_err("Timed out waiting for cache flush\n");
	wbinvd_on_all_cpus();
#else
	WARN_ONCE(1, "Architecture has no drm_cache.c support\n");
#endif