From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D3EBEC433FE for ; Fri, 14 Jan 2022 00:50:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238527AbiANAuA (ORCPT ); Thu, 13 Jan 2022 19:50:00 -0500 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:64272 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S238417AbiANAt7 (ORCPT ); Thu, 13 Jan 2022 19:49:59 -0500 Received: from pps.filterd (m0001303.ppops.net [127.0.0.1]) by m0001303.ppops.net (8.16.1.2/8.16.1.2) with ESMTP id 20DN6YYI002926 for ; Thu, 13 Jan 2022 16:49:59 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=q3CYOeAr6DF4Tj5sbWkXEiSc+qoUQX+iq1lA6pQ0sGM=; b=AQ5lqCHg5WYz3i6YX9c4Cqw+S6kEeY5IuKuP5vBi59g7QzVwZSW2bKxxZhgekxCYiofW KkRnzfHFhbOvxPPjfr7wgZXv3e0XluSFS0YQxp4ArNNF7polXfnZEoux1CsPl7wLp0Nf nTrbnTryzJ0zraBvlIKiE5tX2a8jgqFhqC8= Received: from mail.thefacebook.com ([163.114.132.120]) by m0001303.ppops.net (PPS) with ESMTPS id 3dj4b98m2q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 13 Jan 2022 16:49:59 -0800 Received: from twshared22811.39.frc1.facebook.com (2620:10d:c085:208::f) by mail.thefacebook.com (2620:10d:c085:11d::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.20; Thu, 13 Jan 2022 16:49:24 -0800 Received: by devbig014.vll3.facebook.com (Postfix, from userid 7377) id F3F378FA3208; Thu, 13 Jan 2022 16:49:13 -0800 (PST) From: Kenny Yu To: , , , , CC: Kenny Yu Subject: [PATCH v2 bpf-next 1/4] bpf: Add bpf_access_process_vm() helper Date: Thu, 13 Jan 2022 16:48:57 -0800 Message-ID: <20220114004900.3756025-2-kennyyu@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220114004900.3756025-1-kennyyu@fb.com> References: <20220113233158.1582743-1-kennyyu@fb.com> <20220114004900.3756025-1-kennyyu@fb.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-FB-Internal: Safe Content-Type: text/plain X-Proofpoint-GUID: UwMIf5qWrxUZqZ_Mf5Arpnk5iF6UU5UB X-Proofpoint-ORIG-GUID: UwMIf5qWrxUZqZ_Mf5Arpnk5iF6UU5UB X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-13_10,2022-01-13_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=fb_outbound_notspam policy=fb_outbound score=0 priorityscore=1501 impostorscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 bulkscore=0 spamscore=0 malwarescore=0 clxscore=1015 phishscore=0 mlxscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2201140002 X-FB-Internal: deliver Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org This adds a helper for bpf programs to access the memory of other tasks. This also adds the ability for bpf iterator programs to be sleepable. As an example use case at Meta, we are using a bpf task iterator program and this new helper to print C++ async stack traces for all threads of a given process. Signed-off-by: Kenny Yu --- include/linux/bpf.h | 1 + include/uapi/linux/bpf.h | 10 ++++++++++ kernel/bpf/helpers.c | 19 +++++++++++++++++++ kernel/trace/bpf_trace.c | 2 ++ tools/include/uapi/linux/bpf.h | 10 ++++++++++ 5 files changed, 42 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 6e947cd91152..d3d0ef8df148 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -2222,6 +2222,7 @@ extern const struct bpf_func_proto bpf_kallsyms_loo= kup_name_proto; extern const struct bpf_func_proto bpf_find_vma_proto; extern const struct bpf_func_proto bpf_loop_proto; extern const struct bpf_func_proto bpf_strncmp_proto; +extern const struct bpf_func_proto bpf_access_process_vm_proto; =20 const struct bpf_func_proto *tracing_prog_func_proto( enum bpf_func_id func_id, const struct bpf_prog *prog); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index b0383d371b9a..4b47ec8ae569 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -5018,6 +5018,15 @@ union bpf_attr { * * Return * The number of arguments of the traced function. + * + * long bpf_access_process_vm(struct task_struct *tsk, unsigned long add= r, void *buf, int len, unsigned int gup_flags) + * Description + * Read *len* bytes from user space address *addr* in *tsk*'s + * address space, and stores the data in *buf*. This is a wrapper + * of **access_process_vm**\ (). + * Return + * The number of bytes written to the buffer, or a negative error + * in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5206,6 +5215,7 @@ union bpf_attr { FN(get_func_arg), \ FN(get_func_ret), \ FN(get_func_arg_cnt), \ + FN(access_process_vm), \ /* */ =20 /* integer value in 'imm' field of BPF_CALL instruction selects which he= lper diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 01cfdf40c838..dd588912e197 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -16,6 +16,7 @@ #include #include #include +#include =20 #include "../../lib/kstrtox.h" =20 @@ -671,6 +672,24 @@ const struct bpf_func_proto bpf_copy_from_user_proto= =3D { .arg3_type =3D ARG_ANYTHING, }; =20 +BPF_CALL_5(bpf_access_process_vm, struct task_struct *, tsk, + unsigned long, addr, void *, buf, int, len, unsigned int, gup_flags) +{ + return access_process_vm(tsk, addr, buf, len, gup_flags); +} + +const struct bpf_func_proto bpf_access_process_vm_proto =3D { + .func =3D bpf_access_process_vm, + .gpl_only =3D false, + .ret_type =3D RET_INTEGER, + .arg1_type =3D ARG_PTR_TO_BTF_ID, + .arg1_btf_id =3D &btf_tracing_ids[BTF_TRACING_TYPE_TASK], + .arg2_type =3D ARG_ANYTHING, + .arg3_type =3D ARG_PTR_TO_UNINIT_MEM, + .arg4_type =3D ARG_CONST_SIZE_OR_ZERO, + .arg5_type =3D ARG_ANYTHING, +}; + BPF_CALL_2(bpf_per_cpu_ptr, const void *, ptr, u32, cpu) { if (cpu >=3D nr_cpu_ids) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 21aa30644219..1a6a81ce2e36 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1257,6 +1257,8 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, co= nst struct bpf_prog *prog) return &bpf_find_vma_proto; case BPF_FUNC_trace_vprintk: return bpf_get_trace_vprintk_proto(); + case BPF_FUNC_access_process_vm: + return prog->aux->sleepable ? &bpf_access_process_vm_proto : NULL; default: return bpf_base_func_proto(func_id); } diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bp= f.h index b0383d371b9a..4b47ec8ae569 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -5018,6 +5018,15 @@ union bpf_attr { * * Return * The number of arguments of the traced function. + * + * long bpf_access_process_vm(struct task_struct *tsk, unsigned long add= r, void *buf, int len, unsigned int gup_flags) + * Description + * Read *len* bytes from user space address *addr* in *tsk*'s + * address space, and stores the data in *buf*. This is a wrapper + * of **access_process_vm**\ (). + * Return + * The number of bytes written to the buffer, or a negative error + * in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -5206,6 +5215,7 @@ union bpf_attr { FN(get_func_arg), \ FN(get_func_ret), \ FN(get_func_arg_cnt), \ + FN(access_process_vm), \ /* */ =20 /* integer value in 'imm' field of BPF_CALL instruction selects which he= lper --=20 2.30.2