From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E9E013E6DEB for ; Tue, 29 Sep 2026 13:31:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790688668; cv=none; b=HaAlbTqfsZ+Cvjf8lQnBrmNjB+G/yOvTEfzz/kWamNCVmYjnX6qAQet3AbvUI4FUa15oOzigCbl0DuSNEZvwJtbqiSTzKpR+6Wn+2BZcQA6lMnaPuZng7hanr38VApTMcxWGm37hThSnwW6qc8hz8d+1JdOSNn57CfiCOAZij3Q= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790688668; c=relaxed/simple; bh=d96NjvI2ZPsA06zcrSwm4/B+5vDXouUNlIxq79y4P9E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Cpzd2SKELjst8+q3DLwCVvUt6Y5cwm6rrmP7JsmYlXK7MTwiFm9wZSZvE9uELeI/DGdsOGklSti8Lex+5VbEc2kr38SysEJi4CvM8Ct5at22NdJ8VVcIUAQeFqu1qONoM/wstH3/9S0AC+FIsRNNY+b0zU890R16j847D2Jr3Rs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Gn0YySgL; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Gn0YySgL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DA3681F000FF; Tue, 29 Sep 2026 13:31:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790688666; bh=6bIGgL5nHaZspIjRXf12A9tFZVTFi7zYn/svyhhOf78=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Gn0YySgLH0VwxLYMUV4d+37cNtSDH4hLmMjdzhyIvm8aH+VDGL/PO0uyNYyKq2N0p gYaB1r+Q5Fi+2av0jCXB7Vih7lSQxdPrrrU7TbXXFigJQqomO8MLpOmpLfq0FE9xrO 0VmgaJSb5cLw8wDE9ODbeaU3eMXQNpc8NZkNEkeyltJegKJrsHmOZQQog65aCF1I3I O0Gw9WZhU91zDBRrZVr3Gvid3mkGQph+4BUj2iyGJMj1uSAXRsTSHkzk0u8CKZFKhe I58eW0BlJuqM1/y3DEqenRYYAelhzMfaTqqp5/ZT79cRZe7eueAsOqQwEFk58Y7bkk t7SK6a8edsAWQ== From: Sasha Levin To: stable@vger.kernel.org Cc: "Masami Hiramatsu (Google)" , "Borislav Petkov (AMD)" , "Peter Zijlstra (Intel)" , stable@kernel.org, Sasha Levin Subject: [PATCH 6.6.y] x86/mce: Fix hardware debug register corruption on task migration Date: Tue, 29 Sep 2026 09:31:04 -0400 Message-ID: <20260929133104.3502672-1-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <2026092917-penpal-endearing-abca@gregkh> References: <2026092917-penpal-endearing-abca@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: "Masami Hiramatsu (Google)" [ Upstream commit b8d1d5b63a8ef532038eebd9d97d406860385668 ] In exc_machine_check_user(), local_db_save() and local_db_restore() are invoked in the outer entry stubs (DEFINE_IDTENTRY_MCE_USER, DEFINE_FREDENTRY_MCE, and DEFINE_IDTENTRY_RAW), surrounding exc_machine_check_user(). However, exc_machine_check_user() calls irqentry_exit_to_user_mode(), which handles pending thread work and may schedule() if TIF_NEED_RESCHED is set. If the task migrates to another CPU during schedule(), local_db_restore() runs on the new CPU with the dr7 state saved from the old CPU. This corrupts the new CPU's DR7 hardware debug register and leaves the old CPU's DR7 disabled. In short, local_db_save() and local_db_restore() pair must be run on the same CPU. To fix this, move local_db_save() and local_db_restore() inside exc_machine_check_user() and exc_machine_check_kernel(). In exc_machine_check_user(), DR7 is saved and restored strictly around do_machine_check() to avoid schedule() during migration. In exc_machine_check_kernel(), local_db_save() is called at the entry point to prevent early memory accesses from triggering nested #DB exceptions, and restored on all exits. Fixes: cd840e424f27 ("x86/entry, mce: Disallow #DB during #MC") Assisted-by: LLM Signed-off-by: Masami Hiramatsu (Google) Signed-off-by: Borislav Petkov (AMD) Acked-by: Peter Zijlstra (Intel) Cc: Link: https://patch.msgid.link/179005109564.388919.3937970081044095776.stgit@devnote2 [ Omitted changes to the FRED machine-check handler because it is absent in Linux 6.6. ] Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/mce/core.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 106436ec3c005..fe1bbe1973321 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -2114,6 +2114,9 @@ bool filter_mce(struct mce *m) static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) { irqentry_state_t irq_state; + unsigned long dr7; + + dr7 = local_db_save(); WARN_ON_ONCE(user_mode(regs)); @@ -2122,20 +2125,26 @@ static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) * mce_check_crashing_cpu() for details. */ if (mca_cfg.initialized && mce_check_crashing_cpu()) - return; + goto out; irq_state = irqentry_nmi_enter(regs); do_machine_check(regs); irqentry_nmi_exit(regs, irq_state); +out: + local_db_restore(dr7); } static __always_inline void exc_machine_check_user(struct pt_regs *regs) { + unsigned long dr7; + irqentry_enter_from_user_mode(regs); + dr7 = local_db_save(); do_machine_check(regs); + local_db_restore(dr7); irqentry_exit_to_user_mode(regs); } @@ -2144,34 +2153,22 @@ static __always_inline void exc_machine_check_user(struct pt_regs *regs) /* MCE hit kernel mode */ DEFINE_IDTENTRY_MCE(exc_machine_check) { - unsigned long dr7; - - dr7 = local_db_save(); exc_machine_check_kernel(regs); - local_db_restore(dr7); } /* The user mode variant. */ DEFINE_IDTENTRY_MCE_USER(exc_machine_check) { - unsigned long dr7; - - dr7 = local_db_save(); exc_machine_check_user(regs); - local_db_restore(dr7); } #else /* 32bit unified entry point */ DEFINE_IDTENTRY_RAW(exc_machine_check) { - unsigned long dr7; - - dr7 = local_db_save(); if (user_mode(regs)) exc_machine_check_user(regs); else exc_machine_check_kernel(regs); - local_db_restore(dr7); } #endif -- 2.53.0