Commit 960a8904 authored by Mark Brown's avatar Mark Brown

ASoC: SOF: dma-trace: Change trace_init() ops parameter list

Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>:

Hi,

the DMA trace implementation on AMD platform assumes that the stream_tag pointer
is pointing the stream_tag member of struct sof_ipc_dma_trace_params_ext, which
is true at the moment, but it can not be guarantied and a change in the dtrace
core can cause out of bound accesses for AMD.

For this reason, change the API to pass the struct itself which will remove the
assumption and makes it clear from both sides what is expected to be sent via the
parameter list.

This opens up a window to clean up the intel and AMD implementation at the same
time.

Regards,
Peter
---

Peter Ujfalusi (2):
  ASoC: SOF: intel: hda-trace: Pass the dma buffer pointer to
    hda_dsp_trace_prepare
  ASoC: SOF: dma-trace: Pass pointer to params_ext struct in
    trace_init()

 sound/soc/sof/amd/acp-trace.c   | 38 ++++++++-------------------------
 sound/soc/sof/amd/acp.h         |  3 ++-
 sound/soc/sof/intel/hda-trace.c | 17 ++++++++-------
 sound/soc/sof/intel/hda.h       |  3 ++-
 sound/soc/sof/ops.h             |  4 ++--
 sound/soc/sof/sof-priv.h        |  2 +-
 sound/soc/sof/trace.c           |  2 +-
 7 files changed, 26 insertions(+), 43 deletions(-)

