This is the 4.9.92 stable release

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlq/sz0ACgkQONu9yGCS
 aT4W4w//esMh+X1T4tWptKjji4p0TamE73ptA5lI+hDeD5aDEgjTx2Ue43oyipz6
 8yTDk7k/mDgb9Mr9IF0t+hhM5dVKpGYp0evJoaRTFgf6nVsZMPSN8OjmAWgLHiLt
 Ki/GgGjenzrkN5kFK5/7PIzLrgrnopRvGNuPcvbDbdPDTFZbr84ABA7xFp2C/wkt
 msryzsNnOYEiNKoufx8ExfvIQiUV5Bfw5RqtsJg3p70WpxIs5jlwDAZU3NmJMXzP
 91IZViW7iAm84HGi5FmK4ZbVz1wFutwKH6otZGq2ViFOu9gTgbUkPFSc+q1a3NOH
 /Ac8jDqk2TUjbx1zmb5T1CKU/JKCL0WysjILPDIDOgGM8wOTPKyRqCaAUDmi+TjK
 UfUFfBeHngngj4y4qn5XMiUNSRp8pPlHiWNpcAecilUUedmslKrESpVD2sUHgZQv
 fD47FHKQsoQy0pBa1T1VCYO8mnaQjh8ao7c2FeoK3Jw+emPiaUsmveH9aZgMC5dM
 Pq4axzdRfOxtL5n5JAdApEj6Gu1l/4D9pIGTiTD9UKcGK+ef+r6zJ8/oHtdHB+EY
 04mB95L+UNatrmpctQovdUp7dcDw1xIuNBTRXXF4dOZTQ6nbvrdlNsc+zm8CVgXa
 UEvKWXNhxduiiR0W95rR6v1Od+XUqGk8C/lOG9Cg8F2EKymEVX0=
 =0d+E
 -----END PGP SIGNATURE-----

Merge 4.9.92 into android-4.9

Changes in 4.9.92
	scsi: sg: don't return bogus Sg_requests
	Revert "genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs"
	net sched actions: return explicit error when tunnel_key mode is not specified
	ppp: avoid loop in xmit recursion detection code
	rhashtable: Fix rhlist duplicates insertion
	sch_netem: fix skb leak in netem_enqueue()
	ieee802154: 6lowpan: fix possible NULL deref in lowpan_device_event()
	net: use skb_to_full_sk() in skb_update_prio()
	net: Fix hlist corruptions in inet_evict_bucket()
	dccp: check sk for closed state in dccp_sendmsg()
	ipv6: fix access to non-linear packet in ndisc_fill_redirect_hdr_option()
	l2tp: do not accept arbitrary sockets
	net: ethernet: arc: Fix a potential memory leak if an optional regulator is deferred
	net: ethernet: ti: cpsw: add check for in-band mode setting with RGMII PHY interface
	net: fec: Fix unbalanced PM runtime calls
	net/iucv: Free memory obtained by kzalloc
	netlink: avoid a double skb free in genlmsg_mcast()
	net: Only honor ifindex in IP_PKTINFO if non-0
	skbuff: Fix not waking applications when errors are enqueued
	team: Fix double free in error path
	soc/fsl/qbman: fix issue in qman_delete_cgr_safe()
	s390/qeth: free netdevice when removing a card
	s390/qeth: when thread completes, wake up all waiters
	s390/qeth: lock read device while queueing next buffer
	s390/qeth: on channel error, reject further cmd requests
	net: systemport: Rewrite __bcm_sysport_tx_reclaim()
	kcm: lock lower socket in kcm_attach
	net: hns: Fix a skb used after free bug
	Linux 4.9.92

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2018-03-31 18:42:34 +02:00
commit 9c3fb9cd6e
30 changed files with 166 additions and 104 deletions

View file

@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 91
SUBLEVEL = 92
EXTRAVERSION =
NAME = Roaring Lionus

View file

@ -169,8 +169,10 @@ static int emac_rockchip_probe(struct platform_device *pdev)
/* Optional regulator for PHY */
priv->regulator = devm_regulator_get_optional(dev, "phy");
if (IS_ERR(priv->regulator)) {
if (PTR_ERR(priv->regulator) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) {
err = -EPROBE_DEFER;
goto out_clk_disable;
}
dev_err(dev, "no regulator found\n");
priv->regulator = NULL;
}

View file

