From 5607de60d2a17294b70fc775bd73ba4ec16dc856 Mon Sep 17 00:00:00 2001 From: "Anthony G. Basile" Date: Mon, 2 Dec 2013 15:52:16 -0500 Subject: Grsec/PaX: 3.0-{3.2.53,3.12.2}-201312011111 --- 3.2.53/1049_linux-3.2.50.patch | 2495 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2495 insertions(+) create mode 100644 3.2.53/1049_linux-3.2.50.patch (limited to '3.2.53/1049_linux-3.2.50.patch') diff --git a/3.2.53/1049_linux-3.2.50.patch b/3.2.53/1049_linux-3.2.50.patch new file mode 100644 index 0000000..20b3015 --- /dev/null +++ b/3.2.53/1049_linux-3.2.50.patch @@ -0,0 +1,2495 @@ +diff --git a/Makefile b/Makefile +index 2e3d791..0799e8e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 49 ++SUBLEVEL = 50 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h +index 0192a4e..80de64b 100644 +--- a/arch/powerpc/include/asm/module.h ++++ b/arch/powerpc/include/asm/module.h +@@ -87,10 +87,9 @@ struct exception_table_entry; + void sort_ex_table(struct exception_table_entry *start, + struct exception_table_entry *finish); + +-#ifdef CONFIG_MODVERSIONS ++#if defined(CONFIG_MODVERSIONS) && defined(CONFIG_PPC64) + #define ARCH_RELOCATES_KCRCTAB +- +-extern const unsigned long reloc_start[]; ++#define reloc_start PHYSICAL_START + #endif + #endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_MODULE_H */ +diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S +index 920276c..3e8fe4b 100644 +--- a/arch/powerpc/kernel/vmlinux.lds.S ++++ b/arch/powerpc/kernel/vmlinux.lds.S +@@ -38,9 +38,6 @@ jiffies = jiffies_64 + 4; + #endif + SECTIONS + { +- . = 0; +- reloc_start = .; +- + . = KERNELBASE; + + /* +diff --git a/arch/sparc/kernel/asm-offsets.c b/arch/sparc/kernel/asm-offsets.c +index 68f7e11..ce48203 100644 +--- a/arch/sparc/kernel/asm-offsets.c ++++ b/arch/sparc/kernel/asm-offsets.c +@@ -34,6 +34,8 @@ int foo(void) + DEFINE(AOFF_task_thread, offsetof(struct task_struct, thread)); + BLANK(); + DEFINE(AOFF_mm_context, offsetof(struct mm_struct, context)); ++ BLANK(); ++ DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); + + /* DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); */ + return 0; +diff --git a/arch/sparc/mm/hypersparc.S b/arch/sparc/mm/hypersparc.S +index 44aad32..969f964 100644 +--- a/arch/sparc/mm/hypersparc.S ++++ b/arch/sparc/mm/hypersparc.S +@@ -74,7 +74,7 @@ hypersparc_flush_cache_mm_out: + + /* The things we do for performance... */ + hypersparc_flush_cache_range: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + #ifndef CONFIG_SMP + ld [%o0 + AOFF_mm_context], %g1 + cmp %g1, -1 +@@ -163,7 +163,7 @@ hypersparc_flush_cache_range_out: + */ + /* Verified, my ass... */ + hypersparc_flush_cache_page: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + ld [%o0 + AOFF_mm_context], %g2 + #ifndef CONFIG_SMP + cmp %g2, -1 +@@ -284,7 +284,7 @@ hypersparc_flush_tlb_mm_out: + sta %g5, [%g1] ASI_M_MMUREGS + + hypersparc_flush_tlb_range: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 +@@ -307,7 +307,7 @@ hypersparc_flush_tlb_range_out: + sta %g5, [%g1] ASI_M_MMUREGS + + hypersparc_flush_tlb_page: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + andn %o1, (PAGE_SIZE - 1), %o1 +diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c +index 6ff4d78..b4989f9 100644 +--- a/arch/sparc/mm/init_64.c ++++ b/arch/sparc/mm/init_64.c +@@ -1071,7 +1071,14 @@ static int __init grab_mblocks(struct mdesc_handle *md) + m->size = *val; + val = mdesc_get_property(md, node, + "address-congruence-offset", NULL); +- m->offset = *val; ++ ++ /* The address-congruence-offset property is optional. ++ * Explicity zero it be identifty this. ++ */ ++ if (val) ++ m->offset = *val; ++ else ++ m->offset = 0UL; + + numadbg("MBLOCK[%d]: base[%llx] size[%llx] offset[%llx]\n", + count - 1, m->base, m->size, m->offset); +diff --git a/arch/sparc/mm/swift.S b/arch/sparc/mm/swift.S +index c801c39..5d2b88d 100644 +--- a/arch/sparc/mm/swift.S ++++ b/arch/sparc/mm/swift.S +@@ -105,7 +105,7 @@ swift_flush_cache_mm_out: + + .globl swift_flush_cache_range + swift_flush_cache_range: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + sub %o2, %o1, %o2 + sethi %hi(4096), %o3 + cmp %o2, %o3 +@@ -116,7 +116,7 @@ swift_flush_cache_range: + + .globl swift_flush_cache_page + swift_flush_cache_page: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + 70: + ld [%o0 + AOFF_mm_context], %g2 + cmp %g2, -1 +@@ -219,7 +219,7 @@ swift_flush_sig_insns: + .globl swift_flush_tlb_range + .globl swift_flush_tlb_all + swift_flush_tlb_range: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + swift_flush_tlb_mm: + ld [%o0 + AOFF_mm_context], %g2 + cmp %g2, -1 +@@ -233,7 +233,7 @@ swift_flush_tlb_all_out: + + .globl swift_flush_tlb_page + swift_flush_tlb_page: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + andn %o1, (PAGE_SIZE - 1), %o1 +diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c +index afd021e..072f553 100644 +--- a/arch/sparc/mm/tlb.c ++++ b/arch/sparc/mm/tlb.c +@@ -115,8 +115,8 @@ no_cache_flush: + } + + if (!tb->active) { +- global_flush_tlb_page(mm, vaddr); + flush_tsb_user_page(mm, vaddr); ++ global_flush_tlb_page(mm, vaddr); + goto out; + } + +diff --git a/arch/sparc/mm/tsunami.S b/arch/sparc/mm/tsunami.S +index 4e55e8f..bf10a34 100644 +--- a/arch/sparc/mm/tsunami.S ++++ b/arch/sparc/mm/tsunami.S +@@ -24,7 +24,7 @@ + /* Sliiick... */ + tsunami_flush_cache_page: + tsunami_flush_cache_range: +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + tsunami_flush_cache_mm: + ld [%o0 + AOFF_mm_context], %g2 + cmp %g2, -1 +@@ -46,7 +46,7 @@ tsunami_flush_sig_insns: + + /* More slick stuff... */ + tsunami_flush_tlb_range: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + tsunami_flush_tlb_mm: + ld [%o0 + AOFF_mm_context], %g2 + cmp %g2, -1 +@@ -65,7 +65,7 @@ tsunami_flush_tlb_out: + + /* This one can be done in a fine grained manner... */ + tsunami_flush_tlb_page: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + andn %o1, (PAGE_SIZE - 1), %o1 +diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S +index 6dfcc13..a516372 100644 +--- a/arch/sparc/mm/viking.S ++++ b/arch/sparc/mm/viking.S +@@ -109,7 +109,7 @@ viking_mxcc_flush_page: + viking_flush_cache_page: + viking_flush_cache_range: + #ifndef CONFIG_SMP +- ld [%o0 + 0x0], %o0 /* XXX vma->vm_mm, GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + #endif + viking_flush_cache_mm: + #ifndef CONFIG_SMP +@@ -149,7 +149,7 @@ viking_flush_tlb_mm: + #endif + + viking_flush_tlb_range: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 +@@ -174,7 +174,7 @@ viking_flush_tlb_range: + #endif + + viking_flush_tlb_page: +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + mov SRMMU_CTX_REG, %g1 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 +@@ -240,7 +240,7 @@ sun4dsmp_flush_tlb_range: + tst %g5 + bne 3f + mov SRMMU_CTX_REG, %g1 +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 + sethi %hi(~((1 << SRMMU_PGDIR_SHIFT) - 1)), %o4 +@@ -266,7 +266,7 @@ sun4dsmp_flush_tlb_page: + tst %g5 + bne 2f + mov SRMMU_CTX_REG, %g1 +- ld [%o0 + 0x00], %o0 /* XXX vma->vm_mm GROSS XXX */ ++ ld [%o0 + VMA_VM_MM], %o0 + ld [%o0 + AOFF_mm_context], %o3 + lda [%g1] ASI_M_MMUREGS, %g5 + and %o1, PAGE_MASK, %o1 +diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c +index d985713..f81597f 100644 +--- a/drivers/acpi/acpi_memhotplug.c ++++ b/drivers/acpi/acpi_memhotplug.c +@@ -421,6 +421,7 @@ static int acpi_memory_device_add(struct acpi_device *device) + /* Get the range from the _CRS */ + result = acpi_memory_get_device_resources(mem_device); + if (result) { ++ device->driver_data = NULL; + kfree(mem_device); + return result; + } +diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c +index 7a949af..5b0b5f7 100644 +--- a/drivers/ata/ata_piix.c ++++ b/drivers/ata/ata_piix.c +@@ -352,7 +352,7 @@ static const struct pci_device_id piix_pci_tbl[] = { + /* SATA Controller IDE (Wellsburg) */ + { 0x8086, 0x8d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (Wellsburg) */ +- { 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ { 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb }, + /* SATA Controller IDE (Wellsburg) */ + { 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, + /* SATA Controller IDE (Wellsburg) */ +diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c +index 85fdd4b..2232b85 100644 +--- a/drivers/block/xen-blkback/blkback.c ++++ b/drivers/block/xen-blkback/blkback.c +@@ -277,6 +277,7 @@ int xen_blkif_schedule(void *arg) + { + struct xen_blkif *blkif = arg; + struct xen_vbd *vbd = &blkif->vbd; ++ int ret; + + xen_blkif_get(blkif); + +@@ -297,8 +298,12 @@ int xen_blkif_schedule(void *arg) + blkif->waiting_reqs = 0; + smp_mb(); /* clear flag *before* checking for work */ + +- if (do_block_io_op(blkif)) ++ ret = do_block_io_op(blkif); ++ if (ret > 0) + blkif->waiting_reqs = 1; ++ if (ret == -EACCES) ++ wait_event_interruptible(blkif->shutdown_wq, ++ kthread_should_stop()); + + if (log_stats && time_after(jiffies, blkif->st_print)) + print_stats(blkif); +@@ -539,6 +544,12 @@ __do_block_io_op(struct xen_blkif *blkif) + rp = blk_rings->common.sring->req_prod; + rmb(); /* Ensure we see queued requests up to 'rp'. */ + ++ if (RING_REQUEST_PROD_OVERFLOW(&blk_rings->common, rp)) { ++ rc = blk_rings->common.rsp_prod_pvt; ++ pr_warn(DRV_PFX "Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n", ++ rp, rc, rp - rc, blkif->vbd.pdevice); ++ return -EACCES; ++ } + while (rc != rp) { + + if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc)) +diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h +index dfb1b3a..f67985d 100644 +--- a/drivers/block/xen-blkback/common.h ++++ b/drivers/block/xen-blkback/common.h +@@ -198,6 +198,8 @@ struct xen_blkif { + int st_wr_sect; + + wait_queue_head_t waiting_to_free; ++ /* Thread shutdown wait queue. */ ++ wait_queue_head_t shutdown_wq; + }; + + +diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c +index 674e3c2..77aed26 100644 +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -118,6 +118,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) + atomic_set(&blkif->drain, 0); + blkif->st_print = jiffies; + init_waitqueue_head(&blkif->waiting_to_free); ++ init_waitqueue_head(&blkif->shutdown_wq); + + return blkif; + } +@@ -178,6 +179,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) + { + if (blkif->xenblkd) { + kthread_stop(blkif->xenblkd); ++ wake_up(&blkif->shutdown_wq); + blkif->xenblkd = NULL; + } + +diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c +index c32fd93..8115557 100644 +--- a/drivers/gpu/drm/radeon/radeon_combios.c ++++ b/drivers/gpu/drm/radeon/radeon_combios.c +@@ -147,7 +147,7 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, + enum radeon_combios_table_offset table) + { + struct radeon_device *rdev = dev->dev_private; +- int rev; ++ int rev, size; + uint16_t offset = 0, check_offset; + + if (!rdev->bios) +@@ -156,174 +156,106 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, + switch (table) { + /* absolute offset tables */ + case COMBIOS_ASIC_INIT_1_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0xc); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0xc; + break; + case COMBIOS_BIOS_SUPPORT_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x14); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x14; + break; + case COMBIOS_DAC_PROGRAMMING_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2a; + break; + case COMBIOS_MAX_COLOR_DEPTH_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2c; + break; + case COMBIOS_CRTC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2e; + break; + case COMBIOS_PLL_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x30); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x30; + break; + case COMBIOS_TV_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x32); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x32; + break; + case COMBIOS_DFP_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x34); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x34; + break; + case COMBIOS_HW_CONFIG_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x36); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x36; + break; + case COMBIOS_MULTIMEDIA_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x38); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x38; + break; + case COMBIOS_TV_STD_PATCH_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x3e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x3e; + break; + case COMBIOS_LCD_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x40); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x40; + break; + case COMBIOS_MOBILE_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x42); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x42; + break; + case COMBIOS_PLL_INIT_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x46); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x46; + break; + case COMBIOS_MEM_CONFIG_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x48); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x48; + break; + case COMBIOS_SAVE_MASK_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4a; + break; + case COMBIOS_HARDCODED_EDID_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4c; + break; + case COMBIOS_ASIC_INIT_2_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4e; + break; + case COMBIOS_CONNECTOR_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x50); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x50; + break; + case COMBIOS_DYN_CLK_1_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x52); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x52; + break; + case COMBIOS_RESERVED_MEM_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x54); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x54; + break; + case COMBIOS_EXT_TMDS_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x58); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x58; + break; + case COMBIOS_MEM_CLK_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5a; + break; + case COMBIOS_EXT_DAC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5c; + break; + case COMBIOS_MISC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5e; + break; + case COMBIOS_CRT_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x60); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x60; + break; + case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x62); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x62; + break; + case COMBIOS_COMPONENT_VIDEO_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x64); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x64; + break; + case COMBIOS_FAN_SPEED_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x66); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x66; + break; + case COMBIOS_OVERDRIVE_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x68); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x68; + break; + case COMBIOS_OEM_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6a; + break; + case COMBIOS_DYN_CLK_2_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6c; + break; + case COMBIOS_POWER_CONNECTOR_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6e; + break; + case COMBIOS_I2C_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x70); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x70; + break; + /* relative offset tables */ + case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */ +@@ -439,11 +371,16 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, + } + break; + default: ++ check_offset = 0; + break; + } + +- return offset; ++ size = RBIOS8(rdev->bios_header_start + 0x6); ++ /* check absolute offset tables */ ++ if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size) ++ offset = RBIOS16(rdev->bios_header_start + check_offset); + ++ return offset; + } + + bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) +@@ -953,16 +890,22 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct + dac = RBIOS8(dac_info + 0x3) & 0xf; + p_dac->ps2_pdac_adj = (bg << 8) | (dac); + } +- /* if the values are all zeros, use the table */ +- if (p_dac->ps2_pdac_adj) ++ /* if the values are zeros, use the table */ ++ if ((dac == 0) || (bg == 0)) ++ found = 0; ++ else + found = 1; + } + + /* quirks */ ++ /* Radeon 7000 (RV100) */ ++ if (((dev->pdev->device == 0x5159) && ++ (dev->pdev->subsystem_vendor == 0x174B) && ++ (dev->pdev->subsystem_device == 0x7c28)) || + /* Radeon 9100 (R200) */ +- if ((dev->pdev->device == 0x514D) && ++ ((dev->pdev->device == 0x514D) && + (dev->pdev->subsystem_vendor == 0x174B) && +- (dev->pdev->subsystem_device == 0x7149)) { ++ (dev->pdev->subsystem_device == 0x7149))) { + /* vbios value is bad, use the default */ + found = 0; + } +diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c +index 68fe73c..99b1145 100644 +--- a/drivers/net/dummy.c ++++ b/drivers/net/dummy.c +@@ -186,6 +186,8 @@ static int __init dummy_init_module(void) + + rtnl_lock(); + err = __rtnl_link_register(&dummy_link_ops); ++ if (err < 0) ++ goto out; + + for (i = 0; i < numdummies && !err; i++) { + err = dummy_init_one(); +@@ -193,6 +195,8 @@ static int __init dummy_init_module(void) + } + if (err < 0) + __rtnl_link_unregister(&dummy_link_ops); ++ ++out: + rtnl_unlock(); + + return err; +diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +index dd893b3..87851f0 100644 +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -1685,8 +1685,8 @@ check_sum: + return 0; + } + +-static void atl1e_tx_map(struct atl1e_adapter *adapter, +- struct sk_buff *skb, struct atl1e_tpd_desc *tpd) ++static int atl1e_tx_map(struct atl1e_adapter *adapter, ++ struct sk_buff *skb, struct atl1e_tpd_desc *tpd) + { + struct atl1e_tpd_desc *use_tpd = NULL; + struct atl1e_tx_buffer *tx_buffer = NULL; +@@ -1697,6 +1697,8 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + u16 nr_frags; + u16 f; + int segment; ++ int ring_start = adapter->tx_ring.next_to_use; ++ int ring_end; + + nr_frags = skb_shinfo(skb)->nr_frags; + segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; +@@ -1709,6 +1711,9 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + tx_buffer->length = map_len; + tx_buffer->dma = pci_map_single(adapter->pdev, + skb->data, hdr_len, PCI_DMA_TODEVICE); ++ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) ++ return -ENOSPC; ++ + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); + mapped_len += map_len; + use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); +@@ -1735,6 +1740,22 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + tx_buffer->dma = + pci_map_single(adapter->pdev, skb->data + mapped_len, + map_len, PCI_DMA_TODEVICE); ++ ++ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { ++ /* We need to unwind the mappings we've done */ ++ ring_end = adapter->tx_ring.next_to_use; ++ adapter->tx_ring.next_to_use = ring_start; ++ while (adapter->tx_ring.next_to_use != ring_end) { ++ tpd = atl1e_get_tpd(adapter); ++ tx_buffer = atl1e_get_tx_buffer(adapter, tpd); ++ pci_unmap_single(adapter->pdev, tx_buffer->dma, ++ tx_buffer->length, PCI_DMA_TODEVICE); ++ } ++ /* Reset the tx rings next pointer */ ++ adapter->tx_ring.next_to_use = ring_start; ++ return -ENOSPC; ++ } ++ + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); + mapped_len += map_len; + use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); +@@ -1770,6 +1791,23 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + (i * MAX_TX_BUF_LEN), + tx_buffer->length, + DMA_TO_DEVICE); ++ ++ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { ++ /* We need to unwind the mappings we've done */ ++ ring_end = adapter->tx_ring.next_to_use; ++ adapter->tx_ring.next_to_use = ring_start; ++ while (adapter->tx_ring.next_to_use != ring_end) { ++ tpd = atl1e_get_tpd(adapter); ++ tx_buffer = atl1e_get_tx_buffer(adapter, tpd); ++ dma_unmap_page(&adapter->pdev->dev, tx_buffer->dma, ++ tx_buffer->length, DMA_TO_DEVICE); ++ } ++ ++ /* Reset the ring next to use pointer */ ++ adapter->tx_ring.next_to_use = ring_start; ++ return -ENOSPC; ++ } ++ + ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE); + use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); + use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) | +@@ -1787,6 +1825,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, + /* The last buffer info contain the skb address, + so it will be free after unmap */ + tx_buffer->skb = skb; ++ return 0; + } + + static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count, +@@ -1854,10 +1893,15 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, + return NETDEV_TX_OK; + } + +- atl1e_tx_map(adapter, skb, tpd); ++ if (atl1e_tx_map(adapter, skb, tpd)) { ++ dev_kfree_skb_any(skb); ++ goto out; ++ } ++ + atl1e_tx_queue(adapter, tpd_req, tpd); + + netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ ++out: + spin_unlock_irqrestore(&adapter->tx_lock, flags); + return NETDEV_TX_OK; + } +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index 9b23074..b2077ca 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -136,8 +136,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { + .rmcr_value = 0x00000001, + + .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, +- .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE | +- EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, ++ .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | ++ EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | ++ EESR_ECI, + .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, + + .apr = 1, +@@ -251,9 +252,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = { + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, + + .tx_check = EESR_TC1 | EESR_FTC, +- .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ +- EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ +- EESR_ECI, ++ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | ++ EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | ++ EESR_TDE | EESR_ECI, + .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ + EESR_TFE, + .fdr_value = 0x0000072f, +@@ -355,9 +356,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, + + .tx_check = EESR_TC1 | EESR_FTC, +- .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ +- EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ +- EESR_ECI, ++ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | ++ EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | ++ EESR_TDE | EESR_ECI, + .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ + EESR_TFE, + +diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h +index 47877b1..590705c 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.h ++++ b/drivers/net/ethernet/renesas/sh_eth.h +@@ -461,7 +461,7 @@ enum EESR_BIT { + + #define DEFAULT_TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \ + EESR_RTO) +-#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \ ++#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | \ + EESR_RDE | EESR_RFRMER | EESR_ADE | \ + EESR_TFE | EESR_TDE | EESR_ECI) + #define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \ +diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c +index 8c6c059..bd08919 100644 +--- a/drivers/net/ethernet/sun/sunvnet.c ++++ b/drivers/net/ethernet/sun/sunvnet.c +@@ -1248,6 +1248,8 @@ static int vnet_port_remove(struct vio_dev *vdev) + dev_set_drvdata(&vdev->dev, NULL); + + kfree(port); ++ ++ unregister_netdev(vp->dev); + } + return 0; + } +diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c +index 46b5f5f..b19841a 100644 +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -290,11 +290,17 @@ static int __init ifb_init_module(void) + + rtnl_lock(); + err = __rtnl_link_register(&ifb_link_ops); ++ if (err < 0) ++ goto out; + +- for (i = 0; i < numifbs && !err; i++) ++ for (i = 0; i < numifbs && !err; i++) { + err = ifb_init_one(i); ++ cond_resched(); ++ } + if (err) + __rtnl_link_unregister(&ifb_link_ops); ++ ++out: + rtnl_unlock(); + + return err; +diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c +index 26106c0..96b9e3c 100644 +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -532,8 +532,10 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, + return -EMSGSIZE; + num_pages = get_user_pages_fast(base, size, 0, &page[i]); + if (num_pages != size) { +- for (i = 0; i < num_pages; i++) +- put_page(page[i]); ++ int j; ++ ++ for (j = 0; j < num_pages; j++) ++ put_page(page[i + j]); + return -EFAULT; + } + truesize = size * PAGE_SIZE; +@@ -653,6 +655,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + int vnet_hdr_len = 0; + int copylen = 0; + bool zerocopy = false; ++ size_t linear; + + if (q->flags & IFF_VNET_HDR) { + vnet_hdr_len = q->vnet_hdr_sz; +@@ -707,11 +710,14 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, + copylen = vnet_hdr.hdr_len; + if (!copylen) + copylen = GOODCOPY_LEN; +- } else ++ linear = copylen; ++ } else { + copylen = len; ++ linear = vnet_hdr.hdr_len; ++ } + + skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen, +- vnet_hdr.hdr_len, noblock, &err); ++ linear, noblock, &err); + if (!skb) + goto err; + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 6ee8410..43a6a11 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -508,7 +508,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget) + { + struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi); + void *buf; +- unsigned int len, received = 0; ++ unsigned int r, len, received = 0; + + again: + while (received < budget && +@@ -525,8 +525,9 @@ again: + + /* Out of packets? */ + if (received < budget) { ++ r = virtqueue_enable_cb_prepare(vi->rvq); + napi_complete(napi); +- if (unlikely(!virtqueue_enable_cb(vi->rvq)) && ++ if (unlikely(virtqueue_poll(vi->rvq, r)) && + napi_schedule_prep(napi)) { + virtqueue_disable_cb(vi->rvq); + __napi_schedule(napi); +diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c +index 84a78af..182fcb2 100644 +--- a/drivers/scsi/bnx2fc/bnx2fc_io.c ++++ b/drivers/scsi/bnx2fc/bnx2fc_io.c +@@ -1788,7 +1788,7 @@ static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, + fcp_sns_len = SCSI_SENSE_BUFFERSIZE; + } + +- memset(sc_cmd->sense_buffer, 0, sizeof(sc_cmd->sense_buffer)); ++ memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + if (fcp_sns_len) + memcpy(sc_cmd->sense_buffer, rq_data, fcp_sns_len); + +diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c +index 66ad3dc..e294d11 100644 +--- a/drivers/scsi/isci/task.c ++++ b/drivers/scsi/isci/task.c +@@ -1038,6 +1038,7 @@ int isci_task_abort_task(struct sas_task *task) + int ret = TMF_RESP_FUNC_FAILED; + unsigned long flags; + int perform_termination = 0; ++ int target_done_already = 0; + + /* Get the isci_request reference from the task. Note that + * this check does not depend on the pending request list +@@ -1052,9 +1053,11 @@ int isci_task_abort_task(struct sas_task *task) + /* If task is already done, the request isn't valid */ + if (!(task->task_state_flags & SAS_TASK_STATE_DONE) && + (task->task_state_flags & SAS_TASK_AT_INITIATOR) && +- old_request) ++ old_request) { + isci_device = isci_lookup_device(task->dev); +- ++ target_done_already = test_bit(IREQ_COMPLETE_IN_TARGET, ++ &old_request->flags); ++ } + spin_unlock(&task->task_state_lock); + spin_unlock_irqrestore(&isci_host->scic_lock, flags); + +@@ -1116,7 +1119,7 @@ int isci_task_abort_task(struct sas_task *task) + } + if (task->task_proto == SAS_PROTOCOL_SMP || + sas_protocol_ata(task->task_proto) || +- test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) { ++ target_done_already) { + + spin_unlock_irqrestore(&isci_host->scic_lock, flags); + +diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c +index a4b267e..9fbe260 100644 +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -423,6 +423,8 @@ qla2x00_start_scsi(srb_t *sp) + __constant_cpu_to_le16(CF_SIMPLE_TAG); + break; + } ++ } else { ++ cmd_pkt->control_flags = __constant_cpu_to_le16(CF_SIMPLE_TAG); + } + + /* Load SCSI command packet. */ +@@ -1244,11 +1246,11 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, + fcp_cmnd->task_attribute = TSK_ORDERED; + break; + default: +- fcp_cmnd->task_attribute = 0; ++ fcp_cmnd->task_attribute = TSK_SIMPLE; + break; + } + } else { +- fcp_cmnd->task_attribute = 0; ++ fcp_cmnd->task_attribute = TSK_SIMPLE; + } + + cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */ +@@ -1454,7 +1456,12 @@ qla24xx_start_scsi(srb_t *sp) + case ORDERED_QUEUE_TAG: + cmd_pkt->task = TSK_ORDERED; + break; ++ default: ++ cmd_pkt->task = TSK_SIMPLE; ++ break; + } ++ } else { ++ cmd_pkt->task = TSK_SIMPLE; + } + + /* Load SCSI command packet. */ +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 6dace1a..17603da 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -641,10 +641,17 @@ static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) + + static void sd_unprep_fn(struct request_queue *q, struct request *rq) + { ++ struct scsi_cmnd *SCpnt = rq->special; ++ + if (rq->cmd_flags & REQ_DISCARD) { + free_page((unsigned long)rq->buffer); + rq->buffer = NULL; + } ++ if (SCpnt->cmnd != rq->cmd) { ++ mempool_free(SCpnt->cmnd, sd_cdb_pool); ++ SCpnt->cmnd = NULL; ++ SCpnt->cmd_len = 0; ++ } + } + + /** +@@ -1452,21 +1459,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) + if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) + sd_dif_complete(SCpnt, good_bytes); + +- if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) +- == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) { +- +- /* We have to print a failed command here as the +- * extended CDB gets freed before scsi_io_completion() +- * is called. +- */ +- if (result) +- scsi_print_command(SCpnt); +- +- mempool_free(SCpnt->cmnd, sd_cdb_pool); +- SCpnt->cmnd = NULL; +- SCpnt->cmd_len = 0; +- } +- + return good_bytes; + } + +diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c +index fe4dbf3..7e42190 100644 +--- a/drivers/staging/comedi/comedi_fops.c ++++ b/drivers/staging/comedi/comedi_fops.c +@@ -1078,22 +1078,19 @@ static int do_cmd_ioctl(struct comedi_device *dev, + DPRINTK("subdevice busy\n"); + return -EBUSY; + } +- s->busy = file; + + /* make sure channel/gain list isn't too long */ + if (user_cmd.chanlist_len > s->len_chanlist) { + DPRINTK("channel/gain list too long %u > %d\n", + user_cmd.chanlist_len, s->len_chanlist); +- ret = -EINVAL; +- goto cleanup; ++ return -EINVAL; + } + + /* make sure channel/gain list isn't too short */ + if (user_cmd.chanlist_len < 1) { + DPRINTK("channel/gain list too short %u < 1\n", + user_cmd.chanlist_len); +- ret = -EINVAL; +- goto cleanup; ++ return -EINVAL; + } + + async->cmd = user_cmd; +@@ -1103,8 +1100,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, + kmalloc(async->cmd.chanlist_len * sizeof(int), GFP_KERNEL); + if (!async->cmd.chanlist) { + DPRINTK("allocation failed\n"); +- ret = -ENOMEM; +- goto cleanup; ++ return -ENOMEM; + } + + if (copy_from_user(async->cmd.chanlist, user_cmd.chanlist, +@@ -1156,6 +1152,9 @@ static int do_cmd_ioctl(struct comedi_device *dev, + + comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING); + ++ /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with ++ * comedi_read() or comedi_write() */ ++ s->busy = file; + ret = s->do_cmd(dev, s); + if (ret == 0) + return 0; +@@ -1370,6 +1369,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, + void *file) + { + struct comedi_subdevice *s; ++ int ret; + + if (arg >= dev->n_subdevices) + return -EINVAL; +@@ -1386,7 +1386,11 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, + if (s->busy != file) + return -EBUSY; + +- return do_cancel(dev, s); ++ ret = do_cancel(dev, s); ++ if (comedi_get_subdevice_runflags(s) & SRF_USER) ++ wake_up_interruptible(&s->async->wait_head); ++ ++ return ret; + } + + /* +@@ -1653,6 +1657,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, + + if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) { + if (count == 0) { ++ mutex_lock(&dev->mutex); + if (comedi_get_subdevice_runflags(s) & + SRF_ERROR) { + retval = -EPIPE; +@@ -1660,6 +1665,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, + retval = 0; + } + do_become_nonbusy(dev, s); ++ mutex_unlock(&dev->mutex); + } + break; + } +@@ -1774,6 +1780,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, + + if (n == 0) { + if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) { ++ mutex_lock(&dev->mutex); + do_become_nonbusy(dev, s); + if (comedi_get_subdevice_runflags(s) & + SRF_ERROR) { +@@ -1781,6 +1788,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, + } else { + retval = 0; + } ++ mutex_unlock(&dev->mutex); + break; + } + if (file->f_flags & O_NONBLOCK) { +@@ -1818,9 +1826,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, + buf += n; + break; /* makes device work like a pipe */ + } +- if (!(comedi_get_subdevice_runflags(s) & (SRF_ERROR | SRF_RUNNING)) && +- async->buf_read_count - async->buf_write_count == 0) { +- do_become_nonbusy(dev, s); ++ if (!(comedi_get_subdevice_runflags(s) & (SRF_ERROR | SRF_RUNNING))) { ++ mutex_lock(&dev->mutex); ++ if (async->buf_read_count - async->buf_write_count == 0) ++ do_become_nonbusy(dev, s); ++ mutex_unlock(&dev->mutex); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&async->wait_head, &wait); +diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c +index 9d4c8a6..2d3a420 100644 +--- a/drivers/staging/line6/pcm.c ++++ b/drivers/staging/line6/pcm.c +@@ -360,8 +360,11 @@ static int snd_line6_pcm_free(struct snd_device *device) + */ + static void pcm_disconnect_substream(struct snd_pcm_substream *substream) + { +- if (substream->runtime && snd_pcm_running(substream)) ++ if (substream->runtime && snd_pcm_running(substream)) { ++ snd_pcm_stream_lock_irq(substream); + snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); ++ snd_pcm_stream_unlock_irq(substream); ++ } + } + + /* +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 22cbe06..2768a7e 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -463,6 +463,15 @@ resubmit: + static inline int + hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) + { ++ /* Need to clear both directions for control ep */ ++ if (((devinfo >> 11) & USB_ENDPOINT_XFERTYPE_MASK) == ++ USB_ENDPOINT_XFER_CONTROL) { ++ int status = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ HUB_CLEAR_TT_BUFFER, USB_RT_PORT, ++ devinfo ^ 0x8000, tt, NULL, 0, 1000); ++ if (status) ++ return status; ++ } + return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), + HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo, + tt, NULL, 0, 1000); +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index 29a8e16..4795c0c 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -643,8 +643,8 @@ struct dwc3 { + + struct dwc3_event_type { + u32 is_devspec:1; +- u32 type:6; +- u32 reserved8_31:25; ++ u32 type:7; ++ u32 reserved8_31:24; + } __packed; + + #define DWC3_DEPEVT_XFERCOMPLETE 0x01 +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index b368b83..619ee19 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1217,6 +1217,7 @@ err1: + __dwc3_gadget_ep_disable(dwc->eps[0]); + + err0: ++ dwc->gadget_driver = NULL; + spin_unlock_irqrestore(&dwc->lock, flags); + + return ret; +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index aca647a..79d2720 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -89,7 +89,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + xhci->quirks |= XHCI_AMD_PLL_FIX; + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) { +- xhci->quirks |= XHCI_SPURIOUS_SUCCESS; + xhci->quirks |= XHCI_EP_LIMIT_QUIRK; + xhci->limit_active_eps = 64; + xhci->quirks |= XHCI_SW_BW_CHECKING; +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index d08a804..633476e 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -463,7 +463,7 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, + + /* A ring has pending URBs if its TD list is not empty */ + if (!(ep->ep_state & EP_HAS_STREAMS)) { +- if (!(list_empty(&ep->ring->td_list))) ++ if (ep->ring && !(list_empty(&ep->ring->td_list))) + xhci_ring_ep_doorbell(xhci, slot_id, ep_index, 0); + return; + } +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 136c357..6e1c92a 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1153,9 +1153,6 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, + } + + xhci = hcd_to_xhci(hcd); +- if (xhci->xhc_state & XHCI_STATE_HALTED) +- return -ENODEV; +- + if (check_virt_dev) { + if (!udev->slot_id || !xhci->devs[udev->slot_id]) { + printk(KERN_DEBUG "xHCI %s called with unaddressed " +@@ -1171,6 +1168,9 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, + } + } + ++ if (xhci->xhc_state & XHCI_STATE_HALTED) ++ return -ENODEV; ++ + return 1; + } + +@@ -4178,6 +4178,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) + + get_quirks(dev, xhci); + ++ /* In xhci controllers which follow xhci 1.0 spec gives a spurious ++ * success event after a short transfer. This quirk will ignore such ++ * spurious event. ++ */ ++ if (xhci->hci_version > 0x96) ++ xhci->quirks |= XHCI_SPURIOUS_SUCCESS; ++ + /* Make sure the HC is halted. */ + retval = xhci_halt(xhci); + if (retval) +diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c +index dd573ab..7af163d 100644 +--- a/drivers/usb/misc/sisusbvga/sisusb.c ++++ b/drivers/usb/misc/sisusbvga/sisusb.c +@@ -3247,6 +3247,7 @@ static const struct usb_device_id sisusb_table[] = { + { USB_DEVICE(0x0711, 0x0903) }, + { USB_DEVICE(0x0711, 0x0918) }, + { USB_DEVICE(0x0711, 0x0920) }, ++ { USB_DEVICE(0x0711, 0x0950) }, + { USB_DEVICE(0x182d, 0x021c) }, + { USB_DEVICE(0x182d, 0x0269) }, + { } +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 913a178..c408ff7 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ + { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ + { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ ++ { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */ + { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ + { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ + { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ +@@ -124,6 +125,8 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ + { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ + { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ ++ { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ ++ { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ +@@ -154,6 +157,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ + { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ + { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ ++ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ + { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ + { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ + { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ +diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c +index e89ee48..5e8c736 100644 +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -925,20 +925,20 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) + status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data); + if (status < 0) { + dbg("Reading Spreg failed"); +- return -1; ++ goto err; + } + Data |= 0x80; + status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); + if (status < 0) { + dbg("writing Spreg failed"); +- return -1; ++ goto err; + } + + Data &= ~0x80; + status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); + if (status < 0) { + dbg("writing Spreg failed"); +- return -1; ++ goto err; + } + /* End of block to be checked */ + +@@ -947,7 +947,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) + &Data); + if (status < 0) { + dbg("Reading Controlreg failed"); +- return -1; ++ goto err; + } + Data |= 0x08; /* Driver done bit */ + Data |= 0x20; /* rx_disable */ +@@ -955,7 +955,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) + mos7840_port->ControlRegOffset, Data); + if (status < 0) { + dbg("writing Controlreg failed"); +- return -1; ++ goto err; + } + /* do register settings here */ + /* Set all regs to the device default values. */ +@@ -966,21 +966,21 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) + status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); + if (status < 0) { + dbg("disabling interrupts failed"); +- return -1; ++ goto err; + } + /* Set FIFO_CONTROL_REGISTER to the default value */ + Data = 0x00; + status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); + if (status < 0) { + dbg("Writing FIFO_CONTROL_REGISTER failed"); +- return -1; ++ goto err; + } + + Data = 0xcf; + status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); + if (status < 0) { + dbg("Writing FIFO_CONTROL_REGISTER failed"); +- return -1; ++ goto err; + } + + Data = 0x03; +@@ -1136,7 +1136,15 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) + dbg ("%s leave", __func__); + + return 0; +- ++err: ++ for (j = 0; j < NUM_URBS; ++j) { ++ urb = mos7840_port->write_urb_pool[j]; ++ if (!urb) ++ continue; ++ kfree(urb->transfer_buffer); ++ usb_free_urb(urb); ++ } ++ return status; + } + + /***************************************************************************** +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index b8365a7..c2103f4 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -347,17 +347,12 @@ static void option_instat_callback(struct urb *urb); + #define OLIVETTI_VENDOR_ID 0x0b3c + #define OLIVETTI_PRODUCT_OLICARD100 0xc000 + #define OLIVETTI_PRODUCT_OLICARD145 0xc003 ++#define OLIVETTI_PRODUCT_OLICARD200 0xc005 + + /* Celot products */ + #define CELOT_VENDOR_ID 0x211f + #define CELOT_PRODUCT_CT680M 0x6801 + +-/* ONDA Communication vendor id */ +-#define ONDA_VENDOR_ID 0x1ee8 +- +-/* ONDA MT825UP HSDPA 14.2 modem */ +-#define ONDA_MT825UP 0x000b +- + /* Samsung products */ + #define SAMSUNG_VENDOR_ID 0x04e8 + #define SAMSUNG_PRODUCT_GT_B3730 0x6889 +@@ -450,7 +445,8 @@ static void option_instat_callback(struct urb *urb); + + /* Hyundai Petatel Inc. products */ + #define PETATEL_VENDOR_ID 0x1ff4 +-#define PETATEL_PRODUCT_NP10T 0x600e ++#define PETATEL_PRODUCT_NP10T_600A 0x600a ++#define PETATEL_PRODUCT_NP10T_600E 0x600e + + /* TP-LINK Incorporated products */ + #define TPLINK_VENDOR_ID 0x2357 +@@ -797,6 +793,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ ++ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, +@@ -832,7 +829,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, +@@ -1278,8 +1276,8 @@ static const struct usb_device_id option_ids[] = { + + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, ++ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200) }, + { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ +- { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ + { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) }, +@@ -1351,9 +1349,12 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x00, 0x00) }, + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, +- { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, ++ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, ++ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, + { 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 */ ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */ +@@ -1361,6 +1362,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c +index 9d3b39e..42038ba 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -408,7 +408,7 @@ static int ti_startup(struct usb_serial *serial) + usb_set_serial_data(serial, tdev); + + /* determine device type */ +- if (usb_match_id(serial->interface, ti_id_table_3410)) ++ if (serial->type == &ti_1port_device) + tdev->td_is_3410 = 1; + dbg("%s - device type is %s", __func__, + tdev->td_is_3410 ? "3410" : "5052"); +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 7b8d564..8a3b531 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -657,6 +657,13 @@ UNUSUAL_DEV( 0x054c, 0x016a, 0x0000, 0x9999, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + ++/* Submitted by Ren Bigcren */ ++UNUSUAL_DEV( 0x054c, 0x02a5, 0x0100, 0x0100, ++ "Sony Corp.", ++ "MicroVault Flash Drive", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_READ_CAPACITY_16 ), ++ + /* floppy reports multiple luns */ + UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210, + "SAMSUNG", +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index dc2eed1..4a88ac3 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -360,9 +360,22 @@ void virtqueue_disable_cb(struct virtqueue *_vq) + } + EXPORT_SYMBOL_GPL(virtqueue_disable_cb); + +-bool virtqueue_enable_cb(struct virtqueue *_vq) ++/** ++ * virtqueue_enable_cb_prepare - restart callbacks after disable_cb ++ * @vq: the struct virtqueue we're talking about. ++ * ++ * This re-enables callbacks; it returns current queue state ++ * in an opaque unsigned value. This value should be later tested by ++ * virtqueue_poll, to detect a possible race between the driver checking for ++ * more work, and enabling callbacks. ++ * ++ * Caller must ensure we don't call this with other virtqueue ++ * operations at the same time (except where noted). ++ */ ++unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq) + { + struct vring_virtqueue *vq = to_vvq(_vq); ++ u16 last_used_idx; + + START_USE(vq); + +@@ -372,15 +385,45 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) + * either clear the flags bit or point the event index at the next + * entry. Always do both to keep code simple. */ + vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; +- vring_used_event(&vq->vring) = vq->last_used_idx; ++ vring_used_event(&vq->vring) = last_used_idx = vq->last_used_idx; ++ END_USE(vq); ++ return last_used_idx; ++} ++EXPORT_SYMBOL_GPL(virtqueue_enable_cb_prepare); ++ ++/** ++ * virtqueue_poll - query pending used buffers ++ * @vq: the struct virtqueue we're talking about. ++ * @last_used_idx: virtqueue state (from call to virtqueue_enable_cb_prepare). ++ * ++ * Returns "true" if there are pending used buffers in the queue. ++ * ++ * This does not need to be serialized. ++ */ ++bool virtqueue_poll(struct virtqueue *_vq, unsigned last_used_idx) ++{ ++ struct vring_virtqueue *vq = to_vvq(_vq); ++ + virtio_mb(); +- if (unlikely(more_used(vq))) { +- END_USE(vq); +- return false; +- } ++ return (u16)last_used_idx != vq->vring.used->idx; ++} ++EXPORT_SYMBOL_GPL(virtqueue_poll); + +- END_USE(vq); +- return true; ++/** ++ * virtqueue_enable_cb - restart callbacks after disable_cb. ++ * @vq: the struct virtqueue we're talking about. ++ * ++ * This re-enables callbacks; it returns "false" if there are pending ++ * buffers in the queue, to detect a possible race between the driver ++ * checking for more work, and enabling callbacks. ++ * ++ * Caller must ensure we don't call this with other virtqueue ++ * operations at the same time (except where noted). ++ */ ++bool virtqueue_enable_cb(struct virtqueue *_vq) ++{ ++ unsigned last_used_idx = virtqueue_enable_cb_prepare(_vq); ++ return !virtqueue_poll(_vq, last_used_idx); + } + EXPORT_SYMBOL_GPL(virtqueue_enable_cb); + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 8d4d53d..49eefdb 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -6560,6 +6560,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root, + int err = 0; + int ret; + int level; ++ bool root_dropped = false; + + path = btrfs_alloc_path(); + if (!path) { +@@ -6614,6 +6615,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root, + while (1) { + btrfs_tree_lock(path->nodes[level]); + btrfs_set_lock_blocking(path->nodes[level]); ++ path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; + + ret = btrfs_lookup_extent_info(trans, root, + path->nodes[level]->start, +@@ -6627,6 +6629,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root, + break; + + btrfs_tree_unlock(path->nodes[level]); ++ path->locks[level] = 0; + WARN_ON(wc->refs[level] != 1); + level--; + } +@@ -6707,11 +6710,21 @@ void btrfs_drop_snapshot(struct btrfs_root *root, + free_extent_buffer(root->commit_root); + kfree(root); + } ++ root_dropped = true; + out_free: + btrfs_end_transaction_throttle(trans, tree_root); + kfree(wc); + btrfs_free_path(path); + out: ++ /* ++ * So if we need to stop dropping the snapshot for whatever reason we ++ * need to make sure to add it back to the dead root list so that we ++ * keep trying to do the work later. This also cleans up roots if we ++ * don't have it in the radix (like when we recover after a power fail ++ * or unmount) so we don't leak memory. ++ */ ++ if (root_dropped == false) ++ btrfs_add_dead_root(root); + if (err) + btrfs_std_error(root->fs_info, err); + return; +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 9243103..9b8c131 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -4696,11 +4696,16 @@ do_more: + * blocks being freed are metadata. these blocks shouldn't + * be used until this transaction is committed + */ ++ retry: + new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS); + if (!new_entry) { +- ext4_mb_unload_buddy(&e4b); +- err = -ENOMEM; +- goto error_return; ++ /* ++ * We use a retry loop because ++ * ext4_free_blocks() is not allowed to fail. ++ */ ++ cond_resched(); ++ congestion_wait(BLK_RW_ASYNC, HZ/50); ++ goto retry; + } + new_entry->start_cluster = bit; + new_entry->group = block_group; +diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c +index f0179c3..cd8703d 100644 +--- a/fs/lockd/svclock.c ++++ b/fs/lockd/svclock.c +@@ -913,6 +913,7 @@ nlmsvc_retry_blocked(void) + unsigned long timeout = MAX_SCHEDULE_TIMEOUT; + struct nlm_block *block; + ++ spin_lock(&nlm_blocked_lock); + while (!list_empty(&nlm_blocked) && !kthread_should_stop()) { + block = list_entry(nlm_blocked.next, struct nlm_block, b_list); + +@@ -922,6 +923,7 @@ nlmsvc_retry_blocked(void) + timeout = block->b_when - jiffies; + break; + } ++ spin_unlock(&nlm_blocked_lock); + + dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", + block, block->b_when); +@@ -931,7 +933,9 @@ nlmsvc_retry_blocked(void) + retry_deferred_block(block); + } else + nlmsvc_grant_blocked(block); ++ spin_lock(&nlm_blocked_lock); + } ++ spin_unlock(&nlm_blocked_lock); + + return timeout; + } +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index 1ec1fde..561a3dc 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -782,9 +782,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, + } + *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), + flags, current_cred()); +- if (IS_ERR(*filp)) ++ if (IS_ERR(*filp)) { + host_err = PTR_ERR(*filp); +- else ++ *filp = NULL; ++ } else + host_err = ima_file_check(*filp, access); + out_nfserr: + err = nfserrno(host_err); +diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c +index 9fde1c0..9860f6b 100644 +--- a/fs/notify/fanotify/fanotify_user.c ++++ b/fs/notify/fanotify/fanotify_user.c +@@ -118,6 +118,7 @@ static int fill_event_metadata(struct fsnotify_group *group, + metadata->event_len = FAN_EVENT_METADATA_LEN; + metadata->metadata_len = FAN_EVENT_METADATA_LEN; + metadata->vers = FANOTIFY_METADATA_VERSION; ++ metadata->reserved = 0; + metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS; + metadata->pid = pid_vnr(event->tgid); + if (unlikely(event->mask & FAN_Q_OVERFLOW)) +diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h +index b5f927f..732c962 100644 +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -128,11 +128,11 @@ struct pppoe_tag { + + struct pppoe_hdr { + #if defined(__LITTLE_ENDIAN_BITFIELD) +- __u8 ver : 4; + __u8 type : 4; ++ __u8 ver : 4; + #elif defined(__BIG_ENDIAN_BITFIELD) +- __u8 type : 4; + __u8 ver : 4; ++ __u8 type : 4; + #else + #error "Please fix " + #endif +diff --git a/include/linux/virtio.h b/include/linux/virtio.h +index 4c069d8b..96c7843 100644 +--- a/include/linux/virtio.h ++++ b/include/linux/virtio.h +@@ -96,6 +96,10 @@ void virtqueue_disable_cb(struct virtqueue *vq); + + bool virtqueue_enable_cb(struct virtqueue *vq); + ++unsigned virtqueue_enable_cb_prepare(struct virtqueue *vq); ++ ++bool virtqueue_poll(struct virtqueue *vq, unsigned); ++ + bool virtqueue_enable_cb_delayed(struct virtqueue *vq); + + void *virtqueue_detach_unused_buf(struct virtqueue *vq); +diff --git a/include/net/addrconf.h b/include/net/addrconf.h +index cbc6bb0..44b1110 100644 +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -81,6 +81,9 @@ extern int ipv6_dev_get_saddr(struct net *net, + const struct in6_addr *daddr, + unsigned int srcprefs, + struct in6_addr *saddr); ++extern int __ipv6_get_lladdr(struct inet6_dev *idev, ++ struct in6_addr *addr, ++ unsigned char banned_flags); + extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *addr, + unsigned char banned_flags); +diff --git a/include/net/udp.h b/include/net/udp.h +index 3b285f4..e158330 100644 +--- a/include/net/udp.h ++++ b/include/net/udp.h +@@ -180,6 +180,7 @@ extern int udp_get_port(struct sock *sk, unsigned short snum, + extern void udp_err(struct sk_buff *, u32); + extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, + struct msghdr *msg, size_t len); ++extern int udp_push_pending_frames(struct sock *sk); + extern void udp_flush_pending_frames(struct sock *sk); + extern int udp_rcv(struct sk_buff *skb); + extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); +diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h +index 75271b9..7d28aff 100644 +--- a/include/xen/interface/io/ring.h ++++ b/include/xen/interface/io/ring.h +@@ -188,6 +188,11 @@ struct __name##_back_ring { \ + #define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \ + (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r)) + ++/* Ill-behaved frontend determination: Can there be this many requests? */ ++#define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \ ++ (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r)) ++ ++ + #define RING_PUSH_REQUESTS(_r) do { \ + wmb(); /* back sees requests /before/ updated producer index */ \ + (_r)->sring->req_prod = (_r)->req_prod_pvt; \ +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 0ec6c34..a584ad9 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -631,7 +631,15 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) + + memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN); + max_data->pid = tsk->pid; +- max_data->uid = task_uid(tsk); ++ /* ++ * If tsk == current, then use current_uid(), as that does not use ++ * RCU. The irq tracer can be called out of RCU scope. ++ */ ++ if (tsk == current) ++ max_data->uid = current_uid(); ++ else ++ max_data->uid = task_uid(tsk); ++ + max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO; + max_data->policy = tsk->policy; + max_data->rt_priority = tsk->rt_priority; +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index 0cccca8..b40d3da 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -72,6 +72,8 @@ vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) + { + struct vlan_priority_tci_mapping *mp; + ++ smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */ ++ + mp = vlan_dev_info(dev)->egress_priority_map[(skb->priority & 0xF)]; + while (mp) { + if (mp->priority == skb->priority) { +@@ -232,6 +234,11 @@ int vlan_dev_set_egress_priority(const struct net_device *dev, + np->next = mp; + np->priority = skb_prio; + np->vlan_qos = vlan_qos; ++ /* Before inserting this element in hash table, make sure all its fields ++ * are committed to memory. ++ * coupled with smp_rmb() in vlan_dev_get_egress_qos_mask() ++ */ ++ smp_wmb(); + vlan->egress_priority_map[skb_prio & 0xF] = np; + if (vlan_qos) + vlan->nr_egress_mappings++; +diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c +index de8df95..2ee3879 100644 +--- a/net/9p/trans_common.c ++++ b/net/9p/trans_common.c +@@ -24,11 +24,11 @@ + */ + void p9_release_pages(struct page **pages, int nr_pages) + { +- int i = 0; +- while (pages[i] && nr_pages--) { +- put_page(pages[i]); +- i++; +- } ++ int i; ++ ++ for (i = 0; i < nr_pages; i++) ++ if (pages[i]) ++ put_page(pages[i]); + } + EXPORT_SYMBOL(p9_release_pages); + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 5ac1811..b81500c 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -467,8 +467,9 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, + skb_set_transport_header(skb, skb->len); + mldq = (struct mld_msg *) icmp6_hdr(skb); + +- interval = ipv6_addr_any(group) ? br->multicast_last_member_interval : +- br->multicast_query_response_interval; ++ interval = ipv6_addr_any(group) ? ++ br->multicast_query_response_interval : ++ br->multicast_last_member_interval; + + mldq->mld_type = ICMPV6_MGM_QUERY; + mldq->mld_code = 0; +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 5b9709f..0ea3fd3 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -237,7 +237,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) + we must kill timers etc. and move + it to safe state. + */ +- skb_queue_purge(&n->arp_queue); ++ __skb_queue_purge(&n->arp_queue); + n->output = neigh_blackhole; + if (n->nud_state & NUD_VALID) + n->nud_state = NUD_NOARP; +@@ -291,7 +291,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl) + if (!n) + goto out_entries; + +- skb_queue_head_init(&n->arp_queue); ++ __skb_queue_head_init(&n->arp_queue); + rwlock_init(&n->lock); + seqlock_init(&n->ha_lock); + n->updated = n->used = now; +@@ -701,7 +701,9 @@ void neigh_destroy(struct neighbour *neigh) + if (neigh_del_timer(neigh)) + printk(KERN_WARNING "Impossible event.\n"); + +- skb_queue_purge(&neigh->arp_queue); ++ write_lock_bh(&neigh->lock); ++ __skb_queue_purge(&neigh->arp_queue); ++ write_unlock_bh(&neigh->lock); + + dev_put(neigh->dev); + neigh_parms_put(neigh->parms); +@@ -843,7 +845,7 @@ static void neigh_invalidate(struct neighbour *neigh) + neigh->ops->error_report(neigh, skb); + write_lock(&neigh->lock); + } +- skb_queue_purge(&neigh->arp_queue); ++ __skb_queue_purge(&neigh->arp_queue); + } + + static void neigh_probe(struct neighbour *neigh) +@@ -1176,7 +1178,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, + + write_lock_bh(&neigh->lock); + } +- skb_queue_purge(&neigh->arp_queue); ++ __skb_queue_purge(&neigh->arp_queue); + } + out: + if (update_isrouter) { +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 5a65eea..5decc93 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -766,7 +766,7 @@ send: + /* + * Push out all pending data as one UDP datagram. Socket is locked. + */ +-static int udp_push_pending_frames(struct sock *sk) ++int udp_push_pending_frames(struct sock *sk) + { + struct udp_sock *up = udp_sk(sk); + struct inet_sock *inet = inet_sk(sk); +@@ -785,6 +785,7 @@ out: + up->pending = 0; + return err; + } ++EXPORT_SYMBOL(udp_push_pending_frames); + + int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + size_t len) +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index d603caa..314bda2 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1236,6 +1236,23 @@ try_nextdev: + } + EXPORT_SYMBOL(ipv6_dev_get_saddr); + ++int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, ++ unsigned char banned_flags) ++{ ++ struct inet6_ifaddr *ifp; ++ int err = -EADDRNOTAVAIL; ++ ++ list_for_each_entry(ifp, &idev->addr_list, if_list) { ++ if (ifp->scope == IFA_LINK && ++ !(ifp->flags & banned_flags)) { ++ ipv6_addr_copy(addr, &ifp->addr); ++ err = 0; ++ break; ++ } ++ } ++ return err; ++} ++ + int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + unsigned char banned_flags) + { +@@ -1245,17 +1262,8 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + rcu_read_lock(); + idev = __in6_dev_get(dev); + if (idev) { +- struct inet6_ifaddr *ifp; +- + read_lock_bh(&idev->lock); +- list_for_each_entry(ifp, &idev->addr_list, if_list) { +- if (ifp->scope == IFA_LINK && +- !(ifp->flags & banned_flags)) { +- ipv6_addr_copy(addr, &ifp->addr); +- err = 0; +- break; +- } +- } ++ err = __ipv6_get_lladdr(idev, addr, banned_flags); + read_unlock_bh(&idev->lock); + } + rcu_read_unlock(); +@@ -2434,6 +2442,9 @@ static void init_loopback(struct net_device *dev) + if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) + continue; + ++ if (sp_ifa->rt) ++ continue; ++ + sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); + + /* Failure cases are ignored */ +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 6aadaa8..db60043 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -909,11 +909,17 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk, + const struct flowi6 *fl6) + { + struct ipv6_pinfo *np = inet6_sk(sk); +- struct rt6_info *rt = (struct rt6_info *)dst; ++ struct rt6_info *rt; + + if (!dst) + goto out; + ++ if (dst->ops->family != AF_INET6) { ++ dst_release(dst); ++ return NULL; ++ } ++ ++ rt = (struct rt6_info *)dst; + /* Yes, checking route validity in not connected + * case is not very simple. Take into account, + * that we do not support routing by source, TOS, +@@ -1178,11 +1184,12 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, + return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; + } + +-static void ip6_append_data_mtu(int *mtu, ++static void ip6_append_data_mtu(unsigned int *mtu, + int *maxfraglen, + unsigned int fragheaderlen, + struct sk_buff *skb, +- struct rt6_info *rt) ++ struct rt6_info *rt, ++ bool pmtuprobe) + { + if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { + if (skb == NULL) { +@@ -1194,7 +1201,9 @@ static void ip6_append_data_mtu(int *mtu, + * this fragment is not first, the headers + * space is regarded as data space. + */ +- *mtu = dst_mtu(rt->dst.path); ++ *mtu = min(*mtu, pmtuprobe ? ++ rt->dst.dev->mtu : ++ dst_mtu(rt->dst.path)); + } + *maxfraglen = ((*mtu - fragheaderlen) & ~7) + + fragheaderlen - sizeof(struct frag_hdr); +@@ -1211,11 +1220,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + struct ipv6_pinfo *np = inet6_sk(sk); + struct inet_cork *cork; + struct sk_buff *skb, *skb_prev = NULL; +- unsigned int maxfraglen, fragheaderlen; ++ unsigned int maxfraglen, fragheaderlen, mtu; + int exthdrlen; + int dst_exthdrlen; + int hh_len; +- int mtu; + int copy; + int err; + int offset = 0; +@@ -1378,7 +1386,9 @@ alloc_new_skb: + /* update mtu and maxfraglen if necessary */ + if (skb == NULL || skb_prev == NULL) + ip6_append_data_mtu(&mtu, &maxfraglen, +- fragheaderlen, skb, rt); ++ fragheaderlen, skb, rt, ++ np->pmtudisc == ++ IPV6_PMTUDISC_PROBE); + + skb_prev = skb; + +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index f2d74ea..c7ec4bb 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1334,8 +1334,9 @@ mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted) + return scount; + } + +-static struct sk_buff *mld_newpack(struct net_device *dev, int size) ++static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size) + { ++ struct net_device *dev = idev->dev; + struct net *net = dev_net(dev); + struct sock *sk = net->ipv6.igmp_sk; + struct sk_buff *skb; +@@ -1358,7 +1359,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) + + skb_reserve(skb, LL_RESERVED_SPACE(dev)); + +- if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { ++ if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) { + /* : + * use unspecified address as the source address + * when a valid link-local address is not available. +@@ -1461,7 +1462,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, + struct mld2_grec *pgr; + + if (!skb) +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(pmc->idev, dev->mtu); + if (!skb) + return NULL; + pgr = (struct mld2_grec *)skb_put(skb, sizeof(struct mld2_grec)); +@@ -1481,7 +1482,8 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, + static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, + int type, int gdeleted, int sdeleted) + { +- struct net_device *dev = pmc->idev->dev; ++ struct inet6_dev *idev = pmc->idev; ++ struct net_device *dev = idev->dev; + struct mld2_report *pmr; + struct mld2_grec *pgr = NULL; + struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; +@@ -1510,7 +1512,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, + AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { + if (skb) + mld_sendpack(skb); +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(idev, dev->mtu); + } + } + first = 1; +@@ -1537,7 +1539,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, + pgr->grec_nsrcs = htons(scount); + if (skb) + mld_sendpack(skb); +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(idev, dev->mtu); + first = 1; + scount = 0; + } +@@ -1592,8 +1594,8 @@ static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc) + struct sk_buff *skb = NULL; + int type; + ++ read_lock_bh(&idev->lock); + if (!pmc) { +- read_lock_bh(&idev->lock); + for (pmc=idev->mc_list; pmc; pmc=pmc->next) { + if (pmc->mca_flags & MAF_NOREPORT) + continue; +@@ -1605,7 +1607,6 @@ static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc) + skb = add_grec(skb, pmc, type, 0, 0); + spin_unlock_bh(&pmc->mca_lock); + } +- read_unlock_bh(&idev->lock); + } else { + spin_lock_bh(&pmc->mca_lock); + if (pmc->mca_sfcount[MCAST_EXCLUDE]) +@@ -1615,6 +1616,7 @@ static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc) + skb = add_grec(skb, pmc, type, 0, 0); + spin_unlock_bh(&pmc->mca_lock); + } ++ read_unlock_bh(&idev->lock); + if (skb) + mld_sendpack(skb); + } +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 20f0812..f9e496b 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -893,11 +893,16 @@ static int udp_v6_push_pending_frames(struct sock *sk) + struct udphdr *uh; + struct udp_sock *up = udp_sk(sk); + struct inet_sock *inet = inet_sk(sk); +- struct flowi6 *fl6 = &inet->cork.fl.u.ip6; ++ struct flowi6 *fl6; + int err = 0; + int is_udplite = IS_UDPLITE(sk); + __wsum csum = 0; + ++ if (up->pending == AF_INET) ++ return udp_push_pending_frames(sk); ++ ++ fl6 = &inet->cork.fl.u.ip6; ++ + /* Grab the skbuff where UDP header space exists. */ + if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) + goto out; +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 1e733e9..6fefdfc 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -1705,6 +1705,7 @@ static int key_notify_sa_flush(const struct km_event *c) + hdr->sadb_msg_version = PF_KEY_V2; + hdr->sadb_msg_errno = (uint8_t) 0; + hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); ++ hdr->sadb_msg_reserved = 0; + + pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + +@@ -2686,6 +2687,7 @@ static int key_notify_policy_flush(const struct km_event *c) + hdr->sadb_msg_version = PF_KEY_V2; + hdr->sadb_msg_errno = (uint8_t) 0; + hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); ++ hdr->sadb_msg_reserved = 0; + pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + return 0; + +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 74410e6..e579006 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1778,7 +1778,8 @@ static const struct proto_ops pppol2tp_ops = { + + static const struct pppox_proto pppol2tp_proto = { + .create = pppol2tp_create, +- .ioctl = pppol2tp_ioctl ++ .ioctl = pppol2tp_ioctl, ++ .owner = THIS_MODULE, + }; + + #ifdef CONFIG_L2TP_V3 +diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c +index 3e16c6a..dc24ba9 100644 +--- a/net/x25/af_x25.c ++++ b/net/x25/af_x25.c +@@ -1586,11 +1586,11 @@ out_cud_release: + case SIOCX25CALLACCPTAPPRV: { + rc = -EINVAL; + lock_sock(sk); +- if (sk->sk_state != TCP_CLOSE) +- break; +- clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); ++ if (sk->sk_state == TCP_CLOSE) { ++ clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); ++ rc = 0; ++ } + release_sock(sk); +- rc = 0; + break; + } + +@@ -1598,14 +1598,15 @@ out_cud_release: + rc = -EINVAL; + lock_sock(sk); + if (sk->sk_state != TCP_ESTABLISHED) +- break; ++ goto out_sendcallaccpt_release; + /* must call accptapprv above */ + if (test_bit(X25_ACCPT_APPRV_FLAG, &x25->flags)) +- break; ++ goto out_sendcallaccpt_release; + x25_write_internal(sk, X25_CALL_ACCEPTED); + x25->state = X25_STATE_3; +- release_sock(sk); + rc = 0; ++out_sendcallaccpt_release: ++ release_sock(sk); + break; + } + +diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c +index 76e0d56..823359e 100644 +--- a/sound/arm/pxa2xx-pcm-lib.c ++++ b/sound/arm/pxa2xx-pcm-lib.c +@@ -166,7 +166,9 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) + } else { + printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n", + rtd->params->name, dma_ch, dcsr); ++ snd_pcm_stream_lock(substream); + snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(substream); + } + } + EXPORT_SYMBOL(pxa2xx_pcm_dma_irq); +diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c +index f4b9e2b..fbf0bcd 100644 +--- a/sound/pci/asihpi/asihpi.c ++++ b/sound/pci/asihpi/asihpi.c +@@ -768,7 +768,10 @@ static void snd_card_asihpi_timer_function(unsigned long data) + s->number); + ds->drained_count++; + if (ds->drained_count > 2) { ++ unsigned long flags; ++ snd_pcm_stream_lock_irqsave(s, flags); + snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(s, flags); + continue; + } + } else { +diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c +index 15e4e5e..6faa173 100644 +--- a/sound/pci/atiixp.c ++++ b/sound/pci/atiixp.c +@@ -688,7 +688,9 @@ static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma) + if (! dma->substream || ! dma->running) + return; + snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type); ++ snd_pcm_stream_lock(dma->substream); + snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(dma->substream); + } + + /* +diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c +index 57bf8f4..d752120 100644 +--- a/sound/pci/atiixp_modem.c ++++ b/sound/pci/atiixp_modem.c +@@ -638,7 +638,9 @@ static void snd_atiixp_xrun_dma(struct atiixp_modem *chip, + if (! dma->substream || ! dma->running) + return; + snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type); ++ snd_pcm_stream_lock(dma->substream); + snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(dma->substream); + } + + /* +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index d148a2b..55d9b30 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -1897,6 +1897,8 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { + { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, + { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, + { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, ++{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi }, ++{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_generic_hdmi }, + { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, + { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, + { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, +@@ -1943,6 +1945,8 @@ MODULE_ALIAS("snd-hda-codec-id:10de0041"); + MODULE_ALIAS("snd-hda-codec-id:10de0042"); + MODULE_ALIAS("snd-hda-codec-id:10de0043"); + MODULE_ALIAS("snd-hda-codec-id:10de0044"); ++MODULE_ALIAS("snd-hda-codec-id:10de0051"); ++MODULE_ALIAS("snd-hda-codec-id:10de0060"); + MODULE_ALIAS("snd-hda-codec-id:10de0067"); + MODULE_ALIAS("snd-hda-codec-id:10de8001"); + MODULE_ALIAS("snd-hda-codec-id:17e80047"); +diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c +index b7cf246..d58c575 100644 +--- a/sound/soc/codecs/max98088.c ++++ b/sound/soc/codecs/max98088.c +@@ -1595,7 +1595,7 @@ static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute) + + static void max98088_sync_cache(struct snd_soc_codec *codec) + { +- u16 *reg_cache = codec->reg_cache; ++ u8 *reg_cache = codec->reg_cache; + int i; + + if (!codec->cache_sync) +diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c +index bbcf921..b5d4a97 100644 +--- a/sound/soc/codecs/sgtl5000.c ++++ b/sound/soc/codecs/sgtl5000.c +@@ -38,7 +38,7 @@ + static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = { + [SGTL5000_CHIP_CLK_CTRL] = 0x0008, + [SGTL5000_CHIP_I2S_CTRL] = 0x0010, +- [SGTL5000_CHIP_SSS_CTRL] = 0x0008, ++ [SGTL5000_CHIP_SSS_CTRL] = 0x0010, + [SGTL5000_CHIP_DAC_VOL] = 0x3c3c, + [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f, + [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818, +diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h +index 8a9f435..d3a68bb 100644 +--- a/sound/soc/codecs/sgtl5000.h ++++ b/sound/soc/codecs/sgtl5000.h +@@ -347,7 +347,7 @@ + #define SGTL5000_PLL_INT_DIV_MASK 0xf800 + #define SGTL5000_PLL_INT_DIV_SHIFT 11 + #define SGTL5000_PLL_INT_DIV_WIDTH 5 +-#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700 ++#define SGTL5000_PLL_FRAC_DIV_MASK 0x07ff + #define SGTL5000_PLL_FRAC_DIV_SHIFT 0 + #define SGTL5000_PLL_FRAC_DIV_WIDTH 11 + +diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c +index 55efc2b..75babae 100644 +--- a/sound/soc/s6000/s6000-pcm.c ++++ b/sound/soc/s6000/s6000-pcm.c +@@ -128,7 +128,9 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data) + substream->runtime && + snd_pcm_running(substream)) { + dev_dbg(pcm->dev, "xrun\n"); ++ snd_pcm_stream_lock(substream); + snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(substream); + ret = IRQ_HANDLED; + } + +diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c +index d144cdb..888a7c7 100644 +--- a/sound/usb/6fire/pcm.c ++++ b/sound/usb/6fire/pcm.c +@@ -541,7 +541,7 @@ static snd_pcm_uframes_t usb6fire_pcm_pointer( + snd_pcm_uframes_t ret; + + if (rt->panic || !sub) +- return SNDRV_PCM_STATE_XRUN; ++ return SNDRV_PCM_POS_XRUN; + + spin_lock_irqsave(&sub->lock, flags); + ret = sub->dma_off; +@@ -640,17 +640,25 @@ int __devinit usb6fire_pcm_init(struct sfire_chip *chip) + void usb6fire_pcm_abort(struct sfire_chip *chip) + { + struct pcm_runtime *rt = chip->pcm; ++ unsigned long flags; + int i; + + if (rt) { + rt->panic = true; + +- if (rt->playback.instance) ++ if (rt->playback.instance) { ++ snd_pcm_stream_lock_irqsave(rt->playback.instance, flags); + snd_pcm_stop(rt->playback.instance, + SNDRV_PCM_STATE_XRUN); +- if (rt->capture.instance) ++ snd_pcm_stream_unlock_irqrestore(rt->playback.instance, flags); ++ } ++ ++ if (rt->capture.instance) { ++ snd_pcm_stream_lock_irqsave(rt->capture.instance, flags); + snd_pcm_stop(rt->capture.instance, + SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(rt->capture.instance, flags); ++ } + + for (i = 0; i < PCM_N_URBS; i++) { + usb_poison_urb(&rt->in_urbs[i].instance); +diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c +index c0609c2..84052cf 100644 +--- a/sound/usb/misc/ua101.c ++++ b/sound/usb/misc/ua101.c +@@ -613,14 +613,24 @@ static int start_usb_playback(struct ua101 *ua) + + static void abort_alsa_capture(struct ua101 *ua) + { +- if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) ++ unsigned long flags; ++ ++ if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) { ++ snd_pcm_stream_lock_irqsave(ua->capture.substream, flags); + snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(ua->capture.substream, flags); ++ } + } + + static void abort_alsa_playback(struct ua101 *ua) + { +- if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) ++ unsigned long flags; ++ ++ if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) { ++ snd_pcm_stream_lock_irqsave(ua->playback.substream, flags); + snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(ua->playback.substream, flags); ++ } + } + + static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream, +diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c +index 6ffb371..d5724d8 100644 +--- a/sound/usb/usx2y/usbusx2yaudio.c ++++ b/sound/usb/usx2y/usbusx2yaudio.c +@@ -273,7 +273,11 @@ static void usX2Y_clients_stop(struct usX2Ydev *usX2Y) + struct snd_usX2Y_substream *subs = usX2Y->subs[s]; + if (subs) { + if (atomic_read(&subs->state) >= state_PRERUNNING) { ++ unsigned long flags; ++ ++ snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags); + snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags); + } + for (u = 0; u < NRURBS; u++) { + struct urb *urb = subs->urb[u]; -- cgit v1.2.3-65-gdbad