Pull networking fixes from Jakub Kicinski: "Including fixes from BPF, netfilter, bluetooth and CAN. Current release - regressions: - eth: r8169: multiple fixes for PCIe ASPM-related problems - vrf: fix RCU lockdep splat in output path Previous releases - regressions: - gso: fall back to SW segmenting with GSO_UDP_L4 dodgy bit set - dsa: mv88e6xxx: do a final check before timing out when polling - nf_tables: fix sleep in atomic in nft_chain_validate Previous releases - always broken: - sched: fix undoing tcf_bind_filter() in multiple classifiers - bpf, arm64: fix BTI type used for freplace attached functions - can: gs_usb: fix time stamp counter initialization - nft_set_pipapo: fix improper element removal (leading to UAF) Misc: - net: support STP on bridge in non-root netns, STP prevents packet loops so not supporting it results in freezing systems of unsuspecting users, and in turn very upset noises being made - fix kdoc warnings - annotate various bits of TCP state to prevent data races" * tag 'net-6.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (95 commits) net: phy: prevent stale pointer dereference in phy_init() tcp: annotate data-races around fastopenq.max_qlen tcp: annotate data-races around icsk->icsk_user_timeout tcp: annotate data-races around tp->notsent_lowat tcp: annotate data-races around rskq_defer_accept tcp: annotate data-races around tp->linger2 tcp: annotate data-races around icsk->icsk_syn_retries tcp: annotate data-races around tp->keepalive_probes tcp: annotate data-races around tp->keepalive_intvl tcp: annotate data-races around tp->keepalive_time tcp: annotate data-races around tp->tsoffset tcp: annotate data-races around tp->tcp_tx_delay Bluetooth: MGMT: Use correct address for memcpy() Bluetooth: btusb: Fix bluetooth on Intel Macbook 2014 Bluetooth: SCO: fix sco_conn related locking and validity issues Bluetooth: hci_conn: return ERR_PTR instead of NULL when there is no link Bluetooth: hci_sync: Avoid use-after-free in dbg for hci_remove_adv_monitor() Bluetooth: coredump: fix building with coredump disabled Bluetooth: ISO: fix iso_conn related locking and validity issues Bluetooth: hci_event: call disconnect callback before deleting conn ...
Unified · Split
| @@ -241,6 +241,7 @@ Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com> · 240 unmodified lines | ||
| 241 | 241 | Johan Hovold <johan@kernel.org> <jhovold@gmail.com> |
| 242 | 242 | Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com> |
| 243 | 243 | John Crispin <john@phrozen.org> <blogic@openwrt.org> |
| 244 | +John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com> | |
| 244 | 245 | John Keeping <john@keeping.me.uk> <john@metanate.com> |
| 245 | 246 | John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> |
| 246 | 247 | John Stultz <johnstul@us.ibm.com> |
| @@ -454,6 +455,8 @@ Sebastian Reichel <sre@kernel.org> <sre@debian.org> · 207 unmodified lines | ||
| 454 | 455 | Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de> |
| 455 | 456 | Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com> |
| 456 | 457 | Shannon Nelson <shannon.nelson@amd.com> <snelson@pensando.io> |
| 458 | +Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@intel.com> | |
| 459 | +Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@oracle.com> | |
| 457 | 460 | Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com> |
| 458 | 461 | Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com> |
| 459 | 462 | Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com> |
| @@ -322,7 +322,13 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) · 321 unmodified lines | ||
| 322 | 322 | * |
| 323 | 323 | */ |
| 324 | 324 | |
| 325 | − emit_bti(A64_BTI_C, ctx); | |
| 325 | + /* bpf function may be invoked by 3 instruction types: | |
| 326 | + * 1. bl, attached via freplace to bpf prog via short jump | |
| 327 | + * 2. br, attached via freplace to bpf prog via long jump | |
| 328 | + * 3. blr, working as a function pointer, used by emit_call. | |
| 329 | + * So BTI_JC should used here to support both br and blr. | |
| 330 | + */ | |
| 331 | + emit_bti(A64_BTI_JC, ctx); | |
| 326 | 332 | |
| 327 | 333 | emit(A64_MOV(1, A64_R(9), A64_LR), ctx); |
| 328 | 334 | emit(A64_NOP, ctx); |
| @@ -4104,6 +4104,7 @@ static int btusb_probe(struct usb_interface *intf, · 4103 unmodified lines | ||
| 4104 | 4104 | BT_DBG("intf %p id %p", intf, id); |
| 4105 | 4105 | |
| 4106 | 4106 | if ((id->driver_info & BTUSB_IFNUM_2) && |
| 4107 | + (intf->cur_altsetting->desc.bInterfaceNumber != 0) && | |
| 4107 | 4108 | (intf->cur_altsetting->desc.bInterfaceNumber != 2)) |
| 4108 | 4109 | return -ENODEV; |
| 4109 | 4110 | |
| @@ -227,6 +227,8 @@ static int · 226 unmodified lines | ||
| 227 | 227 | __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv, |
| 228 | 228 | const u8 mode_req, bool nowait) |
| 229 | 229 | { |
| 230 | + const struct can_bittiming *bt = &priv->can.bittiming; | |
| 231 | + unsigned long timeout_us = MCP251XFD_POLL_TIMEOUT_US; | |
| 230 | 232 | u32 con = 0, con_reqop, osc = 0; |
| 231 | 233 | u8 mode; |
| 232 | 234 | int err; |
| @@ -246,12 +248,16 @@ __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv, · 13 unmodified lines | ||
| 246 | 248 | if (mode_req == MCP251XFD_REG_CON_MODE_SLEEP || nowait) |
| 247 | 249 | return 0; |
| 248 | 250 | |
| 251 | + if (bt->bitrate) | |
| 252 | + timeout_us = max_t(unsigned long, timeout_us, | |
| 253 | + MCP251XFD_FRAME_LEN_MAX_BITS * USEC_PER_SEC / | |
| 254 | + bt->bitrate); | |
| 255 | + | |
| 249 | 256 | err = regmap_read_poll_timeout(priv->map_reg, MCP251XFD_REG_CON, con, |
| 250 | 257 | !mcp251xfd_reg_invalid(con) && |
| 251 | 258 | FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK, |
| 252 | 259 | con) == mode_req, |
| 253 | − MCP251XFD_POLL_SLEEP_US, | |
| 254 | − MCP251XFD_POLL_TIMEOUT_US); | |
| 260 | + MCP251XFD_POLL_SLEEP_US, timeout_us); | |
| 255 | 261 | if (err != -ETIMEDOUT && err != -EBADMSG) |
| 256 | 262 | return err; |
| 257 | 263 | |
| @@ -387,6 +387,7 @@ static_assert(MCP251XFD_TIMESTAMP_WORK_DELAY_SEC < · 386 unmodified lines | ||
| 387 | 387 | #define MCP251XFD_OSC_STAB_TIMEOUT_US (10 * MCP251XFD_OSC_STAB_SLEEP_US) |
| 388 | 388 | #define MCP251XFD_POLL_SLEEP_US (10) |
| 389 | 389 | #define MCP251XFD_POLL_TIMEOUT_US (USEC_PER_MSEC) |
| 390 | +#define MCP251XFD_FRAME_LEN_MAX_BITS (736) | |
| 390 | 391 | |
| 391 | 392 | /* Misc */ |
| 392 | 393 | #define MCP251XFD_NAPI_WEIGHT 32 |
| @@ -303,12 +303,6 @@ struct gs_can { · 302 unmodified lines | ||
| 303 | 303 | struct can_bittiming_const bt_const, data_bt_const; |
| 304 | 304 | unsigned int channel; /* channel number */ |
| 305 | 305 | |
| 306 | − /* time counter for hardware timestamps */ | |
| 307 | − struct cyclecounter cc; | |
| 308 | − struct timecounter tc; | |
| 309 | − spinlock_t tc_lock; /* spinlock to guard access tc->cycle_last */ | |
| 310 | − struct delayed_work timestamp; | |
| 311 | − | |
| 312 | 306 | u32 feature; |
| 313 | 307 | unsigned int hf_size_tx; |
| 314 | 308 | |
| @@ -325,6 +319,13 @@ struct gs_usb { · 10 unmodified lines | ||
| 325 | 319 | struct gs_can *canch[GS_MAX_INTF]; |
| 326 | 320 | struct usb_anchor rx_submitted; |
| 327 | 321 | struct usb_device *udev; |
| 322 | + | |
| 323 | + /* time counter for hardware timestamps */ | |
| 324 | + struct cyclecounter cc; | |
| 325 | + struct timecounter tc; | |
| 326 | + spinlock_t tc_lock; /* spinlock to guard access tc->cycle_last */ | |
| 327 | + struct delayed_work timestamp; | |
| 328 | + | |
| 328 | 329 | unsigned int hf_size_rx; |
| 329 | 330 | u8 active_channels; |
| 330 | 331 | }; |
| @@ -388,15 +389,15 @@ static int gs_cmd_reset(struct gs_can *dev) · 57 unmodified lines | ||
| 388 | 389 | GFP_KERNEL); |
| 389 | 390 | } |
| 390 | 391 | |
| 391 | −static inline int gs_usb_get_timestamp(const struct gs_can *dev, | |
| 392 | +static inline int gs_usb_get_timestamp(const struct gs_usb *parent, | |
| 392 | 393 | u32 *timestamp_p) |
| 393 | 394 | { |
| 394 | 395 | __le32 timestamp; |
| 395 | 396 | int rc; |
| 396 | 397 | |
| 397 | − rc = usb_control_msg_recv(dev->udev, 0, GS_USB_BREQ_TIMESTAMP, | |
| 398 | + rc = usb_control_msg_recv(parent->udev, 0, GS_USB_BREQ_TIMESTAMP, | |
| 398 | 399 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
| 399 | − dev->channel, 0, | |
| 400 | + 0, 0, | |
| 400 | 401 | ×tamp, sizeof(timestamp), |
| 401 | 402 | USB_CTRL_GET_TIMEOUT, |
| 402 | 403 | GFP_KERNEL); |
| @@ -410,20 +411,20 @@ static inline int gs_usb_get_timestamp(const struct gs_can *dev, · 7 unmodified lines | ||
| 410 | 411 | |
| 411 | 412 | static u64 gs_usb_timestamp_read(const struct cyclecounter *cc) __must_hold(&dev->tc_lock) |
| 412 | 413 | { |
| 413 | − struct gs_can *dev = container_of(cc, struct gs_can, cc); | |
| 414 | + struct gs_usb *parent = container_of(cc, struct gs_usb, cc); | |
| 414 | 415 | u32 timestamp = 0; |
| 415 | 416 | int err; |
| 416 | 417 | |
| 417 | − lockdep_assert_held(&dev->tc_lock); | |
| 418 | + lockdep_assert_held(&parent->tc_lock); | |
| 418 | 419 | |
| 419 | 420 | /* drop lock for synchronous USB transfer */ |
| 420 | − spin_unlock_bh(&dev->tc_lock); | |
| 421 | − err = gs_usb_get_timestamp(dev, ×tamp); | |
| 422 | − spin_lock_bh(&dev->tc_lock); | |
| 421 | + spin_unlock_bh(&parent->tc_lock); | |
| 422 | + err = gs_usb_get_timestamp(parent, ×tamp); | |
| 423 | + spin_lock_bh(&parent->tc_lock); | |
| 423 | 424 | if (err) |
| 424 | − netdev_err(dev->netdev, | |
| 425 | − "Error %d while reading timestamp. HW timestamps may be inaccurate.", | |
| 426 | − err); | |
| 425 | + dev_err(&parent->udev->dev, | |
| 426 | + "Error %d while reading timestamp. HW timestamps may be inaccurate.", | |
| 427 | + err); | |
| 427 | 428 | |
| 428 | 429 | return timestamp; |
| 429 | 430 | } |
| @@ -431,14 +432,14 @@ static u64 gs_usb_timestamp_read(const struct cyclecounter *cc) __must_hold(&dev · 1 unmodified line | ||
| 431 | 432 | static void gs_usb_timestamp_work(struct work_struct *work) |
| 432 | 433 | { |
| 433 | 434 | struct delayed_work *delayed_work = to_delayed_work(work); |
| 434 | − struct gs_can *dev; | |
| 435 | + struct gs_usb *parent; | |
| 435 | 436 | |
| 436 | − dev = container_of(delayed_work, struct gs_can, timestamp); | |
| 437 | − spin_lock_bh(&dev->tc_lock); | |
| 438 | − timecounter_read(&dev->tc); | |
| 439 | − spin_unlock_bh(&dev->tc_lock); | |
| 437 | + parent = container_of(delayed_work, struct gs_usb, timestamp); | |
| 438 | + spin_lock_bh(&parent->tc_lock); | |
| 439 | + timecounter_read(&parent->tc); | |
| 440 | + spin_unlock_bh(&parent->tc_lock); | |
| 440 | 441 | |
| 441 | − schedule_delayed_work(&dev->timestamp, | |
| 442 | + schedule_delayed_work(&parent->timestamp, | |
| 442 | 443 | GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ); |
| 443 | 444 | } |
| 444 | 445 | |
| @@ -446,37 +447,38 @@ static void gs_usb_skb_set_timestamp(struct gs_can *dev, · 1 unmodified line | ||
| 446 | 447 | struct sk_buff *skb, u32 timestamp) |
| 447 | 448 | { |
| 448 | 449 | struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); |
| 450 | + struct gs_usb *parent = dev->parent; | |
| 449 | 451 | u64 ns; |
| 450 | 452 | |
| 451 | − spin_lock_bh(&dev->tc_lock); | |
| 452 | − ns = timecounter_cyc2time(&dev->tc, timestamp); | |
| 453 | − spin_unlock_bh(&dev->tc_lock); | |
| 453 | + spin_lock_bh(&parent->tc_lock); | |
| 454 | + ns = timecounter_cyc2time(&parent->tc, timestamp); | |
| 455 | + spin_unlock_bh(&parent->tc_lock); | |
| 454 | 456 | |
| 455 | 457 | hwtstamps->hwtstamp = ns_to_ktime(ns); |
| 456 | 458 | } |
| 457 | 459 | |
| 458 | −static void gs_usb_timestamp_init(struct gs_can *dev) | |
| 460 | +static void gs_usb_timestamp_init(struct gs_usb *parent) | |
| 459 | 461 | { |
| 460 | − struct cyclecounter *cc = &dev->cc; | |
| 462 | + struct cyclecounter *cc = &parent->cc; | |
| 461 | 463 | |
| 462 | 464 | cc->read = gs_usb_timestamp_read; |
| 463 | 465 | cc->mask = CYCLECOUNTER_MASK(32); |
| 464 | 466 | cc->shift = 32 - bits_per(NSEC_PER_SEC / GS_USB_TIMESTAMP_TIMER_HZ); |
| 465 | 467 | cc->mult = clocksource_hz2mult(GS_USB_TIMESTAMP_TIMER_HZ, cc->shift); |
| 466 | 468 | |
| 467 | − spin_lock_init(&dev->tc_lock); | |
| 468 | − spin_lock_bh(&dev->tc_lock); | |
| 469 | − timecounter_init(&dev->tc, &dev->cc, ktime_get_real_ns()); | |
| 470 | − spin_unlock_bh(&dev->tc_lock); | |
| 469 | + spin_lock_init(&parent->tc_lock); | |
| 470 | + spin_lock_bh(&parent->tc_lock); | |
| 471 | + timecounter_init(&parent->tc, &parent->cc, ktime_get_real_ns()); | |
| 472 | + spin_unlock_bh(&parent->tc_lock); | |
| 471 | 473 | |
| 472 | − INIT_DELAYED_WORK(&dev->timestamp, gs_usb_timestamp_work); | |
| 473 | − schedule_delayed_work(&dev->timestamp, | |
| 474 | + INIT_DELAYED_WORK(&parent->timestamp, gs_usb_timestamp_work); | |
| 475 | + schedule_delayed_work(&parent->timestamp, | |
| 474 | 476 | GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ); |
| 475 | 477 | } |
| 476 | 478 | |
| 477 | −static void gs_usb_timestamp_stop(struct gs_can *dev) | |
| 479 | +static void gs_usb_timestamp_stop(struct gs_usb *parent) | |
| 478 | 480 | { |
| 479 | − cancel_delayed_work_sync(&dev->timestamp); | |
| 481 | + cancel_delayed_work_sync(&parent->timestamp); | |
| 480 | 482 | } |
| 481 | 483 | |
| 482 | 484 | static void gs_update_state(struct gs_can *dev, struct can_frame *cf) |
| @@ -560,6 +562,9 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) · 77 unmodified lines | ||
| 560 | 562 | if (!netif_device_present(netdev)) |
| 561 | 563 | return; |
| 562 | 564 | |
| 565 | + if (!netif_running(netdev)) | |
| 566 | + goto resubmit_urb; | |
| 567 | + | |
| 563 | 568 | if (hf->echo_id == -1) { /* normal rx */ |
| 564 | 569 | if (hf->flags & GS_CAN_FLAG_FD) { |
| 565 | 570 | skb = alloc_canfd_skb(dev->netdev, &cfd); |
| @@ -833,6 +838,7 @@ static int gs_can_open(struct net_device *netdev) · 267 unmodified lines | ||
| 833 | 838 | .mode = cpu_to_le32(GS_CAN_MODE_START), |
| 834 | 839 | }; |
| 835 | 840 | struct gs_host_frame *hf; |
| 841 | + struct urb *urb = NULL; | |
| 836 | 842 | u32 ctrlmode; |
| 837 | 843 | u32 flags = 0; |
| 838 | 844 | int rc, i; |
| @@ -855,14 +861,18 @@ static int gs_can_open(struct net_device *netdev) · 16 unmodified lines | ||
| 855 | 861 | } |
| 856 | 862 | |
| 857 | 863 | if (!parent->active_channels) { |
| 864 | + if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | |
| 865 | + gs_usb_timestamp_init(parent); | |
| 866 | + | |
| 858 | 867 | for (i = 0; i < GS_MAX_RX_URBS; i++) { |
| 859 | − struct urb *urb; | |
| 860 | 868 | u8 *buf; |
| 861 | 869 | |
| 862 | 870 | /* alloc rx urb */ |
| 863 | 871 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| 864 | − if (!urb) | |
| 865 | − return -ENOMEM; | |
| 872 | + if (!urb) { | |
| 873 | + rc = -ENOMEM; | |
| 874 | + goto out_usb_kill_anchored_urbs; | |
| 875 | + } | |
| 866 | 876 | |
| 867 | 877 | /* alloc rx buffer */ |
| 868 | 878 | buf = kmalloc(dev->parent->hf_size_rx, |
| @@ -870,8 +880,8 @@ static int gs_can_open(struct net_device *netdev) · 1 unmodified line | ||
| 870 | 880 | if (!buf) { |
| 871 | 881 | netdev_err(netdev, |
| 872 | 882 | "No memory left for USB buffer\n"); |
| 873 | − usb_free_urb(urb); | |
| 874 | − return -ENOMEM; | |
| 883 | + rc = -ENOMEM; | |
| 884 | + goto out_usb_free_urb; | |
| 875 | 885 | } |
| 876 | 886 | |
| 877 | 887 | /* fill, anchor, and submit rx urb */ |
| @@ -894,9 +904,7 @@ static int gs_can_open(struct net_device *netdev) · 16 unmodified lines | ||
| 894 | 904 | netdev_err(netdev, |
| 895 | 905 | "usb_submit failed (err=%d)\n", rc); |
| 896 | 906 | |
| 897 | − usb_unanchor_urb(urb); | |
| 898 | − usb_free_urb(urb); | |
| 899 | − break; | |
| 907 | + goto out_usb_unanchor_urb; | |
| 900 | 908 | } |
| 901 | 909 | |
| 902 | 910 | /* Drop reference, |
| @@ -926,13 +934,9 @@ static int gs_can_open(struct net_device *netdev) · 23 unmodified lines | ||
| 926 | 934 | flags |= GS_CAN_MODE_FD; |
| 927 | 935 | |
| 928 | 936 | /* if hardware supports timestamps, enable it */ |
| 929 | − if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) { | |
| 937 | + if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | |
| 930 | 938 | flags |= GS_CAN_MODE_HW_TIMESTAMP; |
| 931 | 939 | |
| 932 | − /* start polling timestamp */ | |
| 933 | − gs_usb_timestamp_init(dev); | |
| 934 | − } | |
| 935 | − | |
| 936 | 940 | /* finally start device */ |
| 937 | 941 | dev->can.state = CAN_STATE_ERROR_ACTIVE; |
| 938 | 942 | dm.flags = cpu_to_le32(flags); |
| @@ -942,10 +946,9 @@ static int gs_can_open(struct net_device *netdev) · 3 unmodified lines | ||
| 942 | 946 | GFP_KERNEL); |
| 943 | 947 | if (rc) { |
| 944 | 948 | netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); |
| 945 | − if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | |
| 946 | − gs_usb_timestamp_stop(dev); | |
| 947 | 949 | dev->can.state = CAN_STATE_STOPPED; |
| 948 | − return rc; | |
| 950 | + | |
| 951 | + goto out_usb_kill_anchored_urbs; | |
| 949 | 952 | } |
| 950 | 953 | |
| 951 | 954 | parent->active_channels++; |
| @@ -953,6 +956,22 @@ static int gs_can_open(struct net_device *netdev) · 1 unmodified line | ||
| 953 | 956 | netif_start_queue(netdev); |
| 954 | 957 | |
| 955 | 958 | return 0; |
| 959 | + | |
| 960 | +out_usb_unanchor_urb: | |
| 961 | + usb_unanchor_urb(urb); | |
| 962 | +out_usb_free_urb: | |
| 963 | + usb_free_urb(urb); | |
| 964 | +out_usb_kill_anchored_urbs: | |
| 965 | + if (!parent->active_channels) { | |
| 966 | + usb_kill_anchored_urbs(&dev->tx_submitted); | |
| 967 | + | |
| 968 | + if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | |
| 969 | + gs_usb_timestamp_stop(parent); | |
| 970 | + } | |
| 971 | + | |
| 972 | + close_candev(netdev); | |
| 973 | + | |
| 974 | + return rc; | |
| 956 | 975 | } |
| 957 | 976 | |
| 958 | 977 | static int gs_usb_get_state(const struct net_device *netdev, |
| @@ -998,14 +1017,13 @@ static int gs_can_close(struct net_device *netdev) · 39 unmodified lines | ||
| 998 | 1017 | |
| 999 | 1018 | netif_stop_queue(netdev); |
| 1000 | 1019 | |
| 1001 | − /* stop polling timestamp */ | |
| 1002 | − if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | |
| 1003 | − gs_usb_timestamp_stop(dev); | |
| 1004 | − | |
| 1005 | 1020 | /* Stop polling */ |
| 1006 | 1021 | parent->active_channels--; |
| 1007 | 1022 | if (!parent->active_channels) { |
| 1008 | 1023 | usb_kill_anchored_urbs(&parent->rx_submitted); |
| 1024 | + | |
| 1025 | + if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | |
| 1026 | + gs_usb_timestamp_stop(parent); | |
| 1009 | 1027 | } |
| 1010 | 1028 | |
| 1011 | 1029 | /* Stop sending URBs */ |
| @@ -506,7 +506,13 @@ static int ksz8_r_sta_mac_table(struct ksz_device *dev, u16 addr, · 505 unmodified lines | ||
| 506 | 506 | (data_hi & masks[STATIC_MAC_TABLE_FWD_PORTS]) >> |
| 507 | 507 | shifts[STATIC_MAC_FWD_PORTS]; |
| 508 | 508 | alu->is_override = (data_hi & masks[STATIC_MAC_TABLE_OVERRIDE]) ? 1 : 0; |
| 509 | − data_hi >>= 1; | |
| 509 | + | |
| 510 | + /* KSZ8795 family switches have STATIC_MAC_TABLE_USE_FID and | |
| 511 | + * STATIC_MAC_TABLE_FID definitions off by 1 when doing read on the | |
| 512 | + * static MAC table compared to doing write. | |
| 513 | + */ | |
| 514 | + if (ksz_is_ksz87xx(dev)) | |
| 515 | + data_hi >>= 1; | |
| 510 | 516 | alu->is_static = true; |
| 511 | 517 | alu->is_use_fid = (data_hi & masks[STATIC_MAC_TABLE_USE_FID]) ? 1 : 0; |
| 512 | 518 | alu->fid = (data_hi & masks[STATIC_MAC_TABLE_FID]) >> |
| @@ -331,13 +331,13 @@ static const u32 ksz8795_masks[] = { · 330 unmodified lines | ||
| 331 | 331 | [STATIC_MAC_TABLE_VALID] = BIT(21), |
| 332 | 332 | [STATIC_MAC_TABLE_USE_FID] = BIT(23), |
| 333 | 333 | [STATIC_MAC_TABLE_FID] = GENMASK(30, 24), |
| 334 | − [STATIC_MAC_TABLE_OVERRIDE] = BIT(26), | |
| 335 | − [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(24, 20), | |
| 334 | + [STATIC_MAC_TABLE_OVERRIDE] = BIT(22), | |
| 335 | + [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(20, 16), | |
| 336 | 336 | [DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(6, 0), |
| 337 | − [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(8), | |
| 337 | + [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(7), | |
| 338 | 338 | [DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7), |
| 339 | 339 | [DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 29), |
| 340 | − [DYNAMIC_MAC_TABLE_FID] = GENMASK(26, 20), | |
| 340 | + [DYNAMIC_MAC_TABLE_FID] = GENMASK(22, 16), | |
| 341 | 341 | [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(26, 24), |
| 342 | 342 | [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(28, 27), |
| 343 | 343 | [P_MII_TX_FLOW_CTRL] = BIT(5), |
| @@ -601,6 +601,13 @@ static inline void ksz_regmap_unlock(void *__mtx) · 600 unmodified lines | ||
| 601 | 601 | mutex_unlock(mtx); |
| 602 | 602 | } |
| 603 | 603 | |
| 604 | +static inline bool ksz_is_ksz87xx(struct ksz_device *dev) | |
| 605 | +{ | |
| 606 | + return dev->chip_id == KSZ8795_CHIP_ID || | |
| 607 | + dev->chip_id == KSZ8794_CHIP_ID || | |
| 608 | + dev->chip_id == KSZ8765_CHIP_ID; | |
| 609 | +} | |
| 610 | + | |
| 604 | 611 | static inline bool ksz_is_ksz88x3(struct ksz_device *dev) |
| 605 | 612 | { |
| 606 | 613 | return dev->chip_id == KSZ8830_CHIP_ID; |
| @@ -109,6 +109,13 @@ int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg, · 108 unmodified lines | ||
| 109 | 109 | usleep_range(1000, 2000); |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | + err = mv88e6xxx_read(chip, addr, reg, &data); | |
| 113 | + if (err) | |
| 114 | + return err; | |
| 115 | + | |
| 116 | + if ((data & mask) == val) | |
| 117 | + return 0; | |
| 118 | + | |
| 112 | 119 | dev_err(chip->dev, "Timeout while waiting for switch\n"); |
| 113 | 120 | return -ETIMEDOUT; |
| 114 | 121 | } |
| @@ -1002,6 +1002,8 @@ static const struct regmap_config ar9331_mdio_regmap_config = { · 1001 unmodified lines | ||
| 1002 | 1002 | .val_bits = 32, |
| 1003 | 1003 | .reg_stride = 4, |
| 1004 | 1004 | .max_register = AR9331_SW_REG_PAGE, |
| 1005 | + .use_single_read = true, | |
| 1006 | + .use_single_write = true, | |
| 1005 | 1007 | |
| 1006 | 1008 | .ranges = ar9331_regmap_range, |
| 1007 | 1009 | .num_ranges = ARRAY_SIZE(ar9331_regmap_range), |
| @@ -1018,8 +1020,6 @@ static struct regmap_bus ar9331_sw_bus = { · 10 unmodified lines | ||
| 1018 | 1020 | .val_format_endian_default = REGMAP_ENDIAN_NATIVE, |
| 1019 | 1021 | .read = ar9331_mdio_read, |
| 1020 | 1022 | .write = ar9331_sw_bus_write, |
| 1021 | − .max_raw_read = 4, | |
| 1022 | − .max_raw_write = 4, | |
| 1023 | 1023 | }; |
| 1024 | 1024 | |
| 1025 | 1025 | static int ar9331_sw_probe(struct mdio_device *mdiodev) |
| @@ -512,11 +512,6 @@ bnad_debugfs_init(struct bnad *bnad) · 511 unmodified lines | ||
| 512 | 512 | if (!bnad->port_debugfs_root) { |
| 513 | 513 | bnad->port_debugfs_root = |
| 514 | 514 | debugfs_create_dir(name, bna_debugfs_root); |
| 515 | − if (!bnad->port_debugfs_root) { | |
| 516 | − netdev_warn(bnad->netdev, | |
| 517 | − "debugfs root dir creation failed\n"); | |
| 518 | − return; | |
| 519 | − } | |
| 520 | 515 | |
| 521 | 516 | atomic_inc(&bna_debugfs_port_count); |
| 522 | 517 | |
| @@ -255,8 +255,10 @@ struct iavf_adapter { · 254 unmodified lines | ||
| 255 | 255 | struct workqueue_struct *wq; |
| 256 | 256 | struct work_struct reset_task; |
| 257 | 257 | struct work_struct adminq_task; |
| 258 | + struct work_struct finish_config; | |
| 258 | 259 | struct delayed_work client_task; |
| 259 | 260 | wait_queue_head_t down_waitqueue; |
| 261 | + wait_queue_head_t reset_waitqueue; | |
| 260 | 262 | wait_queue_head_t vc_waitqueue; |
| 261 | 263 | struct iavf_q_vector *q_vectors; |
| 262 | 264 | struct list_head vlan_filter_list; |
| @@ -518,8 +520,9 @@ int iavf_up(struct iavf_adapter *adapter); · 255 unmodified lines | ||
| 518 | 520 | void iavf_down(struct iavf_adapter *adapter); |
| 519 | 521 | int iavf_process_config(struct iavf_adapter *adapter); |
| 520 | 522 | int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter); |
| 521 | −void iavf_schedule_reset(struct iavf_adapter *adapter); | |
| 523 | +void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags); | |
| 522 | 524 | void iavf_schedule_request_stats(struct iavf_adapter *adapter); |
| 525 | +void iavf_schedule_finish_config(struct iavf_adapter *adapter); | |
| 523 | 526 | void iavf_reset(struct iavf_adapter *adapter); |
| 524 | 527 | void iavf_set_ethtool_ops(struct net_device *netdev); |
| 525 | 528 | void iavf_update_stats(struct iavf_adapter *adapter); |
| @@ -582,4 +585,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter); · 56 unmodified lines | ||
| 582 | 585 | void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter); |
| 583 | 586 | struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, |
| 584 | 587 | const u8 *macaddr); |
| 588 | +int iavf_wait_for_reset(struct iavf_adapter *adapter); | |
| 585 | 589 | #endif /* _IAVF_H_ */ |
| @@ -484,6 +484,7 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags) · 483 unmodified lines | ||
| 484 | 484 | { |
| 485 | 485 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 486 | 486 | u32 orig_flags, new_flags, changed_flags; |
| 487 | + int ret = 0; | |
| 487 | 488 | u32 i; |
| 488 | 489 | |
| 489 | 490 | orig_flags = READ_ONCE(adapter->flags); |
| @@ -531,12 +532,14 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags) · 41 unmodified lines | ||
| 531 | 532 | /* issue a reset to force legacy-rx change to take effect */ |
| 532 | 533 | if (changed_flags & IAVF_FLAG_LEGACY_RX) { |
| 533 | 534 | if (netif_running(netdev)) { |
| 534 | − adapter->flags |= IAVF_FLAG_RESET_NEEDED; | |
| 535 | − queue_work(adapter->wq, &adapter->reset_task); | |
| 535 | + iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); | |
| 536 | + ret = iavf_wait_for_reset(adapter); | |
| 537 | + if (ret) | |
| 538 | + netdev_warn(netdev, "Changing private flags timeout or interrupted waiting for reset"); | |
| 536 | 539 | } |
| 537 | 540 | } |
| 538 | 541 | |
| 539 | − return 0; | |
| 542 | + return ret; | |
| 540 | 543 | } |
| 541 | 544 | |
| 542 | 545 | /** |
| @@ -627,6 +630,7 @@ static int iavf_set_ringparam(struct net_device *netdev, · 84 unmodified lines | ||
| 627 | 630 | { |
| 628 | 631 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 629 | 632 | u32 new_rx_count, new_tx_count; |
| 633 | + int ret = 0; | |
| 630 | 634 | |
| 631 | 635 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
| 632 | 636 | return -EINVAL; |
| @@ -671,11 +675,13 @@ static int iavf_set_ringparam(struct net_device *netdev, · 38 unmodified lines | ||
| 671 | 675 | } |
| 672 | 676 | |
| 673 | 677 | if (netif_running(netdev)) { |
| 674 | − adapter->flags |= IAVF_FLAG_RESET_NEEDED; | |
| 675 | − queue_work(adapter->wq, &adapter->reset_task); | |
| 678 | + iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); | |
| 679 | + ret = iavf_wait_for_reset(adapter); | |
| 680 | + if (ret) | |
| 681 | + netdev_warn(netdev, "Changing ring parameters timeout or interrupted waiting for reset"); | |
| 676 | 682 | } |
| 677 | 683 | |
| 678 | − return 0; | |
| 684 | + return ret; | |
| 679 | 685 | } |
| 680 | 686 | |
| 681 | 687 | /** |
| @@ -1830,7 +1836,7 @@ static int iavf_set_channels(struct net_device *netdev, · 1148 unmodified lines | ||
| 1830 | 1836 | { |
| 1831 | 1837 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 1832 | 1838 | u32 num_req = ch->combined_count; |
| 1833 | − int i; | |
| 1839 | + int ret = 0; | |
| 1834 | 1840 | |
| 1835 | 1841 | if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) && |
| 1836 | 1842 | adapter->num_tc) { |
| @@ -1852,22 +1858,13 @@ static int iavf_set_channels(struct net_device *netdev, · 15 unmodified lines | ||
| 1852 | 1858 | |
| 1853 | 1859 | adapter->num_req_queues = num_req; |
| 1854 | 1860 | adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED; |
| 1855 | − iavf_schedule_reset(adapter); | |
| 1861 | + iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); | |
| 1856 | 1862 | |
| 1857 | − /* wait for the reset is done */ | |
| 1858 | − for (i = 0; i < IAVF_RESET_WAIT_COMPLETE_COUNT; i++) { | |
| 1859 | − msleep(IAVF_RESET_WAIT_MS); | |
| 1860 | − if (adapter->flags & IAVF_FLAG_RESET_PENDING) | |
| 1861 | − continue; | |
| 1862 | − break; | |
| 1863 | − } | |
| 1864 | − if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) { | |
| 1865 | − adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; | |
| 1866 | − adapter->num_active_queues = num_req; | |
| 1867 | − return -EOPNOTSUPP; | |
| 1868 | − } | |
| 1863 | + ret = iavf_wait_for_reset(adapter); | |
| 1864 | + if (ret) | |
| 1865 | + netdev_warn(netdev, "Changing channel count timeout or interrupted waiting for reset"); | |
| 1869 | 1866 | |
| 1870 | − return 0; | |
| 1867 | + return ret; | |
| 1871 | 1868 | } |
| 1872 | 1869 | |
| 1873 | 1870 | /** |
| @@ -166,6 +166,45 @@ static struct iavf_adapter *iavf_pdev_to_adapter(struct pci_dev *pdev) · 165 unmodified lines | ||
| 166 | 166 | return netdev_priv(pci_get_drvdata(pdev)); |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | +/** | |
| 170 | + * iavf_is_reset_in_progress - Check if a reset is in progress | |
| 171 | + * @adapter: board private structure | |
| 172 | + */ | |
| 173 | +static bool iavf_is_reset_in_progress(struct iavf_adapter *adapter) | |
| 174 | +{ | |
| 175 | + if (adapter->state == __IAVF_RESETTING || | |
| 176 | + adapter->flags & (IAVF_FLAG_RESET_PENDING | | |
| 177 | + IAVF_FLAG_RESET_NEEDED)) | |
| 178 | + return true; | |
| 179 | + | |
| 180 | + return false; | |
| 181 | +} | |
| 182 | + | |
| 183 | +/** | |
| 184 | + * iavf_wait_for_reset - Wait for reset to finish. | |
| 185 | + * @adapter: board private structure | |
| 186 | + * | |
| 187 | + * Returns 0 if reset finished successfully, negative on timeout or interrupt. | |
| 188 | + */ | |
| 189 | +int iavf_wait_for_reset(struct iavf_adapter *adapter) | |
| 190 | +{ | |
| 191 | + int ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, | |
| 192 | + !iavf_is_reset_in_progress(adapter), | |
| 193 | + msecs_to_jiffies(5000)); | |
| 194 | + | |
| 195 | + /* If ret < 0 then it means wait was interrupted. | |
| 196 | + * If ret == 0 then it means we got a timeout while waiting | |
| 197 | + * for reset to finish. | |
| 198 | + * If ret > 0 it means reset has finished. | |
| 199 | + */ | |
| 200 | + if (ret > 0) | |
| 201 | + return 0; | |
| 202 | + else if (ret < 0) | |
| 203 | + return -EINTR; | |
| 204 | + else | |
| 205 | + return -EBUSY; | |
| 206 | +} | |
| 207 | + | |
| 169 | 208 | /** |
| 170 | 209 | * iavf_allocate_dma_mem_d - OS specific memory alloc for shared code |
| 171 | 210 | * @hw: pointer to the HW structure |
| @@ -262,12 +301,14 @@ static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs) · 90 unmodified lines | ||
| 262 | 301 | /** |
| 263 | 302 | * iavf_schedule_reset - Set the flags and schedule a reset event |
| 264 | 303 | * @adapter: board private structure |
| 304 | + * @flags: IAVF_FLAG_RESET_PENDING or IAVF_FLAG_RESET_NEEDED | |
| 265 | 305 | **/ |
| 266 | −void iavf_schedule_reset(struct iavf_adapter *adapter) | |
| 306 | +void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags) | |
| 267 | 307 | { |
| 268 | − if (!(adapter->flags & | |
| 269 | − (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED))) { | |
| 270 | − adapter->flags |= IAVF_FLAG_RESET_NEEDED; | |
| 308 | + if (!test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section) && | |
| 309 | + !(adapter->flags & | |
| 310 | + (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED))) { | |
| 311 | + adapter->flags |= flags; | |
| 271 | 312 | queue_work(adapter->wq, &adapter->reset_task); |
| 272 | 313 | } |
| 273 | 314 | } |
| @@ -295,7 +336,7 @@ static void iavf_tx_timeout(struct net_device *netdev, unsigned int txqueue) · 21 unmodified lines | ||
| 295 | 336 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 296 | 337 | |
| 297 | 338 | adapter->tx_timeout_count++; |
| 298 | − iavf_schedule_reset(adapter); | |
| 339 | + iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); | |
| 299 | 340 | } |
| 300 | 341 | |
| 301 | 342 | /** |
| @@ -1651,10 +1692,10 @@ static int iavf_set_interrupt_capability(struct iavf_adapter *adapter) · 1349 unmodified lines | ||
| 1651 | 1692 | adapter->msix_entries[vector].entry = vector; |
| 1652 | 1693 | |
| 1653 | 1694 | err = iavf_acquire_msix_vectors(adapter, v_budget); |
| 1695 | + if (!err) | |
| 1696 | + iavf_schedule_finish_config(adapter); | |
| 1654 | 1697 | |
| 1655 | 1698 | out: |
| 1656 | − netif_set_real_num_rx_queues(adapter->netdev, pairs); | |
| 1657 | − netif_set_real_num_tx_queues(adapter->netdev, pairs); | |
| 1658 | 1699 | return err; |
| 1659 | 1700 | } |
| 1660 | 1701 | |
| @@ -1828,19 +1869,16 @@ static int iavf_alloc_q_vectors(struct iavf_adapter *adapter) · 167 unmodified lines | ||
| 1828 | 1869 | static void iavf_free_q_vectors(struct iavf_adapter *adapter) |
| 1829 | 1870 | { |
| 1830 | 1871 | int q_idx, num_q_vectors; |
| 1831 | − int napi_vectors; | |
| 1832 | 1872 | |
| 1833 | 1873 | if (!adapter->q_vectors) |
| 1834 | 1874 | return; |
| 1835 | 1875 | |
| 1836 | 1876 | num_q_vectors = adapter->num_msix_vectors - NONQ_VECS; |
| 1837 | − napi_vectors = adapter->num_active_queues; | |
| 1838 | 1877 | |
| 1839 | 1878 | for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { |
| 1840 | 1879 | struct iavf_q_vector *q_vector = &adapter->q_vectors[q_idx]; |
| 1841 | 1880 | |
| 1842 | − if (q_idx < napi_vectors) | |
| 1843 | − netif_napi_del(&q_vector->napi); | |
| 1881 | + netif_napi_del(&q_vector->napi); | |
| 1844 | 1882 | } |
| 1845 | 1883 | kfree(adapter->q_vectors); |
| 1846 | 1884 | adapter->q_vectors = NULL; |
| @@ -1877,9 +1915,7 @@ static int iavf_init_interrupt_scheme(struct iavf_adapter *adapter) · 30 unmodified lines | ||
| 1877 | 1915 | goto err_alloc_queues; |
| 1878 | 1916 | } |
| 1879 | 1917 | |
| 1880 | − rtnl_lock(); | |
| 1881 | 1918 | err = iavf_set_interrupt_capability(adapter); |
| 1882 | − rtnl_unlock(); | |
| 1883 | 1919 | if (err) { |
| 1884 | 1920 | dev_err(&adapter->pdev->dev, |
| 1885 | 1921 | "Unable to setup interrupt capabilities\n"); |
| @@ -1932,15 +1968,16 @@ static void iavf_free_rss(struct iavf_adapter *adapter) · 46 unmodified lines | ||
| 1932 | 1968 | /** |
| 1933 | 1969 | * iavf_reinit_interrupt_scheme - Reallocate queues and vectors |
| 1934 | 1970 | * @adapter: board private structure |
| 1971 | + * @running: true if adapter->state == __IAVF_RUNNING | |
| 1935 | 1972 | * |
| 1936 | 1973 | * Returns 0 on success, negative on failure |
| 1937 | 1974 | **/ |
| 1938 | −static int iavf_reinit_interrupt_scheme(struct iavf_adapter *adapter) | |
| 1975 | +static int iavf_reinit_interrupt_scheme(struct iavf_adapter *adapter, bool running) | |
| 1939 | 1976 | { |
| 1940 | 1977 | struct net_device *netdev = adapter->netdev; |
| 1941 | 1978 | int err; |
| 1942 | 1979 | |
| 1943 | − if (netif_running(netdev)) | |
| 1980 | + if (running) | |
| 1944 | 1981 | iavf_free_traffic_irqs(adapter); |
| 1945 | 1982 | iavf_free_misc_irq(adapter); |
| 1946 | 1983 | iavf_reset_interrupt_capability(adapter); |
| @@ -1964,6 +2001,78 @@ err: · 17 unmodified lines | ||
| 1964 | 2001 | return err; |
| 1965 | 2002 | } |
| 1966 | 2003 | |
| 2004 | +/** | |
| 2005 | + * iavf_finish_config - do all netdev work that needs RTNL | |
| 2006 | + * @work: our work_struct | |
| 2007 | + * | |
| 2008 | + * Do work that needs both RTNL and crit_lock. | |
| 2009 | + **/ | |
| 2010 | +static void iavf_finish_config(struct work_struct *work) | |
| 2011 | +{ | |
| 2012 | + struct iavf_adapter *adapter; | |
| 2013 | + int pairs, err; | |
| 2014 | + | |
| 2015 | + adapter = container_of(work, struct iavf_adapter, finish_config); | |
| 2016 | + | |
| 2017 | + /* Always take RTNL first to prevent circular lock dependency */ | |
| 2018 | + rtnl_lock(); | |
| 2019 | + mutex_lock(&adapter->crit_lock); | |
| 2020 | + | |
| 2021 | + if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES) && | |
| 2022 | + adapter->netdev_registered && | |
| 2023 | + !test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) { | |
| 2024 | + netdev_update_features(adapter->netdev); | |
| 2025 | + adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES; | |
| 2026 | + } | |
| 2027 | + | |
| 2028 | + switch (adapter->state) { | |
| 2029 | + case __IAVF_DOWN: | |
| 2030 | + if (!adapter->netdev_registered) { | |
| 2031 | + err = register_netdevice(adapter->netdev); | |
| 2032 | + if (err) { | |
| 2033 | + dev_err(&adapter->pdev->dev, "Unable to register netdev (%d)\n", | |
| 2034 | + err); | |
| 2035 | + | |
| 2036 | + /* go back and try again.*/ | |
| 2037 | + iavf_free_rss(adapter); | |
| 2038 | + iavf_free_misc_irq(adapter); | |
| 2039 | + iavf_reset_interrupt_capability(adapter); | |
| 2040 | + iavf_change_state(adapter, | |
| 2041 | + __IAVF_INIT_CONFIG_ADAPTER); | |
| 2042 | + goto out; | |
| 2043 | + } | |
| 2044 | + adapter->netdev_registered = true; | |
| 2045 | + } | |
| 2046 | + | |
| 2047 | + /* Set the real number of queues when reset occurs while | |
| 2048 | + * state == __IAVF_DOWN | |
| 2049 | + */ | |
| 2050 | + fallthrough; | |
| 2051 | + case __IAVF_RUNNING: | |
| 2052 | + pairs = adapter->num_active_queues; | |
| 2053 | + netif_set_real_num_rx_queues(adapter->netdev, pairs); | |
| 2054 | + netif_set_real_num_tx_queues(adapter->netdev, pairs); | |
| 2055 | + break; | |
| 2056 | + | |
| 2057 | + default: | |
| 2058 | + break; | |
| 2059 | + } | |
| 2060 | + | |
| 2061 | +out: | |
| 2062 | + mutex_unlock(&adapter->crit_lock); | |
| 2063 | + rtnl_unlock(); | |
| 2064 | +} | |
| 2065 | + | |
| 2066 | +/** | |
| 2067 | + * iavf_schedule_finish_config - Set the flags and schedule a reset event | |
| 2068 | + * @adapter: board private structure | |
| 2069 | + **/ | |
| 2070 | +void iavf_schedule_finish_config(struct iavf_adapter *adapter) | |
| 2071 | +{ | |
| 2072 | + if (!test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) | |
| 2073 | + queue_work(adapter->wq, &adapter->finish_config); | |
| 2074 | +} | |
| 2075 | + | |
| 1967 | 2076 | /** |
| 1968 | 2077 | * iavf_process_aq_command - process aq_required flags |
| 1969 | 2078 | * and sends aq command |
| @@ -2371,7 +2480,7 @@ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter) · 401 unmodified lines | ||
| 2371 | 2480 | adapter->vsi_res->num_queue_pairs); |
| 2372 | 2481 | adapter->flags |= IAVF_FLAG_REINIT_MSIX_NEEDED; |
| 2373 | 2482 | adapter->num_req_queues = adapter->vsi_res->num_queue_pairs; |
| 2374 | − iavf_schedule_reset(adapter); | |
| 2483 | + iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); | |
| 2375 | 2484 | |
| 2376 | 2485 | return -EAGAIN; |
| 2377 | 2486 | } |
| @@ -2601,22 +2710,8 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter) · 223 unmodified lines | ||
| 2601 | 2710 | |
| 2602 | 2711 | netif_carrier_off(netdev); |
| 2603 | 2712 | adapter->link_up = false; |
| 2604 | − | |
| 2605 | − /* set the semaphore to prevent any callbacks after device registration | |
| 2606 | − * up to time when state of driver will be set to __IAVF_DOWN | |
| 2607 | − */ | |
| 2608 | − rtnl_lock(); | |
| 2609 | − if (!adapter->netdev_registered) { | |
| 2610 | − err = register_netdevice(netdev); | |
| 2611 | − if (err) { | |
| 2612 | − rtnl_unlock(); | |
| 2613 | − goto err_register; | |
| 2614 | − } | |
| 2615 | − } | |
| 2616 | − | |
| 2617 | − adapter->netdev_registered = true; | |
| 2618 | − | |
| 2619 | 2713 | netif_tx_stop_all_queues(netdev); |
| 2714 | + | |
| 2620 | 2715 | if (CLIENT_ALLOWED(adapter)) { |
| 2621 | 2716 | err = iavf_lan_add_device(adapter); |
| 2622 | 2717 | if (err) |
| @@ -2629,7 +2724,6 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter) · 6 unmodified lines | ||
| 2629 | 2724 | |
| 2630 | 2725 | iavf_change_state(adapter, __IAVF_DOWN); |
| 2631 | 2726 | set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); |
| 2632 | − rtnl_unlock(); | |
| 2633 | 2727 | |
| 2634 | 2728 | iavf_misc_irq_enable(adapter); |
| 2635 | 2729 | wake_up(&adapter->down_waitqueue); |
| @@ -2649,10 +2743,11 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter) · 13 unmodified lines | ||
| 2649 | 2743 | /* request initial VLAN offload settings */ |
| 2650 | 2744 | iavf_set_vlan_offload_features(adapter, 0, netdev->features); |
| 2651 | 2745 | |
| 2746 | + iavf_schedule_finish_config(adapter); | |
| 2652 | 2747 | return; |
| 2748 | + | |
| 2653 | 2749 | err_mem: |
| 2654 | 2750 | iavf_free_rss(adapter); |
| 2655 | −err_register: | |
| 2656 | 2751 | iavf_free_misc_irq(adapter); |
| 2657 | 2752 | err_sw_init: |
| 2658 | 2753 | iavf_reset_interrupt_capability(adapter); |
| @@ -2679,26 +2774,9 @@ static void iavf_watchdog_task(struct work_struct *work) · 20 unmodified lines | ||
| 2679 | 2774 | goto restart_watchdog; |
| 2680 | 2775 | } |
| 2681 | 2776 | |
| 2682 | − if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES) && | |
| 2683 | − adapter->netdev_registered && | |
| 2684 | − !test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section) && | |
| 2685 | − rtnl_trylock()) { | |
| 2686 | − netdev_update_features(adapter->netdev); | |
| 2687 | − rtnl_unlock(); | |
| 2688 | − adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES; | |
| 2689 | − } | |
| 2690 | − | |
| 2691 | 2777 | if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) |
| 2692 | 2778 | iavf_change_state(adapter, __IAVF_COMM_FAILED); |
| 2693 | 2779 | |
| 2694 | − if (adapter->flags & IAVF_FLAG_RESET_NEEDED) { | |
| 2695 | − adapter->aq_required = 0; | |
| 2696 | − adapter->current_op = VIRTCHNL_OP_UNKNOWN; | |
| 2697 | − mutex_unlock(&adapter->crit_lock); | |
| 2698 | − queue_work(adapter->wq, &adapter->reset_task); | |
| 2699 | − return; | |
| 2700 | − } | |
| 2701 | − | |
| 2702 | 2780 | switch (adapter->state) { |
| 2703 | 2781 | case __IAVF_STARTUP: |
| 2704 | 2782 | iavf_startup(adapter); |
| @@ -2826,11 +2904,10 @@ static void iavf_watchdog_task(struct work_struct *work) · 121 unmodified lines | ||
| 2826 | 2904 | /* check for hw reset */ |
| 2827 | 2905 | reg_val = rd32(hw, IAVF_VF_ARQLEN1) & IAVF_VF_ARQLEN1_ARQENABLE_MASK; |
| 2828 | 2906 | if (!reg_val) { |
| 2829 | − adapter->flags |= IAVF_FLAG_RESET_PENDING; | |
| 2830 | 2907 | adapter->aq_required = 0; |
| 2831 | 2908 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; |
| 2832 | 2909 | dev_err(&adapter->pdev->dev, "Hardware reset detected\n"); |
| 2833 | − queue_work(adapter->wq, &adapter->reset_task); | |
| 2910 | + iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING); | |
| 2834 | 2911 | mutex_unlock(&adapter->crit_lock); |
| 2835 | 2912 | queue_delayed_work(adapter->wq, |
| 2836 | 2913 | &adapter->watchdog_task, HZ * 2); |
| @@ -2940,11 +3017,6 @@ static void iavf_reset_task(struct work_struct *work) · 103 unmodified lines | ||
| 2940 | 3017 | int i = 0, err; |
| 2941 | 3018 | bool running; |
| 2942 | 3019 | |
| 2943 | − /* Detach interface to avoid subsequent NDO callbacks */ | |
| 2944 | − rtnl_lock(); | |
| 2945 | − netif_device_detach(netdev); | |
| 2946 | − rtnl_unlock(); | |
| 2947 | − | |
| 2948 | 3020 | /* When device is being removed it doesn't make sense to run the reset |
| 2949 | 3021 | * task, just return in such a case. |
| 2950 | 3022 | */ |
| @@ -2952,7 +3024,7 @@ static void iavf_reset_task(struct work_struct *work) · 1 unmodified line | ||
| 2952 | 3024 | if (adapter->state != __IAVF_REMOVE) |
| 2953 | 3025 | queue_work(adapter->wq, &adapter->reset_task); |
| 2954 | 3026 | |
| 2955 | − goto reset_finish; | |
| 3027 | + return; | |
| 2956 | 3028 | } |
| 2957 | 3029 | |
| 2958 | 3030 | while (!mutex_trylock(&adapter->client_lock)) |
| @@ -3010,11 +3082,6 @@ static void iavf_reset_task(struct work_struct *work) · 51 unmodified lines | ||
| 3010 | 3082 | iavf_disable_vf(adapter); |
| 3011 | 3083 | mutex_unlock(&adapter->client_lock); |
| 3012 | 3084 | mutex_unlock(&adapter->crit_lock); |
| 3013 | − if (netif_running(netdev)) { | |
| 3014 | − rtnl_lock(); | |
| 3015 | − dev_close(netdev); | |
| 3016 | − rtnl_unlock(); | |
| 3017 | − } | |
| 3018 | 3085 | return; /* Do not attempt to reinit. It's dead, Jim. */ |
| 3019 | 3086 | } |
| 3020 | 3087 | |
| @@ -3056,7 +3123,7 @@ continue_reset: · 35 unmodified lines | ||
| 3056 | 3123 | |
| 3057 | 3124 | if ((adapter->flags & IAVF_FLAG_REINIT_MSIX_NEEDED) || |
| 3058 | 3125 | (adapter->flags & IAVF_FLAG_REINIT_ITR_NEEDED)) { |
| 3059 | − err = iavf_reinit_interrupt_scheme(adapter); | |
| 3126 | + err = iavf_reinit_interrupt_scheme(adapter, running); | |
| 3060 | 3127 | if (err) |
| 3061 | 3128 | goto reset_err; |
| 3062 | 3129 | } |
| @@ -3151,10 +3218,11 @@ continue_reset: · 88 unmodified lines | ||
| 3151 | 3218 | |
| 3152 | 3219 | adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; |
| 3153 | 3220 | |
| 3221 | + wake_up(&adapter->reset_waitqueue); | |
| 3154 | 3222 | mutex_unlock(&adapter->client_lock); |
| 3155 | 3223 | mutex_unlock(&adapter->crit_lock); |
| 3156 | 3224 | |
| 3157 | − goto reset_finish; | |
| 3225 | + return; | |
| 3158 | 3226 | reset_err: |
| 3159 | 3227 | if (running) { |
| 3160 | 3228 | set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); |
| @@ -3164,21 +3232,7 @@ reset_err: · 3 unmodified lines | ||
| 3164 | 3232 | |
| 3165 | 3233 | mutex_unlock(&adapter->client_lock); |
| 3166 | 3234 | mutex_unlock(&adapter->crit_lock); |
| 3167 | − | |
| 3168 | − if (netif_running(netdev)) { | |
| 3169 | − /* Close device to ensure that Tx queues will not be started | |
| 3170 | − * during netif_device_attach() at the end of the reset task. | |
| 3171 | − */ | |
| 3172 | − rtnl_lock(); | |
| 3173 | − dev_close(netdev); | |
| 3174 | − rtnl_unlock(); | |
| 3175 | − } | |
| 3176 | − | |
| 3177 | 3235 | dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); |
| 3178 | −reset_finish: | |
| 3179 | − rtnl_lock(); | |
| 3180 | − netif_device_attach(netdev); | |
| 3181 | − rtnl_unlock(); | |
| 3182 | 3236 | } |
| 3183 | 3237 | |
| 3184 | 3238 | /** |
| @@ -3227,9 +3281,7 @@ static void iavf_adminq_task(struct work_struct *work) · 42 unmodified lines | ||
| 3227 | 3281 | } while (pending); |
| 3228 | 3282 | mutex_unlock(&adapter->crit_lock); |
| 3229 | 3283 | |
| 3230 | − if ((adapter->flags & | |
| 3231 | − (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) || | |
| 3232 | − adapter->state == __IAVF_RESETTING) | |
| 3284 | + if (iavf_is_reset_in_progress(adapter)) | |
| 3233 | 3285 | goto freedom; |
| 3234 | 3286 | |
| 3235 | 3287 | /* check for error indications */ |
| @@ -4315,6 +4367,7 @@ static int iavf_close(struct net_device *netdev) · 1079 unmodified lines | ||
| 4315 | 4367 | static int iavf_change_mtu(struct net_device *netdev, int new_mtu) |
| 4316 | 4368 | { |
| 4317 | 4369 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 4370 | + int ret = 0; | |
| 4318 | 4371 | |
| 4319 | 4372 | netdev_dbg(netdev, "changing MTU from %d to %d\n", |
| 4320 | 4373 | netdev->mtu, new_mtu); |
| @@ -4325,11 +4378,15 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu) · 4 unmodified lines | ||
| 4325 | 4378 | } |
| 4326 | 4379 | |
| 4327 | 4380 | if (netif_running(netdev)) { |
| 4328 | − adapter->flags |= IAVF_FLAG_RESET_NEEDED; | |
| 4329 | − queue_work(adapter->wq, &adapter->reset_task); | |
| 4381 | + iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); | |
| 4382 | + ret = iavf_wait_for_reset(adapter); | |
| 4383 | + if (ret < 0) | |
| 4384 | + netdev_warn(netdev, "MTU change interrupted waiting for reset"); | |
| 4385 | + else if (ret) | |
| 4386 | + netdev_warn(netdev, "MTU change timed out waiting for reset"); | |
| 4330 | 4387 | } |
| 4331 | 4388 | |
| 4332 | − return 0; | |
| 4389 | + return ret; | |
| 4333 | 4390 | } |
| 4334 | 4391 | |
| 4335 | 4392 | #define NETIF_VLAN_OFFLOAD_FEATURES (NETIF_F_HW_VLAN_CTAG_RX | \ |
| @@ -4922,6 +4979,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 586 unmodified lines | ||
| 4922 | 4979 | |
| 4923 | 4980 | INIT_WORK(&adapter->reset_task, iavf_reset_task); |
| 4924 | 4981 | INIT_WORK(&adapter->adminq_task, iavf_adminq_task); |
| 4982 | + INIT_WORK(&adapter->finish_config, iavf_finish_config); | |
| 4925 | 4983 | INIT_DELAYED_WORK(&adapter->watchdog_task, iavf_watchdog_task); |
| 4926 | 4984 | INIT_DELAYED_WORK(&adapter->client_task, iavf_client_task); |
| 4927 | 4985 | queue_delayed_work(adapter->wq, &adapter->watchdog_task, |
| @@ -4930,6 +4988,9 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 2 unmodified lines | ||
| 4930 | 4988 | /* Setup the wait queue for indicating transition to down status */ |
| 4931 | 4989 | init_waitqueue_head(&adapter->down_waitqueue); |
| 4932 | 4990 | |
| 4991 | + /* Setup the wait queue for indicating transition to running state */ | |
| 4992 | + init_waitqueue_head(&adapter->reset_waitqueue); | |
| 4993 | + | |
| 4933 | 4994 | /* Setup the wait queue for indicating virtchannel events */ |
| 4934 | 4995 | init_waitqueue_head(&adapter->vc_waitqueue); |
| 4935 | 4996 | |
| @@ -5061,13 +5122,15 @@ static void iavf_remove(struct pci_dev *pdev) · 125 unmodified lines | ||
| 5061 | 5122 | usleep_range(500, 1000); |
| 5062 | 5123 | } |
| 5063 | 5124 | cancel_delayed_work_sync(&adapter->watchdog_task); |
| 5125 | + cancel_work_sync(&adapter->finish_config); | |
| 5064 | 5126 | |
| 5127 | + rtnl_lock(); | |
| 5065 | 5128 | if (adapter->netdev_registered) { |
| 5066 | − rtnl_lock(); | |
| 5067 | 5129 | unregister_netdevice(netdev); |
| 5068 | 5130 | adapter->netdev_registered = false; |
| 5069 | − rtnl_unlock(); | |
| 5070 | 5131 | } |
| 5132 | + rtnl_unlock(); | |
| 5133 | + | |
| 5071 | 5134 | if (CLIENT_ALLOWED(adapter)) { |
| 5072 | 5135 | err = iavf_lan_del_device(adapter); |
| 5073 | 5136 | if (err) |
| @@ -1961,9 +1961,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 1960 unmodified lines | ||
| 1961 | 1961 | case VIRTCHNL_EVENT_RESET_IMPENDING: |
| 1962 | 1962 | dev_info(&adapter->pdev->dev, "Reset indication received from the PF\n"); |
| 1963 | 1963 | if (!(adapter->flags & IAVF_FLAG_RESET_PENDING)) { |
| 1964 | − adapter->flags |= IAVF_FLAG_RESET_PENDING; | |
| 1965 | 1964 | dev_info(&adapter->pdev->dev, "Scheduling reset task\n"); |
| 1966 | − queue_work(adapter->wq, &adapter->reset_task); | |
| 1965 | + iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING); | |
| 1967 | 1966 | } |
| 1968 | 1967 | break; |
| 1969 | 1968 | default: |
| @@ -2237,6 +2236,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 267 unmodified lines | ||
| 2237 | 2236 | |
| 2238 | 2237 | iavf_process_config(adapter); |
| 2239 | 2238 | adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES; |
| 2239 | + iavf_schedule_finish_config(adapter); | |
| 2240 | 2240 | |
| 2241 | 2241 | iavf_set_queue_vlan_tag_loc(adapter); |
| 2242 | 2242 | |
| @@ -2285,6 +2285,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 42 unmodified lines | ||
| 2285 | 2285 | case VIRTCHNL_OP_ENABLE_QUEUES: |
| 2286 | 2286 | /* enable transmits */ |
| 2287 | 2287 | iavf_irq_enable(adapter, true); |
| 2288 | + wake_up(&adapter->reset_waitqueue); | |
| 2288 | 2289 | adapter->flags &= ~IAVF_FLAG_QUEUES_DISABLED; |
| 2289 | 2290 | break; |
| 2290 | 2291 | case VIRTCHNL_OP_DISABLE_QUEUES: |
| @@ -800,6 +800,8 @@ void ice_vsi_free_q_vectors(struct ice_vsi *vsi) · 799 unmodified lines | ||
| 800 | 800 | |
| 801 | 801 | ice_for_each_q_vector(vsi, v_idx) |
| 802 | 802 | ice_free_q_vector(vsi, v_idx); |
| 803 | + | |
| 804 | + vsi->num_q_vectors = 0; | |
| 803 | 805 | } |
| 804 | 806 | |
| 805 | 807 | /** |
| @@ -2681,8 +2681,13 @@ ice_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, · 2680 unmodified lines | ||
| 2681 | 2681 | |
| 2682 | 2682 | ring->rx_max_pending = ICE_MAX_NUM_DESC; |
| 2683 | 2683 | ring->tx_max_pending = ICE_MAX_NUM_DESC; |
| 2684 | − ring->rx_pending = vsi->rx_rings[0]->count; | |
| 2685 | − ring->tx_pending = vsi->tx_rings[0]->count; | |
| 2684 | + if (vsi->tx_rings && vsi->rx_rings) { | |
| 2685 | + ring->rx_pending = vsi->rx_rings[0]->count; | |
| 2686 | + ring->tx_pending = vsi->tx_rings[0]->count; | |
| 2687 | + } else { | |
| 2688 | + ring->rx_pending = 0; | |
| 2689 | + ring->tx_pending = 0; | |
| 2690 | + } | |
| 2686 | 2691 | |
| 2687 | 2692 | /* Rx mini and jumbo rings are not supported */ |
| 2688 | 2693 | ring->rx_mini_max_pending = 0; |
| @@ -2716,6 +2721,10 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, · 27 unmodified lines | ||
| 2716 | 2721 | return -EINVAL; |
| 2717 | 2722 | } |
| 2718 | 2723 | |
| 2724 | + /* Return if there is no rings (device is reloading) */ | |
| 2725 | + if (!vsi->tx_rings || !vsi->rx_rings) | |
| 2726 | + return -EBUSY; | |
| 2727 | + | |
| 2719 | 2728 | new_tx_cnt = ALIGN(ring->tx_pending, ICE_REQ_DESC_MULTIPLE); |
| 2720 | 2729 | if (new_tx_cnt != ring->tx_pending) |
| 2721 | 2730 | netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n", |
| @@ -2972,39 +2972,12 @@ int ice_vsi_release(struct ice_vsi *vsi) · 2971 unmodified lines | ||
| 2972 | 2972 | return -ENODEV; |
| 2973 | 2973 | pf = vsi->back; |
| 2974 | 2974 | |
| 2975 | − /* do not unregister while driver is in the reset recovery pending | |
| 2976 | − * state. Since reset/rebuild happens through PF service task workqueue, | |
| 2977 | − * it's not a good idea to unregister netdev that is associated to the | |
| 2978 | − * PF that is running the work queue items currently. This is done to | |
| 2979 | − * avoid check_flush_dependency() warning on this wq | |
| 2980 | − */ | |
| 2981 | − if (vsi->netdev && !ice_is_reset_in_progress(pf->state) && | |
| 2982 | − (test_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state))) { | |
| 2983 | − unregister_netdev(vsi->netdev); | |
| 2984 | − clear_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state); | |
| 2985 | − } | |
| 2986 | − | |
| 2987 | − if (vsi->type == ICE_VSI_PF) | |
| 2988 | − ice_devlink_destroy_pf_port(pf); | |
| 2989 | − | |
| 2990 | 2975 | if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) |
| 2991 | 2976 | ice_rss_clean(vsi); |
| 2992 | 2977 | |
| 2993 | 2978 | ice_vsi_close(vsi); |
| 2994 | 2979 | ice_vsi_decfg(vsi); |
| 2995 | 2980 | |
| 2996 | − if (vsi->netdev) { | |
| 2997 | − if (test_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state)) { | |
| 2998 | − unregister_netdev(vsi->netdev); | |
| 2999 | − clear_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state); | |
| 3000 | − } | |
| 3001 | − if (test_bit(ICE_VSI_NETDEV_ALLOCD, vsi->state)) { | |
| 3002 | − free_netdev(vsi->netdev); | |
| 3003 | − vsi->netdev = NULL; | |
| 3004 | − clear_bit(ICE_VSI_NETDEV_ALLOCD, vsi->state); | |
| 3005 | − } | |
| 3006 | − } | |
| 3007 | − | |
| 3008 | 2981 | /* retain SW VSI data structure since it is needed to unregister and |
| 3009 | 2982 | * free VSI netdev when PF is not in reset recovery pending state,\ |
| 3010 | 2983 | * for ex: during rmmod. |
| @@ -4430,9 +4430,9 @@ static int ice_start_eth(struct ice_vsi *vsi) · 4429 unmodified lines | ||
| 4430 | 4430 | if (err) |
| 4431 | 4431 | return err; |
| 4432 | 4432 | |
| 4433 | − rtnl_lock(); | |
| 4434 | 4433 | err = ice_vsi_open(vsi); |
| 4435 | − rtnl_unlock(); | |
| 4434 | + if (err) | |
| 4435 | + ice_fltr_remove_all(vsi); | |
| 4436 | 4436 | |
| 4437 | 4437 | return err; |
| 4438 | 4438 | } |
| @@ -4895,6 +4895,7 @@ int ice_load(struct ice_pf *pf) · 456 unmodified lines | ||
| 4895 | 4895 | params = ice_vsi_to_params(vsi); |
| 4896 | 4896 | params.flags = ICE_VSI_FLAG_INIT; |
| 4897 | 4897 | |
| 4898 | + rtnl_lock(); | |
| 4898 | 4899 | err = ice_vsi_cfg(vsi, ¶ms); |
| 4899 | 4900 | if (err) |
| 4900 | 4901 | goto err_vsi_cfg; |
| @@ -4902,6 +4903,7 @@ int ice_load(struct ice_pf *pf) · 1 unmodified line | ||
| 4902 | 4903 | err = ice_start_eth(ice_get_main_vsi(pf)); |
| 4903 | 4904 | if (err) |
| 4904 | 4905 | goto err_start_eth; |
| 4906 | + rtnl_unlock(); | |
| 4905 | 4907 | |
| 4906 | 4908 | err = ice_init_rdma(pf); |
| 4907 | 4909 | if (err) |
| @@ -4916,9 +4918,11 @@ int ice_load(struct ice_pf *pf) · 8 unmodified lines | ||
| 4916 | 4918 | |
| 4917 | 4919 | err_init_rdma: |
| 4918 | 4920 | ice_vsi_close(ice_get_main_vsi(pf)); |
| 4921 | + rtnl_lock(); | |
| 4919 | 4922 | err_start_eth: |
| 4920 | 4923 | ice_vsi_decfg(ice_get_main_vsi(pf)); |
| 4921 | 4924 | err_vsi_cfg: |
| 4925 | + rtnl_unlock(); | |
| 4922 | 4926 | ice_deinit_dev(pf); |
| 4923 | 4927 | return err; |
| 4924 | 4928 | } |
| @@ -4931,8 +4935,10 @@ void ice_unload(struct ice_pf *pf) · 6 unmodified lines | ||
| 4931 | 4935 | { |
| 4932 | 4936 | ice_deinit_features(pf); |
| 4933 | 4937 | ice_deinit_rdma(pf); |
| 4938 | + rtnl_lock(); | |
| 4934 | 4939 | ice_stop_eth(ice_get_main_vsi(pf)); |
| 4935 | 4940 | ice_vsi_decfg(ice_get_main_vsi(pf)); |
| 4941 | + rtnl_unlock(); | |
| 4936 | 4942 | ice_deinit_dev(pf); |
| 4937 | 4943 | } |
| 4938 | 4944 | |
| @@ -2828,9 +2828,8 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring) · 2827 unmodified lines | ||
| 2828 | 2828 | struct netdev_queue *nq = txring_txq(ring); |
| 2829 | 2829 | union igc_adv_tx_desc *tx_desc = NULL; |
| 2830 | 2830 | int cpu = smp_processor_id(); |
| 2831 | − u16 ntu = ring->next_to_use; | |
| 2832 | 2831 | struct xdp_desc xdp_desc; |
| 2833 | − u16 budget; | |
| 2832 | + u16 budget, ntu; | |
| 2834 | 2833 | |
| 2835 | 2834 | if (!netif_carrier_ok(ring->netdev)) |
| 2836 | 2835 | return; |
| @@ -2840,6 +2839,7 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring) · 3 unmodified lines | ||
| 2840 | 2839 | /* Avoid transmit queue timeout since we share it with the slow path */ |
| 2841 | 2840 | txq_trans_cond_update(nq); |
| 2842 | 2841 | |
| 2842 | + ntu = ring->next_to_use; | |
| 2843 | 2843 | budget = igc_desc_unused(ring); |
| 2844 | 2844 | |
| 2845 | 2845 | while (xsk_tx_peek_desc(pool, &xdp_desc) && budget--) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2022 Marvell. |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <crypto/skcipher.h> | |
| 7 | 8 | #include <linux/rtnetlink.h> |
| 8 | 9 | #include <linux/bitfield.h> |
| 9 | 10 | #include "otx2_common.h" |
| @@ -42,6 +43,56 @@ · 32 unmodified lines | ||
| 42 | 43 | #define MCS_TCI_E 0x08 /* encryption */ |
| 43 | 44 | #define MCS_TCI_C 0x04 /* changed text */ |
| 44 | 45 | |
| 46 | +#define CN10K_MAX_HASH_LEN 16 | |
| 47 | +#define CN10K_MAX_SAK_LEN 32 | |
| 48 | + | |
| 49 | +static int cn10k_ecb_aes_encrypt(struct otx2_nic *pfvf, u8 *sak, | |
| 50 | + u16 sak_len, u8 *hash) | |
| 51 | +{ | |
| 52 | + u8 data[CN10K_MAX_HASH_LEN] = { 0 }; | |
| 53 | + struct skcipher_request *req = NULL; | |
| 54 | + struct scatterlist sg_src, sg_dst; | |
| 55 | + struct crypto_skcipher *tfm; | |
| 56 | + DECLARE_CRYPTO_WAIT(wait); | |
| 57 | + int err; | |
| 58 | + | |
| 59 | + tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0); | |
| 60 | + if (IS_ERR(tfm)) { | |
| 61 | + dev_err(pfvf->dev, "failed to allocate transform for ecb-aes\n"); | |
| 62 | + return PTR_ERR(tfm); | |
| 63 | + } | |
| 64 | + | |
| 65 | + req = skcipher_request_alloc(tfm, GFP_KERNEL); | |
| 66 | + if (!req) { | |
| 67 | + dev_err(pfvf->dev, "failed to allocate request for skcipher\n"); | |
| 68 | + err = -ENOMEM; | |
| 69 | + goto free_tfm; | |
| 70 | + } | |
| 71 | + | |
| 72 | + err = crypto_skcipher_setkey(tfm, sak, sak_len); | |
| 73 | + if (err) { | |
| 74 | + dev_err(pfvf->dev, "failed to set key for skcipher\n"); | |
| 75 | + goto free_req; | |
| 76 | + } | |
| 77 | + | |
| 78 | + /* build sg list */ | |
| 79 | + sg_init_one(&sg_src, data, CN10K_MAX_HASH_LEN); | |
| 80 | + sg_init_one(&sg_dst, hash, CN10K_MAX_HASH_LEN); | |
| 81 | + | |
| 82 | + skcipher_request_set_callback(req, 0, crypto_req_done, &wait); | |
| 83 | + skcipher_request_set_crypt(req, &sg_src, &sg_dst, | |
| 84 | + CN10K_MAX_HASH_LEN, NULL); | |
| 85 | + | |
| 86 | + err = crypto_skcipher_encrypt(req); | |
| 87 | + err = crypto_wait_req(err, &wait); | |
| 88 | + | |
| 89 | +free_req: | |
| 90 | + skcipher_request_free(req); | |
| 91 | +free_tfm: | |
| 92 | + crypto_free_skcipher(tfm); | |
| 93 | + return err; | |
| 94 | +} | |
| 95 | + | |
| 45 | 96 | static struct cn10k_mcs_txsc *cn10k_mcs_get_txsc(struct cn10k_mcs_cfg *cfg, |
| 46 | 97 | struct macsec_secy *secy) |
| 47 | 98 | { |
| @@ -330,19 +381,53 @@ fail: · 282 unmodified lines | ||
| 330 | 381 | return ret; |
| 331 | 382 | } |
| 332 | 383 | |
| 384 | +static int cn10k_mcs_write_keys(struct otx2_nic *pfvf, | |
| 385 | + struct macsec_secy *secy, | |
| 386 | + struct mcs_sa_plcy_write_req *req, | |
| 387 | + u8 *sak, u8 *salt, ssci_t ssci) | |
| 388 | +{ | |
| 389 | + u8 hash_rev[CN10K_MAX_HASH_LEN]; | |
| 390 | + u8 sak_rev[CN10K_MAX_SAK_LEN]; | |
| 391 | + u8 salt_rev[MACSEC_SALT_LEN]; | |
| 392 | + u8 hash[CN10K_MAX_HASH_LEN]; | |
| 393 | + u32 ssci_63_32; | |
| 394 | + int err, i; | |
| 395 | + | |
| 396 | + err = cn10k_ecb_aes_encrypt(pfvf, sak, secy->key_len, hash); | |
| 397 | + if (err) { | |
| 398 | + dev_err(pfvf->dev, "Generating hash using ECB(AES) failed\n"); | |
| 399 | + return err; | |
| 400 | + } | |
| 401 | + | |
| 402 | + for (i = 0; i < secy->key_len; i++) | |
| 403 | + sak_rev[i] = sak[secy->key_len - 1 - i]; | |
| 404 | + | |
| 405 | + for (i = 0; i < CN10K_MAX_HASH_LEN; i++) | |
| 406 | + hash_rev[i] = hash[CN10K_MAX_HASH_LEN - 1 - i]; | |
| 407 | + | |
| 408 | + for (i = 0; i < MACSEC_SALT_LEN; i++) | |
| 409 | + salt_rev[i] = salt[MACSEC_SALT_LEN - 1 - i]; | |
| 410 | + | |
| 411 | + ssci_63_32 = (__force u32)cpu_to_be32((__force u32)ssci); | |
| 412 | + | |
| 413 | + memcpy(&req->plcy[0][0], sak_rev, secy->key_len); | |
| 414 | + memcpy(&req->plcy[0][4], hash_rev, CN10K_MAX_HASH_LEN); | |
| 415 | + memcpy(&req->plcy[0][6], salt_rev, MACSEC_SALT_LEN); | |
| 416 | + req->plcy[0][7] |= (u64)ssci_63_32 << 32; | |
| 417 | + | |
| 418 | + return 0; | |
| 419 | +} | |
| 420 | + | |
| 333 | 421 | static int cn10k_mcs_write_rx_sa_plcy(struct otx2_nic *pfvf, |
| 334 | 422 | struct macsec_secy *secy, |
| 335 | 423 | struct cn10k_mcs_rxsc *rxsc, |
| 336 | 424 | u8 assoc_num, bool sa_in_use) |
| 337 | 425 | { |
| 338 | − unsigned char *src = rxsc->sa_key[assoc_num]; | |
| 339 | 426 | struct mcs_sa_plcy_write_req *plcy_req; |
| 340 | − u8 *salt_p = rxsc->salt[assoc_num]; | |
| 427 | + u8 *sak = rxsc->sa_key[assoc_num]; | |
| 428 | + u8 *salt = rxsc->salt[assoc_num]; | |
| 341 | 429 | struct mcs_rx_sc_sa_map *map_req; |
| 342 | 430 | struct mbox *mbox = &pfvf->mbox; |
| 343 | − u64 ssci_salt_95_64 = 0; | |
| 344 | − u8 reg, key_len; | |
| 345 | − u64 salt_63_0; | |
| 346 | 431 | int ret; |
| 347 | 432 | |
| 348 | 433 | mutex_lock(&mbox->lock); |
| @@ -360,20 +445,10 @@ static int cn10k_mcs_write_rx_sa_plcy(struct otx2_nic *pfvf, · 11 unmodified lines | ||
| 360 | 445 | goto fail; |
| 361 | 446 | } |
| 362 | 447 | |
| 363 | − for (reg = 0, key_len = 0; key_len < secy->key_len; key_len += 8) { | |
| 364 | − memcpy((u8 *)&plcy_req->plcy[0][reg], | |
| 365 | − (src + reg * 8), 8); | |
| 366 | − reg++; | |
| 367 | − } | |
| 368 | − | |
| 369 | − if (secy->xpn) { | |
| 370 | − memcpy((u8 *)&salt_63_0, salt_p, 8); | |
| 371 | − memcpy((u8 *)&ssci_salt_95_64, salt_p + 8, 4); | |
| 372 | − ssci_salt_95_64 |= (__force u64)rxsc->ssci[assoc_num] << 32; | |
| 373 | − | |
| 374 | − plcy_req->plcy[0][6] = salt_63_0; | |
| 375 | − plcy_req->plcy[0][7] = ssci_salt_95_64; | |
| 376 | − } | |
| 448 | + ret = cn10k_mcs_write_keys(pfvf, secy, plcy_req, sak, | |
| 449 | + salt, rxsc->ssci[assoc_num]); | |
| 450 | + if (ret) | |
| 451 | + goto fail; | |
| 377 | 452 | |
| 378 | 453 | plcy_req->sa_index[0] = rxsc->hw_sa_id[assoc_num]; |
| 379 | 454 | plcy_req->sa_cnt = 1; |
| @@ -586,13 +661,10 @@ static int cn10k_mcs_write_tx_sa_plcy(struct otx2_nic *pfvf, · 206 unmodified lines | ||
| 586 | 661 | struct cn10k_mcs_txsc *txsc, |
| 587 | 662 | u8 assoc_num) |
| 588 | 663 | { |
| 589 | − unsigned char *src = txsc->sa_key[assoc_num]; | |
| 590 | 664 | struct mcs_sa_plcy_write_req *plcy_req; |
| 591 | − u8 *salt_p = txsc->salt[assoc_num]; | |
| 665 | + u8 *sak = txsc->sa_key[assoc_num]; | |
| 666 | + u8 *salt = txsc->salt[assoc_num]; | |
| 592 | 667 | struct mbox *mbox = &pfvf->mbox; |
| 593 | − u64 ssci_salt_95_64 = 0; | |
| 594 | − u8 reg, key_len; | |
| 595 | − u64 salt_63_0; | |
| 596 | 668 | int ret; |
| 597 | 669 | |
| 598 | 670 | mutex_lock(&mbox->lock); |
| @@ -603,19 +675,10 @@ static int cn10k_mcs_write_tx_sa_plcy(struct otx2_nic *pfvf, · 4 unmodified lines | ||
| 603 | 675 | goto fail; |
| 604 | 676 | } |
| 605 | 677 | |
| 606 | − for (reg = 0, key_len = 0; key_len < secy->key_len; key_len += 8) { | |
| 607 | − memcpy((u8 *)&plcy_req->plcy[0][reg], (src + reg * 8), 8); | |
| 608 | − reg++; | |
| 609 | − } | |
| 610 | − | |
| 611 | − if (secy->xpn) { | |
| 612 | − memcpy((u8 *)&salt_63_0, salt_p, 8); | |
| 613 | − memcpy((u8 *)&ssci_salt_95_64, salt_p + 8, 4); | |
| 614 | − ssci_salt_95_64 |= (__force u64)txsc->ssci[assoc_num] << 32; | |
| 615 | − | |
| 616 | − plcy_req->plcy[0][6] = salt_63_0; | |
| 617 | − plcy_req->plcy[0][7] = ssci_salt_95_64; | |
| 618 | − } | |
| 678 | + ret = cn10k_mcs_write_keys(pfvf, secy, plcy_req, sak, | |
| 679 | + salt, txsc->ssci[assoc_num]); | |
| 680 | + if (ret) | |
| 681 | + goto fail; | |
| 619 | 682 | |
| 620 | 683 | plcy_req->plcy[0][8] = assoc_num; |
| 621 | 684 | plcy_req->sa_index[0] = txsc->hw_sa_id[assoc_num]; |
| @@ -1454,8 +1454,9 @@ static int otx2_init_hw_resources(struct otx2_nic *pf) · 1453 unmodified lines | ||
| 1454 | 1454 | if (err) |
| 1455 | 1455 | goto err_free_npa_lf; |
| 1456 | 1456 | |
| 1457 | − /* Enable backpressure */ | |
| 1458 | − otx2_nix_config_bp(pf, true); | |
| 1457 | + /* Enable backpressure for CGX mapped PF/VFs */ | |
| 1458 | + if (!is_otx2_lbkvf(pf->pdev)) | |
| 1459 | + otx2_nix_config_bp(pf, true); | |
| 1459 | 1460 | |
| 1460 | 1461 | /* Init Auras and pools used by NIX RQ, for free buffer ptrs */ |
| 1461 | 1462 | err = otx2_rq_aura_pool_init(pf); |
| @@ -3846,23 +3846,6 @@ static int mtk_hw_deinit(struct mtk_eth *eth) · 3845 unmodified lines | ||
| 3846 | 3846 | return 0; |
| 3847 | 3847 | } |
| 3848 | 3848 | |
| 3849 | −static int __init mtk_init(struct net_device *dev) | |
| 3850 | −{ | |
| 3851 | − struct mtk_mac *mac = netdev_priv(dev); | |
| 3852 | − struct mtk_eth *eth = mac->hw; | |
| 3853 | − int ret; | |
| 3854 | − | |
| 3855 | − ret = of_get_ethdev_address(mac->of_node, dev); | |
| 3856 | − if (ret) { | |
| 3857 | − /* If the mac address is invalid, use random mac address */ | |
| 3858 | − eth_hw_addr_random(dev); | |
| 3859 | − dev_err(eth->dev, "generated random MAC address %pM\n", | |
| 3860 | − dev->dev_addr); | |
| 3861 | − } | |
| 3862 | − | |
| 3863 | − return 0; | |
| 3864 | −} | |
| 3865 | − | |
| 3866 | 3849 | static void mtk_uninit(struct net_device *dev) |
| 3867 | 3850 | { |
| 3868 | 3851 | struct mtk_mac *mac = netdev_priv(dev); |
| @@ -4278,7 +4261,6 @@ static const struct ethtool_ops mtk_ethtool_ops = { · 409 unmodified lines | ||
| 4278 | 4261 | }; |
| 4279 | 4262 | |
| 4280 | 4263 | static const struct net_device_ops mtk_netdev_ops = { |
| 4281 | − .ndo_init = mtk_init, | |
| 4282 | 4264 | .ndo_uninit = mtk_uninit, |
| 4283 | 4265 | .ndo_open = mtk_open, |
| 4284 | 4266 | .ndo_stop = mtk_stop, |
| @@ -4340,6 +4322,17 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) · 55 unmodified lines | ||
| 4340 | 4322 | mac->hw = eth; |
| 4341 | 4323 | mac->of_node = np; |
| 4342 | 4324 | |
| 4325 | + err = of_get_ethdev_address(mac->of_node, eth->netdev[id]); | |
| 4326 | + if (err == -EPROBE_DEFER) | |
| 4327 | + return err; | |
| 4328 | + | |
| 4329 | + if (err) { | |
| 4330 | + /* If the mac address is invalid, use random mac address */ | |
| 4331 | + eth_hw_addr_random(eth->netdev[id]); | |
| 4332 | + dev_err(eth->dev, "generated random MAC address %pM\n", | |
| 4333 | + eth->netdev[id]->dev_addr); | |
| 4334 | + } | |
| 4335 | + | |
| 4343 | 4336 | memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip)); |
| 4344 | 4337 | mac->hwlro_ip_cnt = 0; |
| 4345 | 4338 | |
| @@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind) · 97 unmodified lines | ||
| 98 | 98 | |
| 99 | 99 | acct = mtk_foe_entry_get_mib(ppe, i, NULL); |
| 100 | 100 | |
| 101 | − type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); | |
| 101 | + type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); | |
| 102 | 102 | seq_printf(m, "%05x %s %7s", i, |
| 103 | 103 | mtk_foe_entry_state_str(state), |
| 104 | 104 | mtk_foe_pkt_type_str(type)); |
| @@ -368,7 +368,8 @@ static bool ocelot_fdma_receive_skb(struct ocelot *ocelot, struct sk_buff *skb) · 367 unmodified lines | ||
| 368 | 368 | if (unlikely(!ndev)) |
| 369 | 369 | return false; |
| 370 | 370 | |
| 371 | − pskb_trim(skb, skb->len - ETH_FCS_LEN); | |
| 371 | + if (pskb_trim(skb, skb->len - ETH_FCS_LEN)) | |
| 372 | + return false; | |
| 372 | 373 | |
| 373 | 374 | skb->dev = ndev; |
| 374 | 375 | skb->protocol = eth_type_trans(skb, skb->dev); |
| @@ -1260,8 +1260,11 @@ static int emac_tso_csum(struct emac_adapter *adpt, · 1259 unmodified lines | ||
| 1260 | 1260 | if (skb->protocol == htons(ETH_P_IP)) { |
| 1261 | 1261 | u32 pkt_len = ((unsigned char *)ip_hdr(skb) - skb->data) |
| 1262 | 1262 | + ntohs(ip_hdr(skb)->tot_len); |
| 1263 | − if (skb->len > pkt_len) | |
| 1264 | − pskb_trim(skb, pkt_len); | |
| 1263 | + if (skb->len > pkt_len) { | |
| 1264 | + ret = pskb_trim(skb, pkt_len); | |
| 1265 | + if (unlikely(ret)) | |
| 1266 | + return ret; | |
| 1267 | + } | |
| 1265 | 1268 | } |
| 1266 | 1269 | |
| 1267 | 1270 | hdr_len = skb_tcp_all_headers(skb); |
| @@ -623,6 +623,7 @@ struct rtl8169_private { · 622 unmodified lines | ||
| 623 | 623 | int cfg9346_usage_count; |
| 624 | 624 | |
| 625 | 625 | unsigned supports_gmii:1; |
| 626 | + unsigned aspm_manageable:1; | |
| 626 | 627 | dma_addr_t counters_phys_addr; |
| 627 | 628 | struct rtl8169_counters *counters; |
| 628 | 629 | struct rtl8169_tc_offsets tc_offset; |
| @@ -2746,7 +2747,15 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) · 2117 unmodified lines | ||
| 2746 | 2747 | if (tp->mac_version < RTL_GIGA_MAC_VER_32) |
| 2747 | 2748 | return; |
| 2748 | 2749 | |
| 2749 | − if (enable) { | |
| 2750 | + /* Don't enable ASPM in the chip if OS can't control ASPM */ | |
| 2751 | + if (enable && tp->aspm_manageable) { | |
| 2752 | + /* On these chip versions ASPM can even harm | |
| 2753 | + * bus communication of other PCI devices. | |
| 2754 | + */ | |
| 2755 | + if (tp->mac_version == RTL_GIGA_MAC_VER_42 || | |
| 2756 | + tp->mac_version == RTL_GIGA_MAC_VER_43) | |
| 2757 | + return; | |
| 2758 | + | |
| 2750 | 2759 | rtl_mod_config5(tp, 0, ASPM_en); |
| 2751 | 2760 | rtl_mod_config2(tp, 0, ClkReqEn); |
| 2752 | 2761 | |
| @@ -4514,10 +4523,6 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) · 1761 unmodified lines | ||
| 4514 | 4523 | } |
| 4515 | 4524 | |
| 4516 | 4525 | if (napi_schedule_prep(&tp->napi)) { |
| 4517 | − rtl_unlock_config_regs(tp); | |
| 4518 | − rtl_hw_aspm_clkreq_enable(tp, false); | |
| 4519 | − rtl_lock_config_regs(tp); | |
| 4520 | − | |
| 4521 | 4526 | rtl_irq_disable(tp); |
| 4522 | 4527 | __napi_schedule(&tp->napi); |
| 4523 | 4528 | } |
| @@ -4577,14 +4582,9 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) · 53 unmodified lines | ||
| 4577 | 4582 | |
| 4578 | 4583 | work_done = rtl_rx(dev, tp, budget); |
| 4579 | 4584 | |
| 4580 | − if (work_done < budget && napi_complete_done(napi, work_done)) { | |
| 4585 | + if (work_done < budget && napi_complete_done(napi, work_done)) | |
| 4581 | 4586 | rtl_irq_enable(tp); |
| 4582 | 4587 | |
| 4583 | − rtl_unlock_config_regs(tp); | |
| 4584 | − rtl_hw_aspm_clkreq_enable(tp, true); | |
| 4585 | − rtl_lock_config_regs(tp); | |
| 4586 | − } | |
| 4587 | − | |
| 4588 | 4588 | return work_done; |
| 4589 | 4589 | } |
| 4590 | 4590 | |
| @@ -5158,6 +5158,16 @@ done: · 567 unmodified lines | ||
| 5158 | 5158 | rtl_rar_set(tp, mac_addr); |
| 5159 | 5159 | } |
| 5160 | 5160 | |
| 5161 | +/* register is set if system vendor successfully tested ASPM 1.2 */ | |
| 5162 | +static bool rtl_aspm_is_safe(struct rtl8169_private *tp) | |
| 5163 | +{ | |
| 5164 | + if (tp->mac_version >= RTL_GIGA_MAC_VER_61 && | |
| 5165 | + r8168_mac_ocp_read(tp, 0xc0b2) & 0xf) | |
| 5166 | + return true; | |
| 5167 | + | |
| 5168 | + return false; | |
| 5169 | +} | |
| 5170 | + | |
| 5161 | 5171 | static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 5162 | 5172 | { |
| 5163 | 5173 | struct rtl8169_private *tp; |
| @@ -5227,6 +5237,19 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 63 unmodified lines | ||
| 5227 | 5237 | xid); |
| 5228 | 5238 | tp->mac_version = chipset; |
| 5229 | 5239 | |
| 5240 | + /* Disable ASPM L1 as that cause random device stop working | |
| 5241 | + * problems as well as full system hangs for some PCIe devices users. | |
| 5242 | + * Chips from RTL8168h partially have issues with L1.2, but seem | |
| 5243 | + * to work fine with L1 and L1.1. | |
| 5244 | + */ | |
| 5245 | + if (rtl_aspm_is_safe(tp)) | |
| 5246 | + rc = 0; | |
| 5247 | + else if (tp->mac_version >= RTL_GIGA_MAC_VER_46) | |
| 5248 | + rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1_2); | |
| 5249 | + else | |
| 5250 | + rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1); | |
| 5251 | + tp->aspm_manageable = !rc; | |
| 5252 | + | |
| 5230 | 5253 | tp->dash_type = rtl_check_dash(tp); |
| 5231 | 5254 | |
| 5232 | 5255 | tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; |
| @@ -106,23 +106,37 @@ struct cpsw_ale_dev_id { · 105 unmodified lines | ||
| 106 | 106 | |
| 107 | 107 | static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) |
| 108 | 108 | { |
| 109 | − int idx; | |
| 109 | + int idx, idx2; | |
| 110 | + u32 hi_val = 0; | |
| 110 | 111 | |
| 111 | 112 | idx = start / 32; |
| 113 | + idx2 = (start + bits - 1) / 32; | |
| 114 | + /* Check if bits to be fetched exceed a word */ | |
| 115 | + if (idx != idx2) { | |
| 116 | + idx2 = 2 - idx2; /* flip */ | |
| 117 | + hi_val = ale_entry[idx2] << ((idx2 * 32) - start); | |
| 118 | + } | |
| 112 | 119 | start -= idx * 32; |
| 113 | 120 | idx = 2 - idx; /* flip */ |
| 114 | − return (ale_entry[idx] >> start) & BITMASK(bits); | |
| 121 | + return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits); | |
| 115 | 122 | } |
| 116 | 123 | |
| 117 | 124 | static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, |
| 118 | 125 | u32 value) |
| 119 | 126 | { |
| 120 | − int idx; | |
| 127 | + int idx, idx2; | |
| 121 | 128 | |
| 122 | 129 | value &= BITMASK(bits); |
| 123 | − idx = start / 32; | |
| 130 | + idx = start / 32; | |
| 131 | + idx2 = (start + bits - 1) / 32; | |
| 132 | + /* Check if bits to be set exceed a word */ | |
| 133 | + if (idx != idx2) { | |
| 134 | + idx2 = 2 - idx2; /* flip */ | |
| 135 | + ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32))); | |
| 136 | + ale_entry[idx2] |= (value >> ((idx2 * 32) - start)); | |
| 137 | + } | |
| 124 | 138 | start -= idx * 32; |
| 125 | − idx = 2 - idx; /* flip */ | |
| 139 | + idx = 2 - idx; /* flip */ | |
| 126 | 140 | ale_entry[idx] &= ~(BITMASK(bits) << start); |
| 127 | 141 | ale_entry[idx] |= (value << start); |
| 128 | 142 | } |
| @@ -1511,7 +1511,6 @@ static void wx_configure_rx(struct wx *wx) · 1510 unmodified lines | ||
| 1511 | 1511 | psrtype = WX_RDB_PL_CFG_L4HDR | |
| 1512 | 1512 | WX_RDB_PL_CFG_L3HDR | |
| 1513 | 1513 | WX_RDB_PL_CFG_L2HDR | |
| 1514 | − WX_RDB_PL_CFG_TUN_TUNHDR | | |
| 1515 | 1514 | WX_RDB_PL_CFG_TUN_TUNHDR; |
| 1516 | 1515 | wr32(wx, WX_RDB_PL_CFG(0), psrtype); |
| 1517 | 1516 | |
| @@ -3451,23 +3451,30 @@ static int __init phy_init(void) · 3450 unmodified lines | ||
| 3451 | 3451 | { |
| 3452 | 3452 | int rc; |
| 3453 | 3453 | |
| 3454 | + ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops); | |
| 3455 | + | |
| 3454 | 3456 | rc = mdio_bus_init(); |
| 3455 | 3457 | if (rc) |
| 3456 | − return rc; | |
| 3458 | + goto err_ethtool_phy_ops; | |
| 3457 | 3459 | |
| 3458 | − ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops); | |
| 3459 | 3460 | features_init(); |
| 3460 | 3461 | |
| 3461 | 3462 | rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE); |
| 3462 | 3463 | if (rc) |
| 3463 | − goto err_c45; | |
| 3464 | + goto err_mdio_bus; | |
| 3464 | 3465 | |
| 3465 | 3466 | rc = phy_driver_register(&genphy_driver, THIS_MODULE); |
| 3466 | − if (rc) { | |
| 3467 | − phy_driver_unregister(&genphy_c45_driver); | |
| 3467 | + if (rc) | |
| 3468 | + goto err_c45; | |
| 3469 | + | |
| 3470 | + return 0; | |
| 3471 | + | |
| 3468 | 3472 | err_c45: |
| 3469 | − mdio_bus_exit(); | |
| 3470 | − } | |
| 3473 | + phy_driver_unregister(&genphy_c45_driver); | |
| 3474 | +err_mdio_bus: | |
| 3475 | + mdio_bus_exit(); | |
| 3476 | +err_ethtool_phy_ops: | |
| 3477 | + ethtool_set_ethtool_phy_ops(NULL); | |
| 3471 | 3478 | |
| 3472 | 3479 | return rc; |
| 3473 | 3480 | } |
| @@ -1775,6 +1775,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) · 1774 unmodified lines | ||
| 1775 | 1775 | } else if (!info->in || !info->out) |
| 1776 | 1776 | status = usbnet_get_endpoints (dev, udev); |
| 1777 | 1777 | else { |
| 1778 | + u8 ep_addrs[3] = { | |
| 1779 | + info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0 | |
| 1780 | + }; | |
| 1781 | + | |
| 1778 | 1782 | dev->in = usb_rcvbulkpipe (xdev, info->in); |
| 1779 | 1783 | dev->out = usb_sndbulkpipe (xdev, info->out); |
| 1780 | 1784 | if (!(info->flags & FLAG_NO_SETINT)) |
| @@ -1784,6 +1788,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) · 3 unmodified lines | ||
| 1784 | 1788 | else |
| 1785 | 1789 | status = 0; |
| 1786 | 1790 | |
| 1791 | + if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs)) | |
| 1792 | + status = -EINVAL; | |
| 1787 | 1793 | } |
| 1788 | 1794 | if (status >= 0 && dev->status) |
| 1789 | 1795 | status = init_status (dev, udev); |
| @@ -664,7 +664,7 @@ static int vrf_finish_output6(struct net *net, struct sock *sk, · 663 unmodified lines | ||
| 664 | 664 | skb->protocol = htons(ETH_P_IPV6); |
| 665 | 665 | skb->dev = dev; |
| 666 | 666 | |
| 667 | − rcu_read_lock_bh(); | |
| 667 | + rcu_read_lock(); | |
| 668 | 668 | nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr); |
| 669 | 669 | neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop); |
| 670 | 670 | if (unlikely(!neigh)) |
| @@ -672,10 +672,10 @@ static int vrf_finish_output6(struct net *net, struct sock *sk, · 1 unmodified line | ||
| 672 | 672 | if (!IS_ERR(neigh)) { |
| 673 | 673 | sock_confirm_neigh(skb, neigh); |
| 674 | 674 | ret = neigh_output(neigh, skb, false); |
| 675 | − rcu_read_unlock_bh(); | |
| 675 | + rcu_read_unlock(); | |
| 676 | 676 | return ret; |
| 677 | 677 | } |
| 678 | − rcu_read_unlock_bh(); | |
| 678 | + rcu_read_unlock(); | |
| 679 | 679 | |
| 680 | 680 | IP6_INC_STATS(dev_net(dst->dev), |
| 681 | 681 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
| @@ -889,7 +889,7 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s · 207 unmodified lines | ||
| 889 | 889 | } |
| 890 | 890 | } |
| 891 | 891 | |
| 892 | − rcu_read_lock_bh(); | |
| 892 | + rcu_read_lock(); | |
| 893 | 893 | |
| 894 | 894 | neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); |
| 895 | 895 | if (!IS_ERR(neigh)) { |
| @@ -898,11 +898,11 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s · 2 unmodified lines | ||
| 898 | 898 | sock_confirm_neigh(skb, neigh); |
| 899 | 899 | /* if crossing protocols, can not use the cached header */ |
| 900 | 900 | ret = neigh_output(neigh, skb, is_v6gw); |
| 901 | − rcu_read_unlock_bh(); | |
| 901 | + rcu_read_unlock(); | |
| 902 | 902 | return ret; |
| 903 | 903 | } |
| 904 | 904 | |
| 905 | − rcu_read_unlock_bh(); | |
| 905 | + rcu_read_unlock(); | |
| 906 | 906 | vrf_tx_error(skb->dev, skb); |
| 907 | 907 | return -EINVAL; |
| 908 | 908 | } |
| @@ -513,7 +513,7 @@ static inline void fastopen_queue_tune(struct sock *sk, int backlog) · 512 unmodified lines | ||
| 513 | 513 | struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; |
| 514 | 514 | int somaxconn = READ_ONCE(sock_net(sk)->core.sysctl_somaxconn); |
| 515 | 515 | |
| 516 | − queue->fastopenq.max_qlen = min_t(unsigned int, backlog, somaxconn); | |
| 516 | + WRITE_ONCE(queue->fastopenq.max_qlen, min_t(unsigned int, backlog, somaxconn)); | |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | 519 | static inline void tcp_move_syn(struct tcp_sock *tp, |
| @@ -593,9 +593,7 @@ struct hci_dev { · 592 unmodified lines | ||
| 593 | 593 | const char *fw_info; |
| 594 | 594 | struct dentry *debugfs; |
| 595 | 595 | |
| 596 | −#ifdef CONFIG_DEV_COREDUMP | |
| 597 | 596 | struct hci_devcoredump dump; |
| 598 | −#endif | |
| 599 | 597 | |
| 600 | 598 | struct device dev; |
| 601 | 599 | |
| @@ -822,6 +820,7 @@ struct hci_conn_params { · 220 unmodified lines | ||
| 822 | 820 | |
| 823 | 821 | struct hci_conn *conn; |
| 824 | 822 | bool explicit_connect; |
| 823 | + /* Accessed without hdev->lock: */ | |
| 825 | 824 | hci_conn_flags_t flags; |
| 826 | 825 | u8 privacy_mode; |
| 827 | 826 | }; |
| @@ -1573,7 +1572,11 @@ struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, · 745 unmodified lines | ||
| 1573 | 1572 | bdaddr_t *addr, u8 addr_type); |
| 1574 | 1573 | void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); |
| 1575 | 1574 | void hci_conn_params_clear_disabled(struct hci_dev *hdev); |
| 1575 | +void hci_conn_params_free(struct hci_conn_params *param); | |
| 1576 | 1576 | |
| 1577 | +void hci_pend_le_list_del_init(struct hci_conn_params *param); | |
| 1578 | +void hci_pend_le_list_add(struct hci_conn_params *param, | |
| 1579 | + struct list_head *list); | |
| 1577 | 1580 | struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, |
| 1578 | 1581 | bdaddr_t *addr, |
| 1579 | 1582 | u8 addr_type); |
| @@ -277,7 +277,7 @@ struct bond_vlan_tag { · 276 unmodified lines | ||
| 277 | 277 | unsigned short vlan_id; |
| 278 | 278 | }; |
| 279 | 279 | |
| 280 | −/** | |
| 280 | +/* | |
| 281 | 281 | * Returns NULL if the net_device does not belong to any of the bond's slaves |
| 282 | 282 | * |
| 283 | 283 | * Caller must hold bond lock for read |
| @@ -170,7 +170,8 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b) · 169 unmodified lines | ||
| 170 | 170 | } |
| 171 | 171 | |
| 172 | 172 | /** |
| 173 | − * @WPAN_PHY_FLAG_TRANSMIT_POWER: Indicates that transceiver will support | |
| 173 | + * enum wpan_phy_flags - WPAN PHY state flags | |
| 174 | + * @WPAN_PHY_FLAG_TXPOWER: Indicates that transceiver will support | |
| 174 | 175 | * transmit power setting. |
| 175 | 176 | * @WPAN_PHY_FLAG_CCA_ED_LEVEL: Indicates that transceiver will support cca ed |
| 176 | 177 | * level setting. |
| @@ -145,8 +145,8 @@ struct codel_vars { · 144 unmodified lines | ||
| 145 | 145 | * @maxpacket: largest packet we've seen so far |
| 146 | 146 | * @drop_count: temp count of dropped packets in dequeue() |
| 147 | 147 | * @drop_len: bytes of dropped packets in dequeue() |
| 148 | − * ecn_mark: number of packets we ECN marked instead of dropping | |
| 149 | − * ce_mark: number of packets CE marked because sojourn time was above ce_threshold | |
| 148 | + * @ecn_mark: number of packets we ECN marked instead of dropping | |
| 149 | + * @ce_mark: number of packets CE marked because sojourn time was above ce_threshold | |
| 150 | 150 | */ |
| 151 | 151 | struct codel_stats { |
| 152 | 152 | u32 maxpacket; |
| @@ -221,7 +221,7 @@ struct devlink_dpipe_field { · 220 unmodified lines | ||
| 221 | 221 | /** |
| 222 | 222 | * struct devlink_dpipe_header - dpipe header object |
| 223 | 223 | * @name: header name |
| 224 | − * @id: index, global/local detrmined by global bit | |
| 224 | + * @id: index, global/local determined by global bit | |
| 225 | 225 | * @fields: fields |
| 226 | 226 | * @fields_count: number of fields |
| 227 | 227 | * @global: indicates if header is shared like most protocol header |
| @@ -241,7 +241,7 @@ struct devlink_dpipe_header { · 13 unmodified lines | ||
| 241 | 241 | * @header_index: header index (packets can have several headers of same |
| 242 | 242 | * type like in case of tunnels) |
| 243 | 243 | * @header: header |
| 244 | − * @fieled_id: field index | |
| 244 | + * @field_id: field index | |
| 245 | 245 | */ |
| 246 | 246 | struct devlink_dpipe_match { |
| 247 | 247 | enum devlink_dpipe_match_type type; |
| @@ -256,7 +256,7 @@ struct devlink_dpipe_match { · 8 unmodified lines | ||
| 256 | 256 | * @header_index: header index (packets can have several headers of same |
| 257 | 257 | * type like in case of tunnels) |
| 258 | 258 | * @header: header |
| 259 | − * @fieled_id: field index | |
| 259 | + * @field_id: field index | |
| 260 | 260 | */ |
| 261 | 261 | struct devlink_dpipe_action { |
| 262 | 262 | enum devlink_dpipe_action_type type; |
| @@ -292,7 +292,7 @@ struct devlink_dpipe_value { · 29 unmodified lines | ||
| 292 | 292 | * struct devlink_dpipe_entry - table entry object |
| 293 | 293 | * @index: index of the entry in the table |
| 294 | 294 | * @match_values: match values |
| 295 | − * @matche_values_count: count of matches tuples | |
| 295 | + * @match_values_count: count of matches tuples | |
| 296 | 296 | * @action_values: actions values |
| 297 | 297 | * @action_values_count: count of actions values |
| 298 | 298 | * @counter: value of counter |
| @@ -342,7 +342,9 @@ struct devlink_dpipe_table_ops; · 43 unmodified lines | ||
| 342 | 342 | */ |
| 343 | 343 | struct devlink_dpipe_table { |
| 344 | 344 | void *priv; |
| 345 | + /* private: */ | |
| 345 | 346 | struct list_head list; |
| 347 | + /* public: */ | |
| 346 | 348 | const char *name; |
| 347 | 349 | bool counters_enabled; |
| 348 | 350 | bool counter_control_extern; |
| @@ -355,13 +357,13 @@ struct devlink_dpipe_table { · 6 unmodified lines | ||
| 355 | 357 | |
| 356 | 358 | /** |
| 357 | 359 | * struct devlink_dpipe_table_ops - dpipe_table ops |
| 358 | − * @actions_dump - dumps all tables actions | |
| 359 | − * @matches_dump - dumps all tables matches | |
| 360 | − * @entries_dump - dumps all active entries in the table | |
| 361 | − * @counters_set_update - when changing the counter status hardware sync | |
| 360 | + * @actions_dump: dumps all tables actions | |
| 361 | + * @matches_dump: dumps all tables matches | |
| 362 | + * @entries_dump: dumps all active entries in the table | |
| 363 | + * @counters_set_update: when changing the counter status hardware sync | |
| 362 | 364 | * maybe needed to allocate/free counter related |
| 363 | 365 | * resources |
| 364 | − * @size_get - get size | |
| 366 | + * @size_get: get size | |
| 365 | 367 | */ |
| 366 | 368 | struct devlink_dpipe_table_ops { |
| 367 | 369 | int (*actions_dump)(void *priv, struct sk_buff *skb); |
| @@ -374,8 +376,8 @@ struct devlink_dpipe_table_ops { · 6 unmodified lines | ||
| 374 | 376 | |
| 375 | 377 | /** |
| 376 | 378 | * struct devlink_dpipe_headers - dpipe headers |
| 377 | − * @headers - header array can be shared (global bit) or driver specific | |
| 378 | − * @headers_count - count of headers | |
| 379 | + * @headers: header array can be shared (global bit) or driver specific | |
| 380 | + * @headers_count: count of headers | |
| 379 | 381 | */ |
| 380 | 382 | struct devlink_dpipe_headers { |
| 381 | 383 | struct devlink_dpipe_header **headers; |
| @@ -387,7 +389,7 @@ struct devlink_dpipe_headers { · 5 unmodified lines | ||
| 387 | 389 | * @size_min: minimum size which can be set |
| 388 | 390 | * @size_max: maximum size which can be set |
| 389 | 391 | * @size_granularity: size granularity |
| 390 | − * @size_unit: resource's basic unit | |
| 392 | + * @unit: resource's basic unit | |
| 391 | 393 | */ |
| 392 | 394 | struct devlink_resource_size_params { |
| 393 | 395 | u64 size_min; |
| @@ -457,6 +459,7 @@ struct devlink_flash_notify { · 63 unmodified lines | ||
| 457 | 459 | |
| 458 | 460 | /** |
| 459 | 461 | * struct devlink_param - devlink configuration parameter data |
| 462 | + * @id: devlink parameter id number | |
| 460 | 463 | * @name: name of the parameter |
| 461 | 464 | * @generic: indicates if the parameter is generic or driver specific |
| 462 | 465 | * @type: parameter type |
| @@ -632,6 +635,7 @@ enum devlink_param_generic_id { · 169 unmodified lines | ||
| 632 | 635 | * struct devlink_flash_update_params - Flash Update parameters |
| 633 | 636 | * @fw: pointer to the firmware data to update from |
| 634 | 637 | * @component: the flash component to update |
| 638 | + * @overwrite_mask: which types of flash update are supported (may be %0) | |
| 635 | 639 | * |
| 636 | 640 | * With the exception of fw, drivers must opt-in to parameters by |
| 637 | 641 | * setting the appropriate bit in the supported_flash_update_params field in |
| @@ -29,7 +29,7 @@ struct fqdir { · 28 unmodified lines | ||
| 29 | 29 | }; |
| 30 | 30 | |
| 31 | 31 | /** |
| 32 | − * fragment queue flags | |
| 32 | + * enum: fragment queue flags | |
| 33 | 33 | * |
| 34 | 34 | * @INET_FRAG_FIRST_IN: first fragment has arrived |
| 35 | 35 | * @INET_FRAG_LAST_IN: final fragment has arrived |
| @@ -111,7 +111,7 @@ void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit); · 110 unmodified lines | ||
| 111 | 111 | void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit); |
| 112 | 112 | int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, u16 *how_many_unacked); |
| 113 | 113 | struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, |
| 114 | − struct llc_addr *laddr); | |
| 114 | + struct llc_addr *laddr, const struct net *net); | |
| 115 | 115 | void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk); |
| 116 | 116 | void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk); |
| 117 | 117 | |
| @@ -269,7 +269,7 @@ static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) · 268 unmodified lines | ||
| 269 | 269 | /** |
| 270 | 270 | * llc_pdu_decode_da - extracts dest address of input frame |
| 271 | 271 | * @skb: input skb that destination address must be extracted from it |
| 272 | − * @sa: pointer to destination address (6 byte array). | |
| 272 | + * @da: pointer to destination address (6 byte array). | |
| 273 | 273 | * |
| 274 | 274 | * This function extracts destination address(MAC) of input frame. |
| 275 | 275 | */ |
| @@ -321,7 +321,7 @@ static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb) · 45 unmodified lines | ||
| 321 | 321 | |
| 322 | 322 | /** |
| 323 | 323 | * llc_pdu_init_as_test_cmd - sets PDU as TEST |
| 324 | − * @skb - Address of the skb to build | |
| 324 | + * @skb: Address of the skb to build | |
| 325 | 325 | * |
| 326 | 326 | * Sets a PDU as TEST |
| 327 | 327 | */ |
| @@ -369,6 +369,8 @@ struct llc_xid_info { · 41 unmodified lines | ||
| 369 | 369 | /** |
| 370 | 370 | * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID |
| 371 | 371 | * @skb: input skb that header must be set into it. |
| 372 | + * @svcs_supported: The class of the LLC (I or II) | |
| 373 | + * @rx_window: The size of the receive window of the LLC | |
| 372 | 374 | * |
| 373 | 375 | * This function sets third,fourth,fifth and sixth bytes of LLC header as |
| 374 | 376 | * a XID PDU. |
| @@ -192,7 +192,7 @@ · 191 unmodified lines | ||
| 192 | 192 | |
| 193 | 193 | /** |
| 194 | 194 | * struct nsh_md1_ctx - Keeps track of NSH context data |
| 195 | − * @nshc<1-4>: NSH Contexts. | |
| 195 | + * @context: NSH Contexts. | |
| 196 | 196 | */ |
| 197 | 197 | struct nsh_md1_ctx { |
| 198 | 198 | __be32 context[4]; |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | /** |
| 18 | 18 | * struct pie_params - contains pie parameters |
| 19 | 19 | * @target: target delay in pschedtime |
| 20 | − * @tudpate: interval at which drop probability is calculated | |
| 20 | + * @tupdate: interval at which drop probability is calculated | |
| 21 | 21 | * @limit: total number of packets that can be in the queue |
| 22 | 22 | * @alpha: parameter to control drop probability |
| 23 | 23 | * @beta: parameter to control drop probability |
| @@ -1,4 +1,4 @@ | ||
| 1 | −/** | |
| 1 | +/* | |
| 2 | 2 | * Copyright (c) 2017 Redpine Signals Inc. |
| 3 | 3 | * |
| 4 | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
| @@ -1509,25 +1509,38 @@ void tcp_leave_memory_pressure(struct sock *sk); · 1508 unmodified lines | ||
| 1509 | 1509 | static inline int keepalive_intvl_when(const struct tcp_sock *tp) |
| 1510 | 1510 | { |
| 1511 | 1511 | struct net *net = sock_net((struct sock *)tp); |
| 1512 | + int val; | |
| 1512 | 1513 | |
| 1513 | − return tp->keepalive_intvl ? : | |
| 1514 | − READ_ONCE(net->ipv4.sysctl_tcp_keepalive_intvl); | |
| 1514 | + /* Paired with WRITE_ONCE() in tcp_sock_set_keepintvl() | |
| 1515 | + * and do_tcp_setsockopt(). | |
| 1516 | + */ | |
| 1517 | + val = READ_ONCE(tp->keepalive_intvl); | |
| 1518 | + | |
| 1519 | + return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_intvl); | |
| 1515 | 1520 | } |
| 1516 | 1521 | |
| 1517 | 1522 | static inline int keepalive_time_when(const struct tcp_sock *tp) |
| 1518 | 1523 | { |
| 1519 | 1524 | struct net *net = sock_net((struct sock *)tp); |
| 1525 | + int val; | |
| 1520 | 1526 | |
| 1521 | − return tp->keepalive_time ? : | |
| 1522 | − READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time); | |
| 1527 | + /* Paired with WRITE_ONCE() in tcp_sock_set_keepidle_locked() */ | |
| 1528 | + val = READ_ONCE(tp->keepalive_time); | |
| 1529 | + | |
| 1530 | + return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time); | |
| 1523 | 1531 | } |
| 1524 | 1532 | |
| 1525 | 1533 | static inline int keepalive_probes(const struct tcp_sock *tp) |
| 1526 | 1534 | { |
| 1527 | 1535 | struct net *net = sock_net((struct sock *)tp); |
| 1536 | + int val; | |
| 1528 | 1537 | |
| 1529 | − return tp->keepalive_probes ? : | |
| 1530 | − READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes); | |
| 1538 | + /* Paired with WRITE_ONCE() in tcp_sock_set_keepcnt() | |
| 1539 | + * and do_tcp_setsockopt(). | |
| 1540 | + */ | |
| 1541 | + val = READ_ONCE(tp->keepalive_probes); | |
| 1542 | + | |
| 1543 | + return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes); | |
| 1531 | 1544 | } |
| 1532 | 1545 | |
| 1533 | 1546 | static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp) |
| @@ -2048,7 +2061,11 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr); · 514 unmodified lines | ||
| 2048 | 2061 | static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp) |
| 2049 | 2062 | { |
| 2050 | 2063 | struct net *net = sock_net((struct sock *)tp); |
| 2051 | − return tp->notsent_lowat ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat); | |
| 2064 | + u32 val; | |
| 2065 | + | |
| 2066 | + val = READ_ONCE(tp->notsent_lowat); | |
| 2067 | + | |
| 2068 | + return val ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat); | |
| 2052 | 2069 | } |
| 2053 | 2070 | |
| 2054 | 2071 | bool tcp_stream_memory_free(const struct sock *sk, int wake); |
| @@ -5573,16 +5573,17 @@ static int update_stack_depth(struct bpf_verifier_env *env, · 5572 unmodified lines | ||
| 5573 | 5573 | * Since recursion is prevented by check_cfg() this algorithm |
| 5574 | 5574 | * only needs a local stack of MAX_CALL_FRAMES to remember callsites |
| 5575 | 5575 | */ |
| 5576 | −static int check_max_stack_depth(struct bpf_verifier_env *env) | |
| 5576 | +static int check_max_stack_depth_subprog(struct bpf_verifier_env *env, int idx) | |
| 5577 | 5577 | { |
| 5578 | − int depth = 0, frame = 0, idx = 0, i = 0, subprog_end; | |
| 5579 | 5578 | struct bpf_subprog_info *subprog = env->subprog_info; |
| 5580 | 5579 | struct bpf_insn *insn = env->prog->insnsi; |
| 5580 | + int depth = 0, frame = 0, i, subprog_end; | |
| 5581 | 5581 | bool tail_call_reachable = false; |
| 5582 | 5582 | int ret_insn[MAX_CALL_FRAMES]; |
| 5583 | 5583 | int ret_prog[MAX_CALL_FRAMES]; |
| 5584 | 5584 | int j; |
| 5585 | 5585 | |
| 5586 | + i = subprog[idx].start; | |
| 5586 | 5587 | process_func: |
| 5587 | 5588 | /* protect against potential stack overflow that might happen when |
| 5588 | 5589 | * bpf2bpf calls get combined with tailcalls. Limit the caller's stack |
| @@ -5621,7 +5622,7 @@ process_func: · 32 unmodified lines | ||
| 5621 | 5622 | continue_func: |
| 5622 | 5623 | subprog_end = subprog[idx + 1].start; |
| 5623 | 5624 | for (; i < subprog_end; i++) { |
| 5624 | − int next_insn; | |
| 5625 | + int next_insn, sidx; | |
| 5625 | 5626 | |
| 5626 | 5627 | if (!bpf_pseudo_call(insn + i) && !bpf_pseudo_func(insn + i)) |
| 5627 | 5628 | continue; |
| @@ -5631,14 +5632,14 @@ continue_func: · 3 unmodified lines | ||
| 5631 | 5632 | |
| 5632 | 5633 | /* find the callee */ |
| 5633 | 5634 | next_insn = i + insn[i].imm + 1; |
| 5634 | − idx = find_subprog(env, next_insn); | |
| 5635 | − if (idx < 0) { | |
| 5635 | + sidx = find_subprog(env, next_insn); | |
| 5636 | + if (sidx < 0) { | |
| 5636 | 5637 | WARN_ONCE(1, "verifier bug. No program starts at insn %d\n", |
| 5637 | 5638 | next_insn); |
| 5638 | 5639 | return -EFAULT; |
| 5639 | 5640 | } |
| 5640 | − if (subprog[idx].is_async_cb) { | |
| 5641 | − if (subprog[idx].has_tail_call) { | |
| 5641 | + if (subprog[sidx].is_async_cb) { | |
| 5642 | + if (subprog[sidx].has_tail_call) { | |
| 5642 | 5643 | verbose(env, "verifier bug. subprog has tail_call and async cb\n"); |
| 5643 | 5644 | return -EFAULT; |
| 5644 | 5645 | } |
| @@ -5647,6 +5648,7 @@ continue_func: · 2 unmodified lines | ||
| 5647 | 5648 | continue; |
| 5648 | 5649 | } |
| 5649 | 5650 | i = next_insn; |
| 5651 | + idx = sidx; | |
| 5650 | 5652 | |
| 5651 | 5653 | if (subprog[idx].has_tail_call) |
| 5652 | 5654 | tail_call_reachable = true; |
| @@ -5682,6 +5684,22 @@ continue_func: · 29 unmodified lines | ||
| 5682 | 5684 | goto continue_func; |
| 5683 | 5685 | } |
| 5684 | 5686 | |
| 5687 | +static int check_max_stack_depth(struct bpf_verifier_env *env) | |
| 5688 | +{ | |
| 5689 | + struct bpf_subprog_info *si = env->subprog_info; | |
| 5690 | + int ret; | |
| 5691 | + | |
| 5692 | + for (int i = 0; i < env->subprog_cnt; i++) { | |
| 5693 | + if (!i || si[i].is_async_cb) { | |
| 5694 | + ret = check_max_stack_depth_subprog(env, i); | |
| 5695 | + if (ret < 0) | |
| 5696 | + return ret; | |
| 5697 | + } | |
| 5698 | + continue; | |
| 5699 | + } | |
| 5700 | + return 0; | |
| 5701 | +} | |
| 5702 | + | |
| 5685 | 5703 | #ifndef CONFIG_BPF_JIT_ALWAYS_ON |
| 5686 | 5704 | static int get_callee_stack_depth(struct bpf_verifier_env *env, |
| 5687 | 5705 | const struct bpf_insn *insn, int idx) |
| @@ -118,7 +118,7 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status) · 117 unmodified lines | ||
| 118 | 118 | */ |
| 119 | 119 | params->explicit_connect = false; |
| 120 | 120 | |
| 121 | − list_del_init(¶ms->action); | |
| 121 | + hci_pend_le_list_del_init(params); | |
| 122 | 122 | |
| 123 | 123 | switch (params->auto_connect) { |
| 124 | 124 | case HCI_AUTO_CONN_EXPLICIT: |
| @@ -127,10 +127,10 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status) · 2 unmodified lines | ||
| 127 | 127 | return; |
| 128 | 128 | case HCI_AUTO_CONN_DIRECT: |
| 129 | 129 | case HCI_AUTO_CONN_ALWAYS: |
| 130 | − list_add(¶ms->action, &hdev->pend_le_conns); | |
| 130 | + hci_pend_le_list_add(params, &hdev->pend_le_conns); | |
| 131 | 131 | break; |
| 132 | 132 | case HCI_AUTO_CONN_REPORT: |
| 133 | − list_add(¶ms->action, &hdev->pend_le_reports); | |
| 133 | + hci_pend_le_list_add(params, &hdev->pend_le_reports); | |
| 134 | 134 | break; |
| 135 | 135 | default: |
| 136 | 136 | break; |
| @@ -1426,8 +1426,8 @@ static int hci_explicit_conn_params_set(struct hci_dev *hdev, · 1289 unmodified lines | ||
| 1426 | 1426 | if (params->auto_connect == HCI_AUTO_CONN_DISABLED || |
| 1427 | 1427 | params->auto_connect == HCI_AUTO_CONN_REPORT || |
| 1428 | 1428 | params->auto_connect == HCI_AUTO_CONN_EXPLICIT) { |
| 1429 | − list_del_init(¶ms->action); | |
| 1430 | − list_add(¶ms->action, &hdev->pend_le_conns); | |
| 1429 | + hci_pend_le_list_del_init(params); | |
| 1430 | + hci_pend_le_list_add(params, &hdev->pend_le_conns); | |
| 1431 | 1431 | } |
| 1432 | 1432 | |
| 1433 | 1433 | params->explicit_connect = true; |
| @@ -1684,7 +1684,7 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, · 250 unmodified lines | ||
| 1684 | 1684 | if (!link) { |
| 1685 | 1685 | hci_conn_drop(acl); |
| 1686 | 1686 | hci_conn_drop(sco); |
| 1687 | − return NULL; | |
| 1687 | + return ERR_PTR(-ENOLINK); | |
| 1688 | 1688 | } |
| 1689 | 1689 | |
| 1690 | 1690 | sco->setting = setting; |
| @@ -2254,7 +2254,7 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst, · 563 unmodified lines | ||
| 2254 | 2254 | if (!link) { |
| 2255 | 2255 | hci_conn_drop(le); |
| 2256 | 2256 | hci_conn_drop(cis); |
| 2257 | − return NULL; | |
| 2257 | + return ERR_PTR(-ENOLINK); | |
| 2258 | 2258 | } |
| 2259 | 2259 | |
| 2260 | 2260 | /* If LE is already connected and CIS handle is already set proceed to |
| @@ -1972,6 +1972,7 @@ static int hci_remove_adv_monitor(struct hci_dev *hdev, · 1971 unmodified lines | ||
| 1972 | 1972 | struct adv_monitor *monitor) |
| 1973 | 1973 | { |
| 1974 | 1974 | int status = 0; |
| 1975 | + int handle; | |
| 1975 | 1976 | |
| 1976 | 1977 | switch (hci_get_adv_monitor_offload_ext(hdev)) { |
| 1977 | 1978 | case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ |
| @@ -1980,9 +1981,10 @@ static int hci_remove_adv_monitor(struct hci_dev *hdev, · 2 unmodified lines | ||
| 1980 | 1981 | goto free_monitor; |
| 1981 | 1982 | |
| 1982 | 1983 | case HCI_ADV_MONITOR_EXT_MSFT: |
| 1984 | + handle = monitor->handle; | |
| 1983 | 1985 | status = msft_remove_monitor(hdev, monitor); |
| 1984 | 1986 | bt_dev_dbg(hdev, "%s remove monitor %d msft status %d", |
| 1985 | − hdev->name, monitor->handle, status); | |
| 1987 | + hdev->name, handle, status); | |
| 1986 | 1988 | break; |
| 1987 | 1989 | } |
| 1988 | 1990 | |
| @@ -2249,21 +2251,45 @@ struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, · 260 unmodified lines | ||
| 2249 | 2251 | return NULL; |
| 2250 | 2252 | } |
| 2251 | 2253 | |
| 2252 | −/* This function requires the caller holds hdev->lock */ | |
| 2254 | +/* This function requires the caller holds hdev->lock or rcu_read_lock */ | |
| 2253 | 2255 | struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, |
| 2254 | 2256 | bdaddr_t *addr, u8 addr_type) |
| 2255 | 2257 | { |
| 2256 | 2258 | struct hci_conn_params *param; |
| 2257 | 2259 | |
| 2258 | − list_for_each_entry(param, list, action) { | |
| 2260 | + rcu_read_lock(); | |
| 2261 | + | |
| 2262 | + list_for_each_entry_rcu(param, list, action) { | |
| 2259 | 2263 | if (bacmp(¶m->addr, addr) == 0 && |
| 2260 | − param->addr_type == addr_type) | |
| 2264 | + param->addr_type == addr_type) { | |
| 2265 | + rcu_read_unlock(); | |
| 2261 | 2266 | return param; |
| 2267 | + } | |
| 2262 | 2268 | } |
| 2263 | 2269 | |
| 2270 | + rcu_read_unlock(); | |
| 2271 | + | |
| 2264 | 2272 | return NULL; |
| 2265 | 2273 | } |
| 2266 | 2274 | |
| 2275 | +/* This function requires the caller holds hdev->lock */ | |
| 2276 | +void hci_pend_le_list_del_init(struct hci_conn_params *param) | |
| 2277 | +{ | |
| 2278 | + if (list_empty(¶m->action)) | |
| 2279 | + return; | |
| 2280 | + | |
| 2281 | + list_del_rcu(¶m->action); | |
| 2282 | + synchronize_rcu(); | |
| 2283 | + INIT_LIST_HEAD(¶m->action); | |
| 2284 | +} | |
| 2285 | + | |
| 2286 | +/* This function requires the caller holds hdev->lock */ | |
| 2287 | +void hci_pend_le_list_add(struct hci_conn_params *param, | |
| 2288 | + struct list_head *list) | |
| 2289 | +{ | |
| 2290 | + list_add_rcu(¶m->action, list); | |
| 2291 | +} | |
| 2292 | + | |
| 2267 | 2293 | /* This function requires the caller holds hdev->lock */ |
| 2268 | 2294 | struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, |
| 2269 | 2295 | bdaddr_t *addr, u8 addr_type) |
| @@ -2297,14 +2323,15 @@ struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, · 27 unmodified lines | ||
| 2297 | 2323 | return params; |
| 2298 | 2324 | } |
| 2299 | 2325 | |
| 2300 | −static void hci_conn_params_free(struct hci_conn_params *params) | |
| 2326 | +void hci_conn_params_free(struct hci_conn_params *params) | |
| 2301 | 2327 | { |
| 2328 | + hci_pend_le_list_del_init(params); | |
| 2329 | + | |
| 2302 | 2330 | if (params->conn) { |
| 2303 | 2331 | hci_conn_drop(params->conn); |
| 2304 | 2332 | hci_conn_put(params->conn); |
| 2305 | 2333 | } |
| 2306 | 2334 | |
| 2307 | − list_del(¶ms->action); | |
| 2308 | 2335 | list_del(¶ms->list); |
| 2309 | 2336 | kfree(params); |
| 2310 | 2337 | } |
| @@ -2342,8 +2369,7 @@ void hci_conn_params_clear_disabled(struct hci_dev *hdev) · 31 unmodified lines | ||
| 2342 | 2369 | continue; |
| 2343 | 2370 | } |
| 2344 | 2371 | |
| 2345 | − list_del(¶ms->list); | |
| 2346 | − kfree(params); | |
| 2372 | + hci_conn_params_free(params); | |
| 2347 | 2373 | } |
| 2348 | 2374 | |
| 2349 | 2375 | BT_DBG("All LE disabled connection parameters were removed"); |
| @@ -1564,7 +1564,7 @@ static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data, · 1563 unmodified lines | ||
| 1564 | 1564 | |
| 1565 | 1565 | params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type); |
| 1566 | 1566 | if (params) |
| 1567 | − params->privacy_mode = cp->mode; | |
| 1567 | + WRITE_ONCE(params->privacy_mode, cp->mode); | |
| 1568 | 1568 | |
| 1569 | 1569 | hci_dev_unlock(hdev); |
| 1570 | 1570 | |
| @@ -2784,6 +2784,9 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) · 1213 unmodified lines | ||
| 2784 | 2784 | hci_enable_advertising(hdev); |
| 2785 | 2785 | } |
| 2786 | 2786 | |
| 2787 | + /* Inform sockets conn is gone before we delete it */ | |
| 2788 | + hci_disconn_cfm(conn, HCI_ERROR_UNSPECIFIED); | |
| 2789 | + | |
| 2787 | 2790 | goto done; |
| 2788 | 2791 | } |
| 2789 | 2792 | |
| @@ -2804,8 +2807,8 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) · 14 unmodified lines | ||
| 2804 | 2807 | |
| 2805 | 2808 | case HCI_AUTO_CONN_DIRECT: |
| 2806 | 2809 | case HCI_AUTO_CONN_ALWAYS: |
| 2807 | − list_del_init(¶ms->action); | |
| 2808 | − list_add(¶ms->action, &hdev->pend_le_conns); | |
| 2810 | + hci_pend_le_list_del_init(params); | |
| 2811 | + hci_pend_le_list_add(params, &hdev->pend_le_conns); | |
| 2809 | 2812 | break; |
| 2810 | 2813 | |
| 2811 | 2814 | default: |
| @@ -3423,8 +3426,8 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data, · 611 unmodified lines | ||
| 3423 | 3426 | |
| 3424 | 3427 | case HCI_AUTO_CONN_DIRECT: |
| 3425 | 3428 | case HCI_AUTO_CONN_ALWAYS: |
| 3426 | − list_del_init(¶ms->action); | |
| 3427 | − list_add(¶ms->action, &hdev->pend_le_conns); | |
| 3429 | + hci_pend_le_list_del_init(params); | |
| 3430 | + hci_pend_le_list_add(params, &hdev->pend_le_conns); | |
| 3428 | 3431 | hci_update_passive_scan(hdev); |
| 3429 | 3432 | break; |
| 3430 | 3433 | |
| @@ -5962,7 +5965,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, · 2531 unmodified lines | ||
| 5962 | 5965 | params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, |
| 5963 | 5966 | conn->dst_type); |
| 5964 | 5967 | if (params) { |
| 5965 | − list_del_init(¶ms->action); | |
| 5968 | + hci_pend_le_list_del_init(params); | |
| 5966 | 5969 | if (params->conn) { |
| 5967 | 5970 | hci_conn_drop(params->conn); |
| 5968 | 5971 | hci_conn_put(params->conn); |
| @@ -2160,15 +2160,23 @@ static int hci_le_del_accept_list_sync(struct hci_dev *hdev, · 2159 unmodified lines | ||
| 2160 | 2160 | return 0; |
| 2161 | 2161 | } |
| 2162 | 2162 | |
| 2163 | +struct conn_params { | |
| 2164 | + bdaddr_t addr; | |
| 2165 | + u8 addr_type; | |
| 2166 | + hci_conn_flags_t flags; | |
| 2167 | + u8 privacy_mode; | |
| 2168 | +}; | |
| 2169 | + | |
| 2163 | 2170 | /* Adds connection to resolve list if needed. |
| 2164 | 2171 | * Setting params to NULL programs local hdev->irk |
| 2165 | 2172 | */ |
| 2166 | 2173 | static int hci_le_add_resolve_list_sync(struct hci_dev *hdev, |
| 2167 | − struct hci_conn_params *params) | |
| 2174 | + struct conn_params *params) | |
| 2168 | 2175 | { |
| 2169 | 2176 | struct hci_cp_le_add_to_resolv_list cp; |
| 2170 | 2177 | struct smp_irk *irk; |
| 2171 | 2178 | struct bdaddr_list_with_irk *entry; |
| 2179 | + struct hci_conn_params *p; | |
| 2172 | 2180 | |
| 2173 | 2181 | if (!use_ll_privacy(hdev)) |
| 2174 | 2182 | return 0; |
| @@ -2203,6 +2211,16 @@ static int hci_le_add_resolve_list_sync(struct hci_dev *hdev, · 28 unmodified lines | ||
| 2203 | 2211 | /* Default privacy mode is always Network */ |
| 2204 | 2212 | params->privacy_mode = HCI_NETWORK_PRIVACY; |
| 2205 | 2213 | |
| 2214 | + rcu_read_lock(); | |
| 2215 | + p = hci_pend_le_action_lookup(&hdev->pend_le_conns, | |
| 2216 | + ¶ms->addr, params->addr_type); | |
| 2217 | + if (!p) | |
| 2218 | + p = hci_pend_le_action_lookup(&hdev->pend_le_reports, | |
| 2219 | + ¶ms->addr, params->addr_type); | |
| 2220 | + if (p) | |
| 2221 | + WRITE_ONCE(p->privacy_mode, HCI_NETWORK_PRIVACY); | |
| 2222 | + rcu_read_unlock(); | |
| 2223 | + | |
| 2206 | 2224 | done: |
| 2207 | 2225 | if (hci_dev_test_flag(hdev, HCI_PRIVACY)) |
| 2208 | 2226 | memcpy(cp.local_irk, hdev->irk, 16); |
| @@ -2215,7 +2233,7 @@ done: · 6 unmodified lines | ||
| 2215 | 2233 | |
| 2216 | 2234 | /* Set Device Privacy Mode. */ |
| 2217 | 2235 | static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev, |
| 2218 | − struct hci_conn_params *params) | |
| 2236 | + struct conn_params *params) | |
| 2219 | 2237 | { |
| 2220 | 2238 | struct hci_cp_le_set_privacy_mode cp; |
| 2221 | 2239 | struct smp_irk *irk; |
| @@ -2240,6 +2258,8 @@ static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev, · 18 unmodified lines | ||
| 2240 | 2258 | bacpy(&cp.bdaddr, &irk->bdaddr); |
| 2241 | 2259 | cp.mode = HCI_DEVICE_PRIVACY; |
| 2242 | 2260 | |
| 2261 | + /* Note: params->privacy_mode is not updated since it is a copy */ | |
| 2262 | + | |
| 2243 | 2263 | return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PRIVACY_MODE, |
| 2244 | 2264 | sizeof(cp), &cp, HCI_CMD_TIMEOUT); |
| 2245 | 2265 | } |
| @@ -2249,7 +2269,7 @@ static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev, · 3 unmodified lines | ||
| 2249 | 2269 | * properly set the privacy mode. |
| 2250 | 2270 | */ |
| 2251 | 2271 | static int hci_le_add_accept_list_sync(struct hci_dev *hdev, |
| 2252 | − struct hci_conn_params *params, | |
| 2272 | + struct conn_params *params, | |
| 2253 | 2273 | u8 *num_entries) |
| 2254 | 2274 | { |
| 2255 | 2275 | struct hci_cp_le_add_to_accept_list cp; |
| @@ -2447,6 +2467,52 @@ struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev, · 191 unmodified lines | ||
| 2447 | 2467 | return __hci_cmd_sync_sk(hdev, opcode, 0, NULL, 0, HCI_CMD_TIMEOUT, sk); |
| 2448 | 2468 | } |
| 2449 | 2469 | |
| 2470 | +static struct conn_params *conn_params_copy(struct list_head *list, size_t *n) | |
| 2471 | +{ | |
| 2472 | + struct hci_conn_params *params; | |
| 2473 | + struct conn_params *p; | |
| 2474 | + size_t i; | |
| 2475 | + | |
| 2476 | + rcu_read_lock(); | |
| 2477 | + | |
| 2478 | + i = 0; | |
| 2479 | + list_for_each_entry_rcu(params, list, action) | |
| 2480 | + ++i; | |
| 2481 | + *n = i; | |
| 2482 | + | |
| 2483 | + rcu_read_unlock(); | |
| 2484 | + | |
| 2485 | + p = kvcalloc(*n, sizeof(struct conn_params), GFP_KERNEL); | |
| 2486 | + if (!p) | |
| 2487 | + return NULL; | |
| 2488 | + | |
| 2489 | + rcu_read_lock(); | |
| 2490 | + | |
| 2491 | + i = 0; | |
| 2492 | + list_for_each_entry_rcu(params, list, action) { | |
| 2493 | + /* Racing adds are handled in next scan update */ | |
| 2494 | + if (i >= *n) | |
| 2495 | + break; | |
| 2496 | + | |
| 2497 | + /* No hdev->lock, but: addr, addr_type are immutable. | |
| 2498 | + * privacy_mode is only written by us or in | |
| 2499 | + * hci_cc_le_set_privacy_mode that we wait for. | |
| 2500 | + * We should be idempotent so MGMT updating flags | |
| 2501 | + * while we are processing is OK. | |
| 2502 | + */ | |
| 2503 | + bacpy(&p[i].addr, ¶ms->addr); | |
| 2504 | + p[i].addr_type = params->addr_type; | |
| 2505 | + p[i].flags = READ_ONCE(params->flags); | |
| 2506 | + p[i].privacy_mode = READ_ONCE(params->privacy_mode); | |
| 2507 | + ++i; | |
| 2508 | + } | |
| 2509 | + | |
| 2510 | + rcu_read_unlock(); | |
| 2511 | + | |
| 2512 | + *n = i; | |
| 2513 | + return p; | |
| 2514 | +} | |
| 2515 | + | |
| 2450 | 2516 | /* Device must not be scanning when updating the accept list. |
| 2451 | 2517 | * |
| 2452 | 2518 | * Update is done using the following sequence: |
| @@ -2466,11 +2532,12 @@ struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev, · 13 unmodified lines | ||
| 2466 | 2532 | */ |
| 2467 | 2533 | static u8 hci_update_accept_list_sync(struct hci_dev *hdev) |
| 2468 | 2534 | { |
| 2469 | − struct hci_conn_params *params; | |
| 2535 | + struct conn_params *params; | |
| 2470 | 2536 | struct bdaddr_list *b, *t; |
| 2471 | 2537 | u8 num_entries = 0; |
| 2472 | 2538 | bool pend_conn, pend_report; |
| 2473 | 2539 | u8 filter_policy; |
| 2540 | + size_t i, n; | |
| 2474 | 2541 | int err; |
| 2475 | 2542 | |
| 2476 | 2543 | /* Pause advertising if resolving list can be used as controllers |
| @@ -2504,6 +2571,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) · 27 unmodified lines | ||
| 2504 | 2571 | if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type)) |
| 2505 | 2572 | continue; |
| 2506 | 2573 | |
| 2574 | + /* Pointers not dereferenced, no locks needed */ | |
| 2507 | 2575 | pend_conn = hci_pend_le_action_lookup(&hdev->pend_le_conns, |
| 2508 | 2576 | &b->bdaddr, |
| 2509 | 2577 | b->bdaddr_type); |
| @@ -2532,23 +2600,50 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) · 22 unmodified lines | ||
| 2532 | 2600 | * available accept list entries in the controller, then |
| 2533 | 2601 | * just abort and return filer policy value to not use the |
| 2534 | 2602 | * accept list. |
| 2603 | + * | |
| 2604 | + * The list and params may be mutated while we wait for events, | |
| 2605 | + * so make a copy and iterate it. | |
| 2535 | 2606 | */ |
| 2536 | − list_for_each_entry(params, &hdev->pend_le_conns, action) { | |
| 2537 | − err = hci_le_add_accept_list_sync(hdev, params, &num_entries); | |
| 2538 | − if (err) | |
| 2607 | + | |
| 2608 | + params = conn_params_copy(&hdev->pend_le_conns, &n); | |
| 2609 | + if (!params) { | |
| 2610 | + err = -ENOMEM; | |
| 2611 | + goto done; | |
| 2612 | + } | |
| 2613 | + | |
| 2614 | + for (i = 0; i < n; ++i) { | |
| 2615 | + err = hci_le_add_accept_list_sync(hdev, ¶ms[i], | |
| 2616 | + &num_entries); | |
| 2617 | + if (err) { | |
| 2618 | + kvfree(params); | |
| 2539 | 2619 | goto done; |
| 2620 | + } | |
| 2540 | 2621 | } |
| 2541 | 2622 | |
| 2623 | + kvfree(params); | |
| 2624 | + | |
| 2542 | 2625 | /* After adding all new pending connections, walk through |
| 2543 | 2626 | * the list of pending reports and also add these to the |
| 2544 | 2627 | * accept list if there is still space. Abort if space runs out. |
| 2545 | 2628 | */ |
| 2546 | − list_for_each_entry(params, &hdev->pend_le_reports, action) { | |
| 2547 | − err = hci_le_add_accept_list_sync(hdev, params, &num_entries); | |
| 2548 | − if (err) | |
| 2629 | + | |
| 2630 | + params = conn_params_copy(&hdev->pend_le_reports, &n); | |
| 2631 | + if (!params) { | |
| 2632 | + err = -ENOMEM; | |
| 2633 | + goto done; | |
| 2634 | + } | |
| 2635 | + | |
| 2636 | + for (i = 0; i < n; ++i) { | |
| 2637 | + err = hci_le_add_accept_list_sync(hdev, ¶ms[i], | |
| 2638 | + &num_entries); | |
| 2639 | + if (err) { | |
| 2640 | + kvfree(params); | |
| 2549 | 2641 | goto done; |
| 2642 | + } | |
| 2550 | 2643 | } |
| 2551 | 2644 | |
| 2645 | + kvfree(params); | |
| 2646 | + | |
| 2552 | 2647 | /* Use the allowlist unless the following conditions are all true: |
| 2553 | 2648 | * - We are not currently suspending |
| 2554 | 2649 | * - There are 1 or more ADV monitors registered and it's not offloaded |
| @@ -4837,12 +4932,12 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev) · 2282 unmodified lines | ||
| 4837 | 4932 | struct hci_conn_params *p; |
| 4838 | 4933 | |
| 4839 | 4934 | list_for_each_entry(p, &hdev->le_conn_params, list) { |
| 4935 | + hci_pend_le_list_del_init(p); | |
| 4840 | 4936 | if (p->conn) { |
| 4841 | 4937 | hci_conn_drop(p->conn); |
| 4842 | 4938 | hci_conn_put(p->conn); |
| 4843 | 4939 | p->conn = NULL; |
| 4844 | 4940 | } |
| 4845 | − list_del_init(&p->action); | |
| 4846 | 4941 | } |
| 4847 | 4942 | |
| 4848 | 4943 | BT_DBG("All LE pending actions cleared"); |
| @@ -123,8 +123,11 @@ static struct iso_conn *iso_conn_add(struct hci_conn *hcon) · 122 unmodified lines | ||
| 123 | 123 | { |
| 124 | 124 | struct iso_conn *conn = hcon->iso_data; |
| 125 | 125 | |
| 126 | − if (conn) | |
| 126 | + if (conn) { | |
| 127 | + if (!conn->hcon) | |
| 128 | + conn->hcon = hcon; | |
| 127 | 129 | return conn; |
| 130 | + } | |
| 128 | 131 | |
| 129 | 132 | conn = kzalloc(sizeof(*conn), GFP_KERNEL); |
| 130 | 133 | if (!conn) |
| @@ -300,14 +303,13 @@ static int iso_connect_bis(struct sock *sk) · 169 unmodified lines | ||
| 300 | 303 | goto unlock; |
| 301 | 304 | } |
| 302 | 305 | |
| 303 | − hci_dev_unlock(hdev); | |
| 304 | − hci_dev_put(hdev); | |
| 306 | + lock_sock(sk); | |
| 305 | 307 | |
| 306 | 308 | err = iso_chan_add(conn, sk, NULL); |
| 307 | − if (err) | |
| 308 | − return err; | |
| 309 | − | |
| 310 | − lock_sock(sk); | |
| 309 | + if (err) { | |
| 310 | + release_sock(sk); | |
| 311 | + goto unlock; | |
| 312 | + } | |
| 311 | 313 | |
| 312 | 314 | /* Update source addr of the socket */ |
| 313 | 315 | bacpy(&iso_pi(sk)->src, &hcon->src); |
| @@ -321,7 +323,6 @@ static int iso_connect_bis(struct sock *sk) · 7 unmodified lines | ||
| 321 | 323 | } |
| 322 | 324 | |
| 323 | 325 | release_sock(sk); |
| 324 | − return err; | |
| 325 | 326 | |
| 326 | 327 | unlock: |
| 327 | 328 | hci_dev_unlock(hdev); |
| @@ -389,14 +390,13 @@ static int iso_connect_cis(struct sock *sk) · 61 unmodified lines | ||
| 389 | 390 | goto unlock; |
| 390 | 391 | } |
| 391 | 392 | |
| 392 | − hci_dev_unlock(hdev); | |
| 393 | − hci_dev_put(hdev); | |
| 393 | + lock_sock(sk); | |
| 394 | 394 | |
| 395 | 395 | err = iso_chan_add(conn, sk, NULL); |
| 396 | − if (err) | |
| 397 | − return err; | |
| 398 | − | |
| 399 | − lock_sock(sk); | |
| 396 | + if (err) { | |
| 397 | + release_sock(sk); | |
| 398 | + goto unlock; | |
| 399 | + } | |
| 400 | 400 | |
| 401 | 401 | /* Update source addr of the socket */ |
| 402 | 402 | bacpy(&iso_pi(sk)->src, &hcon->src); |
| @@ -413,7 +413,6 @@ static int iso_connect_cis(struct sock *sk) · 10 unmodified lines | ||
| 413 | 413 | } |
| 414 | 414 | |
| 415 | 415 | release_sock(sk); |
| 416 | − return err; | |
| 417 | 416 | |
| 418 | 417 | unlock: |
| 419 | 418 | hci_dev_unlock(hdev); |
| @@ -1072,8 +1071,8 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, · 652 unmodified lines | ||
| 1072 | 1071 | size_t len) |
| 1073 | 1072 | { |
| 1074 | 1073 | struct sock *sk = sock->sk; |
| 1075 | − struct iso_conn *conn = iso_pi(sk)->conn; | |
| 1076 | 1074 | struct sk_buff *skb, **frag; |
| 1075 | + size_t mtu; | |
| 1077 | 1076 | int err; |
| 1078 | 1077 | |
| 1079 | 1078 | BT_DBG("sock %p, sk %p", sock, sk); |
| @@ -1085,11 +1084,18 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, · 5 unmodified lines | ||
| 1085 | 1084 | if (msg->msg_flags & MSG_OOB) |
| 1086 | 1085 | return -EOPNOTSUPP; |
| 1087 | 1086 | |
| 1088 | − if (sk->sk_state != BT_CONNECTED) | |
| 1087 | + lock_sock(sk); | |
| 1088 | + | |
| 1089 | + if (sk->sk_state != BT_CONNECTED) { | |
| 1090 | + release_sock(sk); | |
| 1089 | 1091 | return -ENOTCONN; |
| 1092 | + } | |
| 1093 | + | |
| 1094 | + mtu = iso_pi(sk)->conn->hcon->hdev->iso_mtu; | |
| 1095 | + | |
| 1096 | + release_sock(sk); | |
| 1090 | 1097 | |
| 1091 | − skb = bt_skb_sendmsg(sk, msg, len, conn->hcon->hdev->iso_mtu, | |
| 1092 | − HCI_ISO_DATA_HDR_SIZE, 0); | |
| 1098 | + skb = bt_skb_sendmsg(sk, msg, len, mtu, HCI_ISO_DATA_HDR_SIZE, 0); | |
| 1093 | 1099 | if (IS_ERR(skb)) |
| 1094 | 1100 | return PTR_ERR(skb); |
| 1095 | 1101 | |
| @@ -1102,8 +1108,7 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, · 6 unmodified lines | ||
| 1102 | 1108 | while (len) { |
| 1103 | 1109 | struct sk_buff *tmp; |
| 1104 | 1110 | |
| 1105 | − tmp = bt_skb_sendmsg(sk, msg, len, conn->hcon->hdev->iso_mtu, | |
| 1106 | − 0, 0); | |
| 1111 | + tmp = bt_skb_sendmsg(sk, msg, len, mtu, 0, 0); | |
| 1107 | 1112 | if (IS_ERR(tmp)) { |
| 1108 | 1113 | kfree_skb(skb); |
| 1109 | 1114 | return PTR_ERR(tmp); |
| @@ -1158,15 +1163,19 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg, · 48 unmodified lines | ||
| 1158 | 1163 | BT_DBG("sk %p", sk); |
| 1159 | 1164 | |
| 1160 | 1165 | if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { |
| 1166 | + lock_sock(sk); | |
| 1161 | 1167 | switch (sk->sk_state) { |
| 1162 | 1168 | case BT_CONNECT2: |
| 1163 | − lock_sock(sk); | |
| 1164 | 1169 | iso_conn_defer_accept(pi->conn->hcon); |
| 1165 | 1170 | sk->sk_state = BT_CONFIG; |
| 1166 | 1171 | release_sock(sk); |
| 1167 | 1172 | return 0; |
| 1168 | 1173 | case BT_CONNECT: |
| 1174 | + release_sock(sk); | |
| 1169 | 1175 | return iso_connect_cis(sk); |
| 1176 | + default: | |
| 1177 | + release_sock(sk); | |
| 1178 | + break; | |
| 1170 | 1179 | } |
| 1171 | 1180 | } |
| 1172 | 1181 | |
| @@ -1297,15 +1297,15 @@ static void restart_le_actions(struct hci_dev *hdev) · 1296 unmodified lines | ||
| 1297 | 1297 | /* Needed for AUTO_OFF case where might not "really" |
| 1298 | 1298 | * have been powered off. |
| 1299 | 1299 | */ |
| 1300 | − list_del_init(&p->action); | |
| 1300 | + hci_pend_le_list_del_init(p); | |
| 1301 | 1301 | |
| 1302 | 1302 | switch (p->auto_connect) { |
| 1303 | 1303 | case HCI_AUTO_CONN_DIRECT: |
| 1304 | 1304 | case HCI_AUTO_CONN_ALWAYS: |
| 1305 | − list_add(&p->action, &hdev->pend_le_conns); | |
| 1305 | + hci_pend_le_list_add(p, &hdev->pend_le_conns); | |
| 1306 | 1306 | break; |
| 1307 | 1307 | case HCI_AUTO_CONN_REPORT: |
| 1308 | − list_add(&p->action, &hdev->pend_le_reports); | |
| 1308 | + hci_pend_le_list_add(p, &hdev->pend_le_reports); | |
| 1309 | 1309 | break; |
| 1310 | 1310 | default: |
| 1311 | 1311 | break; |
| @@ -5169,7 +5169,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, · 3857 unmodified lines | ||
| 5169 | 5169 | goto unlock; |
| 5170 | 5170 | } |
| 5171 | 5171 | |
| 5172 | − params->flags = current_flags; | |
| 5172 | + WRITE_ONCE(params->flags, current_flags); | |
| 5173 | 5173 | status = MGMT_STATUS_SUCCESS; |
| 5174 | 5174 | |
| 5175 | 5175 | /* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY |
| @@ -7285,7 +7285,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err) · 2109 unmodified lines | ||
| 7285 | 7285 | |
| 7286 | 7286 | bt_dev_dbg(hdev, "err %d", err); |
| 7287 | 7287 | |
| 7288 | − memcpy(&rp.addr, &cp->addr.bdaddr, sizeof(rp.addr)); | |
| 7288 | + memcpy(&rp.addr, &cp->addr, sizeof(rp.addr)); | |
| 7289 | 7289 | |
| 7290 | 7290 | status = mgmt_status(err); |
| 7291 | 7291 | if (status == MGMT_STATUS_SUCCESS) { |
| @@ -7580,7 +7580,7 @@ static int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, · 288 unmodified lines | ||
| 7580 | 7580 | if (params->auto_connect == auto_connect) |
| 7581 | 7581 | return 0; |
| 7582 | 7582 | |
| 7583 | − list_del_init(¶ms->action); | |
| 7583 | + hci_pend_le_list_del_init(params); | |
| 7584 | 7584 | |
| 7585 | 7585 | switch (auto_connect) { |
| 7586 | 7586 | case HCI_AUTO_CONN_DISABLED: |
| @@ -7589,18 +7589,18 @@ static int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, · 2 unmodified lines | ||
| 7589 | 7589 | * connect to device, keep connecting. |
| 7590 | 7590 | */ |
| 7591 | 7591 | if (params->explicit_connect) |
| 7592 | − list_add(¶ms->action, &hdev->pend_le_conns); | |
| 7592 | + hci_pend_le_list_add(params, &hdev->pend_le_conns); | |
| 7593 | 7593 | break; |
| 7594 | 7594 | case HCI_AUTO_CONN_REPORT: |
| 7595 | 7595 | if (params->explicit_connect) |
| 7596 | − list_add(¶ms->action, &hdev->pend_le_conns); | |
| 7596 | + hci_pend_le_list_add(params, &hdev->pend_le_conns); | |
| 7597 | 7597 | else |
| 7598 | − list_add(¶ms->action, &hdev->pend_le_reports); | |
| 7598 | + hci_pend_le_list_add(params, &hdev->pend_le_reports); | |
| 7599 | 7599 | break; |
| 7600 | 7600 | case HCI_AUTO_CONN_DIRECT: |
| 7601 | 7601 | case HCI_AUTO_CONN_ALWAYS: |
| 7602 | 7602 | if (!is_connected(hdev, addr, addr_type)) |
| 7603 | − list_add(¶ms->action, &hdev->pend_le_conns); | |
| 7603 | + hci_pend_le_list_add(params, &hdev->pend_le_conns); | |
| 7604 | 7604 | break; |
| 7605 | 7605 | } |
| 7606 | 7606 | |
| @@ -7823,9 +7823,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, · 216 unmodified lines | ||
| 7823 | 7823 | goto unlock; |
| 7824 | 7824 | } |
| 7825 | 7825 | |
| 7826 | − list_del(¶ms->action); | |
| 7827 | − list_del(¶ms->list); | |
| 7828 | − kfree(params); | |
| 7826 | + hci_conn_params_free(params); | |
| 7829 | 7827 | |
| 7830 | 7828 | device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type); |
| 7831 | 7829 | } else { |
| @@ -7856,9 +7854,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, · 24 unmodified lines | ||
| 7856 | 7854 | p->auto_connect = HCI_AUTO_CONN_EXPLICIT; |
| 7857 | 7855 | continue; |
| 7858 | 7856 | } |
| 7859 | − list_del(&p->action); | |
| 7860 | − list_del(&p->list); | |
| 7861 | − kfree(p); | |
| 7857 | + hci_conn_params_free(p); | |
| 7862 | 7858 | } |
| 7863 | 7859 | |
| 7864 | 7860 | bt_dev_dbg(hdev, "All LE connection parameters were removed"); |
| @@ -126,8 +126,11 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) · 125 unmodified lines | ||
| 126 | 126 | struct hci_dev *hdev = hcon->hdev; |
| 127 | 127 | struct sco_conn *conn = hcon->sco_data; |
| 128 | 128 | |
| 129 | − if (conn) | |
| 129 | + if (conn) { | |
| 130 | + if (!conn->hcon) | |
| 131 | + conn->hcon = hcon; | |
| 130 | 132 | return conn; |
| 133 | + } | |
| 131 | 134 | |
| 132 | 135 | conn = kzalloc(sizeof(struct sco_conn), GFP_KERNEL); |
| 133 | 136 | if (!conn) |
| @@ -268,21 +271,21 @@ static int sco_connect(struct sock *sk) · 134 unmodified lines | ||
| 268 | 271 | goto unlock; |
| 269 | 272 | } |
| 270 | 273 | |
| 271 | − hci_dev_unlock(hdev); | |
| 272 | − hci_dev_put(hdev); | |
| 273 | − | |
| 274 | 274 | conn = sco_conn_add(hcon); |
| 275 | 275 | if (!conn) { |
| 276 | 276 | hci_conn_drop(hcon); |
| 277 | − return -ENOMEM; | |
| 277 | + err = -ENOMEM; | |
| 278 | + goto unlock; | |
| 278 | 279 | } |
| 279 | 280 | |
| 280 | − err = sco_chan_add(conn, sk, NULL); | |
| 281 | − if (err) | |
| 282 | − return err; | |
| 283 | − | |
| 284 | 281 | lock_sock(sk); |
| 285 | 282 | |
| 283 | + err = sco_chan_add(conn, sk, NULL); | |
| 284 | + if (err) { | |
| 285 | + release_sock(sk); | |
| 286 | + goto unlock; | |
| 287 | + } | |
| 288 | + | |
| 286 | 289 | /* Update source addr of the socket */ |
| 287 | 290 | bacpy(&sco_pi(sk)->src, &hcon->src); |
| 288 | 291 | |
| @@ -296,8 +299,6 @@ static int sco_connect(struct sock *sk) · 7 unmodified lines | ||
| 296 | 299 | |
| 297 | 300 | release_sock(sk); |
| 298 | 301 | |
| 299 | − return err; | |
| 300 | − | |
| 301 | 302 | unlock: |
| 302 | 303 | hci_dev_unlock(hdev); |
| 303 | 304 | hci_dev_put(hdev); |
| @@ -1526,6 +1526,12 @@ static int bcm_release(struct socket *sock) · 1525 unmodified lines | ||
| 1526 | 1526 | |
| 1527 | 1527 | lock_sock(sk); |
| 1528 | 1528 | |
| 1529 | +#if IS_ENABLED(CONFIG_PROC_FS) | |
| 1530 | + /* remove procfs entry */ | |
| 1531 | + if (net->can.bcmproc_dir && bo->bcm_proc_read) | |
| 1532 | + remove_proc_entry(bo->procname, net->can.bcmproc_dir); | |
| 1533 | +#endif /* CONFIG_PROC_FS */ | |
| 1534 | + | |
| 1529 | 1535 | list_for_each_entry_safe(op, next, &bo->tx_ops, list) |
| 1530 | 1536 | bcm_remove_op(op); |
| 1531 | 1537 | |
| @@ -1561,12 +1567,6 @@ static int bcm_release(struct socket *sock) · 29 unmodified lines | ||
| 1561 | 1567 | list_for_each_entry_safe(op, next, &bo->rx_ops, list) |
| 1562 | 1568 | bcm_remove_op(op); |
| 1563 | 1569 | |
| 1564 | −#if IS_ENABLED(CONFIG_PROC_FS) | |
| 1565 | − /* remove procfs entry */ | |
| 1566 | − if (net->can.bcmproc_dir && bo->bcm_proc_read) | |
| 1567 | − remove_proc_entry(bo->procname, net->can.bcmproc_dir); | |
| 1568 | −#endif /* CONFIG_PROC_FS */ | |
| 1569 | − | |
| 1570 | 1570 | /* remove device reference */ |
| 1571 | 1571 | if (bo->bound) { |
| 1572 | 1572 | bo->bound = 0; |
| @@ -84,6 +84,7 @@ struct raw_sock { · 83 unmodified lines | ||
| 84 | 84 | struct sock sk; |
| 85 | 85 | int bound; |
| 86 | 86 | int ifindex; |
| 87 | + struct net_device *dev; | |
| 87 | 88 | struct list_head notifier; |
| 88 | 89 | int loopback; |
| 89 | 90 | int recv_own_msgs; |
| @@ -277,7 +278,7 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg, · 187 unmodified lines | ||
| 277 | 278 | if (!net_eq(dev_net(dev), sock_net(sk))) |
| 278 | 279 | return; |
| 279 | 280 | |
| 280 | − if (ro->ifindex != dev->ifindex) | |
| 281 | + if (ro->dev != dev) | |
| 281 | 282 | return; |
| 282 | 283 | |
| 283 | 284 | switch (msg) { |
| @@ -292,6 +293,7 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg, · 8 unmodified lines | ||
| 292 | 293 | |
| 293 | 294 | ro->ifindex = 0; |
| 294 | 295 | ro->bound = 0; |
| 296 | + ro->dev = NULL; | |
| 295 | 297 | ro->count = 0; |
| 296 | 298 | release_sock(sk); |
| 297 | 299 | |
| @@ -337,6 +339,7 @@ static int raw_init(struct sock *sk) · 39 unmodified lines | ||
| 337 | 339 | |
| 338 | 340 | ro->bound = 0; |
| 339 | 341 | ro->ifindex = 0; |
| 342 | + ro->dev = NULL; | |
| 340 | 343 | |
| 341 | 344 | /* set default filter to single entry dfilter */ |
| 342 | 345 | ro->dfilter.can_id = 0; |
| @@ -385,19 +388,13 @@ static int raw_release(struct socket *sock) · 42 unmodified lines | ||
| 385 | 388 | |
| 386 | 389 | lock_sock(sk); |
| 387 | 390 | |
| 391 | + rtnl_lock(); | |
| 388 | 392 | /* remove current filters & unregister */ |
| 389 | 393 | if (ro->bound) { |
| 390 | − if (ro->ifindex) { | |
| 391 | − struct net_device *dev; | |
| 392 | − | |
| 393 | − dev = dev_get_by_index(sock_net(sk), ro->ifindex); | |
| 394 | − if (dev) { | |
| 395 | − raw_disable_allfilters(dev_net(dev), dev, sk); | |
| 396 | − dev_put(dev); | |
| 397 | − } | |
| 398 | − } else { | |
| 394 | + if (ro->dev) | |
| 395 | + raw_disable_allfilters(dev_net(ro->dev), ro->dev, sk); | |
| 396 | + else | |
| 399 | 397 | raw_disable_allfilters(sock_net(sk), NULL, sk); |
| 400 | − } | |
| 401 | 398 | } |
| 402 | 399 | |
| 403 | 400 | if (ro->count > 1) |
| @@ -405,8 +402,10 @@ static int raw_release(struct socket *sock) · 1 unmodified line | ||
| 405 | 402 | |
| 406 | 403 | ro->ifindex = 0; |
| 407 | 404 | ro->bound = 0; |
| 405 | + ro->dev = NULL; | |
| 408 | 406 | ro->count = 0; |
| 409 | 407 | free_percpu(ro->uniq); |
| 408 | + rtnl_unlock(); | |
| 410 | 409 | |
| 411 | 410 | sock_orphan(sk); |
| 412 | 411 | sock->sk = NULL; |
| @@ -422,6 +421,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) · 9 unmodified lines | ||
| 422 | 421 | struct sockaddr_can *addr = (struct sockaddr_can *)uaddr; |
| 423 | 422 | struct sock *sk = sock->sk; |
| 424 | 423 | struct raw_sock *ro = raw_sk(sk); |
| 424 | + struct net_device *dev = NULL; | |
| 425 | 425 | int ifindex; |
| 426 | 426 | int err = 0; |
| 427 | 427 | int notify_enetdown = 0; |
| @@ -431,14 +431,13 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) · 3 unmodified lines | ||
| 431 | 431 | if (addr->can_family != AF_CAN) |
| 432 | 432 | return -EINVAL; |
| 433 | 433 | |
| 434 | + rtnl_lock(); | |
| 434 | 435 | lock_sock(sk); |
| 435 | 436 | |
| 436 | 437 | if (ro->bound && addr->can_ifindex == ro->ifindex) |
| 437 | 438 | goto out; |
| 438 | 439 | |
| 439 | 440 | if (addr->can_ifindex) { |
| 440 | − struct net_device *dev; | |
| 441 | − | |
| 442 | 441 | dev = dev_get_by_index(sock_net(sk), addr->can_ifindex); |
| 443 | 442 | if (!dev) { |
| 444 | 443 | err = -ENODEV; |
| @@ -467,26 +466,20 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) · 22 unmodified lines | ||
| 467 | 466 | if (!err) { |
| 468 | 467 | if (ro->bound) { |
| 469 | 468 | /* unregister old filters */ |
| 470 | − if (ro->ifindex) { | |
| 471 | − struct net_device *dev; | |
| 472 | − | |
| 473 | − dev = dev_get_by_index(sock_net(sk), | |
| 474 | − ro->ifindex); | |
| 475 | − if (dev) { | |
| 476 | − raw_disable_allfilters(dev_net(dev), | |
| 477 | − dev, sk); | |
| 478 | − dev_put(dev); | |
| 479 | − } | |
| 480 | − } else { | |
| 469 | + if (ro->dev) | |
| 470 | + raw_disable_allfilters(dev_net(ro->dev), | |
| 471 | + ro->dev, sk); | |
| 472 | + else | |
| 481 | 473 | raw_disable_allfilters(sock_net(sk), NULL, sk); |
| 482 | − } | |
| 483 | 474 | } |
| 484 | 475 | ro->ifindex = ifindex; |
| 485 | 476 | ro->bound = 1; |
| 477 | + ro->dev = dev; | |
| 486 | 478 | } |
| 487 | 479 | |
| 488 | 480 | out: |
| 489 | 481 | release_sock(sk); |
| 482 | + rtnl_unlock(); | |
| 490 | 483 | |
| 491 | 484 | if (notify_enetdown) { |
| 492 | 485 | sk->sk_err = ENETDOWN; |
| @@ -553,9 +546,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 60 unmodified lines | ||
| 553 | 546 | rtnl_lock(); |
| 554 | 547 | lock_sock(sk); |
| 555 | 548 | |
| 556 | − if (ro->bound && ro->ifindex) { | |
| 557 | − dev = dev_get_by_index(sock_net(sk), ro->ifindex); | |
| 558 | − if (!dev) { | |
| 549 | + dev = ro->dev; | |
| 550 | + if (ro->bound && dev) { | |
| 551 | + if (dev->reg_state != NETREG_REGISTERED) { | |
| 559 | 552 | if (count > 1) |
| 560 | 553 | kfree(filter); |
| 561 | 554 | err = -ENODEV; |
| @@ -596,7 +589,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 34 unmodified lines | ||
| 596 | 589 | ro->count = count; |
| 597 | 590 | |
| 598 | 591 | out_fil: |
| 599 | − dev_put(dev); | |
| 600 | 592 | release_sock(sk); |
| 601 | 593 | rtnl_unlock(); |
| 602 | 594 | |
| @@ -614,9 +606,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 11 unmodified lines | ||
| 614 | 606 | rtnl_lock(); |
| 615 | 607 | lock_sock(sk); |
| 616 | 608 | |
| 617 | − if (ro->bound && ro->ifindex) { | |
| 618 | − dev = dev_get_by_index(sock_net(sk), ro->ifindex); | |
| 619 | − if (!dev) { | |
| 609 | + dev = ro->dev; | |
| 610 | + if (ro->bound && dev) { | |
| 611 | + if (dev->reg_state != NETREG_REGISTERED) { | |
| 620 | 612 | err = -ENODEV; |
| 621 | 613 | goto out_err; |
| 622 | 614 | } |
| @@ -640,7 +632,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 17 unmodified lines | ||
| 640 | 632 | ro->err_mask = err_mask; |
| 641 | 633 | |
| 642 | 634 | out_err: |
| 643 | − dev_put(dev); | |
| 644 | 635 | release_sock(sk); |
| 645 | 636 | rtnl_unlock(); |
| 646 | 637 | |
| @@ -1132,7 +1132,7 @@ static int esp_init_authenc(struct xfrm_state *x, · 1131 unmodified lines | ||
| 1132 | 1132 | err = crypto_aead_setkey(aead, key, keylen); |
| 1133 | 1133 | |
| 1134 | 1134 | free_key: |
| 1135 | − kfree(key); | |
| 1135 | + kfree_sensitive(key); | |
| 1136 | 1136 | |
| 1137 | 1137 | error: |
| 1138 | 1138 | return err; |
| @@ -1019,7 +1019,7 @@ static void reqsk_timer_handler(struct timer_list *t) · 1018 unmodified lines | ||
| 1019 | 1019 | |
| 1020 | 1020 | icsk = inet_csk(sk_listener); |
| 1021 | 1021 | net = sock_net(sk_listener); |
| 1022 | − max_syn_ack_retries = icsk->icsk_syn_retries ? : | |
| 1022 | + max_syn_ack_retries = READ_ONCE(icsk->icsk_syn_retries) ? : | |
| 1023 | 1023 | READ_ONCE(net->ipv4.sysctl_tcp_synack_retries); |
| 1024 | 1024 | /* Normally all the openreqs are young and become mature |
| 1025 | 1025 | * (i.e. converted to established socket) for first timeout. |
| @@ -650,20 +650,8 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) · 649 unmodified lines | ||
| 650 | 650 | spin_lock(lock); |
| 651 | 651 | if (osk) { |
| 652 | 652 | WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); |
| 653 | − ret = sk_hashed(osk); | |
| 654 | − if (ret) { | |
| 655 | − /* Before deleting the node, we insert a new one to make | |
| 656 | − * sure that the look-up-sk process would not miss either | |
| 657 | − * of them and that at least one node would exist in ehash | |
| 658 | − * table all the time. Otherwise there's a tiny chance | |
| 659 | − * that lookup process could find nothing in ehash table. | |
| 660 | − */ | |
| 661 | − __sk_nulls_add_node_tail_rcu(sk, list); | |
| 662 | − sk_nulls_del_node_init_rcu(osk); | |
| 663 | − } | |
| 664 | − goto unlock; | |
| 665 | − } | |
| 666 | − if (found_dup_sk) { | |
| 653 | + ret = sk_nulls_del_node_init_rcu(osk); | |
| 654 | + } else if (found_dup_sk) { | |
| 667 | 655 | *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); |
| 668 | 656 | if (*found_dup_sk) |
| 669 | 657 | ret = false; |
| @@ -672,7 +660,6 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) · 2 unmodified lines | ||
| 672 | 660 | if (ret) |
| 673 | 661 | __sk_nulls_add_node_rcu(sk, list); |
| 674 | 662 | |
| 675 | −unlock: | |
| 676 | 663 | spin_unlock(lock); |
| 677 | 664 | |
| 678 | 665 | return ret; |
| @@ -88,10 +88,10 @@ void inet_twsk_put(struct inet_timewait_sock *tw) · 87 unmodified lines | ||
| 88 | 88 | } |
| 89 | 89 | EXPORT_SYMBOL_GPL(inet_twsk_put); |
| 90 | 90 | |
| 91 | −static void inet_twsk_add_node_tail_rcu(struct inet_timewait_sock *tw, | |
| 92 | − struct hlist_nulls_head *list) | |
| 91 | +static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw, | |
| 92 | + struct hlist_nulls_head *list) | |
| 93 | 93 | { |
| 94 | − hlist_nulls_add_tail_rcu(&tw->tw_node, list); | |
| 94 | + hlist_nulls_add_head_rcu(&tw->tw_node, list); | |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw, |
| @@ -144,7 +144,7 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, · 46 unmodified lines | ||
| 144 | 144 | |
| 145 | 145 | spin_lock(lock); |
| 146 | 146 | |
| 147 | − inet_twsk_add_node_tail_rcu(tw, &ehead->chain); | |
| 147 | + inet_twsk_add_node_rcu(tw, &ehead->chain); | |
| 148 | 148 | |
| 149 | 149 | /* Step 3: Remove SK from hash chain */ |
| 150 | 150 | if (__sk_nulls_del_node_init_rcu(sk)) |
| @@ -548,7 +548,8 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) · 547 unmodified lines | ||
| 548 | 548 | goto err_free_skb; |
| 549 | 549 | |
| 550 | 550 | if (skb->len > dev->mtu + dev->hard_header_len) { |
| 551 | − pskb_trim(skb, dev->mtu + dev->hard_header_len); | |
| 551 | + if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) | |
| 552 | + goto err_free_skb; | |
| 552 | 553 | truncate = true; |
| 553 | 554 | } |
| 554 | 555 | |
| @@ -689,7 +690,8 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, · 134 unmodified lines | ||
| 689 | 690 | goto free_skb; |
| 690 | 691 | |
| 691 | 692 | if (skb->len > dev->mtu + dev->hard_header_len) { |
| 692 | − pskb_trim(skb, dev->mtu + dev->hard_header_len); | |
| 693 | + if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) | |
| 694 | + goto free_skb; | |
| 693 | 695 | truncate = true; |
| 694 | 696 | } |
| 695 | 697 | |
| @@ -3291,7 +3291,7 @@ int tcp_sock_set_syncnt(struct sock *sk, int val) · 3290 unmodified lines | ||
| 3291 | 3291 | return -EINVAL; |
| 3292 | 3292 | |
| 3293 | 3293 | lock_sock(sk); |
| 3294 | − inet_csk(sk)->icsk_syn_retries = val; | |
| 3294 | + WRITE_ONCE(inet_csk(sk)->icsk_syn_retries, val); | |
| 3295 | 3295 | release_sock(sk); |
| 3296 | 3296 | return 0; |
| 3297 | 3297 | } |
| @@ -3300,7 +3300,7 @@ EXPORT_SYMBOL(tcp_sock_set_syncnt); · 2 unmodified lines | ||
| 3300 | 3300 | void tcp_sock_set_user_timeout(struct sock *sk, u32 val) |
| 3301 | 3301 | { |
| 3302 | 3302 | lock_sock(sk); |
| 3303 | − inet_csk(sk)->icsk_user_timeout = val; | |
| 3303 | + WRITE_ONCE(inet_csk(sk)->icsk_user_timeout, val); | |
| 3304 | 3304 | release_sock(sk); |
| 3305 | 3305 | } |
| 3306 | 3306 | EXPORT_SYMBOL(tcp_sock_set_user_timeout); |
| @@ -3312,7 +3312,8 @@ int tcp_sock_set_keepidle_locked(struct sock *sk, int val) · 5 unmodified lines | ||
| 3312 | 3312 | if (val < 1 || val > MAX_TCP_KEEPIDLE) |
| 3313 | 3313 | return -EINVAL; |
| 3314 | 3314 | |
| 3315 | − tp->keepalive_time = val * HZ; | |
| 3315 | + /* Paired with WRITE_ONCE() in keepalive_time_when() */ | |
| 3316 | + WRITE_ONCE(tp->keepalive_time, val * HZ); | |
| 3316 | 3317 | if (sock_flag(sk, SOCK_KEEPOPEN) && |
| 3317 | 3318 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { |
| 3318 | 3319 | u32 elapsed = keepalive_time_elapsed(tp); |
| @@ -3344,7 +3345,7 @@ int tcp_sock_set_keepintvl(struct sock *sk, int val) · 25 unmodified lines | ||
| 3344 | 3345 | return -EINVAL; |
| 3345 | 3346 | |
| 3346 | 3347 | lock_sock(sk); |
| 3347 | − tcp_sk(sk)->keepalive_intvl = val * HZ; | |
| 3348 | + WRITE_ONCE(tcp_sk(sk)->keepalive_intvl, val * HZ); | |
| 3348 | 3349 | release_sock(sk); |
| 3349 | 3350 | return 0; |
| 3350 | 3351 | } |
| @@ -3356,7 +3357,8 @@ int tcp_sock_set_keepcnt(struct sock *sk, int val) · 5 unmodified lines | ||
| 3356 | 3357 | return -EINVAL; |
| 3357 | 3358 | |
| 3358 | 3359 | lock_sock(sk); |
| 3359 | − tcp_sk(sk)->keepalive_probes = val; | |
| 3360 | + /* Paired with READ_ONCE() in keepalive_probes() */ | |
| 3361 | + WRITE_ONCE(tcp_sk(sk)->keepalive_probes, val); | |
| 3360 | 3362 | release_sock(sk); |
| 3361 | 3363 | return 0; |
| 3362 | 3364 | } |
| @@ -3558,19 +3560,19 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 195 unmodified lines | ||
| 3558 | 3560 | if (val < 1 || val > MAX_TCP_KEEPINTVL) |
| 3559 | 3561 | err = -EINVAL; |
| 3560 | 3562 | else |
| 3561 | − tp->keepalive_intvl = val * HZ; | |
| 3563 | + WRITE_ONCE(tp->keepalive_intvl, val * HZ); | |
| 3562 | 3564 | break; |
| 3563 | 3565 | case TCP_KEEPCNT: |
| 3564 | 3566 | if (val < 1 || val > MAX_TCP_KEEPCNT) |
| 3565 | 3567 | err = -EINVAL; |
| 3566 | 3568 | else |
| 3567 | − tp->keepalive_probes = val; | |
| 3569 | + WRITE_ONCE(tp->keepalive_probes, val); | |
| 3568 | 3570 | break; |
| 3569 | 3571 | case TCP_SYNCNT: |
| 3570 | 3572 | if (val < 1 || val > MAX_TCP_SYNCNT) |
| 3571 | 3573 | err = -EINVAL; |
| 3572 | 3574 | else |
| 3573 | − icsk->icsk_syn_retries = val; | |
| 3575 | + WRITE_ONCE(icsk->icsk_syn_retries, val); | |
| 3574 | 3576 | break; |
| 3575 | 3577 | |
| 3576 | 3578 | case TCP_SAVE_SYN: |
| @@ -3583,18 +3585,18 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 6 unmodified lines | ||
| 3583 | 3585 | |
| 3584 | 3586 | case TCP_LINGER2: |
| 3585 | 3587 | if (val < 0) |
| 3586 | − tp->linger2 = -1; | |
| 3588 | + WRITE_ONCE(tp->linger2, -1); | |
| 3587 | 3589 | else if (val > TCP_FIN_TIMEOUT_MAX / HZ) |
| 3588 | − tp->linger2 = TCP_FIN_TIMEOUT_MAX; | |
| 3590 | + WRITE_ONCE(tp->linger2, TCP_FIN_TIMEOUT_MAX); | |
| 3589 | 3591 | else |
| 3590 | − tp->linger2 = val * HZ; | |
| 3592 | + WRITE_ONCE(tp->linger2, val * HZ); | |
| 3591 | 3593 | break; |
| 3592 | 3594 | |
| 3593 | 3595 | case TCP_DEFER_ACCEPT: |
| 3594 | 3596 | /* Translate value in seconds to number of retransmits */ |
| 3595 | − icsk->icsk_accept_queue.rskq_defer_accept = | |
| 3596 | − secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, | |
| 3597 | − TCP_RTO_MAX / HZ); | |
| 3597 | + WRITE_ONCE(icsk->icsk_accept_queue.rskq_defer_accept, | |
| 3598 | + secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, | |
| 3599 | + TCP_RTO_MAX / HZ)); | |
| 3598 | 3600 | break; |
| 3599 | 3601 | |
| 3600 | 3602 | case TCP_WINDOW_CLAMP: |
| @@ -3618,7 +3620,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 17 unmodified lines | ||
| 3618 | 3620 | if (val < 0) |
| 3619 | 3621 | err = -EINVAL; |
| 3620 | 3622 | else |
| 3621 | − icsk->icsk_user_timeout = val; | |
| 3623 | + WRITE_ONCE(icsk->icsk_user_timeout, val); | |
| 3622 | 3624 | break; |
| 3623 | 3625 | |
| 3624 | 3626 | case TCP_FASTOPEN: |
| @@ -3656,13 +3658,13 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 31 unmodified lines | ||
| 3656 | 3658 | if (!tp->repair) |
| 3657 | 3659 | err = -EPERM; |
| 3658 | 3660 | else |
| 3659 | − tp->tsoffset = val - tcp_time_stamp_raw(); | |
| 3661 | + WRITE_ONCE(tp->tsoffset, val - tcp_time_stamp_raw()); | |
| 3660 | 3662 | break; |
| 3661 | 3663 | case TCP_REPAIR_WINDOW: |
| 3662 | 3664 | err = tcp_repair_set_window(tp, optval, optlen); |
| 3663 | 3665 | break; |
| 3664 | 3666 | case TCP_NOTSENT_LOWAT: |
| 3665 | − tp->notsent_lowat = val; | |
| 3667 | + WRITE_ONCE(tp->notsent_lowat, val); | |
| 3666 | 3668 | sk->sk_write_space(sk); |
| 3667 | 3669 | break; |
| 3668 | 3670 | case TCP_INQ: |
| @@ -3674,7 +3676,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 5 unmodified lines | ||
| 3674 | 3676 | case TCP_TX_DELAY: |
| 3675 | 3677 | if (val) |
| 3676 | 3678 | tcp_enable_tx_delay(); |
| 3677 | − tp->tcp_tx_delay = val; | |
| 3679 | + WRITE_ONCE(tp->tcp_tx_delay, val); | |
| 3678 | 3680 | break; |
| 3679 | 3681 | default: |
| 3680 | 3682 | err = -ENOPROTOOPT; |
| @@ -3991,17 +3993,18 @@ int do_tcp_getsockopt(struct sock *sk, int level, · 310 unmodified lines | ||
| 3991 | 3993 | val = keepalive_probes(tp); |
| 3992 | 3994 | break; |
| 3993 | 3995 | case TCP_SYNCNT: |
| 3994 | − val = icsk->icsk_syn_retries ? : | |
| 3996 | + val = READ_ONCE(icsk->icsk_syn_retries) ? : | |
| 3995 | 3997 | READ_ONCE(net->ipv4.sysctl_tcp_syn_retries); |
| 3996 | 3998 | break; |
| 3997 | 3999 | case TCP_LINGER2: |
| 3998 | − val = tp->linger2; | |
| 4000 | + val = READ_ONCE(tp->linger2); | |
| 3999 | 4001 | if (val >= 0) |
| 4000 | 4002 | val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ; |
| 4001 | 4003 | break; |
| 4002 | 4004 | case TCP_DEFER_ACCEPT: |
| 4003 | − val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept, | |
| 4004 | − TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ); | |
| 4005 | + val = READ_ONCE(icsk->icsk_accept_queue.rskq_defer_accept); | |
| 4006 | + val = retrans_to_secs(val, TCP_TIMEOUT_INIT / HZ, | |
| 4007 | + TCP_RTO_MAX / HZ); | |
| 4005 | 4008 | break; |
| 4006 | 4009 | case TCP_WINDOW_CLAMP: |
| 4007 | 4010 | val = tp->window_clamp; |
| @@ -4138,11 +4141,11 @@ int do_tcp_getsockopt(struct sock *sk, int level, · 130 unmodified lines | ||
| 4138 | 4141 | break; |
| 4139 | 4142 | |
| 4140 | 4143 | case TCP_USER_TIMEOUT: |
| 4141 | − val = icsk->icsk_user_timeout; | |
| 4144 | + val = READ_ONCE(icsk->icsk_user_timeout); | |
| 4142 | 4145 | break; |
| 4143 | 4146 | |
| 4144 | 4147 | case TCP_FASTOPEN: |
| 4145 | − val = icsk->icsk_accept_queue.fastopenq.max_qlen; | |
| 4148 | + val = READ_ONCE(icsk->icsk_accept_queue.fastopenq.max_qlen); | |
| 4146 | 4149 | break; |
| 4147 | 4150 | |
| 4148 | 4151 | case TCP_FASTOPEN_CONNECT: |
| @@ -4154,14 +4157,14 @@ int do_tcp_getsockopt(struct sock *sk, int level, · 5 unmodified lines | ||
| 4154 | 4157 | break; |
| 4155 | 4158 | |
| 4156 | 4159 | case TCP_TX_DELAY: |
| 4157 | − val = tp->tcp_tx_delay; | |
| 4160 | + val = READ_ONCE(tp->tcp_tx_delay); | |
| 4158 | 4161 | break; |
| 4159 | 4162 | |
| 4160 | 4163 | case TCP_TIMESTAMP: |
| 4161 | − val = tcp_time_stamp_raw() + tp->tsoffset; | |
| 4164 | + val = tcp_time_stamp_raw() + READ_ONCE(tp->tsoffset); | |
| 4162 | 4165 | break; |
| 4163 | 4166 | case TCP_NOTSENT_LOWAT: |
| 4164 | − val = tp->notsent_lowat; | |
| 4167 | + val = READ_ONCE(tp->notsent_lowat); | |
| 4165 | 4168 | break; |
| 4166 | 4169 | case TCP_INQ: |
| 4167 | 4170 | val = tp->recvmsg_inq; |
| @@ -296,6 +296,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, · 295 unmodified lines | ||
| 296 | 296 | static bool tcp_fastopen_queue_check(struct sock *sk) |
| 297 | 297 | { |
| 298 | 298 | struct fastopen_queue *fastopenq; |
| 299 | + int max_qlen; | |
| 299 | 300 | |
| 300 | 301 | /* Make sure the listener has enabled fastopen, and we don't |
| 301 | 302 | * exceed the max # of pending TFO requests allowed before trying |
| @@ -308,10 +309,11 @@ static bool tcp_fastopen_queue_check(struct sock *sk) · 6 unmodified lines | ||
| 308 | 309 | * temporarily vs a server not supporting Fast Open at all. |
| 309 | 310 | */ |
| 310 | 311 | fastopenq = &inet_csk(sk)->icsk_accept_queue.fastopenq; |
| 311 | − if (fastopenq->max_qlen == 0) | |
| 312 | + max_qlen = READ_ONCE(fastopenq->max_qlen); | |
| 313 | + if (max_qlen == 0) | |
| 312 | 314 | return false; |
| 313 | 315 | |
| 314 | − if (fastopenq->qlen >= fastopenq->max_qlen) { | |
| 316 | + if (fastopenq->qlen >= max_qlen) { | |
| 315 | 317 | struct request_sock *req1; |
| 316 | 318 | spin_lock(&fastopenq->lock); |
| 317 | 319 | req1 = fastopenq->rskq_rst_head; |
| @@ -307,8 +307,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) · 306 unmodified lines | ||
| 307 | 307 | inet->inet_daddr, |
| 308 | 308 | inet->inet_sport, |
| 309 | 309 | usin->sin_port)); |
| 310 | − tp->tsoffset = secure_tcp_ts_off(net, inet->inet_saddr, | |
| 311 | − inet->inet_daddr); | |
| 310 | + WRITE_ONCE(tp->tsoffset, | |
| 311 | + secure_tcp_ts_off(net, inet->inet_saddr, | |
| 312 | + inet->inet_daddr)); | |
| 312 | 313 | } |
| 313 | 314 | |
| 314 | 315 | inet->inet_id = get_random_u16(); |
| @@ -988,11 +989,12 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, · 673 unmodified lines | ||
| 988 | 989 | tcp_rsk(req)->rcv_nxt, |
| 989 | 990 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, |
| 990 | 991 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, |
| 991 | − req->ts_recent, | |
| 992 | + READ_ONCE(req->ts_recent), | |
| 992 | 993 | 0, |
| 993 | 994 | tcp_md5_do_lookup(sk, l3index, addr, AF_INET), |
| 994 | 995 | inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, |
| 995 | − ip_hdr(skb)->tos, tcp_rsk(req)->txhash); | |
| 996 | + ip_hdr(skb)->tos, | |
| 997 | + READ_ONCE(tcp_rsk(req)->txhash)); | |
| 996 | 998 | } |
| 997 | 999 | |
| 998 | 1000 | /* |
| @@ -528,7 +528,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, · 527 unmodified lines | ||
| 528 | 528 | newicsk->icsk_ack.lrcvtime = tcp_jiffies32; |
| 529 | 529 | |
| 530 | 530 | newtp->lsndtime = tcp_jiffies32; |
| 531 | − newsk->sk_txhash = treq->txhash; | |
| 531 | + newsk->sk_txhash = READ_ONCE(treq->txhash); | |
| 532 | 532 | newtp->total_retrans = req->num_retrans; |
| 533 | 533 | |
| 534 | 534 | tcp_init_xmit_timers(newsk); |
| @@ -555,7 +555,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, · 20 unmodified lines | ||
| 555 | 555 | newtp->max_window = newtp->snd_wnd; |
| 556 | 556 | |
| 557 | 557 | if (newtp->rx_opt.tstamp_ok) { |
| 558 | − newtp->rx_opt.ts_recent = req->ts_recent; | |
| 558 | + newtp->rx_opt.ts_recent = READ_ONCE(req->ts_recent); | |
| 559 | 559 | newtp->rx_opt.ts_recent_stamp = ktime_get_seconds(); |
| 560 | 560 | newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED; |
| 561 | 561 | } else { |
| @@ -619,7 +619,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, · 57 unmodified lines | ||
| 619 | 619 | tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL); |
| 620 | 620 | |
| 621 | 621 | if (tmp_opt.saw_tstamp) { |
| 622 | − tmp_opt.ts_recent = req->ts_recent; | |
| 622 | + tmp_opt.ts_recent = READ_ONCE(req->ts_recent); | |
| 623 | 623 | if (tmp_opt.rcv_tsecr) |
| 624 | 624 | tmp_opt.rcv_tsecr -= tcp_rsk(req)->ts_off; |
| 625 | 625 | /* We do not store true stamp, but it is not required, |
| @@ -758,8 +758,11 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, · 132 unmodified lines | ||
| 758 | 758 | |
| 759 | 759 | /* In sequence, PAWS is OK. */ |
| 760 | 760 | |
| 761 | + /* TODO: We probably should defer ts_recent change once | |
| 762 | + * we take ownership of @req. | |
| 763 | + */ | |
| 761 | 764 | if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) |
| 762 | − req->ts_recent = tmp_opt.rcv_tsval; | |
| 765 | + WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval); | |
| 763 | 766 | |
| 764 | 767 | if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { |
| 765 | 768 | /* Truncate SYN, it is out of window starting |
| @@ -878,7 +878,7 @@ static unsigned int tcp_synack_options(const struct sock *sk, · 877 unmodified lines | ||
| 878 | 878 | if (likely(ireq->tstamp_ok)) { |
| 879 | 879 | opts->options |= OPTION_TS; |
| 880 | 880 | opts->tsval = tcp_skb_timestamp(skb) + tcp_rsk(req)->ts_off; |
| 881 | − opts->tsecr = req->ts_recent; | |
| 881 | + opts->tsecr = READ_ONCE(req->ts_recent); | |
| 882 | 882 | remaining -= TCPOLEN_TSTAMP_ALIGNED; |
| 883 | 883 | } |
| 884 | 884 | if (likely(ireq->sack_ok)) { |
| @@ -3660,7 +3660,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, · 2775 unmodified lines | ||
| 3660 | 3660 | rcu_read_lock(); |
| 3661 | 3661 | md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req)); |
| 3662 | 3662 | #endif |
| 3663 | − skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4); | |
| 3663 | + skb_set_hash(skb, READ_ONCE(tcp_rsk(req)->txhash), PKT_HASH_TYPE_L4); | |
| 3664 | 3664 | /* bpf program will be interested in the tcp_flags */ |
| 3665 | 3665 | TCP_SKB_CB(skb)->tcp_flags = TCPHDR_SYN | TCPHDR_ACK; |
| 3666 | 3666 | tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5, |
| @@ -4210,7 +4210,7 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req) · 543 unmodified lines | ||
| 4210 | 4210 | |
| 4211 | 4211 | /* Paired with WRITE_ONCE() in sock_setsockopt() */ |
| 4212 | 4212 | if (READ_ONCE(sk->sk_txrehash) == SOCK_TXREHASH_ENABLED) |
| 4213 | − tcp_rsk(req)->txhash = net_tx_rndhash(); | |
| 4213 | + WRITE_ONCE(tcp_rsk(req)->txhash, net_tx_rndhash()); | |
| 4214 | 4214 | res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL, |
| 4215 | 4215 | NULL); |
| 4216 | 4216 | if (!res) { |
| @@ -274,13 +274,20 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, · 273 unmodified lines | ||
| 274 | 274 | __sum16 check; |
| 275 | 275 | __be16 newlen; |
| 276 | 276 | |
| 277 | − if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) | |
| 278 | − return __udp_gso_segment_list(gso_skb, features, is_ipv6); | |
| 279 | − | |
| 280 | 277 | mss = skb_shinfo(gso_skb)->gso_size; |
| 281 | 278 | if (gso_skb->len <= sizeof(*uh) + mss) |
| 282 | 279 | return ERR_PTR(-EINVAL); |
| 283 | 280 | |
| 281 | + if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) { | |
| 282 | + /* Packet is from an untrusted source, reset gso_segs. */ | |
| 283 | + skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh), | |
| 284 | + mss); | |
| 285 | + return NULL; | |
| 286 | + } | |
| 287 | + | |
| 288 | + if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) | |
| 289 | + return __udp_gso_segment_list(gso_skb, features, is_ipv6); | |
| 290 | + | |
| 284 | 291 | skb_pull(gso_skb, sizeof(*uh)); |
| 285 | 292 | |
| 286 | 293 | /* clear destructor to avoid skb_segment assigning it to tail */ |
| @@ -388,8 +395,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, · 101 unmodified lines | ||
| 388 | 395 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
| 389 | 396 | goto out; |
| 390 | 397 | |
| 391 | − if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && | |
| 392 | − !skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) | |
| 398 | + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) | |
| 393 | 399 | return __udp_gso_segment(skb, features, false); |
| 394 | 400 | |
| 395 | 401 | mss = skb_shinfo(skb)->gso_size; |
| @@ -955,7 +955,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, · 954 unmodified lines | ||
| 955 | 955 | goto tx_err; |
| 956 | 956 | |
| 957 | 957 | if (skb->len > dev->mtu + dev->hard_header_len) { |
| 958 | − pskb_trim(skb, dev->mtu + dev->hard_header_len); | |
| 958 | + if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) | |
| 959 | + goto tx_err; | |
| 959 | 960 | truncate = true; |
| 960 | 961 | } |
| 961 | 962 | |
| @@ -1126,10 +1126,10 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, · 1125 unmodified lines | ||
| 1126 | 1126 | tcp_rsk(req)->rcv_nxt, |
| 1127 | 1127 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, |
| 1128 | 1128 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, |
| 1129 | − req->ts_recent, sk->sk_bound_dev_if, | |
| 1129 | + READ_ONCE(req->ts_recent), sk->sk_bound_dev_if, | |
| 1130 | 1130 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index), |
| 1131 | 1131 | ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority, |
| 1132 | − tcp_rsk(req)->txhash); | |
| 1132 | + READ_ONCE(tcp_rsk(req)->txhash)); | |
| 1133 | 1133 | } |
| 1134 | 1134 | |
| 1135 | 1135 | |
| @@ -43,8 +43,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, · 42 unmodified lines | ||
| 43 | 43 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
| 44 | 44 | goto out; |
| 45 | 45 | |
| 46 | − if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && | |
| 47 | − !skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) | |
| 46 | + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) | |
| 48 | 47 | return __udp_gso_segment(skb, features, true); |
| 49 | 48 | |
| 50 | 49 | mss = skb_shinfo(skb)->gso_size; |
| @@ -402,7 +402,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) · 401 unmodified lines | ||
| 402 | 402 | memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN); |
| 403 | 403 | laddr.lsap = addr->sllc_sap; |
| 404 | 404 | rc = -EADDRINUSE; /* mac + sap clash. */ |
| 405 | − ask = llc_lookup_established(sap, &daddr, &laddr); | |
| 405 | + ask = llc_lookup_established(sap, &daddr, &laddr, &init_net); | |
| 406 | 406 | if (ask) { |
| 407 | 407 | sock_put(ask); |
| 408 | 408 | goto out_put; |
| @@ -453,11 +453,13 @@ static int llc_exec_conn_trans_actions(struct sock *sk, · 452 unmodified lines | ||
| 453 | 453 | static inline bool llc_estab_match(const struct llc_sap *sap, |
| 454 | 454 | const struct llc_addr *daddr, |
| 455 | 455 | const struct llc_addr *laddr, |
| 456 | − const struct sock *sk) | |
| 456 | + const struct sock *sk, | |
| 457 | + const struct net *net) | |
| 457 | 458 | { |
| 458 | 459 | struct llc_sock *llc = llc_sk(sk); |
| 459 | 460 | |
| 460 | − return llc->laddr.lsap == laddr->lsap && | |
| 461 | + return net_eq(sock_net(sk), net) && | |
| 462 | + llc->laddr.lsap == laddr->lsap && | |
| 461 | 463 | llc->daddr.lsap == daddr->lsap && |
| 462 | 464 | ether_addr_equal(llc->laddr.mac, laddr->mac) && |
| 463 | 465 | ether_addr_equal(llc->daddr.mac, daddr->mac); |
| @@ -468,6 +470,7 @@ static inline bool llc_estab_match(const struct llc_sap *sap, · 4 unmodified lines | ||
| 468 | 470 | * @sap: SAP |
| 469 | 471 | * @daddr: address of remote LLC (MAC + SAP) |
| 470 | 472 | * @laddr: address of local LLC (MAC + SAP) |
| 473 | + * @net: netns to look up a socket in | |
| 471 | 474 | * |
| 472 | 475 | * Search connection list of the SAP and finds connection using the remote |
| 473 | 476 | * mac, remote sap, local mac, and local sap. Returns pointer for |
| @@ -476,7 +479,8 @@ static inline bool llc_estab_match(const struct llc_sap *sap, · 2 unmodified lines | ||
| 476 | 479 | */ |
| 477 | 480 | static struct sock *__llc_lookup_established(struct llc_sap *sap, |
| 478 | 481 | struct llc_addr *daddr, |
| 479 | − struct llc_addr *laddr) | |
| 482 | + struct llc_addr *laddr, | |
| 483 | + const struct net *net) | |
| 480 | 484 | { |
| 481 | 485 | struct sock *rc; |
| 482 | 486 | struct hlist_nulls_node *node; |
| @@ -486,12 +490,12 @@ static struct sock *__llc_lookup_established(struct llc_sap *sap, · 3 unmodified lines | ||
| 486 | 490 | rcu_read_lock(); |
| 487 | 491 | again: |
| 488 | 492 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { |
| 489 | − if (llc_estab_match(sap, daddr, laddr, rc)) { | |
| 493 | + if (llc_estab_match(sap, daddr, laddr, rc, net)) { | |
| 490 | 494 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ |
| 491 | 495 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) |
| 492 | 496 | goto again; |
| 493 | 497 | if (unlikely(llc_sk(rc)->sap != sap || |
| 494 | − !llc_estab_match(sap, daddr, laddr, rc))) { | |
| 498 | + !llc_estab_match(sap, daddr, laddr, rc, net))) { | |
| 495 | 499 | sock_put(rc); |
| 496 | 500 | continue; |
| 497 | 501 | } |
| @@ -513,29 +517,33 @@ found: · 15 unmodified lines | ||
| 513 | 517 | |
| 514 | 518 | struct sock *llc_lookup_established(struct llc_sap *sap, |
| 515 | 519 | struct llc_addr *daddr, |
| 516 | − struct llc_addr *laddr) | |
| 520 | + struct llc_addr *laddr, | |
| 521 | + const struct net *net) | |
| 517 | 522 | { |
| 518 | 523 | struct sock *sk; |
| 519 | 524 | |
| 520 | 525 | local_bh_disable(); |
| 521 | − sk = __llc_lookup_established(sap, daddr, laddr); | |
| 526 | + sk = __llc_lookup_established(sap, daddr, laddr, net); | |
| 522 | 527 | local_bh_enable(); |
| 523 | 528 | return sk; |
| 524 | 529 | } |
| 525 | 530 | |
| 526 | 531 | static inline bool llc_listener_match(const struct llc_sap *sap, |
| 527 | 532 | const struct llc_addr *laddr, |
| 528 | − const struct sock *sk) | |
| 533 | + const struct sock *sk, | |
| 534 | + const struct net *net) | |
| 529 | 535 | { |
| 530 | 536 | struct llc_sock *llc = llc_sk(sk); |
| 531 | 537 | |
| 532 | − return sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN && | |
| 538 | + return net_eq(sock_net(sk), net) && | |
| 539 | + sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN && | |
| 533 | 540 | llc->laddr.lsap == laddr->lsap && |
| 534 | 541 | ether_addr_equal(llc->laddr.mac, laddr->mac); |
| 535 | 542 | } |
| 536 | 543 | |
| 537 | 544 | static struct sock *__llc_lookup_listener(struct llc_sap *sap, |
| 538 | − struct llc_addr *laddr) | |
| 545 | + struct llc_addr *laddr, | |
| 546 | + const struct net *net) | |
| 539 | 547 | { |
| 540 | 548 | struct sock *rc; |
| 541 | 549 | struct hlist_nulls_node *node; |
| @@ -545,12 +553,12 @@ static struct sock *__llc_lookup_listener(struct llc_sap *sap, · 3 unmodified lines | ||
| 545 | 553 | rcu_read_lock(); |
| 546 | 554 | again: |
| 547 | 555 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { |
| 548 | − if (llc_listener_match(sap, laddr, rc)) { | |
| 556 | + if (llc_listener_match(sap, laddr, rc, net)) { | |
| 549 | 557 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ |
| 550 | 558 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) |
| 551 | 559 | goto again; |
| 552 | 560 | if (unlikely(llc_sk(rc)->sap != sap || |
| 553 | − !llc_listener_match(sap, laddr, rc))) { | |
| 561 | + !llc_listener_match(sap, laddr, rc, net))) { | |
| 554 | 562 | sock_put(rc); |
| 555 | 563 | continue; |
| 556 | 564 | } |
| @@ -574,6 +582,7 @@ found: · 17 unmodified lines | ||
| 574 | 582 | * llc_lookup_listener - Finds listener for local MAC + SAP |
| 575 | 583 | * @sap: SAP |
| 576 | 584 | * @laddr: address of local LLC (MAC + SAP) |
| 585 | + * @net: netns to look up a socket in | |
| 577 | 586 | * |
| 578 | 587 | * Search connection list of the SAP and finds connection listening on |
| 579 | 588 | * local mac, and local sap. Returns pointer for parent socket found, |
| @@ -581,24 +590,26 @@ found: · 1 unmodified line | ||
| 581 | 590 | * Caller has to make sure local_bh is disabled. |
| 582 | 591 | */ |
| 583 | 592 | static struct sock *llc_lookup_listener(struct llc_sap *sap, |
| 584 | − struct llc_addr *laddr) | |
| 593 | + struct llc_addr *laddr, | |
| 594 | + const struct net *net) | |
| 585 | 595 | { |
| 596 | + struct sock *rc = __llc_lookup_listener(sap, laddr, net); | |
| 586 | 597 | static struct llc_addr null_addr; |
| 587 | − struct sock *rc = __llc_lookup_listener(sap, laddr); | |
| 588 | 598 | |
| 589 | 599 | if (!rc) |
| 590 | − rc = __llc_lookup_listener(sap, &null_addr); | |
| 600 | + rc = __llc_lookup_listener(sap, &null_addr, net); | |
| 591 | 601 | |
| 592 | 602 | return rc; |
| 593 | 603 | } |
| 594 | 604 | |
| 595 | 605 | static struct sock *__llc_lookup(struct llc_sap *sap, |
| 596 | 606 | struct llc_addr *daddr, |
| 597 | − struct llc_addr *laddr) | |
| 607 | + struct llc_addr *laddr, | |
| 608 | + const struct net *net) | |
| 598 | 609 | { |
| 599 | − struct sock *sk = __llc_lookup_established(sap, daddr, laddr); | |
| 610 | + struct sock *sk = __llc_lookup_established(sap, daddr, laddr, net); | |
| 600 | 611 | |
| 601 | − return sk ? : llc_lookup_listener(sap, laddr); | |
| 612 | + return sk ? : llc_lookup_listener(sap, laddr, net); | |
| 602 | 613 | } |
| 603 | 614 | |
| 604 | 615 | /** |
| @@ -776,7 +787,7 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) · 171 unmodified lines | ||
| 776 | 787 | llc_pdu_decode_da(skb, daddr.mac); |
| 777 | 788 | llc_pdu_decode_dsap(skb, &daddr.lsap); |
| 778 | 789 | |
| 779 | − sk = __llc_lookup(sap, &saddr, &daddr); | |
| 790 | + sk = __llc_lookup(sap, &saddr, &daddr, dev_net(skb->dev)); | |
| 780 | 791 | if (!sk) |
| 781 | 792 | goto drop; |
| 782 | 793 | |
| @@ -92,7 +92,7 @@ int llc_establish_connection(struct sock *sk, const u8 *lmac, u8 *dmac, u8 dsap) · 91 unmodified lines | ||
| 92 | 92 | daddr.lsap = dsap; |
| 93 | 93 | memcpy(daddr.mac, dmac, sizeof(daddr.mac)); |
| 94 | 94 | memcpy(laddr.mac, lmac, sizeof(laddr.mac)); |
| 95 | − existing = llc_lookup_established(llc->sap, &daddr, &laddr); | |
| 95 | + existing = llc_lookup_established(llc->sap, &daddr, &laddr, sock_net(sk)); | |
| 96 | 96 | if (existing) { |
| 97 | 97 | if (existing->sk_state == TCP_ESTABLISHED) { |
| 98 | 98 | sk = existing; |
| @@ -163,9 +163,6 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, · 162 unmodified lines | ||
| 163 | 163 | void (*sta_handler)(struct sk_buff *skb); |
| 164 | 164 | void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb); |
| 165 | 165 | |
| 166 | − if (!net_eq(dev_net(dev), &init_net)) | |
| 167 | − goto drop; | |
| 168 | − | |
| 169 | 166 | /* |
| 170 | 167 | * When the interface is in promisc. mode, drop all the crap that it |
| 171 | 168 | * receives, do not try to analyse it. |
| @@ -294,25 +294,29 @@ static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb, · 293 unmodified lines | ||
| 294 | 294 | |
| 295 | 295 | static inline bool llc_dgram_match(const struct llc_sap *sap, |
| 296 | 296 | const struct llc_addr *laddr, |
| 297 | − const struct sock *sk) | |
| 297 | + const struct sock *sk, | |
| 298 | + const struct net *net) | |
| 298 | 299 | { |
| 299 | 300 | struct llc_sock *llc = llc_sk(sk); |
| 300 | 301 | |
| 301 | 302 | return sk->sk_type == SOCK_DGRAM && |
| 302 | − llc->laddr.lsap == laddr->lsap && | |
| 303 | − ether_addr_equal(llc->laddr.mac, laddr->mac); | |
| 303 | + net_eq(sock_net(sk), net) && | |
| 304 | + llc->laddr.lsap == laddr->lsap && | |
| 305 | + ether_addr_equal(llc->laddr.mac, laddr->mac); | |
| 304 | 306 | } |
| 305 | 307 | |
| 306 | 308 | /** |
| 307 | 309 | * llc_lookup_dgram - Finds dgram socket for the local sap/mac |
| 308 | 310 | * @sap: SAP |
| 309 | 311 | * @laddr: address of local LLC (MAC + SAP) |
| 312 | + * @net: netns to look up a socket in | |
| 310 | 313 | * |
| 311 | 314 | * Search socket list of the SAP and finds connection using the local |
| 312 | 315 | * mac, and local sap. Returns pointer for socket found, %NULL otherwise. |
| 313 | 316 | */ |
| 314 | 317 | static struct sock *llc_lookup_dgram(struct llc_sap *sap, |
| 315 | − const struct llc_addr *laddr) | |
| 318 | + const struct llc_addr *laddr, | |
| 319 | + const struct net *net) | |
| 316 | 320 | { |
| 317 | 321 | struct sock *rc; |
| 318 | 322 | struct hlist_nulls_node *node; |
| @@ -322,12 +326,12 @@ static struct sock *llc_lookup_dgram(struct llc_sap *sap, · 3 unmodified lines | ||
| 322 | 326 | rcu_read_lock_bh(); |
| 323 | 327 | again: |
| 324 | 328 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { |
| 325 | − if (llc_dgram_match(sap, laddr, rc)) { | |
| 329 | + if (llc_dgram_match(sap, laddr, rc, net)) { | |
| 326 | 330 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ |
| 327 | 331 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) |
| 328 | 332 | goto again; |
| 329 | 333 | if (unlikely(llc_sk(rc)->sap != sap || |
| 330 | − !llc_dgram_match(sap, laddr, rc))) { | |
| 334 | + !llc_dgram_match(sap, laddr, rc, net))) { | |
| 331 | 335 | sock_put(rc); |
| 332 | 336 | continue; |
| 333 | 337 | } |
| @@ -429,7 +433,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb) · 95 unmodified lines | ||
| 429 | 433 | llc_sap_mcast(sap, &laddr, skb); |
| 430 | 434 | kfree_skb(skb); |
| 431 | 435 | } else { |
| 432 | − struct sock *sk = llc_lookup_dgram(sap, &laddr); | |
| 436 | + struct sock *sk = llc_lookup_dgram(sap, &laddr, dev_net(skb->dev)); | |
| 433 | 437 | if (sk) { |
| 434 | 438 | llc_sap_rcv(sap, skb, sk); |
| 435 | 439 | sock_put(sk); |
| @@ -3685,8 +3685,6 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) · 3684 unmodified lines | ||
| 3685 | 3685 | if (err < 0) |
| 3686 | 3686 | return err; |
| 3687 | 3687 | } |
| 3688 | − | |
| 3689 | − cond_resched(); | |
| 3690 | 3688 | } |
| 3691 | 3689 | |
| 3692 | 3690 | return 0; |
| @@ -3710,6 +3708,8 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) · 17 unmodified lines | ||
| 3710 | 3708 | err = nft_chain_validate(&ctx, chain); |
| 3711 | 3709 | if (err < 0) |
| 3712 | 3710 | return err; |
| 3711 | + | |
| 3712 | + cond_resched(); | |
| 3713 | 3713 | } |
| 3714 | 3714 | |
| 3715 | 3715 | return 0; |
| @@ -4087,6 +4087,8 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info, · 371 unmodified lines | ||
| 4087 | 4087 | list_for_each_entry(chain, &table->chains, list) { |
| 4088 | 4088 | if (!nft_is_active_next(net, chain)) |
| 4089 | 4089 | continue; |
| 4090 | + if (nft_chain_is_bound(chain)) | |
| 4091 | + continue; | |
| 4090 | 4092 | |
| 4091 | 4093 | ctx.chain = chain; |
| 4092 | 4094 | err = nft_delrule_by_chain(&ctx); |
| @@ -10517,6 +10519,9 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, · 6424 unmodified lines | ||
| 10517 | 10519 | |
| 10518 | 10520 | if (!tb[NFTA_VERDICT_CODE]) |
| 10519 | 10521 | return -EINVAL; |
| 10522 | + | |
| 10523 | + /* zero padding hole for memcmp */ | |
| 10524 | + memset(data, 0, sizeof(*data)); | |
| 10520 | 10525 | data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); |
| 10521 | 10526 | |
| 10522 | 10527 | switch (data->verdict.code) { |
| @@ -10799,6 +10804,9 @@ static void __nft_release_table(struct net *net, struct nft_table *table) · 276 unmodified lines | ||
| 10799 | 10804 | ctx.family = table->family; |
| 10800 | 10805 | ctx.table = table; |
| 10801 | 10806 | list_for_each_entry(chain, &table->chains, list) { |
| 10807 | + if (nft_chain_is_bound(chain)) | |
| 10808 | + continue; | |
| 10809 | + | |
| 10802 | 10810 | ctx.chain = chain; |
| 10803 | 10811 | list_for_each_entry_safe(rule, nr, &chain->rules, list) { |
| 10804 | 10812 | list_del(&rule->list); |
| @@ -1929,7 +1929,11 @@ static void nft_pipapo_remove(const struct net *net, const struct nft_set *set, · 1928 unmodified lines | ||
| 1929 | 1929 | int i, start, rules_fx; |
| 1930 | 1930 | |
| 1931 | 1931 | match_start = data; |
| 1932 | − match_end = (const u8 *)nft_set_ext_key_end(&e->ext)->data; | |
| 1932 | + | |
| 1933 | + if (nft_set_ext_exists(&e->ext, NFT_SET_EXT_KEY_END)) | |
| 1934 | + match_end = (const u8 *)nft_set_ext_key_end(&e->ext)->data; | |
| 1935 | + else | |
| 1936 | + match_end = data; | |
| 1933 | 1937 | |
| 1934 | 1938 | start = first_rule; |
| 1935 | 1939 | rules_fx = rules_f0; |
| @@ -406,56 +406,6 @@ static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog, · 405 unmodified lines | ||
| 406 | 406 | return 0; |
| 407 | 407 | } |
| 408 | 408 | |
| 409 | −static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp, | |
| 410 | − struct cls_bpf_prog *prog, unsigned long base, | |
| 411 | − struct nlattr **tb, struct nlattr *est, u32 flags, | |
| 412 | − struct netlink_ext_ack *extack) | |
| 413 | −{ | |
| 414 | − bool is_bpf, is_ebpf, have_exts = false; | |
| 415 | − u32 gen_flags = 0; | |
| 416 | − int ret; | |
| 417 | − | |
| 418 | − is_bpf = tb[TCA_BPF_OPS_LEN] && tb[TCA_BPF_OPS]; | |
| 419 | − is_ebpf = tb[TCA_BPF_FD]; | |
| 420 | − if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) | |
| 421 | − return -EINVAL; | |
| 422 | − | |
| 423 | − ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, flags, | |
| 424 | − extack); | |
| 425 | − if (ret < 0) | |
| 426 | − return ret; | |
| 427 | − | |
| 428 | − if (tb[TCA_BPF_FLAGS]) { | |
| 429 | − u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]); | |
| 430 | − | |
| 431 | − if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT) | |
| 432 | − return -EINVAL; | |
| 433 | − | |
| 434 | − have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT; | |
| 435 | − } | |
| 436 | − if (tb[TCA_BPF_FLAGS_GEN]) { | |
| 437 | − gen_flags = nla_get_u32(tb[TCA_BPF_FLAGS_GEN]); | |
| 438 | − if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS || | |
| 439 | − !tc_flags_valid(gen_flags)) | |
| 440 | − return -EINVAL; | |
| 441 | − } | |
| 442 | − | |
| 443 | − prog->exts_integrated = have_exts; | |
| 444 | − prog->gen_flags = gen_flags; | |
| 445 | − | |
| 446 | − ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) : | |
| 447 | − cls_bpf_prog_from_efd(tb, prog, gen_flags, tp); | |
| 448 | − if (ret < 0) | |
| 449 | − return ret; | |
| 450 | − | |
| 451 | − if (tb[TCA_BPF_CLASSID]) { | |
| 452 | − prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]); | |
| 453 | − tcf_bind_filter(tp, &prog->res, base); | |
| 454 | − } | |
| 455 | − | |
| 456 | − return 0; | |
| 457 | −} | |
| 458 | − | |
| 459 | 409 | static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, |
| 460 | 410 | struct tcf_proto *tp, unsigned long base, |
| 461 | 411 | u32 handle, struct nlattr **tca, |
| @@ -463,9 +413,12 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, · 1 unmodified line | ||
| 463 | 413 | struct netlink_ext_ack *extack) |
| 464 | 414 | { |
| 465 | 415 | struct cls_bpf_head *head = rtnl_dereference(tp->root); |
| 416 | + bool is_bpf, is_ebpf, have_exts = false; | |
| 466 | 417 | struct cls_bpf_prog *oldprog = *arg; |
| 467 | 418 | struct nlattr *tb[TCA_BPF_MAX + 1]; |
| 419 | + bool bound_to_filter = false; | |
| 468 | 420 | struct cls_bpf_prog *prog; |
| 421 | + u32 gen_flags = 0; | |
| 469 | 422 | int ret; |
| 470 | 423 | |
| 471 | 424 | if (tca[TCA_OPTIONS] == NULL) |
| @@ -504,11 +457,51 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, · 32 unmodified lines | ||
| 504 | 457 | goto errout; |
| 505 | 458 | prog->handle = handle; |
| 506 | 459 | |
| 507 | − ret = cls_bpf_set_parms(net, tp, prog, base, tb, tca[TCA_RATE], flags, | |
| 508 | − extack); | |
| 460 | + is_bpf = tb[TCA_BPF_OPS_LEN] && tb[TCA_BPF_OPS]; | |
| 461 | + is_ebpf = tb[TCA_BPF_FD]; | |
| 462 | + if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) { | |
| 463 | + ret = -EINVAL; | |
| 464 | + goto errout_idr; | |
| 465 | + } | |
| 466 | + | |
| 467 | + ret = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &prog->exts, | |
| 468 | + flags, extack); | |
| 469 | + if (ret < 0) | |
| 470 | + goto errout_idr; | |
| 471 | + | |
| 472 | + if (tb[TCA_BPF_FLAGS]) { | |
| 473 | + u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]); | |
| 474 | + | |
| 475 | + if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT) { | |
| 476 | + ret = -EINVAL; | |
| 477 | + goto errout_idr; | |
| 478 | + } | |
| 479 | + | |
| 480 | + have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT; | |
| 481 | + } | |
| 482 | + if (tb[TCA_BPF_FLAGS_GEN]) { | |
| 483 | + gen_flags = nla_get_u32(tb[TCA_BPF_FLAGS_GEN]); | |
| 484 | + if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS || | |
| 485 | + !tc_flags_valid(gen_flags)) { | |
| 486 | + ret = -EINVAL; | |
| 487 | + goto errout_idr; | |
| 488 | + } | |
| 489 | + } | |
| 490 | + | |
| 491 | + prog->exts_integrated = have_exts; | |
| 492 | + prog->gen_flags = gen_flags; | |
| 493 | + | |
| 494 | + ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) : | |
| 495 | + cls_bpf_prog_from_efd(tb, prog, gen_flags, tp); | |
| 509 | 496 | if (ret < 0) |
| 510 | 497 | goto errout_idr; |
| 511 | 498 | |
| 499 | + if (tb[TCA_BPF_CLASSID]) { | |
| 500 | + prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]); | |
| 501 | + tcf_bind_filter(tp, &prog->res, base); | |
| 502 | + bound_to_filter = true; | |
| 503 | + } | |
| 504 | + | |
| 512 | 505 | ret = cls_bpf_offload(tp, prog, oldprog, extack); |
| 513 | 506 | if (ret) |
| 514 | 507 | goto errout_parms; |
| @@ -530,6 +523,8 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, · 15 unmodified lines | ||
| 530 | 523 | return 0; |
| 531 | 524 | |
| 532 | 525 | errout_parms: |
| 526 | + if (bound_to_filter) | |
| 527 | + tcf_unbind_filter(tp, &prog->res); | |
| 533 | 528 | cls_bpf_free_parms(prog); |
| 534 | 529 | errout_idr: |
| 535 | 530 | if (!oldprog) |
| @@ -2173,53 +2173,6 @@ static bool fl_needs_tc_skb_ext(const struct fl_flow_key *mask) · 2172 unmodified lines | ||
| 2173 | 2173 | return mask->meta.l2_miss; |
| 2174 | 2174 | } |
| 2175 | 2175 | |
| 2176 | −static int fl_set_parms(struct net *net, struct tcf_proto *tp, | |
| 2177 | − struct cls_fl_filter *f, struct fl_flow_mask *mask, | |
| 2178 | − unsigned long base, struct nlattr **tb, | |
| 2179 | − struct nlattr *est, | |
| 2180 | − struct fl_flow_tmplt *tmplt, | |
| 2181 | − u32 flags, u32 fl_flags, | |
| 2182 | − struct netlink_ext_ack *extack) | |
| 2183 | −{ | |
| 2184 | − int err; | |
| 2185 | − | |
| 2186 | − err = tcf_exts_validate_ex(net, tp, tb, est, &f->exts, flags, | |
| 2187 | − fl_flags, extack); | |
| 2188 | − if (err < 0) | |
| 2189 | − return err; | |
| 2190 | − | |
| 2191 | − if (tb[TCA_FLOWER_CLASSID]) { | |
| 2192 | − f->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]); | |
| 2193 | − if (flags & TCA_ACT_FLAGS_NO_RTNL) | |
| 2194 | − rtnl_lock(); | |
| 2195 | − tcf_bind_filter(tp, &f->res, base); | |
| 2196 | − if (flags & TCA_ACT_FLAGS_NO_RTNL) | |
| 2197 | − rtnl_unlock(); | |
| 2198 | − } | |
| 2199 | − | |
| 2200 | − err = fl_set_key(net, tb, &f->key, &mask->key, extack); | |
| 2201 | − if (err) | |
| 2202 | − return err; | |
| 2203 | − | |
| 2204 | − fl_mask_update_range(mask); | |
| 2205 | − fl_set_masked_key(&f->mkey, &f->key, mask); | |
| 2206 | − | |
| 2207 | − if (!fl_mask_fits_tmplt(tmplt, mask)) { | |
| 2208 | − NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template"); | |
| 2209 | − return -EINVAL; | |
| 2210 | − } | |
| 2211 | − | |
| 2212 | − /* Enable tc skb extension if filter matches on data extracted from | |
| 2213 | − * this extension. | |
| 2214 | − */ | |
| 2215 | − if (fl_needs_tc_skb_ext(&mask->key)) { | |
| 2216 | − f->needs_tc_skb_ext = 1; | |
| 2217 | − tc_skb_ext_tc_enable(); | |
| 2218 | − } | |
| 2219 | − | |
| 2220 | − return 0; | |
| 2221 | −} | |
| 2222 | − | |
| 2223 | 2176 | static int fl_ht_insert_unique(struct cls_fl_filter *fnew, |
| 2224 | 2177 | struct cls_fl_filter *fold, |
| 2225 | 2178 | bool *in_ht) |
| @@ -2251,6 +2204,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, · 25 unmodified lines | ||
| 2251 | 2204 | struct cls_fl_head *head = fl_head_dereference(tp); |
| 2252 | 2205 | bool rtnl_held = !(flags & TCA_ACT_FLAGS_NO_RTNL); |
| 2253 | 2206 | struct cls_fl_filter *fold = *arg; |
| 2207 | + bool bound_to_filter = false; | |
| 2254 | 2208 | struct cls_fl_filter *fnew; |
| 2255 | 2209 | struct fl_flow_mask *mask; |
| 2256 | 2210 | struct nlattr **tb; |
| @@ -2335,15 +2289,46 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, · 78 unmodified lines | ||
| 2335 | 2289 | if (err < 0) |
| 2336 | 2290 | goto errout_idr; |
| 2337 | 2291 | |
| 2338 | − err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], | |
| 2339 | − tp->chain->tmplt_priv, flags, fnew->flags, | |
| 2340 | − extack); | |
| 2341 | − if (err) | |
| 2292 | + err = tcf_exts_validate_ex(net, tp, tb, tca[TCA_RATE], | |
| 2293 | + &fnew->exts, flags, fnew->flags, | |
| 2294 | + extack); | |
| 2295 | + if (err < 0) | |
| 2342 | 2296 | goto errout_idr; |
| 2343 | 2297 | |
| 2298 | + if (tb[TCA_FLOWER_CLASSID]) { | |
| 2299 | + fnew->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]); | |
| 2300 | + if (flags & TCA_ACT_FLAGS_NO_RTNL) | |
| 2301 | + rtnl_lock(); | |
| 2302 | + tcf_bind_filter(tp, &fnew->res, base); | |
| 2303 | + if (flags & TCA_ACT_FLAGS_NO_RTNL) | |
| 2304 | + rtnl_unlock(); | |
| 2305 | + bound_to_filter = true; | |
| 2306 | + } | |
| 2307 | + | |
| 2308 | + err = fl_set_key(net, tb, &fnew->key, &mask->key, extack); | |
| 2309 | + if (err) | |
| 2310 | + goto unbind_filter; | |
| 2311 | + | |
| 2312 | + fl_mask_update_range(mask); | |
| 2313 | + fl_set_masked_key(&fnew->mkey, &fnew->key, mask); | |
| 2314 | + | |
| 2315 | + if (!fl_mask_fits_tmplt(tp->chain->tmplt_priv, mask)) { | |
| 2316 | + NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template"); | |
| 2317 | + err = -EINVAL; | |
| 2318 | + goto unbind_filter; | |
| 2319 | + } | |
| 2320 | + | |
| 2321 | + /* Enable tc skb extension if filter matches on data extracted from | |
| 2322 | + * this extension. | |
| 2323 | + */ | |
| 2324 | + if (fl_needs_tc_skb_ext(&mask->key)) { | |
| 2325 | + fnew->needs_tc_skb_ext = 1; | |
| 2326 | + tc_skb_ext_tc_enable(); | |
| 2327 | + } | |
| 2328 | + | |
| 2344 | 2329 | err = fl_check_assign_mask(head, fnew, fold, mask); |
| 2345 | 2330 | if (err) |
| 2346 | − goto errout_idr; | |
| 2331 | + goto unbind_filter; | |
| 2347 | 2332 | |
| 2348 | 2333 | err = fl_ht_insert_unique(fnew, fold, &in_ht); |
| 2349 | 2334 | if (err) |
| @@ -2434,6 +2419,16 @@ errout_hw: · 84 unmodified lines | ||
| 2434 | 2419 | fnew->mask->filter_ht_params); |
| 2435 | 2420 | errout_mask: |
| 2436 | 2421 | fl_mask_put(head, fnew->mask); |
| 2422 | + | |
| 2423 | +unbind_filter: | |
| 2424 | + if (bound_to_filter) { | |
| 2425 | + if (flags & TCA_ACT_FLAGS_NO_RTNL) | |
| 2426 | + rtnl_lock(); | |
| 2427 | + tcf_unbind_filter(tp, &fnew->res); | |
| 2428 | + if (flags & TCA_ACT_FLAGS_NO_RTNL) | |
| 2429 | + rtnl_unlock(); | |
| 2430 | + } | |
| 2431 | + | |
| 2437 | 2432 | errout_idr: |
| 2438 | 2433 | if (!fold) |
| 2439 | 2434 | idr_remove(&head->handle_idr, fnew->handle); |
| @@ -159,26 +159,6 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = { · 158 unmodified lines | ||
| 159 | 159 | [TCA_MATCHALL_FLAGS] = { .type = NLA_U32 }, |
| 160 | 160 | }; |
| 161 | 161 | |
| 162 | −static int mall_set_parms(struct net *net, struct tcf_proto *tp, | |
| 163 | − struct cls_mall_head *head, | |
| 164 | − unsigned long base, struct nlattr **tb, | |
| 165 | − struct nlattr *est, u32 flags, u32 fl_flags, | |
| 166 | − struct netlink_ext_ack *extack) | |
| 167 | −{ | |
| 168 | − int err; | |
| 169 | − | |
| 170 | − err = tcf_exts_validate_ex(net, tp, tb, est, &head->exts, flags, | |
| 171 | − fl_flags, extack); | |
| 172 | − if (err < 0) | |
| 173 | − return err; | |
| 174 | − | |
| 175 | − if (tb[TCA_MATCHALL_CLASSID]) { | |
| 176 | − head->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]); | |
| 177 | − tcf_bind_filter(tp, &head->res, base); | |
| 178 | − } | |
| 179 | − return 0; | |
| 180 | −} | |
| 181 | − | |
| 182 | 162 | static int mall_change(struct net *net, struct sk_buff *in_skb, |
| 183 | 163 | struct tcf_proto *tp, unsigned long base, |
| 184 | 164 | u32 handle, struct nlattr **tca, |
| @@ -187,6 +167,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, · 2 unmodified lines | ||
| 187 | 167 | { |
| 188 | 168 | struct cls_mall_head *head = rtnl_dereference(tp->root); |
| 189 | 169 | struct nlattr *tb[TCA_MATCHALL_MAX + 1]; |
| 170 | + bool bound_to_filter = false; | |
| 190 | 171 | struct cls_mall_head *new; |
| 191 | 172 | u32 userflags = 0; |
| 192 | 173 | int err; |
| @@ -226,11 +207,17 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, · 33 unmodified lines | ||
| 226 | 207 | goto err_alloc_percpu; |
| 227 | 208 | } |
| 228 | 209 | |
| 229 | − err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], | |
| 230 | − flags, new->flags, extack); | |
| 231 | − if (err) | |
| 210 | + err = tcf_exts_validate_ex(net, tp, tb, tca[TCA_RATE], | |
| 211 | + &new->exts, flags, new->flags, extack); | |
| 212 | + if (err < 0) | |
| 232 | 213 | goto err_set_parms; |
| 233 | 214 | |
| 215 | + if (tb[TCA_MATCHALL_CLASSID]) { | |
| 216 | + new->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]); | |
| 217 | + tcf_bind_filter(tp, &new->res, base); | |
| 218 | + bound_to_filter = true; | |
| 219 | + } | |
| 220 | + | |
| 234 | 221 | if (!tc_skip_hw(new->flags)) { |
| 235 | 222 | err = mall_replace_hw_filter(tp, new, (unsigned long)new, |
| 236 | 223 | extack); |
| @@ -246,6 +233,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, · 9 unmodified lines | ||
| 246 | 233 | return 0; |
| 247 | 234 | |
| 248 | 235 | err_replace_hw_filter: |
| 236 | + if (bound_to_filter) | |
| 237 | + tcf_unbind_filter(tp, &new->res); | |
| 249 | 238 | err_set_parms: |
| 250 | 239 | free_percpu(new->pf); |
| 251 | 240 | err_alloc_percpu: |
| @@ -712,8 +712,23 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { · 711 unmodified lines | ||
| 712 | 712 | [TCA_U32_FLAGS] = { .type = NLA_U32 }, |
| 713 | 713 | }; |
| 714 | 714 | |
| 715 | +static void u32_unbind_filter(struct tcf_proto *tp, struct tc_u_knode *n, | |
| 716 | + struct nlattr **tb) | |
| 717 | +{ | |
| 718 | + if (tb[TCA_U32_CLASSID]) | |
| 719 | + tcf_unbind_filter(tp, &n->res); | |
| 720 | +} | |
| 721 | + | |
| 722 | +static void u32_bind_filter(struct tcf_proto *tp, struct tc_u_knode *n, | |
| 723 | + unsigned long base, struct nlattr **tb) | |
| 724 | +{ | |
| 725 | + if (tb[TCA_U32_CLASSID]) { | |
| 726 | + n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]); | |
| 727 | + tcf_bind_filter(tp, &n->res, base); | |
| 728 | + } | |
| 729 | +} | |
| 730 | + | |
| 715 | 731 | static int u32_set_parms(struct net *net, struct tcf_proto *tp, |
| 716 | − unsigned long base, | |
| 717 | 732 | struct tc_u_knode *n, struct nlattr **tb, |
| 718 | 733 | struct nlattr *est, u32 flags, u32 fl_flags, |
| 719 | 734 | struct netlink_ext_ack *extack) |
| @@ -760,10 +775,6 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, · 40 unmodified lines | ||
| 760 | 775 | if (ht_old) |
| 761 | 776 | ht_old->refcnt--; |
| 762 | 777 | } |
| 763 | − if (tb[TCA_U32_CLASSID]) { | |
| 764 | − n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]); | |
| 765 | − tcf_bind_filter(tp, &n->res, base); | |
| 766 | − } | |
| 767 | 778 | |
| 768 | 779 | if (ifindex >= 0) |
| 769 | 780 | n->ifindex = ifindex; |
| @@ -903,17 +914,27 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, · 133 unmodified lines | ||
| 903 | 914 | if (!new) |
| 904 | 915 | return -ENOMEM; |
| 905 | 916 | |
| 906 | − err = u32_set_parms(net, tp, base, new, tb, | |
| 907 | − tca[TCA_RATE], flags, new->flags, | |
| 908 | − extack); | |
| 917 | + err = u32_set_parms(net, tp, new, tb, tca[TCA_RATE], | |
| 918 | + flags, new->flags, extack); | |
| 909 | 919 | |
| 910 | 920 | if (err) { |
| 911 | 921 | __u32_destroy_key(new); |
| 912 | 922 | return err; |
| 913 | 923 | } |
| 914 | 924 | |
| 925 | + u32_bind_filter(tp, new, base, tb); | |
| 926 | + | |
| 915 | 927 | err = u32_replace_hw_knode(tp, new, flags, extack); |
| 916 | 928 | if (err) { |
| 929 | + u32_unbind_filter(tp, new, tb); | |
| 930 | + | |
| 931 | + if (tb[TCA_U32_LINK]) { | |
| 932 | + struct tc_u_hnode *ht_old; | |
| 933 | + | |
| 934 | + ht_old = rtnl_dereference(n->ht_down); | |
| 935 | + if (ht_old) | |
| 936 | + ht_old->refcnt++; | |
| 937 | + } | |
| 917 | 938 | __u32_destroy_key(new); |
| 918 | 939 | return err; |
| 919 | 940 | } |
| @@ -1074,15 +1095,18 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, · 154 unmodified lines | ||
| 1074 | 1095 | } |
| 1075 | 1096 | #endif |
| 1076 | 1097 | |
| 1077 | − err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], | |
| 1098 | + err = u32_set_parms(net, tp, n, tb, tca[TCA_RATE], | |
| 1078 | 1099 | flags, n->flags, extack); |
| 1100 | + | |
| 1101 | + u32_bind_filter(tp, n, base, tb); | |
| 1102 | + | |
| 1079 | 1103 | if (err == 0) { |
| 1080 | 1104 | struct tc_u_knode __rcu **ins; |
| 1081 | 1105 | struct tc_u_knode *pins; |
| 1082 | 1106 | |
| 1083 | 1107 | err = u32_replace_hw_knode(tp, n, flags, extack); |
| 1084 | 1108 | if (err) |
| 1085 | − goto errhw; | |
| 1109 | + goto errunbind; | |
| 1086 | 1110 | |
| 1087 | 1111 | if (!tc_in_hw(n->flags)) |
| 1088 | 1112 | n->flags |= TCA_CLS_FLAGS_NOT_IN_HW; |
| @@ -1100,7 +1124,9 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, · 11 unmodified lines | ||
| 1100 | 1124 | return 0; |
| 1101 | 1125 | } |
| 1102 | 1126 | |
| 1103 | −errhw: | |
| 1127 | +errunbind: | |
| 1128 | + u32_unbind_filter(tp, n, tb); | |
| 1129 | + | |
| 1104 | 1130 | #ifdef CONFIG_CLS_U32_MARK |
| 1105 | 1131 | free_percpu(n->pcpu_success); |
| 1106 | 1132 | #endif |
| @@ -22,9 +22,16 @@ static int timer_cb(void *map, int *key, struct bpf_timer *timer) · 21 unmodified lines | ||
| 22 | 22 | return buf[69]; |
| 23 | 23 | } |
| 24 | 24 | |
| 25 | +__attribute__((noinline)) | |
| 26 | +static int bad_timer_cb(void *map, int *key, struct bpf_timer *timer) | |
| 27 | +{ | |
| 28 | + volatile char buf[300] = {}; | |
| 29 | + return buf[255] + timer_cb(NULL, NULL, NULL); | |
| 30 | +} | |
| 31 | + | |
| 25 | 32 | SEC("tc") |
| 26 | −__failure __msg("combined stack size of 2 calls") | |
| 27 | −int prog(struct __sk_buff *ctx) | |
| 33 | +__failure __msg("combined stack size of 2 calls is 576. Too large") | |
| 34 | +int pseudo_call_check(struct __sk_buff *ctx) | |
| 28 | 35 | { |
| 29 | 36 | struct hmap_elem *elem; |
| 30 | 37 | volatile char buf[256] = {}; |
| @@ -37,4 +44,18 @@ int prog(struct __sk_buff *ctx) · 6 unmodified lines | ||
| 37 | 44 | return bpf_timer_set_callback(&elem->timer, timer_cb) + buf[0]; |
| 38 | 45 | } |
| 39 | 46 | |
| 47 | +SEC("tc") | |
| 48 | +__failure __msg("combined stack size of 2 calls is 608. Too large") | |
| 49 | +int async_call_root_check(struct __sk_buff *ctx) | |
| 50 | +{ | |
| 51 | + struct hmap_elem *elem; | |
| 52 | + volatile char buf[256] = {}; | |
| 53 | + | |
| 54 | + elem = bpf_map_lookup_elem(&hmap, &(int){0}); | |
| 55 | + if (!elem) | |
| 56 | + return 0; | |
| 57 | + | |
| 58 | + return bpf_timer_set_callback(&elem->timer, bad_timer_cb) + buf[0]; | |
| 59 | +} | |
| 60 | + | |
| 40 | 61 | char _license[] SEC("license") = "GPL"; |
| @@ -5,6 +5,8 @@ CONFIG_NF_CONNTRACK=m · 4 unmodified lines | ||
| 5 | 5 | CONFIG_NF_CONNTRACK_MARK=y |
| 6 | 6 | CONFIG_NF_CONNTRACK_ZONES=y |
| 7 | 7 | CONFIG_NF_CONNTRACK_LABELS=y |
| 8 | +CONFIG_NF_CONNTRACK_PROCFS=y | |
| 9 | +CONFIG_NF_FLOW_TABLE=m | |
| 8 | 10 | CONFIG_NF_NAT=m |
| 9 | 11 | CONFIG_NETFILTER_XT_TARGET_LOG=m |
| 10 | 12 | |
| @@ -0,0 +1 @@ | ||
| 1 | +timeout=900 | |