@ -707,37 +707,33 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
struct bcm_sysport_tx_ring *ring)
{
struct net_device *ndev = priv->netdev;
unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs;
unsigned int pkts_compl = 0, bytes_compl = 0;
unsigned int txbds_processed = 0;
struct bcm_sysport_cb *cb;
unsigned int txbds_ready;
unsigned int c_index;
u32 hw_ind;
/* Compute how many descriptors have been processed since last call */
hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index));
c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK;
ring->p_index = (hw_ind & RING_PROD_INDEX_MASK);
last_c_index = ring->c_index;
num_tx_cbs = ring->size;
c_index &= (num_tx_cbs - 1);
if (c_index >= last_c_index)
last_tx_cn = c_index - last_c_index;
else
last_tx_cn = num_tx_cbs - last_c_index + c_index;
txbds_ready = (c_index - ring->c_index) & RING_CONS_INDEX_MASK;
netif_dbg(priv, tx_done, ndev,
"ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n",
ring->index, c_index, last_tx_cn, last_c_index);
"ring=%d old_c_index=%u c_index=%u txbds_ready=%u\n",
ring->index, ring->c_index, c_index, txbds_ready);
while (last_tx_cn-- > 0) {
cb = ring->cbs + last_c_index;
while (txbds_processed < txbds_ready) {
cb = &ring->cbs[ring->clean_index];
bcm_sysport_tx_reclaim_one(priv, cb, &bytes_compl, &pkts_compl);
ring->desc_count++;
last_c_index++;
last_c_index &= (num_tx_cbs - 1);
txbds_processed++;
if (likely(ring->clean_index < ring->size - 1))
ring->clean_index++;
else
ring->clean_index = 0;
}
ring->c_index = c_index;
@ -1207,6 +1203,7 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
netif_tx_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64);
ring->index = index;
ring->size = size;
ring->clean_index = 0;
ring->alloc_size = ring->size;
ring->desc_cpu = p;
ring->desc_count = ring->size;

View file

@ -638,7 +638,7 @@ struct bcm_sysport_tx_ring {
unsigned int desc_count; /* Number of descriptors */
unsigned int curr_desc; /* Current descriptor */
unsigned int c_index; /* Last consumer index */
unsigned int p_index; /* Current producer index */
unsigned int clean_index; /* Current clean index */
struct bcm_sysport_cb *cbs; /* Transmit control blocks */
struct dma_desc *desc_cpu; /* CPU view of the descriptor */
struct bcm_sysport_priv *priv; /* private context backpointer */

View file

@ -3533,6 +3533,8 @@ fec_drv_remove(struct platform_device *pdev)
fec_enet_mii_remove(fep);
if (fep->reg_phy)
regulator_disable(fep->reg_phy);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (of_phy_is_fixed_link(np))
of_phy_deregister_fixed_link(np);
of_node_put(fep->phy_node);

View file

@ -901,7 +901,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
/* set speed_in input in case RMII mode is used in 100Mbps */
if (phy->speed == 100)
mac_control |= BIT(15);
else if (phy->speed == 10)
/* in band mode only works in 10Mbps RGMII mode */
else if ((phy->speed == 10) && phy_interface_is_rgmii(phy))
mac_control |= BIT(18); /* In Band mode */
if (priv->rx_pause)

View file

@ -255,7 +255,7 @@ struct ppp_net {
/* Prototypes. */
static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
struct file *file, unsigned int cmd, unsigned long arg);
static void ppp_xmit_process(struct ppp *ppp);
static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb);
static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
static void ppp_push(struct ppp *ppp);
static void ppp_channel_push(struct channel *pch);
@ -511,13 +511,12 @@ static ssize_t ppp_write(struct file *file, const char __user *buf,
goto out;
}
skb_queue_tail(&pf->xq, skb);
switch (pf->kind) {
case INTERFACE:
ppp_xmit_process(PF_TO_PPP(pf));
ppp_xmit_process(PF_TO_PPP(pf), skb);
break;
case CHANNEL:
skb_queue_tail(&pf->xq, skb);
ppp_channel_push(PF_TO_CHANNEL(pf));
break;
}
@ -1261,8 +1260,8 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
put_unaligned_be16(proto, pp);
skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev)));
skb_queue_tail(&ppp->file.xq, skb);
ppp_xmit_process(ppp);
ppp_xmit_process(ppp, skb);
return NETDEV_TX_OK;
outf:
@ -1416,13 +1415,14 @@ static void ppp_setup(struct net_device *dev)
*/
/* Called to do any work queued up on the transmit side that can now be done */
static void __ppp_xmit_process(struct ppp *ppp)
static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
{
struct sk_buff *skb;
ppp_xmit_lock(ppp);
if (!ppp->closing) {
ppp_push(ppp);
if (skb)
skb_queue_tail(&ppp->file.xq, skb);
while (!ppp->xmit_pending &&
(skb = skb_dequeue(&ppp->file.xq)))
ppp_send_frame(ppp, skb);
@ -1436,7 +1436,7 @@ static void __ppp_xmit_process(struct ppp *ppp)
ppp_xmit_unlock(ppp);
}
static void ppp_xmit_process(struct ppp *ppp)
static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
{
local_bh_disable();
@ -1444,7 +1444,7 @@ static void ppp_xmit_process(struct ppp *ppp)
goto err;
(*this_cpu_ptr(ppp->xmit_recursion))++;
__ppp_xmit_process(ppp);
__ppp_xmit_process(ppp, skb);
(*this_cpu_ptr(ppp->xmit_recursion))--;
local_bh_enable();
@ -1454,6 +1454,8 @@ static void ppp_xmit_process(struct ppp *ppp)
err:
local_bh_enable();
kfree_skb(skb);
if (net_ratelimit())
netdev_err(ppp->dev, "recursion detected\n");
}
@ -1938,7 +1940,7 @@ static void __ppp_channel_push(struct channel *pch)
if (skb_queue_empty(&pch->file.xq)) {
ppp = pch->ppp;
if (ppp)
__ppp_xmit_process(ppp);
__ppp_xmit_process(ppp, NULL);
}
}

