156e1a4ccSJason Gunthorpe // SPDX-License-Identifier: GPL-2.0
256e1a4ccSJason Gunthorpe /*
356e1a4ccSJason Gunthorpe * Copyright 2024 Google LLC.
456e1a4ccSJason Gunthorpe */
556e1a4ccSJason Gunthorpe #include <kunit/test.h>
656e1a4ccSJason Gunthorpe #include <linux/io-pgtable.h>
756e1a4ccSJason Gunthorpe
856e1a4ccSJason Gunthorpe #include "arm-smmu-v3.h"
956e1a4ccSJason Gunthorpe
1056e1a4ccSJason Gunthorpe struct arm_smmu_test_writer {
1156e1a4ccSJason Gunthorpe struct arm_smmu_entry_writer writer;
1256e1a4ccSJason Gunthorpe struct kunit *test;
1356e1a4ccSJason Gunthorpe const __le64 *init_entry;
1456e1a4ccSJason Gunthorpe const __le64 *target_entry;
1556e1a4ccSJason Gunthorpe __le64 *entry;
1656e1a4ccSJason Gunthorpe
1756e1a4ccSJason Gunthorpe bool invalid_entry_written;
1856e1a4ccSJason Gunthorpe unsigned int num_syncs;
1956e1a4ccSJason Gunthorpe };
2056e1a4ccSJason Gunthorpe
2156e1a4ccSJason Gunthorpe #define NUM_ENTRY_QWORDS 8
2256e1a4ccSJason Gunthorpe #define NUM_EXPECTED_SYNCS(x) x
2356e1a4ccSJason Gunthorpe
2456e1a4ccSJason Gunthorpe static struct arm_smmu_ste bypass_ste;
2556e1a4ccSJason Gunthorpe static struct arm_smmu_ste abort_ste;
2656e1a4ccSJason Gunthorpe static struct arm_smmu_device smmu = {
2756e1a4ccSJason Gunthorpe .features = ARM_SMMU_FEAT_STALLS | ARM_SMMU_FEAT_ATTR_TYPES_OVR
2856e1a4ccSJason Gunthorpe };
2956e1a4ccSJason Gunthorpe static struct mm_struct sva_mm = {
3056e1a4ccSJason Gunthorpe .pgd = (void *)0xdaedbeefdeadbeefULL,
3156e1a4ccSJason Gunthorpe };
3256e1a4ccSJason Gunthorpe
33*070e326fSMostafa Saleh enum arm_smmu_test_master_feat {
34*070e326fSMostafa Saleh ARM_SMMU_MASTER_TEST_ATS = BIT(0),
35*070e326fSMostafa Saleh ARM_SMMU_MASTER_TEST_STALL = BIT(1),
36*070e326fSMostafa Saleh };
37*070e326fSMostafa Saleh
arm_smmu_entry_differs_in_used_bits(const __le64 * entry,const __le64 * used_bits,const __le64 * target,unsigned int length)3856e1a4ccSJason Gunthorpe static bool arm_smmu_entry_differs_in_used_bits(const __le64 *entry,
3956e1a4ccSJason Gunthorpe const __le64 *used_bits,
4056e1a4ccSJason Gunthorpe const __le64 *target,
4156e1a4ccSJason Gunthorpe unsigned int length)
4256e1a4ccSJason Gunthorpe {
4356e1a4ccSJason Gunthorpe bool differs = false;
4456e1a4ccSJason Gunthorpe unsigned int i;
4556e1a4ccSJason Gunthorpe
4656e1a4ccSJason Gunthorpe for (i = 0; i < length; i++) {
4756e1a4ccSJason Gunthorpe if ((entry[i] & used_bits[i]) != target[i])
4856e1a4ccSJason Gunthorpe differs = true;
4956e1a4ccSJason Gunthorpe }
5056e1a4ccSJason Gunthorpe return differs;
5156e1a4ccSJason Gunthorpe }
5256e1a4ccSJason Gunthorpe
5356e1a4ccSJason Gunthorpe static void
arm_smmu_test_writer_record_syncs(struct arm_smmu_entry_writer * writer)5456e1a4ccSJason Gunthorpe arm_smmu_test_writer_record_syncs(struct arm_smmu_entry_writer *writer)
5556e1a4ccSJason Gunthorpe {
5656e1a4ccSJason Gunthorpe struct arm_smmu_test_writer *test_writer =
5756e1a4ccSJason Gunthorpe container_of(writer, struct arm_smmu_test_writer, writer);
5856e1a4ccSJason Gunthorpe __le64 *entry_used_bits;
5956e1a4ccSJason Gunthorpe
6056e1a4ccSJason Gunthorpe entry_used_bits = kunit_kzalloc(
6156e1a4ccSJason Gunthorpe test_writer->test, sizeof(*entry_used_bits) * NUM_ENTRY_QWORDS,
6256e1a4ccSJason Gunthorpe GFP_KERNEL);
6356e1a4ccSJason Gunthorpe KUNIT_ASSERT_NOT_NULL(test_writer->test, entry_used_bits);
6456e1a4ccSJason Gunthorpe
6556e1a4ccSJason Gunthorpe pr_debug("STE value is now set to: ");
6656e1a4ccSJason Gunthorpe print_hex_dump_debug(" ", DUMP_PREFIX_NONE, 16, 8,
6756e1a4ccSJason Gunthorpe test_writer->entry,
6856e1a4ccSJason Gunthorpe NUM_ENTRY_QWORDS * sizeof(*test_writer->entry),
6956e1a4ccSJason Gunthorpe false);
7056e1a4ccSJason Gunthorpe
7156e1a4ccSJason Gunthorpe test_writer->num_syncs += 1;
7256e1a4ccSJason Gunthorpe if (!test_writer->entry[0]) {
7356e1a4ccSJason Gunthorpe test_writer->invalid_entry_written = true;
7456e1a4ccSJason Gunthorpe } else {
7556e1a4ccSJason Gunthorpe /*
7656e1a4ccSJason Gunthorpe * At any stage in a hitless transition, the entry must be
7756e1a4ccSJason Gunthorpe * equivalent to either the initial entry or the target entry
7856e1a4ccSJason Gunthorpe * when only considering the bits used by the current
7956e1a4ccSJason Gunthorpe * configuration.
8056e1a4ccSJason Gunthorpe */
8156e1a4ccSJason Gunthorpe writer->ops->get_used(test_writer->entry, entry_used_bits);
8256e1a4ccSJason Gunthorpe KUNIT_EXPECT_FALSE(
8356e1a4ccSJason Gunthorpe test_writer->test,
8456e1a4ccSJason Gunthorpe arm_smmu_entry_differs_in_used_bits(
8556e1a4ccSJason Gunthorpe test_writer->entry, entry_used_bits,
8656e1a4ccSJason Gunthorpe test_writer->init_entry, NUM_ENTRY_QWORDS) &&
8756e1a4ccSJason Gunthorpe arm_smmu_entry_differs_in_used_bits(
8856e1a4ccSJason Gunthorpe test_writer->entry, entry_used_bits,
8956e1a4ccSJason Gunthorpe test_writer->target_entry,
9056e1a4ccSJason Gunthorpe NUM_ENTRY_QWORDS));
9156e1a4ccSJason Gunthorpe }
9256e1a4ccSJason Gunthorpe }
9356e1a4ccSJason Gunthorpe
9456e1a4ccSJason Gunthorpe static void
arm_smmu_v3_test_debug_print_used_bits(struct arm_smmu_entry_writer * writer,const __le64 * ste)9556e1a4ccSJason Gunthorpe arm_smmu_v3_test_debug_print_used_bits(struct arm_smmu_entry_writer *writer,
9656e1a4ccSJason Gunthorpe const __le64 *ste)
9756e1a4ccSJason Gunthorpe {
9856e1a4ccSJason Gunthorpe __le64 used_bits[NUM_ENTRY_QWORDS] = {};
9956e1a4ccSJason Gunthorpe
10056e1a4ccSJason Gunthorpe arm_smmu_get_ste_used(ste, used_bits);
10156e1a4ccSJason Gunthorpe pr_debug("STE used bits: ");
10256e1a4ccSJason Gunthorpe print_hex_dump_debug(" ", DUMP_PREFIX_NONE, 16, 8, used_bits,
10356e1a4ccSJason Gunthorpe sizeof(used_bits), false);
10456e1a4ccSJason Gunthorpe }
10556e1a4ccSJason Gunthorpe
10656e1a4ccSJason Gunthorpe static const struct arm_smmu_entry_writer_ops test_ste_ops = {
10756e1a4ccSJason Gunthorpe .sync = arm_smmu_test_writer_record_syncs,
10856e1a4ccSJason Gunthorpe .get_used = arm_smmu_get_ste_used,
10956e1a4ccSJason Gunthorpe };
11056e1a4ccSJason Gunthorpe
11156e1a4ccSJason Gunthorpe static const struct arm_smmu_entry_writer_ops test_cd_ops = {
11256e1a4ccSJason Gunthorpe .sync = arm_smmu_test_writer_record_syncs,
11356e1a4ccSJason Gunthorpe .get_used = arm_smmu_get_cd_used,
11456e1a4ccSJason Gunthorpe };
11556e1a4ccSJason Gunthorpe
arm_smmu_v3_test_ste_expect_transition(struct kunit * test,const struct arm_smmu_ste * cur,const struct arm_smmu_ste * target,unsigned int num_syncs_expected,bool hitless)11656e1a4ccSJason Gunthorpe static void arm_smmu_v3_test_ste_expect_transition(
11756e1a4ccSJason Gunthorpe struct kunit *test, const struct arm_smmu_ste *cur,
11856e1a4ccSJason Gunthorpe const struct arm_smmu_ste *target, unsigned int num_syncs_expected,
11956e1a4ccSJason Gunthorpe bool hitless)
12056e1a4ccSJason Gunthorpe {
12156e1a4ccSJason Gunthorpe struct arm_smmu_ste cur_copy = *cur;
12256e1a4ccSJason Gunthorpe struct arm_smmu_test_writer test_writer = {
12356e1a4ccSJason Gunthorpe .writer = {
12456e1a4ccSJason Gunthorpe .ops = &test_ste_ops,
12556e1a4ccSJason Gunthorpe },
12656e1a4ccSJason Gunthorpe .test = test,
12756e1a4ccSJason Gunthorpe .init_entry = cur->data,
12856e1a4ccSJason Gunthorpe .target_entry = target->data,
12956e1a4ccSJason Gunthorpe .entry = cur_copy.data,
13056e1a4ccSJason Gunthorpe .num_syncs = 0,
13156e1a4ccSJason Gunthorpe .invalid_entry_written = false,
13256e1a4ccSJason Gunthorpe
13356e1a4ccSJason Gunthorpe };
13456e1a4ccSJason Gunthorpe
13556e1a4ccSJason Gunthorpe pr_debug("STE initial value: ");
13656e1a4ccSJason Gunthorpe print_hex_dump_debug(" ", DUMP_PREFIX_NONE, 16, 8, cur_copy.data,
13756e1a4ccSJason Gunthorpe sizeof(cur_copy), false);
13856e1a4ccSJason Gunthorpe arm_smmu_v3_test_debug_print_used_bits(&test_writer.writer, cur->data);
13956e1a4ccSJason Gunthorpe pr_debug("STE target value: ");
14056e1a4ccSJason Gunthorpe print_hex_dump_debug(" ", DUMP_PREFIX_NONE, 16, 8, target->data,
14156e1a4ccSJason Gunthorpe sizeof(cur_copy), false);
14256e1a4ccSJason Gunthorpe arm_smmu_v3_test_debug_print_used_bits(&test_writer.writer,
14356e1a4ccSJason Gunthorpe target->data);
14456e1a4ccSJason Gunthorpe
14556e1a4ccSJason Gunthorpe arm_smmu_write_entry(&test_writer.writer, cur_copy.data, target->data);
14656e1a4ccSJason Gunthorpe
14756e1a4ccSJason Gunthorpe KUNIT_EXPECT_EQ(test, test_writer.invalid_entry_written, !hitless);
14856e1a4ccSJason Gunthorpe KUNIT_EXPECT_EQ(test, test_writer.num_syncs, num_syncs_expected);
14956e1a4ccSJason Gunthorpe KUNIT_EXPECT_MEMEQ(test, target->data, cur_copy.data, sizeof(cur_copy));
15056e1a4ccSJason Gunthorpe }
15156e1a4ccSJason Gunthorpe
arm_smmu_v3_test_ste_expect_non_hitless_transition(struct kunit * test,const struct arm_smmu_ste * cur,const struct arm_smmu_ste * target,unsigned int num_syncs_expected)1523b5302cbSJason Gunthorpe static void arm_smmu_v3_test_ste_expect_non_hitless_transition(
1533b5302cbSJason Gunthorpe struct kunit *test, const struct arm_smmu_ste *cur,
1543b5302cbSJason Gunthorpe const struct arm_smmu_ste *target, unsigned int num_syncs_expected)
1553b5302cbSJason Gunthorpe {
1563b5302cbSJason Gunthorpe arm_smmu_v3_test_ste_expect_transition(test, cur, target,
1573b5302cbSJason Gunthorpe num_syncs_expected, false);
1583b5302cbSJason Gunthorpe }
1593b5302cbSJason Gunthorpe
arm_smmu_v3_test_ste_expect_hitless_transition(struct kunit * test,const struct arm_smmu_ste * cur,const struct arm_smmu_ste * target,unsigned int num_syncs_expected)16056e1a4ccSJason Gunthorpe static void arm_smmu_v3_test_ste_expect_hitless_transition(
16156e1a4ccSJason Gunthorpe struct kunit *test, const struct arm_smmu_ste *cur,
16256e1a4ccSJason Gunthorpe const struct arm_smmu_ste *target, unsigned int num_syncs_expected)
16356e1a4ccSJason Gunthorpe {
16456e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_transition(test, cur, target,
16556e1a4ccSJason Gunthorpe num_syncs_expected, true);
16656e1a4ccSJason Gunthorpe }
16756e1a4ccSJason Gunthorpe
16856e1a4ccSJason Gunthorpe static const dma_addr_t fake_cdtab_dma_addr = 0xF0F0F0F0F0F0;
16956e1a4ccSJason Gunthorpe
arm_smmu_test_make_cdtable_ste(struct arm_smmu_ste * ste,unsigned int s1dss,const dma_addr_t dma_addr,enum arm_smmu_test_master_feat feat)17056e1a4ccSJason Gunthorpe static void arm_smmu_test_make_cdtable_ste(struct arm_smmu_ste *ste,
1713b5302cbSJason Gunthorpe unsigned int s1dss,
172*070e326fSMostafa Saleh const dma_addr_t dma_addr,
173*070e326fSMostafa Saleh enum arm_smmu_test_master_feat feat)
17456e1a4ccSJason Gunthorpe {
175*070e326fSMostafa Saleh bool ats_enabled = feat & ARM_SMMU_MASTER_TEST_ATS;
176*070e326fSMostafa Saleh bool stall_enabled = feat & ARM_SMMU_MASTER_TEST_STALL;
177*070e326fSMostafa Saleh
17856e1a4ccSJason Gunthorpe struct arm_smmu_master master = {
179*070e326fSMostafa Saleh .ats_enabled = ats_enabled,
18056e1a4ccSJason Gunthorpe .cd_table.cdtab_dma = dma_addr,
18156e1a4ccSJason Gunthorpe .cd_table.s1cdmax = 0xFF,
18256e1a4ccSJason Gunthorpe .cd_table.s1fmt = STRTAB_STE_0_S1FMT_64K_L2,
18356e1a4ccSJason Gunthorpe .smmu = &smmu,
184*070e326fSMostafa Saleh .stall_enabled = stall_enabled,
18556e1a4ccSJason Gunthorpe };
18656e1a4ccSJason Gunthorpe
187*070e326fSMostafa Saleh arm_smmu_make_cdtable_ste(ste, &master, ats_enabled, s1dss);
18856e1a4ccSJason Gunthorpe }
18956e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_bypass_to_abort(struct kunit * test)19056e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_bypass_to_abort(struct kunit *test)
19156e1a4ccSJason Gunthorpe {
19256e1a4ccSJason Gunthorpe /*
19356e1a4ccSJason Gunthorpe * Bypass STEs has used bits in the first two Qwords, while abort STEs
19456e1a4ccSJason Gunthorpe * only have used bits in the first QWord. Transitioning from bypass to
19556e1a4ccSJason Gunthorpe * abort requires two syncs: the first to set the first qword and make
19656e1a4ccSJason Gunthorpe * the STE into an abort, the second to clean up the second qword.
19756e1a4ccSJason Gunthorpe */
19856e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(
19956e1a4ccSJason Gunthorpe test, &bypass_ste, &abort_ste, NUM_EXPECTED_SYNCS(2));
20056e1a4ccSJason Gunthorpe }
20156e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_abort_to_bypass(struct kunit * test)20256e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_abort_to_bypass(struct kunit *test)
20356e1a4ccSJason Gunthorpe {
20456e1a4ccSJason Gunthorpe /*
20556e1a4ccSJason Gunthorpe * Transitioning from abort to bypass also requires two syncs: the first
20656e1a4ccSJason Gunthorpe * to set the second qword data required by the bypass STE, and the
20756e1a4ccSJason Gunthorpe * second to set the first qword and switch to bypass.
20856e1a4ccSJason Gunthorpe */
20956e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(
21056e1a4ccSJason Gunthorpe test, &abort_ste, &bypass_ste, NUM_EXPECTED_SYNCS(2));
21156e1a4ccSJason Gunthorpe }
21256e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_cdtable_to_abort(struct kunit * test)21356e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_cdtable_to_abort(struct kunit *test)
21456e1a4ccSJason Gunthorpe {
21556e1a4ccSJason Gunthorpe struct arm_smmu_ste ste;
21656e1a4ccSJason Gunthorpe
2173b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
218*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
21956e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &ste, &abort_ste,
22056e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(2));
22156e1a4ccSJason Gunthorpe }
22256e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_abort_to_cdtable(struct kunit * test)22356e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_abort_to_cdtable(struct kunit *test)
22456e1a4ccSJason Gunthorpe {
22556e1a4ccSJason Gunthorpe struct arm_smmu_ste ste;
22656e1a4ccSJason Gunthorpe
2273b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
228*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
22956e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &abort_ste, &ste,
23056e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(2));
23156e1a4ccSJason Gunthorpe }
23256e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_cdtable_to_bypass(struct kunit * test)23356e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_cdtable_to_bypass(struct kunit *test)
23456e1a4ccSJason Gunthorpe {
23556e1a4ccSJason Gunthorpe struct arm_smmu_ste ste;
23656e1a4ccSJason Gunthorpe
2373b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
238*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
23956e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &ste, &bypass_ste,
24056e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(3));
24156e1a4ccSJason Gunthorpe }
24256e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_bypass_to_cdtable(struct kunit * test)24356e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_bypass_to_cdtable(struct kunit *test)
24456e1a4ccSJason Gunthorpe {
24556e1a4ccSJason Gunthorpe struct arm_smmu_ste ste;
24656e1a4ccSJason Gunthorpe
2473b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
248*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
24956e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &bypass_ste, &ste,
25056e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(3));
25156e1a4ccSJason Gunthorpe }
25256e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_cdtable_s1dss_change(struct kunit * test)2533b5302cbSJason Gunthorpe static void arm_smmu_v3_write_ste_test_cdtable_s1dss_change(struct kunit *test)
2543b5302cbSJason Gunthorpe {
2553b5302cbSJason Gunthorpe struct arm_smmu_ste ste;
2563b5302cbSJason Gunthorpe struct arm_smmu_ste s1dss_bypass;
2573b5302cbSJason Gunthorpe
2583b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
259*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
2603b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&s1dss_bypass, STRTAB_STE_1_S1DSS_BYPASS,
261*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
2623b5302cbSJason Gunthorpe
2633b5302cbSJason Gunthorpe /*
2643b5302cbSJason Gunthorpe * Flipping s1dss on a CD table STE only involves changes to the second
2653b5302cbSJason Gunthorpe * qword of an STE and can be done in a single write.
2663b5302cbSJason Gunthorpe */
2673b5302cbSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(
2683b5302cbSJason Gunthorpe test, &ste, &s1dss_bypass, NUM_EXPECTED_SYNCS(1));
2693b5302cbSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(
2703b5302cbSJason Gunthorpe test, &s1dss_bypass, &ste, NUM_EXPECTED_SYNCS(1));
2713b5302cbSJason Gunthorpe }
2723b5302cbSJason Gunthorpe
2733b5302cbSJason Gunthorpe static void
arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass(struct kunit * test)2743b5302cbSJason Gunthorpe arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass(struct kunit *test)
2753b5302cbSJason Gunthorpe {
2763b5302cbSJason Gunthorpe struct arm_smmu_ste s1dss_bypass;
2773b5302cbSJason Gunthorpe
2783b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&s1dss_bypass, STRTAB_STE_1_S1DSS_BYPASS,
279*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
2803b5302cbSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(
2813b5302cbSJason Gunthorpe test, &s1dss_bypass, &bypass_ste, NUM_EXPECTED_SYNCS(2));
2823b5302cbSJason Gunthorpe }
2833b5302cbSJason Gunthorpe
2843b5302cbSJason Gunthorpe static void
arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass(struct kunit * test)2853b5302cbSJason Gunthorpe arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass(struct kunit *test)
2863b5302cbSJason Gunthorpe {
2873b5302cbSJason Gunthorpe struct arm_smmu_ste s1dss_bypass;
2883b5302cbSJason Gunthorpe
2893b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&s1dss_bypass, STRTAB_STE_1_S1DSS_BYPASS,
290*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
2913b5302cbSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(
2923b5302cbSJason Gunthorpe test, &bypass_ste, &s1dss_bypass, NUM_EXPECTED_SYNCS(2));
2933b5302cbSJason Gunthorpe }
2943b5302cbSJason Gunthorpe
arm_smmu_test_make_s2_ste(struct arm_smmu_ste * ste,enum arm_smmu_test_master_feat feat)29556e1a4ccSJason Gunthorpe static void arm_smmu_test_make_s2_ste(struct arm_smmu_ste *ste,
296*070e326fSMostafa Saleh enum arm_smmu_test_master_feat feat)
29756e1a4ccSJason Gunthorpe {
298*070e326fSMostafa Saleh bool ats_enabled = feat & ARM_SMMU_MASTER_TEST_ATS;
299*070e326fSMostafa Saleh bool stall_enabled = feat & ARM_SMMU_MASTER_TEST_STALL;
30056e1a4ccSJason Gunthorpe struct arm_smmu_master master = {
301*070e326fSMostafa Saleh .ats_enabled = ats_enabled,
30256e1a4ccSJason Gunthorpe .smmu = &smmu,
303*070e326fSMostafa Saleh .stall_enabled = stall_enabled,
30456e1a4ccSJason Gunthorpe };
30556e1a4ccSJason Gunthorpe struct io_pgtable io_pgtable = {};
30656e1a4ccSJason Gunthorpe struct arm_smmu_domain smmu_domain = {
30756e1a4ccSJason Gunthorpe .pgtbl_ops = &io_pgtable.ops,
30856e1a4ccSJason Gunthorpe };
30956e1a4ccSJason Gunthorpe
31056e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s2_cfg.vttbr = 0xdaedbeefdeadbeefULL;
31156e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.ps = 1;
31256e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.tg = 2;
31356e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.sh = 3;
31456e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.orgn = 1;
31556e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.irgn = 2;
31656e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.sl = 3;
31756e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s2_cfg.vtcr.tsz = 4;
31856e1a4ccSJason Gunthorpe
3197497f421SJason Gunthorpe arm_smmu_make_s2_domain_ste(ste, &master, &smmu_domain, ats_enabled);
32056e1a4ccSJason Gunthorpe }
32156e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_s2_to_abort(struct kunit * test)32256e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_s2_to_abort(struct kunit *test)
32356e1a4ccSJason Gunthorpe {
32456e1a4ccSJason Gunthorpe struct arm_smmu_ste ste;
32556e1a4ccSJason Gunthorpe
326*070e326fSMostafa Saleh arm_smmu_test_make_s2_ste(&ste, ARM_SMMU_MASTER_TEST_ATS);
32756e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &ste, &abort_ste,
32856e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(2));
32956e1a4ccSJason Gunthorpe }
33056e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_abort_to_s2(struct kunit * test)33156e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_abort_to_s2(struct kunit *test)
33256e1a4ccSJason Gunthorpe {
33356e1a4ccSJason Gunthorpe struct arm_smmu_ste ste;
33456e1a4ccSJason Gunthorpe
335*070e326fSMostafa Saleh arm_smmu_test_make_s2_ste(&ste, ARM_SMMU_MASTER_TEST_ATS);
33656e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &abort_ste, &ste,
33756e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(2));
33856e1a4ccSJason Gunthorpe }
33956e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_s2_to_bypass(struct kunit * test)34056e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_s2_to_bypass(struct kunit *test)
34156e1a4ccSJason Gunthorpe {
34256e1a4ccSJason Gunthorpe struct arm_smmu_ste ste;
34356e1a4ccSJason Gunthorpe
344*070e326fSMostafa Saleh arm_smmu_test_make_s2_ste(&ste, ARM_SMMU_MASTER_TEST_ATS);
34556e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &ste, &bypass_ste,
34656e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(2));
34756e1a4ccSJason Gunthorpe }
34856e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_bypass_to_s2(struct kunit * test)34956e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_ste_test_bypass_to_s2(struct kunit *test)
35056e1a4ccSJason Gunthorpe {
35156e1a4ccSJason Gunthorpe struct arm_smmu_ste ste;
35256e1a4ccSJason Gunthorpe
353*070e326fSMostafa Saleh arm_smmu_test_make_s2_ste(&ste, ARM_SMMU_MASTER_TEST_ATS);
35456e1a4ccSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &bypass_ste, &ste,
35556e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(2));
35656e1a4ccSJason Gunthorpe }
35756e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_s1_to_s2(struct kunit * test)3583b5302cbSJason Gunthorpe static void arm_smmu_v3_write_ste_test_s1_to_s2(struct kunit *test)
3593b5302cbSJason Gunthorpe {
3603b5302cbSJason Gunthorpe struct arm_smmu_ste s1_ste;
3613b5302cbSJason Gunthorpe struct arm_smmu_ste s2_ste;
3623b5302cbSJason Gunthorpe
3633b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&s1_ste, STRTAB_STE_1_S1DSS_SSID0,
364*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
365*070e326fSMostafa Saleh arm_smmu_test_make_s2_ste(&s2_ste, ARM_SMMU_MASTER_TEST_ATS);
3663b5302cbSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &s1_ste, &s2_ste,
3673b5302cbSJason Gunthorpe NUM_EXPECTED_SYNCS(3));
3683b5302cbSJason Gunthorpe }
3693b5302cbSJason Gunthorpe
arm_smmu_v3_write_ste_test_s2_to_s1(struct kunit * test)3703b5302cbSJason Gunthorpe static void arm_smmu_v3_write_ste_test_s2_to_s1(struct kunit *test)
3713b5302cbSJason Gunthorpe {
3723b5302cbSJason Gunthorpe struct arm_smmu_ste s1_ste;
3733b5302cbSJason Gunthorpe struct arm_smmu_ste s2_ste;
3743b5302cbSJason Gunthorpe
3753b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&s1_ste, STRTAB_STE_1_S1DSS_SSID0,
376*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
377*070e326fSMostafa Saleh arm_smmu_test_make_s2_ste(&s2_ste, ARM_SMMU_MASTER_TEST_ATS);
3783b5302cbSJason Gunthorpe arm_smmu_v3_test_ste_expect_hitless_transition(test, &s2_ste, &s1_ste,
3793b5302cbSJason Gunthorpe NUM_EXPECTED_SYNCS(3));
3803b5302cbSJason Gunthorpe }
3813b5302cbSJason Gunthorpe
arm_smmu_v3_write_ste_test_non_hitless(struct kunit * test)3823b5302cbSJason Gunthorpe static void arm_smmu_v3_write_ste_test_non_hitless(struct kunit *test)
3833b5302cbSJason Gunthorpe {
3843b5302cbSJason Gunthorpe struct arm_smmu_ste ste;
3853b5302cbSJason Gunthorpe struct arm_smmu_ste ste_2;
3863b5302cbSJason Gunthorpe
3873b5302cbSJason Gunthorpe /*
3883b5302cbSJason Gunthorpe * Although no flow resembles this in practice, one way to force an STE
3893b5302cbSJason Gunthorpe * update to be non-hitless is to change its CD table pointer as well as
3903b5302cbSJason Gunthorpe * s1 dss field in the same update.
3913b5302cbSJason Gunthorpe */
3923b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
393*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_ATS);
3943b5302cbSJason Gunthorpe arm_smmu_test_make_cdtable_ste(&ste_2, STRTAB_STE_1_S1DSS_BYPASS,
395*070e326fSMostafa Saleh 0x4B4B4b4B4B, ARM_SMMU_MASTER_TEST_ATS);
3963b5302cbSJason Gunthorpe arm_smmu_v3_test_ste_expect_non_hitless_transition(
3973b5302cbSJason Gunthorpe test, &ste, &ste_2, NUM_EXPECTED_SYNCS(3));
3983b5302cbSJason Gunthorpe }
3993b5302cbSJason Gunthorpe
arm_smmu_v3_test_cd_expect_transition(struct kunit * test,const struct arm_smmu_cd * cur,const struct arm_smmu_cd * target,unsigned int num_syncs_expected,bool hitless)40056e1a4ccSJason Gunthorpe static void arm_smmu_v3_test_cd_expect_transition(
40156e1a4ccSJason Gunthorpe struct kunit *test, const struct arm_smmu_cd *cur,
40256e1a4ccSJason Gunthorpe const struct arm_smmu_cd *target, unsigned int num_syncs_expected,
40356e1a4ccSJason Gunthorpe bool hitless)
40456e1a4ccSJason Gunthorpe {
40556e1a4ccSJason Gunthorpe struct arm_smmu_cd cur_copy = *cur;
40656e1a4ccSJason Gunthorpe struct arm_smmu_test_writer test_writer = {
40756e1a4ccSJason Gunthorpe .writer = {
40856e1a4ccSJason Gunthorpe .ops = &test_cd_ops,
40956e1a4ccSJason Gunthorpe },
41056e1a4ccSJason Gunthorpe .test = test,
41156e1a4ccSJason Gunthorpe .init_entry = cur->data,
41256e1a4ccSJason Gunthorpe .target_entry = target->data,
41356e1a4ccSJason Gunthorpe .entry = cur_copy.data,
41456e1a4ccSJason Gunthorpe .num_syncs = 0,
41556e1a4ccSJason Gunthorpe .invalid_entry_written = false,
41656e1a4ccSJason Gunthorpe
41756e1a4ccSJason Gunthorpe };
41856e1a4ccSJason Gunthorpe
41956e1a4ccSJason Gunthorpe pr_debug("CD initial value: ");
42056e1a4ccSJason Gunthorpe print_hex_dump_debug(" ", DUMP_PREFIX_NONE, 16, 8, cur_copy.data,
42156e1a4ccSJason Gunthorpe sizeof(cur_copy), false);
42256e1a4ccSJason Gunthorpe arm_smmu_v3_test_debug_print_used_bits(&test_writer.writer, cur->data);
42356e1a4ccSJason Gunthorpe pr_debug("CD target value: ");
42456e1a4ccSJason Gunthorpe print_hex_dump_debug(" ", DUMP_PREFIX_NONE, 16, 8, target->data,
42556e1a4ccSJason Gunthorpe sizeof(cur_copy), false);
42656e1a4ccSJason Gunthorpe arm_smmu_v3_test_debug_print_used_bits(&test_writer.writer,
42756e1a4ccSJason Gunthorpe target->data);
42856e1a4ccSJason Gunthorpe
42956e1a4ccSJason Gunthorpe arm_smmu_write_entry(&test_writer.writer, cur_copy.data, target->data);
43056e1a4ccSJason Gunthorpe
43156e1a4ccSJason Gunthorpe KUNIT_EXPECT_EQ(test, test_writer.invalid_entry_written, !hitless);
43256e1a4ccSJason Gunthorpe KUNIT_EXPECT_EQ(test, test_writer.num_syncs, num_syncs_expected);
43356e1a4ccSJason Gunthorpe KUNIT_EXPECT_MEMEQ(test, target->data, cur_copy.data, sizeof(cur_copy));
43456e1a4ccSJason Gunthorpe }
43556e1a4ccSJason Gunthorpe
arm_smmu_v3_test_cd_expect_non_hitless_transition(struct kunit * test,const struct arm_smmu_cd * cur,const struct arm_smmu_cd * target,unsigned int num_syncs_expected)43656e1a4ccSJason Gunthorpe static void arm_smmu_v3_test_cd_expect_non_hitless_transition(
43756e1a4ccSJason Gunthorpe struct kunit *test, const struct arm_smmu_cd *cur,
43856e1a4ccSJason Gunthorpe const struct arm_smmu_cd *target, unsigned int num_syncs_expected)
43956e1a4ccSJason Gunthorpe {
44056e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_transition(test, cur, target,
44156e1a4ccSJason Gunthorpe num_syncs_expected, false);
44256e1a4ccSJason Gunthorpe }
44356e1a4ccSJason Gunthorpe
arm_smmu_v3_test_cd_expect_hitless_transition(struct kunit * test,const struct arm_smmu_cd * cur,const struct arm_smmu_cd * target,unsigned int num_syncs_expected)44456e1a4ccSJason Gunthorpe static void arm_smmu_v3_test_cd_expect_hitless_transition(
44556e1a4ccSJason Gunthorpe struct kunit *test, const struct arm_smmu_cd *cur,
44656e1a4ccSJason Gunthorpe const struct arm_smmu_cd *target, unsigned int num_syncs_expected)
44756e1a4ccSJason Gunthorpe {
44856e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_transition(test, cur, target,
44956e1a4ccSJason Gunthorpe num_syncs_expected, true);
45056e1a4ccSJason Gunthorpe }
45156e1a4ccSJason Gunthorpe
arm_smmu_test_make_s1_cd(struct arm_smmu_cd * cd,unsigned int asid)45256e1a4ccSJason Gunthorpe static void arm_smmu_test_make_s1_cd(struct arm_smmu_cd *cd, unsigned int asid)
45356e1a4ccSJason Gunthorpe {
45456e1a4ccSJason Gunthorpe struct arm_smmu_master master = {
45556e1a4ccSJason Gunthorpe .smmu = &smmu,
45656e1a4ccSJason Gunthorpe };
45756e1a4ccSJason Gunthorpe struct io_pgtable io_pgtable = {};
45856e1a4ccSJason Gunthorpe struct arm_smmu_domain smmu_domain = {
45956e1a4ccSJason Gunthorpe .pgtbl_ops = &io_pgtable.ops,
46056e1a4ccSJason Gunthorpe .cd = {
46156e1a4ccSJason Gunthorpe .asid = asid,
46256e1a4ccSJason Gunthorpe },
46356e1a4ccSJason Gunthorpe };
46456e1a4ccSJason Gunthorpe
46556e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s1_cfg.ttbr = 0xdaedbeefdeadbeefULL;
46656e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s1_cfg.tcr.ips = 1;
46756e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s1_cfg.tcr.tg = 2;
46856e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s1_cfg.tcr.sh = 3;
46956e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s1_cfg.tcr.orgn = 1;
47056e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s1_cfg.tcr.irgn = 2;
47156e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s1_cfg.tcr.tsz = 4;
47256e1a4ccSJason Gunthorpe io_pgtable.cfg.arm_lpae_s1_cfg.mair = 0xabcdef012345678ULL;
47356e1a4ccSJason Gunthorpe
47456e1a4ccSJason Gunthorpe arm_smmu_make_s1_cd(cd, &master, &smmu_domain);
47556e1a4ccSJason Gunthorpe }
47656e1a4ccSJason Gunthorpe
arm_smmu_v3_write_cd_test_s1_clear(struct kunit * test)47756e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_cd_test_s1_clear(struct kunit *test)
47856e1a4ccSJason Gunthorpe {
47956e1a4ccSJason Gunthorpe struct arm_smmu_cd cd = {};
48056e1a4ccSJason Gunthorpe struct arm_smmu_cd cd_2;
48156e1a4ccSJason Gunthorpe
48256e1a4ccSJason Gunthorpe arm_smmu_test_make_s1_cd(&cd_2, 1997);
48356e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_non_hitless_transition(
48456e1a4ccSJason Gunthorpe test, &cd, &cd_2, NUM_EXPECTED_SYNCS(2));
48556e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_non_hitless_transition(
48656e1a4ccSJason Gunthorpe test, &cd_2, &cd, NUM_EXPECTED_SYNCS(2));
48756e1a4ccSJason Gunthorpe }
48856e1a4ccSJason Gunthorpe
arm_smmu_v3_write_cd_test_s1_change_asid(struct kunit * test)48956e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_cd_test_s1_change_asid(struct kunit *test)
49056e1a4ccSJason Gunthorpe {
49156e1a4ccSJason Gunthorpe struct arm_smmu_cd cd = {};
49256e1a4ccSJason Gunthorpe struct arm_smmu_cd cd_2;
49356e1a4ccSJason Gunthorpe
49456e1a4ccSJason Gunthorpe arm_smmu_test_make_s1_cd(&cd, 778);
49556e1a4ccSJason Gunthorpe arm_smmu_test_make_s1_cd(&cd_2, 1997);
49656e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_hitless_transition(test, &cd, &cd_2,
49756e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(1));
49856e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_hitless_transition(test, &cd_2, &cd,
49956e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(1));
50056e1a4ccSJason Gunthorpe }
50156e1a4ccSJason Gunthorpe
arm_smmu_test_make_sva_cd(struct arm_smmu_cd * cd,unsigned int asid)50256e1a4ccSJason Gunthorpe static void arm_smmu_test_make_sva_cd(struct arm_smmu_cd *cd, unsigned int asid)
50356e1a4ccSJason Gunthorpe {
50456e1a4ccSJason Gunthorpe struct arm_smmu_master master = {
50556e1a4ccSJason Gunthorpe .smmu = &smmu,
50656e1a4ccSJason Gunthorpe };
50756e1a4ccSJason Gunthorpe
50856e1a4ccSJason Gunthorpe arm_smmu_make_sva_cd(cd, &master, &sva_mm, asid);
50956e1a4ccSJason Gunthorpe }
51056e1a4ccSJason Gunthorpe
arm_smmu_test_make_sva_release_cd(struct arm_smmu_cd * cd,unsigned int asid)51156e1a4ccSJason Gunthorpe static void arm_smmu_test_make_sva_release_cd(struct arm_smmu_cd *cd,
51256e1a4ccSJason Gunthorpe unsigned int asid)
51356e1a4ccSJason Gunthorpe {
51456e1a4ccSJason Gunthorpe struct arm_smmu_master master = {
51556e1a4ccSJason Gunthorpe .smmu = &smmu,
51656e1a4ccSJason Gunthorpe };
51756e1a4ccSJason Gunthorpe
51856e1a4ccSJason Gunthorpe arm_smmu_make_sva_cd(cd, &master, NULL, asid);
51956e1a4ccSJason Gunthorpe }
52056e1a4ccSJason Gunthorpe
arm_smmu_v3_write_ste_test_s1_to_s2_stall(struct kunit * test)521*070e326fSMostafa Saleh static void arm_smmu_v3_write_ste_test_s1_to_s2_stall(struct kunit *test)
522*070e326fSMostafa Saleh {
523*070e326fSMostafa Saleh struct arm_smmu_ste s1_ste;
524*070e326fSMostafa Saleh struct arm_smmu_ste s2_ste;
525*070e326fSMostafa Saleh
526*070e326fSMostafa Saleh arm_smmu_test_make_cdtable_ste(&s1_ste, STRTAB_STE_1_S1DSS_SSID0,
527*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_STALL);
528*070e326fSMostafa Saleh arm_smmu_test_make_s2_ste(&s2_ste, ARM_SMMU_MASTER_TEST_STALL);
529*070e326fSMostafa Saleh arm_smmu_v3_test_ste_expect_hitless_transition(test, &s1_ste, &s2_ste,
530*070e326fSMostafa Saleh NUM_EXPECTED_SYNCS(3));
531*070e326fSMostafa Saleh }
532*070e326fSMostafa Saleh
arm_smmu_v3_write_ste_test_s2_to_s1_stall(struct kunit * test)533*070e326fSMostafa Saleh static void arm_smmu_v3_write_ste_test_s2_to_s1_stall(struct kunit *test)
534*070e326fSMostafa Saleh {
535*070e326fSMostafa Saleh struct arm_smmu_ste s1_ste;
536*070e326fSMostafa Saleh struct arm_smmu_ste s2_ste;
537*070e326fSMostafa Saleh
538*070e326fSMostafa Saleh arm_smmu_test_make_cdtable_ste(&s1_ste, STRTAB_STE_1_S1DSS_SSID0,
539*070e326fSMostafa Saleh fake_cdtab_dma_addr, ARM_SMMU_MASTER_TEST_STALL);
540*070e326fSMostafa Saleh arm_smmu_test_make_s2_ste(&s2_ste, ARM_SMMU_MASTER_TEST_STALL);
541*070e326fSMostafa Saleh arm_smmu_v3_test_ste_expect_hitless_transition(test, &s2_ste, &s1_ste,
542*070e326fSMostafa Saleh NUM_EXPECTED_SYNCS(3));
543*070e326fSMostafa Saleh }
544*070e326fSMostafa Saleh
arm_smmu_v3_write_cd_test_sva_clear(struct kunit * test)54556e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_cd_test_sva_clear(struct kunit *test)
54656e1a4ccSJason Gunthorpe {
54756e1a4ccSJason Gunthorpe struct arm_smmu_cd cd = {};
54856e1a4ccSJason Gunthorpe struct arm_smmu_cd cd_2;
54956e1a4ccSJason Gunthorpe
55056e1a4ccSJason Gunthorpe arm_smmu_test_make_sva_cd(&cd_2, 1997);
55156e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_non_hitless_transition(
55256e1a4ccSJason Gunthorpe test, &cd, &cd_2, NUM_EXPECTED_SYNCS(2));
55356e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_non_hitless_transition(
55456e1a4ccSJason Gunthorpe test, &cd_2, &cd, NUM_EXPECTED_SYNCS(2));
55556e1a4ccSJason Gunthorpe }
55656e1a4ccSJason Gunthorpe
arm_smmu_v3_write_cd_test_sva_release(struct kunit * test)55756e1a4ccSJason Gunthorpe static void arm_smmu_v3_write_cd_test_sva_release(struct kunit *test)
55856e1a4ccSJason Gunthorpe {
55956e1a4ccSJason Gunthorpe struct arm_smmu_cd cd;
56056e1a4ccSJason Gunthorpe struct arm_smmu_cd cd_2;
56156e1a4ccSJason Gunthorpe
56256e1a4ccSJason Gunthorpe arm_smmu_test_make_sva_cd(&cd, 1997);
56356e1a4ccSJason Gunthorpe arm_smmu_test_make_sva_release_cd(&cd_2, 1997);
56456e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_hitless_transition(test, &cd, &cd_2,
56556e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(2));
56656e1a4ccSJason Gunthorpe arm_smmu_v3_test_cd_expect_hitless_transition(test, &cd_2, &cd,
56756e1a4ccSJason Gunthorpe NUM_EXPECTED_SYNCS(2));
56856e1a4ccSJason Gunthorpe }
56956e1a4ccSJason Gunthorpe
57056e1a4ccSJason Gunthorpe static struct kunit_case arm_smmu_v3_test_cases[] = {
57156e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_bypass_to_abort),
57256e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_abort_to_bypass),
57356e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_cdtable_to_abort),
57456e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_abort_to_cdtable),
57556e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_cdtable_to_bypass),
57656e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_bypass_to_cdtable),
5773b5302cbSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_cdtable_s1dss_change),
5783b5302cbSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass),
5793b5302cbSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass),
58056e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_s2_to_abort),
58156e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_abort_to_s2),
58256e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_s2_to_bypass),
58356e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_bypass_to_s2),
5843b5302cbSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_s1_to_s2),
5853b5302cbSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_s2_to_s1),
5863b5302cbSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_ste_test_non_hitless),
58756e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_cd_test_s1_clear),
58856e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_cd_test_s1_change_asid),
589*070e326fSMostafa Saleh KUNIT_CASE(arm_smmu_v3_write_ste_test_s1_to_s2_stall),
590*070e326fSMostafa Saleh KUNIT_CASE(arm_smmu_v3_write_ste_test_s2_to_s1_stall),
59156e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_cd_test_sva_clear),
59256e1a4ccSJason Gunthorpe KUNIT_CASE(arm_smmu_v3_write_cd_test_sva_release),
59356e1a4ccSJason Gunthorpe {},
59456e1a4ccSJason Gunthorpe };
59556e1a4ccSJason Gunthorpe
arm_smmu_v3_test_suite_init(struct kunit_suite * test)59656e1a4ccSJason Gunthorpe static int arm_smmu_v3_test_suite_init(struct kunit_suite *test)
59756e1a4ccSJason Gunthorpe {
59856e1a4ccSJason Gunthorpe arm_smmu_make_bypass_ste(&smmu, &bypass_ste);
59956e1a4ccSJason Gunthorpe arm_smmu_make_abort_ste(&abort_ste);
60056e1a4ccSJason Gunthorpe return 0;
60156e1a4ccSJason Gunthorpe }
60256e1a4ccSJason Gunthorpe
60356e1a4ccSJason Gunthorpe static struct kunit_suite arm_smmu_v3_test_module = {
60456e1a4ccSJason Gunthorpe .name = "arm-smmu-v3-kunit-test",
60556e1a4ccSJason Gunthorpe .suite_init = arm_smmu_v3_test_suite_init,
60656e1a4ccSJason Gunthorpe .test_cases = arm_smmu_v3_test_cases,
60756e1a4ccSJason Gunthorpe };
60856e1a4ccSJason Gunthorpe kunit_test_suites(&arm_smmu_v3_test_module);
609da55da5aSJason Gunthorpe
610da55da5aSJason Gunthorpe MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
611a35f443dSJeff Johnson MODULE_DESCRIPTION("KUnit tests for arm-smmu-v3 driver");
612da55da5aSJason Gunthorpe MODULE_LICENSE("GPL v2");
613