From nobody Fri Sep 25 21:41:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3D8BC3B8D7E for ; Thu, 24 Sep 2026 14:27:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260035; cv=none; b=tnmwjLmKyaSFoLGkKwDMZrUlx+X1qhy87H8UskJ4HrVIXOSFUUJvCCnPrf3SLfh8TuE8XGA/OClKg5RVtugXyHHsVNKltdCfxwWQznDTiHrPrFvhY331G0rGZTFqkcbjDks5YDOqY5dgTLILI7i3zbTMH3N6PWSUG+DifsvT9bo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260035; c=relaxed/simple; bh=i+XbG0C3Y1Z14Pm7tlM7Ix5h4dqleLfbW9K5xjNIP+E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Lg/4iTwVVu+Ba7sbQsbIlV7KTANarJu/tXhIUXR6fQber/BHO23g0xjcH/u5PABIixaVHWTYpNGK4EPeBC/pZmhqBgAZzs80iqanCtkSlGjN9z4EVFkpTjW8oMzoey1IzZD621mVZM9Lm25Eg+JJrY3PER3/hVquMnXdq90L4HY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [123.138.236.242]) by gateway (Coremail) with SMTP id _____8CxPNI_M7Vq3XAPAA--.45375S3; Thu, 24 Sep 2026 22:27:11 +0800 (CST) Received: from linux.localdomain (unknown [123.138.236.242]) by front1 (Coremail) with SMTP id qMiowJDxBc09M7Vqha8kAA--.50018S3; Thu, 24 Sep 2026 22:27:11 +0800 (CST) From: Tiezhu Yang To: Huacai Chen Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 1/6] LoongArch: Fix bitmask corruption in update_bp_registers() Date: Thu, 24 Sep 2026 22:27:03 +0800 Message-ID: <20260924142708.2459-2-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260924142708.2459-1-yangtiezhu@loongson.cn> References: <20260924142708.2459-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxBc09M7Vqha8kAA--.50018S3 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoW7tFWfKw15JF1fKF1ruF4ftFc_yoW8Zw15pr 17uF4kGF4UWa13Xasrtr1kCr43Gw4Duw47Z3WfK34rtwn8CrnYvwnYgF9xXayUGw4fJ3WI vF1Fgr90vanrAwcCm3ZEXasCq-sJn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUkFb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Jr0_JF4l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Jr0_Gr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv 67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1Y6r17MIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6x kF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x07j83kZUUUUU= Content-Type: text/plain; charset="utf-8" In update_bp_registers(), when disabling a LOAD or STORE watchpoint, the code attempts to clear the bit of LoadEn or StoreEn by using the standard bit-clearing pattern. However, due to the omission of parentheses, the bitwise NOT operator '~' takes higher precedence than the left shift operator '<<'. Then: (1) ~0x1 << MWPnCFG3_LoadEn evaluates to "(~0x1) << 8 =3D 0xFFFFFE00", (2) ~0x1 << MWPnCFG3_StoreEn evaluates to "(~0x1) << 9 =3D 0xFFFFFC00", that incorrectly clears all configuration fields in the lower 8 bits. These fields in the lower 8 bits contain critical configurations such as DSOnly (bit 0), PLV0-PLV3 privilege levels (bits 1-4), and LCL (bit 7). Writing back these corrupted values severely breaks configuration isolation and ruins the hardware watchpoint states. Add parentheses to ensure the correct evaluation order, so that only the targeted LoadEn/StoreEn bit is cleared while preserving the other crucial configuration bits in the lower 8 bits. Fixes: edffa33c7bb5 ("LoongArch: Add hardware breakpoints/watchpoints suppo= rt") Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang --- arch/loongarch/kernel/hw_breakpoint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/= hw_breakpoint.c index c35f9bf38033..6ba7315852f3 100644 --- a/arch/loongarch/kernel/hw_breakpoint.c +++ b/arch/loongarch/kernel/hw_breakpoint.c @@ -469,9 +469,9 @@ static void update_bp_registers(struct pt_regs *regs, i= nt enable, int type) } else { ctrl =3D read_wb_reg(CSR_CFG_CTRL, i, 1); if (info->ctrl.type =3D=3D LOONGARCH_BREAKPOINT_LOAD) - ctrl &=3D ~0x1 << MWPnCFG3_LoadEn; + ctrl &=3D ~(0x1 << MWPnCFG3_LoadEn); if (info->ctrl.type =3D=3D LOONGARCH_BREAKPOINT_STORE) - ctrl &=3D ~0x1 << MWPnCFG3_StoreEn; + ctrl &=3D ~(0x1 << MWPnCFG3_StoreEn); write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl); } regs->csr_prmd &=3D ~CSR_PRMD_PWE; --=20 2.42.0 From nobody Fri Sep 25 21:41:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3D4213B8D5C for ; Thu, 24 Sep 2026 14:27:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260036; cv=none; b=YbvRDli391H9VdlgKZ6MDR2tmOsaxMsiuukyo4MpBkmitJJ7Fa4TGaG1v+fU+ZjhweIxWB+mbiEkzejnggc3S2zkXZGGvE3qaxV4Z5FazkpeDGLR7m2fZKpOU0kBHxcorZ4YiudNoGTFFUHn3a8QIwqVudEruLK5zu7CirwZtOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260036; c=relaxed/simple; bh=LoTeSF2Sp5RJBvRuP5z73LifGbx6GY6oYSFnURWYf3s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CkwaheIMjTyRo9GpRo+XBtEM82PixgrqmsWRrWKFgkeIIiUXcwiKgYzERTv8qk4sOK4VVeHpEPLeGn++qaN9STjCKUT4zOhUfKawEzmrj1seq6LWFuZbcO3NUoaC7pe+Kq5pS0fFL2Q4tBQKJf5V5W3mZ1kPSrySJIN8E/0u74A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [123.138.236.242]) by gateway (Coremail) with SMTP id _____8Bxn9E_M7Vq4HAPAA--.44772S3; Thu, 24 Sep 2026 22:27:11 +0800 (CST) Received: from linux.localdomain (unknown [123.138.236.242]) by front1 (Coremail) with SMTP id qMiowJDxBc09M7Vqha8kAA--.50018S4; Thu, 24 Sep 2026 22:27:11 +0800 (CST) From: Tiezhu Yang To: Huacai Chen Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 2/6] LoongArch: Remove redundant call in update_bp_registers() Date: Thu, 24 Sep 2026 22:27:04 +0800 Message-ID: <20260924142708.2459-3-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260924142708.2459-1-yangtiezhu@loongson.cn> References: <20260924142708.2459-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxBc09M7Vqha8kAA--.50018S4 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoW7Kw4xKw1DKw1UXFWxAw4UWrX_yoW8JFWxpr yY9FZ5Kr4DGF4kC3ZrKF93ZryUGF9ru392vw4Fkay3twnxWr1rJ34UW3s3XFWYvw4fK34I grW5CFyYq3WUAacCm3ZEXasCq-sJn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUk2b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Jr0_Gr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv 67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1Y6r17MIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_JFI_Gr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6x kF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUcDDGUUUUU Content-Type: text/plain; charset="utf-8" In update_bp_registers(), there is a duplicate call to write_wb_reg() when enabling an execute breakpoint: write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE); write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE); The two lines are completely identical. Remove the redundant call to clean up the code and eliminate unnecessary register writes. Fixes: edffa33c7bb5 ("LoongArch: Add hardware breakpoints/watchpoints suppo= rt") Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang --- arch/loongarch/kernel/hw_breakpoint.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/= hw_breakpoint.c index 6ba7315852f3..bd891b3808a6 100644 --- a/arch/loongarch/kernel/hw_breakpoint.c +++ b/arch/loongarch/kernel/hw_breakpoint.c @@ -453,7 +453,6 @@ static void update_bp_registers(struct pt_regs *regs, i= nt enable, int type) if (enable) { if ((info->ctrl.type =3D=3D LOONGARCH_BREAKPOINT_EXECUTE) && (type =3D= =3D 0)) { write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE); - write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE); } else { ctrl =3D read_wb_reg(CSR_CFG_CTRL, i, 1); if (info->ctrl.type =3D=3D LOONGARCH_BREAKPOINT_LOAD) --=20 2.42.0 From nobody Fri Sep 25 21:41:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CC8073B14D7 for ; Thu, 24 Sep 2026 14:27:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260036; cv=none; b=rqwXfscvLmVHOmw1YjawGK2npjN3W+JBja3ByWnLd0QxBoaKtit/FvbFZE/a605Vof+0tv0/zRoKwmBXGvfYhdkvkXBt4u6p2mAqdsMhA4c6/DRkXM+yhEmYaWeVemO54ZBGPUl90cWcKSTgby+yWwl8DMpC9T3GHa74Lf8Aj5s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260036; c=relaxed/simple; bh=7udMkiSJsNGfAumk7yLV2lOLODDFfYghRIte5/70ZI4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n0S3iWk1FnNR8XBBSv5LUbI/LEWnOBbyhTH5AigWAl82paki7BTFk9y1vQI1adRCzVOQqYg70CdAGGLEffNxhWSFshzNoRV7K1TRu8WQbbgCG++16WyAAxNooe2uPTpppy2Lcyrm5AX6tkCS1RcgGXNrvk7kMosgwngrwud4mdo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [123.138.236.242]) by gateway (Coremail) with SMTP id _____8DxOvBAM7Vq43APAA--.45371S3; Thu, 24 Sep 2026 22:27:12 +0800 (CST) Received: from linux.localdomain (unknown [123.138.236.242]) by front1 (Coremail) with SMTP id qMiowJDxBc09M7Vqha8kAA--.50018S5; Thu, 24 Sep 2026 22:27:12 +0800 (CST) From: Tiezhu Yang To: Huacai Chen Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 3/6] LoongArch: Fix architectural naming typo for CSR_FWPS_SKIP Date: Thu, 24 Sep 2026 22:27:05 +0800 Message-ID: <20260924142708.2459-4-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260924142708.2459-1-yangtiezhu@loongson.cn> References: <20260924142708.2459-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxBc09M7Vqha8kAA--.50018S5 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoWxArWxJry5KF15AryxKw1fZrc_yoW5Zryrpr nrZF95GrW8WFs7Gan8ta1rur47tFZ7Gw429anYk3yS9F47X34rJF109rnrXF15Xw4rX34F qFnYkw1jgFyUA3XCm3ZEXasCq-sJn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUk2b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Jr0_Gr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E87Iv 67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1Y6r17MIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_JFI_Gr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6x kF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxU2F4iUUUUU Content-Type: text/plain; charset="utf-8" According to the LoongArch Reference Manual, the single-step 'Skip' bit resides in the instruction breakpoint status register CSR.FWPS, rather than the configuration register CSR.FWPC. Furthermore, the kernel code comments also explicitly document it as "CSR.FWPS.Skip", yet the actual macro was erroneously defined as CSR_FWPC_SKIP and used as such in traps.c and hw_breakpoint.c. This mismatch creates architectural naming confusion. Fix this by renaming the macro from CSR_FWPC_SKIP to CSR_FWPS_SKIP to precisely match the manual and comments. Also, update all call sites to align with the rectified definition. Fixes: 424421a7f34c ("LoongArch: ptrace: Add hardware single step support") Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang --- arch/loongarch/include/asm/loongarch.h | 4 ++-- arch/loongarch/kernel/hw_breakpoint.c | 2 +- arch/loongarch/kernel/traps.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/includ= e/asm/loongarch.h index 2a6bc99177d8..32bbff337c5c 100644 --- a/arch/loongarch/include/asm/loongarch.h +++ b/arch/loongarch/include/asm/loongarch.h @@ -1130,8 +1130,8 @@ #define LOONGARCH_CSR_DERA 0x501 /* debug era */ #define LOONGARCH_CSR_DESAVE 0x502 /* debug save */ =20 -#define CSR_FWPC_SKIP_SHIFT 16 -#define CSR_FWPC_SKIP (_ULCAST_(1) << CSR_FWPC_SKIP_SHIFT) +#define CSR_FWPS_SKIP_SHIFT 16 +#define CSR_FWPS_SKIP (_ULCAST_(1) << CSR_FWPS_SKIP_SHIFT) =20 /* * CSR_ECFG IM diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/= hw_breakpoint.c index bd891b3808a6..7f69cf361a5e 100644 --- a/arch/loongarch/kernel/hw_breakpoint.c +++ b/arch/loongarch/kernel/hw_breakpoint.c @@ -550,7 +550,7 @@ void hw_breakpoint_thread_switch(struct task_struct *ne= xt) addr =3D read_wb_reg(CSR_CFG_ADDR, 0, 0); mask =3D read_wb_reg(CSR_CFG_MASK, 0, 0); if (!((regs->csr_era ^ addr) & ~mask)) - csr_write32(CSR_FWPC_SKIP, LOONGARCH_CSR_FWPS); + csr_write32(CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS); regs->csr_prmd |=3D CSR_PRMD_PWE; } else { /* Update breakpoints */ diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index 776523747ea3..c4d7e55fb3ea 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -829,7 +829,7 @@ asmlinkage void noinstr do_watch(struct pt_regs *regs) * instruction. So don't clear llbit and reset CSR.FWPS.Skip until * the llsc execution is completed. */ - csr_write32(CSR_FWPC_SKIP, LOONGARCH_CSR_FWPS); + csr_write32(CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS); csr_write32(CSR_LLBCTL_KLO, LOONGARCH_CSR_LLBCTL); goto out; } @@ -846,7 +846,7 @@ asmlinkage void noinstr do_watch(struct pt_regs *regs) * current pc, If yes, then we should not set the CSR.FWPS.SKIP * bit to break the original instruction stream. */ - csr_write32(CSR_FWPC_SKIP, LOONGARCH_CSR_FWPS); + csr_write32(CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS); goto out; } } --=20 2.42.0 From nobody Fri Sep 25 21:41:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CEDAD3B5820 for ; Thu, 24 Sep 2026 14:28:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260132; cv=none; b=F9Aoyf8fG673j0A23AQSraubtB8yC2tZsphDX3SLTUDjPqhPHtBdP1HK3t6pWdY94z5Wcqil9IneeElkKrvDeli/OSintnnKquKCU0GCcgHmasLQS00/PR92m2xRSdWPESq6M9bIvAXMk3CoDtJODFLL0cGKtEjdeBPlBLc3uiA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260132; c=relaxed/simple; bh=gP1hbo0fXBOIR/xuHFNmPZCAZbNpdADMI1YaB4qZt5I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KOe1E/VYA52WyMqcziwP5DKxV19E5kH/EDccqGyGHDoxay2RabmZ+guTiZoaKDtJuNzCMH/u5ejd+M/DZpSrsPPid5sewJfJS1u7wUBiny2anAMh9w51V0SlewxtIIoNLPtupZevtNuhmuHtbu7kDnEcb7XyV52NlaHYtkO6NBQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [123.138.236.242]) by gateway (Coremail) with SMTP id _____8AxYdFAM7Vq5nAPAA--.45641S3; Thu, 24 Sep 2026 22:27:12 +0800 (CST) Received: from linux.localdomain (unknown [123.138.236.242]) by front1 (Coremail) with SMTP id qMiowJDxBc09M7Vqha8kAA--.50018S6; Thu, 24 Sep 2026 22:27:12 +0800 (CST) From: Tiezhu Yang To: Huacai Chen Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 4/6] LoongArch: Only send SIGTRAP signal if necessary in do_watch() Date: Thu, 24 Sep 2026 22:27:06 +0800 Message-ID: <20260924142708.2459-5-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260924142708.2459-1-yangtiezhu@loongson.cn> References: <20260924142708.2459-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxBc09M7Vqha8kAA--.50018S6 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoWxXw45AF4xKry3uFyfJr4DJrc_yoWrtw48pF ZruFn3KrWDGr1ku3W3Gw4Dur43Grs5uw47u34Sy34F9rs0grWrJrn2yFnFqFW5W3s8Xa40 qF1Yq3WS9a1UXwbCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUk2b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r106r15M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E87Iv 67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1Y6r17MIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6x kF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUcHUqUUUUU Content-Type: text/plain; charset="utf-8" In do_watch(), the kernel unconditionally forces a SIGTRAP signal at the end of the handler via force_sig(SIGTRAP). This is essential for ptrace operations, but it severely disrupts standard perf_event usage. Under normal perf usage, it is not necessary to force a SIGTRAP signal on every hit. Forcing it unnecessarily aborts the target process if no user-space signal handler is registered, which violates performance monitoring behaviors and injects context switch overheads. However, a conditional check using only 'current->ptrace' would block legitimate user-requested signals when a perf_event is configured with 'attr.sigtrap =3D 1' for asynchronous user-space tracking. Fix this by refactoring breakpoint_handler() and watchpoint_handler() to return a boolean status indicating whether any triggered breakpoint explicitly requires a signal notification. Update do_watch() to enforce the SIGTRAP signal only when the process is actively being debugged via ptrace, or when the underlying perf_event infrastructure specifically demands it via 'attr.sigtrap'. Fixes: 424421a7f34c ("LoongArch: ptrace: Add hardware single step support") Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang --- arch/loongarch/include/asm/hw_breakpoint.h | 4 ++-- arch/loongarch/kernel/hw_breakpoint.c | 18 ++++++++++++++++-- arch/loongarch/kernel/traps.c | 8 +++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/loongarch/include/asm/hw_breakpoint.h b/arch/loongarch/in= clude/asm/hw_breakpoint.h index 5faa97a87a9e..d202052df8a1 100644 --- a/arch/loongarch/include/asm/hw_breakpoint.h +++ b/arch/loongarch/include/asm/hw_breakpoint.h @@ -116,8 +116,8 @@ extern void arch_uninstall_hw_breakpoint(struct perf_ev= ent *bp); extern int hw_breakpoint_slots(int type); extern void hw_breakpoint_pmu_read(struct perf_event *bp); =20 -void breakpoint_handler(struct pt_regs *regs); -void watchpoint_handler(struct pt_regs *regs); +bool breakpoint_handler(struct pt_regs *regs); +bool watchpoint_handler(struct pt_regs *regs); =20 #ifdef CONFIG_HAVE_HW_BREAKPOINT extern void ptrace_hw_copy_thread(struct task_struct *task); diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/= hw_breakpoint.c index 7f69cf361a5e..3683a52b2368 100644 --- a/arch/loongarch/kernel/hw_breakpoint.c +++ b/arch/loongarch/kernel/hw_breakpoint.c @@ -482,10 +482,11 @@ NOKPROBE_SYMBOL(update_bp_registers); /* * Debug exception handlers. */ -void breakpoint_handler(struct pt_regs *regs) +bool breakpoint_handler(struct pt_regs *regs) { int i; struct perf_event *bp, **slots; + bool need_sigtrap =3D false; =20 slots =3D this_cpu_ptr(bp_on_reg); =20 @@ -494,18 +495,25 @@ void breakpoint_handler(struct pt_regs *regs) bp =3D slots[i]; if (bp =3D=3D NULL) continue; + perf_bp_event(bp, regs); + if (bp->attr.sigtrap) + need_sigtrap =3D true; + csr_write32(0x1 << i, LOONGARCH_CSR_FWPS); update_bp_registers(regs, 0, 0); } } + + return need_sigtrap; } NOKPROBE_SYMBOL(breakpoint_handler); =20 -void watchpoint_handler(struct pt_regs *regs) +bool watchpoint_handler(struct pt_regs *regs) { int i; struct perf_event *wp, **slots; + bool need_sigtrap =3D false; =20 slots =3D this_cpu_ptr(wp_on_reg); =20 @@ -514,11 +522,17 @@ void watchpoint_handler(struct pt_regs *regs) wp =3D slots[i]; if (wp =3D=3D NULL) continue; + perf_bp_event(wp, regs); + if (wp->attr.sigtrap) + need_sigtrap =3D true; + csr_write32(0x1 << i, LOONGARCH_CSR_MWPS); update_bp_registers(regs, 0, 1); } } + + return need_sigtrap; } NOKPROBE_SYMBOL(watchpoint_handler); =20 diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index c4d7e55fb3ea..4cbf84b148cd 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -811,6 +811,7 @@ asmlinkage void noinstr do_bp(struct pt_regs *regs) asmlinkage void noinstr do_watch(struct pt_regs *regs) { irqentry_state_t state =3D irqentry_enter(regs); + bool need_sigtrap =3D !!current->ptrace; =20 #ifndef CONFIG_HAVE_HW_BREAKPOINT pr_warn("Hardware watch point handler not implemented!\n"); @@ -851,11 +852,12 @@ asmlinkage void noinstr do_watch(struct pt_regs *regs) } } } else { - breakpoint_handler(regs); - watchpoint_handler(regs); + need_sigtrap |=3D breakpoint_handler(regs); + need_sigtrap |=3D watchpoint_handler(regs); } =20 - force_sig(SIGTRAP); + if (need_sigtrap) + force_sig(SIGTRAP); out: #endif irqentry_exit(regs, state); --=20 2.42.0 From nobody Fri Sep 25 21:41:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 491463BB684 for ; Thu, 24 Sep 2026 14:27:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260037; cv=none; b=pbdGCtGMEaP+1NLCZ68x3QLIQ5aYB4Xm05r/rLjR15UQQSQeeQLeeWlXlfLNlFkfwOJzRf+9Ib8rUfVGy0tKJaZ0Qv94/J6Hz+Kgt304nJAFqSH2sV4cm4m7qqouAU9kgT2EPPttXxE9eA/Rwss5QIPBVHdKc0x4mrb+9i7YeFY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260037; c=relaxed/simple; bh=H+qJAKye2VwOk6NjMOsoAlqoEDHxgsJEC/6qIC9WV5M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=a/Ql4FyqZ1cW978YBGkSNosbnoAjnlrW5Skt6xj8mCNRv6V6bi483VOmrmPQPrElxcFAmxRSkMtLDXDi0hMTSfhzxNOGIwE5iLf66/WOsIfninFmYlVTH87gWolIBE20l5Lp6cvgiTH5zULC1Iww7W2DxNnkw63p5X5b6M3D5TE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [123.138.236.242]) by gateway (Coremail) with SMTP id _____8Bx79JBM7Vq6XAPAA--.45598S3; Thu, 24 Sep 2026 22:27:13 +0800 (CST) Received: from linux.localdomain (unknown [123.138.236.242]) by front1 (Coremail) with SMTP id qMiowJDxBc09M7Vqha8kAA--.50018S7; Thu, 24 Sep 2026 22:27:13 +0800 (CST) From: Tiezhu Yang To: Huacai Chen Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 5/6] LoongArch: Fix perf hardware breakpoint failure via installation Date: Thu, 24 Sep 2026 22:27:07 +0800 Message-ID: <20260924142708.2459-6-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260924142708.2459-1-yangtiezhu@loongson.cn> References: <20260924142708.2459-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxBc09M7Vqha8kAA--.50018S7 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoWxJw1xGw13ZF13Ar4UKrWfWFX_yoW5Gw1Upr ZrAF1vqrW5J3y7G3Zrtan8Aw15JrZru3y7W34akrWYy3ZFvr13tFs29FnrXF18A39Yqa40 gr1kWr1SvF4UXabCm3ZEXasCq-sJn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUk2b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E87Iv 67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1Y6r17MIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6x kF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUcCD7UUUUU Content-Type: text/plain; charset="utf-8" In hw_breakpoint_control(), the logic to enable CSR_PRMD_PWE (global watchpoint enable) incorrectly relies on TIF_LOAD_WATCH. This thread flag is only set during ptrace operations, meaning that the standard hardware breakpoints created via perf_event_open() will never have this flag set. As a result, the CSR_PRMD_PWE switch is skipped, leaving the hardware breakpoint completely inactive in perf usage. Fix this by decoupling the CSR_PRMD_PWE from the ptrace specific flag TIF_LOAD_WATCH, which ensures that CSR_PRMD_PWE is enabled whenever a hardware breakpoint is installed. Here is a user-space reproducer to demonstrate the issue: (1) Test program (test_perf_install.c): #include #include #include #include #include #include static int var =3D 0; int main(void) { size_t count =3D 0; struct perf_event_attr attr =3D { .type =3D PERF_TYPE_BREAKPOINT, .size =3D sizeof(attr), .bp_type =3D HW_BREAKPOINT_W, .bp_addr =3D (unsigned long)&var, .bp_len =3D HW_BREAKPOINT_LEN_1, .exclude_kernel =3D 1, }; int fd =3D syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); asm volatile("st.b %1, %0" : "=3Dm"(var) : "r"(11) : "memory"); ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); read(fd, &count, sizeof(size_t)); printf("Watchpoint counts: expected =3D 1, actual =3D %zu\n", count); close(fd); return 0; } (2) Test steps: $ gcc test_perf_install.c -o test_perf_install $ ./test_perf_install (3) Test results: Without this patch: Watchpoint counts: expected =3D 1, actual =3D 0 With this patch: Watchpoint counts: expected =3D 1, actual =3D 1 Fixes: 3892b11eac5a ("LoongArch: Check TIF_LOAD_WATCH to enable user space = watchpoint") Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang --- arch/loongarch/kernel/hw_breakpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/= hw_breakpoint.c index 3683a52b2368..9dcb122218c2 100644 --- a/arch/loongarch/kernel/hw_breakpoint.c +++ b/arch/loongarch/kernel/hw_breakpoint.c @@ -233,7 +233,7 @@ static int hw_breakpoint_control(struct perf_event *bp, } enable =3D csr_read64(LOONGARCH_CSR_CRMD); csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD); - if (bp->hw.target && test_tsk_thread_flag(bp->hw.target, TIF_LOAD_WATCH)) + if (bp->hw.target) regs->csr_prmd |=3D CSR_PRMD_PWE; break; case HW_BREAKPOINT_UNINSTALL: --=20 2.42.0 From nobody Fri Sep 25 21:41:37 2026 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8E8692D876B for ; Thu, 24 Sep 2026 14:27:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260038; cv=none; b=NfXzAsjAlkV9LWTEGGe1nTyVKiGrC3awcbwbh8RLELo9XefcNhPUMBxTF6gSpOdvp5ViNgFng1bz5yC73EtupVdOWibFWlvfwIGILldxch+SosCoORWiOGYJiux7bIt/Pv3lqVzWqgNXgNQo6tONtJoNBg0W5KNjyVuhXD/xrQE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790260038; c=relaxed/simple; bh=AVL22QDu4RGh1giNy8uCmgnKr+QKxu1r8+OLAMZ0quk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BA7pJ5SiPCJZU1lbzMx2R9iwBXOEUf7Is4ZtLrmCoz/sebk2/b7DcsyfZ06KwV/t48+w6yPvGRt6Fw5JrJJpBzII+76A3NKjjRmUneKSGDc/DfIZGN6ssLQt8Z5tBwzt6inwf1mKZ1JL09Yb8s3DoGj1qHMBVYjuZcb0emXE1gc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [123.138.236.242]) by gateway (Coremail) with SMTP id _____8BxrtJCM7Vq7HAPAA--.45300S3; Thu, 24 Sep 2026 22:27:14 +0800 (CST) Received: from linux.localdomain (unknown [123.138.236.242]) by front1 (Coremail) with SMTP id qMiowJDxBc09M7Vqha8kAA--.50018S8; Thu, 24 Sep 2026 22:27:13 +0800 (CST) From: Tiezhu Yang To: Huacai Chen Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 6/6] LoongArch: Fix one-shot limitation for perf hardware breakpoints Date: Thu, 24 Sep 2026 22:27:08 +0800 Message-ID: <20260924142708.2459-7-yangtiezhu@loongson.cn> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260924142708.2459-1-yangtiezhu@loongson.cn> References: <20260924142708.2459-1-yangtiezhu@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDxBc09M7Vqha8kAA--.50018S8 X-CM-SenderInfo: p1dqw3xlh2x3gn0dqz5rrqw2lrqou0/ X-Coremail-Antispam: 1Uk129KBj93XoW3AF4fGr47Wr1xZF4DXw1kZwc_yoWfZr1rpF 9rAr1kKr40kr1xu3W3Jw4Uur43trs7ua12qryfKa4SyrnFgrWrJFn2kF9rXFy5X3Z5Wa4S qw1a9wsaga1DXabCm3ZEXasCq-sJn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUk2b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r106r15M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E87Iv 67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1Y6r17MIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6x kF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxUcHUqUUUUU Content-Type: text/plain; charset="utf-8" In breakpoint_handler() and watchpoint_handler(), the code disables the hardware slot by executing update_bp_registers(regs, 0, ...). This design forces the active hardware breakpoint configuration to be wiped out upon its first hit, turning standard perf hardware breakpoints into "one-shot" events. Furthermore, while the ptrace single-step path in do_watch() executes a hardware single-step skip mechanism to advance the PC, the standard perf path lacks any mechanism to bypass the original triggering instruction. To maintain the long-term persistence of hardware breakpoints for perf usage, eliminate the disruptive calls to update_bp_registers() within the handler loops to keep the breakpoint configuration enabled. Concurrently, execute a single, unified register write outside the loop to atomize the state transition and explicitly enforce the hardware skip mechanism once per exception return, ensuring the processor safely steps forward without lockups. Meanwhile, in order to prevent status contamination during single-core context switches or cross-core thread migrations, the hardware register skip state of the previous thread is saved first. Then, the skip state is restored and its software skip flag is also cleared only if the next thread has the skip flag; otherwise, 0 is written to clear the FWPS and MWPS registers, which explicitly clears the skip bit according to the architectural specification. Additionally, explicitly clear hbp_break_skip and hbp_watch_skip inside ptrace_hw_copy_thread() which is called by copy_thread() during task creation. This guarantees that a newly cloned child task starts with a clean slate. Here is a user-space reproducer to demonstrate the issue. (1) Test program (test_perf_continuous.c): #include #include #include #include #include #include static int var =3D 0; int main(void) { size_t count =3D 0; struct perf_event_attr attr =3D { .type =3D PERF_TYPE_BREAKPOINT, .size =3D sizeof(attr), .bp_type =3D HW_BREAKPOINT_W, .bp_addr =3D (unsigned long)&var, .bp_len =3D HW_BREAKPOINT_LEN_1, .exclude_kernel =3D 1, }; int fd =3D syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); asm volatile("st.b %1, %0" : "=3Dm"(var) : "r"(11) : "memory"); asm volatile("st.b %1, %0" : "=3Dm"(var) : "r"(22) : "memory"); asm volatile("st.b %1, %0" : "=3Dm"(var) : "r"(33) : "memory"); ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); read(fd, &count, sizeof(size_t)); printf("Watchpoint counts: expected =3D 3, actual =3D %zu\n", count); close(fd); return 0; } (2) Test steps: $ gcc test_perf_continuous.c -o test_perf_continuous $ ./test_perf_continuous (3) Test results: Without this patch: Watchpoint counts: expected =3D 3, actual =3D 1 With this patch: Watchpoint counts: expected =3D 3, actual =3D 3 Fixes: 3eb2a8b23598 ("LoongArch: Fix multiple hardware watchpoint issues") Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang --- arch/loongarch/include/asm/hw_breakpoint.h | 4 +-- arch/loongarch/include/asm/loongarch.h | 3 ++ arch/loongarch/include/asm/processor.h | 3 ++ arch/loongarch/include/asm/switch_to.h | 2 +- arch/loongarch/kernel/hw_breakpoint.c | 39 +++++++++++++++++++--- 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/arch/loongarch/include/asm/hw_breakpoint.h b/arch/loongarch/in= clude/asm/hw_breakpoint.h index d202052df8a1..f4478936787d 100644 --- a/arch/loongarch/include/asm/hw_breakpoint.h +++ b/arch/loongarch/include/asm/hw_breakpoint.h @@ -121,12 +121,12 @@ bool watchpoint_handler(struct pt_regs *regs); =20 #ifdef CONFIG_HAVE_HW_BREAKPOINT extern void ptrace_hw_copy_thread(struct task_struct *task); -extern void hw_breakpoint_thread_switch(struct task_struct *next); +extern void hw_breakpoint_thread_switch(struct task_struct *prev, struct t= ask_struct *next); #else static inline void ptrace_hw_copy_thread(struct task_struct *task) { } -static inline void hw_breakpoint_thread_switch(struct task_struct *next) +static inline void hw_breakpoint_thread_switch(struct task_struct *prev, s= truct task_struct *next) { } #endif diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/includ= e/asm/loongarch.h index 32bbff337c5c..28eff8b49d1b 100644 --- a/arch/loongarch/include/asm/loongarch.h +++ b/arch/loongarch/include/asm/loongarch.h @@ -1133,6 +1133,9 @@ #define CSR_FWPS_SKIP_SHIFT 16 #define CSR_FWPS_SKIP (_ULCAST_(1) << CSR_FWPS_SKIP_SHIFT) =20 +#define CSR_MWPS_SKIP_SHIFT 16 +#define CSR_MWPS_SKIP (_ULCAST_(1) << CSR_MWPS_SKIP_SHIFT) + /* * CSR_ECFG IM */ diff --git a/arch/loongarch/include/asm/processor.h b/arch/loongarch/includ= e/asm/processor.h index ce8b953f8c79..d70d77b25872 100644 --- a/arch/loongarch/include/asm/processor.h +++ b/arch/loongarch/include/asm/processor.h @@ -140,6 +140,9 @@ struct thread_struct { /* Hardware breakpoints pinned to this task. */ struct perf_event *hbp_break[LOONGARCH_MAX_BRP]; struct perf_event *hbp_watch[LOONGARCH_MAX_WRP]; + + bool hbp_break_skip; + bool hbp_watch_skip; }; =20 #define thread_saved_ra(tsk) (tsk->thread.sched_ra) diff --git a/arch/loongarch/include/asm/switch_to.h b/arch/loongarch/includ= e/asm/switch_to.h index 27acbf913774..ab9e0292c7f3 100644 --- a/arch/loongarch/include/asm/switch_to.h +++ b/arch/loongarch/include/asm/switch_to.h @@ -34,7 +34,7 @@ extern asmlinkage struct task_struct *__switch_to(struct = task_struct *prev, do { \ lose_fpu_inatomic(1, prev); \ lose_lbt_inatomic(1, prev); \ - hw_breakpoint_thread_switch(next); \ + hw_breakpoint_thread_switch(prev, next); \ set_current(next); \ (last) =3D __switch_to(prev, next, \ __builtin_return_address(0), __builtin_frame_address(0)); \ diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/= hw_breakpoint.c index 9dcb122218c2..fc0bf9f402bc 100644 --- a/arch/loongarch/kernel/hw_breakpoint.c +++ b/arch/loongarch/kernel/hw_breakpoint.c @@ -156,6 +156,9 @@ static int hw_breakpoint_slot_setup(struct perf_event *= *slots, int max_slots, =20 void ptrace_hw_copy_thread(struct task_struct *tsk) { + tsk->thread.hbp_break_skip =3D 0; + tsk->thread.hbp_watch_skip =3D 0; + memset(tsk->thread.hbp_break, 0, sizeof(tsk->thread.hbp_break)); memset(tsk->thread.hbp_watch, 0, sizeof(tsk->thread.hbp_watch)); } @@ -487,6 +490,7 @@ bool breakpoint_handler(struct pt_regs *regs) int i; struct perf_event *bp, **slots; bool need_sigtrap =3D false; + unsigned int clear_mask =3D 0; =20 slots =3D this_cpu_ptr(bp_on_reg); =20 @@ -500,11 +504,13 @@ bool breakpoint_handler(struct pt_regs *regs) if (bp->attr.sigtrap) need_sigtrap =3D true; =20 - csr_write32(0x1 << i, LOONGARCH_CSR_FWPS); - update_bp_registers(regs, 0, 0); + clear_mask |=3D (0x1 << i); } } =20 + if (clear_mask) + csr_write32(clear_mask | CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS); + return need_sigtrap; } NOKPROBE_SYMBOL(breakpoint_handler); @@ -514,6 +520,7 @@ bool watchpoint_handler(struct pt_regs *regs) int i; struct perf_event *wp, **slots; bool need_sigtrap =3D false; + unsigned int clear_mask =3D 0; =20 slots =3D this_cpu_ptr(wp_on_reg); =20 @@ -527,11 +534,13 @@ bool watchpoint_handler(struct pt_regs *regs) if (wp->attr.sigtrap) need_sigtrap =3D true; =20 - csr_write32(0x1 << i, LOONGARCH_CSR_MWPS); - update_bp_registers(regs, 0, 1); + clear_mask |=3D (0x1 << i); } } =20 + if (clear_mask) + csr_write32(clear_mask | CSR_MWPS_SKIP, LOONGARCH_CSR_MWPS); + return need_sigtrap; } NOKPROBE_SYMBOL(watchpoint_handler); @@ -555,7 +564,7 @@ static int __init arch_hw_breakpoint_init(void) } arch_initcall(arch_hw_breakpoint_init); =20 -void hw_breakpoint_thread_switch(struct task_struct *next) +void hw_breakpoint_thread_switch(struct task_struct *prev, struct task_str= uct *next) { u64 addr, mask; struct pt_regs *regs =3D task_pt_regs(next); @@ -567,6 +576,26 @@ void hw_breakpoint_thread_switch(struct task_struct *n= ext) csr_write32(CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS); regs->csr_prmd |=3D CSR_PRMD_PWE; } else { + unsigned int fwps =3D csr_read32(LOONGARCH_CSR_FWPS); + unsigned int mwps =3D csr_read32(LOONGARCH_CSR_MWPS); + + prev->thread.hbp_break_skip =3D !!(fwps & CSR_FWPS_SKIP); + prev->thread.hbp_watch_skip =3D !!(mwps & CSR_MWPS_SKIP); + + if (next->thread.hbp_break_skip) { + csr_write32(CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS); + next->thread.hbp_break_skip =3D 0; + } else { + csr_write32(0, LOONGARCH_CSR_FWPS); + } + + if (next->thread.hbp_watch_skip) { + csr_write32(CSR_MWPS_SKIP, LOONGARCH_CSR_MWPS); + next->thread.hbp_watch_skip =3D 0; + } else { + csr_write32(0, LOONGARCH_CSR_MWPS); + } + /* Update breakpoints */ update_bp_registers(regs, 1, 0); /* Update watchpoints */ --=20 2.42.0