View file

@ -2403,7 +2403,7 @@ send_done:
if (!nlh) {
err = __send_and_alloc_skb(&skb, team, portid, send_func);
if (err)
goto errout;
return err;
goto send_done;
}
@ -2688,7 +2688,7 @@ send_done:
if (!nlh) {
err = __send_and_alloc_skb(&skb, team, portid, send_func);
if (err)
goto errout;
return err;
goto send_done;
}

View file

@ -522,8 +522,7 @@ static inline int qeth_is_cq(struct qeth_card *card, unsigned int queue)
queue == card->qdio.no_in_queues - 1;
}
static int qeth_issue_next_read(struct qeth_card *card)
static int __qeth_issue_next_read(struct qeth_card *card)
{
int rc;
struct qeth_cmd_buffer *iob;
@ -554,6 +553,17 @@ static int qeth_issue_next_read(struct qeth_card *card)
return rc;
}
static int qeth_issue_next_read(struct qeth_card *card)
{
int ret;
spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card)));
ret = __qeth_issue_next_read(card);
spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card)));
return ret;
}
static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
{
struct qeth_reply *reply;
@ -957,7 +967,7 @@ void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
spin_lock_irqsave(&card->thread_mask_lock, flags);
card->thread_running_mask &= ~thread;
spin_unlock_irqrestore(&card->thread_mask_lock, flags);
wake_up(&card->wait_q);
wake_up_all(&card->wait_q);
}
EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit);
@ -1161,6 +1171,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
}
rc = qeth_get_problem(cdev, irb);
if (rc) {
card->read_or_write_problem = 1;
qeth_clear_ipacmd_list(card);
qeth_schedule_recovery(card);
goto out;
@ -1179,7 +1190,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
return;
if (channel == &card->read &&
channel->state == CH_STATE_UP)
qeth_issue_next_read(card);
__qeth_issue_next_read(card);
iob = channel->iob;
index = channel->buf_no;
@ -4989,8 +5000,6 @@ static void qeth_core_free_card(struct qeth_card *card)
QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
qeth_clean_channel(&card->read);
qeth_clean_channel(&card->write);
if (card->dev)
free_netdev(card->dev);
qeth_free_qdio_buffers(card);
unregister_service_level(&card->qeth_service_level);
kfree(card);

View file

@ -1057,8 +1057,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
qeth_l2_set_offline(cgdev);
if (card->dev) {
netif_napi_del(&card->napi);
unregister_netdev(card->dev);
free_netdev(card->dev);
card->dev = NULL;
}
return;

View file

@ -3192,8 +3192,8 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
qeth_l3_set_offline(cgdev);
if (card->dev) {
netif_napi_del(&card->napi);
unregister_netdev(card->dev);
free_netdev(card->dev);
card->dev = NULL;
}

View file

@ -2064,11 +2064,12 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
if ((1 == resp->done) && (!resp->sg_io_owned) &&
((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
resp->done = 2; /* guard against other readers */
break;
write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
return resp;
}
}
write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
return resp;
return NULL;
}
/* always adds to end of list */

View file

@ -2429,39 +2429,21 @@ struct cgr_comp {
struct completion completion;
};
static int qman_delete_cgr_thread(void *p)
static void qman_delete_cgr_smp_call(void *p)
{
struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
int ret;
ret = qman_delete_cgr(cgr_comp->cgr);
complete(&cgr_comp->completion);
return ret;
qman_delete_cgr((struct qman_cgr *)p);
}
void qman_delete_cgr_safe(struct qman_cgr *cgr)
{
struct task_struct *thread;
struct cgr_comp cgr_comp;
preempt_disable();
if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
init_completion(&cgr_comp.completion);
cgr_comp.cgr = cgr;
thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
"cgr_del");
if (IS_ERR(thread))
goto out;
kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
wake_up_process(thread);
wait_for_completion(&cgr_comp.completion);
smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
qman_delete_cgr_smp_call, cgr, true);
preempt_enable();
return;
}
out:
qman_delete_cgr(cgr);
preempt_enable();
}

