Skip to contentSkip to conversation

FAILED: patch "[PATCH] KVM: x86: Check EFER validity on KVM_SET_SREGS*" failed to apply to 6.12-stable tree

PATCH New [email protected] 2 participants 5 messages Sep 9 – Sep 11

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 184bd464bdb66daa9173670904f24c29c7b7f7d4
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090911-keg-hunk-4c3e@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 184bd464bdb66daa9173670904f24c29c7b7f7d4 Mon Sep 17 00:00:00 2001
From: Yosry Ahmed <[email protected]>
Date: Mon, 13 Jul 2026 18:01:52 +0000
Subject: [PATCH] KVM: x86: Check EFER validity on KVM_SET_SREGS*

When handling userspace SREGS writes, check the validity of EFER (i.e. allowed bits) before writing the new value of EFER through the per-vendor set_efer callbacks. This prevents userspace from writing bogus values (e.g. EFER.SVME=1 with nested=0).

Note: on KVM_SET_MSRS, KVM only checks EFER validity in terms of KVM caps, not guest caps, so it is possible to set EFER bits that are supported by KVM but not by the guest CPUID. Potentially allowing userspace to set msrs before CPUID.

However, for KVM_SET_SREGS*, check the validity of the set bits against both KVM and guest caps. This is consistent with other validity checks (e.g. for CR4) that check validity against guest caps, which already imposes the need to set CPUID before SREGS.

arch/x86/kvm/regs.c +2 -1
index bd8147798cc3..8f66438989e4 100644
@@ -564,7 +564,8 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	}
 
 	return kvm_is_valid_cr4(vcpu, sregs->cr4) &&
-	       kvm_is_valid_cr0(vcpu, sregs->cr0);
+	       kvm_is_valid_cr0(vcpu, sregs->cr0) &&
+	       kvm_valid_efer(vcpu, sregs->efer);
 }
 
 static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
maintainer
#1 lore raw

PATCH 1/4 KVM: x86: Extract REGS and SREGS runtime sync code to helpers

From: Sean Christopherson <[email protected]>

[ Upstream commit 6a8a98aa9c147eb63f5a360f157f207bf46c05ee ]

Extract the REGS and SREGS portions of {store,sync}_regs() into separate helpers in anticipation of moving the register specific code out of x86.c and into regs.c.

No functional change intended.

Message-ID: <[email protected]>

Stable-dep-of: 184bd464bdb6 ("KVM: x86: Check EFER validity on KVM_SET_SREGS*")

---
 arch/x86/kvm/x86.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)
arch/x86/kvm/x86.c +15 -2
index 9e7c9e3edb5b4..34dc99d6e4871 100644
@@ -12307,7 +12307,7 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 	return 0;
 }
 
-static void store_regs(struct kvm_vcpu *vcpu)
+static void kvm_run_sync_regs_to_user(struct kvm_vcpu *vcpu)
 {
 	BUILD_BUG_ON(sizeof(struct kvm_sync_regs) > SYNC_REGS_SIZE_BYTES);
 
@@ -12316,13 +12316,18 @@ static void store_regs(struct kvm_vcpu *vcpu)
 
 	if (vcpu->run->kvm_valid_regs & KVM_SYNC_X86_SREGS)
 		__get_sregs(vcpu, &vcpu->run->s.regs.sregs);
+}
+
+static void store_regs(struct kvm_vcpu *vcpu)
+{
+	kvm_run_sync_regs_to_user(vcpu);
 
 	if (vcpu->run->kvm_valid_regs & KVM_SYNC_X86_EVENTS)
 		kvm_vcpu_ioctl_x86_get_vcpu_events(
 				vcpu, &vcpu->run->s.regs.events);
 }
 
-static int sync_regs(struct kvm_vcpu *vcpu)
+static int kvm_run_sync_regs_from_user(struct kvm_vcpu *vcpu)
 {
 	if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_REGS) {
 		__set_regs(vcpu, &vcpu->run->s.regs.regs);
@@ -12338,6 +12343,14 @@ static int sync_regs(struct kvm_vcpu *vcpu)
 		vcpu->run->kvm_dirty_regs &= ~KVM_SYNC_X86_SREGS;
 	}
 
+	return 0;
+}
+
+static int sync_regs(struct kvm_vcpu *vcpu)
+{
+	if (kvm_run_sync_regs_from_user(vcpu))
+		return -EINVAL;
+
 	if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_EVENTS) {
 		struct kvm_vcpu_events events = vcpu->run->s.regs.events;
 
Signature · 1 line
2.53.0
maintainer
#2 lore raw

PATCH 2/4 KVM: x86: Rename __{g,s}et_sregs2() => kvm_vcpu_ioctl_x86_{g,s}et_sregs2()

From: Sean Christopherson <[email protected]>

[ Upstream commit bd130c8d72a1c7dde5523b3f3fae9867eafaa1dc ]

Rename the KVM_{G,S}ET_SREGS2 helpers in anticipation of moving them out of x86.c (while leaving the ioctl dispatch behind). Having globally visible APIs named __{g,s}et_sregs2() would be "fine", but ugly, given that __{g,s}et_sregs() will NOT be globally visible. As a bonus, this makes it a bit more obvious that the helpers implement newer versions of kvm_arch_vcpu_ioctl_set_sregs().

No functional change intended.

Message-ID: <[email protected]>

Stable-dep-of: 184bd464bdb6 ("KVM: x86: Check EFER validity on KVM_SET_SREGS*")

---
 arch/x86/kvm/x86.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
arch/x86/kvm/x86.c +10 -6
index 34dc99d6e4871..7080d66ecf99a 100644
@@ -135,8 +135,10 @@ static void store_regs(struct kvm_vcpu *vcpu);
 static int sync_regs(struct kvm_vcpu *vcpu);
 static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu);
 
-static int __set_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
-static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
+static int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
+					 struct kvm_sregs2 *sregs2);
+static void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
+					  struct kvm_sregs2 *sregs2);
 
 static DEFINE_MUTEX(vendor_module_lock);
 struct kvm_x86_ops kvm_x86_ops __read_mostly;
@@ -6304,7 +6306,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 		r = -ENOMEM;
 		if (!u.sregs2)
 			goto out;
-		__get_sregs2(vcpu, u.sregs2);
+		kvm_vcpu_ioctl_x86_get_sregs2(vcpu, u.sregs2);
 		r = -EFAULT;
 		if (copy_to_user(argp, u.sregs2, sizeof(struct kvm_sregs2)))
 			goto out;
@@ -6323,7 +6325,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 			u.sregs2 = NULL;
 			goto out;
 		}
-		r = __set_sregs2(vcpu, u.sregs2);
+		r = kvm_vcpu_ioctl_x86_set_sregs2(vcpu, u.sregs2);
 		break;
 	}
 	case KVM_HAS_DEVICE_ATTR:
@@ -11842,7 +11844,8 @@ static void __get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 			(unsigned long *)sregs->interrupt_bitmap);
 }
 
-static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2)
+static void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
+					  struct kvm_sregs2 *sregs2)
 {
 	int i;
 
@@ -12105,7 +12108,8 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	return 0;
 }
 
