diff options
author | Mike Pagano <mpagano@gentoo.org> | 2023-06-05 07:50:42 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2023-06-05 07:50:42 -0400 |
commit | 69042ad09e4a5c8bbee21cfb0a2d5b0eb665106e (patch) | |
tree | 6346bc62463814decc8a318bccfb1ea2c8090ca6 | |
parent | Linux patch 5.4.244 (diff) | |
download | linux-patches-69042ad09e4a5c8bbee21cfb0a2d5b0eb665106e.tar.gz linux-patches-69042ad09e4a5c8bbee21cfb0a2d5b0eb665106e.tar.bz2 linux-patches-69042ad09e4a5c8bbee21cfb0a2d5b0eb665106e.zip |
Linux patch 5.4.2455.4-252
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1244_linux-5.4.245.patch | 1307 |
2 files changed, 1311 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 2bc77166..780ca5e9 100644 --- a/0000_README +++ b/0000_README @@ -1019,6 +1019,10 @@ Patch: 1243_linux-5.4.244.patch From: https://www.kernel.org Desc: Linux 5.4.244 +Patch: 1244_linux-5.4.245.patch +From: https://www.kernel.org +Desc: Linux 5.4.245 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1244_linux-5.4.245.patch b/1244_linux-5.4.245.patch new file mode 100644 index 00000000..39dd4d96 --- /dev/null +++ b/1244_linux-5.4.245.patch @@ -0,0 +1,1307 @@ +diff --git a/Makefile b/Makefile +index a12f1af9b03b1..c0a1daa41dc04 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 244 ++SUBLEVEL = 245 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 4b96742f0fe57..1c39cd12b755a 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -2270,24 +2270,23 @@ static void binder_deferred_fd_close(int fd) + static void binder_transaction_buffer_release(struct binder_proc *proc, + struct binder_thread *thread, + struct binder_buffer *buffer, +- binder_size_t failed_at, ++ binder_size_t off_end_offset, + bool is_failure) + { + int debug_id = buffer->debug_id; +- binder_size_t off_start_offset, buffer_offset, off_end_offset; ++ binder_size_t off_start_offset, buffer_offset; + + binder_debug(BINDER_DEBUG_TRANSACTION, + "%d buffer release %d, size %zd-%zd, failed at %llx\n", + proc->pid, buffer->debug_id, + buffer->data_size, buffer->offsets_size, +- (unsigned long long)failed_at); ++ (unsigned long long)off_end_offset); + + if (buffer->target_node) + binder_dec_node(buffer->target_node, 1, 0); + + off_start_offset = ALIGN(buffer->data_size, sizeof(void *)); +- off_end_offset = is_failure && failed_at ? failed_at : +- off_start_offset + buffer->offsets_size; ++ + for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; + buffer_offset += sizeof(binder_size_t)) { + struct binder_object_header *hdr; +@@ -2447,6 +2446,21 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, + } + } + ++/* Clean up all the objects in the buffer */ ++static inline void binder_release_entire_buffer(struct binder_proc *proc, ++ struct binder_thread *thread, ++ struct binder_buffer *buffer, ++ bool is_failure) ++{ ++ binder_size_t off_end_offset; ++ ++ off_end_offset = ALIGN(buffer->data_size, sizeof(void *)); ++ off_end_offset += buffer->offsets_size; ++ ++ binder_transaction_buffer_release(proc, thread, buffer, ++ off_end_offset, is_failure); ++} ++ + static int binder_translate_binder(struct flat_binder_object *fp, + struct binder_transaction *t, + struct binder_thread *thread) +@@ -3930,7 +3944,7 @@ binder_free_buf(struct binder_proc *proc, + binder_node_inner_unlock(buf_node); + } + trace_binder_transaction_buffer_release(buffer); +- binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure); ++ binder_release_entire_buffer(proc, thread, buffer, is_failure); + binder_alloc_free_buf(&proc->alloc, buffer); + } + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c +index abd066e952286..438be215bbd45 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c +@@ -3,6 +3,7 @@ + + #include <linux/mlx5/vport.h> + #include "lib/devcom.h" ++#include "mlx5_core.h" + + static LIST_HEAD(devcom_list); + +@@ -14,7 +15,7 @@ static LIST_HEAD(devcom_list); + struct mlx5_devcom_component { + struct { + void *data; +- } device[MLX5_MAX_PORTS]; ++ } device[MLX5_DEVCOM_PORTS_SUPPORTED]; + + mlx5_devcom_event_handler_t handler; + struct rw_semaphore sem; +@@ -25,7 +26,7 @@ struct mlx5_devcom_list { + struct list_head list; + + struct mlx5_devcom_component components[MLX5_DEVCOM_NUM_COMPONENTS]; +- struct mlx5_core_dev *devs[MLX5_MAX_PORTS]; ++ struct mlx5_core_dev *devs[MLX5_DEVCOM_PORTS_SUPPORTED]; + }; + + struct mlx5_devcom { +@@ -74,13 +75,16 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev) + + if (!mlx5_core_is_pf(dev)) + return NULL; ++ if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED) ++ return NULL; + ++ mlx5_dev_list_lock(); + sguid0 = mlx5_query_nic_system_image_guid(dev); + list_for_each_entry(iter, &devcom_list, list) { + struct mlx5_core_dev *tmp_dev = NULL; + + idx = -1; +- for (i = 0; i < MLX5_MAX_PORTS; i++) { ++ for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) { + if (iter->devs[i]) + tmp_dev = iter->devs[i]; + else +@@ -100,8 +104,10 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev) + + if (!priv) { + priv = mlx5_devcom_list_alloc(); +- if (!priv) +- return ERR_PTR(-ENOMEM); ++ if (!priv) { ++ devcom = ERR_PTR(-ENOMEM); ++ goto out; ++ } + + idx = 0; + new_priv = true; +@@ -112,12 +118,14 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev) + if (!devcom) { + if (new_priv) + kfree(priv); +- return ERR_PTR(-ENOMEM); ++ devcom = ERR_PTR(-ENOMEM); ++ goto out; + } + + if (new_priv) + list_add(&priv->list, &devcom_list); +- ++out: ++ mlx5_dev_list_unlock(); + return devcom; + } + +@@ -130,20 +138,23 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom) + if (IS_ERR_OR_NULL(devcom)) + return; + ++ mlx5_dev_list_lock(); + priv = devcom->priv; + priv->devs[devcom->idx] = NULL; + + kfree(devcom); + +- for (i = 0; i < MLX5_MAX_PORTS; i++) ++ for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) + if (priv->devs[i]) + break; + +- if (i != MLX5_MAX_PORTS) +- return; ++ if (i != MLX5_DEVCOM_PORTS_SUPPORTED) ++ goto out; + + list_del(&priv->list); + kfree(priv); ++out: ++ mlx5_dev_list_unlock(); + } + + void mlx5_devcom_register_component(struct mlx5_devcom *devcom, +@@ -192,7 +203,7 @@ int mlx5_devcom_send_event(struct mlx5_devcom *devcom, + + comp = &devcom->priv->components[id]; + down_write(&comp->sem); +- for (i = 0; i < MLX5_MAX_PORTS; i++) ++ for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) + if (i != devcom->idx && comp->device[i].data) { + err = comp->handler(event, comp->device[i].data, + event_data); +@@ -240,7 +251,7 @@ void *mlx5_devcom_get_peer_data(struct mlx5_devcom *devcom, + return NULL; + } + +- for (i = 0; i < MLX5_MAX_PORTS; i++) ++ for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) + if (i != devcom->idx) + break; + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h +index 939d5bf1581b5..94313c18bb647 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h +@@ -6,6 +6,8 @@ + + #include <linux/mlx5/driver.h> + ++#define MLX5_DEVCOM_PORTS_SUPPORTED 2 ++ + enum mlx5_devcom_components { + MLX5_DEVCOM_ESW_OFFLOADS, + +diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c +index 1c9a1b94f6e28..4824385fe2c79 100644 +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -175,10 +175,17 @@ static u32 cdc_ncm_check_tx_max(struct usbnet *dev, u32 new_tx) + u32 val, max, min; + + /* clamp new_tx to sane values */ +- min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth16); +- max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)); +- if (max == 0) ++ if (ctx->is_ndp16) ++ min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth16); ++ else ++ min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth32); ++ ++ if (le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize) == 0) + max = CDC_NCM_NTB_MAX_SIZE_TX; /* dwNtbOutMaxSize not set */ ++ else ++ max = clamp_t(u32, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize), ++ USB_CDC_NCM_NTB_MIN_OUT_SIZE, ++ CDC_NCM_NTB_MAX_SIZE_TX); + + /* some devices set dwNtbOutMaxSize too low for the above default */ + min = min(min, max); +@@ -309,10 +316,17 @@ static ssize_t ndp_to_end_store(struct device *d, struct device_attribute *attr + if (enable == (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) + return len; + +- if (enable && !ctx->delayed_ndp16) { +- ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); +- if (!ctx->delayed_ndp16) +- return -ENOMEM; ++ if (enable) { ++ if (ctx->is_ndp16 && !ctx->delayed_ndp16) { ++ ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); ++ if (!ctx->delayed_ndp16) ++ return -ENOMEM; ++ } ++ if (!ctx->is_ndp16 && !ctx->delayed_ndp32) { ++ ctx->delayed_ndp32 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); ++ if (!ctx->delayed_ndp32) ++ return -ENOMEM; ++ } + } + + /* flush pending data before changing flag */ +@@ -514,6 +528,9 @@ static int cdc_ncm_init(struct usbnet *dev) + dev_err(&dev->intf->dev, "SET_CRC_MODE failed\n"); + } + ++ /* use ndp16 by default */ ++ ctx->is_ndp16 = 1; ++ + /* set NTB format, if both formats are supported. + * + * "The host shall only send this command while the NCM Data +@@ -521,14 +538,27 @@ static int cdc_ncm_init(struct usbnet *dev) + */ + if (le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported) & + USB_CDC_NCM_NTB32_SUPPORTED) { +- dev_dbg(&dev->intf->dev, "Setting NTB format to 16-bit\n"); +- err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, +- USB_TYPE_CLASS | USB_DIR_OUT +- | USB_RECIP_INTERFACE, +- USB_CDC_NCM_NTB16_FORMAT, +- iface_no, NULL, 0); +- if (err < 0) ++ if (ctx->drvflags & CDC_NCM_FLAG_PREFER_NTB32) { ++ ctx->is_ndp16 = 0; ++ dev_dbg(&dev->intf->dev, "Setting NTB format to 32-bit\n"); ++ err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, ++ USB_TYPE_CLASS | USB_DIR_OUT ++ | USB_RECIP_INTERFACE, ++ USB_CDC_NCM_NTB32_FORMAT, ++ iface_no, NULL, 0); ++ } else { ++ ctx->is_ndp16 = 1; ++ dev_dbg(&dev->intf->dev, "Setting NTB format to 16-bit\n"); ++ err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, ++ USB_TYPE_CLASS | USB_DIR_OUT ++ | USB_RECIP_INTERFACE, ++ USB_CDC_NCM_NTB16_FORMAT, ++ iface_no, NULL, 0); ++ } ++ if (err < 0) { ++ ctx->is_ndp16 = 1; + dev_err(&dev->intf->dev, "SET_NTB_FORMAT failed\n"); ++ } + } + + /* set initial device values */ +@@ -551,7 +581,10 @@ static int cdc_ncm_init(struct usbnet *dev) + ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; + + /* set up maximum NDP size */ +- ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp16) + (ctx->tx_max_datagrams + 1) * sizeof(struct usb_cdc_ncm_dpe16); ++ if (ctx->is_ndp16) ++ ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp16) + (ctx->tx_max_datagrams + 1) * sizeof(struct usb_cdc_ncm_dpe16); ++ else ++ ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp32) + (ctx->tx_max_datagrams + 1) * sizeof(struct usb_cdc_ncm_dpe32); + + /* initial coalescing timer interval */ + ctx->timer_interval = CDC_NCM_TIMER_INTERVAL_USEC * NSEC_PER_USEC; +@@ -736,7 +769,10 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx) + ctx->tx_curr_skb = NULL; + } + +- kfree(ctx->delayed_ndp16); ++ if (ctx->is_ndp16) ++ kfree(ctx->delayed_ndp16); ++ else ++ kfree(ctx->delayed_ndp32); + + kfree(ctx); + } +@@ -774,10 +810,8 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ + u8 *buf; + int len; + int temp; +- int err; + u8 iface_no; + struct usb_cdc_parsed_header hdr; +- __le16 curr_ntb_format; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) +@@ -881,32 +915,6 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ + goto error2; + } + +- /* +- * Some Huawei devices have been observed to come out of reset in NDP32 mode. +- * Let's check if this is the case, and set the device to NDP16 mode again if +- * needed. +- */ +- if (ctx->drvflags & CDC_NCM_FLAG_RESET_NTB16) { +- err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_FORMAT, +- USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, +- 0, iface_no, &curr_ntb_format, 2); +- if (err < 0) { +- goto error2; +- } +- +- if (curr_ntb_format == cpu_to_le16(USB_CDC_NCM_NTB32_FORMAT)) { +- dev_info(&intf->dev, "resetting NTB format to 16-bit"); +- err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, +- USB_TYPE_CLASS | USB_DIR_OUT +- | USB_RECIP_INTERFACE, +- USB_CDC_NCM_NTB16_FORMAT, +- iface_no, NULL, 0); +- +- if (err < 0) +- goto error2; +- } +- } +- + cdc_ncm_find_endpoints(dev, ctx->data); + cdc_ncm_find_endpoints(dev, ctx->control); + if (!dev->in || !dev->out || !dev->status) { +@@ -931,9 +939,15 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ + + /* Allocate the delayed NDP if needed. */ + if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { +- ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); +- if (!ctx->delayed_ndp16) +- goto error2; ++ if (ctx->is_ndp16) { ++ ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); ++ if (!ctx->delayed_ndp16) ++ goto error2; ++ } else { ++ ctx->delayed_ndp32 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); ++ if (!ctx->delayed_ndp32) ++ goto error2; ++ } + dev_info(&intf->dev, "NDP will be placed at end of frame for this device."); + } + +@@ -1057,7 +1071,7 @@ static void cdc_ncm_align_tail(struct sk_buff *skb, size_t modulus, size_t remai + /* return a pointer to a valid struct usb_cdc_ncm_ndp16 of type sign, possibly + * allocating a new one within skb + */ +-static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign, size_t reserve) ++static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp16(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign, size_t reserve) + { + struct usb_cdc_ncm_ndp16 *ndp16 = NULL; + struct usb_cdc_ncm_nth16 *nth16 = (void *)skb->data; +@@ -1112,12 +1126,73 @@ static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp(struct cdc_ncm_ctx *ctx, struct sk_ + return ndp16; + } + ++static struct usb_cdc_ncm_ndp32 *cdc_ncm_ndp32(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign, size_t reserve) ++{ ++ struct usb_cdc_ncm_ndp32 *ndp32 = NULL; ++ struct usb_cdc_ncm_nth32 *nth32 = (void *)skb->data; ++ size_t ndpoffset = le32_to_cpu(nth32->dwNdpIndex); ++ ++ /* If NDP should be moved to the end of the NCM package, we can't follow the ++ * NTH32 header as we would normally do. NDP isn't written to the SKB yet, and ++ * the wNdpIndex field in the header is actually not consistent with reality. It will be later. ++ */ ++ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { ++ if (ctx->delayed_ndp32->dwSignature == sign) ++ return ctx->delayed_ndp32; ++ ++ /* We can only push a single NDP to the end. Return ++ * NULL to send what we've already got and queue this ++ * skb for later. ++ */ ++ else if (ctx->delayed_ndp32->dwSignature) ++ return NULL; ++ } ++ ++ /* follow the chain of NDPs, looking for a match */ ++ while (ndpoffset) { ++ ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb->data + ndpoffset); ++ if (ndp32->dwSignature == sign) ++ return ndp32; ++ ndpoffset = le32_to_cpu(ndp32->dwNextNdpIndex); ++ } ++ ++ /* align new NDP */ ++ if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) ++ cdc_ncm_align_tail(skb, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size); ++ ++ /* verify that there is room for the NDP and the datagram (reserve) */ ++ if ((ctx->tx_curr_size - skb->len - reserve) < ctx->max_ndp_size) ++ return NULL; ++ ++ /* link to it */ ++ if (ndp32) ++ ndp32->dwNextNdpIndex = cpu_to_le32(skb->len); ++ else ++ nth32->dwNdpIndex = cpu_to_le32(skb->len); ++ ++ /* push a new empty NDP */ ++ if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) ++ ndp32 = skb_put_zero(skb, ctx->max_ndp_size); ++ else ++ ndp32 = ctx->delayed_ndp32; ++ ++ ndp32->dwSignature = sign; ++ ndp32->wLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_ndp32) + sizeof(struct usb_cdc_ncm_dpe32)); ++ return ndp32; ++} ++ + struct sk_buff * + cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + { + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; +- struct usb_cdc_ncm_nth16 *nth16; +- struct usb_cdc_ncm_ndp16 *ndp16; ++ union { ++ struct usb_cdc_ncm_nth16 *nth16; ++ struct usb_cdc_ncm_nth32 *nth32; ++ } nth; ++ union { ++ struct usb_cdc_ncm_ndp16 *ndp16; ++ struct usb_cdc_ncm_ndp32 *ndp32; ++ } ndp; + struct sk_buff *skb_out; + u16 n = 0, index, ndplen; + u8 ready2send = 0; +@@ -1157,6 +1232,9 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + * further. + */ + if (skb_out == NULL) { ++ /* If even the smallest allocation fails, abort. */ ++ if (ctx->tx_curr_size == USB_CDC_NCM_NTB_MIN_OUT_SIZE) ++ goto alloc_failed; + ctx->tx_low_mem_max_cnt = min(ctx->tx_low_mem_max_cnt + 1, + (unsigned)CDC_NCM_LOW_MEM_MAX_CNT); + ctx->tx_low_mem_val = ctx->tx_low_mem_max_cnt; +@@ -1175,20 +1253,23 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + skb_out = alloc_skb(ctx->tx_curr_size, GFP_ATOMIC); + + /* No allocation possible so we will abort */ +- if (skb_out == NULL) { +- if (skb != NULL) { +- dev_kfree_skb_any(skb); +- dev->net->stats.tx_dropped++; +- } +- goto exit_no_skb; +- } ++ if (!skb_out) ++ goto alloc_failed; + ctx->tx_low_mem_val--; + } +- /* fill out the initial 16-bit NTB header */ +- nth16 = skb_put_zero(skb_out, sizeof(struct usb_cdc_ncm_nth16)); +- nth16->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN); +- nth16->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)); +- nth16->wSequence = cpu_to_le16(ctx->tx_seq++); ++ if (ctx->is_ndp16) { ++ /* fill out the initial 16-bit NTB header */ ++ nth.nth16 = skb_put_zero(skb_out, sizeof(struct usb_cdc_ncm_nth16)); ++ nth.nth16->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN); ++ nth.nth16->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)); ++ nth.nth16->wSequence = cpu_to_le16(ctx->tx_seq++); ++ } else { ++ /* fill out the initial 32-bit NTB header */ ++ nth.nth32 = skb_put_zero(skb_out, sizeof(struct usb_cdc_ncm_nth32)); ++ nth.nth32->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH32_SIGN); ++ nth.nth32->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth32)); ++ nth.nth32->wSequence = cpu_to_le16(ctx->tx_seq++); ++ } + + /* count total number of frames in this NTB */ + ctx->tx_curr_frame_num = 0; +@@ -1210,13 +1291,17 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + } + + /* get the appropriate NDP for this skb */ +- ndp16 = cdc_ncm_ndp(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); ++ if (ctx->is_ndp16) ++ ndp.ndp16 = cdc_ncm_ndp16(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); ++ else ++ ndp.ndp32 = cdc_ncm_ndp32(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); + + /* align beginning of next frame */ + cdc_ncm_align_tail(skb_out, ctx->tx_modulus, ctx->tx_remainder, ctx->tx_curr_size); + + /* check if we had enough room left for both NDP and frame */ +- if (!ndp16 || skb_out->len + skb->len + delayed_ndp_size > ctx->tx_curr_size) { ++ if ((ctx->is_ndp16 && !ndp.ndp16) || (!ctx->is_ndp16 && !ndp.ndp32) || ++ skb_out->len + skb->len + delayed_ndp_size > ctx->tx_curr_size) { + if (n == 0) { + /* won't fit, MTU problem? */ + dev_kfree_skb_any(skb); +@@ -1238,13 +1323,22 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + } + + /* calculate frame number withing this NDP */ +- ndplen = le16_to_cpu(ndp16->wLength); +- index = (ndplen - sizeof(struct usb_cdc_ncm_ndp16)) / sizeof(struct usb_cdc_ncm_dpe16) - 1; ++ if (ctx->is_ndp16) { ++ ndplen = le16_to_cpu(ndp.ndp16->wLength); ++ index = (ndplen - sizeof(struct usb_cdc_ncm_ndp16)) / sizeof(struct usb_cdc_ncm_dpe16) - 1; ++ ++ /* OK, add this skb */ ++ ndp.ndp16->dpe16[index].wDatagramLength = cpu_to_le16(skb->len); ++ ndp.ndp16->dpe16[index].wDatagramIndex = cpu_to_le16(skb_out->len); ++ ndp.ndp16->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe16)); ++ } else { ++ ndplen = le16_to_cpu(ndp.ndp32->wLength); ++ index = (ndplen - sizeof(struct usb_cdc_ncm_ndp32)) / sizeof(struct usb_cdc_ncm_dpe32) - 1; + +- /* OK, add this skb */ +- ndp16->dpe16[index].wDatagramLength = cpu_to_le16(skb->len); +- ndp16->dpe16[index].wDatagramIndex = cpu_to_le16(skb_out->len); +- ndp16->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe16)); ++ ndp.ndp32->dpe32[index].dwDatagramLength = cpu_to_le32(skb->len); ++ ndp.ndp32->dpe32[index].dwDatagramIndex = cpu_to_le32(skb_out->len); ++ ndp.ndp32->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe32)); ++ } + skb_put_data(skb_out, skb->data, skb->len); + ctx->tx_curr_frame_payload += skb->len; /* count real tx payload data */ + dev_kfree_skb_any(skb); +@@ -1291,13 +1385,22 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + + /* If requested, put NDP at end of frame. */ + if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { +- nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; +- cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size - ctx->max_ndp_size); +- nth16->wNdpIndex = cpu_to_le16(skb_out->len); +- skb_put_data(skb_out, ctx->delayed_ndp16, ctx->max_ndp_size); ++ if (ctx->is_ndp16) { ++ nth.nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; ++ cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size - ctx->max_ndp_size); ++ nth.nth16->wNdpIndex = cpu_to_le16(skb_out->len); ++ skb_put_data(skb_out, ctx->delayed_ndp16, ctx->max_ndp_size); ++ ++ /* Zero out delayed NDP - signature checking will naturally fail. */ ++ ndp.ndp16 = memset(ctx->delayed_ndp16, 0, ctx->max_ndp_size); ++ } else { ++ nth.nth32 = (struct usb_cdc_ncm_nth32 *)skb_out->data; ++ cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size - ctx->max_ndp_size); ++ nth.nth32->dwNdpIndex = cpu_to_le32(skb_out->len); ++ skb_put_data(skb_out, ctx->delayed_ndp32, ctx->max_ndp_size); + +- /* Zero out delayed NDP - signature checking will naturally fail. */ +- ndp16 = memset(ctx->delayed_ndp16, 0, ctx->max_ndp_size); ++ ndp.ndp32 = memset(ctx->delayed_ndp32, 0, ctx->max_ndp_size); ++ } + } + + /* If collected data size is less or equal ctx->min_tx_pkt +@@ -1320,8 +1423,13 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + } + + /* set final frame length */ +- nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; +- nth16->wBlockLength = cpu_to_le16(skb_out->len); ++ if (ctx->is_ndp16) { ++ nth.nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; ++ nth.nth16->wBlockLength = cpu_to_le16(skb_out->len); ++ } else { ++ nth.nth32 = (struct usb_cdc_ncm_nth32 *)skb_out->data; ++ nth.nth32->dwBlockLength = cpu_to_le32(skb_out->len); ++ } + + /* return skb */ + ctx->tx_curr_skb = NULL; +@@ -1339,6 +1447,11 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + + return skb_out; + ++alloc_failed: ++ if (skb) { ++ dev_kfree_skb_any(skb); ++ dev->net->stats.tx_dropped++; ++ } + exit_no_skb: + /* Start timer, if there is a remaining non-empty skb */ + if (ctx->tx_curr_skb != NULL && n > 0) +@@ -1404,7 +1517,12 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) + goto error; + + spin_lock_bh(&ctx->mtx); +- skb_out = cdc_ncm_fill_tx_frame(dev, skb, cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)); ++ ++ if (ctx->is_ndp16) ++ skb_out = cdc_ncm_fill_tx_frame(dev, skb, cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)); ++ else ++ skb_out = cdc_ncm_fill_tx_frame(dev, skb, cpu_to_le32(USB_CDC_NCM_NDP32_NOCRC_SIGN)); ++ + spin_unlock_bh(&ctx->mtx); + return skb_out; + +@@ -1465,6 +1583,54 @@ error: + } + EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_nth16); + ++int cdc_ncm_rx_verify_nth32(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in) ++{ ++ struct usbnet *dev = netdev_priv(skb_in->dev); ++ struct usb_cdc_ncm_nth32 *nth32; ++ int len; ++ int ret = -EINVAL; ++ ++ if (ctx == NULL) ++ goto error; ++ ++ if (skb_in->len < (sizeof(struct usb_cdc_ncm_nth32) + ++ sizeof(struct usb_cdc_ncm_ndp32))) { ++ netif_dbg(dev, rx_err, dev->net, "frame too short\n"); ++ goto error; ++ } ++ ++ nth32 = (struct usb_cdc_ncm_nth32 *)skb_in->data; ++ ++ if (nth32->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH32_SIGN)) { ++ netif_dbg(dev, rx_err, dev->net, ++ "invalid NTH32 signature <%#010x>\n", ++ le32_to_cpu(nth32->dwSignature)); ++ goto error; ++ } ++ ++ len = le32_to_cpu(nth32->dwBlockLength); ++ if (len > ctx->rx_max) { ++ netif_dbg(dev, rx_err, dev->net, ++ "unsupported NTB block length %u/%u\n", len, ++ ctx->rx_max); ++ goto error; ++ } ++ ++ if ((ctx->rx_seq + 1) != le16_to_cpu(nth32->wSequence) && ++ (ctx->rx_seq || le16_to_cpu(nth32->wSequence)) && ++ !((ctx->rx_seq == 0xffff) && !le16_to_cpu(nth32->wSequence))) { ++ netif_dbg(dev, rx_err, dev->net, ++ "sequence number glitch prev=%d curr=%d\n", ++ ctx->rx_seq, le16_to_cpu(nth32->wSequence)); ++ } ++ ctx->rx_seq = le16_to_cpu(nth32->wSequence); ++ ++ ret = le32_to_cpu(nth32->dwNdpIndex); ++error: ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_nth32); ++ + /* verify NDP header and return number of datagrams, or negative error */ + int cdc_ncm_rx_verify_ndp16(struct sk_buff *skb_in, int ndpoffset) + { +@@ -1501,6 +1667,42 @@ error: + } + EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_ndp16); + ++/* verify NDP header and return number of datagrams, or negative error */ ++int cdc_ncm_rx_verify_ndp32(struct sk_buff *skb_in, int ndpoffset) ++{ ++ struct usbnet *dev = netdev_priv(skb_in->dev); ++ struct usb_cdc_ncm_ndp32 *ndp32; ++ int ret = -EINVAL; ++ ++ if ((ndpoffset + sizeof(struct usb_cdc_ncm_ndp32)) > skb_in->len) { ++ netif_dbg(dev, rx_err, dev->net, "invalid NDP offset <%u>\n", ++ ndpoffset); ++ goto error; ++ } ++ ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb_in->data + ndpoffset); ++ ++ if (le16_to_cpu(ndp32->wLength) < USB_CDC_NCM_NDP32_LENGTH_MIN) { ++ netif_dbg(dev, rx_err, dev->net, "invalid DPT32 length <%u>\n", ++ le16_to_cpu(ndp32->wLength)); ++ goto error; ++ } ++ ++ ret = ((le16_to_cpu(ndp32->wLength) - ++ sizeof(struct usb_cdc_ncm_ndp32)) / ++ sizeof(struct usb_cdc_ncm_dpe32)); ++ ret--; /* we process NDP entries except for the last one */ ++ ++ if ((sizeof(struct usb_cdc_ncm_ndp32) + ++ ret * (sizeof(struct usb_cdc_ncm_dpe32))) > skb_in->len) { ++ netif_dbg(dev, rx_err, dev->net, "Invalid nframes = %d\n", ret); ++ ret = -EINVAL; ++ } ++ ++error: ++ return ret; ++} ++EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_ndp32); ++ + int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) + { + struct sk_buff *skb; +@@ -1509,34 +1711,66 @@ int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) + int nframes; + int x; + int offset; +- struct usb_cdc_ncm_ndp16 *ndp16; +- struct usb_cdc_ncm_dpe16 *dpe16; ++ union { ++ struct usb_cdc_ncm_ndp16 *ndp16; ++ struct usb_cdc_ncm_ndp32 *ndp32; ++ } ndp; ++ union { ++ struct usb_cdc_ncm_dpe16 *dpe16; ++ struct usb_cdc_ncm_dpe32 *dpe32; ++ } dpe; ++ + int ndpoffset; + int loopcount = 50; /* arbitrary max preventing infinite loop */ + u32 payload = 0; + +- ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); ++ if (ctx->is_ndp16) ++ ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); ++ else ++ ndpoffset = cdc_ncm_rx_verify_nth32(ctx, skb_in); ++ + if (ndpoffset < 0) + goto error; + + next_ndp: +- nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); +- if (nframes < 0) +- goto error; ++ if (ctx->is_ndp16) { ++ nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); ++ if (nframes < 0) ++ goto error; + +- ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); ++ ndp.ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); + +- if (ndp16->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) { +- netif_dbg(dev, rx_err, dev->net, +- "invalid DPT16 signature <%#010x>\n", +- le32_to_cpu(ndp16->dwSignature)); +- goto err_ndp; ++ if (ndp.ndp16->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) { ++ netif_dbg(dev, rx_err, dev->net, ++ "invalid DPT16 signature <%#010x>\n", ++ le32_to_cpu(ndp.ndp16->dwSignature)); ++ goto err_ndp; ++ } ++ dpe.dpe16 = ndp.ndp16->dpe16; ++ } else { ++ nframes = cdc_ncm_rx_verify_ndp32(skb_in, ndpoffset); ++ if (nframes < 0) ++ goto error; ++ ++ ndp.ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb_in->data + ndpoffset); ++ ++ if (ndp.ndp32->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP32_NOCRC_SIGN)) { ++ netif_dbg(dev, rx_err, dev->net, ++ "invalid DPT32 signature <%#010x>\n", ++ le32_to_cpu(ndp.ndp32->dwSignature)); ++ goto err_ndp; ++ } ++ dpe.dpe32 = ndp.ndp32->dpe32; + } +- dpe16 = ndp16->dpe16; + +- for (x = 0; x < nframes; x++, dpe16++) { +- offset = le16_to_cpu(dpe16->wDatagramIndex); +- len = le16_to_cpu(dpe16->wDatagramLength); ++ for (x = 0; x < nframes; x++) { ++ if (ctx->is_ndp16) { ++ offset = le16_to_cpu(dpe.dpe16->wDatagramIndex); ++ len = le16_to_cpu(dpe.dpe16->wDatagramLength); ++ } else { ++ offset = le32_to_cpu(dpe.dpe32->dwDatagramIndex); ++ len = le32_to_cpu(dpe.dpe32->dwDatagramLength); ++ } + + /* + * CDC NCM ch. 3.7 +@@ -1567,10 +1801,19 @@ next_ndp: + usbnet_skb_return(dev, skb); + payload += len; /* count payload bytes in this NTB */ + } ++ ++ if (ctx->is_ndp16) ++ dpe.dpe16++; ++ else ++ dpe.dpe32++; + } + err_ndp: + /* are there more NDPs to process? */ +- ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); ++ if (ctx->is_ndp16) ++ ndpoffset = le16_to_cpu(ndp.ndp16->wNextNdpIndex); ++ else ++ ndpoffset = le32_to_cpu(ndp.ndp32->dwNextNdpIndex); ++ + if (ndpoffset && loopcount--) + goto next_ndp; + +diff --git a/drivers/net/usb/huawei_cdc_ncm.c b/drivers/net/usb/huawei_cdc_ncm.c +index e15a472c6a54c..099d848270042 100644 +--- a/drivers/net/usb/huawei_cdc_ncm.c ++++ b/drivers/net/usb/huawei_cdc_ncm.c +@@ -77,11 +77,11 @@ static int huawei_cdc_ncm_bind(struct usbnet *usbnet_dev, + */ + drvflags |= CDC_NCM_FLAG_NDP_TO_END; + +- /* Additionally, it has been reported that some Huawei E3372H devices, with +- * firmware version 21.318.01.00.541, come out of reset in NTB32 format mode, hence +- * needing to be set to the NTB16 one again. ++ /* For many Huawei devices the NTB32 mode is the default and the best mode ++ * they work with. Huawei E5785 and E5885 devices refuse to work in NTB16 mode at all. + */ +- drvflags |= CDC_NCM_FLAG_RESET_NTB16; ++ drvflags |= CDC_NCM_FLAG_PREFER_NTB32; ++ + ret = cdc_ncm_bind_common(usbnet_dev, intf, 1, drvflags); + if (ret) + goto err; +diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c +index 64d87dccea82c..f912284b2e551 100644 +--- a/drivers/power/supply/bq24190_charger.c ++++ b/drivers/power/supply/bq24190_charger.c +@@ -1211,8 +1211,19 @@ static void bq24190_input_current_limit_work(struct work_struct *work) + struct bq24190_dev_info *bdi = + container_of(work, struct bq24190_dev_info, + input_current_limit_work.work); ++ union power_supply_propval val; ++ int ret; + +- power_supply_set_input_current_limit_from_supplier(bdi->charger); ++ ret = power_supply_get_property_from_supplier(bdi->charger, ++ POWER_SUPPLY_PROP_CURRENT_MAX, ++ &val); ++ if (ret) ++ return; ++ ++ bq24190_charger_set_property(bdi->charger, ++ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, ++ &val); ++ power_supply_changed(bdi->charger); + } + + /* Sync the input-current-limit with our parent supply (if we have one) */ +diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c +index b45cbd40294b9..ffdd646d7ebc0 100644 +--- a/drivers/power/supply/bq27xxx_battery.c ++++ b/drivers/power/supply/bq27xxx_battery.c +@@ -1862,8 +1862,8 @@ static void bq27xxx_external_power_changed(struct power_supply *psy) + { + struct bq27xxx_device_info *di = power_supply_get_drvdata(psy); + +- cancel_delayed_work_sync(&di->work); +- schedule_delayed_work(&di->work, 0); ++ /* After charger plug in/out wait 0.5s for things to stabilize */ ++ mod_delayed_work(system_wq, &di->work, HZ / 2); + } + + int bq27xxx_battery_setup(struct bq27xxx_device_info *di) +diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c +index fd24254d90142..3fdc988595b3a 100644 +--- a/drivers/power/supply/power_supply_core.c ++++ b/drivers/power/supply/power_supply_core.c +@@ -375,46 +375,49 @@ int power_supply_is_system_supplied(void) + } + EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); + +-static int __power_supply_get_supplier_max_current(struct device *dev, +- void *data) ++struct psy_get_supplier_prop_data { ++ struct power_supply *psy; ++ enum power_supply_property psp; ++ union power_supply_propval *val; ++}; ++ ++static int __power_supply_get_supplier_property(struct device *dev, void *_data) + { +- union power_supply_propval ret = {0,}; + struct power_supply *epsy = dev_get_drvdata(dev); +- struct power_supply *psy = data; ++ struct psy_get_supplier_prop_data *data = _data; + +- if (__power_supply_is_supplied_by(epsy, psy)) +- if (!epsy->desc->get_property(epsy, +- POWER_SUPPLY_PROP_CURRENT_MAX, +- &ret)) +- return ret.intval; ++ if (__power_supply_is_supplied_by(epsy, data->psy)) ++ if (!epsy->desc->get_property(epsy, data->psp, data->val)) ++ return 1; /* Success */ + +- return 0; ++ return 0; /* Continue iterating */ + } + +-int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy) ++int power_supply_get_property_from_supplier(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val) + { +- union power_supply_propval val = {0,}; +- int curr; +- +- if (!psy->desc->set_property) +- return -EINVAL; ++ struct psy_get_supplier_prop_data data = { ++ .psy = psy, ++ .psp = psp, ++ .val = val, ++ }; ++ int ret; + + /* + * This function is not intended for use with a supply with multiple +- * suppliers, we simply pick the first supply to report a non 0 +- * max-current. ++ * suppliers, we simply pick the first supply to report the psp. + */ +- curr = class_for_each_device(power_supply_class, NULL, psy, +- __power_supply_get_supplier_max_current); +- if (curr <= 0) +- return (curr == 0) ? -ENODEV : curr; +- +- val.intval = curr; ++ ret = class_for_each_device(power_supply_class, NULL, &data, ++ __power_supply_get_supplier_property); ++ if (ret < 0) ++ return ret; ++ if (ret == 0) ++ return -ENODEV; + +- return psy->desc->set_property(psy, +- POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val); ++ return 0; + } +-EXPORT_SYMBOL_GPL(power_supply_set_input_current_limit_from_supplier); ++EXPORT_SYMBOL_GPL(power_supply_get_property_from_supplier); + + int power_supply_set_battery_charged(struct power_supply *psy) + { +diff --git a/fs/io_uring.c b/fs/io_uring.c +index e8df6345a812d..3683ddeb625ae 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -551,7 +551,8 @@ static void io_kill_timeout(struct io_kiocb *req) + atomic_inc(&req->ctx->cq_timeouts); + list_del(&req->list); + io_cqring_fill_event(req->ctx, req->user_data, 0); +- __io_free_req(req); ++ if (refcount_dec_and_test(&req->refs)) ++ __io_free_req(req); + } + } + +@@ -2079,12 +2080,12 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe) + req->sequence -= span; + add: + list_add(&req->list, entry); +- spin_unlock_irq(&ctx->completion_lock); + + hrtimer_init(&req->timeout.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + req->timeout.timer.function = io_timeout_fn; + hrtimer_start(&req->timeout.timer, timespec64_to_ktime(ts), + HRTIMER_MODE_REL); ++ spin_unlock_irq(&ctx->completion_lock); + return 0; + } + +@@ -3738,9 +3739,6 @@ static void io_cancel_async_work(struct io_ring_ctx *ctx, + { + struct io_kiocb *req; + +- if (list_empty(&ctx->task_list)) +- return; +- + spin_lock_irq(&ctx->task_lock); + + list_for_each_entry(req, &ctx->task_list, task_list) { +diff --git a/include/linux/fs.h b/include/linux/fs.h +index e003afcea3f3e..4b1553f570f2c 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1360,28 +1360,28 @@ extern int send_sigurg(struct fown_struct *fown); + * sb->s_flags. Note that these mirror the equivalent MS_* flags where + * represented in both. + */ +-#define SB_RDONLY 1 /* Mount read-only */ +-#define SB_NOSUID 2 /* Ignore suid and sgid bits */ +-#define SB_NODEV 4 /* Disallow access to device special files */ +-#define SB_NOEXEC 8 /* Disallow program execution */ +-#define SB_SYNCHRONOUS 16 /* Writes are synced at once */ +-#define SB_MANDLOCK 64 /* Allow mandatory locks on an FS */ +-#define SB_DIRSYNC 128 /* Directory modifications are synchronous */ +-#define SB_NOATIME 1024 /* Do not update access times. */ +-#define SB_NODIRATIME 2048 /* Do not update directory access times */ +-#define SB_SILENT 32768 +-#define SB_POSIXACL (1<<16) /* VFS does not apply the umask */ +-#define SB_KERNMOUNT (1<<22) /* this is a kern_mount call */ +-#define SB_I_VERSION (1<<23) /* Update inode I_version field */ +-#define SB_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ ++#define SB_RDONLY BIT(0) /* Mount read-only */ ++#define SB_NOSUID BIT(1) /* Ignore suid and sgid bits */ ++#define SB_NODEV BIT(2) /* Disallow access to device special files */ ++#define SB_NOEXEC BIT(3) /* Disallow program execution */ ++#define SB_SYNCHRONOUS BIT(4) /* Writes are synced at once */ ++#define SB_MANDLOCK BIT(6) /* Allow mandatory locks on an FS */ ++#define SB_DIRSYNC BIT(7) /* Directory modifications are synchronous */ ++#define SB_NOATIME BIT(10) /* Do not update access times. */ ++#define SB_NODIRATIME BIT(11) /* Do not update directory access times */ ++#define SB_SILENT BIT(15) ++#define SB_POSIXACL BIT(16) /* VFS does not apply the umask */ ++#define SB_KERNMOUNT BIT(22) /* this is a kern_mount call */ ++#define SB_I_VERSION BIT(23) /* Update inode I_version field */ ++#define SB_LAZYTIME BIT(25) /* Update the on-disk [acm]times lazily */ + + /* These sb flags are internal to the kernel */ +-#define SB_SUBMOUNT (1<<26) +-#define SB_FORCE (1<<27) +-#define SB_NOSEC (1<<28) +-#define SB_BORN (1<<29) +-#define SB_ACTIVE (1<<30) +-#define SB_NOUSER (1<<31) ++#define SB_SUBMOUNT BIT(26) ++#define SB_FORCE BIT(27) ++#define SB_NOSEC BIT(28) ++#define SB_BORN BIT(29) ++#define SB_ACTIVE BIT(30) ++#define SB_NOUSER BIT(31) + + /* + * Umount options +diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h +index 28413f737e7d0..f4aad9554de2e 100644 +--- a/include/linux/power_supply.h ++++ b/include/linux/power_supply.h +@@ -383,8 +383,9 @@ extern int power_supply_batinfo_ocv2cap(struct power_supply_battery_info *info, + int ocv, int temp); + extern void power_supply_changed(struct power_supply *psy); + extern int power_supply_am_i_supplied(struct power_supply *psy); +-extern int power_supply_set_input_current_limit_from_supplier( +- struct power_supply *psy); ++int power_supply_get_property_from_supplier(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val); + extern int power_supply_set_battery_charged(struct power_supply *psy); + + #ifdef CONFIG_POWER_SUPPLY +diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h +index 1646c06989df7..0ce4377545f82 100644 +--- a/include/linux/usb/cdc_ncm.h ++++ b/include/linux/usb/cdc_ncm.h +@@ -46,9 +46,12 @@ + #define CDC_NCM_DATA_ALTSETTING_NCM 1 + #define CDC_NCM_DATA_ALTSETTING_MBIM 2 + +-/* CDC NCM subclass 3.2.1 */ ++/* CDC NCM subclass 3.3.1 */ + #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 + ++/* CDC NCM subclass 3.3.2 */ ++#define USB_CDC_NCM_NDP32_LENGTH_MIN 0x20 ++ + /* Maximum NTB length */ + #define CDC_NCM_NTB_MAX_SIZE_TX 32768 /* bytes */ + #define CDC_NCM_NTB_MAX_SIZE_RX 32768 /* bytes */ +@@ -84,7 +87,7 @@ + /* Driver flags */ + #define CDC_NCM_FLAG_NDP_TO_END 0x02 /* NDP is placed at end of frame */ + #define CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE 0x04 /* Avoid altsetting toggle during init */ +-#define CDC_NCM_FLAG_RESET_NTB16 0x08 /* set NDP16 one more time after altsetting switch */ ++#define CDC_NCM_FLAG_PREFER_NTB32 0x08 /* prefer NDP32 over NDP16 */ + + #define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \ + (x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE) +@@ -113,7 +116,11 @@ struct cdc_ncm_ctx { + + u32 timer_interval; + u32 max_ndp_size; +- struct usb_cdc_ncm_ndp16 *delayed_ndp16; ++ u8 is_ndp16; ++ union { ++ struct usb_cdc_ncm_ndp16 *delayed_ndp16; ++ struct usb_cdc_ncm_ndp32 *delayed_ndp32; ++ }; + + u32 tx_timer_pending; + u32 tx_curr_frame_num; +@@ -150,6 +157,8 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf); + struct sk_buff *cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign); + int cdc_ncm_rx_verify_nth16(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in); + int cdc_ncm_rx_verify_ndp16(struct sk_buff *skb_in, int ndpoffset); ++int cdc_ncm_rx_verify_nth32(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in); ++int cdc_ncm_rx_verify_ndp32(struct sk_buff *skb_in, int ndpoffset); + struct sk_buff * + cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags); + int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in); +diff --git a/include/net/ip.h b/include/net/ip.h +index db841ab388c0e..0ebe5385efcae 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -73,6 +73,7 @@ struct ipcm_cookie { + __be32 addr; + int oif; + struct ip_options_rcu *opt; ++ __u8 protocol; + __u8 ttl; + __s16 tos; + char priority; +@@ -93,6 +94,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm, + ipcm->sockc.tsflags = inet->sk.sk_tsflags; + ipcm->oif = inet->sk.sk_bound_dev_if; + ipcm->addr = inet->inet_saddr; ++ ipcm->protocol = inet->inet_num; + } + + #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) +diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h +index 60e1241d4b77b..f5ac290c22509 100644 +--- a/include/uapi/linux/in.h ++++ b/include/uapi/linux/in.h +@@ -154,6 +154,8 @@ struct in_addr { + #define MCAST_MSFILTER 48 + #define IP_MULTICAST_ALL 49 + #define IP_UNICAST_IF 50 ++#define IP_LOCAL_PORT_RANGE 51 ++#define IP_PROTOCOL 52 + + #define MCAST_EXCLUDE 0 + #define MCAST_INCLUDE 1 +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index 4f8f5204ae7a0..45f6ce1f380e0 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -973,6 +973,34 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, + + BT_DBG("cmd %x arg %lx", cmd, arg); + ++ /* Make sure the cmd is valid before doing anything */ ++ switch (cmd) { ++ case HCIGETDEVLIST: ++ case HCIGETDEVINFO: ++ case HCIGETCONNLIST: ++ case HCIDEVUP: ++ case HCIDEVDOWN: ++ case HCIDEVRESET: ++ case HCIDEVRESTAT: ++ case HCISETSCAN: ++ case HCISETAUTH: ++ case HCISETENCRYPT: ++ case HCISETPTYPE: ++ case HCISETLINKPOL: ++ case HCISETLINKMODE: ++ case HCISETACLMTU: ++ case HCISETSCOMTU: ++ case HCIINQUIRY: ++ case HCISETRAW: ++ case HCIGETCONNINFO: ++ case HCIGETAUTHINFO: ++ case HCIBLOCKADDR: ++ case HCIUNBLOCKADDR: ++ break; ++ default: ++ return -ENOIOCTLCMD; ++ } ++ + lock_sock(sk); + + if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) { +diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c +index aa3fd61818c47..0c528f642eb86 100644 +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -316,7 +316,14 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc, + ipc->tos = val; + ipc->priority = rt_tos2priority(ipc->tos); + break; +- ++ case IP_PROTOCOL: ++ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) ++ return -EINVAL; ++ val = *(int *)CMSG_DATA(cmsg); ++ if (val < 1 || val > 255) ++ return -EINVAL; ++ ipc->protocol = val; ++ break; + default: + return -EINVAL; + } +@@ -1524,6 +1531,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, + case IP_MINTTL: + val = inet->min_ttl; + break; ++ case IP_PROTOCOL: ++ val = inet_sk(sk)->inet_num; ++ break; + default: + release_sock(sk); + return -ENOPROTOOPT; +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index ddc24e57dc555..1044f4985922f 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -558,6 +558,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + } + + ipcm_init_sk(&ipc, inet); ++ /* Keep backward compat */ ++ if (hdrincl) ++ ipc.protocol = IPPROTO_RAW; + + if (msg->msg_controllen) { + err = ip_cmsg_send(sk, msg, &ipc, false); +@@ -625,7 +628,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + + flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos, + RT_SCOPE_UNIVERSE, +- hdrincl ? IPPROTO_RAW : sk->sk_protocol, ++ hdrincl ? ipc.protocol : sk->sk_protocol, + inet_sk_flowi_flags(sk) | + (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), + daddr, saddr, 0, 0, sk->sk_uid); +diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c +index bf052d68e1f5a..731485b18de31 100644 +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -828,7 +828,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + + if (!proto) + proto = inet->inet_num; +- else if (proto != inet->inet_num) ++ else if (proto != inet->inet_num && ++ inet->inet_num != IPPROTO_RAW) + return -EINVAL; + + if (proto > 255) +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 4747daf901e71..754f473ce3de4 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -1229,9 +1229,6 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { + + static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data) + { +- if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) +- return 0; +- + return ctnetlink_filter_match(ct, data); + } + +@@ -1294,11 +1291,6 @@ static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl, + + ct = nf_ct_tuplehash_to_ctrack(h); + +- if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) { +- nf_ct_put(ct); +- return -EBUSY; +- } +- + if (cda[CTA_ID]) { + __be32 id = nla_get_be32(cda[CTA_ID]); + |