View file

@ -613,13 +613,13 @@ struct sock_cgroup_data {
* updaters and return part of the previous pointer as the prioidx or
* classid. Such races are short-lived and the result isn't critical.
*/
static inline u16 sock_cgroup_prioidx(struct sock_cgroup_data *skcd)
static inline u16 sock_cgroup_prioidx(const struct sock_cgroup_data *skcd)
{
/* fallback to 1 which is always the ID of the root cgroup */
return (skcd->is_data & 1) ? skcd->prioidx : 1;
}
static inline u32 sock_cgroup_classid(struct sock_cgroup_data *skcd)
static inline u32 sock_cgroup_classid(const struct sock_cgroup_data *skcd)
{
/* fallback to 0 which is the unconfigured default classid */
return (skcd->is_data & 1) ? skcd->classid : 0;

View file

@ -706,8 +706,10 @@ slow_path:
if (!key ||
(params.obj_cmpfn ?
params.obj_cmpfn(&arg, rht_obj(ht, head)) :
rhashtable_compare(&arg, rht_obj(ht, head))))
rhashtable_compare(&arg, rht_obj(ht, head)))) {
pprev = &head->next;
continue;
}
data = rht_obj(ht, head);

View file

@ -675,6 +675,16 @@ static inline void __qdisc_drop(struct sk_buff *skb, struct sk_buff **to_free)
*to_free = skb;
}
static inline void __qdisc_drop_all(struct sk_buff *skb,
struct sk_buff **to_free)
{
if (skb->prev)
skb->prev->next = *to_free;
else
skb->next = *to_free;
*to_free = skb;
}
static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,
struct qdisc_skb_head *qh,
struct sk_buff **to_free)
@ -795,6 +805,15 @@ static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch,
return NET_XMIT_DROP;
}
static inline int qdisc_drop_all(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
__qdisc_drop_all(skb, to_free);
qdisc_qstats_drop(sch);
return NET_XMIT_DROP;
}
/* Length to Time (L2T) lookup in a qdisc_rate_table, to determine how
long it will take to send a packet given its size.
*/

View file

@ -448,8 +448,10 @@ static void *rhashtable_lookup_one(struct rhashtable *ht,
if (!key ||
(ht->p.obj_cmpfn ?
ht->p.obj_cmpfn(&arg, rht_obj(ht, head)) :
rhashtable_compare(&arg, rht_obj(ht, head))))
rhashtable_compare(&arg, rht_obj(ht, head)))) {
pprev = &head->next;
continue;
}
if (!ht->rhlist)
return rht_obj(ht, head);

View file

@ -3179,15 +3179,23 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
static void skb_update_prio(struct sk_buff *skb)
{
struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap);
const struct netprio_map *map;
const struct sock *sk;
unsigned int prioidx;
if (!skb->priority && skb->sk && map) {
unsigned int prioidx =
sock_cgroup_prioidx(&skb->sk->sk_cgrp_data);
if (skb->priority)
return;
map = rcu_dereference_bh(skb->dev->priomap);
if (!map)
return;
sk = skb_to_full_sk(skb);
if (!sk)
return;
if (prioidx < map->priomap_len)
skb->priority = map->priomap[prioidx];
}
prioidx = sock_cgroup_prioidx(&sk->sk_cgrp_data);
if (prioidx < map->priomap_len)
skb->priority = map->priomap[prioidx];
}
#else
#define skb_update_prio(skb)

View file

@ -3717,7 +3717,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
skb_queue_tail(&sk->sk_error_queue, skb);
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_data_ready(sk);
sk->sk_error_report(sk);
return 0;
}
EXPORT_SYMBOL(sock_queue_err_skb);

View file

@ -789,6 +789,11 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (skb == NULL)
goto out_release;
if (sk->sk_state == DCCP_CLOSED) {
rc = -ENOTCONN;
goto out_discard;
}
skb_reserve(skb, sk->sk_prot->max_header);
rc = memcpy_from_msg(skb_put(skb, len), msg, len);
if (rc != 0)

Some files were not shown because too many files have changed in this diff Show more