From patchwork Sun Nov 12 12:48:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453326 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 07A57648 for ; Sun, 12 Nov 2023 12:49:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="bTiyfPcD" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 698492D5B for ; Sun, 12 Nov 2023 04:49:04 -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 3ACChsUQ023710; Sun, 12 Nov 2023 12:48:44 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=C5jt4Q7tWVZFnGGb0eTPI3NHiRpXN7MnjPjR+tHMzKs=; b=bTiyfPcD8scKg6x4nSK59i7t2ELIJ2JLq/W3SJYZdKKMwO6EmiUNLighhXRm6L/5bqa6 nIFAoFp1w/aW+IdHNn2TelHDmP2MnbxlyMPlGnEkP81jQ68qK8FrmOS7kt4+oI/6SteS fEOOI5P7Bn7gkNLz44qyam33mMA/kVZYK/NDH0GpRtie78XCpcYqKnQxqEEO4KriMrRk TWG9xsel4R1pEOwPjMf0eOjt03Ow1gtFn9N4a29HXTZbUUHhV59J3UdowytRqX58zDYC OOa0nlcE/GOD1iMHwiBl6xXJd2QhP6vfT0Xsatij6EtvWJVmqX+l5eEDP3rjwwk94pgF KQ== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2mdhexx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:48:44 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCEZeE008972; Sun, 12 Nov 2023 12:48:43 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngffv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:48:43 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmce4029718; Sun, 12 Nov 2023 12:48:43 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-2; Sun, 12 Nov 2023 12:48:42 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 01/17] btf: add kind layout encoding, crcs to UAPI Date: Sun, 12 Nov 2023 12:48:18 +0000 Message-Id: <20231112124834.388735-2-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: -wR9c5TENAQE9lKMjk4OYsKT9CEgb4CT X-Proofpoint-ORIG-GUID: -wR9c5TENAQE9lKMjk4OYsKT9CEgb4CT 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..5cc8cc793cd2 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; /* currently unused */ + __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..5cc8cc793cd2 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; /* currently unused */ + __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 Sun Nov 12 12:48:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453327 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 9BCF5811 for ; Sun, 12 Nov 2023 12:49:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="MqZyaOO9" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 73E182D62 for ; Sun, 12 Nov 2023 04:49:06 -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 3ACCjJMb030563; Sun, 12 Nov 2023 12:48:48 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=0zB0lwzVbbOxxaN+/YtN9HrKGbspvfZZLc4/QRvopDw=; b=MqZyaOO9Y1mHqCLP52s4jjYKako0w/IG9Ie185nDCZdFtbytDzsGgXiNtVOBJDaTTz5R 4iNwznjoUSdGj7iEC8N4aWewF3N+7UxER7UKy3x0VM0fE3zMbDbc/xBVznRVH2rvb/Ah nu/KHaENI5M6yCtbupMmv+2+i6uuj0a5xE67n6IBcl4uqVDJKnw6ryt2sPkFcGXhuCxc Ioarzfa79Ki0GqKgc14FevErK66TClJDEv8Pt0JjOEYbcmex75+sT1CeMYXR17NmcEc0 jTQDxMpZfEEPgheC93DOaDxyoMtdaEGyQIqG1AMsy2ltj+1iIvAYXQcQ+zGWlme/8M7Y Rg== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2qd1e1w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:48:48 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCEGNf008467; Sun, 12 Nov 2023 12:48:47 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfgj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:48:47 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmce6029718; Sun, 12 Nov 2023 12:48:47 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-3; Sun, 12 Nov 2023 12:48:47 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 02/17] libbpf: support kind layout section handling in BTF Date: Sun, 12 Nov 2023 12:48:19 +0000 Message-Id: <20231112124834.388735-3-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-ORIG-GUID: HRlIwO_dC2-mtpOanlnvGqaTUe_GPtiD X-Proofpoint-GUID: HRlIwO_dC2-mtpOanlnvGqaTUe_GPtiD 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 | 218 +++++++++++++++++++++++++++++++------------- 1 file changed, 157 insertions(+), 61 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index ee95fd379d4d..1d043fe49d4c 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -39,42 +39,53 @@ 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; + struct btf_header *hdr; /* separately-allocated header data */ void *types_data; size_t types_data_cap; /* used size stored in hdr->type_len */ @@ -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 an allocated 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,32 @@ 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; + + 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 +1009,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) @@ -961,12 +1027,16 @@ void btf__free(struct btf *btf) * sections, so we need to free all of them individually. It * might still have a cached contiguous raw data present, * which will be unconditionally freed below. + * + * Optional kind layout information may be present too. */ - free(btf->hdr); free(btf->types_data); strset__free(btf->strs_set); + free(btf->kind_layout); } 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 +1044,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 +1072,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 +1128,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 +1136,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 +1504,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 +1516,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 +1535,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; @@ -1585,13 +1673,13 @@ 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. +/* Ensure BTF is ready to be modified (by splitting into memory regions + * for types and strings, with kind layout section if needed (btf->hdr + * is already a separate region). Also invalidate cached raw_data, if any. */ static int btf_ensure_modifiable(struct btf *btf) { - void *hdr, *types; + void *types, *kind_layout = NULL; struct strset *set = NULL; int err = -ENOMEM; @@ -1601,15 +1689,20 @@ static int btf_ensure_modifiable(struct btf *btf) return 0; } - /* split raw data into three memory regions */ - hdr = malloc(btf->hdr->hdr_len); + /* split raw data into memory regions; btf->hdr is done already. */ types = malloc(btf->hdr->type_len); - if (!hdr || !types) + if (!types) goto err_out; - - memcpy(hdr, btf->hdr, btf->hdr->hdr_len); memcpy(types, btf->types_data, btf->hdr->type_len); + if (btf->hdr->kind_layout_len && btf->hdr->kind_layout_off) { + 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)) { @@ -1618,11 +1711,12 @@ static int btf_ensure_modifiable(struct btf *btf) } /* only when everything was successful, update internal state */ - btf->hdr = hdr; btf->types_data = types; btf->types_data_cap = btf->hdr->type_len; btf->strs_data = NULL; btf->strs_set = set; + if (kind_layout) + btf->kind_layout = kind_layout; /* if BTF was created from scratch, all strings are guaranteed to be * unique and deduplicated */ @@ -1634,12 +1728,14 @@ 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 Sun Nov 12 12:48:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453328 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 9DF59136C for ; Sun, 12 Nov 2023 12:49:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="o2DlLPm2" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F23D2D5B for ; Sun, 12 Nov 2023 04:49:08 -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 3ACCj0ru028955; Sun, 12 Nov 2023 12:48:52 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=wTuenUrjhd7SdCb4K9JInjA2CPj+wlZnPCxMhg85txE=; b=o2DlLPm2pXIkwm3CC0veGjDWf9/52egImNPHR9q05qZ4HBfXn3lx/JfftHhVYli4Yo1P beHq9tWE03KN57GIJ0GlNUmT/kbE4zcIwQ5IqaY7C3CIu79bUT++8gHUe/3KIXMuPu0e H5FOnrk48p5en+bJ1jQ0aUag3GYeZHCw2F8VlnZRi0wVLcgiHKKby3nl2Q8Fox8OU9gn Ibu2T3sNVIgF0494J49IdshFAqS/wVMTp8w7UJER4RAPXctVGrQxTZrp5qZZvzIFPVWS 7s/Dpz4tIEYYuWirN+S/rlxc41nusJ/xffVZKFDYMsoxsrso6lODF2ftn055nLLZ//Nr PQ== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2qd1e20-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:48:52 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCELJw008866; Sun, 12 Nov 2023 12:48:51 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfhg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:48:51 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmce8029718; Sun, 12 Nov 2023 12:48:51 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-4; Sun, 12 Nov 2023 12:48:50 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 03/17] libbpf: use kind layout to compute an unknown kind size Date: Sun, 12 Nov 2023 12:48:20 +0000 Message-Id: <20231112124834.388735-4-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=932 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-ORIG-GUID: Hj_jxs9cH7vYXV88pJQQV19iWvAgq1cB X-Proofpoint-GUID: Hj_jxs9cH7vYXV88pJQQV19iWvAgq1cB 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 1d043fe49d4c..973da2b21df2 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -350,7 +350,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); @@ -386,8 +408,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); } } @@ -486,7 +507,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) { @@ -1862,7 +1883,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); @@ -1943,7 +1964,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; @@ -4939,7 +4960,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 Sun Nov 12 12:48:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453330 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 A63C28BEA for ; Sun, 12 Nov 2023 12:49:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="gR32dZNK" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8FD472D62 for ; Sun, 12 Nov 2023 04:49:22 -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 3ACCj8BG032220; Sun, 12 Nov 2023 12:48:57 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=Nvd913U0oKOPWtcS2wmOvMxR+DFRt5XP4ZTY0Qmag/o=; b=gR32dZNK1UWIV5Gkc6ou7uRlk3wDo0sKFSA2YaQEGMTPx/I/us9qB7WZq/Gb64LyE37Y ajbSbbMqoYDQZLE+42adRaldmkeyCYGWWT8+p7Ki4gMiSk66IA/YPhQeUXyF0k6R50PT NRm5KQpKC8c+eDjGBi4Co+kWGVZeVyc+uJNqcaMwfrc8sei7+LmT31zog8exbbHpRAag 4Ru65k4QA/RmVlOzDElMaIpCfW8VyBDWk0aHCKiMf0CK+OsZ3Xa3GAPkZiZQAxLEQ1J8 TE/FQ3PYx+aJoEBhr+WMohoy0Jpt/kQM3O2DsoCftBryPiQEWu1NzF8ZzWiquBzNnaPN 8w== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2sthe4t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:48:57 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCEkkC009001; Sun, 12 Nov 2023 12:48:56 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfj0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:48:56 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceA029718; Sun, 12 Nov 2023 12:48:55 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-5; Sun, 12 Nov 2023 12:48:55 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 04/17] libbpf: add kind layout encoding, crc support Date: Sun, 12 Nov 2023 12:48:21 +0000 Message-Id: <20231112124834.388735-5-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: -usB780JpVelgIrTFGBRdLCr3YPV8r_z X-Proofpoint-ORIG-GUID: -usB780JpVelgIrTFGBRdLCr3YPV8r_z 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 | 80 ++++++++++++++++++++++++++++++++++++++-- tools/lib/bpf/btf.h | 11 ++++++ tools/lib/bpf/libbpf.map | 1 + 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 973da2b21df2..fa6104860ebc 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; @@ -1063,8 +1093,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; @@ -1106,6 +1137,29 @@ static struct btf *btf_new_empty(struct btf *base_btf) free(btf); return ERR_PTR(-ENOMEM); } + + if (opts->add_kind_layout) { + hdr->kind_layout_len = sizeof(kind_layouts); + btf->kind_layout = malloc(hdr->kind_layout_len); + if (!btf->kind_layout) { + free(btf->hdr); + free(btf); + return ERR_PTR(-ENOMEM); + } + memcpy(btf->kind_layout, kind_layouts, 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; @@ -1113,12 +1167,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) @@ -1564,6 +1632,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 Sun Nov 12 12:48:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453333 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 7454C8832 for ; Sun, 12 Nov 2023 12:49:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="pZ1v8Xo2" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8904330CB for ; Sun, 12 Nov 2023 04:49:29 -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 3ACCiLml031479; Sun, 12 Nov 2023 12:49:02 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=yamFn1ACTVB7D2hCMqNWe0LbBk0OTjp7Ql85H2s9Mc8=; b=pZ1v8Xo2z7xVS2X+Kv+U61Na5RmhVmER34C5wtgAWnHj8PmWKK3XIuWnRCWbgKge4lvJ 3kGDv/mYLpP3VXp/oYKQMa5EYN9nCy/z+Z3cxW/yQfv6aJkh1RtAibX74pc9eAkfPehe AIiLj3UxrReY0h/ZXVEkrya8KNY1MVkrkHFO/KlrIlHTfTT07WG4U938B2V/MDJZlaw8 08f5lLcmqnfThT28LS1R0SMBr21iacAIChJGCbhClLh5S7xDxfqlOy0N8/reSuZ5Xuat pLyALooiSx6gn/ebsiL+v5ntZ8/yotTZO6exTH2PoAr8QXh7KtRTQr3C1pP5MOIq0jCb mg== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2sthe4v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:02 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCEZeG008972; Sun, 12 Nov 2023 12:49:00 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfk1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:00 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceC029718; Sun, 12 Nov 2023 12:49:00 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-6; Sun, 12 Nov 2023 12:48:59 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 05/17] libbpf: BTF validation can use kind layout for unknown kinds Date: Sun, 12 Nov 2023 12:48:22 +0000 Message-Id: <20231112124834.388735-6-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: MWmgoGq2yCU9trlm5VSzL2v6CuDTP08Y X-Proofpoint-ORIG-GUID: MWmgoGq2yCU9trlm5VSzL2v6CuDTP08Y 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 fa6104860ebc..b0f8d735debb 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -698,8 +698,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 Sun Nov 12 12:48:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453331 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 93C83648 for ; Sun, 12 Nov 2023 12:49:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="iCRXbQ0e" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 466FC30C2 for ; Sun, 12 Nov 2023 04:49:24 -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 3ACCiX1d016531; Sun, 12 Nov 2023 12:49:06 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=Q+gxxl7jNRWaHj64WM5NFv4eWz46znwG7jPNPO9i83I=; b=iCRXbQ0eHMQ8DhfBIxBxOdHp/G0coJz8+83ocWGDiW3/MdC4WI5zc7mY3xiQSuvRgW2R LASxiP+Zm21vRTc4hXw6io7Brq+sHvhdY9Zy0Vn32/4YXpB8xchn28LwpftVYOIqfni3 T7PE9UAaP5dchOxtRXsszMabX/dGjgKBfTcDLvCd0bQiTKkjdzsVGNt4u73Qm/NiclCY nnwhKUrrN7YJ0y0ZFJMYBOEu0rcJ9UYlfLqZegdtHl3UUhuHwRvP9Pvrw4U2wytqVZU3 fqFsRUY9aXvYHhvrun2RjhZb5VEcg33/Jdjn1qAaJPHJvBGZsM0xYEWfrSG0es6bd2zb 0Q== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2m29e8g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:06 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCFBje009314; Sun, 12 Nov 2023 12:49:04 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfkq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:04 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceE029718; Sun, 12 Nov 2023 12:49:04 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-7; Sun, 12 Nov 2023 12:49:04 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 06/17] btf: support kernel parsing of BTF with kind layout Date: Sun, 12 Nov 2023 12:48:23 +0000 Message-Id: <20231112124834.388735-7-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: HQA0_x7U9G8167g1OYEupkK2vg3XjgNU X-Proofpoint-ORIG-GUID: HQA0_x7U9G8167g1OYEupkK2vg3XjgNU 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 63cf4128fc05..554b5b795d6f 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; @@ -4969,23 +4970,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; @@ -5159,7 +5173,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; } @@ -5180,9 +5195,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) @@ -5197,44 +5244,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 */ @@ -5297,7 +5349,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; } @@ -5534,6 +5586,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 Sun Nov 12 12:48:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453332 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 A5D1763D3 for ; Sun, 12 Nov 2023 12:49:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="jD18tR9c" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC3E42D64 for ; Sun, 12 Nov 2023 04:49:27 -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 3ACCiL2H012886; Sun, 12 Nov 2023 12:49:10 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=61TYyj5H8+eGFzSL11VBzh4G3fjDb1CAqf8B71EAdCY=; b=jD18tR9cVG7tvqRAHMOrTNgDXW+WtJ6sBwfKdb6xNy6H9FiQI7WR3oBsRyLD6NbevA3R ZaX7KkkEcE1dvTsNOQUEtq3j+nXoM5ZOpHyLFvtpJ5xCebnyXTfoaq465v+G13WyDDXT QRNaJUpjdCVXY1zdyBqx81IZFZXV/8WKy8bLdDHHQjcI0yHHplz0vkMjhc47MQdWDQT6 kOfh1Aj7o0WFPFrfDCpmRkbh09ydPzgUxvZTRbRxZuV271sIw3RZcZBTApp62AVmBF+a /+ZDr6M1MOpM3Z/vUnJYY5zOKE+L0hAWoq7DuhOTCVVGCQIcyH+I3qB7fj8ofIG/jz05 bg== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2r01eq9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:10 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCEGNi008467; Sun, 12 Nov 2023 12:49:09 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfmd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:09 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceG029718; Sun, 12 Nov 2023 12:49:08 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-8; Sun, 12 Nov 2023 12:49:08 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire , Alexei Starovoitov Subject: [PATCH v4 bpf-next 07/17] bpf: add BTF CRC verification where present Date: Sun, 12 Nov 2023 12:48:24 +0000 Message-Id: <20231112124834.388735-8-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-ORIG-GUID: ws70et_2i-tqNoq0iRrVm0x3D4vnCIqz X-Proofpoint-GUID: ws70et_2i-tqNoq0iRrVm0x3D4vnCIqz 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 554b5b795d6f..96c553e40b43 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -5354,6 +5355,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 Sun Nov 12 12:48:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453334 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 857D18495 for ; Sun, 12 Nov 2023 12:49:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="0IqfxAT0" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 935FB2D5B for ; Sun, 12 Nov 2023 04:49:31 -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 3ACCiaxj012933; Sun, 12 Nov 2023 12:49: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=aSLUpO+Oy9+9EXWKffUG2LeokwAiROZm+yzgXOAg7wM=; b=0IqfxAT0m/JzNgs/hPPRdQUx7ImltCVrKXsdyPvdVXaCgPm0jLNl4f2a/XHu7onJKqAA vAlUQXAI0xj9SlQax5Jb0ov++fPL4pvzitQ7Xq7DhIq2vckJU3bHRoYsx24lCGvbHF9Z 0lxIIi5/AGlQUidEImpDgEgYhMQTL3ifOdT2zm8oFxFg6QKMCeaxCMYpNGoNmQceD3WZ AgqOK/P71A0CTDFX17U8VSWgP2T99eMWwjan4DdnP6rQ9CKsmCGW6g+NP/s1A3BXHpkX k/q1hxsQ7FbAUEi7f7rx+QZNOHaTX/l5jHzGyFGqJ3ZfSQoO6DqViwr3j3WMaqXD/ygh hQ== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2r01eqa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:14 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCF8wb009277; Sun, 12 Nov 2023 12:49:13 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfn9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:13 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceI029718; Sun, 12 Nov 2023 12:49:12 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-9; Sun, 12 Nov 2023 12:49:12 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 08/17] bpf: verify base BTF CRC to ensure it matches module BTF Date: Sun, 12 Nov 2023 12:48:25 +0000 Message-Id: <20231112124834.388735-9-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-ORIG-GUID: QKB4y27Rd1SnReSKakYam1Tn7btLMWdk X-Proofpoint-GUID: QKB4y27Rd1SnReSKakYam1Tn7btLMWdk 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 96c553e40b43..a51dc3ef6a56 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -5369,6 +5369,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 Sun Nov 12 12:48:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453335 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 BE7F9648 for ; Sun, 12 Nov 2023 12:49:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="dfJzzei3" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDA1C2D64 for ; Sun, 12 Nov 2023 04:49:35 -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 3ACCiope031638; Sun, 12 Nov 2023 12:49: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=2A0noEcPZRk9vO9efuZPj783oUGGJPiH8HIglN5iNmA=; b=dfJzzei3XYGT4jPcsuZSP+yiAzutPDpKKYVRYS15sIjjgbDOC+Tzj1UZugaBhuwStCON kr1ma4RNwfFC7EuU9qPkvYSY7rXXRz6XKJNPH9MRLvxPY6jn6v4MCfn8hNsKIHE1D+OJ UxiZuOS1eh+SQbHTjkvbRfaEcjvAImBt9cdZKL2H/57XtOr6Fk2nIZlXXZyvaZJbKw9N 8Ay0S4nYDciYDV0/XIqvAQZzGNqZIwKFLNJUjLLynugQzo1Gyc+sqACXWl611Jas4fp4 F3nGJ1GHlemPItPQVb/c8l8OfEEaa+2WoFItTML/qulA4P4OxK8QJSmM6hxX8/Pwvvug /w== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2sthe53-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:18 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCENCi008877; Sun, 12 Nov 2023 12:49:17 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfnw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:17 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceK029718; Sun, 12 Nov 2023 12:49:16 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-10; Sun, 12 Nov 2023 12:49:16 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 09/17] kbuild, bpf: switch to --btf_features, add crc,kind_layout features Date: Sun, 12 Nov 2023 12:48:26 +0000 Message-Id: <20231112124834.388735-10-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: 4x_eiEopxNJrSH83pDkq7mjoPUIhZZ9K X-Proofpoint-ORIG-GUID: 4x_eiEopxNJrSH83pDkq7mjoPUIhZZ9K 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/Makefile.btf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf index 82377e470aed..f8ce33d7f9bb 100644 --- a/scripts/Makefile.btf +++ b/scripts/Makefile.btf @@ -16,4 +16,6 @@ pahole-flags-$(CONFIG_PAHOLE_HAS_LANG_EXCLUDE) += --lang_exclude=rust pahole-flags-$(call test-ge, $(pahole-ver), 125) += --skip_encoding_btf_inconsistent_proto --btf_gen_optimized +pahole-flags-$(call test-ge, $(pahole-ver), 126) = -j --lang_exclude=rust --btf_features=encode_force,var,float,decl_tag,type_tag,enum64,optimized_func,consistent_func,crc,kind_layout + export PAHOLE_FLAGS := $(pahole-flags-y) From patchwork Sun Nov 12 12:48:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453336 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 E0D80811 for ; Sun, 12 Nov 2023 12:49:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="FD577E/L" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 59E1A2D64 for ; Sun, 12 Nov 2023 04:49:40 -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 3ACCiXNR016532; Sun, 12 Nov 2023 12:49:23 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=FD577E/LiLdLgyd5NnCXp40zyKuSOA0DJnC+diKbSpqgIKN25HAd1k5TX6TAvaOrC6/b 3+v9hWQqQscRfXCQSVPoW62KvBtYnBpzIGcoiXdllkloxiWU4rOIJnJ4rxnjm+wiVZS8 OmYkbbVt0rc4wewAmWO1hMS+MmVyVbTYShaAMSgNEpOlWLRJtd/S6/GYyndb//VxDkdS M4lYG0bmd3ghlO0dE4OGHO2v+vhEb6oWV4I39Pa39QfggKwSqmP1iIi4HLFRtwmrUII/ rZu8CDOZbajlLGwJpHmE4n9jCmzDUG90C0gKs7/+OEQ0JYteCCoRIB2DNo3uEmsYYEI6 SQ== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2m29e8p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:22 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCEZeL008972; Sun, 12 Nov 2023 12:49:21 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfpu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:21 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceM029718; Sun, 12 Nov 2023 12:49:20 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-11; Sun, 12 Nov 2023 12:49:20 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 10/17] bpftool: add BTF dump "format meta" to dump header/metadata Date: Sun, 12 Nov 2023 12:48:27 +0000 Message-Id: <20231112124834.388735-11-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: R-Q1hOToc5e5nLrQhqS-KADRyKNSUwU4 X-Proofpoint-ORIG-GUID: R-Q1hOToc5e5nLrQhqS-KADRyKNSUwU4 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 Sun Nov 12 12:48:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453337 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 20A15648 for ; Sun, 12 Nov 2023 12:49:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="0stlijWA" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3682C2D5B for ; Sun, 12 Nov 2023 04:49:43 -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 3ACCiHEr012817; Sun, 12 Nov 2023 12:49: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=duGHp55YrRgxpthIBFv+XMYAuTI83o5ozohkSNbz4Gg=; b=0stlijWA5giqH6ssWMaKgFXfoVBDuhHz87xNxucF1Wf7zqLdU4mSenh7+bvA301Ceg2b kzmc0bKeRvBgo89qVMD5/e2X8qu/UIV5/4I/ObO1onLHnLf0TymV8s/xFrA4RwrSDbOt cJE2wNzpjOkQhVcf0kq3OOVKFQEvJG9XvA8Rjc3ak+iS6tMmlglowYLUrXTTd02VrsC/ peN3mfqiSJuzzfHFBTPO2F5bHUFhT/NN6xBb0Yo2JR7kHdCsn6WOHOdJTJ4j0zT4066J bUCIh7MhRzYlR44aWVXUHmg/hwWsPzshORSJsg9bSXUeOfqW32Y++P6oSPD2pMNkg7uq KQ== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2r01eqg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:26 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCFBjk009314; Sun, 12 Nov 2023 12:49:25 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfqb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:25 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceO029718; Sun, 12 Nov 2023 12:49:24 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-12; Sun, 12 Nov 2023 12:49:24 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 11/17] bpftool: update doc to describe bpftool btf dump .. format meta Date: Sun, 12 Nov 2023 12:48:28 +0000 Message-Id: <20231112124834.388735-12-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-ORIG-GUID: 7V5_hlsSOkNwhv9sdOH3AgTLBGs8h7k1 X-Proofpoint-GUID: 7V5_hlsSOkNwhv9sdOH3AgTLBGs8h7k1 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 Sun Nov 12 12:48:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453338 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 BBF3A648 for ; Sun, 12 Nov 2023 12:49:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="KGgntZ81" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6E4012D62 for ; Sun, 12 Nov 2023 04:49:49 -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 3ACCjK8H018741; Sun, 12 Nov 2023 12:49:30 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=KGgntZ810aXVaVsrWaZ57CUeqXcHOw83ePWMFKSdXQLrgRvp1fB4wRzwDhbt+ihv5820 e7OEgdHxUnegc/gRUZkdEzdgi+DAAtz1gJgsTSXPpDNYmnoWCjIN1p0yY1kxcmjLdnIQ VnXP5z5Qt5WDDBhYyPKsKKqkCu10GyWLMYwzj7rqznJtducodbeSV0k4uBqSQL3HCg6f 4bSklC0KY72W1OLNjdowQAAwWBY1+5VYSjuGNULlLvAVRowBJyXX5fgeCLEx9lN+03MK UWGrFXT4MC+WoiI0LNpKz6y4GLV6KxJANNMPnN49YKo55r2Y5KTRqCHWi1hvjWd1iSev 9w== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2m29e8s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:30 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCELK4008866; Sun, 12 Nov 2023 12:49:29 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfr1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:29 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceQ029718; Sun, 12 Nov 2023 12:49:28 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-13; Sun, 12 Nov 2023 12:49:28 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 12/17] selftests/bpf: test kind encoding/decoding Date: Sun, 12 Nov 2023 12:48:29 +0000 Message-Id: <20231112124834.388735-13-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: DnJGBPVY1kiWjV3P8BmxfYcxV66oMKD1 X-Proofpoint-ORIG-GUID: DnJGBPVY1kiWjV3P8BmxfYcxV66oMKD1 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 Sun Nov 12 12:48:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453339 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 A79CB3C07 for ; Sun, 12 Nov 2023 12:49:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="2eiTSK94" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 100732D5B for ; Sun, 12 Nov 2023 04:49:51 -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 3ACChtuc027096; Sun, 12 Nov 2023 12:49: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=ivUum2/JCj+FtHFoYVk5pljkUMu4OxwJi22XKzZlXxg=; b=2eiTSK94+unfbgC72ZOuS6C5BZWoPzWEu+r5LE9WXFyUFE7xfYsChzS3dcpKDooOdcs1 dxIaPFE4A7VrS+pspg/op3IOGv6lsBGGhSPRs4l6lpYxQPXPI0pA/YOWqTohVmWUprDN dMC9ZVa/i/QssVv3fUKwxbMZN94x1zBnrAngGsEwD8NI7+F3mD+F3o7kynVDvVjXf940 ewPttQJkRvYX65zyPon2XQ6TIuXRdqzV8aIwxyT/3EQqJovYfrtWJe/veRcIN6wjzNxM ZITmwMtMpHM/7ExQP0QgAXhuWhpM6qZ9NAAXFwTXSbOPzM3EZOQ7p/a3WA3JbbLnJuus Qg== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2qd1e24-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:33 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCENCj008877; Sun, 12 Nov 2023 12:49:33 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfrp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:33 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceS029718; Sun, 12 Nov 2023 12:49:32 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-14; Sun, 12 Nov 2023 12:49:32 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 13/17] bpf: support standalone BTF in modules Date: Sun, 12 Nov 2023 12:48:30 +0000 Message-Id: <20231112124834.388735-14-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-ORIG-GUID: JM8H4v6eD3iMnxWrq2ch9iDKUSRNaSnp X-Proofpoint-GUID: JM8H4v6eD3iMnxWrq2ch9iDKUSRNaSnp 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 a51dc3ef6a56..412184ade0f1 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 { @@ -5882,6 +5883,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; @@ -5933,10 +6181,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; @@ -7876,6 +8143,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); @@ -7936,7 +8213,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; @@ -8005,7 +8281,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; @@ -8063,6 +8346,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; @@ -8156,6 +8445,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 Sun Nov 12 12:48:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453340 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 AB7658832 for ; Sun, 12 Nov 2023 12:49:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="tlQrPTpc" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8CF72D5B for ; Sun, 12 Nov 2023 04:49:54 -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 3ACChvTp023723; Sun, 12 Nov 2023 12:49: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=gKHJWU0T2PN4V4H8YnwkWPyMqTCCKQoI5Xp1gDDfh2o=; b=tlQrPTpcrAc37wSTsct5Fzp7wERYCv0bENtn7ZXATCK6ohkEFaJJ9vjs4R8tGzJ39poi wSskW2DL3b9q3HEZT6dM6G4keSPZ9AFI2oRWx161ZMLxb22rY7ZJfpcY6W276Lmrx7Iy xCjuapesES/YQKjtrZzr4nyWeN/VwTftNzwFU9Bf08+Ui/3Vm9PUIMitovSGBF/5wVmr HKUTaJaTbt1EVdsTnBHs04I/rT0eunIX0Na1iAYYqEY85BedDAdgbfYZMWlKQiBYngoX Kp1A7JHgYvY5IA+aK4LFkS9iOIgHF5jJlO1WdpCAFG3VYvjuMvm+G4b8vE5U7lAtKKJ5 oA== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2mdhey7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:37 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCEP1x008885; Sun, 12 Nov 2023 12:49:37 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfsb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:37 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceU029718; Sun, 12 Nov 2023 12:49:36 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-15; Sun, 12 Nov 2023 12:49:36 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 14/17] kbuild, bpf: allow opt-out from using split BTF for modules Date: Sun, 12 Nov 2023 12:48:31 +0000 Message-Id: <20231112124834.388735-15-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: zrSjkRWugFzXNqQ2w0nVcINF8Zn7Kw4v X-Proofpoint-ORIG-GUID: zrSjkRWugFzXNqQ2w0nVcINF8Zn7Kw4v 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.btf | 3 +++ scripts/Makefile.modfinal | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf index f8ce33d7f9bb..352271a10fb5 100644 --- a/scripts/Makefile.btf +++ b/scripts/Makefile.btf @@ -19,3 +19,6 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125) += --skip_encoding_btf_inconsis pahole-flags-$(call test-ge, $(pahole-ver), 126) = -j --lang_exclude=rust --btf_features=encode_force,var,float,decl_tag,type_tag,enum64,optimized_func,consistent_func,crc,kind_layout export PAHOLE_FLAGS := $(pahole-flags-y) + +# Allow opt-out of split BTF by overriding BTF_BASE +export BTF_BASE := --btf_base vmlinux diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 8568d256d6fb..3400d1a72127 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -39,8 +39,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 Sun Nov 12 12:48:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453341 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 A225D525A for ; Sun, 12 Nov 2023 12:50:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="goFMqafW" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55D3C2D64 for ; Sun, 12 Nov 2023 04:49: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 3ACCiiJl006420; Sun, 12 Nov 2023 12:49: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=j/xT3Hk030zCDc/bbVIEG56D3U6crXbdraI3B6XtZKk=; b=goFMqafWrzyoqKMTBEgQ+zWDfi7U9iBjUiO2UWsoJjXMVE1F84x6SgmO6DnzmEWavJkz KnuYSDmus/nq78H6LyGhICnkRXsAzHr2nvEhBoE2eBbxSdkis8W8+a2poCwJklcoEr0I Poui9g48scO1cALj/rwpZULCyq9G2yhjEoyCzD0thw9QCi394AroPNcs3JURz+BK8vUk GlVhnBta+eDQ2hCZAkwdvV5N2ut7FjmFg66nDNHqVBl1A/Cq3C0aEmDkBsYCmF7PGNhX QydlxuqRDK4UjojTcI6K5C6C2ssstXnk4gF6lFv+LZaWD3MtJq474Nu/rBlyOV3NMvbD xw== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2n39e2d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:42 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCFCuH009374; Sun, 12 Nov 2023 12:49:41 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfsy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:40 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceW029718; Sun, 12 Nov 2023 12:49:40 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-16; Sun, 12 Nov 2023 12:49:40 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 15/17] selftests/bpf: generalize module load to support specifying a module name Date: Sun, 12 Nov 2023 12:48:32 +0000 Message-Id: <20231112124834.388735-16-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: 4Ht93aZbbui6vi2lS5JlGpD2xuWUO6kb X-Proofpoint-ORIG-GUID: 4Ht93aZbbui6vi2lS5JlGpD2xuWUO6kb 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 Sun Nov 12 12:48:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453343 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 6ED17136C for ; Sun, 12 Nov 2023 12:50:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="2BgJRgW4" Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC26130C2 for ; Sun, 12 Nov 2023 04:50:04 -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 3ACCiSwr012913; Sun, 12 Nov 2023 12:49:47 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=xKpzMlIPVcX7sZfuorZdtGd7QFBKIZzjpa4Z9V8e9UA=; b=2BgJRgW44X/WwVV03vfRujExQkYXfOBwJj7J33+nsgTC4HdgviMbUbQiOEP2KOlYXmMG lS7txSxsZVSNFelTpbV6eCWbrrXoocba2cbDy04WkAQ7CfqwmEM+b29UPwZySkOqq2VL jx/Ai8eLbIseLnrLd2Rj+lCF/dJ244BoasEyxP/OFO4CtWZRHPaOfgiqW95/JswIxOzh aYs0XJAbSWT8zo5wcSuzRKE/mNbhsayh8IsF06gPeDJIE3zQtUFS7dABP5d448uEKnHJ fSkAwuLPfT0R11Vmnd8H0Bxir/48F49aefibqaSGrkMuM+Zo5xQ5JlGipC1A/cPiDZ/q pg== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2r01eqq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:46 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCF7EL009258; Sun, 12 Nov 2023 12:49:45 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngftk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:45 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmceY029718; Sun, 12 Nov 2023 12:49:44 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-17; Sun, 12 Nov 2023 12:49:44 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 16/17] selftests/bpf: build separate bpf_testmod module with standalone BTF Date: Sun, 12 Nov 2023 12:48:33 +0000 Message-Id: <20231112124834.388735-17-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-ORIG-GUID: q7C1877-FWVJzqFdkI4TCXB6kc4A_kOO X-Proofpoint-GUID: q7C1877-FWVJzqFdkI4TCXB6kc4A_kOO 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 mainly 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. kfunc iters were also renamed. Signed-off-by: Alan Maguire --- .../selftests/bpf/bpf_testmod/Makefile | 10 +- .../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, 755 insertions(+), 3 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..d7ca383b1b0d 100644 --- a/tools/testing/selftests/bpf/bpf_testmod/Makefile +++ b/tools/testing/selftests/bpf/bpf_testmod/Makefile @@ -7,13 +7,17 @@ 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: - +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) modules + +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) bpf_testmod.ko + +$(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..a0d7d1ade6ff --- /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_standalone_seq_new(struct bpf_iter_testmod_standalone_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_standalone_seq_next(struct bpf_iter_testmod_standalone_seq *it) +{ + if (it->cnt <= 0) + return NULL; + + it->cnt--; + + return &it->value; +} + +__bpf_kfunc void bpf_iter_testmod_standalone_seq_destroy(struct bpf_iter_testmod_standalone_seq *it) +{ + it->cnt = 0; +} + +__bpf_kfunc void bpf_kfunc_standalone_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_standalone_seq_new, KF_ITER_NEW) +BTF_ID_FLAGS(func, bpf_iter_testmod_standalone_seq_next, KF_ITER_NEXT | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_iter_testmod_standalone_seq_destroy, KF_ITER_DESTROY) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_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_standalone_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d) +{ + return a + b + c + d; +} + +__bpf_kfunc int bpf_kfunc_standalone_call_test2(struct sock *sk, u32 a, u32 b) +{ + return a + b; +} + +__bpf_kfunc struct sock *bpf_kfunc_standalone_call_test3(struct sock *sk) +{ + return sk; +} + +__bpf_kfunc long noinline bpf_kfunc_standalone_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_standalone_call_test_acquire(unsigned long *scalar_ptr) +{ + refcount_inc(&prog_test_struct.cnt); + return &prog_test_struct; +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_offset(struct prog_test_ref_kfunc *p) +{ + WARN_ON_ONCE(1); +} + +__bpf_kfunc struct prog_test_member * +bpf_kfunc_standalone_call_memb_acquire(void) +{ + WARN_ON_ONCE(1); + return NULL; +} + +__bpf_kfunc void bpf_kfunc_standalone_call_memb1_release(struct prog_test_member1 *p) +{ + WARN_ON_ONCE(1); +} + +static int *__bpf_kfunc_standalone_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_standalone_call_test_get_rdwr_mem(struct prog_test_ref_kfunc *p, + const int rdwr_buf_size) +{ + return __bpf_kfunc_standalone_call_test_get_mem(p, rdwr_buf_size); +} + +__bpf_kfunc int *bpf_kfunc_standalone_call_test_get_rdonly_mem(struct prog_test_ref_kfunc *p, + const int rdonly_buf_size) +{ + return __bpf_kfunc_standalone_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_standalone_call_test_acq_rdonly_mem(struct prog_test_ref_kfunc *p, + const int rdonly_buf_size) +{ + return __bpf_kfunc_standalone_call_test_get_mem(p, rdonly_buf_size); +} + +__bpf_kfunc void bpf_kfunc_standalone_call_int_mem_release(int *p) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_pass_ctx(struct __sk_buff *skb) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_pass1(struct prog_test_pass1 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_pass2(struct prog_test_pass2 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_fail1(struct prog_test_fail1 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_fail2(struct prog_test_fail2 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_fail3(struct prog_test_fail3 *p) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_mem_len_pass1(void *mem, int mem__sz) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_mem_len_fail1(void *mem, int len) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_mem_len_fail2(u64 *mem, int len) +{ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_ref(struct prog_test_ref_kfunc *p) +{ + /* p != NULL, but p->cnt could be 0 */ +} + +__bpf_kfunc void bpf_kfunc_standalone_call_test_destructive(void) +{ +} + +__bpf_kfunc static u32 bpf_kfunc_standalone_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_standalone_call_test1) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test2) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test3) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test4) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_mem_len_pass1) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_mem_len_fail1) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_mem_len_fail2) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_acquire, KF_ACQUIRE | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_memb_acquire, KF_ACQUIRE | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_memb1_release, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_get_rdwr_mem, KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_get_rdonly_mem, KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_acq_rdonly_mem, KF_ACQUIRE | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_int_mem_release, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_pass_ctx) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_pass1) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_pass2) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_fail1) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_fail2) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_fail3) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_ref, KF_TRUSTED_ARGS | KF_RCU) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_destructive, KF_DESTRUCTIVE) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_call_test_static_unused_arg) +BTF_ID_FLAGS(func, bpf_kfunc_standalone_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..a8a4d75d9a1d --- /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_standalone_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 Sun Nov 12 12:48:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Maguire X-Patchwork-Id: 13453342 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 27EDD63D3 for ; Sun, 12 Nov 2023 12:50:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="gq34GHqv" Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B545E2D5B for ; Sun, 12 Nov 2023 04:50:06 -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 3ACCiKlm023961; Sun, 12 Nov 2023 12:49:50 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=gq34GHqvYaMlBb3EyWwkRR04ZEvhjwbK0aFpCiJDKkz1eFI+WrIKvsjqFw/6EX3giitC CruSSdZcozEropbq8cuJYLKHIb+P4Zr+XEzStNnuIoiWHwq9fXcv9IzCea3Cw/w1nb2O 1ihMqlh0SIknTtkJPx/1XuaeQir0UiAhEYLiE8kKFhBjyJyZjW6sk9LllfXYpZgDNH44 b8iiRaY1jc6E0GZU/8ZCwavMIW40NSc2yQsPvT59DIJu7bgkpRjgOLsjpkWgomsdq0DQ ZLmmXlYSXGXBSxrKrXpgg7uOur3RweOfdSvcdgVO/jKeg/i2PTp48ypix5wljrAnqA2/ +A== Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.appoci.oracle.com [130.35.100.223]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3ua2mdheya-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:49 +0000 Received: from pps.filterd (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 3ACCFEbH009418; Sun, 12 Nov 2023 12:49:49 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3uaxhngfu1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 12 Nov 2023 12:49:49 +0000 Received: from iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3ACCmcea029718; Sun, 12 Nov 2023 12:49:48 GMT Received: from bpf.uk.oracle.com (dhcp-10-175-173-14.vpn.oracle.com [10.175.173.14]) by iadpaimrmta01.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 3uaxhngfep-18; Sun, 12 Nov 2023 12:49:48 +0000 From: Alan Maguire To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, jolsa@kernel.org Cc: 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, masahiroy@kernel.org, bpf@vger.kernel.org, Alan Maguire Subject: [PATCH v4 bpf-next 17/17] selftests/bpf: update btf_module test to ensure standalone BTF works Date: Sun, 12 Nov 2023 12:48:34 +0000 Message-Id: <20231112124834.388735-18-alan.maguire@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20231112124834.388735-1-alan.maguire@oracle.com> References: <20231112124834.388735-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-12_10,2023-11-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311060000 definitions=main-2311120113 X-Proofpoint-GUID: U7lhRgiVLZ2wXzvI1hL9MM4BXJK-fDnV X-Proofpoint-ORIG-GUID: U7lhRgiVLZ2wXzvI1hL9MM4BXJK-fDnV 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); }