Pull networking fixes from David Miller: "Several smallish fixes, I don't think any of this requires another -rc but I'll leave that up to you: 1) Don't leak uninitialzed bytes to userspace in xfrm_user, from Eric Dumazet. 2) Route leak in xfrm_lookup_route(), from Tommi Rantala. 3) Premature poll() returns in AF_XDP, from Björn Töpel. 4) devlink leak in netdevsim, from Jakub Kicinski. 5) Don't BUG_ON in fib_compute_spec_dst, the condition can legitimately happen. From Lorenzo Bianconi. 6) Fix some spectre v1 gadgets in generic socket code, from Jeremy Cline. 7) Don't allow user to bind to out of range multicast groups, from Dmitry Safonov with a follow-up by Dmitry Safonov. 8) Fix metrics leak in fib6_drop_pcpu_from(), from Sabrina Dubroca" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (41 commits) netlink: Don't shift with UB on nlk->ngroups net/ipv6: fix metrics leak xen-netfront: wait xenbus state change when load module manually can: ems_usb: Fix memory leak on ems_usb_disconnect() openvswitch: meter: Fix setting meter id for new entries netlink: Do not subscribe to non-existent groups NET: stmmac: align DMA stuff to largest cache line length tcp_bbr: fix bw probing to raise in-flight data for very small BDPs net: socket: Fix potential spectre v1 gadget in sock_is_registered net: socket: fix potential spectre v1 gadget in socketcall net: mdio-mux: bcm-iproc: fix wrong getter and setter pair ipv4: remove BUG_ON() from fib_compute_spec_dst enic: handle mtu change for vf properly net: lan78xx: fix rx handling before first packet is send nfp: flower: fix port metadata conversion bug bpf: use GFP_ATOMIC instead of GFP_KERNEL in bpf_parse_prog() bpf: fix bpf_skb_load_bytes_relative pkt length check perf build: Build error in libbpf missing initialization net: ena: Fix use of uninitialized DMA address bits field bpf: btf: Use exact btf value_size match in map_check_btf() ...
Unified · Split
| @@ -1441,8 +1441,8 @@ static void emit_prologue(u8 **pprog, u32 stack_depth) · 1440 unmodified lines | ||
| 1441 | 1441 | |
| 1442 | 1442 | /* sub esp,STACK_SIZE */ |
| 1443 | 1443 | EMIT2_off32(0x81, 0xEC, STACK_SIZE); |
| 1444 | − /* sub ebp,SCRATCH_SIZE+4+12*/ | |
| 1445 | − EMIT3(0x83, add_1reg(0xE8, IA32_EBP), SCRATCH_SIZE + 16); | |
| 1444 | + /* sub ebp,SCRATCH_SIZE+12*/ | |
| 1445 | + EMIT3(0x83, add_1reg(0xE8, IA32_EBP), SCRATCH_SIZE + 12); | |
| 1446 | 1446 | /* xor ebx,ebx */ |
| 1447 | 1447 | EMIT2(0x31, add_2reg(0xC0, IA32_EBX, IA32_EBX)); |
| 1448 | 1448 | |
| @@ -1475,8 +1475,8 @@ static void emit_epilogue(u8 **pprog, u32 stack_depth) · 26 unmodified lines | ||
| 1475 | 1475 | /* mov edx,dword ptr [ebp+off]*/ |
| 1476 | 1476 | EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EDX), STACK_VAR(r0[1])); |
| 1477 | 1477 | |
| 1478 | − /* add ebp,SCRATCH_SIZE+4+12*/ | |
| 1479 | − EMIT3(0x83, add_1reg(0xC0, IA32_EBP), SCRATCH_SIZE + 16); | |
| 1478 | + /* add ebp,SCRATCH_SIZE+12*/ | |
| 1479 | + EMIT3(0x83, add_1reg(0xC0, IA32_EBP), SCRATCH_SIZE + 12); | |
| 1480 | 1480 | |
| 1481 | 1481 | /* mov ebx,dword ptr [ebp-12]*/ |
| 1482 | 1482 | EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EBX), -12); |
| @@ -1072,6 +1072,7 @@ static void ems_usb_disconnect(struct usb_interface *intf) · 1071 unmodified lines | ||
| 1072 | 1072 | usb_free_urb(dev->intr_urb); |
| 1073 | 1073 | |
| 1074 | 1074 | kfree(dev->intr_in_buffer); |
| 1075 | + kfree(dev->tx_msg_buffer); | |
| 1075 | 1076 | } |
| 1076 | 1077 | } |
| 1077 | 1078 | |
| @@ -333,6 +333,7 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev, · 332 unmodified lines | ||
| 333 | 333 | |
| 334 | 334 | memset(&io_sq->desc_addr, 0x0, sizeof(io_sq->desc_addr)); |
| 335 | 335 | |
| 336 | + io_sq->dma_addr_bits = ena_dev->dma_addr_bits; | |
| 336 | 337 | io_sq->desc_entry_size = |
| 337 | 338 | (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ? |
| 338 | 339 | sizeof(struct ena_eth_io_tx_desc) : |
| @@ -1111,14 +1111,14 @@ static void xgbe_phy_adjust_link(struct xgbe_prv_data *pdata) · 1110 unmodified lines | ||
| 1111 | 1111 | |
| 1112 | 1112 | if (pdata->tx_pause != pdata->phy.tx_pause) { |
| 1113 | 1113 | new_state = 1; |
| 1114 | − pdata->hw_if.config_tx_flow_control(pdata); | |
| 1115 | 1114 | pdata->tx_pause = pdata->phy.tx_pause; |
| 1115 | + pdata->hw_if.config_tx_flow_control(pdata); | |
| 1116 | 1116 | } |
| 1117 | 1117 | |
| 1118 | 1118 | if (pdata->rx_pause != pdata->phy.rx_pause) { |
| 1119 | 1119 | new_state = 1; |
| 1120 | − pdata->hw_if.config_rx_flow_control(pdata); | |
| 1121 | 1120 | pdata->rx_pause = pdata->phy.rx_pause; |
| 1121 | + pdata->hw_if.config_rx_flow_control(pdata); | |
| 1122 | 1122 | } |
| 1123 | 1123 | |
| 1124 | 1124 | /* Speed support */ |
| @@ -3072,6 +3072,7 @@ static void cxgb_del_udp_tunnel(struct net_device *netdev, · 3071 unmodified lines | ||
| 3072 | 3072 | |
| 3073 | 3073 | adapter->geneve_port = 0; |
| 3074 | 3074 | t4_write_reg(adapter, MPS_RX_GENEVE_TYPE_A, 0); |
| 3075 | + break; | |
| 3075 | 3076 | default: |
| 3076 | 3077 | return; |
| 3077 | 3078 | } |
| @@ -3157,6 +3158,7 @@ static void cxgb_add_udp_tunnel(struct net_device *netdev, · 79 unmodified lines | ||
| 3157 | 3158 | |
| 3158 | 3159 | t4_write_reg(adapter, MPS_RX_GENEVE_TYPE_A, |
| 3159 | 3160 | GENEVE_V(be16_to_cpu(ti->port)) | GENEVE_EN_F); |
| 3161 | + break; | |
| 3160 | 3162 | default: |
| 3161 | 3163 | return; |
| 3162 | 3164 | } |
| @@ -2047,28 +2047,42 @@ static int enic_stop(struct net_device *netdev) · 2046 unmodified lines | ||
| 2047 | 2047 | return 0; |
| 2048 | 2048 | } |
| 2049 | 2049 | |
| 2050 | +static int _enic_change_mtu(struct net_device *netdev, int new_mtu) | |
| 2051 | +{ | |
| 2052 | + bool running = netif_running(netdev); | |
| 2053 | + int err = 0; | |
| 2054 | + | |
| 2055 | + ASSERT_RTNL(); | |
| 2056 | + if (running) { | |
| 2057 | + err = enic_stop(netdev); | |
| 2058 | + if (err) | |
| 2059 | + return err; | |
| 2060 | + } | |
| 2061 | + | |
| 2062 | + netdev->mtu = new_mtu; | |
| 2063 | + | |
| 2064 | + if (running) { | |
| 2065 | + err = enic_open(netdev); | |
| 2066 | + if (err) | |
| 2067 | + return err; | |
| 2068 | + } | |
| 2069 | + | |
| 2070 | + return 0; | |
| 2071 | +} | |
| 2072 | + | |
| 2050 | 2073 | static int enic_change_mtu(struct net_device *netdev, int new_mtu) |
| 2051 | 2074 | { |
| 2052 | 2075 | struct enic *enic = netdev_priv(netdev); |
| 2053 | − int running = netif_running(netdev); | |
| 2054 | 2076 | |
| 2055 | 2077 | if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic)) |
| 2056 | 2078 | return -EOPNOTSUPP; |
| 2057 | 2079 | |
| 2058 | − if (running) | |
| 2059 | − enic_stop(netdev); | |
| 2060 | − | |
| 2061 | − netdev->mtu = new_mtu; | |
| 2062 | − | |
| 2063 | 2080 | if (netdev->mtu > enic->port_mtu) |
| 2064 | 2081 | netdev_warn(netdev, |
| 2065 | − "interface MTU (%d) set higher than port MTU (%d)\n", | |
| 2066 | − netdev->mtu, enic->port_mtu); | |
| 2082 | + "interface MTU (%d) set higher than port MTU (%d)\n", | |
| 2083 | + netdev->mtu, enic->port_mtu); | |
| 2067 | 2084 | |
| 2068 | − if (running) | |
| 2069 | − enic_open(netdev); | |
| 2070 | − | |
| 2071 | − return 0; | |
| 2085 | + return _enic_change_mtu(netdev, new_mtu); | |
| 2072 | 2086 | } |
| 2073 | 2087 | |
| 2074 | 2088 | static void enic_change_mtu_work(struct work_struct *work) |
| @@ -2076,47 +2090,9 @@ static void enic_change_mtu_work(struct work_struct *work) · 1 unmodified line | ||
| 2076 | 2090 | struct enic *enic = container_of(work, struct enic, change_mtu_work); |
| 2077 | 2091 | struct net_device *netdev = enic->netdev; |
| 2078 | 2092 | int new_mtu = vnic_dev_mtu(enic->vdev); |
| 2079 | − int err; | |
| 2080 | − unsigned int i; | |
| 2081 | − | |
| 2082 | − new_mtu = max_t(int, ENIC_MIN_MTU, min_t(int, ENIC_MAX_MTU, new_mtu)); | |
| 2083 | 2093 | |
| 2084 | 2094 | rtnl_lock(); |
| 2085 | − | |
| 2086 | − /* Stop RQ */ | |
| 2087 | − del_timer_sync(&enic->notify_timer); | |
| 2088 | − | |
| 2089 | − for (i = 0; i < enic->rq_count; i++) | |
| 2090 | − napi_disable(&enic->napi[i]); | |
| 2091 | − | |
| 2092 | − vnic_intr_mask(&enic->intr[0]); | |
| 2093 | − enic_synchronize_irqs(enic); | |
| 2094 | − err = vnic_rq_disable(&enic->rq[0]); | |
| 2095 | − if (err) { | |
| 2096 | − rtnl_unlock(); | |
| 2097 | − netdev_err(netdev, "Unable to disable RQ.\n"); | |
| 2098 | − return; | |
| 2099 | − } | |
| 2100 | − vnic_rq_clean(&enic->rq[0], enic_free_rq_buf); | |
| 2101 | − vnic_cq_clean(&enic->cq[0]); | |
| 2102 | − vnic_intr_clean(&enic->intr[0]); | |
| 2103 | − | |
| 2104 | − /* Fill RQ with new_mtu-sized buffers */ | |
| 2105 | − netdev->mtu = new_mtu; | |
| 2106 | − vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf); | |
| 2107 | − /* Need at least one buffer on ring to get going */ | |
| 2108 | − if (vnic_rq_desc_used(&enic->rq[0]) == 0) { | |
| 2109 | − rtnl_unlock(); | |
| 2110 | − netdev_err(netdev, "Unable to alloc receive buffers.\n"); | |
| 2111 | − return; | |
| 2112 | − } | |
| 2113 | − | |
| 2114 | − /* Start RQ */ | |
| 2115 | − vnic_rq_enable(&enic->rq[0]); | |
| 2116 | − napi_enable(&enic->napi[0]); | |
| 2117 | − vnic_intr_unmask(&enic->intr[0]); | |
| 2118 | − enic_notify_timer_start(enic); | |
| 2119 | − | |
| 2095 | + (void)_enic_change_mtu(netdev, new_mtu); | |
| 2120 | 2096 | rtnl_unlock(); |
| 2121 | 2097 | |
| 2122 | 2098 | netdev_info(netdev, "interface MTU set as %d\n", netdev->mtu); |
| @@ -983,6 +983,7 @@ static int nic_dev_init(struct pci_dev *pdev) · 982 unmodified lines | ||
| 983 | 983 | hinic_hwdev_cb_register(nic_dev->hwdev, HINIC_MGMT_MSG_CMD_LINK_STATUS, |
| 984 | 984 | nic_dev, link_status_event_handler); |
| 985 | 985 | |
| 986 | + SET_NETDEV_DEV(netdev, &pdev->dev); | |
| 986 | 987 | err = register_netdev(netdev); |
| 987 | 988 | if (err) { |
| 988 | 989 | dev_err(&pdev->dev, "Failed to register netdev\n"); |
| @@ -80,7 +80,7 @@ nfp_flower_repr_get_type_and_port(struct nfp_app *app, u32 port_id, u8 *port) · 79 unmodified lines | ||
| 80 | 80 | return NFP_REPR_TYPE_VF; |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | − return NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC; | |
| 83 | + return __NFP_REPR_TYPE_MAX; | |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | 86 | static struct net_device * |
| @@ -91,6 +91,8 @@ nfp_flower_repr_get(struct nfp_app *app, u32 port_id) · 4 unmodified lines | ||
| 91 | 91 | u8 port = 0; |
| 92 | 92 | |
| 93 | 93 | repr_type = nfp_flower_repr_get_type_and_port(app, port_id, &port); |
| 94 | + if (repr_type > NFP_REPR_TYPE_MAX) | |
| 95 | + return NULL; | |
| 94 | 96 | |
| 95 | 97 | reprs = rcu_dereference(app->reprs[repr_type]); |
| 96 | 98 | if (!reprs) |
| @@ -53,7 +53,7 @@ · 52 unmodified lines | ||
| 53 | 53 | #include "dwmac1000.h" |
| 54 | 54 | #include "hwif.h" |
| 55 | 55 | |
| 56 | −#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) | |
| 56 | +#define STMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES) | |
| 57 | 57 | #define TSO_MAX_BUFF_SIZE (SZ_16K - 1) |
| 58 | 58 | |
| 59 | 59 | /* Module parameters */ |
| @@ -207,6 +207,7 @@ void nsim_devlink_teardown(struct netdevsim *ns) · 206 unmodified lines | ||
| 207 | 207 | struct net *net = nsim_to_net(ns); |
| 208 | 208 | bool *reg_devlink = net_generic(net, nsim_devlink_id); |
| 209 | 209 | |
| 210 | + devlink_resources_unregister(ns->devlink, NULL); | |
| 210 | 211 | devlink_unregister(ns->devlink); |
| 211 | 212 | devlink_free(ns->devlink); |
| 212 | 213 | ns->devlink = NULL; |
| @@ -218,7 +218,7 @@ out: · 217 unmodified lines | ||
| 218 | 218 | |
| 219 | 219 | static int mdio_mux_iproc_remove(struct platform_device *pdev) |
| 220 | 220 | { |
| 221 | − struct iproc_mdiomux_desc *md = dev_get_platdata(&pdev->dev); | |
| 221 | + struct iproc_mdiomux_desc *md = platform_get_drvdata(pdev); | |
| 222 | 222 | |
| 223 | 223 | mdio_mux_uninit(md->mux_handle); |
| 224 | 224 | mdiobus_unregister(md->mii_bus); |
| @@ -1242,6 +1242,8 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) · 1241 unmodified lines | ||
| 1242 | 1242 | mod_timer(&dev->stat_monitor, |
| 1243 | 1243 | jiffies + STAT_UPDATE_TIMER); |
| 1244 | 1244 | } |
| 1245 | + | |
| 1246 | + tasklet_schedule(&dev->bh); | |
| 1245 | 1247 | } |
| 1246 | 1248 | |
| 1247 | 1249 | return ret; |
| @@ -586,7 +586,8 @@ static struct sk_buff *receive_small(struct net_device *dev, · 585 unmodified lines | ||
| 586 | 586 | struct receive_queue *rq, |
| 587 | 587 | void *buf, void *ctx, |
| 588 | 588 | unsigned int len, |
| 589 | − unsigned int *xdp_xmit) | |
| 589 | + unsigned int *xdp_xmit, | |
| 590 | + unsigned int *rbytes) | |
| 590 | 591 | { |
| 591 | 592 | struct sk_buff *skb; |
| 592 | 593 | struct bpf_prog *xdp_prog; |
| @@ -601,6 +602,7 @@ static struct sk_buff *receive_small(struct net_device *dev, · 8 unmodified lines | ||
| 601 | 602 | int err; |
| 602 | 603 | |
| 603 | 604 | len -= vi->hdr_len; |
| 605 | + *rbytes += len; | |
| 604 | 606 | |
| 605 | 607 | rcu_read_lock(); |
| 606 | 608 | xdp_prog = rcu_dereference(rq->xdp_prog); |
| @@ -705,11 +707,13 @@ static struct sk_buff *receive_big(struct net_device *dev, · 98 unmodified lines | ||
| 705 | 707 | struct virtnet_info *vi, |
| 706 | 708 | struct receive_queue *rq, |
| 707 | 709 | void *buf, |
| 708 | − unsigned int len) | |
| 710 | + unsigned int len, | |
| 711 | + unsigned int *rbytes) | |
| 709 | 712 | { |
| 710 | 713 | struct page *page = buf; |
| 711 | 714 | struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE); |
| 712 | 715 | |
| 716 | + *rbytes += len - vi->hdr_len; | |
| 713 | 717 | if (unlikely(!skb)) |
| 714 | 718 | goto err; |
| 715 | 719 | |
| @@ -727,7 +731,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, · 11 unmodified lines | ||
| 727 | 731 | void *buf, |
| 728 | 732 | void *ctx, |
| 729 | 733 | unsigned int len, |
| 730 | − unsigned int *xdp_xmit) | |
| 734 | + unsigned int *xdp_xmit, | |
| 735 | + unsigned int *rbytes) | |
| 731 | 736 | { |
| 732 | 737 | struct virtio_net_hdr_mrg_rxbuf *hdr = buf; |
| 733 | 738 | u16 num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers); |
| @@ -740,6 +745,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, · 6 unmodified lines | ||
| 740 | 745 | int err; |
| 741 | 746 | |
| 742 | 747 | head_skb = NULL; |
| 748 | + *rbytes += len - vi->hdr_len; | |
| 743 | 749 | |
| 744 | 750 | rcu_read_lock(); |
| 745 | 751 | xdp_prog = rcu_dereference(rq->xdp_prog); |
| @@ -877,6 +883,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, · 131 unmodified lines | ||
| 877 | 883 | goto err_buf; |
| 878 | 884 | } |
| 879 | 885 | |
| 886 | + *rbytes += len; | |
| 880 | 887 | page = virt_to_head_page(buf); |
| 881 | 888 | |
| 882 | 889 | truesize = mergeable_ctx_to_truesize(ctx); |
| @@ -932,6 +939,7 @@ err_skb: · 49 unmodified lines | ||
| 932 | 939 | dev->stats.rx_length_errors++; |
| 933 | 940 | break; |
| 934 | 941 | } |
| 942 | + *rbytes += len; | |
| 935 | 943 | page = virt_to_head_page(buf); |
| 936 | 944 | put_page(page); |
| 937 | 945 | } |
| @@ -942,14 +950,13 @@ xdp_xmit: · 4 unmodified lines | ||
| 942 | 950 | return NULL; |
| 943 | 951 | } |
| 944 | 952 | |
| 945 | −static int receive_buf(struct virtnet_info *vi, struct receive_queue *rq, | |
| 946 | − void *buf, unsigned int len, void **ctx, | |
| 947 | − unsigned int *xdp_xmit) | |
| 953 | +static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, | |
| 954 | + void *buf, unsigned int len, void **ctx, | |
| 955 | + unsigned int *xdp_xmit, unsigned int *rbytes) | |
| 948 | 956 | { |
| 949 | 957 | struct net_device *dev = vi->dev; |
| 950 | 958 | struct sk_buff *skb; |
| 951 | 959 | struct virtio_net_hdr_mrg_rxbuf *hdr; |
| 952 | − int ret; | |
| 953 | 960 | |
| 954 | 961 | if (unlikely(len < vi->hdr_len + ETH_HLEN)) { |
| 955 | 962 | pr_debug("%s: short packet %i\n", dev->name, len); |
| @@ -961,23 +968,22 @@ static int receive_buf(struct virtnet_info *vi, struct receive_queue *rq, · 5 unmodified lines | ||
| 961 | 968 | } else { |
| 962 | 969 | put_page(virt_to_head_page(buf)); |
| 963 | 970 | } |
| 964 | − return 0; | |
| 971 | + return; | |
| 965 | 972 | } |
| 966 | 973 | |
| 967 | 974 | if (vi->mergeable_rx_bufs) |
| 968 | − skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit); | |
| 975 | + skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit, | |
| 976 | + rbytes); | |
| 969 | 977 | else if (vi->big_packets) |
| 970 | − skb = receive_big(dev, vi, rq, buf, len); | |
| 978 | + skb = receive_big(dev, vi, rq, buf, len, rbytes); | |
| 971 | 979 | else |
| 972 | − skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit); | |
| 980 | + skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit, rbytes); | |
| 973 | 981 | |
| 974 | 982 | if (unlikely(!skb)) |
| 975 | − return 0; | |
| 983 | + return; | |
| 976 | 984 | |
| 977 | 985 | hdr = skb_vnet_hdr(skb); |
| 978 | 986 | |
| 979 | − ret = skb->len; | |
| 980 | − | |
| 981 | 987 | if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID) |
| 982 | 988 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 983 | 989 | |
| @@ -994,12 +1000,11 @@ static int receive_buf(struct virtnet_info *vi, struct receive_queue *rq, · 10 unmodified lines | ||
| 994 | 1000 | ntohs(skb->protocol), skb->len, skb->pkt_type); |
| 995 | 1001 | |
| 996 | 1002 | napi_gro_receive(&rq->napi, skb); |
| 997 | − return ret; | |
| 1003 | + return; | |
| 998 | 1004 | |
| 999 | 1005 | frame_err: |
| 1000 | 1006 | dev->stats.rx_frame_errors++; |
| 1001 | 1007 | dev_kfree_skb(skb); |
| 1002 | − return 0; | |
| 1003 | 1008 | } |
| 1004 | 1009 | |
| 1005 | 1010 | /* Unlike mergeable buffers, all buffers are allocated to the |
| @@ -1249,13 +1254,13 @@ static int virtnet_receive(struct receive_queue *rq, int budget, · 243 unmodified lines | ||
| 1249 | 1254 | |
| 1250 | 1255 | while (received < budget && |
| 1251 | 1256 | (buf = virtqueue_get_buf_ctx(rq->vq, &len, &ctx))) { |
| 1252 | − bytes += receive_buf(vi, rq, buf, len, ctx, xdp_xmit); | |
| 1257 | + receive_buf(vi, rq, buf, len, ctx, xdp_xmit, &bytes); | |
| 1253 | 1258 | received++; |
| 1254 | 1259 | } |
| 1255 | 1260 | } else { |
| 1256 | 1261 | while (received < budget && |
| 1257 | 1262 | (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { |
| 1258 | − bytes += receive_buf(vi, rq, buf, len, NULL, xdp_xmit); | |
| 1263 | + receive_buf(vi, rq, buf, len, NULL, xdp_xmit, &bytes); | |
| 1259 | 1264 | received++; |
| 1260 | 1265 | } |
| 1261 | 1266 | } |
| @@ -87,6 +87,7 @@ struct netfront_cb { · 86 unmodified lines | ||
| 87 | 87 | /* IRQ name is queue name with "-tx" or "-rx" appended */ |
| 88 | 88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) |
| 89 | 89 | |
| 90 | +static DECLARE_WAIT_QUEUE_HEAD(module_load_q); | |
| 90 | 91 | static DECLARE_WAIT_QUEUE_HEAD(module_unload_q); |
| 91 | 92 | |
| 92 | 93 | struct netfront_stats { |
| @@ -1330,6 +1331,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) · 1237 unmodified lines | ||
| 1330 | 1331 | netif_carrier_off(netdev); |
| 1331 | 1332 | |
| 1332 | 1333 | xenbus_switch_state(dev, XenbusStateInitialising); |
| 1334 | + wait_event(module_load_q, | |
| 1335 | + xenbus_read_driver_state(dev->otherend) != | |
| 1336 | + XenbusStateClosed && | |
| 1337 | + xenbus_read_driver_state(dev->otherend) != | |
| 1338 | + XenbusStateUnknown); | |
| 1333 | 1339 | return netdev; |
| 1334 | 1340 | |
| 1335 | 1341 | exit: |
| @@ -378,7 +378,7 @@ static int array_map_check_btf(const struct bpf_map *map, const struct btf *btf, · 377 unmodified lines | ||
| 378 | 378 | return -EINVAL; |
| 379 | 379 | |
| 380 | 380 | value_type = btf_type_id_size(btf, &btf_value_id, &value_size); |
| 381 | − if (!value_type || value_size > map->value_size) | |
| 381 | + if (!value_type || value_size != map->value_size) | |
| 382 | 382 | return -EINVAL; |
| 383 | 383 | |
| 384 | 384 | return 0; |
| @@ -1519,9 +1519,9 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, · 1518 unmodified lines | ||
| 1519 | 1519 | { |
| 1520 | 1520 | bool is_union = BTF_INFO_KIND(t->info) == BTF_KIND_UNION; |
| 1521 | 1521 | const struct btf_member *member; |
| 1522 | + u32 meta_needed, last_offset; | |
| 1522 | 1523 | struct btf *btf = env->btf; |
| 1523 | 1524 | u32 struct_size = t->size; |
| 1524 | − u32 meta_needed; | |
| 1525 | 1525 | u16 i; |
| 1526 | 1526 | |
| 1527 | 1527 | meta_needed = btf_type_vlen(t) * sizeof(*member); |
| @@ -1534,6 +1534,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, · 6 unmodified lines | ||
| 1534 | 1534 | |
| 1535 | 1535 | btf_verifier_log_type(env, t, NULL); |
| 1536 | 1536 | |
| 1537 | + last_offset = 0; | |
| 1537 | 1538 | for_each_member(i, t, member) { |
| 1538 | 1539 | if (!btf_name_offset_valid(btf, member->name_off)) { |
| 1539 | 1540 | btf_verifier_log_member(env, t, member, |
| @@ -1555,6 +1556,16 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, · 15 unmodified lines | ||
| 1555 | 1556 | return -EINVAL; |
| 1556 | 1557 | } |
| 1557 | 1558 | |
| 1559 | + /* | |
| 1560 | + * ">" instead of ">=" because the last member could be | |
| 1561 | + * "char a[0];" | |
| 1562 | + */ | |
| 1563 | + if (last_offset > member->offset) { | |
| 1564 | + btf_verifier_log_member(env, t, member, | |
| 1565 | + "Invalid member bits_offset"); | |
| 1566 | + return -EINVAL; | |
| 1567 | + } | |
| 1568 | + | |
| 1558 | 1569 | if (BITS_ROUNDUP_BYTES(member->offset) > struct_size) { |
| 1559 | 1570 | btf_verifier_log_member(env, t, member, |
| 1560 | 1571 | "Memmber bits_offset exceeds its struct size"); |
| @@ -1562,6 +1573,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, · 1 unmodified line | ||
| 1562 | 1573 | } |
| 1563 | 1574 | |
| 1564 | 1575 | btf_verifier_log_member(env, t, member, NULL); |
| 1576 | + last_offset = member->offset; | |
| 1565 | 1577 | } |
| 1566 | 1578 | |
| 1567 | 1579 | return meta_needed; |
| @@ -7149,16 +7149,19 @@ int dev_change_tx_queue_len(struct net_device *dev, unsigned long new_len) · 7148 unmodified lines | ||
| 7149 | 7149 | dev->tx_queue_len = new_len; |
| 7150 | 7150 | res = call_netdevice_notifiers(NETDEV_CHANGE_TX_QUEUE_LEN, dev); |
| 7151 | 7151 | res = notifier_to_errno(res); |
| 7152 | − if (res) { | |
| 7153 | − netdev_err(dev, | |
| 7154 | − "refused to change device tx_queue_len\n"); | |
| 7155 | − dev->tx_queue_len = orig_len; | |
| 7156 | − return res; | |
| 7157 | − } | |
| 7158 | − return dev_qdisc_change_tx_queue_len(dev); | |
| 7152 | + if (res) | |
| 7153 | + goto err_rollback; | |
| 7154 | + res = dev_qdisc_change_tx_queue_len(dev); | |
| 7155 | + if (res) | |
| 7156 | + goto err_rollback; | |
| 7159 | 7157 | } |
| 7160 | 7158 | |
| 7161 | 7159 | return 0; |
| 7160 | + | |
| 7161 | +err_rollback: | |
| 7162 | + netdev_err(dev, "refused to change device tx_queue_len\n"); | |
| 7163 | + dev->tx_queue_len = orig_len; | |
| 7164 | + return res; | |
| 7162 | 7165 | } |
| 7163 | 7166 | |
| 7164 | 7167 | /** |
| @@ -1712,24 +1712,26 @@ static const struct bpf_func_proto bpf_skb_load_bytes_proto = { · 1711 unmodified lines | ||
| 1712 | 1712 | BPF_CALL_5(bpf_skb_load_bytes_relative, const struct sk_buff *, skb, |
| 1713 | 1713 | u32, offset, void *, to, u32, len, u32, start_header) |
| 1714 | 1714 | { |
| 1715 | + u8 *end = skb_tail_pointer(skb); | |
| 1716 | + u8 *net = skb_network_header(skb); | |
| 1717 | + u8 *mac = skb_mac_header(skb); | |
| 1715 | 1718 | u8 *ptr; |
| 1716 | 1719 | |
| 1717 | − if (unlikely(offset > 0xffff || len > skb_headlen(skb))) | |
| 1720 | + if (unlikely(offset > 0xffff || len > (end - mac))) | |
| 1718 | 1721 | goto err_clear; |
| 1719 | 1722 | |
| 1720 | 1723 | switch (start_header) { |
| 1721 | 1724 | case BPF_HDR_START_MAC: |
| 1722 | − ptr = skb_mac_header(skb) + offset; | |
| 1725 | + ptr = mac + offset; | |
| 1723 | 1726 | break; |
| 1724 | 1727 | case BPF_HDR_START_NET: |
| 1725 | − ptr = skb_network_header(skb) + offset; | |
| 1728 | + ptr = net + offset; | |
| 1726 | 1729 | break; |
| 1727 | 1730 | default: |
| 1728 | 1731 | goto err_clear; |
| 1729 | 1732 | } |
| 1730 | 1733 | |
| 1731 | − if (likely(ptr >= skb_mac_header(skb) && | |
| 1732 | − ptr + len <= skb_tail_pointer(skb))) { | |
| 1734 | + if (likely(ptr >= mac && ptr + len <= end)) { | |
| 1733 | 1735 | memcpy(to, ptr, len); |
| 1734 | 1736 | return 0; |
| 1735 | 1737 | } |
| @@ -217,7 +217,7 @@ static int bpf_parse_prog(struct nlattr *attr, struct bpf_lwt_prog *prog, · 216 unmodified lines | ||
| 217 | 217 | if (!tb[LWT_BPF_PROG_FD] || !tb[LWT_BPF_PROG_NAME]) |
| 218 | 218 | return -EINVAL; |
| 219 | 219 | |
| 220 | − prog->name = nla_memdup(tb[LWT_BPF_PROG_NAME], GFP_KERNEL); | |
| 220 | + prog->name = nla_memdup(tb[LWT_BPF_PROG_NAME], GFP_ATOMIC); | |
| 221 | 221 | if (!prog->name) |
| 222 | 222 | return -ENOMEM; |
| 223 | 223 | |
| @@ -345,7 +345,8 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct, · 344 unmodified lines | ||
| 345 | 345 | rcu_read_lock(); |
| 346 | 346 | /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */ |
| 347 | 347 | xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); |
| 348 | − xa->zc_alloc->free(xa->zc_alloc, handle); | |
| 348 | + if (!WARN_ON_ONCE(!xa)) | |
| 349 | + xa->zc_alloc->free(xa->zc_alloc, handle); | |
| 349 | 350 | rcu_read_unlock(); |
| 350 | 351 | default: |
| 351 | 352 | /* Not possible, checked in xdp_rxq_info_reg_mem_model() */ |
| @@ -292,19 +292,19 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb) · 291 unmodified lines | ||
| 292 | 292 | return ip_hdr(skb)->daddr; |
| 293 | 293 | |
| 294 | 294 | in_dev = __in_dev_get_rcu(dev); |
| 295 | − BUG_ON(!in_dev); | |
| 296 | 295 | |
| 297 | 296 | net = dev_net(dev); |
| 298 | 297 | |
| 299 | 298 | scope = RT_SCOPE_UNIVERSE; |
| 300 | 299 | if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) { |
| 300 | + bool vmark = in_dev && IN_DEV_SRC_VMARK(in_dev); | |
| 301 | 301 | struct flowi4 fl4 = { |
| 302 | 302 | .flowi4_iif = LOOPBACK_IFINDEX, |
| 303 | 303 | .flowi4_oif = l3mdev_master_ifindex_rcu(dev), |
| 304 | 304 | .daddr = ip_hdr(skb)->saddr, |
| 305 | 305 | .flowi4_tos = RT_TOS(ip_hdr(skb)->tos), |
| 306 | 306 | .flowi4_scope = scope, |
| 307 | − .flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0, | |
| 307 | + .flowi4_mark = vmark ? skb->mark : 0, | |
| 308 | 308 | }; |
| 309 | 309 | if (!fib_lookup(net, &fl4, &res, 0)) |
| 310 | 310 | return FIB_RES_PREFSRC(net, res); |
| @@ -1387,7 +1387,8 @@ static void ip_mc_hash_remove(struct in_device *in_dev, · 1386 unmodified lines | ||
| 1387 | 1387 | /* |
| 1388 | 1388 | * A socket has joined a multicast group on device dev. |
| 1389 | 1389 | */ |
| 1390 | −void __ip_mc_inc_group(struct in_device *in_dev, __be32 addr, unsigned int mode) | |
| 1390 | +static void __ip_mc_inc_group(struct in_device *in_dev, __be32 addr, | |
| 1391 | + unsigned int mode) | |
| 1391 | 1392 | { |
| 1392 | 1393 | struct ip_mc_list *im; |
| 1393 | 1394 | #ifdef CONFIG_IP_MULTICAST |
| @@ -354,6 +354,10 @@ static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain) · 353 unmodified lines | ||
| 354 | 354 | /* Reduce delayed ACKs by rounding up cwnd to the next even number. */ |
| 355 | 355 | cwnd = (cwnd + 1) & ~1U; |
| 356 | 356 | |
| 357 | + /* Ensure gain cycling gets inflight above BDP even for small BDPs. */ | |
| 358 | + if (bbr->mode == BBR_PROBE_BW && gain > BBR_UNIT) | |
| 359 | + cwnd += 2; | |
| 360 | + | |
| 357 | 361 | return cwnd; |
| 358 | 362 | } |
| 359 | 363 | |
| @@ -246,8 +246,15 @@ static void tcp_ecn_queue_cwr(struct tcp_sock *tp) · 245 unmodified lines | ||
| 246 | 246 | |
| 247 | 247 | static void tcp_ecn_accept_cwr(struct tcp_sock *tp, const struct sk_buff *skb) |
| 248 | 248 | { |
| 249 | − if (tcp_hdr(skb)->cwr) | |
| 249 | + if (tcp_hdr(skb)->cwr) { | |
| 250 | 250 | tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; |
| 251 | + | |
| 252 | + /* If the sender is telling us it has entered CWR, then its | |
| 253 | + * cwnd may be very low (even just 1 packet), so we should ACK | |
| 254 | + * immediately. | |
| 255 | + */ | |
| 256 | + tcp_enter_quickack_mode((struct sock *)tp, 2); | |
| 257 | + } | |
| 251 | 258 | } |
| 252 | 259 | |
| 253 | 260 | static void tcp_ecn_withdraw_cwr(struct tcp_sock *tp) |
| @@ -669,8 +669,10 @@ skip_cow: · 668 unmodified lines | ||
| 669 | 669 | |
| 670 | 670 | sg_init_table(sg, nfrags); |
| 671 | 671 | ret = skb_to_sgvec(skb, sg, 0, skb->len); |
| 672 | − if (unlikely(ret < 0)) | |
| 672 | + if (unlikely(ret < 0)) { | |
| 673 | + kfree(tmp); | |
| 673 | 674 | goto out; |
| 675 | + } | |
| 674 | 676 | |
| 675 | 677 | skb->ip_summed = CHECKSUM_NONE; |
| 676 | 678 | |
| @@ -167,11 +167,22 @@ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags) · 166 unmodified lines | ||
| 167 | 167 | return f6i; |
| 168 | 168 | } |
| 169 | 169 | |
| 170 | +static void fib6_metrics_release(struct fib6_info *f6i) | |
| 171 | +{ | |
| 172 | + struct dst_metrics *m; | |
| 173 | + | |
| 174 | + if (!f6i) | |
| 175 | + return; | |
| 176 | + | |
| 177 | + m = f6i->fib6_metrics; | |
| 178 | + if (m != &dst_default_metrics && refcount_dec_and_test(&m->refcnt)) | |
| 179 | + kfree(m); | |
| 180 | +} | |
| 181 | + | |
| 170 | 182 | void fib6_info_destroy_rcu(struct rcu_head *head) |
| 171 | 183 | { |
| 172 | 184 | struct fib6_info *f6i = container_of(head, struct fib6_info, rcu); |
| 173 | 185 | struct rt6_exception_bucket *bucket; |
| 174 | − struct dst_metrics *m; | |
| 175 | 186 | |
| 176 | 187 | WARN_ON(f6i->fib6_node); |
| 177 | 188 | |
| @@ -201,9 +212,7 @@ void fib6_info_destroy_rcu(struct rcu_head *head) · 23 unmodified lines | ||
| 201 | 212 | if (f6i->fib6_nh.nh_dev) |
| 202 | 213 | dev_put(f6i->fib6_nh.nh_dev); |
| 203 | 214 | |
| 204 | − m = f6i->fib6_metrics; | |
| 205 | − if (m != &dst_default_metrics && refcount_dec_and_test(&m->refcnt)) | |
| 206 | − kfree(m); | |
| 215 | + fib6_metrics_release(f6i); | |
| 207 | 216 | |
| 208 | 217 | kfree(f6i); |
| 209 | 218 | } |
| @@ -887,6 +896,7 @@ static void fib6_drop_pcpu_from(struct fib6_info *f6i, · 677 unmodified lines | ||
| 887 | 896 | |
| 888 | 897 | from = rcu_dereference_protected(pcpu_rt->from, |
| 889 | 898 | lockdep_is_held(&table->tb6_lock)); |
| 899 | + fib6_metrics_release(from); | |
| 890 | 900 | rcu_assign_pointer(pcpu_rt->from, NULL); |
| 891 | 901 | fib6_info_release(from); |
| 892 | 902 | } |
| @@ -480,10 +480,6 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) · 479 unmodified lines | ||
| 480 | 480 | goto tx_err_dst_release; |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | − skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev))); | |
| 484 | − skb_dst_set(skb, dst); | |
| 485 | − skb->dev = skb_dst(skb)->dev; | |
| 486 | − | |
| 487 | 483 | mtu = dst_mtu(dst); |
| 488 | 484 | if (!skb->ignore_df && skb->len > mtu) { |
| 489 | 485 | skb_dst_update_pmtu(skb, mtu); |
| @@ -498,9 +494,14 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) · 8 unmodified lines | ||
| 498 | 494 | htonl(mtu)); |
| 499 | 495 | } |
| 500 | 496 | |
| 501 | − return -EMSGSIZE; | |
| 497 | + err = -EMSGSIZE; | |
| 498 | + goto tx_err_dst_release; | |
| 502 | 499 | } |
| 503 | 500 | |
| 501 | + skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev))); | |
| 502 | + skb_dst_set(skb, dst); | |
| 503 | + skb->dev = skb_dst(skb)->dev; | |
| 504 | + | |
| 504 | 505 | err = dst_output(t->net, skb->sk, skb); |
| 505 | 506 | if (net_xmit_eval(err) == 0) { |
| 506 | 507 | struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); |
| @@ -1009,6 +1009,11 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, · 1008 unmodified lines | ||
| 1009 | 1009 | return err; |
| 1010 | 1010 | } |
| 1011 | 1011 | |
| 1012 | + if (nlk->ngroups == 0) | |
| 1013 | + groups = 0; | |
| 1014 | + else | |
| 1015 | + groups &= (1ULL << nlk->ngroups) - 1; | |
| 1016 | + | |
| 1012 | 1017 | bound = nlk->bound; |
| 1013 | 1018 | if (bound) { |
| 1014 | 1019 | /* Ensure nlk->portid is up-to-date. */ |
| @@ -211,6 +211,7 @@ static struct dp_meter *dp_meter_create(struct nlattr **a) · 210 unmodified lines | ||
| 211 | 211 | if (!meter) |
| 212 | 212 | return ERR_PTR(-ENOMEM); |
| 213 | 213 | |
| 214 | + meter->id = nla_get_u32(a[OVS_METER_ATTR_ID]); | |
| 214 | 215 | meter->used = div_u64(ktime_get_ns(), 1000 * 1000); |
| 215 | 216 | meter->kbps = a[OVS_METER_ATTR_KBPS] ? 1 : 0; |
| 216 | 217 | meter->keep_stats = !a[OVS_METER_ATTR_CLEAR]; |
| @@ -280,6 +281,10 @@ static int ovs_meter_cmd_set(struct sk_buff *skb, struct genl_info *info) · 63 unmodified lines | ||
| 280 | 281 | u32 meter_id; |
| 281 | 282 | bool failed; |
| 282 | 283 | |
| 284 | + if (!a[OVS_METER_ATTR_ID]) { | |
| 285 | + return -ENODEV; | |
| 286 | + } | |
| 287 | + | |
| 283 | 288 | meter = dp_meter_create(a); |
| 284 | 289 | if (IS_ERR_OR_NULL(meter)) |
| 285 | 290 | return PTR_ERR(meter); |
| @@ -298,11 +303,6 @@ static int ovs_meter_cmd_set(struct sk_buff *skb, struct genl_info *info) · 12 unmodified lines | ||
| 298 | 303 | goto exit_unlock; |
| 299 | 304 | } |
| 300 | 305 | |
| 301 | − if (!a[OVS_METER_ATTR_ID]) { | |
| 302 | − err = -ENODEV; | |
| 303 | − goto exit_unlock; | |
| 304 | − } | |
| 305 | − | |
| 306 | 306 | meter_id = nla_get_u32(a[OVS_METER_ATTR_ID]); |
| 307 | 307 | |
| 308 | 308 | /* Cannot fail after this. */ |
| @@ -344,6 +344,11 @@ struct rds_ib_mr *rds_ib_reg_frmr(struct rds_ib_device *rds_ibdev, · 343 unmodified lines | ||
| 344 | 344 | struct rds_ib_frmr *frmr; |
| 345 | 345 | int ret; |
| 346 | 346 | |
| 347 | + if (!ic) { | |
| 348 | + /* TODO: Add FRWR support for RDS_GET_MR using proxy qp*/ | |
| 349 | + return ERR_PTR(-EOPNOTSUPP); | |
| 350 | + } | |
| 351 | + | |
| 347 | 352 | do { |
| 348 | 353 | if (ibmr) |
| 349 | 354 | rds_ib_free_frmr(ibmr, true); |
| @@ -115,7 +115,8 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, · 114 unmodified lines | ||
| 115 | 115 | struct rds_info_rdma_connection *iinfo); |
| 116 | 116 | void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *); |
| 117 | 117 | void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, |
| 118 | − struct rds_sock *rs, u32 *key_ret); | |
| 118 | + struct rds_sock *rs, u32 *key_ret, | |
| 119 | + struct rds_connection *conn); | |
| 119 | 120 | void rds_ib_sync_mr(void *trans_private, int dir); |
| 120 | 121 | void rds_ib_free_mr(void *trans_private, int invalidate); |
| 121 | 122 | void rds_ib_flush_mrs(void); |
| @@ -537,11 +537,12 @@ void rds_ib_flush_mrs(void) · 536 unmodified lines | ||
| 537 | 537 | } |
| 538 | 538 | |
| 539 | 539 | void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, |
| 540 | − struct rds_sock *rs, u32 *key_ret) | |
| 540 | + struct rds_sock *rs, u32 *key_ret, | |
| 541 | + struct rds_connection *conn) | |
| 541 | 542 | { |
| 542 | 543 | struct rds_ib_device *rds_ibdev; |
| 543 | 544 | struct rds_ib_mr *ibmr = NULL; |
| 544 | − struct rds_ib_connection *ic = rs->rs_conn->c_transport_data; | |
| 545 | + struct rds_ib_connection *ic = NULL; | |
| 545 | 546 | int ret; |
| 546 | 547 | |
| 547 | 548 | rds_ibdev = rds_ib_get_device(rs->rs_bound_addr); |
| @@ -550,6 +551,9 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, · 2 unmodified lines | ||
| 550 | 551 | goto out; |
| 551 | 552 | } |
| 552 | 553 | |
| 554 | + if (conn) | |
| 555 | + ic = conn->c_transport_data; | |
| 556 | + | |
| 553 | 557 | if (!rds_ibdev->mr_8k_pool || !rds_ibdev->mr_1m_pool) { |
| 554 | 558 | ret = -ENODEV; |
| 555 | 559 | goto out; |
| @@ -559,17 +563,18 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, · 3 unmodified lines | ||
| 559 | 563 | ibmr = rds_ib_reg_frmr(rds_ibdev, ic, sg, nents, key_ret); |
| 560 | 564 | else |
| 561 | 565 | ibmr = rds_ib_reg_fmr(rds_ibdev, sg, nents, key_ret); |
| 562 | − if (ibmr) | |
| 563 | − rds_ibdev = NULL; | |
| 564 | − | |
| 565 | − out: | |
| 566 | − if (!ibmr) | |
| 566 | + if (IS_ERR(ibmr)) { | |
| 567 | + ret = PTR_ERR(ibmr); | |
| 567 | 568 | pr_warn("RDS/IB: rds_ib_get_mr failed (errno=%d)\n", ret); |
| 569 | + } else { | |
| 570 | + return ibmr; | |
| 571 | + } | |
| 568 | 572 | |
| 573 | + out: | |
| 569 | 574 | if (rds_ibdev) |
| 570 | 575 | rds_ib_dev_put(rds_ibdev); |
| 571 | 576 | |
| 572 | − return ibmr; | |
| 577 | + return ERR_PTR(ret); | |
| 573 | 578 | } |
| 574 | 579 | |
| 575 | 580 | void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool) |
| @@ -170,7 +170,8 @@ static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages, · 169 unmodified lines | ||
| 170 | 170 | } |
| 171 | 171 | |
| 172 | 172 | static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, |
| 173 | − u64 *cookie_ret, struct rds_mr **mr_ret) | |
| 173 | + u64 *cookie_ret, struct rds_mr **mr_ret, | |
| 174 | + struct rds_conn_path *cp) | |
| 174 | 175 | { |
| 175 | 176 | struct rds_mr *mr = NULL, *found; |
| 176 | 177 | unsigned int nr_pages; |
| @@ -269,7 +270,8 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, · 92 unmodified lines | ||
| 269 | 270 | * Note that dma_map() implies that pending writes are |
| 270 | 271 | * flushed to RAM, so no dma_sync is needed here. */ |
| 271 | 272 | trans_private = rs->rs_transport->get_mr(sg, nents, rs, |
| 272 | − &mr->r_key); | |
| 273 | + &mr->r_key, | |
| 274 | + cp ? cp->cp_conn : NULL); | |
| 273 | 275 | |
| 274 | 276 | if (IS_ERR(trans_private)) { |
| 275 | 277 | for (i = 0 ; i < nents; i++) |
| @@ -330,7 +332,7 @@ int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen) · 54 unmodified lines | ||
| 330 | 332 | sizeof(struct rds_get_mr_args))) |
| 331 | 333 | return -EFAULT; |
| 332 | 334 | |
| 333 | − return __rds_rdma_map(rs, &args, NULL, NULL); | |
| 335 | + return __rds_rdma_map(rs, &args, NULL, NULL, NULL); | |
| 334 | 336 | } |
| 335 | 337 | |
| 336 | 338 | int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen) |
| @@ -354,7 +356,7 @@ int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen) · 17 unmodified lines | ||
| 354 | 356 | new_args.cookie_addr = args.cookie_addr; |
| 355 | 357 | new_args.flags = args.flags; |
| 356 | 358 | |
| 357 | − return __rds_rdma_map(rs, &new_args, NULL, NULL); | |
| 359 | + return __rds_rdma_map(rs, &new_args, NULL, NULL, NULL); | |
| 358 | 360 | } |
| 359 | 361 | |
| 360 | 362 | /* |
| @@ -782,7 +784,8 @@ int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, · 421 unmodified lines | ||
| 782 | 784 | rm->m_rdma_cookie != 0) |
| 783 | 785 | return -EINVAL; |
| 784 | 786 | |
| 785 | − return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->rdma.op_rdma_mr); | |
| 787 | + return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, | |
| 788 | + &rm->rdma.op_rdma_mr, rm->m_conn_path); | |
| 786 | 789 | } |
| 787 | 790 | |
| 788 | 791 | /* |
| @@ -464,6 +464,8 @@ struct rds_message { · 463 unmodified lines | ||
| 464 | 464 | struct scatterlist *op_sg; |
| 465 | 465 | } data; |
| 466 | 466 | }; |
| 467 | + | |
| 468 | + struct rds_conn_path *m_conn_path; | |
| 467 | 469 | }; |
| 468 | 470 | |
| 469 | 471 | /* |
| @@ -544,7 +546,8 @@ struct rds_transport { · 74 unmodified lines | ||
| 544 | 546 | unsigned int avail); |
| 545 | 547 | void (*exit)(void); |
| 546 | 548 | void *(*get_mr)(struct scatterlist *sg, unsigned long nr_sg, |
| 547 | − struct rds_sock *rs, u32 *key_ret); | |
| 549 | + struct rds_sock *rs, u32 *key_ret, | |
| 550 | + struct rds_connection *conn); | |
| 548 | 551 | void (*sync_mr)(void *trans_private, int direction); |
| 549 | 552 | void (*free_mr)(void *trans_private, int invalidate); |
| 550 | 553 | void (*flush_mrs)(void); |
| @@ -1169,6 +1169,13 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) · 1168 unmodified lines | ||
| 1169 | 1169 | rs->rs_conn = conn; |
| 1170 | 1170 | } |
| 1171 | 1171 | |
| 1172 | + if (conn->c_trans->t_mp_capable) | |
| 1173 | + cpath = &conn->c_path[rds_send_mprds_hash(rs, conn)]; | |
| 1174 | + else | |
| 1175 | + cpath = &conn->c_path[0]; | |
| 1176 | + | |
| 1177 | + rm->m_conn_path = cpath; | |
| 1178 | + | |
| 1172 | 1179 | /* Parse any control messages the user may have included. */ |
| 1173 | 1180 | ret = rds_cmsg_send(rs, rm, msg, &allocated_mr); |
| 1174 | 1181 | if (ret) { |
| @@ -1192,11 +1199,6 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) · 17 unmodified lines | ||
| 1192 | 1199 | goto out; |
| 1193 | 1200 | } |
| 1194 | 1201 | |
| 1195 | − if (conn->c_trans->t_mp_capable) | |
| 1196 | − cpath = &conn->c_path[rds_send_mprds_hash(rs, conn)]; | |
| 1197 | − else | |
| 1198 | − cpath = &conn->c_path[0]; | |
| 1199 | − | |
| 1200 | 1202 | if (rds_destroy_pending(conn)) { |
| 1201 | 1203 | ret = -EAGAIN; |
| 1202 | 1204 | goto out; |
| @@ -89,6 +89,7 @@ · 88 unmodified lines | ||
| 89 | 89 | #include <linux/magic.h> |
| 90 | 90 | #include <linux/slab.h> |
| 91 | 91 | #include <linux/xattr.h> |
| 92 | +#include <linux/nospec.h> | |
| 92 | 93 | |
| 93 | 94 | #include <linux/uaccess.h> |
| 94 | 95 | #include <asm/unistd.h> |
| @@ -2522,6 +2523,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) · 2427 unmodified lines | ||
| 2522 | 2523 | |
| 2523 | 2524 | if (call < 1 || call > SYS_SENDMMSG) |
| 2524 | 2525 | return -EINVAL; |
| 2526 | + call = array_index_nospec(call, SYS_SENDMMSG + 1); | |
| 2525 | 2527 | |
| 2526 | 2528 | len = nargs[call]; |
| 2527 | 2529 | if (len > sizeof(a)) |
| @@ -2688,7 +2690,8 @@ EXPORT_SYMBOL(sock_unregister); · 160 unmodified lines | ||
| 2688 | 2690 | |
| 2689 | 2691 | bool sock_is_registered(int family) |
| 2690 | 2692 | { |
| 2691 | − return family < NPROTO && rcu_access_pointer(net_families[family]); | |
| 2693 | + return family < NPROTO && | |
| 2694 | + rcu_access_pointer(net_families[array_index_nospec(family, NPROTO)]); | |
| 2692 | 2695 | } |
| 2693 | 2696 | |
| 2694 | 2697 | static int __init sock_init(void) |
| @@ -250,7 +250,7 @@ static inline bool xskq_full_desc(struct xsk_queue *q) · 249 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | static inline bool xskq_empty_desc(struct xsk_queue *q) |
| 252 | 252 | { |
| 253 | − return xskq_nb_free(q, q->prod_tail, 1) == q->nentries; | |
| 253 | + return xskq_nb_free(q, q->prod_tail, q->nentries) == q->nentries; | |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | 256 | void xskq_set_umem(struct xsk_queue *q, struct xdp_umem_props *umem_props); |
| @@ -2286,6 +2286,9 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, · 2285 unmodified lines | ||
| 2286 | 2286 | if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE) |
| 2287 | 2287 | return make_blackhole(net, dst_orig->ops->family, dst_orig); |
| 2288 | 2288 | |
| 2289 | + if (IS_ERR(dst)) | |
| 2290 | + dst_release(dst_orig); | |
| 2291 | + | |
| 2289 | 2292 | return dst; |
| 2290 | 2293 | } |
| 2291 | 2294 | EXPORT_SYMBOL(xfrm_lookup_route); |
| @@ -1025,10 +1025,12 @@ static inline int xfrm_nlmsg_multicast(struct net *net, struct sk_buff *skb, · 1024 unmodified lines | ||
| 1025 | 1025 | { |
| 1026 | 1026 | struct sock *nlsk = rcu_dereference(net->xfrm.nlsk); |
| 1027 | 1027 | |
| 1028 | − if (nlsk) | |
| 1029 | − return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC); | |
| 1030 | − else | |
| 1031 | − return -1; | |
| 1028 | + if (!nlsk) { | |
| 1029 | + kfree_skb(skb); | |
| 1030 | + return -EPIPE; | |
| 1031 | + } | |
| 1032 | + | |
| 1033 | + return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC); | |
| 1032 | 1034 | } |
| 1033 | 1035 | |
| 1034 | 1036 | static inline unsigned int xfrm_spdinfo_msgsize(void) |
| @@ -1671,9 +1673,11 @@ static inline unsigned int userpolicy_type_attrsize(void) · 636 unmodified lines | ||
| 1671 | 1673 | #ifdef CONFIG_XFRM_SUB_POLICY |
| 1672 | 1674 | static int copy_to_user_policy_type(u8 type, struct sk_buff *skb) |
| 1673 | 1675 | { |
| 1674 | − struct xfrm_userpolicy_type upt = { | |
| 1675 | − .type = type, | |
| 1676 | − }; | |
| 1676 | + struct xfrm_userpolicy_type upt; | |
| 1677 | + | |
| 1678 | + /* Sadly there are two holes in struct xfrm_userpolicy_type */ | |
| 1679 | + memset(&upt, 0, sizeof(upt)); | |
| 1680 | + upt.type = type; | |
| 1677 | 1681 | |
| 1678 | 1682 | return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt); |
| 1679 | 1683 | } |
| @@ -76,7 +76,7 @@ struct btf_type { · 75 unmodified lines | ||
| 76 | 76 | */ |
| 77 | 77 | #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) |
| 78 | 78 | #define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16) |
| 79 | −#define BTF_INT_BITS(VAL) ((VAL) & 0x0000ffff) | |
| 79 | +#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff) | |
| 80 | 80 | |
| 81 | 81 | /* Attributes stored in the BTF_INT_ENCODING */ |
| 82 | 82 | #define BTF_INT_SIGNED (1 << 0) |
| @@ -2,7 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | /* Copyright (c) 2018 Facebook */ |
| 3 | 3 | |
| 4 | 4 | #include <stdlib.h> |
| 5 | −#include <stdint.h> | |
| 6 | 5 | #include <string.h> |
| 7 | 6 | #include <unistd.h> |
| 8 | 7 | #include <errno.h> |
| @@ -27,13 +26,13 @@ struct btf { · 18 unmodified lines | ||
| 27 | 26 | struct btf_type **types; |
| 28 | 27 | const char *strings; |
| 29 | 28 | void *nohdr_data; |
| 30 | − uint32_t nr_types; | |
| 31 | − uint32_t types_size; | |
| 32 | − uint32_t data_size; | |
| 29 | + __u32 nr_types; | |
| 30 | + __u32 types_size; | |
| 31 | + __u32 data_size; | |
| 33 | 32 | int fd; |
| 34 | 33 | }; |
| 35 | 34 | |
| 36 | −static const char *btf_name_by_offset(const struct btf *btf, uint32_t offset) | |
| 35 | +static const char *btf_name_by_offset(const struct btf *btf, __u32 offset) | |
| 37 | 36 | { |
| 38 | 37 | if (offset < btf->hdr->str_len) |
| 39 | 38 | return &btf->strings[offset]; |
| @@ -45,7 +44,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t) · 5 unmodified lines | ||
| 45 | 44 | { |
| 46 | 45 | if (btf->types_size - btf->nr_types < 2) { |
| 47 | 46 | struct btf_type **new_types; |
| 48 | − u32 expand_by, new_size; | |
| 47 | + __u32 expand_by, new_size; | |
| 49 | 48 | |
| 50 | 49 | if (btf->types_size == BTF_MAX_NR_TYPES) |
| 51 | 50 | return -E2BIG; |
| @@ -72,7 +71,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t) · 20 unmodified lines | ||
| 72 | 71 | static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log) |
| 73 | 72 | { |
| 74 | 73 | const struct btf_header *hdr = btf->hdr; |
| 75 | − u32 meta_left; | |
| 74 | + __u32 meta_left; | |
| 76 | 75 | |
| 77 | 76 | if (btf->data_size < sizeof(struct btf_header)) { |
| 78 | 77 | elog("BTF header not found\n"); |
| @@ -151,7 +150,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log) · 72 unmodified lines | ||
| 151 | 150 | |
| 152 | 151 | while (next_type < end_type) { |
| 153 | 152 | struct btf_type *t = next_type; |
| 154 | − uint16_t vlen = BTF_INFO_VLEN(t->info); | |
| 153 | + __u16 vlen = BTF_INFO_VLEN(t->info); | |
| 155 | 154 | int err; |
| 156 | 155 | |
| 157 | 156 | next_type += sizeof(*t); |
| @@ -190,8 +189,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log) · 32 unmodified lines | ||
| 190 | 189 | return 0; |
| 191 | 190 | } |
| 192 | 191 | |
| 193 | −static const struct btf_type *btf_type_by_id(const struct btf *btf, | |
| 194 | − uint32_t type_id) | |
| 192 | +const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id) | |
| 195 | 193 | { |
| 196 | 194 | if (type_id > btf->nr_types) |
| 197 | 195 | return NULL; |
| @@ -209,7 +207,7 @@ static bool btf_type_is_void_or_null(const struct btf_type *t) · 11 unmodified lines | ||
| 209 | 207 | return !t || btf_type_is_void(t); |
| 210 | 208 | } |
| 211 | 209 | |
| 212 | −static int64_t btf_type_size(const struct btf_type *t) | |
| 210 | +static __s64 btf_type_size(const struct btf_type *t) | |
| 213 | 211 | { |
| 214 | 212 | switch (BTF_INFO_KIND(t->info)) { |
| 215 | 213 | case BTF_KIND_INT: |
| @@ -226,15 +224,15 @@ static int64_t btf_type_size(const struct btf_type *t) · 10 unmodified lines | ||
| 226 | 224 | |
| 227 | 225 | #define MAX_RESOLVE_DEPTH 32 |
| 228 | 226 | |
| 229 | −int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) | |
| 227 | +__s64 btf__resolve_size(const struct btf *btf, __u32 type_id) | |
| 230 | 228 | { |
| 231 | 229 | const struct btf_array *array; |
| 232 | 230 | const struct btf_type *t; |
| 233 | − uint32_t nelems = 1; | |
| 234 | − int64_t size = -1; | |
| 231 | + __u32 nelems = 1; | |
| 232 | + __s64 size = -1; | |
| 235 | 233 | int i; |
| 236 | 234 | |
| 237 | − t = btf_type_by_id(btf, type_id); | |
| 235 | + t = btf__type_by_id(btf, type_id); | |
| 238 | 236 | for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); |
| 239 | 237 | i++) { |
| 240 | 238 | size = btf_type_size(t); |
| @@ -259,7 +257,7 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) · 18 unmodified lines | ||
| 259 | 257 | return -EINVAL; |
| 260 | 258 | } |
| 261 | 259 | |
| 262 | − t = btf_type_by_id(btf, type_id); | |
| 260 | + t = btf__type_by_id(btf, type_id); | |
| 263 | 261 | } |
| 264 | 262 | |
| 265 | 263 | if (size < 0) |
| @@ -271,9 +269,9 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) · 5 unmodified lines | ||
| 271 | 269 | return nelems * size; |
| 272 | 270 | } |
| 273 | 271 | |
| 274 | −int32_t btf__find_by_name(const struct btf *btf, const char *type_name) | |
| 272 | +__s32 btf__find_by_name(const struct btf *btf, const char *type_name) | |
| 275 | 273 | { |
| 276 | − uint32_t i; | |
| 274 | + __u32 i; | |
| 277 | 275 | |
| 278 | 276 | if (!strcmp(type_name, "void")) |
| 279 | 277 | return 0; |
| @@ -302,10 +300,9 @@ void btf__free(struct btf *btf) · 22 unmodified lines | ||
| 302 | 300 | free(btf); |
| 303 | 301 | } |
| 304 | 302 | |
| 305 | −struct btf *btf__new(uint8_t *data, uint32_t size, | |
| 306 | − btf_print_fn_t err_log) | |
| 303 | +struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log) | |
| 307 | 304 | { |
| 308 | − uint32_t log_buf_size = 0; | |
| 305 | + __u32 log_buf_size = 0; | |
| 309 | 306 | char *log_buf = NULL; |
| 310 | 307 | struct btf *btf; |
| 311 | 308 | int err; |
| @@ -4,19 +4,21 @@ · 3 unmodified lines | ||
| 4 | 4 | #ifndef __BPF_BTF_H |
| 5 | 5 | #define __BPF_BTF_H |
| 6 | 6 | |
| 7 | −#include <stdint.h> | |
| 7 | +#include <linux/types.h> | |
| 8 | 8 | |
| 9 | 9 | #define BTF_ELF_SEC ".BTF" |
| 10 | 10 | |
| 11 | 11 | struct btf; |
| 12 | +struct btf_type; | |
| 12 | 13 | |
| 13 | 14 | typedef int (*btf_print_fn_t)(const char *, ...) |
| 14 | 15 | __attribute__((format(printf, 1, 2))); |
| 15 | 16 | |
| 16 | 17 | void btf__free(struct btf *btf); |
| 17 | −struct btf *btf__new(uint8_t *data, uint32_t size, btf_print_fn_t err_log); | |
| 18 | −int32_t btf__find_by_name(const struct btf *btf, const char *type_name); | |
| 19 | −int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id); | |
| 18 | +struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log); | |
| 19 | +__s32 btf__find_by_name(const struct btf *btf, const char *type_name); | |
| 20 | +const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id); | |
| 21 | +__s64 btf__resolve_size(const struct btf *btf, __u32 type_id); | |
| 20 | 22 | int btf__fd(const struct btf *btf); |
| 21 | 23 | |
| 22 | 24 | #endif |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <linux/err.h> |
| 37 | 37 | #include <linux/kernel.h> |
| 38 | 38 | #include <linux/bpf.h> |
| 39 | +#include <linux/btf.h> | |
| 39 | 40 | #include <linux/list.h> |
| 40 | 41 | #include <linux/limits.h> |
| 41 | 42 | #include <sys/stat.h> |
| @@ -216,8 +217,8 @@ struct bpf_map { · 174 unmodified lines | ||
| 216 | 217 | size_t offset; |
| 217 | 218 | int map_ifindex; |
| 218 | 219 | struct bpf_map_def def; |
| 219 | − uint32_t btf_key_type_id; | |
| 220 | − uint32_t btf_value_type_id; | |
| 220 | + __u32 btf_key_type_id; | |
| 221 | + __u32 btf_value_type_id; | |
| 221 | 222 | void *priv; |
| 222 | 223 | bpf_map_clear_priv_t clear_priv; |
| 223 | 224 | }; |
| @@ -1014,68 +1015,72 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, · 790 unmodified lines | ||
| 1014 | 1015 | |
| 1015 | 1016 | static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) |
| 1016 | 1017 | { |
| 1018 | + const struct btf_type *container_type; | |
| 1019 | + const struct btf_member *key, *value; | |
| 1017 | 1020 | struct bpf_map_def *def = &map->def; |
| 1018 | 1021 | const size_t max_name = 256; |
| 1019 | − int64_t key_size, value_size; | |
| 1020 | − int32_t key_id, value_id; | |
| 1021 | − char name[max_name]; | |
| 1022 | + char container_name[max_name]; | |
| 1023 | + __s64 key_size, value_size; | |
| 1024 | + __s32 container_id; | |
| 1022 | 1025 | |
| 1023 | − /* Find key type by name from BTF */ | |
| 1024 | − if (snprintf(name, max_name, "%s_key", map->name) == max_name) { | |
| 1025 | − pr_warning("map:%s length of BTF key_type:%s_key is too long\n", | |
| 1026 | + if (snprintf(container_name, max_name, "____btf_map_%s", map->name) == | |
| 1027 | + max_name) { | |
| 1028 | + pr_warning("map:%s length of '____btf_map_%s' is too long\n", | |
| 1026 | 1029 | map->name, map->name); |
| 1027 | 1030 | return -EINVAL; |
| 1028 | 1031 | } |
| 1029 | 1032 | |
| 1030 | − key_id = btf__find_by_name(btf, name); | |
| 1031 | − if (key_id < 0) { | |
| 1032 | − pr_debug("map:%s key_type:%s cannot be found in BTF\n", | |
| 1033 | − map->name, name); | |
| 1034 | − return key_id; | |
| 1033 | + container_id = btf__find_by_name(btf, container_name); | |
| 1034 | + if (container_id < 0) { | |
| 1035 | + pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n", | |
| 1036 | + map->name, container_name); | |
| 1037 | + return container_id; | |
| 1035 | 1038 | } |
| 1036 | 1039 | |
| 1037 | − key_size = btf__resolve_size(btf, key_id); | |
| 1038 | − if (key_size < 0) { | |
| 1039 | − pr_warning("map:%s key_type:%s cannot get the BTF type_size\n", | |
| 1040 | − map->name, name); | |
| 1041 | − return key_size; | |
| 1040 | + container_type = btf__type_by_id(btf, container_id); | |
| 1041 | + if (!container_type) { | |
| 1042 | + pr_warning("map:%s cannot find BTF type for container_id:%u\n", | |
| 1043 | + map->name, container_id); | |
| 1044 | + return -EINVAL; | |
| 1042 | 1045 | } |
| 1043 | 1046 | |
| 1044 | − if (def->key_size != key_size) { | |
| 1045 | − pr_warning("map:%s key_type:%s has BTF type_size:%u != key_size:%u\n", | |
| 1046 | − map->name, name, (unsigned int)key_size, def->key_size); | |
| 1047 | + if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT || | |
| 1048 | + BTF_INFO_VLEN(container_type->info) < 2) { | |
| 1049 | + pr_warning("map:%s container_name:%s is an invalid container struct\n", | |
| 1050 | + map->name, container_name); | |
| 1047 | 1051 | return -EINVAL; |
| 1048 | 1052 | } |
| 1049 | 1053 | |
| 1050 | − /* Find value type from BTF */ | |
| 1051 | − if (snprintf(name, max_name, "%s_value", map->name) == max_name) { | |
| 1052 | − pr_warning("map:%s length of BTF value_type:%s_value is too long\n", | |
| 1053 | − map->name, map->name); | |
| 1054 | − return -EINVAL; | |
| 1054 | + key = (struct btf_member *)(container_type + 1); | |
| 1055 | + value = key + 1; | |
| 1056 | + | |
| 1057 | + key_size = btf__resolve_size(btf, key->type); | |
| 1058 | + if (key_size < 0) { | |
| 1059 | + pr_warning("map:%s invalid BTF key_type_size\n", | |
| 1060 | + map->name); | |
| 1061 | + return key_size; | |
| 1055 | 1062 | } |
| 1056 | 1063 | |
| 1057 | − value_id = btf__find_by_name(btf, name); | |
| 1058 | − if (value_id < 0) { | |
| 1059 | − pr_debug("map:%s value_type:%s cannot be found in BTF\n", | |
| 1060 | − map->name, name); | |
| 1061 | − return value_id; | |
| 1064 | + if (def->key_size != key_size) { | |
| 1065 | + pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n", | |
| 1066 | + map->name, (__u32)key_size, def->key_size); | |
| 1067 | + return -EINVAL; | |
| 1062 | 1068 | } |
| 1063 | 1069 | |
| 1064 | − value_size = btf__resolve_size(btf, value_id); | |
| 1070 | + value_size = btf__resolve_size(btf, value->type); | |
| 1065 | 1071 | if (value_size < 0) { |
| 1066 | − pr_warning("map:%s value_type:%s cannot get the BTF type_size\n", | |
| 1067 | − map->name, name); | |
| 1072 | + pr_warning("map:%s invalid BTF value_type_size\n", map->name); | |
| 1068 | 1073 | return value_size; |
| 1069 | 1074 | } |
| 1070 | 1075 | |
| 1071 | 1076 | if (def->value_size != value_size) { |
| 1072 | − pr_warning("map:%s value_type:%s has BTF type_size:%u != value_size:%u\n", | |
| 1073 | − map->name, name, (unsigned int)value_size, def->value_size); | |
| 1077 | + pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n", | |
| 1078 | + map->name, (__u32)value_size, def->value_size); | |
| 1074 | 1079 | return -EINVAL; |
| 1075 | 1080 | } |
| 1076 | 1081 | |
| 1077 | − map->btf_key_type_id = key_id; | |
| 1078 | − map->btf_value_type_id = value_id; | |
| 1082 | + map->btf_key_type_id = key->type; | |
| 1083 | + map->btf_value_type_id = value->type; | |
| 1079 | 1084 | |
| 1080 | 1085 | return 0; |
| 1081 | 1086 | } |
| @@ -2089,12 +2094,12 @@ const char *bpf_map__name(struct bpf_map *map) · 1007 unmodified lines | ||
| 2089 | 2094 | return map ? map->name : NULL; |
| 2090 | 2095 | } |
| 2091 | 2096 | |
| 2092 | −uint32_t bpf_map__btf_key_type_id(const struct bpf_map *map) | |
| 2097 | +__u32 bpf_map__btf_key_type_id(const struct bpf_map *map) | |
| 2093 | 2098 | { |
| 2094 | 2099 | return map ? map->btf_key_type_id : 0; |
| 2095 | 2100 | } |
| 2096 | 2101 | |
| 2097 | −uint32_t bpf_map__btf_value_type_id(const struct bpf_map *map) | |
| 2102 | +__u32 bpf_map__btf_value_type_id(const struct bpf_map *map) | |
| 2098 | 2103 | { |
| 2099 | 2104 | return map ? map->btf_value_type_id : 0; |
| 2100 | 2105 | } |
| @@ -2268,8 +2273,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size, · 167 unmodified lines | ||
| 2268 | 2273 | volatile struct perf_event_mmap_page *header = mem; |
| 2269 | 2274 | __u64 data_tail = header->data_tail; |
| 2270 | 2275 | __u64 data_head = header->data_head; |
| 2276 | + int ret = LIBBPF_PERF_EVENT_ERROR; | |
| 2271 | 2277 | void *base, *begin, *end; |
| 2272 | − int ret; | |
| 2273 | 2278 | |
| 2274 | 2279 | asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */ |
| 2275 | 2280 | if (data_head == data_tail) |
| @@ -244,8 +244,8 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj); · 243 unmodified lines | ||
| 244 | 244 | int bpf_map__fd(struct bpf_map *map); |
| 245 | 245 | const struct bpf_map_def *bpf_map__def(struct bpf_map *map); |
| 246 | 246 | const char *bpf_map__name(struct bpf_map *map); |
| 247 | −uint32_t bpf_map__btf_key_type_id(const struct bpf_map *map); | |
| 248 | −uint32_t bpf_map__btf_value_type_id(const struct bpf_map *map); | |
| 247 | +__u32 bpf_map__btf_key_type_id(const struct bpf_map *map); | |
| 248 | +__u32 bpf_map__btf_value_type_id(const struct bpf_map *map); | |
| 249 | 249 | |
| 250 | 250 | typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); |
| 251 | 251 | int bpf_map__set_priv(struct bpf_map *map, void *priv, |
| @@ -158,6 +158,15 @@ struct bpf_map_def { · 157 unmodified lines | ||
| 158 | 158 | unsigned int numa_node; |
| 159 | 159 | }; |
| 160 | 160 | |
| 161 | +#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \ | |
| 162 | + struct ____btf_map_##name { \ | |
| 163 | + type_key key; \ | |
| 164 | + type_val value; \ | |
| 165 | + }; \ | |
| 166 | + struct ____btf_map_##name \ | |
| 167 | + __attribute__ ((section(".maps." #name), used)) \ | |
| 168 | + ____btf_map_##name = { } | |
| 169 | + | |
| 161 | 170 | static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) = |
| 162 | 171 | (void *) BPF_FUNC_skb_load_bytes; |
| 163 | 172 | static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) = |
| @@ -247,6 +247,34 @@ static struct btf_raw_test raw_tests[] = { · 246 unmodified lines | ||
| 247 | 247 | .max_entries = 4, |
| 248 | 248 | }, |
| 249 | 249 | |
| 250 | +{ | |
| 251 | + .descr = "struct test #3 Invalid member offset", | |
| 252 | + .raw_types = { | |
| 253 | + /* int */ /* [1] */ | |
| 254 | + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | |
| 255 | + /* int64 */ /* [2] */ | |
| 256 | + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8), | |
| 257 | + | |
| 258 | + /* struct A { */ /* [3] */ | |
| 259 | + BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16), | |
| 260 | + BTF_MEMBER_ENC(NAME_TBD, 1, 64), /* int m; */ | |
| 261 | + BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* int64 n; */ | |
| 262 | + /* } */ | |
| 263 | + BTF_END_RAW, | |
| 264 | + }, | |
| 265 | + .str_sec = "\0A\0m\0n\0", | |
| 266 | + .str_sec_size = sizeof("\0A\0m\0n\0"), | |
| 267 | + .map_type = BPF_MAP_TYPE_ARRAY, | |
| 268 | + .map_name = "struct_test3_map", | |
| 269 | + .key_size = sizeof(int), | |
| 270 | + .value_size = 16, | |
| 271 | + .key_type_id = 1, | |
| 272 | + .value_type_id = 3, | |
| 273 | + .max_entries = 4, | |
| 274 | + .btf_load_err = true, | |
| 275 | + .err_str = "Invalid member bits_offset", | |
| 276 | +}, | |
| 277 | + | |
| 250 | 278 | /* Test member exceeds the size of struct. |
| 251 | 279 | * |
| 252 | 280 | * struct A { |
| @@ -479,7 +507,7 @@ static struct btf_raw_test raw_tests[] = { · 226 unmodified lines | ||
| 479 | 507 | .key_size = sizeof(int), |
| 480 | 508 | .value_size = sizeof(void *) * 4, |
| 481 | 509 | .key_type_id = 1, |
| 482 | − .value_type_id = 4, | |
| 510 | + .value_type_id = 5, | |
| 483 | 511 | .max_entries = 4, |
| 484 | 512 | }, |
| 485 | 513 | |
| @@ -1264,6 +1292,88 @@ static struct btf_raw_test raw_tests[] = { · 778 unmodified lines | ||
| 1264 | 1292 | .err_str = "type != 0", |
| 1265 | 1293 | }, |
| 1266 | 1294 | |
| 1295 | +{ | |
| 1296 | + .descr = "arraymap invalid btf key (a bit field)", | |
| 1297 | + .raw_types = { | |
| 1298 | + /* int */ /* [1] */ | |
| 1299 | + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | |
| 1300 | + /* 32 bit int with 32 bit offset */ /* [2] */ | |
| 1301 | + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8), | |
| 1302 | + BTF_END_RAW, | |
| 1303 | + }, | |
| 1304 | + .str_sec = "", | |
| 1305 | + .str_sec_size = sizeof(""), | |
| 1306 | + .map_type = BPF_MAP_TYPE_ARRAY, | |
| 1307 | + .map_name = "array_map_check_btf", | |
| 1308 | + .key_size = sizeof(int), | |
| 1309 | + .value_size = sizeof(int), | |
| 1310 | + .key_type_id = 2, | |
| 1311 | + .value_type_id = 1, | |
| 1312 | + .max_entries = 4, | |
| 1313 | + .map_create_err = true, | |
| 1314 | +}, | |
| 1315 | + | |
| 1316 | +{ | |
| 1317 | + .descr = "arraymap invalid btf key (!= 32 bits)", | |
| 1318 | + .raw_types = { | |
| 1319 | + /* int */ /* [1] */ | |
| 1320 | + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | |
| 1321 | + /* 16 bit int with 0 bit offset */ /* [2] */ | |
| 1322 | + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2), | |
| 1323 | + BTF_END_RAW, | |
| 1324 | + }, | |
| 1325 | + .str_sec = "", | |
| 1326 | + .str_sec_size = sizeof(""), | |
| 1327 | + .map_type = BPF_MAP_TYPE_ARRAY, | |
| 1328 | + .map_name = "array_map_check_btf", | |
| 1329 | + .key_size = sizeof(int), | |
| 1330 | + .value_size = sizeof(int), | |
| 1331 | + .key_type_id = 2, | |
| 1332 | + .value_type_id = 1, | |
| 1333 | + .max_entries = 4, | |
| 1334 | + .map_create_err = true, | |
| 1335 | +}, | |
| 1336 | + | |
| 1337 | +{ | |
| 1338 | + .descr = "arraymap invalid btf value (too small)", | |
| 1339 | + .raw_types = { | |
| 1340 | + /* int */ /* [1] */ | |
| 1341 | + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | |
| 1342 | + BTF_END_RAW, | |
| 1343 | + }, | |
| 1344 | + .str_sec = "", | |
| 1345 | + .str_sec_size = sizeof(""), | |
| 1346 | + .map_type = BPF_MAP_TYPE_ARRAY, | |
| 1347 | + .map_name = "array_map_check_btf", | |
| 1348 | + .key_size = sizeof(int), | |
| 1349 | + /* btf_value_size < map->value_size */ | |
| 1350 | + .value_size = sizeof(__u64), | |
| 1351 | + .key_type_id = 1, | |
| 1352 | + .value_type_id = 1, | |
| 1353 | + .max_entries = 4, | |
| 1354 | + .map_create_err = true, | |
| 1355 | +}, | |
| 1356 | + | |
| 1357 | +{ | |
| 1358 | + .descr = "arraymap invalid btf value (too big)", | |
| 1359 | + .raw_types = { | |
| 1360 | + /* int */ /* [1] */ | |
| 1361 | + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | |
| 1362 | + BTF_END_RAW, | |
| 1363 | + }, | |
| 1364 | + .str_sec = "", | |
| 1365 | + .str_sec_size = sizeof(""), | |
| 1366 | + .map_type = BPF_MAP_TYPE_ARRAY, | |
| 1367 | + .map_name = "array_map_check_btf", | |
| 1368 | + .key_size = sizeof(int), | |
| 1369 | + /* btf_value_size > map->value_size */ | |
| 1370 | + .value_size = sizeof(__u16), | |
| 1371 | + .key_type_id = 1, | |
| 1372 | + .value_type_id = 1, | |
| 1373 | + .max_entries = 4, | |
| 1374 | + .map_create_err = true, | |
| 1375 | +}, | |
| 1376 | + | |
| 1267 | 1377 | }; /* struct btf_raw_test raw_tests[] */ |
| 1268 | 1378 | |
| 1269 | 1379 | static const char *get_next_str(const char *start, const char *end) |
| @@ -2023,7 +2133,7 @@ static struct btf_raw_test pprint_test = { · 753 unmodified lines | ||
| 2023 | 2133 | BTF_ENUM_ENC(NAME_TBD, 2), |
| 2024 | 2134 | BTF_ENUM_ENC(NAME_TBD, 3), |
| 2025 | 2135 | /* struct pprint_mapv */ /* [16] */ |
| 2026 | − BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 28), | |
| 2136 | + BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 32), | |
| 2027 | 2137 | BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */ |
| 2028 | 2138 | BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */ |
| 2029 | 2139 | BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */ |
| @@ -10,11 +10,6 @@ struct ipv_counts { · 9 unmodified lines | ||
| 10 | 10 | unsigned int v6; |
| 11 | 11 | }; |
| 12 | 12 | |
| 13 | −typedef int btf_map_key; | |
| 14 | −typedef struct ipv_counts btf_map_value; | |
| 15 | −btf_map_key dumm_key; | |
| 16 | −btf_map_value dummy_value; | |
| 17 | − | |
| 18 | 13 | struct bpf_map_def SEC("maps") btf_map = { |
| 19 | 14 | .type = BPF_MAP_TYPE_ARRAY, |
| 20 | 15 | .key_size = sizeof(int), |
| @@ -22,6 +17,8 @@ struct bpf_map_def SEC("maps") btf_map = { · 1 unmodified line | ||
| 22 | 17 | .max_entries = 4, |
| 23 | 18 | }; |
| 24 | 19 | |
| 20 | +BPF_ANNOTATE_KV_PAIR(btf_map, int, struct ipv_counts); | |
| 21 | + | |
| 25 | 22 | struct dummy_tracepoint_args { |
| 26 | 23 | unsigned long long pad; |
| 27 | 24 | struct sock *sock; |