summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2017-04-01 19:40:12 -0400
committerAnthony G. Basile <blueness@gentoo.org>2017-04-01 19:40:12 -0400
commitb897bcf385333e0aaa97084370db28c16dc589f4 (patch)
tree603a21bf6485d0ebd9d7216bf3e921f9c1f3a363
parentgrsecurity-3.1-4.9.18-201703261106 (diff)
downloadhardened-patchset-b897bcf385333e0aaa97084370db28c16dc589f4.tar.gz
hardened-patchset-b897bcf385333e0aaa97084370db28c16dc589f4.tar.bz2
hardened-patchset-b897bcf385333e0aaa97084370db28c16dc589f4.zip
grsecurity-3.1-4.9.20-20170331082320170331
-rw-r--r--4.9.18/1016_linux-4.9.17.patch6091
-rw-r--r--4.9.18/1017_linux-4.9.18.patch876
-rw-r--r--4.9.20/0000_README (renamed from 4.9.18/0000_README)10
-rw-r--r--4.9.20/4420_grsecurity-3.1-4.9.20-201703310823.patch (renamed from 4.9.18/4420_grsecurity-3.1-4.9.18-201703261106.patch)208
-rw-r--r--4.9.20/4425_grsec_remove_EI_PAX.patch (renamed from 4.9.18/4425_grsec_remove_EI_PAX.patch)0
-rw-r--r--4.9.20/4426_default_XATTR_PAX_FLAGS.patch (renamed from 4.9.18/4426_default_XATTR_PAX_FLAGS.patch)0
-rw-r--r--4.9.20/4427_force_XATTR_PAX_tmpfs.patch (renamed from 4.9.18/4427_force_XATTR_PAX_tmpfs.patch)0
-rw-r--r--4.9.20/4430_grsec-remove-localversion-grsec.patch (renamed from 4.9.18/4430_grsec-remove-localversion-grsec.patch)0
-rw-r--r--4.9.20/4435_grsec-mute-warnings.patch (renamed from 4.9.18/4435_grsec-mute-warnings.patch)0
-rw-r--r--4.9.20/4440_grsec-remove-protected-paths.patch (renamed from 4.9.18/4440_grsec-remove-protected-paths.patch)0
-rw-r--r--4.9.20/4450_grsec-kconfig-default-gids.patch (renamed from 4.9.18/4450_grsec-kconfig-default-gids.patch)0
-rw-r--r--4.9.20/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 4.9.18/4465_selinux-avc_audit-log-curr_ip.patch)0
-rw-r--r--4.9.20/4470_disable-compat_vdso.patch (renamed from 4.9.18/4470_disable-compat_vdso.patch)0
-rw-r--r--4.9.20/4475_emutramp_default_on.patch (renamed from 4.9.18/4475_emutramp_default_on.patch)0
14 files changed, 143 insertions, 7042 deletions
diff --git a/4.9.18/1016_linux-4.9.17.patch b/4.9.18/1016_linux-4.9.17.patch
deleted file mode 100644
index 1a83496..0000000
--- a/4.9.18/1016_linux-4.9.17.patch
+++ /dev/null
@@ -1,6091 +0,0 @@
-diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
-index 405da11..d11af52 100644
---- a/Documentation/arm64/silicon-errata.txt
-+++ b/Documentation/arm64/silicon-errata.txt
-@@ -42,24 +42,26 @@ file acts as a registry of software workarounds in the Linux Kernel and
- will be updated when new workarounds are committed and backported to
- stable kernels.
-
--| Implementor | Component | Erratum ID | Kconfig |
--+----------------+-----------------+-----------------+-------------------------+
--| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
--| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
--| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
--| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
--| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 |
--| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 |
--| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
--| ARM | Cortex-A57 | #852523 | N/A |
--| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
--| ARM | Cortex-A72 | #853709 | N/A |
--| ARM | MMU-500 | #841119,#826419 | N/A |
--| | | | |
--| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
--| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
--| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
--| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
--| Cavium | ThunderX SMMUv2 | #27704 | N/A |
--| | | | |
--| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
-+| Implementor | Component | Erratum ID | Kconfig |
-++----------------+-----------------+-----------------+-----------------------------+
-+| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
-+| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
-+| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
-+| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
-+| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 |
-+| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 |
-+| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
-+| ARM | Cortex-A57 | #852523 | N/A |
-+| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
-+| ARM | Cortex-A72 | #853709 | N/A |
-+| ARM | MMU-500 | #841119,#826419 | N/A |
-+| | | | |
-+| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
-+| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
-+| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
-+| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
-+| Cavium | ThunderX SMMUv2 | #27704 | N/A |
-+| | | | |
-+| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
-+| | | | |
-+| Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 |
-diff --git a/Makefile b/Makefile
-index 4e0f962..004f90a 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 4
- PATCHLEVEL = 9
--SUBLEVEL = 16
-+SUBLEVEL = 17
- EXTRAVERSION =
- NAME = Roaring Lionus
-
-diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
-index 969ef88..cf57a77 100644
---- a/arch/arm64/Kconfig
-+++ b/arch/arm64/Kconfig
-@@ -474,6 +474,16 @@ config CAVIUM_ERRATUM_27456
-
- If unsure, say Y.
-
-+config QCOM_QDF2400_ERRATUM_0065
-+ bool "QDF2400 E0065: Incorrect GITS_TYPER.ITT_Entry_size"
-+ default y
-+ help
-+ On Qualcomm Datacenter Technologies QDF2400 SoC, ITS hardware reports
-+ ITE size incorrectly. The GITS_TYPER.ITT_Entry_size field should have
-+ been indicated as 16Bytes (0xf), not 8Bytes (0x7).
-+
-+ If unsure, say Y.
-+
- endmenu
-
-
-diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
-index 88e2f2b..55889d0 100644
---- a/arch/arm64/kvm/hyp/tlb.c
-+++ b/arch/arm64/kvm/hyp/tlb.c
-@@ -17,14 +17,62 @@
-
- #include <asm/kvm_hyp.h>
-
-+static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm)
-+{
-+ u64 val;
-+
-+ /*
-+ * With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and
-+ * most TLB operations target EL2/EL0. In order to affect the
-+ * guest TLBs (EL1/EL0), we need to change one of these two
-+ * bits. Changing E2H is impossible (goodbye TTBR1_EL2), so
-+ * let's flip TGE before executing the TLB operation.
-+ */
-+ write_sysreg(kvm->arch.vttbr, vttbr_el2);
-+ val = read_sysreg(hcr_el2);
-+ val &= ~HCR_TGE;
-+ write_sysreg(val, hcr_el2);
-+ isb();
-+}
-+
-+static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm)
-+{
-+ write_sysreg(kvm->arch.vttbr, vttbr_el2);
-+ isb();
-+}
-+
-+static hyp_alternate_select(__tlb_switch_to_guest,
-+ __tlb_switch_to_guest_nvhe,
-+ __tlb_switch_to_guest_vhe,
-+ ARM64_HAS_VIRT_HOST_EXTN);
-+
-+static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm)
-+{
-+ /*
-+ * We're done with the TLB operation, let's restore the host's
-+ * view of HCR_EL2.
-+ */
-+ write_sysreg(0, vttbr_el2);
-+ write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
-+}
-+
-+static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm)
-+{
-+ write_sysreg(0, vttbr_el2);
-+}
-+
-+static hyp_alternate_select(__tlb_switch_to_host,
-+ __tlb_switch_to_host_nvhe,
-+ __tlb_switch_to_host_vhe,
-+ ARM64_HAS_VIRT_HOST_EXTN);
-+
- void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
- {
- dsb(ishst);
-
- /* Switch to requested VMID */
- kvm = kern_hyp_va(kvm);
-- write_sysreg(kvm->arch.vttbr, vttbr_el2);
-- isb();
-+ __tlb_switch_to_guest()(kvm);
-
- /*
- * We could do so much better if we had the VA as well.
-@@ -45,7 +93,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
- dsb(ish);
- isb();
-
-- write_sysreg(0, vttbr_el2);
-+ __tlb_switch_to_host()(kvm);
- }
-
- void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
-@@ -54,14 +102,13 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
-
- /* Switch to requested VMID */
- kvm = kern_hyp_va(kvm);
-- write_sysreg(kvm->arch.vttbr, vttbr_el2);
-- isb();
-+ __tlb_switch_to_guest()(kvm);
-
- asm volatile("tlbi vmalls12e1is" : : );
- dsb(ish);
- isb();
-
-- write_sysreg(0, vttbr_el2);
-+ __tlb_switch_to_host()(kvm);
- }
-
- void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
-@@ -69,14 +116,13 @@ void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
- struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
-
- /* Switch to requested VMID */
-- write_sysreg(kvm->arch.vttbr, vttbr_el2);
-- isb();
-+ __tlb_switch_to_guest()(kvm);
-
- asm volatile("tlbi vmalle1" : : );
- dsb(nsh);
- isb();
-
-- write_sysreg(0, vttbr_el2);
-+ __tlb_switch_to_host()(kvm);
- }
-
- void __hyp_text __kvm_flush_vm_context(void)
-diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c
-index 9fa046d..4119945 100644
---- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c
-+++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c
-@@ -52,7 +52,7 @@ static int crc32c_vpmsum_cra_init(struct crypto_tfm *tfm)
- {
- u32 *key = crypto_tfm_ctx(tfm);
-
-- *key = 0;
-+ *key = ~0;
-
- return 0;
- }
-diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
-index 5c45114..b9e3f0a 100644
---- a/arch/powerpc/include/asm/mmu_context.h
-+++ b/arch/powerpc/include/asm/mmu_context.h
-@@ -19,16 +19,18 @@ extern void destroy_context(struct mm_struct *mm);
- struct mm_iommu_table_group_mem_t;
-
- extern int isolate_lru_page(struct page *page); /* from internal.h */
--extern bool mm_iommu_preregistered(void);
--extern long mm_iommu_get(unsigned long ua, unsigned long entries,
-+extern bool mm_iommu_preregistered(struct mm_struct *mm);
-+extern long mm_iommu_get(struct mm_struct *mm,
-+ unsigned long ua, unsigned long entries,
- struct mm_iommu_table_group_mem_t **pmem);
--extern long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem);
--extern void mm_iommu_init(mm_context_t *ctx);
--extern void mm_iommu_cleanup(mm_context_t *ctx);
--extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(unsigned long ua,
-- unsigned long size);
--extern struct mm_iommu_table_group_mem_t *mm_iommu_find(unsigned long ua,
-- unsigned long entries);
-+extern long mm_iommu_put(struct mm_struct *mm,
-+ struct mm_iommu_table_group_mem_t *mem);
-+extern void mm_iommu_init(struct mm_struct *mm);
-+extern void mm_iommu_cleanup(struct mm_struct *mm);
-+extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm,
-+ unsigned long ua, unsigned long size);
-+extern struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm,
-+ unsigned long ua, unsigned long entries);
- extern long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem,
- unsigned long ua, unsigned long *hpa);
- extern long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem);
-diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
-index 270ee30..f516ac5 100644
---- a/arch/powerpc/kernel/setup-common.c
-+++ b/arch/powerpc/kernel/setup-common.c
-@@ -915,7 +915,7 @@ void __init setup_arch(char **cmdline_p)
- init_mm.context.pte_frag = NULL;
- #endif
- #ifdef CONFIG_SPAPR_TCE_IOMMU
-- mm_iommu_init(&init_mm.context);
-+ mm_iommu_init(&init_mm);
- #endif
- irqstack_early_init();
- exc_lvl_early_init();
-diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c
-index b114f8b..73bf6e1 100644
---- a/arch/powerpc/mm/mmu_context_book3s64.c
-+++ b/arch/powerpc/mm/mmu_context_book3s64.c
-@@ -115,7 +115,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
- mm->context.pte_frag = NULL;
- #endif
- #ifdef CONFIG_SPAPR_TCE_IOMMU
-- mm_iommu_init(&mm->context);
-+ mm_iommu_init(mm);
- #endif
- return 0;
- }
-@@ -156,13 +156,11 @@ static inline void destroy_pagetable_page(struct mm_struct *mm)
- }
- #endif
-
--
- void destroy_context(struct mm_struct *mm)
- {
- #ifdef CONFIG_SPAPR_TCE_IOMMU
-- mm_iommu_cleanup(&mm->context);
-+ WARN_ON_ONCE(!list_empty(&mm->context.iommu_group_mem_list));
- #endif
--
- #ifdef CONFIG_PPC_ICSWX
- drop_cop(mm->context.acop, mm);
- kfree(mm->context.cop_lockp);
-diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c
-index e0f1c33..7de7124 100644
---- a/arch/powerpc/mm/mmu_context_iommu.c
-+++ b/arch/powerpc/mm/mmu_context_iommu.c
-@@ -56,7 +56,7 @@ static long mm_iommu_adjust_locked_vm(struct mm_struct *mm,
- }
-
- pr_debug("[%d] RLIMIT_MEMLOCK HASH64 %c%ld %ld/%ld\n",
-- current->pid,
-+ current ? current->pid : 0,
- incr ? '+' : '-',
- npages << PAGE_SHIFT,
- mm->locked_vm << PAGE_SHIFT,
-@@ -66,12 +66,9 @@ static long mm_iommu_adjust_locked_vm(struct mm_struct *mm,
- return ret;
- }
-
--bool mm_iommu_preregistered(void)
-+bool mm_iommu_preregistered(struct mm_struct *mm)
- {
-- if (!current || !current->mm)
-- return false;
--
-- return !list_empty(&current->mm->context.iommu_group_mem_list);
-+ return !list_empty(&mm->context.iommu_group_mem_list);
- }
- EXPORT_SYMBOL_GPL(mm_iommu_preregistered);
-
-@@ -124,19 +121,16 @@ static int mm_iommu_move_page_from_cma(struct page *page)
- return 0;
- }
-
--long mm_iommu_get(unsigned long ua, unsigned long entries,
-+long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries,
- struct mm_iommu_table_group_mem_t **pmem)
- {
- struct mm_iommu_table_group_mem_t *mem;
- long i, j, ret = 0, locked_entries = 0;
- struct page *page = NULL;
-
-- if (!current || !current->mm)
-- return -ESRCH; /* process exited */
--
- mutex_lock(&mem_list_mutex);
-
-- list_for_each_entry_rcu(mem, &current->mm->context.iommu_group_mem_list,
-+ list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list,
- next) {
- if ((mem->ua == ua) && (mem->entries == entries)) {
- ++mem->used;
-@@ -154,7 +148,7 @@ long mm_iommu_get(unsigned long ua, unsigned long entries,
-
- }
-
-- ret = mm_iommu_adjust_locked_vm(current->mm, entries, true);
-+ ret = mm_iommu_adjust_locked_vm(mm, entries, true);
- if (ret)
- goto unlock_exit;
-
-@@ -190,7 +184,7 @@ long mm_iommu_get(unsigned long ua, unsigned long entries,
- * of the CMA zone if possible. NOTE: faulting in + migration
- * can be expensive. Batching can be considered later
- */
-- if (get_pageblock_migratetype(page) == MIGRATE_CMA) {
-+ if (is_migrate_cma_page(page)) {
- if (mm_iommu_move_page_from_cma(page))
- goto populate;
- if (1 != get_user_pages_fast(ua + (i << PAGE_SHIFT),
-@@ -215,11 +209,11 @@ long mm_iommu_get(unsigned long ua, unsigned long entries,
- mem->entries = entries;
- *pmem = mem;
-
-- list_add_rcu(&mem->next, &current->mm->context.iommu_group_mem_list);
-+ list_add_rcu(&mem->next, &mm->context.iommu_group_mem_list);
-
- unlock_exit:
- if (locked_entries && ret)
-- mm_iommu_adjust_locked_vm(current->mm, locked_entries, false);
-+ mm_iommu_adjust_locked_vm(mm, locked_entries, false);
-
- mutex_unlock(&mem_list_mutex);
-
-@@ -264,17 +258,13 @@ static void mm_iommu_free(struct rcu_head *head)
- static void mm_iommu_release(struct mm_iommu_table_group_mem_t *mem)
- {
- list_del_rcu(&mem->next);
-- mm_iommu_adjust_locked_vm(current->mm, mem->entries, false);
- call_rcu(&mem->rcu, mm_iommu_free);
- }
-
--long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem)
-+long mm_iommu_put(struct mm_struct *mm, struct mm_iommu_table_group_mem_t *mem)
- {
- long ret = 0;
-
-- if (!current || !current->mm)
-- return -ESRCH; /* process exited */
--
- mutex_lock(&mem_list_mutex);
-
- if (mem->used == 0) {
-@@ -297,6 +287,8 @@ long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem)
- /* @mapped became 0 so now mappings are disabled, release the region */
- mm_iommu_release(mem);
-
-+ mm_iommu_adjust_locked_vm(mm, mem->entries, false);
-+
- unlock_exit:
- mutex_unlock(&mem_list_mutex);
-
-@@ -304,14 +296,12 @@ long mm_iommu_put(struct mm_iommu_table_group_mem_t *mem)
- }
- EXPORT_SYMBOL_GPL(mm_iommu_put);
-
--struct mm_iommu_table_group_mem_t *mm_iommu_lookup(unsigned long ua,
-- unsigned long size)
-+struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct mm_struct *mm,
-+ unsigned long ua, unsigned long size)
- {
- struct mm_iommu_table_group_mem_t *mem, *ret = NULL;
-
-- list_for_each_entry_rcu(mem,
-- &current->mm->context.iommu_group_mem_list,
-- next) {
-+ list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) {
- if ((mem->ua <= ua) &&
- (ua + size <= mem->ua +
- (mem->entries << PAGE_SHIFT))) {
-@@ -324,14 +314,12 @@ struct mm_iommu_table_group_mem_t *mm_iommu_lookup(unsigned long ua,
- }
- EXPORT_SYMBOL_GPL(mm_iommu_lookup);
-
--struct mm_iommu_table_group_mem_t *mm_iommu_find(unsigned long ua,
-- unsigned long entries)
-+struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm,
-+ unsigned long ua, unsigned long entries)
- {
- struct mm_iommu_table_group_mem_t *mem, *ret = NULL;
-
-- list_for_each_entry_rcu(mem,
-- &current->mm->context.iommu_group_mem_list,
-- next) {
-+ list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) {
- if ((mem->ua == ua) && (mem->entries == entries)) {
- ret = mem;
- break;
-@@ -373,17 +361,7 @@ void mm_iommu_mapped_dec(struct mm_iommu_table_group_mem_t *mem)
- }
- EXPORT_SYMBOL_GPL(mm_iommu_mapped_dec);
-
--void mm_iommu_init(mm_context_t *ctx)
-+void mm_iommu_init(struct mm_struct *mm)
- {
-- INIT_LIST_HEAD_RCU(&ctx->iommu_group_mem_list);
--}
--
--void mm_iommu_cleanup(mm_context_t *ctx)
--{
-- struct mm_iommu_table_group_mem_t *mem, *tmp;
--
-- list_for_each_entry_safe(mem, tmp, &ctx->iommu_group_mem_list, next) {
-- list_del_rcu(&mem->next);
-- mm_iommu_do_free(mem);
-- }
-+ INIT_LIST_HEAD_RCU(&mm->context.iommu_group_mem_list);
- }
-diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
-index 7fe88bb..38623e2 100644
---- a/arch/x86/events/core.c
-+++ b/arch/x86/events/core.c
-@@ -2096,8 +2096,8 @@ static int x86_pmu_event_init(struct perf_event *event)
-
- static void refresh_pce(void *ignored)
- {
-- if (current->mm)
-- load_mm_cr4(current->mm);
-+ if (current->active_mm)
-+ load_mm_cr4(current->active_mm);
- }
-
- static void x86_pmu_event_mapped(struct perf_event *event)
-diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
-index 8f44c5a..f228f74 100644
---- a/arch/x86/kernel/cpu/mshyperv.c
-+++ b/arch/x86/kernel/cpu/mshyperv.c
-@@ -31,6 +31,7 @@
- #include <asm/apic.h>
- #include <asm/timer.h>
- #include <asm/reboot.h>
-+#include <asm/nmi.h>
-
- struct ms_hyperv_info ms_hyperv;
- EXPORT_SYMBOL_GPL(ms_hyperv);
-@@ -158,6 +159,26 @@ static unsigned char hv_get_nmi_reason(void)
- return 0;
- }
-
-+#ifdef CONFIG_X86_LOCAL_APIC
-+/*
-+ * Prior to WS2016 Debug-VM sends NMIs to all CPUs which makes
-+ * it dificult to process CHANNELMSG_UNLOAD in case of crash. Handle
-+ * unknown NMI on the first CPU which gets it.
-+ */
-+static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs)
-+{
-+ static atomic_t nmi_cpu = ATOMIC_INIT(-1);
-+
-+ if (!unknown_nmi_panic)
-+ return NMI_DONE;
-+
-+ if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1)
-+ return NMI_HANDLED;
-+
-+ return NMI_DONE;
-+}
-+#endif
-+
- static void __init ms_hyperv_init_platform(void)
- {
- /*
-@@ -183,6 +204,9 @@ static void __init ms_hyperv_init_platform(void)
- pr_info("HyperV: LAPIC Timer Frequency: %#x\n",
- lapic_timer_frequency);
- }
-+
-+ register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST,
-+ "hv_nmi_unknown");
- #endif
-
- if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
-diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
-index 54a2372..b5785c1 100644
---- a/arch/x86/kernel/head64.c
-+++ b/arch/x86/kernel/head64.c
-@@ -4,6 +4,7 @@
- * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
- */
-
-+#define DISABLE_BRANCH_PROFILING
- #include <linux/init.h>
- #include <linux/linkage.h>
- #include <linux/types.h>
-diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
-index 46b2f41..eea88fe 100644
---- a/arch/x86/kernel/tsc.c
-+++ b/arch/x86/kernel/tsc.c
-@@ -1287,6 +1287,8 @@ static int __init init_tsc_clocksource(void)
- * exporting a reliable TSC.
- */
- if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
-+ if (boot_cpu_has(X86_FEATURE_ART))
-+ art_related_clocksource = &clocksource_tsc;
- clocksource_register_khz(&clocksource_tsc, tsc_khz);
- return 0;
- }
-diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
-index 0493c17..333362f 100644
---- a/arch/x86/mm/kasan_init_64.c
-+++ b/arch/x86/mm/kasan_init_64.c
-@@ -1,3 +1,4 @@
-+#define DISABLE_BRANCH_PROFILING
- #define pr_fmt(fmt) "kasan: " fmt
- #include <linux/bootmem.h>
- #include <linux/kasan.h>
-diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
-index bedfab9..a00a6c0 100644
---- a/arch/x86/pci/xen.c
-+++ b/arch/x86/pci/xen.c
-@@ -234,23 +234,14 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
- return 1;
-
- for_each_pci_msi_entry(msidesc, dev) {
-- __pci_read_msi_msg(msidesc, &msg);
-- pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
-- ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
-- if (msg.data != XEN_PIRQ_MSI_DATA ||
-- xen_irq_from_pirq(pirq) < 0) {
-- pirq = xen_allocate_pirq_msi(dev, msidesc);
-- if (pirq < 0) {
-- irq = -ENODEV;
-- goto error;
-- }
-- xen_msi_compose_msg(dev, pirq, &msg);
-- __pci_write_msi_msg(msidesc, &msg);
-- dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
-- } else {
-- dev_dbg(&dev->dev,
-- "xen: msi already bound to pirq=%d\n", pirq);
-+ pirq = xen_allocate_pirq_msi(dev, msidesc);
-+ if (pirq < 0) {
-+ irq = -ENODEV;
-+ goto error;
- }
-+ xen_msi_compose_msg(dev, pirq, &msg);
-+ __pci_write_msi_msg(msidesc, &msg);
-+ dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
- irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
- (type == PCI_CAP_ID_MSI) ? nvec : 1,
- (type == PCI_CAP_ID_MSIX) ?
-diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
-index 0774799..c6fee74 100644
---- a/block/scsi_ioctl.c
-+++ b/block/scsi_ioctl.c
-@@ -182,6 +182,9 @@ static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
- __set_bit(WRITE_16, filter->write_ok);
- __set_bit(WRITE_LONG, filter->write_ok);
- __set_bit(WRITE_LONG_2, filter->write_ok);
-+ __set_bit(WRITE_SAME, filter->write_ok);
-+ __set_bit(WRITE_SAME_16, filter->write_ok);
-+ __set_bit(WRITE_SAME_32, filter->write_ok);
- __set_bit(ERASE, filter->write_ok);
- __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok);
- __set_bit(MODE_SELECT, filter->write_ok);
-diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
-index bdc67ba..4421f7c 100644
---- a/drivers/acpi/blacklist.c
-+++ b/drivers/acpi/blacklist.c
-@@ -160,6 +160,34 @@ static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
- DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
- },
- },
-+ {
-+ .callback = dmi_enable_rev_override,
-+ .ident = "DELL Precision 5520",
-+ .matches = {
-+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-+ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5520"),
-+ },
-+ },
-+ {
-+ .callback = dmi_enable_rev_override,
-+ .ident = "DELL Precision 3520",
-+ .matches = {
-+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-+ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520"),
-+ },
-+ },
-+ /*
-+ * Resolves a quirk with the Dell Latitude 3350 that
-+ * causes the ethernet adapter to not function.
-+ */
-+ {
-+ .callback = dmi_enable_rev_override,
-+ .ident = "DELL Latitude 3350",
-+ .matches = {
-+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350"),
-+ },
-+ },
- #endif
- {}
- };
-diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
-index 3bbd2a5..2acaa77 100644
---- a/drivers/clk/bcm/clk-bcm2835.c
-+++ b/drivers/clk/bcm/clk-bcm2835.c
-@@ -1598,7 +1598,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
- .a2w_reg = A2W_PLLH_AUX,
- .load_mask = CM_PLLH_LOADAUX,
- .hold_mask = 0,
-- .fixed_divider = 10),
-+ .fixed_divider = 1),
- [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
- .name = "pllh_pix",
- .source_pll = "pllh",
-diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c
-index 015f711..d235fbe 100644
---- a/drivers/dma/ioat/init.c
-+++ b/drivers/dma/ioat/init.c
-@@ -691,7 +691,7 @@ static int ioat_alloc_chan_resources(struct dma_chan *c)
- /* doing 2 32bit writes to mmio since 1 64b write doesn't work */
- ioat_chan->completion =
- dma_pool_zalloc(ioat_chan->ioat_dma->completion_pool,
-- GFP_KERNEL, &ioat_chan->completion_dma);
-+ GFP_NOWAIT, &ioat_chan->completion_dma);
- if (!ioat_chan->completion)
- return -ENOMEM;
-
-@@ -701,7 +701,7 @@ static int ioat_alloc_chan_resources(struct dma_chan *c)
- ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
-
- order = IOAT_MAX_ORDER;
-- ring = ioat_alloc_ring(c, order, GFP_KERNEL);
-+ ring = ioat_alloc_ring(c, order, GFP_NOWAIT);
- if (!ring)
- return -ENOMEM;
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
-index 77a52b5..70f0344 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
-@@ -95,9 +95,11 @@ nvkm-y += nvkm/engine/disp/cursg84.o
- nvkm-y += nvkm/engine/disp/cursgt215.o
- nvkm-y += nvkm/engine/disp/cursgf119.o
- nvkm-y += nvkm/engine/disp/cursgk104.o
-+nvkm-y += nvkm/engine/disp/cursgp102.o
-
- nvkm-y += nvkm/engine/disp/oimmnv50.o
- nvkm-y += nvkm/engine/disp/oimmg84.o
- nvkm-y += nvkm/engine/disp/oimmgt215.o
- nvkm-y += nvkm/engine/disp/oimmgf119.o
- nvkm-y += nvkm/engine/disp/oimmgk104.o
-+nvkm-y += nvkm/engine/disp/oimmgp102.o
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
-index dd2953b..9d90d8b 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
-@@ -82,7 +82,7 @@ nv50_disp_chan_mthd(struct nv50_disp_chan *chan, int debug)
-
- if (mthd->addr) {
- snprintf(cname_, sizeof(cname_), "%s %d",
-- mthd->name, chan->chid);
-+ mthd->name, chan->chid.user);
- cname = cname_;
- }
-
-@@ -139,7 +139,7 @@ nv50_disp_chan_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
- if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
- notify->size = sizeof(struct nvif_notify_uevent_rep);
- notify->types = 1;
-- notify->index = chan->chid;
-+ notify->index = chan->chid.user;
- return 0;
- }
-
-@@ -159,7 +159,7 @@ nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data)
- struct nv50_disp_chan *chan = nv50_disp_chan(object);
- struct nv50_disp *disp = chan->root->disp;
- struct nvkm_device *device = disp->base.engine.subdev.device;
-- *data = nvkm_rd32(device, 0x640000 + (chan->chid * 0x1000) + addr);
-+ *data = nvkm_rd32(device, 0x640000 + (chan->chid.user * 0x1000) + addr);
- return 0;
- }
-
-@@ -169,7 +169,7 @@ nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data)
- struct nv50_disp_chan *chan = nv50_disp_chan(object);
- struct nv50_disp *disp = chan->root->disp;
- struct nvkm_device *device = disp->base.engine.subdev.device;
-- nvkm_wr32(device, 0x640000 + (chan->chid * 0x1000) + addr, data);
-+ nvkm_wr32(device, 0x640000 + (chan->chid.user * 0x1000) + addr, data);
- return 0;
- }
-
-@@ -196,7 +196,7 @@ nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size)
- struct nv50_disp *disp = chan->root->disp;
- struct nvkm_device *device = disp->base.engine.subdev.device;
- *addr = device->func->resource_addr(device, 0) +
-- 0x640000 + (chan->chid * 0x1000);
-+ 0x640000 + (chan->chid.user * 0x1000);
- *size = 0x001000;
- return 0;
- }
-@@ -243,8 +243,8 @@ nv50_disp_chan_dtor(struct nvkm_object *object)
- {
- struct nv50_disp_chan *chan = nv50_disp_chan(object);
- struct nv50_disp *disp = chan->root->disp;
-- if (chan->chid >= 0)
-- disp->chan[chan->chid] = NULL;
-+ if (chan->chid.user >= 0)
-+ disp->chan[chan->chid.user] = NULL;
- return chan->func->dtor ? chan->func->dtor(chan) : chan;
- }
-
-@@ -263,7 +263,7 @@ nv50_disp_chan = {
- int
- nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func,
- const struct nv50_disp_chan_mthd *mthd,
-- struct nv50_disp_root *root, int chid, int head,
-+ struct nv50_disp_root *root, int ctrl, int user, int head,
- const struct nvkm_oclass *oclass,
- struct nv50_disp_chan *chan)
- {
-@@ -273,21 +273,22 @@ nv50_disp_chan_ctor(const struct nv50_disp_chan_func *func,
- chan->func = func;
- chan->mthd = mthd;
- chan->root = root;
-- chan->chid = chid;
-+ chan->chid.ctrl = ctrl;
-+ chan->chid.user = user;
- chan->head = head;
-
-- if (disp->chan[chan->chid]) {
-- chan->chid = -1;
-+ if (disp->chan[chan->chid.user]) {
-+ chan->chid.user = -1;
- return -EBUSY;
- }
-- disp->chan[chan->chid] = chan;
-+ disp->chan[chan->chid.user] = chan;
- return 0;
- }
-
- int
- nv50_disp_chan_new_(const struct nv50_disp_chan_func *func,
- const struct nv50_disp_chan_mthd *mthd,
-- struct nv50_disp_root *root, int chid, int head,
-+ struct nv50_disp_root *root, int ctrl, int user, int head,
- const struct nvkm_oclass *oclass,
- struct nvkm_object **pobject)
- {
-@@ -297,5 +298,6 @@ nv50_disp_chan_new_(const struct nv50_disp_chan_func *func,
- return -ENOMEM;
- *pobject = &chan->object;
-
-- return nv50_disp_chan_ctor(func, mthd, root, chid, head, oclass, chan);
-+ return nv50_disp_chan_ctor(func, mthd, root, ctrl, user,
-+ head, oclass, chan);
- }
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h
-index f5f683d..737b38f 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.h
-@@ -7,7 +7,11 @@ struct nv50_disp_chan {
- const struct nv50_disp_chan_func *func;
- const struct nv50_disp_chan_mthd *mthd;
- struct nv50_disp_root *root;
-- int chid;
-+
-+ struct {
-+ int ctrl;
-+ int user;
-+ } chid;
- int head;
-
- struct nvkm_object object;
-@@ -25,11 +29,11 @@ struct nv50_disp_chan_func {
-
- int nv50_disp_chan_ctor(const struct nv50_disp_chan_func *,
- const struct nv50_disp_chan_mthd *,
-- struct nv50_disp_root *, int chid, int head,
-+ struct nv50_disp_root *, int ctrl, int user, int head,
- const struct nvkm_oclass *, struct nv50_disp_chan *);
- int nv50_disp_chan_new_(const struct nv50_disp_chan_func *,
- const struct nv50_disp_chan_mthd *,
-- struct nv50_disp_root *, int chid, int head,
-+ struct nv50_disp_root *, int ctrl, int user, int head,
- const struct nvkm_oclass *, struct nvkm_object **);
-
- extern const struct nv50_disp_chan_func nv50_disp_pioc_func;
-@@ -90,13 +94,16 @@ extern const struct nv50_disp_chan_mthd gk104_disp_ovly_chan_mthd;
- struct nv50_disp_pioc_oclass {
- int (*ctor)(const struct nv50_disp_chan_func *,
- const struct nv50_disp_chan_mthd *,
-- struct nv50_disp_root *, int chid,
-+ struct nv50_disp_root *, int ctrl, int user,
- const struct nvkm_oclass *, void *data, u32 size,
- struct nvkm_object **);
- struct nvkm_sclass base;
- const struct nv50_disp_chan_func *func;
- const struct nv50_disp_chan_mthd *mthd;
-- int chid;
-+ struct {
-+ int ctrl;
-+ int user;
-+ } chid;
- };
-
- extern const struct nv50_disp_pioc_oclass nv50_disp_oimm_oclass;
-@@ -114,15 +121,17 @@ extern const struct nv50_disp_pioc_oclass gf119_disp_curs_oclass;
- extern const struct nv50_disp_pioc_oclass gk104_disp_oimm_oclass;
- extern const struct nv50_disp_pioc_oclass gk104_disp_curs_oclass;
-
-+extern const struct nv50_disp_pioc_oclass gp102_disp_oimm_oclass;
-+extern const struct nv50_disp_pioc_oclass gp102_disp_curs_oclass;
-
- int nv50_disp_curs_new(const struct nv50_disp_chan_func *,
- const struct nv50_disp_chan_mthd *,
-- struct nv50_disp_root *, int chid,
-+ struct nv50_disp_root *, int ctrl, int user,
- const struct nvkm_oclass *, void *data, u32 size,
- struct nvkm_object **);
- int nv50_disp_oimm_new(const struct nv50_disp_chan_func *,
- const struct nv50_disp_chan_mthd *,
-- struct nv50_disp_root *, int chid,
-+ struct nv50_disp_root *, int ctrl, int user,
- const struct nvkm_oclass *, void *data, u32 size,
- struct nvkm_object **);
- #endif
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c
-index dd99fc7..fa781b5 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursg84.c
-@@ -33,5 +33,5 @@ g84_disp_curs_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_curs_new,
- .func = &nv50_disp_pioc_func,
-- .chid = 7,
-+ .chid = { 7, 7 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c
-index 2a1574e..2be6fb0 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgf119.c
-@@ -33,5 +33,5 @@ gf119_disp_curs_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_curs_new,
- .func = &gf119_disp_pioc_func,
-- .chid = 13,
-+ .chid = { 13, 13 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c
-index 28e8f06..2a99db4 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgk104.c
-@@ -33,5 +33,5 @@ gk104_disp_curs_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_curs_new,
- .func = &gf119_disp_pioc_func,
-- .chid = 13,
-+ .chid = { 13, 13 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c
-new file mode 100644
-index 0000000..e958210
---- /dev/null
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgp102.c
-@@ -0,0 +1,37 @@
-+/*
-+ * Copyright 2016 Red Hat Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: Ben Skeggs <bskeggs@redhat.com>
-+ */
-+#include "channv50.h"
-+#include "rootnv50.h"
-+
-+#include <nvif/class.h>
-+
-+const struct nv50_disp_pioc_oclass
-+gp102_disp_curs_oclass = {
-+ .base.oclass = GK104_DISP_CURSOR,
-+ .base.minver = 0,
-+ .base.maxver = 0,
-+ .ctor = nv50_disp_curs_new,
-+ .func = &gf119_disp_pioc_func,
-+ .chid = { 13, 17 },
-+};
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c
-index d8a4b9c..00a7f35 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgt215.c
-@@ -33,5 +33,5 @@ gt215_disp_curs_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_curs_new,
- .func = &nv50_disp_pioc_func,
-- .chid = 7,
-+ .chid = { 7, 7 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c
-index 8b13204..82ff82d 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/cursnv50.c
-@@ -33,7 +33,7 @@
- int
- nv50_disp_curs_new(const struct nv50_disp_chan_func *func,
- const struct nv50_disp_chan_mthd *mthd,
-- struct nv50_disp_root *root, int chid,
-+ struct nv50_disp_root *root, int ctrl, int user,
- const struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
- {
-@@ -54,7 +54,7 @@ nv50_disp_curs_new(const struct nv50_disp_chan_func *func,
- } else
- return ret;
-
-- return nv50_disp_chan_new_(func, mthd, root, chid + head,
-+ return nv50_disp_chan_new_(func, mthd, root, ctrl + head, user + head,
- head, oclass, pobject);
- }
-
-@@ -65,5 +65,5 @@ nv50_disp_curs_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_curs_new,
- .func = &nv50_disp_pioc_func,
-- .chid = 7,
-+ .chid = { 7, 7 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c
-index a57f7ce..ce7cd74 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgf119.c
-@@ -32,8 +32,8 @@ gf119_disp_dmac_bind(struct nv50_disp_dmac *chan,
- struct nvkm_object *object, u32 handle)
- {
- return nvkm_ramht_insert(chan->base.root->ramht, object,
-- chan->base.chid, -9, handle,
-- chan->base.chid << 27 | 0x00000001);
-+ chan->base.chid.user, -9, handle,
-+ chan->base.chid.user << 27 | 0x00000001);
- }
-
- void
-@@ -42,22 +42,23 @@ gf119_disp_dmac_fini(struct nv50_disp_dmac *chan)
- struct nv50_disp *disp = chan->base.root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->base.chid;
-+ int ctrl = chan->base.chid.ctrl;
-+ int user = chan->base.chid.user;
-
- /* deactivate channel */
-- nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00001010, 0x00001000);
-- nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000003, 0x00000000);
-+ nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00001010, 0x00001000);
-+ nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000003, 0x00000000);
- if (nvkm_msec(device, 2000,
-- if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x001e0000))
-+ if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x001e0000))
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d fini: %08x\n", chid,
-- nvkm_rd32(device, 0x610490 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d fini: %08x\n", user,
-+ nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
- }
-
- /* disable error reporting and completion notification */
-- nvkm_mask(device, 0x610090, 0x00000001 << chid, 0x00000000);
-- nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000000);
-+ nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000);
-+ nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000);
- }
-
- static int
-@@ -66,26 +67,27 @@ gf119_disp_dmac_init(struct nv50_disp_dmac *chan)
- struct nv50_disp *disp = chan->base.root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->base.chid;
-+ int ctrl = chan->base.chid.ctrl;
-+ int user = chan->base.chid.user;
-
- /* enable error reporting */
-- nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
-+ nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
-
- /* initialise channel for dma command submission */
-- nvkm_wr32(device, 0x610494 + (chid * 0x0010), chan->push);
-- nvkm_wr32(device, 0x610498 + (chid * 0x0010), 0x00010000);
-- nvkm_wr32(device, 0x61049c + (chid * 0x0010), 0x00000001);
-- nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000010, 0x00000010);
-- nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
-- nvkm_wr32(device, 0x610490 + (chid * 0x0010), 0x00000013);
-+ nvkm_wr32(device, 0x610494 + (ctrl * 0x0010), chan->push);
-+ nvkm_wr32(device, 0x610498 + (ctrl * 0x0010), 0x00010000);
-+ nvkm_wr32(device, 0x61049c + (ctrl * 0x0010), 0x00000001);
-+ nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
-+ nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
-+ nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);
-
- /* wait for it to go inactive */
- if (nvkm_msec(device, 2000,
-- if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x80000000))
-+ if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d init: %08x\n", chid,
-- nvkm_rd32(device, 0x610490 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d init: %08x\n", user,
-+ nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
- return -EBUSY;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp104.c
-index ad24c2c..d26d3b4 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp104.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacgp104.c
-@@ -32,26 +32,27 @@ gp104_disp_dmac_init(struct nv50_disp_dmac *chan)
- struct nv50_disp *disp = chan->base.root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->base.chid;
-+ int ctrl = chan->base.chid.ctrl;
-+ int user = chan->base.chid.user;
-
- /* enable error reporting */
-- nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
-+ nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
-
- /* initialise channel for dma command submission */
-- nvkm_wr32(device, 0x611494 + (chid * 0x0010), chan->push);
-- nvkm_wr32(device, 0x611498 + (chid * 0x0010), 0x00010000);
-- nvkm_wr32(device, 0x61149c + (chid * 0x0010), 0x00000001);
-- nvkm_mask(device, 0x610490 + (chid * 0x0010), 0x00000010, 0x00000010);
-- nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
-- nvkm_wr32(device, 0x610490 + (chid * 0x0010), 0x00000013);
-+ nvkm_wr32(device, 0x611494 + (ctrl * 0x0010), chan->push);
-+ nvkm_wr32(device, 0x611498 + (ctrl * 0x0010), 0x00010000);
-+ nvkm_wr32(device, 0x61149c + (ctrl * 0x0010), 0x00000001);
-+ nvkm_mask(device, 0x610490 + (ctrl * 0x0010), 0x00000010, 0x00000010);
-+ nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
-+ nvkm_wr32(device, 0x610490 + (ctrl * 0x0010), 0x00000013);
-
- /* wait for it to go inactive */
- if (nvkm_msec(device, 2000,
-- if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x80000000))
-+ if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x80000000))
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d init: %08x\n", chid,
-- nvkm_rd32(device, 0x610490 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d init: %08x\n", user,
-+ nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
- return -EBUSY;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c
-index 9c6645a..0a1381a 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c
-@@ -149,7 +149,7 @@ nv50_disp_dmac_new_(const struct nv50_disp_dmac_func *func,
- chan->func = func;
-
- ret = nv50_disp_chan_ctor(&nv50_disp_dmac_func_, mthd, root,
-- chid, head, oclass, &chan->base);
-+ chid, chid, head, oclass, &chan->base);
- if (ret)
- return ret;
-
-@@ -179,9 +179,9 @@ nv50_disp_dmac_bind(struct nv50_disp_dmac *chan,
- struct nvkm_object *object, u32 handle)
- {
- return nvkm_ramht_insert(chan->base.root->ramht, object,
-- chan->base.chid, -10, handle,
-- chan->base.chid << 28 |
-- chan->base.chid);
-+ chan->base.chid.user, -10, handle,
-+ chan->base.chid.user << 28 |
-+ chan->base.chid.user);
- }
-
- static void
-@@ -190,21 +190,22 @@ nv50_disp_dmac_fini(struct nv50_disp_dmac *chan)
- struct nv50_disp *disp = chan->base.root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->base.chid;
-+ int ctrl = chan->base.chid.ctrl;
-+ int user = chan->base.chid.user;
-
- /* deactivate channel */
-- nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00001010, 0x00001000);
-- nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00000003, 0x00000000);
-+ nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00001010, 0x00001000);
-+ nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000003, 0x00000000);
- if (nvkm_msec(device, 2000,
-- if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x001e0000))
-+ if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x001e0000))
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d fini timeout, %08x\n", chid,
-- nvkm_rd32(device, 0x610200 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d fini timeout, %08x\n", user,
-+ nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
- }
-
- /* disable error reporting and completion notifications */
-- nvkm_mask(device, 0x610028, 0x00010001 << chid, 0x00000000 << chid);
-+ nvkm_mask(device, 0x610028, 0x00010001 << user, 0x00000000 << user);
- }
-
- static int
-@@ -213,26 +214,27 @@ nv50_disp_dmac_init(struct nv50_disp_dmac *chan)
- struct nv50_disp *disp = chan->base.root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->base.chid;
-+ int ctrl = chan->base.chid.ctrl;
-+ int user = chan->base.chid.user;
-
- /* enable error reporting */
-- nvkm_mask(device, 0x610028, 0x00010000 << chid, 0x00010000 << chid);
-+ nvkm_mask(device, 0x610028, 0x00010000 << user, 0x00010000 << user);
-
- /* initialise channel for dma command submission */
-- nvkm_wr32(device, 0x610204 + (chid * 0x0010), chan->push);
-- nvkm_wr32(device, 0x610208 + (chid * 0x0010), 0x00010000);
-- nvkm_wr32(device, 0x61020c + (chid * 0x0010), chid);
-- nvkm_mask(device, 0x610200 + (chid * 0x0010), 0x00000010, 0x00000010);
-- nvkm_wr32(device, 0x640000 + (chid * 0x1000), 0x00000000);
-- nvkm_wr32(device, 0x610200 + (chid * 0x0010), 0x00000013);
-+ nvkm_wr32(device, 0x610204 + (ctrl * 0x0010), chan->push);
-+ nvkm_wr32(device, 0x610208 + (ctrl * 0x0010), 0x00010000);
-+ nvkm_wr32(device, 0x61020c + (ctrl * 0x0010), ctrl);
-+ nvkm_mask(device, 0x610200 + (ctrl * 0x0010), 0x00000010, 0x00000010);
-+ nvkm_wr32(device, 0x640000 + (ctrl * 0x1000), 0x00000000);
-+ nvkm_wr32(device, 0x610200 + (ctrl * 0x0010), 0x00000013);
-
- /* wait for it to go inactive */
- if (nvkm_msec(device, 2000,
-- if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x80000000))
-+ if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x80000000))
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d init timeout, %08x\n", chid,
-- nvkm_rd32(device, 0x610200 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d init timeout, %08x\n", user,
-+ nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
- return -EBUSY;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c
-index 54a4ae8..5ad5d0f 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmg84.c
-@@ -33,5 +33,5 @@ g84_disp_oimm_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_oimm_new,
- .func = &nv50_disp_pioc_func,
-- .chid = 5,
-+ .chid = { 5, 5 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c
-index c658db5..1f9fd34 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgf119.c
-@@ -33,5 +33,5 @@ gf119_disp_oimm_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_oimm_new,
- .func = &gf119_disp_pioc_func,
-- .chid = 9,
-+ .chid = { 9, 9 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c
-index b1fde8c..0c09fe8 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgk104.c
-@@ -33,5 +33,5 @@ gk104_disp_oimm_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_oimm_new,
- .func = &gf119_disp_pioc_func,
-- .chid = 9,
-+ .chid = { 9, 9 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c
-new file mode 100644
-index 0000000..abf8236
---- /dev/null
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgp102.c
-@@ -0,0 +1,37 @@
-+/*
-+ * Copyright 2016 Red Hat Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: Ben Skeggs <bskeggs@redhat.com>
-+ */
-+#include "channv50.h"
-+#include "rootnv50.h"
-+
-+#include <nvif/class.h>
-+
-+const struct nv50_disp_pioc_oclass
-+gp102_disp_oimm_oclass = {
-+ .base.oclass = GK104_DISP_OVERLAY,
-+ .base.minver = 0,
-+ .base.maxver = 0,
-+ .ctor = nv50_disp_oimm_new,
-+ .func = &gf119_disp_pioc_func,
-+ .chid = { 9, 13 },
-+};
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c
-index f4e7eb3..1281db2 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmgt215.c
-@@ -33,5 +33,5 @@ gt215_disp_oimm_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_oimm_new,
- .func = &nv50_disp_pioc_func,
-- .chid = 5,
-+ .chid = { 5, 5 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c
-index 3940b9c..07540f3 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/oimmnv50.c
-@@ -33,7 +33,7 @@
- int
- nv50_disp_oimm_new(const struct nv50_disp_chan_func *func,
- const struct nv50_disp_chan_mthd *mthd,
-- struct nv50_disp_root *root, int chid,
-+ struct nv50_disp_root *root, int ctrl, int user,
- const struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
- {
-@@ -54,7 +54,7 @@ nv50_disp_oimm_new(const struct nv50_disp_chan_func *func,
- } else
- return ret;
-
-- return nv50_disp_chan_new_(func, mthd, root, chid + head,
-+ return nv50_disp_chan_new_(func, mthd, root, ctrl + head, user + head,
- head, oclass, pobject);
- }
-
-@@ -65,5 +65,5 @@ nv50_disp_oimm_oclass = {
- .base.maxver = 0,
- .ctor = nv50_disp_oimm_new,
- .func = &nv50_disp_pioc_func,
-- .chid = 5,
-+ .chid = { 5, 5 },
- };
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c
-index a625a98..0abaa64 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocgf119.c
-@@ -32,20 +32,21 @@ gf119_disp_pioc_fini(struct nv50_disp_chan *chan)
- struct nv50_disp *disp = chan->root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->chid;
-+ int ctrl = chan->chid.ctrl;
-+ int user = chan->chid.user;
-
-- nvkm_mask(device, 0x610490 + (chid * 0x10), 0x00000001, 0x00000000);
-+ nvkm_mask(device, 0x610490 + (ctrl * 0x10), 0x00000001, 0x00000000);
- if (nvkm_msec(device, 2000,
-- if (!(nvkm_rd32(device, 0x610490 + (chid * 0x10)) & 0x00030000))
-+ if (!(nvkm_rd32(device, 0x610490 + (ctrl * 0x10)) & 0x00030000))
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d fini: %08x\n", chid,
-- nvkm_rd32(device, 0x610490 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d fini: %08x\n", user,
-+ nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
- }
-
- /* disable error reporting and completion notification */
-- nvkm_mask(device, 0x610090, 0x00000001 << chid, 0x00000000);
-- nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000000);
-+ nvkm_mask(device, 0x610090, 0x00000001 << user, 0x00000000);
-+ nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000000);
- }
-
- static int
-@@ -54,20 +55,21 @@ gf119_disp_pioc_init(struct nv50_disp_chan *chan)
- struct nv50_disp *disp = chan->root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->chid;
-+ int ctrl = chan->chid.ctrl;
-+ int user = chan->chid.user;
-
- /* enable error reporting */
-- nvkm_mask(device, 0x6100a0, 0x00000001 << chid, 0x00000001 << chid);
-+ nvkm_mask(device, 0x6100a0, 0x00000001 << user, 0x00000001 << user);
-
- /* activate channel */
-- nvkm_wr32(device, 0x610490 + (chid * 0x10), 0x00000001);
-+ nvkm_wr32(device, 0x610490 + (ctrl * 0x10), 0x00000001);
- if (nvkm_msec(device, 2000,
-- u32 tmp = nvkm_rd32(device, 0x610490 + (chid * 0x10));
-+ u32 tmp = nvkm_rd32(device, 0x610490 + (ctrl * 0x10));
- if ((tmp & 0x00030000) == 0x00010000)
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d init: %08x\n", chid,
-- nvkm_rd32(device, 0x610490 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d init: %08x\n", user,
-+ nvkm_rd32(device, 0x610490 + (ctrl * 0x10)));
- return -EBUSY;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c
-index 9d2618d..0211e0e 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piocnv50.c
-@@ -32,15 +32,16 @@ nv50_disp_pioc_fini(struct nv50_disp_chan *chan)
- struct nv50_disp *disp = chan->root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->chid;
-+ int ctrl = chan->chid.ctrl;
-+ int user = chan->chid.user;
-
-- nvkm_mask(device, 0x610200 + (chid * 0x10), 0x00000001, 0x00000000);
-+ nvkm_mask(device, 0x610200 + (ctrl * 0x10), 0x00000001, 0x00000000);
- if (nvkm_msec(device, 2000,
-- if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x00030000))
-+ if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000))
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d timeout: %08x\n", chid,
-- nvkm_rd32(device, 0x610200 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d timeout: %08x\n", user,
-+ nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
- }
- }
-
-@@ -50,26 +51,27 @@ nv50_disp_pioc_init(struct nv50_disp_chan *chan)
- struct nv50_disp *disp = chan->root->disp;
- struct nvkm_subdev *subdev = &disp->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
-- int chid = chan->chid;
-+ int ctrl = chan->chid.ctrl;
-+ int user = chan->chid.user;
-
-- nvkm_wr32(device, 0x610200 + (chid * 0x10), 0x00002000);
-+ nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00002000);
- if (nvkm_msec(device, 2000,
-- if (!(nvkm_rd32(device, 0x610200 + (chid * 0x10)) & 0x00030000))
-+ if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000))
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d timeout0: %08x\n", chid,
-- nvkm_rd32(device, 0x610200 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d timeout0: %08x\n", user,
-+ nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
- return -EBUSY;
- }
-
-- nvkm_wr32(device, 0x610200 + (chid * 0x10), 0x00000001);
-+ nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00000001);
- if (nvkm_msec(device, 2000,
-- u32 tmp = nvkm_rd32(device, 0x610200 + (chid * 0x10));
-+ u32 tmp = nvkm_rd32(device, 0x610200 + (ctrl * 0x10));
- if ((tmp & 0x00030000) == 0x00010000)
- break;
- ) < 0) {
-- nvkm_error(subdev, "ch %d timeout1: %08x\n", chid,
-- nvkm_rd32(device, 0x610200 + (chid * 0x10)));
-+ nvkm_error(subdev, "ch %d timeout1: %08x\n", user,
-+ nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
- return -EBUSY;
- }
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp104.c
-index 8443e04..b053b29 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp104.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootgp104.c
-@@ -36,8 +36,8 @@ gp104_disp_root = {
- &gp104_disp_ovly_oclass,
- },
- .pioc = {
-- &gk104_disp_oimm_oclass,
-- &gk104_disp_curs_oclass,
-+ &gp102_disp_oimm_oclass,
-+ &gp102_disp_curs_oclass,
- },
- };
-
-diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
-index 2f9cecd..05c829a 100644
---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
-+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
-@@ -207,8 +207,8 @@ nv50_disp_root_pioc_new_(const struct nvkm_oclass *oclass,
- {
- const struct nv50_disp_pioc_oclass *sclass = oclass->priv;
- struct nv50_disp_root *root = nv50_disp_root(oclass->parent);
-- return sclass->ctor(sclass->func, sclass->mthd, root, sclass->chid,
-- oclass, data, size, pobject);
-+ return sclass->ctor(sclass->func, sclass->mthd, root, sclass->chid.ctrl,
-+ sclass->chid.user, oclass, data, size, pobject);
- }
-
- static int
-diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
-index d544ff9..7aadce1 100644
---- a/drivers/gpu/drm/vc4/vc4_crtc.c
-+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
-@@ -83,8 +83,7 @@ struct vc4_crtc_data {
- /* Which channel of the HVS this pixelvalve sources from. */
- int hvs_channel;
-
-- enum vc4_encoder_type encoder0_type;
-- enum vc4_encoder_type encoder1_type;
-+ enum vc4_encoder_type encoder_types[4];
- };
-
- #define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
-@@ -669,6 +668,14 @@ void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id)
- CRTC_WRITE(PV_INTEN, 0);
- }
-
-+/* Must be called with the event lock held */
-+bool vc4_event_pending(struct drm_crtc *crtc)
-+{
-+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-+
-+ return !!vc4_crtc->event;
-+}
-+
- static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
- {
- struct drm_crtc *crtc = &vc4_crtc->base;
-@@ -859,20 +866,26 @@ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
-
- static const struct vc4_crtc_data pv0_data = {
- .hvs_channel = 0,
-- .encoder0_type = VC4_ENCODER_TYPE_DSI0,
-- .encoder1_type = VC4_ENCODER_TYPE_DPI,
-+ .encoder_types = {
-+ [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
-+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
-+ },
- };
-
- static const struct vc4_crtc_data pv1_data = {
- .hvs_channel = 2,
-- .encoder0_type = VC4_ENCODER_TYPE_DSI1,
-- .encoder1_type = VC4_ENCODER_TYPE_SMI,
-+ .encoder_types = {
-+ [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
-+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
-+ },
- };
-
- static const struct vc4_crtc_data pv2_data = {
- .hvs_channel = 1,
-- .encoder0_type = VC4_ENCODER_TYPE_VEC,
-- .encoder1_type = VC4_ENCODER_TYPE_HDMI,
-+ .encoder_types = {
-+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI,
-+ [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
-+ },
- };
-
- static const struct of_device_id vc4_crtc_dt_match[] = {
-@@ -886,17 +899,20 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm,
- struct drm_crtc *crtc)
- {
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-+ const struct vc4_crtc_data *crtc_data = vc4_crtc->data;
-+ const enum vc4_encoder_type *encoder_types = crtc_data->encoder_types;
- struct drm_encoder *encoder;
-
- drm_for_each_encoder(encoder, drm) {
- struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
--
-- if (vc4_encoder->type == vc4_crtc->data->encoder0_type) {
-- vc4_encoder->clock_select = 0;
-- encoder->possible_crtcs |= drm_crtc_mask(crtc);
-- } else if (vc4_encoder->type == vc4_crtc->data->encoder1_type) {
-- vc4_encoder->clock_select = 1;
-- encoder->possible_crtcs |= drm_crtc_mask(crtc);
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(crtc_data->encoder_types); i++) {
-+ if (vc4_encoder->type == encoder_types[i]) {
-+ vc4_encoder->clock_select = i;
-+ encoder->possible_crtcs |= drm_crtc_mask(crtc);
-+ break;
-+ }
- }
- }
- }
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
-index 7c1e4d9..50a55ef 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.h
-+++ b/drivers/gpu/drm/vc4/vc4_drv.h
-@@ -194,6 +194,7 @@ to_vc4_plane(struct drm_plane *plane)
- }
-
- enum vc4_encoder_type {
-+ VC4_ENCODER_TYPE_NONE,
- VC4_ENCODER_TYPE_HDMI,
- VC4_ENCODER_TYPE_VEC,
- VC4_ENCODER_TYPE_DSI0,
-@@ -440,6 +441,7 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
- extern struct platform_driver vc4_crtc_driver;
- int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id);
- void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id);
-+bool vc4_event_pending(struct drm_crtc *crtc);
- int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
- int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
- unsigned int flags, int *vpos, int *hpos,
-diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
-index c1f65c6..67af2af 100644
---- a/drivers/gpu/drm/vc4/vc4_kms.c
-+++ b/drivers/gpu/drm/vc4/vc4_kms.c
-@@ -119,17 +119,34 @@ static int vc4_atomic_commit(struct drm_device *dev,
-
- /* Make sure that any outstanding modesets have finished. */
- if (nonblock) {
-- ret = down_trylock(&vc4->async_modeset);
-- if (ret) {
-+ struct drm_crtc *crtc;
-+ struct drm_crtc_state *crtc_state;
-+ unsigned long flags;
-+ bool busy = false;
-+
-+ /*
-+ * If there's an undispatched event to send then we're
-+ * obviously still busy. If there isn't, then we can
-+ * unconditionally wait for the semaphore because it
-+ * shouldn't be contended (for long).
-+ *
-+ * This is to prevent a race where queuing a new flip
-+ * from userspace immediately on receipt of an event
-+ * beats our clean-up and returns EBUSY.
-+ */
-+ spin_lock_irqsave(&dev->event_lock, flags);
-+ for_each_crtc_in_state(state, crtc, crtc_state, i)
-+ busy |= vc4_event_pending(crtc);
-+ spin_unlock_irqrestore(&dev->event_lock, flags);
-+ if (busy) {
- kfree(c);
- return -EBUSY;
- }
-- } else {
-- ret = down_interruptible(&vc4->async_modeset);
-- if (ret) {
-- kfree(c);
-- return ret;
-- }
-+ }
-+ ret = down_interruptible(&vc4->async_modeset);
-+ if (ret) {
-+ kfree(c);
-+ return ret;
- }
-
- ret = drm_atomic_helper_prepare_planes(dev, state);
-diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
-index 1aa44c2..39f6886 100644
---- a/drivers/gpu/drm/vc4/vc4_regs.h
-+++ b/drivers/gpu/drm/vc4/vc4_regs.h
-@@ -177,8 +177,9 @@
- # define PV_CONTROL_WAIT_HSTART BIT(12)
- # define PV_CONTROL_PIXEL_REP_MASK VC4_MASK(5, 4)
- # define PV_CONTROL_PIXEL_REP_SHIFT 4
--# define PV_CONTROL_CLK_SELECT_DSI_VEC 0
-+# define PV_CONTROL_CLK_SELECT_DSI 0
- # define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI 1
-+# define PV_CONTROL_CLK_SELECT_VEC 2
- # define PV_CONTROL_CLK_SELECT_MASK VC4_MASK(3, 2)
- # define PV_CONTROL_CLK_SELECT_SHIFT 2
- # define PV_CONTROL_FIFO_CLR BIT(1)
-diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
-index c5dee30..acb9d25 100644
---- a/drivers/irqchip/irq-gic-v3-its.c
-+++ b/drivers/irqchip/irq-gic-v3-its.c
-@@ -1598,6 +1598,14 @@ static void __maybe_unused its_enable_quirk_cavium_23144(void *data)
- its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_23144;
- }
-
-+static void __maybe_unused its_enable_quirk_qdf2400_e0065(void *data)
-+{
-+ struct its_node *its = data;
-+
-+ /* On QDF2400, the size of the ITE is 16Bytes */
-+ its->ite_size = 16;
-+}
-+
- static const struct gic_quirk its_quirks[] = {
- #ifdef CONFIG_CAVIUM_ERRATUM_22375
- {
-@@ -1615,6 +1623,14 @@ static const struct gic_quirk its_quirks[] = {
- .init = its_enable_quirk_cavium_23144,
- },
- #endif
-+#ifdef CONFIG_QCOM_QDF2400_ERRATUM_0065
-+ {
-+ .desc = "ITS: QDF2400 erratum 0065",
-+ .iidr = 0x00001070, /* QDF2400 ITS rev 1.x */
-+ .mask = 0xffffffff,
-+ .init = its_enable_quirk_qdf2400_e0065,
-+ },
-+#endif
- {
- }
- };
-diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
-index 302e284..cde43b6 100644
---- a/drivers/media/usb/uvc/uvc_driver.c
-+++ b/drivers/media/usb/uvc/uvc_driver.c
-@@ -1595,6 +1595,114 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain)
- return buffer;
- }
-
-+static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev)
-+{
-+ struct uvc_video_chain *chain;
-+
-+ chain = kzalloc(sizeof(*chain), GFP_KERNEL);
-+ if (chain == NULL)
-+ return NULL;
-+
-+ INIT_LIST_HEAD(&chain->entities);
-+ mutex_init(&chain->ctrl_mutex);
-+ chain->dev = dev;
-+ v4l2_prio_init(&chain->prio);
-+
-+ return chain;
-+}
-+
-+/*
-+ * Fallback heuristic for devices that don't connect units and terminals in a
-+ * valid chain.
-+ *
-+ * Some devices have invalid baSourceID references, causing uvc_scan_chain()
-+ * to fail, but if we just take the entities we can find and put them together
-+ * in the most sensible chain we can think of, turns out they do work anyway.
-+ * Note: This heuristic assumes there is a single chain.
-+ *
-+ * At the time of writing, devices known to have such a broken chain are
-+ * - Acer Integrated Camera (5986:055a)
-+ * - Realtek rtl157a7 (0bda:57a7)
-+ */
-+static int uvc_scan_fallback(struct uvc_device *dev)
-+{
-+ struct uvc_video_chain *chain;
-+ struct uvc_entity *iterm = NULL;
-+ struct uvc_entity *oterm = NULL;
-+ struct uvc_entity *entity;
-+ struct uvc_entity *prev;
-+
-+ /*
-+ * Start by locating the input and output terminals. We only support
-+ * devices with exactly one of each for now.
-+ */
-+ list_for_each_entry(entity, &dev->entities, list) {
-+ if (UVC_ENTITY_IS_ITERM(entity)) {
-+ if (iterm)
-+ return -EINVAL;
-+ iterm = entity;
-+ }
-+
-+ if (UVC_ENTITY_IS_OTERM(entity)) {
-+ if (oterm)
-+ return -EINVAL;
-+ oterm = entity;
-+ }
-+ }
-+
-+ if (iterm == NULL || oterm == NULL)
-+ return -EINVAL;
-+
-+ /* Allocate the chain and fill it. */
-+ chain = uvc_alloc_chain(dev);
-+ if (chain == NULL)
-+ return -ENOMEM;
-+
-+ if (uvc_scan_chain_entity(chain, oterm) < 0)
-+ goto error;
-+
-+ prev = oterm;
-+
-+ /*
-+ * Add all Processing and Extension Units with two pads. The order
-+ * doesn't matter much, use reverse list traversal to connect units in
-+ * UVC descriptor order as we build the chain from output to input. This
-+ * leads to units appearing in the order meant by the manufacturer for
-+ * the cameras known to require this heuristic.
-+ */
-+ list_for_each_entry_reverse(entity, &dev->entities, list) {
-+ if (entity->type != UVC_VC_PROCESSING_UNIT &&
-+ entity->type != UVC_VC_EXTENSION_UNIT)
-+ continue;
-+
-+ if (entity->num_pads != 2)
-+ continue;
-+
-+ if (uvc_scan_chain_entity(chain, entity) < 0)
-+ goto error;
-+
-+ prev->baSourceID[0] = entity->id;
-+ prev = entity;
-+ }
-+
-+ if (uvc_scan_chain_entity(chain, iterm) < 0)
-+ goto error;
-+
-+ prev->baSourceID[0] = iterm->id;
-+
-+ list_add_tail(&chain->list, &dev->chains);
-+
-+ uvc_trace(UVC_TRACE_PROBE,
-+ "Found a video chain by fallback heuristic (%s).\n",
-+ uvc_print_chain(chain));
-+
-+ return 0;
-+
-+error:
-+ kfree(chain);
-+ return -EINVAL;
-+}
-+
- /*
- * Scan the device for video chains and register video devices.
- *
-@@ -1617,15 +1725,10 @@ static int uvc_scan_device(struct uvc_device *dev)
- if (term->chain.next || term->chain.prev)
- continue;
-
-- chain = kzalloc(sizeof(*chain), GFP_KERNEL);
-+ chain = uvc_alloc_chain(dev);
- if (chain == NULL)
- return -ENOMEM;
-
-- INIT_LIST_HEAD(&chain->entities);
-- mutex_init(&chain->ctrl_mutex);
-- chain->dev = dev;
-- v4l2_prio_init(&chain->prio);
--
- term->flags |= UVC_ENTITY_FLAG_DEFAULT;
-
- if (uvc_scan_chain(chain, term) < 0) {
-@@ -1639,6 +1742,9 @@ static int uvc_scan_device(struct uvc_device *dev)
- list_add_tail(&chain->list, &dev->chains);
- }
-
-+ if (list_empty(&dev->chains))
-+ uvc_scan_fallback(dev);
-+
- if (list_empty(&dev->chains)) {
- uvc_printk(KERN_INFO, "No valid video chain found.\n");
- return -1;
-diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
-index a36022b..03dca73 100644
---- a/drivers/net/ethernet/ibm/ibmveth.c
-+++ b/drivers/net/ethernet/ibm/ibmveth.c
-@@ -1181,7 +1181,9 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
-
- static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt)
- {
-+ struct tcphdr *tcph;
- int offset = 0;
-+ int hdr_len;
-
- /* only TCP packets will be aggregated */
- if (skb->protocol == htons(ETH_P_IP)) {
-@@ -1208,14 +1210,20 @@ static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt)
- /* if mss is not set through Large Packet bit/mss in rx buffer,
- * expect that the mss will be written to the tcp header checksum.
- */
-+ tcph = (struct tcphdr *)(skb->data + offset);
- if (lrg_pkt) {
- skb_shinfo(skb)->gso_size = mss;
- } else if (offset) {
-- struct tcphdr *tcph = (struct tcphdr *)(skb->data + offset);
--
- skb_shinfo(skb)->gso_size = ntohs(tcph->check);
- tcph->check = 0;
- }
-+
-+ if (skb_shinfo(skb)->gso_size) {
-+ hdr_len = offset + tcph->doff * 4;
-+ skb_shinfo(skb)->gso_segs =
-+ DIV_ROUND_UP(skb->len - hdr_len,
-+ skb_shinfo(skb)->gso_size);
-+ }
- }
-
- static int ibmveth_poll(struct napi_struct *napi, int budget)
-diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
-index 5b54254..2788a54 100644
---- a/drivers/net/ethernet/intel/igb/e1000_phy.c
-+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
-@@ -77,6 +77,10 @@ s32 igb_get_phy_id(struct e1000_hw *hw)
- s32 ret_val = 0;
- u16 phy_id;
-
-+ /* ensure PHY page selection to fix misconfigured i210 */
-+ if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
-+ phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0);
-+
- ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
- if (ret_val)
- goto out;
-diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
-index b3067137..d4fa851 100644
---- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
-+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
-@@ -81,6 +81,7 @@ static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
- static void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type)
- {
- priv->params.rq_wq_type = rq_type;
-+ priv->params.lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
- switch (priv->params.rq_wq_type) {
- case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
- priv->params.log_rq_size = MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW;
-@@ -92,6 +93,10 @@ static void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type)
- break;
- default: /* MLX5_WQ_TYPE_LINKED_LIST */
- priv->params.log_rq_size = MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE;
-+
-+ /* Extra room needed for build_skb */
-+ priv->params.lro_wqe_sz -= MLX5_RX_HEADROOM +
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
- }
- priv->params.min_rx_wqes = mlx5_min_rx_wqes(priv->params.rq_wq_type,
- BIT(priv->params.log_rq_size));
-@@ -3473,12 +3478,6 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
- mlx5e_build_default_indir_rqt(mdev, priv->params.indirection_rqt,
- MLX5E_INDIR_RQT_SIZE, profile->max_nch(mdev));
-
-- priv->params.lro_wqe_sz =
-- MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ -
-- /* Extra room needed for build_skb */
-- MLX5_RX_HEADROOM -
-- SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
--
- /* Initialize pflags */
- MLX5E_SET_PRIV_FLAG(priv, MLX5E_PFLAG_RX_CQE_BASED_MODER,
- priv->params.rx_cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE);
-@@ -3936,6 +3935,19 @@ static void mlx5e_register_vport_rep(struct mlx5_core_dev *mdev)
- }
- }
-
-+static void mlx5e_unregister_vport_rep(struct mlx5_core_dev *mdev)
-+{
-+ struct mlx5_eswitch *esw = mdev->priv.eswitch;
-+ int total_vfs = MLX5_TOTAL_VPORTS(mdev);
-+ int vport;
-+
-+ if (!MLX5_CAP_GEN(mdev, vport_group_manager))
-+ return;
-+
-+ for (vport = 1; vport < total_vfs; vport++)
-+ mlx5_eswitch_unregister_vport_rep(esw, vport);
-+}
-+
- void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev)
- {
- struct mlx5e_priv *priv = netdev_priv(netdev);
-@@ -3983,6 +3995,7 @@ static int mlx5e_attach(struct mlx5_core_dev *mdev, void *vpriv)
- return err;
- }
-
-+ mlx5e_register_vport_rep(mdev);
- return 0;
- }
-
-@@ -3994,6 +4007,7 @@ static void mlx5e_detach(struct mlx5_core_dev *mdev, void *vpriv)
- if (!netif_device_present(netdev))
- return;
-
-+ mlx5e_unregister_vport_rep(mdev);
- mlx5e_detach_netdev(mdev, netdev);
- mlx5e_destroy_mdev_resources(mdev);
- }
-@@ -4012,8 +4026,6 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
- if (err)
- return NULL;
-
-- mlx5e_register_vport_rep(mdev);
--
- if (MLX5_CAP_GEN(mdev, vport_group_manager))
- ppriv = &esw->offloads.vport_reps[0];
-
-@@ -4065,13 +4077,7 @@ void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv)
-
- static void mlx5e_remove(struct mlx5_core_dev *mdev, void *vpriv)
- {
-- struct mlx5_eswitch *esw = mdev->priv.eswitch;
-- int total_vfs = MLX5_TOTAL_VPORTS(mdev);
- struct mlx5e_priv *priv = vpriv;
-- int vport;
--
-- for (vport = 1; vport < total_vfs; vport++)
-- mlx5_eswitch_unregister_vport_rep(esw, vport);
-
- unregister_netdev(priv->netdev);
- mlx5e_detach(mdev, vpriv);
-diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
-index e7b2158..796bdf0 100644
---- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
-+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
-@@ -92,19 +92,18 @@ static inline void mlx5e_cqes_update_owner(struct mlx5e_cq *cq, u32 cqcc, int n)
- static inline void mlx5e_decompress_cqe(struct mlx5e_rq *rq,
- struct mlx5e_cq *cq, u32 cqcc)
- {
-- u16 wqe_cnt_step;
--
- cq->title.byte_cnt = cq->mini_arr[cq->mini_arr_idx].byte_cnt;
- cq->title.check_sum = cq->mini_arr[cq->mini_arr_idx].checksum;
- cq->title.op_own &= 0xf0;
- cq->title.op_own |= 0x01 & (cqcc >> cq->wq.log_sz);
- cq->title.wqe_counter = cpu_to_be16(cq->decmprs_wqe_counter);
-
-- wqe_cnt_step =
-- rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ ?
-- mpwrq_get_cqe_consumed_strides(&cq->title) : 1;
-- cq->decmprs_wqe_counter =
-- (cq->decmprs_wqe_counter + wqe_cnt_step) & rq->wq.sz_m1;
-+ if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
-+ cq->decmprs_wqe_counter +=
-+ mpwrq_get_cqe_consumed_strides(&cq->title);
-+ else
-+ cq->decmprs_wqe_counter =
-+ (cq->decmprs_wqe_counter + 1) & rq->wq.sz_m1;
- }
-
- static inline void mlx5e_decompress_cqe_no_hash(struct mlx5e_rq *rq,
-diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
-index e83072d..6905630 100644
---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
-+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
-@@ -500,30 +500,40 @@ static int
- mlxsw_sp_vr_lpm_tree_check(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr,
- struct mlxsw_sp_prefix_usage *req_prefix_usage)
- {
-- struct mlxsw_sp_lpm_tree *lpm_tree;
-+ struct mlxsw_sp_lpm_tree *lpm_tree = vr->lpm_tree;
-+ struct mlxsw_sp_lpm_tree *new_tree;
-+ int err;
-
-- if (mlxsw_sp_prefix_usage_eq(req_prefix_usage,
-- &vr->lpm_tree->prefix_usage))
-+ if (mlxsw_sp_prefix_usage_eq(req_prefix_usage, &lpm_tree->prefix_usage))
- return 0;
-
-- lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, req_prefix_usage,
-+ new_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, req_prefix_usage,
- vr->proto, false);
-- if (IS_ERR(lpm_tree)) {
-+ if (IS_ERR(new_tree)) {
- /* We failed to get a tree according to the required
- * prefix usage. However, the current tree might be still good
- * for us if our requirement is subset of the prefixes used
- * in the tree.
- */
- if (mlxsw_sp_prefix_usage_subset(req_prefix_usage,
-- &vr->lpm_tree->prefix_usage))
-+ &lpm_tree->prefix_usage))
- return 0;
-- return PTR_ERR(lpm_tree);
-+ return PTR_ERR(new_tree);
- }
-
-- mlxsw_sp_vr_lpm_tree_unbind(mlxsw_sp, vr);
-- mlxsw_sp_lpm_tree_put(mlxsw_sp, vr->lpm_tree);
-+ /* Prevent packet loss by overwriting existing binding */
-+ vr->lpm_tree = new_tree;
-+ err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, vr);
-+ if (err)
-+ goto err_tree_bind;
-+ mlxsw_sp_lpm_tree_put(mlxsw_sp, lpm_tree);
-+
-+ return 0;
-+
-+err_tree_bind:
- vr->lpm_tree = lpm_tree;
-- return mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, vr);
-+ mlxsw_sp_lpm_tree_put(mlxsw_sp, new_tree);
-+ return err;
- }
-
- static struct mlxsw_sp_vr *mlxsw_sp_vr_get(struct mlxsw_sp *mlxsw_sp,
-diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
-index 8b4822a..3c1f89a 100644
---- a/drivers/net/geneve.c
-+++ b/drivers/net/geneve.c
-@@ -1039,16 +1039,22 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- struct geneve_dev *geneve = netdev_priv(dev);
- struct ip_tunnel_info *info = NULL;
-+ int err;
-
- if (geneve->collect_md)
- info = skb_tunnel_info(skb);
-
-+ rcu_read_lock();
- #if IS_ENABLED(CONFIG_IPV6)
- if ((info && ip_tunnel_info_af(info) == AF_INET6) ||
- (!info && geneve->remote.sa.sa_family == AF_INET6))
-- return geneve6_xmit_skb(skb, dev, info);
-+ err = geneve6_xmit_skb(skb, dev, info);
-+ else
- #endif
-- return geneve_xmit_skb(skb, dev, info);
-+ err = geneve_xmit_skb(skb, dev, info);
-+ rcu_read_unlock();
-+
-+ return err;
- }
-
- static int __geneve_change_mtu(struct net_device *dev, int new_mtu, bool strict)
-diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
-index f424b86..201ffa5 100644
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -611,14 +611,18 @@ void phy_start_machine(struct phy_device *phydev)
- * phy_trigger_machine - trigger the state machine to run
- *
- * @phydev: the phy_device struct
-+ * @sync: indicate whether we should wait for the workqueue cancelation
- *
- * Description: There has been a change in state which requires that the
- * state machine runs.
- */
-
--static void phy_trigger_machine(struct phy_device *phydev)
-+static void phy_trigger_machine(struct phy_device *phydev, bool sync)
- {
-- cancel_delayed_work_sync(&phydev->state_queue);
-+ if (sync)
-+ cancel_delayed_work_sync(&phydev->state_queue);
-+ else
-+ cancel_delayed_work(&phydev->state_queue);
- queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
- }
-
-@@ -655,7 +659,7 @@ static void phy_error(struct phy_device *phydev)
- phydev->state = PHY_HALTED;
- mutex_unlock(&phydev->lock);
-
-- phy_trigger_machine(phydev);
-+ phy_trigger_machine(phydev, false);
- }
-
- /**
-@@ -817,7 +821,7 @@ void phy_change(struct work_struct *work)
- }
-
- /* reschedule state queue work to run as soon as possible */
-- phy_trigger_machine(phydev);
-+ phy_trigger_machine(phydev, true);
- return;
-
- ignore:
-@@ -907,7 +911,7 @@ void phy_start(struct phy_device *phydev)
- if (do_resume)
- phy_resume(phydev);
-
-- phy_trigger_machine(phydev);
-+ phy_trigger_machine(phydev, true);
- }
- EXPORT_SYMBOL(phy_start);
-
-diff --git a/drivers/net/tun.c b/drivers/net/tun.c
-index b31aca8..a931b73 100644
---- a/drivers/net/tun.c
-+++ b/drivers/net/tun.c
-@@ -819,7 +819,18 @@ static void tun_net_uninit(struct net_device *dev)
- /* Net device open. */
- static int tun_net_open(struct net_device *dev)
- {
-+ struct tun_struct *tun = netdev_priv(dev);
-+ int i;
-+
- netif_tx_start_all_queues(dev);
-+
-+ for (i = 0; i < tun->numqueues; i++) {
-+ struct tun_file *tfile;
-+
-+ tfile = rtnl_dereference(tun->tfiles[i]);
-+ tfile->socket.sk->sk_write_space(tfile->socket.sk);
-+ }
-+
- return 0;
- }
-
-@@ -1116,9 +1127,10 @@ static unsigned int tun_chr_poll(struct file *file, poll_table *wait)
- if (!skb_array_empty(&tfile->tx_array))
- mask |= POLLIN | POLLRDNORM;
-
-- if (sock_writeable(sk) ||
-- (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
-- sock_writeable(sk)))
-+ if (tun->dev->flags & IFF_UP &&
-+ (sock_writeable(sk) ||
-+ (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
-+ sock_writeable(sk))))
- mask |= POLLOUT | POLLWRNORM;
-
- if (tun->dev->reg_state != NETREG_REGISTERED)
-diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
-index 95cf1d8..bc744ac 100644
---- a/drivers/net/vrf.c
-+++ b/drivers/net/vrf.c
-@@ -346,6 +346,7 @@ static netdev_tx_t is_ip_tx_frame(struct sk_buff *skb, struct net_device *dev)
-
- static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
- {
-+ int len = skb->len;
- netdev_tx_t ret = is_ip_tx_frame(skb, dev);
-
- if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
-@@ -353,7 +354,7 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
-
- u64_stats_update_begin(&dstats->syncp);
- dstats->tx_pkts++;
-- dstats->tx_bytes += skb->len;
-+ dstats->tx_bytes += len;
- u64_stats_update_end(&dstats->syncp);
- } else {
- this_cpu_inc(dev->dstats->tx_drps);
-diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
-index d4f495b..3c4c2cf 100644
---- a/drivers/net/vxlan.c
-+++ b/drivers/net/vxlan.c
-@@ -1942,7 +1942,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- const struct iphdr *old_iph;
- union vxlan_addr *dst;
- union vxlan_addr remote_ip, local_ip;
-- union vxlan_addr *src;
- struct vxlan_metadata _md;
- struct vxlan_metadata *md = &_md;
- __be16 src_port = 0, dst_port;
-@@ -1956,11 +1955,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-
- info = skb_tunnel_info(skb);
-
-+ rcu_read_lock();
- if (rdst) {
- dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
- vni = rdst->remote_vni;
- dst = &rdst->remote_ip;
-- src = &vxlan->cfg.saddr;
-+ local_ip = vxlan->cfg.saddr;
- dst_cache = &rdst->dst_cache;
- } else {
- if (!info) {
-@@ -1979,7 +1979,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- local_ip.sin6.sin6_addr = info->key.u.ipv6.src;
- }
- dst = &remote_ip;
-- src = &local_ip;
- dst_cache = &info->dst_cache;
- }
-
-@@ -1987,7 +1986,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- if (did_rsc) {
- /* short-circuited back to local bridge */
- vxlan_encap_bypass(skb, vxlan, vxlan);
-- return;
-+ goto out_unlock;
- }
- goto drop;
- }
-@@ -2028,7 +2027,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- rt = vxlan_get_route(vxlan, skb,
- rdst ? rdst->remote_ifindex : 0, tos,
- dst->sin.sin_addr.s_addr,
-- &src->sin.sin_addr.s_addr,
-+ &local_ip.sin.sin_addr.s_addr,
- dst_cache, info);
- if (IS_ERR(rt)) {
- netdev_dbg(dev, "no route to %pI4\n",
-@@ -2056,7 +2055,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- if (!dst_vxlan)
- goto tx_error;
- vxlan_encap_bypass(skb, vxlan, dst_vxlan);
-- return;
-+ goto out_unlock;
- }
-
- if (!info)
-@@ -2071,7 +2070,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- if (err < 0)
- goto xmit_tx_error;
-
-- udp_tunnel_xmit_skb(rt, sk, skb, src->sin.sin_addr.s_addr,
-+ udp_tunnel_xmit_skb(rt, sk, skb, local_ip.sin.sin_addr.s_addr,
- dst->sin.sin_addr.s_addr, tos, ttl, df,
- src_port, dst_port, xnet, !udp_sum);
- #if IS_ENABLED(CONFIG_IPV6)
-@@ -2087,7 +2086,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- ndst = vxlan6_get_route(vxlan, skb,
- rdst ? rdst->remote_ifindex : 0, tos,
- label, &dst->sin6.sin6_addr,
-- &src->sin6.sin6_addr,
-+ &local_ip.sin6.sin6_addr,
- dst_cache, info);
- if (IS_ERR(ndst)) {
- netdev_dbg(dev, "no route to %pI6\n",
-@@ -2117,7 +2116,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- if (!dst_vxlan)
- goto tx_error;
- vxlan_encap_bypass(skb, vxlan, dst_vxlan);
-- return;
-+ goto out_unlock;
- }
-
- if (!info)
-@@ -2131,15 +2130,16 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- if (err < 0) {
- dst_release(ndst);
- dev->stats.tx_errors++;
-- return;
-+ goto out_unlock;
- }
- udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
-- &src->sin6.sin6_addr,
-+ &local_ip.sin6.sin6_addr,
- &dst->sin6.sin6_addr, tos, ttl,
- label, src_port, dst_port, !udp_sum);
- #endif
- }
--
-+out_unlock:
-+ rcu_read_unlock();
- return;
-
- drop:
-@@ -2155,6 +2155,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
- dev->stats.tx_errors++;
- tx_free:
- dev_kfree_skb(skb);
-+ rcu_read_unlock();
- }
-
- /* Transmit local packets over Vxlan
-@@ -2637,7 +2638,7 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
-
- if (data[IFLA_VXLAN_ID]) {
- __u32 id = nla_get_u32(data[IFLA_VXLAN_ID]);
-- if (id >= VXLAN_VID_MASK)
-+ if (id >= VXLAN_N_VID)
- return -ERANGE;
- }
-
-diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
-index e30f05c..4722782 100644
---- a/drivers/pci/iov.c
-+++ b/drivers/pci/iov.c
-@@ -306,13 +306,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
- return rc;
- }
-
-- pci_iov_set_numvfs(dev, nr_virtfn);
-- iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
-- pci_cfg_access_lock(dev);
-- pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
-- msleep(100);
-- pci_cfg_access_unlock(dev);
--
- iov->initial_VFs = initial;
- if (nr_virtfn < initial)
- initial = nr_virtfn;
-@@ -323,6 +316,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
- goto err_pcibios;
- }
-
-+ pci_iov_set_numvfs(dev, nr_virtfn);
-+ iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
-+ pci_cfg_access_lock(dev);
-+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
-+ msleep(100);
-+ pci_cfg_access_unlock(dev);
-+
- for (i = 0; i < initial; i++) {
- rc = pci_iov_add_virtfn(dev, i, 0);
- if (rc)
-@@ -554,21 +554,61 @@ void pci_iov_release(struct pci_dev *dev)
- }
-
- /**
-- * pci_iov_resource_bar - get position of the SR-IOV BAR
-+ * pci_iov_update_resource - update a VF BAR
- * @dev: the PCI device
- * @resno: the resource number
- *
-- * Returns position of the BAR encapsulated in the SR-IOV capability.
-+ * Update a VF BAR in the SR-IOV capability of a PF.
- */
--int pci_iov_resource_bar(struct pci_dev *dev, int resno)
-+void pci_iov_update_resource(struct pci_dev *dev, int resno)
- {
-- if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
-- return 0;
-+ struct pci_sriov *iov = dev->is_physfn ? dev->sriov : NULL;
-+ struct resource *res = dev->resource + resno;
-+ int vf_bar = resno - PCI_IOV_RESOURCES;
-+ struct pci_bus_region region;
-+ u16 cmd;
-+ u32 new;
-+ int reg;
-+
-+ /*
-+ * The generic pci_restore_bars() path calls this for all devices,
-+ * including VFs and non-SR-IOV devices. If this is not a PF, we
-+ * have nothing to do.
-+ */
-+ if (!iov)
-+ return;
-+
-+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &cmd);
-+ if ((cmd & PCI_SRIOV_CTRL_VFE) && (cmd & PCI_SRIOV_CTRL_MSE)) {
-+ dev_WARN(&dev->dev, "can't update enabled VF BAR%d %pR\n",
-+ vf_bar, res);
-+ return;
-+ }
-+
-+ /*
-+ * Ignore unimplemented BARs, unused resource slots for 64-bit
-+ * BARs, and non-movable resources, e.g., those described via
-+ * Enhanced Allocation.
-+ */
-+ if (!res->flags)
-+ return;
-+
-+ if (res->flags & IORESOURCE_UNSET)
-+ return;
-+
-+ if (res->flags & IORESOURCE_PCI_FIXED)
-+ return;
-
-- BUG_ON(!dev->is_physfn);
-+ pcibios_resource_to_bus(dev->bus, &region, res);
-+ new = region.start;
-+ new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
-
-- return dev->sriov->pos + PCI_SRIOV_BAR +
-- 4 * (resno - PCI_IOV_RESOURCES);
-+ reg = iov->pos + PCI_SRIOV_BAR + 4 * vf_bar;
-+ pci_write_config_dword(dev, reg, new);
-+ if (res->flags & IORESOURCE_MEM_64) {
-+ new = region.start >> 16 >> 16;
-+ pci_write_config_dword(dev, reg + 4, new);
-+ }
- }
-
- resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev,
-diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
-index eda6a7c..6922964 100644
---- a/drivers/pci/pci.c
-+++ b/drivers/pci/pci.c
-@@ -564,10 +564,6 @@ static void pci_restore_bars(struct pci_dev *dev)
- {
- int i;
-
-- /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
-- if (dev->is_virtfn)
-- return;
--
- for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
- pci_update_resource(dev, i);
- }
-@@ -4835,36 +4831,6 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags)
- }
- EXPORT_SYMBOL(pci_select_bars);
-
--/**
-- * pci_resource_bar - get position of the BAR associated with a resource
-- * @dev: the PCI device
-- * @resno: the resource number
-- * @type: the BAR type to be filled in
-- *
-- * Returns BAR position in config space, or 0 if the BAR is invalid.
-- */
--int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
--{
-- int reg;
--
-- if (resno < PCI_ROM_RESOURCE) {
-- *type = pci_bar_unknown;
-- return PCI_BASE_ADDRESS_0 + 4 * resno;
-- } else if (resno == PCI_ROM_RESOURCE) {
-- *type = pci_bar_mem32;
-- return dev->rom_base_reg;
-- } else if (resno < PCI_BRIDGE_RESOURCES) {
-- /* device specific resource */
-- *type = pci_bar_unknown;
-- reg = pci_iov_resource_bar(dev, resno);
-- if (reg)
-- return reg;
-- }
--
-- dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
-- return 0;
--}
--
- /* Some architectures require additional programming to enable VGA */
- static arch_set_vga_state_t arch_set_vga_state;
-
-diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
-index 4518562..a5d37f6 100644
---- a/drivers/pci/pci.h
-+++ b/drivers/pci/pci.h
-@@ -245,7 +245,6 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
- int pci_setup_device(struct pci_dev *dev);
- int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
- struct resource *res, unsigned int reg);
--int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type);
- void pci_configure_ari(struct pci_dev *dev);
- void __pci_bus_size_bridges(struct pci_bus *bus,
- struct list_head *realloc_head);
-@@ -289,7 +288,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev)
- #ifdef CONFIG_PCI_IOV
- int pci_iov_init(struct pci_dev *dev);
- void pci_iov_release(struct pci_dev *dev);
--int pci_iov_resource_bar(struct pci_dev *dev, int resno);
-+void pci_iov_update_resource(struct pci_dev *dev, int resno);
- resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
- void pci_restore_iov_state(struct pci_dev *dev);
- int pci_iov_bus_range(struct pci_bus *bus);
-@@ -303,10 +302,6 @@ static inline void pci_iov_release(struct pci_dev *dev)
-
- {
- }
--static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno)
--{
-- return 0;
--}
- static inline void pci_restore_iov_state(struct pci_dev *dev)
- {
- }
-diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
-index 300770c..d266d80 100644
---- a/drivers/pci/probe.c
-+++ b/drivers/pci/probe.c
-@@ -227,7 +227,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
- mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK;
- }
- } else {
-- res->flags |= (l & IORESOURCE_ROM_ENABLE);
-+ if (l & PCI_ROM_ADDRESS_ENABLE)
-+ res->flags |= IORESOURCE_ROM_ENABLE;
- l64 = l & PCI_ROM_ADDRESS_MASK;
- sz64 = sz & PCI_ROM_ADDRESS_MASK;
- mask64 = (u32)PCI_ROM_ADDRESS_MASK;
-diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
-index 06663d3..b6edb18 100644
---- a/drivers/pci/rom.c
-+++ b/drivers/pci/rom.c
-@@ -35,6 +35,11 @@ int pci_enable_rom(struct pci_dev *pdev)
- if (res->flags & IORESOURCE_ROM_SHADOW)
- return 0;
-
-+ /*
-+ * Ideally pci_update_resource() would update the ROM BAR address,
-+ * and we would only set the enable bit here. But apparently some
-+ * devices have buggy ROM BARs that read as zero when disabled.
-+ */
- pcibios_resource_to_bus(pdev->bus, &region, res);
- pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
- rom_addr &= ~PCI_ROM_ADDRESS_MASK;
-diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
-index 9526e34..4bc589e 100644
---- a/drivers/pci/setup-res.c
-+++ b/drivers/pci/setup-res.c
-@@ -25,21 +25,18 @@
- #include <linux/slab.h>
- #include "pci.h"
-
--
--void pci_update_resource(struct pci_dev *dev, int resno)
-+static void pci_std_update_resource(struct pci_dev *dev, int resno)
- {
- struct pci_bus_region region;
- bool disable;
- u16 cmd;
- u32 new, check, mask;
- int reg;
-- enum pci_bar_type type;
- struct resource *res = dev->resource + resno;
-
-- if (dev->is_virtfn) {
-- dev_warn(&dev->dev, "can't update VF BAR%d\n", resno);
-+ /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
-+ if (dev->is_virtfn)
- return;
-- }
-
- /*
- * Ignore resources for unimplemented BARs and unused resource slots
-@@ -60,21 +57,34 @@ void pci_update_resource(struct pci_dev *dev, int resno)
- return;
-
- pcibios_resource_to_bus(dev->bus, &region, res);
-+ new = region.start;
-
-- new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
-- if (res->flags & IORESOURCE_IO)
-+ if (res->flags & IORESOURCE_IO) {
- mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
-- else
-+ new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
-+ } else if (resno == PCI_ROM_RESOURCE) {
-+ mask = (u32)PCI_ROM_ADDRESS_MASK;
-+ } else {
- mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
-+ new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
-+ }
-
-- reg = pci_resource_bar(dev, resno, &type);
-- if (!reg)
-- return;
-- if (type != pci_bar_unknown) {
-+ if (resno < PCI_ROM_RESOURCE) {
-+ reg = PCI_BASE_ADDRESS_0 + 4 * resno;
-+ } else if (resno == PCI_ROM_RESOURCE) {
-+
-+ /*
-+ * Apparently some Matrox devices have ROM BARs that read
-+ * as zero when disabled, so don't update ROM BARs unless
-+ * they're enabled. See https://lkml.org/lkml/2005/8/30/138.
-+ */
- if (!(res->flags & IORESOURCE_ROM_ENABLE))
- return;
-+
-+ reg = dev->rom_base_reg;
- new |= PCI_ROM_ADDRESS_ENABLE;
-- }
-+ } else
-+ return;
-
- /*
- * We can't update a 64-bit BAR atomically, so when possible,
-@@ -110,6 +120,16 @@ void pci_update_resource(struct pci_dev *dev, int resno)
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
-
-+void pci_update_resource(struct pci_dev *dev, int resno)
-+{
-+ if (resno <= PCI_ROM_RESOURCE)
-+ pci_std_update_resource(dev, resno);
-+#ifdef CONFIG_PCI_IOV
-+ else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
-+ pci_iov_update_resource(dev, resno);
-+#endif
-+}
-+
- int pci_claim_resource(struct pci_dev *dev, int resource)
- {
- struct resource *res = &dev->resource[resource];
-diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
-index ed92fb0..76b802c 100644
---- a/drivers/s390/crypto/ap_bus.c
-+++ b/drivers/s390/crypto/ap_bus.c
-@@ -1712,6 +1712,9 @@ static void ap_scan_bus(struct work_struct *unused)
- ap_dev->queue_depth = queue_depth;
- ap_dev->raw_hwtype = device_type;
- ap_dev->device_type = device_type;
-+ /* CEX6 toleration: map to CEX5 */
-+ if (device_type == AP_DEVICE_TYPE_CEX6)
-+ ap_dev->device_type = AP_DEVICE_TYPE_CEX5;
- ap_dev->functions = device_functions;
- spin_lock_init(&ap_dev->lock);
- INIT_LIST_HEAD(&ap_dev->pendingq);
-diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
-index d7fdf5c..fd66d2c 100644
---- a/drivers/s390/crypto/ap_bus.h
-+++ b/drivers/s390/crypto/ap_bus.h
-@@ -105,6 +105,7 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr)
- #define AP_DEVICE_TYPE_CEX3C 9
- #define AP_DEVICE_TYPE_CEX4 10
- #define AP_DEVICE_TYPE_CEX5 11
-+#define AP_DEVICE_TYPE_CEX6 12
-
- /*
- * Known function facilities
-diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
-index 91dfd58..c4fe95a 100644
---- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
-+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
-@@ -22,7 +22,7 @@
- *
- ****************************************************************************/
-
--#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
- #include <linux/module.h>
- #include <linux/kernel.h>
-@@ -82,7 +82,7 @@ static void ibmvscsis_determine_resid(struct se_cmd *se_cmd,
- }
- } else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
- if (se_cmd->data_direction == DMA_TO_DEVICE) {
-- /* residual data from an overflow write */
-+ /* residual data from an overflow write */
- rsp->flags = SRP_RSP_FLAG_DOOVER;
- rsp->data_out_res_cnt = cpu_to_be32(residual_count);
- } else if (se_cmd->data_direction == DMA_FROM_DEVICE) {
-@@ -102,7 +102,7 @@ static void ibmvscsis_determine_resid(struct se_cmd *se_cmd,
- * and the function returns TRUE.
- *
- * EXECUTION ENVIRONMENT:
-- * Interrupt or Process environment
-+ * Interrupt or Process environment
- */
- static bool connection_broken(struct scsi_info *vscsi)
- {
-@@ -325,7 +325,7 @@ static struct viosrp_crq *ibmvscsis_cmd_q_dequeue(uint mask,
- }
-
- /**
-- * ibmvscsis_send_init_message() - send initialize message to the client
-+ * ibmvscsis_send_init_message() - send initialize message to the client
- * @vscsi: Pointer to our adapter structure
- * @format: Which Init Message format to send
- *
-@@ -383,13 +383,13 @@ static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format)
- vscsi->cmd_q.base_addr);
- if (crq) {
- *format = (uint)(crq->format);
-- rc = ERROR;
-+ rc = ERROR;
- crq->valid = INVALIDATE_CMD_RESP_EL;
- dma_rmb();
- }
- } else {
- *format = (uint)(crq->format);
-- rc = ERROR;
-+ rc = ERROR;
- crq->valid = INVALIDATE_CMD_RESP_EL;
- dma_rmb();
- }
-@@ -398,166 +398,6 @@ static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format)
- }
-
- /**
-- * ibmvscsis_establish_new_q() - Establish new CRQ queue
-- * @vscsi: Pointer to our adapter structure
-- * @new_state: New state being established after resetting the queue
-- *
-- * Must be called with interrupt lock held.
-- */
--static long ibmvscsis_establish_new_q(struct scsi_info *vscsi, uint new_state)
--{
-- long rc = ADAPT_SUCCESS;
-- uint format;
--
-- vscsi->flags &= PRESERVE_FLAG_FIELDS;
-- vscsi->rsp_q_timer.timer_pops = 0;
-- vscsi->debit = 0;
-- vscsi->credit = 0;
--
-- rc = vio_enable_interrupts(vscsi->dma_dev);
-- if (rc) {
-- pr_warn("reset_queue: failed to enable interrupts, rc %ld\n",
-- rc);
-- return rc;
-- }
--
-- rc = ibmvscsis_check_init_msg(vscsi, &format);
-- if (rc) {
-- dev_err(&vscsi->dev, "reset_queue: check_init_msg failed, rc %ld\n",
-- rc);
-- return rc;
-- }
--
-- if (format == UNUSED_FORMAT && new_state == WAIT_CONNECTION) {
-- rc = ibmvscsis_send_init_message(vscsi, INIT_MSG);
-- switch (rc) {
-- case H_SUCCESS:
-- case H_DROPPED:
-- case H_CLOSED:
-- rc = ADAPT_SUCCESS;
-- break;
--
-- case H_PARAMETER:
-- case H_HARDWARE:
-- break;
--
-- default:
-- vscsi->state = UNDEFINED;
-- rc = H_HARDWARE;
-- break;
-- }
-- }
--
-- return rc;
--}
--
--/**
-- * ibmvscsis_reset_queue() - Reset CRQ Queue
-- * @vscsi: Pointer to our adapter structure
-- * @new_state: New state to establish after resetting the queue
-- *
-- * This function calls h_free_q and then calls h_reg_q and does all
-- * of the bookkeeping to get us back to where we can communicate.
-- *
-- * Actually, we don't always call h_free_crq. A problem was discovered
-- * where one partition would close and reopen his queue, which would
-- * cause his partner to get a transport event, which would cause him to
-- * close and reopen his queue, which would cause the original partition
-- * to get a transport event, etc., etc. To prevent this, we don't
-- * actually close our queue if the client initiated the reset, (i.e.
-- * either we got a transport event or we have detected that the client's
-- * queue is gone)
-- *
-- * EXECUTION ENVIRONMENT:
-- * Process environment, called with interrupt lock held
-- */
--static void ibmvscsis_reset_queue(struct scsi_info *vscsi, uint new_state)
--{
-- int bytes;
-- long rc = ADAPT_SUCCESS;
--
-- pr_debug("reset_queue: flags 0x%x\n", vscsi->flags);
--
-- /* don't reset, the client did it for us */
-- if (vscsi->flags & (CLIENT_FAILED | TRANS_EVENT)) {
-- vscsi->flags &= PRESERVE_FLAG_FIELDS;
-- vscsi->rsp_q_timer.timer_pops = 0;
-- vscsi->debit = 0;
-- vscsi->credit = 0;
-- vscsi->state = new_state;
-- vio_enable_interrupts(vscsi->dma_dev);
-- } else {
-- rc = ibmvscsis_free_command_q(vscsi);
-- if (rc == ADAPT_SUCCESS) {
-- vscsi->state = new_state;
--
-- bytes = vscsi->cmd_q.size * PAGE_SIZE;
-- rc = h_reg_crq(vscsi->dds.unit_id,
-- vscsi->cmd_q.crq_token, bytes);
-- if (rc == H_CLOSED || rc == H_SUCCESS) {
-- rc = ibmvscsis_establish_new_q(vscsi,
-- new_state);
-- }
--
-- if (rc != ADAPT_SUCCESS) {
-- pr_debug("reset_queue: reg_crq rc %ld\n", rc);
--
-- vscsi->state = ERR_DISCONNECTED;
-- vscsi->flags |= RESPONSE_Q_DOWN;
-- ibmvscsis_free_command_q(vscsi);
-- }
-- } else {
-- vscsi->state = ERR_DISCONNECTED;
-- vscsi->flags |= RESPONSE_Q_DOWN;
-- }
-- }
--}
--
--/**
-- * ibmvscsis_free_cmd_resources() - Free command resources
-- * @vscsi: Pointer to our adapter structure
-- * @cmd: Command which is not longer in use
-- *
-- * Must be called with interrupt lock held.
-- */
--static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi,
-- struct ibmvscsis_cmd *cmd)
--{
-- struct iu_entry *iue = cmd->iue;
--
-- switch (cmd->type) {
-- case TASK_MANAGEMENT:
-- case SCSI_CDB:
-- /*
-- * When the queue goes down this value is cleared, so it
-- * cannot be cleared in this general purpose function.
-- */
-- if (vscsi->debit)
-- vscsi->debit -= 1;
-- break;
-- case ADAPTER_MAD:
-- vscsi->flags &= ~PROCESSING_MAD;
-- break;
-- case UNSET_TYPE:
-- break;
-- default:
-- dev_err(&vscsi->dev, "free_cmd_resources unknown type %d\n",
-- cmd->type);
-- break;
-- }
--
-- cmd->iue = NULL;
-- list_add_tail(&cmd->list, &vscsi->free_cmd);
-- srp_iu_put(iue);
--
-- if (list_empty(&vscsi->active_q) && list_empty(&vscsi->schedule_q) &&
-- list_empty(&vscsi->waiting_rsp) && (vscsi->flags & WAIT_FOR_IDLE)) {
-- vscsi->flags &= ~WAIT_FOR_IDLE;
-- complete(&vscsi->wait_idle);
-- }
--}
--
--/**
- * ibmvscsis_disconnect() - Helper function to disconnect
- * @work: Pointer to work_struct, gives access to our adapter structure
- *
-@@ -576,7 +416,6 @@ static void ibmvscsis_disconnect(struct work_struct *work)
- proc_work);
- u16 new_state;
- bool wait_idle = false;
-- long rc = ADAPT_SUCCESS;
-
- spin_lock_bh(&vscsi->intr_lock);
- new_state = vscsi->new_state;
-@@ -590,7 +429,7 @@ static void ibmvscsis_disconnect(struct work_struct *work)
- * should transitition to the new state
- */
- switch (vscsi->state) {
-- /* Should never be called while in this state. */
-+ /* Should never be called while in this state. */
- case NO_QUEUE:
- /*
- * Can never transition from this state;
-@@ -629,30 +468,24 @@ static void ibmvscsis_disconnect(struct work_struct *work)
- vscsi->state = new_state;
- break;
-
-- /*
-- * If this is a transition into an error state.
-- * a client is attempting to establish a connection
-- * and has violated the RPA protocol.
-- * There can be nothing pending on the adapter although
-- * there can be requests in the command queue.
-- */
- case WAIT_ENABLED:
-- case PART_UP_WAIT_ENAB:
- switch (new_state) {
-- case ERR_DISCONNECT:
-- vscsi->flags |= RESPONSE_Q_DOWN;
-+ case UNCONFIGURING:
- vscsi->state = new_state;
-+ vscsi->flags |= RESPONSE_Q_DOWN;
- vscsi->flags &= ~(SCHEDULE_DISCONNECT |
- DISCONNECT_SCHEDULED);
-- ibmvscsis_free_command_q(vscsi);
-- break;
-- case ERR_DISCONNECT_RECONNECT:
-- ibmvscsis_reset_queue(vscsi, WAIT_ENABLED);
-+ dma_rmb();
-+ if (vscsi->flags & CFG_SLEEPING) {
-+ vscsi->flags &= ~CFG_SLEEPING;
-+ complete(&vscsi->unconfig);
-+ }
- break;
-
- /* should never happen */
-+ case ERR_DISCONNECT:
-+ case ERR_DISCONNECT_RECONNECT:
- case WAIT_IDLE:
-- rc = ERROR;
- dev_err(&vscsi->dev, "disconnect: invalid state %d for WAIT_IDLE\n",
- vscsi->state);
- break;
-@@ -661,6 +494,13 @@ static void ibmvscsis_disconnect(struct work_struct *work)
-
- case WAIT_IDLE:
- switch (new_state) {
-+ case UNCONFIGURING:
-+ vscsi->flags |= RESPONSE_Q_DOWN;
-+ vscsi->state = new_state;
-+ vscsi->flags &= ~(SCHEDULE_DISCONNECT |
-+ DISCONNECT_SCHEDULED);
-+ ibmvscsis_free_command_q(vscsi);
-+ break;
- case ERR_DISCONNECT:
- case ERR_DISCONNECT_RECONNECT:
- vscsi->state = new_state;
-@@ -765,45 +605,348 @@ static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state,
- else
- state = vscsi->state;
-
-- switch (state) {
-- case NO_QUEUE:
-- case UNCONFIGURING:
-- break;
-+ switch (state) {
-+ case NO_QUEUE:
-+ case UNCONFIGURING:
-+ break;
-+
-+ case ERR_DISCONNECTED:
-+ case ERR_DISCONNECT:
-+ case UNDEFINED:
-+ if (new_state == UNCONFIGURING)
-+ vscsi->new_state = new_state;
-+ break;
-+
-+ case ERR_DISCONNECT_RECONNECT:
-+ switch (new_state) {
-+ case UNCONFIGURING:
-+ case ERR_DISCONNECT:
-+ vscsi->new_state = new_state;
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+
-+ case WAIT_ENABLED:
-+ case WAIT_IDLE:
-+ case WAIT_CONNECTION:
-+ case CONNECTED:
-+ case SRP_PROCESSING:
-+ vscsi->new_state = new_state;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ }
-+
-+ pr_debug("Leaving post_disconnect: flags 0x%x, new_state 0x%x\n",
-+ vscsi->flags, vscsi->new_state);
-+}
-+
-+/**
-+ * ibmvscsis_handle_init_compl_msg() - Respond to an Init Complete Message
-+ * @vscsi: Pointer to our adapter structure
-+ *
-+ * Must be called with interrupt lock held.
-+ */
-+static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi)
-+{
-+ long rc = ADAPT_SUCCESS;
-+
-+ switch (vscsi->state) {
-+ case NO_QUEUE:
-+ case ERR_DISCONNECT:
-+ case ERR_DISCONNECT_RECONNECT:
-+ case ERR_DISCONNECTED:
-+ case UNCONFIGURING:
-+ case UNDEFINED:
-+ rc = ERROR;
-+ break;
-+
-+ case WAIT_CONNECTION:
-+ vscsi->state = CONNECTED;
-+ break;
-+
-+ case WAIT_IDLE:
-+ case SRP_PROCESSING:
-+ case CONNECTED:
-+ case WAIT_ENABLED:
-+ default:
-+ rc = ERROR;
-+ dev_err(&vscsi->dev, "init_msg: invalid state %d to get init compl msg\n",
-+ vscsi->state);
-+ ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-+ break;
-+ }
-+
-+ return rc;
-+}
-+
-+/**
-+ * ibmvscsis_handle_init_msg() - Respond to an Init Message
-+ * @vscsi: Pointer to our adapter structure
-+ *
-+ * Must be called with interrupt lock held.
-+ */
-+static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi)
-+{
-+ long rc = ADAPT_SUCCESS;
-+
-+ switch (vscsi->state) {
-+ case WAIT_CONNECTION:
-+ rc = ibmvscsis_send_init_message(vscsi, INIT_COMPLETE_MSG);
-+ switch (rc) {
-+ case H_SUCCESS:
-+ vscsi->state = CONNECTED;
-+ break;
-+
-+ case H_PARAMETER:
-+ dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n",
-+ rc);
-+ ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);
-+ break;
-+
-+ case H_DROPPED:
-+ dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n",
-+ rc);
-+ rc = ERROR;
-+ ibmvscsis_post_disconnect(vscsi,
-+ ERR_DISCONNECT_RECONNECT, 0);
-+ break;
-+
-+ case H_CLOSED:
-+ pr_warn("init_msg: failed to send, rc %ld\n", rc);
-+ rc = 0;
-+ break;
-+ }
-+ break;
-+
-+ case UNDEFINED:
-+ rc = ERROR;
-+ break;
-+
-+ case UNCONFIGURING:
-+ break;
-+
-+ case WAIT_ENABLED:
-+ case CONNECTED:
-+ case SRP_PROCESSING:
-+ case WAIT_IDLE:
-+ case NO_QUEUE:
-+ case ERR_DISCONNECT:
-+ case ERR_DISCONNECT_RECONNECT:
-+ case ERR_DISCONNECTED:
-+ default:
-+ rc = ERROR;
-+ dev_err(&vscsi->dev, "init_msg: invalid state %d to get init msg\n",
-+ vscsi->state);
-+ ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-+ break;
-+ }
-+
-+ return rc;
-+}
-+
-+/**
-+ * ibmvscsis_init_msg() - Respond to an init message
-+ * @vscsi: Pointer to our adapter structure
-+ * @crq: Pointer to CRQ element containing the Init Message
-+ *
-+ * EXECUTION ENVIRONMENT:
-+ * Interrupt, interrupt lock held
-+ */
-+static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq)
-+{
-+ long rc = ADAPT_SUCCESS;
-+
-+ pr_debug("init_msg: state 0x%hx\n", vscsi->state);
-+
-+ rc = h_vioctl(vscsi->dds.unit_id, H_GET_PARTNER_INFO,
-+ (u64)vscsi->map_ioba | ((u64)PAGE_SIZE << 32), 0, 0, 0,
-+ 0);
-+ if (rc == H_SUCCESS) {
-+ vscsi->client_data.partition_number =
-+ be64_to_cpu(*(u64 *)vscsi->map_buf);
-+ pr_debug("init_msg, part num %d\n",
-+ vscsi->client_data.partition_number);
-+ } else {
-+ pr_debug("init_msg h_vioctl rc %ld\n", rc);
-+ rc = ADAPT_SUCCESS;
-+ }
-+
-+ if (crq->format == INIT_MSG) {
-+ rc = ibmvscsis_handle_init_msg(vscsi);
-+ } else if (crq->format == INIT_COMPLETE_MSG) {
-+ rc = ibmvscsis_handle_init_compl_msg(vscsi);
-+ } else {
-+ rc = ERROR;
-+ dev_err(&vscsi->dev, "init_msg: invalid format %d\n",
-+ (uint)crq->format);
-+ ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-+ }
-+
-+ return rc;
-+}
-+
-+/**
-+ * ibmvscsis_establish_new_q() - Establish new CRQ queue
-+ * @vscsi: Pointer to our adapter structure
-+ *
-+ * Must be called with interrupt lock held.
-+ */
-+static long ibmvscsis_establish_new_q(struct scsi_info *vscsi)
-+{
-+ long rc = ADAPT_SUCCESS;
-+ uint format;
-+
-+ vscsi->flags &= PRESERVE_FLAG_FIELDS;
-+ vscsi->rsp_q_timer.timer_pops = 0;
-+ vscsi->debit = 0;
-+ vscsi->credit = 0;
-+
-+ rc = vio_enable_interrupts(vscsi->dma_dev);
-+ if (rc) {
-+ pr_warn("establish_new_q: failed to enable interrupts, rc %ld\n",
-+ rc);
-+ return rc;
-+ }
-+
-+ rc = ibmvscsis_check_init_msg(vscsi, &format);
-+ if (rc) {
-+ dev_err(&vscsi->dev, "establish_new_q: check_init_msg failed, rc %ld\n",
-+ rc);
-+ return rc;
-+ }
-+
-+ if (format == UNUSED_FORMAT) {
-+ rc = ibmvscsis_send_init_message(vscsi, INIT_MSG);
-+ switch (rc) {
-+ case H_SUCCESS:
-+ case H_DROPPED:
-+ case H_CLOSED:
-+ rc = ADAPT_SUCCESS;
-+ break;
-+
-+ case H_PARAMETER:
-+ case H_HARDWARE:
-+ break;
-+
-+ default:
-+ vscsi->state = UNDEFINED;
-+ rc = H_HARDWARE;
-+ break;
-+ }
-+ } else if (format == INIT_MSG) {
-+ rc = ibmvscsis_handle_init_msg(vscsi);
-+ }
-+
-+ return rc;
-+}
-+
-+/**
-+ * ibmvscsis_reset_queue() - Reset CRQ Queue
-+ * @vscsi: Pointer to our adapter structure
-+ *
-+ * This function calls h_free_q and then calls h_reg_q and does all
-+ * of the bookkeeping to get us back to where we can communicate.
-+ *
-+ * Actually, we don't always call h_free_crq. A problem was discovered
-+ * where one partition would close and reopen his queue, which would
-+ * cause his partner to get a transport event, which would cause him to
-+ * close and reopen his queue, which would cause the original partition
-+ * to get a transport event, etc., etc. To prevent this, we don't
-+ * actually close our queue if the client initiated the reset, (i.e.
-+ * either we got a transport event or we have detected that the client's
-+ * queue is gone)
-+ *
-+ * EXECUTION ENVIRONMENT:
-+ * Process environment, called with interrupt lock held
-+ */
-+static void ibmvscsis_reset_queue(struct scsi_info *vscsi)
-+{
-+ int bytes;
-+ long rc = ADAPT_SUCCESS;
-+
-+ pr_debug("reset_queue: flags 0x%x\n", vscsi->flags);
-+
-+ /* don't reset, the client did it for us */
-+ if (vscsi->flags & (CLIENT_FAILED | TRANS_EVENT)) {
-+ vscsi->flags &= PRESERVE_FLAG_FIELDS;
-+ vscsi->rsp_q_timer.timer_pops = 0;
-+ vscsi->debit = 0;
-+ vscsi->credit = 0;
-+ vscsi->state = WAIT_CONNECTION;
-+ vio_enable_interrupts(vscsi->dma_dev);
-+ } else {
-+ rc = ibmvscsis_free_command_q(vscsi);
-+ if (rc == ADAPT_SUCCESS) {
-+ vscsi->state = WAIT_CONNECTION;
-+
-+ bytes = vscsi->cmd_q.size * PAGE_SIZE;
-+ rc = h_reg_crq(vscsi->dds.unit_id,
-+ vscsi->cmd_q.crq_token, bytes);
-+ if (rc == H_CLOSED || rc == H_SUCCESS) {
-+ rc = ibmvscsis_establish_new_q(vscsi);
-+ }
-
-- case ERR_DISCONNECTED:
-- case ERR_DISCONNECT:
-- case UNDEFINED:
-- if (new_state == UNCONFIGURING)
-- vscsi->new_state = new_state;
-- break;
-+ if (rc != ADAPT_SUCCESS) {
-+ pr_debug("reset_queue: reg_crq rc %ld\n", rc);
-
-- case ERR_DISCONNECT_RECONNECT:
-- switch (new_state) {
-- case UNCONFIGURING:
-- case ERR_DISCONNECT:
-- vscsi->new_state = new_state;
-- break;
-- default:
-- break;
-+ vscsi->state = ERR_DISCONNECTED;
-+ vscsi->flags |= RESPONSE_Q_DOWN;
-+ ibmvscsis_free_command_q(vscsi);
- }
-- break;
-+ } else {
-+ vscsi->state = ERR_DISCONNECTED;
-+ vscsi->flags |= RESPONSE_Q_DOWN;
-+ }
-+ }
-+}
-
-- case WAIT_ENABLED:
-- case PART_UP_WAIT_ENAB:
-- case WAIT_IDLE:
-- case WAIT_CONNECTION:
-- case CONNECTED:
-- case SRP_PROCESSING:
-- vscsi->new_state = new_state;
-- break;
-+/**
-+ * ibmvscsis_free_cmd_resources() - Free command resources
-+ * @vscsi: Pointer to our adapter structure
-+ * @cmd: Command which is not longer in use
-+ *
-+ * Must be called with interrupt lock held.
-+ */
-+static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi,
-+ struct ibmvscsis_cmd *cmd)
-+{
-+ struct iu_entry *iue = cmd->iue;
-
-- default:
-- break;
-- }
-+ switch (cmd->type) {
-+ case TASK_MANAGEMENT:
-+ case SCSI_CDB:
-+ /*
-+ * When the queue goes down this value is cleared, so it
-+ * cannot be cleared in this general purpose function.
-+ */
-+ if (vscsi->debit)
-+ vscsi->debit -= 1;
-+ break;
-+ case ADAPTER_MAD:
-+ vscsi->flags &= ~PROCESSING_MAD;
-+ break;
-+ case UNSET_TYPE:
-+ break;
-+ default:
-+ dev_err(&vscsi->dev, "free_cmd_resources unknown type %d\n",
-+ cmd->type);
-+ break;
- }
-
-- pr_debug("Leaving post_disconnect: flags 0x%x, new_state 0x%x\n",
-- vscsi->flags, vscsi->new_state);
-+ cmd->iue = NULL;
-+ list_add_tail(&cmd->list, &vscsi->free_cmd);
-+ srp_iu_put(iue);
-+
-+ if (list_empty(&vscsi->active_q) && list_empty(&vscsi->schedule_q) &&
-+ list_empty(&vscsi->waiting_rsp) && (vscsi->flags & WAIT_FOR_IDLE)) {
-+ vscsi->flags &= ~WAIT_FOR_IDLE;
-+ complete(&vscsi->wait_idle);
-+ }
- }
-
- /**
-@@ -864,10 +1007,6 @@ static long ibmvscsis_trans_event(struct scsi_info *vscsi,
- TRANS_EVENT));
- break;
-
-- case PART_UP_WAIT_ENAB:
-- vscsi->state = WAIT_ENABLED;
-- break;
--
- case SRP_PROCESSING:
- if ((vscsi->debit > 0) ||
- !list_empty(&vscsi->schedule_q) ||
-@@ -896,7 +1035,7 @@ static long ibmvscsis_trans_event(struct scsi_info *vscsi,
- }
- }
-
-- rc = vscsi->flags & SCHEDULE_DISCONNECT;
-+ rc = vscsi->flags & SCHEDULE_DISCONNECT;
-
- pr_debug("Leaving trans_event: flags 0x%x, state 0x%hx, rc %ld\n",
- vscsi->flags, vscsi->state, rc);
-@@ -1067,16 +1206,28 @@ static void ibmvscsis_adapter_idle(struct scsi_info *vscsi)
- free_qs = true;
-
- switch (vscsi->state) {
-+ case UNCONFIGURING:
-+ ibmvscsis_free_command_q(vscsi);
-+ dma_rmb();
-+ isync();
-+ if (vscsi->flags & CFG_SLEEPING) {
-+ vscsi->flags &= ~CFG_SLEEPING;
-+ complete(&vscsi->unconfig);
-+ }
-+ break;
- case ERR_DISCONNECT_RECONNECT:
-- ibmvscsis_reset_queue(vscsi, WAIT_CONNECTION);
-+ ibmvscsis_reset_queue(vscsi);
- pr_debug("adapter_idle, disc_rec: flags 0x%x\n", vscsi->flags);
- break;
-
- case ERR_DISCONNECT:
- ibmvscsis_free_command_q(vscsi);
-- vscsi->flags &= ~DISCONNECT_SCHEDULED;
-+ vscsi->flags &= ~(SCHEDULE_DISCONNECT | DISCONNECT_SCHEDULED);
- vscsi->flags |= RESPONSE_Q_DOWN;
-- vscsi->state = ERR_DISCONNECTED;
-+ if (vscsi->tport.enabled)
-+ vscsi->state = ERR_DISCONNECTED;
-+ else
-+ vscsi->state = WAIT_ENABLED;
- pr_debug("adapter_idle, disc: flags 0x%x, state 0x%hx\n",
- vscsi->flags, vscsi->state);
- break;
-@@ -1221,7 +1372,7 @@ static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi,
- * @iue: Information Unit containing the Adapter Info MAD request
- *
- * EXECUTION ENVIRONMENT:
-- * Interrupt adpater lock is held
-+ * Interrupt adapter lock is held
- */
- static long ibmvscsis_adapter_info(struct scsi_info *vscsi,
- struct iu_entry *iue)
-@@ -1621,8 +1772,8 @@ static void ibmvscsis_send_messages(struct scsi_info *vscsi)
- be64_to_cpu(msg_hi),
- be64_to_cpu(cmd->rsp.tag));
-
-- pr_debug("send_messages: tag 0x%llx, rc %ld\n",
-- be64_to_cpu(cmd->rsp.tag), rc);
-+ pr_debug("send_messages: cmd %p, tag 0x%llx, rc %ld\n",
-+ cmd, be64_to_cpu(cmd->rsp.tag), rc);
-
- /* if all ok free up the command element resources */
- if (rc == H_SUCCESS) {
-@@ -1692,7 +1843,7 @@ static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi,
- * @crq: Pointer to the CRQ entry containing the MAD request
- *
- * EXECUTION ENVIRONMENT:
-- * Interrupt called with adapter lock held
-+ * Interrupt, called with adapter lock held
- */
- static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq)
- {
-@@ -1746,14 +1897,7 @@ static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq)
-
- pr_debug("mad: type %d\n", be32_to_cpu(mad->type));
-
-- if (be16_to_cpu(mad->length) < 0) {
-- dev_err(&vscsi->dev, "mad: length is < 0\n");
-- ibmvscsis_post_disconnect(vscsi,
-- ERR_DISCONNECT_RECONNECT, 0);
-- rc = SRP_VIOLATION;
-- } else {
-- rc = ibmvscsis_process_mad(vscsi, iue);
-- }
-+ rc = ibmvscsis_process_mad(vscsi, iue);
-
- pr_debug("mad: status %hd, rc %ld\n", be16_to_cpu(mad->status),
- rc);
-@@ -1865,7 +2009,7 @@ static long ibmvscsis_srp_login_rej(struct scsi_info *vscsi,
- break;
- case H_PERMISSION:
- if (connection_broken(vscsi))
-- flag_bits = RESPONSE_Q_DOWN | CLIENT_FAILED;
-+ flag_bits = RESPONSE_Q_DOWN | CLIENT_FAILED;
- dev_err(&vscsi->dev, "login_rej: error copying to client, rc %ld\n",
- rc);
- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,
-@@ -2090,248 +2234,98 @@ static void ibmvscsis_srp_cmd(struct scsi_info *vscsi, struct viosrp_crq *crq)
- break;
-
- case SRP_TSK_MGMT:
-- tsk = &vio_iu(iue)->srp.tsk_mgmt;
-- pr_debug("tsk_mgmt tag: %llu (0x%llx)\n", tsk->tag,
-- tsk->tag);
-- cmd->rsp.tag = tsk->tag;
-- vscsi->debit += 1;
-- cmd->type = TASK_MANAGEMENT;
-- list_add_tail(&cmd->list, &vscsi->schedule_q);
-- queue_work(vscsi->work_q, &cmd->work);
-- break;
--
-- case SRP_CMD:
-- pr_debug("srp_cmd tag: %llu (0x%llx)\n", srp->tag,
-- srp->tag);
-- cmd->rsp.tag = srp->tag;
-- vscsi->debit += 1;
-- cmd->type = SCSI_CDB;
-- /*
-- * We want to keep track of work waiting for
-- * the workqueue.
-- */
-- list_add_tail(&cmd->list, &vscsi->schedule_q);
-- queue_work(vscsi->work_q, &cmd->work);
-- break;
--
-- case SRP_I_LOGOUT:
-- rc = ibmvscsis_srp_i_logout(vscsi, cmd, crq);
-- break;
--
-- case SRP_CRED_RSP:
-- case SRP_AER_RSP:
-- default:
-- ibmvscsis_free_cmd_resources(vscsi, cmd);
-- dev_err(&vscsi->dev, "invalid srp cmd, opcode %d\n",
-- (uint)srp->opcode);
-- ibmvscsis_post_disconnect(vscsi,
-- ERR_DISCONNECT_RECONNECT, 0);
-- break;
-- }
-- } else if (srp->opcode == SRP_LOGIN_REQ && vscsi->state == CONNECTED) {
-- rc = ibmvscsis_srp_login(vscsi, cmd, crq);
-- } else {
-- ibmvscsis_free_cmd_resources(vscsi, cmd);
-- dev_err(&vscsi->dev, "Invalid state %d to handle srp cmd\n",
-- vscsi->state);
-- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-- }
--}
--
--/**
-- * ibmvscsis_ping_response() - Respond to a ping request
-- * @vscsi: Pointer to our adapter structure
-- *
-- * Let the client know that the server is alive and waiting on
-- * its native I/O stack.
-- * If any type of error occurs from the call to queue a ping
-- * response then the client is either not accepting or receiving
-- * interrupts. Disconnect with an error.
-- *
-- * EXECUTION ENVIRONMENT:
-- * Interrupt, interrupt lock held
-- */
--static long ibmvscsis_ping_response(struct scsi_info *vscsi)
--{
-- struct viosrp_crq *crq;
-- u64 buffer[2] = { 0, 0 };
-- long rc;
--
-- crq = (struct viosrp_crq *)&buffer;
-- crq->valid = VALID_CMD_RESP_EL;
-- crq->format = (u8)MESSAGE_IN_CRQ;
-- crq->status = PING_RESPONSE;
--
-- rc = h_send_crq(vscsi->dds.unit_id, cpu_to_be64(buffer[MSG_HI]),
-- cpu_to_be64(buffer[MSG_LOW]));
--
-- switch (rc) {
-- case H_SUCCESS:
-- break;
-- case H_CLOSED:
-- vscsi->flags |= CLIENT_FAILED;
-- case H_DROPPED:
-- vscsi->flags |= RESPONSE_Q_DOWN;
-- case H_REMOTE_PARM:
-- dev_err(&vscsi->dev, "ping_response: h_send_crq failed, rc %ld\n",
-- rc);
-- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-- break;
-- default:
-- dev_err(&vscsi->dev, "ping_response: h_send_crq returned unknown rc %ld\n",
-- rc);
-- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);
-- break;
-- }
--
-- return rc;
--}
--
--/**
-- * ibmvscsis_handle_init_compl_msg() - Respond to an Init Complete Message
-- * @vscsi: Pointer to our adapter structure
-- *
-- * Must be called with interrupt lock held.
-- */
--static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi)
--{
-- long rc = ADAPT_SUCCESS;
--
-- switch (vscsi->state) {
-- case NO_QUEUE:
-- case ERR_DISCONNECT:
-- case ERR_DISCONNECT_RECONNECT:
-- case ERR_DISCONNECTED:
-- case UNCONFIGURING:
-- case UNDEFINED:
-- rc = ERROR;
-- break;
--
-- case WAIT_CONNECTION:
-- vscsi->state = CONNECTED;
-- break;
--
-- case WAIT_IDLE:
-- case SRP_PROCESSING:
-- case CONNECTED:
-- case WAIT_ENABLED:
-- case PART_UP_WAIT_ENAB:
-- default:
-- rc = ERROR;
-- dev_err(&vscsi->dev, "init_msg: invalid state %d to get init compl msg\n",
-- vscsi->state);
-- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-- break;
-- }
--
-- return rc;
--}
--
--/**
-- * ibmvscsis_handle_init_msg() - Respond to an Init Message
-- * @vscsi: Pointer to our adapter structure
-- *
-- * Must be called with interrupt lock held.
-- */
--static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi)
--{
-- long rc = ADAPT_SUCCESS;
--
-- switch (vscsi->state) {
-- case WAIT_ENABLED:
-- vscsi->state = PART_UP_WAIT_ENAB;
-- break;
-+ tsk = &vio_iu(iue)->srp.tsk_mgmt;
-+ pr_debug("tsk_mgmt tag: %llu (0x%llx)\n", tsk->tag,
-+ tsk->tag);
-+ cmd->rsp.tag = tsk->tag;
-+ vscsi->debit += 1;
-+ cmd->type = TASK_MANAGEMENT;
-+ list_add_tail(&cmd->list, &vscsi->schedule_q);
-+ queue_work(vscsi->work_q, &cmd->work);
-+ break;
-
-- case WAIT_CONNECTION:
-- rc = ibmvscsis_send_init_message(vscsi, INIT_COMPLETE_MSG);
-- switch (rc) {
-- case H_SUCCESS:
-- vscsi->state = CONNECTED;
-+ case SRP_CMD:
-+ pr_debug("srp_cmd tag: %llu (0x%llx)\n", srp->tag,
-+ srp->tag);
-+ cmd->rsp.tag = srp->tag;
-+ vscsi->debit += 1;
-+ cmd->type = SCSI_CDB;
-+ /*
-+ * We want to keep track of work waiting for
-+ * the workqueue.
-+ */
-+ list_add_tail(&cmd->list, &vscsi->schedule_q);
-+ queue_work(vscsi->work_q, &cmd->work);
- break;
-
-- case H_PARAMETER:
-- dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n",
-- rc);
-- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);
-+ case SRP_I_LOGOUT:
-+ rc = ibmvscsis_srp_i_logout(vscsi, cmd, crq);
- break;
-
-- case H_DROPPED:
-- dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n",
-- rc);
-- rc = ERROR;
-+ case SRP_CRED_RSP:
-+ case SRP_AER_RSP:
-+ default:
-+ ibmvscsis_free_cmd_resources(vscsi, cmd);
-+ dev_err(&vscsi->dev, "invalid srp cmd, opcode %d\n",
-+ (uint)srp->opcode);
- ibmvscsis_post_disconnect(vscsi,
- ERR_DISCONNECT_RECONNECT, 0);
- break;
--
-- case H_CLOSED:
-- pr_warn("init_msg: failed to send, rc %ld\n", rc);
-- rc = 0;
-- break;
- }
-- break;
--
-- case UNDEFINED:
-- rc = ERROR;
-- break;
--
-- case UNCONFIGURING:
-- break;
--
-- case PART_UP_WAIT_ENAB:
-- case CONNECTED:
-- case SRP_PROCESSING:
-- case WAIT_IDLE:
-- case NO_QUEUE:
-- case ERR_DISCONNECT:
-- case ERR_DISCONNECT_RECONNECT:
-- case ERR_DISCONNECTED:
-- default:
-- rc = ERROR;
-- dev_err(&vscsi->dev, "init_msg: invalid state %d to get init msg\n",
-+ } else if (srp->opcode == SRP_LOGIN_REQ && vscsi->state == CONNECTED) {
-+ rc = ibmvscsis_srp_login(vscsi, cmd, crq);
-+ } else {
-+ ibmvscsis_free_cmd_resources(vscsi, cmd);
-+ dev_err(&vscsi->dev, "Invalid state %d to handle srp cmd\n",
- vscsi->state);
- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-- break;
- }
--
-- return rc;
- }
-
- /**
-- * ibmvscsis_init_msg() - Respond to an init message
-+ * ibmvscsis_ping_response() - Respond to a ping request
- * @vscsi: Pointer to our adapter structure
-- * @crq: Pointer to CRQ element containing the Init Message
-+ *
-+ * Let the client know that the server is alive and waiting on
-+ * its native I/O stack.
-+ * If any type of error occurs from the call to queue a ping
-+ * response then the client is either not accepting or receiving
-+ * interrupts. Disconnect with an error.
- *
- * EXECUTION ENVIRONMENT:
- * Interrupt, interrupt lock held
- */
--static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq)
-+static long ibmvscsis_ping_response(struct scsi_info *vscsi)
- {
-- long rc = ADAPT_SUCCESS;
-+ struct viosrp_crq *crq;
-+ u64 buffer[2] = { 0, 0 };
-+ long rc;
-
-- pr_debug("init_msg: state 0x%hx\n", vscsi->state);
-+ crq = (struct viosrp_crq *)&buffer;
-+ crq->valid = VALID_CMD_RESP_EL;
-+ crq->format = (u8)MESSAGE_IN_CRQ;
-+ crq->status = PING_RESPONSE;
-
-- rc = h_vioctl(vscsi->dds.unit_id, H_GET_PARTNER_INFO,
-- (u64)vscsi->map_ioba | ((u64)PAGE_SIZE << 32), 0, 0, 0,
-- 0);
-- if (rc == H_SUCCESS) {
-- vscsi->client_data.partition_number =
-- be64_to_cpu(*(u64 *)vscsi->map_buf);
-- pr_debug("init_msg, part num %d\n",
-- vscsi->client_data.partition_number);
-- } else {
-- pr_debug("init_msg h_vioctl rc %ld\n", rc);
-- rc = ADAPT_SUCCESS;
-- }
-+ rc = h_send_crq(vscsi->dds.unit_id, cpu_to_be64(buffer[MSG_HI]),
-+ cpu_to_be64(buffer[MSG_LOW]));
-
-- if (crq->format == INIT_MSG) {
-- rc = ibmvscsis_handle_init_msg(vscsi);
-- } else if (crq->format == INIT_COMPLETE_MSG) {
-- rc = ibmvscsis_handle_init_compl_msg(vscsi);
-- } else {
-- rc = ERROR;
-- dev_err(&vscsi->dev, "init_msg: invalid format %d\n",
-- (uint)crq->format);
-+ switch (rc) {
-+ case H_SUCCESS:
-+ break;
-+ case H_CLOSED:
-+ vscsi->flags |= CLIENT_FAILED;
-+ case H_DROPPED:
-+ vscsi->flags |= RESPONSE_Q_DOWN;
-+ case H_REMOTE_PARM:
-+ dev_err(&vscsi->dev, "ping_response: h_send_crq failed, rc %ld\n",
-+ rc);
- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-+ break;
-+ default:
-+ dev_err(&vscsi->dev, "ping_response: h_send_crq returned unknown rc %ld\n",
-+ rc);
-+ ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);
-+ break;
- }
-
- return rc;
-@@ -2392,7 +2386,7 @@ static long ibmvscsis_parse_command(struct scsi_info *vscsi,
- break;
-
- case VALID_TRANS_EVENT:
-- rc = ibmvscsis_trans_event(vscsi, crq);
-+ rc = ibmvscsis_trans_event(vscsi, crq);
- break;
-
- case VALID_INIT_MSG:
-@@ -2523,7 +2517,6 @@ static void ibmvscsis_parse_cmd(struct scsi_info *vscsi,
- dev_err(&vscsi->dev, "0x%llx: parsing SRP descriptor table failed.\n",
- srp->tag);
- goto fail;
-- return;
- }
-
- cmd->rsp.sol_not = srp->sol_not;
-@@ -2560,6 +2553,10 @@ static void ibmvscsis_parse_cmd(struct scsi_info *vscsi,
- data_len, attr, dir, 0);
- if (rc) {
- dev_err(&vscsi->dev, "target_submit_cmd failed, rc %d\n", rc);
-+ spin_lock_bh(&vscsi->intr_lock);
-+ list_del(&cmd->list);
-+ ibmvscsis_free_cmd_resources(vscsi, cmd);
-+ spin_unlock_bh(&vscsi->intr_lock);
- goto fail;
- }
- return;
-@@ -2639,6 +2636,9 @@ static void ibmvscsis_parse_task(struct scsi_info *vscsi,
- if (rc) {
- dev_err(&vscsi->dev, "target_submit_tmr failed, rc %d\n",
- rc);
-+ spin_lock_bh(&vscsi->intr_lock);
-+ list_del(&cmd->list);
-+ spin_unlock_bh(&vscsi->intr_lock);
- cmd->se_cmd.se_tmr_req->response =
- TMR_FUNCTION_REJECTED;
- }
-@@ -2787,36 +2787,6 @@ static irqreturn_t ibmvscsis_interrupt(int dummy, void *data)
- }
-
- /**
-- * ibmvscsis_check_q() - Helper function to Check Init Message Valid
-- * @vscsi: Pointer to our adapter structure
-- *
-- * Checks if a initialize message was queued by the initiatior
-- * while the timing window was open. This function is called from
-- * probe after the CRQ is created and interrupts are enabled.
-- * It would only be used by adapters who wait for some event before
-- * completing the init handshake with the client. For ibmvscsi, this
-- * event is waiting for the port to be enabled.
-- *
-- * EXECUTION ENVIRONMENT:
-- * Process level only, interrupt lock held
-- */
--static long ibmvscsis_check_q(struct scsi_info *vscsi)
--{
-- uint format;
-- long rc;
--
-- rc = ibmvscsis_check_init_msg(vscsi, &format);
-- if (rc)
-- ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);
-- else if (format == UNUSED_FORMAT)
-- vscsi->state = WAIT_ENABLED;
-- else
-- vscsi->state = PART_UP_WAIT_ENAB;
--
-- return rc;
--}
--
--/**
- * ibmvscsis_enable_change_state() - Set new state based on enabled status
- * @vscsi: Pointer to our adapter structure
- *
-@@ -2827,77 +2797,19 @@ static long ibmvscsis_check_q(struct scsi_info *vscsi)
- */
- static long ibmvscsis_enable_change_state(struct scsi_info *vscsi)
- {
-+ int bytes;
- long rc = ADAPT_SUCCESS;
-
--handle_state_change:
-- switch (vscsi->state) {
-- case WAIT_ENABLED:
-- rc = ibmvscsis_send_init_message(vscsi, INIT_MSG);
-- switch (rc) {
-- case H_SUCCESS:
-- case H_DROPPED:
-- case H_CLOSED:
-- vscsi->state = WAIT_CONNECTION;
-- rc = ADAPT_SUCCESS;
-- break;
--
-- case H_PARAMETER:
-- break;
--
-- case H_HARDWARE:
-- break;
--
-- default:
-- vscsi->state = UNDEFINED;
-- rc = H_HARDWARE;
-- break;
-- }
-- break;
-- case PART_UP_WAIT_ENAB:
-- rc = ibmvscsis_send_init_message(vscsi, INIT_COMPLETE_MSG);
-- switch (rc) {
-- case H_SUCCESS:
-- vscsi->state = CONNECTED;
-- rc = ADAPT_SUCCESS;
-- break;
--
-- case H_DROPPED:
-- case H_CLOSED:
-- vscsi->state = WAIT_ENABLED;
-- goto handle_state_change;
--
-- case H_PARAMETER:
-- break;
--
-- case H_HARDWARE:
-- break;
--
-- default:
-- rc = H_HARDWARE;
-- break;
-- }
-- break;
--
-- case WAIT_CONNECTION:
-- case WAIT_IDLE:
-- case SRP_PROCESSING:
-- case CONNECTED:
-- rc = ADAPT_SUCCESS;
-- break;
-- /* should not be able to get here */
-- case UNCONFIGURING:
-- rc = ERROR;
-- vscsi->state = UNDEFINED;
-- break;
-+ bytes = vscsi->cmd_q.size * PAGE_SIZE;
-+ rc = h_reg_crq(vscsi->dds.unit_id, vscsi->cmd_q.crq_token, bytes);
-+ if (rc == H_CLOSED || rc == H_SUCCESS) {
-+ vscsi->state = WAIT_CONNECTION;
-+ rc = ibmvscsis_establish_new_q(vscsi);
-+ }
-
-- /* driver should never allow this to happen */
-- case ERR_DISCONNECT:
-- case ERR_DISCONNECT_RECONNECT:
-- default:
-- dev_err(&vscsi->dev, "in invalid state %d during enable_change_state\n",
-- vscsi->state);
-- rc = ADAPT_SUCCESS;
-- break;
-+ if (rc != ADAPT_SUCCESS) {
-+ vscsi->state = ERR_DISCONNECTED;
-+ vscsi->flags |= RESPONSE_Q_DOWN;
- }
-
- return rc;
-@@ -2917,7 +2829,6 @@ static long ibmvscsis_enable_change_state(struct scsi_info *vscsi)
- */
- static long ibmvscsis_create_command_q(struct scsi_info *vscsi, int num_cmds)
- {
-- long rc = 0;
- int pages;
- struct vio_dev *vdev = vscsi->dma_dev;
-
-@@ -2941,22 +2852,7 @@ static long ibmvscsis_create_command_q(struct scsi_info *vscsi, int num_cmds)
- return -ENOMEM;
- }
-
-- rc = h_reg_crq(vscsi->dds.unit_id, vscsi->cmd_q.crq_token, PAGE_SIZE);
-- if (rc) {
-- if (rc == H_CLOSED) {
-- vscsi->state = WAIT_ENABLED;
-- rc = 0;
-- } else {
-- dma_unmap_single(&vdev->dev, vscsi->cmd_q.crq_token,
-- PAGE_SIZE, DMA_BIDIRECTIONAL);
-- free_page((unsigned long)vscsi->cmd_q.base_addr);
-- rc = -ENODEV;
-- }
-- } else {
-- vscsi->state = WAIT_ENABLED;
-- }
--
-- return rc;
-+ return 0;
- }
-
- /**
-@@ -3271,7 +3167,7 @@ static void ibmvscsis_handle_crq(unsigned long data)
- /*
- * if we are in a path where we are waiting for all pending commands
- * to complete because we received a transport event and anything in
-- * the command queue is for a new connection, do nothing
-+ * the command queue is for a new connection, do nothing
- */
- if (TARGET_STOP(vscsi)) {
- vio_enable_interrupts(vscsi->dma_dev);
-@@ -3315,7 +3211,7 @@ static void ibmvscsis_handle_crq(unsigned long data)
- * everything but transport events on the queue
- *
- * need to decrement the queue index so we can
-- * look at the elment again
-+ * look at the element again
- */
- if (vscsi->cmd_q.index)
- vscsi->cmd_q.index -= 1;
-@@ -3379,7 +3275,8 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
- INIT_LIST_HEAD(&vscsi->waiting_rsp);
- INIT_LIST_HEAD(&vscsi->active_q);
-
-- snprintf(vscsi->tport.tport_name, 256, "%s", dev_name(&vdev->dev));
-+ snprintf(vscsi->tport.tport_name, IBMVSCSIS_NAMELEN, "%s",
-+ dev_name(&vdev->dev));
-
- pr_debug("probe tport_name: %s\n", vscsi->tport.tport_name);
-
-@@ -3394,6 +3291,9 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
- strncat(vscsi->eye, vdev->name, MAX_EYE);
-
- vscsi->dds.unit_id = vdev->unit_address;
-+ strncpy(vscsi->dds.partition_name, partition_name,
-+ sizeof(vscsi->dds.partition_name));
-+ vscsi->dds.partition_num = partition_number;
-
- spin_lock_bh(&ibmvscsis_dev_lock);
- list_add_tail(&vscsi->list, &ibmvscsis_dev_list);
-@@ -3470,6 +3370,7 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
- (unsigned long)vscsi);
-
- init_completion(&vscsi->wait_idle);
-+ init_completion(&vscsi->unconfig);
-
- snprintf(wq_name, 24, "ibmvscsis%s", dev_name(&vdev->dev));
- vscsi->work_q = create_workqueue(wq_name);
-@@ -3486,31 +3387,12 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
- goto destroy_WQ;
- }
-
-- spin_lock_bh(&vscsi->intr_lock);
-- vio_enable_interrupts(vdev);
-- if (rc) {
-- dev_err(&vscsi->dev, "enabling interrupts failed, rc %d\n", rc);
-- rc = -ENODEV;
-- spin_unlock_bh(&vscsi->intr_lock);
-- goto free_irq;
-- }
--
-- if (ibmvscsis_check_q(vscsi)) {
-- rc = ERROR;
-- dev_err(&vscsi->dev, "probe: check_q failed, rc %d\n", rc);
-- spin_unlock_bh(&vscsi->intr_lock);
-- goto disable_interrupt;
-- }
-- spin_unlock_bh(&vscsi->intr_lock);
-+ vscsi->state = WAIT_ENABLED;
-
- dev_set_drvdata(&vdev->dev, vscsi);
-
- return 0;
-
--disable_interrupt:
-- vio_disable_interrupts(vdev);
--free_irq:
-- free_irq(vdev->irq, vscsi);
- destroy_WQ:
- destroy_workqueue(vscsi->work_q);
- unmap_buf:
-@@ -3544,10 +3426,11 @@ static int ibmvscsis_remove(struct vio_dev *vdev)
-
- pr_debug("remove (%s)\n", dev_name(&vscsi->dma_dev->dev));
-
-- /*
-- * TBD: Need to handle if there are commands on the waiting_rsp q
-- * Actually, can there still be cmds outstanding to tcm?
-- */
-+ spin_lock_bh(&vscsi->intr_lock);
-+ ibmvscsis_post_disconnect(vscsi, UNCONFIGURING, 0);
-+ vscsi->flags |= CFG_SLEEPING;
-+ spin_unlock_bh(&vscsi->intr_lock);
-+ wait_for_completion(&vscsi->unconfig);
-
- vio_disable_interrupts(vdev);
- free_irq(vdev->irq, vscsi);
-@@ -3556,7 +3439,6 @@ static int ibmvscsis_remove(struct vio_dev *vdev)
- DMA_BIDIRECTIONAL);
- kfree(vscsi->map_buf);
- tasklet_kill(&vscsi->work_task);
-- ibmvscsis_unregister_command_q(vscsi);
- ibmvscsis_destroy_command_q(vscsi);
- ibmvscsis_freetimer(vscsi);
- ibmvscsis_free_cmds(vscsi);
-@@ -3610,7 +3492,7 @@ static int ibmvscsis_get_system_info(void)
-
- num = of_get_property(rootdn, "ibm,partition-no", NULL);
- if (num)
-- partition_number = *num;
-+ partition_number = of_read_number(num, 1);
-
- of_node_put(rootdn);
-
-@@ -3904,18 +3786,22 @@ static ssize_t ibmvscsis_tpg_enable_store(struct config_item *item,
- }
-
- if (tmp) {
-- tport->enabled = true;
- spin_lock_bh(&vscsi->intr_lock);
-+ tport->enabled = true;
- lrc = ibmvscsis_enable_change_state(vscsi);
- if (lrc)
- pr_err("enable_change_state failed, rc %ld state %d\n",
- lrc, vscsi->state);
- spin_unlock_bh(&vscsi->intr_lock);
- } else {
-+ spin_lock_bh(&vscsi->intr_lock);
- tport->enabled = false;
-+ /* This simulates the server going down */
-+ ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);
-+ spin_unlock_bh(&vscsi->intr_lock);
- }
-
-- pr_debug("tpg_enable_store, state %d\n", vscsi->state);
-+ pr_debug("tpg_enable_store, tmp %ld, state %d\n", tmp, vscsi->state);
-
- return count;
- }
-@@ -3985,10 +3871,10 @@ static struct attribute *ibmvscsis_dev_attrs[] = {
- ATTRIBUTE_GROUPS(ibmvscsis_dev);
-
- static struct class ibmvscsis_class = {
-- .name = "ibmvscsis",
-- .dev_release = ibmvscsis_dev_release,
-- .class_attrs = ibmvscsis_class_attrs,
-- .dev_groups = ibmvscsis_dev_groups,
-+ .name = "ibmvscsis",
-+ .dev_release = ibmvscsis_dev_release,
-+ .class_attrs = ibmvscsis_class_attrs,
-+ .dev_groups = ibmvscsis_dev_groups,
- };
-
- static struct vio_device_id ibmvscsis_device_table[] = {
-diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.h b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.h
-index 981a0c9..98b0ca7 100644
---- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.h
-+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.h
-@@ -204,8 +204,6 @@ struct scsi_info {
- struct list_head waiting_rsp;
- #define NO_QUEUE 0x00
- #define WAIT_ENABLED 0X01
-- /* driver has received an initialize command */
--#define PART_UP_WAIT_ENAB 0x02
- #define WAIT_CONNECTION 0x04
- /* have established a connection */
- #define CONNECTED 0x08
-@@ -259,6 +257,8 @@ struct scsi_info {
- #define SCHEDULE_DISCONNECT 0x00400
- /* disconnect handler is scheduled */
- #define DISCONNECT_SCHEDULED 0x00800
-+ /* remove function is sleeping */
-+#define CFG_SLEEPING 0x01000
- u32 flags;
- /* adapter lock */
- spinlock_t intr_lock;
-@@ -287,6 +287,7 @@ struct scsi_info {
-
- struct workqueue_struct *work_q;
- struct completion wait_idle;
-+ struct completion unconfig;
- struct device dev;
- struct vio_dev *dma_dev;
- struct srp_target target;
-diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
-index 4d09bd4..6e3e636 100644
---- a/drivers/tty/serial/8250/8250_pci.c
-+++ b/drivers/tty/serial/8250/8250_pci.c
-@@ -52,6 +52,7 @@ struct serial_private {
- struct pci_dev *dev;
- unsigned int nr;
- struct pci_serial_quirk *quirk;
-+ const struct pciserial_board *board;
- int line[0];
- };
-
-@@ -3871,6 +3872,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
- }
- }
- priv->nr = i;
-+ priv->board = board;
- return priv;
-
- err_deinit:
-@@ -3881,7 +3883,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
- }
- EXPORT_SYMBOL_GPL(pciserial_init_ports);
-
--void pciserial_remove_ports(struct serial_private *priv)
-+void pciserial_detach_ports(struct serial_private *priv)
- {
- struct pci_serial_quirk *quirk;
- int i;
-@@ -3895,7 +3897,11 @@ void pciserial_remove_ports(struct serial_private *priv)
- quirk = find_quirk(priv->dev);
- if (quirk->exit)
- quirk->exit(priv->dev);
-+}
-
-+void pciserial_remove_ports(struct serial_private *priv)
-+{
-+ pciserial_detach_ports(priv);
- kfree(priv);
- }
- EXPORT_SYMBOL_GPL(pciserial_remove_ports);
-@@ -5590,7 +5596,7 @@ static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev,
- return PCI_ERS_RESULT_DISCONNECT;
-
- if (priv)
-- pciserial_suspend_ports(priv);
-+ pciserial_detach_ports(priv);
-
- pci_disable_device(dev);
-
-@@ -5615,9 +5621,18 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev)
- static void serial8250_io_resume(struct pci_dev *dev)
- {
- struct serial_private *priv = pci_get_drvdata(dev);
-+ const struct pciserial_board *board;
-
-- if (priv)
-- pciserial_resume_ports(priv);
-+ if (!priv)
-+ return;
-+
-+ board = priv->board;
-+ kfree(priv);
-+ priv = pciserial_init_ports(dev, board);
-+
-+ if (!IS_ERR(priv)) {
-+ pci_set_drvdata(dev, priv);
-+ }
- }
-
- static const struct pci_error_handlers serial8250_err_handler = {
-diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
-index 45bc997..a95b3e7 100644
---- a/drivers/usb/gadget/udc/atmel_usba_udc.c
-+++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
-@@ -1978,7 +1978,8 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
- dev_err(&pdev->dev, "of_probe: name error(%d)\n", ret);
- goto err;
- }
-- ep->ep.name = kasprintf(GFP_KERNEL, "ep%d", ep->index);
-+ sprintf(ep->name, "ep%d", ep->index);
-+ ep->ep.name = ep->name;
-
- ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
- ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
-diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h
-index 3e1c9d5..b03b2eb 100644
---- a/drivers/usb/gadget/udc/atmel_usba_udc.h
-+++ b/drivers/usb/gadget/udc/atmel_usba_udc.h
-@@ -280,6 +280,7 @@ struct usba_ep {
- void __iomem *ep_regs;
- void __iomem *dma_regs;
- void __iomem *fifo;
-+ char name[8];
- struct usb_ep ep;
- struct usba_udc *udc;
-
-diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
-index 80378dd..c882357 100644
---- a/drivers/vfio/vfio_iommu_spapr_tce.c
-+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
-@@ -31,49 +31,49 @@
- static void tce_iommu_detach_group(void *iommu_data,
- struct iommu_group *iommu_group);
-
--static long try_increment_locked_vm(long npages)
-+static long try_increment_locked_vm(struct mm_struct *mm, long npages)
- {
- long ret = 0, locked, lock_limit;
-
-- if (!current || !current->mm)
-- return -ESRCH; /* process exited */
-+ if (WARN_ON_ONCE(!mm))
-+ return -EPERM;
-
- if (!npages)
- return 0;
-
-- down_write(&current->mm->mmap_sem);
-- locked = current->mm->locked_vm + npages;
-+ down_write(&mm->mmap_sem);
-+ locked = mm->locked_vm + npages;
- lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
- if (locked > lock_limit && !capable(CAP_IPC_LOCK))
- ret = -ENOMEM;
- else
-- current->mm->locked_vm += npages;
-+ mm->locked_vm += npages;
-
- pr_debug("[%d] RLIMIT_MEMLOCK +%ld %ld/%ld%s\n", current->pid,
- npages << PAGE_SHIFT,
-- current->mm->locked_vm << PAGE_SHIFT,
-+ mm->locked_vm << PAGE_SHIFT,
- rlimit(RLIMIT_MEMLOCK),
- ret ? " - exceeded" : "");
-
-- up_write(&current->mm->mmap_sem);
-+ up_write(&mm->mmap_sem);
-
- return ret;
- }
-
--static void decrement_locked_vm(long npages)
-+static void decrement_locked_vm(struct mm_struct *mm, long npages)
- {
-- if (!current || !current->mm || !npages)
-- return; /* process exited */
-+ if (!mm || !npages)
-+ return;
-
-- down_write(&current->mm->mmap_sem);
-- if (WARN_ON_ONCE(npages > current->mm->locked_vm))
-- npages = current->mm->locked_vm;
-- current->mm->locked_vm -= npages;
-+ down_write(&mm->mmap_sem);
-+ if (WARN_ON_ONCE(npages > mm->locked_vm))
-+ npages = mm->locked_vm;
-+ mm->locked_vm -= npages;
- pr_debug("[%d] RLIMIT_MEMLOCK -%ld %ld/%ld\n", current->pid,
- npages << PAGE_SHIFT,
-- current->mm->locked_vm << PAGE_SHIFT,
-+ mm->locked_vm << PAGE_SHIFT,
- rlimit(RLIMIT_MEMLOCK));
-- up_write(&current->mm->mmap_sem);
-+ up_write(&mm->mmap_sem);
- }
-
- /*
-@@ -89,6 +89,15 @@ struct tce_iommu_group {
- };
-
- /*
-+ * A container needs to remember which preregistered region it has
-+ * referenced to do proper cleanup at the userspace process exit.
-+ */
-+struct tce_iommu_prereg {
-+ struct list_head next;
-+ struct mm_iommu_table_group_mem_t *mem;
-+};
-+
-+/*
- * The container descriptor supports only a single group per container.
- * Required by the API as the container is not supplied with the IOMMU group
- * at the moment of initialization.
-@@ -97,24 +106,68 @@ struct tce_container {
- struct mutex lock;
- bool enabled;
- bool v2;
-+ bool def_window_pending;
- unsigned long locked_pages;
-+ struct mm_struct *mm;
- struct iommu_table *tables[IOMMU_TABLE_GROUP_MAX_TABLES];
- struct list_head group_list;
-+ struct list_head prereg_list;
- };
-
-+static long tce_iommu_mm_set(struct tce_container *container)
-+{
-+ if (container->mm) {
-+ if (container->mm == current->mm)
-+ return 0;
-+ return -EPERM;
-+ }
-+ BUG_ON(!current->mm);
-+ container->mm = current->mm;
-+ atomic_inc(&container->mm->mm_count);
-+
-+ return 0;
-+}
-+
-+static long tce_iommu_prereg_free(struct tce_container *container,
-+ struct tce_iommu_prereg *tcemem)
-+{
-+ long ret;
-+
-+ ret = mm_iommu_put(container->mm, tcemem->mem);
-+ if (ret)
-+ return ret;
-+
-+ list_del(&tcemem->next);
-+ kfree(tcemem);
-+
-+ return 0;
-+}
-+
- static long tce_iommu_unregister_pages(struct tce_container *container,
- __u64 vaddr, __u64 size)
- {
- struct mm_iommu_table_group_mem_t *mem;
-+ struct tce_iommu_prereg *tcemem;
-+ bool found = false;
-
- if ((vaddr & ~PAGE_MASK) || (size & ~PAGE_MASK))
- return -EINVAL;
-
-- mem = mm_iommu_find(vaddr, size >> PAGE_SHIFT);
-+ mem = mm_iommu_find(container->mm, vaddr, size >> PAGE_SHIFT);
- if (!mem)
- return -ENOENT;
-
-- return mm_iommu_put(mem);
-+ list_for_each_entry(tcemem, &container->prereg_list, next) {
-+ if (tcemem->mem == mem) {
-+ found = true;
-+ break;
-+ }
-+ }
-+
-+ if (!found)
-+ return -ENOENT;
-+
-+ return tce_iommu_prereg_free(container, tcemem);
- }
-
- static long tce_iommu_register_pages(struct tce_container *container,
-@@ -122,22 +175,36 @@ static long tce_iommu_register_pages(struct tce_container *container,
- {
- long ret = 0;
- struct mm_iommu_table_group_mem_t *mem = NULL;
-+ struct tce_iommu_prereg *tcemem;
- unsigned long entries = size >> PAGE_SHIFT;
-
- if ((vaddr & ~PAGE_MASK) || (size & ~PAGE_MASK) ||
- ((vaddr + size) < vaddr))
- return -EINVAL;
-
-- ret = mm_iommu_get(vaddr, entries, &mem);
-+ mem = mm_iommu_find(container->mm, vaddr, entries);
-+ if (mem) {
-+ list_for_each_entry(tcemem, &container->prereg_list, next) {
-+ if (tcemem->mem == mem)
-+ return -EBUSY;
-+ }
-+ }
-+
-+ ret = mm_iommu_get(container->mm, vaddr, entries, &mem);
- if (ret)
- return ret;
-
-+ tcemem = kzalloc(sizeof(*tcemem), GFP_KERNEL);
-+ tcemem->mem = mem;
-+ list_add(&tcemem->next, &container->prereg_list);
-+
- container->enabled = true;
-
- return 0;
- }
-
--static long tce_iommu_userspace_view_alloc(struct iommu_table *tbl)
-+static long tce_iommu_userspace_view_alloc(struct iommu_table *tbl,
-+ struct mm_struct *mm)
- {
- unsigned long cb = _ALIGN_UP(sizeof(tbl->it_userspace[0]) *
- tbl->it_size, PAGE_SIZE);
-@@ -146,13 +213,13 @@ static long tce_iommu_userspace_view_alloc(struct iommu_table *tbl)
-
- BUG_ON(tbl->it_userspace);
-
-- ret = try_increment_locked_vm(cb >> PAGE_SHIFT);
-+ ret = try_increment_locked_vm(mm, cb >> PAGE_SHIFT);
- if (ret)
- return ret;
-
- uas = vzalloc(cb);
- if (!uas) {
-- decrement_locked_vm(cb >> PAGE_SHIFT);
-+ decrement_locked_vm(mm, cb >> PAGE_SHIFT);
- return -ENOMEM;
- }
- tbl->it_userspace = uas;
-@@ -160,7 +227,8 @@ static long tce_iommu_userspace_view_alloc(struct iommu_table *tbl)
- return 0;
- }
-
--static void tce_iommu_userspace_view_free(struct iommu_table *tbl)
-+static void tce_iommu_userspace_view_free(struct iommu_table *tbl,
-+ struct mm_struct *mm)
- {
- unsigned long cb = _ALIGN_UP(sizeof(tbl->it_userspace[0]) *
- tbl->it_size, PAGE_SIZE);
-@@ -170,7 +238,7 @@ static void tce_iommu_userspace_view_free(struct iommu_table *tbl)
-
- vfree(tbl->it_userspace);
- tbl->it_userspace = NULL;
-- decrement_locked_vm(cb >> PAGE_SHIFT);
-+ decrement_locked_vm(mm, cb >> PAGE_SHIFT);
- }
-
- static bool tce_page_is_contained(struct page *page, unsigned page_shift)
-@@ -230,9 +298,6 @@ static int tce_iommu_enable(struct tce_container *container)
- struct iommu_table_group *table_group;
- struct tce_iommu_group *tcegrp;
-
-- if (!current->mm)
-- return -ESRCH; /* process exited */
--
- if (container->enabled)
- return -EBUSY;
-
-@@ -277,8 +342,12 @@ static int tce_iommu_enable(struct tce_container *container)
- if (!table_group->tce32_size)
- return -EPERM;
-
-+ ret = tce_iommu_mm_set(container);
-+ if (ret)
-+ return ret;
-+
- locked = table_group->tce32_size >> PAGE_SHIFT;
-- ret = try_increment_locked_vm(locked);
-+ ret = try_increment_locked_vm(container->mm, locked);
- if (ret)
- return ret;
-
-@@ -296,10 +365,8 @@ static void tce_iommu_disable(struct tce_container *container)
-
- container->enabled = false;
-
-- if (!current->mm)
-- return;
--
-- decrement_locked_vm(container->locked_pages);
-+ BUG_ON(!container->mm);
-+ decrement_locked_vm(container->mm, container->locked_pages);
- }
-
- static void *tce_iommu_open(unsigned long arg)
-@@ -317,6 +384,7 @@ static void *tce_iommu_open(unsigned long arg)
-
- mutex_init(&container->lock);
- INIT_LIST_HEAD_RCU(&container->group_list);
-+ INIT_LIST_HEAD_RCU(&container->prereg_list);
-
- container->v2 = arg == VFIO_SPAPR_TCE_v2_IOMMU;
-
-@@ -326,7 +394,8 @@ static void *tce_iommu_open(unsigned long arg)
- static int tce_iommu_clear(struct tce_container *container,
- struct iommu_table *tbl,
- unsigned long entry, unsigned long pages);
--static void tce_iommu_free_table(struct iommu_table *tbl);
-+static void tce_iommu_free_table(struct tce_container *container,
-+ struct iommu_table *tbl);
-
- static void tce_iommu_release(void *iommu_data)
- {
-@@ -351,10 +420,20 @@ static void tce_iommu_release(void *iommu_data)
- continue;
-
- tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
-- tce_iommu_free_table(tbl);
-+ tce_iommu_free_table(container, tbl);
-+ }
-+
-+ while (!list_empty(&container->prereg_list)) {
-+ struct tce_iommu_prereg *tcemem;
-+
-+ tcemem = list_first_entry(&container->prereg_list,
-+ struct tce_iommu_prereg, next);
-+ WARN_ON_ONCE(tce_iommu_prereg_free(container, tcemem));
- }
-
- tce_iommu_disable(container);
-+ if (container->mm)
-+ mmdrop(container->mm);
- mutex_destroy(&container->lock);
-
- kfree(container);
-@@ -369,13 +448,14 @@ static void tce_iommu_unuse_page(struct tce_container *container,
- put_page(page);
- }
-
--static int tce_iommu_prereg_ua_to_hpa(unsigned long tce, unsigned long size,
-+static int tce_iommu_prereg_ua_to_hpa(struct tce_container *container,
-+ unsigned long tce, unsigned long size,
- unsigned long *phpa, struct mm_iommu_table_group_mem_t **pmem)
- {
- long ret = 0;
- struct mm_iommu_table_group_mem_t *mem;
-
-- mem = mm_iommu_lookup(tce, size);
-+ mem = mm_iommu_lookup(container->mm, tce, size);
- if (!mem)
- return -EINVAL;
-
-@@ -388,18 +468,18 @@ static int tce_iommu_prereg_ua_to_hpa(unsigned long tce, unsigned long size,
- return 0;
- }
-
--static void tce_iommu_unuse_page_v2(struct iommu_table *tbl,
-- unsigned long entry)
-+static void tce_iommu_unuse_page_v2(struct tce_container *container,
-+ struct iommu_table *tbl, unsigned long entry)
- {
- struct mm_iommu_table_group_mem_t *mem = NULL;
- int ret;
- unsigned long hpa = 0;
- unsigned long *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry);
-
-- if (!pua || !current || !current->mm)
-+ if (!pua)
- return;
-
-- ret = tce_iommu_prereg_ua_to_hpa(*pua, IOMMU_PAGE_SIZE(tbl),
-+ ret = tce_iommu_prereg_ua_to_hpa(container, *pua, IOMMU_PAGE_SIZE(tbl),
- &hpa, &mem);
- if (ret)
- pr_debug("%s: tce %lx at #%lx was not cached, ret=%d\n",
-@@ -429,7 +509,7 @@ static int tce_iommu_clear(struct tce_container *container,
- continue;
-
- if (container->v2) {
-- tce_iommu_unuse_page_v2(tbl, entry);
-+ tce_iommu_unuse_page_v2(container, tbl, entry);
- continue;
- }
-
-@@ -509,13 +589,19 @@ static long tce_iommu_build_v2(struct tce_container *container,
- unsigned long hpa;
- enum dma_data_direction dirtmp;
-
-+ if (!tbl->it_userspace) {
-+ ret = tce_iommu_userspace_view_alloc(tbl, container->mm);
-+ if (ret)
-+ return ret;
-+ }
-+
- for (i = 0; i < pages; ++i) {
- struct mm_iommu_table_group_mem_t *mem = NULL;
- unsigned long *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl,
- entry + i);
-
-- ret = tce_iommu_prereg_ua_to_hpa(tce, IOMMU_PAGE_SIZE(tbl),
-- &hpa, &mem);
-+ ret = tce_iommu_prereg_ua_to_hpa(container,
-+ tce, IOMMU_PAGE_SIZE(tbl), &hpa, &mem);
- if (ret)
- break;
-
-@@ -536,7 +622,7 @@ static long tce_iommu_build_v2(struct tce_container *container,
- ret = iommu_tce_xchg(tbl, entry + i, &hpa, &dirtmp);
- if (ret) {
- /* dirtmp cannot be DMA_NONE here */
-- tce_iommu_unuse_page_v2(tbl, entry + i);
-+ tce_iommu_unuse_page_v2(container, tbl, entry + i);
- pr_err("iommu_tce: %s failed ioba=%lx, tce=%lx, ret=%ld\n",
- __func__, entry << tbl->it_page_shift,
- tce, ret);
-@@ -544,7 +630,7 @@ static long tce_iommu_build_v2(struct tce_container *container,
- }
-
- if (dirtmp != DMA_NONE)
-- tce_iommu_unuse_page_v2(tbl, entry + i);
-+ tce_iommu_unuse_page_v2(container, tbl, entry + i);
-
- *pua = tce;
-
-@@ -572,7 +658,7 @@ static long tce_iommu_create_table(struct tce_container *container,
- if (!table_size)
- return -EINVAL;
-
-- ret = try_increment_locked_vm(table_size >> PAGE_SHIFT);
-+ ret = try_increment_locked_vm(container->mm, table_size >> PAGE_SHIFT);
- if (ret)
- return ret;
-
-@@ -582,25 +668,17 @@ static long tce_iommu_create_table(struct tce_container *container,
- WARN_ON(!ret && !(*ptbl)->it_ops->free);
- WARN_ON(!ret && ((*ptbl)->it_allocated_size != table_size));
-
-- if (!ret && container->v2) {
-- ret = tce_iommu_userspace_view_alloc(*ptbl);
-- if (ret)
-- (*ptbl)->it_ops->free(*ptbl);
-- }
--
-- if (ret)
-- decrement_locked_vm(table_size >> PAGE_SHIFT);
--
- return ret;
- }
-
--static void tce_iommu_free_table(struct iommu_table *tbl)
-+static void tce_iommu_free_table(struct tce_container *container,
-+ struct iommu_table *tbl)
- {
- unsigned long pages = tbl->it_allocated_size >> PAGE_SHIFT;
-
-- tce_iommu_userspace_view_free(tbl);
-+ tce_iommu_userspace_view_free(tbl, container->mm);
- tbl->it_ops->free(tbl);
-- decrement_locked_vm(pages);
-+ decrement_locked_vm(container->mm, pages);
- }
-
- static long tce_iommu_create_window(struct tce_container *container,
-@@ -663,7 +741,7 @@ static long tce_iommu_create_window(struct tce_container *container,
- table_group = iommu_group_get_iommudata(tcegrp->grp);
- table_group->ops->unset_window(table_group, num);
- }
-- tce_iommu_free_table(tbl);
-+ tce_iommu_free_table(container, tbl);
-
- return ret;
- }
-@@ -701,12 +779,41 @@ static long tce_iommu_remove_window(struct tce_container *container,
-
- /* Free table */
- tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
-- tce_iommu_free_table(tbl);
-+ tce_iommu_free_table(container, tbl);
- container->tables[num] = NULL;
-
- return 0;
- }
-
-+static long tce_iommu_create_default_window(struct tce_container *container)
-+{
-+ long ret;
-+ __u64 start_addr = 0;
-+ struct tce_iommu_group *tcegrp;
-+ struct iommu_table_group *table_group;
-+
-+ if (!container->def_window_pending)
-+ return 0;
-+
-+ if (!tce_groups_attached(container))
-+ return -ENODEV;
-+
-+ tcegrp = list_first_entry(&container->group_list,
-+ struct tce_iommu_group, next);
-+ table_group = iommu_group_get_iommudata(tcegrp->grp);
-+ if (!table_group)
-+ return -ENODEV;
-+
-+ ret = tce_iommu_create_window(container, IOMMU_PAGE_SHIFT_4K,
-+ table_group->tce32_size, 1, &start_addr);
-+ WARN_ON_ONCE(!ret && start_addr);
-+
-+ if (!ret)
-+ container->def_window_pending = false;
-+
-+ return ret;
-+}
-+
- static long tce_iommu_ioctl(void *iommu_data,
- unsigned int cmd, unsigned long arg)
- {
-@@ -727,7 +834,17 @@ static long tce_iommu_ioctl(void *iommu_data,
- }
-
- return (ret < 0) ? 0 : ret;
-+ }
-+
-+ /*
-+ * Sanity check to prevent one userspace from manipulating
-+ * another userspace mm.
-+ */
-+ BUG_ON(!container);
-+ if (container->mm && container->mm != current->mm)
-+ return -EPERM;
-
-+ switch (cmd) {
- case VFIO_IOMMU_SPAPR_TCE_GET_INFO: {
- struct vfio_iommu_spapr_tce_info info;
- struct tce_iommu_group *tcegrp;
-@@ -797,6 +914,10 @@ static long tce_iommu_ioctl(void *iommu_data,
- VFIO_DMA_MAP_FLAG_WRITE))
- return -EINVAL;
-
-+ ret = tce_iommu_create_default_window(container);
-+ if (ret)
-+ return ret;
-+
- num = tce_iommu_find_table(container, param.iova, &tbl);
- if (num < 0)
- return -ENXIO;
-@@ -860,6 +981,10 @@ static long tce_iommu_ioctl(void *iommu_data,
- if (param.flags)
- return -EINVAL;
-
-+ ret = tce_iommu_create_default_window(container);
-+ if (ret)
-+ return ret;
-+
- num = tce_iommu_find_table(container, param.iova, &tbl);
- if (num < 0)
- return -ENXIO;
-@@ -888,6 +1013,10 @@ static long tce_iommu_ioctl(void *iommu_data,
- minsz = offsetofend(struct vfio_iommu_spapr_register_memory,
- size);
-
-+ ret = tce_iommu_mm_set(container);
-+ if (ret)
-+ return ret;
-+
- if (copy_from_user(&param, (void __user *)arg, minsz))
- return -EFAULT;
-
-@@ -911,6 +1040,9 @@ static long tce_iommu_ioctl(void *iommu_data,
- if (!container->v2)
- break;
-
-+ if (!container->mm)
-+ return -EPERM;
-+
- minsz = offsetofend(struct vfio_iommu_spapr_register_memory,
- size);
-
-@@ -969,6 +1101,10 @@ static long tce_iommu_ioctl(void *iommu_data,
- if (!container->v2)
- break;
-
-+ ret = tce_iommu_mm_set(container);
-+ if (ret)
-+ return ret;
-+
- if (!tce_groups_attached(container))
- return -ENXIO;
-
-@@ -986,6 +1122,10 @@ static long tce_iommu_ioctl(void *iommu_data,
-
- mutex_lock(&container->lock);
-
-+ ret = tce_iommu_create_default_window(container);
-+ if (ret)
-+ return ret;
-+
- ret = tce_iommu_create_window(container, create.page_shift,
- create.window_size, create.levels,
- &create.start_addr);
-@@ -1003,6 +1143,10 @@ static long tce_iommu_ioctl(void *iommu_data,
- if (!container->v2)
- break;
-
-+ ret = tce_iommu_mm_set(container);
-+ if (ret)
-+ return ret;
-+
- if (!tce_groups_attached(container))
- return -ENXIO;
-
-@@ -1018,6 +1162,11 @@ static long tce_iommu_ioctl(void *iommu_data,
- if (remove.flags)
- return -EINVAL;
-
-+ if (container->def_window_pending && !remove.start_addr) {
-+ container->def_window_pending = false;
-+ return 0;
-+ }
-+
- mutex_lock(&container->lock);
-
- ret = tce_iommu_remove_window(container, remove.start_addr);
-@@ -1043,7 +1192,7 @@ static void tce_iommu_release_ownership(struct tce_container *container,
- continue;
-
- tce_iommu_clear(container, tbl, tbl->it_offset, tbl->it_size);
-- tce_iommu_userspace_view_free(tbl);
-+ tce_iommu_userspace_view_free(tbl, container->mm);
- if (tbl->it_map)
- iommu_release_ownership(tbl);
-
-@@ -1062,10 +1211,7 @@ static int tce_iommu_take_ownership(struct tce_container *container,
- if (!tbl || !tbl->it_map)
- continue;
-
-- rc = tce_iommu_userspace_view_alloc(tbl);
-- if (!rc)
-- rc = iommu_take_ownership(tbl);
--
-+ rc = iommu_take_ownership(tbl);
- if (rc) {
- for (j = 0; j < i; ++j)
- iommu_release_ownership(
-@@ -1100,9 +1246,6 @@ static void tce_iommu_release_ownership_ddw(struct tce_container *container,
- static long tce_iommu_take_ownership_ddw(struct tce_container *container,
- struct iommu_table_group *table_group)
- {
-- long i, ret = 0;
-- struct iommu_table *tbl = NULL;
--
- if (!table_group->ops->create_table || !table_group->ops->set_window ||
- !table_group->ops->release_ownership) {
- WARN_ON_ONCE(1);
-@@ -1111,47 +1254,7 @@ static long tce_iommu_take_ownership_ddw(struct tce_container *container,
-
- table_group->ops->take_ownership(table_group);
-
-- /*
-- * If it the first group attached, check if there is
-- * a default DMA window and create one if none as
-- * the userspace expects it to exist.
-- */
-- if (!tce_groups_attached(container) && !container->tables[0]) {
-- ret = tce_iommu_create_table(container,
-- table_group,
-- 0, /* window number */
-- IOMMU_PAGE_SHIFT_4K,
-- table_group->tce32_size,
-- 1, /* default levels */
-- &tbl);
-- if (ret)
-- goto release_exit;
-- else
-- container->tables[0] = tbl;
-- }
--
-- /* Set all windows to the new group */
-- for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
-- tbl = container->tables[i];
--
-- if (!tbl)
-- continue;
--
-- /* Set the default window to a new group */
-- ret = table_group->ops->set_window(table_group, i, tbl);
-- if (ret)
-- goto release_exit;
-- }
--
- return 0;
--
--release_exit:
-- for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i)
-- table_group->ops->unset_window(table_group, i);
--
-- table_group->ops->release_ownership(table_group);
--
-- return ret;
- }
-
- static int tce_iommu_attach_group(void *iommu_data,
-@@ -1203,10 +1306,13 @@ static int tce_iommu_attach_group(void *iommu_data,
- }
-
- if (!table_group->ops || !table_group->ops->take_ownership ||
-- !table_group->ops->release_ownership)
-+ !table_group->ops->release_ownership) {
- ret = tce_iommu_take_ownership(container, table_group);
-- else
-+ } else {
- ret = tce_iommu_take_ownership_ddw(container, table_group);
-+ if (!tce_groups_attached(container) && !container->tables[0])
-+ container->def_window_pending = true;
-+ }
-
- if (!ret) {
- tcegrp->grp = iommu_group;
-diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
-index 6aaf425..a13b031 100644
---- a/include/linux/bpf_verifier.h
-+++ b/include/linux/bpf_verifier.h
-@@ -18,19 +18,12 @@
-
- struct bpf_reg_state {
- enum bpf_reg_type type;
-- /*
-- * Used to determine if any memory access using this register will
-- * result in a bad access.
-- */
-- s64 min_value;
-- u64 max_value;
- union {
- /* valid when type == CONST_IMM | PTR_TO_STACK | UNKNOWN_VALUE */
- s64 imm;
-
- /* valid when type == PTR_TO_PACKET* */
- struct {
-- u32 id;
- u16 off;
- u16 range;
- };
-@@ -40,6 +33,13 @@ struct bpf_reg_state {
- */
- struct bpf_map *map_ptr;
- };
-+ u32 id;
-+ /* Used to determine if any memory access using this register will
-+ * result in a bad access. These two fields must be last.
-+ * See states_equal()
-+ */
-+ s64 min_value;
-+ u64 max_value;
- };
-
- enum bpf_stack_slot_type {
-diff --git a/include/linux/dccp.h b/include/linux/dccp.h
-index 61d042b..6844929 100644
---- a/include/linux/dccp.h
-+++ b/include/linux/dccp.h
-@@ -163,6 +163,7 @@ struct dccp_request_sock {
- __u64 dreq_isr;
- __u64 dreq_gsr;
- __be32 dreq_service;
-+ spinlock_t dreq_lock;
- struct list_head dreq_featneg;
- __u32 dreq_timestamp_echo;
- __u32 dreq_timestamp_time;
-diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
-index 192eef2f..d596a07 100644
---- a/include/linux/hyperv.h
-+++ b/include/linux/hyperv.h
-@@ -1548,31 +1548,23 @@ static inline struct vmpacket_descriptor *
- get_next_pkt_raw(struct vmbus_channel *channel)
- {
- struct hv_ring_buffer_info *ring_info = &channel->inbound;
-- u32 read_loc = ring_info->priv_read_index;
-+ u32 priv_read_loc = ring_info->priv_read_index;
- void *ring_buffer = hv_get_ring_buffer(ring_info);
-- struct vmpacket_descriptor *cur_desc;
-- u32 packetlen;
- u32 dsize = ring_info->ring_datasize;
-- u32 delta = read_loc - ring_info->ring_buffer->read_index;
-+ /*
-+ * delta is the difference between what is available to read and
-+ * what was already consumed in place. We commit read index after
-+ * the whole batch is processed.
-+ */
-+ u32 delta = priv_read_loc >= ring_info->ring_buffer->read_index ?
-+ priv_read_loc - ring_info->ring_buffer->read_index :
-+ (dsize - ring_info->ring_buffer->read_index) + priv_read_loc;
- u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta);
-
- if (bytes_avail_toread < sizeof(struct vmpacket_descriptor))
- return NULL;
-
-- if ((read_loc + sizeof(*cur_desc)) > dsize)
-- return NULL;
--
-- cur_desc = ring_buffer + read_loc;
-- packetlen = cur_desc->len8 << 3;
--
-- /*
-- * If the packet under consideration is wrapping around,
-- * return failure.
-- */
-- if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > (dsize - 1))
-- return NULL;
--
-- return cur_desc;
-+ return ring_buffer + priv_read_loc;
- }
-
- /*
-@@ -1584,16 +1576,14 @@ static inline void put_pkt_raw(struct vmbus_channel *channel,
- struct vmpacket_descriptor *desc)
- {
- struct hv_ring_buffer_info *ring_info = &channel->inbound;
-- u32 read_loc = ring_info->priv_read_index;
- u32 packetlen = desc->len8 << 3;
- u32 dsize = ring_info->ring_datasize;
-
-- if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > dsize)
-- BUG();
- /*
- * Include the packet trailer.
- */
- ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
-+ ring_info->priv_read_index %= dsize;
- }
-
- /*
-diff --git a/include/uapi/linux/packet_diag.h b/include/uapi/linux/packet_diag.h
-index d08c63f..0c5d5dd 100644
---- a/include/uapi/linux/packet_diag.h
-+++ b/include/uapi/linux/packet_diag.h
-@@ -64,7 +64,7 @@ struct packet_diag_mclist {
- __u32 pdmc_count;
- __u16 pdmc_type;
- __u16 pdmc_alen;
-- __u8 pdmc_addr[MAX_ADDR_LEN];
-+ __u8 pdmc_addr[32]; /* MAX_ADDR_LEN */
- };
-
- struct packet_diag_ring {
-diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
-index 8199821..85d1c94 100644
---- a/kernel/bpf/verifier.c
-+++ b/kernel/bpf/verifier.c
-@@ -212,9 +212,10 @@ static void print_verifier_state(struct bpf_verifier_state *state)
- else if (t == CONST_PTR_TO_MAP || t == PTR_TO_MAP_VALUE ||
- t == PTR_TO_MAP_VALUE_OR_NULL ||
- t == PTR_TO_MAP_VALUE_ADJ)
-- verbose("(ks=%d,vs=%d)",
-+ verbose("(ks=%d,vs=%d,id=%u)",
- reg->map_ptr->key_size,
-- reg->map_ptr->value_size);
-+ reg->map_ptr->value_size,
-+ reg->id);
- if (reg->min_value != BPF_REGISTER_MIN_RANGE)
- verbose(",min_value=%lld",
- (long long)reg->min_value);
-@@ -443,13 +444,19 @@ static void init_reg_state(struct bpf_reg_state *regs)
- regs[BPF_REG_1].type = PTR_TO_CTX;
- }
-
--static void mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno)
-+static void __mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno)
- {
-- BUG_ON(regno >= MAX_BPF_REG);
- regs[regno].type = UNKNOWN_VALUE;
-+ regs[regno].id = 0;
- regs[regno].imm = 0;
- }
-
-+static void mark_reg_unknown_value(struct bpf_reg_state *regs, u32 regno)
-+{
-+ BUG_ON(regno >= MAX_BPF_REG);
-+ __mark_reg_unknown_value(regs, regno);
-+}
-+
- static void reset_reg_range_values(struct bpf_reg_state *regs, u32 regno)
- {
- regs[regno].min_value = BPF_REGISTER_MIN_RANGE;
-@@ -1252,6 +1259,7 @@ static int check_call(struct bpf_verifier_env *env, int func_id)
- return -EINVAL;
- }
- regs[BPF_REG_0].map_ptr = meta.map_ptr;
-+ regs[BPF_REG_0].id = ++env->id_gen;
- } else {
- verbose("unknown return type %d of func %d\n",
- fn->ret_type, func_id);
-@@ -1668,8 +1676,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
- insn->src_reg);
- return -EACCES;
- }
-- regs[insn->dst_reg].type = UNKNOWN_VALUE;
-- regs[insn->dst_reg].map_ptr = NULL;
-+ mark_reg_unknown_value(regs, insn->dst_reg);
- }
- } else {
- /* case: R = imm
-@@ -1931,6 +1938,43 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg,
- check_reg_overflow(true_reg);
- }
-
-+static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id,
-+ enum bpf_reg_type type)
-+{
-+ struct bpf_reg_state *reg = &regs[regno];
-+
-+ if (reg->type == PTR_TO_MAP_VALUE_OR_NULL && reg->id == id) {
-+ reg->type = type;
-+ /* We don't need id from this point onwards anymore, thus we
-+ * should better reset it, so that state pruning has chances
-+ * to take effect.
-+ */
-+ reg->id = 0;
-+ if (type == UNKNOWN_VALUE)
-+ __mark_reg_unknown_value(regs, regno);
-+ }
-+}
-+
-+/* The logic is similar to find_good_pkt_pointers(), both could eventually
-+ * be folded together at some point.
-+ */
-+static void mark_map_regs(struct bpf_verifier_state *state, u32 regno,
-+ enum bpf_reg_type type)
-+{
-+ struct bpf_reg_state *regs = state->regs;
-+ u32 id = regs[regno].id;
-+ int i;
-+
-+ for (i = 0; i < MAX_BPF_REG; i++)
-+ mark_map_reg(regs, i, id, type);
-+
-+ for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) {
-+ if (state->stack_slot_type[i] != STACK_SPILL)
-+ continue;
-+ mark_map_reg(state->spilled_regs, i / BPF_REG_SIZE, id, type);
-+ }
-+}
-+
- static int check_cond_jmp_op(struct bpf_verifier_env *env,
- struct bpf_insn *insn, int *insn_idx)
- {
-@@ -2018,18 +2062,13 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
- if (BPF_SRC(insn->code) == BPF_K &&
- insn->imm == 0 && (opcode == BPF_JEQ || opcode == BPF_JNE) &&
- dst_reg->type == PTR_TO_MAP_VALUE_OR_NULL) {
-- if (opcode == BPF_JEQ) {
-- /* next fallthrough insn can access memory via
-- * this register
-- */
-- regs[insn->dst_reg].type = PTR_TO_MAP_VALUE;
-- /* branch targer cannot access it, since reg == 0 */
-- mark_reg_unknown_value(other_branch->regs,
-- insn->dst_reg);
-- } else {
-- other_branch->regs[insn->dst_reg].type = PTR_TO_MAP_VALUE;
-- mark_reg_unknown_value(regs, insn->dst_reg);
-- }
-+ /* Mark all identical map registers in each branch as either
-+ * safe or unknown depending R == 0 or R != 0 conditional.
-+ */
-+ mark_map_regs(this_branch, insn->dst_reg,
-+ opcode == BPF_JEQ ? PTR_TO_MAP_VALUE : UNKNOWN_VALUE);
-+ mark_map_regs(other_branch, insn->dst_reg,
-+ opcode == BPF_JEQ ? UNKNOWN_VALUE : PTR_TO_MAP_VALUE);
- } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGT &&
- dst_reg->type == PTR_TO_PACKET &&
- regs[insn->src_reg].type == PTR_TO_PACKET_END) {
-@@ -2469,7 +2508,7 @@ static bool states_equal(struct bpf_verifier_env *env,
- * we didn't do a variable access into a map then we are a-ok.
- */
- if (!varlen_map_access &&
-- rold->type == rcur->type && rold->imm == rcur->imm)
-+ memcmp(rold, rcur, offsetofend(struct bpf_reg_state, id)) == 0)
- continue;
-
- /* If we didn't map access then again we don't care about the
-diff --git a/kernel/futex.c b/kernel/futex.c
-index 38b68c2..4c6b6e6 100644
---- a/kernel/futex.c
-+++ b/kernel/futex.c
-@@ -2813,7 +2813,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
- {
- struct hrtimer_sleeper timeout, *to = NULL;
- struct rt_mutex_waiter rt_waiter;
-- struct rt_mutex *pi_mutex = NULL;
- struct futex_hash_bucket *hb;
- union futex_key key2 = FUTEX_KEY_INIT;
- struct futex_q q = futex_q_init;
-@@ -2897,6 +2896,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
- if (q.pi_state && (q.pi_state->owner != current)) {
- spin_lock(q.lock_ptr);
- ret = fixup_pi_state_owner(uaddr2, &q, current);
-+ if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current)
-+ rt_mutex_unlock(&q.pi_state->pi_mutex);
- /*
- * Drop the reference to the pi state which
- * the requeue_pi() code acquired for us.
-@@ -2905,6 +2906,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
- spin_unlock(q.lock_ptr);
- }
- } else {
-+ struct rt_mutex *pi_mutex;
-+
- /*
- * We have been woken up by futex_unlock_pi(), a timeout, or a
- * signal. futex_unlock_pi() will not destroy the lock_ptr nor
-@@ -2928,18 +2931,19 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
- if (res)
- ret = (res < 0) ? res : 0;
-
-+ /*
-+ * If fixup_pi_state_owner() faulted and was unable to handle
-+ * the fault, unlock the rt_mutex and return the fault to
-+ * userspace.
-+ */
-+ if (ret && rt_mutex_owner(pi_mutex) == current)
-+ rt_mutex_unlock(pi_mutex);
-+
- /* Unqueue and drop the lock. */
- unqueue_me_pi(&q);
- }
-
-- /*
-- * If fixup_pi_state_owner() faulted and was unable to handle the
-- * fault, unlock the rt_mutex and return the fault to userspace.
-- */
-- if (ret == -EFAULT) {
-- if (pi_mutex && rt_mutex_owner(pi_mutex) == current)
-- rt_mutex_unlock(pi_mutex);
-- } else if (ret == -EINTR) {
-+ if (ret == -EINTR) {
- /*
- * We've already been requeued, but cannot restart by calling
- * futex_lock_pi() directly. We could restart this syscall, but
-diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c
-index 1591f6b..2bef4ab 100644
---- a/kernel/locking/rwsem-spinlock.c
-+++ b/kernel/locking/rwsem-spinlock.c
-@@ -216,10 +216,8 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state)
- */
- if (sem->count == 0)
- break;
-- if (signal_pending_state(state, current)) {
-- ret = -EINTR;
-- goto out;
-- }
-+ if (signal_pending_state(state, current))
-+ goto out_nolock;
- set_task_state(tsk, state);
- raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
- schedule();
-@@ -227,12 +225,19 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state)
- }
- /* got the lock */
- sem->count = -1;
--out:
- list_del(&waiter.list);
-
- raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
-
- return ret;
-+
-+out_nolock:
-+ list_del(&waiter.list);
-+ if (!list_empty(&sem->wait_list))
-+ __rwsem_do_wake(sem, 1);
-+ raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
-+
-+ return -EINTR;
- }
-
- void __sched __down_write(struct rw_semaphore *sem)
-diff --git a/mm/slab.c b/mm/slab.c
-index bd878f0..1f82d16 100644
---- a/mm/slab.c
-+++ b/mm/slab.c
-@@ -2332,7 +2332,7 @@ static int drain_freelist(struct kmem_cache *cache,
- return nr_freed;
- }
-
--int __kmem_cache_shrink(struct kmem_cache *cachep, bool deactivate)
-+int __kmem_cache_shrink(struct kmem_cache *cachep)
- {
- int ret = 0;
- int node;
-@@ -2352,7 +2352,7 @@ int __kmem_cache_shrink(struct kmem_cache *cachep, bool deactivate)
-
- int __kmem_cache_shutdown(struct kmem_cache *cachep)
- {
-- return __kmem_cache_shrink(cachep, false);
-+ return __kmem_cache_shrink(cachep);
- }
-
- void __kmem_cache_release(struct kmem_cache *cachep)
-diff --git a/mm/slab.h b/mm/slab.h
-index bc05fdc..ceb7d70 100644
---- a/mm/slab.h
-+++ b/mm/slab.h
-@@ -146,7 +146,7 @@ static inline unsigned long kmem_cache_flags(unsigned long object_size,
-
- int __kmem_cache_shutdown(struct kmem_cache *);
- void __kmem_cache_release(struct kmem_cache *);
--int __kmem_cache_shrink(struct kmem_cache *, bool);
-+int __kmem_cache_shrink(struct kmem_cache *);
- void slab_kmem_cache_release(struct kmem_cache *);
-
- struct seq_file;
-diff --git a/mm/slab_common.c b/mm/slab_common.c
-index 329b038..5d2f24f 100644
---- a/mm/slab_common.c
-+++ b/mm/slab_common.c
-@@ -573,6 +573,29 @@ void memcg_deactivate_kmem_caches(struct mem_cgroup *memcg)
- get_online_cpus();
- get_online_mems();
-
-+#ifdef CONFIG_SLUB
-+ /*
-+ * In case of SLUB, we need to disable empty slab caching to
-+ * avoid pinning the offline memory cgroup by freeable kmem
-+ * pages charged to it. SLAB doesn't need this, as it
-+ * periodically purges unused slabs.
-+ */
-+ mutex_lock(&slab_mutex);
-+ list_for_each_entry(s, &slab_caches, list) {
-+ c = is_root_cache(s) ? cache_from_memcg_idx(s, idx) : NULL;
-+ if (c) {
-+ c->cpu_partial = 0;
-+ c->min_partial = 0;
-+ }
-+ }
-+ mutex_unlock(&slab_mutex);
-+ /*
-+ * kmem_cache->cpu_partial is checked locklessly (see
-+ * put_cpu_partial()). Make sure the change is visible.
-+ */
-+ synchronize_sched();
-+#endif
-+
- mutex_lock(&slab_mutex);
- list_for_each_entry(s, &slab_caches, list) {
- if (!is_root_cache(s))
-@@ -584,7 +607,7 @@ void memcg_deactivate_kmem_caches(struct mem_cgroup *memcg)
- if (!c)
- continue;
-
-- __kmem_cache_shrink(c, true);
-+ __kmem_cache_shrink(c);
- arr->entries[idx] = NULL;
- }
- mutex_unlock(&slab_mutex);
-@@ -755,7 +778,7 @@ int kmem_cache_shrink(struct kmem_cache *cachep)
- get_online_cpus();
- get_online_mems();
- kasan_cache_shrink(cachep);
-- ret = __kmem_cache_shrink(cachep, false);
-+ ret = __kmem_cache_shrink(cachep);
- put_online_mems();
- put_online_cpus();
- return ret;
-diff --git a/mm/slob.c b/mm/slob.c
-index 5ec1580..eac04d43 100644
---- a/mm/slob.c
-+++ b/mm/slob.c
-@@ -634,7 +634,7 @@ void __kmem_cache_release(struct kmem_cache *c)
- {
- }
-
--int __kmem_cache_shrink(struct kmem_cache *d, bool deactivate)
-+int __kmem_cache_shrink(struct kmem_cache *d)
- {
- return 0;
- }
-diff --git a/mm/slub.c b/mm/slub.c
-index 7aa0e97..58c7526 100644
---- a/mm/slub.c
-+++ b/mm/slub.c
-@@ -3887,7 +3887,7 @@ EXPORT_SYMBOL(kfree);
- * being allocated from last increasing the chance that the last objects
- * are freed in them.
- */
--int __kmem_cache_shrink(struct kmem_cache *s, bool deactivate)
-+int __kmem_cache_shrink(struct kmem_cache *s)
- {
- int node;
- int i;
-@@ -3899,21 +3899,6 @@ int __kmem_cache_shrink(struct kmem_cache *s, bool deactivate)
- unsigned long flags;
- int ret = 0;
-
-- if (deactivate) {
-- /*
-- * Disable empty slabs caching. Used to avoid pinning offline
-- * memory cgroups by kmem pages that can be freed.
-- */
-- s->cpu_partial = 0;
-- s->min_partial = 0;
--
-- /*
-- * s->cpu_partial is checked locklessly (see put_cpu_partial),
-- * so we have to make sure the change is visible.
-- */
-- synchronize_sched();
-- }
--
- flush_all(s);
- for_each_kmem_cache_node(s, node, n) {
- INIT_LIST_HEAD(&discard);
-@@ -3970,7 +3955,7 @@ static int slab_mem_going_offline_callback(void *arg)
-
- mutex_lock(&slab_mutex);
- list_for_each_entry(s, &slab_caches, list)
-- __kmem_cache_shrink(s, false);
-+ __kmem_cache_shrink(s);
- mutex_unlock(&slab_mutex);
-
- return 0;
-diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
-index 7cb41ae..8498e35 100644
---- a/net/bridge/br_forward.c
-+++ b/net/bridge/br_forward.c
-@@ -186,8 +186,9 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb,
- /* Do not flood unicast traffic to ports that turn it off */
- if (pkt_type == BR_PKT_UNICAST && !(p->flags & BR_FLOOD))
- continue;
-+ /* Do not flood if mc off, except for traffic we originate */
- if (pkt_type == BR_PKT_MULTICAST &&
-- !(p->flags & BR_MCAST_FLOOD))
-+ !(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev)
- continue;
-
- /* Do not flood to ports that enable proxy ARP */
-diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
-index 855b72f..267b46a 100644
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -29,6 +29,7 @@ EXPORT_SYMBOL(br_should_route_hook);
- static int
- br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb)
- {
-+ br_drop_fake_rtable(skb);
- return netif_receive_skb(skb);
- }
-
-diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
-index 7fbdbae..aa1df1a 100644
---- a/net/bridge/br_netfilter_hooks.c
-+++ b/net/bridge/br_netfilter_hooks.c
-@@ -521,21 +521,6 @@ static unsigned int br_nf_pre_routing(void *priv,
- }
-
-
--/* PF_BRIDGE/LOCAL_IN ************************************************/
--/* The packet is locally destined, which requires a real
-- * dst_entry, so detach the fake one. On the way up, the
-- * packet would pass through PRE_ROUTING again (which already
-- * took place when the packet entered the bridge), but we
-- * register an IPv4 PRE_ROUTING 'sabotage' hook that will
-- * prevent this from happening. */
--static unsigned int br_nf_local_in(void *priv,
-- struct sk_buff *skb,
-- const struct nf_hook_state *state)
--{
-- br_drop_fake_rtable(skb);
-- return NF_ACCEPT;
--}
--
- /* PF_BRIDGE/FORWARD *************************************************/
- static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
- {
-@@ -906,12 +891,6 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = {
- .priority = NF_BR_PRI_BRNF,
- },
- {
-- .hook = br_nf_local_in,
-- .pf = NFPROTO_BRIDGE,
-- .hooknum = NF_BR_LOCAL_IN,
-- .priority = NF_BR_PRI_BRNF,
-- },
-- {
- .hook = br_nf_forward_ip,
- .pf = NFPROTO_BRIDGE,
- .hooknum = NF_BR_FORWARD,
-diff --git a/net/core/dev.c b/net/core/dev.c
-index 60b0a604..2e04fd1 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -1697,27 +1697,54 @@ EXPORT_SYMBOL_GPL(net_dec_egress_queue);
- static struct static_key netstamp_needed __read_mostly;
- #ifdef HAVE_JUMP_LABEL
- static atomic_t netstamp_needed_deferred;
-+static atomic_t netstamp_wanted;
- static void netstamp_clear(struct work_struct *work)
- {
- int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
-+ int wanted;
-
-- while (deferred--)
-- static_key_slow_dec(&netstamp_needed);
-+ wanted = atomic_add_return(deferred, &netstamp_wanted);
-+ if (wanted > 0)
-+ static_key_enable(&netstamp_needed);
-+ else
-+ static_key_disable(&netstamp_needed);
- }
- static DECLARE_WORK(netstamp_work, netstamp_clear);
- #endif
-
- void net_enable_timestamp(void)
- {
-+#ifdef HAVE_JUMP_LABEL
-+ int wanted;
-+
-+ while (1) {
-+ wanted = atomic_read(&netstamp_wanted);
-+ if (wanted <= 0)
-+ break;
-+ if (atomic_cmpxchg(&netstamp_wanted, wanted, wanted + 1) == wanted)
-+ return;
-+ }
-+ atomic_inc(&netstamp_needed_deferred);
-+ schedule_work(&netstamp_work);
-+#else
- static_key_slow_inc(&netstamp_needed);
-+#endif
- }
- EXPORT_SYMBOL(net_enable_timestamp);
-
- void net_disable_timestamp(void)
- {
- #ifdef HAVE_JUMP_LABEL
-- /* net_disable_timestamp() can be called from non process context */
-- atomic_inc(&netstamp_needed_deferred);
-+ int wanted;
-+
-+ while (1) {
-+ wanted = atomic_read(&netstamp_wanted);
-+ if (wanted <= 1)
-+ break;
-+ if (atomic_cmpxchg(&netstamp_wanted, wanted, wanted - 1) == wanted)
-+ return;
-+ }
-+ atomic_dec(&netstamp_needed_deferred);
- schedule_work(&netstamp_work);
- #else
- static_key_slow_dec(&netstamp_needed);
-diff --git a/net/core/skbuff.c b/net/core/skbuff.c
-index 1e3e008..f0f462c 100644
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -3814,13 +3814,14 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
- if (!skb_may_tx_timestamp(sk, false))
- return;
-
-- /* take a reference to prevent skb_orphan() from freeing the socket */
-- sock_hold(sk);
--
-- *skb_hwtstamps(skb) = *hwtstamps;
-- __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
--
-- sock_put(sk);
-+ /* Take a reference to prevent skb_orphan() from freeing the socket,
-+ * but only if the socket refcount is not zero.
-+ */
-+ if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) {
-+ *skb_hwtstamps(skb) = *hwtstamps;
-+ __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
-+ sock_put(sk);
-+ }
- }
- EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp);
-
-@@ -3871,7 +3872,7 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked)
- {
- struct sock *sk = skb->sk;
- struct sock_exterr_skb *serr;
-- int err;
-+ int err = 1;
-
- skb->wifi_acked_valid = 1;
- skb->wifi_acked = acked;
-@@ -3881,14 +3882,15 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked)
- serr->ee.ee_errno = ENOMSG;
- serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS;
-
-- /* take a reference to prevent skb_orphan() from freeing the socket */
-- sock_hold(sk);
--
-- err = sock_queue_err_skb(sk, skb);
-+ /* Take a reference to prevent skb_orphan() from freeing the socket,
-+ * but only if the socket refcount is not zero.
-+ */
-+ if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) {
-+ err = sock_queue_err_skb(sk, skb);
-+ sock_put(sk);
-+ }
- if (err)
- kfree_skb(skb);
--
-- sock_put(sk);
- }
- EXPORT_SYMBOL_GPL(skb_complete_wifi_ack);
-
-diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
-index f053198..5e3a730 100644
---- a/net/dccp/ccids/ccid2.c
-+++ b/net/dccp/ccids/ccid2.c
-@@ -749,6 +749,7 @@ static void ccid2_hc_tx_exit(struct sock *sk)
- for (i = 0; i < hc->tx_seqbufc; i++)
- kfree(hc->tx_seqbuf[i]);
- hc->tx_seqbufc = 0;
-+ dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks);
- }
-
- static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
-diff --git a/net/dccp/input.c b/net/dccp/input.c
-index 8fedc2d..4a05d78 100644
---- a/net/dccp/input.c
-+++ b/net/dccp/input.c
-@@ -577,6 +577,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
- struct dccp_sock *dp = dccp_sk(sk);
- struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
- const int old_state = sk->sk_state;
-+ bool acceptable;
- int queued = 0;
-
- /*
-@@ -603,8 +604,13 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
- */
- if (sk->sk_state == DCCP_LISTEN) {
- if (dh->dccph_type == DCCP_PKT_REQUEST) {
-- if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
-- skb) < 0)
-+ /* It is possible that we process SYN packets from backlog,
-+ * so we need to make sure to disable BH right there.
-+ */
-+ local_bh_disable();
-+ acceptable = inet_csk(sk)->icsk_af_ops->conn_request(sk, skb) >= 0;
-+ local_bh_enable();
-+ if (!acceptable)
- return 1;
- consume_skb(skb);
- return 0;
-diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
-index edbe59d..86b0933 100644
---- a/net/dccp/ipv4.c
-+++ b/net/dccp/ipv4.c
-@@ -289,7 +289,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
-
- switch (type) {
- case ICMP_REDIRECT:
-- dccp_do_redirect(skb, sk);
-+ if (!sock_owned_by_user(sk))
-+ dccp_do_redirect(skb, sk);
- goto out;
- case ICMP_SOURCE_QUENCH:
- /* Just silently ignore these. */
-diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
-index 7506c03..237d62c 100644
---- a/net/dccp/ipv6.c
-+++ b/net/dccp/ipv6.c
-@@ -122,10 +122,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
- np = inet6_sk(sk);
-
- if (type == NDISC_REDIRECT) {
-- struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
-+ if (!sock_owned_by_user(sk)) {
-+ struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
-
-- if (dst)
-- dst->ops->redirect(dst, sk, skb);
-+ if (dst)
-+ dst->ops->redirect(dst, sk, skb);
-+ }
- goto out;
- }
-
-diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
-index 53eddf9..39e7e2b 100644
---- a/net/dccp/minisocks.c
-+++ b/net/dccp/minisocks.c
-@@ -122,6 +122,7 @@ struct sock *dccp_create_openreq_child(const struct sock *sk,
- /* It is still raw copy of parent, so invalidate
- * destructor and make plain sk_free() */
- newsk->sk_destruct = NULL;
-+ bh_unlock_sock(newsk);
- sk_free(newsk);
- return NULL;
- }
-@@ -145,6 +146,13 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
- struct dccp_request_sock *dreq = dccp_rsk(req);
- bool own_req;
-
-+ /* TCP/DCCP listeners became lockless.
-+ * DCCP stores complex state in its request_sock, so we need
-+ * a protection for them, now this code runs without being protected
-+ * by the parent (listener) lock.
-+ */
-+ spin_lock_bh(&dreq->dreq_lock);
-+
- /* Check for retransmitted REQUEST */
- if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) {
-
-@@ -159,7 +167,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
- inet_rtx_syn_ack(sk, req);
- }
- /* Network Duplicate, discard packet */
-- return NULL;
-+ goto out;
- }
-
- DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR;
-@@ -185,20 +193,20 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
-
- child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL,
- req, &own_req);
-- if (!child)
-- goto listen_overflow;
--
-- return inet_csk_complete_hashdance(sk, child, req, own_req);
-+ if (child) {
-+ child = inet_csk_complete_hashdance(sk, child, req, own_req);
-+ goto out;
-+ }
-
--listen_overflow:
-- dccp_pr_debug("listen_overflow!\n");
- DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY;
- drop:
- if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET)
- req->rsk_ops->send_reset(sk, skb);
-
- inet_csk_reqsk_queue_drop(sk, req);
-- return NULL;
-+out:
-+ spin_unlock_bh(&dreq->dreq_lock);
-+ return child;
- }
-
- EXPORT_SYMBOL_GPL(dccp_check_req);
-@@ -249,6 +257,7 @@ int dccp_reqsk_init(struct request_sock *req,
- {
- struct dccp_request_sock *dreq = dccp_rsk(req);
-
-+ spin_lock_init(&dreq->dreq_lock);
- inet_rsk(req)->ir_rmt_port = dccp_hdr(skb)->dccph_sport;
- inet_rsk(req)->ir_num = ntohs(dccp_hdr(skb)->dccph_dport);
- inet_rsk(req)->acked = 0;
-diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
-index 21514324..971b947 100644
---- a/net/ipv4/af_inet.c
-+++ b/net/ipv4/af_inet.c
-@@ -1460,8 +1460,10 @@ int inet_gro_complete(struct sk_buff *skb, int nhoff)
- int proto = iph->protocol;
- int err = -ENOSYS;
-
-- if (skb->encapsulation)
-+ if (skb->encapsulation) {
-+ skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IP));
- skb_set_inner_network_header(skb, nhoff);
-+ }
-
- csum_replace2(&iph->check, iph->tot_len, newlen);
- iph->tot_len = newlen;
-diff --git a/net/ipv4/route.c b/net/ipv4/route.c
-index d851cae..17e6fbf 100644
---- a/net/ipv4/route.c
-+++ b/net/ipv4/route.c
-@@ -1968,6 +1968,7 @@ int ip_route_input_noref(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- {
- int res;
-
-+ tos &= IPTOS_RT_MASK;
- rcu_read_lock();
-
- /* Multicast recognition logic is moved from route cache to here.
-diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index c71d49c..ce42ded 100644
---- a/net/ipv4/tcp_input.c
-+++ b/net/ipv4/tcp_input.c
-@@ -5916,9 +5916,15 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
- if (th->syn) {
- if (th->fin)
- goto discard;
-- if (icsk->icsk_af_ops->conn_request(sk, skb) < 0)
-- return 1;
-+ /* It is possible that we process SYN packets from backlog,
-+ * so we need to make sure to disable BH right there.
-+ */
-+ local_bh_disable();
-+ acceptable = icsk->icsk_af_ops->conn_request(sk, skb) >= 0;
-+ local_bh_enable();
-
-+ if (!acceptable)
-+ return 1;
- consume_skb(skb);
- return 0;
- }
-diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
-index 2259114..6988566 100644
---- a/net/ipv4/tcp_ipv4.c
-+++ b/net/ipv4/tcp_ipv4.c
-@@ -269,10 +269,13 @@ EXPORT_SYMBOL(tcp_v4_connect);
- */
- void tcp_v4_mtu_reduced(struct sock *sk)
- {
-- struct dst_entry *dst;
- struct inet_sock *inet = inet_sk(sk);
-- u32 mtu = tcp_sk(sk)->mtu_info;
-+ struct dst_entry *dst;
-+ u32 mtu;
-
-+ if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
-+ return;
-+ mtu = tcp_sk(sk)->mtu_info;
- dst = inet_csk_update_pmtu(sk, mtu);
- if (!dst)
- return;
-@@ -418,7 +421,8 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
-
- switch (type) {
- case ICMP_REDIRECT:
-- do_redirect(icmp_skb, sk);
-+ if (!sock_owned_by_user(sk))
-+ do_redirect(icmp_skb, sk);
- goto out;
- case ICMP_SOURCE_QUENCH:
- /* Just silently ignore these. */
-diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
-index 3ea1cf8..b1e65b3 100644
---- a/net/ipv4/tcp_timer.c
-+++ b/net/ipv4/tcp_timer.c
-@@ -249,7 +249,8 @@ void tcp_delack_timer_handler(struct sock *sk)
-
- sk_mem_reclaim_partial(sk);
-
-- if (sk->sk_state == TCP_CLOSE || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
-+ if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
-+ !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
- goto out;
-
- if (time_after(icsk->icsk_ack.timeout, jiffies)) {
-@@ -552,7 +553,8 @@ void tcp_write_timer_handler(struct sock *sk)
- struct inet_connection_sock *icsk = inet_csk(sk);
- int event;
-
-- if (sk->sk_state == TCP_CLOSE || !icsk->icsk_pending)
-+ if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
-+ !icsk->icsk_pending)
- goto out;
-
- if (time_after(icsk->icsk_timeout, jiffies)) {
-diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
-index ef54852..8c88a37 100644
---- a/net/ipv6/ip6_fib.c
-+++ b/net/ipv6/ip6_fib.c
-@@ -908,6 +908,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
- ins = &rt->dst.rt6_next;
- iter = *ins;
- while (iter) {
-+ if (iter->rt6i_metric > rt->rt6i_metric)
-+ break;
- if (rt6_qualify_for_ecmp(iter)) {
- *ins = iter->dst.rt6_next;
- fib6_purge_rt(iter, fn, info->nl_net);
-diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
-index fc7b401..33b04ec 100644
---- a/net/ipv6/ip6_offload.c
-+++ b/net/ipv6/ip6_offload.c
-@@ -294,8 +294,10 @@ static int ipv6_gro_complete(struct sk_buff *skb, int nhoff)
- struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + nhoff);
- int err = -ENOSYS;
-
-- if (skb->encapsulation)
-+ if (skb->encapsulation) {
-+ skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IPV6));
- skb_set_inner_network_header(skb, nhoff);
-+ }
-
- iph->payload_len = htons(skb->len - nhoff - sizeof(*iph));
-
-diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
-index 9a87bfb..e27b8fd 100644
---- a/net/ipv6/ip6_output.c
-+++ b/net/ipv6/ip6_output.c
-@@ -757,13 +757,14 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
- * Fragment the datagram.
- */
-
-- *prevhdr = NEXTHDR_FRAGMENT;
- troom = rt->dst.dev->needed_tailroom;
-
- /*
- * Keep copying data until we run out.
- */
- while (left > 0) {
-+ u8 *fragnexthdr_offset;
-+
- len = left;
- /* IF: it doesn't fit, use 'mtu' - the data space left */
- if (len > mtu)
-@@ -808,6 +809,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
- */
- skb_copy_from_linear_data(skb, skb_network_header(frag), hlen);
-
-+ fragnexthdr_offset = skb_network_header(frag);
-+ fragnexthdr_offset += prevhdr - skb_network_header(skb);
-+ *fragnexthdr_offset = NEXTHDR_FRAGMENT;
-+
- /*
- * Build fragment header.
- */
-diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
-index c299c1e..66c2b4b 100644
---- a/net/ipv6/ip6_vti.c
-+++ b/net/ipv6/ip6_vti.c
-@@ -691,6 +691,10 @@ vti6_parm_to_user(struct ip6_tnl_parm2 *u, const struct __ip6_tnl_parm *p)
- u->link = p->link;
- u->i_key = p->i_key;
- u->o_key = p->o_key;
-+ if (u->i_key)
-+ u->i_flags |= GRE_KEY;
-+ if (u->o_key)
-+ u->o_flags |= GRE_KEY;
- u->proto = p->proto;
-
- memcpy(u->name, p->name, sizeof(u->name));
-diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
-index 9948b5c..986d4ca 100644
---- a/net/ipv6/netfilter/nf_conntrack_reasm.c
-+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
-@@ -589,6 +589,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
- hdr = ipv6_hdr(skb);
- fhdr = (struct frag_hdr *)skb_transport_header(skb);
-
-+ skb_orphan(skb);
- fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
- skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
- if (fq == NULL) {
-diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
-index 6673965..b2e61a0 100644
---- a/net/ipv6/tcp_ipv6.c
-+++ b/net/ipv6/tcp_ipv6.c
-@@ -375,10 +375,12 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
- np = inet6_sk(sk);
-
- if (type == NDISC_REDIRECT) {
-- struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
-+ if (!sock_owned_by_user(sk)) {
-+ struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
-
-- if (dst)
-- dst->ops->redirect(dst, sk, skb);
-+ if (dst)
-+ dst->ops->redirect(dst, sk, skb);
-+ }
- goto out;
- }
-
-diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
-index c0f0750..ff750bb 100644
---- a/net/l2tp/l2tp_ip.c
-+++ b/net/l2tp/l2tp_ip.c
-@@ -388,7 +388,7 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb)
- drop:
- IP_INC_STATS(sock_net(sk), IPSTATS_MIB_INDISCARDS);
- kfree_skb(skb);
-- return -1;
-+ return 0;
- }
-
- /* Userspace will call sendmsg() on the tunnel socket to send L2TP
-diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
-index 5b77377..1309e2c 100644
---- a/net/mpls/af_mpls.c
-+++ b/net/mpls/af_mpls.c
-@@ -956,7 +956,8 @@ static void mpls_ifdown(struct net_device *dev, int event)
- /* fall through */
- case NETDEV_CHANGE:
- nh->nh_flags |= RTNH_F_LINKDOWN;
-- ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1;
-+ if (event != NETDEV_UNREGISTER)
-+ ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1;
- break;
- }
- if (event == NETDEV_UNREGISTER)
-@@ -1696,6 +1697,7 @@ static void mpls_net_exit(struct net *net)
- for (index = 0; index < platform_labels; index++) {
- struct mpls_route *rt = rtnl_dereference(platform_label[index]);
- RCU_INIT_POINTER(platform_label[index], NULL);
-+ mpls_notify_route(net, index, rt, NULL, NULL);
- mpls_rt_free(rt);
- }
- rtnl_unlock();
-diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
-index eab210b..48386bf 100644
---- a/net/openvswitch/conntrack.c
-+++ b/net/openvswitch/conntrack.c
-@@ -367,7 +367,6 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
- } else if (key->eth.type == htons(ETH_P_IPV6)) {
- enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone;
-
-- skb_orphan(skb);
- memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
- err = nf_ct_frag6_gather(net, skb, user);
- if (err) {
-diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
-index 34de326..f2b04a7 100644
---- a/net/packet/af_packet.c
-+++ b/net/packet/af_packet.c
-@@ -3140,7 +3140,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
- int addr_len)
- {
- struct sock *sk = sock->sk;
-- char name[15];
-+ char name[sizeof(uaddr->sa_data) + 1];
-
- /*
- * Check legality
-@@ -3148,7 +3148,11 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
-
- if (addr_len != sizeof(struct sockaddr))
- return -EINVAL;
-- strlcpy(name, uaddr->sa_data, sizeof(name));
-+ /* uaddr->sa_data comes from the userspace, it's not guaranteed to be
-+ * zero-terminated.
-+ */
-+ memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data));
-+ name[sizeof(uaddr->sa_data)] = 0;
-
- return packet_do_bind(sk, name, 0, pkt_sk(sk)->num);
- }
-diff --git a/net/sched/act_api.c b/net/sched/act_api.c
-index c6c2a93..c651cfc 100644
---- a/net/sched/act_api.c
-+++ b/net/sched/act_api.c
-@@ -820,10 +820,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
- goto out_module_put;
-
- err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops);
-- if (err < 0)
-+ if (err <= 0)
- goto out_module_put;
-- if (err == 0)
-- goto noflush_out;
-
- nla_nest_end(skb, nest);
-
-@@ -840,7 +838,6 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
- out_module_put:
- module_put(ops->owner);
- err_out:
--noflush_out:
- kfree_skb(skb);
- return err;
- }
-diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
-index eae07a2..1191179 100644
---- a/net/sched/act_connmark.c
-+++ b/net/sched/act_connmark.c
-@@ -113,6 +113,9 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
- if (ret < 0)
- return ret;
-
-+ if (!tb[TCA_CONNMARK_PARMS])
-+ return -EINVAL;
-+
- parm = nla_data(tb[TCA_CONNMARK_PARMS]);
-
- if (!tcf_hash_check(tn, parm->index, a, bind)) {
-diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c
-index e7d9638..f85313d 100644
---- a/net/sched/act_skbmod.c
-+++ b/net/sched/act_skbmod.c
-@@ -228,7 +228,6 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
-
- return skb->len;
- nla_put_failure:
-- rcu_read_unlock();
- nlmsg_trim(skb, b);
- return -1;
- }
-diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c
-index 41adf36..b5c279b 100644
---- a/net/strparser/strparser.c
-+++ b/net/strparser/strparser.c
-@@ -504,6 +504,7 @@ static int __init strp_mod_init(void)
-
- static void __exit strp_mod_exit(void)
- {
-+ destroy_workqueue(strp_wq);
- }
- module_init(strp_mod_init);
- module_exit(strp_mod_exit);
diff --git a/4.9.18/1017_linux-4.9.18.patch b/4.9.18/1017_linux-4.9.18.patch
deleted file mode 100644
index 3f957a2..0000000
--- a/4.9.18/1017_linux-4.9.18.patch
+++ /dev/null
@@ -1,876 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 004f90a..c10d0e6 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 4
- PATCHLEVEL = 9
--SUBLEVEL = 17
-+SUBLEVEL = 18
- EXTRAVERSION =
- NAME = Roaring Lionus
-
-diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
-index 7bd69bd..1d8c24d 100644
---- a/arch/parisc/include/asm/cacheflush.h
-+++ b/arch/parisc/include/asm/cacheflush.h
-@@ -45,28 +45,9 @@ static inline void flush_kernel_dcache_page(struct page *page)
-
- #define flush_kernel_dcache_range(start,size) \
- flush_kernel_dcache_range_asm((start), (start)+(size));
--/* vmap range flushes and invalidates. Architecturally, we don't need
-- * the invalidate, because the CPU should refuse to speculate once an
-- * area has been flushed, so invalidate is left empty */
--static inline void flush_kernel_vmap_range(void *vaddr, int size)
--{
-- unsigned long start = (unsigned long)vaddr;
--
-- flush_kernel_dcache_range_asm(start, start + size);
--}
--static inline void invalidate_kernel_vmap_range(void *vaddr, int size)
--{
-- unsigned long start = (unsigned long)vaddr;
-- void *cursor = vaddr;
-
-- for ( ; cursor < vaddr + size; cursor += PAGE_SIZE) {
-- struct page *page = vmalloc_to_page(cursor);
--
-- if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
-- flush_kernel_dcache_page(page);
-- }
-- flush_kernel_dcache_range_asm(start, start + size);
--}
-+void flush_kernel_vmap_range(void *vaddr, int size);
-+void invalidate_kernel_vmap_range(void *vaddr, int size);
-
- #define flush_cache_vmap(start, end) flush_cache_all()
- #define flush_cache_vunmap(start, end) flush_cache_all()
-diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
-index 977f0a4f..53ec75f 100644
---- a/arch/parisc/kernel/cache.c
-+++ b/arch/parisc/kernel/cache.c
-@@ -633,3 +633,25 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
- __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
- }
- }
-+
-+void flush_kernel_vmap_range(void *vaddr, int size)
-+{
-+ unsigned long start = (unsigned long)vaddr;
-+
-+ if ((unsigned long)size > parisc_cache_flush_threshold)
-+ flush_data_cache();
-+ else
-+ flush_kernel_dcache_range_asm(start, start + size);
-+}
-+EXPORT_SYMBOL(flush_kernel_vmap_range);
-+
-+void invalidate_kernel_vmap_range(void *vaddr, int size)
-+{
-+ unsigned long start = (unsigned long)vaddr;
-+
-+ if ((unsigned long)size > parisc_cache_flush_threshold)
-+ flush_data_cache();
-+ else
-+ flush_kernel_dcache_range_asm(start, start + size);
-+}
-+EXPORT_SYMBOL(invalidate_kernel_vmap_range);
-diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
-index 4063943..e81afc37 100644
---- a/arch/parisc/kernel/process.c
-+++ b/arch/parisc/kernel/process.c
-@@ -139,6 +139,8 @@ void machine_power_off(void)
-
- printk(KERN_EMERG "System shut down completed.\n"
- "Please power this system off now.");
-+
-+ for (;;);
- }
-
- void (*pm_power_off)(void) = machine_power_off;
-diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S
-index 861e721..f080abf 100644
---- a/arch/powerpc/boot/zImage.lds.S
-+++ b/arch/powerpc/boot/zImage.lds.S
-@@ -68,6 +68,7 @@ SECTIONS
- }
-
- #ifdef CONFIG_PPC64_BOOT_WRAPPER
-+ . = ALIGN(256);
- .got :
- {
- __toc_start = .;
-diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
-index 6e6c1fb..272608f 100644
---- a/drivers/cpufreq/cpufreq.c
-+++ b/drivers/cpufreq/cpufreq.c
-@@ -680,9 +680,11 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
- char *buf)
- {
- unsigned int cur_freq = __cpufreq_get(policy);
-- if (!cur_freq)
-- return sprintf(buf, "<unknown>");
-- return sprintf(buf, "%u\n", cur_freq);
-+
-+ if (cur_freq)
-+ return sprintf(buf, "%u\n", cur_freq);
-+
-+ return sprintf(buf, "<unknown>\n");
- }
-
- /**
-diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
-index b447a01..09e6a73 100644
---- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
-+++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
-@@ -3506,6 +3506,12 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
- max_sclk = 75000;
- max_mclk = 80000;
- }
-+ } else if (adev->asic_type == CHIP_OLAND) {
-+ if ((adev->pdev->device == 0x6604) &&
-+ (adev->pdev->subsystem_vendor == 0x1028) &&
-+ (adev->pdev->subsystem_device == 0x066F)) {
-+ max_sclk = 75000;
-+ }
- }
- /* Apply dpm quirks */
- while (p && p->chip_device != 0) {
-diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
-index 8703f56..246d1ae 100644
---- a/drivers/gpu/drm/vc4/vc4_drv.c
-+++ b/drivers/gpu/drm/vc4/vc4_drv.c
-@@ -61,21 +61,24 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
- if (ret < 0)
- return ret;
- args->value = V3D_READ(V3D_IDENT0);
-- pm_runtime_put(&vc4->v3d->pdev->dev);
-+ pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
-+ pm_runtime_put_autosuspend(&vc4->v3d->pdev->dev);
- break;
- case DRM_VC4_PARAM_V3D_IDENT1:
- ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
- if (ret < 0)
- return ret;
- args->value = V3D_READ(V3D_IDENT1);
-- pm_runtime_put(&vc4->v3d->pdev->dev);
-+ pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
-+ pm_runtime_put_autosuspend(&vc4->v3d->pdev->dev);
- break;
- case DRM_VC4_PARAM_V3D_IDENT2:
- ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
- if (ret < 0)
- return ret;
- args->value = V3D_READ(V3D_IDENT2);
-- pm_runtime_put(&vc4->v3d->pdev->dev);
-+ pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
-+ pm_runtime_put_autosuspend(&vc4->v3d->pdev->dev);
- break;
- case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
- args->value = true;
-diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
-index 18e3717..ab30169 100644
---- a/drivers/gpu/drm/vc4/vc4_gem.c
-+++ b/drivers/gpu/drm/vc4/vc4_gem.c
-@@ -711,8 +711,10 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
- }
-
- mutex_lock(&vc4->power_lock);
-- if (--vc4->power_refcount == 0)
-- pm_runtime_put(&vc4->v3d->pdev->dev);
-+ if (--vc4->power_refcount == 0) {
-+ pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
-+ pm_runtime_put_autosuspend(&vc4->v3d->pdev->dev);
-+ }
- mutex_unlock(&vc4->power_lock);
-
- kfree(exec);
-diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
-index e6d3c60..7cc346a 100644
---- a/drivers/gpu/drm/vc4/vc4_v3d.c
-+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
-@@ -222,6 +222,8 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
- return ret;
- }
-
-+ pm_runtime_use_autosuspend(dev);
-+ pm_runtime_set_autosuspend_delay(dev, 40); /* a little over 2 frames. */
- pm_runtime_enable(dev);
-
- return 0;
-diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
-index 2543cf5..917321c 100644
---- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c
-+++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
-@@ -608,9 +608,7 @@ static bool
- vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
- {
- uint32_t max_branch_target = 0;
-- bool found_shader_end = false;
- int ip;
-- int shader_end_ip = 0;
- int last_branch = -2;
-
- for (ip = 0; ip < validation_state->max_ip; ip++) {
-@@ -621,8 +619,13 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
- uint32_t branch_target_ip;
-
- if (sig == QPU_SIG_PROG_END) {
-- shader_end_ip = ip;
-- found_shader_end = true;
-+ /* There are two delay slots after program end is
-+ * signaled that are still executed, then we're
-+ * finished. validation_state->max_ip is the
-+ * instruction after the last valid instruction in the
-+ * program.
-+ */
-+ validation_state->max_ip = ip + 3;
- continue;
- }
-
-@@ -676,15 +679,9 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
- }
- set_bit(after_delay_ip, validation_state->branch_targets);
- max_branch_target = max(max_branch_target, after_delay_ip);
--
-- /* There are two delay slots after program end is signaled
-- * that are still executed, then we're finished.
-- */
-- if (found_shader_end && ip == shader_end_ip + 2)
-- break;
- }
-
-- if (max_branch_target > shader_end_ip) {
-+ if (max_branch_target > validation_state->max_ip - 3) {
- DRM_ERROR("Branch landed after QPU_SIG_PROG_END");
- return false;
- }
-diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
-index aecec6d..7f1c625 100644
---- a/drivers/isdn/gigaset/bas-gigaset.c
-+++ b/drivers/isdn/gigaset/bas-gigaset.c
-@@ -2317,6 +2317,9 @@ static int gigaset_probe(struct usb_interface *interface,
- return -ENODEV;
- }
-
-+ if (hostif->desc.bNumEndpoints < 1)
-+ return -ENODEV;
-+
- dev_info(&udev->dev,
- "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n",
- __func__, le16_to_cpu(udev->descriptor.idVendor),
-diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
-index 39fddda..55b5e0e 100644
---- a/drivers/md/raid10.c
-+++ b/drivers/md/raid10.c
-@@ -1470,7 +1470,25 @@ static void raid10_make_request(struct mddev *mddev, struct bio *bio)
- split = bio;
- }
-
-+ /*
-+ * If a bio is splitted, the first part of bio will pass
-+ * barrier but the bio is queued in current->bio_list (see
-+ * generic_make_request). If there is a raise_barrier() called
-+ * here, the second part of bio can't pass barrier. But since
-+ * the first part bio isn't dispatched to underlaying disks
-+ * yet, the barrier is never released, hence raise_barrier will
-+ * alays wait. We have a deadlock.
-+ * Note, this only happens in read path. For write path, the
-+ * first part of bio is dispatched in a schedule() call
-+ * (because of blk plug) or offloaded to raid10d.
-+ * Quitting from the function immediately can change the bio
-+ * order queued in bio_list and avoid the deadlock.
-+ */
- __make_request(mddev, split);
-+ if (split != bio && bio_data_dir(bio) == READ) {
-+ generic_make_request(bio);
-+ break;
-+ }
- } while (split != bio);
-
- /* In case raid10d snuck in to freeze_array */
-diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
-index f9b6fba..a530f08 100644
---- a/drivers/scsi/libiscsi.c
-+++ b/drivers/scsi/libiscsi.c
-@@ -560,8 +560,12 @@ static void iscsi_complete_task(struct iscsi_task *task, int state)
- WARN_ON_ONCE(task->state == ISCSI_TASK_FREE);
- task->state = state;
-
-- if (!list_empty(&task->running))
-+ spin_lock_bh(&conn->taskqueuelock);
-+ if (!list_empty(&task->running)) {
-+ pr_debug_once("%s while task on list", __func__);
- list_del_init(&task->running);
-+ }
-+ spin_unlock_bh(&conn->taskqueuelock);
-
- if (conn->task == task)
- conn->task = NULL;
-@@ -783,7 +787,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
- if (session->tt->xmit_task(task))
- goto free_task;
- } else {
-+ spin_lock_bh(&conn->taskqueuelock);
- list_add_tail(&task->running, &conn->mgmtqueue);
-+ spin_unlock_bh(&conn->taskqueuelock);
- iscsi_conn_queue_work(conn);
- }
-
-@@ -1474,8 +1480,10 @@ void iscsi_requeue_task(struct iscsi_task *task)
- * this may be on the requeue list already if the xmit_task callout
- * is handling the r2ts while we are adding new ones
- */
-+ spin_lock_bh(&conn->taskqueuelock);
- if (list_empty(&task->running))
- list_add_tail(&task->running, &conn->requeue);
-+ spin_unlock_bh(&conn->taskqueuelock);
- iscsi_conn_queue_work(conn);
- }
- EXPORT_SYMBOL_GPL(iscsi_requeue_task);
-@@ -1512,22 +1520,26 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
- * only have one nop-out as a ping from us and targets should not
- * overflow us with nop-ins
- */
-+ spin_lock_bh(&conn->taskqueuelock);
- check_mgmt:
- while (!list_empty(&conn->mgmtqueue)) {
- conn->task = list_entry(conn->mgmtqueue.next,
- struct iscsi_task, running);
- list_del_init(&conn->task->running);
-+ spin_unlock_bh(&conn->taskqueuelock);
- if (iscsi_prep_mgmt_task(conn, conn->task)) {
- /* regular RX path uses back_lock */
- spin_lock_bh(&conn->session->back_lock);
- __iscsi_put_task(conn->task);
- spin_unlock_bh(&conn->session->back_lock);
- conn->task = NULL;
-+ spin_lock_bh(&conn->taskqueuelock);
- continue;
- }
- rc = iscsi_xmit_task(conn);
- if (rc)
- goto done;
-+ spin_lock_bh(&conn->taskqueuelock);
- }
-
- /* process pending command queue */
-@@ -1535,19 +1547,24 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
- conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task,
- running);
- list_del_init(&conn->task->running);
-+ spin_unlock_bh(&conn->taskqueuelock);
- if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
- fail_scsi_task(conn->task, DID_IMM_RETRY);
-+ spin_lock_bh(&conn->taskqueuelock);
- continue;
- }
- rc = iscsi_prep_scsi_cmd_pdu(conn->task);
- if (rc) {
- if (rc == -ENOMEM || rc == -EACCES) {
-+ spin_lock_bh(&conn->taskqueuelock);
- list_add_tail(&conn->task->running,
- &conn->cmdqueue);
- conn->task = NULL;
-+ spin_unlock_bh(&conn->taskqueuelock);
- goto done;
- } else
- fail_scsi_task(conn->task, DID_ABORT);
-+ spin_lock_bh(&conn->taskqueuelock);
- continue;
- }
- rc = iscsi_xmit_task(conn);
-@@ -1558,6 +1575,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
- * we need to check the mgmt queue for nops that need to
- * be sent to aviod starvation
- */
-+ spin_lock_bh(&conn->taskqueuelock);
- if (!list_empty(&conn->mgmtqueue))
- goto check_mgmt;
- }
-@@ -1577,12 +1595,15 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
- conn->task = task;
- list_del_init(&conn->task->running);
- conn->task->state = ISCSI_TASK_RUNNING;
-+ spin_unlock_bh(&conn->taskqueuelock);
- rc = iscsi_xmit_task(conn);
- if (rc)
- goto done;
-+ spin_lock_bh(&conn->taskqueuelock);
- if (!list_empty(&conn->mgmtqueue))
- goto check_mgmt;
- }
-+ spin_unlock_bh(&conn->taskqueuelock);
- spin_unlock_bh(&conn->session->frwd_lock);
- return -ENODATA;
-
-@@ -1738,7 +1759,9 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
- goto prepd_reject;
- }
- } else {
-+ spin_lock_bh(&conn->taskqueuelock);
- list_add_tail(&task->running, &conn->cmdqueue);
-+ spin_unlock_bh(&conn->taskqueuelock);
- iscsi_conn_queue_work(conn);
- }
-
-@@ -2897,6 +2920,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size,
- INIT_LIST_HEAD(&conn->mgmtqueue);
- INIT_LIST_HEAD(&conn->cmdqueue);
- INIT_LIST_HEAD(&conn->requeue);
-+ spin_lock_init(&conn->taskqueuelock);
- INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
-
- /* allocate login_task used for the login/text sequences */
-diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
-index 734a042..f7e3f27 100644
---- a/drivers/scsi/lpfc/lpfc_init.c
-+++ b/drivers/scsi/lpfc/lpfc_init.c
-@@ -11393,6 +11393,7 @@ static struct pci_driver lpfc_driver = {
- .id_table = lpfc_id_table,
- .probe = lpfc_pci_probe_one,
- .remove = lpfc_pci_remove_one,
-+ .shutdown = lpfc_pci_remove_one,
- .suspend = lpfc_pci_suspend_one,
- .resume = lpfc_pci_resume_one,
- .err_handler = &lpfc_err_handler,
-diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
-index bff9689..feab7ea 100644
---- a/drivers/scsi/qla2xxx/qla_target.c
-+++ b/drivers/scsi/qla2xxx/qla_target.c
-@@ -5375,16 +5375,22 @@ qlt_send_busy(struct scsi_qla_host *vha,
-
- static int
- qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
-- struct atio_from_isp *atio)
-+ struct atio_from_isp *atio, bool ha_locked)
- {
- struct qla_hw_data *ha = vha->hw;
- uint16_t status;
-+ unsigned long flags;
-
- if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
- return 0;
-
-+ if (!ha_locked)
-+ spin_lock_irqsave(&ha->hardware_lock, flags);
- status = temp_sam_status;
- qlt_send_busy(vha, atio, status);
-+ if (!ha_locked)
-+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
-+
- return 1;
- }
-
-@@ -5429,7 +5435,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
-
-
- if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
-- rc = qlt_chk_qfull_thresh_hold(vha, atio);
-+ rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked);
- if (rc != 0) {
- tgt->atio_irq_cmd_count--;
- return;
-@@ -5552,7 +5558,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
- break;
- }
-
-- rc = qlt_chk_qfull_thresh_hold(vha, atio);
-+ rc = qlt_chk_qfull_thresh_hold(vha, atio, true);
- if (rc != 0) {
- tgt->irq_cmd_count--;
- return;
-@@ -6794,6 +6800,8 @@ qlt_handle_abts_recv_work(struct work_struct *work)
- spin_lock_irqsave(&ha->hardware_lock, flags);
- qlt_response_pkt_all_vps(vha, (response_t *)&op->atio);
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
-+
-+ kfree(op);
- }
-
- void
-diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
-index 9125d93..ef1c8c1 100644
---- a/drivers/target/target_core_pscsi.c
-+++ b/drivers/target/target_core_pscsi.c
-@@ -154,7 +154,7 @@ static void pscsi_tape_read_blocksize(struct se_device *dev,
-
- buf = kzalloc(12, GFP_KERNEL);
- if (!buf)
-- return;
-+ goto out_free;
-
- memset(cdb, 0, MAX_COMMAND_SIZE);
- cdb[0] = MODE_SENSE;
-@@ -169,9 +169,10 @@ static void pscsi_tape_read_blocksize(struct se_device *dev,
- * If MODE_SENSE still returns zero, set the default value to 1024.
- */
- sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]);
-+out_free:
- if (!sdev->sector_size)
- sdev->sector_size = 1024;
--out_free:
-+
- kfree(buf);
- }
-
-@@ -314,9 +315,10 @@ static int pscsi_add_device_to_list(struct se_device *dev,
- sd->lun, sd->queue_depth);
- }
-
-- dev->dev_attrib.hw_block_size = sd->sector_size;
-+ dev->dev_attrib.hw_block_size =
-+ min_not_zero((int)sd->sector_size, 512);
- dev->dev_attrib.hw_max_sectors =
-- min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q));
-+ min_not_zero(sd->host->max_sectors, queue_max_hw_sectors(q));
- dev->dev_attrib.hw_queue_depth = sd->queue_depth;
-
- /*
-@@ -339,8 +341,10 @@ static int pscsi_add_device_to_list(struct se_device *dev,
- /*
- * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE.
- */
-- if (sd->type == TYPE_TAPE)
-+ if (sd->type == TYPE_TAPE) {
- pscsi_tape_read_blocksize(dev, sd);
-+ dev->dev_attrib.hw_block_size = sd->sector_size;
-+ }
- return 0;
- }
-
-@@ -406,7 +410,7 @@ static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd)
- /*
- * Called with struct Scsi_Host->host_lock called.
- */
--static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd)
-+static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device *sd)
- __releases(sh->host_lock)
- {
- struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
-@@ -433,28 +437,6 @@ static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd)
- return 0;
- }
-
--/*
-- * Called with struct Scsi_Host->host_lock called.
-- */
--static int pscsi_create_type_other(struct se_device *dev,
-- struct scsi_device *sd)
-- __releases(sh->host_lock)
--{
-- struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
-- struct Scsi_Host *sh = sd->host;
-- int ret;
--
-- spin_unlock_irq(sh->host_lock);
-- ret = pscsi_add_device_to_list(dev, sd);
-- if (ret)
-- return ret;
--
-- pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%llu\n",
-- phv->phv_host_id, scsi_device_type(sd->type), sh->host_no,
-- sd->channel, sd->id, sd->lun);
-- return 0;
--}
--
- static int pscsi_configure_device(struct se_device *dev)
- {
- struct se_hba *hba = dev->se_hba;
-@@ -542,11 +524,8 @@ static int pscsi_configure_device(struct se_device *dev)
- case TYPE_DISK:
- ret = pscsi_create_type_disk(dev, sd);
- break;
-- case TYPE_ROM:
-- ret = pscsi_create_type_rom(dev, sd);
-- break;
- default:
-- ret = pscsi_create_type_other(dev, sd);
-+ ret = pscsi_create_type_nondisk(dev, sd);
- break;
- }
-
-@@ -611,8 +590,7 @@ static void pscsi_free_device(struct se_device *dev)
- else if (pdv->pdv_lld_host)
- scsi_host_put(pdv->pdv_lld_host);
-
-- if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM))
-- scsi_device_put(sd);
-+ scsi_device_put(sd);
-
- pdv->pdv_sd = NULL;
- }
-@@ -1069,7 +1047,6 @@ static sector_t pscsi_get_blocks(struct se_device *dev)
- if (pdv->pdv_bd && pdv->pdv_bd->bd_part)
- return pdv->pdv_bd->bd_part->nr_sects;
-
-- dump_stack();
- return 0;
- }
-
-diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
-index aabd660..a53fb23 100644
---- a/drivers/target/target_core_sbc.c
-+++ b/drivers/target/target_core_sbc.c
-@@ -1104,9 +1104,15 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
- return ret;
- break;
- case VERIFY:
-+ case VERIFY_16:
- size = 0;
-- sectors = transport_get_sectors_10(cdb);
-- cmd->t_task_lba = transport_lba_32(cdb);
-+ if (cdb[0] == VERIFY) {
-+ sectors = transport_get_sectors_10(cdb);
-+ cmd->t_task_lba = transport_lba_32(cdb);
-+ } else {
-+ sectors = transport_get_sectors_16(cdb);
-+ cmd->t_task_lba = transport_lba_64(cdb);
-+ }
- cmd->execute_cmd = sbc_emulate_noop;
- goto check_lba;
- case REZERO_UNIT:
-diff --git a/fs/ext4/super.c b/fs/ext4/super.c
-index afe29ba..5fa9ba1 100644
---- a/fs/ext4/super.c
-+++ b/fs/ext4/super.c
-@@ -3830,7 +3830,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
- db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
- EXT4_DESC_PER_BLOCK(sb);
- if (ext4_has_feature_meta_bg(sb)) {
-- if (le32_to_cpu(es->s_first_meta_bg) >= db_count) {
-+ if (le32_to_cpu(es->s_first_meta_bg) > db_count) {
- ext4_msg(sb, KERN_WARNING,
- "first meta block group too large: %u "
- "(group descriptor block count %u)",
-diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
-index a6a3389..51519c2 100644
---- a/fs/gfs2/incore.h
-+++ b/fs/gfs2/incore.h
-@@ -207,7 +207,7 @@ struct lm_lockname {
- struct gfs2_sbd *ln_sbd;
- u64 ln_number;
- unsigned int ln_type;
--};
-+} __packed __aligned(sizeof(int));
-
- #define lm_name_equal(name1, name2) \
- (((name1)->ln_number == (name2)->ln_number) && \
-diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
-index 609840d..1536aeb 100644
---- a/fs/nfs/nfs4proc.c
-+++ b/fs/nfs/nfs4proc.c
-@@ -7426,11 +7426,11 @@ static void nfs4_exchange_id_release(void *data)
- struct nfs41_exchange_id_data *cdata =
- (struct nfs41_exchange_id_data *)data;
-
-- nfs_put_client(cdata->args.client);
- if (cdata->xprt) {
- xprt_put(cdata->xprt);
- rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient);
- }
-+ nfs_put_client(cdata->args.client);
- kfree(cdata->res.impl_id);
- kfree(cdata->res.server_scope);
- kfree(cdata->res.server_owner);
-@@ -7537,10 +7537,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
- task_setup_data.callback_data = calldata;
-
- task = rpc_run_task(&task_setup_data);
-- if (IS_ERR(task)) {
-- status = PTR_ERR(task);
-- goto out_impl_id;
-- }
-+ if (IS_ERR(task))
-+ return PTR_ERR(task);
-
- if (!xprt) {
- status = rpc_wait_for_completion_task(task);
-@@ -7568,6 +7566,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
- kfree(calldata->res.server_owner);
- out_calldata:
- kfree(calldata);
-+ nfs_put_client(clp);
- goto out;
- }
-
-diff --git a/include/linux/log2.h b/include/linux/log2.h
-index fd7ff3d..f38fae2 100644
---- a/include/linux/log2.h
-+++ b/include/linux/log2.h
-@@ -16,12 +16,6 @@
- #include <linux/bitops.h>
-
- /*
-- * deal with unrepresentable constant logarithms
-- */
--extern __attribute__((const, noreturn))
--int ____ilog2_NaN(void);
--
--/*
- * non-constant log of base 2 calculators
- * - the arch may override these in asm/bitops.h if they can be implemented
- * more efficiently than using fls() and fls64()
-@@ -85,7 +79,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
- #define ilog2(n) \
- ( \
- __builtin_constant_p(n) ? ( \
-- (n) < 1 ? ____ilog2_NaN() : \
-+ (n) < 2 ? 0 : \
- (n) & (1ULL << 63) ? 63 : \
- (n) & (1ULL << 62) ? 62 : \
- (n) & (1ULL << 61) ? 61 : \
-@@ -148,10 +142,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
- (n) & (1ULL << 4) ? 4 : \
- (n) & (1ULL << 3) ? 3 : \
- (n) & (1ULL << 2) ? 2 : \
-- (n) & (1ULL << 1) ? 1 : \
-- (n) & (1ULL << 0) ? 0 : \
-- ____ilog2_NaN() \
-- ) : \
-+ 1 ) : \
- (sizeof(n) <= 4) ? \
- __ilog2_u32(n) : \
- __ilog2_u64(n) \
-diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
-index 4d1c46a..c7b1dc7 100644
---- a/include/scsi/libiscsi.h
-+++ b/include/scsi/libiscsi.h
-@@ -196,6 +196,7 @@ struct iscsi_conn {
- struct iscsi_task *task; /* xmit task in progress */
-
- /* xmit */
-+ spinlock_t taskqueuelock; /* protects the next three lists */
- struct list_head mgmtqueue; /* mgmt (control) xmit queue */
- struct list_head cmdqueue; /* data-path cmd queue */
- struct list_head requeue; /* tasks needing another run */
-diff --git a/kernel/cgroup_pids.c b/kernel/cgroup_pids.c
-index 2bd6737..a57242e 100644
---- a/kernel/cgroup_pids.c
-+++ b/kernel/cgroup_pids.c
-@@ -229,7 +229,7 @@ static int pids_can_fork(struct task_struct *task)
- /* Only log the first time events_limit is incremented. */
- if (atomic64_inc_return(&pids->events_limit) == 1) {
- pr_info("cgroup: fork rejected by pids controller in ");
-- pr_cont_cgroup_path(task_cgroup(current, pids_cgrp_id));
-+ pr_cont_cgroup_path(css->cgroup);
- pr_cont("\n");
- }
- cgroup_file_notify(&pids->events_file);
-diff --git a/kernel/events/core.c b/kernel/events/core.c
-index 4b33231..07c0dc8 100644
---- a/kernel/events/core.c
-+++ b/kernel/events/core.c
-@@ -10333,6 +10333,17 @@ void perf_event_free_task(struct task_struct *task)
- continue;
-
- mutex_lock(&ctx->mutex);
-+ raw_spin_lock_irq(&ctx->lock);
-+ /*
-+ * Destroy the task <-> ctx relation and mark the context dead.
-+ *
-+ * This is important because even though the task hasn't been
-+ * exposed yet the context has been (through child_list).
-+ */
-+ RCU_INIT_POINTER(task->perf_event_ctxp[ctxn], NULL);
-+ WRITE_ONCE(ctx->task, TASK_TOMBSTONE);
-+ put_task_struct(task); /* cannot be last */
-+ raw_spin_unlock_irq(&ctx->lock);
- again:
- list_for_each_entry_safe(event, tmp, &ctx->pinned_groups,
- group_entry)
-@@ -10586,7 +10597,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn)
- ret = inherit_task_group(event, parent, parent_ctx,
- child, ctxn, &inherited_all);
- if (ret)
-- break;
-+ goto out_unlock;
- }
-
- /*
-@@ -10602,7 +10613,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn)
- ret = inherit_task_group(event, parent, parent_ctx,
- child, ctxn, &inherited_all);
- if (ret)
-- break;
-+ goto out_unlock;
- }
-
- raw_spin_lock_irqsave(&parent_ctx->lock, flags);
-@@ -10630,6 +10641,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn)
- }
-
- raw_spin_unlock_irqrestore(&parent_ctx->lock, flags);
-+out_unlock:
- mutex_unlock(&parent_ctx->mutex);
-
- perf_unpin_context(parent_ctx);
-diff --git a/mm/percpu.c b/mm/percpu.c
-index 2557143..f014ceb 100644
---- a/mm/percpu.c
-+++ b/mm/percpu.c
-@@ -1010,8 +1010,11 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
- mutex_unlock(&pcpu_alloc_mutex);
- }
-
-- if (chunk != pcpu_reserved_chunk)
-+ if (chunk != pcpu_reserved_chunk) {
-+ spin_lock_irqsave(&pcpu_lock, flags);
- pcpu_nr_empty_pop_pages -= occ_pages;
-+ spin_unlock_irqrestore(&pcpu_lock, flags);
-+ }
-
- if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_LOW)
- pcpu_schedule_balance_work();
-diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
-index e2c37061..69502fa 100644
---- a/net/sunrpc/xprtrdma/verbs.c
-+++ b/net/sunrpc/xprtrdma/verbs.c
-@@ -486,7 +486,8 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
- struct ib_cq *sendcq, *recvcq;
- int rc;
-
-- max_sge = min(ia->ri_device->attrs.max_sge, RPCRDMA_MAX_SEND_SGES);
-+ max_sge = min_t(unsigned int, ia->ri_device->attrs.max_sge,
-+ RPCRDMA_MAX_SEND_SGES);
- if (max_sge < RPCRDMA_MIN_SEND_SGES) {
- pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge);
- return -ENOMEM;
-diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h
-index 4144666..d5677d3 100644
---- a/tools/include/linux/log2.h
-+++ b/tools/include/linux/log2.h
-@@ -13,12 +13,6 @@
- #define _TOOLS_LINUX_LOG2_H
-
- /*
-- * deal with unrepresentable constant logarithms
-- */
--extern __attribute__((const, noreturn))
--int ____ilog2_NaN(void);
--
--/*
- * non-constant log of base 2 calculators
- * - the arch may override these in asm/bitops.h if they can be implemented
- * more efficiently than using fls() and fls64()
-@@ -78,7 +72,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
- #define ilog2(n) \
- ( \
- __builtin_constant_p(n) ? ( \
-- (n) < 1 ? ____ilog2_NaN() : \
-+ (n) < 2 ? 0 : \
- (n) & (1ULL << 63) ? 63 : \
- (n) & (1ULL << 62) ? 62 : \
- (n) & (1ULL << 61) ? 61 : \
-@@ -141,10 +135,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
- (n) & (1ULL << 4) ? 4 : \
- (n) & (1ULL << 3) ? 3 : \
- (n) & (1ULL << 2) ? 2 : \
-- (n) & (1ULL << 1) ? 1 : \
-- (n) & (1ULL << 0) ? 0 : \
-- ____ilog2_NaN() \
-- ) : \
-+ 1 ) : \
- (sizeof(n) <= 4) ? \
- __ilog2_u32(n) : \
- __ilog2_u64(n) \
diff --git a/4.9.18/0000_README b/4.9.20/0000_README
index 8c12f63..a960856 100644
--- a/4.9.18/0000_README
+++ b/4.9.20/0000_README
@@ -2,15 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 1016_linux-4.9.17.patch
-From: http://www.kernel.org
-Desc: Linux 4.9.17
-
-Patch: 1017_linux-4.9.18.patch
-From: http://www.kernel.org
-Desc: Linux 4.9.18
-
-Patch: 4420_grsecurity-3.1-4.9.18-201703261106.patch
+Patch: 4420_grsecurity-3.1-4.9.20-201703310823.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.9.18/4420_grsecurity-3.1-4.9.18-201703261106.patch b/4.9.20/4420_grsecurity-3.1-4.9.20-201703310823.patch
index 3659b97..f803149 100644
--- a/4.9.18/4420_grsecurity-3.1-4.9.18-201703261106.patch
+++ b/4.9.20/4420_grsecurity-3.1-4.9.20-201703310823.patch
@@ -419,7 +419,7 @@ index 3d0ae15..84e5412 100644
cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) $(missing_syscalls_flags)
diff --git a/Makefile b/Makefile
-index c10d0e6..54799eb2 100644
+index 4496018..3f9a080 100644
--- a/Makefile
+++ b/Makefile
@@ -302,7 +302,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -7351,10 +7351,10 @@ index 1652f36..0e22377 100644
{
struct pt_regs *regs;
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
-index a92994d..e389b11 100644
+index bf83dc1..775bed8 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
-@@ -882,6 +882,10 @@ long arch_ptrace(struct task_struct *child, long request,
+@@ -883,6 +883,10 @@ long arch_ptrace(struct task_struct *child, long request,
return ret;
}
@@ -7365,7 +7365,7 @@ index a92994d..e389b11 100644
/*
* Notification of system call entry/exit
* - triggered by current->work.syscall_trace
-@@ -899,6 +903,11 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
+@@ -900,6 +904,11 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
if (secure_computing(NULL) == -1)
return -1;
@@ -11324,7 +11324,7 @@ index 79cc0d1..46d6233 100644
.getproplen = prom_getproplen,
.getproperty = prom_getproperty,
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
-index ac082dd..7170942 100644
+index 7037ca3..070b51b 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -1068,6 +1068,10 @@ long arch_ptrace(struct task_struct *child, long request,
@@ -36277,7 +36277,7 @@ index 69b8f8a..0cf39f5 100644
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index 731044e..399463d 100644
+index e5bc139..5a1766b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2005,8 +2005,8 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data)
@@ -49817,7 +49817,7 @@ index 4d3ec92..cf501fc 100644
ret = cpufreq_register_driver(&dt_cpufreq_driver);
if (ret)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
-index 272608f..5c4a47a 100644
+index cac4a92..93c0aed 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -528,12 +528,12 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq);
@@ -49835,7 +49835,7 @@ index 272608f..5c4a47a 100644
const char *buf, size_t count)
{
int ret, enable;
-@@ -2116,7 +2116,7 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
+@@ -2119,7 +2119,7 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor)
read_unlock_irqrestore(&cpufreq_driver_lock, flags);
mutex_lock(&cpufreq_governor_mutex);
@@ -49844,7 +49844,7 @@ index 272608f..5c4a47a 100644
mutex_unlock(&cpufreq_governor_mutex);
return;
}
-@@ -2336,13 +2336,17 @@ int cpufreq_boost_trigger_state(int state)
+@@ -2339,13 +2339,17 @@ int cpufreq_boost_trigger_state(int state)
return 0;
write_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -49864,7 +49864,7 @@ index 272608f..5c4a47a 100644
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
pr_err("%s: Cannot %s BOOST\n",
-@@ -2383,7 +2387,9 @@ int cpufreq_enable_boost_support(void)
+@@ -2386,7 +2390,9 @@ int cpufreq_enable_boost_support(void)
if (cpufreq_boost_supported())
return 0;
@@ -49875,7 +49875,7 @@ index 272608f..5c4a47a 100644
/* This will get removed on driver unregister */
return create_boost_sysfs_file();
-@@ -2441,8 +2447,11 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+@@ -2444,8 +2450,11 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
cpufreq_driver = driver_data;
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -52248,7 +52248,7 @@ index 1fd6eac..e4206c9 100644
return 0;
}
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
-index e84faec..03aaa9f 100644
+index f5815e1..106f6e1 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -132,7 +132,7 @@ int drm_open(struct inode *inode, struct file *filp)
@@ -52935,7 +52935,7 @@ index 97f3a56..32c712e 100644
ret = drm_ioctl(filp, cmd, arg);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
-index 3fc286c..4c19f25 100644
+index 3fc286cd..4c19f25 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4511,15 +4511,16 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
@@ -55328,7 +55328,7 @@ index c13fb5b..55a3802 100644
*off += size;
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
-index be34547..df73ac5 100644
+index 1606e7f..b207d4b 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -404,7 +404,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
@@ -55340,7 +55340,7 @@ index be34547..df73ac5 100644
ret = create_gpadl_header(kbuffer, size, &msginfo);
if (ret)
-@@ -734,9 +734,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+@@ -737,9 +737,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
* Adjust the size down since vmbus_channel_packet_page_buffer is the
* largest size we support
*/
@@ -57462,10 +57462,10 @@ index 4a95b22..874c182 100644
#include <linux/gameport.h>
#include <linux/jiffies.h>
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
-index 9c0ea36..1e1a411 100644
+index f4e8fbe..0efd9d6 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
-@@ -1855,7 +1855,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
+@@ -1859,7 +1859,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
{
@@ -57474,7 +57474,7 @@ index 9c0ea36..1e1a411 100644
const struct ims_pcu_device_info *info;
int error;
-@@ -1886,7 +1886,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
+@@ -1890,7 +1890,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
}
/* Device appears to be operable, complete initialization */
@@ -65843,10 +65843,10 @@ index 9b56b40..f183a4d 100644
struct lance_private *lp = netdev_priv(dev);
int entry, skblen, len;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
-index bbef959..999ab1d 100644
+index 1592e1c..26df6c5 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
-@@ -1283,14 +1283,14 @@ do { \
+@@ -1285,14 +1285,14 @@ do { \
* operations, everything works on mask values.
*/
#define XMDIO_READ(_pdata, _mmd, _reg) \
@@ -65935,10 +65935,10 @@ index b3bc87f..5bdfdd3 100644
+ .wrapper_rx_desc_init = xgbe_wrapper_rx_descriptor_init,
+};
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
-index 1babcc1..aa7f8f4e 100644
+index ca106d4..36c4702 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
-@@ -2816,7 +2816,7 @@ static void xgbe_powerdown_rx(struct xgbe_prv_data *pdata)
+@@ -2818,7 +2818,7 @@ static void xgbe_powerdown_rx(struct xgbe_prv_data *pdata)
static int xgbe_init(struct xgbe_prv_data *pdata)
{
@@ -65947,7 +65947,7 @@ index 1babcc1..aa7f8f4e 100644
int ret;
DBGPR("-->xgbe_init\n");
-@@ -2882,107 +2882,102 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
+@@ -2884,107 +2884,102 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
return 0;
}
@@ -66133,7 +66133,7 @@ index 1babcc1..aa7f8f4e 100644
+ .set_rss_lookup_table = xgbe_set_rss_lookup_table,
+};
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
-index 7f9216d..26872f6 100644
+index 0f0f3014..882be95 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -245,7 +245,7 @@ static int xgbe_maybe_stop_tx_queue(struct xgbe_channel *channel,
@@ -66380,7 +66380,7 @@ index 7f9216d..26872f6 100644
struct xgbe_ring *ring = channel->rx_ring;
struct xgbe_ring_data *rdata;
-@@ -1794,8 +1794,8 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
+@@ -1812,8 +1812,8 @@ static unsigned int xgbe_rx_buf2_len(struct xgbe_ring_data *rdata,
static int xgbe_tx_poll(struct xgbe_channel *channel)
{
struct xgbe_prv_data *pdata = channel->pdata;
@@ -66391,7 +66391,7 @@ index 7f9216d..26872f6 100644
struct xgbe_ring *ring = channel->tx_ring;
struct xgbe_ring_data *rdata;
struct xgbe_ring_desc *rdesc;
-@@ -1865,7 +1865,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
+@@ -1883,7 +1883,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
{
struct xgbe_prv_data *pdata = channel->pdata;
@@ -68516,7 +68516,7 @@ index 75d07fa..d766d8e 100644
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
-index 0c9ef87..c10ec50 100644
+index 7a196a0..da60bf8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -1312,7 +1312,7 @@ static void remove_one(struct pci_dev *pdev)
@@ -70074,10 +70074,10 @@ index 51fc0c3..6cc1baa 100644
#define VIRTNET_DRIVER_VERSION "1.0.0"
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
-index bc744ac..2abf77e 100644
+index a2afb8e..6d66a2e 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
-@@ -1297,7 +1297,7 @@ static const struct nla_policy vrf_nl_policy[IFLA_VRF_MAX + 1] = {
+@@ -1299,7 +1299,7 @@ static const struct nla_policy vrf_nl_policy[IFLA_VRF_MAX + 1] = {
[IFLA_VRF_TABLE] = { .type = NLA_U32 },
};
@@ -70086,7 +70086,7 @@ index bc744ac..2abf77e 100644
.kind = DRV_NAME,
.priv_size = sizeof(struct net_vrf),
-@@ -1334,7 +1334,7 @@ static int vrf_device_event(struct notifier_block *unused,
+@@ -1336,7 +1336,7 @@ static int vrf_device_event(struct notifier_block *unused,
return NOTIFY_DONE;
}
@@ -86198,7 +86198,7 @@ index 479e223..ba82b75 100644
wake_up(&usb_kill_urb_queue);
usb_put_urb(urb);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index aef81a1..cf6b268 100644
+index c28ccf1..0f884ac 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
@@ -86220,6 +86220,19 @@ index aef81a1..cf6b268 100644
if (hub_is_superspeed(hub->hdev))
unit_load = 150;
else
+diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
+index 3a47077..5cf8b9c 100644
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -982,7 +982,7 @@ EXPORT_SYMBOL_GPL(usb_get_status);
+ * Return: Zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
+-int usb_clear_halt(struct usb_device *dev, int pipe)
++int usb_clear_halt(struct usb_device *dev, unsigned int pipe)
+ {
+ int result;
+ int endp = usb_pipeendpoint(pipe);
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index c953a0f..54c64f4 100644
--- a/drivers/usb/core/sysfs.c
@@ -86894,6 +86907,37 @@ index 8fae28b..8b4bfec 100644
/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
+diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c
+index 191b176..960b4ae 100644
+--- a/drivers/usb/usbip/stub_rx.c
++++ b/drivers/usb/usbip/stub_rx.c
+@@ -80,7 +80,7 @@ static int tweak_clear_halt_cmd(struct urb *urb)
+ struct usb_ctrlrequest *req;
+ int target_endp;
+ int target_dir;
+- int target_pipe;
++ unsigned int target_pipe;
+ int ret;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+@@ -336,7 +336,7 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
+ return priv;
+ }
+
+-static int get_pipe(struct stub_device *sdev, int epnum, int dir)
++static unsigned int get_pipe(struct stub_device *sdev, int epnum, int dir)
+ {
+ struct usb_device *udev = sdev->udev;
+ struct usb_host_endpoint *ep;
+@@ -447,7 +447,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
+ struct stub_priv *priv;
+ struct usbip_device *ud = &sdev->ud;
+ struct usb_device *udev = sdev->udev;
+- int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
++ unsigned int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
+
+ priv = stub_priv_alloc(sdev, pdu);
+ if (!priv)
diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h
index 88b71c4..31cc1ca6 100644
--- a/drivers/usb/usbip/vhci.h
@@ -87227,7 +87271,7 @@ index 9269d56..78d2a06 100644
};
EXPORT_SYMBOL_GPL(dummy_con);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
-index b87f5cf..6aad4f8 100644
+index 4db10d7..582743d 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -106,7 +106,7 @@ static int fbcon_softback_size = 32768;
@@ -107732,10 +107776,10 @@ index 42145be..1f1db90 100644
static ssize_t session_write_kbytes_show(struct ext4_attr *a,
struct ext4_sb_info *sbi, char *buf)
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
-index 4448ed3..523c675 100644
+index 3eeed8f..d68ad95 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
-@@ -414,7 +414,7 @@ static int
+@@ -409,7 +409,7 @@ static int
ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
char *buffer, size_t buffer_size)
{
@@ -107744,7 +107788,7 @@ index 4448ed3..523c675 100644
for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
const struct xattr_handler *handler =
-@@ -435,9 +435,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
+@@ -430,9 +430,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
*buffer++ = 0;
}
rest -= size;
@@ -136720,7 +136764,7 @@ index ede6b97..1f5b11f 100644
int xts_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
struct scatterlist *src, unsigned int nbytes,
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index 6726440..96d599d 100644
+index e9fb2e8..872cabe 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -61,6 +61,7 @@
@@ -136767,7 +136811,7 @@ index 6726440..96d599d 100644
/**
* Creates a driver or general drm_ioctl_desc array entry for the given
-@@ -713,7 +716,8 @@ struct drm_driver {
+@@ -714,7 +717,8 @@ struct drm_driver {
/* List of devices hanging off this driver with stealth attach. */
struct list_head legacy_dev_list;
@@ -136777,7 +136821,7 @@ index 6726440..96d599d 100644
enum drm_minor_type {
DRM_MINOR_PRIMARY,
-@@ -731,7 +735,8 @@ struct drm_info_list {
+@@ -732,7 +736,8 @@ struct drm_info_list {
int (*show)(struct seq_file*, void*); /** show callback */
u32 driver_features; /**< Required driver features for this entry */
void *data;
@@ -136787,7 +136831,7 @@ index 6726440..96d599d 100644
/**
* debugfs node structure. This structure represents a debugfs file.
-@@ -792,7 +797,7 @@ struct drm_device {
+@@ -793,7 +798,7 @@ struct drm_device {
/** \name Usage Counters */
/*@{ */
@@ -144884,7 +144928,7 @@ index 33383ca..44211d6 100644
static __always_inline void put_unaligned_le16(u16 val, void *p)
diff --git a/include/linux/usb.h b/include/linux/usb.h
-index eba1f10..94c966f 100644
+index eba1f10..eac1b52 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -370,7 +370,7 @@ struct usb_bus {
@@ -144905,6 +144949,15 @@ index eba1f10..94c966f 100644
unsigned long active_duration;
+@@ -1700,7 +1700,7 @@ extern int usb_string(struct usb_device *dev, int index,
+ char *buf, size_t size);
+
+ /* wrappers that also update important state inside usbcore */
+-extern int usb_clear_halt(struct usb_device *dev, int pipe);
++extern int usb_clear_halt(struct usb_device *dev, unsigned int pipe);
+ extern int usb_reset_configuration(struct usb_device *dev);
+ extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
+ extern void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr);
@@ -1793,10 +1793,10 @@ void usb_sg_wait(struct usb_sg_request *io);
/* NOTE: these are not the standard USB_ENDPOINT_XFER_* values!! */
@@ -144920,6 +144973,15 @@ index eba1f10..94c966f 100644
#define usb_pipein(pipe) ((pipe) & USB_DIR_IN)
#define usb_pipeout(pipe) (!usb_pipein(pipe))
+@@ -1845,7 +1845,7 @@ usb_pipe_endpoint(struct usb_device *dev, unsigned int pipe)
+ /*-------------------------------------------------------------------------*/
+
+ static inline __u16
+-usb_maxpacket(struct usb_device *udev, int pipe, int is_out)
++usb_maxpacket(struct usb_device *udev, unsigned int pipe, int is_out)
+ {
+ struct usb_host_endpoint *ep;
+ unsigned epnum = usb_pipeendpoint(pipe);
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 66fc137..9602956 100644
--- a/include/linux/usb/hcd.h
@@ -152684,7 +152746,7 @@ index 154fd68..f95f804 100644
(void *)current->task_state_change,
(void *)current->task_state_change);
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
-index 37e2449..61f57aa 100644
+index c95c512..16f39ee 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -219,8 +219,8 @@ static inline bool need_pull_dl_task(struct rq *rq, struct task_struct *prev)
@@ -152846,7 +152908,7 @@ index c242944..c6a1086 100644
struct rq *this_rq = this_rq();
enum cpu_idle_type idle = this_rq->idle_balance ?
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
-index 2516b8d..251b6ab 100644
+index f139f22..c040b45 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -362,8 +362,8 @@ static inline int has_pushable_tasks(struct rq *rq)
@@ -158185,7 +158247,7 @@ index 66ce6b4..c5f0a41 100644
err = -EPERM;
goto out;
diff --git a/mm/mlock.c b/mm/mlock.c
-index 665ab75..41833e6 100644
+index 665ab75..70e0033 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -14,6 +14,7 @@
@@ -158231,6 +158293,20 @@ index 665ab75..41833e6 100644
newflags |= flags;
/* Here we know that vma->vm_start <= nstart < vma->vm_end. */
+@@ -629,11 +639,11 @@ static int apply_vma_lock_flags(unsigned long start, size_t len,
+ * is also counted.
+ * Return value: previously mlocked page counts
+ */
+-static int count_mm_mlocked_page_nr(struct mm_struct *mm,
++static unsigned long count_mm_mlocked_page_nr(struct mm_struct *mm,
+ unsigned long start, size_t len)
+ {
+ struct vm_area_struct *vma;
+- int count = 0;
++ unsigned long count = 0;
+
+ if (mm == NULL)
+ mm = current->mm;
@@ -695,6 +705,10 @@ static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t fla
}
@@ -164507,7 +164583,7 @@ index f0f462c..e5d59e8 100644
}
diff --git a/net/core/sock.c b/net/core/sock.c
-index bc6543f..d9e3e41 100644
+index 470a204..f5adedf 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -411,13 +411,13 @@ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
@@ -164633,7 +164709,7 @@ index bc6543f..d9e3e41 100644
return -EFAULT;
lenout:
if (put_user(len, optlen))
-@@ -1517,7 +1520,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
+@@ -1522,7 +1525,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
newsk->sk_dst_cache = NULL;
newsk->sk_wmem_queued = 0;
newsk->sk_forward_alloc = 0;
@@ -164642,7 +164718,7 @@ index bc6543f..d9e3e41 100644
newsk->sk_send_head = NULL;
newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK;
-@@ -1547,7 +1550,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
+@@ -1558,7 +1561,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
newsk->sk_err_soft = 0;
newsk->sk_priority = 0;
newsk->sk_incoming_cpu = raw_smp_processor_id();
@@ -164651,7 +164727,7 @@ index bc6543f..d9e3e41 100644
mem_cgroup_sk_alloc(newsk);
cgroup_sk_alloc(&newsk->sk_cgrp_data);
-@@ -2477,7 +2480,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
+@@ -2488,7 +2491,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
*/
smp_wmb();
atomic_set(&sk->sk_refcnt, 1);
@@ -164660,7 +164736,7 @@ index bc6543f..d9e3e41 100644
}
EXPORT_SYMBOL(sock_init_data);
-@@ -2601,6 +2604,7 @@ void sock_enable_timestamp(struct sock *sk, int flag)
+@@ -2612,6 +2615,7 @@ void sock_enable_timestamp(struct sock *sk, int flag)
int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
int level, int type)
{
@@ -164668,7 +164744,7 @@ index bc6543f..d9e3e41 100644
struct sock_exterr_skb *serr;
struct sk_buff *skb;
int copied, err;
-@@ -2622,7 +2626,8 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
+@@ -2633,7 +2637,8 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
sock_recv_timestamp(msg, sk, skb);
serr = SKB_EXT_ERR(skb);
@@ -164678,7 +164754,7 @@ index bc6543f..d9e3e41 100644
msg->msg_flags |= MSG_ERRQUEUE;
err = copied;
-@@ -2885,8 +2890,9 @@ static int req_prot_init(const struct proto *prot)
+@@ -2891,8 +2896,9 @@ static int req_prot_init(const struct proto *prot)
int proto_register(struct proto *prot, int alloc_slab)
{
if (alloc_slab) {
@@ -164689,7 +164765,7 @@ index bc6543f..d9e3e41 100644
NULL);
if (prot->slab == NULL) {
-@@ -3074,7 +3080,7 @@ static __net_exit void proto_exit_net(struct net *net)
+@@ -3080,7 +3086,7 @@ static __net_exit void proto_exit_net(struct net *net)
}
@@ -165264,10 +165340,10 @@ index 062a67c..cb05c97 100644
.exit = devinet_exit_net,
};
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
-index 5b03d7f..6c62eaf 100644
+index 6789e48..d779c45 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
-@@ -1140,12 +1140,12 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
+@@ -1141,12 +1141,12 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
#ifdef CONFIG_IP_ROUTE_MULTIPATH
fib_sync_up(dev, RTNH_F_DEAD);
#endif
@@ -165282,7 +165358,7 @@ index 5b03d7f..6c62eaf 100644
if (!ifa->ifa_dev->ifa_list) {
/* Last address was deleted from this interface.
* Disable IP.
-@@ -1185,7 +1185,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
+@@ -1186,7 +1186,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
#ifdef CONFIG_IP_ROUTE_MULTIPATH
fib_sync_up(dev, RTNH_F_DEAD);
#endif
@@ -166119,7 +166195,7 @@ index 80bc36b..d70d622 100644
.exit = ipv4_sysctl_exit_net,
};
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index ce42ded..9c93e33 100644
+index 7727ffe..9488999 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -288,11 +288,13 @@ static void tcp_ecn_rcv_synack(struct tcp_sock *tp, const struct tcphdr *th)
@@ -166270,7 +166346,7 @@ index bf1f3b2..83f355d 100644
.exit = tcp_net_metrics_exit,
};
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
-index 6234eba..8007145 100644
+index 8615a6b..772fcdb 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -27,6 +27,10 @@
@@ -166284,7 +166360,7 @@ index 6234eba..8007145 100644
int sysctl_tcp_abort_on_overflow __read_mostly;
struct inet_timewait_death_row tcp_death_row = {
-@@ -786,7 +790,10 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
+@@ -787,7 +791,10 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
* avoid becoming vulnerable to outside attack aiming at
* resetting legit local connections.
*/
@@ -167308,7 +167384,7 @@ index b2e61a0..bf47484 100644
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
-index e4a8000..ae30c92 100644
+index 40a289f..c8715aa 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -78,6 +78,10 @@ static u32 udp6_ehashfn(const struct net *net,
@@ -172274,7 +172350,7 @@ index 0917f04..f4e3d8c 100644
if (!proc_create("x25/route", S_IRUGO, init_net.proc_net,
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
-index 5bf7e1bf..5ef3f83 100644
+index e0437a7..05fba66 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -338,7 +338,7 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
@@ -172501,10 +172577,10 @@ index 35a7e79..35847ab 100644
__xfrm_sysctl_init(net);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
-index 671a1d0..1b8c39e 100644
+index a7e27e1..0040091 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
-@@ -2471,7 +2471,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+@@ -2478,7 +2478,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EINVAL;
{
@@ -224530,7 +224606,7 @@ index cd0e0eb..89543da 100644
}
}
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
-index 4c93520..e4032f9 100644
+index f3b1d7f..6645b81 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -403,7 +403,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
@@ -224568,7 +224644,7 @@ index 4c93520..e4032f9 100644
}
#endif
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
-index 86240d0..08b468d 100644
+index 3f4efcb..da7bb45 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -50,7 +50,7 @@ struct snd_seq_fifo *snd_seq_fifo_new(int poolsize)
@@ -224580,7 +224656,7 @@ index 86240d0..08b468d 100644
f->head = NULL;
f->tail = NULL;
-@@ -96,7 +96,7 @@ void snd_seq_fifo_clear(struct snd_seq_fifo *f)
+@@ -99,7 +99,7 @@ void snd_seq_fifo_clear(struct snd_seq_fifo *f)
unsigned long flags;
/* clear overflow flag */
@@ -224589,7 +224665,7 @@ index 86240d0..08b468d 100644
snd_use_lock_sync(&f->use_lock);
spin_lock_irqsave(&f->lock, flags);
-@@ -123,7 +123,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
+@@ -126,7 +126,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */
if (err < 0) {
if ((err == -ENOMEM) || (err == -EAGAIN))
@@ -224612,7 +224688,7 @@ index 062c446..a4b6f4c 100644
};
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
-index dfa5156..05c2b75 100644
+index 5847c44..cfec4ed 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -87,7 +87,7 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event,
diff --git a/4.9.18/4425_grsec_remove_EI_PAX.patch b/4.9.20/4425_grsec_remove_EI_PAX.patch
index 594598a..594598a 100644
--- a/4.9.18/4425_grsec_remove_EI_PAX.patch
+++ b/4.9.20/4425_grsec_remove_EI_PAX.patch
diff --git a/4.9.18/4426_default_XATTR_PAX_FLAGS.patch b/4.9.20/4426_default_XATTR_PAX_FLAGS.patch
index f7e97b5..f7e97b5 100644
--- a/4.9.18/4426_default_XATTR_PAX_FLAGS.patch
+++ b/4.9.20/4426_default_XATTR_PAX_FLAGS.patch
diff --git a/4.9.18/4427_force_XATTR_PAX_tmpfs.patch b/4.9.20/4427_force_XATTR_PAX_tmpfs.patch
index 3871139..3871139 100644
--- a/4.9.18/4427_force_XATTR_PAX_tmpfs.patch
+++ b/4.9.20/4427_force_XATTR_PAX_tmpfs.patch
diff --git a/4.9.18/4430_grsec-remove-localversion-grsec.patch b/4.9.20/4430_grsec-remove-localversion-grsec.patch
index 31cf878..31cf878 100644
--- a/4.9.18/4430_grsec-remove-localversion-grsec.patch
+++ b/4.9.20/4430_grsec-remove-localversion-grsec.patch
diff --git a/4.9.18/4435_grsec-mute-warnings.patch b/4.9.20/4435_grsec-mute-warnings.patch
index 8929222..8929222 100644
--- a/4.9.18/4435_grsec-mute-warnings.patch
+++ b/4.9.20/4435_grsec-mute-warnings.patch
diff --git a/4.9.18/4440_grsec-remove-protected-paths.patch b/4.9.20/4440_grsec-remove-protected-paths.patch
index 741546d..741546d 100644
--- a/4.9.18/4440_grsec-remove-protected-paths.patch
+++ b/4.9.20/4440_grsec-remove-protected-paths.patch
diff --git a/4.9.18/4450_grsec-kconfig-default-gids.patch b/4.9.20/4450_grsec-kconfig-default-gids.patch
index cee6e27..cee6e27 100644
--- a/4.9.18/4450_grsec-kconfig-default-gids.patch
+++ b/4.9.20/4450_grsec-kconfig-default-gids.patch
diff --git a/4.9.18/4465_selinux-avc_audit-log-curr_ip.patch b/4.9.20/4465_selinux-avc_audit-log-curr_ip.patch
index 06a5294..06a5294 100644
--- a/4.9.18/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/4.9.20/4465_selinux-avc_audit-log-curr_ip.patch
diff --git a/4.9.18/4470_disable-compat_vdso.patch b/4.9.20/4470_disable-compat_vdso.patch
index a1401d8..a1401d8 100644
--- a/4.9.18/4470_disable-compat_vdso.patch
+++ b/4.9.20/4470_disable-compat_vdso.patch
diff --git a/4.9.18/4475_emutramp_default_on.patch b/4.9.20/4475_emutramp_default_on.patch
index feb8c7b..feb8c7b 100644
--- a/4.9.18/4475_emutramp_default_on.patch
+++ b/4.9.20/4475_emutramp_default_on.patch