]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jul 2025 07:13:44 +0000 (09:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jul 2025 07:13:44 +0000 (09:13 +0200)
added patches:
input-gpio-keys-fix-a-sleep-while-atomic-with-preempt_rt.patch
series
x86-traps-initialize-dr7-by-writing-its-architectural-reset-value.patch

queue-6.12/input-gpio-keys-fix-a-sleep-while-atomic-with-preempt_rt.patch [new file with mode: 0644]
queue-6.12/series [new file with mode: 0644]
queue-6.12/x86-traps-initialize-dr7-by-writing-its-architectural-reset-value.patch [new file with mode: 0644]

diff --git a/queue-6.12/input-gpio-keys-fix-a-sleep-while-atomic-with-preempt_rt.patch b/queue-6.12/input-gpio-keys-fix-a-sleep-while-atomic-with-preempt_rt.patch
new file mode 100644 (file)
index 0000000..f676502
--- /dev/null
@@ -0,0 +1,68 @@
+From f4a8f561d08e39f7833d4a278ebfb12a41eef15f Mon Sep 17 00:00:00 2001
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Date: Fri, 30 May 2025 15:36:43 -0700
+Subject: Input: gpio-keys - fix a sleep while atomic with PREEMPT_RT
+
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+
+commit f4a8f561d08e39f7833d4a278ebfb12a41eef15f upstream.
+
+When enabling PREEMPT_RT, the gpio_keys_irq_timer() callback runs in
+hard irq context, but the input_event() takes a spin_lock, which isn't
+allowed there as it is converted to a rt_spin_lock().
+
+[ 4054.289999] BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
+[ 4054.290028] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/0
+...
+[ 4054.290195]  __might_resched+0x13c/0x1f4
+[ 4054.290209]  rt_spin_lock+0x54/0x11c
+[ 4054.290219]  input_event+0x48/0x80
+[ 4054.290230]  gpio_keys_irq_timer+0x4c/0x78
+[ 4054.290243]  __hrtimer_run_queues+0x1a4/0x438
+[ 4054.290257]  hrtimer_interrupt+0xe4/0x240
+[ 4054.290269]  arch_timer_handler_phys+0x2c/0x44
+[ 4054.290283]  handle_percpu_devid_irq+0x8c/0x14c
+[ 4054.290297]  handle_irq_desc+0x40/0x58
+[ 4054.290307]  generic_handle_domain_irq+0x1c/0x28
+[ 4054.290316]  gic_handle_irq+0x44/0xcc
+
+Considering the gpio_keys_irq_isr() can run in any context, e.g. it can
+be threaded, it seems there's no point in requesting the timer isr to
+run in hard irq context.
+
+Relax the hrtimer not to use the hard context.
+
+Fixes: 019002f20cb5 ("Input: gpio-keys - use hrtimer for release timer")
+Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
+Link: https://lore.kernel.org/r/20250528-gpio_keys_preempt_rt-v2-1-3fc55a9c3619@foss.st.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+[ adjusted context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/input/keyboard/gpio_keys.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/input/keyboard/gpio_keys.c
++++ b/drivers/input/keyboard/gpio_keys.c
+@@ -488,7 +488,7 @@ static irqreturn_t gpio_keys_irq_isr(int
+       if (bdata->release_delay)
+               hrtimer_start(&bdata->release_timer,
+                             ms_to_ktime(bdata->release_delay),
+-                            HRTIMER_MODE_REL_HARD);
++                            HRTIMER_MODE_REL);
+ out:
+       return IRQ_HANDLED;
+ }
+@@ -633,7 +633,7 @@ static int gpio_keys_setup_key(struct pl
+               bdata->release_delay = button->debounce_interval;
+               hrtimer_init(&bdata->release_timer,
+-                           CLOCK_REALTIME, HRTIMER_MODE_REL_HARD);
++                           CLOCK_REALTIME, HRTIMER_MODE_REL);
+               bdata->release_timer.function = gpio_keys_irq_timer;
+               isr = gpio_keys_irq_isr;
diff --git a/queue-6.12/series b/queue-6.12/series
new file mode 100644 (file)
index 0000000..98349df
--- /dev/null
@@ -0,0 +1,2 @@
+x86-traps-initialize-dr7-by-writing-its-architectural-reset-value.patch
+input-gpio-keys-fix-a-sleep-while-atomic-with-preempt_rt.patch
diff --git a/queue-6.12/x86-traps-initialize-dr7-by-writing-its-architectural-reset-value.patch b/queue-6.12/x86-traps-initialize-dr7-by-writing-its-architectural-reset-value.patch
new file mode 100644 (file)
index 0000000..7174a41
--- /dev/null
@@ -0,0 +1,161 @@
+From fa7d0f83c5c4223a01598876352473cb3d3bd4d7 Mon Sep 17 00:00:00 2001
+From: "Xin Li (Intel)" <xin@zytor.com>
+Date: Fri, 20 Jun 2025 16:15:04 -0700
+Subject: x86/traps: Initialize DR7 by writing its architectural reset value
+
+From: Xin Li (Intel) <xin@zytor.com>
+
+commit fa7d0f83c5c4223a01598876352473cb3d3bd4d7 upstream.
+
+Initialize DR7 by writing its architectural reset value to always set
+bit 10, which is reserved to '1', when "clearing" DR7 so as not to
+trigger unanticipated behavior if said bit is ever unreserved, e.g. as
+a feature enabling flag with inverted polarity.
+
+Signed-off-by: Xin Li (Intel) <xin@zytor.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
+Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Sean Christopherson <seanjc@google.com>
+Tested-by: Sohil Mehta <sohil.mehta@intel.com>
+Cc:stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20250620231504.2676902-3-xin%40zytor.com
+[ context adjusted: no KVM_DEBUGREG_AUTO_SWITCH flag test" ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/debugreg.h |   19 +++++++++++++++----
+ arch/x86/include/asm/kvm_host.h |    2 +-
+ arch/x86/kernel/cpu/common.c    |    2 +-
+ arch/x86/kernel/kgdb.c          |    2 +-
+ arch/x86/kernel/process_32.c    |    2 +-
+ arch/x86/kernel/process_64.c    |    2 +-
+ arch/x86/kvm/x86.c              |    4 ++--
+ 7 files changed, 22 insertions(+), 11 deletions(-)
+
+--- a/arch/x86/include/asm/debugreg.h
++++ b/arch/x86/include/asm/debugreg.h
+@@ -9,6 +9,14 @@
+ #include <asm/cpufeature.h>
+ #include <asm/msr.h>
++/*
++ * Define bits that are always set to 1 in DR7, only bit 10 is
++ * architecturally reserved to '1'.
++ *
++ * This is also the init/reset value for DR7.
++ */
++#define DR7_FIXED_1   0x00000400
++
+ DECLARE_PER_CPU(unsigned long, cpu_dr7);
+ #ifndef CONFIG_PARAVIRT_XXL
+@@ -100,8 +108,8 @@ static __always_inline void native_set_d
+ static inline void hw_breakpoint_disable(void)
+ {
+-      /* Zero the control register for HW Breakpoint */
+-      set_debugreg(0UL, 7);
++      /* Reset the control register for HW Breakpoint */
++      set_debugreg(DR7_FIXED_1, 7);
+       /* Zero-out the individual HW breakpoint address registers */
+       set_debugreg(0UL, 0);
+@@ -125,9 +133,12 @@ static __always_inline unsigned long loc
+               return 0;
+       get_debugreg(dr7, 7);
+-      dr7 &= ~0x400; /* architecturally set bit */
++
++      /* Architecturally set bit */
++      dr7 &= ~DR7_FIXED_1;
+       if (dr7)
+-              set_debugreg(0, 7);
++              set_debugreg(DR7_FIXED_1, 7);
++
+       /*
+        * Ensure the compiler doesn't lower the above statements into
+        * the critical section; disabling breakpoints late would not
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -31,6 +31,7 @@
+ #include <asm/apic.h>
+ #include <asm/pvclock-abi.h>
++#include <asm/debugreg.h>
+ #include <asm/desc.h>
+ #include <asm/mtrr.h>
+ #include <asm/msr-index.h>
+@@ -246,7 +247,6 @@ enum x86_intercept_stage;
+ #define DR7_BP_EN_MASK        0x000000ff
+ #define DR7_GE                (1 << 9)
+ #define DR7_GD                (1 << 13)
+-#define DR7_FIXED_1   0x00000400
+ #define DR7_VOLATILE  0xffff2bff
+ #define KVM_GUESTDBG_VALID_MASK \
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -2160,7 +2160,7 @@ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard)
+ static void initialize_debug_regs(void)
+ {
+       /* Control register first -- to make sure everything is disabled. */
+-      set_debugreg(0, 7);
++      set_debugreg(DR7_FIXED_1, 7);
+       set_debugreg(DR6_RESERVED, 6);
+       /* dr5 and dr4 don't exist */
+       set_debugreg(0, 3);
+--- a/arch/x86/kernel/kgdb.c
++++ b/arch/x86/kernel/kgdb.c
+@@ -385,7 +385,7 @@ static void kgdb_disable_hw_debug(struct
+       struct perf_event *bp;
+       /* Disable hardware debugging while we are in kgdb: */
+-      set_debugreg(0UL, 7);
++      set_debugreg(DR7_FIXED_1, 7);
+       for (i = 0; i < HBP_NUM; i++) {
+               if (!breakinfo[i].enabled)
+                       continue;
+--- a/arch/x86/kernel/process_32.c
++++ b/arch/x86/kernel/process_32.c
+@@ -93,7 +93,7 @@ void __show_regs(struct pt_regs *regs, e
+       /* Only print out debug registers if they are in their non-default state. */
+       if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
+-          (d6 == DR6_RESERVED) && (d7 == 0x400))
++          (d6 == DR6_RESERVED) && (d7 == DR7_FIXED_1))
+               return;
+       printk("%sDR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -132,7 +132,7 @@ void __show_regs(struct pt_regs *regs, e
+       /* Only print out debug registers if they are in their non-default state. */
+       if (!((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
+-          (d6 == DR6_RESERVED) && (d7 == 0x400))) {
++          (d6 == DR6_RESERVED) && (d7 == DR7_FIXED_1))) {
+               printk("%sDR0: %016lx DR1: %016lx DR2: %016lx\n",
+                      log_lvl, d0, d1, d2);
+               printk("%sDR3: %016lx DR6: %016lx DR7: %016lx\n",
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -10959,7 +10959,7 @@ static int vcpu_enter_guest(struct kvm_v
+               wrmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err);
+       if (unlikely(vcpu->arch.switch_db_regs)) {
+-              set_debugreg(0, 7);
++              set_debugreg(DR7_FIXED_1, 7);
+               set_debugreg(vcpu->arch.eff_db[0], 0);
+               set_debugreg(vcpu->arch.eff_db[1], 1);
+               set_debugreg(vcpu->arch.eff_db[2], 2);
+@@ -10968,7 +10968,7 @@ static int vcpu_enter_guest(struct kvm_v
+               if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT))
+                       kvm_x86_call(set_dr6)(vcpu, vcpu->arch.dr6);
+       } else if (unlikely(hw_breakpoint_active())) {
+-              set_debugreg(0, 7);
++              set_debugreg(DR7_FIXED_1, 7);
+       }
+       vcpu->arch.host_debugctl = get_debugctlmsr();