From patchwork Fri Nov 10 11:02:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452328 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 B3B9314004 for ; Fri, 10 Nov 2023 11:04:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="zjHJOysd" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6AEEA2B789 for ; Fri, 10 Nov 2023 03:03:59 -0800 (PST) Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MZH5F016135; Fri, 10 Nov 2023 11:03:41 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=3peXo6K443g/MRszRVP3JRcLRsqbm79n40/mIQgDJ6M=; b=zjHJOysdOIKvJhO+KCFNj2lgKKkS3A5pOJIOwa1HjTjDy+TGTqKmb2jxRqDvsEbnrNXZ Z5GwJCuFScW/kLKABBn9I0JGT4T1ijHnHXvT13euIN4aUuGvvGU285NN0m18xjMUnjCg OsYjKbRUkqOzimC+M7hDO/OEw+VSgHOaQnYW0fngC40dTrIndljNuR8reWnMhfdUbe/t ku3rqGcQiqiN31KrwhFyHBohPhnbjOa2OlA7kAGQn2CzezfhApNWeLaCqZVg6o/DRpnl eMait5V2M55aS3d5eY+T6WZpdMvwsOyRTjAnU5RB3vXSf7zJqU/AehGYzlHrCZxPOCBf 0Q== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w26wyj6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:41 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AA9hkpM017517; Fri, 10 Nov 2023 11:03:39 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qg1y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:39 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfg018454; Fri, 10 Nov 2023 11:03:39 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-2; Fri, 10 Nov 2023 11:03:38 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 01/17] btf: add kind layout encoding, crcs to UAPI Date: Fri, 10 Nov 2023 11:02:48 +0000 Message-Id: <20231110110304.63910-2-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: _XwEUeKoE-I37ovKlvjBw9hAZzGLuet6 X-Proofpoint-ORIG-GUID: _XwEUeKoE-I37ovKlvjBw9hAZzGLuet6 X-Patchwork-Delegate: bpf@iogearbox.net BTF kind layouts provide information to parse BTF kinds. By separating parsing BTF from using all the information it provides, we allow BTF to encode new features even if they cannot be used. This is helpful in particular for cases where newer tools for BTF generation run on an older kernel; BTF kinds may be present that the kernel cannot yet use, but at least it can parse the BTF provided. Meanwhile userspace tools with newer libbpf may be able to use the newer information. The intent is to support encoding of kind layouts optionally so that tools like pahole can add this information. So for each kind we record - kind-related flags - length of singular element following struct btf_type - length of each of the btf_vlen() elements following In addition we make space in the BTF header for CRC32s computed over the BTF along with a CRC for the base BTF; this allows split BTF to identify a mismatch explicitly. The ideas here were discussed at [1], [2]; hence Suggested-by: Andrii Nakryiko Signed-off-by: Alan Maguire [1] https://lore.kernel.org/bpf/CAEf4BzYjWHRdNNw4B=eOXOs_ONrDwrgX4bn=Nuc1g8JPFC34MA@mail.gmail.com/ [2] https://lore.kernel.org/bpf/20230531201936.1992188-1-alan.maguire@oracle.com/ --- include/uapi/linux/btf.h | 18 ++++++++++++++++++ tools/include/uapi/linux/btf.h | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h index ec1798b6d3ff..f4965de18f0c 100644 --- a/include/uapi/linux/btf.h +++ b/include/uapi/linux/btf.h @@ -8,6 +8,19 @@ #define BTF_MAGIC 0xeB9F #define BTF_VERSION 1 +/* kind layout section consists of a struct btf_kind_layout for each known + * kind at BTF encoding time. + */ +struct btf_kind_layout { + __u16 flags; /* see BTF_KIND_LAYOUT_* values above */ + __u8 info_sz; /* size of singular element after btf_type */ + __u8 elem_sz; /* size of each of btf_vlen(t) elements */ +}; + +/* for CRCs for BTF, base BTF to be considered usable, flags must be set. */ +#define BTF_FLAG_CRC_SET (1 << 0) +#define BTF_FLAG_BASE_CRC_SET (1 << 1) + struct btf_header { __u16 magic; __u8 version; @@ -19,6 +32,11 @@ struct btf_header { __u32 type_len; /* length of type section */ __u32 str_off; /* offset of string section */ __u32 str_len; /* length of string section */ + __u32 kind_layout_off;/* offset of kind layout section */ + __u32 kind_layout_len;/* length of kind layout section */ + + __u32 crc; /* crc of BTF; used if flags set BTF_FLAG_CRC_SET */ + __u32 base_crc; /* crc of base BTF; used if flags set BTF_FLAG_BASE_CRC_SET */ }; /* Max # of type identifier */ diff --git a/tools/include/uapi/linux/btf.h b/tools/include/uapi/linux/btf.h index ec1798b6d3ff..f4965de18f0c 100644 --- a/tools/include/uapi/linux/btf.h +++ b/tools/include/uapi/linux/btf.h @@ -8,6 +8,19 @@ #define BTF_MAGIC 0xeB9F #define BTF_VERSION 1 +/* kind layout section consists of a struct btf_kind_layout for each known + * kind at BTF encoding time. + */ +struct btf_kind_layout { + __u16 flags; /* see BTF_KIND_LAYOUT_* values above */ + __u8 info_sz; /* size of singular element after btf_type */ + __u8 elem_sz; /* size of each of btf_vlen(t) elements */ +}; + +/* for CRCs for BTF, base BTF to be considered usable, flags must be set. */ +#define BTF_FLAG_CRC_SET (1 << 0) +#define BTF_FLAG_BASE_CRC_SET (1 << 1) + struct btf_header { __u16 magic; __u8 version; @@ -19,6 +32,11 @@ struct btf_header { __u32 type_len; /* length of type section */ __u32 str_off; /* offset of string section */ __u32 str_len; /* length of string section */ + __u32 kind_layout_off;/* offset of kind layout section */ + __u32 kind_layout_len;/* length of kind layout section */ + + __u32 crc; /* crc of BTF; used if flags set BTF_FLAG_CRC_SET */ + __u32 base_crc; /* crc of base BTF; used if flags set BTF_FLAG_BASE_CRC_SET */ }; /* Max # of type identifier */ From patchwork Fri Nov 10 11:02:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452329 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 18D93D2EB for ; Fri, 10 Nov 2023 11:04:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="y9cB63Iv" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E34032B789 for ; Fri, 10 Nov 2023 03:04:02 -0800 (PST) Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MZJkI016187; Fri, 10 Nov 2023 11:03:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=ClTI0tVZNkO/dk+EHJQ0YSPzVxScutkDOFsvwYiOrVY=; b=y9cB63Ivp/dI/HlOnayIAbchYxKrTZqB+xrOC2bV1S23Ty3Y1+ctFHphJjHwodACA2Pi VvibWnYIFEd4829GWBlSLizP+4gBdNyHOQlah7cpd5U3teqX0auDvRmAdxGIdbMggXK7 QSwRTyNJ4DYig4Lm7iKFs4lTxcVWL6CZZQzxU+JiZJw3mRpiQzFKnzGTWWne5EVHM4Xd qoySWQOm/XuUyqrmH6tG7dbMXjpoqtQIJwsNOw/LieMhtZP57XTM8sz+yQrTMf6c85HG 5w2mkRPh3MAvb41ifiMVj0dqbNUy5YOXhWo7Y+4hOibbT2UbZVmyaILj8tNOY2WYjiQT Wg== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w26wyjq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:44 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAA74js018342; Fri, 10 Nov 2023 11:03:43 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qg55-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:43 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfi018454; Fri, 10 Nov 2023 11:03:42 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-3; Fri, 10 Nov 2023 11:03:42 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 02/17] libbpf: support kind layout section handling in BTF Date: Fri, 10 Nov 2023 11:02:49 +0000 Message-Id: <20231110110304.63910-3-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: fxpnprvefeJXMN5QviT3moBKyLp_63fp X-Proofpoint-ORIG-GUID: fxpnprvefeJXMN5QviT3moBKyLp_63fp X-Patchwork-Delegate: bpf@iogearbox.net support reading in kind layout fixing endian issues on reading; also support writing kind layout section to raw BTF object. There is not yet an API to populate the kind layout with meaningful information. As part of this, we need to consider multiple valid BTF header sizes; the original or the kind layout/CRC-extended headers. So to support this, the "struct btf" representation is modified to always allocate a "struct btf_header" and copy the valid portion from the raw data to it; this means we can always safely check fields like btf->hdr->crc or btf->hdr->kind_layout_len. Signed-off-by: Alan Maguire --- tools/lib/bpf/btf.c | 206 +++++++++++++++++++++++++++++++++----------- 1 file changed, 154 insertions(+), 52 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index ee95fd379d4d..7a7a9793126a 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -39,40 +39,51 @@ struct btf { /* * When BTF is loaded from an ELF or raw memory it is stored - * in a contiguous memory block. The hdr, type_data, and, strs_data + * in a contiguous memory block. The type_data, and, strs_data * point inside that memory region to their respective parts of BTF * representation: * - * +--------------------------------+ - * | Header | Types | Strings | - * +--------------------------------+ - * ^ ^ ^ - * | | | - * hdr | | - * types_data-+ | - * strs_data------------+ + * +--------------------------------+---------------------+ + * | Header | Types | Strings |Optional kind layout | + * +--------------------------------+---------------------+ + * ^ ^ ^ ^ + * | | | | + * raw_data | | | + * types_data-+ | | + * strs_data------------+ | + * kind_layout----------------------+ + * + * A separate struct btf_header is allocated for btf->hdr, + * and header information is copied into it. This allows us + * to handle header data for various header formats; the original, + * the extended header with CRCs/kind layout, etc. * * If BTF data is later modified, e.g., due to types added or * removed, BTF deduplication performed, etc, this contiguous - * representation is broken up into three independently allocated - * memory regions to be able to modify them independently. + * representation is broken up into four independent memory + * regions. + * * raw_data is nulled out at that point, but can be later allocated * and cached again if user calls btf__raw_data(), at which point - * raw_data will contain a contiguous copy of header, types, and - * strings: + * raw_data will contain a contiguous copy of header, types, strings + * and optionally kind_layout. kind_layout optionally points to a + * kind_layout array - this allows us to encode information about + * the kinds known at encoding time. If kind_layout is NULL no + * kind information is encoded. * - * +----------+ +---------+ +-----------+ - * | Header | | Types | | Strings | - * +----------+ +---------+ +-----------+ - * ^ ^ ^ - * | | | - * hdr | | - * types_data----+ | - * strset__data(strs_set)-----+ + * +----------+ +---------+ +-----------+ +-----------+ + * | Header | | Types | | Strings | |kind_layout| + * +----------+ +---------+ +-----------+ +-----------+ + * ^ ^ ^ ^ + * | | | | + * hdr | | | + * types_data----+ | | + * strset__data(strs_set)-----+ | + * kind_layout--------------------------------+ * - * +----------+---------+-----------+ - * | Header | Types | Strings | - * raw_data----->+----------+---------+-----------+ + * +----------+---------+-----------+---------------------+ + * | Header | Types | Strings | Optional kind layout| + * raw_data----->+----------+---------+-----------+---------------------+ */ struct btf_header *hdr; @@ -116,6 +127,14 @@ struct btf { /* whether strings are already deduplicated */ bool strs_deduped; + /* Points either at raw kind layout data in parsed BTF (if present, or + * at a local kind layout array when BTF is modifiable. + */ + void *kind_layout; + + /* is BTF modifiable? i.e. is it split into separate sections as described above? */ + bool modifiable; + /* BTF object FD, if loaded into kernel */ int fd; @@ -207,7 +226,7 @@ static int btf_add_type_idx_entry(struct btf *btf, __u32 type_off) return 0; } -static void btf_bswap_hdr(struct btf_header *h) +static void btf_bswap_hdr(struct btf_header *h, __u32 hdr_len) { h->magic = bswap_16(h->magic); h->hdr_len = bswap_32(h->hdr_len); @@ -215,50 +234,70 @@ static void btf_bswap_hdr(struct btf_header *h) h->type_len = bswap_32(h->type_len); h->str_off = bswap_32(h->str_off); h->str_len = bswap_32(h->str_len); + /* May be operating on raw data with hdr_len that does not include below fields */ + if (hdr_len >= sizeof(struct btf_header)) { + h->kind_layout_off = bswap_32(h->kind_layout_off); + h->kind_layout_len = bswap_32(h->kind_layout_len); + h->crc = bswap_32(h->crc); + h->base_crc = bswap_32(h->base_crc); + } } static int btf_parse_hdr(struct btf *btf) { - struct btf_header *hdr = btf->hdr; + struct btf_header *hdr = btf->raw_data; + __u32 hdr_len = hdr->hdr_len; __u32 meta_left; - if (btf->raw_size < sizeof(struct btf_header)) { + if (btf->raw_size < offsetofend(struct btf_header, str_len)) { pr_debug("BTF header not found\n"); return -EINVAL; } if (hdr->magic == bswap_16(BTF_MAGIC)) { btf->swapped_endian = true; - if (bswap_32(hdr->hdr_len) != sizeof(struct btf_header)) { + hdr_len = bswap_32(hdr->hdr_len); + if (hdr_len < offsetofend(struct btf_header, str_len)) { pr_warn("Can't load BTF with non-native endianness due to unsupported header length %u\n", - bswap_32(hdr->hdr_len)); + hdr_len); return -ENOTSUP; } - btf_bswap_hdr(hdr); } else if (hdr->magic != BTF_MAGIC) { pr_debug("Invalid BTF magic: %x\n", hdr->magic); return -EINVAL; } - if (btf->raw_size < hdr->hdr_len) { + if (btf->raw_size < hdr_len) { pr_debug("BTF header len %u larger than data size %u\n", - hdr->hdr_len, btf->raw_size); + hdr_len, btf->raw_size); return -EINVAL; } - meta_left = btf->raw_size - hdr->hdr_len; - if (meta_left < (long long)hdr->str_off + hdr->str_len) { + /* At this point, we have basic header information, so allocate btf->hdr */ + btf->hdr = calloc(1, sizeof(struct btf_header)); + if (!btf->hdr) { + pr_debug("BTF header allocation failed\n"); + return -ENOMEM; + } + if (btf->swapped_endian) + btf_bswap_hdr(hdr, hdr_len); + memcpy(btf->hdr, hdr, hdr_len < sizeof(struct btf_header) ? hdr_len : + sizeof(struct btf_header)); + + meta_left = btf->raw_size - hdr_len; + if (meta_left < (long long)btf->hdr->str_off + btf->hdr->str_len) { pr_debug("Invalid BTF total size: %u\n", btf->raw_size); return -EINVAL; } - if ((long long)hdr->type_off + hdr->type_len > hdr->str_off) { + if ((long long)btf->hdr->type_off + btf->hdr->type_len > btf->hdr->str_off) { pr_debug("Invalid BTF data sections layout: type data at %u + %u, strings data at %u + %u\n", - hdr->type_off, hdr->type_len, hdr->str_off, hdr->str_len); + btf->hdr->type_off, btf->hdr->type_len, btf->hdr->str_off, + btf->hdr->str_len); return -EINVAL; } - if (hdr->type_off % 4) { + if (btf->hdr->type_off % 4) { pr_debug("BTF type section is not aligned to 4 bytes\n"); return -EINVAL; } @@ -285,6 +324,33 @@ static int btf_parse_str_sec(struct btf *btf) return 0; } +static void btf_bswap_kind_layout_sec(struct btf_kind_layout *k, int len) +{ + struct btf_kind_layout *end = (void *)k + len; + + while (k < end) { + k->flags = bswap_16(k->flags); + k++; + } +} + +static int btf_parse_kind_layout_sec(struct btf *btf) +{ + const struct btf_header *hdr = btf->hdr; + + if (!hdr->kind_layout_off || !hdr->kind_layout_len) + return 0; + btf->kind_layout = btf->raw_data + btf->hdr->hdr_len + btf->hdr->kind_layout_off; + + if (hdr->kind_layout_len % sizeof(struct btf_kind_layout) != 0) { + pr_debug("Invalid BTF kind layout section\n"); + return -EINVAL; + } + btf->kind_layout = btf->raw_data + btf->hdr->hdr_len + btf->hdr->kind_layout_off; + + return 0; +} + static int btf_type_size(const struct btf_type *t) { const int base_size = sizeof(struct btf_type); @@ -944,7 +1010,8 @@ __s32 btf__find_by_name_kind(const struct btf *btf, const char *type_name, static bool btf_is_modifiable(const struct btf *btf) { - return (void *)btf->hdr != btf->raw_data; + /* BTF is modifiable if split into multiple sections */ + return btf->modifiable; } void btf__free(struct btf *btf) @@ -962,11 +1029,12 @@ void btf__free(struct btf *btf) * might still have a cached contiguous raw data present, * which will be unconditionally freed below. */ - free(btf->hdr); free(btf->types_data); strset__free(btf->strs_set); } free(btf->raw_data); + if (btf->hdr != btf->raw_data) + free(btf->hdr); free(btf->raw_data_swapped); free(btf->type_offs); free(btf); @@ -974,6 +1042,7 @@ void btf__free(struct btf *btf) static struct btf *btf_new_empty(struct btf *base_btf) { + struct btf_header *hdr; struct btf *btf; btf = calloc(1, sizeof(*btf)); @@ -1001,14 +1070,20 @@ static struct btf *btf_new_empty(struct btf *base_btf) return ERR_PTR(-ENOMEM); } - btf->hdr = btf->raw_data; - btf->hdr->hdr_len = sizeof(struct btf_header); - btf->hdr->magic = BTF_MAGIC; - btf->hdr->version = BTF_VERSION; + hdr = btf->raw_data; + hdr->hdr_len = sizeof(struct btf_header); + hdr->magic = BTF_MAGIC; + hdr->version = BTF_VERSION; - btf->types_data = btf->raw_data + btf->hdr->hdr_len; - btf->strs_data = btf->raw_data + btf->hdr->hdr_len; - btf->hdr->str_len = base_btf ? 0 : 1; /* empty string at offset 0 */ + btf->types_data = btf->raw_data + hdr->hdr_len; + btf->strs_data = btf->raw_data + hdr->hdr_len; + hdr->str_len = base_btf ? 0 : 1; /* empty string at offset 0 */ + btf->hdr = calloc(1, sizeof(struct btf_header)); + if (!btf->hdr) { + free(btf); + return ERR_PTR(-ENOMEM); + } + memcpy(btf->hdr, hdr, sizeof(*hdr)); return btf; } @@ -1051,7 +1126,6 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf) memcpy(btf->raw_data, data, size); btf->raw_size = size; - btf->hdr = btf->raw_data; err = btf_parse_hdr(btf); if (err) goto done; @@ -1060,6 +1134,7 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf) btf->types_data = btf->raw_data + btf->hdr->hdr_len + btf->hdr->type_off; err = btf_parse_str_sec(btf); + err = err ?: btf_parse_kind_layout_sec(btf); err = err ?: btf_parse_type_sec(btf); err = err ?: btf_sanity_check(btf); if (err) @@ -1427,6 +1502,11 @@ static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endi } data_sz = hdr->hdr_len + hdr->type_len + hdr->str_len; + if (btf->kind_layout) { + data_sz = roundup(data_sz, 4); + data_sz += hdr->kind_layout_len; + hdr->kind_layout_off = roundup(hdr->type_len + hdr->str_len, 4); + } data = calloc(1, data_sz); if (!data) return NULL; @@ -1434,7 +1514,7 @@ static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endi memcpy(p, hdr, hdr->hdr_len); if (swap_endian) - btf_bswap_hdr(p); + btf_bswap_hdr(p, hdr->hdr_len); p += hdr->hdr_len; memcpy(p, btf->types_data, hdr->type_len); @@ -1453,7 +1533,13 @@ static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endi p += hdr->type_len; memcpy(p, btf_strs_data(btf), hdr->str_len); - p += hdr->str_len; + + if (btf->kind_layout) { + p = data + hdr->hdr_len + hdr->kind_layout_off; + memcpy(p, btf->kind_layout, hdr->kind_layout_len); + if (swap_endian) + btf_bswap_kind_layout_sec(p, hdr->kind_layout_len); + } *size = data_sz; return data; @@ -1586,12 +1672,12 @@ static void btf_invalidate_raw_data(struct btf *btf) } /* Ensure BTF is ready to be modified (by splitting into a three memory - * regions for header, types, and strings). Also invalidate cached - * raw_data, if any. + * regions for header, types, and strings, with kind layout section if + * needed). Also invalidate cached raw_data, if any. */ static int btf_ensure_modifiable(struct btf *btf) { - void *hdr, *types; + void *hdr, *types, *kind_layout = NULL; struct strset *set = NULL; int err = -ENOMEM; @@ -1604,12 +1690,24 @@ static int btf_ensure_modifiable(struct btf *btf) /* split raw data into three memory regions */ hdr = malloc(btf->hdr->hdr_len); types = malloc(btf->hdr->type_len); + if (btf->hdr->kind_layout_len) + kind_layout = malloc(btf->hdr->kind_layout_len); if (!hdr || !types) goto err_out; + if (btf->hdr->kind_layout_len) + kind_layout = malloc(btf->hdr->kind_layout_len); memcpy(hdr, btf->hdr, btf->hdr->hdr_len); memcpy(types, btf->types_data, btf->hdr->type_len); + if (btf->hdr->kind_layout_len) { + kind_layout = malloc(btf->hdr->kind_layout_len); + if (!kind_layout) + goto err_out; + memcpy(kind_layout, btf->raw_data + btf->hdr->hdr_len + btf->hdr->kind_layout_off, + btf->hdr->kind_layout_len); + } + /* build lookup index for all strings */ set = strset__new(BTF_MAX_STR_OFFSET, btf->strs_data, btf->hdr->str_len); if (IS_ERR(set)) { @@ -1623,6 +1721,7 @@ static int btf_ensure_modifiable(struct btf *btf) btf->types_data_cap = btf->hdr->type_len; btf->strs_data = NULL; btf->strs_set = set; + btf->kind_layout = kind_layout; /* if BTF was created from scratch, all strings are guaranteed to be * unique and deduplicated */ @@ -1634,12 +1733,15 @@ static int btf_ensure_modifiable(struct btf *btf) /* invalidate raw_data representation */ btf_invalidate_raw_data(btf); + btf->modifiable = true; + return 0; err_out: strset__free(set); free(hdr); free(types); + free(kind_layout); return err; } From patchwork Fri Nov 10 11:02:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452330 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 5036512B75 for ; Fri, 10 Nov 2023 11:04:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="G8PYSO/C" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B3AA2B78D for ; Fri, 10 Nov 2023 03:04:06 -0800 (PST) Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAAa6u9017477; Fri, 10 Nov 2023 11:03:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=Zny0GWWT0isQSzvl6z9jaCawxilet081z4jJO7AwjeQ=; b=G8PYSO/CcN1dU7P7ZJFgv/6ruDxHMSypVoAwIO54Im4CDyZqBpg6uHnzCKjjWwWkQ1VJ 3kc5mbKaGtDhnjUeZhSahwEaxZX/u8IIDaJDNXtsaTMWmaHNZ8Z/XIkVy6ocKDt3wDsX F/X1BdtxZJPAP8V7PFt3G+Emh6oGNT831ITOoVoMx6q47BNxr2o5VXbVjQHlMP1YZlKH YigpVSCh6fxp+TXVf73BkebUeLCIkum3oaGOKiNGcnoW/QhzG2jQivpI7GrPq262isY2 3aADCzMNrKgSykuekDDvNeiR6pU82U/+Sz1DSewLsSd3Aj3lI5PlCJ+NlGhC0ogpZ5d8 pA== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w23620y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:48 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAA974o017695; Fri, 10 Nov 2023 11:03:47 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qg7q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:47 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfk018454; Fri, 10 Nov 2023 11:03:46 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-4; Fri, 10 Nov 2023 11:03:46 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 03/17] libbpf: use kind layout to compute an unknown kind size Date: Fri, 10 Nov 2023 11:02:50 +0000 Message-Id: <20231110110304.63910-4-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=941 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: KvAE9K-zt5DABvZX_vsRI63jTKzDwiYZ X-Proofpoint-ORIG-GUID: KvAE9K-zt5DABvZX_vsRI63jTKzDwiYZ X-Patchwork-Delegate: bpf@iogearbox.net This allows BTF parsing to proceed even if we do not know the kind. Signed-off-by: Alan Maguire --- tools/lib/bpf/btf.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 7a7a9793126a..007ce6bcad70 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -351,7 +351,29 @@ static int btf_parse_kind_layout_sec(struct btf *btf) return 0; } -static int btf_type_size(const struct btf_type *t) +/* for unknown kinds, consult kind layout. */ +static int btf_type_size_unknown(const struct btf *btf, const struct btf_type *t) +{ + int size = sizeof(struct btf_type); + struct btf_kind_layout *k = NULL; + __u16 vlen = btf_vlen(t); + __u8 kind = btf_kind(t); + + if (btf->kind_layout) + k = &((struct btf_kind_layout *)btf->kind_layout)[kind]; + + if (!k || (void *)k > ((void *)btf->kind_layout + btf->hdr->kind_layout_len)) { + pr_debug("Unsupported BTF_KIND: %u\n", btf_kind(t)); + return -EINVAL; + } + + size += k->info_sz; + size += vlen * k->elem_sz; + + return size; +} + +static int btf_type_size(const struct btf *btf, const struct btf_type *t) { const int base_size = sizeof(struct btf_type); __u16 vlen = btf_vlen(t); @@ -387,8 +409,7 @@ static int btf_type_size(const struct btf_type *t) case BTF_KIND_DECL_TAG: return base_size + sizeof(struct btf_decl_tag); default: - pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t)); - return -EINVAL; + return btf_type_size_unknown(btf, t); } } @@ -487,7 +508,7 @@ static int btf_parse_type_sec(struct btf *btf) if (btf->swapped_endian) btf_bswap_type_base(next_type); - type_size = btf_type_size(next_type); + type_size = btf_type_size(btf, next_type); if (type_size < 0) return type_size; if (next_type + type_size > end_type) { @@ -1868,7 +1889,7 @@ int btf__add_type(struct btf *btf, const struct btf *src_btf, const struct btf_t struct btf_type *t; int sz, err; - sz = btf_type_size(src_type); + sz = btf_type_size(src_btf, src_type); if (sz < 0) return libbpf_err(sz); @@ -1949,7 +1970,7 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf) memcpy(t, src_btf->types_data, data_sz); for (i = 0; i < cnt; i++) { - sz = btf_type_size(t); + sz = btf_type_size(src_btf, t); if (sz < 0) { /* unlikely, has to be corrupted src_btf */ err = sz; @@ -4945,7 +4966,7 @@ static int btf_dedup_compact_types(struct btf_dedup *d) continue; t = btf__type_by_id(d->btf, id); - len = btf_type_size(t); + len = btf_type_size(d->btf, t); if (len < 0) return len; From patchwork Fri Nov 10 11:02:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452331 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 21A4B12B75 for ; Fri, 10 Nov 2023 11:04:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="R1+xoSHX" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A372D2B78E for ; Fri, 10 Nov 2023 03:04:10 -0800 (PST) Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MZHi9016141; Fri, 10 Nov 2023 11:03:53 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=5TtrD4MPSjQKImg+hp4IcMu2V05HDH+8fp6k3lMubxo=; b=R1+xoSHXUh1zTahyev2rkmQC3NdfqQSCy1YG2Q5Yz+3kwnmgrs1sXuRNn4q7Z9zujqq4 NpCMLNC3OXYPS+1m6fDm7BPb9rLKDGN4mpheAkJqJp4mIy0VMmLQiL00AA2uMKr20fWP dlH8CPLgeMflDF9pKkruwVL7cUB4Toek3+AX0bUvwD2416cA2Wp4FWrEhhKOBaJpsf67 GvIU460hxJyDQe6IWhdRzReuLZyoihX/iRsh0iLAoPpbcrwWKJAnTJ8jKyO3djjadkDb hpa3Op5C6PDgdJiWiughys6goMbSHyH6Q9GIW8Diqy19IpBzZ3lVbJSK7zSU4wfPsZoo Gg== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w26wykc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:52 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AA9pqQf017618; Fri, 10 Nov 2023 11:03:51 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qgak-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:51 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfm018454; Fri, 10 Nov 2023 11:03:50 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-5; Fri, 10 Nov 2023 11:03:50 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 04/17] libbpf: add kind layout encoding, crc support Date: Fri, 10 Nov 2023 11:02:51 +0000 Message-Id: <20231110110304.63910-5-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: gOMUEKB-WC6Y5NcrOV1r9CUq_Z1vnWil X-Proofpoint-ORIG-GUID: gOMUEKB-WC6Y5NcrOV1r9CUq_Z1vnWil X-Patchwork-Delegate: bpf@iogearbox.net Support encoding of BTF kind layout data and crcs via btf__new_empty_opts(). Current supported opts are base_btf, add_kind_layout and add_crc. Kind layout information is maintained in btf.c in the kind_layouts[] array; when BTF is created with the add_kind_layout option it represents the current view of supported BTF kinds. Signed-off-by: Alan Maguire --- tools/lib/bpf/btf.c | 74 ++++++++++++++++++++++++++++++++++++++-- tools/lib/bpf/btf.h | 11 ++++++ tools/lib/bpf/libbpf.map | 1 + 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 007ce6bcad70..ed728d0511a4 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "btf.h" #include "bpf.h" #include "libbpf.h" @@ -28,6 +29,35 @@ static struct btf_type btf_void; +/* Describe how kinds are laid out; some have a singular element following the "struct btf_type", + * some have BTF_INFO_VLEN(t->info) elements. Specify sizes for both. Flags are currently unused. + * Kind layout can be optionally added to the BTF representation in a dedicated section to + * facilitate parsing. New kinds must be added here. + */ +struct btf_kind_layout kind_layouts[NR_BTF_KINDS] = { +/* flags singular element size vlen element(s) size */ +{ 0, 0, 0 }, /* _UNKN */ +{ 0, sizeof(__u32), 0 }, /* _INT */ +{ 0, 0, 0 }, /* _PTR */ +{ 0, sizeof(struct btf_array), 0 }, /* _ARRAY */ +{ 0, 0, sizeof(struct btf_member) }, /* _STRUCT */ +{ 0, 0, sizeof(struct btf_member) }, /* _UNION */ +{ 0, 0, sizeof(struct btf_enum) }, /* _ENUM */ +{ 0, 0, 0 }, /* _FWD */ +{ 0, 0, 0 }, /* _TYPEDEF */ +{ 0, 0, 0 }, /* _VOLATILE */ +{ 0, 0, 0 }, /* _CONST */ +{ 0, 0, 0 }, /* _RESTRICT */ +{ 0, 0, 0 }, /* _FUNC */ +{ 0, 0, sizeof(struct btf_param) }, /* _FUNC_PROTO */ +{ 0, sizeof(struct btf_var), 0 }, /* _VAR */ +{ 0, 0, sizeof(struct btf_var_secinfo) }, /* _DATASEC */ +{ 0, 0, 0 }, /* _FLOAT */ +{ 0, sizeof(struct btf_decl_tag), 0 }, /* _DECL_TAG */ +{ 0, 0, 0 }, /* _TYPE_TAG */ +{ 0, 0, sizeof(struct btf_enum64) }, /* _ENUM64 */ +}; + struct btf { /* raw BTF data in native endianness */ void *raw_data; @@ -1061,8 +1091,9 @@ void btf__free(struct btf *btf) free(btf); } -static struct btf *btf_new_empty(struct btf *base_btf) +static struct btf *btf_new_empty(struct btf_new_opts *opts) { + struct btf *base_btf = OPTS_GET(opts, base_btf, NULL); struct btf_header *hdr; struct btf *btf; @@ -1104,6 +1135,23 @@ static struct btf *btf_new_empty(struct btf *base_btf) free(btf); return ERR_PTR(-ENOMEM); } + + if (opts->add_kind_layout) { + btf->kind_layout = kind_layouts; + hdr->kind_layout_len = sizeof(kind_layouts); + } + if (opts->add_crc) { + if (btf->base_btf) { + struct btf_header *base_hdr = btf->base_btf->hdr; + + if (base_hdr->hdr_len >= sizeof(struct btf_header) && + base_hdr->flags & BTF_FLAG_CRC_SET) { + hdr->base_crc = base_hdr->crc; + hdr->flags |= BTF_FLAG_BASE_CRC_SET; + } + } + hdr->flags |= BTF_FLAG_CRC_SET; + } memcpy(btf->hdr, hdr, sizeof(*hdr)); return btf; @@ -1111,12 +1159,26 @@ static struct btf *btf_new_empty(struct btf *base_btf) struct btf *btf__new_empty(void) { - return libbpf_ptr(btf_new_empty(NULL)); + LIBBPF_OPTS(btf_new_opts, opts); + + return libbpf_ptr(btf_new_empty(&opts)); } struct btf *btf__new_empty_split(struct btf *base_btf) { - return libbpf_ptr(btf_new_empty(base_btf)); + LIBBPF_OPTS(btf_new_opts, opts); + + opts.base_btf = base_btf; + + return libbpf_ptr(btf_new_empty(&opts)); +} + +struct btf *btf__new_empty_opts(struct btf_new_opts *opts) +{ + if (!OPTS_VALID(opts, btf_new_opts)) + return libbpf_err_ptr(-EINVAL); + + return libbpf_ptr(btf_new_empty(opts)); } static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf) @@ -1562,6 +1624,12 @@ static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endi btf_bswap_kind_layout_sec(p, hdr->kind_layout_len); } + if (hdr->flags & BTF_FLAG_CRC_SET) { + struct btf_header *h = data; + + h->crc = crc32(0L, (const Bytef *)data, data_sz); + } + *size = data_sz; return data; err_out: diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index 8e6880d91c84..d25bd5c19eec 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h @@ -107,6 +107,17 @@ LIBBPF_API struct btf *btf__new_empty(void); */ LIBBPF_API struct btf *btf__new_empty_split(struct btf *base_btf); +struct btf_new_opts { + size_t sz; + struct btf *base_btf; /* optional base BTF */ + bool add_kind_layout; /* add BTF kind layout information */ + bool add_crc; /* add CRC information */ + size_t:0; +}; +#define btf_new_opts__last_field add_crc + +LIBBPF_API struct btf *btf__new_empty_opts(struct btf_new_opts *opts); + LIBBPF_API struct btf *btf__parse(const char *path, struct btf_ext **btf_ext); LIBBPF_API struct btf *btf__parse_split(const char *path, struct btf *base_btf); LIBBPF_API struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext); diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index b52dc28dc8af..b8c0716133d1 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -401,6 +401,7 @@ LIBBPF_1.3.0 { bpf_program__attach_netkit; bpf_program__attach_tcx; bpf_program__attach_uprobe_multi; + btf__new_empty_opts; ring__avail_data_size; ring__consume; ring__consumer_pos; From patchwork Fri Nov 10 11:02:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452332 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 7B0C614263 for ; Fri, 10 Nov 2023 11:04:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="u9U/Ncs8" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A1B7A2B791 for ; Fri, 10 Nov 2023 03:04:13 -0800 (PST) Received: from pps.filterd (m0333521.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MZQrh020971; Fri, 10 Nov 2023 11:03:56 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=GJncHJVEfg2zoQGJgGRg2BKgH8NhSIfNP6vd2LCYZ3s=; b=u9U/Ncs8MFTWTgxxxB7k0e8GRP3vfNbkvNi7twcnTaq6kr8wd7HJbbjBffzm4hcB5Dyg qniCuAeYjAg/3o7NPyXnApjqcBcOJk0m6/iQAK6vRk35/9uSpeK/vuYcwokQNKLfV92u NECQC2VnWhPsXtEIAeVb2fIsI4pM0bvXbOlzCRzcTH2rEvHbg7eRAnkanc7XWIZjGAn1 qPyT7KZa39Kb0kREb9dNRqhsHY2J1DgxHJo5JmbPeXOyIOxKJNNC2m/MmESff1GiEd03 1q685QbQmuej0sRG7A0o7TJX1huokaaN8LTbe2VFWR3QKrAdi7qQaShCI6kUGg/9eypl mg== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w23p0xc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:56 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AA9da8M017639; Fri, 10 Nov 2023 11:03:54 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qgcm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:54 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfo018454; Fri, 10 Nov 2023 11:03:54 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-6; Fri, 10 Nov 2023 11:03:54 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 05/17] libbpf: BTF validation can use kind layout for unknown kinds Date: Fri, 10 Nov 2023 11:02:52 +0000 Message-Id: <20231110110304.63910-6-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: Vyj0VlqZ504FudPmC-QrIwSsOss6CQ_x X-Proofpoint-ORIG-GUID: Vyj0VlqZ504FudPmC-QrIwSsOss6CQ_x X-Patchwork-Delegate: bpf@iogearbox.net BTF parsing can use kind layout to navigate unknown kinds, so btf_validate_type() should take kind layout information into account to avoid failure when an unrecognized kind is met. Signed-off-by: Alan Maguire --- tools/lib/bpf/btf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index ed728d0511a4..b2b78ba5e6bf 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -699,8 +699,12 @@ static int btf_validate_type(const struct btf *btf, const struct btf_type *t, __ break; } default: - pr_warn("btf: type [%u]: unrecognized kind %u\n", id, kind); - return -EINVAL; + /* Kind may be represented in kind layout information. */ + if (btf_type_size_unknown(btf, t) < 0) { + pr_warn("btf: type [%u]: unrecognized kind %u\n", id, kind); + return -EINVAL; + } + break; } return 0; } From patchwork Fri Nov 10 11:02:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452335 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 ABA65134DA for ; Fri, 10 Nov 2023 11:04:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="24mgmTC5" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 432BB2B791 for ; Fri, 10 Nov 2023 03:04:24 -0800 (PST) Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MYBOC020650; Fri, 10 Nov 2023 11:03:59 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=IC5vZ3nNt6ftqLW3Fw8sHNHfYyXI0a+pGQl3hUTcQKg=; b=24mgmTC5Ba+5pD18bb92OAcLNrLWbl0YTPQ1I7EzMBuvyRbo6oCuF8Z8QAJ8AUlGYnP8 G7CDAkW/y9W88Mi4W42jy8UHmQyu/9uHaM7uFZsVd+vbVjhGHUm2rVztdgp4qeU0O60/ 8J39IztUMdCt90Umba3vCXD5u58DPo3CUjnO+zQFCED7qgXAjD8n+8F4q4gRDO6frfXp k4igQUQlii0JKV6DVjjlI4wrqOBBYCPEz4KqEuhKIID6EXrd377u/CaRW1wc5PGZvI1T g6m7Ojn6dfERhTwbgiU4hLkdkveAFD5+6QSLmvKNPB1YYrtOJGjd/MFthxIN99wUudGe uQ== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w2264kq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:59 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAAC3hb018329; Fri, 10 Nov 2023 11:03:58 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qget-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:03:58 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfq018454; Fri, 10 Nov 2023 11:03:58 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-7; Fri, 10 Nov 2023 11:03:57 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 06/17] btf: support kernel parsing of BTF with kind layout Date: Fri, 10 Nov 2023 11:02:53 +0000 Message-Id: <20231110110304.63910-7-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: lR0N-XzDTjMNTMoLRAhyd2yAV7TOeEu0 X-Proofpoint-ORIG-GUID: lR0N-XzDTjMNTMoLRAhyd2yAV7TOeEu0 X-Patchwork-Delegate: bpf@iogearbox.net Validate kind layout if present, but because the kernel must be strict in what it accepts, reject BTF with unsupported kinds, even if they are in the kind layout information. Signed-off-by: Alan Maguire --- kernel/bpf/btf.c | 98 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 21 deletions(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 15d71d2986d3..7cc372462124 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -258,6 +258,7 @@ struct btf { struct btf_kfunc_set_tab *kfunc_set_tab; struct btf_id_dtor_kfunc_tab *dtor_kfunc_tab; struct btf_struct_metas *struct_meta_tab; + struct btf_kind_layout *kind_layout; /* split BTF support */ struct btf *base_btf; @@ -4972,23 +4973,36 @@ static s32 btf_check_meta(struct btf_verifier_env *env, return -EINVAL; } - if (BTF_INFO_KIND(t->info) > BTF_KIND_MAX || - BTF_INFO_KIND(t->info) == BTF_KIND_UNKN) { + if (!btf_name_offset_valid(env->btf, t->name_off)) { + btf_verifier_log(env, "[%u] Invalid name_offset:%u", + env->log_type_id, t->name_off); + return -EINVAL; + } + + if (BTF_INFO_KIND(t->info) == BTF_KIND_UNKN) { btf_verifier_log(env, "[%u] Invalid kind:%u", env->log_type_id, BTF_INFO_KIND(t->info)); return -EINVAL; } - if (!btf_name_offset_valid(env->btf, t->name_off)) { - btf_verifier_log(env, "[%u] Invalid name_offset:%u", - env->log_type_id, t->name_off); + if (BTF_INFO_KIND(t->info) > BTF_KIND_MAX && env->btf->kind_layout && + (BTF_INFO_KIND(t->info) * sizeof(struct btf_kind_layout)) < + env->btf->hdr.kind_layout_len) { + btf_verifier_log(env, "[%u] unknown but required kind %u", + env->log_type_id, + BTF_INFO_KIND(t->info)); return -EINVAL; + } else { + if (BTF_INFO_KIND(t->info) > BTF_KIND_MAX) { + btf_verifier_log(env, "[%u] Invalid kind:%u", + env->log_type_id, BTF_INFO_KIND(t->info)); + return -EINVAL; + } + var_meta_size = btf_type_ops(t)->check_meta(env, t, meta_left); + if (var_meta_size < 0) + return var_meta_size; } - var_meta_size = btf_type_ops(t)->check_meta(env, t, meta_left); - if (var_meta_size < 0) - return var_meta_size; - meta_left -= var_meta_size; return saved_meta_left - meta_left; @@ -5162,7 +5176,8 @@ static int btf_parse_str_sec(struct btf_verifier_env *env) start = btf->nohdr_data + hdr->str_off; end = start + hdr->str_len; - if (end != btf->data + btf->data_size) { + if (hdr->hdr_len < sizeof(struct btf_header) && + end != btf->data + btf->data_size) { btf_verifier_log(env, "String section is not at the end"); return -EINVAL; } @@ -5183,9 +5198,41 @@ static int btf_parse_str_sec(struct btf_verifier_env *env) return 0; } +static int btf_parse_kind_layout_sec(struct btf_verifier_env *env) +{ + const struct btf_header *hdr = &env->btf->hdr; + struct btf *btf = env->btf; + void *start, *end; + + if (hdr->hdr_len < sizeof(struct btf_header) || + hdr->kind_layout_len == 0) + return 0; + + /* Kind layout section must align to 4 bytes */ + if (hdr->kind_layout_off & (sizeof(u32) - 1)) { + btf_verifier_log(env, "Unaligned kind_layout_off"); + return -EINVAL; + } + start = btf->nohdr_data + hdr->kind_layout_off; + end = start + hdr->kind_layout_len; + + if (hdr->kind_layout_len < sizeof(struct btf_kind_layout)) { + btf_verifier_log(env, "Kind layout section is too small"); + return -EINVAL; + } + if (end != btf->data + btf->data_size) { + btf_verifier_log(env, "Kind layout section is not at the end"); + return -EINVAL; + } + btf->kind_layout = start; + + return 0; +} + static const size_t btf_sec_info_offset[] = { offsetof(struct btf_header, type_off), offsetof(struct btf_header, str_off), + offsetof(struct btf_header, kind_layout_off), }; static int btf_sec_info_cmp(const void *a, const void *b) @@ -5200,44 +5247,49 @@ static int btf_check_sec_info(struct btf_verifier_env *env, u32 btf_data_size) { struct btf_sec_info secs[ARRAY_SIZE(btf_sec_info_offset)]; - u32 total, expected_total, i; + u32 nr_secs = ARRAY_SIZE(btf_sec_info_offset); + u32 total, expected_total, gap, i; const struct btf_header *hdr; const struct btf *btf; btf = env->btf; hdr = &btf->hdr; + if (hdr->hdr_len < sizeof(struct btf_header)) + nr_secs--; + /* Populate the secs from hdr */ - for (i = 0; i < ARRAY_SIZE(btf_sec_info_offset); i++) + for (i = 0; i < nr_secs; i++) secs[i] = *(struct btf_sec_info *)((void *)hdr + btf_sec_info_offset[i]); - sort(secs, ARRAY_SIZE(btf_sec_info_offset), + sort(secs, nr_secs, sizeof(struct btf_sec_info), btf_sec_info_cmp, NULL); /* Check for gaps and overlap among sections */ total = 0; expected_total = btf_data_size - hdr->hdr_len; - for (i = 0; i < ARRAY_SIZE(btf_sec_info_offset); i++) { + for (i = 0; i < nr_secs; i++) { if (expected_total < secs[i].off) { btf_verifier_log(env, "Invalid section offset"); return -EINVAL; } - if (total < secs[i].off) { - /* gap */ - btf_verifier_log(env, "Unsupported section found"); - return -EINVAL; - } if (total > secs[i].off) { btf_verifier_log(env, "Section overlap found"); return -EINVAL; } + gap = secs[i].off - total; + if (gap >= 4) { + /* gap larger than alignment gap */ + btf_verifier_log(env, "Unsupported section found"); + return -EINVAL; + } if (expected_total - total < secs[i].len) { btf_verifier_log(env, "Total section length too long"); return -EINVAL; } - total += secs[i].len; + total += secs[i].len + gap; } /* There is data other than hdr and known sections */ @@ -5300,7 +5352,7 @@ static int btf_parse_hdr(struct btf_verifier_env *env) return -ENOTSUPP; } - if (hdr->flags) { + if (hdr->flags & ~(BTF_FLAG_CRC_SET | BTF_FLAG_BASE_CRC_SET)) { btf_verifier_log(env, "Unsupported flags"); return -ENOTSUPP; } @@ -5537,6 +5589,10 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat if (err) goto errout; + err = btf_parse_kind_layout_sec(env); + if (err) + goto errout; + err = btf_parse_type_sec(env); if (err) goto errout; From patchwork Fri Nov 10 11:02:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452333 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 08375134DA for ; Fri, 10 Nov 2023 11:04:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="OVavqhVM" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28A052B78E for ; Fri, 10 Nov 2023 03:04:20 -0800 (PST) Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MYBOD020650; Fri, 10 Nov 2023 11:04:03 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=+Y1hdcI5CntZO/WUgo2owHVyNhoSnQ3SeGkaszAGb1s=; b=OVavqhVMJrWJMoNJa98HShgxJT4IAUIDAoXa454wydf1vkOTnx0P0jbgxWgGV5yKhOFb 1lBIpU/QJtX/S4ualf0TyfY16QzlRHFUgyETJN7WaIyGME3qDwoCFg+DSgcpWHa+Wj+z rhH4GGd2yeO2onMRcxh3/fodI8O2YgFce4cXv+n59kGBkaKdCy4pZCqd8XJIG70eTzMK 7UZmcXuqtdULRS5MvZ5VoGpsQczKVR5RpJKNDty5d08bify6uRxtSgcy32gwo6lffciM vlj0AGiMEJJW97nFz3n9AQwjylr0/oUnrGRJ2pEkHvVty8RpH3XogE9316mFvaZH/EOF yA== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w2264kw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:03 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AA9hSpY017608; Fri, 10 Nov 2023 11:04:02 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qgh2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:02 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfs018454; Fri, 10 Nov 2023 11:04:02 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-8; Fri, 10 Nov 2023 11:04:02 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire , Alexei Starovoitov Subject: [PATCH v3 bpf-next 07/17] bpf: add BTF CRC verification where present Date: Fri, 10 Nov 2023 11:02:54 +0000 Message-Id: <20231110110304.63910-8-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: jMIMQiTFw8crD76lU5MBaSnJJt9js5hf X-Proofpoint-ORIG-GUID: jMIMQiTFw8crD76lU5MBaSnJJt9js5hf X-Patchwork-Delegate: bpf@iogearbox.net If a CRC is set in provided BTF, verify it. Suggested-by: Alexei Starovoitov Signed-off-by: Alan Maguire --- kernel/bpf/btf.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 7cc372462124..4eb13634580b 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -5357,6 +5358,20 @@ static int btf_parse_hdr(struct btf_verifier_env *env) return -ENOTSUPP; } + if (hdr->flags & BTF_FLAG_CRC_SET) { + __u32 check, crc = hdr->crc; + struct btf_header *h = btf->data; + + h->crc = 0; + check = crc32(0xffffffff, btf->data, btf_data_size); + check ^= ~0; + h->crc = crc; + if (check != crc) { + btf_verifier_log(env, "Invalid CRC; expected 0x%x ; actual 0x%x", + crc, check); + return -EINVAL; + } + } if (!btf->base_btf && btf_data_size == hdr->hdr_len) { btf_verifier_log(env, "No data"); return -EINVAL; From patchwork Fri Nov 10 11:02:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452334 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 0BA771427E for ; Fri, 10 Nov 2023 11:04:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="b2K+bgq3" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 151982B78E for ; Fri, 10 Nov 2023 03:04:23 -0800 (PST) Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MY59K020629; Fri, 10 Nov 2023 11:04:07 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=uUi5A1cYY335vpW2po9LFcqtECoTTqcgTnrD1OFJaeQ=; b=b2K+bgq33l3ZKVAmJZ/kWk94fLBwg6kRpIgWGgqdgfpXSXPvQAitR3qr9u2JUs7O7eXD KFr+5WH9Mec/Yplg9OAkoN3j9YngM+kYmKUySw/qCVjFQFFRx0X34C1AXFEziecv5rTK iIRt59v0L4FpEfhm99v96ErawQSGog3hasFjqD0lePTL8jJwyzE4O2CHMbLdUghbA35I MfU5iD5lDTY66O7UURaGnRsLyzEvluT0fkC9I2jxivLphHyRwrargIOwwwzbAKporDti ppVtwzT0fOU0b43uJyw+WR6nPm69s9h4I44L0lc0sLUh65vMNNlOwpkhHWCqVZvhY2cA Xw== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w2264m1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:06 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AA9pqQn017618; Fri, 10 Nov 2023 11:04:06 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qgk3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:06 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfu018454; Fri, 10 Nov 2023 11:04:05 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-9; Fri, 10 Nov 2023 11:04:05 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 08/17] bpf: verify base BTF CRC to ensure it matches module BTF Date: Fri, 10 Nov 2023 11:02:55 +0000 Message-Id: <20231110110304.63910-9-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: ke31aeWTx6_BcaoxfWBCVs74yTl47NiI X-Proofpoint-ORIG-GUID: ke31aeWTx6_BcaoxfWBCVs74yTl47NiI X-Patchwork-Delegate: bpf@iogearbox.net Having a base CRC in module BTF allows us to reject base BTF that does not match that CRC; this allows us to recognize incompatible BTF up-front, not having to rely on invalidation due to internal mismatches in module/kernel BTF ids. Signed-off-by: Alan Maguire --- kernel/bpf/btf.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 4eb13634580b..65a85bad13f7 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -5372,6 +5372,24 @@ static int btf_parse_hdr(struct btf_verifier_env *env) return -EINVAL; } } + if (hdr->flags & BTF_FLAG_BASE_CRC_SET) { + struct btf_header *base_hdr = &btf->base_btf->hdr; + + if (!btf->base_btf) { + btf_verifier_log(env, "Specified base BTF CRC but no base BTF"); + return -EINVAL; + } + + if (!(base_hdr->flags & BTF_FLAG_CRC_SET)) { + btf_verifier_log(env, "Specified base BTF CRC but base BTF has no CRC"); + return -EINVAL; + } + if (hdr->base_crc != base_hdr->crc) { + btf_verifier_log(env, "Specified base CRC 0x%x; differs from actual base CRC 0x%x\n", + hdr->base_crc, base_hdr->crc); + return -EINVAL; + } + } if (!btf->base_btf && btf_data_size == hdr->hdr_len) { btf_verifier_log(env, "No data"); return -EINVAL; From patchwork Fri Nov 10 11:02:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452336 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 738D412B8B for ; Fri, 10 Nov 2023 11:04:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="woS+y7OV" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A4AE82B78E for ; Fri, 10 Nov 2023 03:04:28 -0800 (PST) Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MaPCD027485; Fri, 10 Nov 2023 11:04:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=FJ+y8EJTGoUDCQeOIu7lqIhWqMFUASuERWwk11K6+PM=; b=woS+y7OVG8ZS93cP77nQ7Honi1w+Cd+MKVb55sKv1HLqf5eH32OVseW1Kff1GNNzf/bn s7IUH0sk3fC2rejq7eedDa/4A7vA3wV8pKXqFhECXGhy+Y98PMO6L8hSh8zRmBbw4r8V +Pd3EMB0/W7fWlghxMcqvT5/+bqOpStRM+m7eMp9wrd22QfeWcbTiiW/uJFGQxWCXA1y PGO2PFLkhgN/OIDTnHLVhSKucGtosEe/ag/IENihQnYnlxVpQxAb4KPnFJPly1OcfThM DTFeV7QSOO884OoSCqY3fjJe96ulRoypXSzlwdxJPWaXrKLu3kprHxCMzl7qPAsUd7Dq YA== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w23p1ya-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:11 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAA48K5018297; Fri, 10 Nov 2023 11:04:09 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qgnd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:09 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wfw018454; Fri, 10 Nov 2023 11:04:09 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-10; Fri, 10 Nov 2023 11:04:09 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 09/17] bpf: switch to --btf_features, add crc,kind_layout features Date: Fri, 10 Nov 2023 11:02:56 +0000 Message-Id: <20231110110304.63910-10-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-ORIG-GUID: NSxNp0JIHpgDN9NlhTl2Zdf4p4yPnumE X-Proofpoint-GUID: NSxNp0JIHpgDN9NlhTl2Zdf4p4yPnumE X-Patchwork-Delegate: bpf@iogearbox.net For pahole v1.26 and later, --btf_features is used to specify BTF features for encoding. Since it tolerates unknown features, no further version checking will be needed when adding new features. Add crc, kind_layout features. Signed-off-by: Alan Maguire --- scripts/pahole-flags.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh index 728d55190d97..30a3e270308b 100755 --- a/scripts/pahole-flags.sh +++ b/scripts/pahole-flags.sh @@ -26,5 +26,8 @@ fi if [ "${pahole_ver}" -ge "125" ]; then extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_inconsistent_proto --btf_gen_optimized" fi +if [ "${pahole_ver}" -ge "126" ]; then + extra_paholeopt="-j --lang_exclude=rust --btf_features=encode_force,var,float,decl_tag,type_tag,enum64,optimized_func,consistent_func,crc,kind_layout" +fi echo ${extra_paholeopt} From patchwork Fri Nov 10 11:02:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452337 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 836FE12B8B for ; Fri, 10 Nov 2023 11:04:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="xZQ8EYhW" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 190012B78B for ; Fri, 10 Nov 2023 03:04:31 -0800 (PST) Received: from pps.filterd (m0333520.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MY95E011383; Fri, 10 Nov 2023 11:04:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=+7SYwTlS0f6ebaZX+IjeUrhJyi11t5OYODVExiUdP3E=; b=xZQ8EYhW/OpnUrWJR++wibNJm7mM25LvfQbCe6DgkUP8bI8hLMCIDFGr4h0c9aucg/Cq HetAetKcv+XMopQjVrhDuS2jb2MqjDyNhlQsbmWH1BW0IDJuakdUhVJz6OKECMDz1nmJ 80nCKiUAqv2Fh82MgzYpCzQagXsznaALZxXsKF9032WRBLfjbZtFsDtyiU6OwjFApWGx vyy5PdEqOIukn6uF+W5zaWP+otGPPrkZ9MOuzhFg9jGdxMXQuy55PUTiFb31rW2KweGs TT8X1M6lBZoHj1nrHoOX1/sDkCZemJ1V6bTmq2DM1GkEX/QQH8DD7PMIfxP+sCaV3s8c MQ== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w206554-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:14 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AA9da8d017639; Fri, 10 Nov 2023 11:04:13 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qgr5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:13 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wg0018454; Fri, 10 Nov 2023 11:04:13 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-11; Fri, 10 Nov 2023 11:04:12 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 10/17] bpftool: add BTF dump "format meta" to dump header/metadata Date: Fri, 10 Nov 2023 11:02:57 +0000 Message-Id: <20231110110304.63910-11-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-ORIG-GUID: j53GhnZrWj5N6fM_LpF-yWnJT_zaXAix X-Proofpoint-GUID: j53GhnZrWj5N6fM_LpF-yWnJT_zaXAix X-Patchwork-Delegate: bpf@iogearbox.net Provide a way to dump BTF metadata info via bpftool; this consists of BTF size, header fields and kind layout info (if available); for example $ bpftool btf dump file vmlinux format meta size 5161076 magic 0xeb9f version 1 flags 0x1 hdr_len 40 type_len 3036368 type_off 0 str_len 2124588 str_off 3036368 kind_layout_len 80 kind_layout_off 5160956 crc 0x64af901b base_crc 0x0 kind 0 UNKNOWN flags 0x0 info_sz 0 elem_sz 0 kind 1 INT flags 0x0 info_sz 0 elem_sz 0 kind 2 PTR flags 0x0 info_sz 0 elem_sz 0 kind 3 ARRAY flags 0x0 info_sz 0 elem_sz 0 kind 4 STRUCT flags 0x35 info_sz 0 elem_sz 0 ... JSON output is also supported: $ bpftool -j btf dump file vmlinux format meta {"size":5161076,"header":{"magic":60319,"version":1,"flags":1,"hdr_len":40,"type_len":3036368,"type_off":0,"str_len":2124588,"str_off":3036368,"kind_layout_len":80,"kind_layout_offset":5160956,"crc":1689227291,"base_crc":0},"kind_layouts":[{"kind":0,"name":"UNKNOWN","flags":0,"info_sz":0,"elem_sz":0},{"kind":1,"name":"INT","flags":0,"info_sz":0,"elem_sz":0},{"kind":2,"name":"PTR","flags":0,"info_sz":0,"elem_sz":0},{"kind":3,"name":"ARRAY","flags":0,"info_sz":0,"elem_sz":0},{"kind":4,"name":"STRUCT","flags":53,"info_sz":0,"elem_sz":0},{"kind":5,"name":"UNION","flags":0,"info_sz":0,"elem_sz":0},{"kind":6,"name":"ENUM","flags":60319,"info_sz":1,"elem_sz":1},{"kind":7,"name":"FWD","flags":40,"info_sz":0,"elem_sz":0},{"kind":8,"name":"TYPEDEF","flags":0,"info_sz":0,"elem_sz":0},{"kind":9,"name":"VOLATILE","flags":0,"info_sz":0,"elem_sz":0},{"kind":10,"name":"CONST","flags":0,"info_sz":0,"elem_sz":0},{"kind":11,"name":"RESTRICT","flags":1,"info_sz":0,"elem_sz":0},{"kind":12,"name":"FUNC","flags":0,"info_sz":0,"elem_sz":0},{"kind":13,"name":"FUNC_PROTO","flags":80,"info_sz":0,"elem_sz":0},{"kind":14,"name":"VAR","flags":0,"info_sz":0,"elem_sz":0},{"kind":15,"name":"DATASEC","flags":0,"info_sz":0,"elem_sz":0},{"kind":16,"name":"FLOAT","flags":53,"info_sz":0,"elem_sz":0},{"kind":17,"name":"DECL_TAG","flags":0,"info_sz":0,"elem_sz":0},{"kind":18,"name":"TYPE_TAG","flags":11441,"info_sz":3,"elem_sz":0},{"kind":19,"name":"ENUM64","flags":0,"info_sz":0,"elem_sz":0}]} Signed-off-by: Alan Maguire --- tools/bpf/bpftool/bash-completion/bpftool | 2 +- tools/bpf/bpftool/btf.c | 91 ++++++++++++++++++++++- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index 6e4f7ce6bc01..157c3afd8247 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -937,7 +937,7 @@ _bpftool() return 0 ;; format) - COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "c raw meta" -- "$cur" ) ) ;; *) # emit extra options diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c index 91fcb75babe3..208f3a587534 100644 --- a/tools/bpf/bpftool/btf.c +++ b/tools/bpf/bpftool/btf.c @@ -504,6 +504,88 @@ static int dump_btf_c(const struct btf *btf, return err; } +static int dump_btf_meta(const struct btf *btf) +{ + const struct btf_header *hdr; + const struct btf_kind_layout *k; + __u8 i, nr_kinds = 0; + const void *data; + __u32 data_sz; + + data = btf__raw_data(btf, &data_sz); + if (!data) + return -ENOMEM; + hdr = data; + if (json_output) { + jsonw_start_object(json_wtr); /* btf metadata object */ + jsonw_uint_field(json_wtr, "size", data_sz); + jsonw_name(json_wtr, "header"); + jsonw_start_object(json_wtr); /* btf header object */ + jsonw_uint_field(json_wtr, "magic", hdr->magic); + jsonw_uint_field(json_wtr, "version", hdr->version); + jsonw_uint_field(json_wtr, "flags", hdr->flags); + jsonw_uint_field(json_wtr, "hdr_len", hdr->hdr_len); + jsonw_uint_field(json_wtr, "type_len", hdr->type_len); + jsonw_uint_field(json_wtr, "type_off", hdr->type_off); + jsonw_uint_field(json_wtr, "str_len", hdr->str_len); + jsonw_uint_field(json_wtr, "str_off", hdr->str_off); + } else { + printf("size %-10d\n", data_sz); + printf("magic 0x%-10x\nversion %-10d\nflags 0x%-10x\nhdr_len %-10d\n", + hdr->magic, hdr->version, hdr->flags, hdr->hdr_len); + printf("type_len %-10d\ntype_off %-10d\n", hdr->type_len, hdr->type_off); + printf("str_len %-10d\nstr_off %-10d\n", hdr->str_len, hdr->str_off); + } + + if (hdr->hdr_len < sizeof(struct btf_header)) { + if (json_output) { + jsonw_end_object(json_wtr); /* header object */ + jsonw_end_object(json_wtr); /* metadata object */ + } + return 0; + } + if (hdr->kind_layout_len > 0 && hdr->kind_layout_off > 0) { + k = (void *)hdr + hdr->hdr_len + hdr->kind_layout_off; + nr_kinds = hdr->kind_layout_len / sizeof(*k); + } + if (json_output) { + jsonw_uint_field(json_wtr, "kind_layout_len", hdr->kind_layout_len); + jsonw_uint_field(json_wtr, "kind_layout_offset", hdr->kind_layout_off); + jsonw_uint_field(json_wtr, "crc", hdr->crc); + jsonw_uint_field(json_wtr, "base_crc", hdr->base_crc); + jsonw_end_object(json_wtr); /* end header object */ + + if (nr_kinds > 0) { + jsonw_name(json_wtr, "kind_layouts"); + jsonw_start_array(json_wtr); + for (i = 0; i < nr_kinds; i++) { + jsonw_start_object(json_wtr); + jsonw_uint_field(json_wtr, "kind", i); + if (i < NR_BTF_KINDS) + jsonw_string_field(json_wtr, "name", btf_kind_str[i]); + jsonw_uint_field(json_wtr, "flags", k[i].flags); + jsonw_uint_field(json_wtr, "info_sz", k[i].info_sz); + jsonw_uint_field(json_wtr, "elem_sz", k[i].elem_sz); + jsonw_end_object(json_wtr); + } + jsonw_end_array(json_wtr); + } + jsonw_end_object(json_wtr); /* end metadata */ + } else { + printf("kind_layout_len %-10d\nkind_layout_off %-10d\n", + hdr->kind_layout_len, hdr->kind_layout_off); + printf("crc 0x%-10x\nbase_crc 0x%-10x\n", + hdr->crc, hdr->base_crc); + for (i = 0; i < nr_kinds; i++) { + printf("kind %-4d %-10s flags 0x%-4x info_sz %-4d elem_sz %-4d\n", + i, i < NR_BTF_KINDS ? btf_kind_str[i] : "?", + k[i].flags, k[i].info_sz, k[i].elem_sz); + } + } + + return 0; +} + static const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux"; static struct btf *get_vmlinux_btf_from_sysfs(void) @@ -553,6 +635,7 @@ static int do_dump(int argc, char **argv) __u32 root_type_ids[2]; int root_type_cnt = 0; bool dump_c = false; + bool dump_meta = false; __u32 btf_id = -1; const char *src; int fd = -1; @@ -654,10 +737,12 @@ static int do_dump(int argc, char **argv) } if (strcmp(*argv, "c") == 0) { dump_c = true; + } else if (is_prefix(*argv, "meta")) { + dump_meta = true; } else if (strcmp(*argv, "raw") == 0) { dump_c = false; } else { - p_err("unrecognized format specifier: '%s', possible values: raw, c", + p_err("unrecognized format specifier: '%s', possible values: raw, c, meta", *argv); err = -EINVAL; goto done; @@ -692,6 +777,8 @@ static int do_dump(int argc, char **argv) goto done; } err = dump_btf_c(btf, root_type_ids, root_type_cnt); + } else if (dump_meta) { + err = dump_btf_meta(btf); } else { err = dump_btf_raw(btf, root_type_ids, root_type_cnt); } @@ -1063,7 +1150,7 @@ static int do_help(int argc, char **argv) " %1$s %2$s help\n" "\n" " BTF_SRC := { id BTF_ID | prog PROG | map MAP [{key | value | kv | all}] | file FILE }\n" - " FORMAT := { raw | c }\n" + " FORMAT := { raw | c | meta }\n" " " HELP_SPEC_MAP "\n" " " HELP_SPEC_PROGRAM "\n" " " HELP_SPEC_OPTIONS " |\n" From patchwork Fri Nov 10 11:02:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452338 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 9EDCE14282 for ; Fri, 10 Nov 2023 11:04:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="mq0GVMRp" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8AF682B78D for ; Fri, 10 Nov 2023 03:04:35 -0800 (PST) Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MY1b8022401; Fri, 10 Nov 2023 11:04:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=duGHp55YrRgxpthIBFv+XMYAuTI83o5ozohkSNbz4Gg=; b=mq0GVMRpU4k9z+UCAeJz48pxIzk2LXZoE6VjH9dfRFtnc8FHnTdbHpMUEzZ08olZFB3W mmV4MKKZS34gGwbxS123IAy6A+VJvbmtC0Lib8dRjayuNCXGtX0cFUft5VHCnYUcrS5i mgQkHYHIjLRQU3orAolCs5tr7SbGCjnrTm/T1TaTXHBWpT5cgBK5MRYzfrwqc6niaBgy ANvl0tli9ufwoEu86ZGe7Szr02Mxwn2I5Zio3EfKlngGEcnLXZqP17Ve6kRy/Ew3i9TO etV+hSzgify1aKgwoUrk41NqAbDbNPMK254DEBq2LB6SFyGV1wxAtqr2uhBN3f0jfH+F UA== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w2164qj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:17 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAAD35D017599; Fri, 10 Nov 2023 11:04:17 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qgtg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:17 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wg2018454; Fri, 10 Nov 2023 11:04:16 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-12; Fri, 10 Nov 2023 11:04:16 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 11/17] bpftool: update doc to describe bpftool btf dump .. format meta Date: Fri, 10 Nov 2023 11:02:58 +0000 Message-Id: <20231110110304.63910-12-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: vPye75sHbEorx96WHz7XwPzzaCDSNsbn X-Proofpoint-ORIG-GUID: vPye75sHbEorx96WHz7XwPzzaCDSNsbn X-Patchwork-Delegate: bpf@iogearbox.net ...and provide an example of output. Signed-off-by: Alan Maguire --- .../bpf/bpftool/Documentation/bpftool-btf.rst | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-btf.rst b/tools/bpf/bpftool/Documentation/bpftool-btf.rst index 342716f74ec4..ea8bb0a2041c 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-btf.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-btf.rst @@ -28,7 +28,7 @@ BTF COMMANDS | **bpftool** **btf help** | | *BTF_SRC* := { **id** *BTF_ID* | **prog** *PROG* | **map** *MAP* [{**key** | **value** | **kv** | **all**}] | **file** *FILE* } -| *FORMAT* := { **raw** | **c** } +| *FORMAT* := { **raw** | **c** | **meta** } | *MAP* := { **id** *MAP_ID* | **pinned** *FILE* } | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } @@ -67,8 +67,8 @@ DESCRIPTION typically produced by clang or pahole. **format** option can be used to override default (raw) - output format. Raw (**raw**) or C-syntax (**c**) output - formats are supported. + output format. Raw (**raw**), C-syntax (**c**) and + BTF metadata (**meta**) formats are supported. **bpftool btf help** Print short help message. @@ -266,3 +266,27 @@ All the standard ways to specify map or program are supported: [104859] FUNC 'smbalert_work' type_id=9695 linkage=static [104860] FUNC 'smbus_alert' type_id=71367 linkage=static [104861] FUNC 'smbus_do_alert' type_id=84827 linkage=static + + +**# bpftool btf dump file vmlinux format meta** + +:: + + size 5161076 + magic 0xeb9f + version 1 + flags 0x1 + hdr_len 40 + type_len 3036368 + type_off 0 + str_len 2124588 + str_off 3036368 + kind_layout_len 80 + kind_layout_off 5160956 + crc 0x64af901b + base_crc 0x0 + kind 0 UNKNOWN flags 0x0 info_sz 0 elem_sz 0 + kind 1 INT flags 0x0 info_sz 0 elem_sz 0 + kind 2 PTR flags 0x0 info_sz 0 elem_sz 0 + kind 3 ARRAY flags 0x0 info_sz 0 elem_sz 0 + kind 4 STRUCT flags 0x35 info_sz 0 elem_sz 0 From patchwork Fri Nov 10 11:02:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452339 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 E933512B8B for ; Fri, 10 Nov 2023 11:04:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="sJPx97cB" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 809FE2B78D for ; Fri, 10 Nov 2023 03:04:38 -0800 (PST) Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MY4fK020619; Fri, 10 Nov 2023 11:04:22 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=fm9Ws4zLgh7C54OpEB/Ty/BMzjb6hdjWEW0bUYKIfDw=; b=sJPx97cBd6Qb8QrvOJM/n7i2ik7MUaIATlYf3F97McAGXS1fTIxFEry+D6Qv2Xpzg2QO wtUEcWo7Y2zIZhi6upUHuCQqlxFhkRBtJsdSdlp2PhglZpQz6ujZ9d6L1zCc150blwzD m31S4j+styyQiNbw8ztBbkC6jRvgIjhqnipM2Hi5Bitk1HMCj1ZDBbO0vw1ypR4G/GO6 Ge+fcQLQUcHHRMv/NGGQulqo1vXKhDYUaWZygnWuAh0ls/qryIDn1HqsgOeuCXj3APG0 0Vx5+rtfNQEbjmYME8zjK1i6lDRbNuAz7hUBkfbQbRAly0x8QJtP8rNzAgyM4PxogXlX nw== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w2264mu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:22 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAA1VpA017614; Fri, 10 Nov 2023 11:04:21 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qgvv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:21 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wg4018454; Fri, 10 Nov 2023 11:04:20 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-13; Fri, 10 Nov 2023 11:04:20 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 12/17] selftests/bpf: test kind encoding/decoding Date: Fri, 10 Nov 2023 11:02:59 +0000 Message-Id: <20231110110304.63910-13-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: 8WTUFvtU5vlT_MisNp1VT07a7GPqhwp- X-Proofpoint-ORIG-GUID: 8WTUFvtU5vlT_MisNp1VT07a7GPqhwp- X-Patchwork-Delegate: bpf@iogearbox.net verify btf__new_empty_opts() adds kind layouts for all kinds supported, and after adding kind-related types for an unknown kind, ensure that parsing uses this info when that kind is encountered rather than giving up. Signed-off-by: Alan Maguire --- .../selftests/bpf/prog_tests/btf_kind.c | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/btf_kind.c diff --git a/tools/testing/selftests/bpf/prog_tests/btf_kind.c b/tools/testing/selftests/bpf/prog_tests/btf_kind.c new file mode 100644 index 000000000000..41a052787ba6 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/btf_kind.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2023, Oracle and/or its affiliates. */ + +#include +#include +#include + +/* verify kind encoding exists for each kind */ +static void test_btf_kind_encoding(void) +{ + LIBBPF_OPTS(btf_new_opts, opts); + const struct btf_header *hdr; + const void *raw_btf; + struct btf *btf; + __u32 raw_size; + + opts.add_kind_layout = true; + btf = btf__new_empty_opts(&opts); + if (!ASSERT_OK_PTR(btf, "btf_new")) + return; + + raw_btf = btf__raw_data(btf, &raw_size); + if (!ASSERT_OK_PTR(raw_btf, "btf__raw_data")) + return; + + hdr = raw_btf; + + ASSERT_EQ(hdr->kind_layout_off % 4, 0, "kind_layout aligned"); + ASSERT_EQ(hdr->kind_layout_len, sizeof(struct btf_kind_layout) * NR_BTF_KINDS, + "kind_layout_len"); + btf__free(btf); +} + +static void write_raw_btf(const char *btf_path, void *raw_btf, size_t raw_size) +{ + int fd = open(btf_path, O_WRONLY | O_CREAT); + + write(fd, raw_btf, raw_size); + close(fd); +} + +/* fabricate an unrecognized kind at BTF_KIND_MAX + 1, and after adding + * the appropriate struct/typedefs to the BTF such that it recognizes + * this kind, ensure that parsing of BTF containing the unrecognized kind + * can succeed. + */ +void test_btf_kind_decoding(void) +{ + __s32 int_id, unrec_id, id, id2; + LIBBPF_OPTS(btf_new_opts, opts); + struct btf *btf, *new_btf; + struct btf_kind_layout *k; + struct btf_header *hdr; + const void *raw_btf; + struct btf_type *t; + char btf_path[64]; + void *new_raw_btf; + __u32 raw_size; + + opts.add_kind_layout = true; + btf = btf__new_empty_opts(&opts); + if (!ASSERT_OK_PTR(btf, "btf_new")) + return; + + int_id = btf__add_int(btf, "test_char", 1, BTF_INT_CHAR); + if (!ASSERT_GT(int_id, 0, "add_int_id")) + return; + + /* now create our type with unrecognized kind by adding a typedef kind + * we will overwrite it with our unrecognized kind value. + */ + unrec_id = btf__add_typedef(btf, "unrec_kind", int_id); + if (!ASSERT_GT(unrec_id, 0, "add_unrec_id")) + return; + + /* add an id after it that we will look up to verify we can parse + * beyond unrecognized kinds. + */ + id = btf__add_typedef(btf, "test_lookup", int_id); + if (!ASSERT_GT(id, 0, "add_test_lookup_id")) + return; + id2 = btf__add_typedef(btf, "test_lookup2", int_id); + if (!ASSERT_GT(id2, 0, "add_test_lookup_id2")) + return; + + raw_btf = (void *)btf__raw_data(btf, &raw_size); + if (!ASSERT_OK_PTR(raw_btf, "btf__raw_data")) + return; + + new_raw_btf = calloc(1, raw_size + sizeof(*k)); + memcpy(new_raw_btf, raw_btf, raw_size); + + /* add new layout description */ + hdr = new_raw_btf; + hdr->kind_layout_len += sizeof(*k); + k = new_raw_btf + hdr->hdr_len + hdr->kind_layout_off; + k[NR_BTF_KINDS].info_sz = 0; + k[NR_BTF_KINDS].elem_sz = 0; + + /* now modify our typedef added above to be an unrecognized kind. */ + t = (void *)hdr + hdr->hdr_len + hdr->type_off + sizeof(struct btf_type) + + sizeof(__u32); + t->info = (NR_BTF_KINDS << 24); + + /* now write our BTF to a raw file, ready for parsing. */ + snprintf(btf_path, sizeof(btf_path), "/tmp/btf_kind.%d", getpid()); + + write_raw_btf(btf_path, new_raw_btf, raw_size + sizeof(*k)); + + /* verify parsing succeeds, and that we can read type info past + * the unrecognized kind. + */ + new_btf = btf__parse_raw(btf_path); + if (ASSERT_OK_PTR(new_btf, "btf__parse_raw")) { + ASSERT_EQ(btf__find_by_name_kind(new_btf, "test_lookup", + BTF_KIND_TYPEDEF), id, + "verify_id_lookup"); + ASSERT_EQ(btf__find_by_name_kind(new_btf, "test_lookup2", + BTF_KIND_TYPEDEF), id2, + "verify_id2_lookup"); + } + btf__free(new_btf); + + /* next, change info_sz to equal sizeof(struct btf_type); this means the + * "test_lookup" kind will be reinterpreted as a singular info element + * following the unrecognized kind. + */ + k[NR_BTF_KINDS].info_sz = sizeof(struct btf_type); + write_raw_btf(btf_path, new_raw_btf, raw_size + sizeof(*k)); + + new_btf = btf__parse_raw(btf_path); + if (ASSERT_OK_PTR(new_btf, "btf__parse_raw")) { + ASSERT_EQ(btf__find_by_name_kind(new_btf, "test_lookup", + BTF_KIND_TYPEDEF), -ENOENT, + "verify_id_not_found"); + /* id of "test_lookup2" will be id2 -1 as we have removed one type */ + ASSERT_EQ(btf__find_by_name_kind(new_btf, "test_lookup2", + BTF_KIND_TYPEDEF), id2 - 1, + "verify_id_lookup2"); + + } + btf__free(new_btf); + + /* next, change elem_sz to equal sizeof(struct btf_type)/2 and set + * vlen associated with unrecognized type to 2; this allows us to verify + * vlen-specified BTF can still be parsed. + */ + k[NR_BTF_KINDS].info_sz = 0; + k[NR_BTF_KINDS].elem_sz = sizeof(struct btf_type)/2; + t->info |= 2; + write_raw_btf(btf_path, new_raw_btf, raw_size + sizeof(*k)); + + new_btf = btf__parse_raw(btf_path); + if (ASSERT_OK_PTR(new_btf, "btf__parse_raw")) { + ASSERT_EQ(btf__find_by_name_kind(new_btf, "test_lookup", + BTF_KIND_TYPEDEF), -ENOENT, + "verify_id_not_found"); + /* id of "test_lookup2" will be id2 -1 as we have removed one type */ + ASSERT_EQ(btf__find_by_name_kind(new_btf, "test_lookup2", + BTF_KIND_TYPEDEF), id2 - 1, + "verify_id_lookup2"); + + } + btf__free(new_btf); + free(new_raw_btf); + unlink(btf_path); + btf__free(btf); +} + +void test_btf_kind(void) +{ + if (test__start_subtest("btf_kind_encoding")) + test_btf_kind_encoding(); + if (test__start_subtest("btf_kind_decoding")) + test_btf_kind_decoding(); +} From patchwork Fri Nov 10 11:03:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452340 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 2A3C312B75 for ; Fri, 10 Nov 2023 11:04:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="iIQgki6i" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCF682B78D for ; Fri, 10 Nov 2023 03:04:42 -0800 (PST) Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MY4oH020605; Fri, 10 Nov 2023 11:04:26 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=c0u1jY+3OBJFinqHr0M2SBh0IgmvzIXxVT7kIg4NbO8=; b=iIQgki6ieP8Xnvjn1B5r5lHxRNmA8iVhOcMoHoMS/1sWQqxZA220Cf94qKTbqAn5zBDv VlgkZjvb8CK7x27ErwA0BXCT509A4Y6hK1SU/ijUQzo4TNEdRcd+O0upJlC4iLrsrvzB c7Ix6tr7gPMDz02UvFjspBNPMIDRrtVi7qAhEJI+kcexNdp+BUnqNgWv1pfETEnrmErE XYcyVNtCxazD/bRtConlcTw/4BE0RIFu5/55d+tURCi0YVcQv/MoJUZl6xFW53Wd60+L r61Zhdt4Oj9tk4QuQzIE62FluleGq/nwfwOoXwGTuI7HOFSUIDRr6gMgvPsysjFmnBDg Lg== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w2264n6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:25 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AA9Uo3t018243; Fri, 10 Nov 2023 11:04:25 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qh0d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:25 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wg6018454; Fri, 10 Nov 2023 11:04:24 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-14; Fri, 10 Nov 2023 11:04:24 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 13/17] bpf: support standalone BTF in modules Date: Fri, 10 Nov 2023 11:03:00 +0000 Message-Id: <20231110110304.63910-14-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: 3lxDqYfsNHJ0NMgmUbIQzLr_LNQVRoTn X-Proofpoint-ORIG-GUID: 3lxDqYfsNHJ0NMgmUbIQzLr_LNQVRoTn X-Patchwork-Delegate: bpf@iogearbox.net Not all kernel modules can be built in-tree when the core kernel is built. This presents a problem for split BTF, because split module BTF refers to type ids in the base kernel BTF, and if that base kernel BTF changes (even in minor ways) those references become invalid. Such modules then cannot take advantage of BTF (or at least they only can until the kernel changes enough to invalidate their vmlinux type id references). This problem has been discussed before, and the initial approach was to allow BTF mismatch but fail to load BTF. See [1] for more discussion. Generating standalone BTF for modules helps solve this problem because the BTF generated is self-referential only. However, tooling is geared towards split BTF - for example bpftool assumes a module's BTF is defined relative to vmlinux BTF. To handle this, dynamic remapping of standalone BTF is done on module load to make it appear like split BTF - type ids and string offsets are remapped such that they appear as they would in split BTF. It just so happens that the BTF is self-referential. With this approach, existing tooling works with standalone module BTF from /sys/kernel/btf in the same way as before; no knowledge of split versus standalone BTF is required. To verify that the module BTF is standalone we verify that either 1. a CRC is present for BTF, but no base CRC is specified; this indicates that BTF was not generated relative to base BTF; or 2. the string offsets all lie within the range <0, string_section_size>; and 3. the BTF ids all lie within range <0, number_of_types_in_module_BTF> Case 1 is a fastpath available when pahole generates CRCs. The tests carried out in 2 and 3 are fallbacks for when newer pahole is not present. If these conditions are true, BTF and string ids are remapped such that they appear to be split BTF. Note that the kfunc and dtor ids need to be remapped also on registration, since they will be out-of-date with respect to the remapped module BTF. Signed-off-by: Alan Maguire [1] https://lore.kernel.org/bpf/YfK18x%2FXrYL4Vw8o@syu-laptop/ --- kernel/bpf/btf.c | 304 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 302 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 65a85bad13f7..e65c9893aafc 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -267,6 +267,7 @@ struct btf { u32 start_str_off; /* first string offset (0 for base BTF) */ char name[MODULE_NAME_LEN]; bool kernel_btf; + bool standalone_btf; }; enum verifier_phase { @@ -5885,6 +5886,253 @@ struct btf *btf_parse_vmlinux(void) #ifdef CONFIG_DEBUG_INFO_BTF_MODULES +/* verify module BTF is self-contained: + * - if CRC is set and base CRC is not: or + * - no string offset should exceed standalone str len; and + * - the max id referenced should be <= the number of btf types in module BTF + * + * Taken together with the fact that the number of module types is much less + * than the number of types in vmliux BTF, these imply self-reference and hence + * standalone BTF. + */ +static bool btf_module_is_standalone(struct btf_verifier_env *env) +{ + u32 id_max = 0, num_ids = 0; + struct btf *btf = env->btf; + struct btf_header *hdr; + void *cur, *end; + u32 end_str_off; + + hdr = &btf->hdr; + cur = btf->nohdr_data + hdr->type_off; + end = cur + hdr->type_len; + end_str_off = hdr->str_len; + + /* Quick CRC test; if base CRC is absent while CRC is present, + * we know BTF was generated without reference to base BTF. + */ + if (hdr->hdr_len >= sizeof(struct btf_header)) { + if ((hdr->flags & BTF_FLAG_CRC_SET) && + !(hdr->flags & BTF_FLAG_BASE_CRC_SET)) + return true; + } + + while (cur < end) { + struct btf_type *t = cur; + u32 meta_size = sizeof(*t); + struct btf_member *member; + struct btf_param *param; + struct btf_array *array; + struct btf_enum64 *e64; + struct btf_enum *e; + int i, vlen; + + if (t->name_off >= end_str_off) + return false; + + switch (btf_kind(t)) { + case BTF_KIND_FLOAT: + break; + case BTF_KIND_PTR: + case BTF_KIND_FWD: + case BTF_KIND_TYPEDEF: + case BTF_KIND_VOLATILE: + case BTF_KIND_CONST: + case BTF_KIND_RESTRICT: + case BTF_KIND_FUNC: + case BTF_KIND_TYPE_TAG: + if (t->type > id_max) + id_max = t->type; + break; + case BTF_KIND_VAR: + if (t->type > id_max) + id_max = t->type; + meta_size += sizeof(struct btf_var); + break; + case BTF_KIND_INT: + meta_size += sizeof(u32); + break; + case BTF_KIND_DATASEC: + meta_size += btf_vlen(t) * sizeof(struct btf_var_secinfo); + break; + case BTF_KIND_ARRAY: + array = (struct btf_array *)(t + 1); + if (array->type > id_max) + id_max = array->type; + if (array->index_type > id_max) + id_max = array->index_type; + meta_size += sizeof(*array); + break; + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: + member = (struct btf_member *)(t + 1); + vlen = btf_type_vlen(t); + for (i = 0; i < vlen; i++, member++) { + if (member->name_off >= end_str_off) + return false; + if (member->type > id_max) + id_max = member->type; + } + meta_size += vlen * sizeof(*member); + break; + case BTF_KIND_ENUM: + e = (struct btf_enum *)(t + 1); + vlen = btf_type_vlen(t); + for (i = 0; i < vlen; i++, e++) { + if (e->name_off > end_str_off) + return false; + } + meta_size += vlen * sizeof(*e); + break; + case BTF_KIND_ENUM64: + e64 = (struct btf_enum64 *)(t + 1); + vlen = btf_type_vlen(t); + for (i = 0; i < vlen; i++, e64++) { + if (e64->name_off > end_str_off) + return false; + } + meta_size += vlen * sizeof(*e64); + break; + case BTF_KIND_FUNC_PROTO: + param = (struct btf_param *)(t + 1); + vlen = btf_type_vlen(t); + for (i = 0; i < vlen; i++, param++) { + if (param->name_off > end_str_off) + return false; + if (param->type > id_max) + id_max = param->type; + } + meta_size += vlen * sizeof(*param); + break; + case BTF_KIND_DECL_TAG: + if (t->type > id_max) + id_max = t->type; + meta_size += sizeof(struct btf_decl_tag); + break; + } + cur += meta_size; + num_ids++; + } + /* if all standalone string checks look good and we found no references + * to ids higher than the number present here, we can be sure it is + * standalone BTF. + */ + return id_max <= num_ids; +} + +static u32 btf_name_off_renumber(struct btf *btf, u32 name_off) +{ + /* no need to renumber empty string */ + if (name_off == 0) + return name_off; + return name_off + btf->start_str_off; +} + +static u32 btf_id_renumber(struct btf *btf, u32 id) +{ + /* no need to renumber void type id */ + if (id == 0) + return id; + + return id + btf->start_id - 1; +} + +/* Renumber standalone BTF to appear as split BTF; name offsets must + * be relative to btf->start_str_offset and ids relative to btf->start_id. + * When user sees BTF it will appear as normal module split BTF, the only + * difference being it is fully self-referential and does not refer back + * to vmlinux BTF (aside from 0 "void" references). + */ +static void btf_type_renumber(struct btf_verifier_env *env, struct btf_type *t) +{ + struct btf_var_secinfo *secinfo; + struct btf *btf = env->btf; + struct btf_member *member; + struct btf_param *param; + struct btf_array *array; + struct btf_enum64 *e64; + struct btf_enum *e; + int i, vlen; + + t->name_off = btf_name_off_renumber(btf, t->name_off); + + switch (BTF_INFO_KIND(t->info)) { + case BTF_KIND_INT: + case BTF_KIND_FLOAT: + /* nothing to renumber here, no type references */ + break; + case BTF_KIND_PTR: + case BTF_KIND_FWD: + case BTF_KIND_TYPEDEF: + case BTF_KIND_VOLATILE: + case BTF_KIND_CONST: + case BTF_KIND_RESTRICT: + case BTF_KIND_FUNC: + case BTF_KIND_VAR: + case BTF_KIND_TYPE_TAG: + case BTF_KIND_DECL_TAG: + /* renumber the referenced type */ + t->type = btf_id_renumber(btf, t->type); + break; + case BTF_KIND_ARRAY: + array = btf_array(t); + array->type = btf_id_renumber(btf, array->type); + array->index_type = btf_id_renumber(btf, array->index_type); + break; + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: + member = (struct btf_member *)(t + 1); + vlen = btf_type_vlen(t); + for (i = 0; i < vlen; i++, member++) { + member->type = btf_id_renumber(btf, member->type); + member->name_off = btf_name_off_renumber(btf, member->name_off); + } + break; + case BTF_KIND_FUNC_PROTO: + param = (struct btf_param *)(t + 1); + vlen = btf_type_vlen(t); + for (i = 0; i < vlen; i++, param++) { + param->type = btf_id_renumber(btf, param->type); + param->name_off = btf_name_off_renumber(btf, param->name_off); + } + break; + case BTF_KIND_DATASEC: + vlen = btf_type_vlen(t); + secinfo = (struct btf_var_secinfo *)(t + 1); + for (i = 0; i < vlen; i++, secinfo++) + secinfo->type = btf_id_renumber(btf, secinfo->type); + break; + case BTF_KIND_ENUM: + e = (struct btf_enum *)(t + 1); + vlen = btf_type_vlen(t); + for (i = 0; i < vlen; i++, e++) + e->name_off = btf_name_off_renumber(btf, e->name_off); + break; + case BTF_KIND_ENUM64: + e64 = (struct btf_enum64 *)(t + 1); + vlen = btf_type_vlen(t); + for (i = 0; i < vlen; i++, e64++) + e64->name_off = btf_name_off_renumber(btf, e64->name_off); + break; + } +} + +static void btf_renumber(struct btf_verifier_env *env, struct btf *base_btf) +{ + struct btf *btf = env->btf; + int i; + + btf->start_id = base_btf->nr_types; + btf->start_str_off = base_btf->hdr.str_len; + btf->base_btf = base_btf; + + for (i = 1; i < btf->nr_types; i++) + btf_type_renumber(env, btf->types[i]); + /* skip past unneeded void type (we use base id 0 instead) */ + btf->types++; + btf->nr_types--; +} + static struct btf *btf_parse_module(const char *module_name, const void *data, unsigned int data_size) { struct btf_verifier_env *env = NULL; @@ -5936,10 +6184,29 @@ static struct btf *btf_parse_module(const char *module_name, const void *data, u if (err) goto errout; + if (btf_module_is_standalone(env)) { + /* BTF may be standalone; in that case BTF ids and strings + * will all be self-referential. + * + * Later on, once we have checked all metas, we will + * retain start id from base BTF so it will look like + * split BTF (but is self-contained); renumbering is done + * also to give the split BTF-like appearance and not + * confuse pahole which assumes split BTF for modules. + */ + btf->base_btf = NULL; + btf->start_id = 0; + btf->nr_types = 0; + btf->start_str_off = 0; + btf->standalone_btf = true; + } err = btf_check_all_metas(env); if (err) goto errout; + if (btf->standalone_btf) + btf_renumber(env, base_btf); + err = btf_check_type_tags(env, btf, btf_nr_types(base_btf)); if (err) goto errout; @@ -7879,6 +8146,16 @@ static int btf_populate_kfunc_set(struct btf *btf, enum btf_kfunc_hook hook, /* Concatenate the two sets */ memcpy(set->pairs + set->cnt, add_set->pairs, add_set->cnt * sizeof(set->pairs[0])); + if (btf->standalone_btf) { + u32 i; + + /* renumber BTF ids since BTF is standalone and has been mapped to look + * like split BTF, while BTF kfunc ids are still old unmapped values. + */ + for (i = set->cnt; i < set->cnt + add_set->cnt; i++) + set->pairs[i].id = btf_id_renumber(btf, set->pairs[i].id); + } + set->cnt += add_set->cnt; sort(set->pairs, set->cnt, sizeof(set->pairs[0]), btf_id_cmp_func, NULL); @@ -7939,7 +8216,6 @@ static int bpf_prog_type_to_kfunc_hook(enum bpf_prog_type prog_type) case BPF_PROG_TYPE_SYSCALL: return BTF_KFUNC_HOOK_SYSCALL; case BPF_PROG_TYPE_CGROUP_SKB: - case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: return BTF_KFUNC_HOOK_CGROUP_SKB; case BPF_PROG_TYPE_SCHED_ACT: return BTF_KFUNC_HOOK_SCHED_ACT; @@ -8008,7 +8284,14 @@ static int __register_btf_kfunc_id_set(enum btf_kfunc_hook hook, return PTR_ERR(btf); for (i = 0; i < kset->set->cnt; i++) { - ret = btf_check_kfunc_protos(btf, kset->set->pairs[i].id, + u32 kfunc_id = kset->set->pairs[i].id; + + /* standalone BTF renumbers BTF ids to make them appear as split BTF; + * resolve_btfids has the old BTF ids so we need to renumber here. + */ + if (btf->standalone_btf) + kfunc_id = btf_id_renumber(btf, kfunc_id); + ret = btf_check_kfunc_protos(btf, kfunc_id, kset->set->pairs[i].flags); if (ret) goto err_out; @@ -8066,6 +8349,12 @@ static int btf_check_dtor_kfuncs(struct btf *btf, const struct btf_id_dtor_kfunc for (i = 0; i < cnt; i++) { dtor_btf_id = dtors[i].kfunc_btf_id; + /* standalone BTF renumbers BTF ids to make them appear as split BTF; + * resolve_btfids has the old BTF ids so we need to renumber here. + */ + if (btf->standalone_btf) + dtor_btf_id = btf_id_renumber(btf, dtor_btf_id); + dtor_func = btf_type_by_id(btf, dtor_btf_id); if (!dtor_func || !btf_type_is_func(dtor_func)) return -EINVAL; @@ -8159,6 +8448,17 @@ int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_c btf->dtor_kfunc_tab = tab; memcpy(tab->dtors + tab->cnt, dtors, add_cnt * sizeof(tab->dtors[0])); + if (btf->standalone_btf) { + u32 i; + + /* renumber BTF ids since BTF is standalone and has been mapped to look + * like split BTF, while BTF dtor ids are still old unmapped values. + */ + for (i = tab->cnt; i < tab->cnt + add_cnt; i++) { + tab->dtors[i].btf_id = btf_id_renumber(btf, tab->dtors[i].btf_id); + tab->dtors[i].kfunc_btf_id = btf_id_renumber(btf, tab->dtors[i].kfunc_btf_id); + } + } tab->cnt += add_cnt; sort(tab->dtors, tab->cnt, sizeof(tab->dtors[0]), btf_id_cmp_func, NULL); From patchwork Fri Nov 10 11:03:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452341 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 8DC871427B for ; Fri, 10 Nov 2023 11:04:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="wMiFinAu" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D5E62B791 for ; Fri, 10 Nov 2023 03:04:45 -0800 (PST) Received: from pps.filterd (m0246630.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MYEWs006296; Fri, 10 Nov 2023 11:04:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=SsCstpZ0Hx6QnOmaazg1ZCW6Talp96yj/c4oMQoAYxQ=; b=wMiFinAuOGo0HVDSmljequuMFnMqMOAytLYK2JIULm8IXrcLC0Nr11PZ5DyO17I71nit A7z5WnjSA1KDBGlSmpD5vwu3ZwFonvQijWk6E1mIpJOJlJfq5jrbaHIXOOQYjqOVMBcG xHGVgahWVTP4u1eQG7nrpOjRB8vPQXBnIC3wa4huh/dVoV1nslpDkikn6OydeIcjs0Ak mj4yaTezszxtHzHioc09LWYeYSq8/rcF1ynjzcSaexPN59J1Q8KRIX7+WR1gMsk54T4O O6YxPO2iCQoOiWsrsfdSLBJ1hj3rbkqDW9ijpFff/nLYpk0/fnPTm5yqDm7EpWK7wZ8g PA== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w22nyns-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:29 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AA9mLpH018361; Fri, 10 Nov 2023 11:04:28 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qh3n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:28 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3Wg8018454; Fri, 10 Nov 2023 11:04:28 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-15; Fri, 10 Nov 2023 11:04:27 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 14/17] bpf: allow opt-out from using split BTF for modules Date: Fri, 10 Nov 2023 11:03:01 +0000 Message-Id: <20231110110304.63910-15-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-ORIG-GUID: hT0xjczoEiHMI18-pIRwTVE_9tHoS7c6 X-Proofpoint-GUID: hT0xjczoEiHMI18-pIRwTVE_9tHoS7c6 X-Patchwork-Delegate: bpf@iogearbox.net By having a BTF_BASE variable defaulting to using vmlinux as base BTF, we allow module builders to build standalone BTF such that it is generated independently and not de-duplicated with core vmlinux BTF. This allows such modules to be more resilient to changes in vmlinux BTF if they occur, as would happen if a change resulted in a different vmlinux BTF id mapping. Opt-out of split BTF is done via make BTF_BASE= M=path/2/module Signed-off-by: Alan Maguire --- scripts/Makefile.modfinal | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index b3a6aa8fbe8c..b69fd46b040a 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -30,6 +30,8 @@ quiet_cmd_cc_o_c = CC [M] $@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) +BTF_BASE := --btf_base vmlinux + quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o += \ $(LD) -r $(KBUILD_LDFLAGS) \ @@ -42,8 +44,8 @@ quiet_cmd_btf_ko = BTF [M] $@ if [ ! -f vmlinux ]; then \ printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ else \ - LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \ - $(RESOLVE_BTFIDS) -b vmlinux $@; \ + LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(BTF_BASE) $@; \ + $(RESOLVE_BTFIDS) $(BTF_BASE) $@; \ fi; # Same as newer-prereqs, but allows to exclude specified extra dependencies From patchwork Fri Nov 10 11:03:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452342 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 C1A381427B for ; Fri, 10 Nov 2023 11:04:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="pJd7551V" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 253F02B78D for ; Fri, 10 Nov 2023 03:04:50 -0800 (PST) Received: from pps.filterd (m0246630.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MYG9C006333; Fri, 10 Nov 2023 11:04:34 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=j/xT3Hk030zCDc/bbVIEG56D3U6crXbdraI3B6XtZKk=; b=pJd7551VWRfURMbLgCpPrpuvI1o9/dPHKhMi7IXdaBup1HXQVYoPS1Sy5p9qlf6mQERj yLlfnVPB8Wc13Nq87Zz/DV7cwAiJ2cDgHIhwpYUwOF6tWIu+FqGxO7RgUbF1qI4fB2Bo m2zw9TBN/daiu+gj3LN6KALDaTzMvawuMJb3RQOMP3J6Se8Ug99zkUJjP1snyCYcwiqB PlwqRD/TivRTLQd1dAQB9ZrY8Ip2ea+eaA/dwlNuiLtIlLjRxjhUWihn6Y0m/5h3xreY 8fafEuzTZUSRxBGK+IJvQb2AACndqdOX+T9Vx+KdJeuFUGcYoCUTpx0TXcrsyxi0zHNV /A== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w22nyp3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:33 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAA1VpK017614; Fri, 10 Nov 2023 11:04:33 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qh7c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:33 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3WgA018454; Fri, 10 Nov 2023 11:04:32 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-16; Fri, 10 Nov 2023 11:04:32 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 15/17] selftests/bpf: generalize module load to support specifying a module name Date: Fri, 10 Nov 2023 11:03:02 +0000 Message-Id: <20231110110304.63910-16-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-ORIG-GUID: XvGbyy4h8wi4artoC0yNHP4oK1k_t8B1 X-Proofpoint-GUID: XvGbyy4h8wi4artoC0yNHP4oK1k_t8B1 X-Patchwork-Delegate: bpf@iogearbox.net This will be used in testing standalone module BTF. Signed-off-by: Alan Maguire --- .../selftests/bpf/prog_tests/bpf_mod_race.c | 8 +++---- .../selftests/bpf/prog_tests/module_attach.c | 6 ++--- tools/testing/selftests/bpf/test_progs.c | 6 ++--- tools/testing/selftests/bpf/test_verifier.c | 6 ++--- tools/testing/selftests/bpf/testing_helpers.c | 24 ++++++++++--------- tools/testing/selftests/bpf/testing_helpers.h | 4 ++-- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_mod_race.c b/tools/testing/selftests/bpf/prog_tests/bpf_mod_race.c index fe2c502e5089..c4aeb40390a3 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_mod_race.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_mod_race.c @@ -48,7 +48,7 @@ static _Atomic enum bpf_test_state state = _TS_INVALID; static void *load_module_thread(void *p) { - if (!ASSERT_NEQ(load_bpf_testmod(false), 0, "load_module_thread must fail")) + if (!ASSERT_NEQ(load_bpf_testmod("bpf_testmod", false), 0, "load_module_thread must fail")) atomic_store(&state, TS_MODULE_LOAD); else atomic_store(&state, TS_MODULE_LOAD_FAIL); @@ -100,7 +100,7 @@ static void test_bpf_mod_race_config(const struct test_config *config) if (!ASSERT_NEQ(fault_addr, MAP_FAILED, "mmap for uffd registration")) return; - if (!ASSERT_OK(unload_bpf_testmod(false), "unload bpf_testmod")) + if (!ASSERT_OK(unload_bpf_testmod("bpf_testmod", false), "unload bpf_testmod")) goto end_mmap; skel = bpf_mod_race__open(); @@ -178,8 +178,8 @@ static void test_bpf_mod_race_config(const struct test_config *config) bpf_mod_race__destroy(skel); ASSERT_OK(kern_sync_rcu(), "kern_sync_rcu"); end_module: - unload_bpf_testmod(false); - ASSERT_OK(load_bpf_testmod(false), "restore bpf_testmod"); + unload_bpf_testmod("bpf_testmod", false); + ASSERT_OK(load_bpf_testmod("bpf_testmod", false), "restore bpf_testmod"); end_mmap: munmap(fault_addr, 4096); atomic_store(&state, _TS_INVALID); diff --git a/tools/testing/selftests/bpf/prog_tests/module_attach.c b/tools/testing/selftests/bpf/prog_tests/module_attach.c index f53d658ed080..9f1f00c63d30 100644 --- a/tools/testing/selftests/bpf/prog_tests/module_attach.c +++ b/tools/testing/selftests/bpf/prog_tests/module_attach.c @@ -89,21 +89,21 @@ void test_module_attach(void) if (!ASSERT_OK_PTR(link, "attach_fentry")) goto cleanup; - ASSERT_ERR(unload_bpf_testmod(false), "unload_bpf_testmod"); + ASSERT_ERR(unload_bpf_testmod("bpf_testmod", false), "unload_bpf_testmod"); bpf_link__destroy(link); link = bpf_program__attach(skel->progs.handle_fexit); if (!ASSERT_OK_PTR(link, "attach_fexit")) goto cleanup; - ASSERT_ERR(unload_bpf_testmod(false), "unload_bpf_testmod"); + ASSERT_ERR(unload_bpf_testmod("bpf_testmod", false), "unload_bpf_testmod"); bpf_link__destroy(link); link = bpf_program__attach(skel->progs.kprobe_multi); if (!ASSERT_OK_PTR(link, "attach_kprobe_multi")) goto cleanup; - ASSERT_ERR(unload_bpf_testmod(false), "unload_bpf_testmod"); + ASSERT_ERR(unload_bpf_testmod("bpf_testmod", false), "unload_bpf_testmod"); bpf_link__destroy(link); cleanup: diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 1b9387890148..a3a89743e7aa 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -1659,9 +1659,9 @@ int main(int argc, char **argv) env.has_testmod = true; if (!env.list_test_names) { /* ensure previous instance of the module is unloaded */ - unload_bpf_testmod(verbose()); + unload_bpf_testmod("bpf_testmod", verbose()); - if (load_bpf_testmod(verbose())) { + if (load_bpf_testmod("bpf_testmod", verbose())) { fprintf(env.stderr, "WARNING! Selftests relying on bpf_testmod.ko will be skipped.\n"); env.has_testmod = false; } @@ -1761,7 +1761,7 @@ int main(int argc, char **argv) close(env.saved_netns_fd); out: if (!env.list_test_names && env.has_testmod) - unload_bpf_testmod(verbose()); + unload_bpf_testmod("bpf_testmod", verbose()); free_test_selector(&env.test_selector); free_test_selector(&env.subtest_selector); diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 98107e0452d3..b712424d6a10 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -1804,9 +1804,9 @@ static int do_test(bool unpriv, unsigned int from, unsigned int to) int i, passes = 0, errors = 0; /* ensure previous instance of the module is unloaded */ - unload_bpf_testmod(verbose); + unload_bpf_testmod("bpf_testmod", verbose); - if (load_bpf_testmod(verbose)) + if (load_bpf_testmod("bpf_testmod", verbose)) return EXIT_FAILURE; for (i = from; i < to; i++) { @@ -1836,7 +1836,7 @@ static int do_test(bool unpriv, unsigned int from, unsigned int to) } } - unload_bpf_testmod(verbose); + unload_bpf_testmod("bpf_testmod", verbose); kfuncs_cleanup(); printf("Summary: %d PASSED, %d SKIPPED, %d FAILED\n", passes, diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c index 8d994884c7b4..d5cde3f298f1 100644 --- a/tools/testing/selftests/bpf/testing_helpers.c +++ b/tools/testing/selftests/bpf/testing_helpers.c @@ -338,45 +338,47 @@ static int delete_module(const char *name, int flags) return syscall(__NR_delete_module, name, flags); } -int unload_bpf_testmod(bool verbose) +int unload_bpf_testmod(const char *name, bool verbose) { if (kern_sync_rcu()) fprintf(stdout, "Failed to trigger kernel-side RCU sync!\n"); - if (delete_module("bpf_testmod", 0)) { + if (delete_module(name, 0)) { if (errno == ENOENT) { if (verbose) - fprintf(stdout, "bpf_testmod.ko is already unloaded.\n"); + fprintf(stdout, "%s.ko is already unloaded.\n", name); return -1; } - fprintf(stdout, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno); + fprintf(stdout, "Failed to unload %s.ko from kernel: %d\n", name, -errno); return -1; } if (verbose) - fprintf(stdout, "Successfully unloaded bpf_testmod.ko.\n"); + fprintf(stdout, "Successfully unloaded %s.ko.\n", name); return 0; } -int load_bpf_testmod(bool verbose) +int load_bpf_testmod(const char *name, bool verbose) { + char koname[PATH_MAX]; int fd; if (verbose) - fprintf(stdout, "Loading bpf_testmod.ko...\n"); + fprintf(stdout, "Loading %s.ko...\n", name); - fd = open("bpf_testmod.ko", O_RDONLY); + snprintf(koname, sizeof(koname), "%s.ko", name); + fd = open(koname, O_RDONLY); if (fd < 0) { - fprintf(stdout, "Can't find bpf_testmod.ko kernel module: %d\n", -errno); + fprintf(stdout, "Can't find %s.ko kernel module: %d\n", name, -errno); return -ENOENT; } if (finit_module(fd, "", 0)) { - fprintf(stdout, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno); + fprintf(stdout, "Failed to load %s.ko into the kernel: %d\n", name, -errno); close(fd); return -EINVAL; } close(fd); if (verbose) - fprintf(stdout, "Successfully loaded bpf_testmod.ko.\n"); + fprintf(stdout, "Successfully loaded %s.ko.\n", name); return 0; } diff --git a/tools/testing/selftests/bpf/testing_helpers.h b/tools/testing/selftests/bpf/testing_helpers.h index 5b7a55136741..831329ad5091 100644 --- a/tools/testing/selftests/bpf/testing_helpers.h +++ b/tools/testing/selftests/bpf/testing_helpers.h @@ -30,8 +30,8 @@ int parse_test_list_file(const char *path, bool is_glob_pattern); __u64 read_perf_max_sample_freq(void); -int load_bpf_testmod(bool verbose); -int unload_bpf_testmod(bool verbose); +int load_bpf_testmod(const char *name, bool verbose); +int unload_bpf_testmod(const char *name, bool verbose); int kern_sync_rcu(void); static inline __u64 get_time_ns(void) From patchwork Fri Nov 10 11:03:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452343 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 F2910D308 for ; Fri, 10 Nov 2023 11:04:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="yXDye67K" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B8CB2B78B for ; Fri, 10 Nov 2023 03:04:55 -0800 (PST) Received: from pps.filterd (m0246630.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MYEU2006315; Fri, 10 Nov 2023 11:04:38 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=2EUd2HhmUgRU6pwf5dBYy2p+iR2dJsxI52g+oez8dCQ=; b=yXDye67K2EM7Zyls8zQLz0NfGTCgPzyi3giKWEH0UnfrR5fW2hrrKqaiYZQlkOUpyNDD BnYasu3reDs8wZ0wSjzu70TD54m6wN5RqvseFQXUp6xyyZeMFyYFAjYU19dDQXuRbLyM T2WLZNg/zQsOjmV/0a7QGbAUe2MdbGnGuqyI/T1PJpLOf/H3iMcDbE4gD2ES8U+NNdN8 i3Lqro37Mc4+gAQAiyzGznMQUywTDrEnqHCh5EVSk6Ddoa92qb4QMPlhhFTZIPm2efah 8VSGWCmbyGosU8Gfxjeb8o/omp31/hoDBgRlO1UyZysW3Y9bVkkuVlM3MXQKWRFzJQk6 fg== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w22nyp9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:37 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAA48KN018297; Fri, 10 Nov 2023 11:04:37 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qhbv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:37 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3WgC018454; Fri, 10 Nov 2023 11:04:36 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-17; Fri, 10 Nov 2023 11:04:36 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 16/17] selftests/bpf: build separate bpf_testmod module with standalone BTF Date: Fri, 10 Nov 2023 11:03:03 +0000 Message-Id: <20231110110304.63910-17-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-ORIG-GUID: iH3B-h9nxSS941q5rLblVgh5MtXOv07U X-Proofpoint-GUID: iH3B-h9nxSS941q5rLblVgh5MtXOv07U X-Patchwork-Delegate: bpf@iogearbox.net From bpf_testmod.c, build bpf_testmod_standalone.ko which is identical to bpf_testmod.ko aside from being built with standalone BTF, and having enough differences in names such that both can be loaded simultaneously with bpf_testmod. It will be used to test standalone BTF loading. bpf_testmod_standalone* files were generated via running sed 's/bpf_testmod/bpf_testmod_standalone/g' ...on the relevant files, and manually removing bpf_fentry_shadow_test() from bpf_testmod_standalone.c to avoid a symbol clash that would prevent it being loaded at the same time as bpf_testmod. Signed-off-by: Alan Maguire --- .../selftests/bpf/bpf_testmod/Makefile | 16 +- .../bpf_testmod_standalone-events.h | 57 ++ .../bpf/bpf_testmod/bpf_testmod_standalone.c | 551 ++++++++++++++++++ .../bpf/bpf_testmod/bpf_testmod_standalone.h | 31 + .../bpf_testmod_standalone_kfunc.h | 109 ++++ 5 files changed, 760 insertions(+), 4 deletions(-) create mode 100644 tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone-events.h create mode 100644 tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone.c create mode 100644 tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone.h create mode 100644 tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone_kfunc.h diff --git a/tools/testing/selftests/bpf/bpf_testmod/Makefile b/tools/testing/selftests/bpf/bpf_testmod/Makefile index 15cb36c4483a..45e8c70c63be 100644 --- a/tools/testing/selftests/bpf/bpf_testmod/Makefile +++ b/tools/testing/selftests/bpf/bpf_testmod/Makefile @@ -7,13 +7,21 @@ else Q = @ endif -MODULES = bpf_testmod.ko +MODULES = bpf_testmod.ko bpf_testmod_standalone.ko + +obj-m += bpf_testmod.o +obj-m += bpf_testmod_standalone.o -obj-m += bpf_testmod.o CFLAGS_bpf_testmod.o = -I$(src) +CFLAGS_bpf_testmod_standalone.o += -I$(src) + +all: testmod standalone + +testmod: + +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) bpf_testmod.ko -all: - +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) modules +standalone: + +$(Q)make -C $(KDIR) BTF_BASE= M=$(BPF_TESTMOD_DIR) bpf_testmod_standalone.ko clean: +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) clean diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone-events.h b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone-events.h new file mode 100644 index 000000000000..ee1c668b0e3b --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone-events.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2020 Facebook */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM bpf_testmod_standalone + +#if !defined(_BPF_TESTMOD_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _BPF_TESTMOD_EVENTS_H + +#include +#include "bpf_testmod_standalone.h" + +TRACE_EVENT(bpf_testmod_standalone_test_read, + TP_PROTO(struct task_struct *task, struct bpf_testmod_standalone_test_read_ctx *ctx), + TP_ARGS(task, ctx), + TP_STRUCT__entry( + __field(pid_t, pid) + __array(char, comm, TASK_COMM_LEN) + __field(loff_t, off) + __field(size_t, len) + ), + TP_fast_assign( + __entry->pid = task->pid; + memcpy(__entry->comm, task->comm, TASK_COMM_LEN); + __entry->off = ctx->off; + __entry->len = ctx->len; + ), + TP_printk("pid=%d comm=%s off=%llu len=%zu", + __entry->pid, __entry->comm, __entry->off, __entry->len) +); + +/* A bare tracepoint with no event associated with it */ +DECLARE_TRACE(bpf_testmod_standalone_test_write_bare, + TP_PROTO(struct task_struct *task, struct bpf_testmod_standalone_test_write_ctx *ctx), + TP_ARGS(task, ctx) +); + +#undef BPF_TESTMOD_DECLARE_TRACE +#ifdef DECLARE_TRACE_WRITABLE +#define BPF_TESTMOD_DECLARE_TRACE(call, proto, args, size) \ + DECLARE_TRACE_WRITABLE(call, PARAMS(proto), PARAMS(args), size) +#else +#define BPF_TESTMOD_DECLARE_TRACE(call, proto, args, size) \ + DECLARE_TRACE(call, PARAMS(proto), PARAMS(args)) +#endif + +BPF_TESTMOD_DECLARE_TRACE(bpf_testmod_standalone_test_writable_bare, + TP_PROTO(struct bpf_testmod_standalone_test_writable_ctx *ctx), + TP_ARGS(ctx), + sizeof(struct bpf_testmod_standalone_test_writable_ctx) +); + +#endif /* _BPF_TESTMOD_EVENTS_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE bpf_testmod_standalone-events +#include diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone.c new file mode 100644 index 000000000000..0a4828113c34 --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone.c @@ -0,0 +1,551 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Facebook */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "bpf_testmod_standalone.h" +#include "bpf_testmod_standalone_kfunc.h" + +#define CREATE_TRACE_POINTS +#include "bpf_testmod_standalone-events.h" + +typedef int (*func_proto_typedef)(long); +typedef int (*func_proto_typedef_nested1)(func_proto_typedef); +typedef int (*func_proto_typedef_nested2)(func_proto_typedef_nested1); + +DEFINE_PER_CPU(int, bpf_testmod_standalone_ksym_percpu) = 123; +long bpf_testmod_standalone_test_struct_arg_result; + +struct bpf_testmod_standalone_struct_arg_1 { + int a; +}; +struct bpf_testmod_standalone_struct_arg_2 { + long a; + long b; +}; + +struct bpf_testmod_standalone_struct_arg_3 { + int a; + int b[]; +}; + +struct bpf_testmod_standalone_struct_arg_4 { + u64 a; + int b; +}; + +__diag_push(); +__diag_ignore_all("-Wmissing-prototypes", + "Global functions as their definitions will be in bpf_testmod_standalone.ko BTF"); + +noinline int +bpf_testmod_standalone_test_struct_arg_1(struct bpf_testmod_standalone_struct_arg_2 a, int b, int c) { + bpf_testmod_standalone_test_struct_arg_result = a.a + a.b + b + c; + return bpf_testmod_standalone_test_struct_arg_result; +} + +noinline int +bpf_testmod_standalone_test_struct_arg_2(int a, struct bpf_testmod_standalone_struct_arg_2 b, int c) { + bpf_testmod_standalone_test_struct_arg_result = a + b.a + b.b + c; + return bpf_testmod_standalone_test_struct_arg_result; +} + +noinline int +bpf_testmod_standalone_test_struct_arg_3(int a, int b, struct bpf_testmod_standalone_struct_arg_2 c) { + bpf_testmod_standalone_test_struct_arg_result = a + b + c.a + c.b; + return bpf_testmod_standalone_test_struct_arg_result; +} + +noinline int +bpf_testmod_standalone_test_struct_arg_4(struct bpf_testmod_standalone_struct_arg_1 a, int b, + int c, int d, struct bpf_testmod_standalone_struct_arg_2 e) { + bpf_testmod_standalone_test_struct_arg_result = a.a + b + c + d + e.a + e.b; + return bpf_testmod_standalone_test_struct_arg_result; +} + +noinline int +bpf_testmod_standalone_test_struct_arg_5(void) { + bpf_testmod_standalone_test_struct_arg_result = 1; + return bpf_testmod_standalone_test_struct_arg_result; +} + +noinline int +bpf_testmod_standalone_test_struct_arg_6(struct bpf_testmod_standalone_struct_arg_3 *a) { + bpf_testmod_standalone_test_struct_arg_result = a->b[0]; + return bpf_testmod_standalone_test_struct_arg_result; +} + +noinline int +bpf_testmod_standalone_test_struct_arg_7(u64 a, void *b, short c, int d, void *e, + struct bpf_testmod_standalone_struct_arg_4 f) +{ + bpf_testmod_standalone_test_struct_arg_result = a + (long)b + c + d + + (long)e + f.a + f.b; + return bpf_testmod_standalone_test_struct_arg_result; +} + +noinline int +bpf_testmod_standalone_test_struct_arg_8(u64 a, void *b, short c, int d, void *e, + struct bpf_testmod_standalone_struct_arg_4 f, int g) +{ + bpf_testmod_standalone_test_struct_arg_result = a + (long)b + c + d + + (long)e + f.a + f.b + g; + return bpf_testmod_standalone_test_struct_arg_result; +} + +noinline int +bpf_testmod_standalone_test_arg_ptr_to_struct(struct bpf_testmod_standalone_struct_arg_1 *a) { + bpf_testmod_standalone_test_struct_arg_result = a->a; + return bpf_testmod_standalone_test_struct_arg_result; +} + +__bpf_kfunc void +bpf_testmod_standalone_test_mod_kfunc(int i) +{ + *(int *)this_cpu_ptr(&bpf_testmod_standalone_ksym_percpu) = i; +} + +__bpf_kfunc int bpf_iter_testmod_seq_new(struct bpf_iter_testmod_seq *it, s64 value, int cnt) +{ + if (cnt < 0) { + it->cnt = 0; + return -EINVAL; + } + + it->value = value; + it->cnt = cnt; + + return 0; +} + +__bpf_kfunc s64 *bpf_iter_testmod_seq_next(struct bpf_iter_testmod_seq* it) +{ + if (it->cnt <= 0) + return NULL; + + it->cnt--; + + return &it->value; +} + +__bpf_kfunc void bpf_iter_testmod_seq_destroy(struct bpf_iter_testmod_seq *it) +{ + it->cnt = 0; +} + +__bpf_kfunc void bpf_kfunc_common_test(void) +{ +} + +struct bpf_testmod_standalone_btf_type_tag_1 { + int a; +}; + +struct bpf_testmod_standalone_btf_type_tag_2 { + struct bpf_testmod_standalone_btf_type_tag_1 __user *p; +}; + +struct bpf_testmod_standalone_btf_type_tag_3 { + struct bpf_testmod_standalone_btf_type_tag_1 __percpu *p; +}; + +noinline int +bpf_testmod_standalone_test_btf_type_tag_user_1(struct bpf_testmod_standalone_btf_type_tag_1 __user *arg) { + BTF_TYPE_EMIT(func_proto_typedef); + BTF_TYPE_EMIT(func_proto_typedef_nested1); + BTF_TYPE_EMIT(func_proto_typedef_nested2); + return arg->a; +} + +noinline int +bpf_testmod_standalone_test_btf_type_tag_user_2(struct bpf_testmod_standalone_btf_type_tag_2 *arg) { + return arg->p->a; +} + +noinline int +bpf_testmod_standalone_test_btf_type_tag_percpu_1(struct bpf_testmod_standalone_btf_type_tag_1 __percpu *arg) { + return arg->a; +} + +noinline int +bpf_testmod_standalone_test_btf_type_tag_percpu_2(struct bpf_testmod_standalone_btf_type_tag_3 *arg) { + return arg->p->a; +} + +noinline int bpf_testmod_standalone_loop_test(int n) +{ + /* Make sum volatile, so smart compilers, such as clang, will not + * optimize the code by removing the loop. + */ + volatile int sum = 0; + int i; + + /* the primary goal of this test is to test LBR. Create a lot of + * branches in the function, so we can catch it easily. + */ + for (i = 0; i < n; i++) + sum += i; + return sum; +} + +__weak noinline struct file *bpf_testmod_standalone_return_ptr(int arg) +{ + static struct file f = {}; + + switch (arg) { + case 1: return (void *)EINVAL; /* user addr */ + case 2: return (void *)0xcafe4a11; /* user addr */ + case 3: return (void *)-EINVAL; /* canonical, but invalid */ + case 4: return (void *)(1ull << 60); /* non-canonical and invalid */ + case 5: return (void *)~(1ull << 30); /* trigger extable */ + case 6: return &f; /* valid addr */ + case 7: return (void *)((long)&f | 1); /* kernel tricks */ + default: return NULL; + } +} + +noinline int bpf_testmod_standalone_fentry_test1(int a) +{ + return a + 1; +} + +noinline int bpf_testmod_standalone_fentry_test2(int a, u64 b) +{ + return a + b; +} + +noinline int bpf_testmod_standalone_fentry_test3(char a, int b, u64 c) +{ + return a + b + c; +} + +noinline int bpf_testmod_standalone_fentry_test7(u64 a, void *b, short c, int d, + void *e, char f, int g) +{ + return a + (long)b + c + d + (long)e + f + g; +} + +noinline int bpf_testmod_standalone_fentry_test11(u64 a, void *b, short c, int d, + void *e, char f, int g, + unsigned int h, long i, __u64 j, + unsigned long k) +{ + return a + (long)b + c + d + (long)e + f + g + h + i + j + k; +} + +int bpf_testmod_standalone_fentry_ok; + +noinline ssize_t +bpf_testmod_standalone_test_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t len) +{ + struct bpf_testmod_standalone_test_read_ctx ctx = { + .buf = buf, + .off = off, + .len = len, + }; + struct bpf_testmod_standalone_struct_arg_1 struct_arg1 = {10}, struct_arg1_2 = {-1}; + struct bpf_testmod_standalone_struct_arg_2 struct_arg2 = {2, 3}; + struct bpf_testmod_standalone_struct_arg_3 *struct_arg3; + struct bpf_testmod_standalone_struct_arg_4 struct_arg4 = {21, 22}; + int i = 1; + + while (bpf_testmod_standalone_return_ptr(i)) + i++; + + (void)bpf_testmod_standalone_test_struct_arg_1(struct_arg2, 1, 4); + (void)bpf_testmod_standalone_test_struct_arg_2(1, struct_arg2, 4); + (void)bpf_testmod_standalone_test_struct_arg_3(1, 4, struct_arg2); + (void)bpf_testmod_standalone_test_struct_arg_4(struct_arg1, 1, 2, 3, struct_arg2); + (void)bpf_testmod_standalone_test_struct_arg_5(); + (void)bpf_testmod_standalone_test_struct_arg_7(16, (void *)17, 18, 19, + (void *)20, struct_arg4); + (void)bpf_testmod_standalone_test_struct_arg_8(16, (void *)17, 18, 19, + (void *)20, struct_arg4, 23); + + (void)bpf_testmod_standalone_test_arg_ptr_to_struct(&struct_arg1_2); + + struct_arg3 = kmalloc((sizeof(struct bpf_testmod_standalone_struct_arg_3) + + sizeof(int)), GFP_KERNEL); + if (struct_arg3 != NULL) { + struct_arg3->b[0] = 1; + (void)bpf_testmod_standalone_test_struct_arg_6(struct_arg3); + kfree(struct_arg3); + } + + /* This is always true. Use the check to make sure the compiler + * doesn't remove bpf_testmod_standalone_loop_test. + */ + if (bpf_testmod_standalone_loop_test(101) > 100) + trace_bpf_testmod_standalone_test_read(current, &ctx); + + /* Magic number to enable writable tp */ + if (len == 64) { + struct bpf_testmod_standalone_test_writable_ctx writable = { + .val = 1024, + }; + trace_bpf_testmod_standalone_test_writable_bare(&writable); + if (writable.early_ret) + return snprintf(buf, len, "%d\n", writable.val); + } + + if (bpf_testmod_standalone_fentry_test1(1) != 2 || + bpf_testmod_standalone_fentry_test2(2, 3) != 5 || + bpf_testmod_standalone_fentry_test3(4, 5, 6) != 15 || + bpf_testmod_standalone_fentry_test7(16, (void *)17, 18, 19, (void *)20, + 21, 22) != 133 || + bpf_testmod_standalone_fentry_test11(16, (void *)17, 18, 19, (void *)20, + 21, 22, 23, 24, 25, 26) != 231) + goto out; + + bpf_testmod_standalone_fentry_ok = 1; +out: + return -EIO; /* always fail */ +} +EXPORT_SYMBOL(bpf_testmod_standalone_test_read); +ALLOW_ERROR_INJECTION(bpf_testmod_standalone_test_read, ERRNO); + +noinline ssize_t +bpf_testmod_standalone_test_write(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t len) +{ + struct bpf_testmod_standalone_test_write_ctx ctx = { + .buf = buf, + .off = off, + .len = len, + }; + + trace_bpf_testmod_standalone_test_write_bare(current, &ctx); + + return -EIO; /* always fail */ +} +EXPORT_SYMBOL(bpf_testmod_standalone_test_write); +ALLOW_ERROR_INJECTION(bpf_testmod_standalone_test_write, ERRNO); + +__diag_pop(); + +static struct bin_attribute bin_attr_bpf_testmod_standalone_file __ro_after_init = { + .attr = { .name = "bpf_testmod_standalone", .mode = 0666, }, + .read = bpf_testmod_standalone_test_read, + .write = bpf_testmod_standalone_test_write, +}; + +BTF_SET8_START(bpf_testmod_standalone_common_kfunc_ids) +BTF_ID_FLAGS(func, bpf_iter_testmod_seq_new, KF_ITER_NEW) +BTF_ID_FLAGS(func, bpf_iter_testmod_seq_next, KF_ITER_NEXT | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_iter_testmod_seq_destroy, KF_ITER_DESTROY) +BTF_ID_FLAGS(func, bpf_kfunc_common_test) +BTF_SET8_END(bpf_testmod_standalone_common_kfunc_ids) + +static const struct btf_kfunc_id_set bpf_testmod_standalone_common_kfunc_set = { + .owner = THIS_MODULE, + .set = &bpf_testmod_standalone_common_kfunc_ids, +}; + +__bpf_kfunc u64 bpf_kfunc_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d) +{ + return a + b + c + d; +} + +__bpf_kfunc int bpf_kfunc_call_test2(struct sock *sk, u32 a, u32 b) +{ + return a + b; +} + +__bpf_kfunc struct sock *bpf_kfunc_call_test3(struct sock *sk) +{ + return sk; +} + +__bpf_kfunc long noinline bpf_kfunc_call_test4(signed char a, short b, int c, long d) +{ + /* Provoke the compiler to assume that the caller has sign-extended a, + * b and c on platforms where this is required (e.g. s390x). + */ + return (long)a + (long)b + (long)c + d; +} + +static struct prog_test_ref_kfunc prog_test_struct = { + .a = 42, + .b = 108, + .next = &prog_test_struct, + .cnt = REFCOUNT_INIT(1), +}; + +__bpf_kfunc struct prog_test_ref_kfunc * +bpf_kfunc_call_test_acquire(unsigned long *scalar_ptr) +{ + refcount_inc(&prog_test_struct.cnt); + return &prog_test_struct; +} + +__bpf_kfunc void bpf_kfunc_call_test_offset(struct prog_test_ref_kfunc *p) +{ + WARN_ON_ONCE(1); +} + +__bpf_kfunc struct prog_test_member * +bpf_kfunc_call_memb_acquire(void) +{ + WARN_ON_ONCE(1); + return NULL; +} + +__bpf_kfunc void bpf_kfunc_call_memb1_release(struct prog_test_member1 *p) +{ + WARN_ON_ONCE(1); +} + +static int *__bpf_kfunc_call_test_get_mem(struct prog_test_ref_kfunc *p, const int size) +{ + if (size > 2 * sizeof(int)) + return NULL; + + return (int *)p; +} + +__bpf_kfunc int *bpf_kfunc_call_test_get_rdwr_mem(struct prog_test_ref_kfunc *p, + const int rdwr_buf_size) +{ + return __bpf_kfunc_call_test_get_mem(p, rdwr_buf_size); +} + +__bpf_kfunc int *bpf_kfunc_call_test_get_rdonly_mem(struct prog_test_ref_kfunc *p, + const int rdonly_buf_size) +{ + return __bpf_kfunc_call_test_get_mem(p, rdonly_buf_size); +} + +/* the next 2 ones can't be really used for testing expect to ensure + * that the verifier rejects the call. + * Acquire functions must return struct pointers, so these ones are + * failing. + */ +__bpf_kfunc int *bpf_kfunc_call_test_acq_rdonly_mem(struct prog_test_ref_kfunc *p, + const int rdonly_buf_size) +{ + return __bpf_kfunc_call_test_get_mem(p, rdonly_buf_size); +} + +__bpf_kfunc void bpf_kfunc_call_int_mem_release(int *p) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_pass_ctx(struct __sk_buff *skb) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_pass1(struct prog_test_pass1 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_pass2(struct prog_test_pass2 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_fail1(struct prog_test_fail1 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_fail2(struct prog_test_fail2 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_fail3(struct prog_test_fail3 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_mem_len_pass1(void *mem, int mem__sz) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_mem_len_fail1(void *mem, int len) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_mem_len_fail2(u64 *mem, int len) +{ +} + +__bpf_kfunc void bpf_kfunc_call_test_ref(struct prog_test_ref_kfunc *p) +{ + /* p != NULL, but p->cnt could be 0 */ +} + +__bpf_kfunc void bpf_kfunc_call_test_destructive(void) +{ +} + +__bpf_kfunc static u32 bpf_kfunc_call_test_static_unused_arg(u32 arg, u32 unused) +{ + return arg; +} + +BTF_SET8_START(bpf_testmod_standalone_check_kfunc_ids) +BTF_ID_FLAGS(func, bpf_testmod_standalone_test_mod_kfunc) +BTF_ID_FLAGS(func, bpf_kfunc_call_test1) +BTF_ID_FLAGS(func, bpf_kfunc_call_test2) +BTF_ID_FLAGS(func, bpf_kfunc_call_test3) +BTF_ID_FLAGS(func, bpf_kfunc_call_test4) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_pass1) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_fail1) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_fail2) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_acquire, KF_ACQUIRE | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_call_memb_acquire, KF_ACQUIRE | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_call_memb1_release, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_get_rdwr_mem, KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_get_rdonly_mem, KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_acq_rdonly_mem, KF_ACQUIRE | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_call_int_mem_release, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_pass_ctx) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_pass1) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_pass2) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail1) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail2) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail3) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_ref, KF_TRUSTED_ARGS | KF_RCU) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_offset) +BTF_SET8_END(bpf_testmod_standalone_check_kfunc_ids) + +static const struct btf_kfunc_id_set bpf_testmod_standalone_kfunc_set = { + .owner = THIS_MODULE, + .set = &bpf_testmod_standalone_check_kfunc_ids, +}; + +extern int bpf_fentry_test1(int a); + +static int bpf_testmod_standalone_init(void) +{ + int ret; + + ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_UNSPEC, &bpf_testmod_standalone_common_kfunc_set); + ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_testmod_standalone_kfunc_set); + ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_testmod_standalone_kfunc_set); + ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &bpf_testmod_standalone_kfunc_set); + if (ret < 0) + return ret; + if (bpf_fentry_test1(0) < 0) + return -EINVAL; + return sysfs_create_bin_file(kernel_kobj, &bin_attr_bpf_testmod_standalone_file); +} + +static void bpf_testmod_standalone_exit(void) +{ + return sysfs_remove_bin_file(kernel_kobj, &bin_attr_bpf_testmod_standalone_file); +} + +module_init(bpf_testmod_standalone_init); +module_exit(bpf_testmod_standalone_exit); + +MODULE_AUTHOR("Andrii Nakryiko"); +MODULE_DESCRIPTION("BPF selftests module"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone.h b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone.h new file mode 100644 index 000000000000..6d7df67c8ef6 --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2020 Facebook */ +#ifndef _BPF_TESTMOD_STANDALONE_H +#define _BPF_TESTMOD_STANDALONE_H + +#include + +struct bpf_testmod_standalone_test_read_ctx { + char *buf; + loff_t off; + size_t len; +}; + +struct bpf_testmod_standalone_test_write_ctx { + char *buf; + loff_t off; + size_t len; +}; + +struct bpf_testmod_standalone_test_writable_ctx { + bool early_ret; + int val; +}; + +/* BPF iter that returns *value* *n* times in a row */ +struct bpf_iter_testmod_seq { + s64 value; + int cnt; +}; + +#endif /* _BPF_TESTMOD_STANDALONE_H */ diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone_kfunc.h b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone_kfunc.h new file mode 100644 index 000000000000..a23cfd72d7f3 --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_standalone_kfunc.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _BPF_TESTMOD_KFUNC_H +#define _BPF_TESTMOD_KFUNC_H + +#ifndef __KERNEL__ +#include +#include +#else +#define __ksym +struct prog_test_member1 { + int a; +}; + +struct prog_test_member { + struct prog_test_member1 m; + int c; +}; + +struct prog_test_ref_kfunc { + int a; + int b; + struct prog_test_member memb; + struct prog_test_ref_kfunc *next; + refcount_t cnt; +}; +#endif + +struct prog_test_pass1 { + int x0; + struct { + int x1; + struct { + int x2; + struct { + int x3; + }; + }; + }; +}; + +struct prog_test_pass2 { + int len; + short arr1[4]; + struct { + char arr2[4]; + unsigned long arr3[8]; + } x; +}; + +struct prog_test_fail1 { + void *p; + int x; +}; + +struct prog_test_fail2 { + int x8; + struct prog_test_pass1 x; +}; + +struct prog_test_fail3 { + int len; + char arr1[2]; + char arr2[]; +}; + +struct prog_test_ref_kfunc * +bpf_kfunc_call_test_acquire(unsigned long *scalar_ptr) __ksym; +void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p) __ksym; +void bpf_kfunc_call_test_ref(struct prog_test_ref_kfunc *p) __ksym; + +void bpf_kfunc_call_test_mem_len_pass1(void *mem, int len) __ksym; +int *bpf_kfunc_call_test_get_rdwr_mem(struct prog_test_ref_kfunc *p, const int rdwr_buf_size) __ksym; +int *bpf_kfunc_call_test_get_rdonly_mem(struct prog_test_ref_kfunc *p, const int rdonly_buf_size) __ksym; +int *bpf_kfunc_call_test_acq_rdonly_mem(struct prog_test_ref_kfunc *p, const int rdonly_buf_size) __ksym; +void bpf_kfunc_call_int_mem_release(int *p) __ksym; + +/* The bpf_kfunc_call_test_static_unused_arg is defined as static, + * but bpf program compilation needs to see it as global symbol. + */ +#ifndef __KERNEL__ +u32 bpf_kfunc_call_test_static_unused_arg(u32 arg, u32 unused) __ksym; +#endif + +void bpf_testmod_standalone_test_mod_kfunc(int i) __ksym; + +__u64 bpf_kfunc_call_test1(struct sock *sk, __u32 a, __u64 b, + __u32 c, __u64 d) __ksym; +int bpf_kfunc_call_test2(struct sock *sk, __u32 a, __u32 b) __ksym; +struct sock *bpf_kfunc_call_test3(struct sock *sk) __ksym; +long bpf_kfunc_call_test4(signed char a, short b, int c, long d) __ksym; + +void bpf_kfunc_call_test_pass_ctx(struct __sk_buff *skb) __ksym; +void bpf_kfunc_call_test_pass1(struct prog_test_pass1 *p) __ksym; +void bpf_kfunc_call_test_pass2(struct prog_test_pass2 *p) __ksym; +void bpf_kfunc_call_test_mem_len_fail2(__u64 *mem, int len) __ksym; + +void bpf_kfunc_call_test_destructive(void) __ksym; + +void bpf_kfunc_call_test_offset(struct prog_test_ref_kfunc *p); +struct prog_test_member *bpf_kfunc_call_memb_acquire(void); +void bpf_kfunc_call_memb1_release(struct prog_test_member1 *p); +void bpf_kfunc_call_test_fail1(struct prog_test_fail1 *p); +void bpf_kfunc_call_test_fail2(struct prog_test_fail2 *p); +void bpf_kfunc_call_test_fail3(struct prog_test_fail3 *p); +void bpf_kfunc_call_test_mem_len_fail1(void *mem, int len); + +void bpf_kfunc_common_test(void) __ksym; +#endif /* _BPF_TESTMOD_KFUNC_H */ From patchwork Fri Nov 10 11:03:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13452344 X-Patchwork-Delegate: bpf@iogearbox.net Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 77EF1D308 for ; Fri, 10 Nov 2023 11:05:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="td1ZSRFZ" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61F092B78B for ; Fri, 10 Nov 2023 03:05:00 -0800 (PST) Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3A9MY1RX022422; Fri, 10 Nov 2023 11:04:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2023-03-30; bh=E3t/CzbBH2+mV+aLCIR2r1KVJtdifa2cgOteN2OEKLU=; b=td1ZSRFZKYrc98Jcy0xklgYFjjfixm34BiaBmwqfZbyk6HWwhkfpgRGoprgkpa7I1DL5 Ci1hZl4GtqG5SZ0yBuoR6S51zmjIruNHCLjoi4pBNEtl34N3O6DxtwNMVWew4gGf/oB9 BPmPdjTWG0YpcpHVdFkB8mmYsTn8keNleizcpnFzTek7zKXynopmlb7qs2HlGfGs+61b XcUMyUv+2KiilH0YD6y79anZx9ouQNquqwNw+nYMaTIbgSAXB/nBWQY01K285PfDMgG5 rshsW22hKle7pkY/mkaYH6XKMXiJNDfWxiOgpDPDXdvrCtVQm021PmiSeUYLjSswuS/b 9g== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3u7w2164rn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:42 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3AAA8JiD017516; Fri, 10 Nov 2023 11:04:41 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3u8c01qhfe-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Nov 2023 11:04:41 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3AAB3WgE018454; Fri, 10 Nov 2023 11:04:40 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-213-193.vpn.oracle.com [10.175.213.193]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3u8c01qfd7-18; Fri, 10 Nov 2023 11:04:40 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: jolsa@kernel.org, quentin@isovalent.com, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v3 bpf-next 17/17] selftests/bpf: update btf_module test to ensure standalone BTF works Date: Fri, 10 Nov 2023 11:03:04 +0000 Message-Id: <20231110110304.63910-18-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231110110304.63910-1-alan.maguire@oracle.com> References: <20231110110304.63910-1-alan.maguire@oracle.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.987,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-11-10_07,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 phishscore=0 spamscore=0 suspectscore=0 adultscore=0 bulkscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311100090 X-Proofpoint-GUID: y65U0eKKH-z-TZJGHeoTy4Wni0N5aH4F X-Proofpoint-ORIG-GUID: y65U0eKKH-z-TZJGHeoTy4Wni0N5aH4F X-Patchwork-Delegate: bpf@iogearbox.net btf_module test verifies that loading split BTF from bpf_testmod.ko is successful. To test standalone BTF, add a test that loads BTF from bpf_testmod_standalone.ko and verifies we can look up BTF, just as we could for real split BTF. Signed-off-by: Alan Maguire --- tools/testing/selftests/bpf/Makefile | 8 ++++---- .../selftests/bpf/prog_tests/btf_module.c | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 9c27b67bc7b1..5a4421238d5b 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -106,7 +106,7 @@ TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \ flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \ test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \ xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \ - xdp_features + xdp_features btf_testmod_standalone.ko TEST_GEN_FILES += liburandom_read.so urandom_read sign-file uprobe_multi @@ -225,9 +225,9 @@ $(OUTPUT)/sign-file: ../../../../scripts/sign-file.c $(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch]) $(call msg,MOD,,$@) - $(Q)$(RM) bpf_testmod/bpf_testmod.ko # force re-compilation + $(Q)$(RM) bpf_testmod/bpf_testmod*.ko # force re-compilation $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_testmod - $(Q)cp bpf_testmod/bpf_testmod.ko $@ + $(Q)cp bpf_testmod/bpf_testmod*.ko $(OUTPUT) DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool ifneq ($(CROSS_COMPILE),) @@ -728,7 +728,7 @@ EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \ prog_tests/tests.h map_tests/tests.h verifier/tests.h \ feature bpftool \ $(addprefix $(OUTPUT)/,*.o *.skel.h *.lskel.h *.subskel.h \ - no_alu32 cpuv4 bpf_gcc bpf_testmod.ko \ + no_alu32 cpuv4 bpf_gcc bpf_testmod*.ko \ liburandom_read.so) .PHONY: docs docs-clean diff --git a/tools/testing/selftests/bpf/prog_tests/btf_module.c b/tools/testing/selftests/bpf/prog_tests/btf_module.c index 2239d1fe0332..5470342a1d08 100644 --- a/tools/testing/selftests/bpf/prog_tests/btf_module.c +++ b/tools/testing/selftests/bpf/prog_tests/btf_module.c @@ -5,11 +5,13 @@ #include static const char *module_name = "bpf_testmod"; +static const char *standalone_module_name = "bpf_testmod_standalone"; static const char *symbol_name = "bpf_testmod_test_read"; +static const char *standalone_symbol_name = "bpf_testmod_standalone_test_read"; void test_btf_module() { - struct btf *vmlinux_btf, *module_btf; + struct btf *vmlinux_btf, *module_btf, *standalone_module_btf = NULL; __s32 type_id; if (!env.has_testmod) { @@ -26,9 +28,22 @@ void test_btf_module() goto cleanup; type_id = btf__find_by_name(module_btf, symbol_name); - ASSERT_GT(type_id, 0, "func not found"); + if (!ASSERT_GT(type_id, 0, "func not found")) + goto cleanup; + + if (!ASSERT_OK(load_bpf_testmod(standalone_module_name, false), "load standalone BTF module")) + goto cleanup; + + standalone_module_btf = btf__load_module_btf(standalone_module_name, vmlinux_btf); + if (!ASSERT_OK_PTR(standalone_module_btf, "could not load standalone module BTF")) + goto cleanup; + + type_id = btf__find_by_name(standalone_module_btf, standalone_symbol_name); + ASSERT_GT(type_id, 0, "func not found in standalone"); cleanup: + btf__free(standalone_module_btf); btf__free(module_btf); btf__free(vmlinux_btf); + unload_bpf_testmod(standalone_module_name, false); }