ASoC: SOF: ipc4-topology: Correct the allocation size for bytes controls
The size of the data behind of scontrol->ipc_control_data for bytes
controls is:
[1] sizeof(struct sof_ipc4_control_data) + // kernel only struct
[2] sizeof(struct sof_abi_hdr)) + payload
The max_size specifies the size of [2] and it is coming from topology.
Change the function to take this into account and allocate adequate amount
of memory behind scontrol->ipc_control_data.
With the change we will allocate [1] amount more memory to be able to hold
the full size of data.
Fixes: a382082ff7 ("ASoC: SOF: ipc4-topology: Add support for TPLG_CTL_BYTES")
Cc: stable@vger.kernel.org
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://patch.msgid.link/20251217143945.2667-3-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
2fa7471374
commit
a653820700
|
|
@ -2855,22 +2855,41 @@ static int sof_ipc4_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_
|
|||
struct sof_ipc4_msg *msg;
|
||||
int ret;
|
||||
|
||||
if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) {
|
||||
dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n",
|
||||
/*
|
||||
* The max_size is coming from topology and indicates the maximum size
|
||||
* of sof_abi_hdr plus the payload, which excludes the local only
|
||||
* 'struct sof_ipc4_control_data'
|
||||
*/
|
||||
if (scontrol->max_size < sizeof(struct sof_abi_hdr)) {
|
||||
dev_err(sdev->dev,
|
||||
"insufficient maximum size for a bytes control %s: %zu.\n",
|
||||
scontrol->name, scontrol->max_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) {
|
||||
dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n",
|
||||
scontrol->name, scontrol->priv_size,
|
||||
scontrol->max_size - sizeof(*control_data));
|
||||
if (scontrol->priv_size > scontrol->max_size) {
|
||||
dev_err(sdev->dev,
|
||||
"bytes control %s initial data size %zu exceeds max %zu.\n",
|
||||
scontrol->name, scontrol->priv_size, scontrol->max_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size;
|
||||
if (scontrol->priv_size < sizeof(struct sof_abi_hdr)) {
|
||||
dev_err(sdev->dev,
|
||||
"bytes control %s initial data size %zu is insufficient.\n",
|
||||
scontrol->name, scontrol->priv_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL);
|
||||
/*
|
||||
* The used size behind the cdata pointer, which can be smaller than
|
||||
* the maximum size
|
||||
*/
|
||||
scontrol->size = sizeof(*control_data) + scontrol->priv_size;
|
||||
|
||||
/* Allocate the cdata: local struct size + maximum payload size */
|
||||
scontrol->ipc_control_data = kzalloc(sizeof(*control_data) + scontrol->max_size,
|
||||
GFP_KERNEL);
|
||||
if (!scontrol->ipc_control_data)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue