Commit 9e03b7ca authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

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

KVM x86 misc changes for 6.20

 - Disallow changing the virtual CPU model if L2 is active, for all the same
   reasons KVM disallows change the model after the first KVM_RUN.

 - Fix a bug where KVM would incorrectly reject host accesses to PV MSRs that
   were advertised as supported to userspace when running with
   KVM_CAP_ENFORCE_PV_FEATURE_CPUID enabled.

 - Fix a bug where KVM would attempt to read protect guest state (CR3) when
   configuring an async #PF entry.

 - Fail the build if EXPORT_SYMBOL_GPL or EXPORT_SYMBOL is used in KVM (for x86
   only) to enforce usage of EXPORT_SYMBOL_FOR_KVM_INTERNAL.  Explicitly allow
   the few exports that are intended for external usage.

 - Ignore -EBUSY when checking nested events after a vCPU exits blocking as
   the WARN is user-triggerable, and because exiting to userspace on -EBUSY
   does more harm than good in pretty much every situation.

 - Throw in the towel and drop the WARN on INIT/SIPI being blocked when vCPU is
   in Wait-For-SIPI, as playing whack-a-mole with syzkaller turned out to be an
   unwinnable game.

 - Add support for new Intel instructions that don't require anything beyond
   enumerating feature flags to userspace.

 - Grab SRCU when reading PDPTRs in KVM_GET_SREGS2.

 - Add WARNs to guard against modifying KVM's CPU caps outside of the intended
   setup flow, as nested VMX in particular is sensitive to unexpected changes
   in KVM's golden configuration.

 - Add a quirk to allow userspace to opt-in to actually suppress EOI broadcasts
   when the suppression feature is enabled by the guest (currently limited to
   split IRQCHIP, i.e. userspace I/O APIC).  Sadly, simply fixing KVM to honor
   Suppress EOI Broadcasts isn't an option as some userspaces have come to rely
   on KVM's buggy behavior (KVM advertises Supress EOI Broadcast irrespective
   of whether or not userspace I/O APIC supports Directed EOIs).

 - Minor cleanups.
parents 4215ee0d 6517dfbc
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -7910,6 +7910,8 @@ Valid feature flags in args[0] are::

  #define KVM_X2APIC_API_USE_32BIT_IDS                          (1ULL << 0)
  #define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK                (1ULL << 1)
  #define KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST              (1ULL << 2)
  #define KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST             (1ULL << 3)

Enabling KVM_X2APIC_API_USE_32BIT_IDS changes the behavior of
KVM_SET_GSI_ROUTING, KVM_SIGNAL_MSI, KVM_SET_LAPIC, and KVM_GET_LAPIC,
@@ -7922,6 +7924,28 @@ as a broadcast even in x2APIC mode in order to support physical x2APIC
without interrupt remapping.  This is undesirable in logical mode,
where 0xff represents CPUs 0-7 in cluster 0.

Setting KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST instructs KVM to enable
Suppress EOI Broadcasts.  KVM will advertise support for Suppress EOI
Broadcast to the guest and suppress LAPIC EOI broadcasts when the guest
sets the Suppress EOI Broadcast bit in the SPIV register.  This flag is
supported only when using a split IRQCHIP.

Setting KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST disables support for
Suppress EOI Broadcasts entirely, i.e. instructs KVM to NOT advertise
support to the guest.

Modern VMMs should either enable KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST
or KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST.  If not, legacy quirky
behavior will be used by KVM: in split IRQCHIP mode, KVM will advertise
support for Suppress EOI Broadcasts but not actually suppress EOI
broadcasts; for in-kernel IRQCHIP mode, KVM will not advertise support for
Suppress EOI Broadcasts.

Setting both KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST and
KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST will fail with an EINVAL error,
as will setting KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST without a split
IRCHIP.

7.8 KVM_CAP_S390_USER_INSTR0
----------------------------

+1 −0
Original line number Diff line number Diff line
@@ -326,6 +326,7 @@
#define X86_FEATURE_AMX_FP16		(12*32+21) /* AMX fp16 Support */
#define X86_FEATURE_AVX_IFMA            (12*32+23) /* Support for VPMADD52[H,L]UQ */
#define X86_FEATURE_LAM			(12*32+26) /* "lam" Linear Address Masking */
#define X86_FEATURE_MOVRS		(12*32+31) /* MOVRS instructions */

