Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking fixes from David Miller:

 1) Fix OOPS during nf_tables rule dump, from Florian Westphal.

 2) Use after free in ip_vs_in, from Yue Haibing.

 3) Fix various kTLS bugs (NULL deref during device removal resync,
    netdev notification ignoring, etc.) From Jakub Kicinski.

 4) Fix ipv6 redirects with VRF, from David Ahern.

 5) Memory leak fix in igmpv3_del_delrec(), from Eric Dumazet.

 6) Missing memory allocation failure check in ip6_ra_control(), from
    Gen Zhang. And likewise fix ip_ra_control().

 7) TX clean budget logic error in aquantia, from Igor Russkikh.

 8) SKB leak in llc_build_and_send_ui_pkt(), from Eric Dumazet.

 9) Double frees in mlx5, from Parav Pandit.

10) Fix lost MAC address in r8169 during PCI D3, from Heiner Kallweit.

11) Fix botched register access in mvpp2, from Antoine Tenart.

12) Use after free in napi_gro_frags(), from Eric Dumazet.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (89 commits)
  net: correct zerocopy refcnt with udp MSG_MORE
  ethtool: Check for vlan etype or vlan tci when parsing flow_rule
  net: don't clear sock->sk early to avoid trouble in strparser
  net-gro: fix use-after-free read in napi_gro_frags()
  net: dsa: tag_8021q: Create a stable binary format
  net: dsa: tag_8021q: Change order of rx_vid setup
  net: mvpp2: fix bad MVPP2_TXQ_SCHED_TOKEN_CNTR_REG queue value
  ipv4: tcp_input: fix stack out of bounds when parsing TCP options.
  mlxsw: spectrum: Prevent force of 56G
  mlxsw: spectrum_acl: Avoid warning after identical rules insertion
  net: dsa: mv88e6xxx: fix handling of upper half of STATS_TYPE_PORT
  r8169: fix MAC address being lost in PCI D3
  net: core: support XDP generic on stacked devices.
  netvsc: unshare skb in VF rx handler
  udp: Avoid post-GRO UDP checksum recalculation
  net: phy: dp83867: Set up RGMII TX delay
  net: phy: dp83867: do not call config_init twice
  net: phy: dp83867: increase SGMII autoneg timer duration
  net: phy: dp83867: fix speed 10 in sgmii mode
  net: phy: marvell10g: report if the PHY fails to boot firmware
  ...
This commit is contained in:
Linus Torvalds 2019-05-30 21:11:22 -07:00
commit 036e343109
87 changed files with 1765 additions and 680 deletions

View file

