> -----Original Message----- > From: Richardson, Bruce > Sent: Thursday, April 21, 2016 17:28 > To: Kulasek, TomaszX <tomaszx.kulasek at intel.com> > Cc: dev at dpdk.org; Zhang, Helin <helin.zhang at intel.com>; Ananyev, > Konstantin <konstantin.ananyev at intel.com> > Subject: Re: [dpdk-dev] [PATCH] ixgbe: fix bad shift operation in > ixgbe_set_pool_rx > > On Thu, Apr 21, 2016 at 03:44:03PM +0100, Kulasek, TomaszX wrote: > > > > > > > -----Original Message----- > > > From: Richardson, Bruce > > > Sent: Thursday, April 21, 2016 15:52 > > > To: Kulasek, TomaszX <tomaszx.kulasek at intel.com> > > > Cc: dev at dpdk.org; Zhang, Helin <helin.zhang at intel.com>; Ananyev, > > > Konstantin <konstantin.ananyev at intel.com> > > > Subject: Re: [dpdk-dev] [PATCH] ixgbe: fix bad shift operation in > > > ixgbe_set_pool_rx > > > > > > On Fri, Apr 15, 2016 at 03:39:09PM +0200, Tomasz Kulasek wrote: > > > > CID 13193 (#1 of 1): Bad bit shift operation (BAD_SHIFT) > > > > large_shift: In expression 1 << pool, left shifting by more than > > > > 31 bits has undefined behavior. The shift amount, pool, is at least > 32. > > > > > > > > This patch limits mask shift to be in range of 32 bit PFVFRE[1] > > > > register, for pool > 31. > > > > > > > > Fixes: fe3a45fd4104 ("ixgbe: add VMDq support") > > > > > > > > Signed-off-by: Tomasz Kulasek <tomaszx.kulasek at intel.com> > > > > --- > > > > drivers/net/ixgbe/ixgbe_ethdev.c | 2 +- > > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > > > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c > > > > b/drivers/net/ixgbe/ixgbe_ethdev.c > > > > index 3f1ebc1..f676a64 100644 > > > > --- a/drivers/net/ixgbe/ixgbe_ethdev.c > > > > +++ b/drivers/net/ixgbe/ixgbe_ethdev.c > > > > @@ -4401,7 +4401,7 @@ ixgbe_set_pool_rx(struct rte_eth_dev *dev, > > > > uint16_t pool, uint8_t on) > > > > > > > > addr = IXGBE_VFRE(pool >= ETH_64_POOLS/2); > > > > For pool in 0..31 PFVFRE[0] is used, for pool in 32..63, PFVFRE[1], but > for second case, we set/unset (pool-32) bit in the register. Invalid value > if pool > 63, but catching it doesn't solve a problem of possible overflow > for pool > 31. > > > > > > reg = IXGBE_READ_REG(hw, addr); > > > > - val = bit1 << pool; > > > > Previous implementation expects that for shift operation will be used > rol on 32 bit value, and the bits that slide off the end of the register > are fed back into the spaces, eg. (bit1 << 33) == (bit1 << 1). > > Pool value can be bigger than 31, and this is not an error while pool is > smaller than 64. > > > > Truncating pool value is clearer for me, than relay on obscure shift > operation. > > > Thanks for the explanation, that indeed does make it clearer. > > However, all that detail is completely unclear to the reader of the > function, so perhaps we can clean up the code to make it more explicit > what is happening. > For example: > > /* for pool >= 32, set bit in PFVFRE[1], otherwise PFVFRE[0] */ > if (pool >= ETH_64_POOLS) > return -EINVAL; > else if (pool >= ETH_64_POOLS/2) { > addr = IXGBE_VFRE(1); > val = bit1 << (pool - 32); > } else { > addr = IXGBE_VFRE(0); > val = bit1 << pool; > } > > reg = IXGBE_READ_REG(hw, addr); > > This should fix the issue and make the resulting code clearer, I think. > > /Bruce
Yes, I got it. I will send v2. Tomasz