Received: by 2002:a05:7412:419a:b0:f3:1519:9f41 with SMTP id i26csp2806200rdh; Sun, 26 Nov 2023 21:46:33 -0800 (PST) X-Google-Smtp-Source: AGHT+IFDQScqXAK5Wix/Js+N2Omc0+LJI2xjDpKxpDSncJ2q++oUOhVeVmrMDb8fbbcqPlOxwQHK X-Received: by 2002:a17:903:40cb:b0:1cc:6597:f421 with SMTP id t11-20020a17090340cb00b001cc6597f421mr13551354pld.48.1701063993024; Sun, 26 Nov 2023 21:46:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701063993; cv=none; d=google.com; s=arc-20160816; b=iuEVkvV9ltXpKHVPYnZGyOfz6xpwcJ3hVm96SuTDLqAZ7IfvG48vuoGipodrmu/GCe 7E5OgzsbDfT/aXPJcRHsw8zORLd1Wrvf0eGxV5Q3Xv44AGDT+AX2DxErRogVNOTBP6NT 3Wwu5eaCDRXpxLJRWNjIZw9jnt94/wV3BbuEeqZ4X3qKJp+zDmVgvttUygO0iyQNsZ/v a8CpNQKDsK5xd9esslIWEZizpS99EWL1rDeKrpyJAgObfZ3mOR3QgMWIySlnTTKrfPyu 41NiZWa7Lz6twh2iaRFFvOnk3/r0SZ/0h7wHDxelq4IslBoYEqwtakJInYr+uAmv/zha 7sGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:mime-version:date :dkim-signature:message-id; bh=jfng7m5CVVUjMjDZCHK2DOYs3dS/poCbHNGMSgQaFl8=; fh=3XIN12WDqdQrCbD+rWmna2fBAJrWukM+nblGNVe9WSQ=; b=boUCzAwktDVRKQ0geR8yJB9Z80mZKzHvOA1Q+tR6CS+JvcGq8wUDLox502WRgJ9Pyp NpbWmfhYxQ0Avx305SvWos8BLRaFZCfWtPbcEKULZcdgR9ogN3z0TA0YZJfnyCUSSszq JSKh+9PYpLMDSo+UO5jceTmrd+9gz/d5VFuvo50ZyyIJgDtFO4MDvVmgWOvA09u9rrlB DvZ7qDOnPiyefIKxuZJxY6BT3SBJw7JmckjvjTJK0/2igiNj1nl/ulDJMmWo4JwY2CV2 LjjG8sMnfHWXpKoRxFjt8vWsAML0F6Lvj4dTh0OTTXVB6kjGqKo0/L6+Ct55PBv/2Psu mNQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=pVEFZ9Qq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id u13-20020a170903124d00b001bb8c4279f5si9115289plh.148.2023.11.26.21.46.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 Nov 2023 21:46:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=pVEFZ9Qq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id F25DD807C655; Sun, 26 Nov 2023 21:45:16 -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 S229527AbjK0FpC (ORCPT + 99 others); Mon, 27 Nov 2023 00:45:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229450AbjK0FpA (ORCPT ); Mon, 27 Nov 2023 00:45:00 -0500 Received: from out-186.mta0.migadu.com (out-186.mta0.migadu.com [IPv6:2001:41d0:1004:224b::ba]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 856A5124; Sun, 26 Nov 2023 21:45:02 -0800 (PST) Message-ID: <42f9bf0d-695a-412d-bea5-cb7036fa7418@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1701063899; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jfng7m5CVVUjMjDZCHK2DOYs3dS/poCbHNGMSgQaFl8=; b=pVEFZ9QqEWYcXasAIBDiDF5YwRLy6ERVkY4BiC9RFXTTbMs3XRft0JzgWZasUBK7ec+6Pm Ypdq3RByDDY0EQDJN1OE5N5+v5KQkQjvrVDERSMkKpsyDHYwxabApB7aiNLv8Dk42WWlVn UXreyPsOVnzk7PeSIN7MVXfCCyI0R7E= Date: Sun, 26 Nov 2023 21:44:48 -0800 MIME-Version: 1.0 Subject: Re: [PATCH ipsec-next v1 6/7] bpf: selftests: test_tunnel: Disable CO-RE relocations Content-Language: en-GB To: Eduard Zingerman , Daniel Xu Cc: Alexei Starovoitov , Shuah Khan , Daniel Borkmann , Andrii Nakryiko , Alexei Starovoitov , Steffen Klassert , antony.antony@secunet.com, Mykola Lysenko , Martin KaFai Lau , Song Liu , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , bpf , "open list:KERNEL SELFTEST FRAMEWORK" , LKML , devel@linux-ipsec.org, Network Development References: <391d524c496acc97a8801d8bea80976f58485810.1700676682.git.dxu@dxuuu.xyz> <0f210cef-c6e9-41c1-9ba8-225f046435e5@linux.dev> <3ec6c068-7f95-419a-a0ae-a901f95e4838@linux.dev> <18e43cdf65e7ba0d8f6912364fbc5b08a6928b35.camel@gmail.com> <0535eb913f1a0c2d3c291478fde07e0aa2b333f1.camel@gmail.com> X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Yonghong Song In-Reply-To: <0535eb913f1a0c2d3c291478fde07e0aa2b333f1.camel@gmail.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable 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]); Sun, 26 Nov 2023 21:45:17 -0800 (PST) On 11/26/23 8:52 PM, Eduard Zingerman wrote: > On Sun, 2023-11-26 at 18:04 -0600, Daniel Xu wrote: > [...] >>> Tbh I'm not sure. This test passes with preserve_static_offset >>> because it suppresses preserve_access_index. In general clang >>> translates bitfield access to a set of IR statements like: >>> >>> C: >>> struct foo { >>> unsigned _; >>> unsigned a:1; >>> ... >>> }; >>> ... foo->a ... >>> >>> IR: >>> %a = getelementptr inbounds %struct.foo, ptr %0, i32 0, i32 1 >>> %bf.load = load i8, ptr %a, align 4 >>> %bf.clear = and i8 %bf.load, 1 >>> %bf.cast = zext i8 %bf.clear to i32 >>> >>> With preserve_static_offset the getelementptr+load are replaced by a >>> single statement which is preserved as-is till code generation, >>> thus load with align 4 is preserved. >>> >>> On the other hand, I'm not sure that clang guarantees that load or >>> stores used for bitfield access would be always aligned according to >>> verifier expectations. >>> >>> I think we should check if there are some clang knobs that prevent >>> generation of unaligned memory access. I'll take a look. >> Is there a reason to prefer fixing in compiler? I'm not opposed to it, >> but the downside to compiler fix is it takes years to propagate and >> sprinkles ifdefs into the code. >> >> Would it be possible to have an analogue of BPF_CORE_READ_BITFIELD()? > Well, the contraption below passes verification, tunnel selftest > appears to work. I might have messed up some shifts in the macro, though. I didn't test it. But from high level it should work. > > Still, if clang would peek unlucky BYTE_{OFFSET,SIZE} for a particular > field access might be unaligned. clang should pick a sensible BYTE_SIZE/BYTE_OFFSET to meet alignment requirement. This is also required for BPF_CORE_READ_BITFIELD. > > --- > > diff --git a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c > index 3065a716544d..41cd913ac7ff 100644 > --- a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c > +++ b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c > @@ -9,6 +9,7 @@ > #include "vmlinux.h" > #include > #include > +#include > #include "bpf_kfuncs.h" > #include "bpf_tracing_net.h" > > @@ -144,6 +145,38 @@ int ip6gretap_get_tunnel(struct __sk_buff *skb) > return TC_ACT_OK; > } > > +#define BPF_CORE_WRITE_BITFIELD(s, field, new_val) ({ \ > + void *p = (void *)s + __CORE_RELO(s, field, BYTE_OFFSET); \ > + unsigned byte_size = __CORE_RELO(s, field, BYTE_SIZE); \ > + unsigned lshift = __CORE_RELO(s, field, LSHIFT_U64); \ > + unsigned rshift = __CORE_RELO(s, field, RSHIFT_U64); \ > + unsigned bit_size = (rshift - lshift); \ > + unsigned long long nval, val, hi, lo; \ > + \ > + asm volatile("" : "=r"(p) : "0"(p)); \ Use 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; \ > + } \ > + hi = val >> (bit_size + rshift); \ > + hi <<= bit_size + rshift; \ > + lo = val << (bit_size + lshift); \ > + lo >>= bit_size + lshift; \ > + nval = new_val; \ > + nval <<= lshift; \ > + nval >>= rshift; \ > + val = hi | nval | lo; \ > + 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; \ > + } \ > +}) I think this should be put in libbpf public header files but not sure where to put it. bpf_core_read.h although it is core write? But on the other hand, this is a uapi struct bitfield write, strictly speaking, CORE write is really unnecessary here. It would be great if we can relieve users from dealing with such unnecessary CORE writes. In that sense, for this particular case, I would prefer rewriting the code by using byte-level stores... > + > SEC("tc") > int erspan_set_tunnel(struct __sk_buff *skb) > { > @@ -173,9 +206,9 @@ int erspan_set_tunnel(struct __sk_buff *skb) > __u8 hwid = 7; > > md.version = 2; > - md.u.md2.dir = direction; > - md.u.md2.hwid = hwid & 0xf; > - md.u.md2.hwid_upper = (hwid >> 4) & 0x3; > + BPF_CORE_WRITE_BITFIELD(&md.u.md2, dir, direction); > + BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid, (hwid & 0xf)); > + BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid_upper, (hwid >> 4) & 0x3); > #endif > > ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md)); > @@ -214,8 +247,9 @@ int erspan_get_tunnel(struct __sk_buff *skb) > bpf_printk("\tindex %x\n", index); > #else > bpf_printk("\tdirection %d hwid %x timestamp %u\n", > - md.u.md2.dir, > - (md.u.md2.hwid_upper << 4) + md.u.md2.hwid, > + BPF_CORE_READ_BITFIELD(&md.u.md2, dir), > + (BPF_CORE_READ_BITFIELD(&md.u.md2, hwid_upper) << 4) + > + BPF_CORE_READ_BITFIELD(&md.u.md2, hwid), > bpf_ntohl(md.u.md2.timestamp)); > #endif > > @@ -252,9 +286,9 @@ int ip4ip6erspan_set_tunnel(struct __sk_buff *skb) > __u8 hwid = 17; > > md.version = 2; > - md.u.md2.dir = direction; > - md.u.md2.hwid = hwid & 0xf; > - md.u.md2.hwid_upper = (hwid >> 4) & 0x3; > + BPF_CORE_WRITE_BITFIELD(&md.u.md2, dir, direction); > + BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid, (hwid & 0xf)); > + BPF_CORE_WRITE_BITFIELD(&md.u.md2, hwid_upper, (hwid >> 4) & 0x3); > #endif > > ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md)); > @@ -294,8 +328,9 @@ int ip4ip6erspan_get_tunnel(struct __sk_buff *skb) > bpf_printk("\tindex %x\n", index); > #else > bpf_printk("\tdirection %d hwid %x timestamp %u\n", > - md.u.md2.dir, > - (md.u.md2.hwid_upper << 4) + md.u.md2.hwid, > + BPF_CORE_READ_BITFIELD(&md.u.md2, dir), > + (BPF_CORE_READ_BITFIELD(&md.u.md2, hwid_upper) << 4) + > + BPF_CORE_READ_BITFIELD(&md.u.md2, hwid), > bpf_ntohl(md.u.md2.timestamp)); > #endif >