Skip to content

Commit 3b5302c

Browse files
jgunthorpewilldeacon
authored andcommitted
iommu/arm-smmu-v3: Test the STE S1DSS functionality
S1DSS brings in quite a few new transition pairs that are interesting. Test to/from S1DSS_BYPASS <-> S1DSS_SSID0, and BYPASS <-> S1DSS_SSID0. Test a contrived non-hitless flow to make sure that the logic works. Tested-by: Nicolin Chen <[email protected]> Signed-off-by: Michael Shavit <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Reviewed-by: Jerry Snitselaar <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent ce26ea9 commit 3b5302c

File tree

1 file changed

+108
-5
lines changed

1 file changed

+108
-5
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c

Lines changed: 108 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,14 @@ static void arm_smmu_v3_test_ste_expect_transition(
144144
KUNIT_EXPECT_MEMEQ(test, target->data, cur_copy.data, sizeof(cur_copy));
145145
}
146146

147+
static void arm_smmu_v3_test_ste_expect_non_hitless_transition(
148+
struct kunit *test, const struct arm_smmu_ste *cur,
149+
const struct arm_smmu_ste *target, unsigned int num_syncs_expected)
150+
{
151+
arm_smmu_v3_test_ste_expect_transition(test, cur, target,
152+
num_syncs_expected, false);
153+
}
154+
147155
static void arm_smmu_v3_test_ste_expect_hitless_transition(
148156
struct kunit *test, const struct arm_smmu_ste *cur,
149157
const struct arm_smmu_ste *target, unsigned int num_syncs_expected)
@@ -155,6 +163,7 @@ static void arm_smmu_v3_test_ste_expect_hitless_transition(
155163
static const dma_addr_t fake_cdtab_dma_addr = 0xF0F0F0F0F0F0;
156164

157165
static void arm_smmu_test_make_cdtable_ste(struct arm_smmu_ste *ste,
166+
unsigned int s1dss,
158167
const dma_addr_t dma_addr)
159168
{
160169
struct arm_smmu_master master = {
@@ -164,7 +173,7 @@ static void arm_smmu_test_make_cdtable_ste(struct arm_smmu_ste *ste,
164173
.smmu = &smmu,
165174
};
166175

167-
arm_smmu_make_cdtable_ste(ste, &master, true, STRTAB_STE_1_S1DSS_SSID0);
176+
arm_smmu_make_cdtable_ste(ste, &master, true, s1dss);
168177
}
169178

170179
static void arm_smmu_v3_write_ste_test_bypass_to_abort(struct kunit *test)
@@ -194,7 +203,8 @@ static void arm_smmu_v3_write_ste_test_cdtable_to_abort(struct kunit *test)
194203
{
195204
struct arm_smmu_ste ste;
196205

197-
arm_smmu_test_make_cdtable_ste(&ste, fake_cdtab_dma_addr);
206+
arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
207+
fake_cdtab_dma_addr);
198208
arm_smmu_v3_test_ste_expect_hitless_transition(test, &ste, &abort_ste,
199209
NUM_EXPECTED_SYNCS(2));
200210
}
@@ -203,7 +213,8 @@ static void arm_smmu_v3_write_ste_test_abort_to_cdtable(struct kunit *test)
203213
{
204214
struct arm_smmu_ste ste;
205215

206-
arm_smmu_test_make_cdtable_ste(&ste, fake_cdtab_dma_addr);
216+
arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
217+
fake_cdtab_dma_addr);
207218
arm_smmu_v3_test_ste_expect_hitless_transition(test, &abort_ste, &ste,
208219
NUM_EXPECTED_SYNCS(2));
209220
}
@@ -212,7 +223,8 @@ static void arm_smmu_v3_write_ste_test_cdtable_to_bypass(struct kunit *test)
212223
{
213224
struct arm_smmu_ste ste;
214225

215-
arm_smmu_test_make_cdtable_ste(&ste, fake_cdtab_dma_addr);
226+
arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
227+
fake_cdtab_dma_addr);
216228
arm_smmu_v3_test_ste_expect_hitless_transition(test, &ste, &bypass_ste,
217229
NUM_EXPECTED_SYNCS(3));
218230
}
@@ -221,11 +233,54 @@ static void arm_smmu_v3_write_ste_test_bypass_to_cdtable(struct kunit *test)
221233
{
222234
struct arm_smmu_ste ste;
223235

224-
arm_smmu_test_make_cdtable_ste(&ste, fake_cdtab_dma_addr);
236+
arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
237+
fake_cdtab_dma_addr);
225238
arm_smmu_v3_test_ste_expect_hitless_transition(test, &bypass_ste, &ste,
226239
NUM_EXPECTED_SYNCS(3));
227240
}
228241

