commit: 6234c5aeed96c1d36b9fdec5ec0cb535aed897f5 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Wed Oct 18 13:46:38 2017 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Wed Oct 18 13:46:38 2017 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6234c5ae
Linux patch 4.9.57 0000_README | 4 + 1056_linux-4.9.57.patch | 1306 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1310 insertions(+) diff --git a/0000_README b/0000_README index b4a856b..2263df0 100644 --- a/0000_README +++ b/0000_README @@ -267,6 +267,10 @@ Patch: 1055_linux-4.9.56.patch From: http://www.kernel.org Desc: Linux 4.9.56 +Patch: 1056_linux-4.9.57.patch +From: http://www.kernel.org +Desc: Linux 4.9.57 + 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/1056_linux-4.9.57.patch b/1056_linux-4.9.57.patch new file mode 100644 index 0000000..38ef2cc --- /dev/null +++ b/1056_linux-4.9.57.patch @@ -0,0 +1,1306 @@ +diff --git a/Makefile b/Makefile +index feab5f5a507c..d5a2ab9b3291 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 9 +-SUBLEVEL = 56 ++SUBLEVEL = 57 + EXTRAVERSION = + NAME = Roaring Lionus + +diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c +index e9385bcd9723..9ade60ca08e0 100644 +--- a/arch/mips/math-emu/cp1emu.c ++++ b/arch/mips/math-emu/cp1emu.c +@@ -2386,7 +2386,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, + break; + default: + /* Reserved R6 ops */ +- pr_err("Reserved MIPS R6 CMP.condn.S operation\n"); + return SIGILL; + } + } +@@ -2460,7 +2459,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, + break; + default: + /* Reserved R6 ops */ +- pr_err("Reserved MIPS R6 CMP.condn.D operation\n"); + return SIGILL; + } + } +diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h +index e7636bac7372..6c98821fef5e 100644 +--- a/arch/x86/include/asm/alternative-asm.h ++++ b/arch/x86/include/asm/alternative-asm.h +@@ -62,8 +62,10 @@ + #define new_len2 145f-144f + + /* +- * max without conditionals. Idea adapted from: ++ * gas compatible max based on the idea from: + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax ++ * ++ * The additional "-" is needed because gas uses a "true" value of -1. + */ + #define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) + +diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h +index 1b020381ab38..d4aea31eec03 100644 +--- a/arch/x86/include/asm/alternative.h ++++ b/arch/x86/include/asm/alternative.h +@@ -103,12 +103,12 @@ static inline int alternatives_text_reserved(void *start, void *end) + alt_end_marker ":\n" + + /* +- * max without conditionals. Idea adapted from: ++ * gas compatible max based on the idea from: + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax + * +- * The additional "-" is needed because gas works with s32s. ++ * The additional "-" is needed because gas uses a "true" value of -1. + */ +-#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") - (" b ")))))" ++#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))" + + /* + * Pad the second replacement alternative with additional NOPs if it is +diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c +index 5f2412704b81..d29c745f10ad 100644 +--- a/arch/x86/kvm/mmu.c ++++ b/arch/x86/kvm/mmu.c +@@ -3648,13 +3648,6 @@ static bool sync_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, gfn_t gfn, + static inline bool is_last_gpte(struct kvm_mmu *mmu, + unsigned level, unsigned gpte) + { +- /* +- * PT_PAGE_TABLE_LEVEL always terminates. The RHS has bit 7 set +- * iff level <= PT_PAGE_TABLE_LEVEL, which for our purpose means +- * level == PT_PAGE_TABLE_LEVEL; set PT_PAGE_SIZE_MASK in gpte then. +- */ +- gpte |= level - PT_PAGE_TABLE_LEVEL - 1; +- + /* + * The RHS has bit 7 set iff level < mmu->last_nonleaf_level. + * If it is clear, there are no large pages at this level, so clear +@@ -3662,6 +3655,13 @@ static inline bool is_last_gpte(struct kvm_mmu *mmu, + */ + gpte &= level - mmu->last_nonleaf_level; + ++ /* ++ * PT_PAGE_TABLE_LEVEL always terminates. The RHS has bit 7 set ++ * iff level <= PT_PAGE_TABLE_LEVEL, which for our purpose means ++ * level == PT_PAGE_TABLE_LEVEL; set PT_PAGE_SIZE_MASK in gpte then. ++ */ ++ gpte |= level - PT_PAGE_TABLE_LEVEL - 1; ++ + return gpte & PT_PAGE_SIZE_MASK; + } + +@@ -4169,6 +4169,7 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly) + + update_permission_bitmask(vcpu, context, true); + update_pkru_bitmask(vcpu, context, true); ++ update_last_nonleaf_level(vcpu, context); + reset_rsvds_bits_mask_ept(vcpu, context, execonly); + reset_ept_shadow_zero_bits_mask(vcpu, context, execonly); + } +diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h +index a01105485315..37363900297d 100644 +--- a/arch/x86/kvm/paging_tmpl.h ++++ b/arch/x86/kvm/paging_tmpl.h +@@ -324,10 +324,11 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, + --walker->level; + + index = PT_INDEX(addr, walker->level); +- + table_gfn = gpte_to_gfn(pte); + offset = index * sizeof(pt_element_t); + pte_gpa = gfn_to_gpa(table_gfn) + offset; ++ ++ BUG_ON(walker->level < 1); + walker->table_gfn[walker->level - 1] = table_gfn; + walker->pte_gpa[walker->level - 1] = pte_gpa; + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index fb49212d25df..a8ae57acb6f6 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -10690,7 +10690,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, + * (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask(); + */ + vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK); +- kvm_set_cr4(vcpu, vmcs12->host_cr4); ++ vmx_set_cr4(vcpu, vmcs12->host_cr4); + + nested_ept_uninit_mmu_context(vcpu); + +diff --git a/block/bio.c b/block/bio.c +index 655c9016052a..07f287b14cff 100644 +--- a/block/bio.c ++++ b/block/bio.c +@@ -1171,8 +1171,8 @@ struct bio *bio_copy_user_iov(struct request_queue *q, + */ + bmd->is_our_pages = map_data ? 0 : 1; + memcpy(bmd->iov, iter->iov, sizeof(struct iovec) * iter->nr_segs); +- iov_iter_init(&bmd->iter, iter->type, bmd->iov, +- iter->nr_segs, iter->count); ++ bmd->iter = *iter; ++ bmd->iter.iov = bmd->iov; + + ret = -ENOMEM; + bio = bio_kmalloc(gfp_mask, nr_pages); +@@ -1266,6 +1266,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, + int ret, offset; + struct iov_iter i; + struct iovec iov; ++ struct bio_vec *bvec; + + iov_for_each(iov, i, *iter) { + unsigned long uaddr = (unsigned long) iov.iov_base; +@@ -1310,7 +1311,12 @@ struct bio *bio_map_user_iov(struct request_queue *q, + ret = get_user_pages_fast(uaddr, local_nr_pages, + (iter->type & WRITE) != WRITE, + &pages[cur_page]); +- if (ret < local_nr_pages) { ++ if (unlikely(ret < local_nr_pages)) { ++ for (j = cur_page; j < page_limit; j++) { ++ if (!pages[j]) ++ break; ++ put_page(pages[j]); ++ } + ret = -EFAULT; + goto out_unmap; + } +@@ -1318,6 +1324,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, + offset = offset_in_page(uaddr); + for (j = cur_page; j < page_limit; j++) { + unsigned int bytes = PAGE_SIZE - offset; ++ unsigned short prev_bi_vcnt = bio->bi_vcnt; + + if (len <= 0) + break; +@@ -1332,6 +1339,13 @@ struct bio *bio_map_user_iov(struct request_queue *q, + bytes) + break; + ++ /* ++ * check if vector was merged with previous ++ * drop page reference if needed ++ */ ++ if (bio->bi_vcnt == prev_bi_vcnt) ++ put_page(pages[j]); ++ + len -= bytes; + offset = 0; + } +@@ -1364,10 +1378,8 @@ struct bio *bio_map_user_iov(struct request_queue *q, + return bio; + + out_unmap: +- for (j = 0; j < nr_pages; j++) { +- if (!pages[j]) +- break; +- put_page(pages[j]); ++ bio_for_each_segment_all(bvec, bio, j) { ++ put_page(bvec->bv_page); + } + out: + kfree(pages); +diff --git a/crypto/shash.c b/crypto/shash.c +index a051541a4a17..4d8a671d1614 100644 +--- a/crypto/shash.c ++++ b/crypto/shash.c +@@ -274,12 +274,14 @@ static int shash_async_finup(struct ahash_request *req) + + int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) + { +- struct scatterlist *sg = req->src; +- unsigned int offset = sg->offset; + unsigned int nbytes = req->nbytes; ++ struct scatterlist *sg; ++ unsigned int offset; + int err; + +- if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) { ++ if (nbytes && ++ (sg = req->src, offset = sg->offset, ++ nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset))) { + void *data; + + data = kmap_atomic(sg_page(sg)); +diff --git a/drivers/base/property.c b/drivers/base/property.c +index 06f66687fe0b..7b313b567f4c 100644 +--- a/drivers/base/property.c ++++ b/drivers/base/property.c +@@ -20,6 +20,7 @@ + #include <linux/phy.h> + + struct property_set { ++ struct device *dev; + struct fwnode_handle fwnode; + struct property_entry *properties; + }; +@@ -817,6 +818,7 @@ static struct property_set *pset_copy_set(const struct property_set *pset) + void device_remove_properties(struct device *dev) + { + struct fwnode_handle *fwnode; ++ struct property_set *pset; + + fwnode = dev_fwnode(dev); + if (!fwnode) +@@ -826,16 +828,16 @@ void device_remove_properties(struct device *dev) + * the pset. If there is no real firmware node (ACPI/DT) primary + * will hold the pset. + */ +- if (is_pset_node(fwnode)) { ++ pset = to_pset_node(fwnode); ++ if (pset) { + set_primary_fwnode(dev, NULL); +- pset_free_set(to_pset_node(fwnode)); + } else { +- fwnode = fwnode->secondary; +- if (!IS_ERR(fwnode) && is_pset_node(fwnode)) { ++ pset = to_pset_node(fwnode->secondary); ++ if (pset && dev == pset->dev) + set_secondary_fwnode(dev, NULL); +- pset_free_set(to_pset_node(fwnode)); +- } + } ++ if (pset && dev == pset->dev) ++ pset_free_set(pset); + } + EXPORT_SYMBOL_GPL(device_remove_properties); + +@@ -863,6 +865,7 @@ int device_add_properties(struct device *dev, struct property_entry *properties) + + p->fwnode.type = FWNODE_PDATA; + set_secondary_fwnode(dev, &p->fwnode); ++ p->dev = dev; + return 0; + } + EXPORT_SYMBOL_GPL(device_add_properties); +diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c +index 77242b37ef87..57962bff7532 100644 +--- a/drivers/dma/edma.c ++++ b/drivers/dma/edma.c +@@ -1143,11 +1143,24 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( + struct edma_desc *edesc; + struct device *dev = chan->device->dev; + struct edma_chan *echan = to_edma_chan(chan); +- unsigned int width, pset_len; ++ unsigned int width, pset_len, array_size; + + if (unlikely(!echan || !len)) + return NULL; + ++ /* Align the array size (acnt block) with the transfer properties */ ++ switch (__ffs((src | dest | len))) { ++ case 0: ++ array_size = SZ_32K - 1; ++ break; ++ case 1: ++ array_size = SZ_32K - 2; ++ break; ++ default: ++ array_size = SZ_32K - 4; ++ break; ++ } ++ + if (len < SZ_64K) { + /* + * Transfer size less than 64K can be handled with one paRAM +@@ -1169,7 +1182,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( + * When the full_length is multibple of 32767 one slot can be + * used to complete the transfer. + */ +- width = SZ_32K - 1; ++ width = array_size; + pset_len = rounddown(len, width); + /* One slot is enough for lengths multiple of (SZ_32K -1) */ + if (unlikely(pset_len == len)) +@@ -1217,7 +1230,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( + } + dest += pset_len; + src += pset_len; +- pset_len = width = len % (SZ_32K - 1); ++ pset_len = width = len % array_size; + + ret = edma_config_pset(chan, &edesc->pset[1], src, dest, 1, + width, pset_len, DMA_MEM_TO_MEM); +diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c +index 2403475a37cf..88a00d06def6 100644 +--- a/drivers/dma/ti-dma-crossbar.c ++++ b/drivers/dma/ti-dma-crossbar.c +@@ -262,13 +262,14 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec, + mutex_lock(&xbar->mutex); + map->xbar_out = find_first_zero_bit(xbar->dma_inuse, + xbar->dma_requests); +- mutex_unlock(&xbar->mutex); + if (map->xbar_out == xbar->dma_requests) { ++ mutex_unlock(&xbar->mutex); + dev_err(&pdev->dev, "Run out of free DMA requests\n"); + kfree(map); + return ERR_PTR(-ENOMEM); + } + set_bit(map->xbar_out, xbar->dma_inuse); ++ mutex_unlock(&xbar->mutex); + + map->xbar_in = (u16)dma_spec->args[0]; + +diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c +index 8aeb7f8ee59c..80c5cc5640c1 100644 +--- a/drivers/gpu/drm/i915/intel_bios.c ++++ b/drivers/gpu/drm/i915/intel_bios.c +@@ -1219,7 +1219,7 @@ static void parse_ddi_ports(struct drm_i915_private *dev_priv, + { + enum port port; + +- if (!HAS_DDI(dev_priv)) ++ if (!HAS_DDI(dev_priv) && !IS_CHERRYVIEW(dev_priv)) + return; + + if (!dev_priv->vbt.child_dev_num) +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index f8efd20e4a90..ce32303b3013 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -11471,13 +11471,10 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, + { + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; ++ enum transcoder cpu_transcoder; + struct drm_display_mode *mode; + struct intel_crtc_state *pipe_config; +- int htot = I915_READ(HTOTAL(cpu_transcoder)); +- int hsync = I915_READ(HSYNC(cpu_transcoder)); +- int vtot = I915_READ(VTOTAL(cpu_transcoder)); +- int vsync = I915_READ(VSYNC(cpu_transcoder)); ++ u32 htot, hsync, vtot, vsync; + enum pipe pipe = intel_crtc->pipe; + + mode = kzalloc(sizeof(*mode), GFP_KERNEL); +@@ -11505,6 +11502,13 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, + i9xx_crtc_clock_get(intel_crtc, pipe_config); + + mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; ++ ++ cpu_transcoder = pipe_config->cpu_transcoder; ++ htot = I915_READ(HTOTAL(cpu_transcoder)); ++ hsync = I915_READ(HSYNC(cpu_transcoder)); ++ vtot = I915_READ(VTOTAL(cpu_transcoder)); ++ vsync = I915_READ(VSYNC(cpu_transcoder)); ++ + mode->hdisplay = (htot & 0xffff) + 1; + mode->htotal = ((htot & 0xffff0000) >> 16) + 1; + mode->hsync_start = (hsync & 0xffff) + 1; +diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c +index 7b06280b23aa..afa3d010c650 100644 +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -2193,8 +2193,8 @@ static void edp_panel_off(struct intel_dp *intel_dp) + I915_WRITE(pp_ctrl_reg, pp); + POSTING_READ(pp_ctrl_reg); + +- intel_dp->panel_power_off_time = ktime_get_boottime(); + wait_panel_off(intel_dp); ++ intel_dp->panel_power_off_time = ktime_get_boottime(); + + /* We got a reference when we enabled the VDD. */ + power_domain = intel_display_port_aux_power_domain(intel_encoder); +diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c +index ae83af649a60..7838343eb37c 100644 +--- a/drivers/hid/usbhid/hid-core.c ++++ b/drivers/hid/usbhid/hid-core.c +@@ -971,6 +971,8 @@ static int usbhid_parse(struct hid_device *hid) + unsigned int rsize = 0; + char *rdesc; + int ret, n; ++ int num_descriptors; ++ size_t offset = offsetof(struct hid_descriptor, desc); + + quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); +@@ -993,10 +995,18 @@ static int usbhid_parse(struct hid_device *hid) + return -ENODEV; + } + ++ if (hdesc->bLength < sizeof(struct hid_descriptor)) { ++ dbg_hid("hid descriptor is too short\n"); ++ return -EINVAL; ++ } ++ + hid->version = le16_to_cpu(hdesc->bcdHID); + hid->country = hdesc->bCountryCode; + +- for (n = 0; n < hdesc->bNumDescriptors; n++) ++ num_descriptors = min_t(int, hdesc->bNumDescriptors, ++ (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor)); ++ ++ for (n = 0; n < num_descriptors; n++) + if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) + rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); + +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index c380b7e8f1c6..1a0b110f12c0 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -3120,6 +3120,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, + mutex_unlock(&domain->api_lock); + + domain_flush_tlb_pde(domain); ++ domain_flush_complete(domain); + + return unmap_size; + } +diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig +index 0e75d94972ba..671610c989b6 100644 +--- a/drivers/pinctrl/Kconfig ++++ b/drivers/pinctrl/Kconfig +@@ -82,6 +82,7 @@ config PINCTRL_AMD + tristate "AMD GPIO pin control" + depends on GPIOLIB + select GPIOLIB_IRQCHIP ++ select PINMUX + select PINCONF + select GENERIC_PINCONF + help +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index baa7cdcc0ebc..325bf21ba13b 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -2018,6 +2018,8 @@ static DEVICE_ATTR_RO(suspended); + static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) + { + struct usb_composite_dev *cdev = get_gadget_data(gadget); ++ struct usb_gadget_strings *gstr = cdev->driver->strings[0]; ++ struct usb_string *dev_str = gstr->strings; + + /* composite_disconnect() must already have been called + * by the underlying peripheral controller driver! +@@ -2037,6 +2039,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) + + composite_dev_cleanup(cdev); + ++ if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) ++ dev_str[USB_GADGET_MANUFACTURER_IDX].s = ""; ++ + kfree(cdev->def_manufacturer); + kfree(cdev); + set_gadget_data(gadget, NULL); +diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c +index 3984787f8e97..502a096fc380 100644 +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -1140,11 +1140,12 @@ static struct configfs_attribute *interf_grp_attrs[] = { + NULL + }; + +-int usb_os_desc_prepare_interf_dir(struct config_group *parent, +- int n_interf, +- struct usb_os_desc **desc, +- char **names, +- struct module *owner) ++struct config_group *usb_os_desc_prepare_interf_dir( ++ struct config_group *parent, ++ int n_interf, ++ struct usb_os_desc **desc, ++ char **names, ++ struct module *owner) + { + struct config_group *os_desc_group; + struct config_item_type *os_desc_type, *interface_type; +@@ -1156,7 +1157,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, + + char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); + if (!vlabuf) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + + os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); + os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); +@@ -1181,7 +1182,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, + configfs_add_default_group(&d->group, os_desc_group); + } + +- return 0; ++ return os_desc_group; + } + EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); + +diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h +index 36c468c4f5e9..540d5e92ed22 100644 +--- a/drivers/usb/gadget/configfs.h ++++ b/drivers/usb/gadget/configfs.h +@@ -5,11 +5,12 @@ + + void unregister_gadget_item(struct config_item *item); + +-int usb_os_desc_prepare_interf_dir(struct config_group *parent, +- int n_interf, +- struct usb_os_desc **desc, +- char **names, +- struct module *owner); ++struct config_group *usb_os_desc_prepare_interf_dir( ++ struct config_group *parent, ++ int n_interf, ++ struct usb_os_desc **desc, ++ char **names, ++ struct module *owner); + + static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) + { +diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c +index 16562e461121..ba00cdb809d6 100644 +--- a/drivers/usb/gadget/function/f_rndis.c ++++ b/drivers/usb/gadget/function/f_rndis.c +@@ -892,6 +892,7 @@ static void rndis_free_inst(struct usb_function_instance *f) + free_netdev(opts->net); + } + ++ kfree(opts->rndis_interf_group); /* single VLA chunk */ + kfree(opts); + } + +@@ -900,6 +901,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) + struct f_rndis_opts *opts; + struct usb_os_desc *descs[1]; + char *names[1]; ++ struct config_group *rndis_interf_group; + + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) +@@ -920,8 +922,14 @@ static struct usb_function_instance *rndis_alloc_inst(void) + names[0] = "rndis"; + config_group_init_type_name(&opts->func_inst.group, "", + &rndis_func_type); +- usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, +- names, THIS_MODULE); ++ rndis_interf_group = ++ usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, ++ names, THIS_MODULE); ++ if (IS_ERR(rndis_interf_group)) { ++ rndis_free_inst(&opts->func_inst); ++ return ERR_CAST(rndis_interf_group); ++ } ++ opts->rndis_interf_group = rndis_interf_group; + + return &opts->func_inst; + } +diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h +index 4eafd5050545..4e2ad04fe8d6 100644 +--- a/drivers/usb/gadget/function/u_rndis.h ++++ b/drivers/usb/gadget/function/u_rndis.h +@@ -26,6 +26,7 @@ struct f_rndis_opts { + bool bound; + bool borrowed_net; + ++ struct config_group *rndis_interf_group; + struct usb_os_desc rndis_os_desc; + char rndis_ext_compat_id[16]; + +diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c +index fb17fb23fa9a..b62a3de65075 100644 +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -420,6 +420,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) + static void set_link_state(struct dummy_hcd *dum_hcd) + { + struct dummy *dum = dum_hcd->dum; ++ unsigned int power_bit; + + dum_hcd->active = 0; + if (dum->pullup) +@@ -430,17 +431,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd) + return; + + set_link_state_by_speed(dum_hcd); ++ power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ? ++ USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER); + + if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || + dum_hcd->active) + dum_hcd->resuming = 0; + + /* Currently !connected or in reset */ +- if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || ++ if ((dum_hcd->port_status & power_bit) == 0 || + (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { +- unsigned disconnect = USB_PORT_STAT_CONNECTION & ++ unsigned int disconnect = power_bit & + dum_hcd->old_status & (~dum_hcd->port_status); +- unsigned reset = USB_PORT_STAT_RESET & ++ unsigned int reset = USB_PORT_STAT_RESET & + (~dum_hcd->old_status) & dum_hcd->port_status; + + /* Report reset and disconnect events to the driver */ +diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c +index 8897195396b2..6c6a3a8df07a 100644 +--- a/drivers/usb/renesas_usbhs/fifo.c ++++ b/drivers/usb/renesas_usbhs/fifo.c +@@ -860,9 +860,9 @@ static void xfer_work(struct work_struct *work) + fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); + + usbhs_pipe_running(pipe, 1); +- usbhsf_dma_start(pipe, fifo); + usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); + dma_async_issue_pending(chan); ++ usbhsf_dma_start(pipe, fifo); + usbhs_pipe_enable(pipe); + + xfer_work_end: +diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c +index b6f1adefb758..76062ce2d459 100644 +--- a/drivers/usb/serial/console.c ++++ b/drivers/usb/serial/console.c +@@ -186,6 +186,7 @@ static int usb_console_setup(struct console *co, char *options) + tty_kref_put(tty); + reset_open_count: + port->port.count = 0; ++ info->port = NULL; + usb_autopm_put_interface(serial->interface); + error_get_interface: + usb_serial_put(serial); +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 470b17b0c11b..11ee55e080e5 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -171,6 +171,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ + { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ + { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ ++ { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */ + { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ + { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ + { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 19394963f675..3249f42b4b93 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = { + { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, + { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, ++ { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, ++ { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, + { } /* Terminating entry */ + }; + +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 4fcf1cecb6d7..f9d15bd62785 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -609,6 +609,13 @@ + #define ADI_GNICE_PID 0xF000 + #define ADI_GNICEPLUS_PID 0xF001 + ++/* ++ * Cypress WICED USB UART ++ */ ++#define CYPRESS_VID 0x04B4 ++#define CYPRESS_WICED_BT_USB_PID 0x009B ++#define CYPRESS_WICED_WL_USB_PID 0xF900 ++ + /* + * Microchip Technology, Inc. + * +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 2a9944326210..db3d34c2c82e 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb); + + /* TP-LINK Incorporated products */ + #define TPLINK_VENDOR_ID 0x2357 ++#define TPLINK_PRODUCT_LTE 0x000D + #define TPLINK_PRODUCT_MA180 0x0201 + + /* Changhong products */ +@@ -2011,6 +2012,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, + { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, + { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ + { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ +diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c +index 652b4334b26d..e1c1e329c877 100644 +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = { + {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ + {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ + {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ ++ {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ ++ {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ ++ {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ ++ {DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */ + + /* Huawei devices */ + {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ +diff --git a/fs/block_dev.c b/fs/block_dev.c +index 07e46b786500..cb936c90ae82 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -450,10 +450,12 @@ int bdev_write_page(struct block_device *bdev, sector_t sector, + + set_page_writeback(page); + result = ops->rw_page(bdev, sector + get_start_sect(bdev), page, true); +- if (result) ++ if (result) { + end_page_writeback(page); +- else ++ } else { ++ clean_page_buffers(page); + unlock_page(page); ++ } + blk_queue_exit(bdev->bd_queue); + return result; + } +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 48ef401c3c61..7b496a4e650e 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -365,6 +365,8 @@ struct smb_version_operations { + unsigned int (*calc_smb_size)(void *); + /* check for STATUS_PENDING and process it in a positive case */ + bool (*is_status_pending)(char *, struct TCP_Server_Info *, int); ++ /* check for STATUS_NETWORK_SESSION_EXPIRED */ ++ bool (*is_session_expired)(char *); + /* send oplock break response */ + int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *, + struct cifsInodeInfo *); +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index 1f91c9dadd5b..cc420d6b71f7 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1457,6 +1457,13 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) + return length; + server->total_read += length; + ++ if (server->ops->is_session_expired && ++ server->ops->is_session_expired(buf)) { ++ cifs_reconnect(server); ++ wake_up(&server->response_q); ++ return -1; ++ } ++ + if (server->ops->is_status_pending && + server->ops->is_status_pending(buf, server, 0)) { + discard_remaining_data(server); +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index f6712b6128d8..580b3a4ca53a 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -796,6 +796,13 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) + cifs_dump_mem("Bad SMB: ", buf, + min_t(unsigned int, server->total_read, 48)); + ++ if (server->ops->is_session_expired && ++ server->ops->is_session_expired(buf)) { ++ cifs_reconnect(server); ++ wake_up(&server->response_q); ++ return -1; ++ } ++ + if (server->ops->is_status_pending && + server->ops->is_status_pending(buf, server, length)) + return -1; +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index b6968241c26f..812e4884c392 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1018,6 +1018,18 @@ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length) + return true; + } + ++static bool ++smb2_is_session_expired(char *buf) ++{ ++ struct smb2_hdr *hdr = (struct smb2_hdr *)buf; ++ ++ if (hdr->Status != STATUS_NETWORK_SESSION_EXPIRED) ++ return false; ++ ++ cifs_dbg(FYI, "Session expired\n"); ++ return true; ++} ++ + static int + smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, + struct cifsInodeInfo *cinode) +@@ -1609,6 +1621,7 @@ struct smb_version_operations smb20_operations = { + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1690,6 +1703,7 @@ struct smb_version_operations smb21_operations = { + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1773,6 +1787,7 @@ struct smb_version_operations smb30_operations = { + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1862,6 +1877,7 @@ struct smb_version_operations smb311_operations = { + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +diff --git a/fs/direct-io.c b/fs/direct-io.c +index c60756e89833..c6220a2daefd 100644 +--- a/fs/direct-io.c ++++ b/fs/direct-io.c +@@ -835,7 +835,8 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page, + */ + if (sdio->boundary) { + ret = dio_send_cur_page(dio, sdio, map_bh); +- dio_bio_submit(dio, sdio); ++ if (sdio->bio) ++ dio_bio_submit(dio, sdio); + put_page(sdio->cur_page); + sdio->cur_page = NULL; + } +diff --git a/fs/ext4/file.c b/fs/ext4/file.c +index d17d12ed6f73..510e66422f04 100644 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -527,7 +527,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) + inode_lock(inode); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + inode_unlock(inode); + return -ENXIO; + } +@@ -590,7 +590,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) + inode_lock(inode); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + inode_unlock(inode); + return -ENXIO; + } +diff --git a/fs/mpage.c b/fs/mpage.c +index d2fcb149720d..e2ea442bb9e1 100644 +--- a/fs/mpage.c ++++ b/fs/mpage.c +@@ -466,6 +466,16 @@ static void clean_buffers(struct page *page, unsigned first_unmapped) + try_to_free_buffers(page); + } + ++/* ++ * For situations where we want to clean all buffers attached to a page. ++ * We don't need to calculate how many buffers are attached to the page, ++ * we just need to specify a number larger than the maximum number of buffers. ++ */ ++void clean_page_buffers(struct page *page) ++{ ++ clean_buffers(page, ~0U); ++} ++ + static int __mpage_writepage(struct page *page, struct writeback_control *wbc, + void *data) + { +@@ -604,10 +614,8 @@ static int __mpage_writepage(struct page *page, struct writeback_control *wbc, + if (bio == NULL) { + if (first_unmapped == blocks_per_page) { + if (!bdev_write_page(bdev, blocks[0] << (blkbits - 9), +- page, wbc)) { +- clean_buffers(page, first_unmapped); ++ page, wbc)) + goto out; +- } + } + bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9), + BIO_MAX_PAGES, GFP_NOFS|__GFP_HIGH); +diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h +index ebbacd14d450..447a915db25d 100644 +--- a/include/linux/buffer_head.h ++++ b/include/linux/buffer_head.h +@@ -226,6 +226,7 @@ int generic_write_end(struct file *, struct address_space *, + loff_t, unsigned, unsigned, + struct page *, void *); + void page_zero_new_buffers(struct page *page, unsigned from, unsigned to); ++void clean_page_buffers(struct page *page); + int cont_write_begin(struct file *, struct address_space *, loff_t, + unsigned, unsigned, struct page **, void **, + get_block_t *, loff_t *); +diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h +index a03acd0d398a..695257ae64ac 100644 +--- a/include/sound/seq_virmidi.h ++++ b/include/sound/seq_virmidi.h +@@ -60,6 +60,7 @@ struct snd_virmidi_dev { + int port; /* created/attached port */ + unsigned int flags; /* SNDRV_VIRMIDI_* */ + rwlock_t filelist_lock; ++ struct rw_semaphore filelist_sem; + struct list_head filelist; + }; + +diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c +index 10f62c6f48e7..d1a02877a42c 100644 +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -792,8 +792,13 @@ void rcu_irq_exit(void) + long long oldval; + struct rcu_dynticks *rdtp; + +- RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs enabled!!!"); + rdtp = this_cpu_ptr(&rcu_dynticks); ++ ++ /* Page faults can happen in NMI handlers, so check... */ ++ if (READ_ONCE(rdtp->dynticks_nmi_nesting)) ++ return; ++ ++ RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs enabled!!!"); + oldval = rdtp->dynticks_nesting; + rdtp->dynticks_nesting--; + WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && +@@ -930,8 +935,13 @@ void rcu_irq_enter(void) + struct rcu_dynticks *rdtp; + long long oldval; + +- RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs enabled!!!"); + rdtp = this_cpu_ptr(&rcu_dynticks); ++ ++ /* Page faults can happen in NMI handlers, so check... */ ++ if (READ_ONCE(rdtp->dynticks_nmi_nesting)) ++ return; ++ ++ RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs enabled!!!"); + oldval = rdtp->dynticks_nesting; + rdtp->dynticks_nesting++; + WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index ece0fbc08607..c626f679e1c8 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -541,6 +541,14 @@ nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = { + [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED }, + }; + ++/* policy for packet pattern attributes */ ++static const struct nla_policy ++nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { ++ [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, }, ++ [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, }, ++ [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, ++}; ++ + static int nl80211_prepare_wdev_dump(struct sk_buff *skb, + struct netlink_callback *cb, + struct cfg80211_registered_device **rdev, +@@ -10009,7 +10017,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) + u8 *mask_pat; + + nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), +- nla_len(pat), NULL); ++ nla_len(pat), nl80211_packet_pattern_policy); + err = -EINVAL; + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) +@@ -10259,7 +10267,7 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, + u8 *mask_pat; + + nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), +- nla_len(pat), NULL); ++ nla_len(pat), nl80211_packet_pattern_policy); + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) + return -EINVAL; +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index 67c4c68ce041..c41148353e19 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1259,6 +1259,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) + struct snd_seq_port_info *info = arg; + struct snd_seq_client_port *port; + struct snd_seq_port_callback *callback; ++ int port_idx; + + /* it is not allowed to create the port for an another client */ + if (info->addr.client != client->number) +@@ -1269,7 +1270,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) + return -ENOMEM; + + if (client->type == USER_CLIENT && info->kernel) { +- snd_seq_delete_port(client, port->addr.port); ++ port_idx = port->addr.port; ++ snd_seq_port_unlock(port); ++ snd_seq_delete_port(client, port_idx); + return -EINVAL; + } + if (client->type == KERNEL_CLIENT) { +@@ -1290,6 +1293,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) + + snd_seq_set_port_info(port, info); + snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); ++ snd_seq_port_unlock(port); + + return 0; + } +diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c +index fe686ee41c6d..f04714d70bf7 100644 +--- a/sound/core/seq/seq_ports.c ++++ b/sound/core/seq/seq_ports.c +@@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp) + } + + +-/* create a port, port number is returned (-1 on failure) */ ++/* create a port, port number is returned (-1 on failure); ++ * the caller needs to unref the port via snd_seq_port_unlock() appropriately ++ */ + struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, + int port) + { +@@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, + snd_use_lock_init(&new_port->use_lock); + port_subs_info_init(&new_port->c_src); + port_subs_info_init(&new_port->c_dest); ++ snd_use_lock_use(&new_port->use_lock); + + num = port >= 0 ? port : 0; + mutex_lock(&client->ports_mutex); +@@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, + list_add_tail(&new_port->list, &p->list); + client->num_ports++; + new_port->addr.port = num; /* store the port number in the port */ ++ sprintf(new_port->name, "port-%d", num); + write_unlock_irqrestore(&client->ports_lock, flags); + mutex_unlock(&client->ports_mutex); +- sprintf(new_port->name, "port-%d", num); + + return new_port; + } +diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c +index c82ed3e70506..200764948ed1 100644 +--- a/sound/core/seq/seq_virmidi.c ++++ b/sound/core/seq/seq_virmidi.c +@@ -77,13 +77,17 @@ static void snd_virmidi_init_event(struct snd_virmidi *vmidi, + * decode input event and put to read buffer of each opened file + */ + static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, +- struct snd_seq_event *ev) ++ struct snd_seq_event *ev, ++ bool atomic) + { + struct snd_virmidi *vmidi; + unsigned char msg[4]; + int len; + +- read_lock(&rdev->filelist_lock); ++ if (atomic) ++ read_lock(&rdev->filelist_lock); ++ else ++ down_read(&rdev->filelist_sem); + list_for_each_entry(vmidi, &rdev->filelist, list) { + if (!vmidi->trigger) + continue; +@@ -97,7 +101,10 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, + snd_rawmidi_receive(vmidi->substream, msg, len); + } + } +- read_unlock(&rdev->filelist_lock); ++ if (atomic) ++ read_unlock(&rdev->filelist_lock); ++ else ++ up_read(&rdev->filelist_sem); + + return 0; + } +@@ -115,7 +122,7 @@ int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev) + struct snd_virmidi_dev *rdev; + + rdev = rmidi->private_data; +- return snd_virmidi_dev_receive_event(rdev, ev); ++ return snd_virmidi_dev_receive_event(rdev, ev, true); + } + #endif /* 0 */ + +@@ -130,7 +137,7 @@ static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct, + rdev = private_data; + if (!(rdev->flags & SNDRV_VIRMIDI_USE)) + return 0; /* ignored */ +- return snd_virmidi_dev_receive_event(rdev, ev); ++ return snd_virmidi_dev_receive_event(rdev, ev, atomic); + } + + /* +@@ -209,7 +216,6 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) + struct snd_virmidi_dev *rdev = substream->rmidi->private_data; + struct snd_rawmidi_runtime *runtime = substream->runtime; + struct snd_virmidi *vmidi; +- unsigned long flags; + + vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL); + if (vmidi == NULL) +@@ -223,9 +229,11 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) + vmidi->client = rdev->client; + vmidi->port = rdev->port; + runtime->private_data = vmidi; +- write_lock_irqsave(&rdev->filelist_lock, flags); ++ down_write(&rdev->filelist_sem); ++ write_lock_irq(&rdev->filelist_lock); + list_add_tail(&vmidi->list, &rdev->filelist); +- write_unlock_irqrestore(&rdev->filelist_lock, flags); ++ write_unlock_irq(&rdev->filelist_lock); ++ up_write(&rdev->filelist_sem); + vmidi->rdev = rdev; + return 0; + } +@@ -264,9 +272,11 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) + struct snd_virmidi_dev *rdev = substream->rmidi->private_data; + struct snd_virmidi *vmidi = substream->runtime->private_data; + ++ down_write(&rdev->filelist_sem); + write_lock_irq(&rdev->filelist_lock); + list_del(&vmidi->list); + write_unlock_irq(&rdev->filelist_lock); ++ up_write(&rdev->filelist_sem); + snd_midi_event_free(vmidi->parser); + substream->runtime->private_data = NULL; + kfree(vmidi); +@@ -520,6 +530,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi + rdev->rmidi = rmidi; + rdev->device = device; + rdev->client = -1; ++ init_rwsem(&rdev->filelist_sem); + rwlock_init(&rdev->filelist_lock); + INIT_LIST_HEAD(&rdev->filelist); + rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH; +diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c +index b871ba407e4e..4458190149d1 100644 +--- a/sound/usb/caiaq/device.c ++++ b/sound/usb/caiaq/device.c +@@ -469,10 +469,12 @@ static int init_card(struct snd_usb_caiaqdev *cdev) + + err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); + if (err) +- return err; ++ goto err_kill_urb; + +- if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) +- return -ENODEV; ++ if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) { ++ err = -ENODEV; ++ goto err_kill_urb; ++ } + + usb_string(usb_dev, usb_dev->descriptor.iManufacturer, + cdev->vendor_name, CAIAQ_USB_STR_LEN); +@@ -507,6 +509,10 @@ static int init_card(struct snd_usb_caiaqdev *cdev) + + setup_card(cdev); + return 0; ++ ++ err_kill_urb: ++ usb_kill_urb(&cdev->ep1_in_urb); ++ return err; + } + + static int snd_probe(struct usb_interface *intf, +diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c +index ab3c280a23d1..58d624938a9f 100644 +--- a/sound/usb/line6/driver.c ++++ b/sound/usb/line6/driver.c +@@ -775,9 +775,10 @@ int line6_probe(struct usb_interface *interface, + return 0; + + error: +- if (line6->disconnect) +- line6->disconnect(line6); +- snd_card_free(card); ++ /* we can call disconnect callback here because no close-sync is ++ * needed yet at this point ++ */ ++ line6_disconnect(interface); + return ret; + } + EXPORT_SYMBOL_GPL(line6_probe); +diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c +index 49cd4a65e390..5ab9e0c89211 100644 +--- a/sound/usb/line6/podhd.c ++++ b/sound/usb/line6/podhd.c +@@ -307,6 +307,9 @@ static int podhd_init(struct usb_line6 *line6, + + line6->disconnect = podhd_disconnect; + ++ init_timer(&pod->startup_timer); ++ INIT_WORK(&pod->startup_work, podhd_startup_workqueue); ++ + if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { + /* create sysfs entries: */ + err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group); +@@ -330,8 +333,6 @@ static int podhd_init(struct usb_line6 *line6, + } + + /* init device and delay registering */ +- init_timer(&pod->startup_timer); +- INIT_WORK(&pod->startup_work, podhd_startup_workqueue); + podhd_startup(pod); + return 0; + } +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index d09c28c1deaf..d82e3c81c258 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -2228,6 +2228,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) + + static void snd_usb_mixer_free(struct usb_mixer_interface *mixer) + { ++ /* kill pending URBs */ ++ snd_usb_mixer_disconnect(mixer); ++ + kfree(mixer->id_elems); + if (mixer->urb) { + kfree(mixer->urb->transfer_buffer); +@@ -2578,8 +2581,13 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, + + void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer) + { +- usb_kill_urb(mixer->urb); +- usb_kill_urb(mixer->rc_urb); ++ if (mixer->disconnected) ++ return; ++ if (mixer->urb) ++ usb_kill_urb(mixer->urb); ++ if (mixer->rc_urb) ++ usb_kill_urb(mixer->rc_urb); ++ mixer->disconnected = true; + } + + #ifdef CONFIG_PM +diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h +index 2b4b067646ab..545d99b09706 100644 +--- a/sound/usb/mixer.h ++++ b/sound/usb/mixer.h +@@ -22,6 +22,8 @@ struct usb_mixer_interface { + struct urb *rc_urb; + struct usb_ctrlrequest *rc_setup_packet; + u8 rc_buffer[6]; ++ ++ bool disconnected; + }; + + #define MAX_CHANNELS 16 /* max logical channels */