drivers/iommu/generic_pt/kunit_generic_pt.h

Source file repositories/reference/linux-study-clean/drivers/iommu/generic_pt/kunit_generic_pt.h

File Facts

System
Linux kernel
Corpus path
drivers/iommu/generic_pt/kunit_generic_pt.h
Extension
.h
Size
23680 bytes
Lines
840
Domain
Driver Families
Bucket
drivers/iommu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct check_levels_arg {
	struct kunit *test;
	void *fn_arg;
	void (*fn)(struct kunit *test, struct pt_state *pts, void *arg);
};

static int __check_all_levels(struct pt_range *range, void *arg,
			      unsigned int level, struct pt_table_p *table)
{
	struct pt_state pts = pt_init(range, level, table);
	struct check_levels_arg *chk = arg;
	struct kunit *test = chk->test;
	int ret;

	_pt_iter_first(&pts);


	/*
	 * If we were able to use the full VA space this should always be the
	 * last index in each table.
	 */
	if (!(IS_32BIT && range->max_vasz_lg2 > 32)) {
		if (pt_feature(range->common, PT_FEAT_SIGN_EXTEND) &&
		    pts.level == pts.range->top_level)
			KUNIT_ASSERT_EQ(test, pts.index,
					log2_to_int(range->max_vasz_lg2 - 1 -
						    pt_table_item_lg2sz(&pts)) -
						1);
		else
			KUNIT_ASSERT_EQ(test, pts.index,
					log2_to_int(pt_table_oa_lg2sz(&pts) -
						    pt_table_item_lg2sz(&pts)) -
						1);
	}

	if (pt_can_have_table(&pts)) {
		pt_load_single_entry(&pts);
		KUNIT_ASSERT_EQ(test, pts.type, PT_ENTRY_TABLE);
		ret = pt_descend(&pts, arg, __check_all_levels);
		KUNIT_ASSERT_EQ(test, ret, 0);

		/* Index 0 is used by the test */
		if (IS_32BIT && !pts.index)
			return 0;
		KUNIT_ASSERT_NE(chk->test, pts.index, 0);
	}

	/*
	 * A format should not create a table with only one entry, at least this
	 * test approach won't work.
	 */
	KUNIT_ASSERT_GT(chk->test, pts.end_index, 1);

	/*
	 * For increase top we end up using index 0 for the original top's tree,
	 * so use index 1 for testing instead.
	 */
	pts.index = 0;
	pt_index_to_va(&pts);
	pt_load_single_entry(&pts);
	if (pts.type == PT_ENTRY_TABLE && pts.end_index > 2) {
		pts.index = 1;
		pt_index_to_va(&pts);
	}
	(*chk->fn)(chk->test, &pts, chk->fn_arg);
	return 0;
}

/*
 * Call fn for each level in the table with a pts setup to index 0 in a table
 * for that level. This allows writing tests that run on every level.
 * The test can use every index in the table except the last one.
 */
static void check_all_levels(struct kunit *test,
			     void (*fn)(struct kunit *test,
					struct pt_state *pts, void *arg),
			     void *fn_arg)
{
	struct kunit_iommu_priv *priv = test->priv;
	struct pt_range range = pt_top_range(priv->common);
	struct check_levels_arg chk = {
		.test = test,
		.fn = fn,
		.fn_arg = fn_arg,
	};
	int ret;

	if (pt_feature(priv->common, PT_FEAT_DYNAMIC_TOP) &&
	    priv->common->max_vasz_lg2 > range.max_vasz_lg2)
		range.last_va = fvalog2_set_mod_max(range.va,

Annotation

Implementation Notes