From nobody Wed Jul 1 05:42:38 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E1EBC433EF for ; Thu, 27 Jan 2022 18:10:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245385AbiA0SKy (ORCPT ); Thu, 27 Jan 2022 13:10:54 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:59078 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244984AbiA0SKR (ORCPT ); Thu, 27 Jan 2022 13:10:17 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id BBBADB818E1; Thu, 27 Jan 2022 18:10:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B606CC36AE9; Thu, 27 Jan 2022 18:10:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643307014; bh=b/C8U/+cGydSotb1N5mwxoSOetMedXq4j7U1YGhVfA0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V9u03MklyjXhwHUKwBviPqQw81QyIkcQo3W/1RRb3JHVSbcKQqKeIaalUdWEIJpE7 F+mQy4INQ/ZabDYSrjpslFzZu130zDJvvE3SETnk5i/wQhuFnw+cJzhrUmeNsCiP9q vYqO7NkAkr1neZIk43zfFeQN1g0jpDnLDbQ6R0vE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Tvrtko Ursulin , Sushma Venkatesh Reddy , Daniel Vetter , Dave Airlie , Jon Bloomfield , Joonas Lahtinen , Jani Nikula , Linus Torvalds Subject: [PATCH 5.10 1/6] drm/i915: Flush TLBs before releasing backing store Date: Thu, 27 Jan 2022 19:09:17 +0100 Message-Id: <20220127180258.186081636@linuxfoundation.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220127180258.131170405@linuxfoundation.org> References: <20220127180258.131170405@linuxfoundation.org> User-Agent: quilt/0.66 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Tvrtko Ursulin commit 7938d61591d33394a21bdd7797a245b65428f44c upstream. We need to flush TLBs before releasing backing store otherwise userspace is able to encounter stale entries if a) it is not declaring access to certain buffers and b) it races with the backing store release from a such undeclared execution already executing on the GPU in parallel. The approach taken is to mark any buffer objects which were ever bound to the GPU and to trigger a serialized TLB flush when their backing store is released. Alternatively the flushing could be done on VMA unbind, at which point we would be able to ascertain whether there is potential a parallel GPU execution (which could race), but essentially it boils down to paying the cost of TLB flushes potentially needlessly at VMA unbind time (when the backing store is not known to be going away so not needed for safety), versus potentially needlessly at backing store relase time (since we at that point cannot tell whether there is anything executing on the GPU which uses that object). Thereforce simplicity of implementation has been chosen for now with scope to benchmark and refine later as required. Signed-off-by: Tvrtko Ursulin Reported-by: Sushma Venkatesh Reddy Reviewed-by: Daniel Vetter Acked-by: Dave Airlie Cc: Daniel Vetter Cc: Jon Bloomfield Cc: Joonas Lahtinen Cc: Jani Nikula Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Tested-by: Florian Fainelli Tested-by: Fox Chen Tested-by: Guenter Roeck Tested-by: Linux Kernel Functional Testing Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Sudip Mukherjee --- drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 1=20 drivers/gpu/drm/i915/gem/i915_gem_pages.c | 10 ++ drivers/gpu/drm/i915/gt/intel_gt.c | 102 ++++++++++++++++++= +++++ drivers/gpu/drm/i915/gt/intel_gt.h | 2=20 drivers/gpu/drm/i915/gt/intel_gt_types.h | 2=20 drivers/gpu/drm/i915/i915_reg.h | 11 ++ drivers/gpu/drm/i915/i915_vma.c | 3=20 drivers/gpu/drm/i915/intel_uncore.c | 26 ++++- drivers/gpu/drm/i915/intel_uncore.h | 2=20 9 files changed, 155 insertions(+), 4 deletions(-) --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -159,6 +159,7 @@ struct drm_i915_gem_object { #define I915_BO_ALLOC_VOLATILE BIT(1) #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | I915_BO_ALLOC_VOLA= TILE) #define I915_BO_READONLY BIT(2) +#define I915_BO_WAS_BOUND_BIT 3 =20 /* * Is the object to be mapped as read-only to the GPU --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -10,6 +10,8 @@ #include "i915_gem_lmem.h" #include "i915_gem_mman.h" =20 +#include "gt/intel_gt.h" + void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, unsigned int sg_page_sizes) @@ -186,6 +188,14 @@ __i915_gem_object_unset_pages(struct drm __i915_gem_object_reset_page_iter(obj); obj->mm.page_sizes.phys =3D obj->mm.page_sizes.sg =3D 0; =20 + if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) { + struct drm_i915_private *i915 =3D to_i915(obj->base.dev); + intel_wakeref_t wakeref; + + with_intel_runtime_pm_if_active(&i915->runtime_pm, wakeref) + intel_gt_invalidate_tlbs(&i915->gt); + } + return pages; } =20 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -26,6 +26,8 @@ void intel_gt_init_early(struct intel_gt =20 spin_lock_init(>->irq_lock); =20 + mutex_init(>->tlb_invalidate_lock); + INIT_LIST_HEAD(>->closed_vma); spin_lock_init(>->closed_lock); =20 @@ -661,3 +663,103 @@ void intel_gt_info_print(const struct in =20 intel_sseu_dump(&info->sseu, p); } + +struct reg_and_bit { + i915_reg_t reg; + u32 bit; +}; + +static struct reg_and_bit +get_reg_and_bit(const struct intel_engine_cs *engine, const bool gen8, + const i915_reg_t *regs, const unsigned int num) +{ + const unsigned int class =3D engine->class; + struct reg_and_bit rb =3D { }; + + if (drm_WARN_ON_ONCE(&engine->i915->drm, + class >=3D num || !regs[class].reg)) + return rb; + + rb.reg =3D regs[class]; + if (gen8 && class =3D=3D VIDEO_DECODE_CLASS) + rb.reg.reg +=3D 4 * engine->instance; /* GEN8_M2TCR */ + else + rb.bit =3D engine->instance; + + rb.bit =3D BIT(rb.bit); + + return rb; +} + +void intel_gt_invalidate_tlbs(struct intel_gt *gt) +{ + static const i915_reg_t gen8_regs[] =3D { + [RENDER_CLASS] =3D GEN8_RTCR, + [VIDEO_DECODE_CLASS] =3D GEN8_M1TCR, /* , GEN8_M2TCR */ + [VIDEO_ENHANCEMENT_CLASS] =3D GEN8_VTCR, + [COPY_ENGINE_CLASS] =3D GEN8_BTCR, + }; + static const i915_reg_t gen12_regs[] =3D { + [RENDER_CLASS] =3D GEN12_GFX_TLB_INV_CR, + [VIDEO_DECODE_CLASS] =3D GEN12_VD_TLB_INV_CR, + [VIDEO_ENHANCEMENT_CLASS] =3D GEN12_VE_TLB_INV_CR, + [COPY_ENGINE_CLASS] =3D GEN12_BLT_TLB_INV_CR, + }; + struct drm_i915_private *i915 =3D gt->i915; + struct intel_uncore *uncore =3D gt->uncore; + struct intel_engine_cs *engine; + enum intel_engine_id id; + const i915_reg_t *regs; + unsigned int num =3D 0; + + if (I915_SELFTEST_ONLY(gt->awake =3D=3D -ENODEV)) + return; + + if (INTEL_GEN(i915) =3D=3D 12) { + regs =3D gen12_regs; + num =3D ARRAY_SIZE(gen12_regs); + } else if (INTEL_GEN(i915) >=3D 8 && INTEL_GEN(i915) <=3D 11) { + regs =3D gen8_regs; + num =3D ARRAY_SIZE(gen8_regs); + } else if (INTEL_GEN(i915) < 8) { + return; + } + + if (drm_WARN_ONCE(&i915->drm, !num, + "Platform does not implement TLB invalidation!")) + return; + + GEM_TRACE("\n"); + + assert_rpm_wakelock_held(&i915->runtime_pm); + + mutex_lock(>->tlb_invalidate_lock); + intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); + + for_each_engine(engine, gt, id) { + /* + * HW architecture suggest typical invalidation time at 40us, + * with pessimistic cases up to 100us and a recommendation to + * cap at 1ms. We go a bit higher just in case. + */ + const unsigned int timeout_us =3D 100; + const unsigned int timeout_ms =3D 4; + struct reg_and_bit rb; + + rb =3D get_reg_and_bit(engine, regs =3D=3D gen8_regs, regs, num); + if (!i915_mmio_reg_offset(rb.reg)) + continue; + + intel_uncore_write_fw(uncore, rb.reg, rb.bit); + if (__intel_wait_for_register_fw(uncore, + rb.reg, rb.bit, 0, + timeout_us, timeout_ms, + NULL)) + drm_err_ratelimited(>->i915->drm, + "%s TLB invalidation did not complete in %ums!\n", + engine->name, timeout_ms); + } + + intel_uncore_forcewake_put_delayed(uncore, FORCEWAKE_ALL); + mutex_unlock(>->tlb_invalidate_lock); +} --- a/drivers/gpu/drm/i915/gt/intel_gt.h +++ b/drivers/gpu/drm/i915/gt/intel_gt.h @@ -77,4 +77,6 @@ static inline bool intel_gt_is_wedged(co void intel_gt_info_print(const struct intel_gt_info *info, struct drm_printer *p); =20 +void intel_gt_invalidate_tlbs(struct intel_gt *gt); + #endif /* __INTEL_GT_H__ */ --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h @@ -36,6 +36,8 @@ struct intel_gt { =20 struct intel_uc uc; =20 + struct mutex tlb_invalidate_lock; + struct intel_gt_timelines { spinlock_t lock; /* protects active_list */ struct list_head active_list; --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2639,6 +2639,12 @@ static inline bool i915_mmio_reg_valid(i #define GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING (1 << 28) #define GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT (1 << 24) =20 +#define GEN8_RTCR _MMIO(0x4260) +#define GEN8_M1TCR _MMIO(0x4264) +#define GEN8_M2TCR _MMIO(0x4268) +#define GEN8_BTCR _MMIO(0x426c) +#define GEN8_VTCR _MMIO(0x4270) + #if 0 #define PRB0_TAIL _MMIO(0x2030) #define PRB0_HEAD _MMIO(0x2034) @@ -2728,6 +2734,11 @@ static inline bool i915_mmio_reg_valid(i #define FAULT_VA_HIGH_BITS (0xf << 0) #define FAULT_GTT_SEL (1 << 4) =20 +#define GEN12_GFX_TLB_INV_CR _MMIO(0xced8) +#define GEN12_VD_TLB_INV_CR _MMIO(0xcedc) +#define GEN12_VE_TLB_INV_CR _MMIO(0xcee0) +#define GEN12_BLT_TLB_INV_CR _MMIO(0xcee4) + #define GEN12_AUX_ERR_DBG _MMIO(0x43f4) =20 #define FPGA_DBG _MMIO(0x42300) --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -439,6 +439,9 @@ int i915_vma_bind(struct i915_vma *vma, vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags); } =20 + if (vma->obj) + set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags); + atomic_or(bind_flags, &vma->flags); return 0; } --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -694,7 +694,8 @@ void intel_uncore_forcewake_get__locked( } =20 static void __intel_uncore_forcewake_put(struct intel_uncore *uncore, - enum forcewake_domains fw_domains) + enum forcewake_domains fw_domains, + bool delayed) { struct intel_uncore_forcewake_domain *domain; unsigned int tmp; @@ -709,7 +710,11 @@ static void __intel_uncore_forcewake_put continue; } =20 - uncore->funcs.force_wake_put(uncore, domain->mask); + if (delayed && + !(domain->uncore->fw_domains_timer & domain->mask)) + fw_domain_arm_timer(domain); + else + uncore->funcs.force_wake_put(uncore, domain->mask); } } =20 @@ -730,7 +735,20 @@ void intel_uncore_forcewake_put(struct i return; =20 spin_lock_irqsave(&uncore->lock, irqflags); - __intel_uncore_forcewake_put(uncore, fw_domains); + __intel_uncore_forcewake_put(uncore, fw_domains, false); + spin_unlock_irqrestore(&uncore->lock, irqflags); +} + +void intel_uncore_forcewake_put_delayed(struct intel_uncore *uncore, + enum forcewake_domains fw_domains) +{ + unsigned long irqflags; + + if (!uncore->funcs.force_wake_put) + return; + + spin_lock_irqsave(&uncore->lock, irqflags); + __intel_uncore_forcewake_put(uncore, fw_domains, true); spin_unlock_irqrestore(&uncore->lock, irqflags); } =20 @@ -772,7 +790,7 @@ void intel_uncore_forcewake_put__locked( if (!uncore->funcs.force_wake_put) return; =20 - __intel_uncore_forcewake_put(uncore, fw_domains); + __intel_uncore_forcewake_put(uncore, fw_domains, false); } =20 void assert_forcewakes_inactive(struct intel_uncore *uncore) --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -211,6 +211,8 @@ void intel_uncore_forcewake_get(struct i enum forcewake_domains domains); void intel_uncore_forcewake_put(struct intel_uncore *uncore, enum forcewake_domains domains); +void intel_uncore_forcewake_put_delayed(struct intel_uncore *uncore, + enum forcewake_domains domains); void intel_uncore_forcewake_flush(struct intel_uncore *uncore, enum forcewake_domains fw_domains); =20 From nobody Wed Jul 1 05:42:38 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA3D5C433EF for ; Thu, 27 Jan 2022 18:10:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245302AbiA0SK5 (ORCPT ); Thu, 27 Jan 2022 13:10:57 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:59142 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245230AbiA0SKT (ORCPT ); Thu, 27 Jan 2022 13:10:19 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id CD31FB820C8; Thu, 27 Jan 2022 18:10:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05D89C340E8; Thu, 27 Jan 2022 18:10:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643307017; bh=ZyGRMpxVIlJR6370hZIZvu8bKpjzmIBDhxv/v5Ox6so=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tixbjZq4XQJoT7lvAHTaKL0c7q9hShPtEIfsEyoAmPJS6GwvuRPs1d+AgnIE+ZV76 nJDofX84sJwXsnFdNbNiPTkUcl2a06KcR2B/oq/khCNVgKz5A/3L6h5bLFelZSb+3r e+tKuOMksZ3mgk4n/U3HMfXGDZwS+7fushCa0M2k= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , Manish Chopra , Prabhakar Kushwaha , Alok Prasad , Ariel Elior , "David S. Miller" Subject: [PATCH 5.10 2/6] bnx2x: Utilize firmware 7.13.21.0 Date: Thu, 27 Jan 2022 19:09:18 +0100 Message-Id: <20220127180258.217751375@linuxfoundation.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220127180258.131170405@linuxfoundation.org> References: <20220127180258.131170405@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Manish Chopra commit b7a49f73059fe6147b6b78e8f674ce0d21237432 upstream This new firmware addresses few important issues and enhancements as mentioned below - - Support direct invalidation of FP HSI Ver per function ID, required for invalidating FP HSI Ver prior to each VF start, as there is no VF start - BRB hardware block parity error detection support for the driver - Fix the FCOE underrun flow - Fix PSOD during FCoE BFS over the NIC ports after preboot driver - Maintains backward compatibility This patch incorporates this new firmware 7.13.21.0 in bnx2x driver. Signed-off-by: Manish Chopra Signed-off-by: Prabhakar Kushwaha Signed-off-by: Alok Prasad Signed-off-by: Ariel Elior Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Tested-by: Florian Fainelli Tested-by: Fox Chen Tested-by: Guenter Roeck Tested-by: Linux Kernel Functional Testing Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Sudip Mukherjee --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 11 ++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 6 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h | 2=20 drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 3=20 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 75 ++++++++++++++-= ----- 5 files changed, 69 insertions(+), 28 deletions(-) --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1850,6 +1850,14 @@ struct bnx2x { =20 /* Vxlan/Geneve related information */ u16 udp_tunnel_ports[BNX2X_UDP_PORT_MAX]; + +#define FW_CAP_INVALIDATE_VF_FP_HSI BIT(0) + u32 fw_cap; + + u32 fw_major; + u32 fw_minor; + u32 fw_rev; + u32 fw_eng; }; =20 /* Tx queues may be less or equal to Rx queues */ @@ -2526,5 +2534,6 @@ void bnx2x_register_phc(struct bnx2x *bp * Meant for implicit re-load flows. */ int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp); - +int bnx2x_init_firmware(struct bnx2x *bp); +void bnx2x_release_firmware(struct bnx2x *bp); #endif /* bnx2x.h */ --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2364,10 +2364,8 @@ int bnx2x_compare_fw_ver(struct bnx2x *b if (load_code !=3D FW_MSG_CODE_DRV_LOAD_COMMON_CHIP && load_code !=3D FW_MSG_CODE_DRV_LOAD_COMMON) { /* build my FW version dword */ - u32 my_fw =3D (BCM_5710_FW_MAJOR_VERSION) + - (BCM_5710_FW_MINOR_VERSION << 8) + - (BCM_5710_FW_REVISION_VERSION << 16) + - (BCM_5710_FW_ENGINEERING_VERSION << 24); + u32 my_fw =3D (bp->fw_major) + (bp->fw_minor << 8) + + (bp->fw_rev << 16) + (bp->fw_eng << 24); =20 /* read loaded FW from chip */ u32 loaded_fw =3D REG_RD(bp, XSEM_REG_PRAM); --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h @@ -241,6 +241,8 @@ IRO[221].m2)) #define XSTORM_VF_TO_PF_OFFSET(funcId) \ (IRO[48].base + ((funcId) * IRO[48].m1)) +#define XSTORM_ETH_FUNCTION_INFO_FP_HSI_VALID_E2_OFFSET(fid) \ + (IRO[386].base + ((fid) * IRO[386].m1)) #define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0 =20 /* eth hsi version */ --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -3024,7 +3024,8 @@ struct afex_stats { =20 #define BCM_5710_FW_MAJOR_VERSION 7 #define BCM_5710_FW_MINOR_VERSION 13 -#define BCM_5710_FW_REVISION_VERSION 15 +#define BCM_5710_FW_REVISION_VERSION 21 +#define BCM_5710_FW_REVISION_VERSION_V15 15 #define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 =20 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -74,9 +74,19 @@ __stringify(BCM_5710_FW_MINOR_VERSION) "." \ __stringify(BCM_5710_FW_REVISION_VERSION) "." \ __stringify(BCM_5710_FW_ENGINEERING_VERSION) + +#define FW_FILE_VERSION_V15 \ + __stringify(BCM_5710_FW_MAJOR_VERSION) "." \ + __stringify(BCM_5710_FW_MINOR_VERSION) "." \ + __stringify(BCM_5710_FW_REVISION_VERSION_V15) "." \ + __stringify(BCM_5710_FW_ENGINEERING_VERSION) + #define FW_FILE_NAME_E1 "bnx2x/bnx2x-e1-" FW_FILE_VERSION ".fw" #define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" #define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw" +#define FW_FILE_NAME_E1_V15 "bnx2x/bnx2x-e1-" FW_FILE_VERSION_V15 ".fw" +#define FW_FILE_NAME_E1H_V15 "bnx2x/bnx2x-e1h-" FW_FILE_VERSION_V15 ".fw" +#define FW_FILE_NAME_E2_V15 "bnx2x/bnx2x-e2-" FW_FILE_VERSION_V15 ".fw" =20 /* Time in jiffies before concluding the transmitter is hung */ #define TX_TIMEOUT (5*HZ) @@ -747,9 +757,7 @@ static int bnx2x_mc_assert(struct bnx2x CHIP_IS_E1(bp) ? "everest1" : CHIP_IS_E1H(bp) ? "everest1h" : CHIP_IS_E2(bp) ? "everest2" : "everest3", - BCM_5710_FW_MAJOR_VERSION, - BCM_5710_FW_MINOR_VERSION, - BCM_5710_FW_REVISION_VERSION); + bp->fw_major, bp->fw_minor, bp->fw_rev); =20 return rc; } @@ -12355,6 +12363,15 @@ static int bnx2x_init_bp(struct bnx2x *b =20 bnx2x_read_fwinfo(bp); =20 + if (IS_PF(bp)) { + rc =3D bnx2x_init_firmware(bp); + + if (rc) { + bnx2x_free_mem_bp(bp); + return rc; + } + } + func =3D BP_FUNC(bp); =20 /* need to reset chip if undi was active */ @@ -12367,6 +12384,7 @@ static int bnx2x_init_bp(struct bnx2x *b =20 rc =3D bnx2x_prev_unload(bp); if (rc) { + bnx2x_release_firmware(bp); bnx2x_free_mem_bp(bp); return rc; } @@ -13366,16 +13384,11 @@ static int bnx2x_check_firmware(struct b /* Check FW version */ offset =3D be32_to_cpu(fw_hdr->fw_version.offset); fw_ver =3D firmware->data + offset; - if ((fw_ver[0] !=3D BCM_5710_FW_MAJOR_VERSION) || - (fw_ver[1] !=3D BCM_5710_FW_MINOR_VERSION) || - (fw_ver[2] !=3D BCM_5710_FW_REVISION_VERSION) || - (fw_ver[3] !=3D BCM_5710_FW_ENGINEERING_VERSION)) { + if (fw_ver[0] !=3D bp->fw_major || fw_ver[1] !=3D bp->fw_minor || + fw_ver[2] !=3D bp->fw_rev || fw_ver[3] !=3D bp->fw_eng) { BNX2X_ERR("Bad FW version:%d.%d.%d.%d. Should be %d.%d.%d.%d\n", - fw_ver[0], fw_ver[1], fw_ver[2], fw_ver[3], - BCM_5710_FW_MAJOR_VERSION, - BCM_5710_FW_MINOR_VERSION, - BCM_5710_FW_REVISION_VERSION, - BCM_5710_FW_ENGINEERING_VERSION); + fw_ver[0], fw_ver[1], fw_ver[2], fw_ver[3], + bp->fw_major, bp->fw_minor, bp->fw_rev, bp->fw_eng); return -EINVAL; } =20 @@ -13453,34 +13466,51 @@ do { \ (u8 *)bp->arr, len); \ } while (0) =20 -static int bnx2x_init_firmware(struct bnx2x *bp) +int bnx2x_init_firmware(struct bnx2x *bp) { - const char *fw_file_name; + const char *fw_file_name, *fw_file_name_v15; struct bnx2x_fw_file_hdr *fw_hdr; int rc; =20 if (bp->firmware) return 0; =20 - if (CHIP_IS_E1(bp)) + if (CHIP_IS_E1(bp)) { fw_file_name =3D FW_FILE_NAME_E1; - else if (CHIP_IS_E1H(bp)) + fw_file_name_v15 =3D FW_FILE_NAME_E1_V15; + } else if (CHIP_IS_E1H(bp)) { fw_file_name =3D FW_FILE_NAME_E1H; - else if (!CHIP_IS_E1x(bp)) + fw_file_name_v15 =3D FW_FILE_NAME_E1H_V15; + } else if (!CHIP_IS_E1x(bp)) { fw_file_name =3D FW_FILE_NAME_E2; - else { + fw_file_name_v15 =3D FW_FILE_NAME_E2_V15; + } else { BNX2X_ERR("Unsupported chip revision\n"); return -EINVAL; } + BNX2X_DEV_INFO("Loading %s\n", fw_file_name); =20 rc =3D request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); if (rc) { - BNX2X_ERR("Can't load firmware file %s\n", - fw_file_name); - goto request_firmware_exit; + BNX2X_DEV_INFO("Trying to load older fw %s\n", fw_file_name_v15); + + /* try to load prev version */ + rc =3D request_firmware(&bp->firmware, fw_file_name_v15, &bp->pdev->dev); + + if (rc) + goto request_firmware_exit; + + bp->fw_rev =3D BCM_5710_FW_REVISION_VERSION_V15; + } else { + bp->fw_cap |=3D FW_CAP_INVALIDATE_VF_FP_HSI; + bp->fw_rev =3D BCM_5710_FW_REVISION_VERSION; } =20 + bp->fw_major =3D BCM_5710_FW_MAJOR_VERSION; + bp->fw_minor =3D BCM_5710_FW_MINOR_VERSION; + bp->fw_eng =3D BCM_5710_FW_ENGINEERING_VERSION; + rc =3D bnx2x_check_firmware(bp); if (rc) { BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); @@ -13536,7 +13566,7 @@ request_firmware_exit: return rc; } =20 -static void bnx2x_release_firmware(struct bnx2x *bp) +void bnx2x_release_firmware(struct bnx2x *bp) { kfree(bp->init_ops_offsets); kfree(bp->init_ops); @@ -14053,6 +14083,7 @@ static int bnx2x_init_one(struct pci_dev return 0; =20 init_one_freemem: + bnx2x_release_firmware(bp); bnx2x_free_mem_bp(bp); =20 init_one_exit: From nobody Wed Jul 1 05:42:38 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E21A0C433EF for ; Thu, 27 Jan 2022 18:11:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239127AbiA0SLB (ORCPT ); Thu, 27 Jan 2022 13:11:01 -0500 Received: from dfw.source.kernel.org ([139.178.84.217]:47680 "EHLO dfw.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245255AbiA0SKW (ORCPT ); Thu, 27 Jan 2022 13:10:22 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7107761BC5; Thu, 27 Jan 2022 18:10:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2A988C340E4; Thu, 27 Jan 2022 18:10:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643307021; bh=/SpOvRAzSZuL3nSSYY7xGjur0CIUWNo9JKuuksvoas8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FreiJf06OcFR//a41Bjn8oEt0bAKex/WfL7DRWcfUOyZUPxu3DZUYZ4gpuPhnln5u POA5QEdAA/v617/FpvfEk6YKnnE8u++ZpB6AD288um2+6yD+ZyracaCoY5//jipdWt Ku/eV5Cp83Jpay+cvw8+IIdrvPrTI2Luac1ETh/4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , Manish Chopra , Prabhakar Kushwaha , Alok Prasad , Ariel Elior , "David S. Miller" Subject: [PATCH 5.10 3/6] bnx2x: Invalidate fastpath HSI version for VFs Date: Thu, 27 Jan 2022 19:09:19 +0100 Message-Id: <20220127180258.247298538@linuxfoundation.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220127180258.131170405@linuxfoundation.org> References: <20220127180258.131170405@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Manish Chopra commit 802d4d207e75d7208ff75adb712b556c1e91cf1c upstream Commit 0a6890b9b4df ("bnx2x: Utilize FW 7.13.15.0.") added validation for fastpath HSI versions for different client init which was not meant for SR-IOV VF clients, which resulted in firmware asserts when running VF clients with different fastpath HSI version. This patch along with the new firmware support in patch #1 fixes this behavior in order to not validate fastpath HSI version for the VFs. Fixes: 0a6890b9b4df ("bnx2x: Utilize FW 7.13.15.0.") Signed-off-by: Manish Chopra Signed-off-by: Prabhakar Kushwaha Signed-off-by: Alok Prasad Signed-off-by: Ariel Elior Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Tested-by: Florian Fainelli Tested-by: Fox Chen Tested-by: Guenter Roeck Tested-by: Linux Kernel Functional Testing Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Sudip Mukherjee --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -758,9 +758,18 @@ static void bnx2x_vf_igu_reset(struct bn =20 void bnx2x_vf_enable_access(struct bnx2x *bp, u8 abs_vfid) { + u16 abs_fid; + + abs_fid =3D FW_VF_HANDLE(abs_vfid); + /* set the VF-PF association in the FW */ - storm_memset_vf_to_pf(bp, FW_VF_HANDLE(abs_vfid), BP_FUNC(bp)); - storm_memset_func_en(bp, FW_VF_HANDLE(abs_vfid), 1); + storm_memset_vf_to_pf(bp, abs_fid, BP_FUNC(bp)); + storm_memset_func_en(bp, abs_fid, 1); + + /* Invalidate fp_hsi version for vfs */ + if (bp->fw_cap & FW_CAP_INVALIDATE_VF_FP_HSI) + REG_WR8(bp, BAR_XSTRORM_INTMEM + + XSTORM_ETH_FUNCTION_INFO_FP_HSI_VALID_E2_OFFSET(abs_fid), 0); =20 /* clear vf errors*/ bnx2x_vf_semi_clear_err(bp, abs_vfid); From nobody Wed Jul 1 05:42:38 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB9B5C433F5 for ; Thu, 27 Jan 2022 18:11:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245445AbiA0SLC (ORCPT ); Thu, 27 Jan 2022 13:11:02 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:59200 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245045AbiA0SK1 (ORCPT ); Thu, 27 Jan 2022 13:10:27 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 3470EB821B9; Thu, 27 Jan 2022 18:10:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E8D5C340E4; Thu, 27 Jan 2022 18:10:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643307025; bh=+4rfXOUddUEnmEEugWtPvn/EwrB7kCjCzy49CLtooMc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G29KN9tUinqj7x5OSGgTtEwGWPvEZaj2xVNoeyF8xHavw/Wb51v7Y8zfDB0mBQAKl TRJjjCxeuyhur6KNZLi8q6QTMkkIiUUnrS4I/lKT1jf1rTCRAD3Vfp2K4DJwnDmXkI 40w0VI+zZRb80P8ypg9PeeCToZJGQA4g2W9yvX9Q= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Guillaume Morin , "Paul E. McKenney" Subject: [PATCH 5.10 4/6] rcu: Tighten rcu_advance_cbs_nowake() checks Date: Thu, 27 Jan 2022 19:09:20 +0100 Message-Id: <20220127180258.275109635@linuxfoundation.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220127180258.131170405@linuxfoundation.org> References: <20220127180258.131170405@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Paul E. McKenney commit 614ddad17f22a22e035e2ea37a04815f50362017 upstream. Currently, rcu_advance_cbs_nowake() checks that a grace period is in progress, however, that grace period could end just after the check. This commit rechecks that a grace period is still in progress while holding the rcu_node structure's lock. The grace period cannot end while the current CPU's rcu_node structure's ->lock is held, thus avoiding false positives from the WARN_ON_ONCE(). As Daniel Vacek noted, it is not necessary for the rcu_node structure to have a CPU that has not yet passed through its quiescent state. Tested-by: Guillaume Morin Signed-off-by: Paul E. McKenney Signed-off-by: Greg Kroah-Hartman Tested-by: Florian Fainelli Tested-by: Fox Chen Tested-by: Guenter Roeck Tested-by: Linux Kernel Functional Testing Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Sudip Mukherjee --- kernel/rcu/tree.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -1581,10 +1581,11 @@ static void __maybe_unused rcu_advance_c struct rcu_data *rdp) { rcu_lockdep_assert_cblist_protected(rdp); - if (!rcu_seq_state(rcu_seq_current(&rnp->gp_seq)) || - !raw_spin_trylock_rcu_node(rnp)) + if (!rcu_seq_state(rcu_seq_current(&rnp->gp_seq)) || !raw_spin_trylock_rc= u_node(rnp)) return; - WARN_ON_ONCE(rcu_advance_cbs(rnp, rdp)); + // The grace period cannot end while we hold the rcu_node lock. + if (rcu_seq_state(rcu_seq_current(&rnp->gp_seq))) + WARN_ON_ONCE(rcu_advance_cbs(rnp, rdp)); raw_spin_unlock_rcu_node(rnp); } =20 From nobody Wed Jul 1 05:42:38 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C64C6C433FE for ; Thu, 27 Jan 2022 18:11:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245185AbiA0SLK (ORCPT ); Thu, 27 Jan 2022 13:11:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45322 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245165AbiA0SKd (ORCPT ); Thu, 27 Jan 2022 13:10:33 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C223FC0613EB; Thu, 27 Jan 2022 10:10:29 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6267061BBE; Thu, 27 Jan 2022 18:10:29 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 37B6DC340E4; Thu, 27 Jan 2022 18:10:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643307028; bh=opqOAvOwYYBDuTBW3kimmwB19Q6IwQ1e3r2Ikzu3mcc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IIWDvMHteOnqvyG9e7GRP/+akG35mHTkGKioNQZO40Uzal0kqWUmbIuGalj6uCHAw hKMmkKBNK1co85P0NupoP+PqzltJ7zWvLUTgh7odmiqKv8JkYdgKI0hmA1zBzXNMoI HIuBbHaTribUOUPhe2NNIk+hCgm9r3ptyaTwwkFM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, David Matlack , Sean Christopherson , Paolo Bonzini Subject: [PATCH 5.10 5/6] KVM: x86/mmu: Fix write-protection of PTs mapped by the TDP MMU Date: Thu, 27 Jan 2022 19:09:21 +0100 Message-Id: <20220127180258.306175303@linuxfoundation.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220127180258.131170405@linuxfoundation.org> References: <20220127180258.131170405@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: David Matlack commit 7c8a4742c4abe205ec9daf416c9d42fd6b406e8e upstream. When the TDP MMU is write-protection GFNs for page table protection (as opposed to for dirty logging, or due to the HVA not being writable), it checks if the SPTE is already write-protected and if so skips modifying the SPTE and the TLB flush. This behavior is incorrect because it fails to check if the SPTE is write-protected for page table protection, i.e. fails to check that MMU-writable is '0'. If the SPTE was write-protected for dirty logging but not page table protection, the SPTE could locklessly be made writable, and vCPUs could still be running with writable mappings cached in their TLB. Fix this by only skipping setting the SPTE if the SPTE is already write-protected *and* MMU-writable is already clear. Technically, checking only MMU-writable would suffice; a SPTE cannot be writable without MMU-writable being set. But check both to be paranoid and because it arguably yields more readable code. Fixes: 46044f72c382 ("kvm: x86/mmu: Support write protection for nesting in= tdp MMU") Cc: stable@vger.kernel.org Signed-off-by: David Matlack Message-Id: <20220113233020.3986005-2-dmatlack@google.com> Reviewed-by: Sean Christopherson Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman Tested-by: Florian Fainelli Tested-by: Fox Chen Tested-by: Guenter Roeck Tested-by: Linux Kernel Functional Testing Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Sudip Mukherjee --- arch/x86/kvm/mmu/tdp_mmu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1130,12 +1130,12 @@ static bool write_protect_gfn(struct kvm bool spte_set =3D false; =20 tdp_root_for_each_leaf_pte(iter, root, gfn, gfn + 1) { - if (!is_writable_pte(iter.old_spte)) - break; - new_spte =3D iter.old_spte & ~(PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE); =20 + if (new_spte =3D=3D iter.old_spte) + break; + tdp_mmu_set_spte(kvm, &iter, new_spte); spte_set =3D true; } From nobody Wed Jul 1 05:42:38 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5CBE3C4332F for ; Thu, 27 Jan 2022 18:11:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245369AbiA0SLL (ORCPT ); Thu, 27 Jan 2022 13:11:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244883AbiA0SKd (ORCPT ); Thu, 27 Jan 2022 13:10:33 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB6BFC061748; Thu, 27 Jan 2022 10:10:32 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7946E61CFC; Thu, 27 Jan 2022 18:10:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4ECCEC340E8; Thu, 27 Jan 2022 18:10:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643307031; bh=hnC+WHQSB5Y9GOv0QCFpDjFeMVtgDx2Tl+exIvMj6zU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=azVoONjBdj3z2bqsx9Wd5d0X8in+8RO60o0VMxGSF+wrgLU+sUkI8ri2efzhU/UB4 WaLv3cy6fHyJVrpVUcQiLj9cTPsLe/wSQX72VGpOFeQPU1JafoLw76q5ohkUPNoK+O SKGQoj1f3naA3H+LaqynoWvCVhEhgk1s2fSJEzqU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Linus Torvalds , Jan Kara Subject: [PATCH 5.10 6/6] select: Fix indefinitely sleeping task in poll_schedule_timeout() Date: Thu, 27 Jan 2022 19:09:22 +0100 Message-Id: <20220127180258.338319714@linuxfoundation.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220127180258.131170405@linuxfoundation.org> References: <20220127180258.131170405@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Jan Kara commit 68514dacf2715d11b91ca50d88de047c086fea9c upstream. A task can end up indefinitely sleeping in do_select() -> poll_schedule_timeout() when the following race happens: TASK1 (thread1) TASK2 TASK1 (thread2) do_select() setup poll_wqueues table with 'fd' write data to 'fd' pollwake() table->triggered =3D 1 closes 'fd' thread1 is waiting for poll_schedule_timeout() - sees table->triggered table->triggered =3D 0 return -EINTR loop back in do_select() But at this point when TASK1 loops back, the fdget() in the setup of poll_wqueues fails. So now so we never find 'fd' is ready for reading and sleep in poll_schedule_timeout() indefinitely. Treat an fd that got closed as a fd on which some event happened. This makes sure cannot block indefinitely in do_select(). Another option would be to return -EBADF in this case but that has a potential of subtly breaking applications that excercise this behavior and it happens to work for them. So returning fd as active seems like a safer choice. Suggested-by: Linus Torvalds CC: stable@vger.kernel.org Signed-off-by: Jan Kara Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Tested-by: Florian Fainelli Tested-by: Fox Chen Tested-by: Guenter Roeck Tested-by: Linux Kernel Functional Testing Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Sudip Mukherjee --- fs/select.c | 63 +++++++++++++++++++++++++++++++------------------------= ----- 1 file changed, 33 insertions(+), 30 deletions(-) --- a/fs/select.c +++ b/fs/select.c @@ -458,9 +458,11 @@ get_max: return max; } =20 -#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLL= ERR) -#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR) -#define POLLEX_SET (EPOLLPRI) +#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLL= ERR |\ + EPOLLNVAL) +#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR |\ + EPOLLNVAL) +#define POLLEX_SET (EPOLLPRI | EPOLLNVAL) =20 static inline void wait_key_set(poll_table *wait, unsigned long in, unsigned long out, unsigned long bit, @@ -527,6 +529,7 @@ static int do_select(int n, fd_set_bits break; if (!(bit & all_bits)) continue; + mask =3D EPOLLNVAL; f =3D fdget(i); if (f.file) { wait_key_set(wait, in, out, bit, @@ -534,34 +537,34 @@ static int do_select(int n, fd_set_bits mask =3D vfs_poll(f.file, wait); =20 fdput(f); - if ((mask & POLLIN_SET) && (in & bit)) { - res_in |=3D bit; - retval++; - wait->_qproc =3D NULL; - } - if ((mask & POLLOUT_SET) && (out & bit)) { - res_out |=3D bit; - retval++; - wait->_qproc =3D NULL; - } - if ((mask & POLLEX_SET) && (ex & bit)) { - res_ex |=3D bit; - retval++; - wait->_qproc =3D NULL; - } - /* got something, stop busy polling */ - if (retval) { - can_busy_loop =3D false; - busy_flag =3D 0; - - /* - * only remember a returned - * POLL_BUSY_LOOP if we asked for it - */ - } else if (busy_flag & mask) - can_busy_loop =3D true; - } + if ((mask & POLLIN_SET) && (in & bit)) { + res_in |=3D bit; + retval++; + wait->_qproc =3D NULL; + } + if ((mask & POLLOUT_SET) && (out & bit)) { + res_out |=3D bit; + retval++; + wait->_qproc =3D NULL; + } + if ((mask & POLLEX_SET) && (ex & bit)) { + res_ex |=3D bit; + retval++; + wait->_qproc =3D NULL; + } + /* got something, stop busy polling */ + if (retval) { + can_busy_loop =3D false; + busy_flag =3D 0; + + /* + * only remember a returned + * POLL_BUSY_LOOP if we asked for it + */ + } else if (busy_flag & mask) + can_busy_loop =3D true; + } if (res_in) *rinp =3D res_in;