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

Merge tag 'kvm-x86-misc-6.19' of https://github.com/kvm-x86/linux into HEAD

KVM x86 misc changes for 6.19:

 - Fix an async #PF bug where KVM would clear the completion queue when the
   guest transitioned in and out of paging mode, e.g. when handling an SMI and
   then returning to paged mode via RSM.

 - Fix a bug where TDX would effectively corrupt user-return MSR values if the
   TDX Module rejects VP.ENTER and thus doesn't clobber host MSRs as expected.

 - Leave the user-return notifier used to restore MSRs registered when
   disabling virtualization, and instead pin kvm.ko.  Restoring host MSRs via
   IPI callback is either pointless (clean reboot) or dangerous (forced reboot)
   since KVM has no idea what code it's interrupting.

 - Use the checked version of {get,put}_user(), as Linus wants to kill them
   off, and they're measurably faster on modern CPUs due to the unchecked
   versions containing an LFENCE.

 - Fix a long-lurking bug where KVM's lack of catch-up logic for periodic APIC
   timers can result in a hard lockup in the host.

 - Revert the periodic kvmclock sync logic now that KVM doesn't use a
   clocksource that's subject to NPT corrections.

 - Clean up KVM's handling of MMIO Stale Data and L1TF, and bury the latter
   behind CONFIG_CPU_MITIGATIONS.

 - Context switch XCR0, XSS, and PKRU outside of the entry/exit fastpath as
   the only reason they were handled in the faspath was to paper of a bug in
   the core #MC code that has long since been fixed.

 - Add emulator support for AVX MOV instructions to play nice with emulated
   devices whose PCI BARs guest drivers like to access with large multi-byte
   instructions.
parents 23683174 c09816f2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -499,6 +499,11 @@
#define X86_FEATURE_IBPB_EXIT_TO_USER	(21*32+14) /* Use IBPB on exit-to-userspace, see VMSCAPE bug */
#define X86_FEATURE_ABMC		(21*32+15) /* Assignable Bandwidth Monitoring Counters */
#define X86_FEATURE_MSR_IMM		(21*32+16) /* MSR immediate form instructions */
#define X86_FEATURE_CLEAR_CPU_BUF_VM_MMIO (21*32+17) /*
						      * Clear CPU buffers before VM-Enter if the vCPU
						      * can access host MMIO (ignored for all intents
						      * and purposes if CLEAR_CPU_BUF_VM is set).
						      */

/*
 * BUG word(s)
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
#include <linux/threads.h>

typedef struct {
#if IS_ENABLED(CONFIG_KVM_INTEL)
#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL)
	u8	     kvm_cpu_l1tf_flush_l1d;
#endif
	unsigned int __nmi_count;	/* arch dependent */
@@ -68,7 +68,7 @@ extern u64 arch_irq_stat(void);
DECLARE_PER_CPU_CACHE_HOT(u16, __softirq_pending);
#define local_softirq_pending_ref       __softirq_pending

#if IS_ENABLED(CONFIG_KVM_INTEL)
#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL)
/*
 * This function is called from noinstr interrupt contexts
 * and must be inlined to not get instrumentation.
+1 −6
Original line number Diff line number Diff line
@@ -1055,9 +1055,6 @@ struct kvm_vcpu_arch {
	/* be preempted when it's in kernel-mode(cpl=0) */
	bool preempted_in_kernel;

	/* Flush the L1 Data cache for L1TF mitigation on VMENTER */
	bool l1tf_flush_l1d;

	/* Host CPU on which VM-entry was most recently attempted */
	int last_vmentry_cpu;

