5.15.61-rc1 review
Subsystems (11)
Greg Kroah-Hartman
maintainerPATCH 692/779 crypto: blake2s - remove shash module
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit 2d16803c562ecc644803d42ba98a8e0aef9c014e ]
BLAKE2s has no currently known use as an shash. Just remove all of this unnecessary plumbing. Removing this shash was something we talked about back when we were making BLAKE2s a built-in, but I simply never got around to doing it. So this completes that project.
Importantly, this fixs a bug in which the lib code depends on crypto_simd_disabled_for_test, causing linker errors.
Also add more alignment tests to the selftests and compare SIMD and non-SIMD compression functions, to make up for what we lose from testmgr.c.
--- arch/arm/crypto/Kconfig | 2 +- arch/arm/crypto/Makefile | 4 +- arch/arm/crypto/blake2s-shash.c | 75 ----------- arch/x86/crypto/Makefile | 4 +- arch/x86/crypto/blake2s-glue.c | 3 +- arch/x86/crypto/blake2s-shash.c | 77 ----------- crypto/Kconfig | 20 +-- crypto/Makefile | 1 - crypto/blake2s_generic.c | 75 ----------- crypto/tcrypt.c | 12 -- crypto/testmgr.c | 24 ---- crypto/testmgr.h | 217 ------------------------------ include/crypto/internal/blake2s.h | 108 --------------- lib/crypto/blake2s-selftest.c | 41 ++++++ lib/crypto/blake2s.c | 37 ++++- 15 files changed, 76 insertions(+), 624 deletions(-) delete mode 100644 arch/arm/crypto/blake2s-shash.c delete mode 100644 arch/x86/crypto/blake2s-shash.c delete mode 100644 crypto/blake2s_generic.c
arch/arm/crypto/Kconfig +1 -1
@@ -63,7 +63,7 @@ config CRYPTO_SHA512_ARM using optimized ARM assembler and NEON, when available. config CRYPTO_BLAKE2S_ARM - tristate "BLAKE2s digest algorithm (ARM)" + bool "BLAKE2s digest algorithm (ARM)" select CRYPTO_ARCH_HAVE_LIB_BLAKE2S help BLAKE2s digest algorithm optimized with ARM scalar instructions. This
arch/arm/crypto/Makefile +1 -3
@@ -9,8 +9,7 @@ obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o obj-$(CONFIG_CRYPTO_SHA256_ARM) += sha256-arm.o obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o -obj-$(CONFIG_CRYPTO_BLAKE2S_ARM) += blake2s-arm.o -obj-$(if $(CONFIG_CRYPTO_BLAKE2S_ARM),y) += libblake2s-arm.o +obj-$(CONFIG_CRYPTO_BLAKE2S_ARM) += libblake2s-arm.o obj-$(CONFIG_CRYPTO_BLAKE2B_NEON) += blake2b-neon.o obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha-neon.o obj-$(CONFIG_CRYPTO_POLY1305_ARM) += poly1305-arm.o
@@ -32,7 +31,6 @@ sha256-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha256_neon_glue.o sha256-arm-y := sha256-core.o sha256_glue.o $(sha256-arm-neon-y) sha512-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha512-neon-glue.o sha512-arm-y := sha512-core.o sha512-glue.o $(sha512-arm-neon-y) -blake2s-arm-y := blake2s-shash.o libblake2s-arm-y:= blake2s-core.o blake2s-glue.o blake2b-neon-y := blake2b-neon-core.o blake2b-neon-glue.o sha1-arm-ce-y := sha1-ce-core.o sha1-ce-glue.o
arch/arm/crypto/blake2s-shash.c deleted +0 -75
75 lines not on this page · raw message
arch/x86/crypto/Makefile +1 -3
@@ -61,9 +61,7 @@ sha256-ssse3-$(CONFIG_AS_SHA256_NI) += sha256_ni_asm.o obj-$(CONFIG_CRYPTO_SHA512_SSSE3) += sha512-ssse3.o sha512-ssse3-y := sha512-ssse3-asm.o sha512-avx-asm.o sha512-avx2-asm.o sha512_ssse3_glue.o -obj-$(CONFIG_CRYPTO_BLAKE2S_X86) += blake2s-x86_64.o -blake2s-x86_64-y := blake2s-shash.o -obj-$(if $(CONFIG_CRYPTO_BLAKE2S_X86),y) += libblake2s-x86_64.o +obj-$(CONFIG_CRYPTO_BLAKE2S_X86) += libblake2s-x86_64.o libblake2s-x86_64-y := blake2s-core.o blake2s-glue.o obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
arch/x86/crypto/blake2s-glue.c +1 -2
@@ -4,7 +4,6 @@*/ #include <crypto/internal/blake2s.h> -#include <crypto/internal/simd.h> #include <linux/types.h> #include <linux/jump_label.h>
@@ -33,7 +32,7 @@ void blake2s_compress(struct blake2s_state *state, const u8 *block,/* SIMD disables preemption, so relax after processing each page. */ BUILD_BUG_ON (SZ_4K /BLAKE2S_BLOCK_SIZE <8 ); -if (!static_branch_likely (&blake2s_use_ssse3) || !crypto_simd_usable ()) { +if (!static_branch_likely (&blake2s_use_ssse3) || !may_use_simd ()) {blake2s_compress_generic (state, block, nblocks, inc);return ; }
arch/x86/crypto/blake2s-shash.c deleted +0 -77
77 lines not on this page · raw message
crypto/Kconfig +1 -19
@@ -684,26 +684,8 @@ config CRYPTO_BLAKE2B See https://blake2.net for further information. -config CRYPTO_BLAKE2S - tristate "BLAKE2s digest algorithm" - select CRYPTO_LIB_BLAKE2S_GENERIC - select CRYPTO_HASH - help - Implementation of cryptographic hash function BLAKE2s - optimized for 8-32bit platforms and can produce digests of any size - between 1 to 32. The keyed hash is also implemented. - - This module provides the following algorithms: - - - blake2s-128 - - blake2s-160 - - blake2s-224 - - blake2s-256 - - See https://blake2.net for further information. - config CRYPTO_BLAKE2S_X86 - tristate "BLAKE2s digest algorithm (x86 accelerated version)" + bool "BLAKE2s digest algorithm (x86 accelerated version)" depends on X86 && 64BIT select CRYPTO_LIB_BLAKE2S_GENERIC select CRYPTO_ARCH_HAVE_LIB_BLAKE2S
crypto/Makefile +0 -1
@@ -83,7 +83,6 @@ obj-$(CONFIG_CRYPTO_STREEBOG) += streebog_generic.o obj-$(CONFIG_CRYPTO_WP512) += wp512.o CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149 obj-$(CONFIG_CRYPTO_BLAKE2B) += blake2b_generic.o -obj-$(CONFIG_CRYPTO_BLAKE2S) += blake2s_generic.o obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o obj-$(CONFIG_CRYPTO_ECB) += ecb.o obj-$(CONFIG_CRYPTO_CBC) += cbc.o
crypto/blake2s_generic.c deleted +0 -75
75 lines not on this page · raw message
crypto/tcrypt.c +0 -12
@@ -1863,10 +1863,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) ret +=tcrypt_test ("rmd160" );break ; -case 41 : - ret +=tcrypt_test ("blake2s-256" ); -break ; -case 42 : ret +=tcrypt_test ("blake2b-512" );break ;
@@ -2434,10 +2430,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)test_hash_speed ("rmd160" , sec, generic_hash_speed_template);if (mode >300 && mode <400 )break ; fallthrough; -case 316 : -test_hash_speed ("blake2s-256" , sec, generic_hash_speed_template); -if (mode >300 && mode <400 )break ; - fallthrough;case 317 :test_hash_speed ("blake2b-512" , sec, generic_hash_speed_template);if (mode >300 && mode <400 )break ;
@@ -2546,10 +2538,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)test_ahash_speed ("rmd160" , sec, generic_hash_speed_template);if (mode >400 && mode <500 )break ; fallthrough; -case 416 : -test_ahash_speed ("blake2s-256" , sec, generic_hash_speed_template); -if (mode >400 && mode <500 )break ; - fallthrough;case 417 :test_ahash_speed ("blake2b-512" , sec, generic_hash_speed_template);if (mode >400 && mode <500 )break ;
crypto/testmgr.c +0 -24
@@ -4329,30 +4329,6 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .hash = __VECS(blake2b_512_tv_template) } - }, { - .alg = "blake2s-128", - .test = alg_test_hash, - .suite = { - .hash = __VECS(blakes2s_128_tv_template) - } - }, { - .alg = "blake2s-160", - .test = alg_test_hash, - .suite = { - .hash = __VECS(blakes2s_160_tv_template) - } - }, { - .alg = "blake2s-224", - .test = alg_test_hash, - .suite = { - .hash = __VECS(blakes2s_224_tv_template) - } - }, { - .alg = "blake2s-256", - .test = alg_test_hash, - .suite = { - .hash = __VECS(blakes2s_256_tv_template) - } }, { .alg = "cbc(aes)", .test = alg_test_skcipher,
crypto/testmgr.h +0 -217
221 lines not on this page · raw message
include/crypto/internal/blake2s.h +0 -108
118 lines not on this page · raw message
lib/crypto/blake2s-selftest.c +41 -0
52 lines not on this page · raw message
lib/crypto/blake2s.c +30 -7
@@ -16,16 +16,44 @@#include <linux/init.h> #include <linux/bug.h> +static inline void blake2s_set_lastblock (struct blake2s_state *state) +{ + state->f[0 ] =-1 ; +} +void blake2s_update (struct blake2s_state *state,const u8 *in,size_t inlen) { -__blake2s_update (state, in, inlen, false); +const size_t fill =BLAKE2S_BLOCK_SIZE - state->buflen; + +if (unlikely (!inlen)) +return ; +if (inlen > fill) { +memcpy (state->buf + state->buflen, in, fill); +blake2s_compress (state, state->buf,1 ,BLAKE2S_BLOCK_SIZE ); + state->buflen =0 ; + in += fill; + inlen -= fill; + } +if (inlen >BLAKE2S_BLOCK_SIZE ) { +const size_t nblocks =DIV_ROUND_UP (inlen,BLAKE2S_BLOCK_SIZE ); +blake2s_compress (state, in, nblocks -1 ,BLAKE2S_BLOCK_SIZE ); + in +=BLAKE2S_BLOCK_SIZE * (nblocks -1 ); + inlen -=BLAKE2S_BLOCK_SIZE * (nblocks -1 ); + } +memcpy (state->buf + state->buflen, in, inlen); + state->buflen += inlen; }EXPORT_SYMBOL (blake2s_update);void blake2s_final (struct blake2s_state *state,u8 *out) {WARN_ON (IS_ENABLED (DEBUG ) && !out); -__blake2s_final (state, out, false); +blake2s_set_lastblock (state); +memset (state->buf + state->buflen,0 , +BLAKE2S_BLOCK_SIZE - state->buflen);/* Padding */ +blake2s_compress (state, state->buf,1 , state->buflen); +cpu_to_le32_array (state->h,ARRAY_SIZE (state->h)); +memcpy (out, state->h, state->outlen);memzero_explicit (state,sizeof (*state)); }EXPORT_SYMBOL (blake2s_final);
@@ -38,12 +66,7 @@ static int __init blake2s_mod_init(void)return 0 ; } -static void __exit blake2s_mod_exit(void) -{ -} -module_init (blake2s_mod_init); -module_exit (blake2s_mod_exit);MODULE_LICENSE ("GPL v2" );MODULE_DESCRIPTION ("BLAKE2s hash function" );MODULE_AUTHOR ("Jason A. Donenfeld <[email protected]>" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 693/779 drm/dp/mst: Read the extended DPCD capabilities during system resume
In reply to Greg Kroah-HartmanFrom: Imre Deak <[email protected]>
[ Upstream commit 7a710a8bc909313951eb9252d8419924c771d7c2 ]
The WD22TB4 Thunderbolt dock at least will revert its DP_MAX_LINK_RATE from HBR3 to HBR2 after system suspend/resume if the DP_DP13_DPCD_REV registers are not read subsequently also as required.
Fix this by reading DP_DP13_DPCD_REV registers as well, matching what is done during connector detection. While at it also fix up the same call in drm_dp_mst_dump_topology().
--- drivers/gpu/drm/drm_dp_mst_topology.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/gpu/drm/drm_dp_mst_topology.c +2 -5
@@ -3860,9 +3860,7 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,if (!mgr->mst_primary) goto out_fail; - ret =drm_dp_dpcd_read (mgr->aux,DP_DPCD_REV , mgr->dpcd, -DP_RECEIVER_CAP_SIZE ); -if (ret !=DP_RECEIVER_CAP_SIZE ) { +if (drm_dp_read_dpcd_caps (mgr->aux, mgr->dpcd) <0 ) {drm_dbg_kms (mgr->dev,"dpcd read failed - undocked during suspend?\n" ); goto out_fail; }
@@ -4894,8 +4892,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,u8 buf[DP_PAYLOAD_TABLE_SIZE ];int ret; - ret =drm_dp_dpcd_read (mgr->aux,DP_DPCD_REV , buf,DP_RECEIVER_CAP_SIZE ); -if (ret) { +if (drm_dp_read_dpcd_caps (mgr->aux, buf) <0 ) {seq_printf (m,"dpcd read failed\n" ); goto out; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 694/779 drm/vc4: drv: Adopt the dma configuration from the HVS or V3D component
In reply to Greg Kroah-HartmanFrom: Dave Stevenson <[email protected]>
[ Upstream commit da8e393e23efb60eba8959856c7df88f9859f6eb ]
vc4_drv isn't necessarily under the /soc node in DT as it is a virtual device, but it is the one that does the allocations. The DMA addresses are consumed by primarily the HVS or V3D, and those require VideoCore cache alias address mapping, and so will be under /soc.
During probe find the a suitable device node for HVS or V3D, and adopt the DMA configuration of that node.
--- drivers/gpu/drm/vc4/vc4_drv.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
drivers/gpu/drm/vc4/vc4_drv.c +19 -0
@@ -214,6 +214,15 @@ static void vc4_match_add_drivers(struct device *dev, } } +const struct of_device_id vc4_dma_range_matches[] = { + { .compatible ="brcm,bcm2711-hvs" }, + { .compatible ="brcm,bcm2835-hvs" }, + { .compatible ="brcm,bcm2835-v3d" }, + { .compatible ="brcm,cygnus-v3d" }, + { .compatible ="brcm,vc4-v3d" }, + {} +}; +static int vc4_drm_bind (struct device *dev) {struct platform_device *pdev =to_platform_device (dev);
@@ -231,6 +240,16 @@ static int vc4_drm_bind(struct device *dev) vc4_drm_driver.driver_features &= ~DRIVER_RENDER ;of_node_put (node); + node =of_find_matching_node_and_match (NULL , vc4_dma_range_matches, +NULL ); +if (node) { + ret =of_dma_configure (dev, node, true); +of_node_put (node); + +if (ret) +return ret; + } + vc4 = devm_drm_dev_alloc(dev, &vc4_drm_driver, struct vc4_dev, base);if (IS_ERR (vc4))return PTR_ERR (vc4);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 695/779 usbnet: smsc95xx: Dont clear read-only PHY interrupt
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
[ Upstream commit 3108871f19221372b251f7da1ac38736928b5b3a ]
Upon receiving data from the Interrupt Endpoint, the SMSC LAN95xx driver attempts to clear the signaled interrupts by writing "all ones" to the Interrupt Status Register.
However the driver only ever enables a single type of interrupt, namely the PHY Interrupt. And according to page 119 of the LAN950x datasheet, its bit in the Interrupt Status Register is read-only. There's no other way to clear it than in a separate PHY register:
Consequently, writing "all ones" to the Interrupt Status Register is pointless and can be dropped.
--- drivers/net/usb/smsc95xx.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/net/usb/smsc95xx.c +0 -4
@@ -570,10 +570,6 @@ static int smsc95xx_link_reset(struct usbnet *dev)unsigned long flags;int ret; - ret =smsc95xx_write_reg (dev,INT_STS ,INT_STS_CLEAR_ALL_ ); -if (ret <0 ) -return ret; -spin_lock_irqsave (&pdata->mac_cr_lock, flags);if (pdata->phydev->duplex !=DUPLEX_FULL ) { pdata->mac_cr &= ~MAC_CR_FDPX_ ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 696/779 usbnet: smsc95xx: Avoid link settings race on interrupt reception
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
[ Upstream commit 8960f878e39fadc03d74292a6731f1e914cf2019 ]
When a PHY interrupt is signaled, the SMSC LAN95xx driver updates the MAC full duplex mode and PHY flow control registers based on cached data in struct phy_device:
smsc95xx_status() # raises EVENT_LINK_RESET
usbnet_deferred_kevent()
smsc95xx_link_reset() # uses cached data in phydev
Simultaneously, phylib polls link status once per second and updates that cached data:
phy_state_machine()
phy_check_link_status()
phy_read_status()
lan87xx_read_status()
genphy_read_status() # updates cached data in phydev
If smsc95xx_link_reset() wins the race against genphy_read_status(), the registers may be updated based on stale data.
E.g. if the link was previously down, phydev->duplex is set to DUPLEX_UNKNOWN and that's what smsc95xx_link_reset() will use, even though genphy_read_status() may update it to DUPLEX_FULL afterwards.
PHY interrupts are currently only enabled on suspend to trigger wakeup, so the impact of the race is limited, but we're about to enable them perpetually.
Avoid the race by delaying execution of smsc95xx_link_reset() until phy_state_machine() has done its job and calls back via smsc95xx_handle_link_change().
Signaling EVENT_LINK_RESET on wakeup is not necessary because phylib picks up link status changes through polling. So drop the declaration of a ->link_reset() callback.
Note that the semicolon on a line by itself added in smsc95xx_status() is a placeholder for a function call which will be added in a subsequent commit. That function call will actually handle the INT_ENP_PHY_INT_ interrupt.
--- drivers/net/usb/smsc95xx.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/net/usb/smsc95xx.c +9 -7
@@ -564,7 +564,7 @@ static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev)return smsc95xx_write_reg (dev,AFC_CFG , afc_cfg); } -static int smsc95xx_link_reset (struct usbnet *dev) +static void smsc95xx_mac_update_fullduplex (struct usbnet *dev) {struct smsc95xx_priv *pdata = dev->driver_priv;unsigned long flags;
@@ -581,14 +581,16 @@ static int smsc95xx_link_reset(struct usbnet *dev)spin_unlock_irqrestore (&pdata->mac_cr_lock, flags); ret =smsc95xx_write_reg (dev,MAC_CR , pdata->mac_cr); -if (ret <0 ) -return ret; +if (ret <0 ) { +if (ret != -ENODEV ) +netdev_warn (dev->net, +"Error updating MAC full duplex mode\n" ); +return ; + } ret =smsc95xx_phy_update_flowcontrol (dev);if (ret <0 )netdev_warn (dev->net,"Error updating PHY flow control\n" ); - -return ret; }static void smsc95xx_status (struct usbnet *dev,struct urb *urb)
@@ -605,7 +607,7 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)netif_dbg (dev, link, dev->net,"intdata: 0x%08X\n" , intdata);if (intdata &INT_ENP_PHY_INT_ ) -usbnet_defer_kevent (dev,EVENT_LINK_RESET ); + ;else netdev_warn (dev->net,"unexpected interrupt, intdata=0x%08X\n" , intdata);
@@ -1062,6 +1064,7 @@ static void smsc95xx_handle_link_change(struct net_device *net)struct usbnet *dev =netdev_priv (net);phy_print_status (net->phydev); +smsc95xx_mac_update_fullduplex (dev);usbnet_defer_kevent (dev,EVENT_LINK_CHANGE ); }
@@ -1967,7 +1970,6 @@ static const struct driver_info smsc95xx_info = { .description = "smsc95xx USB 2.0 Ethernet", .bind = smsc95xx_bind, .unbind = smsc95xx_unbind, - .link_reset = smsc95xx_link_reset, .reset = smsc95xx_reset, .check_connect = smsc95xx_start_phy, .stop = smsc95xx_stop,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 697/779 usbnet: smsc95xx: Forward PHY interrupts to PHY driver to avoid polling
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
[ Upstream commit 1ce8b37241ed291af56f7a49bbdbf20c08728e88 ]
Link status of SMSC LAN95xx chips is polled once per second, even though they're capable of signaling PHY interrupts through the MAC layer.
Forward those interrupts to the PHY driver to avoid polling. Benefits are reduced bus traffic, reduced CPU overhead and quicker interface bringup.
Polling was introduced in 2016 by commit d69d16949346 ("usbnet:
smsc95xx: fix link detection for disabled autonegotiation"). Back then, the LAN95xx driver neglected to enable the ENERGYON interrupt, hence couldn't detect link-up events when auto-negotiation was disabled. The proper solution would have been to enable the ENERGYON interrupt instead of polling.
Since then, PHY handling was moved from the LAN95xx driver to the SMSC PHY driver with commit 05b35e7eb9a1 ("smsc95xx: add phylib support"). That PHY driver is capable of link detection with auto-negotiation disabled because it enables the ENERGYON interrupt.
Note that signaling interrupts through the MAC layer not only works with the integrated PHY, but also with an external PHY, provided its interrupt pin is attached to LAN95xx's nPHY_INT pin.
In the unlikely event that the interrupt pin of an external PHY is attached to a GPIO of the SoC (or not connected at all), the driver can be amended to retrieve the irq from the PHY's of_node.
To forward PHY interrupts to phylib, it is not sufficient to call phy_mac_interrupt(). Instead, the PHY's interrupt handler needs to run so that PHY interrupts are cleared. That's because according to page 119 of the LAN950x datasheet, "The source of this interrupt is a level. The interrupt persists until it is cleared in the PHY."
Therefore, create an IRQ domain with a single IRQ for the PHY. In the future, the IRQ domain may be extended to support the 11 GPIOs on the LAN95xx.
Normally the PHY interrupt should be masked until the PHY driver has cleared it. However masking requires a (sleeping) USB transaction and interrupts are received in (non-sleepable) softirq context. I decided not to mask the interrupt at all (by using the dummy_irq_chip's noop ->irq_mask() callback): The USB interrupt endpoint is polled in 1 msec intervals and normally that's sufficient to wake the PHY driver's IRQ thread and have it clear the interrupt. If it does take longer, worst thing that can happen is the IRQ thread is woken again. No big deal.
Because PHY interrupts are now perpetually enabled, there's no need to selectively enable them on suspend. So remove all invocations of smsc95xx_enable_phy_wakeup_interrupts().
In smsc95xx_resume(), move the call of phy_init_hw() before usbnet_resume() (which restarts the status URB) to ensure that the PHY is fully initialized when an interrupt is handled.
--- drivers/net/usb/smsc95xx.c | 113 ++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 52 deletions(-)
drivers/net/usb/smsc95xx.c +61 -52
@@ -18,6 +18,8 @@#include <linux/usb/usbnet.h> #include <linux/slab.h> #include <linux/of_net.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> #include <linux/mdio.h> #include <linux/phy.h> #include "smsc95xx.h"
@@ -51,6 +53,9 @@#define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) +#define SMSC95XX_NR_IRQS (1)/* raise to 12 for GPIOs */ +#define PHY_HWIRQ (SMSC95XX_NR_IRQS - 1) +struct smsc95xx_priv {u32 mac_cr;u32 hash_hi;
@@ -59,6 +64,9 @@ struct smsc95xx_priv {spinlock_t mac_cr_lock;u8 features;u8 suspend_flags; +struct irq_chip irqchip; +struct irq_domain *irqdomain; +struct fwnode_handle *irqfwnode;struct mii_bus *mdiobus;struct phy_device *phydev; };
@@ -595,6 +603,8 @@ static void smsc95xx_mac_update_fullduplex(struct usbnet *dev)static void smsc95xx_status (struct usbnet *dev,struct urb *urb) { +struct smsc95xx_priv *pdata = dev->driver_priv; +unsigned long flags;u32 intdata;if (urb->actual_length !=4 ) {
@@ -606,11 +616,15 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb) intdata =get_unaligned_le32 (urb->transfer_buffer);netif_dbg (dev, link, dev->net,"intdata: 0x%08X\n" , intdata); +local_irq_save (flags); +if (intdata &INT_ENP_PHY_INT_ ) - ; +generic_handle_domain_irq (pdata->irqdomain,PHY_HWIRQ );else netdev_warn (dev->net,"unexpected interrupt, intdata=0x%08X\n" , intdata); + +local_irq_restore (flags); }/* Enable or disable Tx & Rx checksum offload engines */
@@ -1072,8 +1086,9 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) {struct smsc95xx_priv *pdata;bool is_internal_phy; +char usb_path[64 ]; +int ret, phy_irq;u32 val; -int ret; printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
@@ -1113,10 +1128,38 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)if (ret) goto free_pdata; +/* create irq domain for use by PHY driver and GPIO consumers */ +usb_make_path (dev->udev, usb_path,sizeof (usb_path)); + pdata->irqfwnode =irq_domain_alloc_named_fwnode (usb_path); +if (!pdata->irqfwnode) { + ret = -ENOMEM ; + goto free_pdata; + } + + pdata->irqdomain =irq_domain_create_linear (pdata->irqfwnode, +SMSC95XX_NR_IRQS , + &irq_domain_simple_ops, + pdata); +if (!pdata->irqdomain) { + ret = -ENOMEM ; + goto free_irqfwnode; + } + + phy_irq =irq_create_mapping (pdata->irqdomain,PHY_HWIRQ ); +if (!phy_irq) { + ret = -ENOENT ; + goto remove_irqdomain; + } + + pdata->irqchip = dummy_irq_chip; + pdata->irqchip.name =SMSC_CHIPNAME ; +irq_set_chip_and_handler_name (phy_irq, &pdata->irqchip, + handle_simple_irq,"phy" ); + pdata->mdiobus =mdiobus_alloc ();if (!pdata->mdiobus) { ret = -ENOMEM ; - goto free_pdata; + goto dispose_irq; } ret =smsc95xx_read_reg (dev,HW_CFG , &val);
@@ -1149,6 +1192,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) goto unregister_mdio; } + pdata->phydev->irq = phy_irq; pdata->phydev->is_internal = is_internal_phy;/* detect device revision as different features may be available */
@@ -1191,6 +1235,15 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) free_mdio:mdiobus_free (pdata->mdiobus); +dispose_irq: +irq_dispose_mapping (phy_irq); + +remove_irqdomain: +irq_domain_remove (pdata->irqdomain); + +free_irqfwnode: +irq_domain_free_fwnode (pdata->irqfwnode); + free_pdata:kfree (pdata);return ret;
@@ -1203,6 +1256,9 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)phy_disconnect (dev->net->phydev);mdiobus_unregister (pdata->mdiobus);mdiobus_free (pdata->mdiobus); +irq_dispose_mapping (irq_find_mapping (pdata->irqdomain,PHY_HWIRQ )); +irq_domain_remove (pdata->irqdomain); +irq_domain_free_fwnode (pdata->irqfwnode);netif_dbg (dev, ifdown, dev->net,"free pdata\n" );kfree (pdata); }
@@ -1227,29 +1283,6 @@ static u32 smsc_crc(const u8 *buffer, size_t len, int filter)return crc << ((filter %2 ) *16 ); } -static int smsc95xx_enable_phy_wakeup_interrupts (struct usbnet *dev,u16 mask) -{ -int ret; - -netdev_dbg (dev->net,"enabling PHY wakeup interrupts\n" ); - -/* read to clear */ - ret =smsc95xx_mdio_read_nopm (dev,PHY_INT_SRC ); -if (ret <0 ) -return ret; - -/* enable interrupt source */ - ret =smsc95xx_mdio_read_nopm (dev,PHY_INT_MASK ); -if (ret <0 ) -return ret; - - ret |= mask; - -smsc95xx_mdio_write_nopm (dev,PHY_INT_MASK , ret); - -return 0 ; -} -static int smsc95xx_link_ok_nopm (struct usbnet *dev) {int ret;
@@ -1416,7 +1449,6 @@ static int smsc95xx_enter_suspend3(struct usbnet *dev)static int smsc95xx_autosuspend (struct usbnet *dev,u32 link_up) {struct smsc95xx_priv *pdata = dev->driver_priv; -int ret;if (!netif_running (dev->net)) {/* interface is ifconfig down so fully power down hw */
@@ -1435,27 +1467,10 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) }netdev_dbg (dev->net,"autosuspend entering SUSPEND1\n" ); - -/* enable PHY wakeup events for if cable is attached */ - ret =smsc95xx_enable_phy_wakeup_interrupts (dev, -PHY_INT_MASK_ANEG_COMP_ ); -if (ret <0 ) { -netdev_warn (dev->net,"error enabling PHY wakeup ints\n" ); -return ret; - } -netdev_info (dev->net,"entering SUSPEND1 mode\n" );return smsc95xx_enter_suspend1 (dev); } -/* enable PHY wakeup events so we remote wakeup if cable is pulled */ - ret =smsc95xx_enable_phy_wakeup_interrupts (dev, -PHY_INT_MASK_LINK_DOWN_ ); -if (ret <0 ) { -netdev_warn (dev->net,"error enabling PHY wakeup ints\n" ); -return ret; - } -netdev_dbg (dev->net,"autosuspend entering SUSPEND3\n" );return smsc95xx_enter_suspend3 (dev); }
@@ -1521,13 +1536,6 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) }if (pdata->wolopts &WAKE_PHY ) { - ret =smsc95xx_enable_phy_wakeup_interrupts (dev, - (PHY_INT_MASK_ANEG_COMP_ |PHY_INT_MASK_LINK_DOWN_ )); -if (ret <0 ) { -netdev_warn (dev->net,"error enabling PHY wakeup ints\n" ); - goto done; - } -/* if link is down then configure EDPD and enter SUSPEND1, * otherwise enter SUSPEND0 below */
@@ -1761,11 +1769,12 @@ static int smsc95xx_resume(struct usb_interface *intf)return ret; } +phy_init_hw (pdata->phydev); + ret =usbnet_resume (intf);if (ret <0 )netdev_warn (dev->net,"usbnet_resume error\n" ); -phy_init_hw (pdata->phydev);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 698/779 usbnet: smsc95xx: Fix deadlock on runtime resume
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
[ Upstream commit 7b960c967f2aa01ab8f45c5a0bd78e754cffdeee ]
Commit 05b35e7eb9a1 ("smsc95xx: add phylib support") amended smsc95xx_resume() to call phy_init_hw(). That function waits for the device to runtime resume even though it is placed in the runtime resume path, causing a deadlock.
The problem is that phy_init_hw() calls down to smsc95xx_mdiobus_read(), which never uses the _nopm variant of usbnet_read_cmd().
Commit b4df480f68ae ("usbnet: smsc95xx: add reset_resume function with reset operation") causes a similar deadlock on resume if the device was already runtime suspended when entering system sleep:
That's because the commit introduced smsc95xx_reset_resume(), which calls down to smsc95xx_reset(), which neglects to use _nopm accessors.
Fix by auto-detecting whether a device access is performed by the suspend/resume task_struct and use the _nopm variant if so. This works because the PM core guarantees that suspend/resume callbacks are run in task context.
Stacktrace for posterity:
INFO: task kworker/2:1:49 blocked for more than 122 seconds. Workqueue: usb_hub_wq hub_event schedule rpm_resume __pm_runtime_resume usb_autopm_get_interface usbnet_read_cmd __smsc95xx_read_reg __smsc95xx_phy_wait_not_busy __smsc95xx_mdio_read smsc95xx_mdiobus_read __mdiobus_read mdiobus_read smsc_phy_reset phy_init_hw smsc95xx_resume usb_resume_interface usb_resume_both usb_runtime_resume __rpm_callback rpm_callback rpm_resume __pm_runtime_resume usb_autoresume_device hub_event process_one_work
--- drivers/net/usb/smsc95xx.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
drivers/net/usb/smsc95xx.c +20 -6
@@ -69,6 +69,7 @@ struct smsc95xx_priv {struct fwnode_handle *irqfwnode;struct mii_bus *mdiobus;struct phy_device *phydev; +struct task_struct *pm_task; };static bool turbo_mode = true;
@@ -78,13 +79,14 @@ MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");static int __must_check __smsc95xx_read_reg (struct usbnet *dev,u32 index,u32 *data,int in_pm) { +struct smsc95xx_priv *pdata = dev->driver_priv;u32 buf;int ret;int (*fn)(struct usbnet *,u8 ,u8 ,u16 ,u16 ,void *,u16 );BUG_ON (!dev); -if (!in_pm) +if (current != pdata->pm_task) fn = usbnet_read_cmd;else fn = usbnet_read_cmd_nopm;
@@ -108,13 +110,14 @@ static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,static int __must_check __smsc95xx_write_reg (struct usbnet *dev,u32 index,u32 data,int in_pm) { +struct smsc95xx_priv *pdata = dev->driver_priv;u32 buf;int ret;int (*fn)(struct usbnet *,u8 ,u8 ,u16 ,u16 ,const void *,u16 );BUG_ON (!dev); -if (!in_pm) +if (current != pdata->pm_task) fn = usbnet_write_cmd;else fn = usbnet_write_cmd_nopm;
@@ -1482,9 +1485,12 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)u32 val, link_up;int ret; + pdata->pm_task = current; + ret =usbnet_suspend (intf, message);if (ret <0 ) {netdev_warn (dev->net,"usbnet_suspend error\n" ); + pdata->pm_task =NULL ;return ret; }
@@ -1724,6 +1730,7 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)if (ret &&PMSG_IS_AUTO (message))usbnet_resume (intf); + pdata->pm_task =NULL ;return ret; }
@@ -1744,29 +1751,31 @@ static int smsc95xx_resume(struct usb_interface *intf)/* do this first to ensure it's cleared even in error case */ pdata->suspend_flags =0 ; + pdata->pm_task = current; +if (suspend_flags &SUSPEND_ALLMODES ) {/* clear wake-up sources */ ret =smsc95xx_read_reg_nopm (dev,WUCSR , &val);if (ret <0 ) -return ret; + goto done; val &= ~(WUCSR_WAKE_EN_ |WUCSR_MPEN_ ); ret =smsc95xx_write_reg_nopm (dev,WUCSR , val);if (ret <0 ) -return ret; + goto done;/* clear wake-up status */ ret =smsc95xx_read_reg_nopm (dev,PM_CTRL , &val);if (ret <0 ) -return ret; + goto done; val &= ~PM_CTL_WOL_EN_ ; val |=PM_CTL_WUPS_ ; ret =smsc95xx_write_reg_nopm (dev,PM_CTRL , val);if (ret <0 ) -return ret; + goto done; }phy_init_hw (pdata->phydev);
@@ -1775,15 +1784,20 @@ static int smsc95xx_resume(struct usb_interface *intf)if (ret <0 )netdev_warn (dev->net,"usbnet_resume error\n" ); +done: + pdata->pm_task =NULL ;return ret; }static int smsc95xx_reset_resume (struct usb_interface *intf) {struct usbnet *dev =usb_get_intfdata (intf); +struct smsc95xx_priv *pdata = dev->driver_priv;int ret; + pdata->pm_task = current; ret =smsc95xx_reset (dev); + pdata->pm_task =NULL ;if (ret <0 )return ret;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 699/779 firmware: arm_scpi: Ensure scpi_info is not assigned if the probe fails
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
[ Upstream commit 689640efc0a2c4e07e6f88affe6d42cd40cc3f85 ]
When scpi probe fails, at any point, we need to ensure that the scpi_info is not set and will remain NULL until the probe succeeds. If it is not taken care, then it could result use-after-free as the value is exported via get_scpi_ops() and could refer to a memory allocated via devm_kzalloc() but freed when the probe fails.
--- drivers/firmware/arm_scpi.c | 61 +++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 26 deletions(-)
drivers/firmware/arm_scpi.c +35 -26
@@ -815,7 +815,7 @@ static int scpi_init_versions(struct scpi_drvinfo *info) info->firmware_version =le32_to_cpu (caps.platform_version); }/* Ignore error if not implemented */ -if (scpi_info->is_legacy && ret == -EOPNOTSUPP ) +if (info->is_legacy && ret == -EOPNOTSUPP )return 0 ;return ret;
@@ -913,13 +913,14 @@ static int scpi_probe(struct platform_device *pdev)struct resource res;struct device *dev = &pdev->dev;struct device_node *np = dev->of_node; +struct scpi_drvinfo *scpi_drvinfo; - scpi_info =devm_kzalloc (dev,sizeof (*scpi_info),GFP_KERNEL ); -if (!scpi_info) + scpi_drvinfo =devm_kzalloc (dev,sizeof (*scpi_drvinfo),GFP_KERNEL ); +if (!scpi_drvinfo)return -ENOMEM ;if (of_match_device (legacy_scpi_of_match, &pdev->dev)) - scpi_info->is_legacy = true; + scpi_drvinfo->is_legacy = true; count =of_count_phandle_with_args (np,"mboxes" ,"#mbox-cells" );if (count <0 ) {
@@ -927,19 +928,19 @@ static int scpi_probe(struct platform_device *pdev)return -ENODEV ; } - scpi_info->channels =devm_kcalloc (dev, count,sizeof (struct scpi_chan ), -GFP_KERNEL ); -if (!scpi_info->channels) + scpi_drvinfo->channels = +devm_kcalloc (dev, count,sizeof (struct scpi_chan ),GFP_KERNEL ); +if (!scpi_drvinfo->channels)return -ENOMEM ; - ret =devm_add_action (dev, scpi_free_channels, scpi_info); + ret =devm_add_action (dev, scpi_free_channels, scpi_drvinfo);if (ret)return ret; -for (; scpi_info->num_chans < count; scpi_info->num_chans++) { +for (; scpi_drvinfo->num_chans < count; scpi_drvinfo->num_chans++) {resource_size_t size; -int idx = scpi_info->num_chans; -struct scpi_chan *pchan = scpi_info->channels + idx; +int idx = scpi_drvinfo->num_chans; +struct scpi_chan *pchan = scpi_drvinfo->channels + idx;struct mbox_client *cl = &pchan->cl;struct device_node *shmem =of_parse_phandle (np,"shmem" , idx);
@@ -986,45 +987,53 @@ static int scpi_probe(struct platform_device *pdev)return ret; } - scpi_info->commands = scpi_std_commands; + scpi_drvinfo->commands = scpi_std_commands; -platform_set_drvdata (pdev, scpi_info); +platform_set_drvdata (pdev, scpi_drvinfo); -if (scpi_info->is_legacy) { +if (scpi_drvinfo->is_legacy) {/* Replace with legacy variants */ scpi_ops.clk_set_val = legacy_scpi_clk_set_val; - scpi_info->commands = scpi_legacy_commands; + scpi_drvinfo->commands = scpi_legacy_commands;/* Fill priority bitmap */ for (idx =0 ; idx <ARRAY_SIZE (legacy_hpriority_cmds); idx++)set_bit (legacy_hpriority_cmds[idx], - scpi_info->cmd_priority); + scpi_drvinfo->cmd_priority); } - ret =scpi_init_versions (scpi_info); + scpi_info = scpi_drvinfo; + + ret =scpi_init_versions (scpi_drvinfo);if (ret) {dev_err (dev,"incorrect or no SCP firmware found\n" ); + scpi_info =NULL ;return ret; } -if (scpi_info->is_legacy && !scpi_info->protocol_version && - !scpi_info->firmware_version) +if (scpi_drvinfo->is_legacy && !scpi_drvinfo->protocol_version && + !scpi_drvinfo->firmware_version)dev_info (dev,"SCP Protocol legacy pre-1.0 firmware\n" );else dev_info (dev,"SCP Protocol %lu.%lu Firmware %lu.%lu.%lu version\n" ,FIELD_GET (PROTO_REV_MAJOR_MASK , - scpi_info->protocol_version), + scpi_drvinfo->protocol_version),FIELD_GET (PROTO_REV_MINOR_MASK , - scpi_info->protocol_version), + scpi_drvinfo->protocol_version),FIELD_GET (FW_REV_MAJOR_MASK , - scpi_info->firmware_version), + scpi_drvinfo->firmware_version),FIELD_GET (FW_REV_MINOR_MASK , - scpi_info->firmware_version), + scpi_drvinfo->firmware_version),FIELD_GET (FW_REV_PATCH_MASK , - scpi_info->firmware_version)); - scpi_info->scpi_ops = &scpi_ops; + scpi_drvinfo->firmware_version)); + + scpi_drvinfo->scpi_ops = &scpi_ops; -return devm_of_platform_populate (dev); + ret =devm_of_platform_populate (dev); +if (ret) + scpi_info =NULL ; + +return ret; }static const struct of_device_id scpi_of_match[] = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 700/779 scsi: lpfc: Fix EEH support for NVMe I/O
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 25ac2c970be32993f1dff607f8354f3c053d42bc ]
Injecting errors on the PCI slot while the driver is handling NVMe I/O will cause crashes and hangs.
There are several rather difficult scenarios occurring. The main issue is that the adapter can report a PCI error before or simultaneously to the PCI subsystem reporting the error. Both paths have different entry points and currently there is no interlock between them. Thus multiple teardown paths are competing and all heck breaks loose.
Complicating things is the NVMs path. To a large degree, I/O was able to be shutdown for a full FC port on the SCSI stack. But on NVMe, there isn't a similar call. At best, it works on a per-controller basis, but even at the controller level, it's a controller "reset" call. All of which means I/O is still flowing on different CPUs with reset paths expecting hw access (mailbox commands) to execute properly.
The following modifications are made:
- A new flag is set in PCI error entrypoints so the driver can track being called by that path.
- An interlock is added in the SLI hw error path and the PCI error path such that only one of the paths proceeds with the teardown logic.
- RPI cleanup is patched such that RPIs are marked unregistered w/o mbx cmds in cases of hw error.
- If entering the SLI port re-init calls, a case where SLI error teardown was quick and beat the PCI calls now reporting error, check whether the SLI port is still live on the PCI bus.
- In the PCI reset code to bring the adapter back, recheck the IRQ settings. Different checks for SLI3 vs SLI4.
- In I/O completions, that may be called as part of the cleanup or underway just before the hw error, check the state of the adapter. If in error, shortcut handling that would expect further adapter completions as the hw error won't be sending them.
- In routines waiting on I/O completions, which may have been in progress prior to the hw error, detect the device is being torn down and abort from their waits and just give up. This points to a larger issue in the driver on ref-counting for data structures, as it doesn't have ref-counting on q and port structures. We'll do this fix for now as it would be a major rework to be done differently.
- Fix the NVMe cleanup to simulate NVMe I/O completions if I/O is being failed back due to hw error.
- In I/O buf allocation, done at the start of new I/Os, check hw state and fail if hw error.
--- drivers/scsi/lpfc/lpfc.h | 1 + drivers/scsi/lpfc/lpfc_hbadisc.c | 1 + drivers/scsi/lpfc/lpfc_init.c | 31 +++++++++++++++- drivers/scsi/lpfc/lpfc_nvme.c | 53 ++++++++++++++++++++++++++- drivers/scsi/lpfc/lpfc_scsi.c | 63 +++++++++++++++++++++----------- drivers/scsi/lpfc/lpfc_sli.c | 31 +++++++++++++++- drivers/scsi/lpfc/lpfc_sli4.h | 2 + 7 files changed, 154 insertions(+), 28 deletions(-)
drivers/scsi/lpfc/lpfc.h +1 -0
@@ -1028,6 +1028,7 @@ struct lpfc_hba {* Firmware supports Forced Link Speed * capability */ +#define HBA_PCI_ERR 0x80000/* The PCI slot is offline */ #define HBA_FLOGI_ISSUED 0x100000/* FLOGI was issued */ #define HBA_CGN_RSVD1 0x200000/* Reserved CGN flag */ #define HBA_CGN_DAY_WRAP 0x400000/* HBA Congestion info day wraps */
drivers/scsi/lpfc/lpfc_hbadisc.c +1 -0
@@ -5349,6 +5349,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) rc =lpfc_sli_issue_mbox (phba, mbox,MBX_NOWAIT );if (rc ==MBX_NOT_FINISHED ) { + ndlp->nlp_flag &= ~NLP_UNREG_INP ;mempool_free (mbox, phba->mbox_mem_pool); acc_plogi =1 ; }
drivers/scsi/lpfc/lpfc_init.c +29 -2
@@ -1606,6 +1606,11 @@ void lpfc_sli4_offline_eratt(struct lpfc_hba *phba) {spin_lock_irq (&phba->hbalock); +if (phba->link_state ==LPFC_HBA_ERROR && + phba->hba_flag &HBA_PCI_ERR ) { +spin_unlock_irq (&phba->hbalock); +return ; + } phba->link_state =LPFC_HBA_ERROR ;spin_unlock_irq (&phba->hbalock);
@@ -1945,7 +1950,6 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)if (pci_channel_offline (phba->pcidev)) {lpfc_printf_log (phba,KERN_ERR ,LOG_TRACE_EVENT ,"3166 pci channel is offline\n" ); -lpfc_sli4_offline_eratt (phba);return ; }
@@ -3643,6 +3647,7 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action)struct lpfc_vport **vports;struct Scsi_Host *shost;int i; +int offline =0 ;if (vport->fc_flag &FC_OFFLINE_MODE )return ;
@@ -3651,6 +3656,8 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action)lpfc_linkdown (phba); + offline =pci_channel_offline (phba->pcidev); +/* Issue an unreg_login to all nodes on all vports */ vports =lpfc_create_vport_work_array (phba);if (vports !=NULL ) {
@@ -3673,7 +3680,14 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) ndlp->nlp_flag &= ~NLP_NPR_ADISC ;spin_unlock_irq (&ndlp->lock); -lpfc_unreg_rpi (vports[i], ndlp); +if (offline) { +spin_lock_irq (&ndlp->lock); + ndlp->nlp_flag &= ~(NLP_UNREG_INP | +NLP_RPI_REGISTERED ); +spin_unlock_irq (&ndlp->lock); + }else { +lpfc_unreg_rpi (vports[i], ndlp); + }/* * Whenever an SLI4 port goes offline, free the * RPI. Get a new RPI when the adapter port
@@ -14070,6 +14084,10 @@ lpfc_pci_resume_one_s3(struct device *dev_d)return error; } +/* Init cpu_map array */ +lpfc_cpu_map_array_init (phba); +/* Init hba_eq_hdl array */ +lpfc_hba_eq_hdl_array_init (phba);/* Configure and enable interrupt */ intr_mode =lpfc_sli_enable_intr (phba, phba->intr_mode);if (intr_mode ==LPFC_INTR_ERROR ) {
@@ -15023,14 +15041,17 @@ lpfc_io_error_detected_s4(struct pci_dev *pdev, pci_channel_state_t state)lpfc_sli4_prep_dev_for_recover (phba);return PCI_ERS_RESULT_CAN_RECOVER ;case pci_channel_io_frozen: + phba->hba_flag |=HBA_PCI_ERR ;/* Fatal error, prepare for slot reset */ lpfc_sli4_prep_dev_for_reset (phba);return PCI_ERS_RESULT_NEED_RESET ;case pci_channel_io_perm_failure: + phba->hba_flag |=HBA_PCI_ERR ;/* Permanent failure, prepare for device down */ lpfc_sli4_prep_dev_for_perm_failure (phba);return PCI_ERS_RESULT_DISCONNECT ;default : + phba->hba_flag |=HBA_PCI_ERR ;/* Unknown state, prepare and request slot reset */ lpfc_printf_log (phba,KERN_ERR ,LOG_TRACE_EVENT ,"2825 Unknown PCI error state: x%x\n" , state);
@@ -15074,6 +15095,7 @@ lpfc_io_slot_reset_s4(struct pci_dev *pdev)pci_restore_state (pdev); + phba->hba_flag &= ~HBA_PCI_ERR ;/* * As the new kernel behavior of pci_restore_state() API call clears * device saved_state flag, need to save the restored state again.
@@ -15098,6 +15120,7 @@ lpfc_io_slot_reset_s4(struct pci_dev *pdev)return PCI_ERS_RESULT_DISCONNECT ; }else phba->intr_mode = intr_mode; +lpfc_cpu_affinity_check (phba, phba->cfg_irq_chann);/* Log the current active interrupt mode */ lpfc_log_intr_mode (phba, phba->intr_mode);
@@ -15299,6 +15322,10 @@ lpfc_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;pci_ers_result_t rc =PCI_ERS_RESULT_DISCONNECT ; +if (phba->link_state ==LPFC_HBA_ERROR && + phba->hba_flag &HBA_IOQ_FLUSH ) +return PCI_ERS_RESULT_NEED_RESET ; +switch (phba->pci_dev_grp) {case LPFC_PCI_DEV_LP : rc =lpfc_io_error_detected_s3 (pdev, state);
drivers/scsi/lpfc/lpfc_nvme.c +51 -2
99 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_scsi.c +41 -22
110 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli.c +29 -2
@@ -1404,7 +1404,8 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) }if ((iocbq->iocb_flag &LPFC_EXCHANGE_BUSY ) && - (sglq->state !=SGL_XRI_ABORTED )) { + (!(unlikely (pci_channel_offline (phba->pcidev)))) && + sglq->state !=SGL_XRI_ABORTED ) {spin_lock_irqsave (&phba->sli4_hba.sgl_list_lock, iflag);
@@ -4583,10 +4584,12 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)lpfc_sli_cancel_iocbs (phba, &txq,IOSTAT_LOCAL_REJECT ,IOERR_SLI_DOWN ); -/* Flush the txcmpq */ +/* Flush the txcmplq */ lpfc_sli_cancel_iocbs (phba, &txcmplq,IOSTAT_LOCAL_REJECT ,IOERR_SLI_DOWN ); +if (unlikely (pci_channel_offline (phba->pcidev))) +lpfc_sli4_io_xri_aborted (phba,NULL ,0 ); } }else { pring = &psli->sli3_ring[LPFC_FCP_RING ];
@@ -22035,8 +22038,26 @@ lpfc_get_io_buf_from_multixri_pools(struct lpfc_hba *phba, qp = &phba->sli4_hba.hdwq[hwqid]; lpfc_ncmd =NULL ; +if (!qp) { +lpfc_printf_log (phba,KERN_INFO , +LOG_SLI |LOG_NVME_ABTS |LOG_FCP , +"5556 NULL qp for hwqid x%x\n" , hwqid); +return lpfc_ncmd; + } multixri_pool = qp->p_multixri_pool; +if (!multixri_pool) { +lpfc_printf_log (phba,KERN_INFO , +LOG_SLI |LOG_NVME_ABTS |LOG_FCP , +"5557 NULL multixri for hwqid x%x\n" , hwqid); +return lpfc_ncmd; + } pvt_pool = &multixri_pool->pvt_pool; +if (!pvt_pool) { +lpfc_printf_log (phba,KERN_INFO , +LOG_SLI |LOG_NVME_ABTS |LOG_FCP , +"5558 NULL pvt_pool for hwqid x%x\n" , hwqid); +return lpfc_ncmd; + } multixri_pool->io_req_count++;/* If pvt_pool is empty, move some XRIs from public to private pool */
@@ -22112,6 +22133,12 @@ struct lpfc_io_buf *lpfc_get_io_buf(struct lpfc_hba *phba, qp = &phba->sli4_hba.hdwq[hwqid]; lpfc_cmd =NULL ; +if (!qp) { +lpfc_printf_log (phba,KERN_WARNING , +LOG_SLI |LOG_NVME_ABTS |LOG_FCP , +"5555 NULL qp for hwqid x%x\n" , hwqid); +return lpfc_cmd; + }if (phba->cfg_xri_rebalancing) lpfc_cmd = lpfc_get_io_buf_from_multixri_pools(
drivers/scsi/lpfc/lpfc_sli4.h +2 -0
@@ -1116,6 +1116,8 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *);int lpfc_sli4_resume_rpi (struct lpfc_nodelist *,void (*)(struct lpfc_hba *,LPFC_MBOXQ_t *),void *);void lpfc_sli4_els_xri_abort_event_proc (struct lpfc_hba *phba); +void lpfc_sli4_nvme_pci_offline_aborted (struct lpfc_hba *phba, +struct lpfc_io_buf *lpfc_ncmd);void lpfc_sli4_nvme_xri_aborted (struct lpfc_hba *phba,struct sli4_wcqe_xri_aborted *axri,struct lpfc_io_buf *lpfc_ncmd);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 701/779 scsi: lpfc: SLI path split: Refactor lpfc_iocbq
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit a680a9298e7b4ff344aca3456177356b276e5038 ]
Currently, SLI3 and SLI4 data paths use the same lpfc_iocbq structure. This is a "common" structure but many of the components refer to sli-rev specific entities which can lead the developer astray as to what they actually mean, should be set to, or when they should be used.
This first patch prepares the lpfc_iocbq structure so that elements common to both SLI3 and SLI4 data paths are more appropriately named, making it clear they apply generically.
Fieldnames based on 'iocb' (sli3) or 'wqe' (sli4) which are actually generic to the paths are renamed to 'cmd':
- iocb_flag is renamed to cmd_flag
- lpfc_vmid_iocb_tag is renamed to lpfc_vmid_tag
- fabric_iocb_cmpl is renamed to fabric_cmd_cmpl
- wait_iocb_cmpl is renamed to wait_cmd_cmpl
- iocb_cmpl and wqe_cmpl are combined and renamed to cmd_cmpl
- rsvd2 member is renamed to num_bdes due to pre-existing usage
The structure name itself will retain the iocb reference as changing to a more relevant "job" or "cmd" title induces many hundreds of line changes for only a name change.
lpfc_post_buffer is also renamed to lpfc_sli3_post_buffer to indicate use in the SLI3 path only.
--- drivers/scsi/lpfc/lpfc_bsg.c | 50 ++--- drivers/scsi/lpfc/lpfc_crtn.h | 2 +- drivers/scsi/lpfc/lpfc_ct.c | 8 +- drivers/scsi/lpfc/lpfc_els.c | 139 ++++++------ drivers/scsi/lpfc/lpfc_init.c | 11 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 4 +- drivers/scsi/lpfc/lpfc_nvme.c | 34 +-- drivers/scsi/lpfc/lpfc_nvme.h | 6 +- drivers/scsi/lpfc/lpfc_nvmet.c | 83 +++---- drivers/scsi/lpfc/lpfc_scsi.c | 75 +++---- drivers/scsi/lpfc/lpfc_sli.c | 340 ++++++++++++++--------------- drivers/scsi/lpfc/lpfc_sli.h | 24 +- 12 files changed, 385 insertions(+), 391 deletions(-)
drivers/scsi/lpfc/lpfc_bsg.c +25 -25
@@ -325,7 +325,7 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,/* Close the timeout handler abort window */ spin_lock_irqsave (&phba->hbalock, flags); - cmdiocbq->iocb_flag &= ~LPFC_IO_CMD_OUTSTANDING ; + cmdiocbq->cmd_flag &= ~LPFC_IO_CMD_OUTSTANDING ;spin_unlock_irqrestore (&phba->hbalock, flags); iocb = &dd_data->context_un.iocb;
@@ -481,11 +481,11 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job) cmd->ulpOwner =OWN_CHIP ; cmdiocbq->vport = phba->pport; cmdiocbq->context3 = bmp; - cmdiocbq->iocb_flag |=LPFC_IO_LIBDFC ; + cmdiocbq->cmd_flag |=LPFC_IO_LIBDFC ; timeout = phba->fc_ratov *2 ; cmd->ulpTimeout = timeout; - cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp; + cmdiocbq->cmd_cmpl = lpfc_bsg_send_mgmt_cmd_cmp; cmdiocbq->context1 = dd_data; cmdiocbq->context2 = cmp; cmdiocbq->context3 = bmp;
@@ -516,9 +516,9 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job)if (iocb_stat ==IOCB_SUCCESS ) {spin_lock_irqsave (&phba->hbalock, flags);/* make sure the I/O had not been completed yet */ -if (cmdiocbq->iocb_flag &LPFC_IO_LIBDFC ) { +if (cmdiocbq->cmd_flag &LPFC_IO_LIBDFC ) {/* open up abort window to timeout handler */ - cmdiocbq->iocb_flag |=LPFC_IO_CMD_OUTSTANDING ; + cmdiocbq->cmd_flag |=LPFC_IO_CMD_OUTSTANDING ; }spin_unlock_irqrestore (&phba->hbalock, flags);return 0 ;/* done for now */
@@ -600,7 +600,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,/* Close the timeout handler abort window */ spin_lock_irqsave (&phba->hbalock, flags); - cmdiocbq->iocb_flag &= ~LPFC_IO_CMD_OUTSTANDING ; + cmdiocbq->cmd_flag &= ~LPFC_IO_CMD_OUTSTANDING ;spin_unlock_irqrestore (&phba->hbalock, flags); rsp = &rspiocbq->iocb;
@@ -726,10 +726,10 @@ lpfc_bsg_rport_els(struct bsg_job *job) cmdiocbq->iocb.ulpContext = phba->sli4_hba.rpi_ids[rpi]; else cmdiocbq->iocb.ulpContext = rpi; - cmdiocbq->iocb_flag |=LPFC_IO_LIBDFC ; + cmdiocbq->cmd_flag |=LPFC_IO_LIBDFC ; cmdiocbq->context1 = dd_data; cmdiocbq->context_un.ndlp = ndlp; - cmdiocbq->iocb_cmpl = lpfc_bsg_rport_els_cmp; + cmdiocbq->cmd_cmpl = lpfc_bsg_rport_els_cmp; dd_data->type =TYPE_IOCB ; dd_data->set_job = job; dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
@@ -757,9 +757,9 @@ lpfc_bsg_rport_els(struct bsg_job *job)if (rc ==IOCB_SUCCESS ) {spin_lock_irqsave (&phba->hbalock, flags);/* make sure the I/O had not been completed/released */ -if (cmdiocbq->iocb_flag &LPFC_IO_LIBDFC ) { +if (cmdiocbq->cmd_flag &LPFC_IO_LIBDFC ) {/* open up abort window to timeout handler */ - cmdiocbq->iocb_flag |=LPFC_IO_CMD_OUTSTANDING ; + cmdiocbq->cmd_flag |=LPFC_IO_CMD_OUTSTANDING ; }spin_unlock_irqrestore (&phba->hbalock, flags);return 0 ;/* done for now */
@@ -1053,7 +1053,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,lpfc_in_buf_free (phba, dmabuf); }else { -lpfc_post_buffer (phba, +lpfc_sli3_post_buffer (phba, pring,1 ); }
@@ -1061,7 +1061,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,default :if (!(phba->sli3_options &LPFC_SLI3_HBQ_ENABLED )) -lpfc_post_buffer (phba, +lpfc_sli3_post_buffer (phba, pring,1 );break ;
@@ -1395,7 +1395,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,/* Close the timeout handler abort window */ spin_lock_irqsave (&phba->hbalock, flags); - cmdiocbq->iocb_flag &= ~LPFC_IO_CMD_OUTSTANDING ; + cmdiocbq->cmd_flag &= ~LPFC_IO_CMD_OUTSTANDING ;spin_unlock_irqrestore (&phba->hbalock, flags); ndlp = dd_data->context_un.iocb.ndlp;
@@ -1549,13 +1549,13 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,"2722 Xmit CT response on exchange x%x Data: x%x x%x x%x\n" , icmd->ulpContext, icmd->ulpIoTag, tag, phba->link_state); - ctiocb->iocb_flag |=LPFC_IO_LIBDFC ; + ctiocb->cmd_flag |=LPFC_IO_LIBDFC ; ctiocb->vport = phba->pport; ctiocb->context1 = dd_data; ctiocb->context2 = cmp; ctiocb->context3 = bmp; ctiocb->context_un.ndlp = ndlp; - ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp; + ctiocb->cmd_cmpl = lpfc_issue_ct_rsp_cmp; dd_data->type =TYPE_IOCB ; dd_data->set_job = job;
@@ -1582,9 +1582,9 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag,if (rc ==IOCB_SUCCESS ) {spin_lock_irqsave (&phba->hbalock, flags);/* make sure the I/O had not been completed/released */ -if (ctiocb->iocb_flag &LPFC_IO_LIBDFC ) { +if (ctiocb->cmd_flag &LPFC_IO_LIBDFC ) {/* open up abort window to timeout handler */ - ctiocb->iocb_flag |=LPFC_IO_CMD_OUTSTANDING ; + ctiocb->cmd_flag |=LPFC_IO_CMD_OUTSTANDING ; }spin_unlock_irqrestore (&phba->hbalock, flags);return 0 ;/* done for now */
@@ -2713,9 +2713,9 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi, cmd->ulpClass =CLASS3 ; cmd->ulpContext = rpi; - cmdiocbq->iocb_flag |=LPFC_IO_LIBDFC ; + cmdiocbq->cmd_flag |=LPFC_IO_LIBDFC ; cmdiocbq->vport = phba->pport; - cmdiocbq->iocb_cmpl =NULL ; + cmdiocbq->cmd_cmpl =NULL ; iocb_stat = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq, rspiocbq,
@@ -3286,10 +3286,10 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job) cmdiocbq->sli4_xritag =NO_XRI ; cmd->unsli3.rcvsli3.ox_id =0xffff ; } - cmdiocbq->iocb_flag |=LPFC_IO_LIBDFC ; - cmdiocbq->iocb_flag |=LPFC_IO_LOOPBACK ; + cmdiocbq->cmd_flag |=LPFC_IO_LIBDFC ; + cmdiocbq->cmd_flag |=LPFC_IO_LOOPBACK ; cmdiocbq->vport = phba->pport; - cmdiocbq->iocb_cmpl =NULL ; + cmdiocbq->cmd_cmpl =NULL ; iocb_stat =lpfc_sli_issue_iocb_wait (phba,LPFC_ELS_RING , cmdiocbq, rspiocbq, (phba->fc_ratov *2 ) +LPFC_DRVR_TIMEOUT );
@@ -5273,11 +5273,11 @@ lpfc_menlo_cmd(struct bsg_job *job) cmd->ulpClass =CLASS3 ; cmd->ulpOwner =OWN_CHIP ; cmd->ulpLe =1 ;/* Limited Edition */ - cmdiocbq->iocb_flag |=LPFC_IO_LIBDFC ; + cmdiocbq->cmd_flag |=LPFC_IO_LIBDFC ; cmdiocbq->vport = phba->pport;/* We want the firmware to timeout before we do */ cmd->ulpTimeout =MENLO_TIMEOUT -5 ; - cmdiocbq->iocb_cmpl = lpfc_bsg_menlo_cmd_cmp; + cmdiocbq->cmd_cmpl = lpfc_bsg_menlo_cmd_cmp; cmdiocbq->context1 = dd_data; cmdiocbq->context2 = cmp; cmdiocbq->context3 = bmp;
@@ -6001,7 +6001,7 @@ lpfc_bsg_timeout(struct bsg_job *job)spin_lock_irqsave (&phba->hbalock, flags);/* make sure the I/O abort window is still open */ -if (!(cmdiocb->iocb_flag &LPFC_IO_CMD_OUTSTANDING )) { +if (!(cmdiocb->cmd_flag &LPFC_IO_CMD_OUTSTANDING )) {spin_unlock_irqrestore (&phba->hbalock, flags);return -EAGAIN ; }
drivers/scsi/lpfc/lpfc_crtn.h +1 -1
@@ -210,7 +210,7 @@ int lpfc_config_port_post(struct lpfc_hba *);int lpfc_hba_down_prep (struct lpfc_hba *);int lpfc_hba_down_post (struct lpfc_hba *);void lpfc_hba_init (struct lpfc_hba *,uint32_t *); -int lpfc_post_buffer (struct lpfc_hba *,struct lpfc_sli_ring *,int ); +int lpfc_sli3_post_buffer (struct lpfc_hba *phba,struct lpfc_sli_ring *pring,int cnt);void lpfc_decode_firmware_rev (struct lpfc_hba *,char *,int );int lpfc_online (struct lpfc_hba *);void lpfc_unblock_mgmt_io (struct lpfc_hba *);
drivers/scsi/lpfc/lpfc_ct.c +4 -4
@@ -239,7 +239,7 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp, cmdiocbq->context1 =lpfc_nlp_get (ndlp); cmdiocbq->context2 = (uint8_t *)mp; cmdiocbq->context3 = (uint8_t *)bmp; - cmdiocbq->iocb_cmpl = lpfc_ct_unsol_cmpl; + cmdiocbq->cmd_cmpl = lpfc_ct_unsol_cmpl; icmd->ulpContext = rx_id;/* Xri / rx_id */ icmd->unsli3.rcvsli3.ox_id = ox_id; icmd->un.ulpWord[3] =
@@ -370,7 +370,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,/* Not enough posted buffers; Try posting more buffers */ phba->fc_stat.NoRcvBuf++;if (!(phba->sli3_options &LPFC_SLI3_HBQ_ENABLED )) -lpfc_post_buffer (phba, pring,2 ); +lpfc_sli3_post_buffer (phba, pring,2 );return ; }
@@ -447,7 +447,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,lpfc_ct_unsol_buffer (phba, iocbq, mp, size);lpfc_in_buf_free (phba, mp); } -lpfc_post_buffer (phba, pring, i); +lpfc_sli3_post_buffer (phba, pring, i); }list_del (&head); }
@@ -652,7 +652,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,"Data: x%x x%x\n" , ndlp->nlp_DID, icmd->ulpIoTag, vport->port_state); - geniocb->iocb_cmpl = cmpl; + geniocb->cmd_cmpl = cmpl; geniocb->drvrTimeout = icmd->ulpTimeout +LPFC_DRVR_TIMEOUT ; geniocb->vport = vport; geniocb->retry = retry;
drivers/scsi/lpfc/lpfc_els.c +69 -70
455 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_init.c +5 -6
@@ -982,7 +982,7 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba)spin_lock_irq (&pring->ring_lock);list_for_each_entry_safe (piocb, next_iocb, &pring->txcmplq, list) - piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ ; + piocb->cmd_flag &= ~LPFC_IO_ON_TXCMPLQ ;list_splice_init (&pring->txcmplq, &completions); pring->txcmplq_cnt =0 ;spin_unlock_irq (&pring->ring_lock);
@@ -2643,7 +2643,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) }/** -* lpfc_post_buffer - Post IOCB(s) with DMA buffer descriptor(s) to a IOCB ring +* lpfc_sli3_post_buffer - Post IOCB(s) with DMA buffer descriptor(s) to a IOCB ring * @phba: pointer to lpfc hba data structure. * @pring: pointer to a IOCB ring. * @cnt: the number of IOCBs to be posted to the IOCB ring.
@@ -2655,7 +2655,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)* The number of IOCBs NOT able to be posted to the IOCB ring. **/ int -lpfc_post_buffer (struct lpfc_hba *phba,struct lpfc_sli_ring *pring,int cnt) +lpfc_sli3_post_buffer (struct lpfc_hba *phba,struct lpfc_sli_ring *pring,int cnt) {IOCB_t *icmd;struct lpfc_iocbq *iocb;
@@ -2761,7 +2761,7 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba)struct lpfc_sli *psli = &phba->sli;/* Ring 0, ELS / CT buffers */ -lpfc_post_buffer (phba, &psli->sli3_ring[LPFC_ELS_RING ],LPFC_BUF_RING0 ); +lpfc_sli3_post_buffer (phba, &psli->sli3_ring[LPFC_ELS_RING ],LPFC_BUF_RING0 );/* Ring 2 - FCP no buffers needed */ return 0 ;
@@ -4215,8 +4215,7 @@ lpfc_io_buf_replenish(struct lpfc_hba *phba, struct list_head *cbuf) qp = &phba->sli4_hba.hdwq[idx]; lpfc_cmd->hdwq_no = idx; lpfc_cmd->hdwq = qp; - lpfc_cmd->cur_iocbq.wqe_cmpl =NULL ; - lpfc_cmd->cur_iocbq.iocb_cmpl =NULL ; + lpfc_cmd->cur_iocbq.cmd_cmpl =NULL ;spin_lock (&qp->io_buf_list_put_lock);list_add_tail (&lpfc_cmd->list, &qp->lpfc_io_buf_list_put);
drivers/scsi/lpfc/lpfc_nportdisc.c +2 -2
@@ -2139,9 +2139,9 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, npr =NULL ; nvpr =NULL ; temp_ptr =lpfc_check_elscmpl_iocb (phba, cmdiocb, rspiocb); -if (cmdiocb->iocb_flag &LPFC_PRLI_FCP_REQ ) +if (cmdiocb->cmd_flag &LPFC_PRLI_FCP_REQ ) npr = (PRLI *) temp_ptr; -else if (cmdiocb->iocb_flag &LPFC_PRLI_NVME_REQ ) +else if (cmdiocb->cmd_flag &LPFC_PRLI_NVME_REQ ) nvpr = (struct lpfc_nvme_prli *) temp_ptr; irsp = &rspiocb->iocb;
drivers/scsi/lpfc/lpfc_nvme.c +18 -16
@@ -352,11 +352,12 @@ __lpfc_nvme_ls_req_cmp(struct lpfc_hba *phba, struct lpfc_vport *vport,static void lpfc_nvme_ls_req_cmp (struct lpfc_hba *phba,struct lpfc_iocbq *cmdwqe, -struct lpfc_wcqe_complete *wcqe) +struct lpfc_iocbq *rspwqe) {struct lpfc_vport *vport = cmdwqe->vport;struct lpfc_nvme_lport *lport;uint32_t status; +struct lpfc_wcqe_complete *wcqe = &rspwqe->wcqe_cmpl; status =bf_get (lpfc_wcqe_c_status, wcqe) &LPFC_IOCB_STATUS_MASK ;
@@ -380,7 +381,7 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,struct lpfc_dmabuf *inp, struct nvmefc_ls_req *pnvme_lsreq, void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, -struct lpfc_wcqe_complete *), +struct lpfc_iocbq *), struct lpfc_nodelist *ndlp, uint32_t num_entry, uint32_t tmo, uint8_t retry) {
@@ -401,7 +402,7 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,memset (wqe,0 ,sizeof (union lpfc_wqe )); genwqe->context3 = (uint8_t *)bmp; - genwqe->iocb_flag |=LPFC_IO_NVME_LS ; + genwqe->cmd_flag |=LPFC_IO_NVME_LS ;/* Save for completion so we can release these resources */ genwqe->context1 =lpfc_nlp_get (ndlp);
@@ -432,7 +433,7 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, first_len = xmit_len; } - genwqe->rsvd2 = num_entry; + genwqe->num_bdes = num_entry; genwqe->hba_wqidx =0 ;/* Words 0 - 2 */
@@ -483,8 +484,7 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,/* Issue GEN REQ WQE for NPORT <did> */ - genwqe->wqe_cmpl = cmpl; - genwqe->iocb_cmpl =NULL ; + genwqe->cmd_cmpl = cmpl; genwqe->drvrTimeout = tmo +LPFC_DRVR_TIMEOUT ; genwqe->vport = vport; genwqe->retry = retry;
@@ -534,7 +534,7 @@ __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,struct nvmefc_ls_req *pnvme_lsreq, void (*gen_req_cmp)(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, - struct lpfc_wcqe_complete *wcqe)) + struct lpfc_iocbq *rspwqe)) { struct lpfc_dmabuf *bmp;struct ulp_bde64 *bpl;
@@ -722,7 +722,7 @@ __lpfc_nvme_ls_abort(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,spin_lock (&pring->ring_lock);list_for_each_entry_safe (wqe, next_wqe, &pring->txcmplq, list) {if (wqe->context2 == pnvme_lsreq) { - wqe->iocb_flag |=LPFC_DRIVER_ABORTED ; + wqe->cmd_flag |=LPFC_DRIVER_ABORTED ; foundit = true;break ; }
@@ -906,7 +906,7 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,/* -* lpfc_nvme_io_cmd_wqe_cmpl - Complete an NVME-over-FCP IO +* lpfc_nvme_io_cmd_cmpl - Complete an NVME-over-FCP IO * * Driver registers this routine as it io request handler. This * routine issues an fcp WQE with data from the @lpfc_nvme_fcpreq
@@ -917,11 +917,12 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,* TODO: What are the failure codes. **/ static void -lpfc_nvme_io_cmd_wqe_cmpl (struct lpfc_hba *phba,struct lpfc_iocbq *pwqeIn, -struct lpfc_wcqe_complete *wcqe) +lpfc_nvme_io_cmd_cmpl (struct lpfc_hba *phba,struct lpfc_iocbq *pwqeIn, +struct lpfc_iocbq *pwqeOut) {struct lpfc_io_buf *lpfc_ncmd = (struct lpfc_io_buf *)pwqeIn->context1; +struct lpfc_wcqe_complete *wcqe = &pwqeOut->wcqe_cmpl;struct lpfc_vport *vport = pwqeIn->vport;struct nvmefc_fcp_req *nCmd;struct nvme_fc_ersp_iu *ep;
@@ -1873,7 +1874,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, }/* Don't abort IOs no longer on the pending queue. */ -if (!(nvmereq_wqe->iocb_flag &LPFC_IO_ON_TXCMPLQ )) { +if (!(nvmereq_wqe->cmd_flag &LPFC_IO_ON_TXCMPLQ )) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "6142 NVME IO req x%px not queued - skipping " "abort req xri x%x\n",
@@ -1887,7 +1888,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, nvmereq_wqe->hba_wqidx, pnvme_rport->port_id);/* Outstanding abort is in progress */ -if (nvmereq_wqe->iocb_flag &LPFC_DRIVER_ABORTED ) { +if (nvmereq_wqe->cmd_flag &LPFC_DRIVER_ABORTED ) {lpfc_printf_vlog (vport,KERN_ERR ,LOG_TRACE_EVENT ,"6144 Outstanding NVME I/O Abort Request " "still pending on nvme_fcreq x%px, "
@@ -1982,8 +1983,8 @@ lpfc_get_nvme_buf(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,/* Setup key fields in buffer that may have been changed * if other protocols used this buffer. */ - pwqeq->iocb_flag =LPFC_IO_NVME ; - pwqeq->wqe_cmpl = lpfc_nvme_io_cmd_wqe_cmpl; + pwqeq->cmd_flag =LPFC_IO_NVME ; + pwqeq->cmd_cmpl = lpfc_nvme_io_cmd_cmpl; lpfc_ncmd->start_time = jiffies; lpfc_ncmd->flags =0 ;
@@ -2749,6 +2750,7 @@ lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,if (phba->sli.sli_flag &LPFC_SLI_ACTIVE )bf_set (lpfc_wcqe_c_xb, wcqep,1 ); - (pwqeIn->wqe_cmpl)(phba, pwqeIn, wcqep); +memcpy (&pwqeIn->wcqe_cmpl, wcqep,sizeof (*wcqep)); + (pwqeIn->cmd_cmpl)(phba, pwqeIn, pwqeIn);#endif }
drivers/scsi/lpfc/lpfc_nvme.h +3 -3
@@ -234,7 +234,7 @@ int __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,struct nvmefc_ls_req *pnvme_lsreq, void (*gen_req_cmp)(struct lpfc_hba *phba,struct lpfc_iocbq *cmdwqe, - struct lpfc_wcqe_complete *wcqe)); + struct lpfc_iocbq *rspwqe));void __lpfc_nvme_ls_req_cmp (struct lpfc_hba *phba,struct lpfc_vport *vport,struct lpfc_iocbq *cmdwqe,struct lpfc_wcqe_complete *wcqe); int __lpfc_nvme_ls_abort(struct lpfc_vport *vport,
@@ -248,6 +248,6 @@ int __lpfc_nvme_xmt_ls_rsp(struct lpfc_async_xchg_ctx *axchg,struct nvmefc_ls_rsp *ls_rsp, void (*xmt_ls_rsp_cmp)(struct lpfc_hba *phba,struct lpfc_iocbq *cmdwqe, - struct lpfc_wcqe_complete *wcqe)); + struct lpfc_iocbq *rspwqe));void __lpfc_nvme_xmt_ls_rsp_cmp (struct lpfc_hba *phba, -struct lpfc_iocbq *cmdwqe,struct lpfc_wcqe_complete *wcqe); +struct lpfc_iocbq *cmdwqe,struct lpfc_iocbq *rspwqe);
drivers/scsi/lpfc/lpfc_nvmet.c +44 -39
291 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_scsi.c +38 -37
266 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli.c +165 -175
910 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli.h +11 -13
@@ -35,7 +35,7 @@ typedef enum _lpfc_ctx_cmd {LPFC_CTX_HOST } lpfc_ctx_cmd; -union lpfc_vmid_iocb_tag { +union lpfc_vmid_tag {uint32_t app_id;uint8_t cs_ctl_vmid;struct lpfc_vmid_context *vmid_context;/* UVEM context information */
@@ -69,16 +69,16 @@ struct lpfc_iocbq {uint16_t sli4_xritag;/* pre-assigned XRI, (OXID) tag. */ uint16_t hba_wqidx;/* index to HBA work queue */ struct lpfc_cq_event cq_event; -struct lpfc_wcqe_complete wcqe_cmpl;/* WQE cmpl */ uint64_t isr_timestamp;union lpfc_wqe128 wqe;/* SLI-4 */ IOCB_t iocb;/* SLI-3 */ +struct lpfc_wcqe_complete wcqe_cmpl;/* WQE cmpl */ -uint8_t rsvd2; +uint8_t num_bdes;uint8_t priority;/* OAS priority */ uint8_t retry;/* retry counter for IOCB cmd - if needed */ -uint32_t iocb_flag; +u32 cmd_flag;#define LPFC_IO_LIBDFC 1/* libdfc iocb */ #define LPFC_IO_WAKE 2/* Synchronous I/O completed */ #define LPFC_IO_WAKE_TMO LPFC_IO_WAKE/* Synchronous I/O timed out */
@@ -123,15 +123,13 @@ struct lpfc_iocbq {struct lpfc_node_rrq *rrq; } context_un; -union lpfc_vmid_iocb_tag vmid_tag; -void (*fabric_iocb_cmpl)(struct lpfc_hba *,struct lpfc_iocbq *, -struct lpfc_iocbq *); -void (*wait_iocb_cmpl)(struct lpfc_hba *,struct lpfc_iocbq *, -struct lpfc_iocbq *); -void (*iocb_cmpl)(struct lpfc_hba *,struct lpfc_iocbq *, -struct lpfc_iocbq *); -void (*wqe_cmpl)(struct lpfc_hba *,struct lpfc_iocbq *, -struct lpfc_wcqe_complete *); +union lpfc_vmid_tag vmid_tag; +void (*fabric_cmd_cmpl)(struct lpfc_hba *phba,struct lpfc_iocbq *cmd, +struct lpfc_iocbq *rsp); +void (*wait_cmd_cmpl)(struct lpfc_hba *phba,struct lpfc_iocbq *cmd, +struct lpfc_iocbq *rsp); +void (*cmd_cmpl)(struct lpfc_hba *phba,struct lpfc_iocbq *cmd, +struct lpfc_iocbq *rsp); };#define SLI_IOCB_RET_IOCB 1/* Return IOCB if cmd ring full */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 702/779 scsi: lpfc: SLI path split: Refactor fast and slow paths to native SLI4
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 1b64aa9eae28ac598a03ed3d62a63ac5e5b295fc ]
Convert the SLI4 fast and slow paths to use native SLI4 wqe constructs instead of iocb SLI3-isms.
Includes the following:
- Create simple get_xxx and set_xxx routines to wrapper access to common elements in both SLI3 and SLI4 commands - allowing calling routines to avoid sli-rev-specific structures to access the elements.
- using the wqe in the job structure as the primary element
- use defines from SLI-4, not SLI-3
- Removal of iocb to wqe conversion from fast and slow path
- Add below routines to handle fast path lpfc_prep_embed_io - prepares the wqe for fast path
lpfc_wqe_bpl2sgl - manages bpl to sgl conversion
lpfc_sli_wqe2iocb - converts a WQE to IOCB for SLI-3 path
- Add lpfc_sli3_iocb2wcqecmpl in completion path to convert an SLI-3 iocb completion to wcqe completion
- Refactor some of the code that works on both revs for clarity
--- drivers/scsi/lpfc/lpfc.h | 36 +++ drivers/scsi/lpfc/lpfc_crtn.h | 1 + drivers/scsi/lpfc/lpfc_hw4.h | 7 + drivers/scsi/lpfc/lpfc_sli.c | 513 ++++++++++++++-------------------- drivers/scsi/lpfc/lpfc_sli.h | 2 + 5 files changed, 257 insertions(+), 302 deletions(-)
drivers/scsi/lpfc/lpfc.h +36 -0
@@ -1803,3 +1803,39 @@ static inline int lpfc_is_vmid_enabled(struct lpfc_hba *phba) {return phba->cfg_vmid_app_header || phba->cfg_vmid_priority_tagging; } + +static inline +u8 get_job_ulpstatus (struct lpfc_hba *phba,struct lpfc_iocbq *iocbq) +{ +if (phba->sli_rev ==LPFC_SLI_REV4 ) +return bf_get (lpfc_wcqe_c_status, &iocbq->wcqe_cmpl); +else +return iocbq->iocb.ulpStatus; +} + +static inline +u32 get_job_word4 (struct lpfc_hba *phba,struct lpfc_iocbq *iocbq) +{ +if (phba->sli_rev ==LPFC_SLI_REV4 ) +return iocbq->wcqe_cmpl.parameter; +else +return iocbq->iocb.un.ulpWord[4 ]; +} + +static inline +u8 get_job_cmnd (struct lpfc_hba *phba,struct lpfc_iocbq *iocbq) +{ +if (phba->sli_rev ==LPFC_SLI_REV4 ) +return bf_get (wqe_cmnd, &iocbq->wqe.generic.wqe_com); +else +return iocbq->iocb.ulpCommand; +} + +static inline +u16 get_job_ulpcontext (struct lpfc_hba *phba,struct lpfc_iocbq *iocbq) +{ +if (phba->sli_rev ==LPFC_SLI_REV4 ) +return bf_get (wqe_ctxt_tag, &iocbq->wqe.generic.wqe_com); +else +return iocbq->iocb.ulpContext; +}
drivers/scsi/lpfc/lpfc_crtn.h +1 -0
@@ -129,6 +129,7 @@ void lpfc_disc_list_loopmap(struct lpfc_vport *);void lpfc_disc_start (struct lpfc_vport *);void lpfc_cleanup_discovery_resources (struct lpfc_vport *);void lpfc_cleanup (struct lpfc_vport *); +void lpfc_prep_embed_io (struct lpfc_hba *phba,struct lpfc_io_buf *lpfc_ncmd);void lpfc_disc_timeout (struct timer_list *);int lpfc_unregister_fcf_prep (struct lpfc_hba *);
drivers/scsi/lpfc/lpfc_hw4.h +7 -0
@@ -60,6 +60,13 @@ ((ptr)->name##_WORD = ((((value) & name##_MASK) << name##_SHIFT) | \ ((ptr)->name##_WORD & ~(name##_MASK << name##_SHIFT)))) +#define get_wqe_reqtag (x) (((x)->wqe.words[9] >> 0) & 0xFFFF) + +#define get_job_ulpword (x, y) ((x)->iocb.un.ulpWord[y]) + +#define set_job_ulpstatus (x, y) bf_set(lpfc_wcqe_c_status, &(x)->wcqe_cmpl, y) +#define set_job_ulpword4 (x, y) ((&(x)->wcqe_cmpl)->parameter = y) +struct dma_address {uint32_t addr_lo;uint32_t addr_hi;
drivers/scsi/lpfc/lpfc_sli.c +211 -302
724 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli.h +2 -0
@@ -76,6 +76,8 @@ struct lpfc_iocbq {struct lpfc_wcqe_complete wcqe_cmpl;/* WQE cmpl */ uint8_t num_bdes; +uint8_t abort_bls;/* ABTS by initiator or responder */ +uint8_t priority;/* OAS priority */ uint8_t retry;/* retry counter for IOCB cmd - if needed */ u32 cmd_flag;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 703/779 scsi: lpfc: SLI path split: Refactor SCSI paths
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 3512ac0942938d6977e7999ee69765d948d2faf1 ]
This patch refactors the SCSI paths to use SLI-4 as the primary interface.
- Conversion away from using SLI-3 iocb structures to set/access fields in common routines. Use the new generic get/set routines that were added. This move changes code from indirect structure references to using local variables with the generic routines.
- Refactor routines when setting non-generic fields, to have both SLI3 and SLI4 specific sections. This replaces the set-as-SLI3 then translate to SLI4 behavior of the past.
--- drivers/scsi/lpfc/lpfc.h | 4 + drivers/scsi/lpfc/lpfc_scsi.c | 374 +++++++++++++++------------------- drivers/scsi/lpfc/lpfc_sli.c | 6 +- 3 files changed, 174 insertions(+), 210 deletions(-)
drivers/scsi/lpfc/lpfc.h +4 -0
@@ -920,6 +920,10 @@ struct lpfc_hba { (struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, uint8_t tmo); +int (*lpfc_scsi_prep_task_mgmt_cmd) + (struct lpfc_vport *vport, +struct lpfc_io_buf *lpfc_cmd, +u64 lun,u8 task_mgmt_cmd);/* IOCB interface function jump table entries */ int (*__lpfc_sli_issue_iocb)
drivers/scsi/lpfc/lpfc_scsi.c +166 -208
573 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli.c +4 -2
@@ -12968,6 +12968,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,wait_queue_head_t *pdone_q;unsigned long iflags;struct lpfc_io_buf *lpfc_cmd; +size_t offset = offsetof(struct lpfc_iocbq , wqe);spin_lock_irqsave (&phba->hbalock, iflags);if (cmdiocbq->cmd_flag &LPFC_IO_WAKE_TMO ) {
@@ -12988,10 +12989,11 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,return ; } +/* Copy the contents of the local rspiocb into the caller's buffer. */ cmdiocbq->cmd_flag |=LPFC_IO_WAKE ;if (cmdiocbq->context2 && rspiocbq) -memcpy (&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, - &rspiocbq->iocb,sizeof (IOCB_t)); +memcpy ((char *)cmdiocbq->context2 + offset, + (char *)rspiocbq + offset,sizeof (*rspiocbq) - offset);/* Set the exchange busy flag for task management commands */ if ((cmdiocbq->cmd_flag & LPFC_IO_FCP) &&
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 704/779 scsi: lpfc: Remove extra atomic_inc on cmd_pending in queuecommand after VMID
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 0948a9c5386095baae4012190a6b65aba684a907 ]
VMID introduced an extra increment of cmd_pending, causing double-counting of the I/O. The normal increment ios performed in lpfc_get_scsi_buf.
--- drivers/scsi/lpfc/lpfc_scsi.c | 1 - 1 file changed, 1 deletion(-)
drivers/scsi/lpfc/lpfc_scsi.c +0 -1
@@ -5707,7 +5707,6 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) cur_iocbq->cmd_flag |=LPFC_IO_VMID ; } } -atomic_inc (&ndlp->cmd_pending);#ifdef CONFIG_SCSI_LPFC_DEBUG_FS if (unlikely (phba->hdwqstat_on &LPFC_CHECK_SCSI_IO ))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 705/779 intel_th: pci: Add Meteor Lake-P support
In reply to Greg Kroah-HartmanFrom: Alexander Shishkin <[email protected]>
[ Upstream commit 802a9a0b1d91274ef10d9fe429b4cc1e8c200aef ]
Add support for the Trace Hub in Meteor Lake-P.
--- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/hwtracing/intel_th/pci.c +5 -0
@@ -284,6 +284,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6), .driver_data = (kernel_ulong_t)&intel_th_2x, }, + { +/* Meteor Lake-P */ +PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x7e24 ), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, {/* Alder Lake CPU */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 706/779 intel_th: pci: Add Raptor Lake-S PCH support
In reply to Greg Kroah-HartmanFrom: Alexander Shishkin <[email protected]>
[ Upstream commit 23e2de5826e2fc4dd43e08bab3a2ea1a5338b063 ]
Add support for the Trace Hub in Raptor Lake-S PCH.
--- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/hwtracing/intel_th/pci.c +5 -0
@@ -289,6 +289,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7e24), .driver_data = (kernel_ulong_t)&intel_th_2x, }, + { +/* Raptor Lake-S */ +PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x7a26 ), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, {/* Alder Lake CPU */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 707/779 intel_th: pci: Add Raptor Lake-S CPU support
In reply to Greg Kroah-HartmanFrom: Alexander Shishkin <[email protected]>
[ Upstream commit ff46a601afc5a66a81c3945b83d0a2caeb88e8bc ]
Add support for the Trace Hub in Raptor Lake-S CPU.
--- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/hwtracing/intel_th/pci.c +5 -0
@@ -294,6 +294,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26), .driver_data = (kernel_ulong_t)&intel_th_2x, }, + { +/* Raptor Lake-S CPU */ +PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0xa76f ), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, {/* Alder Lake CPU */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 708/779 KVM: set_msr_mce: Permit guests to ignore single-bit ECC errors
In reply to Greg Kroah-HartmanFrom: Lev Kujawski <[email protected]>
[ Upstream commit 0471a7bd1bca2a47a5f378f2222c5cf39ce94152 ]
Certain guest operating systems (e.g., UNIXWARE) clear bit 0 of MC1_CTL to ignore single-bit ECC data errors. Single-bit ECC data errors are always correctable and thus are safe to ignore because they are informational in nature rather than signaling a loss of data integrity.
Prior to this patch, these guests would crash upon writing MC1_CTL, with resultant error messages like the following:
error: kvm run failed Operation not permitted
EAX=fffffffe EBX=fffffffe ECX=00000404 EDX=ffffffff ESI=ffffffff EDI=00000001 EBP=fffdaba4 ESP=fffdab20 EIP=c01333a5 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0108 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
CS =0100 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0108 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
DS =0108 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
FS =0000 00000000 ffffffff 00c00000
GS =0000 00000000 ffffffff 00c00000
LDT=0118 c1026390 00000047 00008200 DPL=0 LDT
TR =0110 ffff5af0 00000067 00008b00 DPL=0 TSS32-busy
GDT= ffff5020 000002cf
IDT= ffff52f0 000007ff
CR0=8001003b CR2=00000000 CR3=0100a000 CR4=00000230 DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 DR6=ffff0ff0 DR7=00000400
EFER=0000000000000000
Code=08 89 01 89 51 04 c3 8b 4c 24 08 8b 01 8b 51 04 8b 4c 24 04 <0f> 30 c3 f7 05 a4 6d ff ff 10 00 00 00 74 03 0f 31 c3 33 c0 33 d2 c3 8d 74 26 00 0f 31 c3
Message-Id: <[email protected]>
--- arch/x86/kvm/x86.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/x86/kvm/x86.c +5 -2
@@ -3102,10 +3102,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, struct msr_data *msr_info)/* only 0 or all 1s can be written to IA32_MCi_CTL * some Linux kernels though clear bit 10 in bank 4 to * workaround a BIOS/GART TBL issue on AMD K8s, ignore -* this to avoid an uncatched #GP in the guest +* this to avoid an uncatched #GP in the guest. +* +* UNIXWARE clears bit 0 of MC1_CTL to ignore +* correctable, single-bit ECC data errors. */ if ((offset &0x3 ) ==0 && - data !=0 && (data | (1 <<10 )) != ~(u64 )0 ) + data !=0 && (data | (1 <<10 ) |1 ) != ~(u64 )0 )return -1 ;/* MCi_STATUS */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 709/779 KVM: x86: Signal #GP, not -EPERM, on bad WRMSR(MCi_CTL/STATUS)
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit 2368048bf5c2ec4b604ac3431564071e89a0bc71 ]
Return '1', not '-1', when handling an illegal WRMSR to a MCi_CTL or MCi_STATUS MSR. The behavior of "all zeros' or "all ones" for CTL MSRs is architectural, as is the "only zeros" behavior for STATUS MSRs. I.e. the intent is to inject a #GP, not exit to userspace due to an unhandled emulation case. Returning '-1' gets interpreted as -EPERM up the stack and effecitvely kills the guest.
--- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/x86.c +2 -2
@@ -3109,13 +3109,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, struct msr_data *msr_info)*/ if ((offset &0x3 ) ==0 && data !=0 && (data | (1 <<10 ) |1 ) != ~(u64 )0 ) -return -1 ; +return 1 ;/* MCi_STATUS */ if (!msr_info->host_initiated && (offset &0x3 ) ==1 && data !=0 ) {if (!can_set_mci_status (vcpu)) -return -1 ; +return 1 ; } vcpu->arch.mce_banks[offset] = data;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 710/779 iommu/vt-d: avoid invalid memory access via node_online(NUMA_NO_NODE)
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
[ Upstream commit b0b0b77ea611e3088e9523e60860f4f41b62b235 ]
KASAN reports:
[ 4.668325][ T0] BUG: KASAN: wild-memory-access in dmar_parse_one_rhsa (arch/x86/include/asm/bitops.h:214 arch/x86/include/asm/bitops.h:226 include/asm-generic/bitops/instrumented-non-atomic.h:142 include/linux/nodemask.h:415 drivers/iommu/intel/dmar.c:497) [ 4.676149][ T0] Read of size 8 at addr 1fffffff85115558 by task swapper/0/0 [ 4.683454][ T0] [ 4.685638][ T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.19.0-rc3-00004-g0e862838f290 #1 [ 4.694331][ T0] Hardware name: Supermicro SYS-5018D-FN4T/X10SDV-8C-TLN4F, BIOS 1.1 03/02/2016 [ 4.703196][ T0] Call Trace: [ 4.706334][ T0] <TASK> [ 4.709133][ T0] ? dmar_parse_one_rhsa (arch/x86/include/asm/bitops.h:214 arch/x86/include/asm/bitops.h:226 include/asm-generic/bitops/instrumented-non-atomic.h:142 include/linux/nodemask.h:415 drivers/iommu/intel/dmar.c:497)
after converting the type of the first argument (@nr, bit number) of arch_test_bit() from long to unsigned long[0].
Under certain conditions (for example, when ACPI NUMA is disabled via command line), pxm_to_node() can return %NUMA_NO_NODE (-1). It is valid 'magic' number of NUMA node, but not valid bit number to use in bitops.node_online() eventually descends to test_bit() without checking for the input, assuming it's on caller side (which might be good for perf-critical tasks). There, -1 becomes %ULONG_MAX which leads to an insane array index when calculating bit position in memory.
For now, add an explicit check for @node being not %NUMA_NO_NODE before calling test_bit(). The actual logics didn't change here at all.
[0] https://github.com/norov/linux/commit/0e862838f290147ea9c16db852d8d494b552d38d
--- drivers/iommu/intel/dmar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel/dmar.c +1 -1
@@ -497,7 +497,7 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg)if (drhd->reg_base_addr == rhsa->base_address) {int node =pxm_to_node (rhsa->proximity_domain); -if (!node_online (node)) +if (node !=NUMA_NO_NODE && !node_online (node)) node =NUMA_NO_NODE ; drhd->iommu->node = node;return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 711/779 PCI/AER: Iterate over error counters instead of error strings
In reply to Greg Kroah-HartmanFrom: Mohamed Khalfella <[email protected]>
[ Upstream commit 5e6ae050955b566484f3cc6a66e3925eae87a0ed ]
Previously we iterated over AER stat *names*, e.g., aer_correctable_error_string[32], but the actual stat *counters* may not be that large, e.g., pdev->aer_stats->dev_cor_errs[16], which means that we printed junk in the sysfs stats files.
Iterate over the stat counter arrays instead of the names to avoid this junk.
Also, added a build time check to make sure all
counters have entries in strings array.
--- drivers/pci/pcie/aer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/pci/pcie/aer.c +6 -1
@@ -538,7 +538,7 @@ static const char *aer_agent_string[] = {u64 *stats = pdev->aer_stats->stats_array; \size_t len =0 ; \ \ -for (i =0 ; i <ARRAY_SIZE (strings_array); i++) { \ +for (i =0 ; i <ARRAY_SIZE (pdev->aer_stats->stats_array); i++) {\if (strings_array[i]) \ len += sysfs_emit_at(buf, len, "%s %llu\n", \ strings_array[i], \
@@ -1347,6 +1347,11 @@ static int aer_probe(struct pcie_device *dev)struct device *device = &dev->device;struct pci_dev *port = dev->port; +BUILD_BUG_ON (ARRAY_SIZE (aer_correctable_error_string) < +AER_MAX_TYPEOF_COR_ERRS ); +BUILD_BUG_ON (ARRAY_SIZE (aer_uncorrectable_error_string) < +AER_MAX_TYPEOF_UNCOR_ERRS ); +/* Limit to Root Ports or Root Complex Event Collectors */ if ((pci_pcie_type (port) !=PCI_EXP_TYPE_RC_EC ) && (pci_pcie_type (port) !=PCI_EXP_TYPE_ROOT_PORT ))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 712/779 PCI: qcom: Power on PHY before IPQ8074 DBI register accesses
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit a0e43bb9973b06ce5c666f0901e104e2037c1b34 ]
Currently the Gen2 port in IPQ8074 will cause the system to hang as it accesses DBI registers in qcom_pcie_init_2_3_3(), and those are only accesible after phy_power_on().
Move the DBI read/writes to a new qcom_pcie_post_init_2_3_3(), which is executed after phy_power_on().
--- drivers/pci/controller/dwc/pcie-qcom.c | 48 +++++++++++++++----------- 1 file changed, 28 insertions(+), 20 deletions(-)
drivers/pci/controller/dwc/pcie-qcom.c +28 -20
@@ -1024,9 +1024,7 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3;struct dw_pcie *pci = pcie->pci;struct device *dev = pci->dev; -u16 offset =dw_pcie_find_capability (pci,PCI_CAP_ID_EXP );int i, ret; -u32 val;for (i =0 ; i <ARRAY_SIZE (res->rst); i++) { ret =reset_control_assert (res->rst[i]);
@@ -1083,6 +1081,33 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) goto err_clk_aux; } +return 0 ; + +err_clk_aux: +clk_disable_unprepare (res->ahb_clk); +err_clk_ahb: +clk_disable_unprepare (res->axi_s_clk); +err_clk_axi_s: +clk_disable_unprepare (res->axi_m_clk); +err_clk_axi_m: +clk_disable_unprepare (res->iface); +err_clk_iface: +/* +* Not checking for failure, will anyway return +* the original failure in 'ret'. +*/ +for (i =0 ; i <ARRAY_SIZE (res->rst); i++) +reset_control_assert (res->rst[i]); + +return ret; +} + +static int qcom_pcie_post_init_2_3_3 (struct qcom_pcie *pcie) +{ +struct dw_pcie *pci = pcie->pci; +u16 offset =dw_pcie_find_capability (pci,PCI_CAP_ID_EXP ); +u32 val; +writel (SLV_ADDR_SPACE_SZ , pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
@@ -1110,24 +1135,6 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) PCI_EXP_DEVCTL2);return 0 ; - -err_clk_aux: -clk_disable_unprepare (res->ahb_clk); -err_clk_ahb: -clk_disable_unprepare (res->axi_s_clk); -err_clk_axi_s: -clk_disable_unprepare (res->axi_m_clk); -err_clk_axi_m: -clk_disable_unprepare (res->iface); -err_clk_iface: -/* -* Not checking for failure, will anyway return -* the original failure in 'ret'. -*/ -for (i =0 ; i <ARRAY_SIZE (res->rst); i++) -reset_control_assert (res->rst[i]); - -return ret; }static int qcom_pcie_get_resources_2_7_0 (struct qcom_pcie *pcie)
@@ -1423,6 +1430,7 @@ static const struct qcom_pcie_ops ops_2_4_0 = {static const struct qcom_pcie_ops ops_2_3_3 = { .get_resources = qcom_pcie_get_resources_2_3_3, .init = qcom_pcie_init_2_3_3, + .post_init = qcom_pcie_post_init_2_3_3, .deinit = qcom_pcie_deinit_2_3_3, .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 713/779 serial: 8250_pci: Refactor the loop in pci_ite887x_init()
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
[ Upstream commit 35b4f17231923e2f64521bdf7a2793ce2c3c74a6 ]
The loop can be refactored by using ARRAY_SIZE() instead of NULL terminator. This reduces code base and makes it easier to read and understand.
--- drivers/tty/serial/8250/8250_pci.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
drivers/tty/serial/8250/8250_pci.c +4 -8
@@ -897,18 +897,16 @@ static int pci_netmos_init(struct pci_dev *dev)/* enable IO_Space bit */ #define ITE_887x_POSIO_ENABLE (1 << 31) +/* inta_addr are the configuration addresses of the ITE */ +static const short inta_addr[] = {0x2a0 ,0x2c0 ,0x220 ,0x240 ,0x1e0 ,0x200 ,0x280 };static int pci_ite887x_init (struct pci_dev *dev) { -/* inta_addr are the configuration addresses of the ITE */ -static const short inta_addr[] = {0x2a0 ,0x2c0 ,0x220 ,0x240 ,0x1e0 , -0x200 ,0x280 ,0 };int ret, i, type;struct resource *iobase =NULL ;u32 miscr, uartbar, ioport;/* search for the base-ioport */ - i =0 ; -while (inta_addr[i] && iobase ==NULL ) { +for (i =0 ; i <ARRAY_SIZE (inta_addr); i++) { iobase =request_region (inta_addr[i], ITE_887x_IOSIZE,"ite887x" );if (iobase !=NULL ) {
@@ -925,12 +923,10 @@ static int pci_ite887x_init(struct pci_dev *dev)break ; }release_region (iobase->start, ITE_887x_IOSIZE); - iobase =NULL ; } - i++; } -if (!inta_addr[i]) { +if (i ==ARRAY_SIZE (inta_addr)) {dev_err (&dev->dev,"ite887x: could not find iobase\n" );return -ENODEV ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 714/779 serial: 8250_pci: Replace dev_*() by pci_*() macros
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
[ Upstream commit 1177384179416c7136e1348f07609e0da1ae6b91 ]
PCI subsystem provides convenient shortcut macros for message printing. Use those macros instead of dev_*().
--- drivers/tty/serial/8250/8250_pci.c | 52 +++++++++++++----------------- 1 file changed, 22 insertions(+), 30 deletions(-)
drivers/tty/serial/8250/8250_pci.c +22 -30
@@ -75,13 +75,12 @@ static int pci_default_setup(struct serial_private*,static void moan_device (const char *str,struct pci_dev *dev) { -dev_err (&dev->dev, -"%s: %s\n" +pci_err (dev,"%s\n" "Please send the output of lspci -vv, this\n" "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n" "manufacturer and name of serial board or\n" "modem board to <[email protected]>.\n" , -pci_name (dev), str, dev->vendor, dev->device, + str, dev->vendor, dev->device, dev->subsystem_vendor, dev->subsystem_device); }
@@ -238,7 +237,7 @@ static int pci_inteli960ni_init(struct pci_dev *dev)/* is firmware started? */ pci_read_config_dword (dev,0x44 , &oldval);if (oldval ==0x00001000L ) {/* RESET value */ -dev_dbg (&dev->dev,"Local i960 firmware missing\n" ); +pci_dbg (dev,"Local i960 firmware missing\n" );return -ENODEV ; }return 0 ;
@@ -588,9 +587,8 @@ static int pci_timedia_probe(struct pci_dev *dev)* (0,2,3,5,6: serial only -- 7,8,9: serial + parallel) */ if ((dev->subsystem_device &0x00f0 ) >=0x70 ) { -dev_info (&dev->dev, -"ignoring Timedia subdevice %04x for parport_serial\n" , - dev->subsystem_device); +pci_info (dev,"ignoring Timedia subdevice %04x for parport_serial\n" , + dev->subsystem_device);return -ENODEV ; }
@@ -827,8 +825,7 @@ static int pci_netmos_9900_numports(struct pci_dev *dev)if (sub_serports >0 )return sub_serports; -dev_err (&dev->dev, -"NetMos/Mostech serial driver ignoring port on ambiguous config.\n" ); +pci_err (dev,"NetMos/Mostech serial driver ignoring port on ambiguous config.\n" );return 0 ; }
@@ -927,7 +924,7 @@ static int pci_ite887x_init(struct pci_dev *dev) }if (i ==ARRAY_SIZE (inta_addr)) { -dev_err (&dev->dev,"ite887x: could not find iobase\n" ); +pci_err (dev,"could not find iobase\n" );return -ENODEV ; }
@@ -1022,9 +1019,7 @@ static int pci_endrun_init(struct pci_dev *dev)/* EndRun device */ if (deviceID ==0x07000200 ) { number_uarts =ioread8 (p +4 ); -dev_dbg (&dev->dev, -"%d ports detected on EndRun PCI Express device\n" , - number_uarts); +pci_dbg (dev,"%d ports detected on EndRun PCI Express device\n" , number_uarts); }pci_iounmap (dev, p);return number_uarts;
@@ -1054,9 +1049,7 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)/* Tornado device */ if (deviceID ==0x07000200 ) { number_uarts =ioread8 (p +4 ); -dev_dbg (&dev->dev, -"%d ports detected on Oxford PCI Express device\n" , - number_uarts); +pci_dbg (dev,"%d ports detected on Oxford PCI Express device\n" , number_uarts); }pci_iounmap (dev, p);return number_uarts;
@@ -1116,15 +1109,15 @@ static struct quatech_feature quatech_cards[] = { { 0, } }; -static int pci_quatech_amcc (u16 devid) +static int pci_quatech_amcc (struct pci_dev *dev) {struct quatech_feature *qf = &quatech_cards[0 ];while (qf->devid) { -if (qf->devid == devid) +if (qf->devid == dev->device)return qf->amcc; qf++; } -pr_err ("quatech: unknown port type '0x%04X'.\n" , devid); +pci_err (dev,"unknown port type '0x%04X'.\n" , dev->device);return 0 ; };
@@ -1287,7 +1280,7 @@ static int pci_quatech_rs422(struct uart_8250_port *port)static int pci_quatech_init (struct pci_dev *dev) { -if (pci_quatech_amcc (dev->device)) { +if (pci_quatech_amcc (dev)) {unsigned long base =pci_resource_start (dev,0 );if (base) {u32 tmp;
@@ -1311,7 +1304,7 @@ static int pci_quatech_setup(struct serial_private *priv, port->port.uartclk =pci_quatech_clock (port);/* For now just warn about RS422 */ if (pci_quatech_rs422 (port)) -pr_warn ("quatech: software control of RS422 features not currently supported.\n" ); +pci_warn (priv->dev,"software control of RS422 features not currently supported.\n" );return pci_default_setup (priv, board, port, idx); }
@@ -1525,7 +1518,7 @@ static int pci_fintek_setup(struct serial_private *priv,/* Get the io address from configuration space */ pci_read_config_word (pdev, config_base +4 , &iobase); -dev_dbg (&pdev->dev,"%s: idx=%d iobase=0x%x" , __func__, idx, iobase); +pci_dbg (pdev,"idx=%d iobase=0x%x" , idx, iobase); port->port.iotype =UPIO_PORT ; port->port.iobase = iobase;
@@ -1689,7 +1682,7 @@ static int skip_tx_en_setup(struct serial_private *priv, struct uart_8250_port *port, int idx) { port->port.quirks |=UPQ_NO_TXEN_TEST ; -dev_dbg (&priv->dev->dev, +pci_dbg (priv->dev,"serial8250: skipping TxEn test for device [%04x:%04x] subsystem [%04x:%04x]\n" , priv->dev->vendor, priv->dev->device, priv->dev->subsystem_vendor, priv->dev->subsystem_device);
@@ -4007,12 +4000,12 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) uart.port.irq =0 ; }else {if (pci_match_id (pci_use_msi, dev)) { -dev_dbg (&dev->dev,"Using MSI(-X) interrupts\n" ); +pci_dbg (dev,"Using MSI(-X) interrupts\n" );pci_set_master (dev); uart.port.flags &= ~UPF_SHARE_IRQ ; rc =pci_alloc_irq_vectors (dev,1 ,1 ,PCI_IRQ_ALL_TYPES ); }else { -dev_dbg (&dev->dev,"Using legacy interrupts\n" ); +pci_dbg (dev,"Using legacy interrupts\n" ); rc =pci_alloc_irq_vectors (dev,1 ,1 ,PCI_IRQ_LEGACY ); }if (rc <0 ) {
@@ -4030,12 +4023,12 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)if (quirk->setup (priv, board, &uart, i))break ; -dev_dbg (&dev->dev,"Setup PCI port: port %lx, irq %d, type %d\n" , +pci_dbg (dev,"Setup PCI port: port %lx, irq %d, type %d\n" , uart.port.iobase, uart.port.irq, uart.port.iotype); priv->line[i] =serial8250_register_8250_port (&uart);if (priv->line[i] <0 ) { -dev_err (&dev->dev, +pci_err (dev,"Couldn't register serial port %lx, irq %d, type %d, error %d\n" , uart.port.iobase, uart.port.irq, uart.port.iotype, priv->line[i]);
@@ -4131,8 +4124,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) }if (ent->driver_data >=ARRAY_SIZE (pci_boards)) { -dev_err (&dev->dev,"invalid driver_data: %ld\n" , - ent->driver_data); +pci_err (dev,"invalid driver_data: %ld\n" , ent->driver_data);return -EINVAL ; }
@@ -4215,7 +4207,7 @@ static int pciserial_resume_one(struct device *dev) err =pci_enable_device (pdev);/* FIXME: We cannot simply error out here */ if (err) -dev_err (dev,"Unable to re-enable ports, trying to continue.\n" ); +pci_err (pdev,"Unable to re-enable ports, trying to continue.\n" );pciserial_resume_ports (priv); }return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 715/779 serial: 8250: Fold EndRun device support into OxSemi Tornado code
In reply to Greg Kroah-HartmanFrom: Maciej W. Rozycki <[email protected]>
[ Upstream commit 1f32c65bad24b9787d3e52843de375430e3df822 ]
The EndRun PTP/1588 dual serial port device is based on the Oxford Semiconductor OXPCIe952 UART device with the PCI vendor:device ID set for EndRun Technologies and uses the same sequence to determine the number of ports available. Despite that we have duplicate code specific to the EndRun device.
Remove redundant code then and factor out OxSemi Tornado device detection.
--- drivers/tty/serial/8250/8250_pci.c | 76 ++++++++++-------------------- 1 file changed, 25 insertions(+), 51 deletions(-)
drivers/tty/serial/8250/8250_pci.c +25 -51
@@ -994,41 +994,29 @@ static void pci_ite887x_exit(struct pci_dev *dev) }/* -* EndRun Technologies. -* Determine the number of ports available on the device. +* Oxford Semiconductor Inc. +* Check if an OxSemi device is part of the Tornado range of devices. */ #define PCI_VENDOR_ID_ENDRUN 0x7401#define PCI_DEVICE_ID_ENDRUN_1588 0xe100 -static int pci_endrun_init (struct pci_dev *dev) +static bool pci_oxsemi_tornado_p (struct pci_dev *dev) { -u8 __iomem *p; -unsigned long deviceID; -unsigned int number_uarts =0 ; +/* OxSemi Tornado devices are all 0xCxxx */ +if (dev->vendor ==PCI_VENDOR_ID_OXSEMI && + (dev->device &0xf000 ) !=0xc000 ) +return false; -/* EndRun device is all 0xexxx */ +/* EndRun devices are all 0xExxx */ if (dev->vendor ==PCI_VENDOR_ID_ENDRUN && - (dev->device &0xf000 ) !=0xe000 ) -return 0 ; - - p =pci_iomap (dev,0 ,5 ); -if (p ==NULL ) -return -ENOMEM ; + (dev->device &0xf000 ) !=0xe000 ) +return false; - deviceID =ioread32 (p); -/* EndRun device */ -if (deviceID ==0x07000200 ) { - number_uarts =ioread8 (p +4 ); -pci_dbg (dev,"%d ports detected on EndRun PCI Express device\n" , number_uarts); - } -pci_iounmap (dev, p); -return number_uarts; +return true; }/* -* Oxford Semiconductor Inc. -* Check that device is part of the Tornado range of devices, then determine -* the number of ports available on the device. +* Determine the number of ports available on a Tornado device. */ static int pci_oxsemi_tornado_init (struct pci_dev *dev) {
@@ -1036,9 +1024,7 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)unsigned long deviceID;unsigned int number_uarts =0 ; -/* OxSemi Tornado devices are all 0xCxxx */ -if (dev->vendor ==PCI_VENDOR_ID_OXSEMI && - (dev->device &0xF000 ) !=0xC000 ) +if (!pci_oxsemi_tornado_p (dev))return 0 ; p =pci_iomap (dev,0 ,5 );
@@ -1049,7 +1035,10 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)/* Tornado device */ if (deviceID ==0x07000200 ) { number_uarts =ioread8 (p +4 ); -pci_dbg (dev,"%d ports detected on Oxford PCI Express device\n" , number_uarts); +pci_dbg (dev,"%d ports detected on %s PCI Express device\n" , + number_uarts, + dev->vendor ==PCI_VENDOR_ID_ENDRUN ? +"EndRun" :"Oxford" ); }pci_iounmap (dev, p);return number_uarts;
@@ -2506,7 +2495,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = { .device = PCI_ANY_ID, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .init = pci_endrun_init, + .init = pci_oxsemi_tornado_init, .setup = pci_default_setup, },/*
@@ -2929,7 +2918,6 @@ enum pci_board_num_t { pbn_panacom2, pbn_panacom4, pbn_plx_romulus, - pbn_endrun_2_3906250, pbn_oxsemi, pbn_oxsemi_1_3906250, pbn_oxsemi_2_3906250,
@@ -3455,20 +3443,6 @@ static struct pciserial_board pci_boards[] = { .first_offset = 0x03, }, -/* -* EndRun Technologies -* Uses the size of PCI Base region 0 to -* signal now many ports are available -* 2 port 952 Uart support -*/ - [pbn_endrun_2_3906250] = { - .flags = FL_BASE0, - .num_ports = 2, - .base_baud = 3906250, - .uart_offset = 0x200, - .first_offset = 0x1000, - }, -/* * This board uses the size of PCI Base region 0 to * signal now many ports are available
@@ -4400,13 +4374,6 @@ static const struct pci_device_id serial_pci_tbl[] = { {PCI_VENDOR_ID_PLX ,PCI_DEVICE_ID_PLX_ROMULUS ,0x10b5 ,0x106a ,0 ,0 , pbn_plx_romulus }, -/* -* EndRun Technologies. PCI express device range. -* EndRun PTP/1588 has 2 Native UARTs. -*/ - { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588, -PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , - pbn_endrun_2_3906250 },/* * Quatech cards. These actually have configurable clocks but for * now we just use the default.
@@ -4668,6 +4635,13 @@ static const struct pci_device_id serial_pci_tbl[] = { {PCI_VENDOR_ID_DIGI ,PCIE_DEVICE_ID_NEO_2_OX_IBM ,PCI_SUBVENDOR_ID_IBM ,PCI_ANY_ID ,0 ,0 , pbn_oxsemi_2_3906250 }, +/* +* EndRun Technologies. PCI express device range. +* EndRun PTP/1588 has 2 Native UARTs utilizing OxSemi 952. +*/ + { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588, +PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , + pbn_oxsemi_2_3906250 },/* * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 716/779 serial: 8250: Add proper clock handling for OxSemi PCIe devices
In reply to Greg Kroah-HartmanFrom: Maciej W. Rozycki <[email protected]>
[ Upstream commit 366f6c955d4d1a5125ffcd6875ead26a3c7a2a1c ]
Oxford Semiconductor PCIe (Tornado) 950 serial port devices are driven by a fixed 62.5MHz clock input derived from the 100MHz PCI Express clock.
We currently drive the device using its default oversampling rate of 16 and the clock prescaler disabled, consequently yielding the baud base of 3906250. This base is inadequate for some of the high-speed baud rates such as 460800bps, for which the closest rate possible can be obtained by dividing the baud base by 8, yielding the baud rate of 488281.25bps, which is off by 5.9638%. This is enough for data communication to break with the remote end talking actual 460800bps, where missed stop bits have been observed.
We can do better however, by taking advantage of a reduced oversampling rate, which can be set to any integer value from 4 to 16 inclusive by programming the TCR register, and by using the clock prescaler, which can be set to any value from 1 to 63.875 in increments of 0.125 in the CPR/CPR2 register pair. The prescaler has to be explicitly enabled though by setting bit 7 in the MCR or otherwise it is bypassed (in the enhanced mode that we enable) as if the value of 1 was used.
Make use of these features then as follows:
- Set the baud base to 15625000, reflecting the minimum oversampling rate of 4 with the clock prescaler and divisor both set to 1.
- Override the `set_mctrl' and set the MCR shadow there so as to have MCR[7] always set and have the 8250 core propagate these settings.
- Override the `get_divisor' handler and determine a good combination of parameters by using a lookup table with predetermined value pairs of the oversampling rate and the clock prescaler and finding a pair that divides the input clock such that the quotient, when rounded to the nearest integer, deviates the least from the exact result. Calculate the clock divisor accordingly.
Scale the resulting oversampling rate (only by powers of two) if possible so as to maximise it, reducing the divisor accordingly, and avoid a divisor overflow for very low baud rates by scaling the oversampling rate and/or the prescaler even if that causes some accuracy loss.
Also handle the historic spd_cust feature so as to allow one to set all the three parameters manually to arbitrary values, by keeping the low 16 bits for the divisor and then putting TCR in bits 19:16 and CPR/CPR2 in bits 28:20, sanitising the bit pattern supplied such as to clamp CPR/CPR2 values between 0.000 and 0.875 inclusive to 33.875. This preserves compatibility with any existing setups, that is where requesting a custom divisor that only has any bits set among the low 16 the oversampling rate of 16 and the clock prescaler of 33.875 will be used as with the original 8250.
Finally abuse the `frac' argument to store the determined bit patterns for the TCR, CPR and CPR2 registers.
- Override the set_divisor' handler so as to set the TCR, CPR and CPR2 registers from the frac' value supplied. Set the divisor as usual.
With the baud base set to 15625000 and the unsigned 16-bit UART_DIV_MAX limitation imposed by `serial8250_get_baud_rate' standard baud rates below 300bps become unavailable in the regular way, e.g. the rate of 200bps requires the baud base to be divided by 78125 and that is beyond the unsigned 16-bit range. The historic spd_cust feature can still be used to obtain such rates if so required.
See Documentation/tty/device_drivers/oxsemi-tornado.rst for more details.
--- .../tty/device_drivers/oxsemi-tornado.rst | 129 +++++++ drivers/tty/serial/8250/8250_pci.c | 339 ++++++++++++++---- 2 files changed, 400 insertions(+), 68 deletions(-) create mode 100644 Documentation/tty/device_drivers/oxsemi-tornado.rst
Documentation/tty/device_drivers/oxsemi-tornado.rst new file +129 -0
@@ -0,0 +1,129 @@ +.. SPDX-License-Identifier: GPL-2.0 + +==================================================================== +Notes on Oxford Semiconductor PCIe (Tornado) 950 serial port devices +==================================================================== + +Oxford Semiconductor PCIe (Tornado) 950 serial port devices are driven +by a fixed 62.5MHz clock input derived from the 100MHz PCI Express clock. + +The baud rate produced by the baud generator is obtained from this input +frequency by dividing it by the clock prescaler, which can be set to any +value from 1 to 63.875 in increments of 0.125, and then the usual 16-bit +divisor is used as with the original 8250, to divide the frequency by a +value from 1 to 65535. Finally a programmable oversampling rate is used +that can take any value from 4 to 16 to divide the frequency further and +determine the actual baud rate used. Baud rates from 15625000bps down +to 0.933bps can be obtained this way. + +By default the oversampling rate is set to 16 and the clock prescaler is +set to 33.875, meaning that the frequency to be used as the reference +for the usual 16-bit divisor is 115313.653, which is close enough to the +frequency of 115200 used by the original 8250 for the same values to be +used for the divisor to obtain the requested baud rates by software that +is unaware of the extra clock controls available. + +The oversampling rate is programmed with the TCR register and the clock +prescaler is programmed with the CPR/CPR2 register pair[1][2][3][4]. +To switch away from the default value of 33.875 for the prescaler the +the enhanced mode has to be explicitly enabled though, by setting bit 4 +of the EFR. In that mode setting bit 7 in the MCR enables the prescaler +or otherwise it is bypassed as if the value of 1 was used. Additionally +writing any value to CPR clears CPR2 for compatibility with old software +written for older conventional PCI Oxford Semiconductor devices that do +not have the extra prescaler's 9th bit in CPR2, so the CPR/CPR2 register +pair has to be programmed in the right order. + +By using these parameters rates from 15625000bps down to 1bps can be +obtained, with either exact or highly-accurate actual bit rates for +standard and many non-standard rates. + +Here are the figures for the standard and some non-standard baud rates +(including those quoted in Oxford Semiconductor documentation), giving +the requested rate (r), the actual rate yielded (a) and its deviation +from the requested rate (d), and the values of the oversampling rate +(tcr), the clock prescaler (cpr) and the divisor (div) produced by the +new `get_divisor' handler: + +r: 15625000, a: 15625000.00, d: 0.0000%, tcr: 4, cpr: 1.000, div: 1 +r: 12500000, a: 12500000.00, d: 0.0000%, tcr: 5, cpr: 1.000, div: 1 +r: 10416666, a: 10416666.67, d: 0.0000%, tcr: 6, cpr: 1.000, div: 1 +r: 8928571, a: 8928571.43, d: 0.0000%, tcr: 7, cpr: 1.000, div: 1 +r: 7812500, a: 7812500.00, d: 0.0000%, tcr: 8, cpr: 1.000, div: 1 +r: 4000000, a: 4000000.00, d: 0.0000%, tcr: 5, cpr: 3.125, div: 1 +r: 3686400, a: 3676470.59, d: -0.2694%, tcr: 8, cpr: 2.125, div: 1 +r: 3500000, a: 3496503.50, d: -0.0999%, tcr: 13, cpr: 1.375, div: 1 +r: 3000000, a: 2976190.48, d: -0.7937%, tcr: 14, cpr: 1.500, div: 1 +r: 2500000, a: 2500000.00, d: 0.0000%, tcr: 10, cpr: 2.500, div: 1 +r: 2000000, a: 2000000.00, d: 0.0000%, tcr: 10, cpr: 3.125, div: 1 +r: 1843200, a: 1838235.29, d: -0.2694%, tcr: 16, cpr: 2.125, div: 1 +r: 1500000, a: 1492537.31, d: -0.4975%, tcr: 5, cpr: 8.375, div: 1 +r: 1152000, a: 1152073.73, d: 0.0064%, tcr: 14, cpr: 3.875, div: 1 +r: 921600, a: 919117.65, d: -0.2694%, tcr: 16, cpr: 2.125, div: 2 +r: 576000, a: 576036.87, d: 0.0064%, tcr: 14, cpr: 3.875, div: 2 +r: 460800, a: 460829.49, d: 0.0064%, tcr: 7, cpr: 3.875, div: 5 +r: 230400, a: 230414.75, d: 0.0064%, tcr: 14, cpr: 3.875, div: 5 +r: 115200, a: 115207.37, d: 0.0064%, tcr: 14, cpr: 1.250, div: 31 +r: 57600, a: 57603.69, d: 0.0064%, tcr: 8, cpr: 3.875, div: 35 +r: 38400, a: 38402.46, d: 0.0064%, tcr: 14, cpr: 3.875, div: 30 +r: 19200, a: 19201.23, d: 0.0064%, tcr: 8, cpr: 3.875, div: 105 +r: 9600, a: 9600.06, d: 0.0006%, tcr: 9, cpr: 1.125, div: 643 +r: 4800, a: 4799.98, d: -0.0004%, tcr: 7, cpr: 2.875, div: 647 +r: 2400, a: 2400.02, d: 0.0008%, tcr: 9, cpr: 2.250, div: 1286 +r: 1200, a: 1200.00, d: 0.0000%, tcr: 14, cpr: 2.875, div: 1294 +r: 300, a: 300.00, d: 0.0000%, tcr: 11, cpr: 2.625, div: 7215 +r: 200, a: 200.00, d: 0.0000%, tcr: 16, cpr: 1.250, div: 15625 +r: 150, a: 150.00, d: 0.0000%, tcr: 13, cpr: 2.250, div: 14245 +r: 134, a: 134.00, d: 0.0000%, tcr: 11, cpr: 2.625, div: 16153 +r: 110, a: 110.00, d: 0.0000%, tcr: 12, cpr: 1.000, div: 47348 +r: 75, a: 75.00, d: 0.0000%, tcr: 4, cpr: 5.875, div: 35461 +r: 50, a: 50.00, d: 0.0000%, tcr: 16, cpr: 1.250, div: 62500 +r: 25, a: 25.00, d: 0.0000%, tcr: 16, cpr: 2.500, div: 62500 +r: 4, a: 4.00, d: 0.0000%, tcr: 16, cpr: 20.000, div: 48828 +r: 2, a: 2.00, d: 0.0000%, tcr: 16, cpr: 40.000, div: 48828 +r: 1, a: 1.00, d: 0.0000%, tcr: 16, cpr: 63.875, div: 61154 + +With the baud base set to 15625000 and the unsigned 16-bit UART_DIV_MAX +limitation imposed by `serial8250_get_baud_rate' standard baud rates +below 300bps become unavailable in the regular way, e.g. the rate of +200bps requires the baud base to be divided by 78125 and that is beyond +the unsigned 16-bit range. The historic spd_cust feature can still be +used by encoding the values for, the prescaler, the oversampling rate +and the clock divisor (DLM/DLL) as follows to obtain such rates if so +required: + + 31 29 28 20 19 16 15 0 ++-----+-----------------+-------+-------------------------------+ +|0 0 0| CPR2:CPR | TCR | DLM:DLL | ++-----+-----------------+-------+-------------------------------+ + +Use a value such encoded for the `custom_divisor' field along with the +ASYNC_SPD_CUST flag set in the `flags' field in `struct serial_struct' +passed with the TIOCSSERIAL ioctl(2), such as with the setserial(8) +utility and its `divisor' and `spd_cust' parameters, and the select +the baud rate of 38400bps. Note that the value of 0 in TCR sets the +oversampling rate to 16 and prescaler values below 1 in CPR2/CPR are +clamped by the driver to 1. + +For example the value of 0x1f4004e2 will set CPR2/CPR, TCR and DLM/DLL +respectively to 0x1f4, 0x0 and 0x04e2, choosing the prescaler value, +the oversampling rate and the clock divisor of 62.500, 16 and 1250 +respectively. These parameters will set the baud rate for the serial +port to 62500000 / 62.500 / 1250 / 16 = 50bps. + +References: + +[1] "OXPCIe200 PCI Express Multi-Port Bridge", Oxford Semiconductor, + Inc., DS-0045, 10 Nov 2008, Section "950 Mode", pp. 64-65 + +[2] "OXPCIe952 PCI Express Bridge to Dual Serial & Parallel Port", + Oxford Semiconductor, Inc., DS-0046, Mar 06 08, Section "950 Mode", + p. 20 + +[3] "OXPCIe954 PCI Express Bridge to Quad Serial Port", Oxford + Semiconductor, Inc., DS-0047, Feb 08, Section "950 Mode", p. 20 + +[4] "OXPCIe958 PCI Express Bridge to Octal Serial Port", Oxford + Semiconductor, Inc., DS-0048, Feb 08, Section "950 Mode", p. 20 + +Maciej W. Rozycki <[email protected]>
drivers/tty/serial/8250/8250_pci.c +271 -68
527 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 717/779 tty: 8250: Add support for Brainboxes PX cards.
In reply to Greg Kroah-HartmanFrom: Cameron Williams <[email protected]>
[ Upstream commit ef5a03a26c87a760bc3d86b5af7b773e82f8b1b7 ]
Add support for some of the Brainboxes PCIe (PX) range of serial cards, including the PX-101, PX-235/PX-246, PX-203/PX-257, PX-260/PX-701, PX-310, PX-313, PX-320/PX-324/PX-376/PX-387, PX-335/PX-346, PX-368, PX-420, PX-803 and PX-846.
--- drivers/tty/serial/8250/8250_pci.c | 109 +++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)
drivers/tty/serial/8250/8250_pci.c +109 -0
@@ -5475,6 +5475,115 @@ static const struct pci_device_id serial_pci_tbl[] = {PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , pbn_b2_4_115200 }, +/* +* Brainboxes PX-101 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x4005, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_b0_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4019, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_2_15625000 }, +/* +* Brainboxes PX-235/246 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x4004, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_b0_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4016, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_1_15625000 }, +/* +* Brainboxes PX-203/PX-257 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x4006, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_b0_2_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4015, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_4_15625000 }, +/* +* Brainboxes PX-260/PX-701 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x400A, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_4_15625000 }, +/* +* Brainboxes PX-310 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x400E, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_2_15625000 }, +/* +* Brainboxes PX-313 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x400C, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_2_15625000 }, +/* +* Brainboxes PX-320/324/PX-376/PX-387 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x400B, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_1_15625000 }, +/* +* Brainboxes PX-335/346 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x400F, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_4_15625000 }, +/* +* Brainboxes PX-368 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x4010, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_4_15625000 }, +/* +* Brainboxes PX-420 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x4000, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_b0_4_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4011, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_4_15625000 }, +/* +* Brainboxes PX-803 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x4009, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_b0_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x401E, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_1_15625000 }, +/* +* Brainboxes PX-846 +*/ + { PCI_VENDOR_ID_INTASHIELD, 0x4008, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_b0_1_115200 }, + { PCI_VENDOR_ID_INTASHIELD, 0x4017, +PCI_ANY_ID ,PCI_ANY_ID , +0 ,0 , + pbn_oxsemi_1_15625000 }, +/* * Perle PCI-RAS cards */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 718/779 dm writecache: set a default MAX_WRITEBACK_JOBS
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
[ Upstream commit ca7dc242e358e46d963b32f9d9dd829785a9e957 ]
dm-writecache has the capability to limit the number of writeback jobs in progress. However, this feature was off by default. As such there were some out-of-memory crashes observed when lowering the low watermark while the cache is full.
This commit enables writeback limit by default. It is set to 256MiB or 1/16 of total system memory, whichever is smaller.
--- drivers/md/dm-writecache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm-writecache.c +1 -1
@@ -22,7 +22,7 @@#define HIGH_WATERMARK 50#define LOW_WATERMARK 45 -#define MAX_WRITEBACK_JOBS 0 +#define MAX_WRITEBACK_JOBS min(0x10000000 / PAGE_SIZE, totalram_pages() / 16)#define ENDIO_LATENCY 16#define WRITEBACK_LATENCY 64#define AUTOCOMMIT_BLOCKS_SSD 65536
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 719/779 kexec, KEYS, s390: Make use of built-in and secondary keyring for signature verification
In reply to Greg Kroah-HartmanFrom: Michal Suchanek <[email protected]>
[ Upstream commit 0828c4a39be57768b8788e8cbd0d84683ea757e5 ]
commit e23a8020ce4e ("s390/kexec_file: Signature verification prototype") adds support for KEXEC_SIG verification with keys from platform keyring but the built-in keys and secondary keyring are not used.
Add support for the built-in keys and secondary keyring as x86 does.
--- arch/s390/kernel/machine_kexec_file.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
arch/s390/kernel/machine_kexec_file.c +13 -5
@@ -29,6 +29,7 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len)const unsigned long marker_len =sizeof (MODULE_SIG_STRING ) -1 ;struct module_signature *ms;unsigned long sig_len; +int ret;/* Skip signature verification when not secure IPLed. */ if (!ipl_secure_flag)
@@ -63,11 +64,18 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len) return -EBADMSG; } -return verify_pkcs7_signature (kernel, kernel_len, - kernel + kernel_len, sig_len, -VERIFY_USE_PLATFORM_KEYRING , -VERIFYING_MODULE_SIGNATURE , -NULL ,NULL ); + ret =verify_pkcs7_signature (kernel, kernel_len, + kernel + kernel_len, sig_len, +VERIFY_USE_SECONDARY_KEYRING , +VERIFYING_MODULE_SIGNATURE , +NULL ,NULL ); +if (ret == -ENOKEY &&IS_ENABLED (CONFIG_INTEGRITY_PLATFORM_KEYRING )) + ret =verify_pkcs7_signature (kernel, kernel_len, + kernel + kernel_len, sig_len, +VERIFY_USE_PLATFORM_KEYRING , +VERIFYING_MODULE_SIGNATURE , +NULL ,NULL ); +return ret; }#endif /* CONFIG_KEXEC_SIG */
Signature · 9 lines
2.35.1 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
Greg Kroah-Hartman
maintainerPATCH 720/779 dm thin: fix use-after-free crash in dm_sm_register_threshold_callback
In reply to Greg Kroah-HartmanFrom: Luo Meng <[email protected]>
[ Upstream commit 3534e5a5ed2997ca1b00f44a0378a075bd05e8a3 ]
Fault inject on pool metadata device reports:
BUG: KASAN: use-after-free in dm_pool_register_metadata_threshold+0x40/0x80 Read of size 8 at addr ffff8881b9d50068 by task dmsetup/950 CPU: 7 PID: 950 Comm: dmsetup Tainted: G W 5.19.0-rc6 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x34/0x44 print_address_description.constprop.0.cold+0xeb/0x3f4 kasan_report.cold+0xe6/0x147 dm_pool_register_metadata_threshold+0x40/0x80 pool_ctr+0xa0a/0x1150 dm_table_add_target+0x2c8/0x640 table_load+0x1fd/0x430 ctl_ioctl+0x2c4/0x5a0 dm_ctl_ioctl+0xa/0x10 __x64_sys_ioctl+0xb3/0xd0 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0
This can be easily reproduced using:
echo offline > /sys/block/sda/device/state
dd if=/dev/zero of=/dev/mapper/thin bs=4k count=10
dmsetup load pool --table "0 20971520 thin-pool /dev/sda /dev/sdb 128 0 0"
If a metadata commit fails, the transaction will be aborted and the metadata space maps will be destroyed. If a DM table reload then happens for this failed thin-pool, a use-after-free will occur in dm_sm_register_threshold_callback (called from dm_pool_register_metadata_threshold).
Fix this by in dm_pool_register_metadata_threshold() by returning the -EINVAL error if the thin-pool is in fail mode. Also fail pool_ctr() with a new error message: "Error registering metadata threshold".
--- drivers/md/dm-thin-metadata.c | 7 +++++-- drivers/md/dm-thin.c | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-)
drivers/md/dm-thin-metadata.c +5 -2
@@ -2073,10 +2073,13 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,dm_sm_threshold_fn fn, void *context) { - int r; + int r = -EINVAL;pmd_write_lock_in_core (pmd); - r =dm_sm_register_threshold_callback (pmd->metadata_sm, threshold, fn, context); +if (!pmd->fail_io) { + r =dm_sm_register_threshold_callback (pmd->metadata_sm, + threshold, fn, context); + }pmd_write_unlock (pmd);return r;
drivers/md/dm-thin.c +3 -1
@@ -3401,8 +3401,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)calc_metadata_threshold (pt), metadata_low_callback, pool); -if (r) +if (r) { + ti->error ="Error registering metadata threshold" ; goto out_flags_changed; + }dm_pool_register_pre_commit_callback (pool->pmd, metadata_pre_commit_callback, pool);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 721/779 net/9p: Initialize the iounit field during fid creation
In reply to Greg Kroah-HartmanFrom: Tyler Hicks <[email protected]>
[ Upstream commit aa7aeee169480e98cf41d83c01290a37e569be6d ]
Ensure that the fid's iounit field is set to zero when a new fid is created. Certain 9P operations, such as OPEN and CREATE, allow the server to reply with an iounit size which the client code assigns to the p9_fid struct shortly after the fid is created by p9_fid_create(). On the other hand, an XATTRWALK operation doesn't allow for the server to specify an iounit value. The iounit field of the newly allocated p9_fid struct remained uninitialized in that case. Depending on allocation patterns, the iounit value could have been something reasonable that was carried over from previously freed fids or, in the worst case, could have been arbitrary values from non-fid related usages of the memory location.
The bug was detected in the Windows Subsystem for Linux 2 (WSL2) kernel after the uninitialized iounit field resulted in the typical sequence of two getxattr(2) syscalls, one to get the size of an xattr and another after allocating a sufficiently sized buffer to fit the xattr value, to hit an unexpected ERANGE error in the second call to getxattr(2). An uninitialized iounit field would sometimes force rsize to be smaller than the xattr value size in p9_client_read_once() and the 9P server in WSL refused to chunk up the READ on the attr_fid and, instead, returned ERANGE to the client. The virtfs server in QEMU seems happy to chunk up the READ and this problem goes undetected there.
--- net/9p/client.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
net/9p/client.c +1 -4
@@ -888,16 +888,13 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)struct p9_fid *fid;p9_debug (P9_DEBUG_FID ,"clnt %p\n" , clnt); - fid =kmalloc (sizeof (*fid),GFP_KERNEL ); + fid =kzalloc (sizeof (*fid),GFP_KERNEL );if (!fid)return NULL ; -memset (&fid->qid,0 ,sizeof (fid->qid)); fid->mode =-1 ; fid->uid =current_fsuid (); fid->clnt = clnt; - fid->rdir =NULL ; - fid->fid =0 ;refcount_set (&fid->count,1 );idr_preload (GFP_KERNEL );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 722/779 ARM: remove some dead code
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
[ Upstream commit 08572cd41955166e387d9b4984294d37f8f7526c ]
This code appears to be no longer used so let's get rid of it.
--- arch/arm/include/asm/entry-macro-multi.S | 24 ------------------------ arch/arm/include/asm/smp.h | 5 ----- arch/arm/kernel/smp.c | 5 ----- 3 files changed, 34 deletions(-)
arch/arm/include/asm/entry-macro-multi.S +0 -24
@@ -13,28 +13,4 @@ @ badrne lr, 1b bne asm_do_IRQ - -#ifdef CONFIG_SMP - /* - * XXX - * - * this macro assumes that irqstat (r2) and base (r6) are - * preserved from get_irqnr_and_base above - */ - ALT_SMP(test_for_ipi r0, r2, r6, lr) - ALT_UP_B(9997f) - movne r1, sp - badrne lr, 1b - bne do_IPI -#endif -9997: - .endm - - .macro arch_irq_handler, symbol_name - .align 5 - .global \symbol_name -\symbol_name: - mov r8, lr - arch_irq_handler_default - ret r8 .endm
arch/arm/include/asm/smp.h +0 -5
@@ -24,11 +24,6 @@ struct seq_file;*/ extern void show_ipi_list (struct seq_file *,int ); -/* -* Called from assembly code, this handles an IPI. -*/ -asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); -/* * Called from C code, this handles an IPI. */
arch/arm/kernel/smp.c +0 -5
@@ -622,11 +622,6 @@ static void ipi_complete(unsigned int cpu)/* * Main handler for inter-processor interrupts */ -asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) -{ -handle_IPI (ipinr, regs); -} -static void do_handle_IPI (int ipinr) {unsigned int cpu =smp_processor_id ();
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 723/779 timekeeping: contribute wall clock to rng on time change
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit b8ac29b40183a6038919768b5d189c9bd91ce9b4 ]
The rng's random_init() function contributes the real time to the rng at boot time, so that events can at least start in relation to something particular in the real world. But this clock might not yet be set that point in boot, so nothing is contributed. In addition, the relation between minor clock changes from, say, NTP, and the cycle counter is potentially useful entropic data.
This commit addresses this by mixing in a time stamp on calls to settimeofday and adjtimex. No entropy is credited in doing so, so it doesn't make initialization faster, but it is still useful input to have.
--- kernel/time/timekeeping.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/time/timekeeping.c +6 -1
@@ -23,6 +23,7 @@#include <linux/pvclock_gtod.h> #include <linux/compiler.h> #include <linux/audit.h> +#include <linux/random.h> #include "tick-internal.h" #include "ntp_internal.h"
@@ -1326,8 +1327,10 @@ int do_settimeofday64(const struct timespec64 *ts)/* Signal hrtimers about time change */ clock_was_set (CLOCK_SET_WALL ); -if (!ret) +if (!ret) {audit_tk_injoffset (ts_delta); +add_device_randomness (ts,sizeof (*ts)); + }return ret; }
@@ -2413,6 +2416,7 @@ int do_adjtimex(struct __kernel_timex *txc) ret =timekeeping_validate_timex (txc);if (ret)return ret; +add_device_randomness (txc,sizeof (*txc));if (txc->modes &ADJ_SETOFFSET ) {struct timespec64 delta;
@@ -2430,6 +2434,7 @@ int do_adjtimex(struct __kernel_timex *txc)audit_ntp_init (&ad);ktime_get_real_ts64 (&ts); +add_device_randomness (&ts,sizeof (ts));raw_spin_lock_irqsave (&timekeeper_lock, flags);write_seqcount_begin (&tk_core.seq);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 724/779 locking/csd_lock: Change csdlock_debug from early_param to __setup
In reply to Greg Kroah-HartmanFrom: Chen Zhongjin <[email protected]>
[ Upstream commit 9c9b26b0df270d4f9246e483a44686fca951a29c ]
The csdlock_debug kernel-boot parameter is parsed by the early_param() function csdlock_debug(). If set, csdlock_debug() invokes static_branch_enable() to enable csd_lock_wait feature, which triggers a panic on arm64 for kernels built with CONFIG_SPARSEMEM=y and CONFIG_SPARSEMEM_VMEMMAP=n.
With CONFIG_SPARSEMEM_VMEMMAP=n, __nr_to_section is called in static_key_enable() and returns NULL, resulting in a NULL dereference because mem_section is initialized only later in sparse_init().
This is also a problem for powerpc because early_param() functions are invoked earlier than jump_label_init(), also resulting in static_key_enable() failures. These failures cause the warning "static key 'xxx' used before call to jump_label_init()".
Thus, early_param is too early for csd_lock_wait to run static_branch_enable(), so changes it to __setup to fix these.
--- kernel/smp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/smp.c +2 -2
@@ -174,9 +174,9 @@ static int __init csdlock_debug(char *str)if (val)static_branch_enable (&csdlock_debug_enabled); -return 0 ; +return 1 ; } -early_param ("csdlock_debug" , csdlock_debug); +__setup ("csdlock_debug=" , csdlock_debug); static DEFINE_PER_CPU(call_single_data_t *, cur_csd); static DEFINE_PER_CPU(smp_call_func_t, cur_csd_func);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 725/779 block: remove the struct blk_queue_ctx forward declaration
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit 9778ac77c2027827ffdbb33d3e936b3a0ae9f0f9 ]
This type doesn't exist at all, so no need to forward declare it.
--- include/linux/blkdev.h | 2 -- 1 file changed, 2 deletions(-)
include/linux/blkdev.h +0 -2
@@ -261,8 +261,6 @@ static inline unsigned short req_get_ioprio(struct request *req)#include <linux/elevator.h> -struct blk_queue_ctx ; -struct bio_vec ;enum blk_eh_timer_return {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 726/779 block: dont allow the same type rq_qos add more than once
In reply to Greg Kroah-HartmanFrom: Jinke Han <[email protected]>
[ Upstream commit 14a6e2eb7df5c7897c15b109cba29ab0c4a791b6 ]
In our test of iocost, we encountered some list add/del corruptions of inner_walk list in ioc_timer_fn.
The reason can be described as follows:
cpu 0 cpu 1ioc_qos_write ioc_qos_write
ioc = q_to_ioc(queue);
if (!ioc) {
ioc = kzalloc();
ioc = q_to_ioc(queue);
if (!ioc) {
ioc = kzalloc();
...
rq_qos_add(q, rqos);
}
...
rq_qos_add(q, rqos);
...
}When the io.cost.qos file is written by two cpus concurrently, rq_qos may be added to one disk twice. In that case, there will be two iocs enabled and running on one disk. They own different iocgs on their active list. In the ioc_timer_fn function, because of the iocgs from two iocs have the same root iocg, the root iocg's walk_list may be overwritten by each other and this leads to list add/del corruptions in building or destroying the inner_walk list.
And so far, the blk-rq-qos framework works in case that one instance for one type rq_qos per queue by default. This patch make this explicit and also fix the crash above.
--- block/blk-iocost.c | 20 +++++++++++++------- block/blk-iolatency.c | 18 +++++++++++------- block/blk-rq-qos.h | 11 ++++++++++- block/blk-wbt.c | 12 +++++++++++- 4 files changed, 45 insertions(+), 16 deletions(-)
block/blk-iocost.c +13 -7
@@ -2893,15 +2893,21 @@ static int blk_iocost_init(struct request_queue *q)* called before policy activation completion, can't assume that the * target bio has an iocg associated and need to test for NULL iocg. */ -rq_qos_add (q, rqos); + ret =rq_qos_add (q, rqos); +if (ret) + goto err_free_ioc; + ret =blkcg_activate_policy (q, &blkcg_policy_iocost); -if (ret) { -rq_qos_del (q, rqos); -free_percpu (ioc->pcpu_stat); -kfree (ioc); -return ret; - } +if (ret) + goto err_del_qos;return 0 ; + +err_del_qos: +rq_qos_del (q, rqos); +err_free_ioc: +free_percpu (ioc->pcpu_stat); +kfree (ioc); +return ret; }static struct blkcg_policy_data *ioc_cpd_alloc (gfp_t gfp)
block/blk-iolatency.c +11 -7
@@ -772,19 +772,23 @@ int blk_iolatency_init(struct request_queue *q) rqos->ops = &blkcg_iolatency_ops; rqos->q = q; -rq_qos_add (q, rqos); - + ret =rq_qos_add (q, rqos); +if (ret) + goto err_free; ret =blkcg_activate_policy (q, &blkcg_policy_iolatency); -if (ret) { -rq_qos_del (q, rqos); -kfree (blkiolat); -return ret; - } +if (ret) + goto err_qos_del;timer_setup (&blkiolat->timer, blkiolatency_timer_fn,0 );INIT_WORK (&blkiolat->enable_work, blkiolatency_enable_work_fn);return 0 ; + +err_qos_del: +rq_qos_del (q, rqos); +err_free: +kfree (blkiolat); +return ret; }static void iolatency_set_min_lat_nsec (struct blkcg_gq *blkg,u64 val)
block/blk-rq-qos.h +10 -1
@@ -86,7 +86,7 @@ static inline void rq_wait_init(struct rq_wait *rq_wait)init_waitqueue_head (&rq_wait->wait); } -static inline void rq_qos_add (struct request_queue *q,struct rq_qos *rqos) +static inline int rq_qos_add (struct request_queue *q,struct rq_qos *rqos) {/* * No IO can be in-flight when adding rqos, so freeze queue, which
@@ -98,6 +98,8 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)blk_mq_freeze_queue (q);spin_lock_irq (&q->queue_lock); +if (rq_qos_id (q, rqos->id)) + goto ebusy; rqos->next = q->rq_qos; q->rq_qos = rqos;spin_unlock_irq (&q->queue_lock);
@@ -106,6 +108,13 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)if (rqos->ops->debugfs_attrs)blk_mq_debugfs_register_rqos (rqos); + +return 0 ; +ebusy: +spin_unlock_irq (&q->queue_lock); +blk_mq_unfreeze_queue (q); +return -EBUSY ; + }static inline void rq_qos_del (struct request_queue *q,struct rq_qos *rqos)
block/blk-wbt.c +11 -1
@@ -820,6 +820,7 @@ int wbt_init(struct request_queue *q) {struct rq_wb *rwb;int i; +int ret; rwb =kzalloc (sizeof (*rwb),GFP_KERNEL );if (!rwb)
@@ -846,7 +847,10 @@ int wbt_init(struct request_queue *q)/* * Assign rwb and add the stats callback. */ -rq_qos_add (q, &rwb->rqos); + ret =rq_qos_add (q, &rwb->rqos); +if (ret) + goto err_free; +blk_stat_add_callback (q, rwb->cb); rwb->min_lat_nsec =wbt_default_latency_nsec (q);
@@ -855,4 +859,10 @@ int wbt_init(struct request_queue *q)wbt_set_write_cache (q,test_bit (QUEUE_FLAG_WC , &q->queue_flags));return 0 ; + +err_free: +blk_stat_free_callback (rwb->cb); +kfree (rwb); +return ret; + }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 727/779 btrfs: ensure pages are unlocked on cow_file_range() failure
In reply to Greg Kroah-HartmanFrom: Naohiro Aota <[email protected]>
[ Upstream commit 9ce7466f372d83054c7494f6b3e4b9abaf3f0355 ]
There is a hung_task report on zoned btrfs like below.
https://github.com/naota/linux/issues/59
[726.328648] INFO: task rocksdb:high0:11085 blocked for more than 241 seconds. [726.329839] Not tainted 5.16.0-rc1+ #1 [726.330484] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [726.331603] task:rocksdb:high0 state:D stack: 0 pid:11085 ppid: 11082 flags:0x00000000 [726.331608] Call Trace: [726.331611] <TASK> [726.331614] __schedule+0x2e5/0x9d0 [726.331622] schedule+0x58/0xd0 [726.331626] io_schedule+0x3f/0x70 [726.331629] __folio_lock+0x125/0x200 [726.331634] ? find_get_entries+0x1bc/0x240 [726.331638] ? filemap_invalidate_unlock_two+0x40/0x40 [726.331642] truncate_inode_pages_range+0x5b2/0x770 [726.331649] truncate_inode_pages_final+0x44/0x50 [726.331653] btrfs_evict_inode+0x67/0x480 [726.331658] evict+0xd0/0x180 [726.331661] iput+0x13f/0x200 [726.331664] do_unlinkat+0x1c0/0x2b0 [726.331668] __x64_sys_unlink+0x23/0x30 [726.331670] do_syscall_64+0x3b/0xc0 [726.331674] entry_SYSCALL_64_after_hwframe+0x44/0xae [726.331677] RIP: 0033:0x7fb9490a171b [726.331681] RSP: 002b:00007fb943ffac68 EFLAGS: 00000246 ORIG_RAX: 0000000000000057 [726.331684] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fb9490a171b [726.331686] RDX: 00007fb943ffb040 RSI: 000055a6bbe6ec20 RDI: 00007fb94400d300 [726.331687] RBP: 00007fb943ffad00 R08: 0000000000000000 R09: 0000000000000000 [726.331688] R10: 0000000000000031 R11: 0000000000000246 R12: 00007fb943ffb000 [726.331690] R13: 00007fb943ffb040 R14: 0000000000000000 R15: 00007fb943ffd260 [726.331693] </TASK>
While we debug the issue, we found running fstests generic/551 on 5GB non-zoned null_blk device in the emulated zoned mode also had a similar hung issue.
Also, we can reproduce the same symptom with an error injected cow_file_range() setup.
The hang occurs when cow_file_range() fails in the middle of allocation. cow_file_range() called from do_allocation_zoned() can split the give region ([start, end]) for allocation depending on current block group usages. When btrfs can allocate bytes for one part of the split regions but fails for the other region (e.g. because of -ENOSPC), we return the error leaving the pages in the succeeded regions locked. Technically, this occurs only when @unlock == 0. Otherwise, we unlock the pages in an allocated region after creating an ordered extent.
Considering the callers of cow_file_range(unlock=0) won't write out the pages, we can unlock the pages on error exit from cow_file_range(). So, we can ensure all the pages except @locked_page are unlocked on error case.
In summary, cow_file_range now behaves like this:
- page_started == 1 (return value)
- All the pages are unlocked. IO is started.
- unlock == 1
- All the pages except @locked_page are unlocked in any case
- unlock == 0
- On success, all the pages are locked for writing out them
- On failure, all the pages except @locked_page are unlocked
--- fs/btrfs/inode.c | 72 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 8 deletions(-)
fs/btrfs/inode.c +64 -8
@@ -1053,6 +1053,28 @@ static u64 get_extent_allocation_hint(struct btrfs_inode *inode, u64 start,* *page_started is set to one if we unlock locked_page and do everything * required to start IO on it. It may be clean and already done with * IO when we return. +* +* When unlock == 1, we unlock the pages in successfully allocated regions. +* When unlock == 0, we leave them locked for writing them out. +* +* However, we unlock all the pages except @locked_page in case of failure. +* +* In summary, page locking state will be as follow: +* +* - page_started == 1 (return value) +* - All the pages are unlocked. IO is started. +* - Note that this can happen only on success +* - unlock == 1 +* - All the pages except @locked_page are unlocked in any case +* - unlock == 0 +* - On success, all the pages are locked for writing out them +* - On failure, all the pages except @locked_page are unlocked +* +* When a failure happens in the second or later iteration of the +* while-loop, the ordered extents created in previous iterations are kept +* intact. So, the caller must clean them up by calling +* btrfs_cleanup_ordered_extents(). See btrfs_run_delalloc_range() for +* example. */ static noinline int cow_file_range(struct btrfs_inode *inode, struct page *locked_page,
@@ -1062,6 +1084,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,struct btrfs_root *root = inode->root;struct btrfs_fs_info *fs_info = root->fs_info;u64 alloc_hint =0 ; +u64 orig_start = start;u64 num_bytes;unsigned long ram_size;u64 cur_alloc_size =0 ;
@@ -1245,18 +1268,44 @@ static noinline int cow_file_range(struct btrfs_inode *inode,btrfs_dec_block_group_reservations (fs_info, ins.objectid);btrfs_free_reserved_extent (fs_info, ins.objectid, ins.offset,1 ); out_unlock: +/* +* Now, we have three regions to clean up: +* +* |-------(1)----|---(2)---|-------------(3)----------| +* `- orig_start `- start `- start + cur_alloc_size `- end +* +* We process each region below. +*/ + clear_bits =EXTENT_LOCKED |EXTENT_DELALLOC |EXTENT_DELALLOC_NEW |EXTENT_DEFRAG |EXTENT_CLEAR_META_RESV ; page_ops =PAGE_UNLOCK |PAGE_START_WRITEBACK |PAGE_END_WRITEBACK ; +/* -* If we reserved an extent for our delalloc range (or a subrange) and -* failed to create the respective ordered extent, then it means that -* when we reserved the extent we decremented the extent's size from -* the data space_info's bytes_may_use counter and incremented the -* space_info's bytes_reserved counter by the same amount. We must make -* sure extent_clear_unlock_delalloc() does not try to decrement again -* the data space_info's bytes_may_use counter, therefore we do not pass -* it the flag EXTENT_CLEAR_DATA_RESV. +* For the range (1). We have already instantiated the ordered extents +* for this region. They are cleaned up by +* btrfs_cleanup_ordered_extents() in e.g, +* btrfs_run_delalloc_range(). EXTENT_LOCKED | EXTENT_DELALLOC are +* already cleared in the above loop. And, EXTENT_DELALLOC_NEW | +* EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV are handled by the cleanup +* function. +* +* However, in case of unlock == 0, we still need to unlock the pages +* (except @locked_page) to ensure all the pages are unlocked. +*/ +if (!unlock && orig_start < start) +extent_clear_unlock_delalloc (inode, orig_start, start -1 , + locked_page,0 , page_ops); + +/* +* For the range (2). If we reserved an extent for our delalloc range +* (or a subrange) and failed to create the respective ordered extent, +* then it means that when we reserved the extent we decremented the +* extent's size from the data space_info's bytes_may_use counter and +* incremented the space_info's bytes_reserved counter by the same +* amount. We must make sure extent_clear_unlock_delalloc() does not try +* to decrement again the data space_info's bytes_may_use counter, +* therefore we do not pass it the flag EXTENT_CLEAR_DATA_RESV. */ if (extent_reserved) { extent_clear_unlock_delalloc(inode, start,
@@ -1268,6 +1317,13 @@ static noinline int cow_file_range(struct btrfs_inode *inode,if (start >= end) goto out; } + +/* +* For the range (3). We never touched the region. In addition to the +* clear_bits above, we add EXTENT_CLEAR_DATA_RESV to release the data +* space_info's bytes_may_use counter, reserved in +* btrfs_check_data_free_space(). +*/ extent_clear_unlock_delalloc (inode, start, end, locked_page, clear_bits |EXTENT_CLEAR_DATA_RESV , page_ops);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 728/779 btrfs: reset block group chunk force if we have to wait
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
[ Upstream commit 1314ca78b2c35d3e7d0f097268a2ee6dc0d369ef ]
If you try to force a chunk allocation, but you race with another chunk allocation, you will end up waiting on the chunk allocation that just occurred and then allocate another chunk. If you have many threads all doing this at once you can way over-allocate chunks.
Fix this by resetting force to NO_FORCE, that way if we think we need to allocate we can, otherwise we don't force another chunk allocation if one is already happening.
--- fs/btrfs/block-group.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/block-group.c +1 -0
@@ -3632,6 +3632,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,* attempt. */ wait_for_alloc = true; + force =CHUNK_ALLOC_NO_FORCE ;spin_unlock (&space_info->lock);mutex_lock (&fs_info->chunk_mutex);mutex_unlock (&fs_info->chunk_mutex);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 729/779 btrfs: properly flag filesystem with BTRFS_FEATURE_INCOMPAT_BIG_METADATA
In reply to Greg Kroah-HartmanFrom: Nikolay Borisov <[email protected]>
[ Upstream commit e26b04c4c91925dba57324db177a24e18e2d0013 ]
Commit 6f93e834fa7c seemingly inadvertently moved the code responsible for flagging the filesystem as having BIG_METADATA to a place where setting the flag was essentially lost. This means that filesystems created with kernels containing this bug (starting with 5.15) can potentially be mounted by older (pre-3.4) kernels. In reality chances for this happening are low because there are other incompat flags introduced in the mean time. Still the correct behavior is to set INCOMPAT_BIG_METADATA flag and persist this in the superblock.
--- fs/btrfs/disk-io.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
fs/btrfs/disk-io.c +11 -10
@@ -3337,16 +3337,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device*/ fs_info->compress_type =BTRFS_COMPRESS_ZLIB ; -/* -* Flag our filesystem as having big metadata blocks if they are bigger -* than the page size. -*/ -if (btrfs_super_nodesize (disk_super) >PAGE_SIZE ) { -if (!(features &BTRFS_FEATURE_INCOMPAT_BIG_METADATA )) -btrfs_info (fs_info, -"flagging fs with big metadata feature" ); - features |=BTRFS_FEATURE_INCOMPAT_BIG_METADATA ; - }/* Set up fs_info before parsing mount options */ nodesize =btrfs_super_nodesize (disk_super);
@@ -3387,6 +3377,17 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_deviceif (features &BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA )btrfs_info (fs_info,"has skinny extents" ); +/* +* Flag our filesystem as having big metadata blocks if they are bigger +* than the page size. +*/ +if (btrfs_super_nodesize (disk_super) >PAGE_SIZE ) { +if (!(features &BTRFS_FEATURE_INCOMPAT_BIG_METADATA )) +btrfs_info (fs_info, +"flagging fs with big metadata feature" ); + features |=BTRFS_FEATURE_INCOMPAT_BIG_METADATA ; + } +/* * mixed block groups end up with duplicate but slightly offset * extent buffers for the same range. It leads to corruptions
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 730/779 ACPI: CPPC: Do not prevent CPPC from working in the future
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
[ Upstream commit 4f4179fcf420873002035cf1941d844c9e0e7cb3 ]
There is a problem with the current revision checks in is_cppc_supported() that they essentially prevent the CPPC support from working if a new _CPC package format revision being a proper superset of the v3 and only causing _CPC to return a package with more entries (while retaining the types and meaning of the entries defined by the v3) is introduced in the future and used by the platform firmware.
In that case, as long as the number of entries in the _CPC return package is at least CPPC_V3_NUM_ENT, it should be perfectly fine to use the v3 support code and disregard the additional package entries added by the new package format revision.
For this reason, drop is_cppc_supported() altogether, put the revision checks directly into acpi_cppc_processor_probe() so they are easier to follow and rework them to take the case mentioned above into account.
--- drivers/acpi/cppc_acpi.c | 54 ++++++++++++++++++---------------------- include/acpi/cppc_acpi.h | 2 +- 2 files changed, 25 insertions(+), 31 deletions(-)
drivers/acpi/cppc_acpi.c +24 -30
@@ -597,33 +597,6 @@ static int pcc_data_alloc(int pcc_ss_id)return 0 ; } -/* Check if CPPC revision + num_ent combination is supported */ -static bool is_cppc_supported (int revision,int num_ent) -{ -int expected_num_ent; - -switch (revision) { -case CPPC_V2_REV : - expected_num_ent =CPPC_V2_NUM_ENT ; -break ; -case CPPC_V3_REV : - expected_num_ent =CPPC_V3_NUM_ENT ; -break ; -default : -pr_debug ("Firmware exports unsupported CPPC revision: %d\n" , - revision); -return false; - } - -if (expected_num_ent != num_ent) { -pr_debug ("Firmware exports %d entries. Expected: %d for CPPC rev:%d\n" , - num_ent, expected_num_ent, revision); -return false; - } - -return true; -} -/* * An example CPC table looks like the following. *
@@ -723,7 +696,6 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) cpc_obj->type); goto out_free; } - cpc_ptr->num_entries = num_ent;/* Second entry should be revision. */ cpc_obj = &out_obj->package.elements[1 ];
@@ -734,10 +706,32 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) cpc_obj->type); goto out_free; } - cpc_ptr->version = cpc_rev; -if (!is_cppc_supported (cpc_rev, num_ent)) +if (cpc_rev <CPPC_V2_REV ) { +pr_debug ("Unsupported _CPC Revision (%d) for CPU:%d\n" , cpc_rev, + pr->id); + goto out_free; + } + +/* +* Disregard _CPC if the number of entries in the return pachage is not +* as expected, but support future revisions being proper supersets of +* the v3 and only causing more entries to be returned by _CPC. +*/ +if ((cpc_rev ==CPPC_V2_REV && num_ent !=CPPC_V2_NUM_ENT ) || + (cpc_rev ==CPPC_V3_REV && num_ent !=CPPC_V3_NUM_ENT ) || + (cpc_rev >CPPC_V3_REV && num_ent <=CPPC_V3_NUM_ENT )) { +pr_debug ("Unexpected number of _CPC return package entries (%d) for CPU:%d\n" , + num_ent, pr->id); goto out_free; + } +if (cpc_rev >CPPC_V3_REV ) { + num_ent =CPPC_V3_NUM_ENT ; + cpc_rev =CPPC_V3_REV ; + } + + cpc_ptr->num_entries = num_ent; + cpc_ptr->version = cpc_rev;/* Iterate through remaining entries in _CPC */ for (i =2 ; i < num_ent; i++) {
include/acpi/cppc_acpi.h +1 -1
@@ -17,7 +17,7 @@#include <acpi/pcc.h> #include <acpi/processor.h> -/* Support CPPCv2 and CPPCv3 */ +/* CPPCv2 and CPPCv3 support */ #define CPPC_V2_REV 2#define CPPC_V3_REV 3#define CPPC_V2_NUM_ENT 21
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 731/779 powerpc/powernv/kvm: Use darn for H_RANDOM on Power9
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit 7ef3d06f1bc4a5e62273726f3dc2bd258ae1c71f ]
The existing logic in KVM to support guests calling H_RANDOM only works on Power8, because it looks for an RNG in the device tree, but on Power9 we just use darn.
In addition the existing code needs to work in real mode, so we have the special cased powernv_get_random_real_mode() to deal with that.
Instead just have KVM call ppc_md.get_random_seed(), and do the real mode check inside of there, that way we use whatever RNG is available, including darn on Power9.
--- arch/powerpc/include/asm/archrandom.h | 5 ---- arch/powerpc/kvm/book3s_hv_builtin.c | 7 +++--- arch/powerpc/platforms/powernv/rng.c | 36 ++++++--------------------- 3 files changed, 12 insertions(+), 36 deletions(-)
arch/powerpc/include/asm/archrandom.h +0 -5
@@ -38,12 +38,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)#endif /* CONFIG_ARCH_RANDOM */ #ifdef CONFIG_PPC_POWERNV -int powernv_hwrng_present (void );int powernv_get_random_long (unsigned long *v); -int powernv_get_random_real_mode (unsigned long *v); -#else -static inline int powernv_hwrng_present (void ) {return 0 ; } -static inline int powernv_get_random_real_mode (unsigned long *v) {return 0 ; }#endif #endif /* _ASM_POWERPC_ARCHRANDOM_H */
arch/powerpc/kvm/book3s_hv_builtin.c +4 -3
@@ -20,7 +20,7 @@#include <asm/interrupt.h> #include <asm/kvm_ppc.h> #include <asm/kvm_book3s.h> -#include <asm/archrandom.h> +#include <asm/machdep.h> #include <asm/xics.h> #include <asm/xive.h> #include <asm/dbell.h>
@@ -177,13 +177,14 @@ EXPORT_SYMBOL_GPL(kvmppc_hcall_impl_hv_realmode);int kvmppc_hwrng_present (void ) { -return powernv_hwrng_present (); +return ppc_md.get_random_seed !=NULL ; }EXPORT_SYMBOL_GPL (kvmppc_hwrng_present);long kvmppc_rm_h_random (struct kvm_vcpu *vcpu) { -if (powernv_get_random_real_mode (&vcpu->arch.regs.gpr[4 ])) +if (ppc_md.get_random_seed && + ppc_md.get_random_seed (&vcpu->arch.regs.gpr[4 ]))return H_SUCCESS ;return H_HARDWARE ;
arch/powerpc/platforms/powernv/rng.c +8 -28
@@ -29,15 +29,6 @@ struct powernv_rng { static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); -int powernv_hwrng_present (void ) -{ -struct powernv_rng *rng; - - rng =get_cpu_var (powernv_rng); -put_cpu_var (rng); -return rng !=NULL ; -} -static unsigned long rng_whiten (struct powernv_rng *rng,unsigned long val) {unsigned long parity;
@@ -58,19 +49,6 @@ static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val)return val; } -int powernv_get_random_real_mode (unsigned long *v) -{ -struct powernv_rng *rng; - - rng =raw_cpu_read (powernv_rng); -if (!rng) -return 0 ; - - *v =rng_whiten (rng,__raw_rm_readq (rng->regs_real)); - -return 1 ; -} -static int powernv_get_random_darn (unsigned long *v) {unsigned long val;
@@ -107,12 +85,14 @@ int powernv_get_random_long(unsigned long *v) {struct powernv_rng *rng; - rng =get_cpu_var (powernv_rng); - - *v =rng_whiten (rng,in_be64 (rng->regs)); - -put_cpu_var (rng); - +if (mfmsr () &MSR_DR ) { + rng =get_cpu_var (powernv_rng); + *v =rng_whiten (rng,in_be64 (rng->regs)); +put_cpu_var (rng); + }else { + rng =raw_cpu_read (powernv_rng); + *v =rng_whiten (rng,__raw_rm_readq (rng->regs_real)); + }return 1 ; }EXPORT_SYMBOL_GPL (powernv_get_random_long);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 732/779 KVM: x86/pmu: Introduce the ctrl_mask value for fixed counter
In reply to Greg Kroah-HartmanFrom: Like Xu <[email protected]>
[ Upstream commit 2c985527dd8d283e786ad7a67e532ef7f6f00fac ]
The mask value of fixed counter control register should be dynamic adjusted with the number of fixed counters. This patch introduces a variable that includes the reserved bits of fixed counter control registers. This is a generic code refactoring.
Message-Id: <[email protected]>
--- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-)
arch/x86/include/asm/kvm_host.h +1 -0
@@ -498,6 +498,7 @@ struct kvm_pmu {unsigned nr_arch_fixed_counters;unsigned available_event_types;u64 fixed_ctr_ctrl; +u64 fixed_ctr_ctrl_mask;u64 global_ctrl;u64 global_status;u64 global_ovf_ctrl;
arch/x86/kvm/vmx/pmu_intel.c +5 -1
@@ -402,7 +402,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)case MSR_CORE_PERF_FIXED_CTR_CTRL :if (pmu->fixed_ctr_ctrl == data)return 0 ; -if (!(data &0xfffffffffffff444ull )) { +if (!(data & pmu->fixed_ctr_ctrl_mask)) {reprogram_fixed_counters (pmu, data);return 0 ; }
@@ -472,6 +472,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)struct kvm_cpuid_entry2 *entry;union cpuid10_eax eax;union cpuid10_edx edx; +int i; pmu->nr_arch_gp_counters =0 ; pmu->nr_arch_fixed_counters =0 ;
@@ -480,6 +481,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->version =0 ; pmu->reserved_bits =0xffffffff00200000ull ; pmu->raw_event_mask =X86_RAW_EVENT_MASK ; + pmu->fixed_ctr_ctrl_mask = ~0ull ; entry =kvm_find_cpuid_entry (vcpu,0xa ,0 );if (!entry)
@@ -513,6 +515,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) ((u64 )1 << edx.split.bit_width_fixed) -1 ; } +for (i =0 ; i < pmu->nr_arch_fixed_counters; i++) + pmu->fixed_ctr_ctrl_mask &= ~(0xbull << (i *4 )); pmu->global_ctrl = ((1ull << pmu->nr_arch_gp_counters) -1 ) | (((1ull << pmu->nr_arch_fixed_counters) -1 ) <<INTEL_PMC_IDX_FIXED ); pmu->global_ctrl_mask = ~pmu->global_ctrl;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 733/779 KVM: VMX: Mark all PERF_GLOBAL_(OVF)_CTRL bits reserved if theres no vPMU
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit 93255bf92939d948bc86d81c6bb70bb0fecc5db1 ]
Mark all MSR_CORE_PERF_GLOBAL_CTRL and MSR_CORE_PERF_GLOBAL_OVF_CTRL bits as reserved if there is no guest vPMU. The nVMX VM-Entry consistency checks do not check for a valid vPMU prior to consuming the masks via kvm_valid_perf_global_ctrl(), i.e. may incorrectly allow a non-zero mask to be loaded via VM-Enter or VM-Exit (well, attempted to be loaded, the actual MSR load will be rejected by intel_is_valid_msr()).
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/pmu_intel.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/kvm/vmx/pmu_intel.c +2 -0
@@ -481,6 +481,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->version =0 ; pmu->reserved_bits =0xffffffff00200000ull ; pmu->raw_event_mask =X86_RAW_EVENT_MASK ; + pmu->global_ctrl_mask = ~0ull ; + pmu->global_ovf_ctrl_mask = ~0ull ; pmu->fixed_ctr_ctrl_mask = ~0ull ; entry =kvm_find_cpuid_entry (vcpu,0xa ,0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 734/779 KVM: x86/pmu: Ignore pmu->global_ctrl check if vPMU doesnt support global_ctrl
In reply to Greg Kroah-HartmanFrom: Like Xu <[email protected]>
[ Upstream commit 98defd2e17803263f49548fea930cfc974d505aa ]
MSR_CORE_PERF_GLOBAL_CTRL is introduced as part of Architecture PMU V2, as indicated by Intel SDM 19.2.2 and the intel_is_valid_msr() function.
So in the absence of global_ctrl support, all PMCs are enabled as AMD does.
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/pmu_intel.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kvm/vmx/pmu_intel.c +3 -0
@@ -104,6 +104,9 @@ static bool intel_pmc_is_enabled(struct kvm_pmc *pmc) {struct kvm_pmu *pmu =pmc_to_pmu (pmc); +if (pmu->version <2 ) +return true; +return test_bit (pmc->idx, (unsigned long *)&pmu->global_ctrl); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 735/779 KVM: VMX: Add helper to check if the guest PMU has PERF_GLOBAL_CTRL
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit b663f0b5f3d665c261256d1f76e98f077c6e56af ]
Add a helper to check of the guest PMU has PERF_GLOBAL_CTRL, which is unintuitive _and_ diverges from Intel's architecturally defined behavior. Even worse, KVM currently implements the check using two different (but equivalent) checks, _and_ there has been at least one attempt to add a _third_ flavor.
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/pmu_intel.c | 4 ++-- arch/x86/kvm/vmx/vmx.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx/pmu_intel.c +2 -2
@@ -104,7 +104,7 @@ static bool intel_pmc_is_enabled(struct kvm_pmc *pmc) {struct kvm_pmu *pmu =pmc_to_pmu (pmc); -if (pmu->version <2 ) +if (!intel_pmu_has_perf_global_ctrl (pmu))return true;return test_bit (pmc->idx, (unsigned long *)&pmu->global_ctrl);
@@ -222,7 +222,7 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)case MSR_CORE_PERF_GLOBAL_STATUS :case MSR_CORE_PERF_GLOBAL_CTRL :case MSR_CORE_PERF_GLOBAL_OVF_CTRL : - ret = pmu->version >1 ; +return intel_pmu_has_perf_global_ctrl (pmu);break ;default : ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0) ||
arch/x86/kvm/vmx/vmx.h +12 -0
@@ -92,6 +92,18 @@ union vmx_exit_reason {u32 full; }; +static inline bool intel_pmu_has_perf_global_ctrl (struct kvm_pmu *pmu) +{ +/* +* Architecturally, Intel's SDM states that IA32_PERF_GLOBAL_CTRL is +* supported if "CPUID.0AH: EAX[7:0] > 0", i.e. if the PMU version is +* greater than zero. However, KVM only exposes and emulates the MSR +* to/for the guest if the guest PMU supports at least "Architectural +* Performance Monitoring Version 2". +*/ +return pmu->version >1 ; +} +#define vcpu_to_lbr_desc (vcpu) (&to_vmx(vcpu)->lbr_desc)#define vcpu_to_lbr_records (vcpu) (&to_vmx(vcpu)->lbr_desc.records)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 736/779 KVM: nVMX: Attempt to load PERF_GLOBAL_CTRL on nVMX xfer iff it exists
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit 4496a6f9b45e8cd83343ad86a3984d614e22cf54 ]
Attempt to load PERF_GLOBAL_CTRL during nested VM-Enter/VM-Exit if and only if the MSR exists (according to the guest vCPU model). KVM has very misguided handling of VM_{ENTRY,EXIT}_LOAD_IA32_PERF_GLOBAL_CTRL and attempts to force the nVMX MSR settings to match the vPMU model, i.e. to hide/expose the control based on whether or not the MSR exists from the guest's perspective.
KVM's modifications fail to handle the scenario where the vPMU is hidden from the guest _after_ being exposed to the guest, e.g. by userspace doing multiple KVM_SET_CPUID2 calls, which is allowed if done before any KVM_RUN. nested_vmx_pmu_refresh() is called if and only if there's a recognized vPMU, i.e. KVM will leave the bits in the allow state and then ultimately reject the MSR load and WARN.
KVM should not force the VMX MSRs in the first place. KVM taking control of the MSRs was a misguided attempt at mimicking what commit 5f76f6f5ff96 ("KVM: nVMX: Do not expose MPX VMX controls when guest MPX disabled", 2018-10-01) did for MPX. However, the MPX commit was a workaround for another KVM bug and not something that should be imitated (and it should never been done in the first place).
In other words, KVM's ABI _should_ be that userspace has full control over the MSRs, at which point triggering the WARN that loading the MSR must not fail is trivial.
The intent of the WARN is still valid; KVM has consistency checks to ensure that vmcs12->{guest,host}_ia32_perf_global_ctrl is valid. The problem is that '0' must be considered a valid value at all times, and so the simple/obvious solution is to just not actually load the MSR when it does not exist. It is userspace's responsibility to provide a sane vCPU model, i.e. KVM is well within its ABI and Intel's VMX architecture to skip the loads if the MSR does not exist.
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/nested.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx/nested.c +3 -1
@@ -2611,6 +2611,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, vcpu->arch.walk_mmu->inject_page_fault = vmx_inject_page_fault_nested;if ((vmcs12->vm_entry_controls &VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL ) && +intel_pmu_has_perf_global_ctrl (vcpu_to_pmu (vcpu)) &&WARN_ON_ONCE (kvm_set_msr (vcpu,MSR_CORE_PERF_GLOBAL_CTRL , vmcs12->guest_ia32_perf_global_ctrl))) { *entry_failure_code =ENTRY_FAIL_DEFAULT ;
@@ -4329,7 +4330,8 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,vmcs_write64 (GUEST_IA32_PAT , vmcs12->host_ia32_pat); vcpu->arch.pat = vmcs12->host_ia32_pat; } -if (vmcs12->vm_exit_controls &VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL ) +if ((vmcs12->vm_exit_controls &VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL ) && +intel_pmu_has_perf_global_ctrl (vcpu_to_pmu (vcpu)))WARN_ON_ONCE (kvm_set_msr (vcpu,MSR_CORE_PERF_GLOBAL_CTRL , vmcs12->host_ia32_perf_global_ctrl));
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 737/779 dm raid: fix address sanitizer warning in raid_status
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
[ Upstream commit 1fbeea217d8f297fe0e0956a1516d14ba97d0396 ]
There is this warning when using a kernel with the address sanitizer and running this testsuite:
https://gitlab.com/cki-project/kernel-tests/-/tree/main/storage/swraid/scsi_raid
==================================================================
BUG: KASAN: slab-out-of-bounds in raid_status+0x1747/0x2820 [dm_raid] Read of size 4 at addr ffff888079d2c7e8 by task lvcreate/13319 CPU: 0 PID: 13319 Comm: lvcreate Not tainted 5.18.0-0.rc3.<snip> #1 Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 Call Trace: <TASK> dump_stack_lvl+0x6a/0x9c print_address_description.constprop.0+0x1f/0x1e0 print_report.cold+0x55/0x244 kasan_report+0xc9/0x100 raid_status+0x1747/0x2820 [dm_raid] dm_ima_measure_on_table_load+0x4b8/0xca0 [dm_mod] table_load+0x35c/0x630 [dm_mod] ctl_ioctl+0x411/0x630 [dm_mod] dm_ctl_ioctl+0xa/0x10 [dm_mod] __x64_sys_ioctl+0x12a/0x1a0 do_syscall_64+0x5b/0x80
The warning is caused by reading conf->max_nr_stripes in raid_status. The code in raid_status reads mddev->private, casts it to struct r5conf and reads the entry max_nr_stripes.
However, if we have different raid type than 4/5/6, mddev->private doesn't point to struct r5conf; it may point to struct r0conf, struct r1conf, struct r10conf or struct mpconf. If we cast a pointer to one of these structs to struct r5conf, we will be reading invalid memory and KASAN warns about it.
Fix this bug by reading struct r5conf only if raid type is 4, 5 or 6.
--- drivers/md/dm-raid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm-raid.c +1 -1
@@ -3514,7 +3514,7 @@ static void raid_status(struct dm_target *ti, status_type_t type, {struct raid_set *rs = ti->private;struct mddev *mddev = &rs->md; -struct r5conf *conf = mddev->private; +struct r5conf *conf =rs_is_raid456 (rs) ? mddev->private :NULL ;int i, max_nr_stripes = conf ? conf->max_nr_stripes :0 ;unsigned long recovery;unsigned int raid_param_cnt =1 ;/* at least 1 for chunksize */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 738/779 dm raid: fix address sanitizer warning in raid_resume
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
[ Upstream commit 7dad24db59d2d2803576f2e3645728866a056dab ]
There is a KASAN warning in raid_resume when running the lvm test lvconvert-raid.sh. The reason for the warning is that mddev->raid_disks is greater than rs->raid_disks, so the loop touches one entry beyond the allocated length.
--- drivers/md/dm-raid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm-raid.c +1 -1
@@ -3824,7 +3824,7 @@ static void attempt_restore_of_faulty_devices(struct raid_set *rs)memset (cleared_failed_devices,0 ,sizeof (cleared_failed_devices)); -for (i =0 ; i < mddev->raid_disks; i++) { +for (i =0 ; i < rs->raid_disks; i++) { r = &rs->dev[i].rdev;/* HM FIXME: enhance journal device recovery processing */ if (test_bit (Journal, &r->flags))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 739/779 tracing: Add __rel_loc using trace event macros
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
[ Upstream commit 55de2c0b5610cba5a5a93c0788031133c457e689 ]
Add '__rel_loc' using trace event macros. These macros are usually not used in the kernel, except for testing purpose. This also add "rel_" variant of macros for dynamic_array string, and bitmask.
--- include/trace/bpf_probe.h | 16 +++++ include/trace/perf.h | 16 +++++ include/trace/trace_events.h | 120 ++++++++++++++++++++++++++++++++++- kernel/trace/trace.h | 3 + 4 files changed, 153 insertions(+), 2 deletions(-)
include/trace/bpf_probe.h +16 -0
@@ -21,6 +21,22 @@#undef __get_bitmask#define __get_bitmask (field) (char *)__get_dynamic_array(field) +#undef __get_rel_dynamic_array +#define __get_rel_dynamic_array (field) \ + ((void *)(&__entry->__rel_loc_##field) + \ + sizeof(__entry->__rel_loc_##field) + \ + (__entry->__rel_loc_##field & 0xffff)) + +#undef __get_rel_dynamic_array_len +#define __get_rel_dynamic_array_len (field) \ + ((__entry->__rel_loc_##field >> 16) & 0xffff) + +#undef __get_rel_str +#define __get_rel_str (field) ((char *)__get_rel_dynamic_array(field)) + +#undef __get_rel_bitmask +#define __get_rel_bitmask (field) (char *)__get_rel_dynamic_array(field) +#undef __perf_count#define __perf_count (c) (c)
include/trace/perf.h +16 -0
@@ -21,6 +21,22 @@#undef __get_bitmask#define __get_bitmask (field) (char *)__get_dynamic_array(field) +#undef __get_rel_dynamic_array +#define __get_rel_dynamic_array (field) \ + ((void *)(&__entry->__rel_loc_##field) + \ + sizeof(__entry->__rel_loc_##field) + \ + (__entry->__rel_loc_##field & 0xffff)) + +#undef __get_rel_dynamic_array_len +#define __get_rel_dynamic_array_len (field) \ + ((__entry->__rel_loc_##field >> 16) & 0xffff) + +#undef __get_rel_str +#define __get_rel_str (field) ((char *)__get_rel_dynamic_array(field)) + +#undef __get_rel_bitmask +#define __get_rel_bitmask (field) (char *)__get_rel_dynamic_array(field) +#undef __perf_count#define __perf_count (c) (__count = (c))
include/trace/trace_events.h +118 -2
177 lines not on this page · raw message
kernel/trace/trace.h +3 -0
@@ -83,6 +83,9 @@ enum trace_type {#undef __dynamic_array#define __dynamic_array (type, item) type item[]; +#undef __rel_dynamic_array +#define __rel_dynamic_array (type, item) type item[]; +#undef F_STRUCT #define F_STRUCT(args...) args
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 740/779 tracing: Avoid -Warray-bounds warning for __rel_loc macro
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
[ Upstream commit 58c5724ec2cdd72b22107ec5de00d90cc4797796 ]
Since -Warray-bounds checks the destination size from the type of given pointer, __assign_rel_str() macro gets warned because it passes the pointer to the 'u32' field instead of 'trace_event_raw_*' data structure. Pass the data address calculated from the 'trace_event_raw_*' instead of 'u32' __rel_loc field.
--- include/trace/trace_events.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
include/trace/trace_events.h +4 -3
@@ -318,9 +318,10 @@ TRACE_MAKE_SYSTEM_STR();#define __get_str (field) ((char *)__get_dynamic_array(field))#undef __get_rel_dynamic_array -#define __get_rel_dynamic_array (field) \ - ((void *)(&__entry->__rel_loc_##field) + \ - sizeof(__entry->__rel_loc_##field) + \ +#define __get_rel_dynamic_array (field) \ + ((void *)__entry + \ + offsetof(typeof(*__entry), __rel_loc_##field) + \ + sizeof(__entry->__rel_loc_##field) + \ (__entry->__rel_loc_##field & 0xffff))#undef __get_rel_dynamic_array_len
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 741/779 ext4: update s_overhead_clusters in the superblock during an on-line resize
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
[ Upstream commit de394a86658ffe4e89e5328fd4993abfe41b7435 ]
When doing an online resize, the on-disk superblock on-disk wasn't updated. This means that when the file system is unmounted and remounted, and the on-disk overhead value is non-zero, this would result in the results of statfs(2) to be incorrect.
This was partially fixed by Commits 10b01ee92df5 ("ext4: fix overhead calculation to account for the reserved gdt blocks"), 85d825dbf489 ("ext4: force overhead calculation if the s_overhead_cluster makes no sense"), and eb7054212eac ("ext4: update the cached overhead value in the superblock").
However, since it was too expensive to forcibly recalculate the overhead for bigalloc file systems at every mount, this didn't fix the problem for bigalloc file systems. This commit should address the problem when resizing file systems with the bigalloc feature enabled.
--- fs/ext4/resize.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/resize.c +1 -0
@@ -1472,6 +1472,7 @@ static void ext4_update_super(struct super_block *sb,* Update the fs overhead information */ ext4_calculate_overhead (sb); + es->s_overhead_clusters =cpu_to_le32 (sbi->s_overhead);if (test_opt (sb,DEBUG )) printk(KERN_DEBUG "EXT4-fs: added group %u:"
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 742/779 ext4: fix extent status tree race in writeback error recovery path
In reply to Greg Kroah-HartmanFrom: Eric Whitney <[email protected]>
[ Upstream commit 7f0d8e1d607c1a4fa9a27362a108921d82230874 ]
A race can occur in the unlikely event ext4 is unable to allocate a physical cluster for a delayed allocation in a bigalloc file system during writeback. Failure to allocate a cluster forces error recovery that includes a call to mpage_release_unused_pages(). That function removes any corresponding delayed allocated blocks from the extent status tree. If a new delayed write is in progress on the same cluster simultaneously, resulting in the addition of an new extent containing one or more blocks in that cluster to the extent status tree, delayed block accounting can be thrown off if that delayed write then encounters a similar cluster allocation failure during future writeback.
Write lock the i_data_sem in mpage_release_unused_pages() to fix this problem. Ext4's block/cluster accounting code for bigalloc relies on i_data_sem for mutual exclusion, as is found in the delayed write path, and the locking in mpage_release_unused_pages() is missing.
--- fs/ext4/inode.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/ext4/inode.c +7 -0
@@ -1560,7 +1560,14 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,ext4_lblk_t start, last; start = index << (PAGE_SHIFT - inode->i_blkbits); last = end << (PAGE_SHIFT - inode->i_blkbits); + +/* +* avoid racing with extent status tree scans made by +* ext4_insert_delayed_block() +*/ +down_write (&EXT4_I (inode)->i_data_sem);ext4_es_remove_extent (inode, start, last - start +1 ); +up_write (&EXT4_I (inode)->i_data_sem); }pagevec_init (&pvec);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 743/779 ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
[ Upstream commit 179b14152dcb6a24c3415200603aebca70ff13af ]
When adding an xattr to an inode, we must ensure that the inode_size is not less than EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad. Otherwise, the end position may be greater than the start position, resulting in UAF.
--- fs/ext4/xattr.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
fs/ext4/xattr.h +13 -0
@@ -95,6 +95,19 @@ struct ext4_xattr_entry {#define EXT4_ZERO_XATTR_VALUE ((void *)-1) +/* +* If we want to add an xattr to the inode, we should make sure that +* i_extra_isize is not 0 and that the inode size is not less than +* EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad. +* EXT4_GOOD_OLD_INODE_SIZE extra_isize header entry pad data +* |--------------------------|------------|------|---------|---|-------| +*/ +#define EXT4_INODE_HAS_XATTR_SPACE (inode) \ + ((EXT4_I(inode)->i_extra_isize != 0) && \ + (EXT4_GOOD_OLD_INODE_SIZE + EXT4_I(inode)->i_extra_isize + \ + sizeof(struct ext4_xattr_ibody_header) + EXT4_XATTR_PAD <= \ + EXT4_INODE_SIZE((inode)->i_sb))) +struct ext4_xattr_info {const char *name;const void *value;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 744/779 ext4: fix use-after-free in ext4_xattr_set_entry
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
[ Upstream commit 67d7d8ad99beccd9fe92d585b87f1760dc9018e3 ]
Hulk Robot reported a issue:
==================================================================
BUG: KASAN: use-after-free in ext4_xattr_set_entry+0x18ab/0x3500 Write of size 4105 at addr ffff8881675ef5f4 by task syz-executor.0/7092 CPU: 1 PID: 7092 Comm: syz-executor.0 Not tainted 4.19.90-dirty #17 Call Trace: [...] memcpy+0x34/0x50 mm/kasan/kasan.c:303 ext4_xattr_set_entry+0x18ab/0x3500 fs/ext4/xattr.c:1747 ext4_xattr_ibody_inline_set+0x86/0x2a0 fs/ext4/xattr.c:2205 ext4_xattr_set_handle+0x940/0x1300 fs/ext4/xattr.c:2386 ext4_xattr_set+0x1da/0x300 fs/ext4/xattr.c:2498 __vfs_setxattr+0x112/0x170 fs/xattr.c:149 __vfs_setxattr_noperm+0x11b/0x2a0 fs/xattr.c:180 __vfs_setxattr_locked+0x17b/0x250 fs/xattr.c:238 vfs_setxattr+0xed/0x270 fs/xattr.c:255 setxattr+0x235/0x330 fs/xattr.c:520 path_setxattr+0x176/0x190 fs/xattr.c:539 __do_sys_lsetxattr fs/xattr.c:561 [inline] __se_sys_lsetxattr fs/xattr.c:557 [inline] __x64_sys_lsetxattr+0xc2/0x160 fs/xattr.c:557 do_syscall_64+0xdf/0x530 arch/x86/entry/common.c:298 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x459fe9 RSP: 002b:00007fa5e54b4c08 EFLAGS: 00000246 ORIG_RAX: 00000000000000bd RAX: ffffffffffffffda RBX: 000000000051bf60 RCX: 0000000000459fe9 RDX: 00000000200003c0 RSI: 0000000020000180 RDI: 0000000020000140 RBP: 000000000051bf60 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000001009 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffc73c93fc0 R14: 000000000051bf60 R15: 00007fa5e54b4d80
[...]
==================================================================
Above issue may happen as follows:
-------------------------------------ext4_xattr_set
ext4_xattr_set_handle
ext4_xattr_ibody_find
>> s->end < s->base
>> no EXT4_STATE_XATTR
>> xattr_check_inode is not executed
ext4_xattr_ibody_set
ext4_xattr_set_entry
>> size_t min_offs = s->end - s->base
>> UAF in memcpy
we can easily reproduce this problem with the following commands:
mkfs.ext4 -F /dev/sda
mount -o debug_want_extra_isize=128 /dev/sda /mnt
touch /mnt/file
setfattr -n user.cat -v seq -s z 4096|tr -d '[:digit:]' /mnt/file
In ext4_xattr_ibody_find, we have the following assignment logic:
header = IHDR(inode, raw_inode)
= raw_inode + EXT4_GOOD_OLD_INODE_SIZE + i_extra_isize
is->s.base = IFIRST(header)
= header + sizeof(struct ext4_xattr_ibody_header)
is->s.end = raw_inode + s_inode_size
In ext4_xattr_set_entry
min_offs = s->end - s->base
= s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
sizeof(struct ext4_xattr_ibody_header)
last = s->first
free = min_offs - ((void *)last - s->base) - sizeof(__u32)
= s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
sizeof(struct ext4_xattr_ibody_header) - sizeof(__u32)
In the calculation formula, all values except s_inode_size and i_extra_size are fixed values. When i_extra_size is the maximum value s_inode_size - EXT4_GOOD_OLD_INODE_SIZE, min_offs is -4 and free is -8. The value overflows. As a result, the preceding issue is triggered when memcpy is executed.
Therefore, when finding xattr or setting xattr, check whether there is space for storing xattr in the inode to resolve this issue.
--- fs/ext4/xattr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ext4/xattr.c +4 -2
@@ -2176,8 +2176,9 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,struct ext4_inode *raw_inode;int error; -if (EXT4_I (inode)->i_extra_isize ==0 ) +if (!EXT4_INODE_HAS_XATTR_SPACE (inode))return 0 ; + raw_inode =ext4_raw_inode (&is->iloc); header =IHDR (inode, raw_inode); is->s.base = is->s.first =IFIRST (header);
@@ -2205,8 +2206,9 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,struct ext4_xattr_search *s = &is->s;int error; -if (EXT4_I (inode)->i_extra_isize ==0 ) +if (!EXT4_INODE_HAS_XATTR_SPACE (inode))return -ENOSPC ; + error =ext4_xattr_set_entry (i, s, handle, inode, false/* is_block */ );if (error)return error;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 745/779 ext4: correct max_inline_xattr_value_size computing
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
[ Upstream commit c9fd167d57133c5b748d16913c4eabc55e531c73 ]
If the ext4 inode does not have xattr space, 0 is returned in the get_max_inline_xattr_value_size function. Otherwise, the function returns a negative value when the inode does not contain EXT4_STATE_XATTR.
--- fs/ext4/inline.c | 3 +++ 1 file changed, 3 insertions(+)
fs/ext4/inline.c +3 -0
@@ -35,6 +35,9 @@ static int get_max_inline_xattr_value_size(struct inode *inode,struct ext4_inode *raw_inode;int free, min_offs; +if (!EXT4_INODE_HAS_XATTR_SPACE (inode)) +return 0 ; + min_offs =EXT4_SB (inode->i_sb)->s_inode_size -EXT4_GOOD_OLD_INODE_SIZE - EXT4_I(inode)->i_extra_isize -
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 746/779 ext4: correct the misjudgment in ext4_iget_extra_inode
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
[ Upstream commit fd7e672ea98b95b9d4c9dae316639f03c16a749d ]
Use the EXT4_INODE_HAS_XATTR_SPACE macro to more accurately determine whether the inode have xattr space.
--- fs/ext4/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/ext4/inode.c +1 -2
@@ -4516,8 +4516,7 @@ static inline int ext4_iget_extra_inode(struct inode *inode,__le32 *magic = (void *)raw_inode +EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize; -if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize +sizeof (__le32) <= -EXT4_INODE_SIZE (inode->i_sb) && +if (EXT4_INODE_HAS_XATTR_SPACE (inode) && *magic ==cpu_to_le32 (EXT4_XATTR_MAGIC )) {ext4_set_inode_state (inode,EXT4_STATE_XATTR );return ext4_find_inline_data_nolock (inode);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 747/779 ext4: fix warning in ext4_iomap_begin as race between bmap and write
In reply to Greg Kroah-HartmanFrom: Ye Bin <[email protected]>
[ Upstream commit 51ae846cff568c8c29921b1b28eb2dfbcd4ac12d ]
We got issue as follows:
------------[ cut here ]------------ WARNING: CPU: 3 PID: 9310 at fs/ext4/inode.c:3441 ext4_iomap_begin+0x182/0x5d0 RIP: 0010:ext4_iomap_begin+0x182/0x5d0 RSP: 0018:ffff88812460fa08 EFLAGS: 00010293 RAX: ffff88811f168000 RBX: 0000000000000000 RCX: ffffffff97793c12 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003 RBP: ffff88812c669160 R08: ffff88811f168000 R09: ffffed10258cd20f R10: ffff88812c669077 R11: ffffed10258cd20e R12: 0000000000000001 R13: 00000000000000a4 R14: 000000000000000c R15: ffff88812c6691ee FS: 00007fd0d6ff3740(0000) GS:ffff8883af180000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fd0d6dda290 CR3: 0000000104a62000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: iomap_apply+0x119/0x570 iomap_bmap+0x124/0x150 ext4_bmap+0x14f/0x250 bmap+0x55/0x80 do_vfs_ioctl+0x952/0xbd0 __x64_sys_ioctl+0xc6/0x170 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Above issue may happen as follows:
bmap write
bmap
ext4_bmap
iomap_bmap
ext4_iomap_begin
ext4_file_write_iter
ext4_buffered_write_iter
generic_perform_write
ext4_da_write_begin
ext4_da_write_inline_data_begin
ext4_prepare_inline_data
ext4_create_inline_data
ext4_set_inode_flag(inode,
EXT4_INODE_INLINE_DATA);
if (WARN_ON_ONCE(ext4_has_inline_data(inode))) ->trigger bug_onTo solved above issue hold inode lock in ext4_bamp.
--- fs/ext4/inode.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
fs/ext4/inode.c +9 -3
@@ -3137,13 +3137,15 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block) {struct inode *inode = mapping->host;journal_t *journal; +sector_t ret =0 ;int err; +inode_lock_shared (inode);/* * We can get here for an inline file via the FIBMAP ioctl */ if (ext4_has_inline_data (inode)) -return 0 ; + goto out;if (mapping_tagged (mapping,PAGECACHE_TAG_DIRTY ) &&test_opt (inode->i_sb,DELALLOC )) {
@@ -3182,10 +3184,14 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block)jbd2_journal_unlock_updates (journal);if (err) -return 0 ; + goto out; } -return iomap_bmap (mapping, block, &ext4_iomap_ops); + ret =iomap_bmap (mapping, block, &ext4_iomap_ops); + +out: +inode_unlock_shared (inode); +return ret; }static int ext4_readpage (struct file *file,struct page *page)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 748/779 ext4: check if directory block is within i_size
In reply to Greg Kroah-HartmanFrom: Lukas Czerner <[email protected]>
[ Upstream commit 65f8ea4cd57dbd46ea13b41dc8bac03176b04233 ]
Currently ext4 directory handling code implicitly assumes that the directory blocks are always within the i_size. In fact ext4_append() will attempt to allocate next directory block based solely on i_size and the i_size is then appropriately increased after a successful allocation.
However, for this to work it requires i_size to be correct. If, for any reason, the directory inode i_size is corrupted in a way that the directory tree refers to a valid directory block past i_size, we could end up corrupting parts of the directory tree structure by overwriting already used directory blocks when modifying the directory.
Fix it by catching the corruption early in __ext4_read_dirblock().
Addresses Red-Hat-Bugzilla: #2070205
CVE: CVE-2022-1184
--- fs/ext4/namei.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/ext4/namei.c +7 -0
@@ -110,6 +110,13 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,struct ext4_dir_entry *dirent;int is_dx_block =0 ; +if (block >= inode->i_size) { +ext4_error_inode (inode, func, line, block, +"Attempting to read directory block (%u) that is past i_size (%llu)" , + block, inode->i_size); +return ERR_PTR (-EFSCORRUPTED ); + } +if (ext4_simulate_fail (inode->i_sb,EXT4_SIM_DIRBLOCK_EIO )) bh =ERR_PTR (-EIO );else
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 749/779 ext4: make sure ext4_append() always allocates new block
In reply to Greg Kroah-HartmanFrom: Lukas Czerner <[email protected]>
[ Upstream commit b8a04fe77ef1360fbf73c80fddbdfeaa9407ed1b ]
ext4_append() must always allocate a new block, otherwise we run the risk of overwriting existing directory block corrupting the directory tree in the process resulting in all manner of problems later on.
Add a sanity check to see if the logical block is already allocated and error out if it is.
--- fs/ext4/namei.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
fs/ext4/namei.c +16 -0
@@ -54,6 +54,7 @@ static struct buffer_head *ext4_append(handle_t *handle,struct inode *inode, ext4_lblk_t *block) { + struct ext4_map_blocks map;struct buffer_head *bh;int err;
@@ -63,6 +64,21 @@ static struct buffer_head *ext4_append(handle_t *handle,return ERR_PTR (-ENOSPC ); *block = inode->i_size >> inode->i_sb->s_blocksize_bits; + map.m_lblk = *block; + map.m_len =1 ; + +/* +* We're appending new directory block. Make sure the block is not +* allocated yet, otherwise we will end up corrupting the +* directory. +*/ + err =ext4_map_blocks (NULL , inode, &map,0 ); +if (err <0 ) +return ERR_PTR (err); +if (err) { +EXT4_ERROR_INODE (inode,"Logical block already allocated" ); +return ERR_PTR (-EFSCORRUPTED ); + } bh =ext4_bread (handle, inode, *block,EXT4_GET_BLOCKS_CREATE );if (IS_ERR (bh))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 750/779 ext4: remove EA inode entry from mbcache on inode eviction
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
[ Upstream commit 6bc0d63dad7f9f54d381925ee855b402f652fa39 ]
Currently we remove EA inode from mbcache as soon as its xattr refcount drops to zero. However there can be pending attempts to reuse the inode and thus refcount handling code has to handle the situation when refcount increases from zero anyway. So save some work and just keep EA inode in mbcache until it is getting evicted. At that moment we are sure following iget() of EA inode will fail anyway (or wait for eviction to finish and load things from the disk again) and so removing mbcache entry at that moment is fine and simplifies the code a bit.
--- fs/ext4/inode.c | 2 ++ fs/ext4/xattr.c | 24 ++++++++---------------- fs/ext4/xattr.h | 1 + 3 files changed, 11 insertions(+), 16 deletions(-)
fs/ext4/inode.c +2 -0
@@ -179,6 +179,8 @@ void ext4_evict_inode(struct inode *inode)trace_ext4_evict_inode (inode); +if (EXT4_I (inode)->i_flags &EXT4_EA_INODE_FL ) +ext4_evict_ea_inode (inode);if (inode->i_nlink) {/* * When journalling data dirty buffers are tracked only in the
fs/ext4/xattr.c +8 -16
@@ -436,6 +436,14 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,return err; } +/* Remove entry from mbcache when EA inode is getting evicted */ +void ext4_evict_ea_inode (struct inode *inode) +{ +if (EA_INODE_CACHE (inode)) +mb_cache_entry_delete (EA_INODE_CACHE (inode), +ext4_xattr_inode_get_hash (inode), inode->i_ino); +} + static int ext4_xattr_inode_verify_hashes(struct inode *ea_inode, struct ext4_xattr_entry *entry, void *buffer,
@@ -976,10 +984,8 @@ int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,static int ext4_xattr_inode_update_ref (handle_t *handle,struct inode *ea_inode,int ref_change) { -struct mb_cache *ea_inode_cache =EA_INODE_CACHE (ea_inode);struct ext4_iloc iloc;s64 ref_count; -u32 hash;int ret;inode_lock (ea_inode);
@@ -1002,14 +1008,6 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,set_nlink (ea_inode,1 );ext4_orphan_del (handle, ea_inode); - -if (ea_inode_cache) { - hash =ext4_xattr_inode_get_hash (ea_inode); -mb_cache_entry_create (ea_inode_cache, -GFP_NOFS , hash, - ea_inode->i_ino, - true/* reusable */ ); - } } }else { WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
@@ -1022,12 +1020,6 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,clear_nlink (ea_inode);ext4_orphan_add (handle, ea_inode); - -if (ea_inode_cache) { - hash =ext4_xattr_inode_get_hash (ea_inode); -mb_cache_entry_delete (ea_inode_cache, hash, - ea_inode->i_ino); - } } }
fs/ext4/xattr.h +1 -0
@@ -191,6 +191,7 @@ extern void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *array);extern int ext4_expand_extra_isize_ea (struct inode *inode,int new_extra_isize,struct ext4_inode *raw_inode,handle_t *handle); +extern void ext4_evict_ea_inode (struct inode *inode);extern const struct xattr_handler *ext4_xattr_handlers[];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 751/779 ext4: use kmemdup() to replace kmalloc + memcpy
In reply to Greg Kroah-HartmanFrom: Shuqi Zhang <[email protected]>
[ Upstream commit 4efd9f0d120c55b08852ee5605dbb02a77089a5d ]
Replace kmalloc + memcpy with kmemdup()
--- fs/ext4/xattr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/ext4/xattr.c +1 -2
@@ -1887,11 +1887,10 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,unlock_buffer (bs->bh);ea_bdebug (bs->bh,"cloning" ); - s->base =kmalloc (bs->bh->b_size,GFP_NOFS ); + s->base =kmemdup (BHDR (bs->bh), bs->bh->b_size,GFP_NOFS ); error = -ENOMEM ;if (s->base ==NULL ) goto cleanup; -memcpy (s->base,BHDR (bs->bh), bs->bh->b_size); s->first =ENTRY (header (s->base)+1 );header (s->base)->h_refcount =cpu_to_le32 (1 ); s->here =ENTRY (s->base + offset);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 752/779 ext4: unindent codeblock in ext4_xattr_block_set()
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
[ Upstream commit fd48e9acdf26d0cbd80051de07d4a735d05d29b2 ]
Remove unnecessary else (and thus indentation level) from a code block in ext4_xattr_block_set(). It will also make following code changes easier. No functional changes.
--- fs/ext4/xattr.c | 77 ++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 39 deletions(-)
fs/ext4/xattr.c +38 -39
@@ -1850,6 +1850,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,#define header (x) ((struct ext4_xattr_header *)(x))if (s->base) { +int offset = (char *)s->here - bs->bh->b_data; +BUFFER_TRACE (bs->bh,"get_write_access" ); error =ext4_journal_get_write_access (handle, sb, bs->bh,EXT4_JTR_NONE );
@@ -1882,49 +1884,46 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,if (error) goto cleanup; goto inserted; - }else { -int offset = (char *)s->here - bs->bh->b_data; + } +unlock_buffer (bs->bh); +ea_bdebug (bs->bh,"cloning" ); + s->base =kmemdup (BHDR (bs->bh), bs->bh->b_size,GFP_NOFS ); + error = -ENOMEM ; +if (s->base ==NULL ) + goto cleanup; + s->first =ENTRY (header (s->base)+1 ); +header (s->base)->h_refcount =cpu_to_le32 (1 ); + s->here =ENTRY (s->base + offset); + s->end = s->base + bs->bh->b_size; -unlock_buffer (bs->bh); -ea_bdebug (bs->bh,"cloning" ); - s->base =kmemdup (BHDR (bs->bh), bs->bh->b_size,GFP_NOFS ); - error = -ENOMEM ; -if (s->base ==NULL ) +/* +* If existing entry points to an xattr inode, we need +* to prevent ext4_xattr_set_entry() from decrementing +* ref count on it because the reference belongs to the +* original block. In this case, make the entry look +* like it has an empty value. +*/ +if (!s->not_found && s->here->e_value_inum) { + ea_ino =le32_to_cpu (s->here->e_value_inum); + error =ext4_xattr_inode_iget (inode, ea_ino, +le32_to_cpu (s->here->e_hash), + &tmp_inode); +if (error) goto cleanup; - s->first =ENTRY (header (s->base)+1 ); -header (s->base)->h_refcount =cpu_to_le32 (1 ); - s->here =ENTRY (s->base + offset); - s->end = s->base + bs->bh->b_size; -/* -* If existing entry points to an xattr inode, we need -* to prevent ext4_xattr_set_entry() from decrementing -* ref count on it because the reference belongs to the -* original block. In this case, make the entry look -* like it has an empty value. -*/ -if (!s->not_found && s->here->e_value_inum) { - ea_ino =le32_to_cpu (s->here->e_value_inum); - error =ext4_xattr_inode_iget (inode, ea_ino, -le32_to_cpu (s->here->e_hash), - &tmp_inode); -if (error) - goto cleanup; - -if (!ext4_test_inode_state (tmp_inode, -EXT4_STATE_LUSTRE_EA_INODE )) { -/* -* Defer quota free call for previous -* inode until success is guaranteed. -*/ - old_ea_inode_quota =le32_to_cpu ( - s->here->e_value_size); - } -iput (tmp_inode); - - s->here->e_value_inum =0 ; - s->here->e_value_size =0 ; +if (!ext4_test_inode_state (tmp_inode, +EXT4_STATE_LUSTRE_EA_INODE )) { +/* +* Defer quota free call for previous +* inode until success is guaranteed. +*/ + old_ea_inode_quota =le32_to_cpu ( + s->here->e_value_size); } +iput (tmp_inode); + + s->here->e_value_inum =0 ; + s->here->e_value_size =0 ; } }else {/* Allocate a buffer where we construct the new block. */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 753/779 ext4: fix race when reusing xattr blocks
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
[ Upstream commit 65f8b80053a1b2fd602daa6814e62d6fa90e5e9b ]
When ext4_xattr_block_set() decides to remove xattr block the following race can happen:
CPU1 CPU2ext4_xattr_block_set() ext4_xattr_release_block()
new_bh = ext4_xattr_block_cache_find()
lock_buffer(bh);
ref = le32_to_cpu(BHDR(bh)->h_refcount);
if (ref == 1) {
...
mb_cache_entry_delete();
unlock_buffer(bh);
ext4_free_blocks();
...
ext4_forget(..., bh, ...);
jbd2_journal_revoke(..., bh); ext4_journal_get_write_access(..., new_bh, ...)
do_get_write_access()
jbd2_journal_cancel_revoke(..., new_bh);Later the code in ext4_xattr_block_set() finds out the block got freed and cancels reusal of the block but the revoke stays canceled and so in case of block reuse and journal replay the filesystem can get corrupted. If the race works out slightly differently, we can also hit assertions in the jbd2 code.
Fix the problem by making sure that once matching mbcache entry is found, code dropping the last xattr block reference (or trying to modify xattr block in place) waits until the mbcache entry reference is dropped. This way code trying to reuse xattr block is protected from someone trying to drop the last reference to xattr block.
--- fs/ext4/xattr.c | 67 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 22 deletions(-)
fs/ext4/xattr.c +45 -22
@@ -439,9 +439,16 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,/* Remove entry from mbcache when EA inode is getting evicted */ void ext4_evict_ea_inode (struct inode *inode) { -if (EA_INODE_CACHE (inode)) -mb_cache_entry_delete (EA_INODE_CACHE (inode), -ext4_xattr_inode_get_hash (inode), inode->i_ino); +struct mb_cache_entry *oe; + +if (!EA_INODE_CACHE (inode)) +return ; +/* Wait for entry to get unused so that we can remove it */ +while ((oe =mb_cache_entry_delete_or_get (EA_INODE_CACHE (inode), +ext4_xattr_inode_get_hash (inode), inode->i_ino))) { +mb_cache_entry_wait_unused (oe); +mb_cache_entry_put (EA_INODE_CACHE (inode), oe); + } } static int
@@ -1229,6 +1236,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,if (error) goto out; +retry_ref:lock_buffer (bh); hash =le32_to_cpu (BHDR (bh)->h_hash); ref =le32_to_cpu (BHDR (bh)->h_refcount);
@@ -1238,9 +1246,18 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,* This must happen under buffer lock for * ext4_xattr_block_set() to reliably detect freed block */ -if (ea_block_cache) -mb_cache_entry_delete (ea_block_cache, hash, - bh->b_blocknr); +if (ea_block_cache) { +struct mb_cache_entry *oe; + + oe =mb_cache_entry_delete_or_get (ea_block_cache, hash, + bh->b_blocknr); +if (oe) { +unlock_buffer (bh); +mb_cache_entry_wait_unused (oe); +mb_cache_entry_put (ea_block_cache, oe); + goto retry_ref; + } + }get_bh (bh);unlock_buffer (bh);
@@ -1867,9 +1884,20 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,* ext4_xattr_block_set() to reliably detect modified * block */ -if (ea_block_cache) -mb_cache_entry_delete (ea_block_cache, hash, - bs->bh->b_blocknr); +if (ea_block_cache) { +struct mb_cache_entry *oe; + + oe =mb_cache_entry_delete_or_get (ea_block_cache, + hash, bs->bh->b_blocknr); +if (oe) { +/* +* Xattr block is getting reused. Leave +* it alone. +*/ +mb_cache_entry_put (ea_block_cache, oe); + goto clone_block; + } + }ea_bdebug (bs->bh,"modifying in-place" ); error =ext4_xattr_set_entry (i, s, handle, inode, true/* is_block */ );
@@ -1885,6 +1913,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, goto cleanup; goto inserted; } +clone_block:unlock_buffer (bs->bh);ea_bdebug (bs->bh,"cloning" ); s->base =kmemdup (BHDR (bs->bh), bs->bh->b_size,GFP_NOFS );
@@ -1990,18 +2019,13 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,lock_buffer (new_bh);/* * We have to be careful about races with -* freeing, rehashing or adding references to -* xattr block. Once we hold buffer lock xattr -* block's state is stable so we can check -* whether the block got freed / rehashed or -* not. Since we unhash mbcache entry under -* buffer lock when freeing / rehashing xattr -* block, checking whether entry is still -* hashed is reliable. Same rules hold for -* e_reusable handling. +* adding references to xattr block. Once we +* hold buffer lock xattr block's state is +* stable so we can check the additional +* reference fits. */ -if (hlist_bl_unhashed (&ce->e_hash_list) || - !ce->e_reusable) { + ref =le32_to_cpu (BHDR (new_bh)->h_refcount) +1 ; +if (ref >EXT4_XATTR_REFCOUNT_MAX ) {/* * Undo everything and check mbcache * again.
@@ -2016,9 +2040,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, new_bh =NULL ; goto inserted; } - ref =le32_to_cpu (BHDR (new_bh)->h_refcount) +1 ;BHDR (new_bh)->h_refcount =cpu_to_le32 (ref); -if (ref >=EXT4_XATTR_REFCOUNT_MAX ) +if (ref ==EXT4_XATTR_REFCOUNT_MAX ) ce->e_reusable =0 ;ea_bdebug (new_bh,"reusing; refcount now=%d" , ref);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 754/779 KEYS: asymmetric: enforce SM2 signature use pkey algo
In reply to Greg Kroah-HartmanFrom: Tianjia Zhang <[email protected]>
[ Upstream commit 0815291a8fd66cdcf7db1445d4d99b0d16065829 ]
The signature verification of SM2 needs to add the Za value and recalculate sig->digest, which requires the detection of the pkey_algo in public_key_verify_signature(). As Eric Biggers said, the pkey_algo field in sig is attacker-controlled and should be use pkey->pkey_algo instead of sig->pkey_algo, and secondly, if sig->pkey_algo is NULL, it will also cause signature verification failure.
The software_key_determine_akcipher() already forces the algorithms are matched, so the SM3 algorithm is enforced in the SM2 signature, although this has been checked, we still avoid using any algorithm information in the signature as input.
--- crypto/asymmetric_keys/public_key.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
crypto/asymmetric_keys/public_key.c +5 -2
@@ -304,6 +304,10 @@ static int cert_sig_digest_update(const struct public_key_signature *sig,BUG_ON (!sig->data); +/* SM2 signatures always use the SM3 hash algorithm */ +if (!sig->hash_algo ||strcmp (sig->hash_algo,"sm3" ) !=0 ) +return -EINVAL ; + ret =sm2_compute_z_digest (tfm_pkey,SM2_DEFAULT_USERID ,SM2_DEFAULT_USERID_LEN , dgst);if (ret)
@@ -414,8 +418,7 @@ int public_key_verify_signature(const struct public_key *pkey,if (ret) goto error_free_key; -if (sig->pkey_algo &&strcmp (sig->pkey_algo,"sm2" ) ==0 && - sig->data_size) { +if (strcmp (pkey->pkey_algo,"sm2" ) ==0 && sig->data_size) { ret =cert_sig_digest_update (sig, tfm);if (ret) goto error_free_key;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 755/779 tpm: eventlog: Fix section mismatch for DEBUG_SECTION_MISMATCH
In reply to Greg Kroah-HartmanFrom: Huacai Chen <[email protected]>
[ Upstream commit bed4593645366ad7362a3aa7bc0d100d8d8236a8 ]
If DEBUG_SECTION_MISMATCH enabled, __calc_tpm2_event_size() will not be inlined, this cause section mismatch like this:
WARNING: modpost: vmlinux.o(.text.unlikely+0xe30c): Section mismatch in reference from the variable L0 to the function .init.text:early_ioremap() The function L0() references
the function __init early_memremap().
This is often because L0 lacks a __init
annotation or the annotation of early_ioremap is wrong.
Fix it by using __always_inline instead of inline for the called-once function __calc_tpm2_event_size().
--- include/linux/tpm_eventlog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/tpm_eventlog.h +1 -1
@@ -157,7 +157,7 @@ struct tcg_algorithm_info {* Return: size of the event on success, 0 on failure */ -static inline int __calc_tpm2_event_size (struct tcg_pcr_event2_head *event, +static __always_inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,struct tcg_pcr_event *event_header,bool do_mapping) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 756/779 xen-blkback: fix persistent grants negotiation
In reply to Greg Kroah-HartmanFrom: SeongJae Park <[email protected]>
commit fc9be616bb8f3ed9cf560308f86904f5c06be205 upstream.
Persistent grants feature can be used only when both backend and the frontend supports the feature. The feature was always supported by 'blkback', but commit aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent grants") has introduced a parameter for disabling it runtime.
To avoid the parameter be updated while being used by 'blkback', the commit caches the parameter into 'vbd->feature_gnt_persistent' in 'xen_vbd_create()', and then check if the guest also supports the feature and finally updates the field in 'connect_ring()'.
However, 'connect_ring()' could be called before 'xen_vbd_create()', so later execution of 'xen_vbd_create()' can wrongly overwrite 'true' to 'vbd->feature_gnt_persistent'. As a result, 'blkback' could try to use 'persistent grants' feature even if the guest doesn't support the feature.
This commit fixes the issue by moving the parameter value caching to 'xen_blkif_alloc()', which allocates the 'blkif'. Because the struct embeds 'vbd' object, which will be used by 'connect_ring()' later, this should be called before 'connect_ring()' and therefore this should be the right and safe place to do the caching.
--- drivers/block/xen-blkback/xenbus.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/block/xen-blkback/xenbus.c +7 -8
@@ -156,6 +156,11 @@ static int xen_blkif_alloc_rings(structreturn 0 ; } +/* Enable the persistent grants feature. */ +static bool feature_persistent = true; +module_param (feature_persistent, bool,0644 ); +MODULE_PARM_DESC (feature_persistent,"Enables the persistent grants feature" ); +static struct xen_blkif *xen_blkif_alloc (domid_t domid) {struct xen_blkif *blkif;
@@ -180,6 +185,8 @@ static struct xen_blkif *xen_blkif_alloc__module_get (THIS_MODULE );INIT_WORK (&blkif->free_work, xen_blkif_deferred_free); + blkif->vbd.feature_gnt_persistent = feature_persistent; +return blkif; }
@@ -471,12 +478,6 @@ static void xen_vbd_free(struct xen_vbd vbd->bdev =NULL ; } -/* Enable the persistent grants feature. */ -static bool feature_persistent = true; -module_param (feature_persistent, bool,0644 ); -MODULE_PARM_DESC (feature_persistent, -"Enables the persistent grants feature" ); -static int xen_vbd_create (struct xen_blkif *blkif,blkif_vdev_t handle,unsigned major,unsigned minor,int readonly,int cdrom)
@@ -522,8 +523,6 @@ static int xen_vbd_create(struct xen_blkif (q &&blk_queue_secure_erase (q)) vbd->discard_secure = true; - vbd->feature_gnt_persistent = feature_persistent; -pr_debug ("Successful creation of handle=%04x (dom=%u)\n" , handle, blkif->domid);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 757/779 xen-blkback: Apply feature_persistent parameter when connect
In reply to Greg Kroah-HartmanFrom: Maximilian Heyne <[email protected]>
commit e94c6101e151b019b8babc518ac2a6ada644a5a1 upstream.
In some use cases[1], the backend is created while the frontend doesn't support the persistent grants feature, but later the frontend can be changed to support the feature and reconnect. In the past, 'blkback' enabled the persistent grants feature since it unconditionally checked if frontend supports the persistent grants feature for every connect ('connect_ring()') and decided whether it should use persistent grans or not.
However, commit aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent grants") has mistakenly changed the behavior. It made the frontend feature support check to not be repeated once it shown the 'feature_persistent' as 'false', or the frontend doesn't support persistent grants.
This commit changes the behavior of the parameter to make effect for every connect, so that the previous workflow can work again as expected.
--- Documentation/ABI/testing/sysfs-driver-xen-blkback | 2 +- drivers/block/xen-blkback/xenbus.c | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-)
Documentation/ABI/testing/sysfs-driver-xen-blkback +1 -1
@@ -42,5 +42,5 @@ KernelVersion: 5.10 Contact: SeongJae Park <[email protected]> Description: Whether to enable the persistent grants feature or not. Note - that this option only takes effect on newly created backends. + that this option only takes effect on newly connected backends. The default is Y (enable).
drivers/block/xen-blkback/xenbus.c +3 -6
@@ -185,8 +185,6 @@ static struct xen_blkif *xen_blkif_alloc__module_get (THIS_MODULE );INIT_WORK (&blkif->free_work, xen_blkif_deferred_free); - blkif->vbd.feature_gnt_persistent = feature_persistent; -return blkif; }
@@ -1089,10 +1087,9 @@ static int connect_ring(struct backend_ixenbus_dev_fatal (dev, err,"unknown fe protocol %s" , protocol);return -ENOSYS ; } -if (blkif->vbd.feature_gnt_persistent) - blkif->vbd.feature_gnt_persistent = -xenbus_read_unsigned (dev->otherend, -"feature-persistent" ,0 ); + + blkif->vbd.feature_gnt_persistent = feature_persistent && +xenbus_read_unsigned (dev->otherend,"feature-persistent" ,0 ); blkif->vbd.overflow_max_grants =0 ;
Greg Kroah-Hartman
maintainerPATCH 758/779 xen-blkfront: Apply feature_persistent parameter when connect
In reply to Greg Kroah-HartmanFrom: SeongJae Park <[email protected]>
commit 402c43ea6b34a1b371ffeed9adf907402569eaf5 upstream.
In some use cases[1], the backend is created while the frontend doesn't support the persistent grants feature, but later the frontend can be changed to support the feature and reconnect. In the past, 'blkback' enabled the persistent grants feature since it unconditionally checked if frontend supports the persistent grants feature for every connect ('connect_ring()') and decided whether it should use persistent grans or not.
However, commit aac8a70db24b ("xen-blkback: add a parameter for disabling of persistent grants") has mistakenly changed the behavior. It made the frontend feature support check to not be repeated once it shown the 'feature_persistent' as 'false', or the frontend doesn't support persistent grants.
Similar behavioral change has made on 'blkfront' by commit 74a852479c68 ("xen-blkfront: add a parameter for disabling of persistent grants"). This commit changes the behavior of the parameter to make effect for every connect, so that the previous behavior of 'blkfront' can be restored.
--- Documentation/ABI/testing/sysfs-driver-xen-blkfront | 2 +- drivers/block/xen-blkfront.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-)
Documentation/ABI/testing/sysfs-driver-xen-blkfront +1 -1
@@ -15,5 +15,5 @@ KernelVersion: 5.10 Contact: SeongJae Park <[email protected]> Description: Whether to enable the persistent grants feature or not. Note - that this option only takes effect on newly created frontends. + that this option only takes effect on newly connected frontends. The default is Y (enable).
drivers/block/xen-blkfront.c +1 -3
@@ -2014,8 +2014,6 @@ static int blkfront_probe(struct xenbus_ info->vdevice = vdevice; info->connected =BLKIF_STATE_DISCONNECTED ; - info->feature_persistent = feature_persistent; -/* Front end dir is a number, which is used as the id. */ info->handle =simple_strtoul (strrchr (dev->nodename,'/' )+1 ,NULL ,0 );dev_set_drvdata (&dev->dev, info);
@@ -2309,7 +2307,7 @@ static void blkfront_gather_backend_featif (xenbus_read_unsigned (info->xbdev->otherend,"feature-discard" ,0 ))blkfront_setup_discard (info); -if (info->feature_persistent) +if (feature_persistent) info->feature_persistent = !!xenbus_read_unsigned (info->xbdev->otherend,"feature-persistent" ,0 );
Greg Kroah-Hartman
maintainerPATCH 759/779 powerpc: Fix eh field when calling lwarx on PPC32
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 18db466a9a306406dab3b134014d9f6ed642471c upstream.
Commit 9401f4e46cf6 ("powerpc: Use lwarx/ldarx directly instead of PPC_LWARX/LDARX macros") properly handled the eh field of lwarx in asm/bitops.h but failed to clear it for PPC32 in asm/simple_spinlock.h
So, do as in arch_atomic_try_cmpxchg_lock(), set it to 1 if PPC64 but set it to 0 if PPC32. For that use IS_ENABLED(CONFIG_PPC64) which returns 1 when CONFIG_PPC64 is set and 0 otherwise.
--- arch/powerpc/include/asm/simple_spinlock.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
arch/powerpc/include/asm/simple_spinlock.h +9 -6
@@ -48,10 +48,11 @@ static inline int arch_spin_is_locked(arstatic inline unsigned long __arch_spin_trylock (arch_spinlock_t *lock) {unsigned long tmp, token; +unsigned int eh =IS_ENABLED (CONFIG_PPC64 ); token =LOCK_TOKEN ; __asm__ __volatile__( -"1: lwarx %0,0,%2,1\n\ +"1: lwarx %0,0,%2,%[eh]\n\ cmpwi 0,%0,0\n\ bne- 2f\n\ stwcx. %1,0,%2\n\
@@ -59,7 +60,7 @@ static inline unsigned long __arch_spin_ PPC_ACQUIRE_BARRIER "2:" : "=&r" (tmp) - : "r" (token), "r" (&lock->slock) + : "r" (token), "r" (&lock->slock), [eh] "n" (eh) : "cr0", "memory"); return tmp;
@@ -177,9 +178,10 @@ static inline void arch_spin_unlock(archstatic inline long __arch_read_trylock (arch_rwlock_t *rw) {long tmp; +unsigned int eh =IS_ENABLED (CONFIG_PPC64 ); __asm__ __volatile__( -"1: lwarx %0,0,%1,1\n" +"1: lwarx %0,0,%1,%[eh]\n" __DO_SIGN_EXTEND" addic. %0,%0,1\n\ ble- 2f\n"
@@ -187,7 +189,7 @@ static inline long __arch_read_trylock(a bne- 1b\n" PPC_ACQUIRE_BARRIER "2:" : "=&r" (tmp) - : "r" (&rw->lock) + : "r" (&rw->lock), [eh] "n" (eh) : "cr0", "xer", "memory");return tmp;
@@ -200,17 +202,18 @@ static inline long __arch_read_trylock(astatic inline long __arch_write_trylock (arch_rwlock_t *rw) {long tmp, token; +unsigned int eh =IS_ENABLED (CONFIG_PPC64 ); token =WRLOCK_TOKEN ; __asm__ __volatile__( -"1: lwarx %0,0,%2,1\n\ +"1: lwarx %0,0,%2,%[eh]\n\ cmpwi 0,%0,0\n\ bne- 2f\n" " stwcx. %1,0,%2\n\ bne- 1b\n" PPC_ACQUIRE_BARRIER "2:" :"=&r" (tmp) - :"r" (token),"r" (&rw->lock) + :"r" (token),"r" (&rw->lock), [eh]"n" (eh) :"cr0" ,"memory" );return tmp;
Greg Kroah-Hartman
maintainerPATCH 760/779 tracing: Use a struct alignof to determine trace event field alignment
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (Google) <[email protected]>
commit 4c3d2f9388d36eb28640a220a6f908328442d873 upstream.
alignof() gives an alignment of types as they would be as standalone variables. But alignment in structures might be different, and when building the fields of events, the alignment must be the actual alignment otherwise the field offsets may not match what they actually are.
This caused trace-cmd to crash, as libtraceevent did not check if the field offset was bigger than the event. The write_msr and read_msr events on 32 bit had their fields incorrect, because it had a u64 field between two ints. alignof(u64) would give 8, but the u64 field was at a 4 byte alignment.
Define a macro as:
ALIGN_STRUCTFIELD(type) ((int)(offsetof(struct {char a; type b;}, b)))
which gives the actual alignment of types in a structure.
--- include/trace/trace_events.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
include/trace/trace_events.h +5 -3
@@ -479,16 +479,18 @@ static struct trace_event_functions trac#include TRACE_INCLUDE (TRACE_INCLUDE_FILE ) +#define ALIGN_STRUCTFIELD (type) ((int)(offsetof(struct {char a; type b;}, b))) +#undef __field_ext#define __field_ext (_type, _item, _filter_type) { \ .type = #_type, .name = #_item, \ - .size = sizeof(_type), .align = __alignof__(_type), \ + .size = sizeof(_type), .align = ALIGN_STRUCTFIELD(_type), \ .is_signed = is_signed_type(_type), .filter_type = _filter_type },#undef __field_struct_ext#define __field_struct_ext (_type, _item, _filter_type) { \ .type = #_type, .name = #_item, \ - .size = sizeof(_type), .align = __alignof__(_type), \ + .size = sizeof(_type), .align = ALIGN_STRUCTFIELD(_type), \ 0, .filter_type = _filter_type },#undef __field
@@ -500,7 +502,7 @@ static struct trace_event_functions trac#undef __array#define __array (_type, _item, _len) { \ .type = #_type"["__stringify(_len)"]", .name = #_item, \ - .size = sizeof(_type[_len]), .align = __alignof__(_type), \ + .size = sizeof(_type[_len]), .align = ALIGN_STRUCTFIELD(_type), \ .is_signed = is_signed_type(_type), .filter_type = FILTER_OTHER },#undef __dynamic_array
Greg Kroah-Hartman
maintainerPATCH 761/779 net_sched: cls_route: remove from list when handle is 0
In reply to Greg Kroah-HartmanFrom: Thadeu Lima de Souza Cascardo <[email protected]>
commit 9ad36309e2719a884f946678e0296be10f0bb4c1 upstream.
When a route filter is replaced and the old filter has a 0 handle, the old one won't be removed from the hashtable, while it will still be freed.
The test was there since before commit 1109c00547fc ("net: sched: RCU cls_route"), when a new filter was not allocated when there was an old one. The old filter was reused and the reinserting would only be necessary if an old filter was replaced. That was still wrong for the same case where the old handle was 0.
Remove the old filter from the list independently from its handle value.
This fixes CVE-2022-2588, also reported as ZDI-CAN-17440.
--- net/sched/cls_route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sched/cls_route.c +1 -1
@@ -526,7 +526,7 @@ static int route4_change(struct net *netrcu_assign_pointer (f->next, f1);rcu_assign_pointer (*fp, f); -if (fold && fold->handle && f->handle != fold->handle) { +if (fold) { th =to_hash (fold->handle); h =from_hash (fold->handle >>16 ); b =rtnl_dereference (head->table[th]);
Greg Kroah-Hartman
maintainerPATCH 762/779 mac80211: fix a memory leak where sta_info is not freed
In reply to Greg Kroah-HartmanFrom: Ahmed Zaki <[email protected]>
commit 8f9dcc29566626f683843ccac6113a12208315ca upstream.
The following is from a system that went OOM due to a memory leak:
wlan0: Allocated STA 74:83:c2:64:0b:87
wlan0: Allocated STA 74:83:c2:64:0b:87
wlan0: IBSS finish 74:83:c2:64:0b:87 (---from ieee80211_ibss_add_sta)
wlan0: Adding new IBSS station 74:83:c2:64:0b:87
wlan0: moving STA 74:83:c2:64:0b:87 to state 2
wlan0: moving STA 74:83:c2:64:0b:87 to state 3
wlan0: Inserted STA 74:83:c2:64:0b:87
wlan0: IBSS finish 74:83:c2:64:0b:87 (---from ieee80211_ibss_work)
wlan0: Adding new IBSS station 74:83:c2:64:0b:87
wlan0: moving STA 74:83:c2:64:0b:87 to state 2
wlan0: moving STA 74:83:c2:64:0b:87 to state 3
.
.
wlan0: expiring inactive not authorized STA 74:83:c2:64:0b:87
wlan0: moving STA 74:83:c2:64:0b:87 to state 2
wlan0: moving STA 74:83:c2:64:0b:87 to state 1
wlan0: Removed STA 74:83:c2:64:0b:87
wlan0: Destroyed STA 74:83:c2:64:0b:87
The ieee80211_ibss_finish_sta() is called twice on the same STA from 2 different locations. On the second attempt, the allocated STA is not destroyed creating a kernel memory leak.
This is happening because sta_info_insert_finish() does not call sta_info_free() the second time when the STA already exists (returns -EEXIST). Note that the caller sta_info_insert_rcu() assumes STA is destroyed upon errors.
Same fix is applied to -ENOMEM.
--- net/mac80211/sta_info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/mac80211/sta_info.c +3 -3
@@ -641,13 +641,13 @@ static int sta_info_insert_finish(struct/* check if STA exists already */ if (sta_info_get_bss (sdata, sta->sta.addr)) { err = -EEXIST ; - goto out_err; + goto out_cleanup; } sinfo =kzalloc (sizeof (struct station_info ),GFP_KERNEL );if (!sinfo) { err = -ENOMEM ; - goto out_err; + goto out_cleanup; } local->num_sta++;
@@ -703,8 +703,8 @@ static int sta_info_insert_finish(struct out_drop_sta: local->num_sta--;synchronize_net (); + out_cleanup:cleanup_single_sta (sta); - out_err:mutex_unlock (&local->sta_mtx);kfree (sinfo);rcu_read_lock ();
Greg Kroah-Hartman
maintainerPATCH 763/779 tcp: fix over estimation in sk_forced_mem_schedule()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit c4ee118561a0f74442439b7b5b486db1ac1ddfeb upstream.
sk_forced_mem_schedule() has a bug similar to ones fixed in commit 7c80b038d23e ("net: fix sk_wmem_schedule() and sk_rmem_schedule() errors")
While this bug has little chance to trigger in old kernels, we need to fix it before the following patch.
--- net/ipv4/tcp_output.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/ipv4/tcp_output.c +4 -3
@@ -3372,11 +3372,12 @@ void tcp_xmit_retransmit_queue(struct so*/ void sk_forced_mem_schedule (struct sock *sk,int size) { -int amt; +int delta, amt; -if (size <= sk->sk_forward_alloc) + delta = size - sk->sk_forward_alloc; +if (delta <=0 )return ; - amt =sk_mem_pages (size); + amt =sk_mem_pages (delta); sk->sk_forward_alloc += amt *SK_MEM_QUANTUM ;sk_memory_allocated_add (sk, amt);
Greg Kroah-Hartman
maintainerPATCH 764/779 crypto: lib/blake2s - reduce stack frame usage in self test
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
commit d6c14da474bf260d73953fbf7992c98d9112aec7 upstream.
Using 3 blocks here doesn't give us much more than using 2, and it causes a stack frame size warning on certain compiler/config/arch combinations:
lib/crypto/blake2s-selftest.c: In function 'blake2s_selftest':
Quoted 1 line
Quoted 1 line
lib/crypto/blake2s-selftest.c:632:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=]
632 | }
| ^So this patch just reduces the block from 3 to 2, which makes the warning go away.
--- lib/crypto/blake2s-selftest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
lib/crypto/blake2s-selftest.c +3 -3
@@ -593,7 +593,7 @@ bool __init blake2s_selftest(void)enum {TEST_ALIGNMENT =16 };u8 unaligned_block[BLAKE2S_BLOCK_SIZE +TEST_ALIGNMENT -1 ]__aligned(TEST_ALIGNMENT) ; -u8 blocks[BLAKE2S_BLOCK_SIZE *3 ]; +u8 blocks[BLAKE2S_BLOCK_SIZE *2 ];struct blake2s_state state1, state2;get_random_bytes (blocks,sizeof (blocks));
@@ -603,8 +603,8 @@ bool __init blake2s_selftest(void) defined(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S) memcpy(&state1, &state, sizeof(state1));memcpy (&state2, &state,sizeof (state2)); -blake2s_compress (&state1, blocks,3 ,BLAKE2S_BLOCK_SIZE ); -blake2s_compress_generic (&state2, blocks,3 ,BLAKE2S_BLOCK_SIZE ); +blake2s_compress (&state1, blocks,2 ,BLAKE2S_BLOCK_SIZE ); +blake2s_compress_generic (&state2, blocks,2 ,BLAKE2S_BLOCK_SIZE );if (memcmp (&state1, &state2,sizeof (state1))) {pr_err ("blake2s random compress self-test %d: FAIL\n" , i +1 );
Greg Kroah-Hartman
maintainerPATCH 765/779 Revert "mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv"
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
commit 5f8954e099b8ae96e7de1bb95950e00c85bedd40 upstream.
This reverts commit a52ed4866d2b90dd5e4ae9dabd453f3ed8fa3cbc as it causes build problems in linux-next. It needs to be reintroduced in a way that can allow the api to evolve and not require a "flag day" to catch all users.
--- drivers/net/wireless/marvell/mwifiex/init.c | 9 ++++----- drivers/net/wireless/marvell/mwifiex/main.h | 3 +-- drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++--- 3 files changed, 8 insertions(+), 10 deletions(-)
drivers/net/wireless/marvell/mwifiex/init.c +4 -5
@@ -63,10 +63,9 @@ static void wakeup_timer_fn(struct timer adapter->if_ops.card_reset (adapter); } -static void fw_dump_work (struct work_struct *work) +static void fw_dump_timer_fn (struct timer_list *t) { -struct mwifiex_adapter *adapter = - container_of(work, struct mwifiex_adapter, devdump_work.work); +struct mwifiex_adapter *adapter =from_timer (adapter, t, devdump_timer);mwifiex_upload_device_dump (adapter); }
@@ -322,7 +321,7 @@ static void mwifiex_init_adapter(struct adapter->active_scan_triggered = false;timer_setup (&adapter->wakeup_timer, wakeup_timer_fn,0 ); adapter->devdump_len =0 ; -INIT_DELAYED_WORK (&adapter->devdump_work, fw_dump_work); +timer_setup (&adapter->devdump_timer, fw_dump_timer_fn,0 ); }/*
@@ -401,7 +400,7 @@ static void mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) {del_timer (&adapter->wakeup_timer); -cancel_delayed_work_sync (&adapter->devdump_work); +del_timer_sync (&adapter->devdump_timer);mwifiex_cancel_all_pending_cmd (adapter);wake_up_interruptible (&adapter->cmd_wait_q.wait);wake_up_interruptible (&adapter->hs_activate_wait_q);
drivers/net/wireless/marvell/mwifiex/main.h +1 -2
@@ -49,7 +49,6 @@#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/of_irq.h> -#include <linux/workqueue.h> #include "decl.h" #include "ioctl.h"
@@ -1054,7 +1053,7 @@ struct mwifiex_adapter {/* Device dump data/length */ void *devdump_data;int devdump_len; -struct delayed_work devdump_work; +struct timer_list devdump_timer;bool ignore_btcoex_events; };
drivers/net/wireless/marvell/mwifiex/sta_event.c +3 -3
@@ -623,8 +623,8 @@ mwifiex_fw_dump_info_event(struct mwifie* transmission event get lost, in this cornel case, * user would still get partial of the dump. */ -schedule_delayed_work (&adapter->devdump_work, -msecs_to_jiffies (MWIFIEX_TIMER_10S )); +mod_timer (&adapter->devdump_timer, + jiffies +msecs_to_jiffies (MWIFIEX_TIMER_10S )); }/* Overflow check */
@@ -643,7 +643,7 @@ mwifiex_fw_dump_info_event(struct mwifiereturn ; upload_dump: -cancel_delayed_work_sync (&adapter->devdump_work); +del_timer_sync (&adapter->devdump_timer);mwifiex_upload_device_dump (adapter); }
Greg Kroah-Hartman
maintainerPATCH 766/779 Revert "s390/smp: enforce lowcore protection on CPU restart"
In reply to Greg Kroah-HartmanFrom: Alexander Gordeev <[email protected]>
commit 953503751a426413ea8aee2299ae3ee971b70d9b upstream.
This reverts commit 6f5c672d17f583b081e283927f5040f726c54598.
This breaks normal crash dump when CPU0 is offline.
--- arch/s390/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kernel/setup.c +1 -1
@@ -507,8 +507,8 @@ static void __init setup_lowcore_dat_on( S390_lowcore.svc_new_psw.mask |=PSW_MASK_DAT ; S390_lowcore.program_new_psw.mask |=PSW_MASK_DAT ; S390_lowcore.io_new_psw.mask |=PSW_MASK_DAT ; -__ctl_set_bit (0 ,28 );__ctl_store (S390_lowcore.cregs_save_area,0 ,15 ); +__ctl_set_bit (0 ,28 );put_abs_lowcore (restart_flags,RESTART_FLAG_CTLREGS );put_abs_lowcore (program_new_psw, lc->program_new_psw);for (cr =0 ; cr <ARRAY_SIZE (lc->cregs_save_area); cr++)
Greg Kroah-Hartman
maintainerPATCH 767/779 drm/bridge: tc358767: Fix (e)DP bridge endpoint parsing in dedicated function
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
commit 9030a9e571b3ba250d3d450a98310e3c74ecaff4 upstream.
Per toshiba,tc358767.yaml DT binding document, port@2 the output (e)DP port is optional. In case this port is not described in DT, the bridge driver operates in DPI-to-DP mode. The drm_of_find_panel_or_bridge() call in tc_probe_edp_bridge_endpoint() returns -ENODEV in case port@2 is not present in DT and this specific return value is incorrectly propagated outside of tc_probe_edp_bridge_endpoint() function. All other error values must be propagated and are propagated correctly.
Return 0 in case the port@2 is missing instead, that reinstates the original behavior before the commit this patch fixes.
--- drivers/gpu/drm/bridge/tc358767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/bridge/tc358767.c +1 -1
@@ -1573,7 +1573,7 @@ static int tc_probe_edp_bridge_endpoint( tc->bridge.type = DRM_MODE_CONNECTOR_DisplayPort; } -return ret; +return 0 ; }static int tc_probe (struct i2c_client *client,const struct i2c_device_id *id)
Greg Kroah-Hartman
maintainerPATCH 768/779 net: phy: smsc: Disable Energy Detect Power-Down in interrupt mode
In reply to Greg Kroah-HartmanFrom: Lukas Wunner <[email protected]>
commit 2642cc6c3bbe0900ba15bab078fd15ad8baccbc5 upstream.
Simon reports that if two LAN9514 USB adapters are directly connected without an intermediate switch, the link fails to come up and link LEDs remain dark. The issue was introduced by commit 1ce8b37241ed ("usbnet:
smsc95xx: Forward PHY interrupts to PHY driver to avoid polling").
The PHY suffers from a known erratum wherein link detection becomes unreliable if Energy Detect Power-Down is used. In poll mode, the driver works around the erratum by briefly disabling EDPD for 640 msec to detect a neighbor, then re-enabling it to save power.
In interrupt mode, no interrupt is signaled if EDPD is used by both link partners, so it must not be enabled at all.
We'll recoup the power savings by enabling SUSPEND1 mode on affected LAN95xx chips in a forthcoming commit.
--- drivers/net/phy/smsc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/phy/smsc.c +4 -2
@@ -110,7 +110,7 @@ static int smsc_phy_config_init(struct pstruct smsc_phy_priv *priv = phydev->priv;int rc; -if (!priv->energy_enable) +if (!priv->energy_enable || phydev->irq !=PHY_POLL )return 0 ; rc =phy_read (phydev,MII_LAN83C185_CTRL_STATUS );
@@ -210,6 +210,8 @@ static int lan95xx_config_aneg_ext(struc* response on link pulses to detect presence of plugged Ethernet cable. * The Energy Detect Power-Down mode is enabled again in the end of procedure to * save approximately 220 mW of power if cable is unplugged. +* The workaround is only applicable to poll mode. Energy Detect Power-Down may +* not be used in interrupt mode lest link change detection becomes unreliable. */ static int lan87xx_read_status (struct phy_device *phydev) {
@@ -217,7 +219,7 @@ static int lan87xx_read_status(struct phint err =genphy_read_status (phydev); -if (!phydev->link && priv->energy_enable) { +if (!phydev->link && priv->energy_enable && phydev->irq ==PHY_POLL ) {/* Disable EDPD to wake up PHY */ int rc =phy_read (phydev,MII_LAN83C185_CTRL_STATUS );if (rc <0 )
Greg Kroah-Hartman
maintainerPATCH 769/779 drm/vc4: change vc4_dma_range_matches from a global to static
In reply to Greg Kroah-HartmanFrom: Tom Rix <[email protected]>
commit 63569d90863ff26c8b10c8971d1271c17a45224b upstream.
sparse reportsdrivers/gpu/drm/vc4/vc4_drv.c:270:27: warning: symbol 'vc4_dma_range_matches' was not declared. Should it be static?
vc4_dma_range_matches is only used in vc4_drv.c, so it's storage class specifier should be static.
--- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/vc4/vc4_drv.c +1 -1
@@ -214,7 +214,7 @@ static void vc4_match_add_drivers(struct } } -const struct of_device_id vc4_dma_range_matches[] = { +static const struct of_device_id vc4_dma_range_matches[] = { { .compatible ="brcm,bcm2711-hvs" }, { .compatible ="brcm,bcm2835-hvs" }, { .compatible ="brcm,bcm2835-v3d" },
Greg Kroah-Hartman
maintainerPATCH 770/779 tracing/perf: Avoid -Warray-bounds warning for __rel_loc macro
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
commit c6d777acdf8f62d4ebaef0e5c6cd8fedbd6e8546 upstream.
As done for trace_events.h, also fix the __rel_loc macro in perf.h, which silences the -Warray-bounds warning:
In file included from ./include/linux/string.h:253,
from ./include/linux/bitmap.h:11,
from ./include/linux/cpumask.h:12,
from ./include/linux/mm_types_task.h:14,
from ./include/linux/mm_types.h:5,
from ./include/linux/buildid.h:5,
from ./include/linux/module.h:14,
from samples/trace_events/trace-events-sample.c:2:In function '__fortify_strcpy',
inlined from 'perf_trace_foo_rel_loc' at samples/trace_events/./trace-events-sample.h:519:1:./include/linux/fortify-string.h:47:33: warning: '__builtin_strcpy' offset 12 is out of the bounds [ 0, 4] [-Warray-bounds]
47 | #define __underlying_strcpy __builtin_strcpy
| ^
./include/linux/fortify-string.h:445:24: note: in expansion of macro '__underlying_strcpy'
445 | return __underlying_strcpy(p, q);
| ^~~~~~~~~~~~~~~~~~~Also make __data struct member a proper flexible array to avoid future problems.
--- include/trace/perf.h | 5 +++-- include/trace/trace_events.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-)
include/trace/perf.h +3 -2
@@ -23,8 +23,9 @@#undef __get_rel_dynamic_array#define __get_rel_dynamic_array (field) \ - ((void *)(&__entry->__rel_loc_##field) + \ - sizeof(__entry->__rel_loc_##field) + \ + ((void *)__entry + \ + offsetof(typeof(*__entry), __rel_loc_##field) + \ + sizeof(__entry->__rel_loc_##field) + \ (__entry->__rel_loc_##field & 0xffff))#undef __get_rel_dynamic_array_len
include/trace/trace_events.h +1 -1
@@ -128,7 +128,7 @@ TRACE_MAKE_SYSTEM_STR(); struct trace_event_raw_##name { \ struct trace_entry ent; \ tstruct \ - char __data[0]; \ + char __data[]; \ }; \ \ static struct trace_event_class event_class_##name;
Greg Kroah-Hartman
maintainerPATCH 771/779 drm/msm: Fix dirtyfb refcounting
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
commit 9225b337072a10bf9b09df8bf281437488dd8a26 upstream.
refcount_t complains about 0->1 transitions, which isn't *quite* what we wanted. So use dirtyfb==1 to mean that the fb is not connected to any output that requires dirtyfb flushing, so that we can keep the underflow and overflow checking.
--- drivers/gpu/drm/msm/msm_fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/msm_fb.c +3 -1
@@ -37,7 +37,7 @@ static int msm_framebuffer_dirtyfb(struc/* If this fb is not used on any display requiring pixel data to be * flushed, then skip dirtyfb */ -if (refcount_read (&msm_fb->dirtyfb) ==0 ) +if (refcount_read (&msm_fb->dirtyfb) ==1 )return 0 ; return drm_atomic_helper_dirtyfb(fb, file_priv, flags, color,
@@ -221,6 +221,8 @@ static struct drm_framebuffer *msm_frame goto fail; } +refcount_set (&msm_fb->dirtyfb,1 ); +drm_dbg_state (dev,"create: FB ID: %d (%p)" , fb->base.id, fb);return fb;
Greg Kroah-Hartman
maintainerPATCH 772/779 drm/meson: Fix refcount leak in meson_encoder_hdmi_init
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
commit 7381076809586528e2a812a709e2758916318a99 upstream.
of_find_device_by_node() takes reference, we should use put_device() to release it when not need anymore.
Add missing put_device() in error path to avoid refcount leak.
--- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/meson/meson_encoder_hdmi.c +3 -1
@@ -438,8 +438,10 @@ int meson_encoder_hdmi_init(struct mesoncec_fill_conn_info_from_drm (&conn_info, meson_encoder_hdmi->connector); notifier =cec_notifier_conn_register (&pdev->dev,NULL , &conn_info); -if (!notifier) +if (!notifier) { +put_device (&pdev->dev);return -ENOMEM ; + } meson_encoder_hdmi->cec_notifier = notifier; }
Greg Kroah-Hartman
maintainerPATCH 773/779 io_uring: mem-account pbuf buckets
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit cc18cc5e82033d406f54144ad6f8092206004684 upstream.
Potentially, someone may create as many pbuf bucket as there are indexes in an xarray without any other restrictions bounding our memory usage, put memory needed for the buckets under memory accounting.
--- fs/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/io_uring.c +2 -1
@@ -4477,7 +4477,8 @@ static int io_provide_buffers(struct io_ ret =io_add_buffers (p, &head);if (ret >=0 && !list) { - ret =xa_insert (&ctx->io_buffers, p->bgid, head,GFP_KERNEL ); + ret =xa_insert (&ctx->io_buffers, p->bgid, head, +GFP_KERNEL_ACCOUNT );if (ret <0 )__io_remove_buffers (ctx, head, p->bgid,-1U ); }
Greg Kroah-Hartman
maintainerPATCH 774/779 Revert "net: usb: ax88179_178a needs FLAG_SEND_ZLP"
In reply to Greg Kroah-HartmanFrom: Jose Alonso <[email protected]>
commit 6fd2c17fb6e02a8c0ab51df1cfec82ce96b8e83d upstream.
This reverts commit 36a15e1cb134c0395261ba1940762703f778438c.
The usage of FLAG_SEND_ZLP causes problems to other firmware/hardware versions that have no issues.
The FLAG_SEND_ZLP is not safe to use in this context. See:
https://patchwork.ozlabs.org/project/netdev/patch/1270599787.8900.8.camel@Linuxdev4-laptop/#118378
The original problem needs another way to solve.
--- drivers/net/usb/ax88179_178a.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/net/usb/ax88179_178a.c +10 -10
@@ -1796,7 +1796,7 @@ static const struct driver_info ax88179_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1809,7 +1809,7 @@ static const struct driver_info ax88178a .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1822,7 +1822,7 @@ static const struct driver_info cypress_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1835,7 +1835,7 @@ static const struct driver_info dlink_du .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1848,7 +1848,7 @@ static const struct driver_info sitecom_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1861,7 +1861,7 @@ static const struct driver_info samsung_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1874,7 +1874,7 @@ static const struct driver_info lenovo_i .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1887,7 +1887,7 @@ static const struct driver_info belkin_i .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1900,7 +1900,7 @@ static const struct driver_info toshiba_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1913,7 +1913,7 @@ static const struct driver_info mct_info .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
Greg Kroah-Hartman
maintainerPATCH 775/779 Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm regression
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
commit 332f1795ca202489c665a75e62e18ff6284de077 upstream.
The patch d0be8347c623: "Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put" from Jul 21, 2022, leads to the following Smatch static checker warning:
net/bluetooth/l2cap_core.c:1977 l2cap_global_chan_by_psm()
error: we previously assumed 'c' could be null (see line 1996)
--- net/bluetooth/l2cap_core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
net/bluetooth/l2cap_core.c +6 -7
@@ -1970,11 +1970,11 @@ static struct l2cap_chan *l2cap_global_c bdaddr_t *dst, u8 link_type) { -struct l2cap_chan *c, *c1 =NULL ; +struct l2cap_chan *c, *tmp, *c1 =NULL ;read_lock (&chan_list_lock); -list_for_each_entry (c, &chan_list, global_l) { +list_for_each_entry_safe (c, tmp, &chan_list, global_l) {if (state && c->state != state)continue ;
@@ -1993,11 +1993,10 @@ static struct l2cap_chan *l2cap_global_c dst_match = !bacmp (&c->dst, dst);if (src_match && dst_match) { c =l2cap_chan_hold_unless_zero (c); -if (!c) -continue ; - -read_unlock (&chan_list_lock); -return c; +if (c) { +read_unlock (&chan_list_lock); +return c; + } }/* Closest match */
Greg Kroah-Hartman
maintainerPATCH 776/779 drm/bridge: Move devm_drm_of_get_bridge to bridge/panel.c
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
commit d4ae66f10c8b9959dce1766d9a87070e567236eb upstream.
By depending on devm_drm_panel_bridge_add(), devm_drm_of_get_bridge() introduces a circular dependency between the modules drm (where devm_drm_of_get_bridge() ends up) and drm_kms_helper (where devm_drm_panel_bridge_add() is).
Fix this by moving devm_drm_of_get_bridge() to bridge/panel.c and thus drm_kms_helper.
--- drivers/gpu/drm/bridge/panel.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_bridge.c | 34 ---------------------------------- 2 files changed, 37 insertions(+), 34 deletions(-)
drivers/gpu/drm/bridge/panel.c +37 -0
@@ -9,6 +9,7 @@#include <drm/drm_connector.h> #include <drm/drm_encoder.h> #include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_of.h> #include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h>
@@ -332,3 +333,39 @@ struct drm_connector *drm_panel_bridge_creturn &panel_bridge->connector; }EXPORT_SYMBOL (drm_panel_bridge_connector); + +#ifdef CONFIG_OF +/** +* devm_drm_of_get_bridge - Return next bridge in the chain +* @dev: device to tie the bridge lifetime to +* @np: device tree node containing encoder output ports +* @port: port in the device tree node +* @endpoint: endpoint in the device tree node +* +* Given a DT node's port and endpoint number, finds the connected node +* and returns the associated bridge if any, or creates and returns a +* drm panel bridge instance if a panel is connected. +* +* Returns a pointer to the bridge if successful, or an error pointer +* otherwise. +*/ +struct drm_bridge *devm_drm_of_get_bridge (struct device *dev, +struct device_node *np, +u32 port,u32 endpoint) +{ +struct drm_bridge *bridge; +struct drm_panel *panel; +int ret; + + ret =drm_of_find_panel_or_bridge (np, port, endpoint, + &panel, &bridge); +if (ret) +return ERR_PTR (ret); + +if (panel) + bridge =devm_drm_panel_bridge_add (dev, panel); + +return bridge; +} +EXPORT_SYMBOL (devm_drm_of_get_bridge); +#endif
drivers/gpu/drm/drm_bridge.c +0 -34
@@ -1232,40 +1232,6 @@ struct drm_bridge *of_drm_find_bridge(st return NULL; }EXPORT_SYMBOL (of_drm_find_bridge); - -/** -* devm_drm_of_get_bridge - Return next bridge in the chain -* @dev: device to tie the bridge lifetime to -* @np: device tree node containing encoder output ports -* @port: port in the device tree node -* @endpoint: endpoint in the device tree node -* -* Given a DT node's port and endpoint number, finds the connected node -* and returns the associated bridge if any, or creates and returns a -* drm panel bridge instance if a panel is connected. -* -* Returns a pointer to the bridge if successful, or an error pointer -* otherwise. -*/ -struct drm_bridge *devm_drm_of_get_bridge (struct device *dev, -struct device_node *np, -u32 port,u32 endpoint) -{ -struct drm_bridge *bridge; -struct drm_panel *panel; -int ret; - - ret =drm_of_find_panel_or_bridge (np, port, endpoint, - &panel, &bridge); -if (ret) -return ERR_PTR (ret); - -if (panel) - bridge =devm_drm_panel_bridge_add (dev, panel); - -return bridge; -} -EXPORT_SYMBOL (devm_drm_of_get_bridge);#endif MODULE_AUTHOR ("Ajay Kumar <[email protected]>" );
Greg Kroah-Hartman
maintainerPATCH 777/779 scsi: lpfc: Fix locking for lpfc_sli_iocbq_lookup()
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
commit c26bd6602e1d348bfa754dc55e5608c922dd2801 upstream.
The rules changed for lpfc_sli_iocbq_lookup() vs locking. Prior, the routine properly took out the lock. In newly refactored code, the locks must be held when calling the routine.
Fix lpfc_sli_process_sol_iocb() to take the locks before calling the routine.
Fix lpfc_sli_handle_fast_ring_event() to not release the locks to call the routine.
--- drivers/scsi/lpfc/lpfc_sli.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/scsi/lpfc/lpfc_sli.c +8 -2
@@ -3642,7 +3642,15 @@ lpfc_sli_process_sol_iocb(struct lpfc_hbunsigned long iflag;u32 ulp_command, ulp_status, ulp_word4, ulp_context, iotag; +if (phba->sli_rev ==LPFC_SLI_REV4 ) +spin_lock_irqsave (&pring->ring_lock, iflag); +else +spin_lock_irqsave (&phba->hbalock, iflag); cmdiocbp =lpfc_sli_iocbq_lookup (phba, pring, saveq); +if (phba->sli_rev ==LPFC_SLI_REV4 ) +spin_unlock_irqrestore (&pring->ring_lock, iflag); +else +spin_unlock_irqrestore (&phba->hbalock, iflag); ulp_command =get_job_cmnd (phba, saveq); ulp_status =get_job_ulpstatus (phba, saveq);
@@ -3979,10 +3987,8 @@ lpfc_sli_handle_fast_ring_event(struct lbreak ; } -spin_unlock_irqrestore (&phba->hbalock, iflag); cmdiocbq =lpfc_sli_iocbq_lookup (phba, pring, &rspiocbq); -spin_lock_irqsave (&phba->hbalock, iflag);if (unlikely (!cmdiocbq))break ;if (cmdiocbq->cmd_flag &LPFC_DRIVER_ABORTED )
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.61 release. There are 779 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Aug 2022 18:01:29 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.61-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.61 release. There are 779 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully cross-compiled for arm64 (bcm2711_defconfig, GCC 10.2.0) and powerpc (ps3_defconfig, GCC 12.1.0).
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Greg Kroah-Hartman
maintainerPATCH 778/779 scsi: lpfc: Fix element offset in __lpfc_sli_release_iocbq_s4()
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
commit 84c6f99e39074d45f75986e42ca28e27c140fd0d upstream.
The prior commit that moved from iocb elements to explicit wqe elements missed a name change.
Correct __lpfc_sli_release_iocbq_s4() to reference wqe rather than iocb.
--- drivers/scsi/lpfc/lpfc_sli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_sli.c +1 -1
@@ -1384,7 +1384,7 @@ static void __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) { struct lpfc_sglq *sglq; -size_t start_clean = offsetof(struct lpfc_iocbq , iocb); +size_t start_clean = offsetof(struct lpfc_iocbq , wqe);unsigned long iflag =0 ;struct lpfc_sli_ring *pring;
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.61 release. There are 779 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Aug 2022 18:01:29 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.61-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
The powerpc defconfig failed on stable-rc 5.15.
* powerpc, build
- gcc-10-ppc6xx_defconfig
- gcc-11-ppc6xx_defconfig
- gcc-8-ppc6xx_defconfig
- gcc-9-ppc6xx_defconfig
arch/powerpc/sysdev/fsl_pci.c: In function 'fsl_add_bridge':arch/powerpc/sysdev/fsl_pci.c:601:39: error:
'PCI_CLASS_BRIDGE_PCI_NORMAL' undeclared (first use in this function); did you mean 'PCI_CLASS_BRIDGE_PCI'?
601 | class_code |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
| PCI_CLASS_BRIDGE_PCIarch/powerpc/sysdev/fsl_pci.c:601:39: note: each undeclared identifier is reported only once for each function it appears in
make[3]: *** [scripts/Makefile.build:289: arch/powerpc/sysdev/fsl_pci.o] Error 1
Steps to reproduce:
--------------------
# To install tuxmake on your system globally:
# sudo pip3 install -U tuxmake # # See https://docs.tuxmake.org/ for complete documentation. # Original tuxmake command with fragments listed below.
tuxmake --runtime podman --target-arch powerpc --toolchain gcc-11 --kconfig ppc6xx_defconfig
--
Linaro LKFT
https://lkft.linaro.org
Quoted 33 lines · On Tuesday 16 August 2022 14:11:45 Naresh Kamboju wrote:
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.61 release. There are 779 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Aug 2022 18:01:29 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.61-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
The powerpc defconfig failed on stable-rc 5.15.
* powerpc, build
- gcc-10-ppc6xx_defconfig
- gcc-11-ppc6xx_defconfig
- gcc-8-ppc6xx_defconfig
- gcc-9-ppc6xx_defconfig
arch/powerpc/sysdev/fsl_pci.c: In function 'fsl_add_bridge':arch/powerpc/sysdev/fsl_pci.c:601:39: error:
'PCI_CLASS_BRIDGE_PCI_NORMAL' undeclared (first use in this function); did you mean 'PCI_CLASS_BRIDGE_PCI'?
Quoted 6 lines
601 | class_code |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ | PCI_CLASS_BRIDGE_PCI
arch/powerpc/sysdev/fsl_pci.c:601:39: note: each undeclared identifier is reported only once for each function it appears in
make[3]: *** [scripts/Makefile.build:289:arch/powerpc/sysdev/fsl_pci.o] Error 1
Hello, this is probably because of missing PCI_CLASS_BRIDGE_PCI_NORMAL define which was added in this change:
Quoted 17 lines
Steps to reproduce:
--------------------
# To install tuxmake on your system globally:# sudo pip3 install -U tuxmake # # See https://docs.tuxmake.org/ for complete documentation. # Original tuxmake command with fragments listed below.tuxmake --runtime podman --target-arch powerpc --toolchain gcc-11 --kconfig
ppc6xx_defconfig--
Linaro LKFT
https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 41 lines · Pali Rohár
Quoted 33 lines · On Tuesday 16 August 2022 14:11:45 Naresh Kamboju wrote:
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.61 release. There are 779 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Aug 2022 18:01:29 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.61-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
The powerpc defconfig failed on stable-rc 5.15.
* powerpc, build
- gcc-10-ppc6xx_defconfig
- gcc-11-ppc6xx_defconfig
- gcc-8-ppc6xx_defconfig
- gcc-9-ppc6xx_defconfig
arch/powerpc/sysdev/fsl_pci.c: In function 'fsl_add_bridge':arch/powerpc/sysdev/fsl_pci.c:601:39: error:
'PCI_CLASS_BRIDGE_PCI_NORMAL' undeclared (first use in this function); did you mean 'PCI_CLASS_BRIDGE_PCI'?Quoted 6 lines
601 | class_code |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ | PCI_CLASS_BRIDGE_PCI
arch/powerpc/sysdev/fsl_pci.c:601:39: note: each undeclared identifier is reported only once for each function it appears in
make[3]: *** [scripts/Makefile.build:289:arch/powerpc/sysdev/fsl_pci.o] Error 1
Quoted 4 lines
Hello, this is probably because of missing
PCI_CLASS_BRIDGE_PCI_NORMALdefine which was added in this change:
I've taken that portion of the commit in the tree now, thanks.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 779/779 scsi: lpfc: Resolve some cleanup issues following SLI path refactoring
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
commit e27f05147bff21408c1b8410ad8e90cd286e7952 upstream.
Following refactoring and consolidation in SLI processing, fix up some minor issues related to SLI path:
- Correct the setting of LPFC_EXCHANGE_BUSY flag in response IOCB.
- Fix some typographical errors.
- Fix duplicate log messages.
--- drivers/scsi/lpfc/lpfc_init.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-)
drivers/scsi/lpfc/lpfc_init.c +1 -1
@@ -11964,7 +11964,7 @@ lpfc_sli_enable_msi(struct lpfc_hba *phb rc =pci_enable_msi (phba->pcidev);if (!rc)lpfc_printf_log (phba,KERN_INFO ,LOG_INIT , -"0462 PCI enable MSI mode success.\n" ); +"0012 PCI enable MSI mode success.\n" );else {lpfc_printf_log (phba,KERN_INFO ,LOG_INIT ,"0471 PCI enable MSI mode failed (%d)\n" , rc);
drivers/scsi/lpfc/lpfc_sli.c +12 -13
@@ -1939,7 +1939,7 @@ lpfc_issue_cmf_sync_wqe(struct lpfc_hba sync_buf =__lpfc_sli_get_iocbq (phba);if (!sync_buf) {lpfc_printf_log (phba,KERN_ERR ,LOG_CGN_MGMT , -"6213 No available WQEs for CMF_SYNC_WQE\n" ); +"6244 No available WQEs for CMF_SYNC_WQE\n" ); ret_val =ENOMEM ; goto out_unlock; }
@@ -3737,7 +3737,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hbset_job_ulpword4 (cmdiocbp,IOERR_ABORT_REQUESTED );/* -* For SLI4, irsiocb contains +* For SLI4, irspiocb contains * NO_XRI in sli_xritag, it * shall not affect releasing * sgl (xri) process.
@@ -3755,7 +3755,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hb } } } - (cmdiocbp->cmd_cmpl) (phba, cmdiocbp, saveq); + cmdiocbp->cmd_cmpl (phba, cmdiocbp, saveq); }else lpfc_sli_release_iocbq (phba, cmdiocbp); }else {
@@ -3995,8 +3995,7 @@ lpfc_sli_handle_fast_ring_event(struct l cmdiocbq->cmd_flag &= ~LPFC_DRIVER_ABORTED ;if (cmdiocbq->cmd_cmpl) {spin_unlock_irqrestore (&phba->hbalock, iflag); - (cmdiocbq->cmd_cmpl)(phba, cmdiocbq, - &rspiocbq); + cmdiocbq->cmd_cmpl (phba, cmdiocbq, &rspiocbq);spin_lock_irqsave (&phba->hbalock, iflag); }break ;
@@ -10936,7 +10935,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba* @flag: Flag indicating if this command can be put into txq. * * __lpfc_sli_issue_fcp_io_s3 is wrapper function to invoke lockless func to -* send an iocb command to an HBA with SLI-4 interface spec. +* send an iocb command to an HBA with SLI-3 interface spec. * * This function takes the hbalock before invoking the lockless version. * The function will return success after it successfully submit the wqe to
@@ -12989,7 +12988,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba cmdiocbq->cmd_cmpl = cmdiocbq->wait_cmd_cmpl; cmdiocbq->wait_cmd_cmpl =NULL ;if (cmdiocbq->cmd_cmpl) - (cmdiocbq->cmd_cmpl)(phba, cmdiocbq,NULL ); + cmdiocbq->cmd_cmpl (phba, cmdiocbq,NULL );else lpfc_sli_release_iocbq (phba, cmdiocbq);return ;
@@ -13003,9 +13002,9 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba/* Set the exchange busy flag for task management commands */ if ((cmdiocbq->cmd_flag &LPFC_IO_FCP ) && - !(cmdiocbq->cmd_flag &LPFC_IO_LIBDFC )) { + !(cmdiocbq->cmd_flag &LPFC_IO_LIBDFC )) { lpfc_cmd = container_of(cmdiocbq, struct lpfc_io_buf, - cur_iocbq); + cur_iocbq);if (rspiocbq && (rspiocbq->cmd_flag &LPFC_EXCHANGE_BUSY )) lpfc_cmd->flags |=LPFC_SBUF_XBUSY ;else
@@ -14143,7 +14142,7 @@ void lpfc_sli4_els_xri_abort_event_proc(* @irspiocbq: Pointer to work-queue completion queue entry. * * This routine handles an ELS work-queue completion event and construct -* a pseudo response ELS IODBQ from the SLI4 ELS WCQE for the common +* a pseudo response ELS IOCBQ from the SLI4 ELS WCQE for the common * discovery engine to handle. * * Return: Pointer to the receive IOCBQ, NULL otherwise.
@@ -14187,7 +14186,7 @@ lpfc_sli4_els_preprocess_rspiocbq(structif (bf_get (lpfc_wcqe_c_xb, wcqe)) {spin_lock_irqsave (&phba->hbalock, iflags); - cmdiocbq->cmd_flag |=LPFC_EXCHANGE_BUSY ; + irspiocbq->cmd_flag |=LPFC_EXCHANGE_BUSY ;spin_unlock_irqrestore (&phba->hbalock, iflags); }
@@ -15046,7 +15045,7 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc/* Pass the cmd_iocb and the wcqe to the upper layer */ memcpy (&cmdiocbq->wcqe_cmpl, wcqe,sizeof (struct lpfc_wcqe_complete )); - (cmdiocbq->cmd_cmpl)(phba, cmdiocbq, cmdiocbq); + cmdiocbq->cmd_cmpl (phba, cmdiocbq, cmdiocbq); }else {lpfc_printf_log (phba,KERN_WARNING ,LOG_SLI , "0375 FCP cmdiocb not callback function "
@@ -19210,7 +19209,7 @@ lpfc_sli4_send_seq_to_ulp(struct lpfc_vp/* Free iocb created in lpfc_prep_seq */ list_for_each_entry_safe (curr_iocb, next_iocb, - &iocbq->list, list) { + &iocbq->list, list) {list_del_init (&curr_iocb->list);lpfc_sli_release_iocbq (phba, curr_iocb); }
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.61 release. There are 779 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Aug 2022 18:01:29 +0000. Anything received after that time might be too late.
Building powerpc:ppc32_allmodconfig ... failed
Building powerpc:ppc6xx_defconfig ... failed
--------------
Error log:arch/powerpc/sysdev/fsl_pci.c: In function 'fsl_add_bridge':arch/powerpc/sysdev/fsl_pci.c:601:39: error: 'PCI_CLASS_BRIDGE_PCI_NORMAL' undeclared
This affects v5.15.y and earlier branches. Several patches would be needded to make this work. In mainline:
0c551abfa004 powerpc/fsl-pci: Fix Class Code of PCIe Root Port 113fe88eed53 powerpc: Don't include asm/setup.h in asm/machdep.h e6f6390ab7b9 powerpc: Add missing headers904b10fb189c PCI: Add defines for normal and subtractive PCI bridges
There may be others since the patches touch several files, and it seems quite unlikely that they all apply to older kernels. It may be easier to define PCI_CLASS_BRIDGE_PCI_NORMAL locally.
Guenter
Greg Kroah-Hartman
maintainerQuoted 20 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.61 release. There are 779 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Aug 2022 18:01:29 +0000. Anything received after that time might be too late.
Building powerpc:ppc32_allmodconfig ... failed
Building powerpc:ppc6xx_defconfig ... failed
--------------
Error log:arch/powerpc/sysdev/fsl_pci.c: In function 'fsl_add_bridge':arch/powerpc/sysdev/fsl_pci.c:601:39: error: 'PCI_CLASS_BRIDGE_PCI_NORMAL' undeclaredThis affects v5.15.y and earlier branches. Several patches would be needded to make this work. In mainline:
Quoted 8 lines
0c551abfa004powerpc/fsl-pci: Fix Class Code of PCIe Root Port113fe88eed53powerpc: Don't includeasm/setup.hinasm/machdep.he6f6390ab7b9powerpc: Add missing headers904b10fb189cPCI: Add defines for normal and subtractive PCI bridgesThere may be others since the patches touch several files, and it seems quite unlikely that they all apply to older kernels. It may be easier to define
PCI_CLASS_BRIDGE_PCI_NORMALlocally.
Yeah, I'll just pick that portion out of 904b10fb189c ("PCI: Add defines for normal and subtractive PCI bridges") to fix this build up (and the build on older queues.)
thanks,
greg k-h