diff options
author | Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | 2019-04-30 18:09:18 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-05-03 14:56:31 +0900 |
commit | 8e3a6e45a77bd4167554b4bd0633a2adabf1bd77 (patch) | |
tree | bcfe8008ad4645aaa4a7851225ada17e69dd616e /sound/soc | |
parent | 4acb1c2ea42e19101eae4ac9f002853553b8b721 (diff) | |
download | linux-8e3a6e45a77bd4167554b4bd0633a2adabf1bd77.tar.bz2 |
ASoC: SOF: topology: add support for stricter ABI checks
Fail early if topology is more recent than kernel and Kconfig is
selected.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/sof/topology.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 1f71857298a9..c88afa872a58 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -3049,6 +3049,7 @@ static int sof_manifest(struct snd_soc_component *scomp, int index, { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); u32 size; + u32 abi_version; size = le32_to_cpu(man->priv.size); @@ -3058,20 +3059,36 @@ static int sof_manifest(struct snd_soc_component *scomp, int index, return 0; } - if (size == SOF_TPLG_ABI_SIZE) { - dev_info(sdev->dev, - "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n", - man->priv.data[0], man->priv.data[1], - man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR, - SOF_ABI_PATCH); - if (SOF_ABI_VER(man->priv.data[0], man->priv.data[1], - man->priv.data[2]) <= SOF_ABI_VERSION) - return 0; + if (size != SOF_TPLG_ABI_SIZE) { + dev_err(sdev->dev, "error: invalid topology ABI size\n"); + return -EINVAL; } - dev_err(sdev->dev, - "error: Incompatible ABI version %d:%d:%d\n", - man->priv.data[0], man->priv.data[1], man->priv.data[2]); - return -EINVAL; + + dev_info(sdev->dev, + "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n", + man->priv.data[0], man->priv.data[1], + man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR, + SOF_ABI_PATCH); + + abi_version = SOF_ABI_VER(man->priv.data[0], + man->priv.data[1], + man->priv.data[2]); + + if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) { + dev_err(sdev->dev, "error: incompatible topology ABI version\n"); + return -EINVAL; + } + + if (abi_version > SOF_ABI_VERSION) { + if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { + dev_warn(sdev->dev, "warn: topology ABI is more recent than kernel\n"); + } else { + dev_err(sdev->dev, "error: topology ABI is more recent than kernel\n"); + return -EINVAL; + } + } + + return 0; } /* vendor specific kcontrol handlers available for binding */ |