cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

soc-topology-test.c (24862B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * soc-topology-test.c  --  ALSA SoC Topology Kernel Unit Tests
      4 *
      5 * Copyright(c) 2021 Intel Corporation. All rights reserved.
      6 */
      7
      8#include <linux/firmware.h>
      9#include <sound/core.h>
     10#include <sound/soc.h>
     11#include <sound/soc-topology.h>
     12#include <kunit/test.h>
     13
     14/* ===== HELPER FUNCTIONS =================================================== */
     15
     16/*
     17 * snd_soc_component needs device to operate on (primarily for prints), create
     18 * fake one, as we don't register with PCI or anything else
     19 * device_driver name is used in some of the prints (fmt_single_name) so
     20 * we also mock up minimal one
     21 */
     22static struct device *test_dev;
     23
     24static struct device_driver test_drv = {
     25	.name = "sound-soc-topology-test-driver",
     26};
     27
     28static int snd_soc_tplg_test_init(struct kunit *test)
     29{
     30	test_dev = root_device_register("sound-soc-topology-test");
     31	test_dev = get_device(test_dev);
     32	if (!test_dev)
     33		return -ENODEV;
     34
     35	test_dev->driver = &test_drv;
     36
     37	return 0;
     38}
     39
     40static void snd_soc_tplg_test_exit(struct kunit *test)
     41{
     42	put_device(test_dev);
     43	root_device_unregister(test_dev);
     44}
     45
     46/*
     47 * helper struct we use when registering component, as we load topology during
     48 * component probe, we need to pass struct kunit somehow to probe function, so
     49 * we can report test result
     50 */
     51struct kunit_soc_component {
     52	struct kunit *kunit;
     53	int expect; /* what result we expect when loading topology */
     54	struct snd_soc_component comp;
     55	struct snd_soc_card card;
     56	struct firmware fw;
     57};
     58
     59static int d_probe(struct snd_soc_component *component)
     60{
     61	struct kunit_soc_component *kunit_comp =
     62			container_of(component, struct kunit_soc_component, comp);
     63	int ret;
     64
     65	ret = snd_soc_tplg_component_load(component, NULL, &kunit_comp->fw);
     66	KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
     67			    "Failed topology load");
     68
     69	return 0;
     70}
     71
     72static void d_remove(struct snd_soc_component *component)
     73{
     74	struct kunit_soc_component *kunit_comp =
     75			container_of(component, struct kunit_soc_component, comp);
     76	int ret;
     77
     78	ret = snd_soc_tplg_component_remove(component);
     79	KUNIT_EXPECT_EQ(kunit_comp->kunit, 0, ret);
     80}
     81
     82/*
     83 * ASoC minimal boiler plate
     84 */
     85SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY()));
     86
     87SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("sound-soc-topology-test")));
     88
     89static struct snd_soc_dai_link kunit_dai_links[] = {
     90	{
     91		.name = "KUNIT Audio Port",
     92		.id = 0,
     93		.stream_name = "Audio Playback/Capture",
     94		.nonatomic = 1,
     95		.dynamic = 1,
     96		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
     97		.dpcm_playback = 1,
     98		.dpcm_capture = 1,
     99		SND_SOC_DAILINK_REG(dummy, dummy, platform),
    100	},
    101};
    102
    103static const struct snd_soc_component_driver test_component = {
    104	.name = "sound-soc-topology-test",
    105	.probe = d_probe,
    106	.remove = d_remove,
    107	.non_legacy_dai_naming = 1,
    108};
    109
    110/* ===== TOPOLOGY TEMPLATES ================================================= */
    111
    112// Structural representation of topology which can be generated with:
    113// $ touch empty
    114// $ alsatplg -c empty -o empty.tplg
    115// $ xxd -i empty.tplg
    116
    117struct tplg_tmpl_001 {
    118	struct snd_soc_tplg_hdr header;
    119	struct snd_soc_tplg_manifest manifest;
    120} __packed;
    121
    122static struct tplg_tmpl_001 tplg_tmpl_empty = {
    123	.header = {
    124		.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
    125		.abi = cpu_to_le32(5),
    126		.version = 0,
    127		.type = cpu_to_le32(SND_SOC_TPLG_TYPE_MANIFEST),
    128		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
    129		.vendor_type = 0,
    130		.payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
    131		.index = 0,
    132		.count = cpu_to_le32(1),
    133	},
    134
    135	.manifest = {
    136		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
    137		/* rest of fields is 0 */
    138	},
    139};
    140
    141// Structural representation of topology containing SectionPCM
    142
    143struct tplg_tmpl_002 {
    144	struct snd_soc_tplg_hdr header;
    145	struct snd_soc_tplg_manifest manifest;
    146	struct snd_soc_tplg_hdr pcm_header;
    147	struct snd_soc_tplg_pcm pcm;
    148} __packed;
    149
    150static struct tplg_tmpl_002 tplg_tmpl_with_pcm = {
    151	.header = {
    152		.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
    153		.abi = cpu_to_le32(5),
    154		.version = 0,
    155		.type = cpu_to_le32(SND_SOC_TPLG_TYPE_MANIFEST),
    156		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
    157		.vendor_type = 0,
    158		.payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
    159		.index = 0,
    160		.count = cpu_to_le32(1),
    161	},
    162	.manifest = {
    163		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
    164		.pcm_elems = cpu_to_le32(1),
    165		/* rest of fields is 0 */
    166	},
    167	.pcm_header = {
    168		.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
    169		.abi = cpu_to_le32(5),
    170		.version = 0,
    171		.type = cpu_to_le32(SND_SOC_TPLG_TYPE_PCM),
    172		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
    173		.vendor_type = 0,
    174		.payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_pcm)),
    175		.index = 0,
    176		.count = cpu_to_le32(1),
    177	},
    178	.pcm = {
    179		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_pcm)),
    180		.pcm_name = "KUNIT Audio",
    181		.dai_name = "kunit-audio-dai",
    182		.pcm_id = 0,
    183		.dai_id = 0,
    184		.playback = cpu_to_le32(1),
    185		.capture = cpu_to_le32(1),
    186		.compress = 0,
    187		.stream = {
    188			[0] = {
    189				.channels = cpu_to_le32(2),
    190			},
    191			[1] = {
    192				.channels = cpu_to_le32(2),
    193			},
    194		},
    195		.num_streams = 0,
    196		.caps = {
    197			[0] = {
    198				.name = "kunit-audio-playback",
    199				.channels_min = cpu_to_le32(2),
    200				.channels_max = cpu_to_le32(2),
    201			},
    202			[1] = {
    203				.name = "kunit-audio-capture",
    204				.channels_min = cpu_to_le32(2),
    205				.channels_max = cpu_to_le32(2),
    206			},
    207		},
    208		.flag_mask = 0,
    209		.flags = 0,
    210		.priv = { 0 },
    211	},
    212};
    213
    214/* ===== TEST CASES ========================================================= */
    215
    216// TEST CASE
    217// Test passing NULL component as parameter to snd_soc_tplg_component_load
    218
    219/*
    220 * need to override generic probe function with one using NULL when calling
    221 * topology load during component initialization, we don't need .remove
    222 * handler as load should fail
    223 */
    224static int d_probe_null_comp(struct snd_soc_component *component)
    225{
    226	struct kunit_soc_component *kunit_comp =
    227			container_of(component, struct kunit_soc_component, comp);
    228	int ret;
    229
    230	/* instead of passing component pointer as first argument, pass NULL here */
    231	ret = snd_soc_tplg_component_load(NULL, NULL, &kunit_comp->fw);
    232	KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
    233			    "Failed topology load");
    234
    235	return 0;
    236}
    237
    238static const struct snd_soc_component_driver test_component_null_comp = {
    239	.name = "sound-soc-topology-test",
    240	.probe = d_probe_null_comp,
    241	.non_legacy_dai_naming = 1,
    242};
    243
    244static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test)
    245{
    246	struct kunit_soc_component *kunit_comp;
    247	int ret;
    248
    249	/* prepare */
    250	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    251	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    252	kunit_comp->kunit = test;
    253	kunit_comp->expect = -EINVAL; /* expect failure */
    254
    255	kunit_comp->card.dev = test_dev,
    256	kunit_comp->card.name = "kunit-card",
    257	kunit_comp->card.owner = THIS_MODULE,
    258	kunit_comp->card.dai_link = kunit_dai_links,
    259	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    260	kunit_comp->card.fully_routed = true,
    261
    262	/* run test */
    263	ret = snd_soc_register_card(&kunit_comp->card);
    264	if (ret != 0 && ret != -EPROBE_DEFER)
    265		KUNIT_FAIL(test, "Failed to register card");
    266
    267	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_comp, test_dev);
    268	KUNIT_EXPECT_EQ(test, 0, ret);
    269
    270	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    271	KUNIT_EXPECT_EQ(test, 0, ret);
    272
    273	/* cleanup */
    274	ret = snd_soc_unregister_card(&kunit_comp->card);
    275	KUNIT_EXPECT_EQ(test, 0, ret);
    276
    277	snd_soc_unregister_component(test_dev);
    278}
    279
    280// TEST CASE
    281// Test passing NULL ops as parameter to snd_soc_tplg_component_load
    282
    283/*
    284 * NULL ops is default case, we pass empty topology (fw), so we don't have
    285 * anything to parse and just do nothing, which results in return 0; from
    286 * calling soc_tplg_dapm_complete in soc_tplg_process_headers
    287 */
    288static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test)
    289{
    290	struct kunit_soc_component *kunit_comp;
    291	int ret;
    292
    293	/* prepare */
    294	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    295	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    296	kunit_comp->kunit = test;
    297	kunit_comp->expect = 0; /* expect success */
    298
    299	kunit_comp->card.dev = test_dev,
    300	kunit_comp->card.name = "kunit-card",
    301	kunit_comp->card.owner = THIS_MODULE,
    302	kunit_comp->card.dai_link = kunit_dai_links,
    303	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    304	kunit_comp->card.fully_routed = true,
    305
    306	/* run test */
    307	ret = snd_soc_register_card(&kunit_comp->card);
    308	if (ret != 0 && ret != -EPROBE_DEFER)
    309		KUNIT_FAIL(test, "Failed to register card");
    310
    311	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    312	KUNIT_EXPECT_EQ(test, 0, ret);
    313
    314	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    315	KUNIT_EXPECT_EQ(test, 0, ret);
    316
    317	/* cleanup */
    318	ret = snd_soc_unregister_card(&kunit_comp->card);
    319	KUNIT_EXPECT_EQ(test, 0, ret);
    320
    321	snd_soc_unregister_component(test_dev);
    322}
    323
    324// TEST CASE
    325// Test passing NULL fw as parameter to snd_soc_tplg_component_load
    326
    327/*
    328 * need to override generic probe function with one using NULL pointer to fw
    329 * when calling topology load during component initialization, we don't need
    330 * .remove handler as load should fail
    331 */
    332static int d_probe_null_fw(struct snd_soc_component *component)
    333{
    334	struct kunit_soc_component *kunit_comp =
    335			container_of(component, struct kunit_soc_component, comp);
    336	int ret;
    337
    338	/* instead of passing fw pointer as third argument, pass NULL here */
    339	ret = snd_soc_tplg_component_load(component, NULL, NULL);
    340	KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
    341			    "Failed topology load");
    342
    343	return 0;
    344}
    345
    346static const struct snd_soc_component_driver test_component_null_fw = {
    347	.name = "sound-soc-topology-test",
    348	.probe = d_probe_null_fw,
    349	.non_legacy_dai_naming = 1,
    350};
    351
    352static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test)
    353{
    354	struct kunit_soc_component *kunit_comp;
    355	int ret;
    356
    357	/* prepare */
    358	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    359	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    360	kunit_comp->kunit = test;
    361	kunit_comp->expect = -EINVAL; /* expect failure */
    362
    363	kunit_comp->card.dev = test_dev,
    364	kunit_comp->card.name = "kunit-card",
    365	kunit_comp->card.owner = THIS_MODULE,
    366	kunit_comp->card.dai_link = kunit_dai_links,
    367	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    368	kunit_comp->card.fully_routed = true,
    369
    370	/* run test */
    371	ret = snd_soc_register_card(&kunit_comp->card);
    372	if (ret != 0 && ret != -EPROBE_DEFER)
    373		KUNIT_FAIL(test, "Failed to register card");
    374
    375	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_fw, test_dev);
    376	KUNIT_EXPECT_EQ(test, 0, ret);
    377
    378	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    379	KUNIT_EXPECT_EQ(test, 0, ret);
    380
    381	/* cleanup */
    382	ret = snd_soc_unregister_card(&kunit_comp->card);
    383	KUNIT_EXPECT_EQ(test, 0, ret);
    384
    385	snd_soc_unregister_component(test_dev);
    386}
    387
    388// TEST CASE
    389// Test passing "empty" topology file
    390static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test)
    391{
    392	struct kunit_soc_component *kunit_comp;
    393	struct tplg_tmpl_001 *data;
    394	int size;
    395	int ret;
    396
    397	/* prepare */
    398	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    399	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    400	kunit_comp->kunit = test;
    401	kunit_comp->expect = 0; /* expect success */
    402
    403	size = sizeof(tplg_tmpl_empty);
    404	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
    405	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
    406
    407	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
    408
    409	kunit_comp->fw.data = (u8 *)data;
    410	kunit_comp->fw.size = size;
    411
    412	kunit_comp->card.dev = test_dev,
    413	kunit_comp->card.name = "kunit-card",
    414	kunit_comp->card.owner = THIS_MODULE,
    415	kunit_comp->card.dai_link = kunit_dai_links,
    416	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    417	kunit_comp->card.fully_routed = true,
    418
    419	/* run test */
    420	ret = snd_soc_register_card(&kunit_comp->card);
    421	if (ret != 0 && ret != -EPROBE_DEFER)
    422		KUNIT_FAIL(test, "Failed to register card");
    423
    424	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    425	KUNIT_EXPECT_EQ(test, 0, ret);
    426
    427	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    428	KUNIT_EXPECT_EQ(test, 0, ret);
    429
    430	/* cleanup */
    431	ret = snd_soc_unregister_card(&kunit_comp->card);
    432	KUNIT_EXPECT_EQ(test, 0, ret);
    433
    434	snd_soc_unregister_component(test_dev);
    435}
    436
    437// TEST CASE
    438// Test "empty" topology file, but with bad "magic"
    439// In theory we could loop through all possible bad values, but it takes too
    440// long, so just use SND_SOC_TPLG_MAGIC + 1
    441static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test)
    442{
    443	struct kunit_soc_component *kunit_comp;
    444	struct tplg_tmpl_001 *data;
    445	int size;
    446	int ret;
    447
    448	/* prepare */
    449	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    450	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    451	kunit_comp->kunit = test;
    452	kunit_comp->expect = -EINVAL; /* expect failure */
    453
    454	size = sizeof(tplg_tmpl_empty);
    455	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
    456	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
    457
    458	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
    459	/*
    460	 * override abi
    461	 * any value != magic number is wrong
    462	 */
    463	data->header.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC + 1);
    464
    465	kunit_comp->fw.data = (u8 *)data;
    466	kunit_comp->fw.size = size;
    467
    468	kunit_comp->card.dev = test_dev,
    469	kunit_comp->card.name = "kunit-card",
    470	kunit_comp->card.owner = THIS_MODULE,
    471	kunit_comp->card.dai_link = kunit_dai_links,
    472	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    473	kunit_comp->card.fully_routed = true,
    474
    475	/* run test */
    476	ret = snd_soc_register_card(&kunit_comp->card);
    477	if (ret != 0 && ret != -EPROBE_DEFER)
    478		KUNIT_FAIL(test, "Failed to register card");
    479
    480	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    481	KUNIT_EXPECT_EQ(test, 0, ret);
    482
    483	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    484	KUNIT_EXPECT_EQ(test, 0, ret);
    485
    486	/* cleanup */
    487	ret = snd_soc_unregister_card(&kunit_comp->card);
    488	KUNIT_EXPECT_EQ(test, 0, ret);
    489
    490	snd_soc_unregister_component(test_dev);
    491}
    492
    493// TEST CASE
    494// Test "empty" topology file, but with bad "abi"
    495// In theory we could loop through all possible bad values, but it takes too
    496// long, so just use SND_SOC_TPLG_ABI_VERSION + 1
    497static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test)
    498{
    499	struct kunit_soc_component *kunit_comp;
    500	struct tplg_tmpl_001 *data;
    501	int size;
    502	int ret;
    503
    504	/* prepare */
    505	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    506	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    507	kunit_comp->kunit = test;
    508	kunit_comp->expect = -EINVAL; /* expect failure */
    509
    510	size = sizeof(tplg_tmpl_empty);
    511	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
    512	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
    513
    514	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
    515	/*
    516	 * override abi
    517	 * any value != accepted range is wrong
    518	 */
    519	data->header.abi = cpu_to_le32(SND_SOC_TPLG_ABI_VERSION + 1);
    520
    521	kunit_comp->fw.data = (u8 *)data;
    522	kunit_comp->fw.size = size;
    523
    524	kunit_comp->card.dev = test_dev,
    525	kunit_comp->card.name = "kunit-card",
    526	kunit_comp->card.owner = THIS_MODULE,
    527	kunit_comp->card.dai_link = kunit_dai_links,
    528	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    529	kunit_comp->card.fully_routed = true,
    530
    531	/* run test */
    532	ret = snd_soc_register_card(&kunit_comp->card);
    533	if (ret != 0 && ret != -EPROBE_DEFER)
    534		KUNIT_FAIL(test, "Failed to register card");
    535
    536	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    537	KUNIT_EXPECT_EQ(test, 0, ret);
    538
    539	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    540	KUNIT_EXPECT_EQ(test, 0, ret);
    541
    542	/* cleanup */
    543	ret = snd_soc_unregister_card(&kunit_comp->card);
    544	KUNIT_EXPECT_EQ(test, 0, ret);
    545
    546	snd_soc_unregister_component(test_dev);
    547}
    548
    549// TEST CASE
    550// Test "empty" topology file, but with bad "size"
    551// In theory we could loop through all possible bad values, but it takes too
    552// long, so just use sizeof(struct snd_soc_tplg_hdr) + 1
    553static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test)
    554{
    555	struct kunit_soc_component *kunit_comp;
    556	struct tplg_tmpl_001 *data;
    557	int size;
    558	int ret;
    559
    560	/* prepare */
    561	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    562	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    563	kunit_comp->kunit = test;
    564	kunit_comp->expect = -EINVAL; /* expect failure */
    565
    566	size = sizeof(tplg_tmpl_empty);
    567	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
    568	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
    569
    570	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
    571	/*
    572	 * override size
    573	 * any value != struct size is wrong
    574	 */
    575	data->header.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr) + 1);
    576
    577	kunit_comp->fw.data = (u8 *)data;
    578	kunit_comp->fw.size = size;
    579
    580	kunit_comp->card.dev = test_dev,
    581	kunit_comp->card.name = "kunit-card",
    582	kunit_comp->card.owner = THIS_MODULE,
    583	kunit_comp->card.dai_link = kunit_dai_links,
    584	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    585	kunit_comp->card.fully_routed = true,
    586
    587	/* run test */
    588	ret = snd_soc_register_card(&kunit_comp->card);
    589	if (ret != 0 && ret != -EPROBE_DEFER)
    590		KUNIT_FAIL(test, "Failed to register card");
    591
    592	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    593	KUNIT_EXPECT_EQ(test, 0, ret);
    594
    595	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    596	KUNIT_EXPECT_EQ(test, 0, ret);
    597
    598	/* cleanup */
    599	ret = snd_soc_unregister_card(&kunit_comp->card);
    600	KUNIT_EXPECT_EQ(test, 0, ret);
    601
    602	snd_soc_unregister_component(test_dev);
    603}
    604
    605// TEST CASE
    606// Test "empty" topology file, but with bad "payload_size"
    607// In theory we could loop through all possible bad values, but it takes too
    608// long, so just use the known wrong one
    609static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *test)
    610{
    611	struct kunit_soc_component *kunit_comp;
    612	struct tplg_tmpl_001 *data;
    613	int size;
    614	int ret;
    615
    616	/* prepare */
    617	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    618	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    619	kunit_comp->kunit = test;
    620	kunit_comp->expect = -EINVAL; /* expect failure */
    621
    622	size = sizeof(tplg_tmpl_empty);
    623	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
    624	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
    625
    626	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
    627	/*
    628	 * override payload size
    629	 * there is only explicit check for 0, so check with it, other values
    630	 * are handled by just not reading behind EOF
    631	 */
    632	data->header.payload_size = 0;
    633
    634	kunit_comp->fw.data = (u8 *)data;
    635	kunit_comp->fw.size = size;
    636
    637	kunit_comp->card.dev = test_dev,
    638	kunit_comp->card.name = "kunit-card",
    639	kunit_comp->card.owner = THIS_MODULE,
    640	kunit_comp->card.dai_link = kunit_dai_links,
    641	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    642	kunit_comp->card.fully_routed = true,
    643
    644	/* run test */
    645	ret = snd_soc_register_card(&kunit_comp->card);
    646	if (ret != 0 && ret != -EPROBE_DEFER)
    647		KUNIT_FAIL(test, "Failed to register card");
    648
    649	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    650	KUNIT_EXPECT_EQ(test, 0, ret);
    651
    652	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    653	KUNIT_EXPECT_EQ(test, 0, ret);
    654
    655	/* cleanup */
    656	snd_soc_unregister_component(test_dev);
    657
    658	ret = snd_soc_unregister_card(&kunit_comp->card);
    659	KUNIT_EXPECT_EQ(test, 0, ret);
    660}
    661
    662// TEST CASE
    663// Test passing topology file with PCM definition
    664static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test)
    665{
    666	struct kunit_soc_component *kunit_comp;
    667	u8 *data;
    668	int size;
    669	int ret;
    670
    671	/* prepare */
    672	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    673	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    674	kunit_comp->kunit = test;
    675	kunit_comp->expect = 0; /* expect success */
    676
    677	size = sizeof(tplg_tmpl_with_pcm);
    678	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
    679	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
    680
    681	memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
    682
    683	kunit_comp->fw.data = data;
    684	kunit_comp->fw.size = size;
    685
    686	kunit_comp->card.dev = test_dev,
    687	kunit_comp->card.name = "kunit-card",
    688	kunit_comp->card.owner = THIS_MODULE,
    689	kunit_comp->card.dai_link = kunit_dai_links,
    690	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    691	kunit_comp->card.fully_routed = true,
    692
    693	/* run test */
    694	ret = snd_soc_register_card(&kunit_comp->card);
    695	if (ret != 0 && ret != -EPROBE_DEFER)
    696		KUNIT_FAIL(test, "Failed to register card");
    697
    698	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    699	KUNIT_EXPECT_EQ(test, 0, ret);
    700
    701	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    702	KUNIT_EXPECT_EQ(test, 0, ret);
    703
    704	snd_soc_unregister_component(test_dev);
    705
    706	/* cleanup */
    707	ret = snd_soc_unregister_card(&kunit_comp->card);
    708	KUNIT_EXPECT_EQ(test, 0, ret);
    709}
    710
    711// TEST CASE
    712// Test passing topology file with PCM definition
    713// with component reload
    714static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test)
    715{
    716	struct kunit_soc_component *kunit_comp;
    717	u8 *data;
    718	int size;
    719	int ret;
    720	int i;
    721
    722	/* prepare */
    723	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    724	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    725	kunit_comp->kunit = test;
    726	kunit_comp->expect = 0; /* expect success */
    727
    728	size = sizeof(tplg_tmpl_with_pcm);
    729	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
    730	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
    731
    732	memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
    733
    734	kunit_comp->fw.data = data;
    735	kunit_comp->fw.size = size;
    736
    737	kunit_comp->card.dev = test_dev,
    738	kunit_comp->card.name = "kunit-card",
    739	kunit_comp->card.owner = THIS_MODULE,
    740	kunit_comp->card.dai_link = kunit_dai_links,
    741	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    742	kunit_comp->card.fully_routed = true,
    743
    744	/* run test */
    745	ret = snd_soc_register_card(&kunit_comp->card);
    746	if (ret != 0 && ret != -EPROBE_DEFER)
    747		KUNIT_FAIL(test, "Failed to register card");
    748
    749	for (i = 0; i < 100; i++) {
    750		ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    751		KUNIT_EXPECT_EQ(test, 0, ret);
    752
    753		ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    754		KUNIT_EXPECT_EQ(test, 0, ret);
    755
    756		snd_soc_unregister_component(test_dev);
    757	}
    758
    759	/* cleanup */
    760	ret = snd_soc_unregister_card(&kunit_comp->card);
    761	KUNIT_EXPECT_EQ(test, 0, ret);
    762}
    763
    764// TEST CASE
    765// Test passing topology file with PCM definition
    766// with card reload
    767static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test)
    768{
    769	struct kunit_soc_component *kunit_comp;
    770	u8 *data;
    771	int size;
    772	int ret;
    773	int i;
    774
    775	/* prepare */
    776	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
    777	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
    778	kunit_comp->kunit = test;
    779	kunit_comp->expect = 0; /* expect success */
    780
    781	size = sizeof(tplg_tmpl_with_pcm);
    782	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
    783	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
    784
    785	memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
    786
    787	kunit_comp->fw.data = data;
    788	kunit_comp->fw.size = size;
    789
    790	kunit_comp->card.dev = test_dev,
    791	kunit_comp->card.name = "kunit-card",
    792	kunit_comp->card.owner = THIS_MODULE,
    793	kunit_comp->card.dai_link = kunit_dai_links,
    794	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
    795	kunit_comp->card.fully_routed = true,
    796
    797	/* run test */
    798	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
    799	KUNIT_EXPECT_EQ(test, 0, ret);
    800
    801	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
    802	KUNIT_EXPECT_EQ(test, 0, ret);
    803
    804	for (i = 0; i < 100; i++) {
    805		ret = snd_soc_register_card(&kunit_comp->card);
    806		if (ret != 0 && ret != -EPROBE_DEFER)
    807			KUNIT_FAIL(test, "Failed to register card");
    808
    809		ret = snd_soc_unregister_card(&kunit_comp->card);
    810		KUNIT_EXPECT_EQ(test, 0, ret);
    811	}
    812
    813	/* cleanup */
    814	snd_soc_unregister_component(test_dev);
    815}
    816
    817/* ===== KUNIT MODULE DEFINITIONS =========================================== */
    818
    819static struct kunit_case snd_soc_tplg_test_cases[] = {
    820	KUNIT_CASE(snd_soc_tplg_test_load_with_null_comp),
    821	KUNIT_CASE(snd_soc_tplg_test_load_with_null_ops),
    822	KUNIT_CASE(snd_soc_tplg_test_load_with_null_fw),
    823	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg),
    824	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_magic),
    825	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_abi),
    826	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_size),
    827	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_payload_size),
    828	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg),
    829	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_comp),
    830	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_card),
    831	{}
    832};
    833
    834static struct kunit_suite snd_soc_tplg_test_suite = {
    835	.name = "snd_soc_tplg_test",
    836	.init = snd_soc_tplg_test_init,
    837	.exit = snd_soc_tplg_test_exit,
    838	.test_cases = snd_soc_tplg_test_cases,
    839};
    840
    841kunit_test_suites(&snd_soc_tplg_test_suite);
    842
    843MODULE_LICENSE("GPL");