--
2.35.0
parents dcc2c012 bab05b50
...@@ -34,51 +34,31 @@ int acp_sof_trace_release(struct snd_sof_dev *sdev) ...@@ -34,51 +34,31 @@ int acp_sof_trace_release(struct snd_sof_dev *sdev)
} }
EXPORT_SYMBOL_NS(acp_sof_trace_release, SND_SOC_SOF_AMD_COMMON); EXPORT_SYMBOL_NS(acp_sof_trace_release, SND_SOC_SOF_AMD_COMMON);
static int acp_sof_trace_prepare(struct snd_sof_dev *sdev, int acp_sof_trace_init(struct snd_sof_dev *sdev,
struct sof_ipc_dma_trace_params_ext *params) struct sof_ipc_dma_trace_params_ext *dtrace_params)
{ {
struct acp_dsp_stream *stream; struct acp_dsp_stream *stream;
struct acp_dev_data *adata; struct acp_dev_data *adata;
int ret; int ret;
adata = sdev->pdata->hw_pdata; adata = sdev->pdata->hw_pdata;
stream = adata->dtrace_stream; stream = acp_dsp_stream_get(sdev, ACP_LOGGER_STREAM);
if (!stream)
return -ENODEV;
stream->dmab = &sdev->dmatb; stream->dmab = &sdev->dmatb;
stream->num_pages = NUM_PAGES; stream->num_pages = NUM_PAGES;
ret = acp_dsp_stream_config(sdev, stream); ret = acp_dsp_stream_config(sdev, stream);
if (ret < 0) { if (ret < 0) {
dev_err(sdev->dev, "Failed to configure trace stream\n"); acp_dsp_stream_put(sdev, stream);
return ret; return ret;
} }
params->buffer.phy_addr = stream->reg_offset;
params->stream_tag = stream->stream_tag;
return 0;
}
int acp_sof_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag)
{
struct sof_ipc_dma_trace_params_ext *params;
struct acp_dsp_stream *stream;
struct acp_dev_data *adata;
int ret;
adata = sdev->pdata->hw_pdata;
stream = acp_dsp_stream_get(sdev, ACP_LOGGER_STREAM);
if (!stream)
return -ENODEV;
adata->dtrace_stream = stream; adata->dtrace_stream = stream;
params = container_of(stream_tag, struct sof_ipc_dma_trace_params_ext, stream_tag); dtrace_params->stream_tag = stream->stream_tag;
ret = acp_sof_trace_prepare(sdev, params); dtrace_params->buffer.phy_addr = stream->reg_offset;
if (ret < 0) {
acp_dsp_stream_put(sdev, stream);
return ret;
}
*stream_tag = stream->stream_tag;
return 0; return 0;
} }
EXPORT_SYMBOL_NS(acp_sof_trace_init, SND_SOC_SOF_AMD_COMMON); EXPORT_SYMBOL_NS(acp_sof_trace_init, SND_SOC_SOF_AMD_COMMON);
...@@ -210,7 +210,8 @@ extern const struct snd_sof_dsp_ops sof_renoir_ops; ...@@ -210,7 +210,8 @@ extern const struct snd_sof_dsp_ops sof_renoir_ops;
int snd_amd_acp_find_config(struct pci_dev *pci); int snd_amd_acp_find_config(struct pci_dev *pci);
/* Trace */ /* Trace */
int acp_sof_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag); int acp_sof_trace_init(struct snd_sof_dev *sdev,
struct sof_ipc_dma_trace_params_ext *dtrace_params);
int acp_sof_trace_release(struct snd_sof_dev *sdev); int acp_sof_trace_release(struct snd_sof_dev *sdev);
struct sof_amd_acp_desc { struct sof_amd_acp_desc {
......
...@@ -19,16 +19,15 @@ ...@@ -19,16 +19,15 @@
#include "../ops.h" #include "../ops.h"
#include "hda.h" #include "hda.h"
static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev) static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab)
{ {
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct hdac_ext_stream *stream = hda->dtrace_stream; struct hdac_ext_stream *stream = hda->dtrace_stream;
struct hdac_stream *hstream = &stream->hstream; struct hdac_stream *hstream = &stream->hstream;
struct snd_dma_buffer *dmab = &sdev->dmatb;
int ret; int ret;
hstream->period_bytes = 0;/* initialize period_bytes */ hstream->period_bytes = 0;/* initialize period_bytes */
hstream->bufsize = sdev->dmatb.bytes; hstream->bufsize = dmab->bytes;
ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL); ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL);
if (ret < 0) if (ret < 0)
...@@ -37,7 +36,8 @@ static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev) ...@@ -37,7 +36,8 @@ static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev)
return ret; return ret;
} }
int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) int hda_dsp_trace_init(struct snd_sof_dev *sdev,
struct sof_ipc_dma_trace_params_ext *dtrace_params)
{ {
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
int ret; int ret;
...@@ -51,18 +51,19 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) ...@@ -51,18 +51,19 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag)
return -ENODEV; return -ENODEV;
} }
*stream_tag = hda->dtrace_stream->hstream.stream_tag; dtrace_params->stream_tag = hda->dtrace_stream->hstream.stream_tag;
/* /*
* initialize capture stream, set BDL address and return corresponding * initialize capture stream, set BDL address and return corresponding
* stream tag which will be sent to the firmware by IPC message. * stream tag which will be sent to the firmware by IPC message.
*/ */
ret = hda_dsp_trace_prepare(sdev); ret = hda_dsp_trace_prepare(sdev, &sdev->dmatb);
if (ret < 0) { if (ret < 0) {
dev_err(sdev->dev, "error: hdac trace init failed: %d\n", ret); dev_err(sdev->dev, "error: hdac trace init failed: %d\n", ret);
hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE, *stream_tag); hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE,
dtrace_params->stream_tag);
hda->dtrace_stream = NULL; hda->dtrace_stream = NULL;
*stream_tag = 0; dtrace_params->stream_tag = 0;
} }
return ret; return ret;
......
...@@ -670,7 +670,8 @@ static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; } ...@@ -670,7 +670,8 @@ static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; }
/* /*
* Trace Control. * Trace Control.
*/ */
int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag); int hda_dsp_trace_init(struct snd_sof_dev *sdev,
struct sof_ipc_dma_trace_params_ext *dtrace_params);
int hda_dsp_trace_release(struct snd_sof_dev *sdev); int hda_dsp_trace_release(struct snd_sof_dev *sdev);
int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd); int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd);
......
...@@ -369,10 +369,10 @@ static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev, ...@@ -369,10 +369,10 @@ static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev,
/* host DMA trace */ /* host DMA trace */
static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev, static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev,
u32 *stream_tag) struct sof_ipc_dma_trace_params_ext *dtrace_params)
{ {
if (sof_ops(sdev)->trace_init) if (sof_ops(sdev)->trace_init)
return sof_ops(sdev)->trace_init(sdev, stream_tag); return sof_ops(sdev)->trace_init(sdev, dtrace_params);
return 0; return 0;
} }
......
...@@ -281,7 +281,7 @@ struct snd_sof_dsp_ops { ...@@ -281,7 +281,7 @@ struct snd_sof_dsp_ops {
/* host DMA trace initialization */ /* host DMA trace initialization */
int (*trace_init)(struct snd_sof_dev *sdev, int (*trace_init)(struct snd_sof_dev *sdev,
u32 *stream_tag); /* optional */ struct sof_ipc_dma_trace_params_ext *dtrace_params); /* optional */
int (*trace_release)(struct snd_sof_dev *sdev); /* optional */ int (*trace_release)(struct snd_sof_dev *sdev); /* optional */
int (*trace_trigger)(struct snd_sof_dev *sdev, int (*trace_trigger)(struct snd_sof_dev *sdev,
int cmd); /* optional */ int cmd); /* optional */
......
...@@ -409,7 +409,7 @@ int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev) ...@@ -409,7 +409,7 @@ int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev)
sdev->host_offset = 0; sdev->host_offset = 0;
sdev->dtrace_draining = false; sdev->dtrace_draining = false;
ret = snd_sof_dma_trace_init(sdev, &params.stream_tag); ret = snd_sof_dma_trace_init(sdev, &params);
if (ret < 0) { if (ret < 0) {
dev_err(sdev->dev, dev_err(sdev->dev,
"error: fail in snd_sof_dma_trace_init %d\n", ret); "error: fail in snd_sof_dma_trace_init %d\n", ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment