FAILED: patch "[PATCH] KVM: x86: Check EFER validity on KVM_SET_SREGS*" failed to apply to 7.2-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 7.2-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-7.2.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 '2026090910-manned-fang-c784@gregkh' --subject-prefix 'PATCH 7.2.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
@@ -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,
Sasha Levin
maintainerPATCH 1/5 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
@@ -12685,7 +12685,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 );
@@ -12694,13 +12694,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);
@@ -12716,6 +12721,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
Sasha Levin
maintainerPATCH 2/5 KVM: x86: Move get_segment_base() to regs.h, as kvm_get_segment_base()
From: Sean Christopherson <[email protected]>
[ Upstream commit 0217de73439caf56db74da95b3bbad8c1cb066c4 ]
Move get_segment_base() to regs.h, as kvm_get_segment_base(), so that the bulk of the register code can be moved from x86.c to a new regs.c, without simultaneously needing to rename "public" helpers to explicitly scope them to KVM.
No functional change intended.
Message-ID: <[email protected]>
Stable-dep-of: 184bd464bdb6 ("KVM: x86: Check EFER validity on KVM_SET_SREGS*")
--- arch/x86/kvm/regs.h | 5 +++++ arch/x86/kvm/x86.c | 9 ++------- 2 files changed, 7 insertions(+), 7 deletions(-)
arch/x86/kvm/regs.h +5 -0
@@ -420,4 +420,9 @@ static inline bool is_guest_mode(struct kvm_vcpu *vcpu) return vcpu->arch.hflags & HF_GUEST_MASK; } +static inline unsigned long kvm_get_segment_base (struct kvm_vcpu *vcpu,int seg) +{ +return kvm_x86_call (get_segment_base)(vcpu, seg); +} +#endif
arch/x86/kvm/x86.c +2 -7
@@ -8492,11 +8492,6 @@ static int emulator_pio_out_emulated(struct x86_emulate_ctxt *ctxt,return emulator_pio_out (emul_to_vcpu (ctxt), size, port, val, count); } -static unsigned long get_segment_base (struct kvm_vcpu *vcpu,int seg) -{ -return kvm_x86_call (get_segment_base)(vcpu, seg); -} -static void emulator_invlpg (struct x86_emulate_ctxt *ctxt,ulong address) {kvm_mmu_invlpg (emul_to_vcpu (ctxt), address);
@@ -8641,7 +8636,7 @@ static void emulator_set_idt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)static unsigned long emulator_get_cached_segment_base (struct x86_emulate_ctxt *ctxt,int seg) { -return get_segment_base (emul_to_vcpu (ctxt), seg); +return kvm_get_segment_base (emul_to_vcpu (ctxt), seg); } static bool emulator_get_segment(struct x86_emulate_ctxt *ctxt, u16 *selector,
@@ -13843,7 +13838,7 @@ unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu)if (is_64_bit_mode (vcpu))return kvm_rip_read (vcpu); -return (u32)(get_segment_base (vcpu,VCPU_SREG_CS ) + +return (u32)(kvm_get_segment_base (vcpu,VCPU_SREG_CS ) +kvm_rip_read (vcpu)); }EXPORT_SYMBOL_FOR_KVM_INTERNAL (kvm_get_linear_rip);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/5 KVM: x86: Rename __{g,s}et_sregs2() => kvm_vcpu_ioctl_x86_{g,s}et_sregs2()
In reply to Sasha LevinFrom: 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
@@ -133,8 +133,10 @@ static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);static void store_regs (struct kvm_vcpu *vcpu);static int sync_regs (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);static void kvm_load_guest_fpu (struct kvm_vcpu *vcpu);
@@ -6623,7 +6625,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;
@@ -6642,7 +6644,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 :
@@ -12210,7 +12212,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;
@@ -12478,7 +12481,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
Sasha Levin
maintainerPATCH 4/5 KVM: x86: Move the bulk of register specific code from x86.c to regs.c
In reply to Sasha LevinFrom: 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]>
Stable-dep-of: 184bd464bdb6 ("KVM: x86: Check EFER validity on KVM_SET_SREGS*")
--- arch/x86/kvm/Makefile | 4 +- arch/x86/kvm/regs.c | 873 +++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/regs.h | 25 ++ arch/x86/kvm/x86.c | 885 +----------------------------------------- arch/x86/kvm/x86.h | 2 + 5 files changed, 904 insertions(+), 885 deletions(-) create mode 100644 arch/x86/kvm/regs.c
arch/x86/kvm/Makefile +2 -2
@@ -5,8 +5,8 @@ ccflags-$(CONFIG_KVM_WERROR) += -Werror include $(srctree)/virt/kvm/Makefile.kvm -kvm-y += x86.o emulate.o irq.o lapic.o cpuid.o pmu.o mtrr.o \ - debugfs.o mmu/mmu.o mmu/page_track.o mmu/spte.o +kvm-y += x86.o emulate.o irq.o lapic.o cpuid.o pmu.o regs.o \ + mtrr.o debugfs.o mmu/mmu.o mmu/page_track.o mmu/spte.o kvm-$(CONFIG_X86_64) += mmu/tdp_iter.o mmu/tdp_mmu.o kvm-$(CONFIG_KVM_IOAPIC) += i8259.o i8254.o ioapic.o
arch/x86/kvm/regs.c new file +873 -0
873 lines not on this page · raw message
arch/x86/kvm/regs.h +25 -0
@@ -397,6 +397,14 @@ static inline bool kvm_dr6_valid(u64 data)return !(data >>32 ); } +static inline unsigned long kvm_get_effective_dr7 (struct kvm_vcpu *vcpu) +{ +if (vcpu->guest_debug &KVM_GUESTDBG_USE_HW_BP ) +return vcpu->arch.guest_debug_dr7; + +return vcpu->arch.dr7; +} +static inline void enter_guest_mode (struct kvm_vcpu *vcpu) { vcpu->arch.hflags |=HF_GUEST_MASK ;
@@ -425,4 +433,21 @@ static inline unsigned long kvm_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); + +#endif
arch/x86/kvm/x86.c +2 -883
954 lines not on this page · raw message
arch/x86/kvm/x86.h +2 -0
@@ -403,6 +403,7 @@ int handle_ud(struct kvm_vcpu *vcpu);void kvm_deliver_exception_payload (struct kvm_vcpu *vcpu,struct kvm_queued_exception *ex); +void kvm_handle_exception_payload_quirk (struct kvm_vcpu *vcpu);int kvm_mtrr_set_msr (struct kvm_vcpu *vcpu,u32 msr,u64 data);int kvm_mtrr_get_msr (struct kvm_vcpu *vcpu,u32 msr,u64 *pdata);
@@ -597,6 +598,7 @@ static inline void kvm_machine_check(void)int kvm_spec_ctrl_test_value (u64 value);int kvm_handle_memory_failure (struct kvm_vcpu *vcpu,int r,struct x86_exception *e); +void kvm_invalidate_pcid (struct kvm_vcpu *vcpu,unsigned long pcid);int kvm_handle_invpcid (struct kvm_vcpu *vcpu,unsigned long type,gva_t gva);bool kvm_msr_allowed (struct kvm_vcpu *vcpu,u32 index,u32 type);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 5/5 KVM: x86: Check EFER validity on KVM_SET_SREGS*
In reply to Sasha LevinFrom: 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
@@ -563,7 +563,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