-static int __set_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2)
+static int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
+					 struct kvm_sregs2 *sregs2)
 {
 	int mmu_reset_needed = 0;
 	bool valid_pdptrs = sregs2->flags & KVM_SREGS2_FLAGS_PDPTRS_VALID;
Signature · 1 line
2.53.0
maintainer
#3 lore raw

PATCH 3/4 KVM: x86: Move the bulk of register specific code from x86.c to regs.c

In reply to Sasha Levin

From: Sean Christopherson <[email protected]>

[ Upstream commit 2f5bb3fe583510cf20f9d64aa73089577be3dc36 ]

Introduce regs.c, and move the vast majority of register specific code out of x86.c and into regs.c. Deliberately leave behind MSR code, as KVM's MSR support is complex enough to warrant its own compilation unit, and doesn't have much in common with the other register code.

Note, "struct kvm_sregs" has fields for EFER and MSR_IA32_APICBASE, and so the {G,S}ET_REGS flows technically contain a tiny amount of MSR code. MSR_IA32_APICBASE is already managed by lapic.c, and so doesn't require a "placement decision". As for EFER, leave all other EFER handling in x86.c (later to be moved to msrs.c). The primary interface to EFER, set_efer(), is very much MSR specific, even though EFER is arguably more of a Control Register than an MSR.

No functional change intended.

Message-ID: <[email protected]>

Backport to 6.12: move the existing stable register implementations instead of importing upstream versions that depend on newer MMU, APIC, register cache and symbol-export interfaces. Keep the stable Makefile objects and add regs.o. Use kvm_cache_regs.h and x86.h instead of introducing regs.h.

Move the existing kvm_pv_async_pf_enabled() and get_segment_base() helpers to x86.h for use by both compilation units, and expose the existing update_cr8_intercept() alongside the upstream cross-file declarations. Preserve all function bodies and exported symbols; no new functions are introduced. The resulting regs.c accepts the EFER validation fix in 184bd464bdb66daa9173670904f24c29c7b7f7d4 without changes.

[ sashal: Reduced backport -- upstream 2f5bb3fe58351 touches 5 file(s), this
backport carries 4. Not backported here:
arch/x86/kvm/regs.h
This note is generated from the file lists only; see the resolution record for the reasoning. ]

Stable-dep-of: 184bd464bdb6 ("KVM: x86: Check EFER validity on KVM_SET_SREGS*")

---
 arch/x86/kvm/Makefile |   2 +-
 arch/x86/kvm/regs.c   | 871 +++++++++++++++++++++++++++++++++++++++++
 arch/x86/kvm/x86.c    | 889 +-----------------------------------------
 arch/x86/kvm/x86.h    |  28 ++
 4 files changed, 903 insertions(+), 887 deletions(-)
 create mode 100644 arch/x86/kvm/regs.c
arch/x86/kvm/Makefile +1 -1
index f9dddb8cb4669..8e5b4e29d4828 100644
@@ -6,7 +6,7 @@ ccflags-$(CONFIG_KVM_WERROR) += -Werror
 include $(srctree)/virt/kvm/Makefile.kvm
 
 kvm-y			+= x86.o emulate.o i8259.o irq.o lapic.o \
-			   i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
+			   i8254.o ioapic.o irq_comm.o cpuid.o pmu.o regs.o mtrr.o \
 			   debugfs.o mmu/mmu.o mmu/page_track.o \
 			   mmu/spte.o
 
arch/x86/kvm/regs.c new file +871 -0

871 lines not on this page · raw message

arch/x86/kvm/x86.c +3 -886

972 lines not on this page · raw message

arch/x86/kvm/x86.h +28 -0
index a1bd382232f43..ffd53e8b63059 100644
@@ -615,4 +615,32 @@ int kvm_sev_es_string_io(struct kvm_vcpu *vcpu, unsigned int size,
 			 unsigned int port, void *data,  unsigned int count,
 			 int in);
 
+static inline bool kvm_pv_async_pf_enabled(struct kvm_vcpu *vcpu)
+{
+	u64 mask = KVM_ASYNC_PF_ENABLED | KVM_ASYNC_PF_DELIVERY_AS_INT;
+
+	return (vcpu->arch.apf.msr_en_val & mask) == mask;
+}
+
+static inline unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
+{
+	return kvm_x86_call(get_segment_base)(vcpu, seg);
+}
+
+void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
+void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
+				   struct kvm_sregs2 *sregs2);
+int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
+				  struct kvm_sregs2 *sregs2);
+void kvm_run_sync_regs_to_user(struct kvm_vcpu *vcpu);
+int kvm_run_sync_regs_from_user(struct kvm_vcpu *vcpu);
+void kvm_update_dr0123(struct kvm_vcpu *vcpu);
+int kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
+				     struct kvm_debugregs *dbgregs);
+int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
+				     struct kvm_debugregs *dbgregs);
+void kvm_invalidate_pcid(struct kvm_vcpu *vcpu, unsigned long pcid);
+void kvm_handle_exception_payload_quirk(struct kvm_vcpu *vcpu);
+void update_cr8_intercept(struct kvm_vcpu *vcpu);
+
 #endif
Signature · 1 line
2.53.0
maintainer
#4 lore raw

PATCH 4/4 KVM: x86: Check EFER validity on KVM_SET_SREGS*

In reply to Sasha Levin

From: Yosry Ahmed <[email protected]>

[ Upstream commit 184bd464bdb66daa9173670904f24c29c7b7f7d4 ]

When handling userspace SREGS writes, check the validity of EFER (i.e. allowed bits) before writing the new value of EFER through the per-vendor set_efer callbacks. This prevents userspace from writing bogus values (e.g. EFER.SVME=1 with nested=0).

Note: on KVM_SET_MSRS, KVM only checks EFER validity in terms of KVM caps, not guest caps, so it is possible to set EFER bits that are supported by KVM but not by the guest CPUID. Potentially allowing userspace to set msrs before CPUID.

However, for KVM_SET_SREGS*, check the validity of the set bits against both KVM and guest caps. This is consistent with other validity checks (e.g. for CR4) that check validity against guest caps, which already imposes the need to set CPUID before SREGS.

---
 arch/x86/kvm/regs.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kvm/regs.c +2 -1
index 82f217e126a59..26ee933ef5490 100644
@@ -556,7 +556,8 @@ static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	}
 
 	return kvm_is_valid_cr4(vcpu, sregs->cr4) &&
-	       kvm_is_valid_cr0(vcpu, sregs->cr0);
+	       kvm_is_valid_cr0(vcpu, sregs->cr0) &&
+	       kvm_valid_efer(vcpu, sregs->efer);
 }
 
 static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
Signature · 1 line
2.53.0