@@ -1456,8 +1453,6 @@ struct kvm_arch {
	bool use_master_clock;
	u64 master_kernel_ns;
	u64 master_cycle_now;
	struct delayed_work kvmclock_update_work;
	struct delayed_work kvmclock_sync_work;

#ifdef CONFIG_KVM_HYPERV
	struct kvm_hv hyperv;
@@ -2167,6 +2162,7 @@ void __kvm_prepare_emulation_failure_exit(struct kvm_vcpu *vcpu,
void kvm_prepare_emulation_failure_exit(struct kvm_vcpu *vcpu);

void kvm_prepare_event_vectoring_exit(struct kvm_vcpu *vcpu, gpa_t gpa);
void kvm_prepare_unexpected_reason_exit(struct kvm_vcpu *vcpu, u64 exit_reason);

void kvm_enable_efer_bits(u64);
bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer);
@@ -2378,7 +2374,6 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
int kvm_add_user_return_msr(u32 msr);
int kvm_find_user_return_msr(u32 msr);
int kvm_set_user_return_msr(unsigned index, u64 val, u64 mask);
void kvm_user_return_msr_update_cache(unsigned int index, u64 val);
u64 kvm_get_user_return_msr(unsigned int slot);

static inline bool kvm_is_supported_user_return_msr(u32 msr)
+15 −15
Original line number Diff line number Diff line
@@ -308,24 +308,26 @@
 * CFLAGS.ZF.
 * Note: Only the memory operand variant of VERW clears the CPU buffers.
 */
.macro __CLEAR_CPU_BUFFERS feature
#ifdef CONFIG_X86_64
	ALTERNATIVE "", "verw x86_verw_sel(%rip)", \feature
#define VERW	verw x86_verw_sel(%rip)
#else
/*
	 * In 32bit mode, the memory operand must be a %cs reference. The data
	 * segments may not be usable (vm86 mode), and the stack segment may not
	 * be flat (ESPFIX32).
 * In 32bit mode, the memory operand must be a %cs reference. The data segments
 * may not be usable (vm86 mode), and the stack segment may not be flat (ESPFIX32).
 */
	ALTERNATIVE "", "verw %cs:x86_verw_sel", \feature
#define VERW	verw %cs:x86_verw_sel
#endif
.endm

#define CLEAR_CPU_BUFFERS \
	__CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF
/*
 * Provide a stringified VERW macro for simple usage, and a non-stringified
 * VERW macro for use in more elaborate sequences, e.g. to encode a conditional
 * VERW within an ALTERNATIVE.
 */
#define __CLEAR_CPU_BUFFERS	__stringify(VERW)

#define VM_CLEAR_CPU_BUFFERS \
	__CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF_VM
/* If necessary, emit VERW on exit-to-userspace to clear CPU buffers. */
#define CLEAR_CPU_BUFFERS \
	ALTERNATIVE "", __CLEAR_CPU_BUFFERS, X86_FEATURE_CLEAR_CPU_BUF

#ifdef CONFIG_X86_64
.macro CLEAR_BRANCH_HISTORY
@@ -580,8 +582,6 @@ DECLARE_STATIC_KEY_FALSE(cpu_buf_idle_clear);

DECLARE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush);

DECLARE_STATIC_KEY_FALSE(cpu_buf_vm_clear);

extern u16 x86_verw_sel;

#include <asm/segment.h>
+9 −13
Original line number Diff line number Diff line
@@ -192,14 +192,6 @@ EXPORT_SYMBOL_GPL(cpu_buf_idle_clear);
 */
DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush);

/*
 * Controls CPU Fill buffer clear before VMenter. This is a subset of
 * X86_FEATURE_CLEAR_CPU_BUF, and should only be enabled when KVM-only
 * mitigation is required.
 */
DEFINE_STATIC_KEY_FALSE(cpu_buf_vm_clear);
EXPORT_SYMBOL_GPL(cpu_buf_vm_clear);

#undef pr_fmt
#define pr_fmt(fmt)	"mitigations: " fmt

@@ -489,8 +481,8 @@ static enum rfds_mitigations rfds_mitigation __ro_after_init =
	IS_ENABLED(CONFIG_MITIGATION_RFDS) ? RFDS_MITIGATION_AUTO : RFDS_MITIGATION_OFF;

/*
 * Set if any of MDS/TAA/MMIO/RFDS are going to enable VERW clearing
 * through X86_FEATURE_CLEAR_CPU_BUF on kernel and guest entry.
 * Set if any of MDS/TAA/MMIO/RFDS are going to enable VERW clearing on exit to
 * userspace *and* on entry to KVM guests.
 */
static bool verw_clear_cpu_buf_mitigation_selected __ro_after_init;

@@ -536,6 +528,7 @@ static void __init mds_apply_mitigation(void)
	if (mds_mitigation == MDS_MITIGATION_FULL ||
	    mds_mitigation == MDS_MITIGATION_VMWERV) {
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
		if (!boot_cpu_has(X86_BUG_MSBDS_ONLY) &&
		    (mds_nosmt || smt_mitigations == SMT_MITIGATIONS_ON))
			cpu_smt_disable(false);
@@ -647,6 +640,7 @@ static void __init taa_apply_mitigation(void)
		 * present on host, enable the mitigation for UCODE_NEEDED as well.
		 */
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);

		if (taa_nosmt || smt_mitigations == SMT_MITIGATIONS_ON)
			cpu_smt_disable(false);
@@ -748,9 +742,9 @@ static void __init mmio_apply_mitigation(void)
	 */
	if (verw_clear_cpu_buf_mitigation_selected) {
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
		static_branch_disable(&cpu_buf_vm_clear);
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
	} else {
		static_branch_enable(&cpu_buf_vm_clear);
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM_MMIO);
	}

	/*
@@ -839,8 +833,10 @@ static void __init rfds_update_mitigation(void)

static void __init rfds_apply_mitigation(void)
{
	if (rfds_mitigation == RFDS_MITIGATION_VERW)
	if (rfds_mitigation == RFDS_MITIGATION_VERW) {
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
	}
}

static __init int rfds_parse_cmdline(char *str)
Loading