/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
#define X86_FEATURE_CLZERO		(13*32+ 0) /* "clzero" CLZERO instruction */
+9 −0
Original line number Diff line number Diff line
@@ -784,6 +784,8 @@ enum kvm_only_cpuid_leafs {
	CPUID_24_0_EBX,
	CPUID_8000_0021_ECX,
	CPUID_7_1_ECX,
	CPUID_1E_1_EAX,
	CPUID_24_1_ECX,
	NR_KVM_CPU_CAPS,

	NKVMCAPINTS = NR_KVM_CPU_CAPS - NCAPINTS,
@@ -1234,6 +1236,12 @@ enum kvm_irqchip_mode {
	KVM_IRQCHIP_SPLIT,        /* created with KVM_CAP_SPLIT_IRQCHIP */
};

enum kvm_suppress_eoi_broadcast_mode {
	KVM_SUPPRESS_EOI_BROADCAST_QUIRKED, /* Legacy behavior */
	KVM_SUPPRESS_EOI_BROADCAST_ENABLED, /* Enable Suppress EOI broadcast */
	KVM_SUPPRESS_EOI_BROADCAST_DISABLED /* Disable Suppress EOI broadcast */
};

struct kvm_x86_msr_filter {
	u8 count;
	bool default_allow:1;
@@ -1483,6 +1491,7 @@ struct kvm_arch {

	bool x2apic_format;
	bool x2apic_broadcast_quirk_disabled;
	enum kvm_suppress_eoi_broadcast_mode suppress_eoi_broadcast_mode;

	bool has_mapped_host_mmio;
	bool guest_can_read_msr_platform_info;
+4 −2
Original line number Diff line number Diff line
@@ -916,8 +916,10 @@ struct kvm_sev_snp_launch_finish {
	__u64 pad1[4];
};

#define KVM_X2APIC_API_USE_32BIT_IDS            (1ULL << 0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK  (1ULL << 1)
#define KVM_X2APIC_API_USE_32BIT_IDS			_BITULL(0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK		_BITULL(1)
#define KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST	_BITULL(2)
#define KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST	_BITULL(3)

struct kvm_hyperv_eventfd {
	__u32 conn_id;
+49 −0
Original line number Diff line number Diff line
@@ -47,3 +47,52 @@ $(obj)/kvm-asm-offsets.h: $(obj)/kvm-asm-offsets.s FORCE

targets += kvm-asm-offsets.s
clean-files += kvm-asm-offsets.h


# Fail the build if there is unexpected EXPORT_SYMBOL_GPL (or EXPORT_SYMBOL)
# usage.  All KVM-internal exports should use EXPORT_SYMBOL_FOR_KVM_INTERNAL.
# Only a handful of exports intended for other modules (VFIO, KVMGT) should
# use EXPORT_SYMBOL_GPL, and EXPORT_SYMBOL should never be used.
ifdef CONFIG_KVM_X86
# Search recursively for whole words and print line numbers.  Filter out the
# allowed set of exports, i.e. those that are intended for external usage.
exports_grep_trailer := --include='*.[ch]' -nrw $(srctree)/virt/kvm $(srctree)/arch/x86/kvm | \
			grep -v -e kvm_page_track_register_notifier \
				-e kvm_page_track_unregister_notifier \
				-e kvm_write_track_add_gfn \
				-e kvm_write_track_remove_gfn \
				-e kvm_get_kvm \
				-e kvm_get_kvm_safe \
				-e kvm_put_kvm

# Force grep to emit a goofy group separator that can in turn be replaced with
# the above newline macro (newlines in Make are a nightmare).  Note, grep only
# prints the group separator when N lines of context are requested via -C,
# a.k.a. --NUM.  Simply request zero lines.  Print the separator only after
# filtering out expected exports to avoid extra newlines in the error message.
define get_kvm_exports
$(shell grep "$(1)" -C0 $(exports_grep_trailer) | grep "$(1)" -C0 --group-separator="!SEP!")
endef

define check_kvm_exports
nr_kvm_exports := $(shell grep "$(1)" $(exports_grep_trailer) | wc -l)

ifneq (0,$$(nr_kvm_exports))
$$(error ERROR ***\
$$(newline)found $$(nr_kvm_exports) unwanted occurrences of $(1):\
$$(newline)  $(subst !SEP!,$$(newline) ,$(call get_kvm_exports,$(1)))\
$$(newline)in directories:\
$$(newline)  $(srctree)/arch/x86/kvm\
$$(newline)  $(srctree)/virt/kvm\
$$(newline)Use EXPORT_SYMBOL_FOR_KVM_INTERNAL, not $(1))
endif # nr_kvm_exports != 0
undefine nr_kvm_exports
endef # check_kvm_exports

$(eval $(call check_kvm_exports,EXPORT_SYMBOL_GPL))
$(eval $(call check_kvm_exports,EXPORT_SYMBOL))

undefine check_kvm_exports
undefine get_kvm_exports
undefine exports_grep_trailer
endif # CONFIG_KVM_X86
Loading