diff options
author | Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 2023-11-24 21:01:36 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-12-20 19:00:25 +0300 |
commit | f2955dd3e9334c9b070e6f5696f3ebc57be88ae6 (patch) | |
tree | 68cd69dd2fed00be469bd68902bad55dcedaea4d /drivers/soundwire | |
parent | 56f762659a5e9fde8220a88e19fd5ec4b12eda6d (diff) | |
download | linux-f2955dd3e9334c9b070e6f5696f3ebc57be88ae6.tar.xz |
soundwire: stream: fix NULL pointer dereference for multi_link
commit e199bf52ffda8f98f129728d57244a9cd9ad5623 upstream.
If bus is marked as multi_link, but number of masters in the stream is
not higher than bus->hw_sync_min_links (bus->multi_link && m_rt_count >=
bus->hw_sync_min_links), bank switching should not happen. The first
part of do_bank_switch() code properly takes these conditions into
account, but second part (sdw_ml_sync_bank_switch()) relies purely on
bus->multi_link property. This is not balanced and leads to NULL
pointer dereference:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
...
Call trace:
wait_for_completion_timeout+0x124/0x1f0
do_bank_switch+0x370/0x6f8
sdw_prepare_stream+0x2d0/0x438
qcom_snd_sdw_prepare+0xa0/0x118
sm8450_snd_prepare+0x128/0x148
snd_soc_link_prepare+0x5c/0xe8
__soc_pcm_prepare+0x28/0x1ec
dpcm_be_dai_prepare+0x1e0/0x2c0
dpcm_fe_dai_prepare+0x108/0x28c
snd_pcm_do_prepare+0x44/0x68
snd_pcm_action_single+0x54/0xc0
snd_pcm_action_nonatomic+0xe4/0xec
snd_pcm_prepare+0xc4/0x114
snd_pcm_common_ioctl+0x1154/0x1cc0
snd_pcm_ioctl+0x54/0x74
Fixes: ce6e74d008ff ("soundwire: Add support for multi link bank switch")
Cc: stable@vger.kernel.org
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20231124180136.390621-1-krzysztof.kozlowski@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/soundwire')
-rw-r--r-- | drivers/soundwire/stream.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index b10ea69a638e..2624441d2fa9 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -744,14 +744,15 @@ error_1: * sdw_ml_sync_bank_switch: Multilink register bank switch * * @bus: SDW bus instance + * @multi_link: whether this is a multi-link stream with hardware-based sync * * Caller function should free the buffers on error */ -static int sdw_ml_sync_bank_switch(struct sdw_bus *bus) +static int sdw_ml_sync_bank_switch(struct sdw_bus *bus, bool multi_link) { unsigned long time_left; - if (!bus->multi_link) + if (!multi_link) return 0; /* Wait for completion of transfer */ @@ -848,7 +849,7 @@ static int do_bank_switch(struct sdw_stream_runtime *stream) bus->bank_switch_timeout = DEFAULT_BANK_SWITCH_TIMEOUT; /* Check if bank switch was successful */ - ret = sdw_ml_sync_bank_switch(bus); + ret = sdw_ml_sync_bank_switch(bus, multi_link); if (ret < 0) { dev_err(bus->dev, "multi link bank switch failed: %d\n", ret); |