From a19d31a1d00f2fadc97eb7cfe7591ab879d8495d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 24 Jul 2025 09:13:44 +0200 Subject: [PATCH] 6.12-stable patches 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 --- ...a-sleep-while-atomic-with-preempt_rt.patch | 68 ++++++++ queue-6.12/series | 2 + ...riting-its-architectural-reset-value.patch | 161 ++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 queue-6.12/input-gpio-keys-fix-a-sleep-while-atomic-with-preempt_rt.patch create mode 100644 queue-6.12/series create mode 100644 queue-6.12/x86-traps-initialize-dr7-by-writing-its-architectural-reset-value.patch 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 index 0000000000..f6765029b5 --- /dev/null +++ b/queue-6.12/input-gpio-keys-fix-a-sleep-while-atomic-with-preempt_rt.patch @@ -0,0 +1,68 @@ +From f4a8f561d08e39f7833d4a278ebfb12a41eef15f Mon Sep 17 00:00:00 2001 +From: Fabrice Gasnier +Date: Fri, 30 May 2025 15:36:43 -0700 +Subject: Input: gpio-keys - fix a sleep while atomic with PREEMPT_RT + +From: Fabrice Gasnier + +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 +Signed-off-by: Fabrice Gasnier +Signed-off-by: Gatien Chevallier +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 +[ adjusted context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..98349dff6d --- /dev/null +++ b/queue-6.12/series @@ -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 index 0000000000..7174a41915 --- /dev/null +++ b/queue-6.12/x86-traps-initialize-dr7-by-writing-its-architectural-reset-value.patch @@ -0,0 +1,161 @@ +From fa7d0f83c5c4223a01598876352473cb3d3bd4d7 Mon Sep 17 00:00:00 2001 +From: "Xin Li (Intel)" +Date: Fri, 20 Jun 2025 16:15:04 -0700 +Subject: x86/traps: Initialize DR7 by writing its architectural reset value + +From: Xin Li (Intel) + +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) +Signed-off-by: Dave Hansen +Reviewed-by: H. Peter Anvin (Intel) +Reviewed-by: Sohil Mehta +Acked-by: Peter Zijlstra (Intel) +Acked-by: Sean Christopherson +Tested-by: Sohil Mehta +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + ++/* ++ * 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 + #include ++#include + #include + #include + #include +@@ -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(); -- 2.47.2