Commit d1bcf2b6 authored by David S. Miller's avatar David S. Miller

Merge tag 'mlx5-fixes-2019-04-19' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
Mellanox, mlx5 fixes 2019-04-19

This series introduces some fixes to mlx5 driver.

Please pull and let me know if there is any problem.

For -stable v4.7:
  ('net/mlx5e: ethtool, Remove unsupported SFP EEPROM high pages query')

For -stable v4.19:
  ('net/mlx5e: Fix the max MTU check in case of XDP')

For -stable v5.0:
  ('net/mlx5e: Fix use-after-free after xdp_return_frame')
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 925b0c84 ace329f4
...@@ -33,6 +33,26 @@ ...@@ -33,6 +33,26 @@
#include <linux/bpf_trace.h> #include <linux/bpf_trace.h>
#include "en/xdp.h" #include "en/xdp.h"
int mlx5e_xdp_max_mtu(struct mlx5e_params *params)
{
int hr = NET_IP_ALIGN + XDP_PACKET_HEADROOM;
/* Let S := SKB_DATA_ALIGN(sizeof(struct skb_shared_info)).
* The condition checked in mlx5e_rx_is_linear_skb is:
* SKB_DATA_ALIGN(sw_mtu + hard_mtu + hr) + S <= PAGE_SIZE (1)
* (Note that hw_mtu == sw_mtu + hard_mtu.)
* What is returned from this function is:
* max_mtu = PAGE_SIZE - S - hr - hard_mtu (2)
* After assigning sw_mtu := max_mtu, the left side of (1) turns to
* SKB_DATA_ALIGN(PAGE_SIZE - S) + S, which is equal to PAGE_SIZE,
* because both PAGE_SIZE and S are already aligned. Any number greater
* than max_mtu would make the left side of (1) greater than PAGE_SIZE,
* so max_mtu is the maximum MTU allowed.
*/
return MLX5E_HW2SW_MTU(params, SKB_MAX_HEAD(hr));
}
static inline bool static inline bool
mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_dma_info *di, mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_dma_info *di,
struct xdp_buff *xdp) struct xdp_buff *xdp)
...@@ -304,9 +324,9 @@ bool mlx5e_poll_xdpsq_cq(struct mlx5e_cq *cq, struct mlx5e_rq *rq) ...@@ -304,9 +324,9 @@ bool mlx5e_poll_xdpsq_cq(struct mlx5e_cq *cq, struct mlx5e_rq *rq)
mlx5e_xdpi_fifo_pop(xdpi_fifo); mlx5e_xdpi_fifo_pop(xdpi_fifo);
if (is_redirect) { if (is_redirect) {
xdp_return_frame(xdpi.xdpf);
dma_unmap_single(sq->pdev, xdpi.dma_addr, dma_unmap_single(sq->pdev, xdpi.dma_addr,
xdpi.xdpf->len, DMA_TO_DEVICE); xdpi.xdpf->len, DMA_TO_DEVICE);
xdp_return_frame(xdpi.xdpf);
} else { } else {
/* Recycle RX page */ /* Recycle RX page */
mlx5e_page_release(rq, &xdpi.di, true); mlx5e_page_release(rq, &xdpi.di, true);
...@@ -345,9 +365,9 @@ void mlx5e_free_xdpsq_descs(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq) ...@@ -345,9 +365,9 @@ void mlx5e_free_xdpsq_descs(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq)
mlx5e_xdpi_fifo_pop(xdpi_fifo); mlx5e_xdpi_fifo_pop(xdpi_fifo);
if (is_redirect) { if (is_redirect) {
xdp_return_frame(xdpi.xdpf);
dma_unmap_single(sq->pdev, xdpi.dma_addr, dma_unmap_single(sq->pdev, xdpi.dma_addr,
xdpi.xdpf->len, DMA_TO_DEVICE); xdpi.xdpf->len, DMA_TO_DEVICE);
xdp_return_frame(xdpi.xdpf);
} else { } else {
/* Recycle RX page */ /* Recycle RX page */
mlx5e_page_release(rq, &xdpi.di, false); mlx5e_page_release(rq, &xdpi.di, false);
......
...@@ -34,13 +34,12 @@ ...@@ -34,13 +34,12 @@
#include "en.h" #include "en.h"
#define MLX5E_XDP_MAX_MTU ((int)(PAGE_SIZE - \
MLX5_SKB_FRAG_SZ(XDP_PACKET_HEADROOM)))
#define MLX5E_XDP_MIN_INLINE (ETH_HLEN + VLAN_HLEN) #define MLX5E_XDP_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
#define MLX5E_XDP_TX_EMPTY_DS_COUNT \ #define MLX5E_XDP_TX_EMPTY_DS_COUNT \
(sizeof(struct mlx5e_tx_wqe) / MLX5_SEND_WQE_DS) (sizeof(struct mlx5e_tx_wqe) / MLX5_SEND_WQE_DS)
#define MLX5E_XDP_TX_DS_COUNT (MLX5E_XDP_TX_EMPTY_DS_COUNT + 1 /* SG DS */) #define MLX5E_XDP_TX_DS_COUNT (MLX5E_XDP_TX_EMPTY_DS_COUNT + 1 /* SG DS */)
int mlx5e_xdp_max_mtu(struct mlx5e_params *params);
bool mlx5e_xdp_handle(struct mlx5e_rq *rq, struct mlx5e_dma_info *di, bool mlx5e_xdp_handle(struct mlx5e_rq *rq, struct mlx5e_dma_info *di,
void *va, u16 *rx_headroom, u32 *len); void *va, u16 *rx_headroom, u32 *len);
bool mlx5e_poll_xdpsq_cq(struct mlx5e_cq *cq, struct mlx5e_rq *rq); bool mlx5e_poll_xdpsq_cq(struct mlx5e_cq *cq, struct mlx5e_rq *rq);
......
...@@ -1586,7 +1586,7 @@ static int mlx5e_get_module_info(struct net_device *netdev, ...@@ -1586,7 +1586,7 @@ static int mlx5e_get_module_info(struct net_device *netdev,
break; break;
case MLX5_MODULE_ID_SFP: case MLX5_MODULE_ID_SFP:
modinfo->type = ETH_MODULE_SFF_8472; modinfo->type = ETH_MODULE_SFF_8472;
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; modinfo->eeprom_len = MLX5_EEPROM_PAGE_LENGTH;
break; break;
default: default:
netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n", netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
......
...@@ -3777,7 +3777,7 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu, ...@@ -3777,7 +3777,7 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
if (params->xdp_prog && if (params->xdp_prog &&
!mlx5e_rx_is_linear_skb(priv->mdev, &new_channels.params)) { !mlx5e_rx_is_linear_skb(priv->mdev, &new_channels.params)) {
netdev_err(netdev, "MTU(%d) > %d is not allowed while XDP enabled\n", netdev_err(netdev, "MTU(%d) > %d is not allowed while XDP enabled\n",
new_mtu, MLX5E_XDP_MAX_MTU); new_mtu, mlx5e_xdp_max_mtu(params));
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -4212,7 +4212,8 @@ static int mlx5e_xdp_allowed(struct mlx5e_priv *priv, struct bpf_prog *prog) ...@@ -4212,7 +4212,8 @@ static int mlx5e_xdp_allowed(struct mlx5e_priv *priv, struct bpf_prog *prog)
if (!mlx5e_rx_is_linear_skb(priv->mdev, &new_channels.params)) { if (!mlx5e_rx_is_linear_skb(priv->mdev, &new_channels.params)) {
netdev_warn(netdev, "XDP is not allowed with MTU(%d) > %d\n", netdev_warn(netdev, "XDP is not allowed with MTU(%d) > %d\n",
new_channels.params.sw_mtu, MLX5E_XDP_MAX_MTU); new_channels.params.sw_mtu,
mlx5e_xdp_max_mtu(&new_channels.params));
return -EINVAL; return -EINVAL;
} }
......
...@@ -317,10 +317,6 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, ...@@ -317,10 +317,6 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
size -= offset + size - MLX5_EEPROM_PAGE_LENGTH; size -= offset + size - MLX5_EEPROM_PAGE_LENGTH;
i2c_addr = MLX5_I2C_ADDR_LOW; i2c_addr = MLX5_I2C_ADDR_LOW;
if (offset >= MLX5_EEPROM_PAGE_LENGTH) {
i2c_addr = MLX5_I2C_ADDR_HIGH;
offset -= MLX5_EEPROM_PAGE_LENGTH;
}
MLX5_SET(mcia_reg, in, l, 0); MLX5_SET(mcia_reg, in, l, 0);
MLX5_SET(mcia_reg, in, module, module_num); MLX5_SET(mcia_reg, in, module, module_num);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment