From: Sasha Levin Date: Thu, 17 Aug 2023 14:52:49 +0000 (-0400) Subject: Fixes for 4.19 X-Git-Tag: v6.4.12~98 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3c9193ce7fad0b5b3bcb8bed4461f4aa6254a0ca;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/alsa-emu10k1-roll-up-loops-in-dsp-setup-code-for-aud.patch b/queue-4.19/alsa-emu10k1-roll-up-loops-in-dsp-setup-code-for-aud.patch new file mode 100644 index 00000000000..dc637f84224 --- /dev/null +++ b/queue-4.19/alsa-emu10k1-roll-up-loops-in-dsp-setup-code-for-aud.patch @@ -0,0 +1,153 @@ +From 5c2ebe2661a7d9e5372d7333a2ed1ad27b61d459 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 May 2023 19:39:05 +0200 +Subject: ALSA: emu10k1: roll up loops in DSP setup code for Audigy + +From: Oswald Buddenhagen + +[ Upstream commit 8cabf83c7aa54530e699be56249fb44f9505c4f3 ] + +There is no apparent reason for the massive code duplication. + +Signed-off-by: Oswald Buddenhagen +Link: https://lore.kernel.org/r/20230510173917.3073107-3-oswald.buddenhagen@gmx.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/emu10k1/emufx.c | 112 +++----------------------------------- + 1 file changed, 9 insertions(+), 103 deletions(-) + +diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c +index 1f25e6d029d82..84d98c098b744 100644 +--- a/sound/pci/emu10k1/emufx.c ++++ b/sound/pci/emu10k1/emufx.c +@@ -1550,14 +1550,8 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) + gpr += 2; + + /* Master volume (will be renamed later) */ +- A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS)); +- A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS)); +- A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS)); +- A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS)); +- A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS)); +- A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS)); +- A_OP(icode, &ptr, iMAC0, A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS)); +- A_OP(icode, &ptr, iMAC0, A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS)); ++ for (z = 0; z < 8; z++) ++ A_OP(icode, &ptr, iMAC0, A_GPR(playback+z+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+z+SND_EMU10K1_PLAYBACK_CHANNELS)); + snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0); + gpr += 2; + +@@ -1641,102 +1635,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) + dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n", + gpr, tmp); + */ +- /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ +- /* A_P16VIN(0) is delayed by one sample, +- * so all other A_P16VIN channels will need to also be delayed +- */ +- /* Left ADC in. 1 of 2 */ + snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); +- /* Right ADC in 1 of 2 */ +- gpr_map[gpr++] = 0x00000000; +- /* Delaying by one sample: instead of copying the input +- * value A_P16VIN to output A_FXBUS2 as in the first channel, +- * we use an auxiliary register, delaying the value by one +- * sample +- */ +- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) ); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) ); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000); +- /* For 96kHz mode */ +- /* Left ADC in. 2 of 2 */ +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) ); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000); +- /* Right ADC in 2 of 2 */ +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) ); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) ); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); +- /* Pavel Hofman - we still have voices, A_FXBUS2s, and +- * A_P16VINs available - +- * let's add 8 more capture channels - total of 16 +- */ +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, +- bit_shifter16, +- A_GPR(gpr - 1), +- A_FXBUS2(0x10)); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8), +- A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, +- bit_shifter16, +- A_GPR(gpr - 1), +- A_FXBUS2(0x12)); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9), +- A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, +- bit_shifter16, +- A_GPR(gpr - 1), +- A_FXBUS2(0x14)); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa), +- A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, +- bit_shifter16, +- A_GPR(gpr - 1), +- A_FXBUS2(0x16)); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb), +- A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, +- bit_shifter16, +- A_GPR(gpr - 1), +- A_FXBUS2(0x18)); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc), +- A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, +- bit_shifter16, +- A_GPR(gpr - 1), +- A_FXBUS2(0x1a)); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd), +- A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, +- bit_shifter16, +- A_GPR(gpr - 1), +- A_FXBUS2(0x1c)); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe), +- A_C_00000000, A_C_00000000); +- gpr_map[gpr++] = 0x00000000; +- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, +- bit_shifter16, +- A_GPR(gpr - 1), +- A_FXBUS2(0x1e)); +- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf), +- A_C_00000000, A_C_00000000); ++ /* A_P16VIN(0) is delayed by one sample, so all other A_P16VIN channels ++ * will need to also be delayed; we use an auxiliary register for that. */ ++ for (z = 1; z < 0x10; z++) { ++ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr), A_FXBUS2(z * 2) ); ++ A_OP(icode, &ptr, iACC3, A_GPR(gpr), A_P16VIN(z), A_C_00000000, A_C_00000000); ++ gpr_map[gpr++] = 0x00000000; ++ } + } + + #if 0 +-- +2.40.1 + diff --git a/queue-4.19/block-fix-signed-int-overflow-in-amiga-partition-sup.patch b/queue-4.19/block-fix-signed-int-overflow-in-amiga-partition-sup.patch new file mode 100644 index 00000000000..f191b3ed908 --- /dev/null +++ b/queue-4.19/block-fix-signed-int-overflow-in-amiga-partition-sup.patch @@ -0,0 +1,73 @@ +From b3db5bacad32a2e7f2e66447b3310f21f2cb152e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Jun 2023 08:17:23 +1200 +Subject: block: fix signed int overflow in Amiga partition support + +From: Michael Schmitz + +[ Upstream commit fc3d092c6bb48d5865fec15ed5b333c12f36288c ] + +The Amiga partition parser module uses signed int for partition sector +address and count, which will overflow for disks larger than 1 TB. + +Use sector_t as type for sector address and size to allow using disks +up to 2 TB without LBD support, and disks larger than 2 TB with LBD. + +This bug was reported originally in 2012, and the fix was created by +the RDB author, Joanne Dow . A patch had been +discussed and reviewed on linux-m68k at that time but never officially +submitted. This patch differs from Joanne's patch only in its use of +sector_t instead of unsigned int. No checking for overflows is done +(see patch 3 of this series for that). + +Reported-by: Martin Steigerwald +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511 +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Message-ID: <201206192146.09327.Martin@lichtvoll.de> +Cc: # 5.2 +Signed-off-by: Michael Schmitz +Tested-by: Martin Steigerwald +Reviewed-by: Geert Uytterhoeven +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20230620201725.7020-2-schmitzmic@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/partitions/amiga.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/block/partitions/amiga.c b/block/partitions/amiga.c +index 560936617d9c1..4a4160221183b 100644 +--- a/block/partitions/amiga.c ++++ b/block/partitions/amiga.c +@@ -32,7 +32,8 @@ int amiga_partition(struct parsed_partitions *state) + unsigned char *data; + struct RigidDiskBlock *rdb; + struct PartitionBlock *pb; +- int start_sect, nr_sects, blk, part, res = 0; ++ sector_t start_sect, nr_sects; ++ int blk, part, res = 0; + int blksize = 1; /* Multiplier for disk block size */ + int slot = 1; + char b[BDEVNAME_SIZE]; +@@ -100,14 +101,14 @@ int amiga_partition(struct parsed_partitions *state) + + /* Tell Kernel about it */ + +- nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 - +- be32_to_cpu(pb->pb_Environment[9])) * ++ nr_sects = ((sector_t)be32_to_cpu(pb->pb_Environment[10]) + 1 - ++ be32_to_cpu(pb->pb_Environment[9])) * + be32_to_cpu(pb->pb_Environment[3]) * + be32_to_cpu(pb->pb_Environment[5]) * + blksize; + if (!nr_sects) + continue; +- start_sect = be32_to_cpu(pb->pb_Environment[9]) * ++ start_sect = (sector_t)be32_to_cpu(pb->pb_Environment[9]) * + be32_to_cpu(pb->pb_Environment[3]) * + be32_to_cpu(pb->pb_Environment[5]) * + blksize; +-- +2.40.1 + diff --git a/queue-4.19/bluetooth-l2cap-fix-use-after-free.patch b/queue-4.19/bluetooth-l2cap-fix-use-after-free.patch new file mode 100644 index 00000000000..aab62a413f1 --- /dev/null +++ b/queue-4.19/bluetooth-l2cap-fix-use-after-free.patch @@ -0,0 +1,41 @@ +From bf66bf13724ac68d7ab5383887f0a31ffa7cda02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 May 2023 17:04:15 -0700 +Subject: Bluetooth: L2CAP: Fix use-after-free + +From: Zhengping Jiang + +[ Upstream commit f752a0b334bb95fe9b42ecb511e0864e2768046f ] + +Fix potential use-after-free in l2cap_le_command_rej. + +Signed-off-by: Zhengping Jiang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index fcc471f921895..9346fae5d664b 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -5705,9 +5705,14 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn, + if (!chan) + goto done; + ++ chan = l2cap_chan_hold_unless_zero(chan); ++ if (!chan) ++ goto done; ++ + l2cap_chan_lock(chan); + l2cap_chan_del(chan, ECONNREFUSED); + l2cap_chan_unlock(chan); ++ l2cap_chan_put(chan); + + done: + mutex_unlock(&conn->chan_lock); +-- +2.40.1 + diff --git a/queue-4.19/drm-amdgpu-fix-potential-fence-use-after-free-v2.patch b/queue-4.19/drm-amdgpu-fix-potential-fence-use-after-free-v2.patch new file mode 100644 index 00000000000..bf97f857729 --- /dev/null +++ b/queue-4.19/drm-amdgpu-fix-potential-fence-use-after-free-v2.patch @@ -0,0 +1,52 @@ +From f49632c56ca0d84e311ee22e688ea83c3d4abc4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Jun 2023 18:10:47 -0700 +Subject: drm/amdgpu: Fix potential fence use-after-free v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: shanzhulig + +[ Upstream commit 2e54154b9f27262efd0cb4f903cc7d5ad1fe9628 ] + +fence Decrements the reference count before exiting. +Avoid Race Vulnerabilities for fence use-after-free. + +v2 (chk): actually fix the use after free and not just move it. + +Signed-off-by: shanzhulig +Signed-off-by: Christian König +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +index e667bcf64bc7f..70e446c2acf82 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -1502,15 +1502,15 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev, + continue; + + r = dma_fence_wait_timeout(fence, true, timeout); ++ if (r > 0 && fence->error) ++ r = fence->error; ++ + dma_fence_put(fence); + if (r < 0) + return r; + + if (r == 0) + break; +- +- if (fence->error) +- return fence->error; + } + + memset(wait, 0, sizeof(*wait)); +-- +2.40.1 + diff --git a/queue-4.19/drm-radeon-fix-integer-overflow-in-radeon_cs_parser_.patch b/queue-4.19/drm-radeon-fix-integer-overflow-in-radeon_cs_parser_.patch new file mode 100644 index 00000000000..60b6652b2d2 --- /dev/null +++ b/queue-4.19/drm-radeon-fix-integer-overflow-in-radeon_cs_parser_.patch @@ -0,0 +1,41 @@ +From b47e989f06e1e4fad09ee421ce3def8c2f09e1c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Apr 2023 20:20:58 +0800 +Subject: drm/radeon: Fix integer overflow in radeon_cs_parser_init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: hackyzh002 + +[ Upstream commit f828b681d0cd566f86351c0b913e6cb6ed8c7b9c ] + +The type of size is unsigned, if size is 0x40000000, there will be an +integer overflow, size will be zero after size *= sizeof(uint32_t), +will cause uninitialized memory to be referenced later + +Reviewed-by: Christian König +Signed-off-by: hackyzh002 +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/radeon/radeon_cs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c +index 1ae31dbc61c64..5e61abb3dce5c 100644 +--- a/drivers/gpu/drm/radeon/radeon_cs.c ++++ b/drivers/gpu/drm/radeon/radeon_cs.c +@@ -265,7 +265,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) + { + struct drm_radeon_cs *cs = data; + uint64_t *chunk_array_ptr; +- unsigned size, i; ++ u64 size; ++ unsigned i; + u32 ring = RADEON_CS_RING_GFX; + s32 priority = 0; + +-- +2.40.1 + diff --git a/queue-4.19/fs-jfs-check-for-read-only-mounted-filesystem-in-txb.patch b/queue-4.19/fs-jfs-check-for-read-only-mounted-filesystem-in-txb.patch new file mode 100644 index 00000000000..559ade8dcc3 --- /dev/null +++ b/queue-4.19/fs-jfs-check-for-read-only-mounted-filesystem-in-txb.patch @@ -0,0 +1,39 @@ +From b13da086c1415e12a25aa12f5f7ec94c9b611455 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Jun 2023 19:17:08 +0530 +Subject: FS: JFS: Check for read-only mounted filesystem in txBegin + +From: Immad Mir + +[ Upstream commit 95e2b352c03b0a86c5717ba1d24ea20969abcacc ] + + This patch adds a check for read-only mounted filesystem + in txBegin before starting a transaction potentially saving + from NULL pointer deref. + +Signed-off-by: Immad Mir +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_txnmgr.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c +index 78789c5ed36b0..e10db01f253b8 100644 +--- a/fs/jfs/jfs_txnmgr.c ++++ b/fs/jfs/jfs_txnmgr.c +@@ -367,6 +367,11 @@ tid_t txBegin(struct super_block *sb, int flag) + jfs_info("txBegin: flag = 0x%x", flag); + log = JFS_SBI(sb)->log; + ++ if (!log) { ++ jfs_error(sb, "read-only filesystem\n"); ++ return 0; ++ } ++ + TXN_LOCK(); + + INCREMENT(TxStat.txBegin); +-- +2.40.1 + diff --git a/queue-4.19/fs-jfs-fix-null-ptr-deref-read-in-txbegin.patch b/queue-4.19/fs-jfs-fix-null-ptr-deref-read-in-txbegin.patch new file mode 100644 index 00000000000..bcda60628e9 --- /dev/null +++ b/queue-4.19/fs-jfs-fix-null-ptr-deref-read-in-txbegin.patch @@ -0,0 +1,44 @@ +From f81faa8296c2f86d2d0356d97484a1d430e38676 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Jun 2023 19:14:01 +0530 +Subject: FS: JFS: Fix null-ptr-deref Read in txBegin + +From: Immad Mir + +[ Upstream commit 47cfdc338d674d38f4b2f22b7612cc6a2763ba27 ] + + Syzkaller reported an issue where txBegin may be called + on a superblock in a read-only mounted filesystem which leads + to NULL pointer deref. This could be solved by checking if + the filesystem is read-only before calling txBegin, and returning + with appropiate error code. + +Reported-By: syzbot+f1faa20eec55e0c8644c@syzkaller.appspotmail.com +Link: https://syzkaller.appspot.com/bug?id=be7e52c50c5182cc09a09ea6fc456446b2039de3 + +Signed-off-by: Immad Mir +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/namei.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c +index 14528c0ffe635..c2c439acbb780 100644 +--- a/fs/jfs/namei.c ++++ b/fs/jfs/namei.c +@@ -811,6 +811,11 @@ static int jfs_link(struct dentry *old_dentry, + if (rc) + goto out; + ++ if (isReadOnly(ip)) { ++ jfs_error(ip->i_sb, "read-only filesystem\n"); ++ return -EROFS; ++ } ++ + tid = txBegin(ip->i_sb, 0); + + mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT); +-- +2.40.1 + diff --git a/queue-4.19/fs-jfs-fix-ubsan-array-index-out-of-bounds-in-dballo.patch b/queue-4.19/fs-jfs-fix-ubsan-array-index-out-of-bounds-in-dballo.patch new file mode 100644 index 00000000000..1806789ff0b --- /dev/null +++ b/queue-4.19/fs-jfs-fix-ubsan-array-index-out-of-bounds-in-dballo.patch @@ -0,0 +1,86 @@ +From 369b1936a7022319258d11058e05559240f13c1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Jun 2023 00:07:03 +0530 +Subject: fs: jfs: Fix UBSAN: array-index-out-of-bounds in dbAllocDmapLev + +From: Yogesh + +[ Upstream commit 4e302336d5ca1767a06beee7596a72d3bdc8d983 ] + +Syzkaller reported the following issue: + +UBSAN: array-index-out-of-bounds in fs/jfs/jfs_dmap.c:1965:6 +index -84 is out of range for type 's8[341]' (aka 'signed char[341]') +CPU: 1 PID: 4995 Comm: syz-executor146 Not tainted 6.4.0-rc6-syzkaller-00037-gb6dad5178cea #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023 +Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106 + ubsan_epilogue lib/ubsan.c:217 [inline] + __ubsan_handle_out_of_bounds+0x11c/0x150 lib/ubsan.c:348 + dbAllocDmapLev+0x3e5/0x430 fs/jfs/jfs_dmap.c:1965 + dbAllocCtl+0x113/0x920 fs/jfs/jfs_dmap.c:1809 + dbAllocAG+0x28f/0x10b0 fs/jfs/jfs_dmap.c:1350 + dbAlloc+0x658/0xca0 fs/jfs/jfs_dmap.c:874 + dtSplitUp fs/jfs/jfs_dtree.c:974 [inline] + dtInsert+0xda7/0x6b00 fs/jfs/jfs_dtree.c:863 + jfs_create+0x7b6/0xbb0 fs/jfs/namei.c:137 + lookup_open fs/namei.c:3492 [inline] + open_last_lookups fs/namei.c:3560 [inline] + path_openat+0x13df/0x3170 fs/namei.c:3788 + do_filp_open+0x234/0x490 fs/namei.c:3818 + do_sys_openat2+0x13f/0x500 fs/open.c:1356 + do_sys_open fs/open.c:1372 [inline] + __do_sys_openat fs/open.c:1388 [inline] + __se_sys_openat fs/open.c:1383 [inline] + __x64_sys_openat+0x247/0x290 fs/open.c:1383 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd +RIP: 0033:0x7f1f4e33f7e9 +Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 14 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007ffc21129578 EFLAGS: 00000246 ORIG_RAX: 0000000000000101 +RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1f4e33f7e9 +RDX: 000000000000275a RSI: 0000000020000040 RDI: 00000000ffffff9c +RBP: 00007f1f4e2ff080 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 00007f1f4e2ff110 +R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 + + +The bug occurs when the dbAllocDmapLev()function attempts to access +dp->tree.stree[leafidx + LEAFIND] while the leafidx value is negative. + +To rectify this, the patch introduces a safeguard within the +dbAllocDmapLev() function. A check has been added to verify if leafidx is +negative. If it is, the function immediately returns an I/O error, preventing +any further execution that could potentially cause harm. + +Tested via syzbot. + +Reported-by: syzbot+853a6f4dfa3cf37d3aea@syzkaller.appspotmail.com +Link: https://syzkaller.appspot.com/bug?extid=ae2f5a27a07ae44b0f17 +Signed-off-by: Yogesh +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_dmap.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 07b9df8938f29..63ad6b1d575a5 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -2040,6 +2040,9 @@ dbAllocDmapLev(struct bmap * bmp, + if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx)) + return -ENOSPC; + ++ if (leafidx < 0) ++ return -EIO; ++ + /* determine the block number within the file system corresponding + * to the leaf at which free space was found. + */ +-- +2.40.1 + diff --git a/queue-4.19/gfs2-fix-possible-data-races-in-gfs2_show_options.patch b/queue-4.19/gfs2-fix-possible-data-races-in-gfs2_show_options.patch new file mode 100644 index 00000000000..2a5c1081735 --- /dev/null +++ b/queue-4.19/gfs2-fix-possible-data-races-in-gfs2_show_options.patch @@ -0,0 +1,86 @@ +From ebec742dc0cea69366abb536403c832c4193fe01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Jun 2023 11:06:37 +0800 +Subject: gfs2: Fix possible data races in gfs2_show_options() + +From: Tuo Li + +[ Upstream commit 6fa0a72cbbe45db4ed967a51f9e6f4e3afe61d20 ] + +Some fields such as gt_logd_secs of the struct gfs2_tune are accessed +without holding the lock gt_spin in gfs2_show_options(): + + val = sdp->sd_tune.gt_logd_secs; + if (val != 30) + seq_printf(s, ",commit=%d", val); + +And thus can cause data races when gfs2_show_options() and other functions +such as gfs2_reconfigure() are concurrently executed: + + spin_lock(>->gt_spin); + gt->gt_logd_secs = newargs->ar_commit; + +To fix these possible data races, the lock sdp->sd_tune.gt_spin is +acquired before accessing the fields of gfs2_tune and released after these +accesses. + +Further changes by Andreas: + +- Don't hold the spin lock over the seq_printf operations. + +Reported-by: BassCheck +Signed-off-by: Tuo Li +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/super.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c +index bb0eaa4638e3c..29157f7d9663d 100644 +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -1374,7 +1374,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) + { + struct gfs2_sbd *sdp = root->d_sb->s_fs_info; + struct gfs2_args *args = &sdp->sd_args; +- int val; ++ unsigned int logd_secs, statfs_slow, statfs_quantum, quota_quantum; ++ ++ spin_lock(&sdp->sd_tune.gt_spin); ++ logd_secs = sdp->sd_tune.gt_logd_secs; ++ quota_quantum = sdp->sd_tune.gt_quota_quantum; ++ statfs_quantum = sdp->sd_tune.gt_statfs_quantum; ++ statfs_slow = sdp->sd_tune.gt_statfs_slow; ++ spin_unlock(&sdp->sd_tune.gt_spin); + + if (is_ancestor(root, sdp->sd_master_dir)) + seq_puts(s, ",meta"); +@@ -1429,17 +1436,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) + } + if (args->ar_discard) + seq_puts(s, ",discard"); +- val = sdp->sd_tune.gt_logd_secs; +- if (val != 30) +- seq_printf(s, ",commit=%d", val); +- val = sdp->sd_tune.gt_statfs_quantum; +- if (val != 30) +- seq_printf(s, ",statfs_quantum=%d", val); +- else if (sdp->sd_tune.gt_statfs_slow) ++ if (logd_secs != 30) ++ seq_printf(s, ",commit=%d", logd_secs); ++ if (statfs_quantum != 30) ++ seq_printf(s, ",statfs_quantum=%d", statfs_quantum); ++ else if (statfs_slow) + seq_puts(s, ",statfs_quantum=0"); +- val = sdp->sd_tune.gt_quota_quantum; +- if (val != 60) +- seq_printf(s, ",quota_quantum=%d", val); ++ if (quota_quantum != 60) ++ seq_printf(s, ",quota_quantum=%d", quota_quantum); + if (args->ar_statfs_percent) + seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent); + if (args->ar_errors != GFS2_ERRORS_DEFAULT) { +-- +2.40.1 + diff --git a/queue-4.19/hid-add-quirk-for-03f0-464a-hp-elite-presenter-mouse.patch b/queue-4.19/hid-add-quirk-for-03f0-464a-hp-elite-presenter-mouse.patch new file mode 100644 index 00000000000..4ad108a9252 --- /dev/null +++ b/queue-4.19/hid-add-quirk-for-03f0-464a-hp-elite-presenter-mouse.patch @@ -0,0 +1,54 @@ +From 8b2928c86cf74a5e698ca990f6bba7570780deb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 May 2023 15:40:08 +0200 +Subject: HID: add quirk for 03f0:464a HP Elite Presenter Mouse + +From: Marco Morandini + +[ Upstream commit 0db117359e47750d8bd310d19f13e1c4ef7fc26a ] + +HP Elite Presenter Mouse HID Record Descriptor shows +two mouses (Repord ID 0x1 and 0x2), one keypad (Report ID 0x5), +two Consumer Controls (Report IDs 0x6 and 0x3). +Previous to this commit it registers one mouse, one keypad +and one Consumer Control, and it was usable only as a +digitl laser pointer (one of the two mouses). This patch defines +the 464a USB device ID and enables the HID_QUIRK_MULTI_INPUT +quirk for it, allowing to use the device both as a mouse +and a digital laser pointer. + +Signed-off-by: Marco Morandini +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index c0ba8d6f4978f..a9d6f8acf70b5 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -571,6 +571,7 @@ + #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 + + #define USB_VENDOR_ID_HP 0x03f0 ++#define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A 0x464a + #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a + #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a + #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 8de294aa3184a..a2ab338166e61 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -98,6 +98,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL }, ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL }, +-- +2.40.1 + diff --git a/queue-4.19/iio-adc-stx104-implement-and-utilize-register-struct.patch b/queue-4.19/iio-adc-stx104-implement-and-utilize-register-struct.patch new file mode 100644 index 00000000000..117b6c00b54 --- /dev/null +++ b/queue-4.19/iio-adc-stx104-implement-and-utilize-register-struct.patch @@ -0,0 +1,213 @@ +From 01a0b9adf5bdd86d3a9e7fc0b24eb114f2fc8e47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Jul 2022 13:21:24 -0400 +Subject: iio: adc: stx104: Implement and utilize register structures + +From: William Breathitt Gray + +[ Upstream commit 6cfd14c54b1f42f29097244c1b6208f8268d7d5b ] + +Reduce magic numbers and improve code readability by implementing and +utilizing named register data structures. + +Tested-by: Fred Eckert +Signed-off-by: William Breathitt Gray +Link: https://lore.kernel.org/r/8cb91d5b53e57b066120e42ea07000d6c7ef5543.1657213745.git.william.gray@linaro.org +Signed-off-by: Jonathan Cameron +Stable-dep-of: 4f9b80aefb9e ("iio: addac: stx104: Fix race condition when converting analog-to-digital") +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/stx104.c | 74 +++++++++++++++++++++++++++------------- + 1 file changed, 50 insertions(+), 24 deletions(-) + +diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c +index bdc4281d9fdaf..c25523ecebab2 100644 +--- a/drivers/iio/adc/stx104.c ++++ b/drivers/iio/adc/stx104.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #define STX104_OUT_CHAN(chan) { \ + .type = IIO_VOLTAGE, \ +@@ -52,14 +53,36 @@ static unsigned int num_stx104; + module_param_hw_array(base, uint, ioport, &num_stx104, 0); + MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses"); + ++/** ++ * struct stx104_reg - device register structure ++ * @ssr_ad: Software Strobe Register and ADC Data ++ * @achan: ADC Channel ++ * @dio: Digital I/O ++ * @dac: DAC Channels ++ * @cir_asr: Clear Interrupts and ADC Status ++ * @acr: ADC Control ++ * @pccr_fsh: Pacer Clock Control and FIFO Status MSB ++ * @acfg: ADC Configuration ++ */ ++struct stx104_reg { ++ u16 ssr_ad; ++ u8 achan; ++ u8 dio; ++ u16 dac[2]; ++ u8 cir_asr; ++ u8 acr; ++ u8 pccr_fsh; ++ u8 acfg; ++}; ++ + /** + * struct stx104_iio - IIO device private data structure + * @chan_out_states: channels' output states +- * @base: base port address of the IIO device ++ * @reg: I/O address offset for the device registers + */ + struct stx104_iio { + unsigned int chan_out_states[STX104_NUM_OUT_CHAN]; +- void __iomem *base; ++ struct stx104_reg __iomem *reg; + }; + + /** +@@ -72,7 +95,7 @@ struct stx104_iio { + struct stx104_gpio { + struct gpio_chip chip; + spinlock_t lock; +- void __iomem *base; ++ u8 __iomem *base; + unsigned int out_state; + }; + +@@ -80,6 +103,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long mask) + { + struct stx104_iio *const priv = iio_priv(indio_dev); ++ struct stx104_reg __iomem *const reg = priv->reg; + unsigned int adc_config; + int adbu; + int gain; +@@ -87,7 +111,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev, + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + /* get gain configuration */ +- adc_config = ioread8(priv->base + 11); ++ adc_config = ioread8(®->acfg); + gain = adc_config & 0x3; + + *val = 1 << gain; +@@ -99,24 +123,26 @@ static int stx104_read_raw(struct iio_dev *indio_dev, + } + + /* select ADC channel */ +- iowrite8(chan->channel | (chan->channel << 4), priv->base + 2); ++ iowrite8(chan->channel | (chan->channel << 4), ®->achan); + +- /* trigger ADC sample capture and wait for completion */ +- iowrite8(0, priv->base); +- while (ioread8(priv->base + 8) & BIT(7)); ++ /* trigger ADC sample capture by writing to the 8-bit ++ * Software Strobe Register and wait for completion ++ */ ++ iowrite8(0, ®->ssr_ad); ++ while (ioread8(®->cir_asr) & BIT(7)); + +- *val = ioread16(priv->base); ++ *val = ioread16(®->ssr_ad); + return IIO_VAL_INT; + case IIO_CHAN_INFO_OFFSET: + /* get ADC bipolar/unipolar configuration */ +- adc_config = ioread8(priv->base + 11); ++ adc_config = ioread8(®->acfg); + adbu = !(adc_config & BIT(2)); + + *val = -32768 * adbu; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* get ADC bipolar/unipolar and gain configuration */ +- adc_config = ioread8(priv->base + 11); ++ adc_config = ioread8(®->acfg); + adbu = !(adc_config & BIT(2)); + gain = adc_config & 0x3; + +@@ -138,16 +164,16 @@ static int stx104_write_raw(struct iio_dev *indio_dev, + /* Only four gain states (x1, x2, x4, x8) */ + switch (val) { + case 1: +- iowrite8(0, priv->base + 11); ++ iowrite8(0, &priv->reg->acfg); + break; + case 2: +- iowrite8(1, priv->base + 11); ++ iowrite8(1, &priv->reg->acfg); + break; + case 4: +- iowrite8(2, priv->base + 11); ++ iowrite8(2, &priv->reg->acfg); + break; + case 8: +- iowrite8(3, priv->base + 11); ++ iowrite8(3, &priv->reg->acfg); + break; + default: + return -EINVAL; +@@ -161,7 +187,7 @@ static int stx104_write_raw(struct iio_dev *indio_dev, + return -EINVAL; + + priv->chan_out_states[chan->channel] = val; +- iowrite16(val, priv->base + 4 + 2 * chan->channel); ++ iowrite16(val, &priv->reg->dac[chan->channel]); + + return 0; + } +@@ -315,15 +341,15 @@ static int stx104_probe(struct device *dev, unsigned int id) + } + + priv = iio_priv(indio_dev); +- priv->base = devm_ioport_map(dev, base[id], STX104_EXTENT); +- if (!priv->base) ++ priv->reg = devm_ioport_map(dev, base[id], STX104_EXTENT); ++ if (!priv->reg) + return -ENOMEM; + + indio_dev->info = &stx104_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + /* determine if differential inputs */ +- if (ioread8(priv->base + 8) & BIT(5)) { ++ if (ioread8(&priv->reg->cir_asr) & BIT(5)) { + indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff); + indio_dev->channels = stx104_channels_diff; + } else { +@@ -335,14 +361,14 @@ static int stx104_probe(struct device *dev, unsigned int id) + indio_dev->dev.parent = dev; + + /* configure device for software trigger operation */ +- iowrite8(0, priv->base + 9); ++ iowrite8(0, &priv->reg->acr); + + /* initialize gain setting to x1 */ +- iowrite8(0, priv->base + 11); ++ iowrite8(0, &priv->reg->acfg); + + /* initialize DAC output to 0V */ +- iowrite16(0, priv->base + 4); +- iowrite16(0, priv->base + 6); ++ iowrite16(0, &priv->reg->dac[0]); ++ iowrite16(0, &priv->reg->dac[1]); + + stx104gpio->chip.label = dev_name(dev); + stx104gpio->chip.parent = dev; +@@ -357,7 +383,7 @@ static int stx104_probe(struct device *dev, unsigned int id) + stx104gpio->chip.get_multiple = stx104_gpio_get_multiple; + stx104gpio->chip.set = stx104_gpio_set; + stx104gpio->chip.set_multiple = stx104_gpio_set_multiple; +- stx104gpio->base = priv->base + 3; ++ stx104gpio->base = &priv->reg->dio; + stx104gpio->out_state = 0x0; + + spin_lock_init(&stx104gpio->lock); +-- +2.40.1 + diff --git a/queue-4.19/iio-adc-stx104-utilize-iomap-interface.patch b/queue-4.19/iio-adc-stx104-utilize-iomap-interface.patch new file mode 100644 index 00000000000..eedbacec5dd --- /dev/null +++ b/queue-4.19/iio-adc-stx104-utilize-iomap-interface.patch @@ -0,0 +1,206 @@ +From 78c12340236da83257794603494c7af355be3fdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 May 2022 13:30:59 -0400 +Subject: iio: adc: stx104: Utilize iomap interface + +From: William Breathitt Gray + +[ Upstream commit 73b8390cc27e096ab157be261ccc4eaaa6db87af ] + +This driver doesn't need to access I/O ports directly via inb()/outb() +and friends. This patch abstracts such access by calling ioport_map() +to enable the use of more typical ioread8()/iowrite8() I/O memory +accessor calls. + +Suggested-by: David Laight +Signed-off-by: William Breathitt Gray +Reviewed-by: Linus Walleij +Link: https://lore.kernel.org/r/64673797df382c52fc32fce24348b25a0b05e73a.1652201921.git.william.gray@linaro.org +Signed-off-by: Jonathan Cameron +Stable-dep-of: 4f9b80aefb9e ("iio: addac: stx104: Fix race condition when converting analog-to-digital") +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/stx104.c | 56 +++++++++++++++++++++------------------- + 1 file changed, 29 insertions(+), 27 deletions(-) + +diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c +index 0662ca199eb0b..bdc4281d9fdaf 100644 +--- a/drivers/iio/adc/stx104.c ++++ b/drivers/iio/adc/stx104.c +@@ -59,7 +59,7 @@ MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses"); + */ + struct stx104_iio { + unsigned int chan_out_states[STX104_NUM_OUT_CHAN]; +- unsigned int base; ++ void __iomem *base; + }; + + /** +@@ -72,7 +72,7 @@ struct stx104_iio { + struct stx104_gpio { + struct gpio_chip chip; + spinlock_t lock; +- unsigned int base; ++ void __iomem *base; + unsigned int out_state; + }; + +@@ -87,7 +87,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev, + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + /* get gain configuration */ +- adc_config = inb(priv->base + 11); ++ adc_config = ioread8(priv->base + 11); + gain = adc_config & 0x3; + + *val = 1 << gain; +@@ -99,24 +99,24 @@ static int stx104_read_raw(struct iio_dev *indio_dev, + } + + /* select ADC channel */ +- outb(chan->channel | (chan->channel << 4), priv->base + 2); ++ iowrite8(chan->channel | (chan->channel << 4), priv->base + 2); + + /* trigger ADC sample capture and wait for completion */ +- outb(0, priv->base); +- while (inb(priv->base + 8) & BIT(7)); ++ iowrite8(0, priv->base); ++ while (ioread8(priv->base + 8) & BIT(7)); + +- *val = inw(priv->base); ++ *val = ioread16(priv->base); + return IIO_VAL_INT; + case IIO_CHAN_INFO_OFFSET: + /* get ADC bipolar/unipolar configuration */ +- adc_config = inb(priv->base + 11); ++ adc_config = ioread8(priv->base + 11); + adbu = !(adc_config & BIT(2)); + + *val = -32768 * adbu; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* get ADC bipolar/unipolar and gain configuration */ +- adc_config = inb(priv->base + 11); ++ adc_config = ioread8(priv->base + 11); + adbu = !(adc_config & BIT(2)); + gain = adc_config & 0x3; + +@@ -138,16 +138,16 @@ static int stx104_write_raw(struct iio_dev *indio_dev, + /* Only four gain states (x1, x2, x4, x8) */ + switch (val) { + case 1: +- outb(0, priv->base + 11); ++ iowrite8(0, priv->base + 11); + break; + case 2: +- outb(1, priv->base + 11); ++ iowrite8(1, priv->base + 11); + break; + case 4: +- outb(2, priv->base + 11); ++ iowrite8(2, priv->base + 11); + break; + case 8: +- outb(3, priv->base + 11); ++ iowrite8(3, priv->base + 11); + break; + default: + return -EINVAL; +@@ -161,7 +161,7 @@ static int stx104_write_raw(struct iio_dev *indio_dev, + return -EINVAL; + + priv->chan_out_states[chan->channel] = val; +- outw(val, priv->base + 4 + 2 * chan->channel); ++ iowrite16(val, priv->base + 4 + 2 * chan->channel); + + return 0; + } +@@ -230,7 +230,7 @@ static int stx104_gpio_get(struct gpio_chip *chip, unsigned int offset) + if (offset >= 4) + return -EINVAL; + +- return !!(inb(stx104gpio->base) & BIT(offset)); ++ return !!(ioread8(stx104gpio->base) & BIT(offset)); + } + + static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, +@@ -238,7 +238,7 @@ static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, + { + struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); + +- *bits = inb(stx104gpio->base); ++ *bits = ioread8(stx104gpio->base); + + return 0; + } +@@ -260,7 +260,7 @@ static void stx104_gpio_set(struct gpio_chip *chip, unsigned int offset, + else + stx104gpio->out_state &= ~mask; + +- outb(stx104gpio->out_state, stx104gpio->base); ++ iowrite8(stx104gpio->out_state, stx104gpio->base); + + spin_unlock_irqrestore(&stx104gpio->lock, flags); + } +@@ -287,7 +287,7 @@ static void stx104_gpio_set_multiple(struct gpio_chip *chip, + + stx104gpio->out_state &= ~*mask; + stx104gpio->out_state |= *mask & *bits; +- outb(stx104gpio->out_state, stx104gpio->base); ++ iowrite8(stx104gpio->out_state, stx104gpio->base); + + spin_unlock_irqrestore(&stx104gpio->lock, flags); + } +@@ -314,11 +314,16 @@ static int stx104_probe(struct device *dev, unsigned int id) + return -EBUSY; + } + ++ priv = iio_priv(indio_dev); ++ priv->base = devm_ioport_map(dev, base[id], STX104_EXTENT); ++ if (!priv->base) ++ return -ENOMEM; ++ + indio_dev->info = &stx104_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + /* determine if differential inputs */ +- if (inb(base[id] + 8) & BIT(5)) { ++ if (ioread8(priv->base + 8) & BIT(5)) { + indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff); + indio_dev->channels = stx104_channels_diff; + } else { +@@ -329,18 +334,15 @@ static int stx104_probe(struct device *dev, unsigned int id) + indio_dev->name = dev_name(dev); + indio_dev->dev.parent = dev; + +- priv = iio_priv(indio_dev); +- priv->base = base[id]; +- + /* configure device for software trigger operation */ +- outb(0, base[id] + 9); ++ iowrite8(0, priv->base + 9); + + /* initialize gain setting to x1 */ +- outb(0, base[id] + 11); ++ iowrite8(0, priv->base + 11); + + /* initialize DAC output to 0V */ +- outw(0, base[id] + 4); +- outw(0, base[id] + 6); ++ iowrite16(0, priv->base + 4); ++ iowrite16(0, priv->base + 6); + + stx104gpio->chip.label = dev_name(dev); + stx104gpio->chip.parent = dev; +@@ -355,7 +357,7 @@ static int stx104_probe(struct device *dev, unsigned int id) + stx104gpio->chip.get_multiple = stx104_gpio_get_multiple; + stx104gpio->chip.set = stx104_gpio_set; + stx104gpio->chip.set_multiple = stx104_gpio_set_multiple; +- stx104gpio->base = base[id] + 3; ++ stx104gpio->base = priv->base + 3; + stx104gpio->out_state = 0x0; + + spin_lock_init(&stx104gpio->lock); +-- +2.40.1 + diff --git a/queue-4.19/iio-add-addac-subdirectory.patch b/queue-4.19/iio-add-addac-subdirectory.patch new file mode 100644 index 00000000000..4aff0094848 --- /dev/null +++ b/queue-4.19/iio-add-addac-subdirectory.patch @@ -0,0 +1,78 @@ +From 38d6fea16ab4e19911c67a8e5d0203e9b8c25d64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Dec 2021 13:40:43 +0200 +Subject: iio: add addac subdirectory + +From: Cosmin Tanislav + +[ Upstream commit b62e2e1763cda3a6c494ed754317f19be1249297 ] + +For IIO devices that expose both ADC and DAC functionality. + +Signed-off-by: Cosmin Tanislav +Link: https://lore.kernel.org/r/20211205114045.173612-2-cosmin.tanislav@analog.com +Signed-off-by: Jonathan Cameron +Stable-dep-of: 4f9b80aefb9e ("iio: addac: stx104: Fix race condition when converting analog-to-digital") +Signed-off-by: Sasha Levin +--- + drivers/iio/Kconfig | 1 + + drivers/iio/Makefile | 1 + + drivers/iio/addac/Kconfig | 8 ++++++++ + drivers/iio/addac/Makefile | 6 ++++++ + 4 files changed, 16 insertions(+) + create mode 100644 drivers/iio/addac/Kconfig + create mode 100644 drivers/iio/addac/Makefile + +diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig +index d08aeb41cd078..810e72e4e8b7d 100644 +--- a/drivers/iio/Kconfig ++++ b/drivers/iio/Kconfig +@@ -70,6 +70,7 @@ config IIO_TRIGGERED_EVENT + + source "drivers/iio/accel/Kconfig" + source "drivers/iio/adc/Kconfig" ++source "drivers/iio/addac/Kconfig" + source "drivers/iio/afe/Kconfig" + source "drivers/iio/amplifiers/Kconfig" + source "drivers/iio/chemical/Kconfig" +diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile +index cb5993251381e..a60d0cbfe4cd2 100644 +--- a/drivers/iio/Makefile ++++ b/drivers/iio/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o + + obj-y += accel/ + obj-y += adc/ ++obj-y += addac/ + obj-y += afe/ + obj-y += amplifiers/ + obj-y += buffer/ +diff --git a/drivers/iio/addac/Kconfig b/drivers/iio/addac/Kconfig +new file mode 100644 +index 0000000000000..2e64d7755d5ea +--- /dev/null ++++ b/drivers/iio/addac/Kconfig +@@ -0,0 +1,8 @@ ++# ++# ADC DAC drivers ++# ++# When adding new entries keep the list in alphabetical order ++ ++menu "Analog to digital and digital to analog converters" ++ ++endmenu +diff --git a/drivers/iio/addac/Makefile b/drivers/iio/addac/Makefile +new file mode 100644 +index 0000000000000..b888b9ee12da0 +--- /dev/null ++++ b/drivers/iio/addac/Makefile +@@ -0,0 +1,6 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Makefile for industrial I/O ADDAC drivers ++# ++ ++# When adding new entries keep the list in alphabetical order +-- +2.40.1 + diff --git a/queue-4.19/iio-addac-stx104-fix-race-condition-for-stx104_write.patch b/queue-4.19/iio-addac-stx104-fix-race-condition-for-stx104_write.patch new file mode 100644 index 00000000000..b3abbe514d0 --- /dev/null +++ b/queue-4.19/iio-addac-stx104-fix-race-condition-for-stx104_write.patch @@ -0,0 +1,74 @@ +From f2770b749c9896c514acf77cd4370c57ca851e60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Apr 2023 10:40:10 -0400 +Subject: iio: addac: stx104: Fix race condition for stx104_write_raw() + +From: William Breathitt Gray + +[ Upstream commit 9740827468cea80c42db29e7171a50e99acf7328 ] + +The priv->chan_out_states array and actual DAC value can become +mismatched if stx104_write_raw() is called concurrently. Prevent such a +race condition by utilizing a mutex. + +Fixes: 97a445dad37a ("iio: Add IIO support for the DAC on the Apex Embedded Systems STX104") +Signed-off-by: William Breathitt Gray +Link: https://lore.kernel.org/r/c95c9a77fcef36b2a052282146950f23bbc1ebdc.1680790580.git.william.gray@linaro.org +Cc: +Signed-off-by: Jonathan Cameron +Stable-dep-of: 4f9b80aefb9e ("iio: addac: stx104: Fix race condition when converting analog-to-digital") +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/stx104.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c +index c25523ecebab2..78e87d1aaaefb 100644 +--- a/drivers/iio/adc/stx104.c ++++ b/drivers/iio/adc/stx104.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -77,10 +78,12 @@ struct stx104_reg { + + /** + * struct stx104_iio - IIO device private data structure ++ * @lock: synchronization lock to prevent I/O race conditions + * @chan_out_states: channels' output states + * @reg: I/O address offset for the device registers + */ + struct stx104_iio { ++ struct mutex lock; + unsigned int chan_out_states[STX104_NUM_OUT_CHAN]; + struct stx104_reg __iomem *reg; + }; +@@ -186,9 +189,12 @@ static int stx104_write_raw(struct iio_dev *indio_dev, + if ((unsigned int)val > 65535) + return -EINVAL; + ++ mutex_lock(&priv->lock); ++ + priv->chan_out_states[chan->channel] = val; + iowrite16(val, &priv->reg->dac[chan->channel]); + ++ mutex_unlock(&priv->lock); + return 0; + } + return -EINVAL; +@@ -360,6 +366,8 @@ static int stx104_probe(struct device *dev, unsigned int id) + indio_dev->name = dev_name(dev); + indio_dev->dev.parent = dev; + ++ mutex_init(&priv->lock); ++ + /* configure device for software trigger operation */ + iowrite8(0, &priv->reg->acr); + +-- +2.40.1 + diff --git a/queue-4.19/iio-addac-stx104-fix-race-condition-when-converting-.patch b/queue-4.19/iio-addac-stx104-fix-race-condition-when-converting-.patch new file mode 100644 index 00000000000..4d4daf3c787 --- /dev/null +++ b/queue-4.19/iio-addac-stx104-fix-race-condition-when-converting-.patch @@ -0,0 +1,50 @@ +From 469195b93471bed37b6ff7d9a81c6f8f9e427690 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Apr 2023 10:40:11 -0400 +Subject: iio: addac: stx104: Fix race condition when converting + analog-to-digital + +From: William Breathitt Gray + +[ Upstream commit 4f9b80aefb9e2f542a49d9ec087cf5919730e1dd ] + +The ADC conversion procedure requires several device I/O operations +performed in a particular sequence. If stx104_read_raw() is called +concurrently, the ADC conversion procedure could be clobbered. Prevent +such a race condition by utilizing a mutex. + +Fixes: 4075a283ae83 ("iio: stx104: Add IIO support for the ADC channels") +Signed-off-by: William Breathitt Gray +Link: https://lore.kernel.org/r/2ae5e40eed5006ca735e4c12181a9ff5ced65547.1680790580.git.william.gray@linaro.org +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/stx104.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c +index 78e87d1aaaefb..49aeb76212fd0 100644 +--- a/drivers/iio/adc/stx104.c ++++ b/drivers/iio/adc/stx104.c +@@ -125,6 +125,8 @@ static int stx104_read_raw(struct iio_dev *indio_dev, + return IIO_VAL_INT; + } + ++ mutex_lock(&priv->lock); ++ + /* select ADC channel */ + iowrite8(chan->channel | (chan->channel << 4), ®->achan); + +@@ -135,6 +137,8 @@ static int stx104_read_raw(struct iio_dev *indio_dev, + while (ioread8(®->cir_asr) & BIT(7)); + + *val = ioread16(®->ssr_ad); ++ ++ mutex_unlock(&priv->lock); + return IIO_VAL_INT; + case IIO_CHAN_INFO_OFFSET: + /* get ADC bipolar/unipolar configuration */ +-- +2.40.1 + diff --git a/queue-4.19/ima-allow-fix-uml-builds.patch b/queue-4.19/ima-allow-fix-uml-builds.patch new file mode 100644 index 00000000000..956f98b1aff --- /dev/null +++ b/queue-4.19/ima-allow-fix-uml-builds.patch @@ -0,0 +1,56 @@ +From df9d89da2061d1cdc29a5604ea48f38d81030fb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Feb 2023 19:27:03 -0800 +Subject: IMA: allow/fix UML builds + +From: Randy Dunlap + +[ Upstream commit 644f17412f5acf01a19af9d04a921937a2bc86c6 ] + +UML supports HAS_IOMEM since 0bbadafdc49d (um: allow disabling +NO_IOMEM). + +Current IMA build on UML fails on allmodconfig (with TCG_TPM=m): + +ld: security/integrity/ima/ima_queue.o: in function `ima_add_template_entry': +ima_queue.c:(.text+0x2d9): undefined reference to `tpm_pcr_extend' +ld: security/integrity/ima/ima_init.o: in function `ima_init': +ima_init.c:(.init.text+0x43f): undefined reference to `tpm_default_chip' +ld: security/integrity/ima/ima_crypto.o: in function `ima_calc_boot_aggregate_tfm': +ima_crypto.c:(.text+0x1044): undefined reference to `tpm_pcr_read' +ld: ima_crypto.c:(.text+0x10d8): undefined reference to `tpm_pcr_read' + +Modify the IMA Kconfig entry so that it selects TCG_TPM if HAS_IOMEM +is set, regardless of the UML Kconfig setting. +This updates TCG_TPM from =m to =y and fixes the linker errors. + +Fixes: f4a0391dfa91 ("ima: fix Kconfig dependencies") +Cc: Stable # v5.14+ +Signed-off-by: Randy Dunlap +Cc: Fabio Estevam +Cc: Richard Weinberger +Cc: Anton Ivanov +Cc: Johannes Berg +Cc: linux-um@lists.infradead.org +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig +index 3ec45028a8c54..cd32fe3311afe 100644 +--- a/security/integrity/ima/Kconfig ++++ b/security/integrity/ima/Kconfig +@@ -7,7 +7,7 @@ config IMA + select CRYPTO_HMAC + select CRYPTO_SHA1 + select CRYPTO_HASH_INFO +- select TCG_TPM if HAS_IOMEM && !UML ++ select TCG_TPM if HAS_IOMEM + select TCG_TIS if TCG_TPM && X86 + select TCG_CRB if TCG_TPM && ACPI + select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES +-- +2.40.1 + diff --git a/queue-4.19/irqchip-mips-gic-get-rid-of-the-reliance-on-irq_cpu_.patch b/queue-4.19/irqchip-mips-gic-get-rid-of-the-reliance-on-irq_cpu_.patch new file mode 100644 index 00000000000..f11baebd795 --- /dev/null +++ b/queue-4.19/irqchip-mips-gic-get-rid-of-the-reliance-on-irq_cpu_.patch @@ -0,0 +1,102 @@ +From 783736785dd7f5d88565e7c874dccbd1b284ec30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Oct 2021 18:04:13 +0100 +Subject: irqchip/mips-gic: Get rid of the reliance on irq_cpu_online() + +From: Marc Zyngier + +[ Upstream commit dd098a0e031928cf88c89f7577d31821e1f0e6de ] + +The MIPS GIC driver uses irq_cpu_online() to go and program the +per-CPU interrupts. However, this method iterates over all IRQs +in the system, despite only 3 per-CPU interrupts being of interest. + +Let's be terribly bold and do the iteration ourselves. To ensure +mutual exclusion, hold the gic_lock spinlock that is otherwise +taken while dealing with these interrupts. + +Signed-off-by: Marc Zyngier +Reviewed-by: Serge Semin +Reviewed-by: Florian Fainelli +Tested-by: Serge Semin +Link: https://lore.kernel.org/r/20211021170414.3341522-3-maz@kernel.org +Stable-dep-of: 3d6a0e4197c0 ("irqchip/mips-gic: Use raw spinlock for gic_lock") +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-mips-gic.c | 37 ++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 11 deletions(-) + +diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c +index f3985469c2211..6b8c3dd0f76f4 100644 +--- a/drivers/irqchip/irq-mips-gic.c ++++ b/drivers/irqchip/irq-mips-gic.c +@@ -380,24 +380,35 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d) + spin_unlock_irqrestore(&gic_lock, flags); + } + +-static void gic_all_vpes_irq_cpu_online(struct irq_data *d) ++static void gic_all_vpes_irq_cpu_online(void) + { +- struct gic_all_vpes_chip_data *cd; +- unsigned int intr; ++ static const unsigned int local_intrs[] = { ++ GIC_LOCAL_INT_TIMER, ++ GIC_LOCAL_INT_PERFCTR, ++ GIC_LOCAL_INT_FDC, ++ }; ++ unsigned long flags; ++ int i; + +- intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); +- cd = irq_data_get_irq_chip_data(d); ++ spin_lock_irqsave(&gic_lock, flags); + +- write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map); +- if (cd->mask) +- write_gic_vl_smask(BIT(intr)); ++ for (i = 0; i < ARRAY_SIZE(local_intrs); i++) { ++ unsigned int intr = local_intrs[i]; ++ struct gic_all_vpes_chip_data *cd; ++ ++ cd = &gic_all_vpes_chip_data[intr]; ++ write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map); ++ if (cd->mask) ++ write_gic_vl_smask(BIT(intr)); ++ } ++ ++ spin_unlock_irqrestore(&gic_lock, flags); + } + + static struct irq_chip gic_all_vpes_local_irq_controller = { + .name = "MIPS GIC Local", + .irq_mask = gic_mask_local_irq_all_vpes, + .irq_unmask = gic_unmask_local_irq_all_vpes, +- .irq_cpu_online = gic_all_vpes_irq_cpu_online, + }; + + static void __gic_irq_dispatch(void) +@@ -476,6 +487,10 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, + intr = GIC_HWIRQ_TO_LOCAL(hwirq); + map = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin; + ++ /* ++ * If adding support for more per-cpu interrupts, keep the the ++ * array in gic_all_vpes_irq_cpu_online() in sync. ++ */ + switch (intr) { + case GIC_LOCAL_INT_TIMER: + /* CONFIG_MIPS_CMP workaround (see __gic_init) */ +@@ -662,8 +677,8 @@ static int gic_cpu_startup(unsigned int cpu) + /* Clear all local IRQ masks (ie. disable all local interrupts) */ + write_gic_vl_rmask(~0); + +- /* Invoke irq_cpu_online callbacks to enable desired interrupts */ +- irq_cpu_online(); ++ /* Enable desired interrupts */ ++ gic_all_vpes_irq_cpu_online(); + + return 0; + } +-- +2.40.1 + diff --git a/queue-4.19/irqchip-mips-gic-use-raw-spinlock-for-gic_lock.patch b/queue-4.19/irqchip-mips-gic-use-raw-spinlock-for-gic_lock.patch new file mode 100644 index 00000000000..29f4905994d --- /dev/null +++ b/queue-4.19/irqchip-mips-gic-use-raw-spinlock-for-gic_lock.patch @@ -0,0 +1,163 @@ +From feb545b8c1569af0c5b6425f3ce4399cb2fc5865 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Apr 2023 11:31:56 +0100 +Subject: irqchip/mips-gic: Use raw spinlock for gic_lock + +From: Jiaxun Yang + +[ Upstream commit 3d6a0e4197c04599d75d85a608c8bb16a630a38c ] + +Since we may hold gic_lock in hardirq context, use raw spinlock +makes more sense given that it is for low-level interrupt handling +routine and the critical section is small. + +Fixes BUG: + +[ 0.426106] ============================= +[ 0.426257] [ BUG: Invalid wait context ] +[ 0.426422] 6.3.0-rc7-next-20230421-dirty #54 Not tainted +[ 0.426638] ----------------------------- +[ 0.426766] swapper/0/1 is trying to lock: +[ 0.426954] ffffffff8104e7b8 (gic_lock){....}-{3:3}, at: gic_set_type+0x30/08 + +Fixes: 95150ae8b330 ("irqchip: mips-gic: Implement irq_set_type callback") +Cc: stable@vger.kernel.org +Signed-off-by: Jiaxun Yang +Reviewed-by: Serge Semin +Tested-by: Serge Semin +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20230424103156.66753-3-jiaxun.yang@flygoat.com +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-mips-gic.c | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c +index 6b8c3dd0f76f4..dd9b111038b06 100644 +--- a/drivers/irqchip/irq-mips-gic.c ++++ b/drivers/irqchip/irq-mips-gic.c +@@ -48,7 +48,7 @@ void __iomem *mips_gic_base; + + DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks); + +-static DEFINE_SPINLOCK(gic_lock); ++static DEFINE_RAW_SPINLOCK(gic_lock); + static struct irq_domain *gic_irq_domain; + static struct irq_domain *gic_ipi_domain; + static int gic_shared_intrs; +@@ -207,7 +207,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) + + irq = GIC_HWIRQ_TO_SHARED(d->hwirq); + +- spin_lock_irqsave(&gic_lock, flags); ++ raw_spin_lock_irqsave(&gic_lock, flags); + switch (type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_FALLING: + pol = GIC_POL_FALLING_EDGE; +@@ -247,7 +247,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) + else + irq_set_chip_handler_name_locked(d, &gic_level_irq_controller, + handle_level_irq, NULL); +- spin_unlock_irqrestore(&gic_lock, flags); ++ raw_spin_unlock_irqrestore(&gic_lock, flags); + + return 0; + } +@@ -265,7 +265,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, + return -EINVAL; + + /* Assumption : cpumask refers to a single CPU */ +- spin_lock_irqsave(&gic_lock, flags); ++ raw_spin_lock_irqsave(&gic_lock, flags); + + /* Re-route this IRQ */ + write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu))); +@@ -276,7 +276,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, + set_bit(irq, per_cpu_ptr(pcpu_masks, cpu)); + + irq_data_update_effective_affinity(d, cpumask_of(cpu)); +- spin_unlock_irqrestore(&gic_lock, flags); ++ raw_spin_unlock_irqrestore(&gic_lock, flags); + + return IRQ_SET_MASK_OK; + } +@@ -354,12 +354,12 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d) + cd = irq_data_get_irq_chip_data(d); + cd->mask = false; + +- spin_lock_irqsave(&gic_lock, flags); ++ raw_spin_lock_irqsave(&gic_lock, flags); + for_each_online_cpu(cpu) { + write_gic_vl_other(mips_cm_vp_id(cpu)); + write_gic_vo_rmask(BIT(intr)); + } +- spin_unlock_irqrestore(&gic_lock, flags); ++ raw_spin_unlock_irqrestore(&gic_lock, flags); + } + + static void gic_unmask_local_irq_all_vpes(struct irq_data *d) +@@ -372,12 +372,12 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d) + cd = irq_data_get_irq_chip_data(d); + cd->mask = true; + +- spin_lock_irqsave(&gic_lock, flags); ++ raw_spin_lock_irqsave(&gic_lock, flags); + for_each_online_cpu(cpu) { + write_gic_vl_other(mips_cm_vp_id(cpu)); + write_gic_vo_smask(BIT(intr)); + } +- spin_unlock_irqrestore(&gic_lock, flags); ++ raw_spin_unlock_irqrestore(&gic_lock, flags); + } + + static void gic_all_vpes_irq_cpu_online(void) +@@ -390,7 +390,7 @@ static void gic_all_vpes_irq_cpu_online(void) + unsigned long flags; + int i; + +- spin_lock_irqsave(&gic_lock, flags); ++ raw_spin_lock_irqsave(&gic_lock, flags); + + for (i = 0; i < ARRAY_SIZE(local_intrs); i++) { + unsigned int intr = local_intrs[i]; +@@ -402,7 +402,7 @@ static void gic_all_vpes_irq_cpu_online(void) + write_gic_vl_smask(BIT(intr)); + } + +- spin_unlock_irqrestore(&gic_lock, flags); ++ raw_spin_unlock_irqrestore(&gic_lock, flags); + } + + static struct irq_chip gic_all_vpes_local_irq_controller = { +@@ -432,11 +432,11 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, + + data = irq_get_irq_data(virq); + +- spin_lock_irqsave(&gic_lock, flags); ++ raw_spin_lock_irqsave(&gic_lock, flags); + write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); + write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); + irq_data_update_effective_affinity(data, cpumask_of(cpu)); +- spin_unlock_irqrestore(&gic_lock, flags); ++ raw_spin_unlock_irqrestore(&gic_lock, flags); + + return 0; + } +@@ -529,12 +529,12 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, + if (!gic_local_irq_is_routable(intr)) + return -EPERM; + +- spin_lock_irqsave(&gic_lock, flags); ++ raw_spin_lock_irqsave(&gic_lock, flags); + for_each_online_cpu(cpu) { + write_gic_vl_other(mips_cm_vp_id(cpu)); + write_gic_vo_map(mips_gic_vx_map_reg(intr), map); + } +- spin_unlock_irqrestore(&gic_lock, flags); ++ raw_spin_unlock_irqrestore(&gic_lock, flags); + + return 0; + } +-- +2.40.1 + diff --git a/queue-4.19/media-platform-mediatek-vpu-fix-null-ptr-dereference.patch b/queue-4.19/media-platform-mediatek-vpu-fix-null-ptr-dereference.patch new file mode 100644 index 00000000000..011aea63d0c --- /dev/null +++ b/queue-4.19/media-platform-mediatek-vpu-fix-null-ptr-dereference.patch @@ -0,0 +1,51 @@ +From b88cd36a1e94e801cef71aaf2c8d602d95fc9552 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 May 2023 13:11:47 +0100 +Subject: media: platform: mediatek: vpu: fix NULL ptr dereference + +From: Hans Verkuil + +[ Upstream commit 3df55cd773e8603b623425cc97b05e542854ad27 ] + +If pdev is NULL, then it is still dereferenced. + +This fixes this smatch warning: + +drivers/media/platform/mediatek/vpu/mtk_vpu.c:570 vpu_load_firmware() warn: address of NULL pointer 'pdev' + +Signed-off-by: Hans Verkuil +Cc: Yunfei Dong +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/platform/mtk-vpu/mtk_vpu.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c +index 9b57fb2857285..46ec1f2699aa7 100644 +--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c ++++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c +@@ -537,16 +537,18 @@ static int load_requested_vpu(struct mtk_vpu *vpu, + int vpu_load_firmware(struct platform_device *pdev) + { + struct mtk_vpu *vpu; +- struct device *dev = &pdev->dev; ++ struct device *dev; + struct vpu_run *run; + const struct firmware *vpu_fw = NULL; + int ret; + + if (!pdev) { +- dev_err(dev, "VPU platform device is invalid\n"); ++ pr_err("VPU platform device is invalid\n"); + return -EINVAL; + } + ++ dev = &pdev->dev; ++ + vpu = platform_get_drvdata(pdev); + run = &vpu->run; + +-- +2.40.1 + diff --git a/queue-4.19/media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch b/queue-4.19/media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch new file mode 100644 index 00000000000..639999ff91c --- /dev/null +++ b/queue-4.19/media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch @@ -0,0 +1,69 @@ +From 40c201c4158807ce01d9c26148cbeb6722ca4cd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Apr 2023 16:17:40 +0800 +Subject: media: v4l2-mem2mem: add lock to protect parameter num_rdy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yunfei Dong + +[ Upstream commit 56b5c3e67b0f9af3f45cf393be048ee8d8a92694 ] + +Getting below error when using KCSAN to check the driver. Adding lock to +protect parameter num_rdy when getting the value with function: +v4l2_m2m_num_src_bufs_ready/v4l2_m2m_num_dst_bufs_ready. + +kworker/u16:3: [name:report&]BUG: KCSAN: data-race in v4l2_m2m_buf_queue +kworker/u16:3: [name:report&] + +kworker/u16:3: [name:report&]read-write to 0xffffff8105f35b94 of 1 bytes by task 20865 on cpu 7: +kworker/u16:3:  v4l2_m2m_buf_queue+0xd8/0x10c + +Signed-off-by: Pina Chen +Signed-off-by: Yunfei Dong +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + include/media/v4l2-mem2mem.h | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h +index d655720e16a15..62c67e9e190c0 100644 +--- a/include/media/v4l2-mem2mem.h ++++ b/include/media/v4l2-mem2mem.h +@@ -405,7 +405,14 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, + static inline + unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) + { +- return m2m_ctx->out_q_ctx.num_rdy; ++ unsigned int num_buf_rdy; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); ++ num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy; ++ spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); ++ ++ return num_buf_rdy; + } + + /** +@@ -417,7 +424,14 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) + static inline + unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) + { +- return m2m_ctx->cap_q_ctx.num_rdy; ++ unsigned int num_buf_rdy; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); ++ num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy; ++ spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); ++ ++ return num_buf_rdy; + } + + /** +-- +2.40.1 + diff --git a/queue-4.19/mips-dec-prom-address-warray-bounds-warning.patch b/queue-4.19/mips-dec-prom-address-warray-bounds-warning.patch new file mode 100644 index 00000000000..c46cd738937 --- /dev/null +++ b/queue-4.19/mips-dec-prom-address-warray-bounds-warning.patch @@ -0,0 +1,54 @@ +From ccf3d6017197970c2a17a3d970844de937b2e5cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Jun 2023 17:43:57 -0600 +Subject: MIPS: dec: prom: Address -Warray-bounds warning + +From: Gustavo A. R. Silva + +[ Upstream commit 7b191b9b55df2a844bd32d1d380f47a7df1c2896 ] + +Zero-length arrays are deprecated, and we are replacing them with flexible +array members instead. So, replace zero-length array with flexible-array +member in struct memmap. + +Address the following warning found after building (with GCC-13) mips64 +with decstation_64_defconfig: +In function 'rex_setup_memory_region', + inlined from 'prom_meminit' at arch/mips/dec/prom/memory.c:91:3: +arch/mips/dec/prom/memory.c:72:31: error: array subscript i is outside array bounds of 'unsigned char[0]' [-Werror=array-bounds=] + 72 | if (bm->bitmap[i] == 0xff) + | ~~~~~~~~~~^~~ +In file included from arch/mips/dec/prom/memory.c:16: +./arch/mips/include/asm/dec/prom.h: In function 'prom_meminit': +./arch/mips/include/asm/dec/prom.h:73:23: note: while referencing 'bitmap' + 73 | unsigned char bitmap[0]; + +This helps with the ongoing efforts to globally enable -Warray-bounds. + +This results in no differences in binary output. + +Link: https://github.com/KSPP/linux/issues/79 +Link: https://github.com/KSPP/linux/issues/323 +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/include/asm/dec/prom.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/mips/include/asm/dec/prom.h b/arch/mips/include/asm/dec/prom.h +index 09538ff5e9245..6f0405ba27d6d 100644 +--- a/arch/mips/include/asm/dec/prom.h ++++ b/arch/mips/include/asm/dec/prom.h +@@ -74,7 +74,7 @@ static inline bool prom_is_rex(u32 magic) + */ + typedef struct { + int pagesize; +- unsigned char bitmap[0]; ++ unsigned char bitmap[]; + } memmap; + + +-- +2.40.1 + diff --git a/queue-4.19/mmc-bcm2835-fix-deferred-probing.patch b/queue-4.19/mmc-bcm2835-fix-deferred-probing.patch new file mode 100644 index 00000000000..fe1406cfb3f --- /dev/null +++ b/queue-4.19/mmc-bcm2835-fix-deferred-probing.patch @@ -0,0 +1,44 @@ +From 42a2baffe81d41706371f8a900d0cc33baa787a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jun 2023 23:36:11 +0300 +Subject: mmc: bcm2835: fix deferred probing + +From: Sergey Shtylyov + +[ Upstream commit 71150ac12558bcd9d75e6e24cf7c872c2efd80f3 ] + +The driver overrides the error codes and IRQ0 returned by platform_get_irq() +to -EINVAL, so if it returns -EPROBE_DEFER, the driver will fail the probe +permanently instead of the deferred probing. Switch to propagating the error +codes upstream. Since commit ce753ad1549c ("platform: finally disallow IRQ0 +in platform_get_irq() and its ilk") IRQ0 is no longer returned by those APIs, +so we now can safely ignore it... + +Fixes: 660fc733bd74 ("mmc: bcm2835: Add new driver for the sdhost controller.") +Cc: stable@vger.kernel.org # v5.19+ +Signed-off-by: Sergey Shtylyov +Link: https://lore.kernel.org/r/20230617203622.6812-2-s.shtylyov@omp.ru +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/bcm2835.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c +index 11026474dda47..2b3ff4be7ae07 100644 +--- a/drivers/mmc/host/bcm2835.c ++++ b/drivers/mmc/host/bcm2835.c +@@ -1417,8 +1417,8 @@ static int bcm2835_probe(struct platform_device *pdev) + host->max_clk = clk_get_rate(clk); + + host->irq = platform_get_irq(pdev, 0); +- if (host->irq <= 0) { +- ret = -EINVAL; ++ if (host->irq < 0) { ++ ret = host->irq; + goto err; + } + +-- +2.40.1 + diff --git a/queue-4.19/mmc-meson-gx-remove-redundant-mmc_request_done-call-.patch b/queue-4.19/mmc-meson-gx-remove-redundant-mmc_request_done-call-.patch new file mode 100644 index 00000000000..f8535ff1043 --- /dev/null +++ b/queue-4.19/mmc-meson-gx-remove-redundant-mmc_request_done-call-.patch @@ -0,0 +1,107 @@ +From 3ec73050704ec7d9f7659012445d9210aa478ebc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jun 2023 10:27:12 +0200 +Subject: mmc: meson-gx: remove redundant mmc_request_done() call from irq + context +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin Hundebøll + +[ Upstream commit 3c40eb8145325b0f5b93b8a169146078cb2c49d6 ] + +The call to mmc_request_done() can schedule, so it must not be called +from irq context. Wake the irq thread if it needs to be called, and let +its existing logic do its work. + +Fixes the following kernel bug, which appears when running an RT patched +kernel on the AmLogic Meson AXG A113X SoC: +[ 11.111407] BUG: scheduling while atomic: kworker/0:1H/75/0x00010001 +[ 11.111438] Modules linked in: +[ 11.111451] CPU: 0 PID: 75 Comm: kworker/0:1H Not tainted 6.4.0-rc3-rt2-rtx-00081-gfd07f41ed6b4-dirty #1 +[ 11.111461] Hardware name: RTX AXG A113X Linux Platform Board (DT) +[ 11.111469] Workqueue: kblockd blk_mq_run_work_fn +[ 11.111492] Call trace: +[ 11.111497] dump_backtrace+0xac/0xe8 +[ 11.111510] show_stack+0x18/0x28 +[ 11.111518] dump_stack_lvl+0x48/0x60 +[ 11.111530] dump_stack+0x18/0x24 +[ 11.111537] __schedule_bug+0x4c/0x68 +[ 11.111548] __schedule+0x80/0x574 +[ 11.111558] schedule_loop+0x2c/0x50 +[ 11.111567] schedule_rtlock+0x14/0x20 +[ 11.111576] rtlock_slowlock_locked+0x468/0x730 +[ 11.111587] rt_spin_lock+0x40/0x64 +[ 11.111596] __wake_up_common_lock+0x5c/0xc4 +[ 11.111610] __wake_up+0x18/0x24 +[ 11.111620] mmc_blk_mq_req_done+0x68/0x138 +[ 11.111633] mmc_request_done+0x104/0x118 +[ 11.111644] meson_mmc_request_done+0x38/0x48 +[ 11.111654] meson_mmc_irq+0x128/0x1f0 +[ 11.111663] __handle_irq_event_percpu+0x70/0x114 +[ 11.111674] handle_irq_event_percpu+0x18/0x4c +[ 11.111683] handle_irq_event+0x80/0xb8 +[ 11.111691] handle_fasteoi_irq+0xa4/0x120 +[ 11.111704] handle_irq_desc+0x20/0x38 +[ 11.111712] generic_handle_domain_irq+0x1c/0x28 +[ 11.111721] gic_handle_irq+0x8c/0xa8 +[ 11.111735] call_on_irq_stack+0x24/0x4c +[ 11.111746] do_interrupt_handler+0x88/0x94 +[ 11.111757] el1_interrupt+0x34/0x64 +[ 11.111769] el1h_64_irq_handler+0x18/0x24 +[ 11.111779] el1h_64_irq+0x64/0x68 +[ 11.111786] __add_wait_queue+0x0/0x4c +[ 11.111795] mmc_blk_rw_wait+0x84/0x118 +[ 11.111804] mmc_blk_mq_issue_rq+0x5c4/0x654 +[ 11.111814] mmc_mq_queue_rq+0x194/0x214 +[ 11.111822] blk_mq_dispatch_rq_list+0x3ac/0x528 +[ 11.111834] __blk_mq_sched_dispatch_requests+0x340/0x4d0 +[ 11.111847] blk_mq_sched_dispatch_requests+0x38/0x70 +[ 11.111858] blk_mq_run_work_fn+0x3c/0x70 +[ 11.111865] process_one_work+0x17c/0x1f0 +[ 11.111876] worker_thread+0x1d4/0x26c +[ 11.111885] kthread+0xe4/0xf4 +[ 11.111894] ret_from_fork+0x10/0x20 + +Fixes: 51c5d8447bd7 ("MMC: meson: initial support for GX platforms") +Cc: stable@vger.kernel.org +Signed-off-by: Martin Hundebøll +Link: https://lore.kernel.org/r/20230607082713.517157-1-martin@geanix.com +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/meson-gx-mmc.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c +index 313aff92b97c9..a3e5be81b4660 100644 +--- a/drivers/mmc/host/meson-gx-mmc.c ++++ b/drivers/mmc/host/meson-gx-mmc.c +@@ -1067,11 +1067,8 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) + if (status & (IRQ_END_OF_CHAIN | IRQ_RESP_STATUS)) { + if (data && !cmd->error) + data->bytes_xfered = data->blksz * data->blocks; +- if (meson_mmc_bounce_buf_read(data) || +- meson_mmc_get_next_command(cmd)) +- ret = IRQ_WAKE_THREAD; +- else +- ret = IRQ_HANDLED; ++ ++ return IRQ_WAKE_THREAD; + } + + out: +@@ -1086,9 +1083,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) + writel(start, host->regs + SD_EMMC_START); + } + +- if (ret == IRQ_HANDLED) +- meson_mmc_request_done(host->mmc, cmd->mrq); +- + return ret; + } + +-- +2.40.1 + diff --git a/queue-4.19/mmc-meson-gx-remove-useless-lock.patch b/queue-4.19/mmc-meson-gx-remove-useless-lock.patch new file mode 100644 index 00000000000..7c4eb3724e3 --- /dev/null +++ b/queue-4.19/mmc-meson-gx-remove-useless-lock.patch @@ -0,0 +1,69 @@ +From 9f9d0e3644e24e7aab6eee0aaa5c2e79ce59c29d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Dec 2018 16:18:26 +0100 +Subject: mmc: meson-gx: remove useless lock + +From: Jerome Brunet + +[ Upstream commit 83076d2268c72d123f3d1eaf186a9f56ec1b943a ] + +The spinlock is only used within the irq handler so it does not +seem very useful. + +Signed-off-by: Jerome Brunet +Signed-off-by: Ulf Hansson +Stable-dep-of: 3c40eb814532 ("mmc: meson-gx: remove redundant mmc_request_done() call from irq context") +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/meson-gx-mmc.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c +index dba98c2886f26..313aff92b97c9 100644 +--- a/drivers/mmc/host/meson-gx-mmc.c ++++ b/drivers/mmc/host/meson-gx-mmc.c +@@ -26,7 +26,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -159,7 +158,6 @@ struct meson_host { + struct mmc_host *mmc; + struct mmc_command *cmd; + +- spinlock_t lock; + void __iomem *regs; + struct clk *core_clk; + struct clk *mmc_clk; +@@ -1042,8 +1040,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) + if (WARN_ON(!host) || WARN_ON(!host->cmd)) + return IRQ_NONE; + +- spin_lock(&host->lock); +- + cmd = host->cmd; + data = cmd->data; + cmd->error = 0; +@@ -1093,7 +1089,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) + if (ret == IRQ_HANDLED) + meson_mmc_request_done(host->mmc, cmd->mrq); + +- spin_unlock(&host->lock); + return ret; + } + +@@ -1246,8 +1241,6 @@ static int meson_mmc_probe(struct platform_device *pdev) + host->dev = &pdev->dev; + dev_set_drvdata(&pdev->dev, host); + +- spin_lock_init(&host->lock); +- + /* Get regulators and the supported OCR mask */ + host->vqmmc_enabled = false; + ret = mmc_regulator_get_supply(mmc); +-- +2.40.1 + diff --git a/queue-4.19/mmc-remove-dev_err-usage-after-platform_get_irq.patch b/queue-4.19/mmc-remove-dev_err-usage-after-platform_get_irq.patch new file mode 100644 index 00000000000..f271b31870c --- /dev/null +++ b/queue-4.19/mmc-remove-dev_err-usage-after-platform_get_irq.patch @@ -0,0 +1,204 @@ +From 5ef212e99d146c29d618d71f0704fe8737c9b128 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Jul 2019 11:15:29 -0700 +Subject: mmc: Remove dev_err() usage after platform_get_irq() + +From: Stephen Boyd + +[ Upstream commit 9a7957d0c9557f7780cdda970a2530d6351bd861 ] + +We don't need dev_err() messages when platform_get_irq() fails now that +platform_get_irq() prints an error message itself when something goes +wrong. Let's remove these prints with a simple semantic patch. + +// +@@ +expression ret; +struct platform_device *E; +@@ + +ret = +( +platform_get_irq(E, ...) +| +platform_get_irq_byname(E, ...) +); + +if ( \( ret < 0 \| ret <= 0 \) ) +{ +( +-if (ret != -EPROBE_DEFER) +-{ ... +-dev_err(...); +-... } +| +... +-dev_err(...); +) +... +} +// + +While we're here, remove braces on if statements that only have one +statement (manually). + +Cc: Ulf Hansson +Cc: linux-mmc@vger.kernel.org +Cc: Greg Kroah-Hartman +Signed-off-by: Stephen Boyd +Signed-off-by: Ulf Hansson +Stable-dep-of: 71150ac12558 ("mmc: bcm2835: fix deferred probing") +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/bcm2835.c | 1 - + drivers/mmc/host/jz4740_mmc.c | 1 - + drivers/mmc/host/meson-gx-mmc.c | 1 - + drivers/mmc/host/mxcmmc.c | 4 +--- + drivers/mmc/host/s3cmci.c | 1 - + drivers/mmc/host/sdhci-msm.c | 2 -- + drivers/mmc/host/sdhci-pltfm.c | 1 - + drivers/mmc/host/sdhci-s3c.c | 4 +--- + drivers/mmc/host/sdhci_f_sdh30.c | 4 +--- + drivers/mmc/host/uniphier-sd.c | 4 +--- + 10 files changed, 4 insertions(+), 19 deletions(-) + +diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c +index 5301302fb5310..11026474dda47 100644 +--- a/drivers/mmc/host/bcm2835.c ++++ b/drivers/mmc/host/bcm2835.c +@@ -1418,7 +1418,6 @@ static int bcm2835_probe(struct platform_device *pdev) + + host->irq = platform_get_irq(pdev, 0); + if (host->irq <= 0) { +- dev_err(dev, "get IRQ failed\n"); + ret = -EINVAL; + goto err; + } +diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c +index 864338e308e2b..b8fb518c6db01 100644 +--- a/drivers/mmc/host/jz4740_mmc.c ++++ b/drivers/mmc/host/jz4740_mmc.c +@@ -1060,7 +1060,6 @@ static int jz4740_mmc_probe(struct platform_device* pdev) + host->irq = platform_get_irq(pdev, 0); + if (host->irq < 0) { + ret = host->irq; +- dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); + goto err_free_host; + } + +diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c +index a3e5be81b4660..28f07d4100433 100644 +--- a/drivers/mmc/host/meson-gx-mmc.c ++++ b/drivers/mmc/host/meson-gx-mmc.c +@@ -1272,7 +1272,6 @@ static int meson_mmc_probe(struct platform_device *pdev) + + host->irq = platform_get_irq(pdev, 0); + if (host->irq <= 0) { +- dev_err(&pdev->dev, "failed to get interrupt resource.\n"); + ret = -EINVAL; + goto free_host; + } +diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c +index 6215feb976e32..a0e8ac9124455 100644 +--- a/drivers/mmc/host/mxcmmc.c ++++ b/drivers/mmc/host/mxcmmc.c +@@ -1017,10 +1017,8 @@ static int mxcmci_probe(struct platform_device *pdev) + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); +- if (irq < 0) { +- dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq); ++ if (irq < 0) + return irq; +- } + + mmc = mmc_alloc_host(sizeof(*host), &pdev->dev); + if (!mmc) +diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c +index f774936043129..ca2239ea6d96d 100644 +--- a/drivers/mmc/host/s3cmci.c ++++ b/drivers/mmc/host/s3cmci.c +@@ -1661,7 +1661,6 @@ static int s3cmci_probe(struct platform_device *pdev) + + host->irq = platform_get_irq(pdev, 0); + if (host->irq <= 0) { +- dev_err(&pdev->dev, "failed to get interrupt resource.\n"); + ret = -EINVAL; + goto probe_iounmap; + } +diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c +index 4970cd40813b2..feede31fab47d 100644 +--- a/drivers/mmc/host/sdhci-msm.c ++++ b/drivers/mmc/host/sdhci-msm.c +@@ -1914,8 +1914,6 @@ static int sdhci_msm_probe(struct platform_device *pdev) + /* Setup IRQ for handling power/voltage tasks with PMIC */ + msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq"); + if (msm_host->pwr_irq < 0) { +- dev_err(&pdev->dev, "Get pwr_irq failed (%d)\n", +- msm_host->pwr_irq); + ret = msm_host->pwr_irq; + goto clk_disable; + } +diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c +index 02bea6159d792..ac380c54bd170 100644 +--- a/drivers/mmc/host/sdhci-pltfm.c ++++ b/drivers/mmc/host/sdhci-pltfm.c +@@ -131,7 +131,6 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { +- dev_err(&pdev->dev, "failed to get IRQ number\n"); + ret = irq; + goto err; + } +diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c +index 9ef89d00970e1..936d88a33a675 100644 +--- a/drivers/mmc/host/sdhci-s3c.c ++++ b/drivers/mmc/host/sdhci-s3c.c +@@ -493,10 +493,8 @@ static int sdhci_s3c_probe(struct platform_device *pdev) + } + + irq = platform_get_irq(pdev, 0); +- if (irq < 0) { +- dev_err(dev, "no irq specified\n"); ++ if (irq < 0) + return irq; +- } + + host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c)); + if (IS_ERR(host)) { +diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c +index ca9e05440da1d..ee8160d6015ea 100644 +--- a/drivers/mmc/host/sdhci_f_sdh30.c ++++ b/drivers/mmc/host/sdhci_f_sdh30.c +@@ -122,10 +122,8 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev) + u32 reg = 0; + + irq = platform_get_irq(pdev, 0); +- if (irq < 0) { +- dev_err(dev, "%s: no irq specified\n", __func__); ++ if (irq < 0) + return irq; +- } + + host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv)); + if (IS_ERR(host)) +diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c +index 10e7b30c792a2..2e57bbb0883f8 100644 +--- a/drivers/mmc/host/uniphier-sd.c ++++ b/drivers/mmc/host/uniphier-sd.c +@@ -552,10 +552,8 @@ static int uniphier_sd_probe(struct platform_device *pdev) + int irq, ret; + + irq = platform_get_irq(pdev, 0); +- if (irq < 0) { +- dev_err(dev, "failed to get IRQ number"); ++ if (irq < 0) + return irq; +- } + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) +-- +2.40.1 + diff --git a/queue-4.19/mmc-sdhci-spear-fix-deferred-probing.patch b/queue-4.19/mmc-sdhci-spear-fix-deferred-probing.patch new file mode 100644 index 00000000000..04b19a8e4c1 --- /dev/null +++ b/queue-4.19/mmc-sdhci-spear-fix-deferred-probing.patch @@ -0,0 +1,46 @@ +From 4e092284044f9ae0209daad56be089aa2238cae4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jun 2023 23:36:19 +0300 +Subject: mmc: sdhci-spear: fix deferred probing + +From: Sergey Shtylyov + +[ Upstream commit 8d0caeedcd05a721f3cc2537b0ea212ec4027307 ] + +The driver overrides the error codes and IRQ0 returned by platform_get_irq() +to -EINVAL, so if it returns -EPROBE_DEFER, the driver will fail the probe +permanently instead of the deferred probing. Switch to propagating the error +codes upstream. Since commit ce753ad1549c ("platform: finally disallow IRQ0 +in platform_get_irq() and its ilk") IRQ0 is no longer returned by those APIs, +so we now can safely ignore it... + +Fixes: 682798a596a6 ("mmc: sdhci-spear: Handle return value of platform_get_irq") +Cc: stable@vger.kernel.org # v5.19+ +Signed-off-by: Sergey Shtylyov +Acked-by: Viresh Kumar +Acked-by: Adrian Hunter +Link: https://lore.kernel.org/r/20230617203622.6812-10-s.shtylyov@omp.ru +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/sdhci-spear.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c +index 9247d51f2eed2..705cc51861599 100644 +--- a/drivers/mmc/host/sdhci-spear.c ++++ b/drivers/mmc/host/sdhci-spear.c +@@ -82,8 +82,8 @@ static int sdhci_probe(struct platform_device *pdev) + host->hw_name = "sdhci"; + host->ops = &sdhci_pltfm_ops; + host->irq = platform_get_irq(pdev, 0); +- if (host->irq <= 0) { +- ret = -EINVAL; ++ if (host->irq < 0) { ++ ret = host->irq; + goto err_host; + } + host->quirks = SDHCI_QUIRK_BROKEN_ADMA; +-- +2.40.1 + diff --git a/queue-4.19/mmc-sunxi-fix-deferred-probing.patch b/queue-4.19/mmc-sunxi-fix-deferred-probing.patch new file mode 100644 index 00000000000..cea8de23edb --- /dev/null +++ b/queue-4.19/mmc-sunxi-fix-deferred-probing.patch @@ -0,0 +1,45 @@ +From 4c388718c453114fa90be46d83f35a513e3cc82a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 17 Jun 2023 23:36:21 +0300 +Subject: mmc: sunxi: fix deferred probing + +From: Sergey Shtylyov + +[ Upstream commit c2df53c5806cfd746dae08e07bc8c4ad247c3b70 ] + +The driver overrides the error codes and IRQ0 returned by platform_get_irq() +to -EINVAL, so if it returns -EPROBE_DEFER, the driver will fail the probe +permanently instead of the deferred probing. Switch to propagating the error +codes upstream. Since commit ce753ad1549c ("platform: finally disallow IRQ0 +in platform_get_irq() and its ilk") IRQ0 is no longer returned by those APIs, +so we now can safely ignore it... + +Fixes: 2408a08583d2 ("mmc: sunxi-mmc: Handle return value of platform_get_irq") +Cc: stable@vger.kernel.org # v5.19+ +Signed-off-by: Sergey Shtylyov +Reviewed-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20230617203622.6812-12-s.shtylyov@omp.ru +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/sunxi-mmc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c +index 757eb175611fb..bc3f8a1df10cc 100644 +--- a/drivers/mmc/host/sunxi-mmc.c ++++ b/drivers/mmc/host/sunxi-mmc.c +@@ -1308,8 +1308,8 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, + return ret; + + host->irq = platform_get_irq(pdev, 0); +- if (host->irq <= 0) { +- ret = -EINVAL; ++ if (host->irq < 0) { ++ ret = host->irq; + goto error_disable_mmc; + } + +-- +2.40.1 + diff --git a/queue-4.19/mmc-tmio-move-tmio_mmc_set_clock-to-platform-hook.patch b/queue-4.19/mmc-tmio-move-tmio_mmc_set_clock-to-platform-hook.patch new file mode 100644 index 00000000000..d811841ed4e --- /dev/null +++ b/queue-4.19/mmc-tmio-move-tmio_mmc_set_clock-to-platform-hook.patch @@ -0,0 +1,380 @@ +From f825417593b25af3423223450901b46ccc0bf1dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Aug 2018 13:44:16 +0900 +Subject: mmc: tmio: move tmio_mmc_set_clock() to platform hook + +From: Masahiro Yamada + +[ Upstream commit 0196c8db8363f7627df6f78615271ae0ba430500 ] + +tmio_mmc_set_clock() is full of quirks because different SoC vendors +extended this in different ways. + +The original IP defines the divisor range 1/2 ... 1/512. + + bit 7 is set: 1/512 + bit 6 is set: 1/256 + ... + bit 0 is set: 1/4 + all bits clear: 1/2 + +It is platform-dependent how to achieve the 1/1 clock. + +I guess the TMIO-MFD variant uses the clock selector outside of this IP, +as far as I see tmio_core_mmc_clk_div() in drivers/mfd/tmio_core.c + +I guess bit[7:0]=0xff is Renesas-specific extension. + +Socionext (and Panasonic) uses bit 10 (CLKSEL) for 1/1. Also, newer +versions of UniPhier SoC variants use bit 16 for 1/1024. + +host->clk_update() is only used by the Renesas variants, whereas +host->set_clk_div() is only used by the TMIO-MFD variants. + +To cope with this mess, promote tmio_mmc_set_clock() to a new +platform hook ->set_clock(), and melt the old two hooks into it. + +Signed-off-by: Masahiro Yamada +Reviewed-by: Wolfram Sang +Signed-off-by: Ulf Hansson +Stable-dep-of: 71150ac12558 ("mmc: bcm2835: fix deferred probing") +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/renesas_sdhi_core.c | 62 ++++++++++++++++++- + drivers/mmc/host/tmio_mmc.c | 48 +++++++++++++++ + drivers/mmc/host/tmio_mmc.h | 4 +- + drivers/mmc/host/tmio_mmc_core.c | 92 +++------------------------- + 4 files changed, 117 insertions(+), 89 deletions(-) + +diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c +index eabfcb5bbafff..a2c44cc8e2e7c 100644 +--- a/drivers/mmc/host/renesas_sdhi_core.c ++++ b/drivers/mmc/host/renesas_sdhi_core.c +@@ -155,6 +155,66 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host, + return ret == 0 ? best_freq : clk_get_rate(priv->clk); + } + ++static void renesas_sdhi_clk_start(struct tmio_mmc_host *host) ++{ ++ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | ++ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); ++ ++ /* HW engineers overrode docs: no sleep needed on R-Car2+ */ ++ if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) ++ usleep_range(10000, 11000); ++} ++ ++static void renesas_sdhi_clk_stop(struct tmio_mmc_host *host) ++{ ++ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & ++ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); ++ ++ /* HW engineers overrode docs: no sleep needed on R-Car2+ */ ++ if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) ++ usleep_range(10000, 11000); ++} ++ ++static void renesas_sdhi_set_clock(struct tmio_mmc_host *host, ++ unsigned int new_clock) ++{ ++ u32 clk = 0, clock; ++ ++ if (new_clock == 0) { ++ renesas_sdhi_clk_stop(host); ++ return; ++ } ++ /* ++ * Both HS400 and HS200/SD104 set 200MHz, but some devices need to ++ * set 400MHz to distinguish the CPG settings in HS400. ++ */ ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 && ++ host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400 && ++ new_clock == 200000000) ++ new_clock = 400000000; ++ ++ clock = renesas_sdhi_clk_update(host, new_clock) / 512; ++ ++ for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) ++ clock <<= 1; ++ ++ /* 1/1 clock is option */ ++ if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1)) { ++ if (!(host->mmc->ios.timing == MMC_TIMING_MMC_HS400)) ++ clk |= 0xff; ++ else ++ clk &= ~0xff; ++ } ++ ++ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & ++ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); ++ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); ++ if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) ++ usleep_range(10000, 11000); ++ ++ renesas_sdhi_clk_start(host); ++} ++ + static void renesas_sdhi_clk_disable(struct tmio_mmc_host *host) + { + struct renesas_sdhi *priv = host_to_priv(host); +@@ -621,8 +681,8 @@ int renesas_sdhi_probe(struct platform_device *pdev, + + host->write16_hook = renesas_sdhi_write16_hook; + host->clk_enable = renesas_sdhi_clk_enable; +- host->clk_update = renesas_sdhi_clk_update; + host->clk_disable = renesas_sdhi_clk_disable; ++ host->set_clock = renesas_sdhi_set_clock; + host->multi_io_quirk = renesas_sdhi_multi_io_quirk; + host->dma_ops = dma_ops; + +diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c +index 43a2ea5cff24f..b031a776c12e0 100644 +--- a/drivers/mmc/host/tmio_mmc.c ++++ b/drivers/mmc/host/tmio_mmc.c +@@ -13,6 +13,7 @@ + * published by the Free Software Foundation. + */ + ++#include + #include + #include + #include +@@ -23,6 +24,52 @@ + + #include "tmio_mmc.h" + ++static void tmio_mmc_clk_start(struct tmio_mmc_host *host) ++{ ++ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | ++ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); ++ ++ usleep_range(10000, 11000); ++ sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); ++ usleep_range(10000, 11000); ++} ++ ++static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) ++{ ++ sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); ++ usleep_range(10000, 11000); ++ ++ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & ++ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); ++ ++ usleep_range(10000, 11000); ++} ++ ++static void tmio_mmc_set_clock(struct tmio_mmc_host *host, ++ unsigned int new_clock) ++{ ++ u32 clk = 0, clock; ++ ++ if (new_clock == 0) { ++ tmio_mmc_clk_stop(host); ++ return; ++ } ++ ++ clock = host->mmc->f_min; ++ ++ for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) ++ clock <<= 1; ++ ++ host->pdata->set_clk_div(host->pdev, (clk >> 22) & 1); ++ ++ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & ++ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); ++ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); ++ usleep_range(10000, 11000); ++ ++ tmio_mmc_clk_start(host); ++} ++ + #ifdef CONFIG_PM_SLEEP + static int tmio_mmc_suspend(struct device *dev) + { +@@ -100,6 +147,7 @@ static int tmio_mmc_probe(struct platform_device *pdev) + + /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ + host->bus_shift = resource_size(res) >> 10; ++ host->set_clock = tmio_mmc_set_clock; + + host->mmc->f_max = pdata->hclk; + host->mmc->f_min = pdata->hclk / 512; +diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h +index 7c40a7e1fea1c..358aa258cb159 100644 +--- a/drivers/mmc/host/tmio_mmc.h ++++ b/drivers/mmc/host/tmio_mmc.h +@@ -133,7 +133,6 @@ struct tmio_mmc_host { + + /* Callbacks for clock / power control */ + void (*set_pwr)(struct platform_device *host, int state); +- void (*set_clk_div)(struct platform_device *host, int state); + + /* pio related stuff */ + struct scatterlist *sg_ptr; +@@ -170,10 +169,9 @@ struct tmio_mmc_host { + + /* Mandatory callback */ + int (*clk_enable)(struct tmio_mmc_host *host); ++ void (*set_clock)(struct tmio_mmc_host *host, unsigned int clock); + + /* Optional callbacks */ +- unsigned int (*clk_update)(struct tmio_mmc_host *host, +- unsigned int new_clock); + void (*clk_disable)(struct tmio_mmc_host *host); + int (*multi_io_quirk)(struct mmc_card *card, + unsigned int direction, int blk_size); +diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c +index 195f45a84282e..f819757e125e0 100644 +--- a/drivers/mmc/host/tmio_mmc_core.c ++++ b/drivers/mmc/host/tmio_mmc_core.c +@@ -161,83 +161,6 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) + } + } + +-static void tmio_mmc_clk_start(struct tmio_mmc_host *host) +-{ +- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | +- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); +- +- /* HW engineers overrode docs: no sleep needed on R-Car2+ */ +- if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) +- usleep_range(10000, 11000); +- +- if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { +- sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); +- usleep_range(10000, 11000); +- } +-} +- +-static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) +-{ +- if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { +- sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); +- usleep_range(10000, 11000); +- } +- +- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & +- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); +- +- /* HW engineers overrode docs: no sleep needed on R-Car2+ */ +- if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) +- usleep_range(10000, 11000); +-} +- +-static void tmio_mmc_set_clock(struct tmio_mmc_host *host, +- unsigned int new_clock) +-{ +- u32 clk = 0, clock; +- +- if (new_clock == 0) { +- tmio_mmc_clk_stop(host); +- return; +- } +- /* +- * Both HS400 and HS200/SD104 set 200MHz, but some devices need to +- * set 400MHz to distinguish the CPG settings in HS400. +- */ +- if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 && +- host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400 && +- new_clock == 200000000) +- new_clock = 400000000; +- +- if (host->clk_update) +- clock = host->clk_update(host, new_clock) / 512; +- else +- clock = host->mmc->f_min; +- +- for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) +- clock <<= 1; +- +- /* 1/1 clock is option */ +- if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && +- ((clk >> 22) & 0x1)) { +- if (!(host->mmc->ios.timing == MMC_TIMING_MMC_HS400)) +- clk |= 0xff; +- else +- clk &= ~0xff; +- } +- +- if (host->set_clk_div) +- host->set_clk_div(host->pdev, (clk >> 22) & 1); +- +- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & +- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); +- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); +- if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) +- usleep_range(10000, 11000); +- +- tmio_mmc_clk_start(host); +-} +- + static void tmio_mmc_reset(struct tmio_mmc_host *host) + { + /* FIXME - should we set stop clock reg here */ +@@ -1051,15 +974,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + switch (ios->power_mode) { + case MMC_POWER_OFF: + tmio_mmc_power_off(host); +- tmio_mmc_set_clock(host, 0); ++ host->set_clock(host, 0); + break; + case MMC_POWER_UP: + tmio_mmc_power_on(host, ios->vdd); +- tmio_mmc_set_clock(host, ios->clock); ++ host->set_clock(host, ios->clock); + tmio_mmc_set_bus_width(host, ios->bus_width); + break; + case MMC_POWER_ON: +- tmio_mmc_set_clock(host, ios->clock); ++ host->set_clock(host, ios->clock); + tmio_mmc_set_bus_width(host, ios->bus_width); + break; + } +@@ -1245,7 +1168,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) + int ret; + + /* +- * Check the sanity of mmc->f_min to prevent tmio_mmc_set_clock() from ++ * Check the sanity of mmc->f_min to prevent host->set_clock() from + * looping forever... + */ + if (mmc->f_min == 0) +@@ -1255,7 +1178,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) + _host->write16_hook = NULL; + + _host->set_pwr = pdata->set_pwr; +- _host->set_clk_div = pdata->set_clk_div; + + ret = tmio_mmc_init_ocr(_host); + if (ret < 0) +@@ -1318,7 +1240,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) + if (pdata->flags & TMIO_MMC_SDIO_IRQ) + _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; + +- tmio_mmc_set_clock(_host, 0); ++ _host->set_clock(_host, 0); + tmio_mmc_reset(_host); + + _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK); +@@ -1402,7 +1324,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev) + tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); + + if (host->clk_cache) +- tmio_mmc_set_clock(host, 0); ++ host->set_clock(host, 0); + + tmio_mmc_clk_disable(host); + +@@ -1423,7 +1345,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev) + tmio_mmc_clk_enable(host); + + if (host->clk_cache) +- tmio_mmc_set_clock(host, host->clk_cache); ++ host->set_clock(host, host->clk_cache); + + if (host->native_hotplug) + tmio_mmc_enable_mmc_irqs(host, +-- +2.40.1 + diff --git a/queue-4.19/mmc-tmio-replace-tmio_mmc_clk_stop-calls-with-tmio_m.patch b/queue-4.19/mmc-tmio-replace-tmio_mmc_clk_stop-calls-with-tmio_m.patch new file mode 100644 index 00000000000..8d7d63a2646 --- /dev/null +++ b/queue-4.19/mmc-tmio-replace-tmio_mmc_clk_stop-calls-with-tmio_m.patch @@ -0,0 +1,56 @@ +From 3c65f1223c864e1ea3c06f506b709cbe217ca63b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Aug 2018 13:44:15 +0900 +Subject: mmc: tmio: replace tmio_mmc_clk_stop() calls with + tmio_mmc_set_clock() + +From: Masahiro Yamada + +[ Upstream commit 74005a01f1ff66f98bf24163297932144d4da1ae ] + +tmio_mmc_clk_stop(host) is equivalent to tmio_mmc_set_clock(host, 0). +This replacement is needed for the next commit. + +Signed-off-by: Masahiro Yamada +Reviewed-by: Wolfram Sang +Signed-off-by: Ulf Hansson +Stable-dep-of: 71150ac12558 ("mmc: bcm2835: fix deferred probing") +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/tmio_mmc_core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c +index 33c9ca8f14a97..195f45a84282e 100644 +--- a/drivers/mmc/host/tmio_mmc_core.c ++++ b/drivers/mmc/host/tmio_mmc_core.c +@@ -1051,7 +1051,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + switch (ios->power_mode) { + case MMC_POWER_OFF: + tmio_mmc_power_off(host); +- tmio_mmc_clk_stop(host); ++ tmio_mmc_set_clock(host, 0); + break; + case MMC_POWER_UP: + tmio_mmc_power_on(host, ios->vdd); +@@ -1318,7 +1318,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) + if (pdata->flags & TMIO_MMC_SDIO_IRQ) + _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; + +- tmio_mmc_clk_stop(_host); ++ tmio_mmc_set_clock(_host, 0); + tmio_mmc_reset(_host); + + _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK); +@@ -1402,7 +1402,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev) + tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); + + if (host->clk_cache) +- tmio_mmc_clk_stop(host); ++ tmio_mmc_set_clock(host, 0); + + tmio_mmc_clk_disable(host); + +-- +2.40.1 + diff --git a/queue-4.19/mmc-uniphier-sd-add-uniphier-sd-emmc-controller-driv.patch b/queue-4.19/mmc-uniphier-sd-add-uniphier-sd-emmc-controller-driv.patch new file mode 100644 index 00000000000..3d9db650935 --- /dev/null +++ b/queue-4.19/mmc-uniphier-sd-add-uniphier-sd-emmc-controller-driv.patch @@ -0,0 +1,812 @@ +From c343ea70c67bf61df8e1046119d24453efc8475c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Aug 2018 13:44:18 +0900 +Subject: mmc: uniphier-sd: add UniPhier SD/eMMC controller driver + +From: Masahiro Yamada + +[ Upstream commit 3fd784f745dd1747863775a99ec749619ee6759c ] + +Here is another TMIO MMC variant found in Socionext UniPhier SoCs. + +As commit b6147490e6aa ("mmc: tmio: split core functionality, DMA and +MFD glue") said, these MMC controllers use the IP from Panasonic. + +However, the MMC controller in the TMIO (Toshiba Mobile IO) MFD chip +was the first upstreamed user of this IP. The common driver code +for this IP is now called 'tmio-mmc-core' in Linux although it is a +historical misnomer. + +Anyway, this driver select's MMC_TMIO_CORE to borrow the common code +from tmio-mmc-core.c + +Older UniPhier SoCs (LD4, Pro4, sLD8) support the external DMA engine +like renesas_sdhi_sys_dmac.c. The difference is UniPhier SoCs use a +single DMA channel whereas Renesas chips request separate channels for +RX and TX. + +Newer UniPhier SoCs (Pro5 and later) support the internal DMA engine +like renesas_sdhi_internal_dmac.c The register map is almost the same, +so I guess Renesas and Socionext use the same internal DMA hardware. +The main difference is, the register offsets are doubled for Renesas. + + Renesas Socionext + SDHI UniPhier + DM_CM_DTRAN_MODE 0x820 0x410 + DM_CM_DTRAN_CTRL 0x828 0x414 + DM_CM_RST 0x830 0x418 + DM_CM_INFO1 0x840 0x420 + DM_CM_INFO1_MASK 0x848 0x424 + DM_CM_INFO2 0x850 0x428 + DM_CM_INFO2_MASK 0x858 0x42c + DM_DTRAN_ADDR 0x880 0x440 + DM_DTRAN_ADDREX --- 0x444 + +This comes from the difference of host->bus_shift; 2 for Renesas SoCs, +and 1 for UniPhier SoCs. Also, the datasheet for UniPhier SoCs defines +DM_DTRAN_ADDR and DM_DTRAN_ADDREX as two separate registers. + +It could be possible to factor out the DMA common code by introducing +some hooks to cope with platform quirks, but this patch does not touch +that for now. + +Signed-off-by: Masahiro Yamada +Acked-by: Wolfram Sang +Signed-off-by: Ulf Hansson +Stable-dep-of: 71150ac12558 ("mmc: bcm2835: fix deferred probing") +Signed-off-by: Sasha Levin +--- + MAINTAINERS | 1 + + drivers/mmc/host/Kconfig | 10 + + drivers/mmc/host/Makefile | 1 + + drivers/mmc/host/uniphier-sd.c | 693 +++++++++++++++++++++++++++++++++ + 4 files changed, 705 insertions(+) + create mode 100644 drivers/mmc/host/uniphier-sd.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 59003315a9597..1827d859491b5 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2195,6 +2195,7 @@ F: drivers/clk/uniphier/ + F: drivers/gpio/gpio-uniphier.c + F: drivers/i2c/busses/i2c-uniphier* + F: drivers/irqchip/irq-uniphier-aidet.c ++F: drivers/mmc/host/uniphier-sd.c + F: drivers/pinctrl/uniphier/ + F: drivers/reset/reset-uniphier.c + F: drivers/tty/serial/8250/8250_uniphier.c +diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +index 2c11944686cf9..f45dd8223526f 100644 +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -630,6 +630,16 @@ config MMC_SDHI_INTERNAL_DMAC + using on-chip bus mastering. This supports the controllers + found in arm64 based SoCs. + ++config MMC_UNIPHIER ++ tristate "UniPhier SD/eMMC Host Controller support" ++ depends on ARCH_UNIPHIER || COMPILE_TEST ++ depends on OF ++ select MMC_TMIO_CORE ++ help ++ This provides support for the SD/eMMC controller found in ++ UniPhier SoCs. The eMMC variant of this controller is used ++ only for 32-bit SoCs. ++ + config MMC_CB710 + tristate "ENE CB710 MMC/SD Interface support" + depends on PCI +diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile +index ce8398e6f2c0e..a835d1a0546d2 100644 +--- a/drivers/mmc/host/Makefile ++++ b/drivers/mmc/host/Makefile +@@ -42,6 +42,7 @@ obj-$(CONFIG_MMC_TMIO_CORE) += tmio_mmc_core.o + obj-$(CONFIG_MMC_SDHI) += renesas_sdhi_core.o + obj-$(CONFIG_MMC_SDHI_SYS_DMAC) += renesas_sdhi_sys_dmac.o + obj-$(CONFIG_MMC_SDHI_INTERNAL_DMAC) += renesas_sdhi_internal_dmac.o ++obj-$(CONFIG_MMC_UNIPHIER) += uniphier-sd.o + obj-$(CONFIG_MMC_CB710) += cb710-mmc.o + obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o + octeon-mmc-objs := cavium.o cavium-octeon.o +diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c +new file mode 100644 +index 0000000000000..10e7b30c792a2 +--- /dev/null ++++ b/drivers/mmc/host/uniphier-sd.c +@@ -0,0 +1,693 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// ++// Copyright (C) 2017-2018 Socionext Inc. ++// Author: Masahiro Yamada ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "tmio_mmc.h" ++ ++#define UNIPHIER_SD_CLK_CTL_DIV1024 BIT(16) ++#define UNIPHIER_SD_CLK_CTL_DIV1 BIT(10) ++#define UNIPHIER_SD_CLKCTL_OFFEN BIT(9) // auto SDCLK stop ++#define UNIPHIER_SD_CC_EXT_MODE 0x1b0 ++#define UNIPHIER_SD_CC_EXT_MODE_DMA BIT(1) ++#define UNIPHIER_SD_HOST_MODE 0x1c8 ++#define UNIPHIER_SD_VOLT 0x1e4 ++#define UNIPHIER_SD_VOLT_MASK GENMASK(1, 0) ++#define UNIPHIER_SD_VOLT_OFF 0 ++#define UNIPHIER_SD_VOLT_330 1 // 3.3V signal ++#define UNIPHIER_SD_VOLT_180 2 // 1.8V signal ++#define UNIPHIER_SD_DMA_MODE 0x410 ++#define UNIPHIER_SD_DMA_MODE_DIR_MASK GENMASK(17, 16) ++#define UNIPHIER_SD_DMA_MODE_DIR_TO_DEV 0 ++#define UNIPHIER_SD_DMA_MODE_DIR_FROM_DEV 1 ++#define UNIPHIER_SD_DMA_MODE_WIDTH_MASK GENMASK(5, 4) ++#define UNIPHIER_SD_DMA_MODE_WIDTH_8 0 ++#define UNIPHIER_SD_DMA_MODE_WIDTH_16 1 ++#define UNIPHIER_SD_DMA_MODE_WIDTH_32 2 ++#define UNIPHIER_SD_DMA_MODE_WIDTH_64 3 ++#define UNIPHIER_SD_DMA_MODE_ADDR_INC BIT(0) // 1: inc, 0: fixed ++#define UNIPHIER_SD_DMA_CTL 0x414 ++#define UNIPHIER_SD_DMA_CTL_START BIT(0) // start DMA (auto cleared) ++#define UNIPHIER_SD_DMA_RST 0x418 ++#define UNIPHIER_SD_DMA_RST_CH1 BIT(9) ++#define UNIPHIER_SD_DMA_RST_CH0 BIT(8) ++#define UNIPHIER_SD_DMA_ADDR_L 0x440 ++#define UNIPHIER_SD_DMA_ADDR_H 0x444 ++ ++/* ++ * IP is extended to support various features: built-in DMA engine, ++ * 1/1024 divisor, etc. ++ */ ++#define UNIPHIER_SD_CAP_EXTENDED_IP BIT(0) ++/* RX channel of the built-in DMA controller is broken (Pro5) */ ++#define UNIPHIER_SD_CAP_BROKEN_DMA_RX BIT(1) ++ ++struct uniphier_sd_priv { ++ struct tmio_mmc_data tmio_data; ++ struct pinctrl *pinctrl; ++ struct pinctrl_state *pinstate_default; ++ struct pinctrl_state *pinstate_uhs; ++ struct clk *clk; ++ struct reset_control *rst; ++ struct reset_control *rst_br; ++ struct reset_control *rst_hw; ++ struct dma_chan *chan; ++ enum dma_data_direction dma_dir; ++ unsigned long clk_rate; ++ unsigned long caps; ++}; ++ ++static void *uniphier_sd_priv(struct tmio_mmc_host *host) ++{ ++ return container_of(host->pdata, struct uniphier_sd_priv, tmio_data); ++} ++ ++static void uniphier_sd_dma_endisable(struct tmio_mmc_host *host, int enable) ++{ ++ sd_ctrl_write16(host, CTL_DMA_ENABLE, DMA_ENABLE_DMASDRW); ++} ++ ++/* external DMA engine */ ++static void uniphier_sd_external_dma_issue(unsigned long arg) ++{ ++ struct tmio_mmc_host *host = (void *)arg; ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ ++ uniphier_sd_dma_endisable(host, 1); ++ dma_async_issue_pending(priv->chan); ++} ++ ++static void uniphier_sd_external_dma_callback(void *param, ++ const struct dmaengine_result *result) ++{ ++ struct tmio_mmc_host *host = param; ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ unsigned long flags; ++ ++ dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len, ++ priv->dma_dir); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (result->result == DMA_TRANS_NOERROR) { ++ /* ++ * When the external DMA engine is enabled, strangely enough, ++ * the DATAEND flag can be asserted even if the DMA engine has ++ * not been kicked yet. Enable the TMIO_STAT_DATAEND irq only ++ * after we make sure the DMA engine finishes the transfer, ++ * hence, in this callback. ++ */ ++ tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND); ++ } else { ++ host->data->error = -ETIMEDOUT; ++ tmio_mmc_do_data_irq(host); ++ } ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static void uniphier_sd_external_dma_start(struct tmio_mmc_host *host, ++ struct mmc_data *data) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ enum dma_transfer_direction dma_tx_dir; ++ struct dma_async_tx_descriptor *desc; ++ dma_cookie_t cookie; ++ int sg_len; ++ ++ if (!priv->chan) ++ goto force_pio; ++ ++ if (data->flags & MMC_DATA_READ) { ++ priv->dma_dir = DMA_FROM_DEVICE; ++ dma_tx_dir = DMA_DEV_TO_MEM; ++ } else { ++ priv->dma_dir = DMA_TO_DEVICE; ++ dma_tx_dir = DMA_MEM_TO_DEV; ++ } ++ ++ sg_len = dma_map_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len, ++ priv->dma_dir); ++ if (sg_len == 0) ++ goto force_pio; ++ ++ desc = dmaengine_prep_slave_sg(priv->chan, host->sg_ptr, sg_len, ++ dma_tx_dir, DMA_CTRL_ACK); ++ if (!desc) ++ goto unmap_sg; ++ ++ desc->callback_result = uniphier_sd_external_dma_callback; ++ desc->callback_param = host; ++ ++ cookie = dmaengine_submit(desc); ++ if (cookie < 0) ++ goto unmap_sg; ++ ++ return; ++ ++unmap_sg: ++ dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len, ++ priv->dma_dir); ++force_pio: ++ host->force_pio = true; ++ uniphier_sd_dma_endisable(host, 0); ++} ++ ++static void uniphier_sd_external_dma_enable(struct tmio_mmc_host *host, ++ bool enable) ++{ ++} ++ ++static void uniphier_sd_external_dma_request(struct tmio_mmc_host *host, ++ struct tmio_mmc_data *pdata) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ struct dma_chan *chan; ++ ++ chan = dma_request_chan(mmc_dev(host->mmc), "rx-tx"); ++ if (IS_ERR(chan)) { ++ dev_warn(mmc_dev(host->mmc), ++ "failed to request DMA channel. falling back to PIO\n"); ++ return; /* just use PIO even for -EPROBE_DEFER */ ++ } ++ ++ /* this driver uses a single channel for both RX an TX */ ++ priv->chan = chan; ++ host->chan_rx = chan; ++ host->chan_tx = chan; ++ ++ tasklet_init(&host->dma_issue, uniphier_sd_external_dma_issue, ++ (unsigned long)host); ++} ++ ++static void uniphier_sd_external_dma_release(struct tmio_mmc_host *host) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ ++ if (priv->chan) ++ dma_release_channel(priv->chan); ++} ++ ++static void uniphier_sd_external_dma_abort(struct tmio_mmc_host *host) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ ++ uniphier_sd_dma_endisable(host, 0); ++ ++ if (priv->chan) ++ dmaengine_terminate_sync(priv->chan); ++} ++ ++static void uniphier_sd_external_dma_dataend(struct tmio_mmc_host *host) ++{ ++ uniphier_sd_dma_endisable(host, 0); ++ ++ tmio_mmc_do_data_irq(host); ++} ++ ++static const struct tmio_mmc_dma_ops uniphier_sd_external_dma_ops = { ++ .start = uniphier_sd_external_dma_start, ++ .enable = uniphier_sd_external_dma_enable, ++ .request = uniphier_sd_external_dma_request, ++ .release = uniphier_sd_external_dma_release, ++ .abort = uniphier_sd_external_dma_abort, ++ .dataend = uniphier_sd_external_dma_dataend, ++}; ++ ++static void uniphier_sd_internal_dma_issue(unsigned long arg) ++{ ++ struct tmio_mmc_host *host = (void *)arg; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND); ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ uniphier_sd_dma_endisable(host, 1); ++ writel(UNIPHIER_SD_DMA_CTL_START, host->ctl + UNIPHIER_SD_DMA_CTL); ++} ++ ++static void uniphier_sd_internal_dma_start(struct tmio_mmc_host *host, ++ struct mmc_data *data) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ struct scatterlist *sg = host->sg_ptr; ++ dma_addr_t dma_addr; ++ unsigned int dma_mode_dir; ++ u32 dma_mode; ++ int sg_len; ++ ++ if (WARN_ON(host->sg_len != 1)) ++ goto force_pio; ++ ++ if (!IS_ALIGNED(sg->offset, 8)) ++ goto force_pio; ++ ++ if (data->flags & MMC_DATA_READ) { ++ priv->dma_dir = DMA_FROM_DEVICE; ++ dma_mode_dir = UNIPHIER_SD_DMA_MODE_DIR_FROM_DEV; ++ } else { ++ priv->dma_dir = DMA_TO_DEVICE; ++ dma_mode_dir = UNIPHIER_SD_DMA_MODE_DIR_TO_DEV; ++ } ++ ++ sg_len = dma_map_sg(mmc_dev(host->mmc), sg, 1, priv->dma_dir); ++ if (sg_len == 0) ++ goto force_pio; ++ ++ dma_mode = FIELD_PREP(UNIPHIER_SD_DMA_MODE_DIR_MASK, dma_mode_dir); ++ dma_mode |= FIELD_PREP(UNIPHIER_SD_DMA_MODE_WIDTH_MASK, ++ UNIPHIER_SD_DMA_MODE_WIDTH_64); ++ dma_mode |= UNIPHIER_SD_DMA_MODE_ADDR_INC; ++ ++ writel(dma_mode, host->ctl + UNIPHIER_SD_DMA_MODE); ++ ++ dma_addr = sg_dma_address(data->sg); ++ writel(lower_32_bits(dma_addr), host->ctl + UNIPHIER_SD_DMA_ADDR_L); ++ writel(upper_32_bits(dma_addr), host->ctl + UNIPHIER_SD_DMA_ADDR_H); ++ ++ return; ++force_pio: ++ host->force_pio = true; ++ uniphier_sd_dma_endisable(host, 0); ++} ++ ++static void uniphier_sd_internal_dma_enable(struct tmio_mmc_host *host, ++ bool enable) ++{ ++} ++ ++static void uniphier_sd_internal_dma_request(struct tmio_mmc_host *host, ++ struct tmio_mmc_data *pdata) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ ++ /* ++ * Due to a hardware bug, Pro5 cannot use DMA for RX. ++ * We can still use DMA for TX, but PIO for RX. ++ */ ++ if (!(priv->caps & UNIPHIER_SD_CAP_BROKEN_DMA_RX)) ++ host->chan_rx = (void *)0xdeadbeaf; ++ ++ host->chan_tx = (void *)0xdeadbeaf; ++ ++ tasklet_init(&host->dma_issue, uniphier_sd_internal_dma_issue, ++ (unsigned long)host); ++} ++ ++static void uniphier_sd_internal_dma_release(struct tmio_mmc_host *host) ++{ ++ /* Each value is set to zero to assume "disabling" each DMA */ ++ host->chan_rx = NULL; ++ host->chan_tx = NULL; ++} ++ ++static void uniphier_sd_internal_dma_abort(struct tmio_mmc_host *host) ++{ ++ u32 tmp; ++ ++ uniphier_sd_dma_endisable(host, 0); ++ ++ tmp = readl(host->ctl + UNIPHIER_SD_DMA_RST); ++ tmp &= ~(UNIPHIER_SD_DMA_RST_CH1 | UNIPHIER_SD_DMA_RST_CH0); ++ writel(tmp, host->ctl + UNIPHIER_SD_DMA_RST); ++ ++ tmp |= UNIPHIER_SD_DMA_RST_CH1 | UNIPHIER_SD_DMA_RST_CH0; ++ writel(tmp, host->ctl + UNIPHIER_SD_DMA_RST); ++} ++ ++static void uniphier_sd_internal_dma_dataend(struct tmio_mmc_host *host) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ ++ uniphier_sd_dma_endisable(host, 0); ++ dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, 1, priv->dma_dir); ++ ++ tmio_mmc_do_data_irq(host); ++} ++ ++static const struct tmio_mmc_dma_ops uniphier_sd_internal_dma_ops = { ++ .start = uniphier_sd_internal_dma_start, ++ .enable = uniphier_sd_internal_dma_enable, ++ .request = uniphier_sd_internal_dma_request, ++ .release = uniphier_sd_internal_dma_release, ++ .abort = uniphier_sd_internal_dma_abort, ++ .dataend = uniphier_sd_internal_dma_dataend, ++}; ++ ++static int uniphier_sd_clk_enable(struct tmio_mmc_host *host) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ struct mmc_host *mmc = host->mmc; ++ int ret; ++ ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) ++ return ret; ++ ++ ret = clk_set_rate(priv->clk, ULONG_MAX); ++ if (ret) ++ goto disable_clk; ++ ++ priv->clk_rate = clk_get_rate(priv->clk); ++ ++ /* If max-frequency property is set, use it. */ ++ if (!mmc->f_max) ++ mmc->f_max = priv->clk_rate; ++ ++ /* ++ * 1/512 is the finest divisor in the original IP. Newer versions ++ * also supports 1/1024 divisor. (UniPhier-specific extension) ++ */ ++ if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) ++ mmc->f_min = priv->clk_rate / 1024; ++ else ++ mmc->f_min = priv->clk_rate / 512; ++ ++ ret = reset_control_deassert(priv->rst); ++ if (ret) ++ goto disable_clk; ++ ++ ret = reset_control_deassert(priv->rst_br); ++ if (ret) ++ goto assert_rst; ++ ++ return 0; ++ ++assert_rst: ++ reset_control_assert(priv->rst); ++disable_clk: ++ clk_disable_unprepare(priv->clk); ++ ++ return ret; ++} ++ ++static void uniphier_sd_clk_disable(struct tmio_mmc_host *host) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ ++ reset_control_assert(priv->rst_br); ++ reset_control_assert(priv->rst); ++ clk_disable_unprepare(priv->clk); ++} ++ ++static void uniphier_sd_hw_reset(struct tmio_mmc_host *host) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ ++ reset_control_assert(priv->rst_hw); ++ /* For eMMC, minimum is 1us but give it 9us for good measure */ ++ udelay(9); ++ reset_control_deassert(priv->rst_hw); ++ /* For eMMC, minimum is 200us but give it 300us for good measure */ ++ usleep_range(300, 1000); ++} ++ ++static void uniphier_sd_set_clock(struct tmio_mmc_host *host, ++ unsigned int clock) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ unsigned long divisor; ++ u32 tmp; ++ ++ tmp = readl(host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); ++ ++ /* stop the clock before changing its rate to avoid a glitch signal */ ++ tmp &= ~CLK_CTL_SCLKEN; ++ writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); ++ ++ if (clock == 0) ++ return; ++ ++ tmp &= ~UNIPHIER_SD_CLK_CTL_DIV1024; ++ tmp &= ~UNIPHIER_SD_CLK_CTL_DIV1; ++ tmp &= ~CLK_CTL_DIV_MASK; ++ ++ divisor = priv->clk_rate / clock; ++ ++ /* ++ * In the original IP, bit[7:0] represents the divisor. ++ * bit7 set: 1/512, ... bit0 set:1/4, all bits clear: 1/2 ++ * ++ * The IP does not define a way to achieve 1/1. For UniPhier variants, ++ * bit10 is used for 1/1. Newer versions of UniPhier variants use ++ * bit16 for 1/1024. ++ */ ++ if (divisor <= 1) ++ tmp |= UNIPHIER_SD_CLK_CTL_DIV1; ++ else if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP && divisor > 512) ++ tmp |= UNIPHIER_SD_CLK_CTL_DIV1024; ++ else ++ tmp |= roundup_pow_of_two(divisor) >> 2; ++ ++ writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); ++ ++ tmp |= CLK_CTL_SCLKEN; ++ writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); ++} ++ ++static void uniphier_sd_host_init(struct tmio_mmc_host *host) ++{ ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ u32 val; ++ ++ /* ++ * Connected to 32bit AXI. ++ * This register holds settings for SoC-specific internal bus ++ * connection. What is worse, the register spec was changed, ++ * breaking the backward compatibility. Write an appropriate ++ * value depending on a flag associated with a compatible string. ++ */ ++ if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) ++ val = 0x00000101; ++ else ++ val = 0x00000000; ++ ++ writel(val, host->ctl + UNIPHIER_SD_HOST_MODE); ++ ++ val = 0; ++ /* ++ * If supported, the controller can automatically ++ * enable/disable the clock line to the card. ++ */ ++ if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) ++ val |= UNIPHIER_SD_CLKCTL_OFFEN; ++ ++ writel(val, host->ctl + (CTL_SD_CARD_CLK_CTL << 1)); ++} ++ ++static int uniphier_sd_start_signal_voltage_switch(struct mmc_host *mmc, ++ struct mmc_ios *ios) ++{ ++ struct tmio_mmc_host *host = mmc_priv(mmc); ++ struct uniphier_sd_priv *priv = uniphier_sd_priv(host); ++ struct pinctrl_state *pinstate; ++ u32 val, tmp; ++ ++ switch (ios->signal_voltage) { ++ case MMC_SIGNAL_VOLTAGE_330: ++ val = UNIPHIER_SD_VOLT_330; ++ pinstate = priv->pinstate_default; ++ break; ++ case MMC_SIGNAL_VOLTAGE_180: ++ val = UNIPHIER_SD_VOLT_180; ++ pinstate = priv->pinstate_uhs; ++ break; ++ default: ++ return -ENOTSUPP; ++ } ++ ++ tmp = readl(host->ctl + UNIPHIER_SD_VOLT); ++ tmp &= ~UNIPHIER_SD_VOLT_MASK; ++ tmp |= FIELD_PREP(UNIPHIER_SD_VOLT_MASK, val); ++ writel(tmp, host->ctl + UNIPHIER_SD_VOLT); ++ ++ pinctrl_select_state(priv->pinctrl, pinstate); ++ ++ return 0; ++} ++ ++static int uniphier_sd_uhs_init(struct tmio_mmc_host *host, ++ struct uniphier_sd_priv *priv) ++{ ++ priv->pinctrl = devm_pinctrl_get(mmc_dev(host->mmc)); ++ if (IS_ERR(priv->pinctrl)) ++ return PTR_ERR(priv->pinctrl); ++ ++ priv->pinstate_default = pinctrl_lookup_state(priv->pinctrl, ++ PINCTRL_STATE_DEFAULT); ++ if (IS_ERR(priv->pinstate_default)) ++ return PTR_ERR(priv->pinstate_default); ++ ++ priv->pinstate_uhs = pinctrl_lookup_state(priv->pinctrl, "uhs"); ++ if (IS_ERR(priv->pinstate_uhs)) ++ return PTR_ERR(priv->pinstate_uhs); ++ ++ host->ops.start_signal_voltage_switch = ++ uniphier_sd_start_signal_voltage_switch; ++ ++ return 0; ++} ++ ++static int uniphier_sd_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct uniphier_sd_priv *priv; ++ struct tmio_mmc_data *tmio_data; ++ struct tmio_mmc_host *host; ++ int irq, ret; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "failed to get IRQ number"); ++ return irq; ++ } ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->caps = (unsigned long)of_device_get_match_data(dev); ++ ++ priv->clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(priv->clk)) { ++ dev_err(dev, "failed to get clock\n"); ++ return PTR_ERR(priv->clk); ++ } ++ ++ priv->rst = devm_reset_control_get_shared(dev, "host"); ++ if (IS_ERR(priv->rst)) { ++ dev_err(dev, "failed to get host reset\n"); ++ return PTR_ERR(priv->rst); ++ } ++ ++ /* old version has one more reset */ ++ if (!(priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP)) { ++ priv->rst_br = devm_reset_control_get_shared(dev, "bridge"); ++ if (IS_ERR(priv->rst_br)) { ++ dev_err(dev, "failed to get bridge reset\n"); ++ return PTR_ERR(priv->rst_br); ++ } ++ } ++ ++ tmio_data = &priv->tmio_data; ++ tmio_data->flags |= TMIO_MMC_32BIT_DATA_PORT; ++ ++ host = tmio_mmc_host_alloc(pdev, tmio_data); ++ if (IS_ERR(host)) ++ return PTR_ERR(host); ++ ++ if (host->mmc->caps & MMC_CAP_HW_RESET) { ++ priv->rst_hw = devm_reset_control_get_exclusive(dev, "hw"); ++ if (IS_ERR(priv->rst_hw)) { ++ dev_err(dev, "failed to get hw reset\n"); ++ ret = PTR_ERR(priv->rst_hw); ++ goto free_host; ++ } ++ host->hw_reset = uniphier_sd_hw_reset; ++ } ++ ++ if (host->mmc->caps & MMC_CAP_UHS) { ++ ret = uniphier_sd_uhs_init(host, priv); ++ if (ret) { ++ dev_warn(dev, ++ "failed to setup UHS (error %d). Disabling UHS.", ++ ret); ++ host->mmc->caps &= ~MMC_CAP_UHS; ++ } ++ } ++ ++ ret = devm_request_irq(dev, irq, tmio_mmc_irq, IRQF_SHARED, ++ dev_name(dev), host); ++ if (ret) ++ goto free_host; ++ ++ if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) ++ host->dma_ops = &uniphier_sd_internal_dma_ops; ++ else ++ host->dma_ops = &uniphier_sd_external_dma_ops; ++ ++ host->bus_shift = 1; ++ host->clk_enable = uniphier_sd_clk_enable; ++ host->clk_disable = uniphier_sd_clk_disable; ++ host->set_clock = uniphier_sd_set_clock; ++ ++ ret = uniphier_sd_clk_enable(host); ++ if (ret) ++ goto free_host; ++ ++ uniphier_sd_host_init(host); ++ ++ tmio_data->ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34; ++ if (host->mmc->caps & MMC_CAP_UHS) ++ tmio_data->ocr_mask |= MMC_VDD_165_195; ++ ++ tmio_data->max_segs = 1; ++ tmio_data->max_blk_count = U16_MAX; ++ ++ ret = tmio_mmc_host_probe(host); ++ if (ret) ++ goto free_host; ++ ++ return 0; ++ ++free_host: ++ tmio_mmc_host_free(host); ++ ++ return ret; ++} ++ ++static int uniphier_sd_remove(struct platform_device *pdev) ++{ ++ struct tmio_mmc_host *host = platform_get_drvdata(pdev); ++ ++ tmio_mmc_host_remove(host); ++ uniphier_sd_clk_disable(host); ++ ++ return 0; ++} ++ ++static const struct of_device_id uniphier_sd_match[] = { ++ { ++ .compatible = "socionext,uniphier-sd-v2.91", ++ }, ++ { ++ .compatible = "socionext,uniphier-sd-v3.1", ++ .data = (void *)(UNIPHIER_SD_CAP_EXTENDED_IP | ++ UNIPHIER_SD_CAP_BROKEN_DMA_RX), ++ }, ++ { ++ .compatible = "socionext,uniphier-sd-v3.1.1", ++ .data = (void *)UNIPHIER_SD_CAP_EXTENDED_IP, ++ }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, uniphier_sd_match); ++ ++static struct platform_driver uniphier_sd_driver = { ++ .probe = uniphier_sd_probe, ++ .remove = uniphier_sd_remove, ++ .driver = { ++ .name = "uniphier-sd", ++ .of_match_table = uniphier_sd_match, ++ }, ++}; ++module_platform_driver(uniphier_sd_driver); ++ ++MODULE_AUTHOR("Masahiro Yamada "); ++MODULE_DESCRIPTION("UniPhier SD/eMMC host controller driver"); ++MODULE_LICENSE("GPL v2"); +-- +2.40.1 + diff --git a/queue-4.19/nfsd-remove-incorrect-check-in-nfsd4_validate_statei.patch b/queue-4.19/nfsd-remove-incorrect-check-in-nfsd4_validate_statei.patch new file mode 100644 index 00000000000..7254b90d186 --- /dev/null +++ b/queue-4.19/nfsd-remove-incorrect-check-in-nfsd4_validate_statei.patch @@ -0,0 +1,43 @@ +From 4f26a1c4edd1c5752c89413fb4a5f437874ab4b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Jul 2023 08:38:37 -0400 +Subject: nfsd: Remove incorrect check in nfsd4_validate_stateid + +From: Trond Myklebust + +[ Upstream commit f75546f58a70da5cfdcec5a45ffc377885ccbee8 ] + +If the client is calling TEST_STATEID, then it is because some event +occurred that requires it to check all the stateids for validity and +call FREE_STATEID on the ones that have been revoked. In this case, +either the stateid exists in the list of stateids associated with that +nfs4_client, in which case it should be tested, or it does not. There +are no additional conditions to be considered. + +Reported-by: "Frank Ch. Eigler" +Fixes: 7df302f75ee2 ("NFSD: TEST_STATEID should not return NFS4ERR_STALE_STATEID") +Cc: stable@vger.kernel.org # v5.7+ +Signed-off-by: Trond Myklebust +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4state.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 653ba2ffd4339..35aa2db611b65 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4998,8 +4998,6 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) + if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) || + CLOSE_STATEID(stateid)) + return status; +- if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid)) +- return status; + spin_lock(&cl->cl_lock); + s = find_stateid_locked(cl, stateid); + if (!s) +-- +2.40.1 + diff --git a/queue-4.19/nfsd4-kill-warnings-on-testing-stateids-with-mismatc.patch b/queue-4.19/nfsd4-kill-warnings-on-testing-stateids-with-mismatc.patch new file mode 100644 index 00000000000..f81611cc9e5 --- /dev/null +++ b/queue-4.19/nfsd4-kill-warnings-on-testing-stateids-with-mismatc.patch @@ -0,0 +1,45 @@ +From 33da0f6ccbb96fe6e52d9343ac6d62d8c8be5b47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2020 10:18:49 -0400 +Subject: nfsd4: kill warnings on testing stateids with mismatched clientids + +From: J. Bruce Fields + +[ Upstream commit 663e36f07666ff924012defa521f88875f6e5402 ] + +It's normal for a client to test a stateid from a previous instance, +e.g. after a network partition. + +Signed-off-by: J. Bruce Fields +Reviewed-by: Benjamin Coddington +Signed-off-by: Chuck Lever +Stable-dep-of: f75546f58a70 ("nfsd: Remove incorrect check in nfsd4_validate_stateid") +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4state.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 78191320f8e21..653ba2ffd4339 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -4998,15 +4998,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) + if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) || + CLOSE_STATEID(stateid)) + return status; +- /* Client debugging aid. */ +- if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid)) { +- char addr_str[INET6_ADDRSTRLEN]; +- rpc_ntop((struct sockaddr *)&cl->cl_addr, addr_str, +- sizeof(addr_str)); +- pr_warn_ratelimited("NFSD: client %s testing state ID " +- "with incorrect client ID\n", addr_str); ++ if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid)) + return status; +- } + spin_lock(&cl->cl_lock); + s = find_stateid_locked(cl, stateid); + if (!s) +-- +2.40.1 + diff --git a/queue-4.19/pci-endpoint-add-helper-to-get-first-unreserved-bar.patch b/queue-4.19/pci-endpoint-add-helper-to-get-first-unreserved-bar.patch new file mode 100644 index 00000000000..b19d95d1c9b --- /dev/null +++ b/queue-4.19/pci-endpoint-add-helper-to-get-first-unreserved-bar.patch @@ -0,0 +1,72 @@ +From a15ca4dc80ee6fe71010ff55e80ab03771f66da6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Jan 2019 16:45:05 +0530 +Subject: PCI: endpoint: Add helper to get first unreserved BAR + +From: Kishon Vijay Abraham I + +[ Upstream commit 1e9efe6c9976552e88c6e6feaca3a78b8cf5aaf6 ] + +Add a helper function pci_epc_get_first_free_bar() to get the first +unreserved BAR that can be used for endpoint function. + +Tested-by: Gustavo Pimentel +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Lorenzo Pieralisi +Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode") +Signed-off-by: Sasha Levin +--- + drivers/pci/endpoint/pci-epc-core.c | 23 +++++++++++++++++++++++ + include/linux/pci-epc.h | 2 ++ + 2 files changed, 25 insertions(+) + +diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c +index 5a099479d9aba..e4712a0f249cb 100644 +--- a/drivers/pci/endpoint/pci-epc-core.c ++++ b/drivers/pci/endpoint/pci-epc-core.c +@@ -83,6 +83,29 @@ struct pci_epc *pci_epc_get(const char *epc_name) + } + EXPORT_SYMBOL_GPL(pci_epc_get); + ++/** ++ * pci_epc_get_first_free_bar() - helper to get first unreserved BAR ++ * @epc_features: pci_epc_features structure that holds the reserved bar bitmap ++ * ++ * Invoke to get the first unreserved BAR that can be used for endpoint ++ * function. For any incorrect value in reserved_bar return '0'. ++ */ ++unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features ++ *epc_features) ++{ ++ int free_bar; ++ ++ if (!epc_features) ++ return 0; ++ ++ free_bar = ffz(epc_features->reserved_bar); ++ if (free_bar > 5) ++ return 0; ++ ++ return free_bar; ++} ++EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar); ++ + /** + * pci_epc_get_features() - get the features supported by EPC + * @epc: the features supported by *this* EPC device will be returned +diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h +index fcd5e50475468..dcaecf715b1cf 100644 +--- a/include/linux/pci-epc.h ++++ b/include/linux/pci-epc.h +@@ -183,6 +183,8 @@ int pci_epc_start(struct pci_epc *epc); + void pci_epc_stop(struct pci_epc *epc); + const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, + u8 func_no); ++unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features ++ *epc_features); + struct pci_epc *pci_epc_get(const char *epc_name); + void pci_epc_put(struct pci_epc *epc); + +-- +2.40.1 + diff --git a/queue-4.19/pci-endpoint-add-new-pci_epc_ops-to-get-epc-features.patch b/queue-4.19/pci-endpoint-add-new-pci_epc_ops-to-get-epc-features.patch new file mode 100644 index 00000000000..6600f638349 --- /dev/null +++ b/queue-4.19/pci-endpoint-add-new-pci_epc_ops-to-get-epc-features.patch @@ -0,0 +1,115 @@ +From 62bdf7eced9f5325b8c7c00018eec9cf7c85650f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Jan 2019 16:44:59 +0530 +Subject: PCI: endpoint: Add new pci_epc_ops to get EPC features + +From: Kishon Vijay Abraham I + +[ Upstream commit 41cb8d189c9d4964df52a6f497cab7b301ae831b ] + +Add a new pci_epc_ops ->get_features() to get the features +supported by the EPC. Since EPC can provide different features to +different functions, the ->get_features() ops takes _func_no_ as +an argument. + +Tested-by: Gustavo Pimentel +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Lorenzo Pieralisi +Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode") +Signed-off-by: Sasha Levin +--- + drivers/pci/endpoint/pci-epc-core.c | 30 +++++++++++++++++++++++++++++ + include/linux/pci-epc.h | 22 +++++++++++++++++++++ + 2 files changed, 52 insertions(+) + +diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c +index 094dcc3203b8d..5a099479d9aba 100644 +--- a/drivers/pci/endpoint/pci-epc-core.c ++++ b/drivers/pci/endpoint/pci-epc-core.c +@@ -83,6 +83,36 @@ struct pci_epc *pci_epc_get(const char *epc_name) + } + EXPORT_SYMBOL_GPL(pci_epc_get); + ++/** ++ * pci_epc_get_features() - get the features supported by EPC ++ * @epc: the features supported by *this* EPC device will be returned ++ * @func_no: the features supported by the EPC device specific to the ++ * endpoint function with func_no will be returned ++ * ++ * Invoke to get the features provided by the EPC which may be ++ * specific to an endpoint function. Returns pci_epc_features on success ++ * and NULL for any failures. ++ */ ++const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, ++ u8 func_no) ++{ ++ const struct pci_epc_features *epc_features; ++ unsigned long flags; ++ ++ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions) ++ return NULL; ++ ++ if (!epc->ops->get_features) ++ return NULL; ++ ++ spin_lock_irqsave(&epc->lock, flags); ++ epc_features = epc->ops->get_features(epc, func_no); ++ spin_unlock_irqrestore(&epc->lock, flags); ++ ++ return epc_features; ++} ++EXPORT_SYMBOL_GPL(pci_epc_get_features); ++ + /** + * pci_epc_stop() - stop the PCI link + * @epc: the link of the EPC device that has to be stopped +diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h +index 931fda3e5e0d9..fcd5e50475468 100644 +--- a/include/linux/pci-epc.h ++++ b/include/linux/pci-epc.h +@@ -59,6 +59,8 @@ struct pci_epc_ops { + enum pci_epc_irq_type type, u16 interrupt_num); + int (*start)(struct pci_epc *epc); + void (*stop)(struct pci_epc *epc); ++ const struct pci_epc_features* (*get_features)(struct pci_epc *epc, ++ u8 func_no); + struct module *owner; + }; + +@@ -103,6 +105,24 @@ struct pci_epc { + unsigned int features; + }; + ++/** ++ * struct pci_epc_features - features supported by a EPC device per function ++ * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up ++ * @msi_capable: indicate if the endpoint function has MSI capability ++ * @msix_capable: indicate if the endpoint function has MSI-X capability ++ * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver ++ * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs ++ * @bar_fixed_size: Array specifying the size supported by each BAR ++ */ ++struct pci_epc_features { ++ unsigned int linkup_notifier : 1; ++ unsigned int msi_capable : 1; ++ unsigned int msix_capable : 1; ++ u8 reserved_bar; ++ u8 bar_fixed_64bit; ++ u64 bar_fixed_size[BAR_5 + 1]; ++}; ++ + #define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0) + #define EPC_FEATURE_BAR_MASK (BIT(1) | BIT(2) | BIT(3)) + #define EPC_FEATURE_MSIX_AVAILABLE BIT(4) +@@ -161,6 +181,8 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, + enum pci_epc_irq_type type, u16 interrupt_num); + int pci_epc_start(struct pci_epc *epc); + void pci_epc_stop(struct pci_epc *epc); ++const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, ++ u8 func_no); + struct pci_epc *pci_epc_get(const char *epc_name); + void pci_epc_put(struct pci_epc *epc); + +-- +2.40.1 + diff --git a/queue-4.19/pci-endpoint-add-support-to-specify-alignment-for-bu.patch b/queue-4.19/pci-endpoint-add-support-to-specify-alignment-for-bu.patch new file mode 100644 index 00000000000..fc05aa98205 --- /dev/null +++ b/queue-4.19/pci-endpoint-add-support-to-specify-alignment-for-bu.patch @@ -0,0 +1,135 @@ +From f6001f24c202da6845f12873e32dc7f63c7e653f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2019 15:09:39 +0530 +Subject: PCI: endpoint: Add support to specify alignment for buffers allocated + to BARs + +From: Kishon Vijay Abraham I + +[ Upstream commit 2a9a801620efac92885fc9cd53594c0b9aba87a4 ] + +The address that is allocated using pci_epf_alloc_space() is +directly written to the target address of the Inbound Address +Translation unit (ie the HW component implementing inbound address +decoding) on endpoint controllers. + +Designware IP [1] has a configuration parameter (CX_ATU_MIN_REGION_SIZE +[2]) which has 64KB as default value and the lower 16 bits of the Base, +Limit and Target registers of the Inbound ATU are fixed to zero. If the +programmed memory address is not aligned to 64 KB boundary this causes +memory corruption. + +Modify pci_epf_alloc_space() API to take alignment size as argument in +order to allocate buffers to be mapped to BARs with an alignment that +suits the platform where they are used. + +Add an 'align' parameter to epc_features which can be used by platform +drivers to specify the BAR allocation alignment requirements and use +this while invoking pci_epf_alloc_space(). + +[1] "I/O and MEM Match Modes" section in DesignWare Cores PCI Express + Controller Databook version 4.90a +[2] http://www.ti.com/lit/ug/spruid7c/spruid7c.pdf + +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Lorenzo Pieralisi +Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode") +Signed-off-by: Sasha Levin +--- + drivers/pci/endpoint/functions/pci-epf-test.c | 5 +++-- + drivers/pci/endpoint/pci-epf-core.c | 10 ++++++++-- + include/linux/pci-epc.h | 2 ++ + include/linux/pci-epf.h | 3 ++- + 4 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c +index 5cde41afb9a73..a87e7ddcff9de 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-test.c ++++ b/drivers/pci/endpoint/functions/pci-epf-test.c +@@ -437,7 +437,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) + epc_features = epf_test->epc_features; + + base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), +- test_reg_bar); ++ test_reg_bar, epc_features->align); + if (!base) { + dev_err(dev, "Failed to allocated register space\n"); + return -ENOMEM; +@@ -451,7 +451,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) + if (!!(epc_features->reserved_bar & (1 << bar))) + continue; + +- base = pci_epf_alloc_space(epf, bar_size[bar], bar); ++ base = pci_epf_alloc_space(epf, bar_size[bar], bar, ++ epc_features->align); + if (!base) + dev_err(dev, "Failed to allocate space for BAR%d\n", + bar); +diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c +index 825fa24427a39..7f16b436e1cba 100644 +--- a/drivers/pci/endpoint/pci-epf-core.c ++++ b/drivers/pci/endpoint/pci-epf-core.c +@@ -109,10 +109,12 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space); + * pci_epf_alloc_space() - allocate memory for the PCI EPF register space + * @size: the size of the memory that has to be allocated + * @bar: the BAR number corresponding to the allocated register space ++ * @align: alignment size for the allocation region + * + * Invoke to allocate memory for the PCI EPF register space. + */ +-void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar) ++void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, ++ size_t align) + { + void *space; + struct device *dev = epf->epc->dev.parent; +@@ -120,7 +122,11 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar) + + if (size < 128) + size = 128; +- size = roundup_pow_of_two(size); ++ ++ if (align) ++ size = ALIGN(size, align); ++ else ++ size = roundup_pow_of_two(size); + + space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); + if (!space) { +diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h +index dcaecf715b1cf..a9b31ef810faf 100644 +--- a/include/linux/pci-epc.h ++++ b/include/linux/pci-epc.h +@@ -113,6 +113,7 @@ struct pci_epc { + * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver + * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs + * @bar_fixed_size: Array specifying the size supported by each BAR ++ * @align: alignment size required for BAR buffer allocation + */ + struct pci_epc_features { + unsigned int linkup_notifier : 1; +@@ -121,6 +122,7 @@ struct pci_epc_features { + u8 reserved_bar; + u8 bar_fixed_64bit; + u64 bar_fixed_size[BAR_5 + 1]; ++ size_t align; + }; + + #define EPC_FEATURE_NO_LINKUP_NOTIFIER BIT(0) +diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h +index ec02f58758c84..2d6f075566824 100644 +--- a/include/linux/pci-epf.h ++++ b/include/linux/pci-epf.h +@@ -149,7 +149,8 @@ void pci_epf_destroy(struct pci_epf *epf); + int __pci_epf_register_driver(struct pci_epf_driver *driver, + struct module *owner); + void pci_epf_unregister_driver(struct pci_epf_driver *driver); +-void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar); ++void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, ++ size_t align); + void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar); + int pci_epf_bind(struct pci_epf *epf); + void pci_epf_unbind(struct pci_epf *epf); +-- +2.40.1 + diff --git a/queue-4.19/pci-pci-epf-test-remove-setting-epf_bar-flags-in-fun.patch b/queue-4.19/pci-pci-epf-test-remove-setting-epf_bar-flags-in-fun.patch new file mode 100644 index 00000000000..1dfc9fce105 --- /dev/null +++ b/queue-4.19/pci-pci-epf-test-remove-setting-epf_bar-flags-in-fun.patch @@ -0,0 +1,39 @@ +From 6a539b42cb7a89d3c63bc8fee76603c1e4e45be8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Jan 2019 16:45:07 +0530 +Subject: PCI: pci-epf-test: Remove setting epf_bar flags in function driver + +From: Kishon Vijay Abraham I + +[ Upstream commit 0342e9a797db42a7d4d083d10b5d3f38b0cfc193 ] + +Now that pci_epf_alloc_space() sets BAR MEM TYPE flags as 64Bit or +32Bit based on size, remove setting it in function driver. + +Tested-by: Gustavo Pimentel +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Lorenzo Pieralisi +Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode") +Signed-off-by: Sasha Levin +--- + drivers/pci/endpoint/functions/pci-epf-test.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c +index 09a1e449cd1c6..878e5c97963cb 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-test.c ++++ b/drivers/pci/endpoint/functions/pci-epf-test.c +@@ -406,10 +406,6 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) + for (bar = BAR_0; bar <= BAR_5; bar++) { + epf_bar = &epf->bar[bar]; + +- epf_bar->flags |= upper_32_bits(epf_bar->size) ? +- PCI_BASE_ADDRESS_MEM_TYPE_64 : +- PCI_BASE_ADDRESS_MEM_TYPE_32; +- + ret = pci_epc_set_bar(epc, epf->func_no, epf_bar); + if (ret) { + pci_epf_free_space(epf, epf_test->reg[bar], bar); +-- +2.40.1 + diff --git a/queue-4.19/pci-pci-epf-test-use-pci_epc_get_features-to-get-epc.patch b/queue-4.19/pci-pci-epf-test-use-pci_epc_get_features-to-get-epc.patch new file mode 100644 index 00000000000..64a8b5d57c5 --- /dev/null +++ b/queue-4.19/pci-pci-epf-test-use-pci_epc_get_features-to-get-epc.patch @@ -0,0 +1,207 @@ +From bd1175a424859cb6bfcabe731f157c40b6674df4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Jan 2019 16:45:09 +0530 +Subject: PCI: pci-epf-test: Use pci_epc_get_features() to get EPC features + +From: Kishon Vijay Abraham I + +[ Upstream commit 2c04c5b8eef797dca99699cfb55ff42dd3c12c23 ] + +Use pci_epc_get_features() to get EPC features such as linkup +notifier support, MSI/MSIX capable, BAR configuration etc and use it +for configuring pci-epf-test. Since these features are now obtained +directly from EPC driver, remove pci_epf_test_data which was initially +added to have EPC features in endpoint function driver. + +Tested-by: Gustavo Pimentel +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Lorenzo Pieralisi +Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode") +Signed-off-by: Sasha Levin +--- + drivers/pci/endpoint/functions/pci-epf-test.c | 87 ++++++++++++------- + 1 file changed, 54 insertions(+), 33 deletions(-) + +diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c +index 878e5c97963cb..5cde41afb9a73 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-test.c ++++ b/drivers/pci/endpoint/functions/pci-epf-test.c +@@ -47,9 +47,8 @@ struct pci_epf_test { + void *reg[6]; + struct pci_epf *epf; + enum pci_barno test_reg_bar; +- bool linkup_notifier; +- bool msix_available; + struct delayed_work cmd_handler; ++ const struct pci_epc_features *epc_features; + }; + + struct pci_epf_test_reg { +@@ -71,11 +70,6 @@ static struct pci_epf_header test_header = { + .interrupt_pin = PCI_INTERRUPT_INTA, + }; + +-struct pci_epf_test_data { +- enum pci_barno test_reg_bar; +- bool linkup_notifier; +-}; +- + static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 }; + + static int pci_epf_test_copy(struct pci_epf_test *epf_test) +@@ -402,10 +396,16 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) + struct device *dev = &epf->dev; + struct pci_epf_test *epf_test = epf_get_drvdata(epf); + enum pci_barno test_reg_bar = epf_test->test_reg_bar; ++ const struct pci_epc_features *epc_features; ++ ++ epc_features = epf_test->epc_features; + + for (bar = BAR_0; bar <= BAR_5; bar++) { + epf_bar = &epf->bar[bar]; + ++ if (!!(epc_features->reserved_bar & (1 << bar))) ++ continue; ++ + ret = pci_epc_set_bar(epc, epf->func_no, epf_bar); + if (ret) { + pci_epf_free_space(epf, epf_test->reg[bar], bar); +@@ -432,6 +432,9 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) + void *base; + int bar; + enum pci_barno test_reg_bar = epf_test->test_reg_bar; ++ const struct pci_epc_features *epc_features; ++ ++ epc_features = epf_test->epc_features; + + base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), + test_reg_bar); +@@ -444,6 +447,10 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) + for (bar = BAR_0; bar <= BAR_5; bar++) { + if (bar == test_reg_bar) + continue; ++ ++ if (!!(epc_features->reserved_bar & (1 << bar))) ++ continue; ++ + base = pci_epf_alloc_space(epf, bar_size[bar], bar); + if (!base) + dev_err(dev, "Failed to allocate space for BAR%d\n", +@@ -454,25 +461,50 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) + return 0; + } + ++static void pci_epf_configure_bar(struct pci_epf *epf, ++ const struct pci_epc_features *epc_features) ++{ ++ struct pci_epf_bar *epf_bar; ++ bool bar_fixed_64bit; ++ int i; ++ ++ for (i = BAR_0; i <= BAR_5; i++) { ++ epf_bar = &epf->bar[i]; ++ bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i)); ++ if (bar_fixed_64bit) ++ epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; ++ if (epc_features->bar_fixed_size[i]) ++ bar_size[i] = epc_features->bar_fixed_size[i]; ++ } ++} ++ + static int pci_epf_test_bind(struct pci_epf *epf) + { + int ret; + struct pci_epf_test *epf_test = epf_get_drvdata(epf); + struct pci_epf_header *header = epf->header; ++ const struct pci_epc_features *epc_features; ++ enum pci_barno test_reg_bar = BAR_0; + struct pci_epc *epc = epf->epc; + struct device *dev = &epf->dev; ++ bool linkup_notifier = false; ++ bool msix_capable = false; ++ bool msi_capable = true; + + if (WARN_ON_ONCE(!epc)) + return -EINVAL; + +- if (epc->features & EPC_FEATURE_NO_LINKUP_NOTIFIER) +- epf_test->linkup_notifier = false; +- else +- epf_test->linkup_notifier = true; +- +- epf_test->msix_available = epc->features & EPC_FEATURE_MSIX_AVAILABLE; ++ epc_features = pci_epc_get_features(epc, epf->func_no); ++ if (epc_features) { ++ linkup_notifier = epc_features->linkup_notifier; ++ msix_capable = epc_features->msix_capable; ++ msi_capable = epc_features->msi_capable; ++ test_reg_bar = pci_epc_get_first_free_bar(epc_features); ++ pci_epf_configure_bar(epf, epc_features); ++ } + +- epf_test->test_reg_bar = EPC_FEATURE_GET_BAR(epc->features); ++ epf_test->test_reg_bar = test_reg_bar; ++ epf_test->epc_features = epc_features; + + ret = pci_epc_write_header(epc, epf->func_no, header); + if (ret) { +@@ -488,13 +520,15 @@ static int pci_epf_test_bind(struct pci_epf *epf) + if (ret) + return ret; + +- ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); +- if (ret) { +- dev_err(dev, "MSI configuration failed\n"); +- return ret; ++ if (msi_capable) { ++ ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); ++ if (ret) { ++ dev_err(dev, "MSI configuration failed\n"); ++ return ret; ++ } + } + +- if (epf_test->msix_available) { ++ if (msix_capable) { + ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts); + if (ret) { + dev_err(dev, "MSI-X configuration failed\n"); +@@ -502,7 +536,7 @@ static int pci_epf_test_bind(struct pci_epf *epf) + } + } + +- if (!epf_test->linkup_notifier) ++ if (!linkup_notifier) + queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); + + return 0; +@@ -519,17 +553,6 @@ static int pci_epf_test_probe(struct pci_epf *epf) + { + struct pci_epf_test *epf_test; + struct device *dev = &epf->dev; +- const struct pci_epf_device_id *match; +- struct pci_epf_test_data *data; +- enum pci_barno test_reg_bar = BAR_0; +- bool linkup_notifier = true; +- +- match = pci_epf_match_device(pci_epf_test_ids, epf); +- data = (struct pci_epf_test_data *)match->driver_data; +- if (data) { +- test_reg_bar = data->test_reg_bar; +- linkup_notifier = data->linkup_notifier; +- } + + epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL); + if (!epf_test) +@@ -537,8 +560,6 @@ static int pci_epf_test_probe(struct pci_epf *epf) + + epf->header = &test_header; + epf_test->epf = epf; +- epf_test->test_reg_bar = test_reg_bar; +- epf_test->linkup_notifier = linkup_notifier; + + INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler); + +-- +2.40.1 + diff --git a/queue-4.19/pci-rockchip-populate-get_features-dw_pcie_ep_ops.patch b/queue-4.19/pci-rockchip-populate-get_features-dw_pcie_ep_ops.patch new file mode 100644 index 00000000000..20d24ebbd03 --- /dev/null +++ b/queue-4.19/pci-rockchip-populate-get_features-dw_pcie_ep_ops.patch @@ -0,0 +1,55 @@ +From 1af927614d7669730343e869536001fa06c08749 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Jan 2019 16:45:03 +0530 +Subject: PCI: rockchip: Populate ->get_features() dw_pcie_ep_ops + +From: Kishon Vijay Abraham I + +[ Upstream commit 146221768c74bbd969f968b61ec95a0254a6b311 ] + +Populate ->get_features() dw_pcie_ep_ops to return the EPC features +supported by Rockchip PCIe endpoint controller. + +Tested-by: Gustavo Pimentel +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Lorenzo Pieralisi +Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode") +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/pcie-rockchip-ep.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c +index 4d3a589af1296..48b4a1c35523f 100644 +--- a/drivers/pci/controller/pcie-rockchip-ep.c ++++ b/drivers/pci/controller/pcie-rockchip-ep.c +@@ -483,6 +483,18 @@ static int rockchip_pcie_ep_start(struct pci_epc *epc) + return 0; + } + ++static const struct pci_epc_features rockchip_pcie_epc_features = { ++ .linkup_notifier = false, ++ .msi_capable = true, ++ .msix_capable = false, ++}; ++ ++static const struct pci_epc_features* ++rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) ++{ ++ return &rockchip_pcie_epc_features; ++} ++ + static const struct pci_epc_ops rockchip_pcie_epc_ops = { + .write_header = rockchip_pcie_ep_write_header, + .set_bar = rockchip_pcie_ep_set_bar, +@@ -493,6 +505,7 @@ static const struct pci_epc_ops rockchip_pcie_epc_ops = { + .get_msi = rockchip_pcie_ep_get_msi, + .raise_irq = rockchip_pcie_ep_raise_irq, + .start = rockchip_pcie_ep_start, ++ .get_features = rockchip_pcie_ep_get_features, + }; + + static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip, +-- +2.40.1 + diff --git a/queue-4.19/pci-rockchip-set-address-alignment-for-endpoint-mode.patch b/queue-4.19/pci-rockchip-set-address-alignment-for-endpoint-mode.patch new file mode 100644 index 00000000000..90428a040e8 --- /dev/null +++ b/queue-4.19/pci-rockchip-set-address-alignment-for-endpoint-mode.patch @@ -0,0 +1,40 @@ +From a9072cf071373984db4fbd54bbb2c45b96c06188 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Apr 2023 09:46:58 +0200 +Subject: PCI: rockchip: Set address alignment for endpoint mode + +From: Damien Le Moal + +[ Upstream commit 7e6689b34a815bd379dfdbe9855d36f395ef056c ] + +The address translation unit of the rockchip EP controller does not use +the lower 8 bits of a PCIe-space address to map local memory. Thus we +must set the align feature field to 256 to let the user know about this +constraint. + +Link: https://lore.kernel.org/r/20230418074700.1083505-12-rick.wertenbroek@gmail.com +Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") +Signed-off-by: Damien Le Moal +Signed-off-by: Rick Wertenbroek +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/pcie-rockchip-ep.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c +index 48b4a1c35523f..d6e9013936446 100644 +--- a/drivers/pci/controller/pcie-rockchip-ep.c ++++ b/drivers/pci/controller/pcie-rockchip-ep.c +@@ -487,6 +487,7 @@ static const struct pci_epc_features rockchip_pcie_epc_features = { + .linkup_notifier = false, + .msi_capable = true, + .msix_capable = false, ++ .align = 256, + }; + + static const struct pci_epc_features* +-- +2.40.1 + diff --git a/queue-4.19/pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch b/queue-4.19/pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch new file mode 100644 index 00000000000..d4b6e5df2de --- /dev/null +++ b/queue-4.19/pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch @@ -0,0 +1,66 @@ +From 12de82c1f0c4f743500b127c5b6ad680c851075c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 20:45:29 +0200 +Subject: pcmcia: rsrc_nonstatic: Fix memory leak in + nonstatic_release_resource_db() + +From: Armin Wolf + +[ Upstream commit c85fd9422fe0f5d667305efb27f56d09eab120b0 ] + +When nonstatic_release_resource_db() frees all resources associated +with an PCMCIA socket, it forgets to free socket_data too, causing +a memory leak observable with kmemleak: + +unreferenced object 0xc28d1000 (size 64): + comm "systemd-udevd", pid 297, jiffies 4294898478 (age 194.484s) + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 f0 85 0e c3 00 00 00 00 ................ + 00 00 00 00 0c 10 8d c2 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __kmem_cache_alloc_node+0x2d7/0x4a0 + [<7e51f0c8>] kmalloc_trace+0x31/0xa4 + [] nonstatic_init+0x24/0x1a4 [pcmcia_rsrc] + [] pcmcia_register_socket+0x200/0x35c [pcmcia_core] + [] yenta_probe+0x4d8/0xa70 [yenta_socket] + [] pci_device_probe+0x99/0x194 + [<84b7c690>] really_probe+0x181/0x45c + [<8060fe6e>] __driver_probe_device+0x75/0x1f4 + [] driver_probe_device+0x28/0xac + [<648b766f>] __driver_attach+0xeb/0x1e4 + [<6e9659eb>] bus_for_each_dev+0x61/0xb4 + [<25a669f3>] driver_attach+0x1e/0x28 + [] bus_add_driver+0x102/0x20c + [] driver_register+0x5b/0x120 + [<942cd8a4>] __pci_register_driver+0x44/0x4c + [] __UNIQUE_ID___addressable_cleanup_module188+0x1c/0xfffff000 [iTCO_vendor_support] + +Fix this by freeing socket_data too. + +Tested on a Acer Travelmate 4002WLMi by manually binding/unbinding +the yenta_cardbus driver (yenta_socket). + +Signed-off-by: Armin Wolf +Message-ID: <20230512184529.5094-1-W_Armin@gmx.de> +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/pcmcia/rsrc_nonstatic.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c +index 123420cac6b54..b75b12c2c702d 100644 +--- a/drivers/pcmcia/rsrc_nonstatic.c ++++ b/drivers/pcmcia/rsrc_nonstatic.c +@@ -1056,6 +1056,8 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s) + q = p->next; + kfree(p); + } ++ ++ kfree(data); + } + + +-- +2.40.1 + diff --git a/queue-4.19/powerpc-64s-radix-fix-soft-dirty-tracking.patch b/queue-4.19/powerpc-64s-radix-fix-soft-dirty-tracking.patch new file mode 100644 index 00000000000..cf7008da633 --- /dev/null +++ b/queue-4.19/powerpc-64s-radix-fix-soft-dirty-tracking.patch @@ -0,0 +1,61 @@ +From eea2d6aa84aed635e7dfd151fd07f33d4b7956c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 May 2023 21:42:24 +1000 +Subject: powerpc/64s/radix: Fix soft dirty tracking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michael Ellerman + +[ Upstream commit 66b2ca086210732954a7790d63d35542936fc664 ] + +It was reported that soft dirty tracking doesn't work when using the +Radix MMU. + +The tracking is supposed to work by clearing the soft dirty bit for a +mapping and then write protecting the PTE. If/when the page is written +to, a page fault occurs and the soft dirty bit is added back via +pte_mkdirty(). For example in wp_page_reuse(): + + entry = maybe_mkwrite(pte_mkdirty(entry), vma); + if (ptep_set_access_flags(vma, vmf->address, vmf->pte, entry, 1)) + update_mmu_cache(vma, vmf->address, vmf->pte); + +Unfortunately on radix _PAGE_SOFTDIRTY is being dropped by +radix__ptep_set_access_flags(), called from ptep_set_access_flags(), +meaning the soft dirty bit is not set even though the page has been +written to. + +Fix it by adding _PAGE_SOFTDIRTY to the set of bits that are able to be +changed in radix__ptep_set_access_flags(). + +Fixes: b0b5e9b13047 ("powerpc/mm/radix: Add radix pte #defines") +Cc: stable@vger.kernel.org # v4.7+ +Reported-by: Dan Horák +Link: https://lore.kernel.org/r/20230511095558.56663a50f86bdc4cd97700b7@danny.cz +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20230511114224.977423-1-mpe@ellerman.id.au +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/pgtable-radix.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c +index 9ee235fca4278..75cbedaac5d26 100644 +--- a/arch/powerpc/mm/pgtable-radix.c ++++ b/arch/powerpc/mm/pgtable-radix.c +@@ -1041,8 +1041,8 @@ void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, + pte_t entry, unsigned long address, int psize) + { + struct mm_struct *mm = vma->vm_mm; +- unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED | +- _PAGE_RW | _PAGE_EXEC); ++ unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_SOFT_DIRTY | ++ _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); + + unsigned long change = pte_val(entry) ^ pte_val(*ptep); + /* +-- +2.40.1 + diff --git a/queue-4.19/powerpc-mm-dump-block-address-translation-on-book3s-.patch b/queue-4.19/powerpc-mm-dump-block-address-translation-on-book3s-.patch new file mode 100644 index 00000000000..a3eb2b7f5a8 --- /dev/null +++ b/queue-4.19/powerpc-mm-dump-block-address-translation-on-book3s-.patch @@ -0,0 +1,256 @@ +From 6b94d52bb965d57cd503294d03df13b3be61f62c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Dec 2018 17:40:25 +0000 +Subject: powerpc/mm: dump block address translation on book3s/32 + +From: Christophe Leroy + +[ Upstream commit 7c91efce1608325634494b25ff6491320208e457 ] + +This patch adds a debugfs file to dump block address translation: + +~# cat /sys/kernel/debug/powerpc/block_address_translation +---[ Instruction Block Address Translations ]--- +0: - +1: - +2: 0xc0000000-0xcfffffff 0x00000000 Kernel EXEC coherent +3: 0xd0000000-0xdfffffff 0x10000000 Kernel EXEC coherent +4: - +5: - +6: - +7: - + +---[ Data Block Address Translations ]--- +0: - +1: - +2: 0xc0000000-0xcfffffff 0x00000000 Kernel RW coherent +3: 0xd0000000-0xdfffffff 0x10000000 Kernel RW coherent +4: - +5: - +6: - +7: - + +Signed-off-by: Christophe Leroy + +Signed-off-by: Michael Ellerman +Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking") +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/book3s/32/mmu-hash.h | 4 + + arch/powerpc/mm/Makefile | 2 +- + arch/powerpc/mm/dump_bats.c | 173 ++++++++++++++++++ + 3 files changed, 178 insertions(+), 1 deletion(-) + create mode 100644 arch/powerpc/mm/dump_bats.c + +diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h +index 5bd26c218b94f..958b18cecc96a 100644 +--- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h ++++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h +@@ -34,8 +34,12 @@ + #define BAT_PHYS_ADDR(x) ((u32)((x & 0x00000000fffe0000ULL) | \ + ((x & 0x0000000e00000000ULL) >> 24) | \ + ((x & 0x0000000100000000ULL) >> 30))) ++#define PHYS_BAT_ADDR(x) (((u64)(x) & 0x00000000fffe0000ULL) | \ ++ (((u64)(x) << 24) & 0x0000000e00000000ULL) | \ ++ (((u64)(x) << 30) & 0x0000000100000000ULL)) + #else + #define BAT_PHYS_ADDR(x) (x) ++#define PHYS_BAT_ADDR(x) ((x) & 0xfffe0000) + #endif + + struct ppc_bat { +diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile +index d2784730c0e5d..8ace67f002752 100644 +--- a/arch/powerpc/mm/Makefile ++++ b/arch/powerpc/mm/Makefile +@@ -47,7 +47,7 @@ ifdef CONFIG_PPC_PTDUMP + obj-$(CONFIG_4xx) += dump_linuxpagetables-generic.o + obj-$(CONFIG_PPC_8xx) += dump_linuxpagetables-8xx.o + obj-$(CONFIG_PPC_BOOK3E_MMU) += dump_linuxpagetables-generic.o +-obj-$(CONFIG_PPC_BOOK3S_32) += dump_linuxpagetables-generic.o dump_sr.o ++obj-$(CONFIG_PPC_BOOK3S_32) += dump_linuxpagetables-generic.o dump_bats.o dump_sr.o + obj-$(CONFIG_PPC_BOOK3S_64) += dump_linuxpagetables-book3s64.o + endif + obj-$(CONFIG_PPC_HTDUMP) += dump_hashpagetable.o +diff --git a/arch/powerpc/mm/dump_bats.c b/arch/powerpc/mm/dump_bats.c +new file mode 100644 +index 0000000000000..a0d23e96e841a +--- /dev/null ++++ b/arch/powerpc/mm/dump_bats.c +@@ -0,0 +1,173 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright 2018, Christophe Leroy CS S.I. ++ * ++ * ++ * This dumps the content of BATS ++ */ ++ ++#include ++#include ++#include ++ ++static char *pp_601(int k, int pp) ++{ ++ if (pp == 0) ++ return k ? "NA" : "RWX"; ++ if (pp == 1) ++ return k ? "ROX" : "RWX"; ++ if (pp == 2) ++ return k ? "RWX" : "RWX"; ++ return k ? "ROX" : "ROX"; ++} ++ ++static void bat_show_601(struct seq_file *m, int idx, u32 lower, u32 upper) ++{ ++ u32 blpi = upper & 0xfffe0000; ++ u32 k = (upper >> 2) & 3; ++ u32 pp = upper & 3; ++ phys_addr_t pbn = PHYS_BAT_ADDR(lower); ++ u32 bsm = lower & 0x3ff; ++ u32 size = (bsm + 1) << 17; ++ ++ seq_printf(m, "%d: ", idx); ++ if (!(lower & 0x40)) { ++ seq_puts(m, " -\n"); ++ return; ++ } ++ ++ seq_printf(m, "0x%08x-0x%08x ", blpi, blpi + size - 1); ++#ifdef CONFIG_PHYS_64BIT ++ seq_printf(m, "0x%016llx ", pbn); ++#else ++ seq_printf(m, "0x%08x ", pbn); ++#endif ++ ++ seq_printf(m, "Kernel %s User %s", pp_601(k & 2, pp), pp_601(k & 1, pp)); ++ ++ if (lower & _PAGE_WRITETHRU) ++ seq_puts(m, "write through "); ++ if (lower & _PAGE_NO_CACHE) ++ seq_puts(m, "no cache "); ++ if (lower & _PAGE_COHERENT) ++ seq_puts(m, "coherent "); ++ seq_puts(m, "\n"); ++} ++ ++#define BAT_SHOW_601(_m, _n, _l, _u) bat_show_601(_m, _n, mfspr(_l), mfspr(_u)) ++ ++static int bats_show_601(struct seq_file *m, void *v) ++{ ++ seq_puts(m, "---[ Block Address Translation ]---\n"); ++ ++ BAT_SHOW_601(m, 0, SPRN_IBAT0L, SPRN_IBAT0U); ++ BAT_SHOW_601(m, 1, SPRN_IBAT1L, SPRN_IBAT1U); ++ BAT_SHOW_601(m, 2, SPRN_IBAT2L, SPRN_IBAT2U); ++ BAT_SHOW_601(m, 3, SPRN_IBAT3L, SPRN_IBAT3U); ++ ++ return 0; ++} ++ ++static void bat_show_603(struct seq_file *m, int idx, u32 lower, u32 upper, bool is_d) ++{ ++ u32 bepi = upper & 0xfffe0000; ++ u32 bl = (upper >> 2) & 0x7ff; ++ u32 k = upper & 3; ++ phys_addr_t brpn = PHYS_BAT_ADDR(lower); ++ u32 size = (bl + 1) << 17; ++ ++ seq_printf(m, "%d: ", idx); ++ if (k == 0) { ++ seq_puts(m, " -\n"); ++ return; ++ } ++ ++ seq_printf(m, "0x%08x-0x%08x ", bepi, bepi + size - 1); ++#ifdef CONFIG_PHYS_64BIT ++ seq_printf(m, "0x%016llx ", brpn); ++#else ++ seq_printf(m, "0x%08x ", brpn); ++#endif ++ ++ if (k == 1) ++ seq_puts(m, "User "); ++ else if (k == 2) ++ seq_puts(m, "Kernel "); ++ else ++ seq_puts(m, "Kernel/User "); ++ ++ if (lower & BPP_RX) ++ seq_puts(m, is_d ? "RO " : "EXEC "); ++ else if (lower & BPP_RW) ++ seq_puts(m, is_d ? "RW " : "EXEC "); ++ else ++ seq_puts(m, is_d ? "NA " : "NX "); ++ ++ if (lower & _PAGE_WRITETHRU) ++ seq_puts(m, "write through "); ++ if (lower & _PAGE_NO_CACHE) ++ seq_puts(m, "no cache "); ++ if (lower & _PAGE_COHERENT) ++ seq_puts(m, "coherent "); ++ if (lower & _PAGE_GUARDED) ++ seq_puts(m, "guarded "); ++ seq_puts(m, "\n"); ++} ++ ++#define BAT_SHOW_603(_m, _n, _l, _u, _d) bat_show_603(_m, _n, mfspr(_l), mfspr(_u), _d) ++ ++static int bats_show_603(struct seq_file *m, void *v) ++{ ++ seq_puts(m, "---[ Instruction Block Address Translation ]---\n"); ++ ++ BAT_SHOW_603(m, 0, SPRN_IBAT0L, SPRN_IBAT0U, false); ++ BAT_SHOW_603(m, 1, SPRN_IBAT1L, SPRN_IBAT1U, false); ++ BAT_SHOW_603(m, 2, SPRN_IBAT2L, SPRN_IBAT2U, false); ++ BAT_SHOW_603(m, 3, SPRN_IBAT3L, SPRN_IBAT3U, false); ++ if (mmu_has_feature(MMU_FTR_USE_HIGH_BATS)) { ++ BAT_SHOW_603(m, 4, SPRN_IBAT4L, SPRN_IBAT4U, false); ++ BAT_SHOW_603(m, 5, SPRN_IBAT5L, SPRN_IBAT5U, false); ++ BAT_SHOW_603(m, 6, SPRN_IBAT6L, SPRN_IBAT6U, false); ++ BAT_SHOW_603(m, 7, SPRN_IBAT7L, SPRN_IBAT7U, false); ++ } ++ ++ seq_puts(m, "\n---[ Data Block Address Translation ]---\n"); ++ ++ BAT_SHOW_603(m, 0, SPRN_DBAT0L, SPRN_DBAT0U, true); ++ BAT_SHOW_603(m, 1, SPRN_DBAT1L, SPRN_DBAT1U, true); ++ BAT_SHOW_603(m, 2, SPRN_DBAT2L, SPRN_DBAT2U, true); ++ BAT_SHOW_603(m, 3, SPRN_DBAT3L, SPRN_DBAT3U, true); ++ if (mmu_has_feature(MMU_FTR_USE_HIGH_BATS)) { ++ BAT_SHOW_603(m, 4, SPRN_DBAT4L, SPRN_DBAT4U, true); ++ BAT_SHOW_603(m, 5, SPRN_DBAT5L, SPRN_DBAT5U, true); ++ BAT_SHOW_603(m, 6, SPRN_DBAT6L, SPRN_DBAT6U, true); ++ BAT_SHOW_603(m, 7, SPRN_DBAT7L, SPRN_DBAT7U, true); ++ } ++ ++ return 0; ++} ++ ++static int bats_open(struct inode *inode, struct file *file) ++{ ++ if (cpu_has_feature(CPU_FTR_601)) ++ return single_open(file, bats_show_601, NULL); ++ ++ return single_open(file, bats_show_603, NULL); ++} ++ ++static const struct file_operations bats_fops = { ++ .open = bats_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int __init bats_init(void) ++{ ++ struct dentry *debugfs_file; ++ ++ debugfs_file = debugfs_create_file("block_address_translation", 0400, ++ powerpc_debugfs_root, NULL, &bats_fops); ++ return debugfs_file ? 0 : -ENOMEM; ++} ++device_initcall(bats_init); +-- +2.40.1 + diff --git a/queue-4.19/powerpc-mm-dump-segment-registers-on-book3s-32.patch b/queue-4.19/powerpc-mm-dump-segment-registers-on-book3s-32.patch new file mode 100644 index 00000000000..b3cdcdf5188 --- /dev/null +++ b/queue-4.19/powerpc-mm-dump-segment-registers-on-book3s-32.patch @@ -0,0 +1,130 @@ +From 8f066e89dffcf8a6e82e3025ac11e42fdb988270 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Nov 2018 17:06:43 +0000 +Subject: powerpc/mm: dump segment registers on book3s/32 + +From: Christophe Leroy + +[ Upstream commit 0261a508c9fcb33e60f09cac42032f85c31e2039 ] + +This patch creates a debugfs file to see content of +segment registers + + # cat /sys/kernel/debug/segment_registers + ---[ User Segments ]--- + 0x00000000-0x0fffffff Kern key 1 User key 1 VSID 0xade2b0 + 0x10000000-0x1fffffff Kern key 1 User key 1 VSID 0xade3c1 + 0x20000000-0x2fffffff Kern key 1 User key 1 VSID 0xade4d2 + 0x30000000-0x3fffffff Kern key 1 User key 1 VSID 0xade5e3 + 0x40000000-0x4fffffff Kern key 1 User key 1 VSID 0xade6f4 + 0x50000000-0x5fffffff Kern key 1 User key 1 VSID 0xade805 + 0x60000000-0x6fffffff Kern key 1 User key 1 VSID 0xade916 + 0x70000000-0x7fffffff Kern key 1 User key 1 VSID 0xadea27 + 0x80000000-0x8fffffff Kern key 1 User key 1 VSID 0xadeb38 + 0x90000000-0x9fffffff Kern key 1 User key 1 VSID 0xadec49 + 0xa0000000-0xafffffff Kern key 1 User key 1 VSID 0xaded5a + 0xb0000000-0xbfffffff Kern key 1 User key 1 VSID 0xadee6b + + ---[ Kernel Segments ]--- + 0xc0000000-0xcfffffff Kern key 0 User key 1 VSID 0x000ccc + 0xd0000000-0xdfffffff Kern key 0 User key 1 VSID 0x000ddd + 0xe0000000-0xefffffff Kern key 0 User key 1 VSID 0x000eee + 0xf0000000-0xffffffff Kern key 0 User key 1 VSID 0x000fff + +Signed-off-by: Christophe Leroy +[mpe: Move it under /sys/kernel/debug/powerpc, make sr_init() __init] +Signed-off-by: Michael Ellerman +Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking") +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/Makefile | 2 +- + arch/powerpc/mm/dump_sr.c | 64 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 65 insertions(+), 1 deletion(-) + create mode 100644 arch/powerpc/mm/dump_sr.c + +diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile +index 3c844bdd16c4e..d2784730c0e5d 100644 +--- a/arch/powerpc/mm/Makefile ++++ b/arch/powerpc/mm/Makefile +@@ -47,7 +47,7 @@ ifdef CONFIG_PPC_PTDUMP + obj-$(CONFIG_4xx) += dump_linuxpagetables-generic.o + obj-$(CONFIG_PPC_8xx) += dump_linuxpagetables-8xx.o + obj-$(CONFIG_PPC_BOOK3E_MMU) += dump_linuxpagetables-generic.o +-obj-$(CONFIG_PPC_BOOK3S_32) += dump_linuxpagetables-generic.o ++obj-$(CONFIG_PPC_BOOK3S_32) += dump_linuxpagetables-generic.o dump_sr.o + obj-$(CONFIG_PPC_BOOK3S_64) += dump_linuxpagetables-book3s64.o + endif + obj-$(CONFIG_PPC_HTDUMP) += dump_hashpagetable.o +diff --git a/arch/powerpc/mm/dump_sr.c b/arch/powerpc/mm/dump_sr.c +new file mode 100644 +index 0000000000000..501843664bb91 +--- /dev/null ++++ b/arch/powerpc/mm/dump_sr.c +@@ -0,0 +1,64 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright 2018, Christophe Leroy CS S.I. ++ * ++ * ++ * This dumps the content of Segment Registers ++ */ ++ ++#include ++ ++static void seg_show(struct seq_file *m, int i) ++{ ++ u32 val = mfsrin(i << 28); ++ ++ seq_printf(m, "0x%01x0000000-0x%01xfffffff ", i, i); ++ seq_printf(m, "Kern key %d ", (val >> 30) & 1); ++ seq_printf(m, "User key %d ", (val >> 29) & 1); ++ if (val & 0x80000000) { ++ seq_printf(m, "Device 0x%03x", (val >> 20) & 0x1ff); ++ seq_printf(m, "-0x%05x", val & 0xfffff); ++ } else { ++ if (val & 0x10000000) ++ seq_puts(m, "No Exec "); ++ seq_printf(m, "VSID 0x%06x", val & 0xffffff); ++ } ++ seq_puts(m, "\n"); ++} ++ ++static int sr_show(struct seq_file *m, void *v) ++{ ++ int i; ++ ++ seq_puts(m, "---[ User Segments ]---\n"); ++ for (i = 0; i < TASK_SIZE >> 28; i++) ++ seg_show(m, i); ++ ++ seq_puts(m, "\n---[ Kernel Segments ]---\n"); ++ for (; i < 16; i++) ++ seg_show(m, i); ++ ++ return 0; ++} ++ ++static int sr_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, sr_show, NULL); ++} ++ ++static const struct file_operations sr_fops = { ++ .open = sr_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int __init sr_init(void) ++{ ++ struct dentry *debugfs_file; ++ ++ debugfs_file = debugfs_create_file("segment_registers", 0400, ++ powerpc_debugfs_root, NULL, &sr_fops); ++ return debugfs_file ? 0 : -ENOMEM; ++} ++device_initcall(sr_init); +-- +2.40.1 + diff --git a/queue-4.19/powerpc-mm-move-pgtable_t-into-platform-headers.patch b/queue-4.19/powerpc-mm-move-pgtable_t-into-platform-headers.patch new file mode 100644 index 00000000000..94eacf10afe --- /dev/null +++ b/queue-4.19/powerpc-mm-move-pgtable_t-into-platform-headers.patch @@ -0,0 +1,121 @@ +From 44ac7236ce509367e6726dbc9d07063b1ab71466 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Nov 2018 14:06:57 +0000 +Subject: powerpc/mm: Move pgtable_t into platform headers + +From: Christophe Leroy + +[ Upstream commit d09780f3a8d48fd49136d7bae8f0ae30de7f261a ] + +This patch move pgtable_t into platform headers. + +It gets rid of the CONFIG_PPC_64K_PAGES case for PPC64 +as nohash/64 doesn't support CONFIG_PPC_64K_PAGES. + +Reviewed-by: Aneesh Kumar K.V +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking") +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/book3s/32/mmu-hash.h | 2 ++ + arch/powerpc/include/asm/book3s/64/mmu.h | 9 +++++++++ + arch/powerpc/include/asm/nohash/32/mmu.h | 4 ++++ + arch/powerpc/include/asm/nohash/64/mmu.h | 4 ++++ + arch/powerpc/include/asm/page.h | 14 -------------- + 5 files changed, 19 insertions(+), 14 deletions(-) + +diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h +index e38c91388c40f..5bd26c218b94f 100644 +--- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h ++++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h +@@ -42,6 +42,8 @@ struct ppc_bat { + u32 batu; + u32 batl; + }; ++ ++typedef struct page *pgtable_t; + #endif /* !__ASSEMBLY__ */ + + /* +diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h +index 9c8c669a6b6a3..488e7ed07e967 100644 +--- a/arch/powerpc/include/asm/book3s/64/mmu.h ++++ b/arch/powerpc/include/asm/book3s/64/mmu.h +@@ -2,6 +2,8 @@ + #ifndef _ASM_POWERPC_BOOK3S_64_MMU_H_ + #define _ASM_POWERPC_BOOK3S_64_MMU_H_ + ++#include ++ + #ifndef __ASSEMBLY__ + /* + * Page size definition +@@ -24,6 +26,13 @@ struct mmu_psize_def { + }; + extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; + ++/* ++ * For BOOK3s 64 with 4k and 64K linux page size ++ * we want to use pointers, because the page table ++ * actually store pfn ++ */ ++typedef pte_t *pgtable_t; ++ + #endif /* __ASSEMBLY__ */ + + /* 64-bit classic hash table MMU */ +diff --git a/arch/powerpc/include/asm/nohash/32/mmu.h b/arch/powerpc/include/asm/nohash/32/mmu.h +index af0e8b54876ab..f61f933a4cd8c 100644 +--- a/arch/powerpc/include/asm/nohash/32/mmu.h ++++ b/arch/powerpc/include/asm/nohash/32/mmu.h +@@ -16,4 +16,8 @@ + #include + #endif + ++#ifndef __ASSEMBLY__ ++typedef struct page *pgtable_t; ++#endif ++ + #endif /* _ASM_POWERPC_NOHASH_32_MMU_H_ */ +diff --git a/arch/powerpc/include/asm/nohash/64/mmu.h b/arch/powerpc/include/asm/nohash/64/mmu.h +index 87871d027b75e..e6585480dfc40 100644 +--- a/arch/powerpc/include/asm/nohash/64/mmu.h ++++ b/arch/powerpc/include/asm/nohash/64/mmu.h +@@ -5,4 +5,8 @@ + /* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */ + #include + ++#ifndef __ASSEMBLY__ ++typedef struct page *pgtable_t; ++#endif ++ + #endif /* _ASM_POWERPC_NOHASH_64_MMU_H_ */ +diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h +index f6a1265face29..ddfb4b965e5bd 100644 +--- a/arch/powerpc/include/asm/page.h ++++ b/arch/powerpc/include/asm/page.h +@@ -335,20 +335,6 @@ void arch_free_page(struct page *page, int order); + #endif + + struct vm_area_struct; +-#ifdef CONFIG_PPC_BOOK3S_64 +-/* +- * For BOOK3s 64 with 4k and 64K linux page size +- * we want to use pointers, because the page table +- * actually store pfn +- */ +-typedef pte_t *pgtable_t; +-#else +-#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC64) +-typedef pte_t *pgtable_t; +-#else +-typedef struct page *pgtable_t; +-#endif +-#endif + + #include + #endif /* __ASSEMBLY__ */ +-- +2.40.1 + diff --git a/queue-4.19/powerpc-mm-move-platform-specific-mmu-xxx.h-in-platf.patch b/queue-4.19/powerpc-mm-move-platform-specific-mmu-xxx.h-in-platf.patch new file mode 100644 index 00000000000..c82ba5c7670 --- /dev/null +++ b/queue-4.19/powerpc-mm-move-platform-specific-mmu-xxx.h-in-platf.patch @@ -0,0 +1,166 @@ +From 4818ce449f5d5c01fec316ecd27178841dcaba62 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Nov 2018 14:06:55 +0000 +Subject: powerpc/mm: move platform specific mmu-xxx.h in platform directories + +From: Christophe Leroy + +[ Upstream commit 994da93d196866f914c9d64aafb86e95e3decbb2 ] + +The purpose of this patch is to move platform specific +mmu-xxx.h files in platform directories like pte-xxx.h files. + +In the meantime this patch creates common nohash and +nohash/32 + nohash/64 mmu.h files for future common parts. + +Reviewed-by: Aneesh Kumar K.V +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking") +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/mmu.h | 14 ++------------ + .../include/asm/{ => nohash/32}/mmu-40x.h | 0 + .../include/asm/{ => nohash/32}/mmu-44x.h | 0 + .../include/asm/{ => nohash/32}/mmu-8xx.h | 0 + arch/powerpc/include/asm/nohash/32/mmu.h | 19 +++++++++++++++++++ + arch/powerpc/include/asm/nohash/64/mmu.h | 8 ++++++++ + .../include/asm/{ => nohash}/mmu-book3e.h | 0 + arch/powerpc/include/asm/nohash/mmu.h | 11 +++++++++++ + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +- + arch/powerpc/kvm/e500.h | 2 +- + 10 files changed, 42 insertions(+), 14 deletions(-) + rename arch/powerpc/include/asm/{ => nohash/32}/mmu-40x.h (100%) + rename arch/powerpc/include/asm/{ => nohash/32}/mmu-44x.h (100%) + rename arch/powerpc/include/asm/{ => nohash/32}/mmu-8xx.h (100%) + create mode 100644 arch/powerpc/include/asm/nohash/32/mmu.h + create mode 100644 arch/powerpc/include/asm/nohash/64/mmu.h + rename arch/powerpc/include/asm/{ => nohash}/mmu-book3e.h (100%) + create mode 100644 arch/powerpc/include/asm/nohash/mmu.h + +diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h +index 13ea441ac5319..2b396de45e9ec 100644 +--- a/arch/powerpc/include/asm/mmu.h ++++ b/arch/powerpc/include/asm/mmu.h +@@ -326,18 +326,8 @@ static inline void mmu_early_init_devtree(void) { } + #if defined(CONFIG_PPC_STD_MMU_32) + /* 32-bit classic hash table MMU */ + #include +-#elif defined(CONFIG_40x) +-/* 40x-style software loaded TLB */ +-# include +-#elif defined(CONFIG_44x) +-/* 44x-style software loaded TLB */ +-# include +-#elif defined(CONFIG_PPC_BOOK3E_MMU) +-/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */ +-# include +-#elif defined (CONFIG_PPC_8xx) +-/* Motorola/Freescale 8xx software loaded TLB */ +-# include ++#elif defined(CONFIG_PPC_MMU_NOHASH) ++#include + #endif + + #endif /* __KERNEL__ */ +diff --git a/arch/powerpc/include/asm/mmu-40x.h b/arch/powerpc/include/asm/nohash/32/mmu-40x.h +similarity index 100% +rename from arch/powerpc/include/asm/mmu-40x.h +rename to arch/powerpc/include/asm/nohash/32/mmu-40x.h +diff --git a/arch/powerpc/include/asm/mmu-44x.h b/arch/powerpc/include/asm/nohash/32/mmu-44x.h +similarity index 100% +rename from arch/powerpc/include/asm/mmu-44x.h +rename to arch/powerpc/include/asm/nohash/32/mmu-44x.h +diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h +similarity index 100% +rename from arch/powerpc/include/asm/mmu-8xx.h +rename to arch/powerpc/include/asm/nohash/32/mmu-8xx.h +diff --git a/arch/powerpc/include/asm/nohash/32/mmu.h b/arch/powerpc/include/asm/nohash/32/mmu.h +new file mode 100644 +index 0000000000000..af0e8b54876ab +--- /dev/null ++++ b/arch/powerpc/include/asm/nohash/32/mmu.h +@@ -0,0 +1,19 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _ASM_POWERPC_NOHASH_32_MMU_H_ ++#define _ASM_POWERPC_NOHASH_32_MMU_H_ ++ ++#if defined(CONFIG_40x) ++/* 40x-style software loaded TLB */ ++#include ++#elif defined(CONFIG_44x) ++/* 44x-style software loaded TLB */ ++#include ++#elif defined(CONFIG_PPC_BOOK3E_MMU) ++/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */ ++#include ++#elif defined (CONFIG_PPC_8xx) ++/* Motorola/Freescale 8xx software loaded TLB */ ++#include ++#endif ++ ++#endif /* _ASM_POWERPC_NOHASH_32_MMU_H_ */ +diff --git a/arch/powerpc/include/asm/nohash/64/mmu.h b/arch/powerpc/include/asm/nohash/64/mmu.h +new file mode 100644 +index 0000000000000..87871d027b75e +--- /dev/null ++++ b/arch/powerpc/include/asm/nohash/64/mmu.h +@@ -0,0 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _ASM_POWERPC_NOHASH_64_MMU_H_ ++#define _ASM_POWERPC_NOHASH_64_MMU_H_ ++ ++/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */ ++#include ++ ++#endif /* _ASM_POWERPC_NOHASH_64_MMU_H_ */ +diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/nohash/mmu-book3e.h +similarity index 100% +rename from arch/powerpc/include/asm/mmu-book3e.h +rename to arch/powerpc/include/asm/nohash/mmu-book3e.h +diff --git a/arch/powerpc/include/asm/nohash/mmu.h b/arch/powerpc/include/asm/nohash/mmu.h +new file mode 100644 +index 0000000000000..a037cb1efb57e +--- /dev/null ++++ b/arch/powerpc/include/asm/nohash/mmu.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _ASM_POWERPC_NOHASH_MMU_H_ ++#define _ASM_POWERPC_NOHASH_MMU_H_ ++ ++#ifdef CONFIG_PPC64 ++#include ++#else ++#include ++#endif ++ ++#endif /* _ASM_POWERPC_NOHASH_MMU_H_ */ +diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S +index 8d142e5d84cd0..5fbc890d10943 100644 +--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S ++++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S +@@ -17,7 +17,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + +diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h +index 94f04fcb373e1..962ee90a0dfea 100644 +--- a/arch/powerpc/kvm/e500.h ++++ b/arch/powerpc/kvm/e500.h +@@ -20,7 +20,7 @@ + #define KVM_E500_H + + #include +-#include ++#include + #include + #include + +-- +2.40.1 + diff --git a/queue-4.19/powerpc-move-page-table-dump-files-in-a-dedicated-su.patch b/queue-4.19/powerpc-move-page-table-dump-files-in-a-dedicated-su.patch new file mode 100644 index 00000000000..fd142f77520 --- /dev/null +++ b/queue-4.19/powerpc-move-page-table-dump-files-in-a-dedicated-su.patch @@ -0,0 +1,175 @@ +From 316cc85929ef2989c932a46f34aa022f42837b07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Feb 2019 12:28:36 +0000 +Subject: powerpc: Move page table dump files in a dedicated subdirectory + +From: Christophe Leroy + +[ Upstream commit e66c3209c7fd17209ccc4cbbee8b1b1bd5c438dd ] + +This patch moves the files related to page table dump in a +dedicated subdirectory. + +The purpose is to clean a bit arch/powerpc/mm by regrouping +multiple files handling a dedicated function. + +Signed-off-by: Christophe Leroy +[mpe: Shorten the file names while we're at it] +Signed-off-by: Michael Ellerman +Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking") +Signed-off-by: Sasha Levin +--- + arch/powerpc/Kconfig.debug | 4 ---- + arch/powerpc/mm/Makefile | 10 +--------- + .../mm/{dump_linuxpagetables-8xx.c => ptdump/8xx.c} | 2 +- + arch/powerpc/mm/ptdump/Makefile | 9 +++++++++ + arch/powerpc/mm/{dump_bats.c => ptdump/bats.c} | 0 + .../book3s64.c} | 2 +- + .../{dump_hashpagetable.c => ptdump/hashpagetable.c} | 0 + .../mm/{dump_linuxpagetables.c => ptdump/ptdump.c} | 2 +- + .../mm/{dump_linuxpagetables.h => ptdump/ptdump.h} | 0 + arch/powerpc/mm/{dump_sr.c => ptdump/segment_regs.c} | 0 + .../shared.c} | 2 +- + 11 files changed, 14 insertions(+), 17 deletions(-) + rename arch/powerpc/mm/{dump_linuxpagetables-8xx.c => ptdump/8xx.c} (97%) + create mode 100644 arch/powerpc/mm/ptdump/Makefile + rename arch/powerpc/mm/{dump_bats.c => ptdump/bats.c} (100%) + rename arch/powerpc/mm/{dump_linuxpagetables-book3s64.c => ptdump/book3s64.c} (98%) + rename arch/powerpc/mm/{dump_hashpagetable.c => ptdump/hashpagetable.c} (100%) + rename arch/powerpc/mm/{dump_linuxpagetables.c => ptdump/ptdump.c} (99%) + rename arch/powerpc/mm/{dump_linuxpagetables.h => ptdump/ptdump.h} (100%) + rename arch/powerpc/mm/{dump_sr.c => ptdump/segment_regs.c} (100%) + rename arch/powerpc/mm/{dump_linuxpagetables-generic.c => ptdump/shared.c} (97%) + +diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug +index 923b3b794d13f..1f54bb93b5cc7 100644 +--- a/arch/powerpc/Kconfig.debug ++++ b/arch/powerpc/Kconfig.debug +@@ -368,10 +368,6 @@ config PPC_PTDUMP + + If you are unsure, say N. + +-config PPC_HTDUMP +- def_bool y +- depends on PPC_PTDUMP && PPC_BOOK3S_64 +- + config PPC_FAST_ENDIAN_SWITCH + bool "Deprecated fast endian-switch syscall" + depends on DEBUG_KERNEL && PPC_BOOK3S_64 +diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile +index 8ace67f002752..d4648a1e6e6c1 100644 +--- a/arch/powerpc/mm/Makefile ++++ b/arch/powerpc/mm/Makefile +@@ -42,13 +42,5 @@ obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o + obj-$(CONFIG_HIGHMEM) += highmem.o + obj-$(CONFIG_PPC_COPRO_BASE) += copro_fault.o + obj-$(CONFIG_SPAPR_TCE_IOMMU) += mmu_context_iommu.o +-obj-$(CONFIG_PPC_PTDUMP) += dump_linuxpagetables.o +-ifdef CONFIG_PPC_PTDUMP +-obj-$(CONFIG_4xx) += dump_linuxpagetables-generic.o +-obj-$(CONFIG_PPC_8xx) += dump_linuxpagetables-8xx.o +-obj-$(CONFIG_PPC_BOOK3E_MMU) += dump_linuxpagetables-generic.o +-obj-$(CONFIG_PPC_BOOK3S_32) += dump_linuxpagetables-generic.o dump_bats.o dump_sr.o +-obj-$(CONFIG_PPC_BOOK3S_64) += dump_linuxpagetables-book3s64.o +-endif +-obj-$(CONFIG_PPC_HTDUMP) += dump_hashpagetable.o ++obj-$(CONFIG_PPC_PTDUMP) += ptdump/ + obj-$(CONFIG_PPC_MEM_KEYS) += pkeys.o +diff --git a/arch/powerpc/mm/dump_linuxpagetables-8xx.c b/arch/powerpc/mm/ptdump/8xx.c +similarity index 97% +rename from arch/powerpc/mm/dump_linuxpagetables-8xx.c +rename to arch/powerpc/mm/ptdump/8xx.c +index 33f52a97975b4..80b4f73f7fdc2 100644 +--- a/arch/powerpc/mm/dump_linuxpagetables-8xx.c ++++ b/arch/powerpc/mm/ptdump/8xx.c +@@ -7,7 +7,7 @@ + #include + #include + +-#include "dump_linuxpagetables.h" ++#include "ptdump.h" + + static const struct flag_info flag_array[] = { + { +diff --git a/arch/powerpc/mm/ptdump/Makefile b/arch/powerpc/mm/ptdump/Makefile +new file mode 100644 +index 0000000000000..712762be3cb11 +--- /dev/null ++++ b/arch/powerpc/mm/ptdump/Makefile +@@ -0,0 +1,9 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y += ptdump.o ++ ++obj-$(CONFIG_4xx) += shared.o ++obj-$(CONFIG_PPC_8xx) += 8xx.o ++obj-$(CONFIG_PPC_BOOK3E_MMU) += shared.o ++obj-$(CONFIG_PPC_BOOK3S_32) += shared.o bats.o segment_regs.o ++obj-$(CONFIG_PPC_BOOK3S_64) += book3s64.o hashpagetable.o +diff --git a/arch/powerpc/mm/dump_bats.c b/arch/powerpc/mm/ptdump/bats.c +similarity index 100% +rename from arch/powerpc/mm/dump_bats.c +rename to arch/powerpc/mm/ptdump/bats.c +diff --git a/arch/powerpc/mm/dump_linuxpagetables-book3s64.c b/arch/powerpc/mm/ptdump/book3s64.c +similarity index 98% +rename from arch/powerpc/mm/dump_linuxpagetables-book3s64.c +rename to arch/powerpc/mm/ptdump/book3s64.c +index a637e612b2055..0bce5b85d0112 100644 +--- a/arch/powerpc/mm/dump_linuxpagetables-book3s64.c ++++ b/arch/powerpc/mm/ptdump/book3s64.c +@@ -7,7 +7,7 @@ + #include + #include + +-#include "dump_linuxpagetables.h" ++#include "ptdump.h" + + static const struct flag_info flag_array[] = { + { +diff --git a/arch/powerpc/mm/dump_hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c +similarity index 100% +rename from arch/powerpc/mm/dump_hashpagetable.c +rename to arch/powerpc/mm/ptdump/hashpagetable.c +diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/ptdump/ptdump.c +similarity index 99% +rename from arch/powerpc/mm/dump_linuxpagetables.c +rename to arch/powerpc/mm/ptdump/ptdump.c +index 6aa41669ac1ae..76be98988578d 100644 +--- a/arch/powerpc/mm/dump_linuxpagetables.c ++++ b/arch/powerpc/mm/ptdump/ptdump.c +@@ -28,7 +28,7 @@ + #include + #include + +-#include "dump_linuxpagetables.h" ++#include "ptdump.h" + + #ifdef CONFIG_PPC32 + #define KERN_VIRT_START 0 +diff --git a/arch/powerpc/mm/dump_linuxpagetables.h b/arch/powerpc/mm/ptdump/ptdump.h +similarity index 100% +rename from arch/powerpc/mm/dump_linuxpagetables.h +rename to arch/powerpc/mm/ptdump/ptdump.h +diff --git a/arch/powerpc/mm/dump_sr.c b/arch/powerpc/mm/ptdump/segment_regs.c +similarity index 100% +rename from arch/powerpc/mm/dump_sr.c +rename to arch/powerpc/mm/ptdump/segment_regs.c +diff --git a/arch/powerpc/mm/dump_linuxpagetables-generic.c b/arch/powerpc/mm/ptdump/shared.c +similarity index 97% +rename from arch/powerpc/mm/dump_linuxpagetables-generic.c +rename to arch/powerpc/mm/ptdump/shared.c +index fed6923bcb46e..1cda3d91c6c26 100644 +--- a/arch/powerpc/mm/dump_linuxpagetables-generic.c ++++ b/arch/powerpc/mm/ptdump/shared.c +@@ -7,7 +7,7 @@ + #include + #include + +-#include "dump_linuxpagetables.h" ++#include "ptdump.h" + + static const struct flag_info flag_array[] = { + { +-- +2.40.1 + diff --git a/queue-4.19/quota-fix-warning-in-dqgrab.patch b/queue-4.19/quota-fix-warning-in-dqgrab.patch new file mode 100644 index 00000000000..673f2300b67 --- /dev/null +++ b/queue-4.19/quota-fix-warning-in-dqgrab.patch @@ -0,0 +1,104 @@ +From c755c6874f94cf27a32550b59f636a6933b2e05f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jun 2023 22:07:31 +0800 +Subject: quota: fix warning in dqgrab() + +From: Ye Bin + +[ Upstream commit d6a95db3c7ad160bc16b89e36449705309b52bcb ] + +There's issue as follows when do fault injection: +WARNING: CPU: 1 PID: 14870 at include/linux/quotaops.h:51 dquot_disable+0x13b7/0x18c0 +Modules linked in: +CPU: 1 PID: 14870 Comm: fsconfig Not tainted 6.3.0-next-20230505-00006-g5107a9c821af-dirty #541 +RIP: 0010:dquot_disable+0x13b7/0x18c0 +RSP: 0018:ffffc9000acc79e0 EFLAGS: 00010246 +RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff88825e41b980 +RDX: 0000000000000000 RSI: ffff88825e41b980 RDI: 0000000000000002 +RBP: ffff888179f68000 R08: ffffffff82087ca7 R09: 0000000000000000 +R10: 0000000000000001 R11: ffffed102f3ed026 R12: ffff888179f68130 +R13: ffff888179f68110 R14: dffffc0000000000 R15: ffff888179f68118 +FS: 00007f450a073740(0000) GS:ffff88882fc00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007ffe96f2efd8 CR3: 000000025c8ad000 CR4: 00000000000006e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + dquot_load_quota_sb+0xd53/0x1060 + dquot_resume+0x172/0x230 + ext4_reconfigure+0x1dc6/0x27b0 + reconfigure_super+0x515/0xa90 + __x64_sys_fsconfig+0xb19/0xd20 + do_syscall_64+0x39/0xb0 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Above issue may happens as follows: +ProcessA ProcessB ProcessC +sys_fsconfig + vfs_fsconfig_locked + reconfigure_super + ext4_remount + dquot_suspend -> suspend all type quota + + sys_fsconfig + vfs_fsconfig_locked + reconfigure_super + ext4_remount + dquot_resume + ret = dquot_load_quota_sb + add_dquot_ref + do_open -> open file O_RDWR + vfs_open + do_dentry_open + get_write_access + atomic_inc_unless_negative(&inode->i_writecount) + ext4_file_open + dquot_file_open + dquot_initialize + __dquot_initialize + dqget + atomic_inc(&dquot->dq_count); + + __dquot_initialize + __dquot_initialize + dqget + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + ext4_acquire_dquot + -> Return error DQ_ACTIVE_B flag isn't set + dquot_disable + invalidate_dquots + if (atomic_read(&dquot->dq_count)) + dqgrab + WARN_ON_ONCE(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + -> Trigger warning + +In the above scenario, 'dquot->dq_flags' has no DQ_ACTIVE_B is normal when +dqgrab(). +To solve above issue just replace the dqgrab() use in invalidate_dquots() with +atomic_inc(&dquot->dq_count). + +Signed-off-by: Ye Bin +Signed-off-by: Jan Kara +Message-Id: <20230605140731.2427629-3-yebin10@huawei.com> +Signed-off-by: Sasha Levin +--- + fs/quota/dquot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index 0d3ffc727bb00..303987d29b9c9 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -540,7 +540,7 @@ static void invalidate_dquots(struct super_block *sb, int type) + continue; + /* Wait for dquot users */ + if (atomic_read(&dquot->dq_count)) { +- dqgrab(dquot); ++ atomic_inc(&dquot->dq_count); + spin_unlock(&dq_list_lock); + /* + * Once dqput() wakes us up, we know it's time to free +-- +2.40.1 + diff --git a/queue-4.19/quota-properly-disable-quotas-when-add_dquot_ref-fai.patch b/queue-4.19/quota-properly-disable-quotas-when-add_dquot_ref-fai.patch new file mode 100644 index 00000000000..667e4af1909 --- /dev/null +++ b/queue-4.19/quota-properly-disable-quotas-when-add_dquot_ref-fai.patch @@ -0,0 +1,43 @@ +From 002bb0459ab3e97da35be94efeba998549ad4c55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jun 2023 22:07:30 +0800 +Subject: quota: Properly disable quotas when add_dquot_ref() fails + +From: Jan Kara + +[ Upstream commit 6a4e3363792e30177cc3965697e34ddcea8b900b ] + +When add_dquot_ref() fails (usually due to IO error or ENOMEM), we want +to disable quotas we are trying to enable. However dquot_disable() call +was passed just the flags we are enabling so in case flags == +DQUOT_USAGE_ENABLED dquot_disable() call will just fail with EINVAL +instead of properly disabling quotas. Fix the problem by always passing +DQUOT_LIMITS_ENABLED | DQUOT_USAGE_ENABLED to dquot_disable() in this +case. + +Reported-and-tested-by: Ye Bin +Reported-by: syzbot+e633c79ceaecbf479854@syzkaller.appspotmail.com +Signed-off-by: Jan Kara +Message-Id: <20230605140731.2427629-2-yebin10@huawei.com> +Signed-off-by: Sasha Levin +--- + fs/quota/dquot.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index 770a2b1434856..0d3ffc727bb00 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -2407,7 +2407,8 @@ int dquot_load_quota_sb(struct super_block *sb, int type, int format_id, + + error = add_dquot_ref(sb, type); + if (error) +- dquot_disable(sb, type, flags); ++ dquot_disable(sb, type, ++ DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + + return error; + out_fmt: +-- +2.40.1 + diff --git a/queue-4.19/selftests-forwarding-tc_flower-relax-success-criteri.patch b/queue-4.19/selftests-forwarding-tc_flower-relax-success-criteri.patch new file mode 100644 index 00000000000..186edcfd185 --- /dev/null +++ b/queue-4.19/selftests-forwarding-tc_flower-relax-success-criteri.patch @@ -0,0 +1,61 @@ +From 246326823d374cfece35d20a216d737fa1733b85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Aug 2023 17:14:58 +0300 +Subject: selftests: forwarding: tc_flower: Relax success criterion + +From: Ido Schimmel + +[ Upstream commit 9ee37e53e7687654b487fc94e82569377272a7a8 ] + +The test checks that filters that match on source or destination MAC +were only hit once. A host can send more than one packet with a given +source or destination MAC, resulting in failures. + +Fix by relaxing the success criterion and instead check that the filters +were not hit zero times. Using tc_check_at_least_x_packets() is also an +option, but it is not available in older kernels. + +Fixes: 07e5c75184a1 ("selftests: forwarding: Introduce tc flower matching tests") +Reported-by: Mirsad Todorovac +Closes: https://lore.kernel.org/netdev/adc5e40d-d040-a65e-eb26-edf47dac5b02@alu.unizg.hr/ +Signed-off-by: Ido Schimmel +Reviewed-by: Petr Machata +Tested-by: Mirsad Todorovac +Reviewed-by: Hangbin Liu +Acked-by: Nikolay Aleksandrov +Link: https://lore.kernel.org/r/20230808141503.4060661-13-idosch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/tc_flower.sh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/testing/selftests/net/forwarding/tc_flower.sh b/tools/testing/selftests/net/forwarding/tc_flower.sh +index 20d1077e5a3de..85faef980887a 100755 +--- a/tools/testing/selftests/net/forwarding/tc_flower.sh ++++ b/tools/testing/selftests/net/forwarding/tc_flower.sh +@@ -48,8 +48,8 @@ match_dst_mac_test() + tc_check_packets "dev $h2 ingress" 101 1 + check_fail $? "Matched on a wrong filter" + +- tc_check_packets "dev $h2 ingress" 102 1 +- check_err $? "Did not match on correct filter" ++ tc_check_packets "dev $h2 ingress" 102 0 ++ check_fail $? "Did not match on correct filter" + + tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower + tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower +@@ -74,8 +74,8 @@ match_src_mac_test() + tc_check_packets "dev $h2 ingress" 101 1 + check_fail $? "Matched on a wrong filter" + +- tc_check_packets "dev $h2 ingress" 102 1 +- check_err $? "Did not match on correct filter" ++ tc_check_packets "dev $h2 ingress" 102 0 ++ check_fail $? "Did not match on correct filter" + + tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower + tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower +-- +2.40.1 + diff --git a/queue-4.19/series b/queue-4.19/series index 2a0e9374557..6f1777a14f9 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -1 +1,54 @@ lib-mpi-eliminate-unused-umul_ppmm-definitions-for-mips.patch +selftests-forwarding-tc_flower-relax-success-criteri.patch +drm-radeon-fix-integer-overflow-in-radeon_cs_parser_.patch +alsa-emu10k1-roll-up-loops-in-dsp-setup-code-for-aud.patch +quota-properly-disable-quotas-when-add_dquot_ref-fai.patch +quota-fix-warning-in-dqgrab.patch +hid-add-quirk-for-03f0-464a-hp-elite-presenter-mouse.patch +udf-fix-uninitialized-array-access-for-some-pathname.patch +fs-jfs-fix-ubsan-array-index-out-of-bounds-in-dballo.patch +mips-dec-prom-address-warray-bounds-warning.patch +fs-jfs-fix-null-ptr-deref-read-in-txbegin.patch +fs-jfs-check-for-read-only-mounted-filesystem-in-txb.patch +media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch +media-platform-mediatek-vpu-fix-null-ptr-dereference.patch +gfs2-fix-possible-data-races-in-gfs2_show_options.patch +pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch +bluetooth-l2cap-fix-use-after-free.patch +drm-amdgpu-fix-potential-fence-use-after-free-v2.patch +ima-allow-fix-uml-builds.patch +iio-add-addac-subdirectory.patch +iio-adc-stx104-utilize-iomap-interface.patch +iio-adc-stx104-implement-and-utilize-register-struct.patch +iio-addac-stx104-fix-race-condition-for-stx104_write.patch +iio-addac-stx104-fix-race-condition-when-converting-.patch +powerpc-mm-move-platform-specific-mmu-xxx.h-in-platf.patch +powerpc-mm-move-pgtable_t-into-platform-headers.patch +powerpc-mm-dump-segment-registers-on-book3s-32.patch +powerpc-mm-dump-block-address-translation-on-book3s-.patch +powerpc-move-page-table-dump-files-in-a-dedicated-su.patch +powerpc-64s-radix-fix-soft-dirty-tracking.patch +x86-topology-fix-erroneous-smp_num_siblings-on-intel.patch +irqchip-mips-gic-get-rid-of-the-reliance-on-irq_cpu_.patch +irqchip-mips-gic-use-raw-spinlock-for-gic_lock.patch +usb-dwc3-qcom-add-helper-functions-to-enable-disable.patch +usb-dwc3-qcom-fix-null-deref-on-suspend.patch +mmc-meson-gx-remove-useless-lock.patch +mmc-meson-gx-remove-redundant-mmc_request_done-call-.patch +mmc-sdhci-spear-fix-deferred-probing.patch +mmc-tmio-replace-tmio_mmc_clk_stop-calls-with-tmio_m.patch +mmc-tmio-move-tmio_mmc_set_clock-to-platform-hook.patch +mmc-uniphier-sd-add-uniphier-sd-emmc-controller-driv.patch +mmc-remove-dev_err-usage-after-platform_get_irq.patch +mmc-bcm2835-fix-deferred-probing.patch +mmc-sunxi-fix-deferred-probing.patch +block-fix-signed-int-overflow-in-amiga-partition-sup.patch +pci-endpoint-add-new-pci_epc_ops-to-get-epc-features.patch +pci-rockchip-populate-get_features-dw_pcie_ep_ops.patch +pci-endpoint-add-helper-to-get-first-unreserved-bar.patch +pci-pci-epf-test-remove-setting-epf_bar-flags-in-fun.patch +pci-pci-epf-test-use-pci_epc_get_features-to-get-epc.patch +pci-endpoint-add-support-to-specify-alignment-for-bu.patch +pci-rockchip-set-address-alignment-for-endpoint-mode.patch +nfsd4-kill-warnings-on-testing-stateids-with-mismatc.patch +nfsd-remove-incorrect-check-in-nfsd4_validate_statei.patch diff --git a/queue-4.19/udf-fix-uninitialized-array-access-for-some-pathname.patch b/queue-4.19/udf-fix-uninitialized-array-access-for-some-pathname.patch new file mode 100644 index 00000000000..b9bd1824b0b --- /dev/null +++ b/queue-4.19/udf-fix-uninitialized-array-access-for-some-pathname.patch @@ -0,0 +1,39 @@ +From bbaa7a6630c53e59fd397ac57291ce0b9a32cbd2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Jun 2023 11:32:35 +0200 +Subject: udf: Fix uninitialized array access for some pathnames + +From: Jan Kara + +[ Upstream commit 028f6055c912588e6f72722d89c30b401bbcf013 ] + +For filenames that begin with . and are between 2 and 5 characters long, +UDF charset conversion code would read uninitialized memory in the +output buffer. The only practical impact is that the name may be prepended a +"unification hash" when it is not actually needed but still it is good +to fix this. + +Reported-by: syzbot+cd311b1e43cc25f90d18@syzkaller.appspotmail.com +Link: https://lore.kernel.org/all/000000000000e2638a05fe9dc8f9@google.com +Signed-off-by: Jan Kara +Signed-off-by: Sasha Levin +--- + fs/udf/unicode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c +index 5fcfa96463ebb..85521d6b02370 100644 +--- a/fs/udf/unicode.c ++++ b/fs/udf/unicode.c +@@ -247,7 +247,7 @@ static int udf_name_from_CS0(struct super_block *sb, + } + + if (translate) { +- if (str_o_len <= 2 && str_o[0] == '.' && ++ if (str_o_len > 0 && str_o_len <= 2 && str_o[0] == '.' && + (str_o_len == 1 || str_o[1] == '.')) + needsCRC = 1; + if (needsCRC) { +-- +2.40.1 + diff --git a/queue-4.19/usb-dwc3-qcom-add-helper-functions-to-enable-disable.patch b/queue-4.19/usb-dwc3-qcom-add-helper-functions-to-enable-disable.patch new file mode 100644 index 00000000000..8c4dcf94131 --- /dev/null +++ b/queue-4.19/usb-dwc3-qcom-add-helper-functions-to-enable-disable.patch @@ -0,0 +1,108 @@ +From d6b90837ba12f656707c7faa566fe8c5b74eb2f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jun 2022 10:00:52 +0530 +Subject: usb: dwc3: qcom: Add helper functions to enable,disable wake irqs + +From: Sandeep Maheswaram + +[ Upstream commit 360e8230516de94d74d30c64f0cdcf228b8e8b67 ] + +Adding helper functions to enable,disable wake irqs to make +the code simple and readable. + +Reviewed-by: Matthias Kaehlcke +Reviewed-by: Pavankumar Kondeti +Signed-off-by: Sandeep Maheswaram +Signed-off-by: Krishna Kurapati +Link: https://lore.kernel.org/r/1655094654-24052-4-git-send-email-quic_kriskura@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: d2d69354226d ("USB: dwc3: qcom: fix NULL-deref on suspend") +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc3/dwc3-qcom.c | 58 ++++++++++++++++-------------------- + 1 file changed, 26 insertions(+), 32 deletions(-) + +diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c +index 58e1bc3a77d80..cbf9286d4c46f 100644 +--- a/drivers/usb/dwc3/dwc3-qcom.c ++++ b/drivers/usb/dwc3/dwc3-qcom.c +@@ -181,50 +181,44 @@ static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom) + return dwc->xhci; + } + ++static void dwc3_qcom_enable_wakeup_irq(int irq) ++{ ++ if (!irq) ++ return; ++ ++ enable_irq(irq); ++ enable_irq_wake(irq); ++} ++ ++static void dwc3_qcom_disable_wakeup_irq(int irq) ++{ ++ if (!irq) ++ return; ++ ++ disable_irq_wake(irq); ++ disable_irq_nosync(irq); ++} ++ + static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom) + { +- if (qcom->hs_phy_irq) { +- disable_irq_wake(qcom->hs_phy_irq); +- disable_irq_nosync(qcom->hs_phy_irq); +- } ++ dwc3_qcom_disable_wakeup_irq(qcom->hs_phy_irq); + +- if (qcom->dp_hs_phy_irq) { +- disable_irq_wake(qcom->dp_hs_phy_irq); +- disable_irq_nosync(qcom->dp_hs_phy_irq); +- } ++ dwc3_qcom_disable_wakeup_irq(qcom->dp_hs_phy_irq); + +- if (qcom->dm_hs_phy_irq) { +- disable_irq_wake(qcom->dm_hs_phy_irq); +- disable_irq_nosync(qcom->dm_hs_phy_irq); +- } ++ dwc3_qcom_disable_wakeup_irq(qcom->dm_hs_phy_irq); + +- if (qcom->ss_phy_irq) { +- disable_irq_wake(qcom->ss_phy_irq); +- disable_irq_nosync(qcom->ss_phy_irq); +- } ++ dwc3_qcom_disable_wakeup_irq(qcom->ss_phy_irq); + } + + static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom) + { +- if (qcom->hs_phy_irq) { +- enable_irq(qcom->hs_phy_irq); +- enable_irq_wake(qcom->hs_phy_irq); +- } ++ dwc3_qcom_enable_wakeup_irq(qcom->hs_phy_irq); + +- if (qcom->dp_hs_phy_irq) { +- enable_irq(qcom->dp_hs_phy_irq); +- enable_irq_wake(qcom->dp_hs_phy_irq); +- } ++ dwc3_qcom_enable_wakeup_irq(qcom->dp_hs_phy_irq); + +- if (qcom->dm_hs_phy_irq) { +- enable_irq(qcom->dm_hs_phy_irq); +- enable_irq_wake(qcom->dm_hs_phy_irq); +- } ++ dwc3_qcom_enable_wakeup_irq(qcom->dm_hs_phy_irq); + +- if (qcom->ss_phy_irq) { +- enable_irq(qcom->ss_phy_irq); +- enable_irq_wake(qcom->ss_phy_irq); +- } ++ dwc3_qcom_enable_wakeup_irq(qcom->ss_phy_irq); + } + + static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) +-- +2.40.1 + diff --git a/queue-4.19/usb-dwc3-qcom-fix-null-deref-on-suspend.patch b/queue-4.19/usb-dwc3-qcom-fix-null-deref-on-suspend.patch new file mode 100644 index 00000000000..4c1aa670575 --- /dev/null +++ b/queue-4.19/usb-dwc3-qcom-fix-null-deref-on-suspend.patch @@ -0,0 +1,68 @@ +From 7acfa55cf503ce72254d08687a3aa73139a8b5f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jun 2023 12:05:39 +0200 +Subject: USB: dwc3: qcom: fix NULL-deref on suspend + +From: Johan Hovold + +[ Upstream commit d2d69354226de0b333d4405981f3d9c41ba8430a ] + +The Qualcomm dwc3 glue driver is currently accessing the driver data of +the child core device during suspend and on wakeup interrupts. This is +clearly a bad idea as the child may not have probed yet or could have +been unbound from its driver. + +The first such layering violation was part of the initial version of the +driver, but this was later made worse when the hack that accesses the +driver data of the grand child xhci device to configure the wakeup +interrupts was added. + +Fixing this properly is not that easily done, so add a sanity check to +make sure that the child driver data is non-NULL before dereferencing it +for now. + +Note that this relies on subtleties like the fact that driver core is +making sure that the parent is not suspended while the child is probing. + +Reported-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/all/20230325165217.31069-4-manivannan.sadhasivam@linaro.org/ +Fixes: d9152161b4bf ("usb: dwc3: Add Qualcomm DWC3 glue layer driver") +Fixes: 6895ea55c385 ("usb: dwc3: qcom: Configure wakeup interrupts during suspend") +Cc: stable@vger.kernel.org # 3.18: a872ab303d5d: "usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup" +Cc: Sandeep Maheswaram +Cc: Krishna Kurapati +Signed-off-by: Johan Hovold +Acked-by: Thinh Nguyen +Reviewed-by: Manivannan Sadhasivam +Message-ID: <20230607100540.31045-2-johan+linaro@kernel.org> +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc3/dwc3-qcom.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c +index cbf9286d4c46f..0f090188e265b 100644 +--- a/drivers/usb/dwc3/dwc3-qcom.c ++++ b/drivers/usb/dwc3/dwc3-qcom.c +@@ -176,7 +176,16 @@ static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom) + /* Only usable in contexts where the role can not change. */ + static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom) + { +- struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); ++ struct dwc3 *dwc; ++ ++ /* ++ * FIXME: Fix this layering violation. ++ */ ++ dwc = platform_get_drvdata(qcom->dwc3); ++ ++ /* Core driver may not have probed yet. */ ++ if (!dwc) ++ return false; + + return dwc->xhci; + } +-- +2.40.1 + diff --git a/queue-4.19/x86-topology-fix-erroneous-smp_num_siblings-on-intel.patch b/queue-4.19/x86-topology-fix-erroneous-smp_num_siblings-on-intel.patch new file mode 100644 index 00000000000..4d69bd8fde2 --- /dev/null +++ b/queue-4.19/x86-topology-fix-erroneous-smp_num_siblings-on-intel.patch @@ -0,0 +1,96 @@ +From c429b416c053eab6a839cd6d138e8381f67f65f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Mar 2023 09:56:40 +0800 +Subject: x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid + platforms + +From: Zhang Rui + +[ Upstream commit edc0a2b5957652f4685ef3516f519f84807087db ] + +Traditionally, all CPUs in a system have identical numbers of SMT +siblings. That changes with hybrid processors where some logical CPUs +have a sibling and others have none. + +Today, the CPU boot code sets the global variable smp_num_siblings when +every CPU thread is brought up. The last thread to boot will overwrite +it with the number of siblings of *that* thread. That last thread to +boot will "win". If the thread is a Pcore, smp_num_siblings == 2. If it +is an Ecore, smp_num_siblings == 1. + +smp_num_siblings describes if the *system* supports SMT. It should +specify the maximum number of SMT threads among all cores. + +Ensure that smp_num_siblings represents the system-wide maximum number +of siblings by always increasing its value. Never allow it to decrease. + +On MeteorLake-P platform, this fixes a problem that the Ecore CPUs are +not updated in any cpu sibling map because the system is treated as an +UP system when probing Ecore CPUs. + +Below shows part of the CPU topology information before and after the +fix, for both Pcore and Ecore CPU (cpu0 is Pcore, cpu 12 is Ecore). +... +-/sys/devices/system/cpu/cpu0/topology/package_cpus:000fff +-/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-11 ++/sys/devices/system/cpu/cpu0/topology/package_cpus:3fffff ++/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-21 +... +-/sys/devices/system/cpu/cpu12/topology/package_cpus:001000 +-/sys/devices/system/cpu/cpu12/topology/package_cpus_list:12 ++/sys/devices/system/cpu/cpu12/topology/package_cpus:3fffff ++/sys/devices/system/cpu/cpu12/topology/package_cpus_list:0-21 + +Notice that the "before" 'package_cpus_list' has only one CPU. This +means that userspace tools like lscpu will see a little laptop like +an 11-socket system: + +-Core(s) per socket: 1 +-Socket(s): 11 ++Core(s) per socket: 16 ++Socket(s): 1 + +This is also expected to make the scheduler do rather wonky things +too. + +[ dhansen: remove CPUID detail from changelog, add end user effects ] + +CC: stable@kernel.org +Fixes: bbb65d2d365e ("x86: use cpuid vector 0xb when available for detecting cpu topology") +Fixes: 95f3d39ccf7a ("x86/cpu/topology: Provide detect_extended_topology_early()") +Suggested-by: Len Brown +Signed-off-by: Zhang Rui +Signed-off-by: Dave Hansen +Acked-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/all/20230323015640.27906-1-rui.zhang%40intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cpu/topology.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c +index 71ca064e37948..31fe56a90cbf8 100644 +--- a/arch/x86/kernel/cpu/topology.c ++++ b/arch/x86/kernel/cpu/topology.c +@@ -44,7 +44,7 @@ int detect_extended_topology_early(struct cpuinfo_x86 *c) + * initial apic id, which also represents 32-bit extended x2apic id. + */ + c->initial_apicid = edx; +- smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); ++ smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx)); + #endif + return 0; + } +@@ -68,7 +68,8 @@ int detect_extended_topology(struct cpuinfo_x86 *c) + * Populate HT related information from sub-leaf level 0. + */ + cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx); +- core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); ++ core_level_siblings = LEVEL_MAX_SIBLINGS(ebx); ++ smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx)); + core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); + + sub_index = 1; +-- +2.40.1 +