Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp4221368rdb; Mon, 11 Dec 2023 12:21:03 -0800 (PST) X-Google-Smtp-Source: AGHT+IFugBOD8lXeENVW5+r2jjD2Pp8rCYsCyf8qcTgVxHQSpNS1vqflwyZuE1ybSjyB4nFe7OFK X-Received: by 2002:a05:6a00:a1b:b0:6d0:9913:335f with SMTP id p27-20020a056a000a1b00b006d09913335fmr1035586pfh.55.1702326063055; Mon, 11 Dec 2023 12:21:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702326063; cv=none; d=google.com; s=arc-20160816; b=kebCcyolCRIOlSjZPS6ItGC+LZxct8tWZ8ES9fNKcRRAxVJzn+pR0RbYdiwElw9cOr ZhtLulPbVTmEvutOargAbl7hXX8aCcRmrlM83Q7nYwA7xp7wVfcbzbxJHrVPPlH65dgd 6r7s4mHVXCRGQj3Wmdo+7dA+ABVg5o85Lay3O3pCCltIaGKs6Jtfv8HExPVJR9koFKq4 Ibg848LCTVA4cDXO75gWAQnGjpDcwF8JxJxDniPQK0Br8npeL9o0Jww956Cn8oHQ4W5c pIzgjF3RaG1ihPepXmrB/gAvwTjkhlALCtTiSCZOVuFTTM9Q8I4mMi+436tzbV+tB38m XDxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :feedback-id:dkim-signature:dkim-signature; bh=1ORZQIDuXwXnlUl6JXOOGY6ASexrD5pFldnSGT1cA6s=; fh=TkYRG8ubQINWQWAUhv3TMJzowAxftXkY1Q/9+ipUrRc=; b=F9X0B7euE5rsup/YD22YrbkftdFSmHshBxVvlAdOXzY0mPdDgKIvniU2Q9mWWyoQ+R maai6wqf4SaxPGTLAXvE3Hi2xEhu7eY00WWXV6qrTyvHp1ULdxA1PvE98qW9UzwEpPm6 bu22f3243P5cZ5jAE1FGIgnVkppBKNWdMmsq7GDFugN0mmtPhCCbLVEv5sUK5LkjVgWc uWDtFyCjQvIhGNM928RrMXZGCFiQxt+1mgfKuPhgjOuSY37qK8mtW3XrMfvQxcfxjNRR dkZ8FgMQkxHDivHM6x2dExlEBxrfpO2j3hUWDw0/XL3VJhUUTT6GljltVZk/aKrwYQTx JBEA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@dxuuu.xyz header.s=fm3 header.b=PsNFQn8o; dkim=pass header.i=@messagingengine.com header.s=fm1 header.b=zmvTlhAL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id p20-20020a056a000b5400b006ce94299059si6590020pfo.179.2023.12.11.12.21.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Dec 2023 12:21:03 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@dxuuu.xyz header.s=fm3 header.b=PsNFQn8o; dkim=pass header.i=@messagingengine.com header.s=fm1 header.b=zmvTlhAL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 086D980A777C; Mon, 11 Dec 2023 12:21:02 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345016AbjLKUUh (ORCPT + 99 others); Mon, 11 Dec 2023 15:20:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345001AbjLKUUb (ORCPT ); Mon, 11 Dec 2023 15:20:31 -0500 Received: from new1-smtp.messagingengine.com (new1-smtp.messagingengine.com [66.111.4.221]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A92FFE5; Mon, 11 Dec 2023 12:20:36 -0800 (PST) Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailnew.nyi.internal (Postfix) with ESMTP id D7FF558093A; Mon, 11 Dec 2023 15:20:35 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Mon, 11 Dec 2023 15:20:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dxuuu.xyz; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm3; t=1702326035; x= 1702333235; bh=1ORZQIDuXwXnlUl6JXOOGY6ASexrD5pFldnSGT1cA6s=; b=P sNFQn8oXBF4WxLnIKPvIqKdou4WF8Dok45+7WCjxB57eFqrDKJJ6M+5WxbhW1TYj xi50Rj/n8kod03Dbt9pnccoIOXjSFbsfm6ek1HJcP1Sm+t09KOeKhTccL0JS/SDc iaPeG7DytijavrV0NvbM2QQhXGB5isAo8e3pIqxF3nOvMFQt5nv9rqiu4Oaf0ovb t1p8Qd7bgVBcIcxC8Aoqt2oZV8WrZZC8WdOsMtQ4lHoMavAKb0HuIST9kqyDRdA5 BE8yzBHlqpj5IrwW806SGO6bVaL+pS5LIr3OwbtByrSOmj2gEgVh4KETJAd6FqyI 86Oz3MZNOI+BP3q5loFrw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1702326035; x= 1702333235; bh=1ORZQIDuXwXnlUl6JXOOGY6ASexrD5pFldnSGT1cA6s=; b=z mvTlhALtY1A/UFoakFOytn45ayXt3atCMaRWRrAB99HwW0mBrFZeRQqP5a5Ft9Zf H7no+vgo0qk7k3SXgtk94FxoejA08FSudsS0vbFh2ADoWEBnINf/npwE8hQYYSPG eDrrxVlV8MBwVrgi9moY3ZNn3I+3h5kCSG/8bq9KSnbX8Kh9yd6MpCsCYnN7AMhZ WrvgbNyEfJdSfcbW4Ids93M2KCK5hx8gPFuUJ5sZBxGCf9Bgur5DOCbUS4DJ844d 6V3f0MFUXLppZN0y8ZDMyCAFQXAX6OqCRyNb0TjzxCLwk+i8Eg5J+b632T3k41KL p3HX/gFc/A9Y13mR9iWsA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrudelvddgudefkecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enfghrlhcuvffnffculddvfedmnecujfgurhephffvvefufffkofgjfhgggfestdekredt redttdenucfhrhhomhepffgrnhhivghlucgiuhcuoegugihusegugihuuhhurdighiiiqe enucggtffrrghtthgvrhhnpeeigeffteehteffheejkeefjeeuudfgvdekkeetudeghedu gffgleffhefgjeevgfenucffohhmrghinheplhhlvhhmrdhorhhgnecuvehluhhsthgvrh fuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepugiguhesugiguhhuuhdrgiih ii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 11 Dec 2023 15:20:33 -0500 (EST) From: Daniel Xu To: ndesaulniers@google.com, daniel@iogearbox.net, nathan@kernel.org, ast@kernel.org, andrii@kernel.org, steffen.klassert@secunet.com, antony.antony@secunet.com, alexei.starovoitov@gmail.com, yonghong.song@linux.dev, eddyz87@gmail.com, eyal.birger@gmail.com Cc: martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, trix@redhat.com, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, devel@linux-ipsec.org, netdev@vger.kernel.org, Jonathan Lemon Subject: [PATCH bpf-next v5 3/9] libbpf: Add BPF_CORE_WRITE_BITFIELD() macro Date: Mon, 11 Dec 2023 13:20:07 -0700 Message-ID: <4d3dd215a4fd57d980733886f9c11a45e1a9adf3.1702325874.git.dxu@dxuuu.xyz> X-Mailer: git-send-email 2.42.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Mon, 11 Dec 2023 12:21:02 -0800 (PST) === Motivation === Similar to reading from CO-RE bitfields, we need a CO-RE aware bitfield writing wrapper to make the verifier happy. Two alternatives to this approach are: 1. Use the upcoming `preserve_static_offset` [0] attribute to disable CO-RE on specific structs. 2. Use broader byte-sized writes to write to bitfields. (1) is a bit hard to use. It requires specific and not-very-obvious annotations to bpftool generated vmlinux.h. It's also not generally available in released LLVM versions yet. (2) makes the code quite hard to read and write. And especially if BPF_CORE_READ_BITFIELD() is already being used, it makes more sense to to have an inverse helper for writing. === Implementation details === Since the logic is a bit non-obvious, I thought it would be helpful to explain exactly what's going on. To start, it helps by explaining what LSHIFT_U64 (lshift) and RSHIFT_U64 (rshift) is designed to mean. Consider the core of the BPF_CORE_READ_BITFIELD() algorithm: val <<= __CORE_RELO(s, field, LSHIFT_U64); val = val >> __CORE_RELO(s, field, RSHIFT_U64); Basically what happens is we lshift to clear the non-relevant (blank) higher order bits. Then we rshift to bring the relevant bits (bitfield) down to LSB position (while also clearing blank lower order bits). To illustrate: Start: ........XXX...... Lshift: XXX......00000000 Rshift: 00000000000000XXX where `.` means blank bit, `0` means 0 bit, and `X` means bitfield bit. After the two operations, the bitfield is ready to be interpreted as a regular integer. Next, we want to build an alternative (but more helpful) mental model on lshift and rshift. That is, to consider: * rshift as the total number of blank bits in the u64 * lshift as number of blank bits left of the bitfield in the u64 Take a moment to consider why that is true by consulting the above diagram. With this insight, we can now define the following relationship: bitfield _ | | 0.....00XXX0...00 | | | | |______| | | lshift | | |____| (rshift - lshift) That is, we know the number of higher order blank bits is just lshift. And the number of lower order blank bits is (rshift - lshift). Finally, we can examine the core of the write side algorithm: mask = (~0ULL << rshift) >> lshift; // 1 val = (val & ~mask) | ((nval << rpad) & mask); // 2 1. Compute a mask where the set bits are the bitfield bits. The first left shift zeros out exactly the number of blank bits, leaving a bitfield sized set of 1s. The subsequent right shift inserts the correct amount of higher order blank bits. 2. On the left of the `|`, mask out the bitfield bits. This creates 0s where the new bitfield bits will go. On the right of the `|`, bring nval into the correct bit position and mask out any bits that fall outside of the bitfield. Finally, by bor'ing the two halves, we get the final set of bits to write back. [0]: https://reviews.llvm.org/D133361 Co-developed-by: Eduard Zingerman Signed-off-by: Eduard Zingerman Co-developed-by: Jonathan Lemon Signed-off-by: Jonathan Lemon Acked-by: Andrii Nakryiko Signed-off-by: Daniel Xu --- tools/lib/bpf/bpf_core_read.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.h index 1ac57bb7ac55..7325a12692a3 100644 --- a/tools/lib/bpf/bpf_core_read.h +++ b/tools/lib/bpf/bpf_core_read.h @@ -111,6 +111,38 @@ enum bpf_enum_value_kind { val; \ }) +/* + * Write to a bitfield, identified by s->field. + * This is the inverse of BPF_CORE_WRITE_BITFIELD(). + */ +#define BPF_CORE_WRITE_BITFIELD(s, field, new_val) ({ \ + void *p = (void *)s + __CORE_RELO(s, field, BYTE_OFFSET); \ + unsigned int byte_size = __CORE_RELO(s, field, BYTE_SIZE); \ + unsigned int lshift = __CORE_RELO(s, field, LSHIFT_U64); \ + unsigned int rshift = __CORE_RELO(s, field, RSHIFT_U64); \ + unsigned long long mask, val, nval = new_val; \ + unsigned int rpad = rshift - lshift; \ + \ + asm volatile("" : "+r"(p)); \ + \ + switch (byte_size) { \ + case 1: val = *(unsigned char *)p; break; \ + case 2: val = *(unsigned short *)p; break; \ + case 4: val = *(unsigned int *)p; break; \ + case 8: val = *(unsigned long long *)p; break; \ + } \ + \ + mask = (~0ULL << rshift) >> lshift; \ + val = (val & ~mask) | ((nval << rpad) & mask); \ + \ + switch (byte_size) { \ + case 1: *(unsigned char *)p = val; break; \ + case 2: *(unsigned short *)p = val; break; \ + case 4: *(unsigned int *)p = val; break; \ + case 8: *(unsigned long long *)p = val; break; \ + } \ +}) + #define ___bpf_field_ref1(field) (field) #define ___bpf_field_ref2(type, field) (((typeof(type) *)0)->field) #define ___bpf_field_ref(args...) \ -- 2.42.1