From patchwork Tue Dec 8 15:28:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 553941 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 917D61402BD for ; Wed, 9 Dec 2015 02:29:54 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965063AbbLHP3i (ORCPT ); Tue, 8 Dec 2015 10:29:38 -0500 Received: from mout.kundenserver.de ([212.227.126.187]:53878 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756891AbbLHP3h (ORCPT ); Tue, 8 Dec 2015 10:29:37 -0500 Received: from wuerfel.localnet ([134.3.118.24]) by mrelayeu.kundenserver.de (mreue002) with ESMTPSA (Nemesis) id 0LfKSP-1adPsc176n-00p3vY; Tue, 08 Dec 2015 16:29:03 +0100 From: Arnd Bergmann To: "David S. Miller" Cc: Noam Camus , Tal Zilcer , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH] net: ezchip: fix address space confusion in nps_enet.c Date: Tue, 08 Dec 2015 16:28:59 +0100 Message-ID: <33732958.3idC7H2UPT@wuerfel> User-Agent: KMail/4.11.5 (Linux/3.16.0-10-generic; KDE/4.11.5; x86_64; ; ) MIME-Version: 1.0 X-Provags-ID: V03:K0:N+D/+hWlmhz2gFYCr44sYUqSXkI5MJj5ol3vmebvACaE57U2bJP JDJQQFCn4h0cwW0aZanfUbX42hlQU1xfswAsrndBSD/jRld4n4yvle0Cjz+bhTpIvYkNZOz 1Pj+nc0J34hMm4h8AFmE3QP9cZP1i41tgQYbkC37Cxi12qKCH1cNUWa0OidKp/k4pdF/amM y6GboS/9w13GFD1gVFJ9A== X-UI-Out-Filterresults: notjunk:1; V01:K0:I63J4t1cyFc=:wQDtTUjF0+h+vFkKnKwDLU /oBdh4LvkjlRL/f/pJdwZdHOG1vMUTbTAhTtw4onZXmcrbLw0HIcqCU8wXIiLbbRw5yaXW9nS FTFTCkr8sHYuiy8mf6nOmRdH2F5dyfFfGrSC3csFY87Gks3EvOw4CVveoHKH7O6onnzAHUJ2f ufx3ajF8B9lRAEBL1nns6HOKCBjNoZi3GGa6uSR74TwDV0jn3vuh9H8JLf+Ol24Xi4+eDhUw4 ZmK728qvORJPareDxKpW7W+FvRaqgBCFdAmnaVqrPdD3qkeK9CR7EHZWQudtExEserfeyaHkm E6olLEZoRdWas0+/Z8v4BdF9IFlbftl6zsIidxuSd5yardOwROf61vekEExjyPj5YS0/53e8c RS9HJ8nhASO5IemACJYbPyia/fDtjSi5DvioVFdr2GXnzpBvIATDcj6mHEFDIUFPffG2jcm55 QGEx8Zsej+NE5cHDXt0xDiHJzJ82WQXk5UZ/GTvaZJHg8Mk/XeV3E9reGURdRXB2S/jxOY2wp eIgpkH81W0qQNqBaACUhwuTcDNLbgA1a02xlKeXrX4yXT/2CR+dnfng5CUrcwAAMJpnhOIrvP TLCBAUsqxew8Y1ob6m6esdoGxoyjx0Mdo4cf4oTcUVft8ympplNYAalBsDA8lUqcgHDiyS4UP 7PbAOp+kVYYPrzg3k0zAvX6jZSS2p6zsz69pGI+gkcUbvDr7ng2oYiXU7WErzcP7Qc7LIkO3F qNUfWEnQVvrgunj5 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The nps_enet driver happily mixes virtual, physical and __iomem addresses, which are all different depending on the architecture and configuration. That causes a warning when building the code on ARM with LPAE mode enabled: drivers/net/ethernet/ezchip/nps_enet.c: In function 'nps_enet_send_frame': drivers/net/ethernet/ezchip/nps_enet.c:370:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] but will also fail to work for other reasons. In this patch, I'm trying to change the code to use only normal kernel pointers, which I assume is what the author actually meant: * For reading or writing a 32-bit word that may be unaligned when an SKB contains unaligned data, I'm using get_unaligned/put_unaligned() rather than memcpy_fromio/toio. * For converting a u8 pointer to a u32 pointer, I use a cast rather than the incorrect virt_to_phys. * For copying a couple of bytes from one place to another while respecting alignment, I use memcpy instead of memcpy_toio. Signed-off-by: Arnd Bergmann --- drivers/net/ethernet/ezchip/nps_enet.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) It would be helpful to test this patch on real hardware before it gets applied. The current behavior is so obscure that it's hard to know what the author of the code actually intended to happen here, this is based on my best guess. diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c index 63c2bcf8031a..b1026689b78f 100644 --- a/drivers/net/ethernet/ezchip/nps_enet.c +++ b/drivers/net/ethernet/ezchip/nps_enet.c @@ -48,21 +48,15 @@ static void nps_enet_read_rx_fifo(struct net_device *ndev, *reg = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); else { /* !dst_is_aligned */ for (i = 0; i < len; i++, reg++) { - u32 buf = - nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); - - /* to accommodate word-unaligned address of "reg" - * we have to do memcpy_toio() instead of simple "=". - */ - memcpy_toio((void __iomem *)reg, &buf, sizeof(buf)); + u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); + put_unaligned(buf, reg); } } /* copy last bytes (if any) */ if (last) { u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); - - memcpy_toio((void __iomem *)reg, &buf, last); + memcpy((u8*)reg, &buf, last); } } @@ -367,7 +361,7 @@ static void nps_enet_send_frame(struct net_device *ndev, struct nps_enet_tx_ctl tx_ctrl; short length = skb->len; u32 i, len = DIV_ROUND_UP(length, sizeof(u32)); - u32 *src = (u32 *)virt_to_phys(skb->data); + u32 *src = (void *)skb->data; bool src_is_aligned = IS_ALIGNED((unsigned long)src, sizeof(u32)); tx_ctrl.value = 0; @@ -375,17 +369,11 @@ static void nps_enet_send_frame(struct net_device *ndev, if (src_is_aligned) for (i = 0; i < len; i++, src++) nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF, *src); - else { /* !src_is_aligned */ - for (i = 0; i < len; i++, src++) { - u32 buf; - - /* to accommodate word-unaligned address of "src" - * we have to do memcpy_fromio() instead of simple "=" - */ - memcpy_fromio(&buf, (void __iomem *)src, sizeof(buf)); - nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF, buf); - } - } + else /* !src_is_aligned */ + for (i = 0; i < len; i++, src++) + nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF, + get_unaligned(src)); + /* Write the length of the Frame */ tx_ctrl.nt = length;