From patchwork Fri Jan 12 04:29:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 859493 X-Patchwork-Delegate: bpf@iogearbox.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="tPNMYXI5"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zHqYC1jjqz9sQm for ; Fri, 12 Jan 2018 15:30:23 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933341AbeALEaV (ORCPT ); Thu, 11 Jan 2018 23:30:21 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:45256 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933182AbeALE34 (ORCPT ); Thu, 11 Jan 2018 23:29:56 -0500 Received: by mail-pg0-f66.google.com with SMTP id c194so3792366pga.12 for ; Thu, 11 Jan 2018 20:29:56 -0800 (PST) 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=p+eRx9dAC5Fi7LZ8mtbwwkCBJi1Db4ojEon5Kvqii3U=; b=tPNMYXI5D1ILRpGm+W1AKpEXPU1V4Qm1IWINJ2sHRwAlUlOUn7vMZQ33wUiJlw/4YW 4NN89Ms4807evE5/l9BUxwEBBi0nP4FvrJMWE0VtpjBFpK/C4bwntMM67H8WzfXpugBt TwZuMjljHUJY7gfnIIFVHZyOBGt/3duL5Y5Yq2HRyLQagYG/lpsTT4FTeWv1X4d3CoBu aDzrV3wiLUHeukdDlg59NOsJR/IbXuVKtBOFiA0v+fSGpsdLWbm7J4RNYTk8tyP6wEQZ z7SgMqk2Ed9sMIghlOWCWSIwQJRqciCdCPGpO4yOFFR8phnzH2dzkJCwgZkDesREbuSy XGAg== 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=p+eRx9dAC5Fi7LZ8mtbwwkCBJi1Db4ojEon5Kvqii3U=; b=jxDsCPxhb3nTCI9ojdXnUuXq6nX/mSi/OpyIBeRlaS+7RZVStKgnlS55MSn2HsDv+8 rDVkaVPLhlBtEo1QeZklt7AzxuPoU/csA+W3oZF6lJA1EgtVOhsAhXQ0BPtRoGGBPNMb i5jK0qazUqSxCRGkY5juu1nrEp+nqZJvsxFstEKiQXDUu0rithQf+iDUhaMDZ5Dh1C2z onHv+6vxUfxZcw86tq3InNgGlDzlDzY5LMa0sNvenlFmBpanfkrsfnaju6/tbOpJ5z/6 UdM6PPeP0K4upIF5NzMtIx4/y6pWsMZmU3YHBvnS9/7KWfAHL+IvR6yDWDBKYEOcWpTu StEQ== X-Gm-Message-State: AKwxytekfu6lxp9aXKq7IUdyYuyQVjqyu6gCxR50Xc7vn9jy0dIQpAQV lck510DF4Lt9rD4k9bScTQrgLg== X-Google-Smtp-Source: ACJfBotEsrAlq9Mb2Yi8iDkXGzxR9AUnoBJb975Jjz5c3zQ8CJRV/rTgCYQmUsH/oWsVVcljcOnAmQ== X-Received: by 10.98.227.8 with SMTP id g8mr9112504pfh.164.1515731395668; Thu, 11 Jan 2018 20:29:55 -0800 (PST) Received: from jkicinski-Precision-T1700.netronome.com ([75.53.12.129]) by smtp.gmail.com with ESMTPSA id e8sm45863875pfk.6.2018.01.11.20.29.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 11 Jan 2018 20:29:55 -0800 (PST) From: Jakub Kicinski To: alexei.starovoitov@gmail.com, daniel@iogearbox.net, davem@davemloft.net Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, tehnerd@fb.com, Jakub Kicinski Subject: [PATCH bpf-next v2 12/15] nfp: bpf: add helpers for updating immediate instructions Date: Thu, 11 Jan 2018 20:29:14 -0800 Message-Id: <20180112042917.10348-13-jakub.kicinski@netronome.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180112042917.10348-1-jakub.kicinski@netronome.com> References: <20180112042917.10348-1-jakub.kicinski@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Immediate loads are used to load the return address of a helper. We need to be able to update those loads for relocations. Immediate loads can be slightly more complex and spread over two instructions in general, but here we only care about simple loads of small (< 65k) constants, so complex cases are not handled. Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/netronome/nfp/nfp_asm.c | 58 ++++++++++++++++++++++++++++ drivers/net/ethernet/netronome/nfp/nfp_asm.h | 4 ++ 2 files changed, 62 insertions(+) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_asm.c b/drivers/net/ethernet/netronome/nfp/nfp_asm.c index 9ee3a3f60cc7..3f6952b66a49 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_asm.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_asm.c @@ -50,6 +50,11 @@ const struct cmd_tgt_act cmd_tgt_act[__CMD_TGT_MAP_SIZE] = { [CMD_TGT_READ_SWAP_LE] = { 0x03, 0x40 }, }; +static bool unreg_is_imm(u16 reg) +{ + return (reg & UR_REG_IMM) == UR_REG_IMM; +} + u16 br_get_offset(u64 instr) { u16 addr_lo, addr_hi; @@ -80,6 +85,59 @@ void br_add_offset(u64 *instr, u16 offset) br_set_offset(instr, addr + offset); } +static bool immed_can_modify(u64 instr) +{ + if (FIELD_GET(OP_IMMED_INV, instr) || + FIELD_GET(OP_IMMED_SHIFT, instr) || + FIELD_GET(OP_IMMED_WIDTH, instr) != IMMED_WIDTH_ALL) { + pr_err("Can't decode/encode immed!\n"); + return false; + } + return true; +} + +u16 immed_get_value(u64 instr) +{ + u16 reg; + + if (!immed_can_modify(instr)) + return 0; + + reg = FIELD_GET(OP_IMMED_A_SRC, instr); + if (!unreg_is_imm(reg)) + reg = FIELD_GET(OP_IMMED_B_SRC, instr); + + return (reg & 0xff) | FIELD_GET(OP_IMMED_IMM, instr); +} + +void immed_set_value(u64 *instr, u16 immed) +{ + if (!immed_can_modify(*instr)) + return; + + if (unreg_is_imm(FIELD_GET(OP_IMMED_A_SRC, *instr))) { + *instr &= ~FIELD_PREP(OP_IMMED_A_SRC, 0xff); + *instr |= FIELD_PREP(OP_IMMED_A_SRC, immed & 0xff); + } else { + *instr &= ~FIELD_PREP(OP_IMMED_B_SRC, 0xff); + *instr |= FIELD_PREP(OP_IMMED_B_SRC, immed & 0xff); + } + + *instr &= ~OP_IMMED_IMM; + *instr |= FIELD_PREP(OP_IMMED_IMM, immed >> 8); +} + +void immed_add_value(u64 *instr, u16 offset) +{ + u16 val; + + if (!immed_can_modify(*instr)) + return; + + val = immed_get_value(*instr); + immed_set_value(instr, val + offset); +} + static u16 nfp_swreg_to_unreg(swreg reg, bool is_dst) { bool lm_id, lm_dec = false; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_asm.h b/drivers/net/ethernet/netronome/nfp/nfp_asm.h index 20e51cb60e69..5f9291db98e0 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_asm.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_asm.h @@ -138,6 +138,10 @@ enum immed_shift { IMMED_SHIFT_2B = 2, }; +u16 immed_get_value(u64 instr); +void immed_set_value(u64 *instr, u16 immed); +void immed_add_value(u64 *instr, u16 offset); + #define OP_SHF_BASE 0x08000000000ULL #define OP_SHF_A_SRC 0x000000000ffULL #define OP_SHF_SC 0x00000000300ULL