From 8e3a6e45a77bd4167554b4bd0633a2adabf1bd77 Mon Sep 17 00:00:00 2001
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Date: Tue, 30 Apr 2019 18:09:18 -0500
Subject: [PATCH] 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>
---
 sound/soc/sof/topology.c | 43 ++++++++++++++++++++++++++++------------
 1 file 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 */
-- 
GitLab