From patchwork Wed Aug 19 22:40:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hao Luo X-Patchwork-Id: 1348025 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=d09BxCdw; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BX2mn4tGJz9sTK for ; Thu, 20 Aug 2020 08:40:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727870AbgHSWkk (ORCPT ); Wed, 19 Aug 2020 18:40:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726466AbgHSWkh (ORCPT ); Wed, 19 Aug 2020 18:40:37 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31E2AC061757 for ; Wed, 19 Aug 2020 15:40:37 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id a5so121111ybh.3 for ; Wed, 19 Aug 2020 15:40:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=fel8U13mcQz8NJwoVuBeyh1ojxpwIB/G3MPwv2FpVU0=; b=d09BxCdwUlmvgi1tBGE7b1p9k9ZuhElD7Pf72XUY+2GwbIiLXCPuBvHIAqUvQmmJlj v6wyP/OPbSbVrmPw7WIHEmfSpu9iXM/ka9FbiEqsYwvdFyf4k2NQatiMn2a4xCN+DeNG 68MjEbY34wmxzdne8bsPEI8ZrUltvKjqztBzrspV/s+rp41IpMJq/ccoOJSpJ9o2x6cs ACRzzjvGwQkDCHDxQw45YqGuAhuHZUugqq0HKKMclPM98RrFPbttnsoo/NQSFjS+N99d BpXDhfN2k+7hs7q0kaXb3AWcJMK7IsOk4rsZyzJxut+1/0Egh+zn5EwndZmJHg5wAYov 4Udw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=fel8U13mcQz8NJwoVuBeyh1ojxpwIB/G3MPwv2FpVU0=; b=KoHVeGmgNu/iKITuGT0cAj05Bo8oPx/yheSRhNOL50q6FUJatY2HauzyTsgpU1rXfX XvSYM5yWi/oBNJ80CpOvoAEr0zgld0AQSuupbkX3cx/7ixEcwNpoXhdVA6PUEBwbGpkj GhG/HfNxlK85ulc9XQgKAT34STeCpIxV7W4xOAeUNS1AVG2YXoogcHscn2cnQqj8m7Qt UIAQYGcxG0Erd8Bvu7zpYwTlgGdFQL5pJ8ETETOO1qtrsuITwg88XvV/XMuh+n9/2t3A D+OzEyBL2eSl88DWiLwuHjh+9RJXeR+xPiaGk93w9aPlU3CiyOwQOYuyep4XvwyChDoe f2aw== X-Gm-Message-State: AOAM533muu4zJq+LOZOuSL8OMldDhkhX0wx7YcvR3njUXqrFgXnPWsJD l1ZRSThKLtdZcCSmGQJ72JIlSaNaNWY= X-Google-Smtp-Source: ABdhPJxTJLddDl62KuvmP7G4cW9FHWLCZo9MeO51ib6vpq8g3sHDg87/xQGoZiNWz5NGIkOVUBbVzrMtgwE= X-Received: from haoluo.svl.corp.google.com ([2620:15c:2cd:202:f693:9fff:fef4:e444]) (user=haoluo job=sendgmr) by 2002:a25:ac63:: with SMTP id r35mr831435ybd.298.1597876836156; Wed, 19 Aug 2020 15:40:36 -0700 (PDT) Date: Wed, 19 Aug 2020 15:40:23 -0700 In-Reply-To: <20200819224030.1615203-1-haoluo@google.com> Message-Id: <20200819224030.1615203-2-haoluo@google.com> Mime-Version: 1.0 References: <20200819224030.1615203-1-haoluo@google.com> X-Mailer: git-send-email 2.28.0.220.ged08abb693-goog Subject: [PATCH bpf-next v1 1/8] bpf: Introduce pseudo_btf_id From: Hao Luo To: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Shuah Khan , Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Quentin Monnet , Hao Luo , Steven Rostedt , Ingo Molnar , Andrey Ignatov , Jakub Sitnicki Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Pseudo_btf_id is a type of ld_imm insn that associates a btf_id to a ksym so that further dereferences on the ksym can use the BTF info to validate accesses. Internally, when seeing a pseudo_btf_id ld insn, the verifier reads the btf_id stored in the insn[0]'s imm field and marks the dst_reg as PTR_TO_BTF_ID. The btf_id points to a VAR_KIND, which is encoded in btf_vminux by pahole. If the VAR is not of a struct type, the dst reg will be marked as PTR_TO_MEM instead of PTR_TO_BTF_ID and the mem_size is resolved to the size of the VAR's type. From the VAR btf_id, the verifier can also read the address of the ksym's corresponding kernel var from kallsyms and use that to fill dst_reg. Therefore, the proper functionality of pseudo_btf_id depends on (1) kallsyms and (2) the encoding of kernel global VARs in pahole, which should be available since pahole v1.18. Signed-off-by: Hao Luo --- include/linux/btf.h | 15 +++++++++ include/uapi/linux/bpf.h | 38 ++++++++++++++++------ kernel/bpf/btf.c | 15 --------- kernel/bpf/verifier.c | 68 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 24 deletions(-) diff --git a/include/linux/btf.h b/include/linux/btf.h index 8b81fbb4497c..cee4089e83c0 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -107,6 +107,21 @@ static inline bool btf_type_is_func_proto(const struct btf_type *t) return BTF_INFO_KIND(t->info) == BTF_KIND_FUNC_PROTO; } +static inline bool btf_type_is_var(const struct btf_type *t) +{ + return BTF_INFO_KIND(t->info) == BTF_KIND_VAR; +} + +/* union is only a special case of struct: + * all its offsetof(member) == 0 + */ +static inline bool btf_type_is_struct(const struct btf_type *t) +{ + u8 kind = BTF_INFO_KIND(t->info); + + return kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION; +} + static inline u16 btf_type_vlen(const struct btf_type *t) { return BTF_INFO_VLEN(t->info); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 0480f893facd..468376f2910b 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -346,18 +346,38 @@ enum bpf_link_type { #define BPF_F_TEST_STATE_FREQ (1U << 3) /* When BPF ldimm64's insn[0].src_reg != 0 then this can have - * two extensions: - * - * insn[0].src_reg: BPF_PSEUDO_MAP_FD BPF_PSEUDO_MAP_VALUE - * insn[0].imm: map fd map fd - * insn[1].imm: 0 offset into value - * insn[0].off: 0 0 - * insn[1].off: 0 0 - * ldimm64 rewrite: address of map address of map[0]+offset - * verifier type: CONST_PTR_TO_MAP PTR_TO_MAP_VALUE + * the following extensions: + * + * insn[0].src_reg: BPF_PSEUDO_MAP_FD + * insn[0].imm: map fd + * insn[1].imm: 0 + * insn[0].off: 0 + * insn[1].off: 0 + * ldimm64 rewrite: address of map + * verifier type: CONST_PTR_TO_MAP */ #define BPF_PSEUDO_MAP_FD 1 +/* + * insn[0].src_reg: BPF_PSEUDO_MAP_VALUE + * insn[0].imm: map fd + * insn[1].imm: offset into value + * insn[0].off: 0 + * insn[1].off: 0 + * ldimm64 rewrite: address of map[0]+offset + * verifier type: PTR_TO_MAP_VALUE + */ #define BPF_PSEUDO_MAP_VALUE 2 +/* + * insn[0].src_reg: BPF_PSEUDO_BTF_ID + * insn[0].imm: kernel btd id of VAR + * insn[1].imm: 0 + * insn[0].off: 0 + * insn[1].off: 0 + * ldimm64 rewrite: address of the kernel variable + * verifier type: PTR_TO_BTF_ID or PTR_TO_MEM, depending on whether the var + * is struct/union. + */ +#define BPF_PSEUDO_BTF_ID 3 /* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative * offset to another bpf function diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 91afdd4c82e3..b6d8f653afe2 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -353,16 +353,6 @@ static bool btf_type_nosize_or_null(const struct btf_type *t) return !t || btf_type_nosize(t); } -/* union is only a special case of struct: - * all its offsetof(member) == 0 - */ -static bool btf_type_is_struct(const struct btf_type *t) -{ - u8 kind = BTF_INFO_KIND(t->info); - - return kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION; -} - static bool __btf_type_is_struct(const struct btf_type *t) { return BTF_INFO_KIND(t->info) == BTF_KIND_STRUCT; @@ -373,11 +363,6 @@ static bool btf_type_is_array(const struct btf_type *t) return BTF_INFO_KIND(t->info) == BTF_KIND_ARRAY; } -static bool btf_type_is_var(const struct btf_type *t) -{ - return BTF_INFO_KIND(t->info) == BTF_KIND_VAR; -} - static bool btf_type_is_datasec(const struct btf_type *t) { return BTF_INFO_KIND(t->info) == BTF_KIND_DATASEC; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ef938f17b944..47badde71f83 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -7205,6 +7205,68 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, return 0; } +/* verify ld_imm64 insn of type PSEUDO_BTF_ID is valid */ +static inline int check_pseudo_btf_id(struct bpf_verifier_env *env, + struct bpf_insn *insn) +{ + struct bpf_reg_state *regs = cur_regs(env); + u32 type, id = insn->imm; + u64 addr; + const char *sym_name; + const struct btf_type *t = btf_type_by_id(btf_vmlinux, id); + + if (!t) { + verbose(env, "%s: invalid btf_id %d\n", __func__, id); + return -ENOENT; + } + + if (insn[1].imm != 0) { + verbose(env, "%s: BPF_PSEUDO_BTF_ID uses reserved fields\n", + __func__); + return -EINVAL; + } + + if (!btf_type_is_var(t)) { + verbose(env, "%s: btf_id %d isn't KIND_VAR\n", __func__, id); + return -EINVAL; + } + + sym_name = btf_name_by_offset(btf_vmlinux, t->name_off); + addr = kallsyms_lookup_name(sym_name); + if (!addr) { + verbose(env, "%s: failed to find the address of symbol '%s'.\n", + __func__, sym_name); + return -ENOENT; + } + + insn[0].imm = (u32)addr; + insn[1].imm = addr >> 32; + mark_reg_known_zero(env, regs, insn->dst_reg); + + type = t->type; + t = btf_type_skip_modifiers(btf_vmlinux, type, NULL); + if (!btf_type_is_struct(t)) { + u32 tsize; + const struct btf_type *ret; + const char *tname; + + /* resolve the type size of ksym. */ + ret = btf_resolve_size(btf_vmlinux, t, &tsize, NULL, NULL); + if (IS_ERR(ret)) { + tname = btf_name_by_offset(btf_vmlinux, t->name_off); + verbose(env, "unable to resolve the size of type '%s': %ld\n", + tname, PTR_ERR(ret)); + return -EINVAL; + } + regs[insn->dst_reg].type = PTR_TO_MEM; + regs[insn->dst_reg].mem_size = tsize; + } else { + regs[insn->dst_reg].type = PTR_TO_BTF_ID; + regs[insn->dst_reg].btf_id = type; + } + return 0; +} + /* verify BPF_LD_IMM64 instruction */ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) { @@ -7234,6 +7296,9 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) return 0; } + if (insn->src_reg == BPF_PSEUDO_BTF_ID) + return check_pseudo_btf_id(env, insn); + map = env->used_maps[aux->map_index]; mark_reg_known_zero(env, regs, insn->dst_reg); regs[insn->dst_reg].map_ptr = map; @@ -9255,6 +9320,9 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env) /* valid generic load 64-bit imm */ goto next_insn; + if (insn[0].src_reg == BPF_PSEUDO_BTF_ID) + goto next_insn; + /* In final convert_pseudo_ld_imm64() step, this is * converted into regular 64-bit imm load insn. */ From patchwork Wed Aug 19 22:40:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hao Luo X-Patchwork-Id: 1348040 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=vqBrpVaL; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BX2pT2Q4jz9sTK for ; Thu, 20 Aug 2020 08:42:09 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728049AbgHSWmC (ORCPT ); Wed, 19 Aug 2020 18:42:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727864AbgHSWkj (ORCPT ); Wed, 19 Aug 2020 18:40:39 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 057FFC061387 for ; Wed, 19 Aug 2020 15:40:39 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id b18so19396pge.8 for ; Wed, 19 Aug 2020 15:40:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=4lUOSfg5crC/CXFRp8F/K1Jb1PQLzPLA9O5+4H789wU=; b=vqBrpVaLG5hgyuLORPxN8M2fiZFQB9dD18R/Ooo0adUnZ41ijb7pOrysJRfD0R3QWh Ad1zPUlUDRdgRHl6q1yvEdA+t0YasDSvU5kcljOIAHzujqBZo1fV5ygeNVw0jYT0poGC bWQahRedPnzPBQkh0DEDaII0mgLKbi4mi+sMdw8Za+uAtyt4OPAhkWNN1Mtu4TZgFAU4 6C74G1IiRmIW8+IF4ZDmaSUcoh4dyqUx7pc2wnJeY0+MV50EipBwVjS36jTc6VQflbvT 5LnFtOofo9HL8sPEOxaDyAC5Ia/2Hzl6Bvm7qCu4zPqc0pfm+ZZI2hu0FhiRVl6ZuIzW Cb6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=4lUOSfg5crC/CXFRp8F/K1Jb1PQLzPLA9O5+4H789wU=; b=soKp0iIFHlBbSAWqH+9/5xrQPgqVbh75U3k1lOIg74jiriK2tPpbRUVz/YV3gvDWtV CRPZnbghXKGEQpUtvPdeV0c/A2cr3yGnRLqgsHBVuIei/DgFRYRpvK3C/e3LXMBoDUW8 Lith4J6NoQIAFLTzsxesh4yzf3fLy/6xPSH12OltDrK/b6qGTgKBFF4bUz8uRrIsTbUE rVMMz8AzNDhisPkCtvP0Pp7QBDOPXUSKtOC29/ks89JpMeURZ/gcY1RiXh1qjZRQbUwJ 9NukY2s4DwkjPDKLT1UNJ7NApjfS40AQYakvBBKe6gDF/rKRKuXKgYXRGgx8TQfqHvQq UTig== X-Gm-Message-State: AOAM530bB/N8WqX8pi9RTCbdCxPrps88UWq4C7in/AkiiDYtIw2ji8Cv yic+NjVVSX1gCoBfuF7s06j20DvbMOUxg5ZN+5HLelamTQsTD8XDHp4V3Mi6762+pa8VR4kqELC qatKE2uqAB1vWCzEe+ysVo7tiqM1VQJr06dUID/wljHGUpxs/qlgczVUigD1vHQ== X-Google-Smtp-Source: ABdhPJw60HhYSD5xD+NKMghulZyrwy7CSfEqKWANtTW3eDGeqH3EPOr0UctlJdOGdV4ZXKaGvMSwbdfQlz4= X-Received: from haoluo.svl.corp.google.com ([2620:15c:2cd:202:f693:9fff:fef4:e444]) (user=haoluo job=sendgmr) by 2002:aa7:8ec4:: with SMTP id b4mr34434pfr.227.1597876838302; Wed, 19 Aug 2020 15:40:38 -0700 (PDT) Date: Wed, 19 Aug 2020 15:40:24 -0700 In-Reply-To: <20200819224030.1615203-1-haoluo@google.com> Message-Id: <20200819224030.1615203-3-haoluo@google.com> Mime-Version: 1.0 References: <20200819224030.1615203-1-haoluo@google.com> X-Mailer: git-send-email 2.28.0.220.ged08abb693-goog Subject: [PATCH bpf-next v1 2/8] bpf: Propagate BPF_PSEUDO_BTF_ID to uapi headers in /tools From: Hao Luo To: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Shuah Khan , Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Quentin Monnet , Hao Luo , Steven Rostedt , Ingo Molnar , Andrey Ignatov , Jakub Sitnicki Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Propagate BPF_PSEUDO_BTF_ID from include/linux/uapi/bpf.h to tools/include/linux/uapi/bpf.h. Signed-off-by: Hao Luo --- tools/include/uapi/linux/bpf.h | 38 ++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 0480f893facd..468376f2910b 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -346,18 +346,38 @@ enum bpf_link_type { #define BPF_F_TEST_STATE_FREQ (1U << 3) /* When BPF ldimm64's insn[0].src_reg != 0 then this can have - * two extensions: - * - * insn[0].src_reg: BPF_PSEUDO_MAP_FD BPF_PSEUDO_MAP_VALUE - * insn[0].imm: map fd map fd - * insn[1].imm: 0 offset into value - * insn[0].off: 0 0 - * insn[1].off: 0 0 - * ldimm64 rewrite: address of map address of map[0]+offset - * verifier type: CONST_PTR_TO_MAP PTR_TO_MAP_VALUE + * the following extensions: + * + * insn[0].src_reg: BPF_PSEUDO_MAP_FD + * insn[0].imm: map fd + * insn[1].imm: 0 + * insn[0].off: 0 + * insn[1].off: 0 + * ldimm64 rewrite: address of map + * verifier type: CONST_PTR_TO_MAP */ #define BPF_PSEUDO_MAP_FD 1 +/* + * insn[0].src_reg: BPF_PSEUDO_MAP_VALUE + * insn[0].imm: map fd + * insn[1].imm: offset into value + * insn[0].off: 0 + * insn[1].off: 0 + * ldimm64 rewrite: address of map[0]+offset + * verifier type: PTR_TO_MAP_VALUE + */ #define BPF_PSEUDO_MAP_VALUE 2 +/* + * insn[0].src_reg: BPF_PSEUDO_BTF_ID + * insn[0].imm: kernel btd id of VAR + * insn[1].imm: 0 + * insn[0].off: 0 + * insn[1].off: 0 + * ldimm64 rewrite: address of the kernel variable + * verifier type: PTR_TO_BTF_ID or PTR_TO_MEM, depending on whether the var + * is struct/union. + */ +#define BPF_PSEUDO_BTF_ID 3 /* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative * offset to another bpf function From patchwork Wed Aug 19 22:40:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hao Luo X-Patchwork-Id: 1348038 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=bvCqfxtE; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BX2pK36JNz9sRK for ; Thu, 20 Aug 2020 08:42:01 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727885AbgHSWmA (ORCPT ); Wed, 19 Aug 2020 18:42:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727872AbgHSWkm (ORCPT ); Wed, 19 Aug 2020 18:40:42 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0756C061757 for ; Wed, 19 Aug 2020 15:40:40 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id d26so77011yba.20 for ; Wed, 19 Aug 2020 15:40:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=05RINSlNZpxkz4+XFh9vffd8x++7Xi2oImwEGbIboIw=; b=bvCqfxtE89wPaDPHtG2KP3DVu3Cufv99C8GojGuQCFL9y27nN0rOopfPwO2vwfymzC lqkRkUypcojwKSQVGrz26UL/g4gE3fBQYLpODEQ9ICYgV2hp18x332AL6x7b641aTOmp Iz8k6B8r/tPk5Orl/N7dDyMCG/rSjX7v8Z6zazG5bZR9FjE7Tz2qLrfRaL6Hk0hvdMjX mLRJ5glMA/vaZ70wPFs6ft1f/gh0xj3HRoar/Pj1zKXRf0HjTS14gKksTiqDwQfT7OFH E/pmIx93X/0dz+6kUiVVUghypZ10lb4nxzGm7CYih879+eiAqNx6m7WGHdXn7ozCU++F LYQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=05RINSlNZpxkz4+XFh9vffd8x++7Xi2oImwEGbIboIw=; b=dYJQe68a/zexGaBPCyoefpGyX7VUJauOj+JVJ8xqVYnLof6fsimypPfd0QpTMTPw60 NSmPVR4KejWA8lFMjspXUNIcZQruUJ27U5tTrEmZT+RHr1G7/w4Ji0ZuyXMEdWNZj74p gIhzdw4JaFliaIyTQwt54EaHOS6h0DvindeEk9PvqelbK3z3fGEVD5mWkMCm6Lannvvu Vs3PdrJI8GT9EUyM9rFQtnOY5IJxzBsIPbatiisT0j3lBceVpdnfyFe4JnALJCErusZC aWSm+vEGx1Byen+vOHTyjdkXyVCa9UYK4AijV0I7jHi24UxbnSUoqHO2hxvgqnwBwbLh 0Oog== X-Gm-Message-State: AOAM532i+w/0dtIzWwwUXJsO0qgoflrFnXMRI+myA63jz9KuRQEcTlUi HODsbPYEu88OvP4+5MRaViEhyIwOM94= X-Google-Smtp-Source: ABdhPJx+VL0RsYyIRSbcn1wDvK0fb0lyt4S9Ju6v1CCixPKoa2AzooiMvkcYAjrEIUWzQ0XfkYjGGpXZSrI= X-Received: from haoluo.svl.corp.google.com ([2620:15c:2cd:202:f693:9fff:fef4:e444]) (user=haoluo job=sendgmr) by 2002:a5b:744:: with SMTP id s4mr965454ybq.26.1597876840168; Wed, 19 Aug 2020 15:40:40 -0700 (PDT) Date: Wed, 19 Aug 2020 15:40:25 -0700 In-Reply-To: <20200819224030.1615203-1-haoluo@google.com> Message-Id: <20200819224030.1615203-4-haoluo@google.com> Mime-Version: 1.0 References: <20200819224030.1615203-1-haoluo@google.com> X-Mailer: git-send-email 2.28.0.220.ged08abb693-goog Subject: [PATCH bpf-next v1 3/8] bpf: Introduce help function to validate ksym's type. From: Hao Luo To: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Shuah Khan , Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Quentin Monnet , Hao Luo , Steven Rostedt , Ingo Molnar , Andrey Ignatov , Jakub Sitnicki Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org For a ksym to be safely dereferenced and accessed, its type defined in bpf program should basically match its type defined in kernel. Implement a help function for a quick matching, which is used by libbpf when resolving the kernel btf_id of a ksym. Signed-off-by: Hao Luo --- tools/lib/bpf/btf.c | 171 ++++++++++++++++++++++++++++++++++++++++++++ tools/lib/bpf/btf.h | 2 + 2 files changed, 173 insertions(+) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index a3d259e614b0..2ff31f244d7a 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -1005,6 +1005,177 @@ int btf__get_map_kv_tids(const struct btf *btf, const char *map_name, return 0; } +/* + * Basic type check for ksym support. Only checks type kind and resolved size. + */ +static inline +bool btf_ksym_equal_type(const struct btf *ba, __u32 type_a, + const struct btf *bb, __u32 type_b) +{ + const struct btf_type *ta, *tb; + + ta = btf__type_by_id(ba, type_a); + tb = btf__type_by_id(bb, type_b); + + /* compare type kind */ + if (btf_kind(ta) != btf_kind(tb)) + return false; + + /* compare resolved type size */ + return btf__resolve_size(ba, type_a) == btf__resolve_size(bb, type_b); +} + +/* + * Match a ksym's type defined in bpf programs against its type encoded in + * kernel btf. + */ +bool btf_ksym_type_match(const struct btf *ba, __u32 id_a, + const struct btf *bb, __u32 id_b) +{ + const struct btf_type *ta = btf__type_by_id(ba, id_a); + const struct btf_type *tb = btf__type_by_id(bb, id_b); + int i; + + /* compare type kind */ + if (btf_kind(ta) != btf_kind(tb)) { + pr_warn("%s:mismatched type kind (%d v.s. %d).\n", + __func__, btf_kind(ta), btf_kind(tb)); + return false; + } + + switch (btf_kind(ta)) { + case BTF_KIND_INT: { /* compare size and encoding */ + __u32 ea, eb; + + if (ta->size != tb->size) { + pr_warn("%s:INT size mismatch, (%u v.s. %u)\n", + __func__, ta->size, tb->size); + return false; + } + ea = *(__u32 *)(ta + 1); + eb = *(__u32 *)(tb + 1); + if (ea != eb) { + pr_warn("%s:INT encoding mismatch (%u v.s. %u)\n", + __func__, ea, eb); + return false; + } + break; + } + case BTF_KIND_ARRAY: { /* compare type and number of elements */ + const struct btf_array *ea, *eb; + + ea = btf_array(ta); + eb = btf_array(tb); + if (!btf_ksym_equal_type(ba, ea->type, bb, eb->type)) { + pr_warn("%s:ARRAY elem type mismatch.\n", __func__); + return false; + } + if (ea->nelems != eb->nelems) { + pr_warn("%s:ARRAY nelems mismatch (%d v.s. %d)\n", + __func__, ea->nelems, eb->nelems); + return false; + } + break; + } + case BTF_KIND_STRUCT: + case BTF_KIND_UNION: { /* compare size, vlen and member offset, name */ + const struct btf_member *ma, *mb; + + if (ta->size != tb->size) { + pr_warn("%s:STRUCT size mismatch, (%u v.s. %u)\n", + __func__, ta->size, tb->size); + return false; + } + if (btf_vlen(ta) != btf_vlen(tb)) { + pr_warn("%s:STRUCT vlen mismatch, (%u v.s. %u)\n", + __func__, btf_vlen(ta), btf_vlen(tb)); + return false; + } + + ma = btf_members(ta); + mb = btf_members(tb); + for (i = 0; i < btf_vlen(ta); i++, ma++, mb++) { + const char *na, *nb; + + if (ma->offset != mb->offset) { + pr_warn("%s:STRUCT field offset mismatch, (%u v.s. %u)\n", + __func__, ma->offset, mb->offset); + return false; + } + na = btf__name_by_offset(ba, ma->name_off); + nb = btf__name_by_offset(bb, mb->name_off); + if (strcmp(na, nb)) { + pr_warn("%s:STRUCT field name mismatch, (%s v.s. %s)\n", + __func__, na, nb); + return false; + } + } + break; + } + case BTF_KIND_ENUM: { /* compare vlen and member value, name */ + const struct btf_enum *ma, *mb; + + if (btf_vlen(ta) != btf_vlen(tb)) { + pr_warn("%s:ENUM vlen mismatch, (%u v.s. %u)\n", + __func__, btf_vlen(ta), btf_vlen(tb)); + return false; + } + + ma = btf_enum(ta); + mb = btf_enum(tb); + for (i = 0; i < btf_vlen(ta); i++, ma++, mb++) { + if (ma->val != mb->val) { + pr_warn("%s:ENUM val mismatch, (%u v.s. %u)\n", + __func__, ma->val, mb->val); + return false; + } + } + break; + } + case BTF_KIND_PTR: { /* naive compare of ref type for PTR */ + if (!btf_ksym_equal_type(ba, ta->type, bb, tb->type)) { + pr_warn("%s:PTR ref type mismatch.\n", __func__); + return false; + } + break; + } + case BTF_KIND_FUNC_PROTO: { /* naive compare of vlen and param types */ + const struct btf_param *pa, *pb; + + if (btf_vlen(ta) != btf_vlen(tb)) { + pr_warn("%s:FUNC_PROTO vlen mismatch, (%u v.s. %u)\n", + __func__, btf_vlen(ta), btf_vlen(tb)); + return false; + } + + pa = btf_params(ta); + pb = btf_params(tb); + for (i = 0; i < btf_vlen(ta); i++, pa++, pb++) { + if (!btf_ksym_equal_type(ba, pa->type, bb, pb->type)) { + pr_warn("%s:FUNC_PROTO params type mismatch.\n", + __func__); + return false; + } + } + break; + } + case BTF_KIND_FUNC: + case BTF_KIND_CONST: + case BTF_KIND_VOLATILE: + case BTF_KIND_RESTRICT: + case BTF_KIND_TYPEDEF: + case BTF_KIND_VAR: + case BTF_KIND_DATASEC: + pr_warn("unexpected type for matching ksym types.\n"); + return false; + default: + pr_warn("unsupported btf types.\n"); + return false; + } + + return true; +} + struct btf_ext_sec_setup_param { __u32 off; __u32 len; diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index 91f0ad0e0325..5ef220e52485 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h @@ -52,6 +52,8 @@ LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name, __u32 expected_key_size, __u32 expected_value_size, __u32 *key_type_id, __u32 *value_type_id); +LIBBPF_API bool btf_ksym_type_match(const struct btf *ba, __u32 id_a, + const struct btf *bb, __u32 id_b); LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size); LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext); From patchwork Wed Aug 19 22:40:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hao Luo X-Patchwork-Id: 1348028 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=KEVm/sGP; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BX2nD56bDz9sRK for ; Thu, 20 Aug 2020 08:41:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727927AbgHSWk7 (ORCPT ); Wed, 19 Aug 2020 18:40:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727888AbgHSWkt (ORCPT ); Wed, 19 Aug 2020 18:40:49 -0400 Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 06789C061348 for ; Wed, 19 Aug 2020 15:40:43 -0700 (PDT) Received: by mail-qv1-xf4a.google.com with SMTP id y12so40157qva.8 for ; Wed, 19 Aug 2020 15:40:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=o5hcafLIur4TPskQP5E6KPZVFbh+qjZrYmSthTwVB04=; b=KEVm/sGPyfyG51HlhTXV0YroOEI5zQYZmoLUdxXgIMqVb18ASyPW/KbBdlS7ux/IYv py7s5CBpnuj5Z2kI0U5feqHgVdccNJ+ILv5x/tYIgODbbvld+P0r4wahQGtF0n0SOEe+ YeshFbT8qj9ZXs9EgwKnXGF7Mwlc35Fi/xc3ryWZp9MNsYPfcpSuUnoyD/sjHjkd8fMe HyQ6yQr7/g1qaABSsKISXqpygyG+prMVRoGAr81nHP3iHvFjQg4CnPfYp/0Ob3zKEpGQ gPHLQRFCRb51ZDeq8u5vgR6X66B0t92iLLHDiNdQi0I8CUu8qonHMcXHm4Iaw5HGqpVI IcdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=o5hcafLIur4TPskQP5E6KPZVFbh+qjZrYmSthTwVB04=; b=pqLi/l6cuLpORNyNA3auz/FJZ88PVekpDyI2xs7+4kbBjdUWLxCk3Di4VnFWOjm9Wf vgP+joXSHmYSptGKmVrdB/Ltg0LI4yx02Zn5XlXTTpXAQnwvF91H9aQBMnJYxMc/IPLR HOoUhO7FZVyOFcyDFK0ZTwS9V6jpdCUWxLoS+pD0eoKe/6ZOO3ym9G+bbTIDq1juQHmc JvA17UOV9/Nk/6InH+uuu5V2KUp4Py9+bF0K9XuuulK6WFCqYckH6h/7IIanHBHx/Yuy L2Cndr3+TRAcBT1pPET2HTuNS4PImIiagHNT9bgh2Ml9Frxm2oSzBobDvE3zT8LMiPck CIMA== X-Gm-Message-State: AOAM53289Ba3qm8ZEEcsIkTAlKn6ztY0KCo/jdD2FDT5QJ6A6J9+8n79 +uWdFcr2qDRDq3oZjf9WkPT9v9lSXnc= X-Google-Smtp-Source: ABdhPJxyHUudWy1NYp/N8b6eKKKkk9EiTNiuow7ZaLf2G2NTFN8IF+TFATrnL0TqyK5NApAWp9Is+3Q5V9c= X-Received: from haoluo.svl.corp.google.com ([2620:15c:2cd:202:f693:9fff:fef4:e444]) (user=haoluo job=sendgmr) by 2002:a0c:ee41:: with SMTP id m1mr476956qvs.214.1597876842123; Wed, 19 Aug 2020 15:40:42 -0700 (PDT) Date: Wed, 19 Aug 2020 15:40:26 -0700 In-Reply-To: <20200819224030.1615203-1-haoluo@google.com> Message-Id: <20200819224030.1615203-5-haoluo@google.com> Mime-Version: 1.0 References: <20200819224030.1615203-1-haoluo@google.com> X-Mailer: git-send-email 2.28.0.220.ged08abb693-goog Subject: [PATCH bpf-next v1 4/8] bpf/libbpf: BTF support for typed ksyms From: Hao Luo To: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Shuah Khan , Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Quentin Monnet , Hao Luo , Steven Rostedt , Ingo Molnar , Andrey Ignatov , Jakub Sitnicki Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org If a ksym is defined with a type, libbpf will try to find the ksym's btf information from kernel btf. If a valid btf entry for the ksym is found, libbpf can pass in the found btf id to the verifier, which validates the ksym's type and value. Typeless ksyms (i.e. those defined as 'void') will not have such btf_id, but it has the symbol's address (read from kallsyms) and its value is treated as a raw pointer. Signed-off-by: Hao Luo --- tools/lib/bpf/libbpf.c | 130 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 114 insertions(+), 16 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 4a81c6b2d21b..94eff612c7c2 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -357,7 +357,16 @@ struct extern_desc { bool is_signed; } kcfg; struct { - unsigned long long addr; + /* + * 1. If ksym is typeless, the field 'addr' is valid. + * 2. If ksym is typed, the field 'vmlinux_btf_id' is + * valid. + */ + bool is_typeless; + union { + unsigned long long addr; + int vmlinux_btf_id; + }; } ksym; }; }; @@ -382,6 +391,7 @@ struct bpf_object { bool loaded; bool has_pseudo_calls; + bool has_typed_ksyms; /* * Information when doing elf related work. Only valid if fd @@ -2521,6 +2531,10 @@ static int bpf_object__load_vmlinux_btf(struct bpf_object *obj) if (obj->btf_ext && obj->btf_ext->core_relo_info.len) need_vmlinux_btf = true; + /* Support for typed ksyms needs kernel BTF */ + if (obj->has_typed_ksyms) + need_vmlinux_btf = true; + bpf_object__for_each_program(prog, obj) { if (!prog->load) continue; @@ -2975,10 +2989,10 @@ static int bpf_object__collect_externs(struct bpf_object *obj) ext->type = EXT_KSYM; vt = skip_mods_and_typedefs(obj->btf, t->type, NULL); - if (!btf_is_void(vt)) { - pr_warn("extern (ksym) '%s' is not typeless (void)\n", ext_name); - return -ENOTSUP; - } + ext->ksym.is_typeless = btf_is_void(vt); + + if (!obj->has_typed_ksyms && !ext->ksym.is_typeless) + obj->has_typed_ksyms = true; } else { pr_warn("unrecognized extern section '%s'\n", sec_name); return -ENOTSUP; @@ -2992,9 +3006,9 @@ static int bpf_object__collect_externs(struct bpf_object *obj) /* sort externs by type, for kcfg ones also by (align, size, name) */ qsort(obj->externs, obj->nr_extern, sizeof(*ext), cmp_externs); - /* for .ksyms section, we need to turn all externs into allocated - * variables in BTF to pass kernel verification; we do this by - * pretending that each extern is a 8-byte variable + /* for .ksyms section, we need to turn all typeless externs into + * allocated variables in BTF to pass kernel verification; we do + * this by pretending that each typeless extern is a 8-byte variable */ if (ksym_sec) { /* find existing 4-byte integer type in BTF to use for fake @@ -3012,7 +3026,7 @@ static int bpf_object__collect_externs(struct bpf_object *obj) sec = ksym_sec; n = btf_vlen(sec); - for (i = 0, off = 0; i < n; i++, off += sizeof(int)) { + for (i = 0, off = 0; i < n; i++) { struct btf_var_secinfo *vs = btf_var_secinfos(sec) + i; struct btf_type *vt; @@ -3025,9 +3039,14 @@ static int bpf_object__collect_externs(struct bpf_object *obj) return -ESRCH; } btf_var(vt)->linkage = BTF_VAR_GLOBAL_ALLOCATED; - vt->type = int_btf_id; + if (ext->ksym.is_typeless) { + vt->type = int_btf_id; + vs->size = sizeof(int); + } vs->offset = off; - vs->size = sizeof(int); + off += vs->size; + pr_debug("ksym var_secinfo: var '%s', type #%d, size %d, offset %d\n", + ext->name, vt->type, vs->size, vs->offset); } sec->size = off; } @@ -5300,8 +5319,13 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj) insn[0].imm = obj->maps[obj->kconfig_map_idx].fd; insn[1].imm = ext->kcfg.data_off; } else /* EXT_KSYM */ { - insn[0].imm = (__u32)ext->ksym.addr; - insn[1].imm = ext->ksym.addr >> 32; + if (ext->ksym.is_typeless) { /* typelss ksyms */ + insn[0].imm = (__u32)ext->ksym.addr; + insn[1].imm = ext->ksym.addr >> 32; + } else { /* typed ksyms */ + insn[0].src_reg = BPF_PSEUDO_BTF_ID; + insn[0].imm = ext->ksym.vmlinux_btf_id; + } } break; case RELO_CALL: @@ -6019,6 +6043,10 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj) if (!ext || ext->type != EXT_KSYM) continue; + /* Typed ksyms have the verifier to fill their addresses. */ + if (!ext->ksym.is_typeless) + continue; + if (ext->is_set && ext->ksym.addr != sym_addr) { pr_warn("extern (ksym) '%s' resolution is ambiguous: 0x%llx or 0x%llx\n", sym_name, ext->ksym.addr, sym_addr); @@ -6037,10 +6065,72 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj) return err; } +static int bpf_object__resolve_ksyms_btf_id(struct bpf_object *obj) +{ + struct extern_desc *ext; + int i, id; + + if (!obj->btf_vmlinux) { + pr_warn("support of typed ksyms needs kernel btf.\n"); + return -ENOENT; + } + + for (i = 0; i < obj->nr_extern; i++) { + const struct btf_type *v, *vx; /* VARs in object and vmlinux btf */ + const struct btf_type *t, *tx; /* TYPEs in btf */ + __u32 vt, vtx; /* btf_ids of TYPEs */ + + ext = &obj->externs[i]; + if (ext->type != EXT_KSYM) + continue; + + if (ext->ksym.is_typeless) + continue; + + if (ext->is_set) { + pr_warn("typed ksym '%s' resolved as typeless ksyms.\n", + ext->name); + return -EFAULT; + } + + id = btf__find_by_name_kind(obj->btf_vmlinux, ext->name, + BTF_KIND_VAR); + if (id <= 0) { + pr_warn("no btf entry for ksym '%s' in vmlinux.\n", + ext->name); + return -ESRCH; + } + + vx = btf__type_by_id(obj->btf_vmlinux, id); + tx = skip_mods_and_typedefs(obj->btf_vmlinux, vx->type, &vtx); + + v = btf__type_by_id(obj->btf, ext->btf_id); + t = skip_mods_and_typedefs(obj->btf, v->type, &vt); + + if (!btf_ksym_type_match(obj->btf_vmlinux, vtx, obj->btf, vt)) { + const char *tname, *txname; /* names of TYPEs */ + + txname = btf__name_by_offset(obj->btf_vmlinux, tx->name_off); + tname = btf__name_by_offset(obj->btf, t->name_off); + + pr_warn("ksym '%s' expects type '%s' (vmlinux_btf_id: #%d), " + "but got '%s' (btf_id: #%d)\n", ext->name, + txname, vtx, tname, vt); + return -EINVAL; + } + + ext->is_set = true; + ext->ksym.vmlinux_btf_id = id; + pr_debug("extern (ksym) %s=vmlinux_btf_id(#%d)\n", ext->name, id); + } + return 0; +} + static int bpf_object__resolve_externs(struct bpf_object *obj, const char *extra_kconfig) { - bool need_config = false, need_kallsyms = false; + bool need_config = false; + bool need_kallsyms = false, need_vmlinux_btf = false; struct extern_desc *ext; void *kcfg_data = NULL; int err, i; @@ -6071,7 +6161,10 @@ static int bpf_object__resolve_externs(struct bpf_object *obj, strncmp(ext->name, "CONFIG_", 7) == 0) { need_config = true; } else if (ext->type == EXT_KSYM) { - need_kallsyms = true; + if (ext->ksym.is_typeless) + need_kallsyms = true; + else + need_vmlinux_btf = true; } else { pr_warn("unrecognized extern '%s'\n", ext->name); return -EINVAL; @@ -6100,6 +6193,11 @@ static int bpf_object__resolve_externs(struct bpf_object *obj, if (err) return -EINVAL; } + if (need_vmlinux_btf) { + err = bpf_object__resolve_ksyms_btf_id(obj); + if (err) + return -EINVAL; + } for (i = 0; i < obj->nr_extern; i++) { ext = &obj->externs[i]; @@ -6132,10 +6230,10 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) } err = bpf_object__probe_loading(obj); + err = err ? : bpf_object__load_vmlinux_btf(obj); err = err ? : bpf_object__resolve_externs(obj, obj->kconfig); err = err ? : bpf_object__sanitize_and_load_btf(obj); err = err ? : bpf_object__sanitize_maps(obj); - err = err ? : bpf_object__load_vmlinux_btf(obj); err = err ? : bpf_object__init_kern_struct_ops_maps(obj); err = err ? : bpf_object__create_maps(obj); err = err ? : bpf_object__relocate(obj, attr->target_btf_path); From patchwork Wed Aug 19 22:40:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hao Luo X-Patchwork-Id: 1348030 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=RwVnai6K; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BX2nL0hz0z9sRK for ; Thu, 20 Aug 2020 08:41:10 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727882AbgHSWlF (ORCPT ); Wed, 19 Aug 2020 18:41:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726603AbgHSWkv (ORCPT ); Wed, 19 Aug 2020 18:40:51 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EB09C06134B for ; Wed, 19 Aug 2020 15:40:45 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id w23so210251pll.21 for ; Wed, 19 Aug 2020 15:40:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=eoycBj0dmzWV6TvaHW20mHC8PQPI+NKXhCcr88+dCvE=; b=RwVnai6KEHm0pCu5e/M8tbhY+lVSbUDwH/ocIBZ47Ye96EW4Wqdot6YPifg1lURWEk h0ooSs6RVb3Fdh6C2KKsnuIWUj6v5JVx3sEtvT+6G7HErImJtqMxdK1GYy8ZyJzcGkGk DQ17w7Vdd20SU3IjDzReDIdQC71ResXtsvX8t0YjoZvvkY0irLg56zkdR4U/tXEA2gNq iiuMBafkZNOSd2FcbEX/l37c9yxwCRYtrPM8UwAY7Ww5BofwK4lr4zQIAK9/XEiAV//G nxz7cxHbFQF6hQQkQpLFwzAkPplIfGaVBLQLxMElFOT17HySzeGXovPSexH0bPArPAMO Xrkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=eoycBj0dmzWV6TvaHW20mHC8PQPI+NKXhCcr88+dCvE=; b=WJeUGIH88t1pa5DO74MAReTS99aRfqzqtKgEvSFu9x6oX4H3phH0dKOHuYU/fZDB8d Mmt8B6tevWWoT1uIRjIMuSH6tn5BP8qXUl5nL4vNJpcrN0mBOaOclcQHxF8RKDXifw51 SckEAei/O/ZwXxlzieuYuuM9JDi9UuoCKZ+q2tPNCPylDsuyAhpoxOy9thqA56U0jpQG ZcboNl6xE0b0M8JrPV0HSFm2vqTNEGwXRmc3qpVjry9ppDRAfR4vgp8nBtEcxNtFVf1Y O1WzICGB8pSWjUJUVY2GFCMi5e+ew3Z4K1jKyFCh1Oe2B60vSz7wqqqLHaoyQS/SWTT+ 4V7Q== X-Gm-Message-State: AOAM5311o6YTmHHWS/wQIiS5/q86WO09jXv3o0twJnb2xmXGtviHy3vT foePf+Wzc8L7o4aAP3Aq/JzZwQmdPdg= X-Google-Smtp-Source: ABdhPJzEZsN56SetJK1yr8c+VYky6alODaG8BWZVW+ZyriIS6DogfyX6fd2aZWq/cYIwQyLAOoqZYC08r1o= X-Received: from haoluo.svl.corp.google.com ([2620:15c:2cd:202:f693:9fff:fef4:e444]) (user=haoluo job=sendgmr) by 2002:a17:90b:4c46:: with SMTP id np6mr62568pjb.201.1597876844231; Wed, 19 Aug 2020 15:40:44 -0700 (PDT) Date: Wed, 19 Aug 2020 15:40:27 -0700 In-Reply-To: <20200819224030.1615203-1-haoluo@google.com> Message-Id: <20200819224030.1615203-6-haoluo@google.com> Mime-Version: 1.0 References: <20200819224030.1615203-1-haoluo@google.com> X-Mailer: git-send-email 2.28.0.220.ged08abb693-goog Subject: [PATCH bpf-next v1 5/8] bpf/selftests: ksyms_btf to test typed ksyms From: Hao Luo To: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Shuah Khan , Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Quentin Monnet , Hao Luo , Steven Rostedt , Ingo Molnar , Andrey Ignatov , Jakub Sitnicki Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Selftests for typed ksyms. Tests two types of ksyms: one is a struct, the other is a plain int. This tests two paths in the kernel. Struct ksyms will be converted into PTR_TO_BTF_ID by the verifier while int typed ksyms will be converted into PTR_TO_MEM. Signed-off-by: Hao Luo --- .../selftests/bpf/prog_tests/ksyms_btf.c | 77 +++++++++++++++++++ .../selftests/bpf/progs/test_ksyms_btf.c | 23 ++++++ 2 files changed, 100 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/ksyms_btf.c create mode 100644 tools/testing/selftests/bpf/progs/test_ksyms_btf.c diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c b/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c new file mode 100644 index 000000000000..1dad61ba7e99 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Google */ + +#include +#include +#include +#include "test_ksyms_btf.skel.h" + +static int duration; + +static __u64 kallsyms_find(const char *sym) +{ + char type, name[500]; + __u64 addr, res = 0; + FILE *f; + + f = fopen("/proc/kallsyms", "r"); + if (CHECK(!f, "kallsyms_fopen", "failed to open: %d\n", errno)) + return 0; + + while (fscanf(f, "%llx %c %499s%*[^\n]\n", &addr, &type, name) > 0) { + if (strcmp(name, sym) == 0) { + res = addr; + goto out; + } + } + + CHECK(false, "not_found", "symbol %s not found\n", sym); +out: + fclose(f); + return res; +} + +void test_ksyms_btf(void) +{ + __u64 runqueues_addr = kallsyms_find("runqueues"); + __u64 bpf_prog_active_addr = kallsyms_find("bpf_prog_active"); + struct test_ksyms_btf *skel; + struct test_ksyms_btf__data *data; + struct btf *btf; + int percpu_datasec; + int err; + + btf = libbpf_find_kernel_btf(); + if (CHECK(IS_ERR(btf), "btf_exists", "failed to load kernel BTF: %ld\n", + PTR_ERR(btf))) + return; + + percpu_datasec = btf__find_by_name_kind(btf, ".data..percpu", + BTF_KIND_DATASEC); + if (percpu_datasec < 0) { + printf("%s:SKIP:no PERCPU DATASEC in kernel btf\n", + __func__); + test__skip(); + return; + } + + skel = test_ksyms_btf__open_and_load(); + if (CHECK(!skel, "skel_open", "failed to open and load skeleton\n")) + return; + + err = test_ksyms_btf__attach(skel); + if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) + goto cleanup; + + /* trigger tracepoint */ + usleep(1); + + data = skel->data; + CHECK(data->out__runqueues != runqueues_addr, "runqueues", + "got %llu, exp %llu\n", data->out__runqueues, runqueues_addr); + CHECK(data->out__bpf_prog_active != bpf_prog_active_addr, "bpf_prog_active", + "got %llu, exp %llu\n", data->out__bpf_prog_active, bpf_prog_active_addr); + +cleanup: + test_ksyms_btf__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/test_ksyms_btf.c b/tools/testing/selftests/bpf/progs/test_ksyms_btf.c new file mode 100644 index 000000000000..e04e31117f84 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_ksyms_btf.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Google */ + +#include "vmlinux.h" + +#include + +__u64 out__runqueues = -1; +__u64 out__bpf_prog_active = -1; + +extern const struct rq runqueues __ksym; /* struct type global var. */ +extern const int bpf_prog_active __ksym; /* int type global var. */ + +SEC("raw_tp/sys_enter") +int handler(const void *ctx) +{ + out__runqueues = (__u64)&runqueues; + out__bpf_prog_active = (__u64)&bpf_prog_active; + + return 0; +} + +char _license[] SEC("license") = "GPL"; From patchwork Wed Aug 19 22:40:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hao Luo X-Patchwork-Id: 1348032 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=CaHLnB3h; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BX2nV2QFlz9sRK for ; Thu, 20 Aug 2020 08:41:18 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727955AbgHSWlO (ORCPT ); Wed, 19 Aug 2020 18:41:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727905AbgHSWkw (ORCPT ); Wed, 19 Aug 2020 18:40:52 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4919CC06134D for ; Wed, 19 Aug 2020 15:40:47 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id e196so114091ybh.6 for ; Wed, 19 Aug 2020 15:40:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=afpt0scmaMzcHXIzp9Twx0dB3tEDbNEdi+Fw7mN7FIw=; b=CaHLnB3haQfx6MS2XC38I9D/MfLgVT1XUQHMfUepLNppnOGkbLBb6SsG8xp2hB1g8U tC7lmStG8YvCaDdZPVJ9y6PhlH8t6310HFK0znFVybfVuzTCH1LxDNU4GaUYKgr+/osQ SCLCNd4Eo7U9VbRDFwLW5Xqz0P0jD+xRUykjThPnNtGIJtjieBvbawYs0ubT8ytXBJT4 kNsGqSjTt/rS2kNgemuUknrhD8obiU3x8HV6FW8HzYE7HHCbIOEKLRRv5AyHrGgQXt8e TadPkVYURET9F3BWrG1yVcvGYWzdofaf+Reg2BhmzEaVhI2hmvwsoMGqzRIbvgdPhBuR NFIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=afpt0scmaMzcHXIzp9Twx0dB3tEDbNEdi+Fw7mN7FIw=; b=XA6n1IMSU6nSOONLNDgE8SopLrjkwoz3fO31E/QfWL5Lhb+F8jneBOMvnvHaiEMoJv Whs8lFPfc8k1/imZcJf2xakPoDypi3RINM6/me70jou3ZVP5FHrRuWHwO0oV3qYmBnuh MPFdF2ZXkch/0n5Tf0u4ot4neDCRDGWRh1F+WksZdY1Kn0XN1Zw2zLeNUyqX+vYjUC1P MjE3jYfcwsj7lNKTki5y2IKznaYlG3PY8yjI9pLE8VlKOZjwemymqGg87cwWSicE3C1k S8/vvIUKFfeCXNEjb4h3NUHkBYDSmG7kSsvPIEkV2Yd3T/WQNc+AEVfeOd0TY6ebim5a vEQA== X-Gm-Message-State: AOAM532ktuKZgtnBd3m6XBWjekEIjzynLvdoewD7IDNAbM3yCOf5JS21 GcOmD59CQ04FHpMc/n9m1+k6oSpjSDNY72gfmSaoKvMe1OEb9IbHSVpzydH3LoEprFHRDYqdVrW XzNocuUvH8nZzEk10R9+emSFAPmWNp9Coo3OF7uHuPJtkmMTTPvyk7HqQ3Om0jA== X-Google-Smtp-Source: ABdhPJx1SBqLs8Bkr7O8Zl7ClzzAPwhu+tQxqiv7VTVMn7zbURfW1doOwgpZE92q6ImKVA/MAqPhIBzkBew= X-Received: from haoluo.svl.corp.google.com ([2620:15c:2cd:202:f693:9fff:fef4:e444]) (user=haoluo job=sendgmr) by 2002:a25:c347:: with SMTP id t68mr961734ybf.105.1597876846395; Wed, 19 Aug 2020 15:40:46 -0700 (PDT) Date: Wed, 19 Aug 2020 15:40:28 -0700 In-Reply-To: <20200819224030.1615203-1-haoluo@google.com> Message-Id: <20200819224030.1615203-7-haoluo@google.com> Mime-Version: 1.0 References: <20200819224030.1615203-1-haoluo@google.com> X-Mailer: git-send-email 2.28.0.220.ged08abb693-goog Subject: [PATCH bpf-next v1 6/8] bpf: Introduce bpf_per_cpu_ptr() From: Hao Luo To: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Shuah Khan , Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Quentin Monnet , Hao Luo , Steven Rostedt , Ingo Molnar , Andrey Ignatov , Jakub Sitnicki Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add bpf_per_cpu_ptr() to help bpf programs access percpu vars. bpf_per_cpu_ptr() has the same semantic as per_cpu_ptr() in the kernel except that it may return NULL. This happens when the cpu parameter is out of range. So the caller must check the returned value. Signed-off-by: Hao Luo Acked-by: Andrii Nakryiko --- include/linux/bpf.h | 3 ++ include/linux/btf.h | 11 +++++++ include/uapi/linux/bpf.h | 14 +++++++++ kernel/bpf/btf.c | 10 ------- kernel/bpf/verifier.c | 64 ++++++++++++++++++++++++++++++++++++++-- kernel/trace/bpf_trace.c | 18 +++++++++++ 6 files changed, 107 insertions(+), 13 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 55f694b63164..613404beab33 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -268,6 +268,7 @@ enum bpf_arg_type { ARG_PTR_TO_ALLOC_MEM, /* pointer to dynamically allocated memory */ ARG_PTR_TO_ALLOC_MEM_OR_NULL, /* pointer to dynamically allocated memory or NULL */ ARG_CONST_ALLOC_SIZE_OR_ZERO, /* number of allocated bytes requested */ + ARG_PTR_TO_PERCPU_BTF_ID, /* pointer to in-kernel percpu type */ }; /* type of values returned from helper functions */ @@ -281,6 +282,7 @@ enum bpf_return_type { RET_PTR_TO_SOCK_COMMON_OR_NULL, /* returns a pointer to a sock_common or NULL */ RET_PTR_TO_ALLOC_MEM_OR_NULL, /* returns a pointer to dynamically allocated memory or NULL */ RET_PTR_TO_BTF_ID_OR_NULL, /* returns a pointer to a btf_id or NULL */ + RET_PTR_TO_MEM_OR_BTF_OR_NULL, /* returns a pointer to a valid memory or a btf_id or NULL */ }; /* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs @@ -360,6 +362,7 @@ enum bpf_reg_type { PTR_TO_RDONLY_BUF_OR_NULL, /* reg points to a readonly buffer or NULL */ PTR_TO_RDWR_BUF, /* reg points to a read/write buffer */ PTR_TO_RDWR_BUF_OR_NULL, /* reg points to a read/write buffer or NULL */ + PTR_TO_PERCPU_BTF_ID, /* reg points to percpu kernel type */ }; /* The information passed from prog-specific *_is_valid_access diff --git a/include/linux/btf.h b/include/linux/btf.h index cee4089e83c0..dc3509246913 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -72,6 +72,11 @@ btf_resolve_size(const struct btf *btf, const struct btf_type *type, i < btf_type_vlen(struct_type); \ i++, member++) +#define for_each_vsi(i, struct_type, member) \ + for (i = 0, member = btf_type_var_secinfo(struct_type); \ + i < btf_type_vlen(struct_type); \ + i++, member++) + static inline bool btf_type_is_ptr(const struct btf_type *t) { return BTF_INFO_KIND(t->info) == BTF_KIND_PTR; @@ -156,6 +161,12 @@ static inline const struct btf_member *btf_type_member(const struct btf_type *t) return (const struct btf_member *)(t + 1); } +static inline const struct btf_var_secinfo *btf_type_var_secinfo( + const struct btf_type *t) +{ + return (const struct btf_var_secinfo *)(t + 1); +} + #ifdef CONFIG_BPF_SYSCALL const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id); const char *btf_name_by_offset(const struct btf *btf, u32 offset); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 468376f2910b..c7e49a102ed2 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3415,6 +3415,19 @@ union bpf_attr { * A non-negative value equal to or less than *size* on success, * or a negative error in case of failure. * + * void *bpf_per_cpu_ptr(const void *ptr, u32 cpu) + * Description + * Take the address of a percpu ksym and return a pointer pointing + * to the variable on *cpu*. A ksym is an extern variable decorated + * with '__ksym'. A ksym is percpu if there is a global percpu var + * (either static or global) defined of the same name in the kernel. + * + * bpf_per_cpu_ptr() has the same semantic as per_cpu_ptr() in the + * kernel, except that bpf_per_cpu_ptr() may return NULL. This + * happens if *cpu* is larger than nr_cpu_ids. The caller of + * bpf_per_cpu_ptr() must check the returned value. + * Return + * A generic pointer pointing to the variable on *cpu*. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3559,6 +3572,7 @@ union bpf_attr { FN(skc_to_tcp_request_sock), \ FN(skc_to_udp6_sock), \ FN(get_task_stack), \ + FN(bpf_per_cpu_ptr), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index b6d8f653afe2..e735804f5f34 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -186,11 +186,6 @@ i < btf_type_vlen(struct_type); \ i++, member++) -#define for_each_vsi(i, struct_type, member) \ - for (i = 0, member = btf_type_var_secinfo(struct_type); \ - i < btf_type_vlen(struct_type); \ - i++, member++) - #define for_each_vsi_from(i, from, struct_type, member) \ for (i = from, member = btf_type_var_secinfo(struct_type) + from; \ i < btf_type_vlen(struct_type); \ @@ -511,11 +506,6 @@ static const struct btf_var *btf_type_var(const struct btf_type *t) return (const struct btf_var *)(t + 1); } -static const struct btf_var_secinfo *btf_type_var_secinfo(const struct btf_type *t) -{ - return (const struct btf_var_secinfo *)(t + 1); -} - static const struct btf_kind_operations *btf_type_ops(const struct btf_type *t) { return kind_ops[BTF_INFO_KIND(t->info)]; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 47badde71f83..c2db6308d6fa 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -238,6 +238,7 @@ struct bpf_call_arg_meta { int ref_obj_id; int func_id; u32 btf_id; + u32 ret_btf_id; }; struct btf *btf_vmlinux; @@ -503,6 +504,7 @@ static const char * const reg_type_str[] = { [PTR_TO_XDP_SOCK] = "xdp_sock", [PTR_TO_BTF_ID] = "ptr_", [PTR_TO_BTF_ID_OR_NULL] = "ptr_or_null_", + [PTR_TO_PERCPU_BTF_ID] = "percpu_ptr_", [PTR_TO_MEM] = "mem", [PTR_TO_MEM_OR_NULL] = "mem_or_null", [PTR_TO_RDONLY_BUF] = "rdonly_buf", @@ -569,7 +571,9 @@ static void print_verifier_state(struct bpf_verifier_env *env, /* reg->off should be 0 for SCALAR_VALUE */ verbose(env, "%lld", reg->var_off.value + reg->off); } else { - if (t == PTR_TO_BTF_ID || t == PTR_TO_BTF_ID_OR_NULL) + if (t == PTR_TO_BTF_ID || + t == PTR_TO_BTF_ID_OR_NULL || + t == PTR_TO_PERCPU_BTF_ID) verbose(env, "%s", kernel_type_name(reg->btf_id)); verbose(env, "(id=%d", reg->id); if (reg_type_may_be_refcounted_or_null(t)) @@ -2183,6 +2187,7 @@ static bool is_spillable_regtype(enum bpf_reg_type type) case PTR_TO_RDONLY_BUF_OR_NULL: case PTR_TO_RDWR_BUF: case PTR_TO_RDWR_BUF_OR_NULL: + case PTR_TO_PERCPU_BTF_ID: return true; default: return false; @@ -3959,6 +3964,15 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, if (type != expected_type) goto err_type; } + } else if (arg_type == ARG_PTR_TO_PERCPU_BTF_ID) { + expected_type = PTR_TO_PERCPU_BTF_ID; + if (type != expected_type) + goto err_type; + if (!reg->btf_id) { + verbose(env, "Helper has zero btf_id in R%d\n", regno); + return -EACCES; + } + meta->ret_btf_id = reg->btf_id; } else if (arg_type == ARG_PTR_TO_BTF_ID) { expected_type = PTR_TO_BTF_ID; if (type != expected_type) @@ -4904,6 +4918,30 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn regs[BPF_REG_0].type = PTR_TO_MEM_OR_NULL; regs[BPF_REG_0].id = ++env->id_gen; regs[BPF_REG_0].mem_size = meta.mem_size; + } else if (fn->ret_type == RET_PTR_TO_MEM_OR_BTF_OR_NULL) { + const struct btf_type *t; + + mark_reg_known_zero(env, regs, BPF_REG_0); + t = btf_type_skip_modifiers(btf_vmlinux, meta.ret_btf_id, NULL); + if (!btf_type_is_struct(t)) { + u32 tsize; + const struct btf_type *ret; + const char *tname; + + /* resolve the type size of ksym. */ + ret = btf_resolve_size(btf_vmlinux, t, &tsize, NULL, NULL); + if (IS_ERR(ret)) { + tname = btf_name_by_offset(btf_vmlinux, t->name_off); + verbose(env, "unable to resolve the size of type '%s': %ld\n", + tname, PTR_ERR(ret)); + return -EINVAL; + } + regs[BPF_REG_0].type = PTR_TO_MEM_OR_NULL; + regs[BPF_REG_0].mem_size = tsize; + } else { + regs[BPF_REG_0].type = PTR_TO_BTF_ID_OR_NULL; + regs[BPF_REG_0].btf_id = meta.ret_btf_id; + } } else if (fn->ret_type == RET_PTR_TO_BTF_ID_OR_NULL) { int ret_btf_id; @@ -7210,10 +7248,15 @@ static inline int check_pseudo_btf_id(struct bpf_verifier_env *env, struct bpf_insn *insn) { struct bpf_reg_state *regs = cur_regs(env); - u32 type, id = insn->imm; + u32 datasec_id, type, id = insn->imm; u64 addr; const char *sym_name; const struct btf_type *t = btf_type_by_id(btf_vmlinux, id); + const struct btf_type *datasec; + const struct btf_var_secinfo *vsi; + int i; + + bool percpu = false; if (!t) { verbose(env, "%s: invalid btf_id %d\n", __func__, id); @@ -7243,9 +7286,24 @@ static inline int check_pseudo_btf_id(struct bpf_verifier_env *env, insn[1].imm = addr >> 32; mark_reg_known_zero(env, regs, insn->dst_reg); + datasec_id = btf_find_by_name_kind(btf_vmlinux, ".data..percpu", + BTF_KIND_DATASEC); + if (datasec_id > 0) { + datasec = btf_type_by_id(btf_vmlinux, datasec_id); + for_each_vsi(i, datasec, vsi) { + if (vsi->type == id) { + percpu = true; + break; + } + } + } + type = t->type; t = btf_type_skip_modifiers(btf_vmlinux, type, NULL); - if (!btf_type_is_struct(t)) { + if (percpu) { + regs[insn->dst_reg].type = PTR_TO_PERCPU_BTF_ID; + regs[insn->dst_reg].btf_id = type; + } else if (!btf_type_is_struct(t)) { u32 tsize; const struct btf_type *ret; const char *tname; diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index a8d4f253ed77..7f0033960d82 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1098,6 +1098,22 @@ static const struct bpf_func_proto bpf_send_signal_thread_proto = { .arg1_type = ARG_ANYTHING, }; +BPF_CALL_2(bpf_per_cpu_ptr, const void *, ptr, u32, cpu) +{ + if (cpu >= nr_cpu_ids) + return 0; + + return (u64)per_cpu_ptr(ptr, cpu); +} + +static const struct bpf_func_proto bpf_per_cpu_ptr_proto = { + .func = bpf_per_cpu_ptr, + .gpl_only = false, + .ret_type = RET_PTR_TO_MEM_OR_BTF_OR_NULL, + .arg1_type = ARG_PTR_TO_PERCPU_BTF_ID, + .arg2_type = ARG_ANYTHING, +}; + const struct bpf_func_proto * bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) { @@ -1182,6 +1198,8 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_jiffies64_proto; case BPF_FUNC_get_task_stack: return &bpf_get_task_stack_proto; + case BPF_FUNC_bpf_per_cpu_ptr: + return &bpf_per_cpu_ptr_proto; default: return NULL; } From patchwork Wed Aug 19 22:40:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hao Luo X-Patchwork-Id: 1348033 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=oyjRIqCq; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BX2nm1RCsz9sRK for ; Thu, 20 Aug 2020 08:41:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726681AbgHSWl3 (ORCPT ); Wed, 19 Aug 2020 18:41:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727920AbgHSWky (ORCPT ); Wed, 19 Aug 2020 18:40:54 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1B8EC061358 for ; Wed, 19 Aug 2020 15:40:48 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id v10so235048plp.5 for ; Wed, 19 Aug 2020 15:40:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=NLjzglEfUx/tYjZ6bE489vKKomGgM6zRTKGgnxbmNyw=; b=oyjRIqCqy9fSSlUqNZozmrxpfmDEkCPtM3Cbc/Cnz1QCDqFxh3i6SpKu6iDmReppja dtK/A8mDKHu06jn23AvBgZCKx+ZRrUwIpzpfBg67FF20329ReDCclK/KenPGjzDVbi98 M/i6GSj6NgfhscpB31fcZDq2zOuBc8qGR9VzGqpidj4qwhW9LalXAE+AUV0PoPFcUY9B yZ6wFH/k8ZWaUpOO5ECXxkMp0iL2iw8lOmzQ+Orr4ailvkpDzMw7hclCPDS5ZBHPhWPo Dq+URx2udIlMrRS4wtzgbHWS3ZgzuF6n4c6ZSwSGsPPm61DvhzDOWej2iH6nWltjmrNv vP/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=NLjzglEfUx/tYjZ6bE489vKKomGgM6zRTKGgnxbmNyw=; b=JWK7vbGKEdpLUH6uyVO4b07Al9UsLM3Pz3dH7Xxs4yRycIszq6GNMHzSCuYR0QbDKf 6aQfTz1DkT400BLNHj9HkFslYSMsb68AnCA3IUnGa1tpQk9BxhVRVWxfgPwSXnWA+SWs LrItmxzMjAZZpftIMVTw49zqZPaTQlXUNrZtlC6FMdqfnroMPZgawRMjQuDtKV3rnTz5 wcCGnLtCsVGqPhxGWPZnlYCtOZAHa30AoXiYrWw/STExzBCuIJy3+SRk1B4ii86lfWl2 HCUJEUGI5FJqXSogww71Ilr0XF7JjctOrMP1Nkox8ZaanCw8pmKnkrVzBx1Xne/iNU8p K4Vg== X-Gm-Message-State: AOAM53182J8feHba0OUtFtILA6UxxS0tQ9ztJ4j/ncnM4G1GgDfvVz6l 4Z3tTosc4Ib+gqy6jDzvq+YJHhZDU10= X-Google-Smtp-Source: ABdhPJx1hKQ8+B9EP1bBAT5p24RynlXXCuRT/DErWwZMGYM0QNfK2w7ueHo92OOANb7IeKdC4KJnmB+h4jw= X-Received: from haoluo.svl.corp.google.com ([2620:15c:2cd:202:f693:9fff:fef4:e444]) (user=haoluo job=sendgmr) by 2002:a17:90a:7485:: with SMTP id p5mr92595pjk.130.1597876848380; Wed, 19 Aug 2020 15:40:48 -0700 (PDT) Date: Wed, 19 Aug 2020 15:40:29 -0700 In-Reply-To: <20200819224030.1615203-1-haoluo@google.com> Message-Id: <20200819224030.1615203-8-haoluo@google.com> Mime-Version: 1.0 References: <20200819224030.1615203-1-haoluo@google.com> X-Mailer: git-send-email 2.28.0.220.ged08abb693-goog Subject: [PATCH bpf-next v1 7/8] bpf: Propagate bpf_per_cpu_ptr() to /tools From: Hao Luo To: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Shuah Khan , Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Quentin Monnet , Hao Luo , Steven Rostedt , Ingo Molnar , Andrey Ignatov , Jakub Sitnicki Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Sync tools/include/linux/uapi/bpf.h with include/linux/uapi/bpf.h Signed-off-by: Hao Luo --- tools/include/uapi/linux/bpf.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 468376f2910b..7e3dfb2bbb86 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3415,6 +3415,20 @@ union bpf_attr { * A non-negative value equal to or less than *size* on success, * or a negative error in case of failure. * + * void *bpf_per_cpu_ptr(const void *ptr, u32 cpu) + * Description + * Take the address of a percpu ksym and return a pointer pointing + * to the variable on *cpu*. A ksym is an extern variable decorated + * with '__ksym'. A ksym is percpu if there is a global percpu var + * (either static or global) defined of the same name in the kernel. + * + * bpf_per_cpu_ptr() has the same semantic as per_cpu_ptr() in the + * kernel, except that bpf_per_cpu_ptr() may return NULL. This + * happens if *cpu* is larger than nr_cpu_ids. The caller of + * bpf_per_cpu_ptr() must check the returned value. + * Return + * A generic pointer pointing to the variable on *cpu*. + * */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3559,6 +3573,7 @@ union bpf_attr { FN(skc_to_tcp_request_sock), \ FN(skc_to_udp6_sock), \ FN(get_task_stack), \ + FN(bpf_per_cpu_ptr), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper From patchwork Wed Aug 19 22:40:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hao Luo X-Patchwork-Id: 1348035 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=Jk23KIiA; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BX2p44Lckz9sTK for ; Thu, 20 Aug 2020 08:41:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727961AbgHSWl2 (ORCPT ); Wed, 19 Aug 2020 18:41:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726617AbgHSWk5 (ORCPT ); Wed, 19 Aug 2020 18:40:57 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D535C061387 for ; Wed, 19 Aug 2020 15:40:51 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id cp23so45540pjb.9 for ; Wed, 19 Aug 2020 15:40:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=DU+DeOt4r+Fv0uxk+6Q5tVdQKnGcEbfoUocacOxwgMU=; b=Jk23KIiA7W88ZhegNRM2yFYJA2nirIUkscEgy3RSxO65DBKHFteJW8rfJvsuIIMNYC JtSJALfn/NCRxOG5lOZKqD9fbP+hoHU03zqswpWd3wv/rZRI7SaFg2PIc+bHzXDkQGDc z/rfsKXh3vSr1jYoSm3tbO/kxyOJlYtmn/AP3rJoReDr7JVP2OfoJFUVPLt46PqeWCD3 +UGaXlRuokYAEYkJqiw6jFIF0mcmD6zFSicEmY0SqNrFYttXI3E6XGP5ipylrDE8poOp M0u2GSMFQWJWrNYJchrUXS1zvckkPOZZLROZSv57idk0dZob7fsWwjs9eHPZCk+eUVFC wXWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=DU+DeOt4r+Fv0uxk+6Q5tVdQKnGcEbfoUocacOxwgMU=; b=uknlq/YyGnKrJ6jBioxEinRiO0w5MoZ3nmQEBmsfeFiTkdzleWkJHcjXU9ZrsqfvhJ /gAJo4xnvENDqDmYKw7YmRThHwhltQ/ByY2IhXqaYQ0yNysobqe+jNb7Md92l+FyROQg 0ZVoJA1IA7i+ar7q3xFw+X5GT1JJVJk0yjBPAfYWUxSCiufhKWDZTowRy/fWfJursehb xLW+Fy135cRu/LEzr2tQcHWutIH5lI1xTnuEx8415zaQraNveeLbQ0bRbQz7W/bI9F87 s0DqkEQHMrX2PBqmbE+kl+YGCSlDbUarb8wum6oGbT+9WcQKpKwtDj/xNtdGaP5oXZDn WDXQ== X-Gm-Message-State: AOAM530L2oT8SEaj13L7FTS2S2GV+pJGl08kymLWdW+oSDZhAB/O0a2j sZMPdbaJ3vmIBZohwYJfyf4XNnWR2/Y= X-Google-Smtp-Source: ABdhPJwbVXCs5G7r9UtdEIL5EAxGaM9Kalf4iGsFal/f5OTBIlAgdKRFO2oDzF3oxIHTTNIrcbUPT9YIo4M= X-Received: from haoluo.svl.corp.google.com ([2620:15c:2cd:202:f693:9fff:fef4:e444]) (user=haoluo job=sendgmr) by 2002:a63:2482:: with SMTP id k124mr422506pgk.251.1597876850514; Wed, 19 Aug 2020 15:40:50 -0700 (PDT) Date: Wed, 19 Aug 2020 15:40:30 -0700 In-Reply-To: <20200819224030.1615203-1-haoluo@google.com> Message-Id: <20200819224030.1615203-9-haoluo@google.com> Mime-Version: 1.0 References: <20200819224030.1615203-1-haoluo@google.com> X-Mailer: git-send-email 2.28.0.220.ged08abb693-goog Subject: [PATCH bpf-next v1 8/8] bpf/selftests: Test for bpf_per_cpu_ptr() From: Hao Luo To: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Shuah Khan , Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Quentin Monnet , Hao Luo , Steven Rostedt , Ingo Molnar , Andrey Ignatov , Jakub Sitnicki Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Test bpf_per_cpu_ptr(). Test two paths in the kernel. If the base pointer points to a struct, the returned reg is of type PTR_TO_BTF_ID. Direct pointer dereference can be applied on the returned variable. If the base pointer isn't a struct, the returned reg is of type PTR_TO_MEM, which also supports direct pointer dereference. Signed-off-by: Hao Luo Acked-by: Andrii Nakryiko --- .../testing/selftests/bpf/prog_tests/ksyms_btf.c | 4 ++++ .../testing/selftests/bpf/progs/test_ksyms_btf.c | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c b/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c index 1dad61ba7e99..bdedd4a76b42 100644 --- a/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c +++ b/tools/testing/selftests/bpf/prog_tests/ksyms_btf.c @@ -71,6 +71,10 @@ void test_ksyms_btf(void) "got %llu, exp %llu\n", data->out__runqueues, runqueues_addr); CHECK(data->out__bpf_prog_active != bpf_prog_active_addr, "bpf_prog_active", "got %llu, exp %llu\n", data->out__bpf_prog_active, bpf_prog_active_addr); + CHECK(data->out__rq_cpu != 1, "rq_cpu", + "got %u, exp %u\n", data->out__rq_cpu, 1); + CHECK(data->out__process_counts == -1, "process_counts", + "got %lu, exp != -1", data->out__process_counts); cleanup: test_ksyms_btf__destroy(skel); diff --git a/tools/testing/selftests/bpf/progs/test_ksyms_btf.c b/tools/testing/selftests/bpf/progs/test_ksyms_btf.c index e04e31117f84..78cf1ebb753d 100644 --- a/tools/testing/selftests/bpf/progs/test_ksyms_btf.c +++ b/tools/testing/selftests/bpf/progs/test_ksyms_btf.c @@ -7,16 +7,29 @@ __u64 out__runqueues = -1; __u64 out__bpf_prog_active = -1; +__u32 out__rq_cpu = -1; +unsigned long out__process_counts = -1; -extern const struct rq runqueues __ksym; /* struct type global var. */ +extern const struct rq runqueues __ksym; /* struct type percpu var. */ extern const int bpf_prog_active __ksym; /* int type global var. */ +extern const unsigned long process_counts __ksym; /* int type percpu var. */ SEC("raw_tp/sys_enter") int handler(const void *ctx) { + struct rq *rq; + unsigned long *count; + out__runqueues = (__u64)&runqueues; out__bpf_prog_active = (__u64)&bpf_prog_active; + rq = (struct rq *)bpf_per_cpu_ptr(&runqueues, 1); + if (rq) + out__rq_cpu = rq->cpu; + count = (unsigned long *)bpf_per_cpu_ptr(&process_counts, 1); + if (count) + out__process_counts = *count; + return 0; }