From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id DCDB41395E2 for ; Fri, 11 Nov 2016 00:58:25 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 01797E084C; Fri, 11 Nov 2016 00:58:25 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id B9271E084C for ; Fri, 11 Nov 2016 00:58:24 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 390D834165E for ; Fri, 11 Nov 2016 00:58:23 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 1831924B0 for ; Fri, 11 Nov 2016 00:58:21 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1478825893.552490bf4090bcf87c75d5faba3a9f7351760986.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:3.12 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1066_linux-3.12.67.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 552490bf4090bcf87c75d5faba3a9f7351760986 X-VCS-Branch: 3.12 Date: Fri, 11 Nov 2016 00:58:21 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 0a65d37c-2df7-4ec2-9c8b-af4a354a1ea6 X-Archives-Hash: c22ceb690345adc326187f1e5be4b3c8 commit: 552490bf4090bcf87c75d5faba3a9f7351760986 Author: Mike Pagano gentoo org> AuthorDate: Fri Nov 11 00:58:13 2016 +0000 Commit: Mike Pagano gentoo org> CommitDate: Fri Nov 11 00:58:13 2016 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=552490bf Linux patch 3.12.67 0000_README | 4 + 1066_linux-3.12.67.patch | 2912 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2916 insertions(+) diff --git a/0000_README b/0000_README index 930d266..1f30ddb 100644 --- a/0000_README +++ b/0000_README @@ -306,6 +306,10 @@ Patch: 1065_linux-3.12.66.patch From: http://www.kernel.org Desc: Linux 3.12.66 +Patch: 1066_linux-3.12.67.patch +From: http://www.kernel.org +Desc: Linux 3.12.67 + 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/1066_linux-3.12.67.patch b/1066_linux-3.12.67.patch new file mode 100644 index 0000000..238465a --- /dev/null +++ b/1066_linux-3.12.67.patch @@ -0,0 +1,2912 @@ +diff --git a/Makefile b/Makefile +index eb81ece69d00..32dbd8513eee 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 12 +-SUBLEVEL = 66 ++SUBLEVEL = 67 + EXTRAVERSION = + NAME = One Giant Leap for Frogkind + +diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c +index a0c63fc48457..ca6bcd132a14 100644 +--- a/arch/arc/kernel/signal.c ++++ b/arch/arc/kernel/signal.c +@@ -80,13 +80,14 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) + int err; + + err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); +- if (!err) +- set_current_blocked(&set); +- + err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs.scratch), + sizeof(sf->uc.uc_mcontext.regs.scratch)); ++ if (err) ++ return err; + +- return err; ++ set_current_blocked(&set); ++ ++ return 0; + } + + static inline int is_do_ss_needed(unsigned int magic) +diff --git a/arch/metag/include/asm/atomic.h b/arch/metag/include/asm/atomic.h +index 307ecd2bd9a1..d7d6b9e53e44 100644 +--- a/arch/metag/include/asm/atomic.h ++++ b/arch/metag/include/asm/atomic.h +@@ -38,6 +38,7 @@ + #define atomic_dec(v) atomic_sub(1, (v)) + + #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) ++#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v) + + #define smp_mb__before_atomic_dec() barrier() + #define smp_mb__after_atomic_dec() barrier() +@@ -46,8 +47,6 @@ + + #endif + +-#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v) +- + #include + + #endif /* __ASM_METAG_ATOMIC_H */ +diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h +index 5e6cd0947393..a288de2199d8 100644 +--- a/arch/mips/include/asm/ptrace.h ++++ b/arch/mips/include/asm/ptrace.h +@@ -73,7 +73,7 @@ static inline int is_syscall_success(struct pt_regs *regs) + + static inline long regs_return_value(struct pt_regs *regs) + { +- if (is_syscall_success(regs)) ++ if (is_syscall_success(regs) || !user_mode(regs)) + return regs->regs[2]; + else + return -regs->regs[2]; +diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c +index d3a132c9127c..33d998fda24e 100644 +--- a/arch/powerpc/kernel/eeh_driver.c ++++ b/arch/powerpc/kernel/eeh_driver.c +@@ -697,6 +697,14 @@ static void eeh_handle_special_event(void) + + /* Notify all devices to be down */ + bus = eeh_pe_bus_get(phb_pe); ++ if (!bus) { ++ pr_err("%s: Cannot find PCI bus for " ++ "PHB#%d-PE#%x\n", ++ __func__, ++ pe->phb->global_number, ++ pe->addr); ++ break; ++ } + eeh_pe_dev_traverse(pe, + eeh_report_failure, NULL); + pcibios_remove_pci_devices(bus); +diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c +index 8213ee1eb05a..1def48da21b2 100644 +--- a/arch/powerpc/kernel/nvram_64.c ++++ b/arch/powerpc/kernel/nvram_64.c +@@ -288,7 +288,7 @@ int __init nvram_remove_partition(const char *name, int sig, + + /* Make partition a free partition */ + part->header.signature = NVRAM_SIG_FREE; +- strncpy(part->header.name, "wwwwwwwwwwww", 12); ++ memset(part->header.name, 'w', 12); + part->header.checksum = nvram_checksum(&part->header); + rc = nvram_write_header(part); + if (rc <= 0) { +@@ -306,8 +306,8 @@ int __init nvram_remove_partition(const char *name, int sig, + } + if (prev) { + prev->header.length += part->header.length; +- prev->header.checksum = nvram_checksum(&part->header); +- rc = nvram_write_header(part); ++ prev->header.checksum = nvram_checksum(&prev->header); ++ rc = nvram_write_header(prev); + if (rc <= 0) { + printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc); + return rc; +diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S +index 79796de11737..3263ee23170d 100644 +--- a/arch/powerpc/kernel/vdso64/datapage.S ++++ b/arch/powerpc/kernel/vdso64/datapage.S +@@ -57,7 +57,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) + bl V_LOCAL_FUNC(__get_datapage) + mtlr r12 + addi r3,r3,CFG_SYSCALL_MAP64 +- cmpli cr0,r4,0 ++ cmpldi cr0,r4,0 + crclr cr0*4+so + beqlr + li r0,__NR_syscalls +diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S +index a76b4af37ef2..382021324883 100644 +--- a/arch/powerpc/kernel/vdso64/gettimeofday.S ++++ b/arch/powerpc/kernel/vdso64/gettimeofday.S +@@ -145,7 +145,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) + bne cr0,99f + + li r3,0 +- cmpli cr0,r4,0 ++ cmpldi cr0,r4,0 + crclr cr0*4+so + beqlr + lis r5,CLOCK_REALTIME_RES@h +diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S +index d73a59014900..be94e1be4ae3 100644 +--- a/arch/powerpc/lib/copyuser_64.S ++++ b/arch/powerpc/lib/copyuser_64.S +@@ -336,6 +336,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) + addi r3,r3,8 + 171: + 177: ++179: + addi r3,r3,8 + 370: + 372: +@@ -350,7 +351,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) + 173: + 174: + 175: +-179: + 181: + 184: + 186: +diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c +index b91083370bc6..605a2f07618e 100644 +--- a/arch/powerpc/platforms/powernv/eeh-ioda.c ++++ b/arch/powerpc/platforms/powernv/eeh-ioda.c +@@ -493,6 +493,11 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) + ret = ioda_eeh_phb_reset(hose, option); + } else { + bus = eeh_pe_bus_get(pe); ++ if (!bus) { ++ pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n", ++ __func__, pe->phb->global_number, pe->addr); ++ return -EIO; ++ } + if (pci_is_root_bus(bus) || + pci_is_root_bus(bus->parent)) + ret = ioda_eeh_root_reset(hose, option); +diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c +index 52746b3caf08..ec78cdb13288 100644 +--- a/arch/powerpc/platforms/powernv/pci.c ++++ b/arch/powerpc/platforms/powernv/pci.c +@@ -179,8 +179,8 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pnv_phb *phb) + pr_info(" dma1ErrorLog1 = 0x%016llx\n", data->dma1ErrorLog1); + + for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { +- if ((data->pestA[i] >> 63) == 0 && +- (data->pestB[i] >> 63) == 0) ++ if ((be64_to_cpu(data->pestA[i]) >> 63) == 0 && ++ (be64_to_cpu(data->pestB[i]) >> 63) == 0) + continue; + pr_info(" PE[%3d] PESTA = 0x%016llx\n", i, data->pestA[i]); + pr_info(" PESTB = 0x%016llx\n", data->pestB[i]); +diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c +index 691a479f7d97..73f2c2f35f6d 100644 +--- a/arch/powerpc/platforms/pseries/lpar.c ++++ b/arch/powerpc/platforms/pseries/lpar.c +@@ -373,7 +373,7 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot, + unsigned long *vpn, int count, + int psize, int ssize) + { +- unsigned long param[8]; ++ unsigned long param[PLPAR_HCALL9_BUFSIZE]; + int i = 0, pix = 0, rc; + unsigned long flags = 0; + int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); +@@ -490,7 +490,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) + unsigned long flags = 0; + struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); +- unsigned long param[9]; ++ unsigned long param[PLPAR_HCALL9_BUFSIZE]; + unsigned long hash, index, shift, hidx, slot; + real_pte_t pte; + int psize, ssize; +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h +index 01635e4e187a..5838fa911aa0 100644 +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -383,11 +383,7 @@ do { \ + #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ + asm volatile("1: mov"itype" %1,%"rtype"0\n" \ + "2:\n" \ +- ".section .fixup,\"ax\"\n" \ +- "3:xor"itype" %"rtype"0,%"rtype"0\n" \ +- " jmp 2b\n" \ +- ".previous\n" \ +- _ASM_EXTABLE_EX(1b, 3b) \ ++ _ASM_EXTABLE_EX(1b, 2b) \ + : ltype(x) : "m" (__m(addr))) + + #define __put_user_nocheck(x, ptr, size) \ +diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h +index 7d01b8c56c00..1da6bb44f94f 100644 +--- a/arch/x86/um/asm/barrier.h ++++ b/arch/x86/um/asm/barrier.h +@@ -51,11 +51,7 @@ + + #else /* CONFIG_SMP */ + +-#define smp_mb() barrier() +-#define smp_rmb() barrier() +-#define smp_wmb() barrier() +-#define smp_read_barrier_depends() do { } while (0) +-#define set_mb(var, value) do { var = value; barrier(); } while (0) ++#include + + #endif /* CONFIG_SMP */ + +diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c +index b19c9f391761..cf3c8dc4acce 100644 +--- a/block/cfq-iosched.c ++++ b/block/cfq-iosched.c +@@ -2812,7 +2812,6 @@ static struct request *cfq_check_fifo(struct cfq_queue *cfqq) + if (time_before(jiffies, rq_fifo_time(rq))) + rq = NULL; + +- cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq); + return rq; + } + +@@ -3186,6 +3185,9 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq) + { + unsigned int max_dispatch; + ++ if (cfq_cfqq_must_dispatch(cfqq)) ++ return true; ++ + /* + * Drain async requests before we start sync IO + */ +@@ -3277,15 +3279,20 @@ static bool cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq) + + BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); + ++ rq = cfq_check_fifo(cfqq); ++ if (rq) ++ cfq_mark_cfqq_must_dispatch(cfqq); ++ + if (!cfq_may_dispatch(cfqd, cfqq)) + return false; + + /* + * follow expired path, else get first next available + */ +- rq = cfq_check_fifo(cfqq); + if (!rq) + rq = cfqq->next_rq; ++ else ++ cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq); + + /* + * insert request into driver dispatch list +@@ -3794,7 +3801,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, + * if the new request is sync, but the currently running queue is + * not, let the sync request have priority. + */ +- if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) ++ if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq) && !cfq_cfqq_must_dispatch(cfqq)) + return true; + + if (new_cfqq->cfqg != cfqq->cfqg) +diff --git a/crypto/gcm.c b/crypto/gcm.c +index d2a0f7371cf0..49b6fb20cceb 100644 +--- a/crypto/gcm.c ++++ b/crypto/gcm.c +@@ -109,7 +109,7 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key, + struct crypto_ablkcipher *ctr = ctx->ctr; + struct { + be128 hash; +- u8 iv[8]; ++ u8 iv[16]; + + struct crypto_gcm_setkey_result result; + +diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c +index d9c1fa0e3648..b950668ddd67 100644 +--- a/drivers/char/hw_random/omap-rng.c ++++ b/drivers/char/hw_random/omap-rng.c +@@ -387,7 +387,7 @@ static int omap_rng_probe(struct platform_device *pdev) + + pm_runtime_enable(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); +- if (ret) { ++ if (ret < 0) { + dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret); + pm_runtime_put_noidle(&pdev->dev); + goto err_ioremap; +@@ -447,7 +447,7 @@ static int omap_rng_resume(struct device *dev) + int ret; + + ret = pm_runtime_get_sync(dev); +- if (ret) { ++ if (ret < 0) { + dev_err(dev, "Failed to runtime_get device: %d\n", ret); + pm_runtime_put_noidle(dev); + return ret; +diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c +index 2aa3ca215bd6..d5376aa1c5e1 100644 +--- a/drivers/gpio/gpio-mpc8xxx.c ++++ b/drivers/gpio/gpio-mpc8xxx.c +@@ -295,7 +295,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq, + mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data; + + irq_set_chip_data(virq, h->host_data); +- irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); ++ irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_edge_irq); + + return 0; + } +diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c +index 729ad831886f..d52ab40369b6 100644 +--- a/drivers/gpu/drm/radeon/r600_dpm.c ++++ b/drivers/gpu/drm/radeon/r600_dpm.c +@@ -155,19 +155,20 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev) + struct drm_device *dev = rdev->ddev; + struct drm_crtc *crtc; + struct radeon_crtc *radeon_crtc; +- u32 line_time_us, vblank_lines; ++ u32 vblank_in_pixels; + u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ + + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + radeon_crtc = to_radeon_crtc(crtc); + if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { +- line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / +- radeon_crtc->hw_mode.clock; +- vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - +- radeon_crtc->hw_mode.crtc_vdisplay + +- (radeon_crtc->v_border * 2); +- vblank_time_us = vblank_lines * line_time_us; ++ vblank_in_pixels = ++ radeon_crtc->hw_mode.crtc_htotal * ++ (radeon_crtc->hw_mode.crtc_vblank_end - ++ radeon_crtc->hw_mode.crtc_vdisplay + ++ (radeon_crtc->v_border * 2)); ++ ++ vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock; + break; + } + } +diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +index b05ce8ac9bf4..dbfd435485fe 100644 +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -570,8 +570,9 @@ bool radeon_card_posted(struct radeon_device *rdev) + { + uint32_t reg; + +- /* for pass through, always force asic_init */ +- if (radeon_device_is_virtual()) ++ /* for pass through, always force asic_init for CI */ ++ if (rdev->family >= CHIP_BONAIRE && ++ radeon_device_is_virtual()) + return false; + + /* required for EFI mode on macbook2,1 which uses an r5xx asic */ +diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c +index db9c7d26ed16..c1281fc39040 100644 +--- a/drivers/gpu/drm/radeon/si_dpm.c ++++ b/drivers/gpu/drm/radeon/si_dpm.c +@@ -3968,7 +3968,7 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev, + &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) { + si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table); + +- table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] = ++ table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] = + cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low); + + si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay, +diff --git a/drivers/gpu/drm/radeon/sislands_smc.h b/drivers/gpu/drm/radeon/sislands_smc.h +index 5578e9837026..0c3f65dfa743 100644 +--- a/drivers/gpu/drm/radeon/sislands_smc.h ++++ b/drivers/gpu/drm/radeon/sislands_smc.h +@@ -194,6 +194,7 @@ typedef struct SISLANDS_SMC_SWSTATE SISLANDS_SMC_SWSTATE; + #define SISLANDS_SMC_VOLTAGEMASK_VDDC 0 + #define SISLANDS_SMC_VOLTAGEMASK_MVDD 1 + #define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2 ++#define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3 + #define SISLANDS_SMC_VOLTAGEMASK_MAX 4 + + struct SISLANDS_SMC_VOLTAGEMASKTABLE +diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c +index b5de139920e3..0a36be44dc72 100644 +--- a/drivers/i2c/i2c-core.c ++++ b/drivers/i2c/i2c-core.c +@@ -1522,6 +1522,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) + /* add the driver to the list of i2c drivers in the driver core */ + driver->driver.owner = owner; + driver->driver.bus = &i2c_bus_type; ++ INIT_LIST_HEAD(&driver->clients); + + /* When registration returns, the driver core + * will have called probe() for all matching-but-unbound devices. +@@ -1540,7 +1541,6 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) + + pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); + +- INIT_LIST_HEAD(&driver->clients); + /* Walk the adapters that are already present */ + i2c_for_each_dev(driver, __process_new_driver); + +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index cbe20b0099a2..a25fc40522f3 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1389,10 +1389,10 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { + }, + }, + { +- /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */ ++ /* Fujitsu H760 does not work with crc_enabled == 0 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"), + }, + }, + { +@@ -1402,6 +1402,27 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"), + }, + }, ++ { ++ /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"), ++ }, ++ }, ++ { ++ /* Fujitsu LIFEBOOK E556 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E556"), ++ }, ++ }, ++ { ++ /* Fujitsu H760 also has a middle button */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"), ++ }, ++ }, + #endif + { } + }; +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 78ab0a131cf1..8c82835a4749 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -2428,6 +2428,7 @@ EXPORT_SYMBOL_GPL(dm_device_name); + + static void __dm_destroy(struct mapped_device *md, bool wait) + { ++ struct request_queue *q = md->queue; + struct dm_table *map; + int srcu_idx; + +@@ -2438,6 +2439,10 @@ static void __dm_destroy(struct mapped_device *md, bool wait) + set_bit(DMF_FREEING, &md->flags); + spin_unlock(&_minor_lock); + ++ spin_lock_irq(q->queue_lock); ++ queue_flag_set(QUEUE_FLAG_DYING, q); ++ spin_unlock_irq(q->queue_lock); ++ + /* + * Take suspend_lock so that presuspend and postsuspend methods + * do not race with internal suspend. +diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c +index 2c7217fb1415..4a1346fb383e 100644 +--- a/drivers/media/dvb-frontends/mb86a20s.c ++++ b/drivers/media/dvb-frontends/mb86a20s.c +@@ -75,25 +75,27 @@ static struct regdata mb86a20s_init1[] = { + }; + + static struct regdata mb86a20s_init2[] = { +- { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 }, ++ { 0x50, 0xd1 }, { 0x51, 0x22 }, ++ { 0x39, 0x01 }, ++ { 0x71, 0x00 }, + { 0x3b, 0x21 }, +- { 0x3c, 0x38 }, ++ { 0x3c, 0x3a }, + { 0x01, 0x0d }, +- { 0x04, 0x08 }, { 0x05, 0x03 }, ++ { 0x04, 0x08 }, { 0x05, 0x05 }, + { 0x04, 0x0e }, { 0x05, 0x00 }, +- { 0x04, 0x0f }, { 0x05, 0x37 }, +- { 0x04, 0x0b }, { 0x05, 0x78 }, ++ { 0x04, 0x0f }, { 0x05, 0x14 }, ++ { 0x04, 0x0b }, { 0x05, 0x8c }, + { 0x04, 0x00 }, { 0x05, 0x00 }, +- { 0x04, 0x01 }, { 0x05, 0x1e }, +- { 0x04, 0x02 }, { 0x05, 0x07 }, +- { 0x04, 0x03 }, { 0x05, 0xd0 }, ++ { 0x04, 0x01 }, { 0x05, 0x07 }, ++ { 0x04, 0x02 }, { 0x05, 0x0f }, ++ { 0x04, 0x03 }, { 0x05, 0xa0 }, + { 0x04, 0x09 }, { 0x05, 0x00 }, + { 0x04, 0x0a }, { 0x05, 0xff }, +- { 0x04, 0x27 }, { 0x05, 0x00 }, ++ { 0x04, 0x27 }, { 0x05, 0x64 }, + { 0x04, 0x28 }, { 0x05, 0x00 }, +- { 0x04, 0x1e }, { 0x05, 0x00 }, +- { 0x04, 0x29 }, { 0x05, 0x64 }, +- { 0x04, 0x32 }, { 0x05, 0x02 }, ++ { 0x04, 0x1e }, { 0x05, 0xff }, ++ { 0x04, 0x29 }, { 0x05, 0x0a }, ++ { 0x04, 0x32 }, { 0x05, 0x0a }, + { 0x04, 0x14 }, { 0x05, 0x02 }, + { 0x04, 0x04 }, { 0x05, 0x00 }, + { 0x04, 0x05 }, { 0x05, 0x22 }, +@@ -101,8 +103,6 @@ static struct regdata mb86a20s_init2[] = { + { 0x04, 0x07 }, { 0x05, 0xd8 }, + { 0x04, 0x12 }, { 0x05, 0x00 }, + { 0x04, 0x13 }, { 0x05, 0xff }, +- { 0x04, 0x15 }, { 0x05, 0x4e }, +- { 0x04, 0x16 }, { 0x05, 0x20 }, + + /* + * On this demod, when the bit count reaches the count below, +@@ -156,42 +156,36 @@ static struct regdata mb86a20s_init2[] = { + { 0x50, 0x51 }, { 0x51, 0x04 }, /* MER symbol 4 */ + { 0x45, 0x04 }, /* CN symbol 4 */ + { 0x48, 0x04 }, /* CN manual mode */ +- ++ { 0x50, 0xd5 }, { 0x51, 0x01 }, + { 0x50, 0xd6 }, { 0x51, 0x1f }, + { 0x50, 0xd2 }, { 0x51, 0x03 }, +- { 0x50, 0xd7 }, { 0x51, 0xbf }, +- { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xff }, +- { 0x28, 0x46 }, { 0x29, 0x00 }, { 0x2a, 0x1a }, { 0x2b, 0x0c }, +- +- { 0x04, 0x40 }, { 0x05, 0x00 }, +- { 0x28, 0x00 }, { 0x2b, 0x08 }, +- { 0x28, 0x05 }, { 0x2b, 0x00 }, ++ { 0x50, 0xd7 }, { 0x51, 0x3f }, + { 0x1c, 0x01 }, +- { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x1f }, +- { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x18 }, +- { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x12 }, +- { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x30 }, +- { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x37 }, +- { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, +- { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x09 }, +- { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x06 }, +- { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7b }, +- { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x76 }, +- { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7d }, +- { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x08 }, +- { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0b }, +- { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, +- { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf2 }, +- { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf3 }, +- { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x05 }, +- { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, +- { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, +- { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xef }, +- { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xd8 }, +- { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xf1 }, +- { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x3d }, +- { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x94 }, +- { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xba }, ++ { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 }, ++ { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d }, ++ { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, ++ { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 }, ++ { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 }, ++ { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 }, ++ { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, ++ { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 }, ++ { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e }, ++ { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e }, ++ { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 }, ++ { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, ++ { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 }, ++ { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 }, ++ { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe }, ++ { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 }, ++ { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee }, ++ { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 }, ++ { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f }, ++ { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 }, ++ { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 }, ++ { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a }, ++ { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc }, ++ { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba }, ++ { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 }, + { 0x50, 0x1e }, { 0x51, 0x5d }, + { 0x50, 0x22 }, { 0x51, 0x00 }, + { 0x50, 0x23 }, { 0x51, 0xc8 }, +@@ -200,9 +194,7 @@ static struct regdata mb86a20s_init2[] = { + { 0x50, 0x26 }, { 0x51, 0x00 }, + { 0x50, 0x27 }, { 0x51, 0xc3 }, + { 0x50, 0x39 }, { 0x51, 0x02 }, +- { 0xec, 0x0f }, +- { 0xeb, 0x1f }, +- { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, ++ { 0x50, 0xd5 }, { 0x51, 0x01 }, + { 0xd0, 0x00 }, + }; + +@@ -321,7 +313,11 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status) + if (val >= 7) + *status |= FE_HAS_SYNC; + +- if (val >= 8) /* Maybe 9? */ ++ /* ++ * Actually, on state S8, it starts receiving TS, but the TS ++ * output is only on normal state after the transition to S9. ++ */ ++ if (val >= 9) + *status |= FE_HAS_LOCK; + + dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n", +@@ -2080,6 +2076,11 @@ static void mb86a20s_release(struct dvb_frontend *fe) + kfree(state); + } + ++static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++ + static struct dvb_frontend_ops mb86a20s_ops; + + struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, +@@ -2153,6 +2154,7 @@ static struct dvb_frontend_ops mb86a20s_ops = { + .read_status = mb86a20s_read_status_and_stats, + .read_signal_strength = mb86a20s_read_signal_strength_from_cache, + .tune = mb86a20s_tune, ++ .get_frontend_algo = mb86a20s_get_frontend_algo, + }; + + MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware"); +diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c +index 89de00bf4f82..bd45858cc927 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c ++++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c +@@ -1260,7 +1260,10 @@ int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev, + dev->board.agc_analog_digital_select_gpio, + analog_or_digital); + +- return status; ++ if (status < 0) ++ return status; ++ ++ return 0; + } + + int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3) +diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c +index a384f80f595e..0c106f34ab66 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-cards.c ++++ b/drivers/media/usb/cx231xx/cx231xx-cards.c +@@ -489,7 +489,7 @@ struct cx231xx_board cx231xx_boards[] = { + .output_mode = OUT_MODE_VIP11, + .demod_xfer_mode = 0, + .ctl_pin_status_mask = 0xFFFFFFC4, +- .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */ ++ .agc_analog_digital_select_gpio = 0x1c, + .tuner_sif_gpio = -1, + .tuner_scl_gpio = -1, + .tuner_sda_gpio = -1, +diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c +index 4ba3ce09b713..6f5ffcc19356 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-core.c ++++ b/drivers/media/usb/cx231xx/cx231xx-core.c +@@ -723,6 +723,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) + break; + case CX231XX_BOARD_CNXT_RDE_253S: + case CX231XX_BOARD_CNXT_RDU_253S: ++ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: + errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); + break; + case CX231XX_BOARD_HAUPPAUGE_EXETER: +@@ -747,7 +748,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) + case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: + case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL: + case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC: +- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); ++ errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); + break; + default: + break; +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index 0405fba9f7a8..9a7e7e251338 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -1598,7 +1598,7 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq, + struct mmc_blk_data *md = mq->data; + struct mmc_packed *packed = mqrq->packed; + bool do_rel_wr, do_data_tag; +- u32 *packed_cmd_hdr; ++ __le32 *packed_cmd_hdr; + u8 hdr_blocks; + u8 i = 1; + +@@ -2121,7 +2121,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, + set_capacity(md->disk, size); + + if (mmc_host_cmd23(card->host)) { +- if (mmc_card_mmc(card) || ++ if ((mmc_card_mmc(card) && ++ card->csd.mmca_vsn >= CSD_SPEC_VER_3) || + (mmc_card_sd(card) && + card->scr.cmds & SD_SCR_CMD23_SUPPORT)) + md->flags |= MMC_BLK_CMD23; +diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h +index 99e6521e6169..f42c11293dd8 100644 +--- a/drivers/mmc/card/queue.h ++++ b/drivers/mmc/card/queue.h +@@ -24,7 +24,7 @@ enum mmc_packed_type { + + struct mmc_packed { + struct list_head list; +- u32 cmd_hdr[1024]; ++ __le32 cmd_hdr[1024]; + unsigned int blocks; + u8 nr_entries; + u8 retries; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 221aa4795017..1c7c3048117b 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -7265,6 +7265,12 @@ static pci_ers_result_t i40e_pci_error_detected(struct pci_dev *pdev, + + dev_info(&pdev->dev, "%s: error %d\n", __func__, error); + ++ if (!pf) { ++ dev_info(&pdev->dev, ++ "Cannot recover - error happened during device probe\n"); ++ return PCI_ERS_RESULT_DISCONNECT; ++ } ++ + /* shutdown all operations */ + i40e_pf_quiesce_all_vsi(pf); + +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +index 35d3821bed50..58ccdc2b012d 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +@@ -2077,7 +2077,7 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac) + struct mlx4_en_dev *mdev = en_priv->mdev; + u64 mac_u64 = mlx4_en_mac_to_u64(mac); + +- if (!is_valid_ether_addr(mac)) ++ if (is_multicast_ether_addr(mac)) + return -EINVAL; + + return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64); +diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c +index 45c16447744b..1ed4145164d6 100644 +--- a/drivers/regulator/tps65910-regulator.c ++++ b/drivers/regulator/tps65910-regulator.c +@@ -1080,6 +1080,12 @@ static int tps65910_probe(struct platform_device *pdev) + pmic->num_regulators = ARRAY_SIZE(tps65910_regs); + pmic->ext_sleep_control = tps65910_ext_sleep_control; + info = tps65910_regs; ++ /* Work around silicon erratum SWCZ010: output programmed ++ * voltage level can go higher than expected or crash ++ * Workaround: use no synchronization of DCDC clocks ++ */ ++ tps65910_reg_clear_bits(pmic->mfd, TPS65910_DCDCCTRL, ++ DCDCCTRL_DCDCCKSYNC_MASK); + break; + case TPS65911: + pmic->get_ctrl_reg = &tps65911_get_ctrl_register; +diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c +index 132a905b6bdb..371aed75eb83 100644 +--- a/drivers/s390/scsi/zfcp_dbf.c ++++ b/drivers/s390/scsi/zfcp_dbf.c +@@ -3,7 +3,7 @@ + * + * Debug traces for zfcp. + * +- * Copyright IBM Corp. 2002, 2013 ++ * Copyright IBM Corp. 2002, 2016 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -65,7 +65,7 @@ void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area, + * @tag: tag indicating which kind of unsolicited status has been received + * @req: request for which a response was received + */ +-void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) ++void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req) + { + struct zfcp_dbf *dbf = req->adapter->dbf; + struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix; +@@ -85,6 +85,8 @@ void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) + rec->u.res.req_issued = req->issued; + rec->u.res.prot_status = q_pref->prot_status; + rec->u.res.fsf_status = q_head->fsf_status; ++ rec->u.res.port_handle = q_head->port_handle; ++ rec->u.res.lun_handle = q_head->lun_handle; + + memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual, + FSF_PROT_STATUS_QUAL_SIZE); +@@ -97,7 +99,7 @@ void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) + rec->pl_len, "fsf_res", req->req_id); + } + +- debug_event(dbf->hba, 1, rec, sizeof(*rec)); ++ debug_event(dbf->hba, level, rec, sizeof(*rec)); + spin_unlock_irqrestore(&dbf->hba_lock, flags); + } + +@@ -241,7 +243,8 @@ static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec, + if (sdev) { + rec->lun_status = atomic_read(&sdev_to_zfcp(sdev)->status); + rec->lun = zfcp_scsi_dev_lun(sdev); +- } ++ } else ++ rec->lun = ZFCP_DBF_INVALID_LUN; + } + + /** +@@ -320,13 +323,48 @@ void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp) + spin_unlock_irqrestore(&dbf->rec_lock, flags); + } + ++/** ++ * zfcp_dbf_rec_run_wka - trace wka port event with info like running recovery ++ * @tag: identifier for event ++ * @wka_port: well known address port ++ * @req_id: request ID to correlate with potential HBA trace record ++ */ ++void zfcp_dbf_rec_run_wka(char *tag, struct zfcp_fc_wka_port *wka_port, ++ u64 req_id) ++{ ++ struct zfcp_dbf *dbf = wka_port->adapter->dbf; ++ struct zfcp_dbf_rec *rec = &dbf->rec_buf; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dbf->rec_lock, flags); ++ memset(rec, 0, sizeof(*rec)); ++ ++ rec->id = ZFCP_DBF_REC_RUN; ++ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); ++ rec->port_status = wka_port->status; ++ rec->d_id = wka_port->d_id; ++ rec->lun = ZFCP_DBF_INVALID_LUN; ++ ++ rec->u.run.fsf_req_id = req_id; ++ rec->u.run.rec_status = ~0; ++ rec->u.run.rec_step = ~0; ++ rec->u.run.rec_action = ~0; ++ rec->u.run.rec_count = ~0; ++ ++ debug_event(dbf->rec, 1, rec, sizeof(*rec)); ++ spin_unlock_irqrestore(&dbf->rec_lock, flags); ++} ++ + static inline +-void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len, +- u64 req_id, u32 d_id) ++void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, ++ char *paytag, struct scatterlist *sg, u8 id, u16 len, ++ u64 req_id, u32 d_id, u16 cap_len) + { + struct zfcp_dbf_san *rec = &dbf->san_buf; + u16 rec_len; + unsigned long flags; ++ struct zfcp_dbf_pay *payload = &dbf->pay_buf; ++ u16 pay_sum = 0; + + spin_lock_irqsave(&dbf->san_lock, flags); + memset(rec, 0, sizeof(*rec)); +@@ -334,10 +372,41 @@ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len, + rec->id = id; + rec->fsf_req_id = req_id; + rec->d_id = d_id; +- rec_len = min(len, (u16)ZFCP_DBF_SAN_MAX_PAYLOAD); +- memcpy(rec->payload, data, rec_len); + memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); ++ rec->pl_len = len; /* full length even if we cap pay below */ ++ if (!sg) ++ goto out; ++ rec_len = min_t(unsigned int, sg->length, ZFCP_DBF_SAN_MAX_PAYLOAD); ++ memcpy(rec->payload, sg_virt(sg), rec_len); /* part of 1st sg entry */ ++ if (len <= rec_len) ++ goto out; /* skip pay record if full content in rec->payload */ ++ ++ /* if (len > rec_len): ++ * dump data up to cap_len ignoring small duplicate in rec->payload ++ */ ++ spin_lock(&dbf->pay_lock); ++ memset(payload, 0, sizeof(*payload)); ++ memcpy(payload->area, paytag, ZFCP_DBF_TAG_LEN); ++ payload->fsf_req_id = req_id; ++ payload->counter = 0; ++ for (; sg && pay_sum < cap_len; sg = sg_next(sg)) { ++ u16 pay_len, offset = 0; ++ ++ while (offset < sg->length && pay_sum < cap_len) { ++ pay_len = min((u16)ZFCP_DBF_PAY_MAX_REC, ++ (u16)(sg->length - offset)); ++ /* cap_len <= pay_sum < cap_len+ZFCP_DBF_PAY_MAX_REC */ ++ memcpy(payload->data, sg_virt(sg) + offset, pay_len); ++ debug_event(dbf->pay, 1, payload, ++ zfcp_dbf_plen(pay_len)); ++ payload->counter++; ++ offset += pay_len; ++ pay_sum += pay_len; ++ } ++ } ++ spin_unlock(&dbf->pay_lock); + ++out: + debug_event(dbf->san, 1, rec, sizeof(*rec)); + spin_unlock_irqrestore(&dbf->san_lock, flags); + } +@@ -354,9 +423,62 @@ void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id) + struct zfcp_fsf_ct_els *ct_els = fsf->data; + u16 length; + +- length = (u16)(ct_els->req->length + FC_CT_HDR_LEN); +- zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length, +- fsf->req_id, d_id); ++ length = (u16)zfcp_qdio_real_bytes(ct_els->req); ++ zfcp_dbf_san(tag, dbf, "san_req", ct_els->req, ZFCP_DBF_SAN_REQ, ++ length, fsf->req_id, d_id, length); ++} ++ ++static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, ++ struct zfcp_fsf_req *fsf, ++ u16 len) ++{ ++ struct zfcp_fsf_ct_els *ct_els = fsf->data; ++ struct fc_ct_hdr *reqh = sg_virt(ct_els->req); ++ struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1); ++ struct scatterlist *resp_entry = ct_els->resp; ++ struct fc_gpn_ft_resp *acc; ++ int max_entries, x, last = 0; ++ ++ if (!(memcmp(tag, "fsscth2", 7) == 0 ++ && ct_els->d_id == FC_FID_DIR_SERV ++ && reqh->ct_rev == FC_CT_REV ++ && reqh->ct_in_id[0] == 0 ++ && reqh->ct_in_id[1] == 0 ++ && reqh->ct_in_id[2] == 0 ++ && reqh->ct_fs_type == FC_FST_DIR ++ && reqh->ct_fs_subtype == FC_NS_SUBTYPE ++ && reqh->ct_options == 0 ++ && reqh->_ct_resvd1 == 0 ++ && reqh->ct_cmd == FC_NS_GPN_FT ++ /* reqh->ct_mr_size can vary so do not match but read below */ ++ && reqh->_ct_resvd2 == 0 ++ && reqh->ct_reason == 0 ++ && reqh->ct_explan == 0 ++ && reqh->ct_vendor == 0 ++ && reqn->fn_resvd == 0 ++ && reqn->fn_domain_id_scope == 0 ++ && reqn->fn_area_id_scope == 0 ++ && reqn->fn_fc4_type == FC_TYPE_FCP)) ++ return len; /* not GPN_FT response so do not cap */ ++ ++ acc = sg_virt(resp_entry); ++ max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp)) ++ + 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one ++ * to account for header as 1st pseudo "entry" */; ++ ++ /* the basic CT_IU preamble is the same size as one entry in the GPN_FT ++ * response, allowing us to skip special handling for it - just skip it ++ */ ++ for (x = 1; x < max_entries && !last; x++) { ++ if (x % (ZFCP_FC_GPN_FT_ENT_PAGE + 1)) ++ acc++; ++ else ++ acc = sg_virt(++resp_entry); ++ ++ last = acc->fp_flags & FC_NS_FID_LAST; ++ } ++ len = min(len, (u16)(x * sizeof(struct fc_gpn_ft_resp))); ++ return len; /* cap after last entry */ + } + + /** +@@ -370,9 +492,10 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf) + struct zfcp_fsf_ct_els *ct_els = fsf->data; + u16 length; + +- length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN); +- zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length, +- fsf->req_id, 0); ++ length = (u16)zfcp_qdio_real_bytes(ct_els->resp); ++ zfcp_dbf_san(tag, dbf, "san_res", ct_els->resp, ZFCP_DBF_SAN_RES, ++ length, fsf->req_id, ct_els->d_id, ++ zfcp_dbf_san_res_cap_len_if_gpn_ft(tag, fsf, length)); + } + + /** +@@ -386,11 +509,13 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf) + struct fsf_status_read_buffer *srb = + (struct fsf_status_read_buffer *) fsf->data; + u16 length; ++ struct scatterlist sg; + + length = (u16)(srb->length - + offsetof(struct fsf_status_read_buffer, payload)); +- zfcp_dbf_san(tag, dbf, srb->payload.data, ZFCP_DBF_SAN_ELS, length, +- fsf->req_id, ntoh24(srb->d_id)); ++ sg_init_one(&sg, srb->payload.data, length); ++ zfcp_dbf_san(tag, dbf, "san_els", &sg, ZFCP_DBF_SAN_ELS, length, ++ fsf->req_id, ntoh24(srb->d_id), length); + } + + /** +@@ -399,7 +524,8 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf) + * @sc: pointer to struct scsi_cmnd + * @fsf: pointer to struct zfcp_fsf_req + */ +-void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf) ++void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc, ++ struct zfcp_fsf_req *fsf) + { + struct zfcp_adapter *adapter = + (struct zfcp_adapter *) sc->device->host->hostdata[0]; +@@ -441,7 +567,7 @@ void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf) + } + } + +- debug_event(dbf->scsi, 1, rec, sizeof(*rec)); ++ debug_event(dbf->scsi, level, rec, sizeof(*rec)); + spin_unlock_irqrestore(&dbf->scsi_lock, flags); + } + +diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h +index 3ac7a4b30dd9..440aa619da1d 100644 +--- a/drivers/s390/scsi/zfcp_dbf.h ++++ b/drivers/s390/scsi/zfcp_dbf.h +@@ -2,7 +2,7 @@ + * zfcp device driver + * debug feature declarations + * +- * Copyright IBM Corp. 2008, 2010 ++ * Copyright IBM Corp. 2008, 2015 + */ + + #ifndef ZFCP_DBF_H +@@ -17,6 +17,11 @@ + + #define ZFCP_DBF_INVALID_LUN 0xFFFFFFFFFFFFFFFFull + ++enum zfcp_dbf_pseudo_erp_act_type { ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD = 0xff, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL = 0xfe, ++}; ++ + /** + * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action + * @ready: number of ready recovery actions +@@ -110,6 +115,7 @@ struct zfcp_dbf_san { + u32 d_id; + #define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32) + char payload[ZFCP_DBF_SAN_MAX_PAYLOAD]; ++ u16 pl_len; + } __packed; + + /** +@@ -126,6 +132,8 @@ struct zfcp_dbf_hba_res { + u8 prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE]; + u32 fsf_status; + u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; ++ u32 port_handle; ++ u32 lun_handle; + } __packed; + + /** +@@ -279,7 +287,7 @@ static inline + void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req) + { + if (level <= req->adapter->dbf->hba->level) +- zfcp_dbf_hba_fsf_res(tag, req); ++ zfcp_dbf_hba_fsf_res(tag, level, req); + } + + /** +@@ -318,7 +326,7 @@ void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd, + scmd->device->host->hostdata[0]; + + if (level <= adapter->dbf->scsi->level) +- zfcp_dbf_scsi(tag, scmd, req); ++ zfcp_dbf_scsi(tag, level, scmd, req); + } + + /** +diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c +index c82fe65c4128..ac86ff90c897 100644 +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -3,7 +3,7 @@ + * + * Error Recovery Procedures (ERP). + * +- * Copyright IBM Corp. 2002, 2010 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -1224,8 +1224,14 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) + break; + + case ZFCP_ERP_ACTION_REOPEN_PORT: +- if (result == ZFCP_ERP_SUCCEEDED) +- zfcp_scsi_schedule_rport_register(port); ++ /* This switch case might also happen after a forced reopen ++ * was successfully done and thus overwritten with a new ++ * non-forced reopen at `ersfs_2'. In this case, we must not ++ * do the clean-up of the non-forced version. ++ */ ++ if (act->step != ZFCP_ERP_STEP_UNINITIALIZED) ++ if (result == ZFCP_ERP_SUCCEEDED) ++ zfcp_scsi_schedule_rport_register(port); + /* fall through */ + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + put_device(&port->dev); +diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h +index a9c570a09b85..1f1fe41ecb97 100644 +--- a/drivers/s390/scsi/zfcp_ext.h ++++ b/drivers/s390/scsi/zfcp_ext.h +@@ -3,7 +3,7 @@ + * + * External function declarations. + * +- * Copyright IBM Corp. 2002, 2010 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #ifndef ZFCP_EXT_H +@@ -35,8 +35,9 @@ extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *); + extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *, + struct zfcp_port *, struct scsi_device *, u8, u8); + extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *); ++extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64); + extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *); +-extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *); ++extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *); + extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *); + extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *); + extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **); +@@ -44,7 +45,8 @@ extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *); + extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32); + extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *); + extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *); +-extern void zfcp_dbf_scsi(char *, struct scsi_cmnd *, struct zfcp_fsf_req *); ++extern void zfcp_dbf_scsi(char *, int, struct scsi_cmnd *, ++ struct zfcp_fsf_req *); + + /* zfcp_erp.c */ + extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32); +diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c +index 0fe8d5d95119..6065212fdeed 100644 +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -3,7 +3,7 @@ + * + * Implementation of FSF commands. + * +- * Copyright IBM Corp. 2002, 2013 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -508,7 +508,10 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) + fc_host_port_type(shost) = FC_PORTTYPE_PTP; + break; + case FSF_TOPO_FABRIC: +- fc_host_port_type(shost) = FC_PORTTYPE_NPORT; ++ if (bottom->connection_features & FSF_FEATURE_NPIV_MODE) ++ fc_host_port_type(shost) = FC_PORTTYPE_NPIV; ++ else ++ fc_host_port_type(shost) = FC_PORTTYPE_NPORT; + break; + case FSF_TOPO_AL: + fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; +@@ -613,7 +616,6 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req) + + if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) { + fc_host_permanent_port_name(shost) = bottom->wwpn; +- fc_host_port_type(shost) = FC_PORTTYPE_NPIV; + } else + fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + fc_host_maxframe_size(shost) = bottom->maximum_frame_size; +@@ -982,8 +984,12 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, + if (zfcp_adapter_multi_buffer_active(adapter)) { + if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req)) + return -EIO; ++ qtcb->bottom.support.req_buf_length = ++ zfcp_qdio_real_bytes(sg_req); + if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp)) + return -EIO; ++ qtcb->bottom.support.resp_buf_length = ++ zfcp_qdio_real_bytes(sg_resp); + + zfcp_qdio_set_data_div(qdio, &req->qdio_req, + zfcp_qdio_sbale_count(sg_req)); +@@ -1073,6 +1079,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, + + req->handler = zfcp_fsf_send_ct_handler; + req->qtcb->header.port_handle = wka_port->handle; ++ ct->d_id = wka_port->d_id; + req->data = ct; + + zfcp_dbf_san_req("fssct_1", req, wka_port->d_id); +@@ -1169,6 +1176,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, + + hton24(req->qtcb->bottom.support.d_id, d_id); + req->handler = zfcp_fsf_send_els_handler; ++ els->d_id = d_id; + req->data = els; + + zfcp_dbf_san_req("fssels1", req, d_id); +@@ -1576,7 +1584,7 @@ out: + int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) + { + struct zfcp_qdio *qdio = wka_port->adapter->qdio; +- struct zfcp_fsf_req *req; ++ struct zfcp_fsf_req *req = NULL; + int retval = -EIO; + + spin_lock_irq(&qdio->req_q_lock); +@@ -1605,6 +1613,8 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) + zfcp_fsf_req_free(req); + out: + spin_unlock_irq(&qdio->req_q_lock); ++ if (req && !IS_ERR(req)) ++ zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id); + return retval; + } + +@@ -1629,7 +1639,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req) + int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) + { + struct zfcp_qdio *qdio = wka_port->adapter->qdio; +- struct zfcp_fsf_req *req; ++ struct zfcp_fsf_req *req = NULL; + int retval = -EIO; + + spin_lock_irq(&qdio->req_q_lock); +@@ -1658,6 +1668,8 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) + zfcp_fsf_req_free(req); + out: + spin_unlock_irq(&qdio->req_q_lock); ++ if (req && !IS_ERR(req)) ++ zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id); + return retval; + } + +diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h +index 57ae3ae1046d..be1c04b334c5 100644 +--- a/drivers/s390/scsi/zfcp_fsf.h ++++ b/drivers/s390/scsi/zfcp_fsf.h +@@ -3,7 +3,7 @@ + * + * Interface to the FSF support functions. + * +- * Copyright IBM Corp. 2002, 2010 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #ifndef FSF_H +@@ -436,6 +436,7 @@ struct zfcp_blk_drv_data { + * @handler_data: data passed to handler function + * @port: Optional pointer to port for zfcp internal ELS (only test link ADISC) + * @status: used to pass error status to calling function ++ * @d_id: Destination ID of either open WKA port for CT or of D_ID for ELS + */ + struct zfcp_fsf_ct_els { + struct scatterlist *req; +@@ -444,6 +445,7 @@ struct zfcp_fsf_ct_els { + void *handler_data; + struct zfcp_port *port; + int status; ++ u32 d_id; + }; + + #endif /* FSF_H */ +diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c +index 7b353647cb90..38ee0df633a3 100644 +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -3,7 +3,7 @@ + * + * Interface to Linux SCSI midlayer. + * +- * Copyright IBM Corp. 2002, 2013 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -577,6 +577,9 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port) + ids.port_id = port->d_id; + ids.roles = FC_RPORT_ROLE_FCP_TARGET; + ++ zfcp_dbf_rec_trig("scpaddy", port->adapter, port, NULL, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD); + rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids); + if (!rport) { + dev_err(&port->adapter->ccw_device->dev, +@@ -598,6 +601,9 @@ static void zfcp_scsi_rport_block(struct zfcp_port *port) + struct fc_rport *rport = port->rport; + + if (rport) { ++ zfcp_dbf_rec_trig("scpdely", port->adapter, port, NULL, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL); + fc_remote_port_delete(rport); + port->rport = NULL; + } +diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c +index 1822cb9ec623..66dda86e62e1 100644 +--- a/drivers/scsi/arcmsr/arcmsr_hba.c ++++ b/drivers/scsi/arcmsr/arcmsr_hba.c +@@ -1803,7 +1803,8 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, + + case ARCMSR_MESSAGE_WRITE_WQBUFFER: { + unsigned char *ver_addr; +- int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; ++ uint32_t user_len; ++ int32_t my_empty_len, wqbuf_firstindex, wqbuf_lastindex; + uint8_t *pQbuffer, *ptmpuserbuffer; + + ver_addr = kmalloc(1032, GFP_ATOMIC); +@@ -1820,6 +1821,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, + } + ptmpuserbuffer = ver_addr; + user_len = pcmdmessagefld->cmdmessage.Length; ++ if (user_len > 1032) { ++ retvalue = ARCMSR_MESSAGE_FAIL; ++ kfree(ver_addr); ++ goto message_out; ++ } + memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); + wqbuf_lastindex = acb->wqbuf_lastindex; + wqbuf_firstindex = acb->wqbuf_firstindex; +diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c +index 23f5ba5e6472..26d31b7e7331 100644 +--- a/drivers/scsi/ibmvscsi/ibmvfc.c ++++ b/drivers/scsi/ibmvscsi/ibmvfc.c +@@ -717,7 +717,6 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) + spin_lock_irqsave(vhost->host->host_lock, flags); + vhost->state = IBMVFC_NO_CRQ; + vhost->logged_in = 0; +- ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); + + /* Clean out the queue */ + memset(crq->msgs, 0, PAGE_SIZE); +diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c +index 25073167bcc4..1c87d74bf130 100644 +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -1537,12 +1537,12 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, + out_err: + kfree(lun_data); + out: +- scsi_device_put(sdev); + if (scsi_device_created(sdev)) + /* + * the sdev we used didn't appear in the report luns scan + */ + __scsi_remove_device(sdev); ++ scsi_device_put(sdev); + return ret; + } + +diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c +index 1270f3b26139..9d6a9105d83f 100644 +--- a/drivers/uio/uio_dmem_genirq.c ++++ b/drivers/uio/uio_dmem_genirq.c +@@ -229,7 +229,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) + ++uiomem; + } + +- priv->dmem_region_start = i; ++ priv->dmem_region_start = uiomem - &uioinfo->mem[0]; + priv->num_dmem_regions = pdata->num_dynamic_regions; + + for (i = 0; i < pdata->num_dynamic_regions; ++i) { +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 0fb8c85b77bf..5e788077675b 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2929,7 +2929,7 @@ static int usb_disable_remote_wakeup(struct usb_device *udev) + USB_CTRL_SET_TIMEOUT); + else + return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), +- USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE, ++ USB_REQ_SET_FEATURE, USB_RECIP_INTERFACE, + USB_INTRF_FUNC_SUSPEND, 0, NULL, 0, + USB_CTRL_SET_TIMEOUT); + } +diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c +index fcb950031246..dbd5fb207869 100644 +--- a/drivers/video/efifb.c ++++ b/drivers/video/efifb.c +@@ -54,9 +54,9 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, + return 1; + + if (regno < 16) { +- red >>= 8; +- green >>= 8; +- blue >>= 8; ++ red >>= 16 - info->var.red.length; ++ green >>= 16 - info->var.green.length; ++ blue >>= 16 - info->var.blue.length; + ((u32 *)(info->pseudo_palette))[regno] = + (red << info->var.red.offset) | + (green << info->var.green.offset) | +diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c +index f3ac4154cbb6..5a3e796461be 100644 +--- a/fs/cifs/cifs_debug.c ++++ b/fs/cifs/cifs_debug.c +@@ -170,6 +170,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) + list_for_each(tmp1, &cifs_tcp_ses_list) { + server = list_entry(tmp1, struct TCP_Server_Info, + tcp_ses_list); ++ seq_printf(m, "\nNumber of credits: %d", server->credits); + i++; + list_for_each(tmp2, &server->smb_ses_list) { + ses = list_entry(tmp2, struct cifs_ses, +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index b9f5709b54ca..037b8f7e8a94 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -260,7 +260,7 @@ cifs_alloc_inode(struct super_block *sb) + cifs_inode->createtime = 0; + cifs_inode->epoch = 0; + #ifdef CONFIG_CIFS_SMB2 +- get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE); ++ generate_random_uuid(cifs_inode->lease_key); + #endif + /* + * Can not set i_flags here - they get immediately overwritten to zero +@@ -1185,7 +1185,6 @@ init_cifs(void) + GlobalTotalActiveXid = 0; + GlobalMaxActiveXid = 0; + spin_lock_init(&cifs_tcp_ses_lock); +- spin_lock_init(&cifs_file_list_lock); + spin_lock_init(&GlobalMid_Lock); + + if (cifs_max_pending < 2) { +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index cee6a796d596..fa30efe15ba2 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -761,6 +761,7 @@ struct cifs_tcon { + struct list_head tcon_list; + int tc_count; + struct list_head openFileList; ++ spinlock_t open_file_lock; /* protects list above */ + struct cifs_ses *ses; /* pointer to session associated with */ + char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ + char *nativeFileSystem; +@@ -817,7 +818,7 @@ struct cifs_tcon { + #endif /* CONFIG_CIFS_STATS2 */ + __u64 bytes_read; + __u64 bytes_written; +- spinlock_t stat_lock; ++ spinlock_t stat_lock; /* protects the two fields above */ + #endif /* CONFIG_CIFS_STATS */ + FILE_SYSTEM_DEVICE_INFO fsDevInfo; + FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ +@@ -959,8 +960,10 @@ struct cifs_fid_locks { + }; + + struct cifsFileInfo { ++ /* following two lists are protected by tcon->open_file_lock */ + struct list_head tlist; /* pointer to next fid owned by tcon */ + struct list_head flist; /* next fid (file instance) for this inode */ ++ /* lock list below protected by cifsi->lock_sem */ + struct cifs_fid_locks *llist; /* brlocks held by this fid */ + kuid_t uid; /* allows finding which FileInfo structure */ + __u32 pid; /* process id who opened file */ +@@ -968,11 +971,12 @@ struct cifsFileInfo { + /* BB add lock scope info here if needed */ ; + /* lock scope id (0 if none) */ + struct dentry *dentry; +- unsigned int f_flags; + struct tcon_link *tlink; ++ unsigned int f_flags; + bool invalidHandle:1; /* file closed via session abend */ + bool oplock_break_cancelled:1; +- int count; /* refcount protected by cifs_file_list_lock */ ++ int count; ++ spinlock_t file_info_lock; /* protects four flag/count fields above */ + struct mutex fh_mutex; /* prevents reopen race after dead ses*/ + struct cifs_search_info srch_inf; + struct work_struct oplock_break; /* work for oplock breaks */ +@@ -1036,7 +1040,7 @@ struct cifs_writedata { + + /* + * Take a reference on the file private data. Must be called with +- * cifs_file_list_lock held. ++ * cfile->file_info_lock held. + */ + static inline void + cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file) +@@ -1422,8 +1426,10 @@ require use of the stronger protocol */ + * GlobalMid_Lock protects: + * list operations on pending_mid_q and oplockQ + * updates to XID counters, multiplex id and SMB sequence numbers +- * cifs_file_list_lock protects: +- * list operations on tcp and SMB session lists and tCon lists ++ * tcp_ses_lock protects: ++ * list operations on tcp and SMB session lists ++ * tcon->open_file_lock protects the list of open files hanging off the tcon ++ * cfile->file_info_lock protects counters and fields in cifs file struct + * f_owner.lock protects certain per file struct operations + * mapping->page_lock protects certain per page operations + * +@@ -1455,18 +1461,12 @@ GLOBAL_EXTERN struct list_head cifs_tcp_ses_list; + * tcp session, and the list of tcon's per smb session. It also protects + * the reference counters for the server, smb session, and tcon. Finally, + * changes to the tcon->tidStatus should be done while holding this lock. ++ * generally the locks should be taken in order tcp_ses_lock before ++ * tcon->open_file_lock and that before file->file_info_lock since the ++ * structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file + */ + GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock; + +-/* +- * This lock protects the cifs_file->llist and cifs_file->flist +- * list operations, and updates to some flags (cifs_file->invalidHandle) +- * It will be moved to either use the tcon->stat_lock or equivalent later. +- * If cifs_tcp_ses_lock and the lock below are both needed to be held, then +- * the cifs_tcp_ses_lock must be grabbed first and released last. +- */ +-GLOBAL_EXTERN spinlock_t cifs_file_list_lock; +- + #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */ + /* Outstanding dir notify requests */ + GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index f53a6e8204d8..9c93c2f29af1 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -98,13 +98,13 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon) + struct list_head *tmp1; + + /* list all files open on tree connection and mark them invalid */ +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_for_each_safe(tmp, tmp1, &tcon->openFileList) { + open_file = list_entry(tmp, struct cifsFileInfo, tlist); + open_file->invalidHandle = true; + open_file->oplock_break_cancelled = true; + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + /* + * BB Add call to invalidate_inodes(sb) for all superblocks mounted + * to this tcon. +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 7bdcf8fbc1ff..54f507bd2c09 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -2147,7 +2147,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) + memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, + sizeof(tcp_ses->dstaddr)); + #ifdef CONFIG_CIFS_SMB2 +- get_random_bytes(tcp_ses->client_guid, SMB2_CLIENT_GUID_SIZE); ++ generate_random_uuid(tcp_ses->client_guid); + #endif + /* + * at this point we are the only ones with the pointer +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index 381e60e6ef92..1e7883fb679d 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -306,6 +306,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + cfile->tlink = cifs_get_tlink(tlink); + INIT_WORK(&cfile->oplock_break, cifs_oplock_break); + mutex_init(&cfile->fh_mutex); ++ spin_lock_init(&cfile->file_info_lock); + + cifs_sb_active(inode->i_sb); + +@@ -318,7 +319,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + oplock = 0; + } + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE && oplock) + oplock = fid->pending_open->oplock; + list_del(&fid->pending_open->olist); +@@ -327,12 +328,13 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + server->ops->set_fid(cfile, fid, oplock); + + list_add(&cfile->tlist, &tcon->openFileList); ++ + /* if readable file instance put first in list*/ + if (file->f_mode & FMODE_READ) + list_add(&cfile->flist, &cinode->openFileList); + else + list_add_tail(&cfile->flist, &cinode->openFileList); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + + if (fid->purge_cache) + cifs_invalidate_mapping(inode); +@@ -344,16 +346,16 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + struct cifsFileInfo * + cifsFileInfo_get(struct cifsFileInfo *cifs_file) + { +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&cifs_file->file_info_lock); + cifsFileInfo_get_locked(cifs_file); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cifs_file->file_info_lock); + return cifs_file; + } + + /* + * Release a reference on the file private data. This may involve closing + * the filehandle out on the server. Must be called without holding +- * cifs_file_list_lock. ++ * tcon->open_file_lock and cifs_file->file_info_lock. + */ + void cifsFileInfo_put(struct cifsFileInfo *cifs_file) + { +@@ -368,11 +370,15 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) + struct cifs_pending_open open; + bool oplock_break_cancelled; + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); ++ ++ spin_lock(&cifs_file->file_info_lock); + if (--cifs_file->count > 0) { +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cifs_file->file_info_lock); ++ spin_unlock(&tcon->open_file_lock); + return; + } ++ spin_unlock(&cifs_file->file_info_lock); + + if (server->ops->get_lease_key) + server->ops->get_lease_key(inode, &fid); +@@ -396,7 +402,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) + CIFS_I(inode)->invalid_mapping = true; + cifs_set_oplock_level(cifsi, 0); + } +- spin_unlock(&cifs_file_list_lock); ++ ++ spin_unlock(&tcon->open_file_lock); + + oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break); + +@@ -765,10 +772,10 @@ int cifs_closedir(struct inode *inode, struct file *file) + server = tcon->ses->server; + + cifs_dbg(FYI, "Freeing private data in close dir\n"); +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&cfile->file_info_lock); + if (server->ops->dir_needs_close(cfile)) { + cfile->invalidHandle = true; +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cfile->file_info_lock); + if (server->ops->close_dir) + rc = server->ops->close_dir(xid, tcon, &cfile->fid); + else +@@ -777,7 +784,7 @@ int cifs_closedir(struct inode *inode, struct file *file) + /* not much we can do if it fails anyway, ignore rc */ + rc = 0; + } else +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cfile->file_info_lock); + + buf = cfile->srch_inf.ntwrk_buf_start; + if (buf) { +@@ -1719,12 +1726,13 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, + { + struct cifsFileInfo *open_file = NULL; + struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); ++ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + + /* only filter by fsuid on multiuser mounts */ + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) + fsuid_only = false; + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + /* we could simply get the first_list_entry since write-only entries + are always at the end of the list but since the first entry might + have a close pending, we go through the whole list */ +@@ -1735,8 +1743,8 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, + if (!open_file->invalidHandle) { + /* found a good file */ + /* lock it so it will not be closed on us */ +- cifsFileInfo_get_locked(open_file); +- spin_unlock(&cifs_file_list_lock); ++ cifsFileInfo_get(open_file); ++ spin_unlock(&tcon->open_file_lock); + return open_file; + } /* else might as well continue, and look for + another, or simply have the caller reopen it +@@ -1744,7 +1752,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, + } else /* write only file */ + break; /* write only files are last so must be done */ + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + return NULL; + } + +@@ -1753,6 +1761,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, + { + struct cifsFileInfo *open_file, *inv_file = NULL; + struct cifs_sb_info *cifs_sb; ++ struct cifs_tcon *tcon; + bool any_available = false; + int rc; + unsigned int refind = 0; +@@ -1768,15 +1777,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, + } + + cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); ++ tcon = cifs_sb_master_tcon(cifs_sb); + + /* only filter by fsuid on multiuser mounts */ + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) + fsuid_only = false; + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + refind_writable: + if (refind > MAX_REOPEN_ATT) { +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + return NULL; + } + list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { +@@ -1787,8 +1797,8 @@ refind_writable: + if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { + if (!open_file->invalidHandle) { + /* found a good writable file */ +- cifsFileInfo_get_locked(open_file); +- spin_unlock(&cifs_file_list_lock); ++ cifsFileInfo_get(open_file); ++ spin_unlock(&tcon->open_file_lock); + return open_file; + } else { + if (!inv_file) +@@ -1804,24 +1814,24 @@ refind_writable: + + if (inv_file) { + any_available = false; +- cifsFileInfo_get_locked(inv_file); ++ cifsFileInfo_get(inv_file); + } + +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + + if (inv_file) { + rc = cifs_reopen_file(inv_file, false); + if (!rc) + return inv_file; + else { +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_move_tail(&inv_file->flist, + &cifs_inode->openFileList); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + cifsFileInfo_put(inv_file); +- spin_lock(&cifs_file_list_lock); + ++refind; + inv_file = NULL; ++ spin_lock(&tcon->open_file_lock); + goto refind_writable; + } + } +@@ -3505,15 +3515,17 @@ static int cifs_readpage(struct file *file, struct page *page) + static int is_inode_writable(struct cifsInodeInfo *cifs_inode) + { + struct cifsFileInfo *open_file; ++ struct cifs_tcon *tcon = ++ cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb)); + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { + if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + return 1; + } + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + return 0; + } + +diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c +index 912a52e5e8cc..e360c9494b00 100644 +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -120,6 +120,7 @@ tconInfoAlloc(void) + ++ret_buf->tc_count; + INIT_LIST_HEAD(&ret_buf->openFileList); + INIT_LIST_HEAD(&ret_buf->tcon_list); ++ spin_lock_init(&ret_buf->open_file_lock); + #ifdef CONFIG_CIFS_STATS + spin_lock_init(&ret_buf->stat_lock); + #endif +@@ -462,7 +463,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) + continue; + + cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks); +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_for_each(tmp2, &tcon->openFileList) { + netfile = list_entry(tmp2, struct cifsFileInfo, + tlist); +@@ -492,11 +493,11 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) + &netfile->oplock_break); + netfile->oplock_break_cancelled = false; + +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + return true; + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + cifs_dbg(FYI, "No matching file for oplock break\n"); + return true; +@@ -645,9 +646,9 @@ backup_cred(struct cifs_sb_info *cifs_sb) + void + cifs_del_pending_open(struct cifs_pending_open *open) + { +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tlink_tcon(open->tlink)->open_file_lock); + list_del(&open->olist); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tlink_tcon(open->tlink)->open_file_lock); + } + + void +@@ -667,7 +668,7 @@ void + cifs_add_pending_open(struct cifs_fid *fid, struct tcon_link *tlink, + struct cifs_pending_open *open) + { +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tlink_tcon(tlink)->open_file_lock); + cifs_add_pending_open_locked(fid, tlink, open); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tlink_tcon(open->tlink)->open_file_lock); + } +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c +index 5454aff19d18..a4e276e65b0a 100644 +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -592,14 +592,14 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos, + is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) { + /* close and restart search */ + cifs_dbg(FYI, "search backing up - close and restart search\n"); +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&cfile->file_info_lock); + if (server->ops->dir_needs_close(cfile)) { + cfile->invalidHandle = true; +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cfile->file_info_lock); + if (server->ops->close_dir) + server->ops->close_dir(xid, tcon, &cfile->fid); + } else +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cfile->file_info_lock); + if (cfile->srch_inf.ntwrk_buf_start) { + cifs_dbg(FYI, "freeing SMB ff cache buf on search rewind\n"); + if (cfile->srch_inf.smallBuf) +diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h +index 0ffa18094335..238759c146ba 100644 +--- a/fs/cifs/smb2glob.h ++++ b/fs/cifs/smb2glob.h +@@ -61,4 +61,14 @@ + /* Maximum buffer size value we can send with 1 credit */ + #define SMB2_MAX_BUFFER_SIZE 65536 + ++/* ++ * Maximum number of credits to keep available. ++ * This value is chosen somewhat arbitrarily. The Windows client ++ * defaults to 128 credits, the Windows server allows clients up to ++ * 512 credits, and the NetApp server does not limit clients at all. ++ * Choose a high enough value such that the client shouldn't limit ++ * performance. ++ */ ++#define SMB2_MAX_CREDITS_AVAILABLE 32000 ++ + #endif /* _SMB2_GLOB_H */ +diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c +index f970c5d5b253..549676f7b811 100644 +--- a/fs/cifs/smb2inode.c ++++ b/fs/cifs/smb2inode.c +@@ -266,9 +266,15 @@ smb2_set_file_info(struct inode *inode, const char *full_path, + struct tcon_link *tlink; + int rc; + ++ if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) && ++ (buf->LastWriteTime == 0) && (buf->ChangeTime) && ++ (buf->Attributes == 0)) ++ return 0; /* would be a no op, no sense sending this */ ++ + tlink = cifs_sb_tlink(cifs_sb); + if (IS_ERR(tlink)) + return PTR_ERR(tlink); ++ + rc = smb2_open_op_close(xid, tlink_tcon(tlink), cifs_sb, full_path, + FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf, + SMB2_OP_SET_INFO); +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index b8021fde987d..579645d87f93 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -502,19 +502,19 @@ smb2_is_valid_lease_break(char *buffer) + list_for_each(tmp1, &server->smb_ses_list) { + ses = list_entry(tmp1, struct cifs_ses, smb_ses_list); + +- spin_lock(&cifs_file_list_lock); + list_for_each(tmp2, &ses->tcon_list) { + tcon = list_entry(tmp2, struct cifs_tcon, + tcon_list); ++ spin_lock(&tcon->open_file_lock); + cifs_stats_inc( + &tcon->stats.cifs_stats.num_oplock_brks); + if (smb2_tcon_has_lease(tcon, rsp, lw)) { +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + return true; + } ++ spin_unlock(&tcon->open_file_lock); + } +- spin_unlock(&cifs_file_list_lock); + } + } + spin_unlock(&cifs_tcp_ses_lock); +@@ -556,7 +556,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + tcon = list_entry(tmp1, struct cifs_tcon, tcon_list); + + cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks); +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_for_each(tmp2, &tcon->openFileList) { + cfile = list_entry(tmp2, struct cifsFileInfo, + tlist); +@@ -568,7 +568,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + + cifs_dbg(FYI, "file id match, oplock break\n"); + cinode = CIFS_I(cfile->dentry->d_inode); +- ++ spin_lock(&cfile->file_info_lock); + if (!CIFS_CACHE_WRITE(cinode) && + rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE) + cfile->oplock_break_cancelled = true; +@@ -590,14 +590,14 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + clear_bit( + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &cinode->flags); +- ++ spin_unlock(&cfile->file_info_lock); + queue_work(cifsiod_wq, &cfile->oplock_break); + +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + return true; + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + cifs_dbg(FYI, "No matching file for oplock break\n"); + return true; +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index a3a7a52aef04..6f74de30bd29 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -595,7 +595,7 @@ smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid) + static void + smb2_new_lease_key(struct cifs_fid *fid) + { +- get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE); ++ generate_random_uuid(fid->lease_key); + } + + #define SMB2_SYMLINK_STRUCT_SIZE \ +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 609350a69680..1a6dde4bce62 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -102,7 +102,21 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ , + hdr->ProtocolId[3] = 'B'; + hdr->StructureSize = cpu_to_le16(64); + hdr->Command = smb2_cmd; +- hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */ ++ if (tcon && tcon->ses && tcon->ses->server) { ++ struct TCP_Server_Info *server = tcon->ses->server; ++ ++ spin_lock(&server->req_lock); ++ /* Request up to 2 credits but don't go over the limit. */ ++ if (server->credits >= SMB2_MAX_CREDITS_AVAILABLE) ++ hdr->CreditRequest = cpu_to_le16(0); ++ else ++ hdr->CreditRequest = cpu_to_le16( ++ min_t(int, SMB2_MAX_CREDITS_AVAILABLE - ++ server->credits, 2)); ++ spin_unlock(&server->req_lock); ++ } else { ++ hdr->CreditRequest = cpu_to_le16(2); ++ } + hdr->ProcessId = cpu_to_le32((__u16)current->tgid); + + if (!tcon) +@@ -552,6 +566,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, + char *security_blob; + char *ntlmssp_blob = NULL; + bool use_spnego = false; /* else use raw ntlmssp */ ++ u64 previous_session = ses->Suid; + + cifs_dbg(FYI, "Session Setup\n"); + +@@ -588,6 +603,10 @@ ssetup_ntlmssp_authenticate: + return rc; + + req->hdr.SessionId = 0; /* First session, not a reauthenticate */ ++ ++ /* if reconnect, we need to send previous sess id, otherwise it is 0 */ ++ req->PreviousSessionId = previous_session; ++ + req->VcNumber = 0; /* MBZ */ + /* to enable echos and oplocks */ + req->hdr.CreditRequest = cpu_to_le16(3); +diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h +index 6133a4e45c6e..efcc77b51556 100644 +--- a/fs/cifs/smb2pdu.h ++++ b/fs/cifs/smb2pdu.h +@@ -228,7 +228,7 @@ struct smb2_sess_setup_req { + __le32 Channel; + __le16 SecurityBufferOffset; + __le16 SecurityBufferLength; +- __le64 PreviousSessionId; ++ __u64 PreviousSessionId; + __u8 Buffer[1]; /* variable length GSS security buffer */ + } __packed; + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index aa9a1e7b0255..4a3735a795d0 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3565,7 +3565,7 @@ int ext4_can_truncate(struct inode *inode) + } + + /* +- * ext4_punch_hole: punches a hole in a file by releaseing the blocks ++ * ext4_punch_hole: punches a hole in a file by releasing the blocks + * associated with the given offset and length + * + * @inode: File inode +@@ -3599,7 +3599,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) + * Write out all dirty pages to avoid race conditions + * Then release them. + */ +- if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { ++ if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { + ret = filemap_write_and_wait_range(mapping, offset, + offset + length - 1); + if (ret) +@@ -4399,14 +4399,14 @@ static int ext4_do_update_inode(handle_t *handle, + * Fix up interoperability with old kernels. Otherwise, old inodes get + * re-used with the upper 16 bits of the uid/gid intact + */ +- if (!ei->i_dtime) { ++ if (ei->i_dtime && list_empty(&ei->i_orphan)) { ++ raw_inode->i_uid_high = 0; ++ raw_inode->i_gid_high = 0; ++ } else { + raw_inode->i_uid_high = + cpu_to_le16(high_16_bits(i_uid)); + raw_inode->i_gid_high = + cpu_to_le16(high_16_bits(i_gid)); +- } else { +- raw_inode->i_uid_high = 0; +- raw_inode->i_gid_high = 0; + } + } else { + raw_inode->i_uid_low = cpu_to_le16(fs_high2lowuid(i_uid)); +diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c +index 2e2af97df075..77ac62441385 100644 +--- a/fs/isofs/inode.c ++++ b/fs/isofs/inode.c +@@ -710,6 +710,11 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) + pri_bh = NULL; + + root_found: ++ /* We don't support read-write mounts */ ++ if (!(s->s_flags & MS_RDONLY)) { ++ error = -EACCES; ++ goto out_freebh; ++ } + + if (joliet_level && (pri == NULL || !opt.rock)) { + /* This is the case of Joliet with the norock mount flag. +@@ -1522,9 +1527,6 @@ struct inode *__isofs_iget(struct super_block *sb, + static struct dentry *isofs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) + { +- /* We don't support read-write mounts */ +- if (!(flags & MS_RDONLY)) +- return ERR_PTR(-EACCES); + return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super); + } + +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index fbe7e2f90a3c..e9eda0d5ba60 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1448,6 +1448,9 @@ restart: + "Zeroing state\n", __func__, status); + case -ENOENT: + case -ENOMEM: ++ case -EACCES: ++ case -EROFS: ++ case -EIO: + case -ESTALE: + /* + * Open state on this file cannot be recovered +diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c +index bda61a759b68..7df456db7c33 100644 +--- a/fs/pstore/ram_core.c ++++ b/fs/pstore/ram_core.c +@@ -45,43 +45,10 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz) + return atomic_read(&prz->buffer->start); + } + +-/* increase and wrap the start pointer, returning the old value */ +-static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a) +-{ +- int old; +- int new; +- +- do { +- old = atomic_read(&prz->buffer->start); +- new = old + a; +- while (unlikely(new > prz->buffer_size)) +- new -= prz->buffer_size; +- } while (atomic_cmpxchg(&prz->buffer->start, old, new) != old); +- +- return old; +-} +- +-/* increase the size counter until it hits the max size */ +-static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a) +-{ +- size_t old; +- size_t new; +- +- if (atomic_read(&prz->buffer->size) == prz->buffer_size) +- return; +- +- do { +- old = atomic_read(&prz->buffer->size); +- new = old + a; +- if (new > prz->buffer_size) +- new = prz->buffer_size; +- } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); +-} +- + static DEFINE_RAW_SPINLOCK(buffer_lock); + + /* increase and wrap the start pointer, returning the old value */ +-static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) ++static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) + { + int old; + int new; +@@ -91,7 +58,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) + + old = atomic_read(&prz->buffer->start); + new = old + a; +- while (unlikely(new > prz->buffer_size)) ++ while (unlikely(new >= prz->buffer_size)) + new -= prz->buffer_size; + atomic_set(&prz->buffer->start, new); + +@@ -101,7 +68,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) + } + + /* increase the size counter until it hits the max size */ +-static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a) ++static void buffer_size_add(struct persistent_ram_zone *prz, size_t a) + { + size_t old; + size_t new; +@@ -122,9 +89,6 @@ exit: + raw_spin_unlock_irqrestore(&buffer_lock, flags); + } + +-static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic; +-static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic; +- + static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, + uint8_t *data, size_t len, uint8_t *ecc) + { +@@ -299,7 +263,7 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz, + const void *s, unsigned int start, unsigned int count) + { + struct persistent_ram_buffer *buffer = prz->buffer; +- memcpy(buffer->data + start, s, count); ++ memcpy_toio(buffer->data + start, s, count); + persistent_ram_update_ecc(prz, start, count); + } + +@@ -322,8 +286,8 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) + } + + prz->old_log_size = size; +- memcpy(prz->old_log, &buffer->data[start], size - start); +- memcpy(prz->old_log + size - start, &buffer->data[0], start); ++ memcpy_fromio(prz->old_log, &buffer->data[start], size - start); ++ memcpy_fromio(prz->old_log + size - start, &buffer->data[0], start); + } + + int notrace persistent_ram_write(struct persistent_ram_zone *prz, +@@ -426,9 +390,6 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size, + return NULL; + } + +- buffer_start_add = buffer_start_add_locked; +- buffer_size_add = buffer_size_add_locked; +- + if (memtype) + va = ioremap(start, size); + else +diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c +index 580b038456f8..77663d68ee02 100644 +--- a/fs/reiserfs/super.c ++++ b/fs/reiserfs/super.c +@@ -188,7 +188,15 @@ static int remove_save_link_only(struct super_block *s, + static int reiserfs_quota_on_mount(struct super_block *, int); + #endif + +-/* look for uncompleted unlinks and truncates and complete them */ ++/* ++ * Look for uncompleted unlinks and truncates and complete them ++ * ++ * Called with superblock write locked. If quotas are enabled, we have to ++ * release/retake lest we call dquot_quota_on_mount(), proceed to ++ * schedule_on_each_cpu() in invalidate_bdev() and deadlock waiting for the per ++ * cpu worklets to complete flush_async_commits() that in turn wait for the ++ * superblock write lock. ++ */ + static int finish_unfinished(struct super_block *s) + { + INITIALIZE_PATH(path); +@@ -235,7 +243,9 @@ static int finish_unfinished(struct super_block *s) + quota_enabled[i] = 0; + continue; + } ++ reiserfs_write_unlock(s); + ret = reiserfs_quota_on_mount(s, i); ++ reiserfs_write_lock(s); + if (ret < 0) + reiserfs_warning(s, "reiserfs-2500", + "cannot turn on journaled " +diff --git a/fs/super.c b/fs/super.c +index e3406833d82f..d9a7d620e747 100644 +--- a/fs/super.c ++++ b/fs/super.c +@@ -1337,8 +1337,8 @@ int freeze_super(struct super_block *sb) + } + } + /* +- * This is just for debugging purposes so that fs can warn if it +- * sees write activity when frozen is set to SB_FREEZE_COMPLETE. ++ * For debugging purposes so that fs can warn if it sees write activity ++ * when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super(). + */ + sb->s_writers.frozen = SB_FREEZE_COMPLETE; + up_write(&sb->s_umount); +@@ -1357,7 +1357,7 @@ int thaw_super(struct super_block *sb) + int error; + + down_write(&sb->s_umount); +- if (sb->s_writers.frozen == SB_UNFROZEN) { ++ if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) { + up_write(&sb->s_umount); + return -EINVAL; + } +diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c +index 0f7139bdb2c2..69a42f36b421 100644 +--- a/fs/ubifs/xattr.c ++++ b/fs/ubifs/xattr.c +@@ -167,6 +167,7 @@ out_cancel: + host_ui->xattr_cnt -= 1; + host_ui->xattr_size -= CALC_DENT_SIZE(nm->len); + host_ui->xattr_size -= CALC_XATTR_BYTES(size); ++ host_ui->xattr_names -= nm->len; + mutex_unlock(&host_ui->ui_mutex); + out_free: + make_bad_inode(inode); +@@ -514,6 +515,7 @@ out_cancel: + host_ui->xattr_cnt += 1; + host_ui->xattr_size += CALC_DENT_SIZE(nm->len); + host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len); ++ host_ui->xattr_names += nm->len; + mutex_unlock(&host_ui->ui_mutex); + ubifs_release_budget(c, &req); + make_bad_inode(inode); +diff --git a/include/linux/compiler.h b/include/linux/compiler.h +index 913532c0c140..f968eefaf1e8 100644 +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -362,7 +362,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s + + /* Is this type a native word size -- useful for atomic operations */ + #ifndef __native_word +-# define __native_word(t) (sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) ++# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) + #endif + + /* Compile time object size, -1 for unknown */ +diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h +index a2a89a5c7be5..05009a1631fa 100644 +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -157,4 +157,8 @@ enum { + /* changeable features with no special hardware requirements */ + #define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) + ++#define NETIF_F_GSO_ENCAP_ALL (NETIF_F_GSO_GRE | \ ++ NETIF_F_GSO_UDP_TUNNEL | \ ++ NETIF_F_GSO_MPLS) ++ + #endif /* _LINUX_NETDEV_FEATURES_H */ +diff --git a/include/linux/sem.h b/include/linux/sem.h +index 976ce3a19f1b..d0efd6e6c20a 100644 +--- a/include/linux/sem.h ++++ b/include/linux/sem.h +@@ -21,6 +21,7 @@ struct sem_array { + struct list_head list_id; /* undo requests on this array */ + int sem_nsems; /* no. of semaphores in array */ + int complex_count; /* pending complex operations */ ++ bool complex_mode; /* no parallel simple ops */ + }; + + #ifdef CONFIG_SYSVIPC +diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h +index a0a4a100f5c9..df661ab4aa23 100644 +--- a/include/net/ip_tunnels.h ++++ b/include/net/ip_tunnels.h +@@ -150,6 +150,22 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, + __be32 src, __be32 dst, __u8 proto, + __u8 tos, __u8 ttl, __be16 df, bool xnet); + ++static inline int iptunnel_pull_offloads(struct sk_buff *skb) ++{ ++ if (skb_is_gso(skb)) { ++ int err; ++ ++ err = skb_unclone(skb, GFP_ATOMIC); ++ if (unlikely(err)) ++ return err; ++ skb_shinfo(skb)->gso_type &= ~(NETIF_F_GSO_ENCAP_ALL >> ++ NETIF_F_GSO_SHIFT); ++ } ++ ++ skb->encapsulation = 0; ++ return 0; ++} ++ + static inline void iptunnel_xmit_stats(int err, + struct net_device_stats *err_stats, + struct pcpu_tstats __percpu *stats) +diff --git a/ipc/msg.c b/ipc/msg.c +index f8c22afff450..b92acb6a138c 100644 +--- a/ipc/msg.c ++++ b/ipc/msg.c +@@ -1046,21 +1046,23 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it) + struct user_namespace *user_ns = seq_user_ns(s); + struct msg_queue *msq = it; + +- return seq_printf(s, +- "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", +- msq->q_perm.key, +- msq->q_perm.id, +- msq->q_perm.mode, +- msq->q_cbytes, +- msq->q_qnum, +- msq->q_lspid, +- msq->q_lrpid, +- from_kuid_munged(user_ns, msq->q_perm.uid), +- from_kgid_munged(user_ns, msq->q_perm.gid), +- from_kuid_munged(user_ns, msq->q_perm.cuid), +- from_kgid_munged(user_ns, msq->q_perm.cgid), +- msq->q_stime, +- msq->q_rtime, +- msq->q_ctime); ++ seq_printf(s, ++ "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", ++ msq->q_perm.key, ++ msq->q_perm.id, ++ msq->q_perm.mode, ++ msq->q_cbytes, ++ msq->q_qnum, ++ msq->q_lspid, ++ msq->q_lrpid, ++ from_kuid_munged(user_ns, msq->q_perm.uid), ++ from_kgid_munged(user_ns, msq->q_perm.gid), ++ from_kuid_munged(user_ns, msq->q_perm.cuid), ++ from_kgid_munged(user_ns, msq->q_perm.cgid), ++ msq->q_stime, ++ msq->q_rtime, ++ msq->q_ctime); ++ ++ return 0; + } + #endif +diff --git a/ipc/sem.c b/ipc/sem.c +index 7fb486739cbb..857f7f8c27c4 100644 +--- a/ipc/sem.c ++++ b/ipc/sem.c +@@ -155,14 +155,21 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it); + + /* + * Locking: ++ * a) global sem_lock() for read/write + * sem_undo.id_next, + * sem_array.complex_count, +- * sem_array.pending{_alter,_cont}, +- * sem_array.sem_undo: global sem_lock() for read/write +- * sem_undo.proc_next: only "current" is allowed to read/write that field. ++ * sem_array.complex_mode ++ * sem_array.pending{_alter,_const}, ++ * sem_array.sem_undo + * ++ * b) global or semaphore sem_lock() for read/write: + * sem_array.sem_base[i].pending_{const,alter}: +- * global or semaphore sem_lock() for read/write ++ * sem_array.complex_mode (for read) ++ * ++ * c) special: ++ * sem_undo_list.list_proc: ++ * * undo_list->lock for write ++ * * rcu for read + */ + + #define sc_semmsl sem_ctls[0] +@@ -263,24 +270,25 @@ static void sem_rcu_free(struct rcu_head *head) + #define ipc_smp_acquire__after_spin_is_unlocked() smp_rmb() + + /* +- * Wait until all currently ongoing simple ops have completed. ++ * Enter the mode suitable for non-simple operations: + * Caller must own sem_perm.lock. +- * New simple ops cannot start, because simple ops first check +- * that sem_perm.lock is free. +- * that a) sem_perm.lock is free and b) complex_count is 0. + */ +-static void sem_wait_array(struct sem_array *sma) ++static void complexmode_enter(struct sem_array *sma) + { + int i; + struct sem *sem; + +- if (sma->complex_count) { +- /* The thread that increased sma->complex_count waited on +- * all sem->lock locks. Thus we don't need to wait again. +- */ ++ if (sma->complex_mode) { ++ /* We are already in complex_mode. Nothing to do */ + return; + } + ++ /* We need a full barrier after seting complex_mode: ++ * The write to complex_mode must be visible ++ * before we read the first sem->lock spinlock state. ++ */ ++ set_mb(sma->complex_mode, true); ++ + for (i = 0; i < sma->sem_nsems; i++) { + sem = sma->sem_base + i; + spin_unlock_wait(&sem->lock); +@@ -289,6 +297,28 @@ static void sem_wait_array(struct sem_array *sma) + } + + /* ++ * Try to leave the mode that disallows simple operations: ++ * Caller must own sem_perm.lock. ++ */ ++static void complexmode_tryleave(struct sem_array *sma) ++{ ++ if (sma->complex_count) { ++ /* Complex ops are sleeping. ++ * We must stay in complex mode ++ */ ++ return; ++ } ++ /* ++ * Immediately after setting complex_mode to false, ++ * a simple op can start. Thus: all memory writes ++ * performed by the current operation must be visible ++ * before we set complex_mode to false. ++ */ ++ smp_store_release(&sma->complex_mode, false); ++} ++ ++#define SEM_GLOBAL_LOCK (-1) ++/* + * If the request contains only one semaphore operation, and there are + * no complex transactions pending, lock only the semaphore involved. + * Otherwise, lock the entire semaphore array, since we either have +@@ -304,56 +334,42 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, + /* Complex operation - acquire a full lock */ + ipc_lock_object(&sma->sem_perm); + +- /* And wait until all simple ops that are processed +- * right now have dropped their locks. +- */ +- sem_wait_array(sma); +- return -1; ++ /* Prevent parallel simple ops */ ++ complexmode_enter(sma); ++ return SEM_GLOBAL_LOCK; + } + + /* + * Only one semaphore affected - try to optimize locking. +- * The rules are: +- * - optimized locking is possible if no complex operation +- * is either enqueued or processed right now. +- * - The test for enqueued complex ops is simple: +- * sma->complex_count != 0 +- * - Testing for complex ops that are processed right now is +- * a bit more difficult. Complex ops acquire the full lock +- * and first wait that the running simple ops have completed. +- * (see above) +- * Thus: If we own a simple lock and the global lock is free +- * and complex_count is now 0, then it will stay 0 and +- * thus just locking sem->lock is sufficient. ++ * Optimized locking is possible if no complex operation ++ * is either enqueued or processed right now. ++ * ++ * Both facts are tracked by complex_mode. + */ + sem = sma->sem_base + sops->sem_num; + +- if (sma->complex_count == 0) { ++ /* ++ * Initial check for complex_mode. Just an optimization, ++ * no locking, no memory barrier. ++ */ ++ if (!sma->complex_mode) { + /* + * It appears that no complex operation is around. + * Acquire the per-semaphore lock. + */ + spin_lock(&sem->lock); + +- /* Then check that the global lock is free */ +- if (!spin_is_locked(&sma->sem_perm.lock)) { +- /* +- * We need a memory barrier with acquire semantics, +- * otherwise we can race with another thread that does: +- * complex_count++; +- * spin_unlock(sem_perm.lock); +- */ +- ipc_smp_acquire__after_spin_is_unlocked(); ++ /* ++ * See 51d7d5205d33 ++ * ("powerpc: Add smp_mb() to arch_spin_is_locked()"): ++ * A full barrier is required: the write of sem->lock ++ * must be visible before the read is executed ++ */ ++ smp_mb(); + +- /* +- * Now repeat the test of complex_count: +- * It can't change anymore until we drop sem->lock. +- * Thus: if is now 0, then it will stay 0. +- */ +- if (sma->complex_count == 0) { +- /* fast path successful! */ +- return sops->sem_num; +- } ++ if (!smp_load_acquire(&sma->complex_mode)) { ++ /* fast path successful! */ ++ return sops->sem_num; + } + spin_unlock(&sem->lock); + } +@@ -373,15 +389,16 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, + /* Not a false alarm, thus complete the sequence for a + * full lock. + */ +- sem_wait_array(sma); +- return -1; ++ complexmode_enter(sma); ++ return SEM_GLOBAL_LOCK; + } + } + + static inline void sem_unlock(struct sem_array *sma, int locknum) + { +- if (locknum == -1) { ++ if (locknum == SEM_GLOBAL_LOCK) { + unmerge_queues(sma); ++ complexmode_tryleave(sma); + ipc_unlock_object(&sma->sem_perm); + } else { + struct sem *sem = sma->sem_base + locknum; +@@ -534,6 +551,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) + } + + sma->complex_count = 0; ++ sma->complex_mode = true; /* dropped by sem_unlock below */ + INIT_LIST_HEAD(&sma->pending_alter); + INIT_LIST_HEAD(&sma->pending_const); + INIT_LIST_HEAD(&sma->list_id); +@@ -2167,24 +2185,28 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it) + /* + * The proc interface isn't aware of sem_lock(), it calls + * ipc_lock_object() directly (in sysvipc_find_ipc). +- * In order to stay compatible with sem_lock(), we must wait until +- * all simple semop() calls have left their critical regions. ++ * In order to stay compatible with sem_lock(), we must ++ * enter / leave complex_mode. + */ +- sem_wait_array(sma); ++ complexmode_enter(sma); + + sem_otime = get_semotime(sma); + +- return seq_printf(s, +- "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n", +- sma->sem_perm.key, +- sma->sem_perm.id, +- sma->sem_perm.mode, +- sma->sem_nsems, +- from_kuid_munged(user_ns, sma->sem_perm.uid), +- from_kgid_munged(user_ns, sma->sem_perm.gid), +- from_kuid_munged(user_ns, sma->sem_perm.cuid), +- from_kgid_munged(user_ns, sma->sem_perm.cgid), +- sem_otime, +- sma->sem_ctime); ++ seq_printf(s, ++ "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n", ++ sma->sem_perm.key, ++ sma->sem_perm.id, ++ sma->sem_perm.mode, ++ sma->sem_nsems, ++ from_kuid_munged(user_ns, sma->sem_perm.uid), ++ from_kgid_munged(user_ns, sma->sem_perm.gid), ++ from_kuid_munged(user_ns, sma->sem_perm.cuid), ++ from_kgid_munged(user_ns, sma->sem_perm.cgid), ++ sem_otime, ++ sma->sem_ctime); ++ ++ complexmode_tryleave(sma); ++ ++ return 0; + } + #endif +diff --git a/ipc/shm.c b/ipc/shm.c +index 02f7125c8a0f..4066519acc64 100644 +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -1340,25 +1340,27 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) + #define SIZE_SPEC "%21lu" + #endif + +- return seq_printf(s, +- "%10d %10d %4o " SIZE_SPEC " %5u %5u " +- "%5lu %5u %5u %5u %5u %10lu %10lu %10lu " +- SIZE_SPEC " " SIZE_SPEC "\n", +- shp->shm_perm.key, +- shp->shm_perm.id, +- shp->shm_perm.mode, +- shp->shm_segsz, +- shp->shm_cprid, +- shp->shm_lprid, +- shp->shm_nattch, +- from_kuid_munged(user_ns, shp->shm_perm.uid), +- from_kgid_munged(user_ns, shp->shm_perm.gid), +- from_kuid_munged(user_ns, shp->shm_perm.cuid), +- from_kgid_munged(user_ns, shp->shm_perm.cgid), +- shp->shm_atim, +- shp->shm_dtim, +- shp->shm_ctim, +- rss * PAGE_SIZE, +- swp * PAGE_SIZE); ++ seq_printf(s, ++ "%10d %10d %4o " SIZE_SPEC " %5u %5u " ++ "%5lu %5u %5u %5u %5u %10lu %10lu %10lu " ++ SIZE_SPEC " " SIZE_SPEC "\n", ++ shp->shm_perm.key, ++ shp->shm_perm.id, ++ shp->shm_perm.mode, ++ shp->shm_segsz, ++ shp->shm_cprid, ++ shp->shm_lprid, ++ shp->shm_nattch, ++ from_kuid_munged(user_ns, shp->shm_perm.uid), ++ from_kgid_munged(user_ns, shp->shm_perm.gid), ++ from_kuid_munged(user_ns, shp->shm_perm.cuid), ++ from_kgid_munged(user_ns, shp->shm_perm.cgid), ++ shp->shm_atim, ++ shp->shm_dtim, ++ shp->shm_ctim, ++ rss * PAGE_SIZE, ++ swp * PAGE_SIZE); ++ ++ return 0; + } + #endif +diff --git a/ipc/util.c b/ipc/util.c +index 735342570a87..cc106890784b 100644 +--- a/ipc/util.c ++++ b/ipc/util.c +@@ -904,8 +904,10 @@ static int sysvipc_proc_show(struct seq_file *s, void *it) + struct ipc_proc_iter *iter = s->private; + struct ipc_proc_iface *iface = iter->iface; + +- if (it == SEQ_START_TOKEN) +- return seq_puts(s, iface->header); ++ if (it == SEQ_START_TOKEN) { ++ seq_puts(s, iface->header); ++ return 0; ++ } + + return iface->show(s, it); + } +diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c +index 452d6f2ba21d..6733fbf14dbe 100644 +--- a/kernel/irq/generic-chip.c ++++ b/kernel/irq/generic-chip.c +@@ -395,8 +395,28 @@ static int irq_map_generic_chip(struct irq_domain *d, unsigned int virq, + return 0; + } + ++static void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq) ++{ ++ struct irq_data *data = irq_get_irq_data(virq); ++ struct irq_domain_chip_generic *dgc = d->gc; ++ unsigned int hw_irq = data->hwirq; ++ struct irq_chip_generic *gc; ++ int irq_idx; ++ ++ gc = irq_get_domain_generic_chip(d, hw_irq); ++ if (!gc) ++ return; ++ ++ irq_idx = hw_irq % dgc->irqs_per_chip; ++ ++ clear_bit(irq_idx, &gc->installed); ++ irq_set_chip_and_handler(virq, &no_irq_chip, NULL); ++ irq_set_chip_data(virq, NULL); ++} ++ + struct irq_domain_ops irq_generic_chip_ops = { + .map = irq_map_generic_chip, ++ .unmap = irq_unmap_generic_chip, + .xlate = irq_domain_xlate_onetwocell, + }; + EXPORT_SYMBOL_GPL(irq_generic_chip_ops); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index a3a9676c65cf..2aaf11bdfb17 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -899,12 +899,13 @@ static void dissolve_free_huge_page(struct page *page) + { + spin_lock(&hugetlb_lock); + if (PageHuge(page) && !page_count(page)) { +- struct hstate *h = page_hstate(page); +- int nid = page_to_nid(page); +- list_del(&page->lru); ++ struct page *head = compound_head(page); ++ struct hstate *h = page_hstate(head); ++ int nid = page_to_nid(head); ++ list_del(&head->lru); + h->free_huge_pages--; + h->free_huge_pages_node[nid]--; +- update_and_free_page(h, page); ++ update_and_free_page(h, head); + } + spin_unlock(&hugetlb_lock); + } +@@ -912,7 +913,8 @@ static void dissolve_free_huge_page(struct page *page) + /* + * Dissolve free hugepages in a given pfn range. Used by memory hotplug to + * make specified memory blocks removable from the system. +- * Note that start_pfn should aligned with (minimum) hugepage size. ++ * Note that this will dissolve a free gigantic hugepage completely, if any ++ * part of it lies within the given range. + */ + void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) + { +@@ -924,7 +926,6 @@ void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) + for_each_hstate(h) + if (order > huge_page_order(h)) + order = huge_page_order(h); +- VM_BUG_ON(!IS_ALIGNED(start_pfn, 1 << order)); + for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << order) + dissolve_free_huge_page(pfn_to_page(pfn)); + } +diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c +index ff3f84f38e6d..792dd807c635 100644 +--- a/net/ipv4/ip_tunnel_core.c ++++ b/net/ipv4/ip_tunnel_core.c +@@ -114,6 +114,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto) + skb->vlan_tci = 0; + skb_set_queue_mapping(skb, 0); + skb->pkt_type = PACKET_HOST; +- return 0; ++ ++ return iptunnel_pull_offloads(skb); + } + EXPORT_SYMBOL_GPL(iptunnel_pull_header); +diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c +index a883776bcec8..a28d8d2bbd8f 100644 +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -647,14 +647,15 @@ static int ipip6_rcv(struct sk_buff *skb) + skb->mac_header = skb->network_header; + skb_reset_network_header(skb); + IPCB(skb)->flags = 0; +- skb->protocol = htons(ETH_P_IPV6); ++ skb->dev = tunnel->dev; + + if (packet_is_spoofed(skb, iph, tunnel)) { + tunnel->dev->stats.rx_errors++; + goto out; + } + +- __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); ++ if (iptunnel_pull_header(skb, 0, htons(ETH_P_IPV6))) ++ goto out; + + err = IP_ECN_decapsulate(iph, skb); + if (unlikely(err)) { +diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c +index a9c829be5216..0b6e9bacfe58 100644 +--- a/tools/perf/util/symbol-elf.c ++++ b/tools/perf/util/symbol-elf.c +@@ -952,8 +952,8 @@ new_symbol: + * For misannotated, zeroed, ASM function sizes. + */ + if (nr > 0) { +- symbols__fixup_duplicate(&dso->symbols[map->type]); + symbols__fixup_end(&dso->symbols[map->type]); ++ symbols__fixup_duplicate(&dso->symbols[map->type]); + if (kmap) { + /* + * We need to fixup this here too because we create new +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index 7eb0362f4ffd..3c8f825eb7d4 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -903,8 +903,8 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, + if (dso__load_all_kallsyms(dso, filename, map) < 0) + return -1; + +- symbols__fixup_duplicate(&dso->symbols[map->type]); + symbols__fixup_end(&dso->symbols[map->type]); ++ symbols__fixup_duplicate(&dso->symbols[map->type]); + + if (dso->kernel == DSO_TYPE_GUEST_KERNEL) + dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;