From patchwork Mon May 14 11:51:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandipan Das X-Patchwork-Id: 912888 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=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40kzZq1b5yz9s08 for ; Mon, 14 May 2018 21:52:19 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753139AbeENLwQ (ORCPT ); Mon, 14 May 2018 07:52:16 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:38004 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752829AbeENLvb (ORCPT ); Mon, 14 May 2018 07:51:31 -0400 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w4EBnNOZ014792 for ; Mon, 14 May 2018 07:51:31 -0400 Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com [195.75.94.109]) by mx0a-001b2d01.pphosted.com with ESMTP id 2hy9ak1nds-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 14 May 2018 07:51:31 -0400 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 14 May 2018 12:51:28 +0100 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 14 May 2018 12:51:26 +0100 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w4EBpQfB8782190; Mon, 14 May 2018 11:51:26 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E15DBA4059; Mon, 14 May 2018 12:42:58 +0100 (BST) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E3E16A4053; Mon, 14 May 2018 12:42:57 +0100 (BST) Received: from localhost.localdomain (unknown [9.40.193.84]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 14 May 2018 12:42:57 +0100 (BST) From: Sandipan Das To: ast@fb.com, daniel@iogearbox.net Cc: netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, mpe@ellerman.id.au, naveen.n.rao@linux.vnet.ibm.com Subject: [RFC][PATCH bpf v3 3/5] bpf: get JITed function addresses via syscall Date: Mon, 14 May 2018 17:21:16 +0530 X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180514115118.8149-1-sandipan@linux.vnet.ibm.com> References: <20180514115118.8149-1-sandipan@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18051411-0012-0000-0000-000005D66663 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18051411-0013-0000-0000-000019537BE4 Message-Id: <20180514115118.8149-3-sandipan@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-05-14_02:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1805140122 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This adds new two new fields to struct bpf_prog_info. For multi-function programs, these fields can be used to pass a list of kernel symbol addresses for all functions in a given program and to userspace using the bpf system call with the BPF_OBJ_GET_INFO_BY_FD command. When bpf_jit_kallsyms is enabled, we can get the address of the corresponding kernel symbol for a callee function and resolve the symbol's name. The address is determined by adding the value of the call instruction's imm field to __bpf_call_base. This offset gets assigned to the imm field by the verifier. For some architectures, such as powerpc64, the imm field is not large enough to hold this offset. We resolve this by: [1] Assigning the subprog id to the imm field of a call instruction in the verifier instead of the offset of the callee's symbol's address from __bpf_call_base. [2] Determining the address of a callee's corresponding symbol by using the imm field as an index for the list of function addresses now available from the program info. Suggested-by: Daniel Borkmann Signed-off-by: Sandipan Das --- include/uapi/linux/bpf.h | 2 ++ kernel/bpf/syscall.c | 18 ++++++++++++++++++ kernel/bpf/verifier.c | 7 +------ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 93d5a4eeec2a..b9c9c7690337 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -2108,6 +2108,8 @@ struct bpf_prog_info { __u32 xlated_prog_len; __aligned_u64 jited_prog_insns; __aligned_u64 xlated_prog_insns; + __aligned_u64 jited_funcs; + __u32 nr_jited_funcs; __u64 load_time; /* ns since boottime */ __u32 created_by_uid; __u32 nr_map_ids; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 9b87198deea2..600da849233d 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1924,6 +1924,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, if (!capable(CAP_SYS_ADMIN)) { info.jited_prog_len = 0; info.xlated_prog_len = 0; + info.nr_jited_funcs = 0; goto done; } @@ -1972,6 +1973,23 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, } } + ulen = info.nr_jited_funcs; + info.nr_jited_funcs = prog->aux->func_cnt; + if (info.nr_jited_funcs && ulen) { + u64 __user *user_jited_funcs = u64_to_user_ptr(info.jited_funcs); + u32 i; + + /* copy the start addresses of the JITed images for all + * functions + */ + ulen = min_t(u32, info.nr_jited_funcs, ulen); + for (i = 0; i < ulen; i++) { + if (put_user((u64) prog->aux->func[i]->bpf_func & PAGE_MASK, + &user_jited_funcs[i])) + return -EFAULT; + } + } + done: if (copy_to_user(uinfo, &info, info_len) || put_user(info_len, &uattr->info.info_len)) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index aa76879f4fd1..fc864eb3e29d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5416,17 +5416,12 @@ static int jit_subprogs(struct bpf_verifier_env *env) * later look the same as if they were interpreted only. */ for (i = 0, insn = prog->insnsi; i < prog->len; i++, insn++) { - unsigned long addr; - if (insn->code != (BPF_JMP | BPF_CALL) || insn->src_reg != BPF_PSEUDO_CALL) continue; insn->off = env->insn_aux_data[i].call_imm; subprog = find_subprog(env, i + insn->off + 1); - addr = (unsigned long)func[subprog]->bpf_func; - addr &= PAGE_MASK; - insn->imm = (u64 (*)(u64, u64, u64, u64, u64)) - addr - __bpf_call_base; + insn->imm = subprog; } prog->jited = 1;