242+
static void arm_smmu_v3_write_ste_test_cdtable_s1dss_change(struct kunit *test)
243+
{
244+
struct arm_smmu_ste ste;
245+
struct arm_smmu_ste s1dss_bypass;
246+
247+
arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
248+
fake_cdtab_dma_addr);
249+
arm_smmu_test_make_cdtable_ste(&s1dss_bypass, STRTAB_STE_1_S1DSS_BYPASS,
250+
fake_cdtab_dma_addr);
251+
252+
/*
253+
* Flipping s1dss on a CD table STE only involves changes to the second
254+
* qword of an STE and can be done in a single write.
255+
*/
256+
arm_smmu_v3_test_ste_expect_hitless_transition(
257+
test, &ste, &s1dss_bypass, NUM_EXPECTED_SYNCS(1));
258+
arm_smmu_v3_test_ste_expect_hitless_transition(
259+
test, &s1dss_bypass, &ste, NUM_EXPECTED_SYNCS(1));
260+
}
261+
262+
static void
263+
arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass(struct kunit *test)
264+
{
265+
struct arm_smmu_ste s1dss_bypass;
266+
267+
arm_smmu_test_make_cdtable_ste(&s1dss_bypass, STRTAB_STE_1_S1DSS_BYPASS,
268+
fake_cdtab_dma_addr);
269+
arm_smmu_v3_test_ste_expect_hitless_transition(
270+
test, &s1dss_bypass, &bypass_ste, NUM_EXPECTED_SYNCS(2));
271+
}
272+
273+
static void
274+
arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass(struct kunit *test)
275+
{
276+
struct arm_smmu_ste s1dss_bypass;
277+
278+
arm_smmu_test_make_cdtable_ste(&s1dss_bypass, STRTAB_STE_1_S1DSS_BYPASS,
279+
fake_cdtab_dma_addr);
280+
arm_smmu_v3_test_ste_expect_hitless_transition(
281+
test, &bypass_ste, &s1dss_bypass, NUM_EXPECTED_SYNCS(2));
282+
}
283+
229284
static void arm_smmu_test_make_s2_ste(struct arm_smmu_ste *ste,
230285
bool ats_enabled)
231286
{
@@ -285,6 +340,48 @@ static void arm_smmu_v3_write_ste_test_bypass_to_s2(struct kunit *test)
285340
NUM_EXPECTED_SYNCS(2));
286341
}
287342

343+
static void arm_smmu_v3_write_ste_test_s1_to_s2(struct kunit *test)
344+
{
345+
struct arm_smmu_ste s1_ste;
346+
struct arm_smmu_ste s2_ste;
347+
348+
arm_smmu_test_make_cdtable_ste(&s1_ste, STRTAB_STE_1_S1DSS_SSID0,
349+
fake_cdtab_dma_addr);
350+
arm_smmu_test_make_s2_ste(&s2_ste, true);
351+
arm_smmu_v3_test_ste_expect_hitless_transition(test, &s1_ste, &s2_ste,
352+
NUM_EXPECTED_SYNCS(3));
353+
}
354+
355+
static void arm_smmu_v3_write_ste_test_s2_to_s1(struct kunit *test)
356+
{
357+
struct arm_smmu_ste s1_ste;
358+
struct arm_smmu_ste s2_ste;
359+
360+
arm_smmu_test_make_cdtable_ste(&s1_ste, STRTAB_STE_1_S1DSS_SSID0,
361+
fake_cdtab_dma_addr);
362+
arm_smmu_test_make_s2_ste(&s2_ste, true);
363+
arm_smmu_v3_test_ste_expect_hitless_transition(test, &s2_ste, &s1_ste,
364+
NUM_EXPECTED_SYNCS(3));
365+
}
366+
367+
static void arm_smmu_v3_write_ste_test_non_hitless(struct kunit *test)
368+
{
369+
struct arm_smmu_ste ste;
370+
struct arm_smmu_ste ste_2;
371+
372+
/*
373+
* Although no flow resembles this in practice, one way to force an STE
374+
* update to be non-hitless is to change its CD table pointer as well as
375+
* s1 dss field in the same update.
376+
*/
377+
arm_smmu_test_make_cdtable_ste(&ste, STRTAB_STE_1_S1DSS_SSID0,
378+
fake_cdtab_dma_addr);
379+
arm_smmu_test_make_cdtable_ste(&ste_2, STRTAB_STE_1_S1DSS_BYPASS,
380+
0x4B4B4b4B4B);
381+
arm_smmu_v3_test_ste_expect_non_hitless_transition(
382+
test, &ste, &ste_2, NUM_EXPECTED_SYNCS(3));
383+
}
384+
288385
static void arm_smmu_v3_test_cd_expect_transition(
289386
struct kunit *test, const struct arm_smmu_cd *cur,
290387
const struct arm_smmu_cd *target, unsigned int num_syncs_expected,
@@ -438,10 +535,16 @@ static struct kunit_case arm_smmu_v3_test_cases[] = {
438535
KUNIT_CASE(arm_smmu_v3_write_ste_test_abort_to_cdtable),
439536
KUNIT_CASE(arm_smmu_v3_write_ste_test_cdtable_to_bypass),
440537
KUNIT_CASE(arm_smmu_v3_write_ste_test_bypass_to_cdtable),
538+
KUNIT_CASE(arm_smmu_v3_write_ste_test_cdtable_s1dss_change),
539+
KUNIT_CASE(arm_smmu_v3_write_ste_test_s1dssbypass_to_stebypass),
540+
KUNIT_CASE(arm_smmu_v3_write_ste_test_stebypass_to_s1dssbypass),
441541
KUNIT_CASE(arm_smmu_v3_write_ste_test_s2_to_abort),
442542
KUNIT_CASE(arm_smmu_v3_write_ste_test_abort_to_s2),
443543
KUNIT_CASE(arm_smmu_v3_write_ste_test_s2_to_bypass),
444544
KUNIT_CASE(arm_smmu_v3_write_ste_test_bypass_to_s2),
545+
KUNIT_CASE(arm_smmu_v3_write_ste_test_s1_to_s2),
546+
KUNIT_CASE(arm_smmu_v3_write_ste_test_s2_to_s1),
547+
KUNIT_CASE(arm_smmu_v3_write_ste_test_non_hitless),
445548
KUNIT_CASE(arm_smmu_v3_write_cd_test_s1_clear),
446549
KUNIT_CASE(arm_smmu_v3_write_cd_test_s1_change_asid),
447550
KUNIT_CASE(arm_smmu_v3_write_cd_test_sva_clear),

0 commit comments

Comments
 (0)