From patchwork Mon Oct 23 18:58:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 829593 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="zMiDiuJu"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yLQm43XnXz9sRg for ; Tue, 24 Oct 2017 06:03:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751667AbdJWTD3 (ORCPT ); Mon, 23 Oct 2017 15:03:29 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:43526 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751810AbdJWS6b (ORCPT ); Mon, 23 Oct 2017 14:58:31 -0400 Received: by mail-pf0-f193.google.com with SMTP id a8so17779800pfc.0 for ; Mon, 23 Oct 2017 11:58:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TmL69V5OTjWaPxSyp2sGCltSI3gKbyPLn1cVwDjlzoc=; b=zMiDiuJufqD3lpHi8XXDGFi/WyT5Mr4A5T7j7JslbRbYPY0nE3/7arPOyCJLQCbfZ1 ymIJk96EVNkbnp+DKSyrKgz6AcfNblklRYJ3K6WoA8ViH9ruXd0MVy1XKeWD3l3hOmAN NCVMNvhobL8rXTd60Y4WcTRhSxc9GAKOm3+GOhIf6dBcTpFyRPF+HoqHcV0y4AO2b6w/ 0OV6v7bWBcOxW+9fhTy0+ljNwQ5ejtu2kE3HUp+l3Ii41sPOn/VElbRlkKOCyAToZDPK 0woJrzf02Jv78Thod0nyYSEQxdqH6/TG3wk/jmIeZP9IoZMjIdWsh4jG4lkJlz1Ha441 tW0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TmL69V5OTjWaPxSyp2sGCltSI3gKbyPLn1cVwDjlzoc=; b=U0HQZU3FEvTNvXQy07nkRznRhq0lMnnGVPSD2WFr1lljJEDU8ttxR8CWa5q01aXm+h dPD5u6EoCJhsGVwMOd+S/1zr49vXVNSstkTL+38JwD5O1OWB+wDyHrcD2S1tqDXkVbrF DH/cdi8oKL0rAsEU604Lmucmvmpw4GKMa93CniDrvLt5cnUTuISravR0dzigNI8gqkhc SD9kV6xmi4rAEujE11pEascYGsnpmmTHNkKHMZpJ76VYOrfNDIMReX8PAFue4wXjep0z RHTWMxM2WXKeRDckIdWRPclGIENr8tK1XDUG0NQ0k4/iFaWvwEdsjyyHW2WHYat9FFhg 23+Q== X-Gm-Message-State: AMCzsaU2fi8UVcJjjE784s9BfyHw0EyB0XmVZIEPaM8nGvKL82o6rcZR 9lO6CXLQGCn/TRrXRnrht1SLRqzV X-Google-Smtp-Source: ABhQp+TZhVvSRlbdYQ3As9R1pPj2UpUXp4/0p9v3ukr9M4MZdClvTpg7LtPtOchAiKrDFZL0xMy18g== X-Received: by 10.84.168.69 with SMTP id e63mr10842880plb.193.1508785111023; Mon, 23 Oct 2017 11:58:31 -0700 (PDT) Received: from jkicinski-Precision-T1700.netronome.com ([75.53.12.129]) by smtp.gmail.com with ESMTPSA id x11sm11599255pgq.29.2017.10.23.11.58.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 23 Oct 2017 11:58:30 -0700 (PDT) From: Jakub Kicinski To: netdev@vger.kernel.org Cc: oss-drivers@netronome.com, Jakub Kicinski Subject: [PATCH net-next 6/9] nfp: bpf: allow stack accesses via modified stack registers Date: Mon, 23 Oct 2017 11:58:11 -0700 Message-Id: <20171023185814.4797-7-jakub.kicinski@netronome.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171023185814.4797-1-jakub.kicinski@netronome.com> References: <20171023185814.4797-1-jakub.kicinski@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org As long as the verifier tells us the stack offset exactly we can render the LMEM reads quite easily. Simply make sure that the offset is constant for a given instruction and add it to the instruction's offset. Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet --- drivers/net/ethernet/netronome/nfp/bpf/jit.c | 23 ++++++++++++---------- drivers/net/ethernet/netronome/nfp/bpf/main.h | 3 +++ drivers/net/ethernet/netronome/nfp/bpf/verifier.c | 24 ++++++++++++++++------- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c index 6730690cf9d8..073e382cba04 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c @@ -771,9 +771,10 @@ wrp_lmem_store(struct nfp_prog *nfp_prog, u8 src, u8 src_byte, s32 off, static int mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, - unsigned int size, u8 gpr, bool clr_gpr, lmem_step step) + unsigned int size, unsigned int ptr_off, u8 gpr, bool clr_gpr, + lmem_step step) { - s32 off = nfp_prog->stack_depth + meta->insn.off; + s32 off = nfp_prog->stack_depth + meta->insn.off + ptr_off; bool first = true, last; u8 prev_gpr = 255; u32 gpr_byte = 0; @@ -1311,10 +1312,10 @@ static int data_ind_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) static int mem_ldx_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, - unsigned int size) + unsigned int size, unsigned int ptr_off) { - return mem_op_stack(nfp_prog, meta, size, meta->insn.dst_reg * 2, true, - wrp_lmem_load); + return mem_op_stack(nfp_prog, meta, size, ptr_off, + meta->insn.dst_reg * 2, true, wrp_lmem_load); } static int mem_ldx_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, @@ -1401,7 +1402,8 @@ mem_ldx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, return mem_ldx_data(nfp_prog, meta, size); if (meta->ptr.type == PTR_TO_STACK) - return mem_ldx_stack(nfp_prog, meta, size); + return mem_ldx_stack(nfp_prog, meta, size, + meta->ptr.off + meta->ptr.var_off.value); return -EOPNOTSUPP; } @@ -1482,10 +1484,10 @@ mem_stx_data(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, static int mem_stx_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, - unsigned int size) + unsigned int size, unsigned int ptr_off) { - return mem_op_stack(nfp_prog, meta, size, meta->insn.src_reg * 2, false, - wrp_lmem_store); + return mem_op_stack(nfp_prog, meta, size, ptr_off, + meta->insn.src_reg * 2, false, wrp_lmem_store); } static int @@ -1496,7 +1498,8 @@ mem_stx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, return mem_stx_data(nfp_prog, meta, size); if (meta->ptr.type == PTR_TO_STACK) - return mem_stx_stack(nfp_prog, meta, size); + return mem_stx_stack(nfp_prog, meta, size, + meta->ptr.off + meta->ptr.var_off.value); return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h index a31632681e79..d4f144a62f0f 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.h +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h @@ -56,6 +56,7 @@ enum br_special { enum static_regs { STATIC_REG_IMM = 21, /* Bank AB */ + STATIC_REG_STACK = 22, /* Bank A */ STATIC_REG_PKT_LEN = 22, /* Bank B */ }; @@ -74,6 +75,8 @@ enum nfp_bpf_action_type { #define pv_len(np) reg_lm(1, PKT_VEC_PKT_LEN) #define pv_ctm_ptr(np) reg_lm(1, PKT_VEC_PKT_PTR) +#define stack_reg(np) reg_a(STATIC_REG_STACK) +#define stack_imm(np) imm_b(np) #define plen_reg(np) reg_b(STATIC_REG_PKT_LEN) #define pptr_reg(np) pv_ctm_ptr(np) #define imm_a(np) reg_a(STATIC_REG_IMM) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index 376d9938b823..633db3e1a11e 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c @@ -111,19 +111,29 @@ nfp_bpf_check_exit(struct nfp_prog *nfp_prog, return 0; } -static int nfp_bpf_check_stack_access(const struct bpf_reg_state *reg) +static int +nfp_bpf_check_stack_access(struct nfp_insn_meta *meta, + const struct bpf_reg_state *reg) { + s32 old_off, new_off; + if (!tnum_is_const(reg->var_off)) { pr_info("variable ptr stack access\n"); return -EINVAL; } - if (reg->var_off.value || reg->off) { - pr_info("stack access via modified register\n"); - return -EINVAL; - } + if (meta->ptr.type == NOT_INIT) + return 0; - return 0; + old_off = meta->ptr.off + meta->ptr.var_off.value; + new_off = reg->off + reg->var_off.value; + + if (old_off == new_off) + return 0; + + pr_info("stack access changed location was:%d is:%d\n", + old_off, new_off); + return -EINVAL; } static int @@ -141,7 +151,7 @@ nfp_bpf_check_ptr(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, } if (reg->type == PTR_TO_STACK) { - err = nfp_bpf_check_stack_access(reg); + err = nfp_bpf_check_stack_access(meta, reg); if (err) return err; }