From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from www62.your-server.de (www62.your-server.de [213.133.104.62]) (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 9E80D31D74B for ; Mon, 10 Aug 2026 13:43:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.133.104.62 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786369432; cv=none; b=gH/zu/eHOoY1AvrnWUR4CfckJ9G5y7yjstYsbrdT7/dFzCEL1PbArcpBdDGVJDPpuRdUgmOnkjC8C+xl6wXS9UgmFgjOg4Kn/PElbduQUg0rcNUtliWIO4w7wIOLonp8XsYbEfwWEPIqcZWfb1qsaUHKGEogZVCqoxS0/Fzju08= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786369432; c=relaxed/simple; bh=I3HiiSKoItN22cdvH5e098KQFoDdZVQ0dSdAbfAqcwg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Aqd700zzQm+7gVptmpE874YZAjwDsaVDcqvS04UkEUVo3DeF4TY+FvXGf1J0vx0GJCrC8N3VF/SaSAtiusTmPm6D5xo/m8zPERidq+IdvGykrZDEshuhP/eLGm8lSx3e9eokTRgNFbB2+uRUvVLaIzsm0FfXGp1cHoFqyKZS+Gc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iogearbox.net; spf=pass smtp.mailfrom=iogearbox.net; dkim=pass (2048-bit key) header.d=iogearbox.net header.i=@iogearbox.net header.b=QfQn8NRM; arc=none smtp.client-ip=213.133.104.62 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iogearbox.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iogearbox.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iogearbox.net header.i=@iogearbox.net header.b="QfQn8NRM" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=iogearbox.net; s=default2302; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=0ARfxLYfpPIfa175RYRniTWEBGGbz7wwxgJiAd1uGQc=; b=QfQn8NRMiUvk5lUu3oxKEjWoP+ HQD9Qhppng1HI8CbUlFd3r3eCKRM5fjHHFYRUc8fSgKD7BwKwlvLM8QStLtNmdKxMsW7bwa0oQN88 3IIx7zOICmFbcc/K8Co/DD/+M4ThdY6WmpAFcQKc3twZPzJQO8BgJ5iyzrGmpgGfkZWwYNoBX5yeW ffS5pGe9npMuwF/B9NStnme3/7wiXhfGDqLy7EeiAwdhtTgXpYx+KnUSwxCs3Vvh3bpTRXlp5Ije4 h1Kzt6CUGWtSCZzY/fpEiuX8o1/0oyigOLYm4FnCCA4+golK98RkzAhgqJ/ZGJ4h5jeFq9sBU0dAh zdwg+GAA==; Received: from localhost ([127.0.0.1]) by www62.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.96.2) (envelope-from ) id 1wtQI7-00050H-0t; Mon, 10 Aug 2026 15:43:47 +0200 From: Daniel Borkmann To: memxor@gmail.com Cc: eddyz87@gmail.com, puranjay@kernel.org, bpf@vger.kernel.org, Pu Lehui Subject: [PATCH bpf-next 2/6] bpf, riscv: Clear fetch destination on faulting arena atomic Date: Mon, 10 Aug 2026 15:43:42 +0200 Message-ID: <20260810134346.466004-2-daniel@iogearbox.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810134346.466004-1-daniel@iogearbox.net> References: <20260810134346.466004-1-daniel@iogearbox.net> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Virus-Scanned: Clear (ClamAV 1.4.3/28088/Mon Aug 10 08:24:15 2026) A RMW atomic on an arena pointer is converted to BPF_PROBE_ATOMIC and gets an exception table entry, but that entry records no destination register to clear unless the instruction is a load-acquire today. That is right for a plain BPF_{ADD,AND,OR,XOR}, which only writes memory, but an RMW carrying BPF_FETCH also reads the old value into a register: src_reg for BPF_{ADD,AND,OR,XOR} | BPF_FETCH and BPF_XCHG, and r0 for BPF_CMPXCHG. emit_atomic_rmw() emits it that way, e.g.: [...] case BPF_XCHG: ctx->ex_insn_off = ctx->ninsns; emit(is64 ? rv_amoswap_d(rs, rs, rd, 1, 1) : rv_amoswap_w(rs, rs, rd, 1, 1), ctx); [...] Thus, a fault over an unmapped arena page ex_handler_bpf() jumps over the access but leaves rs untouched, and the program resumes with whatever it held before the atomic instead of the 0 that every other BPF_PROBE_* access delivers. Fill the exception table entry in from bpf_atomic_load_reg(), which returns the BPF register an atomic reads the memory operand into or -1 when it has none. A load-acquire ends up with the same register it gets today, it just goes through the helper. Unlike x86-64 and arm64, riscv64 does not report arena violations from its exception handler, so there is no access direction to correct here, only the missing register clear. Fixes: fb7cefabae81 ("riscv, bpf: Add support arena atomics for RV64") Signed-off-by: Daniel Borkmann Cc: Pu Lehui --- arch/riscv/net/bpf_jit_comp64.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c index 6b9972b07c1b..2504df1fa111 100644 --- a/arch/riscv/net/bpf_jit_comp64.c +++ b/arch/riscv/net/bpf_jit_comp64.c @@ -1992,10 +1992,19 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, ret = emit_atomic_rmw(rd, rs, insn, ctx); /* ret can be 1 (skip-zext); extable entry still needs to be added */ - if (ret >= 0) - ret = add_exception_handler(insn, - bpf_atomic_is_load_acq(insn) ? rd : REG_DONT_CLEAR_MARKER, - ctx) ?: ret; + if (ret >= 0) { + /* + * A load-acquire reads into dst_reg, and a read-modify-write + * carrying BPF_FETCH reads the old value into src_reg, or into + * r0 for a BPF_CMPXCHG. Clear that register on fault, the + * remaining atomics have no destination register. + */ + int load_reg = bpf_atomic_load_reg(insn); + + ret = add_exception_handler(insn, load_reg < 0 ? + REG_DONT_CLEAR_MARKER : regmap[load_reg], + ctx) ?: ret; + } if (ret) return ret; -- 2.43.0