@ -1676,9 +1676,9 @@ dsp_cmx_send(void *arg)
#ifdef CMX_CONF_DEBUG
if (conf->software && members > 1)
#else
if (conf->software && members > 2)
if (conf->software && members > 2)
#endif
mustmix = 1;
mustmix = 1;
}
/* transmission required */
@ -1699,263 +1699,262 @@ dsp_cmx_send(void *arg)
#ifdef CMX_CONF_DEBUG
if (conf->software && members > 1) {
#else
if (conf->software && members > 2) {
if (conf->software && members > 2) {
#endif
/* check for hdlc conf */
member = list_entry(conf->mlist.next,
struct dsp_conf_member, list);
if (member->dsp->hdlc)
continue;
/* mix all data */
memset(mixbuffer, 0, length * sizeof(s32));
list_for_each_entry(member, &conf->mlist, list) {
dsp = member->dsp;
/* get range of data to mix */
c = mixbuffer;
q = dsp->rx_buff;
r = dsp->rx_R;
rr = (r + length) & CMX_BUFF_MASK;
/* add member's data */
while (r != rr) {
*c++ += dsp_audio_law_to_s32[q[r]];
r = (r + 1) & CMX_BUFF_MASK;
}
}
/* process each member */
list_for_each_entry(member, &conf->mlist, list) {
/* transmission */
dsp_cmx_send_member(member->dsp, length,
mixbuffer, members);
/* check for hdlc conf */
member = list_entry(conf->mlist.next,
struct dsp_conf_member, list);
if (member->dsp->hdlc)
continue;
/* mix all data */
memset(mixbuffer, 0, length * sizeof(s32));
list_for_each_entry(member, &conf->mlist, list) {
dsp = member->dsp;
/* get range of data to mix */
c = mixbuffer;
q = dsp->rx_buff;
r = dsp->rx_R;
rr = (r + length) & CMX_BUFF_MASK;
/* add member's data */
while (r != rr) {
*c++ += dsp_audio_law_to_s32[q[r]];
r = (r + 1) & CMX_BUFF_MASK;
}
}
/* process each member */
list_for_each_entry(member, &conf->mlist, list) {
/* transmission */
dsp_cmx_send_member(member->dsp, length,
mixbuffer, members);
}
}
}
/* delete rx-data, increment buffers, change pointers */
list_for_each_entry(dsp, &dsp_ilist, list) {
if (dsp->hdlc)
continue;
p = dsp->rx_buff;
q = dsp->tx_buff;
r = dsp->rx_R;
/* move receive pointer when receiving */
if (!dsp->rx_is_off) {
rr = (r + length) & CMX_BUFF_MASK;
/* delete rx-data */
while (r != rr) {
p[r] = dsp_silence;
r = (r + 1) & CMX_BUFF_MASK;
}
/* increment rx-buffer pointer */
dsp->rx_R = r; /* write incremented read pointer */
}
/* delete rx-data, increment buffers, change pointers */
list_for_each_entry(dsp, &dsp_ilist, list) {
if (dsp->hdlc)
continue;
p = dsp->rx_buff;
q = dsp->tx_buff;
r = dsp->rx_R;
/* move receive pointer when receiving */
if (!dsp->rx_is_off) {
rr = (r + length) & CMX_BUFF_MASK;
/* check current rx_delay */
delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
if (delay >= CMX_BUFF_HALF)
delay = 0; /* will be the delay before next write */
/* check for lower delay */
if (delay < dsp->rx_delay[0])
dsp->rx_delay[0] = delay;
/* check current tx_delay */
delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
if (delay >= CMX_BUFF_HALF)
delay = 0; /* will be the delay before next write */
/* check for lower delay */
if (delay < dsp->tx_delay[0])
dsp->tx_delay[0] = delay;
if (jittercheck) {
/* find the lowest of all rx_delays */
delay = dsp->rx_delay[0];
i = 1;
while (i < MAX_SECONDS_JITTER_CHECK) {
if (delay > dsp->rx_delay[i])
delay = dsp->rx_delay[i];
i++;
}
/*
* remove rx_delay only if we have delay AND we
* have not preset cmx_delay AND
* the delay is greater dsp_poll
*/
if (delay > dsp_poll && !dsp->cmx_delay) {
if (dsp_debug & DEBUG_DSP_CLOCK)
printk(KERN_DEBUG
"%s lowest rx_delay of %d bytes for"
" dsp %s are now removed.\n",
__func__, delay,
dsp->name);
r = dsp->rx_R;
rr = (r + delay - (dsp_poll >> 1))
& CMX_BUFF_MASK;
/* delete rx-data */
while (r != rr) {
p[r] = dsp_silence;
r = (r + 1) & CMX_BUFF_MASK;
}
/* increment rx-buffer pointer */
dsp->rx_R = r; /* write incremented read pointer */
dsp->rx_R = r;
/* write incremented read pointer */
}
/* check current rx_delay */
delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
if (delay >= CMX_BUFF_HALF)
delay = 0; /* will be the delay before next write */
/* check for lower delay */
if (delay < dsp->rx_delay[0])
dsp->rx_delay[0] = delay;
/* check current tx_delay */
delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
if (delay >= CMX_BUFF_HALF)
delay = 0; /* will be the delay before next write */
/* check for lower delay */
if (delay < dsp->tx_delay[0])
dsp->tx_delay[0] = delay;
if (jittercheck) {
/* find the lowest of all rx_delays */
delay = dsp->rx_delay[0];
i = 1;
while (i < MAX_SECONDS_JITTER_CHECK) {
if (delay > dsp->rx_delay[i])
delay = dsp->rx_delay[i];
i++;
}
/*
* remove rx_delay only if we have delay AND we
* have not preset cmx_delay AND
* the delay is greater dsp_poll
*/
if (delay > dsp_poll && !dsp->cmx_delay) {
if (dsp_debug & DEBUG_DSP_CLOCK)
printk(KERN_DEBUG
"%s lowest rx_delay of %d bytes for"
" dsp %s are now removed.\n",
__func__, delay,
dsp->name);
r = dsp->rx_R;
rr = (r + delay - (dsp_poll >> 1))
& CMX_BUFF_MASK;
/* delete rx-data */
while (r != rr) {
p[r] = dsp_silence;
r = (r + 1) & CMX_BUFF_MASK;
}
/* increment rx-buffer pointer */
dsp->rx_R = r;
/* write incremented read pointer */
}
/* find the lowest of all tx_delays */
delay = dsp->tx_delay[0];
i = 1;
while (i < MAX_SECONDS_JITTER_CHECK) {
if (delay > dsp->tx_delay[i])
delay = dsp->tx_delay[i];
i++;
}
/*
* remove delay only if we have delay AND we
* have enabled tx_dejitter
*/
if (delay > dsp_poll && dsp->tx_dejitter) {
if (dsp_debug & DEBUG_DSP_CLOCK)
printk(KERN_DEBUG
"%s lowest tx_delay of %d bytes for"
" dsp %s are now removed.\n",
__func__, delay,
dsp->name);
r = dsp->tx_R;
rr = (r + delay - (dsp_poll >> 1))
& CMX_BUFF_MASK;
/* delete tx-data */
while (r != rr) {
q[r] = dsp_silence;
r = (r + 1) & CMX_BUFF_MASK;
}
/* increment rx-buffer pointer */
dsp->tx_R = r;
/* write incremented read pointer */
}
/* scroll up delays */
i = MAX_SECONDS_JITTER_CHECK - 1;
while (i) {
dsp->rx_delay[i] = dsp->rx_delay[i - 1];
dsp->tx_delay[i] = dsp->tx_delay[i - 1];
i--;
}
dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
/* find the lowest of all tx_delays */
delay = dsp->tx_delay[0];
i = 1;
while (i < MAX_SECONDS_JITTER_CHECK) {
if (delay > dsp->tx_delay[i])
delay = dsp->tx_delay[i];
i++;
}
/*
* remove delay only if we have delay AND we
* have enabled tx_dejitter
*/
if (delay > dsp_poll && dsp->tx_dejitter) {
if (dsp_debug & DEBUG_DSP_CLOCK)
printk(KERN_DEBUG
"%s lowest tx_delay of %d bytes for"
" dsp %s are now removed.\n",
__func__, delay,
dsp->name);
r = dsp->tx_R;
rr = (r + delay - (dsp_poll >> 1))
& CMX_BUFF_MASK;
/* delete tx-data */
while (r != rr) {
q[r] = dsp_silence;
r = (r + 1) & CMX_BUFF_MASK;
}
/* increment rx-buffer pointer */
dsp->tx_R = r;
/* write incremented read pointer */
}
/* scroll up delays */
i = MAX_SECONDS_JITTER_CHECK - 1;
while (i) {
dsp->rx_delay[i] = dsp->rx_delay[i - 1];
dsp->tx_delay[i] = dsp->tx_delay[i - 1];
i--;
}
dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
}
/* if next event would be in the past ... */
if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0)
dsp_spl_jiffies = jiffies + 1;
else
dsp_spl_jiffies += dsp_tics;
dsp_spl_tl.expires = dsp_spl_jiffies;
add_timer(&dsp_spl_tl);
/* unlock */
spin_unlock_irqrestore(&dsp_lock, flags);
}
/* if next event would be in the past ... */
if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0)
dsp_spl_jiffies = jiffies + 1;
else
dsp_spl_jiffies += dsp_tics;
dsp_spl_tl.expires = dsp_spl_jiffies;
add_timer(&dsp_spl_tl);
/* unlock */
spin_unlock_irqrestore(&dsp_lock, flags);
}
/*
* audio data is transmitted from upper layer to the dsp
*/
void
dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
{
u_int w, ww;
u8 *d, *p;
int space; /* todo: , l = skb->len; */
void
dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
{
u_int w, ww;
u8 *d, *p;
int space; /* todo: , l = skb->len; */
#ifdef CMX_TX_DEBUG
char debugbuf[256] = "";
char debugbuf[256] = "";
#endif
/* check if there is enough space, and then copy */
w = dsp->tx_W;
ww = dsp->tx_R;
p = dsp->tx_buff;
d = skb->data;
space = (ww - w - 1) & CMX_BUFF_MASK;
/* write-pointer should not overrun nor reach read pointer */
if (space < skb->len) {
/* write to the space we have left */
ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
if (dsp_debug & DEBUG_DSP_CLOCK)
printk(KERN_DEBUG "%s: TX overflow space=%d skb->len="
"%d, w=0x%04x, ww=0x%04x\n", __func__, space,
skb->len, w, ww);
} else
/* write until all byte are copied */
ww = (w + skb->len) & CMX_BUFF_MASK;
dsp->tx_W = ww;
/* check if there is enough space, and then copy */
w = dsp->tx_W;
ww = dsp->tx_R;
p = dsp->tx_buff;
d = skb->data;
space = (ww - w - 1) & CMX_BUFF_MASK;
/* write-pointer should not overrun nor reach read pointer */
if (space < skb->len) {
/* write to the space we have left */
ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
if (dsp_debug & DEBUG_DSP_CLOCK)
printk(KERN_DEBUG "%s: TX overflow space=%d skb->len="
"%d, w=0x%04x, ww=0x%04x\n", __func__, space,
skb->len, w, ww);
} else
/* write until all byte are copied */
ww = (w + skb->len) & CMX_BUFF_MASK;
dsp->tx_W = ww;
/* show current buffer */
#ifdef CMX_DEBUG
printk(KERN_DEBUG
"cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
(u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name);
printk(KERN_DEBUG
"cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
(u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name);
#endif
/* copy transmit data to tx-buffer */
/* copy transmit data to tx-buffer */
#ifdef CMX_TX_DEBUG
sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
#endif
while (w != ww) {
while (w != ww) {
#ifdef CMX_TX_DEBUG
if (strlen(debugbuf) < 48)
sprintf(debugbuf + strlen(debugbuf), " %02x", *d);
if (strlen(debugbuf) < 48)
sprintf(debugbuf + strlen(debugbuf), " %02x", *d);
#endif
p[w] = *d++;
w = (w + 1) & CMX_BUFF_MASK;
}
#ifdef CMX_TX_DEBUG
printk(KERN_DEBUG "%s\n", debugbuf);
#endif
p[w] = *d++;
w = (w + 1) & CMX_BUFF_MASK;
}
#ifdef CMX_TX_DEBUG
printk(KERN_DEBUG "%s\n", debugbuf);
#endif
}
/*
* hdlc data is received from card and sent to all members.
*/
void
dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
{
struct sk_buff *nskb = NULL;
struct dsp_conf_member *member;
struct mISDNhead *hh;
void
dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
{
struct sk_buff *nskb = NULL;
struct dsp_conf_member *member;
struct mISDNhead *hh;
/* not if not active */
if (!dsp->b_active)
return;
/* not if not active */
if (!dsp->b_active)
return;
/* check if we have sompen */
if (skb->len < 1)
return;
/* check if we have sompen */
if (skb->len < 1)
return;
/* no conf */
if (!dsp->conf) {
/* in case of software echo */
if (dsp->echo.software) {
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
hh = mISDN_HEAD_P(nskb);
hh->prim = PH_DATA_REQ;
hh->id = 0;
skb_queue_tail(&dsp->sendq, nskb);
schedule_work(&dsp->workq);
}
/* no conf */
if (!dsp->conf) {
/* in case of software echo */
if (dsp->echo.software) {
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
hh = mISDN_HEAD_P(nskb);
hh->prim = PH_DATA_REQ;
hh->id = 0;
skb_queue_tail(&dsp->sendq, nskb);
schedule_work(&dsp->workq);
}
return;
}
/* in case of hardware conference */
if (dsp->conf->hardware)
return;
list_for_each_entry(member, &dsp->conf->mlist, list) {
if (dsp->echo.software || member->dsp != dsp) {
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
hh = mISDN_HEAD_P(nskb);
hh->prim = PH_DATA_REQ;
hh->id = 0;
skb_queue_tail(&member->dsp->sendq, nskb);
schedule_work(&member->dsp->workq);
}
return;
}
/* in case of hardware conference */
if (dsp->conf->hardware)
return;
list_for_each_entry(member, &dsp->conf->mlist, list) {
if (dsp->echo.software || member->dsp != dsp) {
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
hh = mISDN_HEAD_P(nskb);
hh->prim = PH_DATA_REQ;
hh->id = 0;
skb_queue_tail(&member->dsp->sendq, nskb);
schedule_work(&member->dsp->workq);
}
}
}
}

View file

@ -393,7 +393,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
memcpy(di.channelmap, dev->channelmap,
sizeof(di.channelmap));
di.nrbchan = dev->nrbchan;
strcpy(di.name, dev_name(&dev->dev));
strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
if (copy_to_user((void __user *)arg, &di, sizeof(di)))
err = -EFAULT;
} else
@ -676,7 +676,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
memcpy(di.channelmap, dev->channelmap,
sizeof(di.channelmap));
di.nrbchan = dev->nrbchan;
strcpy(di.name, dev_name(&dev->dev));
strscpy(di.name, dev_name(&dev->dev), sizeof(di.name));
if (copy_to_user((void __user *)arg, &di, sizeof(di)))
err = -EFAULT;
} else
@ -690,6 +690,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
err = -EFAULT;
break;
}
dn.name[sizeof(dn.name) - 1] = '\0';
dev = get_mdevice(dn.id);
if (dev)
err = device_rename(&dev->dev, dn.name);