Received: by 2002:a05:6358:e9c4:b0:b2:91dc:71ab with SMTP id hc4csp1433472rwb; Fri, 5 Aug 2022 01:37:58 -0700 (PDT) X-Google-Smtp-Source: AA6agR4xa/8yZUWVuqTyLh/VQFhPTiSHTXXxyS03boKGbAb5N53HpwiET1eNKJnitX9FiL/4voOV X-Received: by 2002:a17:90b:4f44:b0:1f5:1310:9e7f with SMTP id pj4-20020a17090b4f4400b001f513109e7fmr14879415pjb.235.1659688678453; Fri, 05 Aug 2022 01:37:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659688678; cv=none; d=google.com; s=arc-20160816; b=F1IOqp9Rs4tG7QNkdFEBIS06AtNYojSaMr24en9cnztBPRfclBupq2mpNN9vnxtPhZ RwqOfM76hLF0G3HHY0DjotaeQ8dCuBhRkh0r2gPUIANqhGvs19AgfnHnPkwvs6uKV8se 6YGPDTcknVU8QF8EYW5LpSe4j+0U844e38VdGXjgoH8mkLOCmxqSthRK0b+GWU2qncfY 9vT6SlSaw+8woFsUTJ77HcrlbCG+TpYvMLkcTNC4tL5x2wm4AQ2IL2tWT12514pGuVFa 3T5oINWEvDzXnEuWdB+qkOhoCnXZs8NoF72P0/ITDgUzk2wsLx56wBj0tA1GMiIvlnF1 WuMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=ZWk9ma5M79Z4Wqhxv3DfLZj3YkPOjUsw905Ysq/x12o=; b=h7qhhngaBJNmE9meknhnvaLmEV/Hnw0I8Cl07evN82KeUfS0QodjijwymigGP/YffR /LUUnC6jbFcSJw6X5+iR+/nzflkvQWdfhnr0CuUd2/L5qx/UPjA3eA+Uf2J4aWIfN5Pl Y0HhDGZj6RBVKUiLTTAtpTWKEOjKHewm6Xcb/bHUw9AthwIQCys17kEi/b5UlaHAOVo8 emEtKUsNzHucTgdtrIZ1Z5px0BdUyqbyCT/O8mJtdBH5zWEziWcP48RSb3geHiurXedZ McZ7Bvl/SbwFmrG1gYkrvSYZhuhZJGKkcXXxfF8oPf+wgnA5F8ArQOR5Wz7Wey/5yZgz lfCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=NpmAHdMw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n13-20020a170902d2cd00b001637dbe1bc4si3983196plc.44.2022.08.05.01.37.44; Fri, 05 Aug 2022 01:37:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=NpmAHdMw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237248AbiHEISk (ORCPT + 99 others); Fri, 5 Aug 2022 04:18:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231347AbiHEISj (ORCPT ); Fri, 5 Aug 2022 04:18:39 -0400 Received: from mail-io1-xd2e.google.com (mail-io1-xd2e.google.com [IPv6:2607:f8b0:4864:20::d2e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B59D74CE0; Fri, 5 Aug 2022 01:18:38 -0700 (PDT) Received: by mail-io1-xd2e.google.com with SMTP id e69so1432820iof.5; Fri, 05 Aug 2022 01:18:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc; bh=ZWk9ma5M79Z4Wqhxv3DfLZj3YkPOjUsw905Ysq/x12o=; b=NpmAHdMwOklNCLaKhx1KSd5S4DvLO87IMiPPfx2aofLGFcCCC/yvh8K0s+jsIwujgR GEozheo+M2woXmuPYoG4dwBvDF56DdEmgVSjDlD7Flkcds+BaA3YcaY+6175JGS3jvN7 G0n7bjLPX9h6W4juZkcoS/eHoGiFARGM8EJu/TD59JezxpnZNbJ6Oy75Sdc4BnyerCLp 0JvnPsgZm3j1ALRtZFtbukV0RnCrNn0C/eWmwvaTFWqqWACBcryiQN13qWwPWzKBqfF6 r/kRRcnVAk4gJzQ7OaHkjzaSOsdM2G4Cj4NKUbNOTHq+8wizKc7YMMxRIb2avrCA+nRN kkVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc; bh=ZWk9ma5M79Z4Wqhxv3DfLZj3YkPOjUsw905Ysq/x12o=; b=DyE9R0KDZZ5N1s7yWoCEf+3qsrWp6YmFf+fhjYDpJXxuuTfZVIFE6VtsmxJeb41ddh iiN9NEleHNQr0hJeTHR6d9Ju25xJJDQr6i7S45cC9oZS+/vjhVh/jZ2mu6rWONWB45Xz ZOVX47q0s2LFHCM8HnljPeFLYS0NDUNSmMYPFeg9NwZjcFbkQDJBrCs/ExOhgXmz+jFG JQ0P62JQTHZJk5vEmOTxAMmUW8r59YehWQaEc1KGi/Qi0LJ0mN0cN94rCtse8gRtaVxM rK3fl1Z0vv400IHLB9M2uei2wYnBMSLHq3+kQQuiaFCFAn3af6s7DMtFBZJ3PDpF22WX Rnrw== X-Gm-Message-State: ACgBeo3yvAI1H+SofW9lLf5mo1rb6SvCEfWkwuSW1cutn/zJ6gbdbPbh Qli9JshO9MFMX4qhuIqRcyybydUmRvE= X-Received: by 2002:a05:6638:4705:b0:342:74bb:dfa3 with SMTP id cs5-20020a056638470500b0034274bbdfa3mr2570392jab.1.1659687516958; Fri, 05 Aug 2022 01:18:36 -0700 (PDT) Received: from james-x399.localdomain (71-33-138-207.hlrn.qwest.net. [71.33.138.207]) by smtp.gmail.com with ESMTPSA id h3-20020a92d843000000b002de42539fddsm1385624ilq.68.2022.08.05.01.18.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Aug 2022 01:18:36 -0700 (PDT) From: James Hilliard To: bpf@vger.kernel.org Cc: James Hilliard , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Nathan Chancellor , Nick Desaulniers , Tom Rix , linux-kernel@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v4] bpf/scripts: Generate GCC compatible helper defs header Date: Fri, 5 Aug 2022 02:17:12 -0600 Message-Id: <20220805081713.2182833-1-james.hilliard1@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The current bpf_helper_defs.h helpers are llvm specific and don't work correctly with gcc. GCC requires kernel helper funcs to have the following attribute set: __attribute__((kernel_helper(NUM))) Generate gcc compatible headers based on the format in bpf-helpers.h. This leaves the bpf_helper_defs.h entirely unchanged and generates a fully separate GCC compatible bpf_helper_defs_attr.h header file which is conditionally included if the GCC kernel_helper attribute is supported. This adds GCC attribute style kernel helpers in bpf_helper_defs_attr.h: void *bpf_map_lookup_elem(void *map, const void *key) __attribute__((kernel_helper(1))); long bpf_map_update_elem(void *map, const void *key, const void *value, __u64 flags) __attribute__((kernel_helper(2))); See: https://github.com/gcc-mirror/gcc/blob/releases/gcc-12.1.0/gcc/config/bpf/bpf-helpers.h#L24-L27 This fixes the following build error: error: indirect call in function, which are not supported by eBPF Signed-off-by: James Hilliard --- Changes v3 -> v4: - don't modify bpf_helper_defs.h - generate bpf_helper_defs_attr.h for GCC - check __has_attribute(kernel_helper) for selecting GCC defs Changes v2 -> v3: - use a conditional helper macro Changes v1 -> v2: - more details in commit log --- scripts/bpf_doc.py | 58 ++++++++++++++++++++++--------------- tools/lib/bpf/Makefile | 7 ++++- tools/lib/bpf/bpf_helpers.h | 4 +++ 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index dfb260de17a8..c4e8fa3619d8 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -570,9 +570,10 @@ class PrinterHelpers(Printer): be included from BPF program. @parser: A HeaderParser with Helper objects to print to standard output """ - def __init__(self, parser): + def __init__(self, parser, attr_header): self.elements = parser.helpers self.elem_number_check(parser.desc_unique_helpers, parser.define_unique_helpers, 'helper', '__BPF_FUNC_MAPPER') + self.attr_header = attr_header type_fwds = [ 'struct bpf_fib_lookup', @@ -719,6 +720,24 @@ class PrinterHelpers(Printer): seen_helpers = set() + def print_args(self, proto): + comma = '' + for i, a in enumerate(proto['args']): + t = a['type'] + n = a['name'] + if proto['name'] in self.overloaded_helpers and i == 0: + t = 'void' + n = 'ctx' + one_arg = '{}{}'.format(comma, self.map_type(t)) + if n: + if a['star']: + one_arg += ' {}'.format(a['star']) + else: + one_arg += ' ' + one_arg += '{}'.format(n) + comma = ', ' + print(one_arg, end='') + def print_one(self, helper): proto = helper.proto_break_down() @@ -742,26 +761,16 @@ class PrinterHelpers(Printer): print(' *{}{}'.format(' \t' if line else '', line)) print(' */') - print('static %s %s(*%s)(' % (self.map_type(proto['ret_type']), - proto['ret_star'], proto['name']), end='') - comma = '' - for i, a in enumerate(proto['args']): - t = a['type'] - n = a['name'] - if proto['name'] in self.overloaded_helpers and i == 0: - t = 'void' - n = 'ctx' - one_arg = '{}{}'.format(comma, self.map_type(t)) - if n: - if a['star']: - one_arg += ' {}'.format(a['star']) - else: - one_arg += ' ' - one_arg += '{}'.format(n) - comma = ', ' - print(one_arg, end='') - - print(') = (void *) %d;' % len(self.seen_helpers)) + if self.attr_header: + print('%s %s%s(' % (self.map_type(proto['ret_type']), + proto['ret_star'], proto['name']), end='') + self.print_args(proto) + print(') __attribute__((kernel_helper(%d)));' % len(self.seen_helpers)) + else: + print('static %s %s(*%s)(' % (self.map_type(proto['ret_type']), + proto['ret_star'], proto['name']), end='') + self.print_args(proto) + print(') = (void *) %d;' % len(self.seen_helpers)) print('') ############################################################################### @@ -785,6 +794,8 @@ rst2man utility. """) argParser.add_argument('--header', action='store_true', help='generate C header file') +argParser.add_argument('--attr-header', action='store_true', + help='generate GCC attr style C header file') if (os.path.isfile(bpfh)): argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h', default=bpfh) @@ -799,10 +810,11 @@ headerParser = HeaderParser(args.filename) headerParser.run() # Print formatted output to standard output. -if args.header: +if args.header or args.attr_header: if args.target != 'helpers': raise NotImplementedError('Only helpers header generation is supported') - printer = PrinterHelpers(headerParser) + attr_header = True if args.attr_header else False + printer = PrinterHelpers(headerParser, attr_header) else: printer = printers[args.target](headerParser) printer.print_all() diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 4c904ef0b47e..cf9efe764030 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -116,7 +116,8 @@ STATIC_OBJDIR := $(OUTPUT)staticobjs/ BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o BPF_HELPER_DEFS := $(OUTPUT)bpf_helper_defs.h -BPF_GENERATED := $(BPF_HELPER_DEFS) +BPF_HELPER_DEFS_ATTR := $(OUTPUT)bpf_helper_defs_attr.h +BPF_GENERATED := $(BPF_HELPER_DEFS) $(BPF_HELPER_DEFS_ATTR) LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) @@ -160,6 +161,10 @@ $(BPF_HELPER_DEFS): $(srctree)/tools/include/uapi/linux/bpf.h $(QUIET_GEN)$(srctree)/scripts/bpf_doc.py --header \ --file $(srctree)/tools/include/uapi/linux/bpf.h > $(BPF_HELPER_DEFS) +$(BPF_HELPER_DEFS_ATTR): $(srctree)/tools/include/uapi/linux/bpf.h + $(QUIET_GEN)$(srctree)/scripts/bpf_doc.py --attr-header \ + --file $(srctree)/tools/include/uapi/linux/bpf.h > $(BPF_HELPER_DEFS_ATTR) + $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN_SHARED) $(VERSION_SCRIPT) diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h index 7349b16b8e2f..b7573e7d3feb 100644 --- a/tools/lib/bpf/bpf_helpers.h +++ b/tools/lib/bpf/bpf_helpers.h @@ -8,7 +8,11 @@ * in advance since bpf_helper_defs.h uses such types * as __u64. */ +#if __has_attribute(kernel_helper) +#include "bpf_helper_defs_attr.h" +#else #include "bpf_helper_defs.h" +#endif #define __uint(name, val) int (*name)[val] #define __type(name, val) typeof(val) *name -- 2.34.1