diff options
author | 2017-04-01 19:40:12 -0400 | |
---|---|---|
committer | 2017-04-01 19:40:12 -0400 | |
commit | b897bcf385333e0aaa97084370db28c16dc589f4 (patch) | |
tree | 603a21bf6485d0ebd9d7216bf3e921f9c1f3a363 | |
parent | grsecurity-3.1-4.9.18-201703261106 (diff) | |
download | hardened-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.patch | 6091 | ||||
-rw-r--r-- | 4.9.18/1017_linux-4.9.18.patch | 876 | ||||
-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(¤t->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, ¤t->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, ¤t->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, -- ¤t->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, -- ¤t->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, ®ion, 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, ®ion, 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, ®ion, 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(¤t->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(¤t->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(¤t->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(¤t->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(¶m, (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 = ®s[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 |