Commit 72da3bc0cb3e82bd95f278a0c5c988e506e56d13
Exists in
master
and in
39 other branches
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (22 commits) netlink: bug fix: wrong size was calculated for vfinfo list blob netlink: bug fix: don't overrun skbs on vf_port dump xt_tee: use skb_dst_drop() netdev/fec: fix ifconfig eth0 down hang issue cnic: Fix context memory init. on 5709. drivers/net: Eliminate a NULL pointer dereference drivers/net/hamradio: Eliminate a NULL pointer dereference be2net: Patch removes redundant while statement in loop. ipv6: Add GSO support on forwarding path net: fix __neigh_event_send() vhost: fix the memory leak which will happen when memory_access_ok fails vhost-net: fix to check the return value of copy_to/from_user() correctly vhost: fix to check the return value of copy_to/from_user() correctly vhost: Fix host panic if ioctl called with wrong index net: fix lock_sock_bh/unlock_sock_bh net/iucv: Add missing spin_unlock net: ll_temac: fix checksum offload logic net: ll_temac: fix interrupt bug when interrupt 0 is used sctp: dubious bitfields in sctp_transport ipmr: off by one in __ipmr_fill_mroute() ...
Showing 25 changed files Side-by-side Diff
- drivers/net/3c507.c
- drivers/net/benet/be_cmds.c
- drivers/net/benet/be_main.c
- drivers/net/cnic.c
- drivers/net/cnic_if.h
- drivers/net/fec.c
- drivers/net/hamradio/yam.c
- drivers/net/ll_temac.h
- drivers/net/ll_temac_main.c
- drivers/vhost/net.c
- drivers/vhost/vhost.c
- include/net/cls_cgroup.h
- include/net/sctp/structs.h
- include/net/sock.h
- net/core/datagram.c
- net/core/neighbour.c
- net/core/rtnetlink.c
- net/core/sock.c
- net/ipv4/ipmr.c
- net/ipv4/udp.c
- net/ipv6/ip6_output.c
- net/ipv6/ip6mr.c
- net/ipv6/udp.c
- net/iucv/af_iucv.c
- net/netfilter/xt_TEE.c
drivers/net/3c507.c
drivers/net/benet/be_cmds.c
drivers/net/benet/be_main.c
drivers/net/cnic.c
... | ... | @@ -3367,13 +3367,9 @@ |
3367 | 3367 | |
3368 | 3368 | static void cnic_init_context(struct cnic_dev *dev, u32 cid) |
3369 | 3369 | { |
3370 | - struct cnic_local *cp = dev->cnic_priv; | |
3371 | 3370 | u32 cid_addr; |
3372 | 3371 | int i; |
3373 | 3372 | |
3374 | - if (CHIP_NUM(cp) == CHIP_NUM_5709) | |
3375 | - return; | |
3376 | - | |
3377 | 3373 | cid_addr = GET_CID_ADDR(cid); |
3378 | 3374 | |
3379 | 3375 | for (i = 0; i < CTX_SIZE; i += 4) |
3380 | 3376 | |
... | ... | @@ -3530,14 +3526,11 @@ |
3530 | 3526 | |
3531 | 3527 | sb_id = cp->status_blk_num; |
3532 | 3528 | tx_cid = 20; |
3533 | - cnic_init_context(dev, tx_cid); | |
3534 | - cnic_init_context(dev, tx_cid + 1); | |
3535 | 3529 | cp->tx_cons_ptr = &s_blk->status_tx_quick_consumer_index2; |
3536 | 3530 | if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { |
3537 | 3531 | struct status_block_msix *sblk = cp->status_blk.bnx2; |
3538 | 3532 | |
3539 | 3533 | tx_cid = TX_TSS_CID + sb_id - 1; |
3540 | - cnic_init_context(dev, tx_cid); | |
3541 | 3534 | CNIC_WR(dev, BNX2_TSCH_TSS_CFG, (sb_id << 24) | |
3542 | 3535 | (TX_TSS_CID << 7)); |
3543 | 3536 | cp->tx_cons_ptr = &sblk->status_tx_quick_consumer_index; |
... | ... | @@ -3556,6 +3549,9 @@ |
3556 | 3549 | offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI; |
3557 | 3550 | offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI; |
3558 | 3551 | } else { |
3552 | + cnic_init_context(dev, tx_cid); | |
3553 | + cnic_init_context(dev, tx_cid + 1); | |
3554 | + | |
3559 | 3555 | offset0 = BNX2_L2CTX_TYPE; |
3560 | 3556 | offset1 = BNX2_L2CTX_CMD_TYPE; |
3561 | 3557 | offset2 = BNX2_L2CTX_TBDR_BHADDR_HI; |
drivers/net/cnic_if.h
... | ... | @@ -12,8 +12,8 @@ |
12 | 12 | #ifndef CNIC_IF_H |
13 | 13 | #define CNIC_IF_H |
14 | 14 | |
15 | -#define CNIC_MODULE_VERSION "2.1.1" | |
16 | -#define CNIC_MODULE_RELDATE "Feb 22, 2010" | |
15 | +#define CNIC_MODULE_VERSION "2.1.2" | |
16 | +#define CNIC_MODULE_RELDATE "May 26, 2010" | |
17 | 17 | |
18 | 18 | #define CNIC_ULP_RDMA 0 |
19 | 19 | #define CNIC_ULP_ISCSI 1 |
drivers/net/fec.c
... | ... | @@ -681,6 +681,8 @@ |
681 | 681 | struct phy_device *phy_dev = NULL; |
682 | 682 | int phy_addr; |
683 | 683 | |
684 | + fep->phy_dev = NULL; | |
685 | + | |
684 | 686 | /* find the first phy */ |
685 | 687 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { |
686 | 688 | if (fep->mii_bus->phy_map[phy_addr]) { |
... | ... | @@ -711,6 +713,11 @@ |
711 | 713 | fep->link = 0; |
712 | 714 | fep->full_duplex = 0; |
713 | 715 | |
716 | + printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " | |
717 | + "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, | |
718 | + fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), | |
719 | + fep->phy_dev->irq); | |
720 | + | |
714 | 721 | return 0; |
715 | 722 | } |
716 | 723 | |
717 | 724 | |
... | ... | @@ -756,13 +763,8 @@ |
756 | 763 | if (mdiobus_register(fep->mii_bus)) |
757 | 764 | goto err_out_free_mdio_irq; |
758 | 765 | |
759 | - if (fec_enet_mii_probe(dev) != 0) | |
760 | - goto err_out_unregister_bus; | |
761 | - | |
762 | 766 | return 0; |
763 | 767 | |
764 | -err_out_unregister_bus: | |
765 | - mdiobus_unregister(fep->mii_bus); | |
766 | 768 | err_out_free_mdio_irq: |
767 | 769 | kfree(fep->mii_bus->irq); |
768 | 770 | err_out_free_mdiobus: |
... | ... | @@ -915,7 +917,12 @@ |
915 | 917 | if (ret) |
916 | 918 | return ret; |
917 | 919 | |
918 | - /* schedule a link state check */ | |
920 | + /* Probe and connect to PHY when open the interface */ | |
921 | + ret = fec_enet_mii_probe(dev); | |
922 | + if (ret) { | |
923 | + fec_enet_free_buffers(dev); | |
924 | + return ret; | |
925 | + } | |
919 | 926 | phy_start(fep->phy_dev); |
920 | 927 | netif_start_queue(dev); |
921 | 928 | fep->opened = 1; |
922 | 929 | |
... | ... | @@ -929,10 +936,12 @@ |
929 | 936 | |
930 | 937 | /* Don't know what to do yet. */ |
931 | 938 | fep->opened = 0; |
932 | - phy_stop(fep->phy_dev); | |
933 | 939 | netif_stop_queue(dev); |
934 | 940 | fec_stop(dev); |
935 | 941 | |
942 | + if (fep->phy_dev) | |
943 | + phy_disconnect(fep->phy_dev); | |
944 | + | |
936 | 945 | fec_enet_free_buffers(dev); |
937 | 946 | |
938 | 947 | return 0; |
... | ... | @@ -1315,11 +1324,6 @@ |
1315 | 1324 | ret = register_netdev(ndev); |
1316 | 1325 | if (ret) |
1317 | 1326 | goto failed_register; |
1318 | - | |
1319 | - printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " | |
1320 | - "(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name, | |
1321 | - fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), | |
1322 | - fep->phy_dev->irq); | |
1323 | 1327 | |
1324 | 1328 | return 0; |
1325 | 1329 |
drivers/net/hamradio/yam.c
... | ... | @@ -1151,8 +1151,7 @@ |
1151 | 1151 | dev = alloc_netdev(sizeof(struct yam_port), name, |
1152 | 1152 | yam_setup); |
1153 | 1153 | if (!dev) { |
1154 | - printk(KERN_ERR "yam: cannot allocate net device %s\n", | |
1155 | - dev->name); | |
1154 | + pr_err("yam: cannot allocate net device\n"); | |
1156 | 1155 | err = -ENOMEM; |
1157 | 1156 | goto error; |
1158 | 1157 | } |
drivers/net/ll_temac.h
... | ... | @@ -295,6 +295,10 @@ |
295 | 295 | |
296 | 296 | #define MULTICAST_CAM_TABLE_NUM 4 |
297 | 297 | |
298 | +/* TEMAC Synthesis features */ | |
299 | +#define TEMAC_FEATURE_RX_CSUM (1 << 0) | |
300 | +#define TEMAC_FEATURE_TX_CSUM (1 << 1) | |
301 | + | |
298 | 302 | /* TX/RX CURDESC_PTR points to first descriptor */ |
299 | 303 | /* TX/RX TAILDESC_PTR points to last descriptor in linked list */ |
300 | 304 | |
... | ... | @@ -353,6 +357,7 @@ |
353 | 357 | struct mutex indirect_mutex; |
354 | 358 | u32 options; /* Current options word */ |
355 | 359 | int last_link; |
360 | + unsigned int temac_features; | |
356 | 361 | |
357 | 362 | /* Buffer descriptors */ |
358 | 363 | struct cdmac_bd *tx_bd_v; |
drivers/net/ll_temac_main.c
... | ... | @@ -245,7 +245,7 @@ |
245 | 245 | CHNL_CTRL_IRQ_COAL_EN); |
246 | 246 | /* 0x10220483 */ |
247 | 247 | /* 0x00100483 */ |
248 | - lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 | | |
248 | + lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 | | |
249 | 249 | CHNL_CTRL_IRQ_EN | |
250 | 250 | CHNL_CTRL_IRQ_DLY_EN | |
251 | 251 | CHNL_CTRL_IRQ_COAL_EN | |
... | ... | @@ -574,6 +574,10 @@ |
574 | 574 | if (cur_p->app4) |
575 | 575 | dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); |
576 | 576 | cur_p->app0 = 0; |
577 | + cur_p->app1 = 0; | |
578 | + cur_p->app2 = 0; | |
579 | + cur_p->app3 = 0; | |
580 | + cur_p->app4 = 0; | |
577 | 581 | |
578 | 582 | ndev->stats.tx_packets++; |
579 | 583 | ndev->stats.tx_bytes += cur_p->len; |
... | ... | @@ -589,6 +593,29 @@ |
589 | 593 | netif_wake_queue(ndev); |
590 | 594 | } |
591 | 595 | |
596 | +static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) | |
597 | +{ | |
598 | + struct cdmac_bd *cur_p; | |
599 | + int tail; | |
600 | + | |
601 | + tail = lp->tx_bd_tail; | |
602 | + cur_p = &lp->tx_bd_v[tail]; | |
603 | + | |
604 | + do { | |
605 | + if (cur_p->app0) | |
606 | + return NETDEV_TX_BUSY; | |
607 | + | |
608 | + tail++; | |
609 | + if (tail >= TX_BD_NUM) | |
610 | + tail = 0; | |
611 | + | |
612 | + cur_p = &lp->tx_bd_v[tail]; | |
613 | + num_frag--; | |
614 | + } while (num_frag >= 0); | |
615 | + | |
616 | + return 0; | |
617 | +} | |
618 | + | |
592 | 619 | static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
593 | 620 | { |
594 | 621 | struct temac_local *lp = netdev_priv(ndev); |
... | ... | @@ -603,7 +630,7 @@ |
603 | 630 | start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; |
604 | 631 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
605 | 632 | |
606 | - if (cur_p->app0 & STS_CTRL_APP0_CMPLT) { | |
633 | + if (temac_check_tx_bd_space(lp, num_frag)) { | |
607 | 634 | if (!netif_queue_stopped(ndev)) { |
608 | 635 | netif_stop_queue(ndev); |
609 | 636 | return NETDEV_TX_BUSY; |
610 | 637 | |
611 | 638 | |
... | ... | @@ -613,29 +640,14 @@ |
613 | 640 | |
614 | 641 | cur_p->app0 = 0; |
615 | 642 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
616 | - const struct iphdr *ip = ip_hdr(skb); | |
617 | - int length = 0, start = 0, insert = 0; | |
643 | + unsigned int csum_start_off = skb_transport_offset(skb); | |
644 | + unsigned int csum_index_off = csum_start_off + skb->csum_offset; | |
618 | 645 | |
619 | - switch (ip->protocol) { | |
620 | - case IPPROTO_TCP: | |
621 | - start = sizeof(struct iphdr) + ETH_HLEN; | |
622 | - insert = sizeof(struct iphdr) + ETH_HLEN + 16; | |
623 | - length = ip->tot_len - sizeof(struct iphdr); | |
624 | - break; | |
625 | - case IPPROTO_UDP: | |
626 | - start = sizeof(struct iphdr) + ETH_HLEN; | |
627 | - insert = sizeof(struct iphdr) + ETH_HLEN + 6; | |
628 | - length = ip->tot_len - sizeof(struct iphdr); | |
629 | - break; | |
630 | - default: | |
631 | - break; | |
632 | - } | |
633 | - cur_p->app1 = ((start << 16) | insert); | |
634 | - cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr, | |
635 | - length, ip->protocol, 0); | |
636 | - skb->data[insert] = 0; | |
637 | - skb->data[insert + 1] = 0; | |
646 | + cur_p->app0 |= 1; /* TX Checksum Enabled */ | |
647 | + cur_p->app1 = (csum_start_off << 16) | csum_index_off; | |
648 | + cur_p->app2 = 0; /* initial checksum seed */ | |
638 | 649 | } |
650 | + | |
639 | 651 | cur_p->app0 |= STS_CTRL_APP0_SOP; |
640 | 652 | cur_p->len = skb_headlen(skb); |
641 | 653 | cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, |
... | ... | @@ -699,6 +711,15 @@ |
699 | 711 | skb->protocol = eth_type_trans(skb, ndev); |
700 | 712 | skb->ip_summed = CHECKSUM_NONE; |
701 | 713 | |
714 | + /* if we're doing rx csum offload, set it up */ | |
715 | + if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && | |
716 | + (skb->protocol == __constant_htons(ETH_P_IP)) && | |
717 | + (skb->len > 64)) { | |
718 | + | |
719 | + skb->csum = cur_p->app3 & 0xFFFF; | |
720 | + skb->ip_summed = CHECKSUM_COMPLETE; | |
721 | + } | |
722 | + | |
702 | 723 | netif_rx(skb); |
703 | 724 | |
704 | 725 | ndev->stats.rx_packets++; |
... | ... | @@ -883,6 +904,7 @@ |
883 | 904 | struct temac_local *lp; |
884 | 905 | struct net_device *ndev; |
885 | 906 | const void *addr; |
907 | + __be32 *p; | |
886 | 908 | int size, rc = 0; |
887 | 909 | |
888 | 910 | /* Init network device structure */ |
... | ... | @@ -926,6 +948,18 @@ |
926 | 948 | goto nodev; |
927 | 949 | } |
928 | 950 | |
951 | + /* Setup checksum offload, but default to off if not specified */ | |
952 | + lp->temac_features = 0; | |
953 | + p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); | |
954 | + if (p && be32_to_cpu(*p)) { | |
955 | + lp->temac_features |= TEMAC_FEATURE_TX_CSUM; | |
956 | + /* Can checksum TCP/UDP over IPv4. */ | |
957 | + ndev->features |= NETIF_F_IP_CSUM; | |
958 | + } | |
959 | + p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); | |
960 | + if (p && be32_to_cpu(*p)) | |
961 | + lp->temac_features |= TEMAC_FEATURE_RX_CSUM; | |
962 | + | |
929 | 963 | /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ |
930 | 964 | np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); |
931 | 965 | if (!np) { |
... | ... | @@ -950,7 +984,7 @@ |
950 | 984 | |
951 | 985 | lp->rx_irq = irq_of_parse_and_map(np, 0); |
952 | 986 | lp->tx_irq = irq_of_parse_and_map(np, 1); |
953 | - if (!lp->rx_irq || !lp->tx_irq) { | |
987 | + if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { | |
954 | 988 | dev_err(&op->dev, "could not determine irqs\n"); |
955 | 989 | rc = -ENOMEM; |
956 | 990 | goto nodev; |
drivers/vhost/net.c
... | ... | @@ -593,17 +593,17 @@ |
593 | 593 | int r; |
594 | 594 | switch (ioctl) { |
595 | 595 | case VHOST_NET_SET_BACKEND: |
596 | - r = copy_from_user(&backend, argp, sizeof backend); | |
597 | - if (r < 0) | |
598 | - return r; | |
596 | + if (copy_from_user(&backend, argp, sizeof backend)) | |
597 | + return -EFAULT; | |
599 | 598 | return vhost_net_set_backend(n, backend.index, backend.fd); |
600 | 599 | case VHOST_GET_FEATURES: |
601 | 600 | features = VHOST_FEATURES; |
602 | - return copy_to_user(featurep, &features, sizeof features); | |
601 | + if (copy_to_user(featurep, &features, sizeof features)) | |
602 | + return -EFAULT; | |
603 | + return 0; | |
603 | 604 | case VHOST_SET_FEATURES: |
604 | - r = copy_from_user(&features, featurep, sizeof features); | |
605 | - if (r < 0) | |
606 | - return r; | |
605 | + if (copy_from_user(&features, featurep, sizeof features)) | |
606 | + return -EFAULT; | |
607 | 607 | if (features & ~VHOST_FEATURES) |
608 | 608 | return -EOPNOTSUPP; |
609 | 609 | return vhost_net_set_features(n, features); |
drivers/vhost/vhost.c
... | ... | @@ -320,10 +320,8 @@ |
320 | 320 | { |
321 | 321 | struct vhost_memory mem, *newmem, *oldmem; |
322 | 322 | unsigned long size = offsetof(struct vhost_memory, regions); |
323 | - long r; | |
324 | - r = copy_from_user(&mem, m, size); | |
325 | - if (r) | |
326 | - return r; | |
323 | + if (copy_from_user(&mem, m, size)) | |
324 | + return -EFAULT; | |
327 | 325 | if (mem.padding) |
328 | 326 | return -EOPNOTSUPP; |
329 | 327 | if (mem.nregions > VHOST_MEMORY_MAX_NREGIONS) |
330 | 328 | |
331 | 329 | |
332 | 330 | |
... | ... | @@ -333,15 +331,16 @@ |
333 | 331 | return -ENOMEM; |
334 | 332 | |
335 | 333 | memcpy(newmem, &mem, size); |
336 | - r = copy_from_user(newmem->regions, m->regions, | |
337 | - mem.nregions * sizeof *m->regions); | |
338 | - if (r) { | |
334 | + if (copy_from_user(newmem->regions, m->regions, | |
335 | + mem.nregions * sizeof *m->regions)) { | |
339 | 336 | kfree(newmem); |
340 | - return r; | |
337 | + return -EFAULT; | |
341 | 338 | } |
342 | 339 | |
343 | - if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL))) | |
340 | + if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL))) { | |
341 | + kfree(newmem); | |
344 | 342 | return -EFAULT; |
343 | + } | |
345 | 344 | oldmem = d->memory; |
346 | 345 | rcu_assign_pointer(d->memory, newmem); |
347 | 346 | synchronize_rcu(); |
... | ... | @@ -374,7 +373,7 @@ |
374 | 373 | r = get_user(idx, idxp); |
375 | 374 | if (r < 0) |
376 | 375 | return r; |
377 | - if (idx > d->nvqs) | |
376 | + if (idx >= d->nvqs) | |
378 | 377 | return -ENOBUFS; |
379 | 378 | |
380 | 379 | vq = d->vqs + idx; |
381 | 380 | |
... | ... | @@ -389,9 +388,10 @@ |
389 | 388 | r = -EBUSY; |
390 | 389 | break; |
391 | 390 | } |
392 | - r = copy_from_user(&s, argp, sizeof s); | |
393 | - if (r < 0) | |
391 | + if (copy_from_user(&s, argp, sizeof s)) { | |
392 | + r = -EFAULT; | |
394 | 393 | break; |
394 | + } | |
395 | 395 | if (!s.num || s.num > 0xffff || (s.num & (s.num - 1))) { |
396 | 396 | r = -EINVAL; |
397 | 397 | break; |
398 | 398 | |
... | ... | @@ -405,9 +405,10 @@ |
405 | 405 | r = -EBUSY; |
406 | 406 | break; |
407 | 407 | } |
408 | - r = copy_from_user(&s, argp, sizeof s); | |
409 | - if (r < 0) | |
408 | + if (copy_from_user(&s, argp, sizeof s)) { | |
409 | + r = -EFAULT; | |
410 | 410 | break; |
411 | + } | |
411 | 412 | if (s.num > 0xffff) { |
412 | 413 | r = -EINVAL; |
413 | 414 | break; |
414 | 415 | |
415 | 416 | |
... | ... | @@ -419,12 +420,14 @@ |
419 | 420 | case VHOST_GET_VRING_BASE: |
420 | 421 | s.index = idx; |
421 | 422 | s.num = vq->last_avail_idx; |
422 | - r = copy_to_user(argp, &s, sizeof s); | |
423 | + if (copy_to_user(argp, &s, sizeof s)) | |
424 | + r = -EFAULT; | |
423 | 425 | break; |
424 | 426 | case VHOST_SET_VRING_ADDR: |
425 | - r = copy_from_user(&a, argp, sizeof a); | |
426 | - if (r < 0) | |
427 | + if (copy_from_user(&a, argp, sizeof a)) { | |
428 | + r = -EFAULT; | |
427 | 429 | break; |
430 | + } | |
428 | 431 | if (a.flags & ~(0x1 << VHOST_VRING_F_LOG)) { |
429 | 432 | r = -EOPNOTSUPP; |
430 | 433 | break; |
431 | 434 | |
... | ... | @@ -477,9 +480,10 @@ |
477 | 480 | vq->used = (void __user *)(unsigned long)a.used_user_addr; |
478 | 481 | break; |
479 | 482 | case VHOST_SET_VRING_KICK: |
480 | - r = copy_from_user(&f, argp, sizeof f); | |
481 | - if (r < 0) | |
483 | + if (copy_from_user(&f, argp, sizeof f)) { | |
484 | + r = -EFAULT; | |
482 | 485 | break; |
486 | + } | |
483 | 487 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
484 | 488 | if (IS_ERR(eventfp)) { |
485 | 489 | r = PTR_ERR(eventfp); |
486 | 490 | |
... | ... | @@ -492,9 +496,10 @@ |
492 | 496 | filep = eventfp; |
493 | 497 | break; |
494 | 498 | case VHOST_SET_VRING_CALL: |
495 | - r = copy_from_user(&f, argp, sizeof f); | |
496 | - if (r < 0) | |
499 | + if (copy_from_user(&f, argp, sizeof f)) { | |
500 | + r = -EFAULT; | |
497 | 501 | break; |
502 | + } | |
498 | 503 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
499 | 504 | if (IS_ERR(eventfp)) { |
500 | 505 | r = PTR_ERR(eventfp); |
501 | 506 | |
... | ... | @@ -510,9 +515,10 @@ |
510 | 515 | filep = eventfp; |
511 | 516 | break; |
512 | 517 | case VHOST_SET_VRING_ERR: |
513 | - r = copy_from_user(&f, argp, sizeof f); | |
514 | - if (r < 0) | |
518 | + if (copy_from_user(&f, argp, sizeof f)) { | |
519 | + r = -EFAULT; | |
515 | 520 | break; |
521 | + } | |
516 | 522 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
517 | 523 | if (IS_ERR(eventfp)) { |
518 | 524 | r = PTR_ERR(eventfp); |
519 | 525 | |
... | ... | @@ -575,9 +581,10 @@ |
575 | 581 | r = vhost_set_memory(d, argp); |
576 | 582 | break; |
577 | 583 | case VHOST_SET_LOG_BASE: |
578 | - r = copy_from_user(&p, argp, sizeof p); | |
579 | - if (r < 0) | |
584 | + if (copy_from_user(&p, argp, sizeof p)) { | |
585 | + r = -EFAULT; | |
580 | 586 | break; |
587 | + } | |
581 | 588 | if ((u64)(unsigned long)p != p) { |
582 | 589 | r = -EFAULT; |
583 | 590 | break; |
include/net/cls_cgroup.h
include/net/sctp/structs.h
... | ... | @@ -876,7 +876,7 @@ |
876 | 876 | |
877 | 877 | /* Reference counting. */ |
878 | 878 | atomic_t refcnt; |
879 | - int dead:1, | |
879 | + __u32 dead:1, | |
880 | 880 | /* RTO-Pending : A flag used to track if one of the DATA |
881 | 881 | * chunks sent to this address is currently being |
882 | 882 | * used to compute a RTT. If this flag is 0, |
include/net/sock.h
... | ... | @@ -1026,15 +1026,23 @@ |
1026 | 1026 | SINGLE_DEPTH_NESTING) |
1027 | 1027 | #define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock)) |
1028 | 1028 | |
1029 | -static inline void lock_sock_bh(struct sock *sk) | |
1029 | +extern bool lock_sock_fast(struct sock *sk); | |
1030 | +/** | |
1031 | + * unlock_sock_fast - complement of lock_sock_fast | |
1032 | + * @sk: socket | |
1033 | + * @slow: slow mode | |
1034 | + * | |
1035 | + * fast unlock socket for user context. | |
1036 | + * If slow mode is on, we call regular release_sock() | |
1037 | + */ | |
1038 | +static inline void unlock_sock_fast(struct sock *sk, bool slow) | |
1030 | 1039 | { |
1031 | - spin_lock_bh(&sk->sk_lock.slock); | |
1040 | + if (slow) | |
1041 | + release_sock(sk); | |
1042 | + else | |
1043 | + spin_unlock_bh(&sk->sk_lock.slock); | |
1032 | 1044 | } |
1033 | 1045 | |
1034 | -static inline void unlock_sock_bh(struct sock *sk) | |
1035 | -{ | |
1036 | - spin_unlock_bh(&sk->sk_lock.slock); | |
1037 | -} | |
1038 | 1046 | |
1039 | 1047 | extern struct sock *sk_alloc(struct net *net, int family, |
1040 | 1048 | gfp_t priority, |
net/core/datagram.c
... | ... | @@ -229,15 +229,17 @@ |
229 | 229 | |
230 | 230 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) |
231 | 231 | { |
232 | + bool slow; | |
233 | + | |
232 | 234 | if (likely(atomic_read(&skb->users) == 1)) |
233 | 235 | smp_rmb(); |
234 | 236 | else if (likely(!atomic_dec_and_test(&skb->users))) |
235 | 237 | return; |
236 | 238 | |
237 | - lock_sock_bh(sk); | |
239 | + slow = lock_sock_fast(sk); | |
238 | 240 | skb_orphan(skb); |
239 | 241 | sk_mem_reclaim_partial(sk); |
240 | - unlock_sock_bh(sk); | |
242 | + unlock_sock_fast(sk, slow); | |
241 | 243 | |
242 | 244 | /* skb is now orphaned, can be freed outside of locked section */ |
243 | 245 | __kfree_skb(skb); |
net/core/neighbour.c
net/core/rtnetlink.c
... | ... | @@ -650,11 +650,12 @@ |
650 | 650 | if (dev->dev.parent && dev_is_pci(dev->dev.parent)) { |
651 | 651 | |
652 | 652 | int num_vfs = dev_num_vf(dev->dev.parent); |
653 | - size_t size = nlmsg_total_size(sizeof(struct nlattr)); | |
654 | - size += nlmsg_total_size(num_vfs * sizeof(struct nlattr)); | |
655 | - size += num_vfs * (sizeof(struct ifla_vf_mac) + | |
656 | - sizeof(struct ifla_vf_vlan) + | |
657 | - sizeof(struct ifla_vf_tx_rate)); | |
653 | + size_t size = nla_total_size(sizeof(struct nlattr)); | |
654 | + size += nla_total_size(num_vfs * sizeof(struct nlattr)); | |
655 | + size += num_vfs * | |
656 | + (nla_total_size(sizeof(struct ifla_vf_mac)) + | |
657 | + nla_total_size(sizeof(struct ifla_vf_vlan)) + | |
658 | + nla_total_size(sizeof(struct ifla_vf_tx_rate))); | |
658 | 659 | return size; |
659 | 660 | } else |
660 | 661 | return 0; |
661 | 662 | |
662 | 663 | |
... | ... | @@ -722,14 +723,13 @@ |
722 | 723 | |
723 | 724 | for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) { |
724 | 725 | vf_port = nla_nest_start(skb, IFLA_VF_PORT); |
725 | - if (!vf_port) { | |
726 | - nla_nest_cancel(skb, vf_ports); | |
727 | - return -EMSGSIZE; | |
728 | - } | |
726 | + if (!vf_port) | |
727 | + goto nla_put_failure; | |
729 | 728 | NLA_PUT_U32(skb, IFLA_PORT_VF, vf); |
730 | 729 | err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb); |
730 | + if (err == -EMSGSIZE) | |
731 | + goto nla_put_failure; | |
731 | 732 | if (err) { |
732 | -nla_put_failure: | |
733 | 733 | nla_nest_cancel(skb, vf_port); |
734 | 734 | continue; |
735 | 735 | } |
... | ... | @@ -739,6 +739,10 @@ |
739 | 739 | nla_nest_end(skb, vf_ports); |
740 | 740 | |
741 | 741 | return 0; |
742 | + | |
743 | +nla_put_failure: | |
744 | + nla_nest_cancel(skb, vf_ports); | |
745 | + return -EMSGSIZE; | |
742 | 746 | } |
743 | 747 | |
744 | 748 | static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev) |
... | ... | @@ -753,7 +757,7 @@ |
753 | 757 | err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb); |
754 | 758 | if (err) { |
755 | 759 | nla_nest_cancel(skb, port_self); |
756 | - return err; | |
760 | + return (err == -EMSGSIZE) ? err : 0; | |
757 | 761 | } |
758 | 762 | |
759 | 763 | nla_nest_end(skb, port_self); |
net/core/sock.c
... | ... | @@ -2007,6 +2007,39 @@ |
2007 | 2007 | } |
2008 | 2008 | EXPORT_SYMBOL(release_sock); |
2009 | 2009 | |
2010 | +/** | |
2011 | + * lock_sock_fast - fast version of lock_sock | |
2012 | + * @sk: socket | |
2013 | + * | |
2014 | + * This version should be used for very small section, where process wont block | |
2015 | + * return false if fast path is taken | |
2016 | + * sk_lock.slock locked, owned = 0, BH disabled | |
2017 | + * return true if slow path is taken | |
2018 | + * sk_lock.slock unlocked, owned = 1, BH enabled | |
2019 | + */ | |
2020 | +bool lock_sock_fast(struct sock *sk) | |
2021 | +{ | |
2022 | + might_sleep(); | |
2023 | + spin_lock_bh(&sk->sk_lock.slock); | |
2024 | + | |
2025 | + if (!sk->sk_lock.owned) | |
2026 | + /* | |
2027 | + * Note : We must disable BH | |
2028 | + */ | |
2029 | + return false; | |
2030 | + | |
2031 | + __lock_sock(sk); | |
2032 | + sk->sk_lock.owned = 1; | |
2033 | + spin_unlock(&sk->sk_lock.slock); | |
2034 | + /* | |
2035 | + * The sk_lock has mutex_lock() semantics here: | |
2036 | + */ | |
2037 | + mutex_acquire(&sk->sk_lock.dep_map, 0, 0, _RET_IP_); | |
2038 | + local_bh_enable(); | |
2039 | + return true; | |
2040 | +} | |
2041 | +EXPORT_SYMBOL(lock_sock_fast); | |
2042 | + | |
2010 | 2043 | int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) |
2011 | 2044 | { |
2012 | 2045 | struct timeval tv; |
net/ipv4/ipmr.c
net/ipv4/udp.c
... | ... | @@ -1063,10 +1063,11 @@ |
1063 | 1063 | spin_unlock_bh(&rcvq->lock); |
1064 | 1064 | |
1065 | 1065 | if (!skb_queue_empty(&list_kill)) { |
1066 | - lock_sock_bh(sk); | |
1066 | + bool slow = lock_sock_fast(sk); | |
1067 | + | |
1067 | 1068 | __skb_queue_purge(&list_kill); |
1068 | 1069 | sk_mem_reclaim_partial(sk); |
1069 | - unlock_sock_bh(sk); | |
1070 | + unlock_sock_fast(sk, slow); | |
1070 | 1071 | } |
1071 | 1072 | return res; |
1072 | 1073 | } |
... | ... | @@ -1123,6 +1124,7 @@ |
1123 | 1124 | int peeked; |
1124 | 1125 | int err; |
1125 | 1126 | int is_udplite = IS_UDPLITE(sk); |
1127 | + bool slow; | |
1126 | 1128 | |
1127 | 1129 | /* |
1128 | 1130 | * Check any passed addresses |
1129 | 1131 | |
... | ... | @@ -1197,10 +1199,10 @@ |
1197 | 1199 | return err; |
1198 | 1200 | |
1199 | 1201 | csum_copy_err: |
1200 | - lock_sock_bh(sk); | |
1202 | + slow = lock_sock_fast(sk); | |
1201 | 1203 | if (!skb_kill_datagram(sk, skb, flags)) |
1202 | 1204 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
1203 | - unlock_sock_bh(sk); | |
1205 | + unlock_sock_fast(sk, slow); | |
1204 | 1206 | |
1205 | 1207 | if (noblock) |
1206 | 1208 | return -EAGAIN; |
1207 | 1209 | |
... | ... | @@ -1625,9 +1627,9 @@ |
1625 | 1627 | |
1626 | 1628 | void udp_destroy_sock(struct sock *sk) |
1627 | 1629 | { |
1628 | - lock_sock_bh(sk); | |
1630 | + bool slow = lock_sock_fast(sk); | |
1629 | 1631 | udp_flush_pending_frames(sk); |
1630 | - unlock_sock_bh(sk); | |
1632 | + unlock_sock_fast(sk, slow); | |
1631 | 1633 | } |
1632 | 1634 | |
1633 | 1635 | /* |
net/ipv6/ip6_output.c
... | ... | @@ -507,7 +507,7 @@ |
507 | 507 | if (mtu < IPV6_MIN_MTU) |
508 | 508 | mtu = IPV6_MIN_MTU; |
509 | 509 | |
510 | - if (skb->len > mtu) { | |
510 | + if (skb->len > mtu && !skb_is_gso(skb)) { | |
511 | 511 | /* Again, force OUTPUT device used as source address */ |
512 | 512 | skb->dev = dst->dev; |
513 | 513 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
net/ipv6/ip6mr.c
... | ... | @@ -2017,7 +2017,7 @@ |
2017 | 2017 | struct rtattr *mp_head; |
2018 | 2018 | |
2019 | 2019 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
2020 | - if (c->mf6c_parent > MAXMIFS) | |
2020 | + if (c->mf6c_parent >= MAXMIFS) | |
2021 | 2021 | return -ENOENT; |
2022 | 2022 | |
2023 | 2023 | if (MIF_EXISTS(mrt, c->mf6c_parent)) |
net/ipv6/udp.c
... | ... | @@ -328,6 +328,7 @@ |
328 | 328 | int err; |
329 | 329 | int is_udplite = IS_UDPLITE(sk); |
330 | 330 | int is_udp4; |
331 | + bool slow; | |
331 | 332 | |
332 | 333 | if (addr_len) |
333 | 334 | *addr_len=sizeof(struct sockaddr_in6); |
... | ... | @@ -424,7 +425,7 @@ |
424 | 425 | return err; |
425 | 426 | |
426 | 427 | csum_copy_err: |
427 | - lock_sock_bh(sk); | |
428 | + slow = lock_sock_fast(sk); | |
428 | 429 | if (!skb_kill_datagram(sk, skb, flags)) { |
429 | 430 | if (is_udp4) |
430 | 431 | UDP_INC_STATS_USER(sock_net(sk), |
... | ... | @@ -433,7 +434,7 @@ |
433 | 434 | UDP6_INC_STATS_USER(sock_net(sk), |
434 | 435 | UDP_MIB_INERRORS, is_udplite); |
435 | 436 | } |
436 | - unlock_sock_bh(sk); | |
437 | + unlock_sock_fast(sk, slow); | |
437 | 438 | |
438 | 439 | if (flags & MSG_DONTWAIT) |
439 | 440 | return -EAGAIN; |
net/iucv/af_iucv.c
net/netfilter/xt_TEE.c
... | ... | @@ -76,7 +76,7 @@ |
76 | 76 | if (ip_route_output_key(net, &rt, &fl) != 0) |
77 | 77 | return false; |
78 | 78 | |
79 | - dst_release(skb_dst(skb)); | |
79 | + skb_dst_drop(skb); | |
80 | 80 | skb_dst_set(skb, &rt->u.dst); |
81 | 81 | skb->dev = rt->u.dst.dev; |
82 | 82 | skb->protocol = htons(ETH_P_IP); |
... | ... | @@ -157,7 +157,7 @@ |
157 | 157 | if (dst == NULL) |
158 | 158 | return false; |
159 | 159 | |
160 | - dst_release(skb_dst(skb)); | |
160 | + skb_dst_drop(skb); | |
161 | 161 | skb_dst_set(skb, dst); |
162 | 162 | skb->dev = dst->dev; |
163 | 163 | skb->protocol = htons(ETH_P_IPV6); |