diff options
author | Mike Pagano <mpagano@gentoo.org> | 2018-03-21 10:41:38 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2018-03-21 10:41:38 -0400 |
commit | 132266687094fdbd0edd1e77a757165d29b8a673 (patch) | |
tree | 26cdd61b45423a662ac24e98d98841eb1ad60674 | |
parent | Linux patch 4.14.28 (diff) | |
download | linux-patches-132266687094fdbd0edd1e77a757165d29b8a673.tar.gz linux-patches-132266687094fdbd0edd1e77a757165d29b8a673.tar.bz2 linux-patches-132266687094fdbd0edd1e77a757165d29b8a673.zip |
Linux patch 4.14.294.14-34
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1028_linux-4.14.29.patch | 1579 |
2 files changed, 1583 insertions, 0 deletions
diff --git a/0000_README b/0000_README index a239cba6..aaa36a22 100644 --- a/0000_README +++ b/0000_README @@ -155,6 +155,10 @@ Patch: 1027_linux-4.14.28.patch From: http://www.kernel.org Desc: Linux 4.14.28 +Patch: 1028_linux-4.14.29.patch +From: http://www.kernel.org +Desc: Linux 4.14.29 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1028_linux-4.14.29.patch b/1028_linux-4.14.29.patch new file mode 100644 index 00000000..8122364e --- /dev/null +++ b/1028_linux-4.14.29.patch @@ -0,0 +1,1579 @@ +diff --git a/Makefile b/Makefile +index 9ae370a47ff9..4b2aa0dd4043 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 14 +-SUBLEVEL = 28 ++SUBLEVEL = 29 + EXTRAVERSION = + NAME = Petit Gorille + +diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c +index 79089778725b..e3b45546d589 100644 +--- a/arch/parisc/kernel/cache.c ++++ b/arch/parisc/kernel/cache.c +@@ -543,7 +543,8 @@ void flush_cache_mm(struct mm_struct *mm) + rp3440, etc. So, avoid it if the mm isn't too big. */ + if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && + mm_total_size(mm) >= parisc_cache_flush_threshold) { +- flush_tlb_all(); ++ if (mm->context) ++ flush_tlb_all(); + flush_cache_all(); + return; + } +@@ -571,6 +572,8 @@ void flush_cache_mm(struct mm_struct *mm) + pfn = pte_pfn(*ptep); + if (!pfn_valid(pfn)) + continue; ++ if (unlikely(mm->context)) ++ flush_tlb_page(vma, addr); + __flush_cache_page(vma, addr, PFN_PHYS(pfn)); + } + } +@@ -579,26 +582,46 @@ void flush_cache_mm(struct mm_struct *mm) + void flush_cache_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) + { ++ pgd_t *pgd; ++ unsigned long addr; ++ + if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && + end - start >= parisc_cache_flush_threshold) { +- flush_tlb_range(vma, start, end); ++ if (vma->vm_mm->context) ++ flush_tlb_range(vma, start, end); + flush_cache_all(); + return; + } + +- flush_user_dcache_range_asm(start, end); +- if (vma->vm_flags & VM_EXEC) +- flush_user_icache_range_asm(start, end); +- flush_tlb_range(vma, start, end); ++ if (vma->vm_mm->context == mfsp(3)) { ++ flush_user_dcache_range_asm(start, end); ++ if (vma->vm_flags & VM_EXEC) ++ flush_user_icache_range_asm(start, end); ++ flush_tlb_range(vma, start, end); ++ return; ++ } ++ ++ pgd = vma->vm_mm->pgd; ++ for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { ++ unsigned long pfn; ++ pte_t *ptep = get_ptep(pgd, addr); ++ if (!ptep) ++ continue; ++ pfn = pte_pfn(*ptep); ++ if (pfn_valid(pfn)) { ++ if (unlikely(vma->vm_mm->context)) ++ flush_tlb_page(vma, addr); ++ __flush_cache_page(vma, addr, PFN_PHYS(pfn)); ++ } ++ } + } + + void + flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) + { +- BUG_ON(!vma->vm_mm->context); +- + if (pfn_valid(pfn)) { +- flush_tlb_page(vma, vmaddr); ++ if (likely(vma->vm_mm->context)) ++ flush_tlb_page(vma, vmaddr); + __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); + } + } +diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h +index 66c14347c502..23a65439c37c 100644 +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -314,6 +314,7 @@ + #define X86_FEATURE_VPCLMULQDQ (16*32+10) /* Carry-Less Multiplication Double Quadword */ + #define X86_FEATURE_AVX512_VNNI (16*32+11) /* Vector Neural Network Instructions */ + #define X86_FEATURE_AVX512_BITALG (16*32+12) /* Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */ ++#define X86_FEATURE_TME (16*32+13) /* Intel Total Memory Encryption */ + #define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */ + #define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */ + #define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */ +@@ -326,6 +327,7 @@ + /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */ + #define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ + #define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ ++#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ + #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ + #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ + #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ +diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h +index d0dabeae0505..f928ad9b143f 100644 +--- a/arch/x86/include/asm/nospec-branch.h ++++ b/arch/x86/include/asm/nospec-branch.h +@@ -183,7 +183,10 @@ + * otherwise we'll run out of registers. We don't care about CET + * here, anyway. + */ +-# define CALL_NOSPEC ALTERNATIVE("call *%[thunk_target]\n", \ ++# define CALL_NOSPEC \ ++ ALTERNATIVE( \ ++ ANNOTATE_RETPOLINE_SAFE \ ++ "call *%[thunk_target]\n", \ + " jmp 904f;\n" \ + " .align 16\n" \ + "901: call 903f;\n" \ +diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c +index 4aa9fd379390..c3af167d0a70 100644 +--- a/arch/x86/kernel/cpu/intel.c ++++ b/arch/x86/kernel/cpu/intel.c +@@ -105,7 +105,7 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c) + /* + * Early microcode releases for the Spectre v2 mitigation were broken. + * Information taken from; +- * - https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/microcode-update-guidance.pdf ++ * - https://newsroom.intel.com/wp-content/uploads/sites/11/2018/03/microcode-update-guidance.pdf + * - https://kb.vmware.com/s/article/52345 + * - Microcode revisions observed in the wild + * - Release note from 20180108 microcode release +@@ -123,7 +123,6 @@ static const struct sku_microcode spectre_bad_microcodes[] = { + { INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x80 }, + { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, + { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, +- { INTEL_FAM6_SKYLAKE_DESKTOP, 0x03, 0xc2 }, + { INTEL_FAM6_BROADWELL_CORE, 0x04, 0x28 }, + { INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b }, + { INTEL_FAM6_BROADWELL_XEON_D, 0x02, 0x14 }, +diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c +index 5edb27f1a2c4..9d0b5af7db91 100644 +--- a/arch/x86/kernel/vm86_32.c ++++ b/arch/x86/kernel/vm86_32.c +@@ -727,7 +727,8 @@ void handle_vm86_fault(struct kernel_vm86_regs *regs, long error_code) + return; + + check_vip: +- if (VEFLAGS & X86_EFLAGS_VIP) { ++ if ((VEFLAGS & (X86_EFLAGS_VIP | X86_EFLAGS_VIF)) == ++ (X86_EFLAGS_VIP | X86_EFLAGS_VIF)) { + save_v86_state(regs, VM86_STI); + return; + } +diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c +index 2b6f8a4f2731..f438e0c4aa8c 100644 +--- a/arch/x86/kvm/mmu.c ++++ b/arch/x86/kvm/mmu.c +@@ -2758,8 +2758,10 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, + else + pte_access &= ~ACC_WRITE_MASK; + ++ if (!kvm_is_mmio_pfn(pfn)) ++ spte |= shadow_me_mask; ++ + spte |= (u64)pfn << PAGE_SHIFT; +- spte |= shadow_me_mask; + + if (pte_access & ACC_WRITE_MASK) { + +diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c +index 4c155ee0f89e..0133d26f16be 100644 +--- a/arch/x86/mm/fault.c ++++ b/arch/x86/mm/fault.c +@@ -330,7 +330,7 @@ static noinline int vmalloc_fault(unsigned long address) + if (!pmd_k) + return -1; + +- if (pmd_huge(*pmd_k)) ++ if (pmd_large(*pmd_k)) + return 0; + + pte_k = pte_offset_kernel(pmd_k, address); +@@ -479,7 +479,7 @@ static noinline int vmalloc_fault(unsigned long address) + if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref)) + BUG(); + +- if (pud_huge(*pud)) ++ if (pud_large(*pud)) + return 0; + + pmd = pmd_offset(pud, address); +@@ -490,7 +490,7 @@ static noinline int vmalloc_fault(unsigned long address) + if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref)) + BUG(); + +- if (pmd_huge(*pmd)) ++ if (pmd_large(*pmd)) + return 0; + + pte_ref = pte_offset_kernel(pmd_ref, address); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +index 848242821ef3..1eff36a87595 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +@@ -69,25 +69,18 @@ void amdgpu_connector_hotplug(struct drm_connector *connector) + /* don't do anything if sink is not display port, i.e., + * passive dp->(dvi|hdmi) adaptor + */ +- if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { +- int saved_dpms = connector->dpms; +- /* Only turn off the display if it's physically disconnected */ +- if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) { +- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); +- } else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) { +- /* Don't try to start link training before we +- * have the dpcd */ +- if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector)) +- return; +- +- /* set it to OFF so that drm_helper_connector_dpms() +- * won't return immediately since the current state +- * is ON at this point. +- */ +- connector->dpms = DRM_MODE_DPMS_OFF; +- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); +- } +- connector->dpms = saved_dpms; ++ if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT && ++ amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd) && ++ amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) { ++ /* Don't start link training before we have the DPCD */ ++ if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector)) ++ return; ++ ++ /* Turn the connector off and back on immediately, which ++ * will trigger link training ++ */ ++ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); ++ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); + } + } + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +index 7171968f261e..837332e84d78 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +@@ -36,8 +36,6 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj) + struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj); + + if (robj) { +- if (robj->gem_base.import_attach) +- drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); + amdgpu_mn_unregister(robj); + amdgpu_bo_unref(&robj); + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +index ffe483980362..4d08957d2108 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +@@ -46,6 +46,8 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) + + amdgpu_bo_kunmap(bo); + ++ if (bo->gem_base.import_attach) ++ drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg); + drm_gem_object_release(&bo->gem_base); + amdgpu_bo_unref(&bo->parent); + if (!list_empty(&bo->shadow_list)) { +diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c +index 380f340204e8..f56f60f695e1 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c ++++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c +@@ -268,13 +268,13 @@ nouveau_backlight_init(struct drm_device *dev) + struct nvif_device *device = &drm->client.device; + struct drm_connector *connector; + ++ INIT_LIST_HEAD(&drm->bl_connectors); ++ + if (apple_gmux_present()) { + NV_INFO(drm, "Apple GMUX detected: not registering Nouveau backlight interface\n"); + return 0; + } + +- INIT_LIST_HEAD(&drm->bl_connectors); +- + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && + connector->connector_type != DRM_MODE_CONNECTOR_eDP) +diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c +index 3386452bd2f0..ac467b80edc7 100644 +--- a/drivers/gpu/drm/radeon/radeon_gem.c ++++ b/drivers/gpu/drm/radeon/radeon_gem.c +@@ -34,8 +34,6 @@ void radeon_gem_object_free(struct drm_gem_object *gobj) + struct radeon_bo *robj = gem_to_radeon_bo(gobj); + + if (robj) { +- if (robj->gem_base.import_attach) +- drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); + radeon_mn_unregister(robj); + radeon_bo_unref(&robj); + } +diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c +index 093594976126..baadb706c276 100644 +--- a/drivers/gpu/drm/radeon/radeon_object.c ++++ b/drivers/gpu/drm/radeon/radeon_object.c +@@ -82,6 +82,8 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo) + mutex_unlock(&bo->rdev->gem.mutex); + radeon_bo_clear_surface_reg(bo); + WARN_ON_ONCE(!list_empty(&bo->va)); ++ if (bo->gem_base.import_attach) ++ drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg); + drm_gem_object_release(&bo->gem_base); + kfree(bo); + } +diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c +index 42713511b53b..524e6134642e 100644 +--- a/drivers/infiniband/sw/rdmavt/mr.c ++++ b/drivers/infiniband/sw/rdmavt/mr.c +@@ -489,11 +489,13 @@ static int rvt_check_refs(struct rvt_mregion *mr, const char *t) + unsigned long timeout; + struct rvt_dev_info *rdi = ib_to_rvt(mr->pd->device); + +- if (percpu_ref_is_zero(&mr->refcount)) +- return 0; +- /* avoid dma mr */ +- if (mr->lkey) ++ if (mr->lkey) { ++ /* avoid dma mr */ + rvt_dereg_clean_qps(mr); ++ /* @mr was indexed on rcu protected @lkey_table */ ++ synchronize_rcu(); ++ } ++ + timeout = wait_for_completion_timeout(&mr->comp, 5 * HZ); + if (!timeout) { + rvt_pr_err(rdi, +diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index e88395605e32..af57f8473a88 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -1310,7 +1310,7 @@ static struct irq_chip its_irq_chip = { + * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations. + */ + #define IRQS_PER_CHUNK_SHIFT 5 +-#define IRQS_PER_CHUNK (1 << IRQS_PER_CHUNK_SHIFT) ++#define IRQS_PER_CHUNK (1UL << IRQS_PER_CHUNK_SHIFT) + #define ITS_MAX_LPI_NRBITS 16 /* 64K LPIs */ + + static unsigned long *lpi_bitmap; +@@ -2026,11 +2026,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + /* +- * At least one bit of EventID is being used, hence a minimum +- * of two entries. No, the architecture doesn't let you +- * express an ITT with a single entry. ++ * We allocate at least one chunk worth of LPIs bet device, ++ * and thus that many ITEs. The device may require less though. + */ +- nr_ites = max(2UL, roundup_pow_of_two(nvecs)); ++ nr_ites = max(IRQS_PER_CHUNK, roundup_pow_of_two(nvecs)); + sz = nr_ites * its->ite_size; + sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; + itt = kzalloc(sz, GFP_KERNEL); +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index 9603886737b5..2300c02ab5e6 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -102,11 +102,16 @@ qla2x00_async_iocb_timeout(void *data) + struct srb_iocb *lio = &sp->u.iocb_cmd; + struct event_arg ea; + +- ql_dbg(ql_dbg_disc, fcport->vha, 0x2071, +- "Async-%s timeout - hdl=%x portid=%06x %8phC.\n", +- sp->name, sp->handle, fcport->d_id.b24, fcport->port_name); ++ if (fcport) { ++ ql_dbg(ql_dbg_disc, fcport->vha, 0x2071, ++ "Async-%s timeout - hdl=%x portid=%06x %8phC.\n", ++ sp->name, sp->handle, fcport->d_id.b24, fcport->port_name); + +- fcport->flags &= ~FCF_ASYNC_SENT; ++ fcport->flags &= ~FCF_ASYNC_SENT; ++ } else { ++ pr_info("Async-%s timeout - hdl=%x.\n", ++ sp->name, sp->handle); ++ } + + switch (sp->type) { + case SRB_LOGIN_CMD: +diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c +index 78df7cfca568..d77dde89118e 100644 +--- a/drivers/scsi/qla2xxx/qla_mid.c ++++ b/drivers/scsi/qla2xxx/qla_mid.c +@@ -582,8 +582,9 @@ qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req) + ret = qla25xx_init_req_que(vha, req); + if (ret != QLA_SUCCESS) + return QLA_FUNCTION_FAILED; ++ ++ qla25xx_free_req_que(vha, req); + } +- qla25xx_free_req_que(vha, req); + + return ret; + } +@@ -598,8 +599,9 @@ qla25xx_delete_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) + ret = qla25xx_init_rsp_que(vha, rsp); + if (ret != QLA_SUCCESS) + return QLA_FUNCTION_FAILED; ++ ++ qla25xx_free_rsp_que(vha, rsp); + } +- qla25xx_free_rsp_que(vha, rsp); + + return ret; + } +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index cfe7654f6bd3..1e17175692d3 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -442,7 +442,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, + ha->req_q_map[0] = req; + set_bit(0, ha->rsp_qid_map); + set_bit(0, ha->req_qid_map); +- return 1; ++ return 0; + + fail_qpair_map: + kfree(ha->base_qpair); +@@ -459,6 +459,9 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, + + static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req) + { ++ if (!ha->req_q_map) ++ return; ++ + if (IS_QLAFX00(ha)) { + if (req && req->ring_fx00) + dma_free_coherent(&ha->pdev->dev, +@@ -469,14 +472,17 @@ static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req) + (req->length + 1) * sizeof(request_t), + req->ring, req->dma); + +- if (req) ++ if (req) { + kfree(req->outstanding_cmds); +- +- kfree(req); ++ kfree(req); ++ } + } + + static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp) + { ++ if (!ha->rsp_q_map) ++ return; ++ + if (IS_QLAFX00(ha)) { + if (rsp && rsp->ring) + dma_free_coherent(&ha->pdev->dev, +@@ -487,7 +493,8 @@ static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp) + (rsp->length + 1) * sizeof(response_t), + rsp->ring, rsp->dma); + } +- kfree(rsp); ++ if (rsp) ++ kfree(rsp); + } + + static void qla2x00_free_queues(struct qla_hw_data *ha) +@@ -1710,6 +1717,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) + struct qla_tgt_cmd *cmd; + uint8_t trace = 0; + ++ if (!ha->req_q_map) ++ return; + spin_lock_irqsave(&ha->hardware_lock, flags); + for (que = 0; que < ha->max_req_queues; que++) { + req = ha->req_q_map[que]; +@@ -3063,14 +3072,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) + /* Set up the irqs */ + ret = qla2x00_request_irqs(ha, rsp); + if (ret) +- goto probe_hw_failed; ++ goto probe_failed; + + /* Alloc arrays of request and response ring ptrs */ +- if (!qla2x00_alloc_queues(ha, req, rsp)) { ++ if (qla2x00_alloc_queues(ha, req, rsp)) { + ql_log(ql_log_fatal, base_vha, 0x003d, + "Failed to allocate memory for queue pointers..." + "aborting.\n"); +- goto probe_init_failed; ++ goto probe_failed; + } + + if (ha->mqenable && shost_use_blk_mq(host)) { +@@ -3347,15 +3356,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) + + return 0; + +-probe_init_failed: +- qla2x00_free_req_que(ha, req); +- ha->req_q_map[0] = NULL; +- clear_bit(0, ha->req_qid_map); +- qla2x00_free_rsp_que(ha, rsp); +- ha->rsp_q_map[0] = NULL; +- clear_bit(0, ha->rsp_qid_map); +- ha->max_req_queues = ha->max_rsp_queues = 0; +- + probe_failed: + if (base_vha->timer_active) + qla2x00_stop_timer(base_vha); +@@ -4435,11 +4435,17 @@ qla2x00_mem_free(struct qla_hw_data *ha) + if (ha->init_cb) + dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, + ha->init_cb, ha->init_cb_dma); +- vfree(ha->optrom_buffer); +- kfree(ha->nvram); +- kfree(ha->npiv_info); +- kfree(ha->swl); +- kfree(ha->loop_id_map); ++ ++ if (ha->optrom_buffer) ++ vfree(ha->optrom_buffer); ++ if (ha->nvram) ++ kfree(ha->nvram); ++ if (ha->npiv_info) ++ kfree(ha->npiv_info); ++ if (ha->swl) ++ kfree(ha->swl); ++ if (ha->loop_id_map) ++ kfree(ha->loop_id_map); + + ha->srb_mempool = NULL; + ha->ctx_mempool = NULL; +@@ -4455,6 +4461,15 @@ qla2x00_mem_free(struct qla_hw_data *ha) + ha->ex_init_cb_dma = 0; + ha->async_pd = NULL; + ha->async_pd_dma = 0; ++ ha->loop_id_map = NULL; ++ ha->npiv_info = NULL; ++ ha->optrom_buffer = NULL; ++ ha->swl = NULL; ++ ha->nvram = NULL; ++ ha->mctp_dump = NULL; ++ ha->dcbx_tlv = NULL; ++ ha->xgmac_data = NULL; ++ ha->sfp_data = NULL; + + ha->s_dma_pool = NULL; + ha->dl_dma_pool = NULL; +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index 040a76011ffa..d6fe08de59a0 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -971,6 +971,7 @@ static void qlt_free_session_done(struct work_struct *work) + + logo.id = sess->d_id; + logo.cmd_count = 0; ++ sess->send_els_logo = 0; + qlt_send_first_logo(vha, &logo); + } + +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index ea910acb4bb0..fc28819253f7 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -166,13 +166,15 @@ + #define DWC3_GDBGFIFOSPACE_TYPE(n) (((n) << 5) & 0x1e0) + #define DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(n) (((n) >> 16) & 0xffff) + +-#define DWC3_TXFIFOQ 1 +-#define DWC3_RXFIFOQ 3 +-#define DWC3_TXREQQ 5 +-#define DWC3_RXREQQ 7 +-#define DWC3_RXINFOQ 9 +-#define DWC3_DESCFETCHQ 13 +-#define DWC3_EVENTQ 15 ++#define DWC3_TXFIFOQ 0 ++#define DWC3_RXFIFOQ 1 ++#define DWC3_TXREQQ 2 ++#define DWC3_RXREQQ 3 ++#define DWC3_RXINFOQ 4 ++#define DWC3_PSTATQ 5 ++#define DWC3_DESCFETCHQ 6 ++#define DWC3_EVENTQ 7 ++#define DWC3_AUXEVENTQ 8 + + /* Global RX Threshold Configuration Register */ + #define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19) +diff --git a/drivers/usb/gadget/udc/bdc/bdc_pci.c b/drivers/usb/gadget/udc/bdc/bdc_pci.c +index 02968842b359..708e36f530d8 100644 +--- a/drivers/usb/gadget/udc/bdc/bdc_pci.c ++++ b/drivers/usb/gadget/udc/bdc/bdc_pci.c +@@ -82,6 +82,7 @@ static int bdc_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) + if (ret) { + dev_err(&pci->dev, + "couldn't add resources to bdc device\n"); ++ platform_device_put(bdc); + return ret; + } + +diff --git a/fs/aio.c b/fs/aio.c +index 5a2487217072..c3ace7833a03 100644 +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -68,9 +68,9 @@ struct aio_ring { + #define AIO_RING_PAGES 8 + + struct kioctx_table { +- struct rcu_head rcu; +- unsigned nr; +- struct kioctx *table[]; ++ struct rcu_head rcu; ++ unsigned nr; ++ struct kioctx __rcu *table[]; + }; + + struct kioctx_cpu { +@@ -115,7 +115,8 @@ struct kioctx { + struct page **ring_pages; + long nr_pages; + +- struct work_struct free_work; ++ struct rcu_head free_rcu; ++ struct work_struct free_work; /* see free_ioctx() */ + + /* + * signals when all in-flight requests are done +@@ -329,7 +330,7 @@ static int aio_ring_mremap(struct vm_area_struct *vma) + for (i = 0; i < table->nr; i++) { + struct kioctx *ctx; + +- ctx = table->table[i]; ++ ctx = rcu_dereference(table->table[i]); + if (ctx && ctx->aio_ring_file == file) { + if (!atomic_read(&ctx->dead)) { + ctx->user_id = ctx->mmap_base = vma->vm_start; +@@ -588,6 +589,12 @@ static int kiocb_cancel(struct aio_kiocb *kiocb) + return cancel(&kiocb->common); + } + ++/* ++ * free_ioctx() should be RCU delayed to synchronize against the RCU ++ * protected lookup_ioctx() and also needs process context to call ++ * aio_free_ring(), so the double bouncing through kioctx->free_rcu and ++ * ->free_work. ++ */ + static void free_ioctx(struct work_struct *work) + { + struct kioctx *ctx = container_of(work, struct kioctx, free_work); +@@ -601,6 +608,14 @@ static void free_ioctx(struct work_struct *work) + kmem_cache_free(kioctx_cachep, ctx); + } + ++static void free_ioctx_rcufn(struct rcu_head *head) ++{ ++ struct kioctx *ctx = container_of(head, struct kioctx, free_rcu); ++ ++ INIT_WORK(&ctx->free_work, free_ioctx); ++ schedule_work(&ctx->free_work); ++} ++ + static void free_ioctx_reqs(struct percpu_ref *ref) + { + struct kioctx *ctx = container_of(ref, struct kioctx, reqs); +@@ -609,8 +624,8 @@ static void free_ioctx_reqs(struct percpu_ref *ref) + if (ctx->rq_wait && atomic_dec_and_test(&ctx->rq_wait->count)) + complete(&ctx->rq_wait->comp); + +- INIT_WORK(&ctx->free_work, free_ioctx); +- schedule_work(&ctx->free_work); ++ /* Synchronize against RCU protected table->table[] dereferences */ ++ call_rcu(&ctx->free_rcu, free_ioctx_rcufn); + } + + /* +@@ -651,9 +666,9 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm) + while (1) { + if (table) + for (i = 0; i < table->nr; i++) +- if (!table->table[i]) { ++ if (!rcu_access_pointer(table->table[i])) { + ctx->id = i; +- table->table[i] = ctx; ++ rcu_assign_pointer(table->table[i], ctx); + spin_unlock(&mm->ioctx_lock); + + /* While kioctx setup is in progress, +@@ -834,11 +849,11 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx, + } + + table = rcu_dereference_raw(mm->ioctx_table); +- WARN_ON(ctx != table->table[ctx->id]); +- table->table[ctx->id] = NULL; ++ WARN_ON(ctx != rcu_access_pointer(table->table[ctx->id])); ++ RCU_INIT_POINTER(table->table[ctx->id], NULL); + spin_unlock(&mm->ioctx_lock); + +- /* percpu_ref_kill() will do the necessary call_rcu() */ ++ /* free_ioctx_reqs() will do the necessary RCU synchronization */ + wake_up_all(&ctx->wait); + + /* +@@ -880,7 +895,8 @@ void exit_aio(struct mm_struct *mm) + + skipped = 0; + for (i = 0; i < table->nr; ++i) { +- struct kioctx *ctx = table->table[i]; ++ struct kioctx *ctx = ++ rcu_dereference_protected(table->table[i], true); + + if (!ctx) { + skipped++; +@@ -1069,7 +1085,7 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id) + if (!table || id >= table->nr) + goto out; + +- ctx = table->table[id]; ++ ctx = rcu_dereference(table->table[id]); + if (ctx && ctx->user_id == ctx_id) { + percpu_ref_get(&ctx->users); + ret = ctx; +diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c +index b517ef1477ea..0531cb9a3ba9 100644 +--- a/fs/btrfs/backref.c ++++ b/fs/btrfs/backref.c +@@ -1252,7 +1252,16 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, + while (node) { + ref = rb_entry(node, struct prelim_ref, rbnode); + node = rb_next(&ref->rbnode); +- WARN_ON(ref->count < 0); ++ /* ++ * ref->count < 0 can happen here if there are delayed ++ * refs with a node->action of BTRFS_DROP_DELAYED_REF. ++ * prelim_ref_insert() relies on this when merging ++ * identical refs to keep the overall count correct. ++ * prelim_ref_insert() will merge only those refs ++ * which compare identically. Any refs having ++ * e.g. different offsets would not be merged, ++ * and would retain their original ref->count < 0. ++ */ + if (roots && ref->count && ref->root_id && ref->parent == 0) { + if (sc && sc->root_objectid && + ref->root_id != sc->root_objectid) { +@@ -1496,6 +1505,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr) + if (!node) + break; + bytenr = node->val; ++ shared.share_count = 0; + cond_resched(); + } + +diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c +index 6154825c30e1..32b186c5694c 100644 +--- a/fs/btrfs/raid56.c ++++ b/fs/btrfs/raid56.c +@@ -1348,6 +1348,7 @@ static int find_bio_stripe(struct btrfs_raid_bio *rbio, + stripe_start = stripe->physical; + if (physical >= stripe_start && + physical < stripe_start + rbio->stripe_len && ++ stripe->dev->bdev && + bio->bi_disk == stripe->dev->bdev->bd_disk && + bio->bi_partno == stripe->dev->bdev->bd_partno) { + return i; +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index bc534fafacf9..71b3cd634436 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -589,6 +589,7 @@ void btrfs_free_stale_device(struct btrfs_device *cur_dev) + btrfs_sysfs_remove_fsid(fs_devs); + list_del(&fs_devs->list); + free_fs_devices(fs_devs); ++ break; + } else { + fs_devs->num_devices--; + list_del(&dev->dev_list); +@@ -4733,10 +4734,13 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, + ndevs = min(ndevs, devs_max); + + /* +- * the primary goal is to maximize the number of stripes, so use as many +- * devices as possible, even if the stripes are not maximum sized. ++ * The primary goal is to maximize the number of stripes, so use as ++ * many devices as possible, even if the stripes are not maximum sized. ++ * ++ * The DUP profile stores more than one stripe per device, the ++ * max_avail is the total size so we have to adjust. + */ +- stripe_size = devices_info[ndevs-1].max_avail; ++ stripe_size = div_u64(devices_info[ndevs - 1].max_avail, dev_stripes); + num_stripes = ndevs * dev_stripes; + + /* +@@ -4771,8 +4775,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, + stripe_size = devices_info[ndevs-1].max_avail; + } + +- stripe_size = div_u64(stripe_size, dev_stripes); +- + /* align to BTRFS_STRIPE_LEN */ + stripe_size = round_down(stripe_size, BTRFS_STRIPE_LEN); + +@@ -7080,10 +7082,24 @@ int btrfs_run_dev_stats(struct btrfs_trans_handle *trans, + + mutex_lock(&fs_devices->device_list_mutex); + list_for_each_entry(device, &fs_devices->devices, dev_list) { +- if (!device->dev_stats_valid || !btrfs_dev_stats_dirty(device)) ++ stats_cnt = atomic_read(&device->dev_stats_ccnt); ++ if (!device->dev_stats_valid || stats_cnt == 0) + continue; + +- stats_cnt = atomic_read(&device->dev_stats_ccnt); ++ ++ /* ++ * There is a LOAD-LOAD control dependency between the value of ++ * dev_stats_ccnt and updating the on-disk values which requires ++ * reading the in-memory counters. Such control dependencies ++ * require explicit read memory barriers. ++ * ++ * This memory barriers pairs with smp_mb__before_atomic in ++ * btrfs_dev_stat_inc/btrfs_dev_stat_set and with the full ++ * barrier implied by atomic_xchg in ++ * btrfs_dev_stats_read_and_reset ++ */ ++ smp_rmb(); ++ + ret = update_dev_stat_item(trans, fs_info, device); + if (!ret) + atomic_sub(stats_cnt, &device->dev_stats_ccnt); +diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h +index 6108fdfec67f..c5dd48eb7b3d 100644 +--- a/fs/btrfs/volumes.h ++++ b/fs/btrfs/volumes.h +@@ -498,6 +498,12 @@ static inline void btrfs_dev_stat_inc(struct btrfs_device *dev, + int index) + { + atomic_inc(dev->dev_stat_values + index); ++ /* ++ * This memory barrier orders stores updating statistics before stores ++ * updating dev_stats_ccnt. ++ * ++ * It pairs with smp_rmb() in btrfs_run_dev_stats(). ++ */ + smp_mb__before_atomic(); + atomic_inc(&dev->dev_stats_ccnt); + } +@@ -523,6 +529,12 @@ static inline void btrfs_dev_stat_set(struct btrfs_device *dev, + int index, unsigned long val) + { + atomic_set(dev->dev_stat_values + index, val); ++ /* ++ * This memory barrier orders stores updating statistics before stores ++ * updating dev_stats_ccnt. ++ * ++ * It pairs with smp_rmb() in btrfs_run_dev_stats(). ++ */ + smp_mb__before_atomic(); + atomic_inc(&dev->dev_stats_ccnt); + } +diff --git a/fs/dcache.c b/fs/dcache.c +index b8d999a5768b..a1417787e269 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -644,11 +644,16 @@ static inline struct dentry *lock_parent(struct dentry *dentry) + spin_unlock(&parent->d_lock); + goto again; + } +- rcu_read_unlock(); +- if (parent != dentry) ++ if (parent != dentry) { + spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); +- else ++ if (unlikely(dentry->d_lockref.count < 0)) { ++ spin_unlock(&parent->d_lock); ++ parent = NULL; ++ } ++ } else { + parent = NULL; ++ } ++ rcu_read_unlock(); + return parent; + } + +diff --git a/fs/namei.c b/fs/namei.c +index cbe24e367a70..f839b0750ca3 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -578,9 +578,10 @@ static int __nd_alloc_stack(struct nameidata *nd) + static bool path_connected(const struct path *path) + { + struct vfsmount *mnt = path->mnt; ++ struct super_block *sb = mnt->mnt_sb; + +- /* Only bind mounts can have disconnected paths */ +- if (mnt->mnt_root == mnt->mnt_sb->s_root) ++ /* Bind mounts and multi-root filesystems can have disconnected paths */ ++ if (!(sb->s_iflags & SB_I_MULTIROOT) && (mnt->mnt_root == sb->s_root)) + return true; + + return is_subdir(path->dentry, mnt->mnt_root); +diff --git a/fs/nfs/super.c b/fs/nfs/super.c +index 216f67d628b3..38de09b08e96 100644 +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -2623,6 +2623,8 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server, + /* initial superblock/root creation */ + mount_info->fill_super(s, mount_info); + nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned); ++ if (!(server->flags & NFS_MOUNT_UNSHARED)) ++ s->s_iflags |= SB_I_MULTIROOT; + } + + mntroot = nfs_get_root(s, mount_info->mntfh, dev_name); +diff --git a/include/linux/fs.h b/include/linux/fs.h +index d54f41a63dbf..cc613f20e5a6 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1312,6 +1312,7 @@ extern int send_sigurg(struct fown_struct *fown); + #define SB_I_CGROUPWB 0x00000001 /* cgroup-aware writeback enabled */ + #define SB_I_NOEXEC 0x00000002 /* Ignore executables on this fs */ + #define SB_I_NODEV 0x00000004 /* Ignore devices on this fs */ ++#define SB_I_MULTIROOT 0x00000008 /* Multiple roots to the dentry tree */ + + /* sb->s_iflags to limit user namespace mounts */ + #define SB_I_USERNS_VISIBLE 0x00000010 /* fstype already mounted */ +diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h +index 14b74f22d43c..bacb499c512c 100644 +--- a/include/linux/irqchip/arm-gic-v3.h ++++ b/include/linux/irqchip/arm-gic-v3.h +@@ -501,6 +501,7 @@ + + #define ICH_HCR_EN (1 << 0) + #define ICH_HCR_UIE (1 << 1) ++#define ICH_HCR_NPIE (1 << 3) + #define ICH_HCR_TC (1 << 10) + #define ICH_HCR_TALL0 (1 << 11) + #define ICH_HCR_TALL1 (1 << 12) +diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h +index d3453ee072fc..68d8b1f73682 100644 +--- a/include/linux/irqchip/arm-gic.h ++++ b/include/linux/irqchip/arm-gic.h +@@ -84,6 +84,7 @@ + + #define GICH_HCR_EN (1 << 0) + #define GICH_HCR_UIE (1 << 1) ++#define GICH_HCR_NPIE (1 << 3) + + #define GICH_LR_VIRTUALID (0x3ff << 0) + #define GICH_LR_PHYSID_CPUID_SHIFT (10) +diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c +index c2db7e905f7d..012881461058 100644 +--- a/sound/core/oss/pcm_oss.c ++++ b/sound/core/oss/pcm_oss.c +@@ -1762,10 +1762,9 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) + return -ENOMEM; + _snd_pcm_hw_params_any(params); + err = snd_pcm_hw_refine(substream, params); +- format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); +- kfree(params); + if (err < 0) +- return err; ++ goto error; ++ format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); + for (fmt = 0; fmt < 32; ++fmt) { + if (snd_mask_test(format_mask, fmt)) { + int f = snd_pcm_oss_format_to(fmt); +@@ -1773,7 +1772,10 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) + formats |= f; + } + } +- return formats; ++ ++ error: ++ kfree(params); ++ return err < 0 ? err : formats; + } + + static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index 1f3aa466ac9b..a4c571cb3b87 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -255,12 +255,12 @@ static int seq_free_client1(struct snd_seq_client *client) + + if (!client) + return 0; +- snd_seq_delete_all_ports(client); +- snd_seq_queue_client_leave(client->number); + spin_lock_irqsave(&clients_lock, flags); + clienttablock[client->number] = 1; + clienttab[client->number] = NULL; + spin_unlock_irqrestore(&clients_lock, flags); ++ snd_seq_delete_all_ports(client); ++ snd_seq_queue_client_leave(client->number); + snd_use_lock_sync(&client->use_lock); + snd_seq_queue_client_termination(client->number); + if (client->pool) +diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c +index bc1c8488fc2a..2bc6759e4adc 100644 +--- a/sound/core/seq/seq_prioq.c ++++ b/sound/core/seq/seq_prioq.c +@@ -87,7 +87,7 @@ void snd_seq_prioq_delete(struct snd_seq_prioq **fifo) + if (f->cells > 0) { + /* drain prioQ */ + while (f->cells > 0) +- snd_seq_cell_free(snd_seq_prioq_cell_out(f)); ++ snd_seq_cell_free(snd_seq_prioq_cell_out(f, NULL)); + } + + kfree(f); +@@ -214,8 +214,18 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, + return 0; + } + ++/* return 1 if the current time >= event timestamp */ ++static int event_is_ready(struct snd_seq_event *ev, void *current_time) ++{ ++ if ((ev->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK) ++ return snd_seq_compare_tick_time(current_time, &ev->time.tick); ++ else ++ return snd_seq_compare_real_time(current_time, &ev->time.time); ++} ++ + /* dequeue cell from prioq */ +-struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f) ++struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f, ++ void *current_time) + { + struct snd_seq_event_cell *cell; + unsigned long flags; +@@ -227,6 +237,8 @@ struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f) + spin_lock_irqsave(&f->lock, flags); + + cell = f->head; ++ if (cell && current_time && !event_is_ready(&cell->event, current_time)) ++ cell = NULL; + if (cell) { + f->head = cell->next; + +@@ -252,18 +264,6 @@ int snd_seq_prioq_avail(struct snd_seq_prioq * f) + return f->cells; + } + +- +-/* peek at cell at the head of the prioq */ +-struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f) +-{ +- if (f == NULL) { +- pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n"); +- return NULL; +- } +- return f->head; +-} +- +- + static inline int prioq_match(struct snd_seq_event_cell *cell, + int client, int timestamp) + { +diff --git a/sound/core/seq/seq_prioq.h b/sound/core/seq/seq_prioq.h +index d38bb78d9345..2c315ca10fc4 100644 +--- a/sound/core/seq/seq_prioq.h ++++ b/sound/core/seq/seq_prioq.h +@@ -44,14 +44,12 @@ void snd_seq_prioq_delete(struct snd_seq_prioq **fifo); + int snd_seq_prioq_cell_in(struct snd_seq_prioq *f, struct snd_seq_event_cell *cell); + + /* dequeue cell from prioq */ +-struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f); ++struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f, ++ void *current_time); + + /* return number of events available in prioq */ + int snd_seq_prioq_avail(struct snd_seq_prioq *f); + +-/* peek at cell at the head of the prioq */ +-struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq *f); +- + /* client left queue */ + void snd_seq_prioq_leave(struct snd_seq_prioq *f, int client, int timestamp); + +diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c +index 79e0c5604ef8..1a6dc4ff44a6 100644 +--- a/sound/core/seq/seq_queue.c ++++ b/sound/core/seq/seq_queue.c +@@ -277,30 +277,20 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop) + + __again: + /* Process tick queue... */ +- while ((cell = snd_seq_prioq_cell_peek(q->tickq)) != NULL) { +- if (snd_seq_compare_tick_time(&q->timer->tick.cur_tick, +- &cell->event.time.tick)) { +- cell = snd_seq_prioq_cell_out(q->tickq); +- if (cell) +- snd_seq_dispatch_event(cell, atomic, hop); +- } else { +- /* event remains in the queue */ ++ for (;;) { ++ cell = snd_seq_prioq_cell_out(q->tickq, ++ &q->timer->tick.cur_tick); ++ if (!cell) + break; +- } ++ snd_seq_dispatch_event(cell, atomic, hop); + } + +- + /* Process time queue... */ +- while ((cell = snd_seq_prioq_cell_peek(q->timeq)) != NULL) { +- if (snd_seq_compare_real_time(&q->timer->cur_time, +- &cell->event.time.time)) { +- cell = snd_seq_prioq_cell_out(q->timeq); +- if (cell) +- snd_seq_dispatch_event(cell, atomic, hop); +- } else { +- /* event remains in the queue */ ++ for (;;) { ++ cell = snd_seq_prioq_cell_out(q->timeq, &q->timer->cur_time); ++ if (!cell) + break; +- } ++ snd_seq_dispatch_event(cell, atomic, hop); + } + + /* free lock */ +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 96143df19b21..d5017adf9feb 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -181,11 +181,15 @@ static const struct kernel_param_ops param_ops_xint = { + }; + #define param_check_xint param_check_int + +-static int power_save = -1; ++static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; + module_param(power_save, xint, 0644); + MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " + "(in second, 0 = disable)."); + ++static bool pm_blacklist = true; ++module_param(pm_blacklist, bool, 0644); ++MODULE_PARM_DESC(pm_blacklist, "Enable power-management blacklist"); ++ + /* reset the HD-audio controller in power save mode. + * this may give more power-saving, but will take longer time to + * wake up. +@@ -2300,10 +2304,9 @@ static int azx_probe_continue(struct azx *chip) + + val = power_save; + #ifdef CONFIG_PM +- if (val == -1) { ++ if (pm_blacklist) { + const struct snd_pci_quirk *q; + +- val = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; + q = snd_pci_quirk_lookup(chip->pci, power_save_blacklist); + if (q && val) { + dev_info(chip->card->dev, "device %04x:%04x is on the power_save blacklist, forcing power_save to 0\n", +diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c +index d075ea0e5ca1..ade443a88421 100644 +--- a/tools/testing/selftests/x86/entry_from_vm86.c ++++ b/tools/testing/selftests/x86/entry_from_vm86.c +@@ -95,6 +95,31 @@ asm ( + "int3\n\t" + "vmcode_int80:\n\t" + "int $0x80\n\t" ++ "vmcode_popf_hlt:\n\t" ++ "push %ax\n\t" ++ "popf\n\t" ++ "hlt\n\t" ++ "vmcode_umip:\n\t" ++ /* addressing via displacements */ ++ "smsw (2052)\n\t" ++ "sidt (2054)\n\t" ++ "sgdt (2060)\n\t" ++ /* addressing via registers */ ++ "mov $2066, %bx\n\t" ++ "smsw (%bx)\n\t" ++ "mov $2068, %bx\n\t" ++ "sidt (%bx)\n\t" ++ "mov $2074, %bx\n\t" ++ "sgdt (%bx)\n\t" ++ /* register operands, only for smsw */ ++ "smsw %ax\n\t" ++ "mov %ax, (2080)\n\t" ++ "int3\n\t" ++ "vmcode_umip_str:\n\t" ++ "str %eax\n\t" ++ "vmcode_umip_sldt:\n\t" ++ "sldt %eax\n\t" ++ "int3\n\t" + ".size vmcode, . - vmcode\n\t" + "end_vmcode:\n\t" + ".code32\n\t" +@@ -103,7 +128,8 @@ asm ( + + extern unsigned char vmcode[], end_vmcode[]; + extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[], +- vmcode_sti[], vmcode_int3[], vmcode_int80[]; ++ vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_popf_hlt[], ++ vmcode_umip[], vmcode_umip_str[], vmcode_umip_sldt[]; + + /* Returns false if the test was skipped. */ + static bool do_test(struct vm86plus_struct *v86, unsigned long eip, +@@ -153,13 +179,75 @@ static bool do_test(struct vm86plus_struct *v86, unsigned long eip, + (VM86_TYPE(ret) == rettype && VM86_ARG(ret) == retarg)) { + printf("[OK]\tReturned correctly\n"); + } else { +- printf("[FAIL]\tIncorrect return reason\n"); ++ printf("[FAIL]\tIncorrect return reason (started at eip = 0x%lx, ended at eip = 0x%lx)\n", eip, v86->regs.eip); + nerrs++; + } + + return true; + } + ++void do_umip_tests(struct vm86plus_struct *vm86, unsigned char *test_mem) ++{ ++ struct table_desc { ++ unsigned short limit; ++ unsigned long base; ++ } __attribute__((packed)); ++ ++ /* Initialize variables with arbitrary values */ ++ struct table_desc gdt1 = { .base = 0x3c3c3c3c, .limit = 0x9999 }; ++ struct table_desc gdt2 = { .base = 0x1a1a1a1a, .limit = 0xaeae }; ++ struct table_desc idt1 = { .base = 0x7b7b7b7b, .limit = 0xf1f1 }; ++ struct table_desc idt2 = { .base = 0x89898989, .limit = 0x1313 }; ++ unsigned short msw1 = 0x1414, msw2 = 0x2525, msw3 = 3737; ++ ++ /* UMIP -- exit with INT3 unless kernel emulation did not trap #GP */ ++ do_test(vm86, vmcode_umip - vmcode, VM86_TRAP, 3, "UMIP tests"); ++ ++ /* Results from displacement-only addressing */ ++ msw1 = *(unsigned short *)(test_mem + 2052); ++ memcpy(&idt1, test_mem + 2054, sizeof(idt1)); ++ memcpy(&gdt1, test_mem + 2060, sizeof(gdt1)); ++ ++ /* Results from register-indirect addressing */ ++ msw2 = *(unsigned short *)(test_mem + 2066); ++ memcpy(&idt2, test_mem + 2068, sizeof(idt2)); ++ memcpy(&gdt2, test_mem + 2074, sizeof(gdt2)); ++ ++ /* Results when using register operands */ ++ msw3 = *(unsigned short *)(test_mem + 2080); ++ ++ printf("[INFO]\tResult from SMSW:[0x%04x]\n", msw1); ++ printf("[INFO]\tResult from SIDT: limit[0x%04x]base[0x%08lx]\n", ++ idt1.limit, idt1.base); ++ printf("[INFO]\tResult from SGDT: limit[0x%04x]base[0x%08lx]\n", ++ gdt1.limit, gdt1.base); ++ ++ if (msw1 != msw2 || msw1 != msw3) ++ printf("[FAIL]\tAll the results of SMSW should be the same.\n"); ++ else ++ printf("[PASS]\tAll the results from SMSW are identical.\n"); ++ ++ if (memcmp(&gdt1, &gdt2, sizeof(gdt1))) ++ printf("[FAIL]\tAll the results of SGDT should be the same.\n"); ++ else ++ printf("[PASS]\tAll the results from SGDT are identical.\n"); ++ ++ if (memcmp(&idt1, &idt2, sizeof(idt1))) ++ printf("[FAIL]\tAll the results of SIDT should be the same.\n"); ++ else ++ printf("[PASS]\tAll the results from SIDT are identical.\n"); ++ ++ sethandler(SIGILL, sighandler, 0); ++ do_test(vm86, vmcode_umip_str - vmcode, VM86_SIGNAL, 0, ++ "STR instruction"); ++ clearhandler(SIGILL); ++ ++ sethandler(SIGILL, sighandler, 0); ++ do_test(vm86, vmcode_umip_sldt - vmcode, VM86_SIGNAL, 0, ++ "SLDT instruction"); ++ clearhandler(SIGILL); ++} ++ + int main(void) + { + struct vm86plus_struct v86; +@@ -180,6 +268,9 @@ int main(void) + v86.regs.ds = load_addr / 16; + v86.regs.es = load_addr / 16; + ++ /* Use the end of the page as our stack. */ ++ v86.regs.esp = 4096; ++ + assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */ + + /* #BR -- should deliver SIG??? */ +@@ -211,6 +302,23 @@ int main(void) + v86.regs.eflags &= ~X86_EFLAGS_IF; + do_test(&v86, vmcode_sti - vmcode, VM86_STI, 0, "STI with VIP set"); + ++ /* POPF with VIP set but IF clear: should not trap */ ++ v86.regs.eflags = X86_EFLAGS_VIP; ++ v86.regs.eax = 0; ++ do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP set and IF clear"); ++ ++ /* POPF with VIP set and IF set: should trap */ ++ v86.regs.eflags = X86_EFLAGS_VIP; ++ v86.regs.eax = X86_EFLAGS_IF; ++ do_test(&v86, vmcode_popf_hlt - vmcode, VM86_STI, 0, "POPF with VIP and IF set"); ++ ++ /* POPF with VIP clear and IF set: should not trap */ ++ v86.regs.eflags = 0; ++ v86.regs.eax = X86_EFLAGS_IF; ++ do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP clear and IF set"); ++ ++ v86.regs.eflags = 0; ++ + /* INT3 -- should cause #BP */ + do_test(&v86, vmcode_int3 - vmcode, VM86_TRAP, 3, "INT3"); + +@@ -218,6 +326,9 @@ int main(void) + v86.regs.eax = (unsigned int)-1; + do_test(&v86, vmcode_int80 - vmcode, VM86_INTx, 0x80, "int80"); + ++ /* UMIP -- should exit with INTx 0x80 unless UMIP was not disabled */ ++ do_umip_tests(&v86, addr); ++ + /* Execute a null pointer */ + v86.regs.cs = 0; + v86.regs.ss = 0; +@@ -231,7 +342,7 @@ int main(void) + clearhandler(SIGSEGV); + + /* Make sure nothing explodes if we fork. */ +- if (fork() > 0) ++ if (fork() == 0) + return 0; + + return (nerrs == 0 ? 0 : 1); +diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c +index 8e89d63005c7..49a7d8c75937 100644 +--- a/virt/kvm/arm/arch_timer.c ++++ b/virt/kvm/arm/arch_timer.c +@@ -602,7 +602,7 @@ int kvm_timer_hyp_init(void) + return err; + } + +- kvm_info("virtual timer IRQ%d\n", host_vtimer_irq); ++ kvm_debug("virtual timer IRQ%d\n", host_vtimer_irq); + + cpuhp_setup_state(CPUHP_AP_KVM_ARM_TIMER_STARTING, + "kvm/arm/timer:starting", kvm_timer_starting_cpu, +diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c +index 91728faa13fd..f2d1d4e8ae59 100644 +--- a/virt/kvm/arm/hyp/vgic-v3-sr.c ++++ b/virt/kvm/arm/hyp/vgic-v3-sr.c +@@ -215,7 +215,8 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu) + * are now visible to the system register interface. + */ + if (!cpu_if->vgic_sre) { +- dsb(st); ++ dsb(sy); ++ isb(); + cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2); + } + +diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c +index 9dea96380339..b69798a7880e 100644 +--- a/virt/kvm/arm/mmu.c ++++ b/virt/kvm/arm/mmu.c +@@ -1760,9 +1760,9 @@ int kvm_mmu_init(void) + */ + BUG_ON((hyp_idmap_start ^ (hyp_idmap_end - 1)) & PAGE_MASK); + +- kvm_info("IDMAP page: %lx\n", hyp_idmap_start); +- kvm_info("HYP VA range: %lx:%lx\n", +- kern_hyp_va(PAGE_OFFSET), kern_hyp_va(~0UL)); ++ kvm_debug("IDMAP page: %lx\n", hyp_idmap_start); ++ kvm_debug("HYP VA range: %lx:%lx\n", ++ kern_hyp_va(PAGE_OFFSET), kern_hyp_va(~0UL)); + + if (hyp_idmap_start >= kern_hyp_va(PAGE_OFFSET) && + hyp_idmap_start < kern_hyp_va(~0UL) && +diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c +index e4187e52bb26..841d4b27555a 100644 +--- a/virt/kvm/arm/vgic/vgic-v2.c ++++ b/virt/kvm/arm/vgic/vgic-v2.c +@@ -37,6 +37,13 @@ void vgic_v2_init_lrs(void) + vgic_v2_write_lr(i, 0); + } + ++void vgic_v2_set_npie(struct kvm_vcpu *vcpu) ++{ ++ struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2; ++ ++ cpuif->vgic_hcr |= GICH_HCR_NPIE; ++} ++ + void vgic_v2_set_underflow(struct kvm_vcpu *vcpu) + { + struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2; +@@ -63,7 +70,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) + struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2; + int lr; + +- cpuif->vgic_hcr &= ~GICH_HCR_UIE; ++ cpuif->vgic_hcr &= ~(GICH_HCR_UIE | GICH_HCR_NPIE); + + for (lr = 0; lr < vgic_cpu->used_lrs; lr++) { + u32 val = cpuif->vgic_lr[lr]; +@@ -380,7 +387,7 @@ int vgic_v2_probe(const struct gic_kvm_info *info) + kvm_vgic_global_state.type = VGIC_V2; + kvm_vgic_global_state.max_gic_vcpus = VGIC_V2_MAX_CPUS; + +- kvm_info("vgic-v2@%llx\n", info->vctrl.start); ++ kvm_debug("vgic-v2@%llx\n", info->vctrl.start); + + return 0; + out: +diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c +index 502f2100e7bf..9dcc31600a8b 100644 +--- a/virt/kvm/arm/vgic/vgic-v3.c ++++ b/virt/kvm/arm/vgic/vgic-v3.c +@@ -25,6 +25,13 @@ static bool group0_trap; + static bool group1_trap; + static bool common_trap; + ++void vgic_v3_set_npie(struct kvm_vcpu *vcpu) ++{ ++ struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3; ++ ++ cpuif->vgic_hcr |= ICH_HCR_NPIE; ++} ++ + void vgic_v3_set_underflow(struct kvm_vcpu *vcpu) + { + struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3; +@@ -45,7 +52,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) + u32 model = vcpu->kvm->arch.vgic.vgic_model; + int lr; + +- cpuif->vgic_hcr &= ~ICH_HCR_UIE; ++ cpuif->vgic_hcr &= ~(ICH_HCR_UIE | ICH_HCR_NPIE); + + for (lr = 0; lr < vgic_cpu->used_lrs; lr++) { + u64 val = cpuif->vgic_lr[lr]; +diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c +index da53c6e7d688..c9a8e7b7c300 100644 +--- a/virt/kvm/arm/vgic/vgic.c ++++ b/virt/kvm/arm/vgic/vgic.c +@@ -610,22 +610,37 @@ static inline void vgic_set_underflow(struct kvm_vcpu *vcpu) + vgic_v3_set_underflow(vcpu); + } + ++static inline void vgic_set_npie(struct kvm_vcpu *vcpu) ++{ ++ if (kvm_vgic_global_state.type == VGIC_V2) ++ vgic_v2_set_npie(vcpu); ++ else ++ vgic_v3_set_npie(vcpu); ++} ++ + /* Requires the ap_list_lock to be held. */ +-static int compute_ap_list_depth(struct kvm_vcpu *vcpu) ++static int compute_ap_list_depth(struct kvm_vcpu *vcpu, ++ bool *multi_sgi) + { + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct vgic_irq *irq; + int count = 0; + ++ *multi_sgi = false; ++ + DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock)); + + list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { + spin_lock(&irq->irq_lock); + /* GICv2 SGIs can count for more than one... */ +- if (vgic_irq_is_sgi(irq->intid) && irq->source) +- count += hweight8(irq->source); +- else ++ if (vgic_irq_is_sgi(irq->intid) && irq->source) { ++ int w = hweight8(irq->source); ++ ++ count += w; ++ *multi_sgi |= (w > 1); ++ } else { + count++; ++ } + spin_unlock(&irq->irq_lock); + } + return count; +@@ -636,28 +651,43 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu) + { + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct vgic_irq *irq; +- int count = 0; ++ int count; ++ bool npie = false; ++ bool multi_sgi; ++ u8 prio = 0xff; + + DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock)); + +- if (compute_ap_list_depth(vcpu) > kvm_vgic_global_state.nr_lr) ++ count = compute_ap_list_depth(vcpu, &multi_sgi); ++ if (count > kvm_vgic_global_state.nr_lr || multi_sgi) + vgic_sort_ap_list(vcpu); + ++ count = 0; ++ + list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { + spin_lock(&irq->irq_lock); + +- if (unlikely(vgic_target_oracle(irq) != vcpu)) +- goto next; +- + /* +- * If we get an SGI with multiple sources, try to get +- * them in all at once. ++ * If we have multi-SGIs in the pipeline, we need to ++ * guarantee that they are all seen before any IRQ of ++ * lower priority. In that case, we need to filter out ++ * these interrupts by exiting early. This is easy as ++ * the AP list has been sorted already. + */ +- do { ++ if (multi_sgi && irq->priority > prio) { ++ spin_unlock(&irq->irq_lock); ++ break; ++ } ++ ++ if (likely(vgic_target_oracle(irq) == vcpu)) { + vgic_populate_lr(vcpu, irq, count++); +- } while (irq->source && count < kvm_vgic_global_state.nr_lr); + +-next: ++ if (irq->source) { ++ npie = true; ++ prio = irq->priority; ++ } ++ } ++ + spin_unlock(&irq->irq_lock); + + if (count == kvm_vgic_global_state.nr_lr) { +@@ -668,6 +698,9 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu) + } + } + ++ if (npie) ++ vgic_set_npie(vcpu); ++ + vcpu->arch.vgic_cpu.used_lrs = count; + + /* Nuke remaining LRs */ +diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h +index bf9ceab67c77..f7450dc41ab3 100644 +--- a/virt/kvm/arm/vgic/vgic.h ++++ b/virt/kvm/arm/vgic/vgic.h +@@ -150,6 +150,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu); + void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr); + void vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr); + void vgic_v2_set_underflow(struct kvm_vcpu *vcpu); ++void vgic_v2_set_npie(struct kvm_vcpu *vcpu); + int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr); + int vgic_v2_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write, + int offset, u32 *val); +@@ -179,6 +180,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu); + void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr); + void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr); + void vgic_v3_set_underflow(struct kvm_vcpu *vcpu); ++void vgic_v3_set_npie(struct kvm_vcpu *vcpu); + void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); + void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); + void vgic_v3_enable(struct kvm_vcpu *vcpu); |