From a2d7fd7b066d92d8ea41f9b1119eff67096bfeae Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Fri, 16 Jun 2023 20:33:40 -0400 Subject: [PATCH] Fixes for 5.15 Signed-off-by: Sasha Levin --- ...express-add-missing-cache-properties.patch | 37 + ...dma-init-to-snd_soc_dai_driver-probe.patch | 146 ++++ ...soc-pcm-test-if-a-be-can-be-prepared.patch | 93 +++ ...ory-allocation-failure-in-btrfs_csum.patch | 48 ++ ...harder-to-mark-raid56-block-groups-r.patch | 95 +++ ...ix-missing-buffer-object-unlock-in-f.patch | 59 ++ ...rectly-validate-of-quirk-descriptors.patch | 41 ++ ...isable-pseudo-nmis-on-mediatek-devic.patch | 138 ++++ queue-5.15/mips-alchemy-fix-dbdma2.patch | 87 +++ ..._start-check-after-initrd-address-sa.patch | 52 ++ queue-5.15/mips-restore-au1300-support.patch | 48 ++ queue-5.15/mips-unhide-pata_platform.patch | 34 + ...vme-add-maxio-1602-to-bogus-nid-list.patch | 71 ++ ...issing-of_node_put-in-error-case-of-.patch | 37 + ...ay-rename-variables-to-be-consistent.patch | 270 ++++++++ ...ork-overlay-apply-and-remove-kfree-s.patch | 635 ++++++++++++++++++ ...t-writes-and-adjust-gatt-mask-in-par.patch | 62 ++ ...ache-flushing-for-pcxl-in-arch_sync_.patch | 57 ++ ...s-wmi-ignore-wmi-events-with-codes-0.patch | 50 ++ ...8500-fix-external_power_changed-race.patch | 73 ++ ...7xxx-use-mod_delayed_work-instead-of.patch | 40 ++ ...-logic-checking-if-system-is-running.patch | 66 ++ ...upply-ratelimit-no-data-debug-output.patch | 43 ++ ...27xx-fix-external_power_changed-race.patch | 70 ++ ...rror-checking-for-debugfs_create_dir.patch | 46 ++ queue-5.15/series | 27 + ...-debounce_period_us-output-of-lsgpio.patch | 37 + ...kfront-only-check-req_fua-for-writes.patch | 45 ++ 28 files changed, 2507 insertions(+) create mode 100644 queue-5.15/arm-dts-vexpress-add-missing-cache-properties.patch create mode 100644 queue-5.15/asoc-dwc-move-dma-init-to-snd_soc_dai_driver-probe.patch create mode 100644 queue-5.15/asoc-soc-pcm-test-if-a-be-can-be-prepared.patch create mode 100644 queue-5.15/btrfs-handle-memory-allocation-failure-in-btrfs_csum.patch create mode 100644 queue-5.15/btrfs-scrub-try-harder-to-mark-raid56-block-groups-r.patch create mode 100644 queue-5.15/drm-amd-amdgpu-fix-missing-buffer-object-unlock-in-f.patch create mode 100644 queue-5.15/irqchip-gic-correctly-validate-of-quirk-descriptors.patch create mode 100644 queue-5.15/irqchip-gic-v3-disable-pseudo-nmis-on-mediatek-devic.patch create mode 100644 queue-5.15/mips-alchemy-fix-dbdma2.patch create mode 100644 queue-5.15/mips-move-initrd_start-check-after-initrd-address-sa.patch create mode 100644 queue-5.15/mips-restore-au1300-support.patch create mode 100644 queue-5.15/mips-unhide-pata_platform.patch create mode 100644 queue-5.15/nvme-add-maxio-1602-to-bogus-nid-list.patch create mode 100644 queue-5.15/of-overlay-fix-missing-of_node_put-in-error-case-of-.patch create mode 100644 queue-5.15/of-overlay-rename-variables-to-be-consistent.patch create mode 100644 queue-5.15/of-overlay-rework-overlay-apply-and-remove-kfree-s.patch create mode 100644 queue-5.15/parisc-flush-gatt-writes-and-adjust-gatt-mask-in-par.patch create mode 100644 queue-5.15/parisc-improve-cache-flushing-for-pcxl-in-arch_sync_.patch create mode 100644 queue-5.15/platform-x86-asus-wmi-ignore-wmi-events-with-codes-0.patch create mode 100644 queue-5.15/power-supply-ab8500-fix-external_power_changed-race.patch create mode 100644 queue-5.15/power-supply-bq27xxx-use-mod_delayed_work-instead-of.patch create mode 100644 queue-5.15/power-supply-fix-logic-checking-if-system-is-running.patch create mode 100644 queue-5.15/power-supply-ratelimit-no-data-debug-output.patch create mode 100644 queue-5.15/power-supply-sc27xx-fix-external_power_changed-race.patch create mode 100644 queue-5.15/regulator-fix-error-checking-for-debugfs_create_dir.patch create mode 100644 queue-5.15/tools-gpio-fix-debounce_period_us-output-of-lsgpio.patch create mode 100644 queue-5.15/xen-blkfront-only-check-req_fua-for-writes.patch diff --git a/queue-5.15/arm-dts-vexpress-add-missing-cache-properties.patch b/queue-5.15/arm-dts-vexpress-add-missing-cache-properties.patch new file mode 100644 index 00000000000..4660cfc44e8 --- /dev/null +++ b/queue-5.15/arm-dts-vexpress-add-missing-cache-properties.patch @@ -0,0 +1,37 @@ +From 9f3b0985c30ab81282a4c487f0a4c8301a42d653 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 23 Apr 2023 17:08:37 +0200 +Subject: ARM: dts: vexpress: add missing cache properties + +From: Krzysztof Kozlowski + +[ Upstream commit 328acc5657c6197753238d7ce0a6924ead829347 ] + +As all level 2 and level 3 caches are unified, add required +cache-unified property to fix warnings like: + + vexpress-v2p-ca5s.dtb: cache-controller@2c0f0000: 'cache-unified' is a required property + +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20230423150837.118466-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/vexpress-v2p-ca5s.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts +index 3b88209bacea2..ff1f9a1bcfcfc 100644 +--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts ++++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts +@@ -132,6 +132,7 @@ L2: cache-controller@2c0f0000 { + reg = <0x2c0f0000 0x1000>; + interrupts = <0 84 4>; + cache-level = <2>; ++ cache-unified; + }; + + pmu { +-- +2.39.2 + diff --git a/queue-5.15/asoc-dwc-move-dma-init-to-snd_soc_dai_driver-probe.patch b/queue-5.15/asoc-dwc-move-dma-init-to-snd_soc_dai_driver-probe.patch new file mode 100644 index 00000000000..0e5f0e36194 --- /dev/null +++ b/queue-5.15/asoc-dwc-move-dma-init-to-snd_soc_dai_driver-probe.patch @@ -0,0 +1,146 @@ +From 143460b76c8afe1bd7dba28a5d72129885966a35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 14:03:42 +0300 +Subject: ASoC: dwc: move DMA init to snd_soc_dai_driver probe() + +From: Maxim Kochetkov + +[ Upstream commit 011a8719d6105dcb48077ea7a6a88ac019d4aa50 ] + +When using DMA mode we are facing with Oops: +[ 396.458157] Unable to handle kernel access to user memory without uaccess routines at virtual address 000000000000000c +[ 396.469374] Oops [#1] +[ 396.471839] Modules linked in: +[ 396.475144] CPU: 0 PID: 114 Comm: arecord Not tainted 6.0.0-00164-g9a8eccdaf2be-dirty #68 +[ 396.483619] Hardware name: YMP ELCT FPGA (DT) +[ 396.488156] epc : dmaengine_pcm_open+0x1d2/0x342 +[ 396.493227] ra : dmaengine_pcm_open+0x1d2/0x342 +[ 396.498140] epc : ffffffff807fe346 ra : ffffffff807fe346 sp : ffffffc804e138f0 +[ 396.505602] gp : ffffffff817bf730 tp : ffffffd8042c8ac0 t0 : 6500000000000000 +[ 396.513045] t1 : 0000000000000064 t2 : 656e69676e65616d s0 : ffffffc804e13990 +[ 396.520477] s1 : ffffffd801b86a18 a0 : 0000000000000026 a1 : ffffffff816920f8 +[ 396.527897] a2 : 0000000000000010 a3 : fffffffffffffffe a4 : 0000000000000000 +[ 396.535319] a5 : 0000000000000000 a6 : ffffffd801b87040 a7 : 0000000000000038 +[ 396.542740] s2 : ffffffd801b94a00 s3 : 0000000000000000 s4 : ffffffd80427f5e8 +[ 396.550153] s5 : ffffffd80427f5e8 s6 : ffffffd801b44410 s7 : fffffffffffffff5 +[ 396.557569] s8 : 0000000000000800 s9 : 0000000000000001 s10: ffffffff8066d254 +[ 396.564978] s11: ffffffd8059cf768 t3 : ffffffff817d5577 t4 : ffffffff817d5577 +[ 396.572391] t5 : ffffffff817d5578 t6 : ffffffc804e136e8 +[ 396.577876] status: 0000000200000120 badaddr: 000000000000000c cause: 000000000000000d +[ 396.586007] [] snd_soc_component_open+0x1a/0x68 +[ 396.592439] [] __soc_pcm_open+0xf0/0x502 +[ 396.598217] [] soc_pcm_open+0x2e/0x4e +[ 396.603741] [] snd_pcm_open_substream+0x442/0x68e +[ 396.610313] [] snd_pcm_open+0xfa/0x212 +[ 396.615868] [] snd_pcm_capture_open+0x3a/0x60 +[ 396.622048] [] snd_open+0xa8/0x17a +[ 396.627421] [] chrdev_open+0xa0/0x218 +[ 396.632893] [] do_dentry_open+0x17c/0x2a6 +[ 396.638713] [] vfs_open+0x1e/0x26 +[ 396.643850] [] path_openat+0x96e/0xc96 +[ 396.649518] [] do_filp_open+0x7c/0xf6 +[ 396.655034] [] do_sys_openat2+0x8a/0x11e +[ 396.660765] [] sys_openat+0x50/0x7c +[ 396.666068] [] ret_from_syscall+0x0/0x2 +[ 396.674964] ---[ end trace 0000000000000000 ]--- + +It happens because of play_dma_data/capture_dma_data pointers are NULL. +Current implementation assigns these pointers at snd_soc_dai_driver +startup() callback and reset them back to NULL at shutdown(). But +soc_pcm_open() sequence uses DMA pointers in dmaengine_pcm_open() +before snd_soc_dai_driver startup(). +Most generic DMA capable I2S drivers use snd_soc_dai_driver probe() +callback to init DMA pointers only once at probe. So move DMA init +to dw_i2s_dai_probe and drop shutdown() and startup() callbacks. + +Signed-off-by: Maxim Kochetkov +Link: https://lore.kernel.org/r/20230512110343.66664-1-fido_max@inbox.ru +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/dwc/dwc-i2s.c | 41 +++++++++-------------------------------- + 1 file changed, 9 insertions(+), 32 deletions(-) + +diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c +index 14ad8023fcdcb..feed7281ba215 100644 +--- a/sound/soc/dwc/dwc-i2s.c ++++ b/sound/soc/dwc/dwc-i2s.c +@@ -183,30 +183,6 @@ static void i2s_stop(struct dw_i2s_dev *dev, + } + } + +-static int dw_i2s_startup(struct snd_pcm_substream *substream, +- struct snd_soc_dai *cpu_dai) +-{ +- struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); +- union dw_i2s_snd_dma_data *dma_data = NULL; +- +- if (!(dev->capability & DWC_I2S_RECORD) && +- (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) +- return -EINVAL; +- +- if (!(dev->capability & DWC_I2S_PLAY) && +- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) +- return -EINVAL; +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) +- dma_data = &dev->play_dma_data; +- else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) +- dma_data = &dev->capture_dma_data; +- +- snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data); +- +- return 0; +-} +- + static void dw_i2s_config(struct dw_i2s_dev *dev, int stream) + { + u32 ch_reg; +@@ -305,12 +281,6 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, + return 0; + } + +-static void dw_i2s_shutdown(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai) +-{ +- snd_soc_dai_set_dma_data(dai, substream, NULL); +-} +- + static int dw_i2s_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) + { +@@ -382,8 +352,6 @@ static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) + } + + static const struct snd_soc_dai_ops dw_i2s_dai_ops = { +- .startup = dw_i2s_startup, +- .shutdown = dw_i2s_shutdown, + .hw_params = dw_i2s_hw_params, + .prepare = dw_i2s_prepare, + .trigger = dw_i2s_trigger, +@@ -624,6 +592,14 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, + + } + ++static int dw_i2s_dai_probe(struct snd_soc_dai *dai) ++{ ++ struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, &dev->capture_dma_data); ++ return 0; ++} ++ + static int dw_i2s_probe(struct platform_device *pdev) + { + const struct i2s_platform_data *pdata = pdev->dev.platform_data; +@@ -642,6 +618,7 @@ static int dw_i2s_probe(struct platform_device *pdev) + return -ENOMEM; + + dw_i2s_dai->ops = &dw_i2s_dai_ops; ++ dw_i2s_dai->probe = dw_i2s_dai_probe; + + dev->i2s_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(dev->i2s_base)) +-- +2.39.2 + diff --git a/queue-5.15/asoc-soc-pcm-test-if-a-be-can-be-prepared.patch b/queue-5.15/asoc-soc-pcm-test-if-a-be-can-be-prepared.patch new file mode 100644 index 00000000000..eab1140d6de --- /dev/null +++ b/queue-5.15/asoc-soc-pcm-test-if-a-be-can-be-prepared.patch @@ -0,0 +1,93 @@ +From fe5b21d5745653ff5c9732a6b60212e40a921163 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 May 2023 13:57:31 -0500 +Subject: ASoC: soc-pcm: test if a BE can be prepared + +From: Ranjani Sridharan + +[ Upstream commit e123036be377ddf628226a7c6d4f9af5efd113d3 ] + +In the BE hw_params configuration, the existing code checks if any of the +existing FEs are prepared, running, paused or suspended - and skips the +configuration in those cases. This allows multiple calls of hw_params +which the ALSA state machine supports. + +This check is not handled for the prepare stage, which can lead to the +same BE being prepared multiple times. This patch adds a check similar to +that of the hw_params, with the main difference being that the suspended +state is allowed: the ALSA state machine allows a transition from +suspended to prepared with hw_params skipped. + +This problem was detected on Intel IPC4/SoundWire devices, where the BE +dailink .prepare stage is used to configure the SoundWire stream with a +bank switch. Multiple .prepare calls lead to conflicts with the .trigger +operation with IPC4 configurations. This problem was not detected earlier +on Intel devices, HDaudio BE dailinks detect that the link is already +prepared and skip the configuration, and for IPC3 devices there is no BE +trigger. + +Link: https://github.com/thesofproject/sof/issues/7596 +Signed-off-by: Ranjani Sridharan +--- + include/sound/soc-dpcm.h | 4 ++++ + sound/soc/soc-pcm.c | 20 ++++++++++++++++++++ + 2 files changed, 24 insertions(+) + +diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h +index d963f3b608489..4bb3ebfdaa45e 100644 +--- a/include/sound/soc-dpcm.h ++++ b/include/sound/soc-dpcm.h +@@ -123,6 +123,10 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, + int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, + struct snd_soc_pcm_runtime *be, int stream); + ++/* can this BE perform prepare */ ++int snd_soc_dpcm_can_be_prepared(struct snd_soc_pcm_runtime *fe, ++ struct snd_soc_pcm_runtime *be, int stream); ++ + /* is the current PCM operation for this FE ? */ + int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream); + +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index 76c807372ef50..6ec248778e2fc 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -2398,6 +2398,9 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) + if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + continue; + ++ if (!snd_soc_dpcm_can_be_prepared(fe, be, stream)) ++ continue; ++ + if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && + (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND) && +@@ -3047,3 +3050,20 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, + return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state)); + } + EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); ++ ++/* ++ * We can only prepare a BE DAI if any of it's FE are not prepared, ++ * running or paused for the specified stream direction. ++ */ ++int snd_soc_dpcm_can_be_prepared(struct snd_soc_pcm_runtime *fe, ++ struct snd_soc_pcm_runtime *be, int stream) ++{ ++ const enum snd_soc_dpcm_state state[] = { ++ SND_SOC_DPCM_STATE_START, ++ SND_SOC_DPCM_STATE_PAUSED, ++ SND_SOC_DPCM_STATE_PREPARE, ++ }; ++ ++ return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state)); ++} ++EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_prepared); +-- +2.39.2 + diff --git a/queue-5.15/btrfs-handle-memory-allocation-failure-in-btrfs_csum.patch b/queue-5.15/btrfs-handle-memory-allocation-failure-in-btrfs_csum.patch new file mode 100644 index 00000000000..4b70b627b9d --- /dev/null +++ b/queue-5.15/btrfs-handle-memory-allocation-failure-in-btrfs_csum.patch @@ -0,0 +1,48 @@ +From 02f0db41f18925218848b4f58694ae9980b37622 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 May 2023 13:58:13 +0200 +Subject: btrfs: handle memory allocation failure in btrfs_csum_one_bio + +From: Johannes Thumshirn + +[ Upstream commit 806570c0bb7b4847828c22c4934fcf2dc8fc572f ] + +Since f8a53bb58ec7 ("btrfs: handle checksum generation in the storage +layer") the failures of btrfs_csum_one_bio() are handled via +bio_end_io(). + +This means, we can return BLK_STS_RESOURCE from btrfs_csum_one_bio() in +case the allocation of the ordered sums fails. + +This also fixes a syzkaller report, where injecting a failure into the +kvzalloc() call results in a BUG_ON(). + +Reported-by: syzbot+d8941552e21eac774778@syzkaller.appspotmail.com +Reviewed-by: Christoph Hellwig +Reviewed-by: Anand Jain +Signed-off-by: Johannes Thumshirn +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/file-item.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c +index dd8b02a2a14a0..4c210b2ac6994 100644 +--- a/fs/btrfs/file-item.c ++++ b/fs/btrfs/file-item.c +@@ -700,7 +700,9 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio, + sums = kvzalloc(btrfs_ordered_sum_size(fs_info, + bytes_left), GFP_KERNEL); + memalloc_nofs_restore(nofs_flag); +- BUG_ON(!sums); /* -ENOMEM */ ++ if (!sums) ++ return BLK_STS_RESOURCE; ++ + sums->len = bytes_left; + ordered = btrfs_lookup_ordered_extent(inode, + offset); +-- +2.39.2 + diff --git a/queue-5.15/btrfs-scrub-try-harder-to-mark-raid56-block-groups-r.patch b/queue-5.15/btrfs-scrub-try-harder-to-mark-raid56-block-groups-r.patch new file mode 100644 index 00000000000..cb997ab701e --- /dev/null +++ b/queue-5.15/btrfs-scrub-try-harder-to-mark-raid56-block-groups-r.patch @@ -0,0 +1,95 @@ +From d7c2b1c5ea6f251045821698f4a7dd49fabc04ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Apr 2023 13:57:17 +0800 +Subject: btrfs: scrub: try harder to mark RAID56 block groups read-only + +From: Qu Wenruo + +[ Upstream commit 7561551e7ba870b9659083b95feb520fb2dacce3 ] + +Currently we allow a block group not to be marked read-only for scrub. + +But for RAID56 block groups if we require the block group to be +read-only, then we're allowed to use cached content from scrub stripe to +reduce unnecessary RAID56 reads. + +So this patch would: + +- Make btrfs_inc_block_group_ro() try harder + During my tests, for cases like btrfs/061 and btrfs/064, we can hit + ENOSPC from btrfs_inc_block_group_ro() calls during scrub. + + The reason is if we only have one single data chunk, and trying to + scrub it, we won't have any space left for any newer data writes. + + But this check should be done by the caller, especially for scrub + cases we only temporarily mark the chunk read-only. + And newer data writes would always try to allocate a new data chunk + when needed. + +- Return error for scrub if we failed to mark a RAID56 chunk read-only + +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 14 ++++++++++++-- + fs/btrfs/scrub.c | 9 ++++++++- + 2 files changed, 20 insertions(+), 3 deletions(-) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 19f71c305b988..a76796f153d5f 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -2576,10 +2576,20 @@ int btrfs_inc_block_group_ro(struct btrfs_block_group *cache, + } + + ret = inc_block_group_ro(cache, 0); +- if (!do_chunk_alloc || ret == -ETXTBSY) +- goto unlock_out; + if (!ret) + goto out; ++ if (ret == -ETXTBSY) ++ goto unlock_out; ++ ++ /* ++ * Skip chunk alloction if the bg is SYSTEM, this is to avoid system ++ * chunk allocation storm to exhaust the system chunk array. Otherwise ++ * we still want to try our best to mark the block group read-only. ++ */ ++ if (!do_chunk_alloc && ret == -ENOSPC && ++ (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM)) ++ goto unlock_out; ++ + alloc_flags = btrfs_get_alloc_profile(fs_info, cache->space_info->flags); + ret = btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE); + if (ret < 0) +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index ca8d6979c7887..0d1715ebdef9c 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -3812,13 +3812,20 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, + + if (ret == 0) { + ro_set = 1; +- } else if (ret == -ENOSPC && !sctx->is_dev_replace) { ++ } else if (ret == -ENOSPC && !sctx->is_dev_replace && ++ !(cache->flags & BTRFS_BLOCK_GROUP_RAID56_MASK)) { + /* + * btrfs_inc_block_group_ro return -ENOSPC when it + * failed in creating new chunk for metadata. + * It is not a problem for scrub, because + * metadata are always cowed, and our scrub paused + * commit_transactions. ++ * ++ * For RAID56 chunks, we have to mark them read-only ++ * for scrub, as later we would use our own cache ++ * out of RAID56 realm. ++ * Thus we want the RAID56 bg to be marked RO to ++ * prevent RMW from screwing up out cache. + */ + ro_set = 0; + } else if (ret == -ETXTBSY) { +-- +2.39.2 + diff --git a/queue-5.15/drm-amd-amdgpu-fix-missing-buffer-object-unlock-in-f.patch b/queue-5.15/drm-amd-amdgpu-fix-missing-buffer-object-unlock-in-f.patch new file mode 100644 index 00000000000..f1607a71f89 --- /dev/null +++ b/queue-5.15/drm-amd-amdgpu-fix-missing-buffer-object-unlock-in-f.patch @@ -0,0 +1,59 @@ +From e59b56dcb8fd2ff4b9ed5816a041f173d37375bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 May 2023 16:15:07 -0700 +Subject: drm:amd:amdgpu: Fix missing buffer object unlock in failure path + +From: Sukrut Bellary + +[ Upstream commit 60ecaaf54886b0642d5c4744f7fbf1ff0d6b3e42 ] + +smatch warning - +1) drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c:3615 gfx_v9_0_kiq_resume() +warn: inconsistent returns 'ring->mqd_obj->tbo.base.resv'. + +2) drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:6901 gfx_v10_0_kiq_resume() +warn: inconsistent returns 'ring->mqd_obj->tbo.base.resv'. + +Signed-off-by: Sukrut Bellary +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 4 +++- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 4 +++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +index 9da0d5d6d73d8..938f13956aeef 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +@@ -7197,8 +7197,10 @@ static int gfx_v10_0_kiq_resume(struct amdgpu_device *adev) + return r; + + r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr); +- if (unlikely(r != 0)) ++ if (unlikely(r != 0)) { ++ amdgpu_bo_unreserve(ring->mqd_obj); + return r; ++ } + + gfx_v10_0_kiq_init_queue(ring); + amdgpu_bo_kunmap(ring->mqd_obj); +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +index 5f325ded7f752..de1fab165041f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -3871,8 +3871,10 @@ static int gfx_v9_0_kiq_resume(struct amdgpu_device *adev) + return r; + + r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr); +- if (unlikely(r != 0)) ++ if (unlikely(r != 0)) { ++ amdgpu_bo_unreserve(ring->mqd_obj); + return r; ++ } + + gfx_v9_0_kiq_init_queue(ring); + amdgpu_bo_kunmap(ring->mqd_obj); +-- +2.39.2 + diff --git a/queue-5.15/irqchip-gic-correctly-validate-of-quirk-descriptors.patch b/queue-5.15/irqchip-gic-correctly-validate-of-quirk-descriptors.patch new file mode 100644 index 00000000000..9ee21511591 --- /dev/null +++ b/queue-5.15/irqchip-gic-correctly-validate-of-quirk-descriptors.patch @@ -0,0 +1,41 @@ +From 6dea94272466fc7fa767aa26c678ea782bd96ff1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 May 2023 11:01:22 +0100 +Subject: irqchip/gic: Correctly validate OF quirk descriptors + +From: Marc Zyngier + +[ Upstream commit 91539341a3b6e9c868024a4292455dae36e6f58c ] + +When checking for OF quirks, make sure either 'compatible' or 'property' +is set, and give up otherwise. + +This avoids non-OF quirks being randomly applied as they don't have any +of the OF data that need checking. + +Cc: Douglas Anderson +Reported-by: Geert Uytterhoeven +Tested-by: Geert Uytterhoeven +Fixes: 44bd78dd2b88 ("irqchip/gic-v3: Disable pseudo NMIs on Mediatek devices w/ firmware issues") +Signed-off-by: Marc Zyngier +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-gic-common.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c +index de47b51cdadbe..afd6a1841715a 100644 +--- a/drivers/irqchip/irq-gic-common.c ++++ b/drivers/irqchip/irq-gic-common.c +@@ -16,6 +16,8 @@ void gic_enable_of_quirks(const struct device_node *np, + const struct gic_quirk *quirks, void *data) + { + for (; quirks->desc; quirks++) { ++ if (!quirks->compatible && !quirks->property) ++ continue; + if (quirks->compatible && + !of_device_is_compatible(np, quirks->compatible)) + continue; +-- +2.39.2 + diff --git a/queue-5.15/irqchip-gic-v3-disable-pseudo-nmis-on-mediatek-devic.patch b/queue-5.15/irqchip-gic-v3-disable-pseudo-nmis-on-mediatek-devic.patch new file mode 100644 index 00000000000..b05f2f7bf06 --- /dev/null +++ b/queue-5.15/irqchip-gic-v3-disable-pseudo-nmis-on-mediatek-devic.patch @@ -0,0 +1,138 @@ +From 44176898974e548e21e8c7b355cf1baa45e4f066 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 May 2023 13:13:51 -0700 +Subject: irqchip/gic-v3: Disable pseudo NMIs on Mediatek devices w/ firmware + issues + +From: Douglas Anderson + +[ Upstream commit 44bd78dd2b8897f59b7e3963f088caadb7e4f047 ] + +Some Chromebooks with Mediatek SoCs have a problem where the firmware +doesn't properly save/restore certain GICR registers. Newer +Chromebooks should fix this issue and we may be able to do firmware +updates for old Chromebooks. At the moment, the only known issue with +these Chromebooks is that we can't enable "pseudo NMIs" since the +priority register can be lost. Enabling "pseudo NMIs" on Chromebooks +with the problematic firmware causes crashes and freezes. + +Let's detect devices with this problem and then disable "pseudo NMIs" +on them. We'll detect the problem by looking for the presence of the +"mediatek,broken-save-restore-fw" property in the GIC device tree +node. Any devices with fixed firmware will not have this property. + +Our detection plan works because we never bake a Chromebook's device +tree into firmware. Instead, device trees are always bundled with the +kernel. We'll update the device trees of all affected Chromebooks and +then we'll never enable "pseudo NMI" on a kernel that is bundled with +old device trees. When a firmware update is shipped that fixes this +issue it will know to patch the device tree to remove the property. + +In order to make this work, the quick detection mechanism of the GICv3 +code is extended to be able to look for properties in addition to +looking at "compatible". + +Reviewed-by: Julius Werner +Signed-off-by: Douglas Anderson +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20230515131353.v2.2.I88dc0a0eb1d9d537de61604cd8994ecc55c0cac1@changeid +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-gic-common.c | 8 ++++++-- + drivers/irqchip/irq-gic-common.h | 1 + + drivers/irqchip/irq-gic-v3.c | 20 ++++++++++++++++++++ + 3 files changed, 27 insertions(+), 2 deletions(-) + +diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c +index a610821c8ff2a..de47b51cdadbe 100644 +--- a/drivers/irqchip/irq-gic-common.c ++++ b/drivers/irqchip/irq-gic-common.c +@@ -16,7 +16,11 @@ void gic_enable_of_quirks(const struct device_node *np, + const struct gic_quirk *quirks, void *data) + { + for (; quirks->desc; quirks++) { +- if (!of_device_is_compatible(np, quirks->compatible)) ++ if (quirks->compatible && ++ !of_device_is_compatible(np, quirks->compatible)) ++ continue; ++ if (quirks->property && ++ !of_property_read_bool(np, quirks->property)) + continue; + if (quirks->init(data)) + pr_info("GIC: enabling workaround for %s\n", +@@ -28,7 +32,7 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks, + void *data) + { + for (; quirks->desc; quirks++) { +- if (quirks->compatible) ++ if (quirks->compatible || quirks->property) + continue; + if (quirks->iidr != (quirks->mask & iidr)) + continue; +diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h +index 27e3d4ed4f328..3db4592cda1c0 100644 +--- a/drivers/irqchip/irq-gic-common.h ++++ b/drivers/irqchip/irq-gic-common.h +@@ -13,6 +13,7 @@ + struct gic_quirk { + const char *desc; + const char *compatible; ++ const char *property; + bool (*init)(void *data); + u32 iidr; + u32 mask; +diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c +index 9507989bf2e1e..500e0c6d17f61 100644 +--- a/drivers/irqchip/irq-gic-v3.c ++++ b/drivers/irqchip/irq-gic-v3.c +@@ -35,6 +35,7 @@ + + #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0) + #define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1) ++#define FLAGS_WORKAROUND_MTK_GICR_SAVE (1ULL << 2) + + #define GIC_IRQ_TYPE_PARTITION (GIC_IRQ_TYPE_LPI + 1) + +@@ -1646,6 +1647,15 @@ static bool gic_enable_quirk_msm8996(void *data) + return true; + } + ++static bool gic_enable_quirk_mtk_gicr(void *data) ++{ ++ struct gic_chip_data *d = data; ++ ++ d->flags |= FLAGS_WORKAROUND_MTK_GICR_SAVE; ++ ++ return true; ++} ++ + static bool gic_enable_quirk_cavium_38539(void *data) + { + struct gic_chip_data *d = data; +@@ -1681,6 +1691,11 @@ static const struct gic_quirk gic_quirks[] = { + .compatible = "qcom,msm8996-gic-v3", + .init = gic_enable_quirk_msm8996, + }, ++ { ++ .desc = "GICv3: Mediatek Chromebook GICR save problem", ++ .property = "mediatek,broken-save-restore-fw", ++ .init = gic_enable_quirk_mtk_gicr, ++ }, + { + .desc = "GICv3: HIP06 erratum 161010803", + .iidr = 0x0204043b, +@@ -1717,6 +1732,11 @@ static void gic_enable_nmi_support(void) + if (!gic_prio_masking_enabled()) + return; + ++ if (gic_data.flags & FLAGS_WORKAROUND_MTK_GICR_SAVE) { ++ pr_warn("Skipping NMI enable due to firmware issues\n"); ++ return; ++ } ++ + ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL); + if (!ppi_nmi_refs) + return; +-- +2.39.2 + diff --git a/queue-5.15/mips-alchemy-fix-dbdma2.patch b/queue-5.15/mips-alchemy-fix-dbdma2.patch new file mode 100644 index 00000000000..26f7a7ac24e --- /dev/null +++ b/queue-5.15/mips-alchemy-fix-dbdma2.patch @@ -0,0 +1,87 @@ +From 27317503f6557c8a9a1cabb5771df8fe9e7115fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 May 2023 17:30:10 +0200 +Subject: MIPS: Alchemy: fix dbdma2 + +From: Manuel Lauss + +[ Upstream commit 2d645604f69f3a772d58ead702f9a8e84ab2b342 ] + +Various fixes for the Au1200/Au1550/Au1300 DBDMA2 code: + +- skip cache invalidation if chip has working coherency circuitry. +- invalidate KSEG0-portion of the (physical) data address. +- force the dma channel doorbell write out to bus immediately with + a sync. + +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/alchemy/common/dbdma.c | 27 +++++++++++++++------------ + 1 file changed, 15 insertions(+), 12 deletions(-) + +diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c +index 4ca2c28878e0f..e9ee9ab90a0c6 100644 +--- a/arch/mips/alchemy/common/dbdma.c ++++ b/arch/mips/alchemy/common/dbdma.c +@@ -30,6 +30,7 @@ + * + */ + ++#include /* for dma_default_coherent */ + #include + #include + #include +@@ -623,17 +624,18 @@ u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) + dp->dscr_cmd0 &= ~DSCR_CMD0_IE; + + /* +- * There is an errata on the Au1200/Au1550 parts that could result +- * in "stale" data being DMA'ed. It has to do with the snoop logic on +- * the cache eviction buffer. DMA_NONCOHERENT is on by default for +- * these parts. If it is fixed in the future, these dma_cache_inv will +- * just be nothing more than empty macros. See io.h. ++ * There is an erratum on certain Au1200/Au1550 revisions that could ++ * result in "stale" data being DMA'ed. It has to do with the snoop ++ * logic on the cache eviction buffer. dma_default_coherent is set ++ * to false on these parts. + */ +- dma_cache_wback_inv((unsigned long)buf, nbytes); ++ if (!dma_default_coherent) ++ dma_cache_wback_inv(KSEG0ADDR(buf), nbytes); + dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ + wmb(); /* drain writebuffer */ + dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); + ctp->chan_ptr->ddma_dbell = 0; ++ wmb(); /* force doorbell write out to dma engine */ + + /* Get next descriptor pointer. */ + ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); +@@ -685,17 +687,18 @@ u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) + dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1); + #endif + /* +- * There is an errata on the Au1200/Au1550 parts that could result in +- * "stale" data being DMA'ed. It has to do with the snoop logic on the +- * cache eviction buffer. DMA_NONCOHERENT is on by default for these +- * parts. If it is fixed in the future, these dma_cache_inv will just +- * be nothing more than empty macros. See io.h. ++ * There is an erratum on certain Au1200/Au1550 revisions that could ++ * result in "stale" data being DMA'ed. It has to do with the snoop ++ * logic on the cache eviction buffer. dma_default_coherent is set ++ * to false on these parts. + */ +- dma_cache_inv((unsigned long)buf, nbytes); ++ if (!dma_default_coherent) ++ dma_cache_inv(KSEG0ADDR(buf), nbytes); + dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ + wmb(); /* drain writebuffer */ + dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); + ctp->chan_ptr->ddma_dbell = 0; ++ wmb(); /* force doorbell write out to dma engine */ + + /* Get next descriptor pointer. */ + ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); +-- +2.39.2 + diff --git a/queue-5.15/mips-move-initrd_start-check-after-initrd-address-sa.patch b/queue-5.15/mips-move-initrd_start-check-after-initrd-address-sa.patch new file mode 100644 index 00000000000..c8fec01c9df --- /dev/null +++ b/queue-5.15/mips-move-initrd_start-check-after-initrd-address-sa.patch @@ -0,0 +1,52 @@ +From cbe822196fef848840b99eef7036f75d8cfe5444 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 May 2023 18:29:21 +0100 +Subject: mips: Move initrd_start check after initrd address sanitisation. + +From: Liviu Dudau + +[ Upstream commit 4897a898a216058dec55e5e5902534e6e224fcdf ] + +PAGE_OFFSET is technically a virtual address so when checking the value of +initrd_start against it we should make sure that it has been sanitised from +the values passed by the bootloader. Without this change, even with a bootloader +that passes correct addresses for an initrd, we are failing to load it on MT7621 +boards, for example. + +Signed-off-by: Liviu Dudau +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/kernel/setup.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c +index ef73ba1e0ec10..c8d849d8a8440 100644 +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -156,10 +156,6 @@ static unsigned long __init init_initrd(void) + pr_err("initrd start must be page aligned\n"); + goto disable; + } +- if (initrd_start < PAGE_OFFSET) { +- pr_err("initrd start < PAGE_OFFSET\n"); +- goto disable; +- } + + /* + * Sanitize initrd addresses. For example firmware +@@ -172,6 +168,11 @@ static unsigned long __init init_initrd(void) + initrd_end = (unsigned long)__va(end); + initrd_start = (unsigned long)__va(__pa(initrd_start)); + ++ if (initrd_start < PAGE_OFFSET) { ++ pr_err("initrd start < PAGE_OFFSET\n"); ++ goto disable; ++ } ++ + ROOT_DEV = Root_RAM0; + return PFN_UP(end); + disable: +-- +2.39.2 + diff --git a/queue-5.15/mips-restore-au1300-support.patch b/queue-5.15/mips-restore-au1300-support.patch new file mode 100644 index 00000000000..4507f61f3c7 --- /dev/null +++ b/queue-5.15/mips-restore-au1300-support.patch @@ -0,0 +1,48 @@ +From 599caaf5f2a1b25fdb4bdd5dc4221d576aa90f97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 May 2023 12:33:23 +0200 +Subject: MIPS: Restore Au1300 support + +From: Manuel Lauss + +[ Upstream commit f2041708dee30a3425f680265c337acd28293782 ] + +The Au1300, at least the one I have to test, uses the NetLogic vendor +ID, but commit 95b8a5e0111a ("MIPS: Remove NETLOGIC support") also +dropped Au1300 detection. Restore Au1300 detection. + +Tested on DB1300 with Au1380 chip. + +Signed-off-by: Manuel Lauss +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/kernel/cpu-probe.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c +index 7c861e6a89529..df40880d84495 100644 +--- a/arch/mips/kernel/cpu-probe.c ++++ b/arch/mips/kernel/cpu-probe.c +@@ -1565,6 +1565,10 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu) + break; + } + break; ++ case PRID_IMP_NETLOGIC_AU13XX: ++ c->cputype = CPU_ALCHEMY; ++ __cpu_name[cpu] = "Au1300"; ++ break; + } + } + +@@ -2005,6 +2009,7 @@ void cpu_probe(void) + cpu_probe_mips(c, cpu); + break; + case PRID_COMP_ALCHEMY: ++ case PRID_COMP_NETLOGIC: + cpu_probe_alchemy(c, cpu); + break; + case PRID_COMP_SIBYTE: +-- +2.39.2 + diff --git a/queue-5.15/mips-unhide-pata_platform.patch b/queue-5.15/mips-unhide-pata_platform.patch new file mode 100644 index 00000000000..d95221db2f1 --- /dev/null +++ b/queue-5.15/mips-unhide-pata_platform.patch @@ -0,0 +1,34 @@ +From d00e455d39ceb63f1b559af7a0921c1756f356a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 May 2023 20:57:44 +0200 +Subject: MIPS: unhide PATA_PLATFORM + +From: Manuel Lauss + +[ Upstream commit 75b18aac6fa39a1720677970cfcb52ecea1eb44c ] + +Alchemy DB1200/DB1300 boards can use the pata_platform driver. +Unhide the config entry in all of MIPS. + +Signed-off-by: Manuel Lauss +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index 393eb2133243f..56c0f75e7a76e 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -81,6 +81,7 @@ config MIPS + select HAVE_LD_DEAD_CODE_DATA_ELIMINATION + select HAVE_MOD_ARCH_SPECIFIC + select HAVE_NMI ++ select HAVE_PATA_PLATFORM + select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP +-- +2.39.2 + diff --git a/queue-5.15/nvme-add-maxio-1602-to-bogus-nid-list.patch b/queue-5.15/nvme-add-maxio-1602-to-bogus-nid-list.patch new file mode 100644 index 00000000000..3fd180ac46c --- /dev/null +++ b/queue-5.15/nvme-add-maxio-1602-to-bogus-nid-list.patch @@ -0,0 +1,71 @@ +From 93c620734425f98aae0cb794f4aa53c0e5b0514c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 20 May 2023 21:23:50 +0900 +Subject: NVMe: Add MAXIO 1602 to bogus nid list. + +From: Tatsuki Sugiura + +[ Upstream commit a3a9d63dcd15535e7fdf4c7c1b32bfaed762973a ] + +HIKSEMI FUTURE M.2 SSD uses the same dummy nguid and eui64. +I confirmed it with my two devices. + +This patch marks the controller as NVME_QUIRK_BOGUS_NID. + +--------------------------------------------------------- +sugi@tempest:~% sudo nvme id-ctrl /dev/nvme0 +NVME Identify Controller: +vid : 0x1e4b +ssvid : 0x1e4b +sn : 30096022612 +mn : HS-SSD-FUTURE 2048G +fr : SN10542 +rab : 0 +ieee : 000000 +cmic : 0 +mdts : 7 +cntlid : 0 +ver : 0x10400 +rtd3r : 0x7a120 +rtd3e : 0x1e8480 +oaes : 0x200 +ctratt : 0x2 +rrls : 0 +cntrltype : 1 +fguid : 00000000-0000-0000-0000-000000000000 + +--------------------------------------------------------- + +--------------------------------------------------------- +sugi@tempest:~% sudo nvme id-ns /dev/nvme0n1 +NVME Identify Namespace 1: + +nguid : 00000000000000000000000000000000 +eui64 : 0000000000000002 +lbaf 0 : ms:0 lbads:9 rp:0 (in use) +--------------------------------------------------------- + +Signed-off-by: Tatsuki Sugiura +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index d04c06e07fbb2..a646757f76b34 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3390,6 +3390,8 @@ static const struct pci_device_id nvme_id_table[] = { + .driver_data = NVME_QUIRK_BOGUS_NID, }, + { PCI_DEVICE(0x1e4B, 0x1202), /* MAXIO MAP1202 */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, ++ { PCI_DEVICE(0x1e4B, 0x1602), /* MAXIO MAP1602 */ ++ .driver_data = NVME_QUIRK_BOGUS_NID, }, + { PCI_DEVICE(0x1cc1, 0x5350), /* ADATA XPG GAMMIX S50 */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, + { PCI_DEVICE(0x1e49, 0x0021), /* ZHITAI TiPro5000 NVMe SSD */ +-- +2.39.2 + diff --git a/queue-5.15/of-overlay-fix-missing-of_node_put-in-error-case-of-.patch b/queue-5.15/of-overlay-fix-missing-of_node_put-in-error-case-of-.patch new file mode 100644 index 00000000000..935e51535ce --- /dev/null +++ b/queue-5.15/of-overlay-fix-missing-of_node_put-in-error-case-of-.patch @@ -0,0 +1,37 @@ +From ce327b8514a21adc4de6c53d04d328fe25d1b7ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Jun 2023 11:05:02 +0900 +Subject: of: overlay: Fix missing of_node_put() in error case of + init_overlay_changeset() + +From: Kunihiko Hayashi + +[ Upstream commit 39affd1fdf65983904fafc07cf607cff737eaf30 ] + +In init_overlay_changeset(), the variable "node" is from +of_get_child_by_name(), and the "node" should be discarded in error case. + +Fixes: d1651b03c2df ("of: overlay: add overlay symbols to live device tree") +Signed-off-by: Kunihiko Hayashi +Link: https://lore.kernel.org/r/20230602020502.11693-1-hayashi.kunihiko@socionext.com +Signed-off-by: Rob Herring +Signed-off-by: Sasha Levin +--- + drivers/of/overlay.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c +index 119dd6a0be868..74dd63089bb46 100644 +--- a/drivers/of/overlay.c ++++ b/drivers/of/overlay.c +@@ -818,6 +818,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs) + if (!fragment->target) { + pr_err("symbols in overlay, but not in live tree\n"); + ret = -EINVAL; ++ of_node_put(node); + goto err_out; + } + +-- +2.39.2 + diff --git a/queue-5.15/of-overlay-rename-variables-to-be-consistent.patch b/queue-5.15/of-overlay-rename-variables-to-be-consistent.patch new file mode 100644 index 00000000000..8706141be2e --- /dev/null +++ b/queue-5.15/of-overlay-rename-variables-to-be-consistent.patch @@ -0,0 +1,270 @@ +From bf1f19542d9f57e34cc0f34ce805161b05b3e66b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Apr 2022 17:25:04 -0500 +Subject: of: overlay: rename variables to be consistent + +From: Frank Rowand + +[ Upstream commit 1e4089667c7c732dd1b92c4c6bc7bd240ca30213 ] + +Variables change name across function calls when there is not a good +reason to do so. Fix by changing "fdt" to "new_fdt" and "tree" to +"overlay_root". + +The name disparity was confusing when creating the following commit. +The name changes are in this separate commit to make review of the +following commmit less complex. + +Signed-off-by: Frank Rowand +Signed-off-by: Rob Herring +Link: https://lore.kernel.org/r/20220420222505.928492-2-frowand.list@gmail.com +Stable-dep-of: 39affd1fdf65 ("of: overlay: Fix missing of_node_put() in error case of init_overlay_changeset()") +Signed-off-by: Sasha Levin +--- + drivers/of/overlay.c | 94 ++++++++++++++++++++++---------------------- + 1 file changed, 47 insertions(+), 47 deletions(-) + +diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c +index 424682372417d..56afef5594112 100644 +--- a/drivers/of/overlay.c ++++ b/drivers/of/overlay.c +@@ -57,8 +57,8 @@ struct fragment { + * struct overlay_changeset + * @id: changeset identifier + * @ovcs_list: list on which we are located +- * @fdt: base of memory allocated to hold aligned FDT that was unflattened to create @overlay_tree +- * @overlay_tree: expanded device tree that contains the fragment nodes ++ * @new_fdt: Memory allocated to hold unflattened aligned FDT ++ * @overlay_root: expanded device tree that contains the fragment nodes + * @count: count of fragment structures + * @fragments: fragment nodes in the overlay expanded device tree + * @symbols_fragment: last element of @fragments[] is the __symbols__ node +@@ -67,8 +67,8 @@ struct fragment { + struct overlay_changeset { + int id; + struct list_head ovcs_list; +- const void *fdt; +- struct device_node *overlay_tree; ++ const void *new_fdt; ++ struct device_node *overlay_root; + int count; + struct fragment *fragments; + bool symbols_fragment; +@@ -183,7 +183,7 @@ static int overlay_notify(struct overlay_changeset *ovcs, + + /* + * The values of properties in the "/__symbols__" node are paths in +- * the ovcs->overlay_tree. When duplicating the properties, the paths ++ * the ovcs->overlay_root. When duplicating the properties, the paths + * need to be adjusted to be the correct path for the live device tree. + * + * The paths refer to a node in the subtree of a fragment node's "__overlay__" +@@ -219,7 +219,7 @@ static struct property *dup_and_fixup_symbol_prop( + + if (path_len < 1) + return NULL; +- fragment_node = __of_find_node_by_path(ovcs->overlay_tree, path + 1); ++ fragment_node = __of_find_node_by_path(ovcs->overlay_root, path + 1); + overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/"); + of_node_put(fragment_node); + of_node_put(overlay_node); +@@ -716,19 +716,20 @@ static struct device_node *find_target(struct device_node *info_node) + + /** + * init_overlay_changeset() - initialize overlay changeset from overlay tree +- * @ovcs: Overlay changeset to build +- * @fdt: base of memory allocated to hold aligned FDT that was unflattened to create @tree +- * @tree: Contains the overlay fragments and overlay fixup nodes ++ * @ovcs: Overlay changeset to build ++ * @new_fdt: Memory allocated to hold unflattened aligned FDT ++ * @overlay_root: Contains the overlay fragments and overlay fixup nodes + * + * Initialize @ovcs. Populate @ovcs->fragments with node information from +- * the top level of @tree. The relevant top level nodes are the fragment +- * nodes and the __symbols__ node. Any other top level node will be ignored. ++ * the top level of @overlay_root. The relevant top level nodes are the ++ * fragment nodes and the __symbols__ node. Any other top level node will ++ * be ignored. + * + * Return: 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error +- * detected in @tree, or -ENOSPC if idr_alloc() error. ++ * detected in @overlay_root, or -ENOSPC if idr_alloc() error. + */ + static int init_overlay_changeset(struct overlay_changeset *ovcs, +- const void *fdt, struct device_node *tree) ++ const void *new_fdt, struct device_node *overlay_root) + { + struct device_node *node, *overlay_node; + struct fragment *fragment; +@@ -739,17 +740,17 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + * Warn for some issues. Can not return -EINVAL for these until + * of_unittest_apply_overlay() is fixed to pass these checks. + */ +- if (!of_node_check_flag(tree, OF_DYNAMIC)) +- pr_debug("%s() tree is not dynamic\n", __func__); ++ if (!of_node_check_flag(overlay_root, OF_DYNAMIC)) ++ pr_debug("%s() overlay_root is not dynamic\n", __func__); + +- if (!of_node_check_flag(tree, OF_DETACHED)) +- pr_debug("%s() tree is not detached\n", __func__); ++ if (!of_node_check_flag(overlay_root, OF_DETACHED)) ++ pr_debug("%s() overlay_root is not detached\n", __func__); + +- if (!of_node_is_root(tree)) +- pr_debug("%s() tree is not root\n", __func__); ++ if (!of_node_is_root(overlay_root)) ++ pr_debug("%s() overlay_root is not root\n", __func__); + +- ovcs->overlay_tree = tree; +- ovcs->fdt = fdt; ++ ovcs->overlay_root = overlay_root; ++ ovcs->new_fdt = new_fdt; + + INIT_LIST_HEAD(&ovcs->ovcs_list); + +@@ -762,7 +763,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + cnt = 0; + + /* fragment nodes */ +- for_each_child_of_node(tree, node) { ++ for_each_child_of_node(overlay_root, node) { + overlay_node = of_get_child_by_name(node, "__overlay__"); + if (overlay_node) { + cnt++; +@@ -770,7 +771,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + } + } + +- node = of_get_child_by_name(tree, "__symbols__"); ++ node = of_get_child_by_name(overlay_root, "__symbols__"); + if (node) { + cnt++; + of_node_put(node); +@@ -783,7 +784,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + } + + cnt = 0; +- for_each_child_of_node(tree, node) { ++ for_each_child_of_node(overlay_root, node) { + overlay_node = of_get_child_by_name(node, "__overlay__"); + if (!overlay_node) + continue; +@@ -805,7 +806,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + * if there is a symbols fragment in ovcs->fragments[i] it is + * the final element in the array + */ +- node = of_get_child_by_name(tree, "__symbols__"); ++ node = of_get_child_by_name(overlay_root, "__symbols__"); + if (node) { + ovcs->symbols_fragment = 1; + fragment = &fragments[cnt]; +@@ -859,12 +860,12 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) + } + kfree(ovcs->fragments); + /* +- * There should be no live pointers into ovcs->overlay_tree and +- * ovcs->fdt due to the policy that overlay notifiers are not allowed +- * to retain pointers into the overlay devicetree. ++ * There should be no live pointers into ovcs->overlay_root and ++ * ovcs->new_fdt due to the policy that overlay notifiers are not ++ * allowed to retain pointers into the overlay devicetree. + */ +- kfree(ovcs->overlay_tree); +- kfree(ovcs->fdt); ++ kfree(ovcs->overlay_root); ++ kfree(ovcs->new_fdt); + kfree(ovcs); + } + +@@ -872,16 +873,15 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) + * internal documentation + * + * of_overlay_apply() - Create and apply an overlay changeset +- * @fdt: base of memory allocated to hold the aligned FDT +- * @tree: Expanded overlay device tree +- * @ovcs_id: Pointer to overlay changeset id ++ * @new_fdt: Memory allocated to hold the aligned FDT ++ * @overlay_root: Expanded overlay device tree ++ * @ovcs_id: Pointer to overlay changeset id + * + * Creates and applies an overlay changeset. + * + * If an error occurs in a pre-apply notifier, then no changes are made + * to the device tree. + * +- + * A non-zero return value will not have created the changeset if error is from: + * - parameter checks + * - building the changeset +@@ -911,8 +911,8 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) + * id is returned to *ovcs_id. + */ + +-static int of_overlay_apply(const void *fdt, struct device_node *tree, +- int *ovcs_id) ++static int of_overlay_apply(const void *new_fdt, ++ struct device_node *overlay_root, int *ovcs_id) + { + struct overlay_changeset *ovcs; + int ret = 0, ret_revert, ret_tmp; +@@ -924,16 +924,16 @@ static int of_overlay_apply(const void *fdt, struct device_node *tree, + + if (devicetree_corrupt()) { + pr_err("devicetree state suspect, refuse to apply overlay\n"); +- kfree(fdt); +- kfree(tree); ++ kfree(new_fdt); ++ kfree(overlay_root); + ret = -EBUSY; + goto out; + } + + ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL); + if (!ovcs) { +- kfree(fdt); +- kfree(tree); ++ kfree(new_fdt); ++ kfree(overlay_root); + ret = -ENOMEM; + goto out; + } +@@ -941,20 +941,20 @@ static int of_overlay_apply(const void *fdt, struct device_node *tree, + of_overlay_mutex_lock(); + mutex_lock(&of_mutex); + +- ret = of_resolve_phandles(tree); ++ ret = of_resolve_phandles(overlay_root); + if (ret) + goto err_free_tree; + +- ret = init_overlay_changeset(ovcs, fdt, tree); ++ ret = init_overlay_changeset(ovcs, new_fdt, overlay_root); + if (ret) + goto err_free_tree; + + /* +- * after overlay_notify(), ovcs->overlay_tree related pointers may have ++ * After overlay_notify(), ovcs->overlay_root related pointers may have + * leaked to drivers, so can not kfree() tree, aka ovcs->overlay_tree; + * and can not free memory containing aligned fdt. The aligned fdt +- * is contained within the memory at ovcs->fdt, possibly at an offset +- * from ovcs->fdt. ++ * is contained within the memory at ovcs->new_fdt, possibly at an ++ * offset from ovcs->new_fdt. + */ + ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY); + if (ret) { +@@ -996,8 +996,8 @@ static int of_overlay_apply(const void *fdt, struct device_node *tree, + goto out_unlock; + + err_free_tree: +- kfree(fdt); +- kfree(tree); ++ kfree(new_fdt); ++ kfree(overlay_root); + + err_free_overlay_changeset: + free_overlay_changeset(ovcs); +-- +2.39.2 + diff --git a/queue-5.15/of-overlay-rework-overlay-apply-and-remove-kfree-s.patch b/queue-5.15/of-overlay-rework-overlay-apply-and-remove-kfree-s.patch new file mode 100644 index 00000000000..814aa3a1eea --- /dev/null +++ b/queue-5.15/of-overlay-rework-overlay-apply-and-remove-kfree-s.patch @@ -0,0 +1,635 @@ +From b25174708f96e76a1f72ddf249a00a545ea42561 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Apr 2022 17:25:05 -0500 +Subject: of: overlay: rework overlay apply and remove kfree()s + +From: Frank Rowand + +[ Upstream commit 067c098766c6af667a9002d4e33cf1f3c998abbe ] + +Fix various kfree() issues related to of_overlay_apply(). + - Double kfree() of fdt and tree when init_overlay_changeset() + returns an error. + - free_overlay_changeset() free the root of the unflattened + overlay (variable tree) instead of the memory that contains + the unflattened overlay. + - For the case of a failure during applying an overlay, move kfree() + of new_fdt and overlay_mem into free_overlay_changeset(), which + is called by the function that allocated them. + - For the case of removing an overlay, the kfree() of new_fdt and + overlay_mem remains in free_overlay_changeset(). + - Check return value of of_fdt_unflatten_tree() for error instead + of checking the returned value of overlay_root. + - When storing pointers to allocated objects in ovcs, do so as + near to the allocation as possible instead of in deeply layered + function. + +More clearly document policy related to lifetime of pointers into +overlay memory. + +Double kfree() +Reported-by: Slawomir Stepien + +Signed-off-by: Frank Rowand +Signed-off-by: Rob Herring +Link: https://lore.kernel.org/r/20220420222505.928492-3-frowand.list@gmail.com +Stable-dep-of: 39affd1fdf65 ("of: overlay: Fix missing of_node_put() in error case of init_overlay_changeset()") +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/overlay-notes.rst | 30 ++- + drivers/of/overlay.c | 263 ++++++++++----------- + include/linux/of.h | 3 +- + 3 files changed, 153 insertions(+), 143 deletions(-) + +diff --git a/Documentation/devicetree/overlay-notes.rst b/Documentation/devicetree/overlay-notes.rst +index b2b8db765b8c6..e139f22b363e9 100644 +--- a/Documentation/devicetree/overlay-notes.rst ++++ b/Documentation/devicetree/overlay-notes.rst +@@ -119,10 +119,32 @@ Finally, if you need to remove all overlays in one-go, just call + of_overlay_remove_all() which will remove every single one in the correct + order. + +-In addition, there is the option to register notifiers that get called on ++There is the option to register notifiers that get called on + overlay operations. See of_overlay_notifier_register/unregister and + enum of_overlay_notify_action for details. + +-Note that a notifier callback is not supposed to store pointers to a device +-tree node or its content beyond OF_OVERLAY_POST_REMOVE corresponding to the +-respective node it received. ++A notifier callback for OF_OVERLAY_PRE_APPLY, OF_OVERLAY_POST_APPLY, or ++OF_OVERLAY_PRE_REMOVE may store pointers to a device tree node in the overlay ++or its content but these pointers must not persist past the notifier callback ++for OF_OVERLAY_POST_REMOVE. The memory containing the overlay will be ++kfree()ed after OF_OVERLAY_POST_REMOVE notifiers are called. Note that the ++memory will be kfree()ed even if the notifier for OF_OVERLAY_POST_REMOVE ++returns an error. ++ ++The changeset notifiers in drivers/of/dynamic.c are a second type of notifier ++that could be triggered by applying or removing an overlay. These notifiers ++are not allowed to store pointers to a device tree node in the overlay ++or its content. The overlay code does not protect against such pointers ++remaining active when the memory containing the overlay is freed as a result ++of removing the overlay. ++ ++Any other code that retains a pointer to the overlay nodes or data is ++considered to be a bug because after removing the overlay the pointer ++will refer to freed memory. ++ ++Users of overlays must be especially aware of the overall operations that ++occur on the system to ensure that other kernel code does not retain any ++pointers to the overlay nodes or data. Any example of an inadvertent use ++of such pointers is if a driver or subsystem module is loaded after an ++overlay has been applied, and the driver or subsystem scans the entire ++devicetree or a large portion of it, including the overlay nodes. +diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c +index 56afef5594112..119dd6a0be868 100644 +--- a/drivers/of/overlay.c ++++ b/drivers/of/overlay.c +@@ -58,7 +58,9 @@ struct fragment { + * @id: changeset identifier + * @ovcs_list: list on which we are located + * @new_fdt: Memory allocated to hold unflattened aligned FDT ++ * @overlay_mem: the memory chunk that contains @overlay_root + * @overlay_root: expanded device tree that contains the fragment nodes ++ * @notify_state: most recent notify action used on overlay + * @count: count of fragment structures + * @fragments: fragment nodes in the overlay expanded device tree + * @symbols_fragment: last element of @fragments[] is the __symbols__ node +@@ -68,7 +70,9 @@ struct overlay_changeset { + int id; + struct list_head ovcs_list; + const void *new_fdt; ++ const void *overlay_mem; + struct device_node *overlay_root; ++ enum of_overlay_notify_action notify_state; + int count; + struct fragment *fragments; + bool symbols_fragment; +@@ -115,7 +119,6 @@ void of_overlay_mutex_unlock(void) + mutex_unlock(&of_overlay_phandle_mutex); + } + +- + static LIST_HEAD(ovcs_list); + static DEFINE_IDR(ovcs_idr); + +@@ -162,6 +165,8 @@ static int overlay_notify(struct overlay_changeset *ovcs, + struct of_overlay_notify_data nd; + int i, ret; + ++ ovcs->notify_state = action; ++ + for (i = 0; i < ovcs->count; i++) { + struct fragment *fragment = &ovcs->fragments[i]; + +@@ -717,53 +722,49 @@ static struct device_node *find_target(struct device_node *info_node) + /** + * init_overlay_changeset() - initialize overlay changeset from overlay tree + * @ovcs: Overlay changeset to build +- * @new_fdt: Memory allocated to hold unflattened aligned FDT +- * @overlay_root: Contains the overlay fragments and overlay fixup nodes + * + * Initialize @ovcs. Populate @ovcs->fragments with node information from + * the top level of @overlay_root. The relevant top level nodes are the + * fragment nodes and the __symbols__ node. Any other top level node will +- * be ignored. ++ * be ignored. Populate other @ovcs fields. + * + * Return: 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error +- * detected in @overlay_root, or -ENOSPC if idr_alloc() error. ++ * detected in @overlay_root. On error return, the caller of ++ * init_overlay_changeset() must call free_overlay_changeset(). + */ +-static int init_overlay_changeset(struct overlay_changeset *ovcs, +- const void *new_fdt, struct device_node *overlay_root) ++static int init_overlay_changeset(struct overlay_changeset *ovcs) + { + struct device_node *node, *overlay_node; + struct fragment *fragment; + struct fragment *fragments; +- int cnt, id, ret; ++ int cnt, ret; ++ ++ /* ++ * None of the resources allocated by this function will be freed in ++ * the error paths. Instead the caller of this function is required ++ * to call free_overlay_changeset() (which will free the resources) ++ * if error return. ++ */ + + /* + * Warn for some issues. Can not return -EINVAL for these until + * of_unittest_apply_overlay() is fixed to pass these checks. + */ +- if (!of_node_check_flag(overlay_root, OF_DYNAMIC)) +- pr_debug("%s() overlay_root is not dynamic\n", __func__); ++ if (!of_node_check_flag(ovcs->overlay_root, OF_DYNAMIC)) ++ pr_debug("%s() ovcs->overlay_root is not dynamic\n", __func__); + +- if (!of_node_check_flag(overlay_root, OF_DETACHED)) +- pr_debug("%s() overlay_root is not detached\n", __func__); ++ if (!of_node_check_flag(ovcs->overlay_root, OF_DETACHED)) ++ pr_debug("%s() ovcs->overlay_root is not detached\n", __func__); + +- if (!of_node_is_root(overlay_root)) +- pr_debug("%s() overlay_root is not root\n", __func__); +- +- ovcs->overlay_root = overlay_root; +- ovcs->new_fdt = new_fdt; +- +- INIT_LIST_HEAD(&ovcs->ovcs_list); ++ if (!of_node_is_root(ovcs->overlay_root)) ++ pr_debug("%s() ovcs->overlay_root is not root\n", __func__); + + of_changeset_init(&ovcs->cset); + +- id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL); +- if (id <= 0) +- return id; +- + cnt = 0; + + /* fragment nodes */ +- for_each_child_of_node(overlay_root, node) { ++ for_each_child_of_node(ovcs->overlay_root, node) { + overlay_node = of_get_child_by_name(node, "__overlay__"); + if (overlay_node) { + cnt++; +@@ -771,7 +772,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + } + } + +- node = of_get_child_by_name(overlay_root, "__symbols__"); ++ node = of_get_child_by_name(ovcs->overlay_root, "__symbols__"); + if (node) { + cnt++; + of_node_put(node); +@@ -780,11 +781,12 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL); + if (!fragments) { + ret = -ENOMEM; +- goto err_free_idr; ++ goto err_out; + } ++ ovcs->fragments = fragments; + + cnt = 0; +- for_each_child_of_node(overlay_root, node) { ++ for_each_child_of_node(ovcs->overlay_root, node) { + overlay_node = of_get_child_by_name(node, "__overlay__"); + if (!overlay_node) + continue; +@@ -796,7 +798,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + of_node_put(fragment->overlay); + ret = -EINVAL; + of_node_put(node); +- goto err_free_fragments; ++ goto err_out; + } + + cnt++; +@@ -806,7 +808,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + * if there is a symbols fragment in ovcs->fragments[i] it is + * the final element in the array + */ +- node = of_get_child_by_name(overlay_root, "__symbols__"); ++ node = of_get_child_by_name(ovcs->overlay_root, "__symbols__"); + if (node) { + ovcs->symbols_fragment = 1; + fragment = &fragments[cnt]; +@@ -816,7 +818,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + if (!fragment->target) { + pr_err("symbols in overlay, but not in live tree\n"); + ret = -EINVAL; +- goto err_free_fragments; ++ goto err_out; + } + + cnt++; +@@ -825,20 +827,14 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, + if (!cnt) { + pr_err("no fragments or symbols in overlay\n"); + ret = -EINVAL; +- goto err_free_fragments; ++ goto err_out; + } + +- ovcs->id = id; + ovcs->count = cnt; +- ovcs->fragments = fragments; + + return 0; + +-err_free_fragments: +- kfree(fragments); +-err_free_idr: +- idr_remove(&ovcs_idr, id); +- ++err_out: + pr_err("%s() failed, ret = %d\n", __func__, ret); + + return ret; +@@ -851,21 +847,34 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) + if (ovcs->cset.entries.next) + of_changeset_destroy(&ovcs->cset); + +- if (ovcs->id) ++ if (ovcs->id) { + idr_remove(&ovcs_idr, ovcs->id); ++ list_del(&ovcs->ovcs_list); ++ ovcs->id = 0; ++ } ++ + + for (i = 0; i < ovcs->count; i++) { + of_node_put(ovcs->fragments[i].target); + of_node_put(ovcs->fragments[i].overlay); + } + kfree(ovcs->fragments); ++ + /* +- * There should be no live pointers into ovcs->overlay_root and ++ * There should be no live pointers into ovcs->overlay_mem and + * ovcs->new_fdt due to the policy that overlay notifiers are not +- * allowed to retain pointers into the overlay devicetree. ++ * allowed to retain pointers into the overlay devicetree other ++ * than during the window from OF_OVERLAY_PRE_APPLY overlay ++ * notifiers until the OF_OVERLAY_POST_REMOVE overlay notifiers. ++ * ++ * A memory leak will occur here if within the window. + */ +- kfree(ovcs->overlay_root); +- kfree(ovcs->new_fdt); ++ ++ if (ovcs->notify_state == OF_OVERLAY_INIT || ++ ovcs->notify_state == OF_OVERLAY_POST_REMOVE) { ++ kfree(ovcs->overlay_mem); ++ kfree(ovcs->new_fdt); ++ } + kfree(ovcs); + } + +@@ -873,27 +882,13 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) + * internal documentation + * + * of_overlay_apply() - Create and apply an overlay changeset +- * @new_fdt: Memory allocated to hold the aligned FDT +- * @overlay_root: Expanded overlay device tree +- * @ovcs_id: Pointer to overlay changeset id ++ * @ovcs: overlay changeset + * + * Creates and applies an overlay changeset. + * +- * If an error occurs in a pre-apply notifier, then no changes are made +- * to the device tree. +- * +- * A non-zero return value will not have created the changeset if error is from: +- * - parameter checks +- * - building the changeset +- * - overlay changeset pre-apply notifier +- * + * If an error is returned by an overlay changeset pre-apply notifier + * then no further overlay changeset pre-apply notifier will be called. + * +- * A non-zero return value will have created the changeset if error is from: +- * - overlay changeset entry notifier +- * - overlay changeset post-apply notifier +- * + * If an error is returned by an overlay changeset post-apply notifier + * then no further overlay changeset post-apply notifier will be called. + * +@@ -907,64 +902,37 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) + * following attempt to apply or remove an overlay changeset will be + * refused. + * +- * Returns 0 on success, or a negative error number. Overlay changeset +- * id is returned to *ovcs_id. ++ * Returns 0 on success, or a negative error number. On error return, ++ * the caller of of_overlay_apply() must call free_overlay_changeset(). + */ + +-static int of_overlay_apply(const void *new_fdt, +- struct device_node *overlay_root, int *ovcs_id) ++static int of_overlay_apply(struct overlay_changeset *ovcs) + { +- struct overlay_changeset *ovcs; + int ret = 0, ret_revert, ret_tmp; + +- /* +- * As of this point, fdt and tree belong to the overlay changeset. +- * overlay changeset code is responsible for freeing them. +- */ +- + if (devicetree_corrupt()) { + pr_err("devicetree state suspect, refuse to apply overlay\n"); +- kfree(new_fdt); +- kfree(overlay_root); + ret = -EBUSY; + goto out; + } + +- ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL); +- if (!ovcs) { +- kfree(new_fdt); +- kfree(overlay_root); +- ret = -ENOMEM; +- goto out; +- } +- +- of_overlay_mutex_lock(); +- mutex_lock(&of_mutex); +- +- ret = of_resolve_phandles(overlay_root); ++ ret = of_resolve_phandles(ovcs->overlay_root); + if (ret) +- goto err_free_tree; ++ goto out; + +- ret = init_overlay_changeset(ovcs, new_fdt, overlay_root); ++ ret = init_overlay_changeset(ovcs); + if (ret) +- goto err_free_tree; ++ goto out; + +- /* +- * After overlay_notify(), ovcs->overlay_root related pointers may have +- * leaked to drivers, so can not kfree() tree, aka ovcs->overlay_tree; +- * and can not free memory containing aligned fdt. The aligned fdt +- * is contained within the memory at ovcs->new_fdt, possibly at an +- * offset from ovcs->new_fdt. +- */ + ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY); + if (ret) { + pr_err("overlay changeset pre-apply notify error %d\n", ret); +- goto err_free_overlay_changeset; ++ goto out; + } + + ret = build_changeset(ovcs); + if (ret) +- goto err_free_overlay_changeset; ++ goto out; + + ret_revert = 0; + ret = __of_changeset_apply_entries(&ovcs->cset, &ret_revert); +@@ -974,7 +942,7 @@ static int of_overlay_apply(const void *new_fdt, + ret_revert); + devicetree_state_flags |= DTSF_APPLY_FAIL; + } +- goto err_free_overlay_changeset; ++ goto out; + } + + ret = __of_changeset_apply_notify(&ovcs->cset); +@@ -982,9 +950,6 @@ static int of_overlay_apply(const void *new_fdt, + pr_err("overlay apply changeset entry notify error %d\n", ret); + /* notify failure is not fatal, continue */ + +- list_add_tail(&ovcs->ovcs_list, &ovcs_list); +- *ovcs_id = ovcs->id; +- + ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_APPLY); + if (ret_tmp) { + pr_err("overlay changeset post-apply notify error %d\n", +@@ -993,19 +958,6 @@ static int of_overlay_apply(const void *new_fdt, + ret = ret_tmp; + } + +- goto out_unlock; +- +-err_free_tree: +- kfree(new_fdt); +- kfree(overlay_root); +- +-err_free_overlay_changeset: +- free_overlay_changeset(ovcs); +- +-out_unlock: +- mutex_unlock(&of_mutex); +- of_overlay_mutex_unlock(); +- + out: + pr_debug("%s() err=%d\n", __func__, ret); + +@@ -1013,15 +965,16 @@ static int of_overlay_apply(const void *new_fdt, + } + + int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size, +- int *ovcs_id) ++ int *ret_ovcs_id) + { + void *new_fdt; + void *new_fdt_align; ++ void *overlay_mem; + int ret; + u32 size; +- struct device_node *overlay_root = NULL; ++ struct overlay_changeset *ovcs; + +- *ovcs_id = 0; ++ *ret_ovcs_id = 0; + + if (overlay_fdt_size < sizeof(struct fdt_header) || + fdt_check_header(overlay_fdt)) { +@@ -1033,41 +986,67 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size, + if (overlay_fdt_size < size) + return -EINVAL; + ++ ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL); ++ if (!ovcs) ++ return -ENOMEM; ++ ++ of_overlay_mutex_lock(); ++ mutex_lock(&of_mutex); ++ ++ /* ++ * ovcs->notify_state must be set to OF_OVERLAY_INIT before allocating ++ * ovcs resources, implicitly set by kzalloc() of ovcs ++ */ ++ ++ ovcs->id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL); ++ if (ovcs->id <= 0) { ++ ret = ovcs->id; ++ goto err_free_ovcs; ++ } ++ ++ INIT_LIST_HEAD(&ovcs->ovcs_list); ++ list_add_tail(&ovcs->ovcs_list, &ovcs_list); ++ + /* + * Must create permanent copy of FDT because of_fdt_unflatten_tree() + * will create pointers to the passed in FDT in the unflattened tree. + */ + new_fdt = kmalloc(size + FDT_ALIGN_SIZE, GFP_KERNEL); +- if (!new_fdt) +- return -ENOMEM; ++ if (!new_fdt) { ++ ret = -ENOMEM; ++ goto err_free_ovcs; ++ } ++ ovcs->new_fdt = new_fdt; + + new_fdt_align = PTR_ALIGN(new_fdt, FDT_ALIGN_SIZE); + memcpy(new_fdt_align, overlay_fdt, size); + +- of_fdt_unflatten_tree(new_fdt_align, NULL, &overlay_root); +- if (!overlay_root) { ++ overlay_mem = of_fdt_unflatten_tree(new_fdt_align, NULL, ++ &ovcs->overlay_root); ++ if (!overlay_mem) { + pr_err("unable to unflatten overlay_fdt\n"); + ret = -EINVAL; +- goto out_free_new_fdt; ++ goto err_free_ovcs; + } ++ ovcs->overlay_mem = overlay_mem; + +- ret = of_overlay_apply(new_fdt, overlay_root, ovcs_id); +- if (ret < 0) { +- /* +- * new_fdt and overlay_root now belong to the overlay +- * changeset. +- * overlay changeset code is responsible for freeing them. +- */ +- goto out; +- } ++ ret = of_overlay_apply(ovcs); ++ if (ret < 0) ++ goto err_free_ovcs; ++ ++ mutex_unlock(&of_mutex); ++ of_overlay_mutex_unlock(); ++ ++ *ret_ovcs_id = ovcs->id; + + return 0; + ++err_free_ovcs: ++ free_overlay_changeset(ovcs); + +-out_free_new_fdt: +- kfree(new_fdt); ++ mutex_unlock(&of_mutex); ++ of_overlay_mutex_unlock(); + +-out: + return ret; + } + EXPORT_SYMBOL_GPL(of_overlay_fdt_apply); +@@ -1204,28 +1183,26 @@ int of_overlay_remove(int *ovcs_id) + if (!ovcs) { + ret = -ENODEV; + pr_err("remove: Could not find overlay #%d\n", *ovcs_id); +- goto out_unlock; ++ goto err_unlock; + } + + if (!overlay_removal_is_ok(ovcs)) { + ret = -EBUSY; +- goto out_unlock; ++ goto err_unlock; + } + + ret = overlay_notify(ovcs, OF_OVERLAY_PRE_REMOVE); + if (ret) { + pr_err("overlay changeset pre-remove notify error %d\n", ret); +- goto out_unlock; ++ goto err_unlock; + } + +- list_del(&ovcs->ovcs_list); +- + ret_apply = 0; + ret = __of_changeset_revert_entries(&ovcs->cset, &ret_apply); + if (ret) { + if (ret_apply) + devicetree_state_flags |= DTSF_REVERT_FAIL; +- goto out_unlock; ++ goto err_unlock; + } + + ret = __of_changeset_revert_notify(&ovcs->cset); +@@ -1235,6 +1212,11 @@ int of_overlay_remove(int *ovcs_id) + + *ovcs_id = 0; + ++ /* ++ * Note that the overlay memory will be kfree()ed by ++ * free_overlay_changeset() even if the notifier for ++ * OF_OVERLAY_POST_REMOVE returns an error. ++ */ + ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_REMOVE); + if (ret_tmp) { + pr_err("overlay changeset post-remove notify error %d\n", +@@ -1245,7 +1227,12 @@ int of_overlay_remove(int *ovcs_id) + + free_overlay_changeset(ovcs); + +-out_unlock: ++err_unlock: ++ /* ++ * If jumped over free_overlay_changeset(), then did not kfree() ++ * overlay related memory. This is a memory leak unless a subsequent ++ * of_overlay_remove() of this overlay is successful. ++ */ + mutex_unlock(&of_mutex); + + out: +diff --git a/include/linux/of.h b/include/linux/of.h +index 6f1c41f109bbe..83414a0b41de5 100644 +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -1486,7 +1486,8 @@ static inline bool of_device_is_system_power_controller(const struct device_node + */ + + enum of_overlay_notify_action { +- OF_OVERLAY_PRE_APPLY = 0, ++ OF_OVERLAY_INIT = 0, /* kzalloc() of ovcs sets this value */ ++ OF_OVERLAY_PRE_APPLY, + OF_OVERLAY_POST_APPLY, + OF_OVERLAY_PRE_REMOVE, + OF_OVERLAY_POST_REMOVE, +-- +2.39.2 + diff --git a/queue-5.15/parisc-flush-gatt-writes-and-adjust-gatt-mask-in-par.patch b/queue-5.15/parisc-flush-gatt-writes-and-adjust-gatt-mask-in-par.patch new file mode 100644 index 00000000000..59c0a591e45 --- /dev/null +++ b/queue-5.15/parisc-flush-gatt-writes-and-adjust-gatt-mask-in-par.patch @@ -0,0 +1,62 @@ +From 24e6218ff57086a0db0c9f03d1303f518ff1bfbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 May 2023 15:54:40 +0200 +Subject: parisc: Flush gatt writes and adjust gatt mask in + parisc_agp_mask_memory() + +From: Helge Deller + +[ Upstream commit d703797380c540bbeac03f104ebcfc364eaf47cc ] + +Flush caches after changing gatt entries and calculate entry according +to SBA requirements. + +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/char/agp/parisc-agp.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c +index d68d05d5d3838..514f9f287a781 100644 +--- a/drivers/char/agp/parisc-agp.c ++++ b/drivers/char/agp/parisc-agp.c +@@ -90,6 +90,9 @@ parisc_agp_tlbflush(struct agp_memory *mem) + { + struct _parisc_agp_info *info = &parisc_agp_info; + ++ /* force fdc ops to be visible to IOMMU */ ++ asm_io_sync(); ++ + writeq(info->gart_base | ilog2(info->gart_size), info->ioc_regs+IOC_PCOM); + readq(info->ioc_regs+IOC_PCOM); /* flush */ + } +@@ -158,6 +161,7 @@ parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type) + info->gatt[j] = + parisc_agp_mask_memory(agp_bridge, + paddr, type); ++ asm_io_fdc(&info->gatt[j]); + } + } + +@@ -191,7 +195,16 @@ static unsigned long + parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr, + int type) + { +- return SBA_PDIR_VALID_BIT | addr; ++ unsigned ci; /* coherent index */ ++ dma_addr_t pa; ++ ++ pa = addr & IOVP_MASK; ++ asm("lci 0(%1), %0" : "=r" (ci) : "r" (phys_to_virt(pa))); ++ ++ pa |= (ci >> PAGE_SHIFT) & 0xff;/* move CI (8 bits) into lowest byte */ ++ pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */ ++ ++ return cpu_to_le64(pa); + } + + static void +-- +2.39.2 + diff --git a/queue-5.15/parisc-improve-cache-flushing-for-pcxl-in-arch_sync_.patch b/queue-5.15/parisc-improve-cache-flushing-for-pcxl-in-arch_sync_.patch new file mode 100644 index 00000000000..d5ba9c66f13 --- /dev/null +++ b/queue-5.15/parisc-improve-cache-flushing-for-pcxl-in-arch_sync_.patch @@ -0,0 +1,57 @@ +From da1dc0db36c4a25bb9ecc20d00e74af3ccd06527 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 May 2023 15:52:30 +0200 +Subject: parisc: Improve cache flushing for PCXL in arch_sync_dma_for_cpu() + +From: Helge Deller + +[ Upstream commit 59fa12646d9f56c842b4d5b6418ed77af625c588 ] + +Add comment in arch_sync_dma_for_device() and handle the direction flag in +arch_sync_dma_for_cpu(). + +When receiving data from the device (DMA_FROM_DEVICE) unconditionally +purge the data cache in arch_sync_dma_for_cpu(). + +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + arch/parisc/kernel/pci-dma.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c +index 36a57aa38e87e..3b0227b17c070 100644 +--- a/arch/parisc/kernel/pci-dma.c ++++ b/arch/parisc/kernel/pci-dma.c +@@ -446,11 +446,27 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr, + void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) + { ++ /* ++ * fdc: The data cache line is written back to memory, if and only if ++ * it is dirty, and then invalidated from the data cache. ++ */ + flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size); + } + + void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) + { +- flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size); ++ unsigned long addr = (unsigned long) phys_to_virt(paddr); ++ ++ switch (dir) { ++ case DMA_TO_DEVICE: ++ case DMA_BIDIRECTIONAL: ++ flush_kernel_dcache_range(addr, size); ++ return; ++ case DMA_FROM_DEVICE: ++ purge_kernel_dcache_range_asm(addr, addr + size); ++ return; ++ default: ++ BUG(); ++ } + } +-- +2.39.2 + diff --git a/queue-5.15/platform-x86-asus-wmi-ignore-wmi-events-with-codes-0.patch b/queue-5.15/platform-x86-asus-wmi-ignore-wmi-events-with-codes-0.patch new file mode 100644 index 00000000000..72ca3ca00fe --- /dev/null +++ b/queue-5.15/platform-x86-asus-wmi-ignore-wmi-events-with-codes-0.patch @@ -0,0 +1,50 @@ +From 4eb0dbb7d61258949ddc096e6ffb3d3a67b92c6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 13:15:17 +0300 +Subject: platform/x86: asus-wmi: Ignore WMI events with codes 0x7B, 0xC0 + +From: Alexandru Sorodoc + +[ Upstream commit 362c1f2ec82cb65940e1c73e15a395a7a891fc6f ] + +On ASUS GU604V the key 0x7B is issued when the charger is connected or +disconnected, and key 0xC0 is issued when an external display is +connected or disconnected. + +This commit maps them to KE_IGNORE to slience kernel messages about +unknown keys, such as: + + kernel: asus_wmi: Unknown key code 0x7b + +Signed-off-by: Alexandru Sorodoc +Link: https://lore.kernel.org/r/20230512101517.47416-1-ealex95@gmail.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/asus-nb-wmi.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c +index 4d7327b67a7db..2c43801a18a28 100644 +--- a/drivers/platform/x86/asus-nb-wmi.c ++++ b/drivers/platform/x86/asus-nb-wmi.c +@@ -550,6 +550,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = { + { KE_KEY, 0x71, { KEY_F13 } }, /* General-purpose button */ + { KE_IGNORE, 0x79, }, /* Charger type dectection notification */ + { KE_KEY, 0x7a, { KEY_ALS_TOGGLE } }, /* Ambient Light Sensor Toggle */ ++ { KE_IGNORE, 0x7B, }, /* Charger connect/disconnect notification */ + { KE_KEY, 0x7c, { KEY_MICMUTE } }, + { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */ + { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, /* Bluetooth Disable */ +@@ -575,6 +576,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = { + { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */ + { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */ + { KE_KEY, 0xB5, { KEY_CALC } }, ++ { KE_IGNORE, 0xC0, }, /* External display connect/disconnect notification */ + { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, + { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, + { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */ +-- +2.39.2 + diff --git a/queue-5.15/power-supply-ab8500-fix-external_power_changed-race.patch b/queue-5.15/power-supply-ab8500-fix-external_power_changed-race.patch new file mode 100644 index 00000000000..99d36f9ffeb --- /dev/null +++ b/queue-5.15/power-supply-ab8500-fix-external_power_changed-race.patch @@ -0,0 +1,73 @@ +From 821933325c29accb1997c687d5de17ca1d9bf457 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Apr 2023 18:07:29 +0200 +Subject: power: supply: ab8500: Fix external_power_changed race + +From: Hans de Goede + +[ Upstream commit a5299ce4e96f3e8930e9c051b28d8093ada87b08 ] + +ab8500_btemp_external_power_changed() dereferences di->btemp_psy, +which gets sets in ab8500_btemp_probe() like this: + + di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc, + &psy_cfg); + +As soon as devm_power_supply_register() has called device_add() +the external_power_changed callback can get called. So there is a window +where ab8500_btemp_external_power_changed() may get called while +di->btemp_psy has not been set yet leading to a NULL pointer dereference. + +Fixing this is easy. The external_power_changed callback gets passed +the power_supply which will eventually get stored in di->btemp_psy, +so ab8500_btemp_external_power_changed() can simply directly use +the passed in psy argument which is always valid. + +And the same applies to ab8500_fg_external_power_changed(). + +Signed-off-by: Hans de Goede +Reviewed-by: Linus Walleij +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/ab8500_btemp.c | 6 ++---- + drivers/power/supply/ab8500_fg.c | 6 ++---- + 2 files changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c +index b6c9111d77d7d..896309d3cadfe 100644 +--- a/drivers/power/supply/ab8500_btemp.c ++++ b/drivers/power/supply/ab8500_btemp.c +@@ -902,10 +902,8 @@ static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data) + */ + static void ab8500_btemp_external_power_changed(struct power_supply *psy) + { +- struct ab8500_btemp *di = power_supply_get_drvdata(psy); +- +- class_for_each_device(power_supply_class, NULL, +- di->btemp_psy, ab8500_btemp_get_ext_psy_data); ++ class_for_each_device(power_supply_class, NULL, psy, ++ ab8500_btemp_get_ext_psy_data); + } + + /* ab8500 btemp driver interrupts and their respective isr */ +diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c +index 57799a8079d44..eb7eac23da70f 100644 +--- a/drivers/power/supply/ab8500_fg.c ++++ b/drivers/power/supply/ab8500_fg.c +@@ -2384,10 +2384,8 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di) + */ + static void ab8500_fg_external_power_changed(struct power_supply *psy) + { +- struct ab8500_fg *di = power_supply_get_drvdata(psy); +- +- class_for_each_device(power_supply_class, NULL, +- di->fg_psy, ab8500_fg_get_ext_psy_data); ++ class_for_each_device(power_supply_class, NULL, psy, ++ ab8500_fg_get_ext_psy_data); + } + + /** +-- +2.39.2 + diff --git a/queue-5.15/power-supply-bq27xxx-use-mod_delayed_work-instead-of.patch b/queue-5.15/power-supply-bq27xxx-use-mod_delayed_work-instead-of.patch new file mode 100644 index 00000000000..ebb13eb9f0d --- /dev/null +++ b/queue-5.15/power-supply-bq27xxx-use-mod_delayed_work-instead-of.patch @@ -0,0 +1,40 @@ +From c120e97a266faebea7e6ffa165d3ea33ca07e0b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Apr 2023 20:23:39 +0200 +Subject: power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + + schedule() + +From: Hans de Goede + +[ Upstream commit 59dddea9879713423c7b2ade43c423bb71e0d216 ] + +Use mod_delayed_work() instead of separate cancel_delayed_work_sync() + +schedule_delayed_work() calls. + +Signed-off-by: Hans de Goede +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/bq27xxx_battery.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c +index ffb5f5c028223..7c1295986b594 100644 +--- a/drivers/power/supply/bq27xxx_battery.c ++++ b/drivers/power/supply/bq27xxx_battery.c +@@ -1083,10 +1083,8 @@ static int poll_interval_param_set(const char *val, const struct kernel_param *k + return ret; + + mutex_lock(&bq27xxx_list_lock); +- list_for_each_entry(di, &bq27xxx_battery_devices, list) { +- cancel_delayed_work_sync(&di->work); +- schedule_delayed_work(&di->work, 0); +- } ++ list_for_each_entry(di, &bq27xxx_battery_devices, list) ++ mod_delayed_work(system_wq, &di->work, 0); + mutex_unlock(&bq27xxx_list_lock); + + return ret; +-- +2.39.2 + diff --git a/queue-5.15/power-supply-fix-logic-checking-if-system-is-running.patch b/queue-5.15/power-supply-fix-logic-checking-if-system-is-running.patch new file mode 100644 index 00000000000..b7c66800aae --- /dev/null +++ b/queue-5.15/power-supply-fix-logic-checking-if-system-is-running.patch @@ -0,0 +1,66 @@ +From 07ce5720c71eaa1e5685cce576286a4f90d94dbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 May 2023 13:25:40 -0500 +Subject: power: supply: Fix logic checking if system is running from battery + +From: Mario Limonciello + +[ Upstream commit 95339f40a8b652b5b1773def31e63fc53c26378a ] + +The logic used for power_supply_is_system_supplied() counts all power +supplies and assumes that the system is running from AC if there is +either a non-battery power-supply reporting to be online or if no +power-supplies exist at all. + +The second rule is for desktop systems, that don't have any +battery/charger devices. These systems will incorrectly report to be +powered from battery once a device scope power-supply is registered +(e.g. a HID device), since these power-supplies increase the counter. + +Apart from HID devices, recent dGPUs provide UCSI power supplies on a +desktop systems. The dGPU by default doesn't have anything plugged in so +it's 'offline'. This makes power_supply_is_system_supplied() return 0 +with a count of 1 meaning all drivers that use this get a wrong judgement. + +To fix this case adjust the logic to also examine the scope of the power +supply. If the power supply is deemed a device power supply, then don't +count it. + +Cc: Evan Quan +Suggested-by: Lijo Lazar +Signed-off-by: Mario Limonciello +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/power_supply_core.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c +index daf76d7885c05..8b2cd63016160 100644 +--- a/drivers/power/supply/power_supply_core.c ++++ b/drivers/power/supply/power_supply_core.c +@@ -347,6 +347,10 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data) + struct power_supply *psy = dev_get_drvdata(dev); + unsigned int *count = data; + ++ if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret)) ++ if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE) ++ return 0; ++ + (*count)++; + if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) + if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, +@@ -365,8 +369,8 @@ int power_supply_is_system_supplied(void) + __power_supply_is_system_supplied); + + /* +- * If no power class device was found at all, most probably we are +- * running on a desktop system, so assume we are on mains power. ++ * If no system scope power class device was found at all, most probably we ++ * are running on a desktop system, so assume we are on mains power. + */ + if (count == 0) + return 1; +-- +2.39.2 + diff --git a/queue-5.15/power-supply-ratelimit-no-data-debug-output.patch b/queue-5.15/power-supply-ratelimit-no-data-debug-output.patch new file mode 100644 index 00000000000..9af2b7995e7 --- /dev/null +++ b/queue-5.15/power-supply-ratelimit-no-data-debug-output.patch @@ -0,0 +1,43 @@ +From 77526e0d18f82fb3abefdd2335ab90e0c1517c89 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Mar 2023 21:52:26 +0100 +Subject: power: supply: Ratelimit no data debug output + +From: Marek Vasut + +[ Upstream commit 155c45a25679f571c2ae57d10db843a9dfc63430 ] + +Reduce the amount of output this dev_dbg() statement emits into logs, +otherwise if system software polls the sysfs entry for data and keeps +getting -ENODATA, it could end up filling the logs up. + +This does in fact make systemd journald choke, since during boot the +sysfs power supply entries are polled and if journald starts at the +same time, the journal is just being repeatedly filled up, and the +system stops on trying to start journald without booting any further. + +Signed-off-by: Marek Vasut +Reviewed-by: Hans de Goede +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/power_supply_sysfs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c +index c3d7cbcd4fad5..7a0485c35ba9d 100644 +--- a/drivers/power/supply/power_supply_sysfs.c ++++ b/drivers/power/supply/power_supply_sysfs.c +@@ -276,7 +276,8 @@ static ssize_t power_supply_show_property(struct device *dev, + + if (ret < 0) { + if (ret == -ENODATA) +- dev_dbg(dev, "driver has no data for `%s' property\n", ++ dev_dbg_ratelimited(dev, ++ "driver has no data for `%s' property\n", + attr->attr.name); + else if (ret != -ENODEV && ret != -EAGAIN) + dev_err_ratelimited(dev, +-- +2.39.2 + diff --git a/queue-5.15/power-supply-sc27xx-fix-external_power_changed-race.patch b/queue-5.15/power-supply-sc27xx-fix-external_power_changed-race.patch new file mode 100644 index 00000000000..e6133bcdab3 --- /dev/null +++ b/queue-5.15/power-supply-sc27xx-fix-external_power_changed-race.patch @@ -0,0 +1,70 @@ +From c9acbf41192b0510464d9c2a5a5435aa31a92fed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Apr 2023 18:07:32 +0200 +Subject: power: supply: sc27xx: Fix external_power_changed race + +From: Hans de Goede + +[ Upstream commit 4d5c129d6c8993fe96e9ae712141eedcb9ca68c2 ] + +sc27xx_fgu_external_power_changed() dereferences data->battery, +which gets sets in ab8500_btemp_probe() like this: + + data->battery = devm_power_supply_register(dev, &sc27xx_fgu_desc, + &fgu_cfg); + +As soon as devm_power_supply_register() has called device_add() +the external_power_changed callback can get called. So there is a window +where sc27xx_fgu_external_power_changed() may get called while +data->battery has not been set yet leading to a NULL pointer dereference. + +Fixing this is easy. The external_power_changed callback gets passed +the power_supply which will eventually get stored in data->battery, +so sc27xx_fgu_external_power_changed() can simply directly use +the passed in psy argument which is always valid. + +After this change sc27xx_fgu_external_power_changed() is reduced to just +"power_supply_changed(psy);" and it has the same prototype. While at it +simply replace it with making the external_power_changed callback +directly point to power_supply_changed. + +Cc: Orson Zhai +Cc: Chunyan Zhang +Signed-off-by: Hans de Goede +Reviewed-by: Baolin Wang +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/sc27xx_fuel_gauge.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c +index ae45069bd5e1b..3d8a85df87f4d 100644 +--- a/drivers/power/supply/sc27xx_fuel_gauge.c ++++ b/drivers/power/supply/sc27xx_fuel_gauge.c +@@ -733,13 +733,6 @@ static int sc27xx_fgu_set_property(struct power_supply *psy, + return ret; + } + +-static void sc27xx_fgu_external_power_changed(struct power_supply *psy) +-{ +- struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); +- +- power_supply_changed(data->battery); +-} +- + static int sc27xx_fgu_property_is_writeable(struct power_supply *psy, + enum power_supply_property psp) + { +@@ -774,7 +767,7 @@ static const struct power_supply_desc sc27xx_fgu_desc = { + .num_properties = ARRAY_SIZE(sc27xx_fgu_props), + .get_property = sc27xx_fgu_get_property, + .set_property = sc27xx_fgu_set_property, +- .external_power_changed = sc27xx_fgu_external_power_changed, ++ .external_power_changed = power_supply_changed, + .property_is_writeable = sc27xx_fgu_property_is_writeable, + .no_thermal = true, + }; +-- +2.39.2 + diff --git a/queue-5.15/regulator-fix-error-checking-for-debugfs_create_dir.patch b/queue-5.15/regulator-fix-error-checking-for-debugfs_create_dir.patch new file mode 100644 index 00000000000..e3667d48f31 --- /dev/null +++ b/queue-5.15/regulator-fix-error-checking-for-debugfs_create_dir.patch @@ -0,0 +1,46 @@ +From af3d352ad85cb6274c1251a2faa02d9903d85cc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 May 2023 22:29:38 +0500 +Subject: regulator: Fix error checking for debugfs_create_dir + +From: Osama Muhammad + +[ Upstream commit 2bf1c45be3b8f3a3f898d0756c1282f09719debd ] + +This patch fixes the error checking in core.c in debugfs_create_dir. +The correct way to check if an error occurred is 'IS_ERR' inline function. + +Signed-off-by: Osama Muhammad +--- + drivers/regulator/core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 9ddb80d10dee3..211ab227b000c 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -5193,7 +5193,7 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) + } + + rdev->debugfs = debugfs_create_dir(rname, debugfs_root); +- if (!rdev->debugfs) { ++ if (IS_ERR(rdev->debugfs)) { + rdev_warn(rdev, "Failed to create debugfs directory\n"); + return; + } +@@ -6103,7 +6103,7 @@ static int __init regulator_init(void) + ret = class_register(®ulator_class); + + debugfs_root = debugfs_create_dir("regulator", NULL); +- if (!debugfs_root) ++ if (IS_ERR(debugfs_root)) + pr_warn("regulator: Failed to create debugfs directory\n"); + + #ifdef CONFIG_DEBUG_FS +-- +2.39.2 + diff --git a/queue-5.15/series b/queue-5.15/series index bfa7c055ae4..23956cf9326 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -3,3 +3,30 @@ test_firmware-prevent-race-conditions-by-a-correct-i.patch test_firmware-fix-a-memory-leak-with-reqs-buffer.patch ksmbd-fix-slab-out-of-bounds-read-in-smb2_handle_neg.patch drm-amdgpu-fix-null-pointer-dereference-error-in-amd.patch +of-overlay-rename-variables-to-be-consistent.patch +of-overlay-rework-overlay-apply-and-remove-kfree-s.patch +of-overlay-fix-missing-of_node_put-in-error-case-of-.patch +power-supply-ab8500-fix-external_power_changed-race.patch +power-supply-sc27xx-fix-external_power_changed-race.patch +power-supply-bq27xxx-use-mod_delayed_work-instead-of.patch +arm-dts-vexpress-add-missing-cache-properties.patch +tools-gpio-fix-debounce_period_us-output-of-lsgpio.patch +power-supply-ratelimit-no-data-debug-output.patch +platform-x86-asus-wmi-ignore-wmi-events-with-codes-0.patch +regulator-fix-error-checking-for-debugfs_create_dir.patch +irqchip-gic-v3-disable-pseudo-nmis-on-mediatek-devic.patch +power-supply-fix-logic-checking-if-system-is-running.patch +btrfs-scrub-try-harder-to-mark-raid56-block-groups-r.patch +btrfs-handle-memory-allocation-failure-in-btrfs_csum.patch +asoc-soc-pcm-test-if-a-be-can-be-prepared.patch +parisc-improve-cache-flushing-for-pcxl-in-arch_sync_.patch +parisc-flush-gatt-writes-and-adjust-gatt-mask-in-par.patch +mips-unhide-pata_platform.patch +mips-restore-au1300-support.patch +mips-alchemy-fix-dbdma2.patch +mips-move-initrd_start-check-after-initrd-address-sa.patch +asoc-dwc-move-dma-init-to-snd_soc_dai_driver-probe.patch +xen-blkfront-only-check-req_fua-for-writes.patch +drm-amd-amdgpu-fix-missing-buffer-object-unlock-in-f.patch +nvme-add-maxio-1602-to-bogus-nid-list.patch +irqchip-gic-correctly-validate-of-quirk-descriptors.patch diff --git a/queue-5.15/tools-gpio-fix-debounce_period_us-output-of-lsgpio.patch b/queue-5.15/tools-gpio-fix-debounce_period_us-output-of-lsgpio.patch new file mode 100644 index 00000000000..9eca120700b --- /dev/null +++ b/queue-5.15/tools-gpio-fix-debounce_period_us-output-of-lsgpio.patch @@ -0,0 +1,37 @@ +From bcb7cd2765311b2a1624819b21542332e15210b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 May 2023 15:18:48 +0200 +Subject: tools: gpio: fix debounce_period_us output of lsgpio + +From: Milo Spadacini + +[ Upstream commit eb4b8eca1bad98f4b8574558a74f041f9acb5a54 ] + +Fix incorrect output that could occur when more attributes are used and +GPIO_V2_LINE_ATTR_ID_DEBOUNCE is not the first one. + +Signed-off-by: Milo Spadacini +Reviewed-by: Linus Walleij +Reviewed-by: Andy Shevchenko +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + tools/gpio/lsgpio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/gpio/lsgpio.c b/tools/gpio/lsgpio.c +index c61d061247e17..52a0be45410c9 100644 +--- a/tools/gpio/lsgpio.c ++++ b/tools/gpio/lsgpio.c +@@ -94,7 +94,7 @@ static void print_attributes(struct gpio_v2_line_info *info) + for (i = 0; i < info->num_attrs; i++) { + if (info->attrs[i].id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE) + fprintf(stdout, ", debounce_period=%dusec", +- info->attrs[0].debounce_period_us); ++ info->attrs[i].debounce_period_us); + } + } + +-- +2.39.2 + diff --git a/queue-5.15/xen-blkfront-only-check-req_fua-for-writes.patch b/queue-5.15/xen-blkfront-only-check-req_fua-for-writes.patch new file mode 100644 index 00000000000..9a58ccd8292 --- /dev/null +++ b/queue-5.15/xen-blkfront-only-check-req_fua-for-writes.patch @@ -0,0 +1,45 @@ +From 4d425fd6a92fc856eb83e102ffa489cce3f3f74f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Apr 2023 17:40:05 +0100 +Subject: xen/blkfront: Only check REQ_FUA for writes + +From: Ross Lagerwall + +[ Upstream commit b6ebaa8100090092aa602530d7e8316816d0c98d ] + +The existing code silently converts read operations with the +REQ_FUA bit set into write-barrier operations. This results in data +loss as the backend scribbles zeroes over the data instead of returning +it. + +While the REQ_FUA bit doesn't make sense on a read operation, at least +one well-known out-of-tree kernel module does set it and since it +results in data loss, let's be safe here and only look at REQ_FUA for +writes. + +Signed-off-by: Ross Lagerwall +Acked-by: Juergen Gross +Link: https://lore.kernel.org/r/20230426164005.2213139-1-ross.lagerwall@citrix.com +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/block/xen-blkfront.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c +index 24a86d829f92a..831747ba8113c 100644 +--- a/drivers/block/xen-blkfront.c ++++ b/drivers/block/xen-blkfront.c +@@ -780,7 +780,8 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri + ring_req->u.rw.handle = info->handle; + ring_req->operation = rq_data_dir(req) ? + BLKIF_OP_WRITE : BLKIF_OP_READ; +- if (req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA) { ++ if (req_op(req) == REQ_OP_FLUSH || ++ (req_op(req) == REQ_OP_WRITE && (req->cmd_flags & REQ_FUA))) { + /* + * Ideally we can do an unordered flush-to-disk. + * In case the backend onlysupports barriers, use that. +-- +2.39.2 + -- 2.47.2