diff options
| author | Ben Hutchings <bhutchings@solarflare.com> | 2011-12-15 08:55:01 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-12-16 13:52:47 -0500 |
| commit | 7850f63f1620512631445b901ae11cd149e7375c (patch) | |
| tree | d26a5f049dcf3634c4bf9e1b86915d201fab3836 /drivers/net/vmxnet3 | |
| parent | 14596f7006297b67516e2b6a2b26bcb11fe08fb3 (diff) | |
ethtool: Centralise validation of ETHTOOL_{G, S}RXFHINDIR parameters
Add a new ethtool operation (get_rxfh_indir_size) to get the
indirectional table size. Use this to validate the user buffer size
before calling get_rxfh_indir or set_rxfh_indir. Use get_rxnfc to get
the number of RX rings, and validate the contents of the new
indirection table before calling set_rxfh_indir. Remove this
validation from drivers.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Acked-by: Dimitris Michailidis <dm@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vmxnet3')
| -rw-r--r-- | drivers/net/vmxnet3/vmxnet3_ethtool.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index b492ee1e5f17..a3eb75a62ea9 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c | |||
| @@ -565,44 +565,38 @@ vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info, | |||
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | #ifdef VMXNET3_RSS | 567 | #ifdef VMXNET3_RSS |
| 568 | static u32 | ||
| 569 | vmxnet3_get_rss_indir_size(struct net_device *netdev) | ||
| 570 | { | ||
| 571 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); | ||
| 572 | struct UPT1_RSSConf *rssConf = adapter->rss_conf; | ||
| 573 | |||
| 574 | return rssConf->indTableSize; | ||
| 575 | } | ||
| 576 | |||
| 568 | static int | 577 | static int |
| 569 | vmxnet3_get_rss_indir(struct net_device *netdev, | 578 | vmxnet3_get_rss_indir(struct net_device *netdev, u32 *p) |
| 570 | struct ethtool_rxfh_indir *p) | ||
| 571 | { | 579 | { |
| 572 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); | 580 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); |
| 573 | struct UPT1_RSSConf *rssConf = adapter->rss_conf; | 581 | struct UPT1_RSSConf *rssConf = adapter->rss_conf; |
| 574 | unsigned int n = min_t(unsigned int, p->size, rssConf->indTableSize); | 582 | unsigned int n = rssConf->indTableSize; |
| 575 | 583 | ||
| 576 | p->size = rssConf->indTableSize; | ||
| 577 | while (n--) | 584 | while (n--) |
| 578 | p->ring_index[n] = rssConf->indTable[n]; | 585 | p[n] = rssConf->indTable[n]; |
| 579 | return 0; | 586 | return 0; |
| 580 | 587 | ||
| 581 | } | 588 | } |
| 582 | 589 | ||
| 583 | static int | 590 | static int |
| 584 | vmxnet3_set_rss_indir(struct net_device *netdev, | 591 | vmxnet3_set_rss_indir(struct net_device *netdev, const u32 *p) |
| 585 | const struct ethtool_rxfh_indir *p) | ||
| 586 | { | 592 | { |
| 587 | unsigned int i; | 593 | unsigned int i; |
| 588 | unsigned long flags; | 594 | unsigned long flags; |
| 589 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); | 595 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); |
| 590 | struct UPT1_RSSConf *rssConf = adapter->rss_conf; | 596 | struct UPT1_RSSConf *rssConf = adapter->rss_conf; |
| 591 | 597 | ||
| 592 | if (p->size != rssConf->indTableSize) | ||
| 593 | return -EINVAL; | ||
| 594 | for (i = 0; i < rssConf->indTableSize; i++) { | ||
| 595 | /* | ||
| 596 | * Return with error code if any of the queue indices | ||
| 597 | * is out of range | ||
| 598 | */ | ||
| 599 | if (p->ring_index[i] < 0 || | ||
| 600 | p->ring_index[i] >= adapter->num_rx_queues) | ||
| 601 | return -EINVAL; | ||
| 602 | } | ||
| 603 | |||
| 604 | for (i = 0; i < rssConf->indTableSize; i++) | 598 | for (i = 0; i < rssConf->indTableSize; i++) |
| 605 | rssConf->indTable[i] = p->ring_index[i]; | 599 | rssConf->indTable[i] = p[i]; |
| 606 | 600 | ||
| 607 | spin_lock_irqsave(&adapter->cmd_lock, flags); | 601 | spin_lock_irqsave(&adapter->cmd_lock, flags); |
| 608 | VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, | 602 | VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, |
| @@ -629,6 +623,7 @@ static struct ethtool_ops vmxnet3_ethtool_ops = { | |||
| 629 | .set_ringparam = vmxnet3_set_ringparam, | 623 | .set_ringparam = vmxnet3_set_ringparam, |
| 630 | .get_rxnfc = vmxnet3_get_rxnfc, | 624 | .get_rxnfc = vmxnet3_get_rxnfc, |
| 631 | #ifdef VMXNET3_RSS | 625 | #ifdef VMXNET3_RSS |
| 626 | .get_rxfh_indir_size = vmxnet3_get_rss_indir_size, | ||
| 632 | .get_rxfh_indir = vmxnet3_get_rss_indir, | 627 | .get_rxfh_indir = vmxnet3_get_rss_indir, |
| 633 | .set_rxfh_indir = vmxnet3_set_rss_indir, | 628 | .set_rxfh_indir = vmxnet3_set_rss_indir, |
| 634 | #endif | 629 | #endif |
