drivers/iommu/generic_pt/pt_defs.h

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

File Facts

System
Linux kernel
Corpus path
drivers/iommu/generic_pt/pt_defs.h
Extension
.h
Size
10585 bytes
Lines
333
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 pt_range {
	struct pt_common *common;
	struct pt_table_p *top_table;
	pt_vaddr_t va;
	pt_vaddr_t last_va;
	u8 top_level;
	u8 max_vasz_lg2;
};

/*
 * Similar to xa_state, this records information about an in-progress parse at a
 * single level.
 */
struct pt_state {
	struct pt_range *range;
	struct pt_table_p *table;
	struct pt_table_p *table_lower;
	u64 entry;
	enum pt_entry_type type;
	unsigned short index;
	unsigned short end_index;
	u8 level;
};

#define pt_cur_table(pts, type) ((type *)((pts)->table))

/*
 * Try to install a new table pointer. The locking methodology requires this to
 * be atomic (multiple threads can race to install a pointer). The losing
 * threads will fail the atomic and return false. They should free any memory
 * and reparse the table level again.
 */
#if !IS_ENABLED(CONFIG_GENERIC_ATOMIC64)
static inline bool pt_table_install64(struct pt_state *pts, u64 table_entry)
{
	u64 *entryp = pt_cur_table(pts, u64) + pts->index;
	u64 old_entry = pts->entry;
	bool ret;

	/*
	 * Ensure the zero'd table content itself is visible before its PTE can
	 * be. release is a NOP on !SMP, but the HW is still doing an acquire.
	 */
	if (!IS_ENABLED(CONFIG_SMP))
		dma_wmb();
	ret = try_cmpxchg64_release(entryp, &old_entry, table_entry);
	if (ret)
		pts->entry = table_entry;
	return ret;
}
#endif

static inline bool pt_table_install32(struct pt_state *pts, u32 table_entry)
{
	u32 *entryp = pt_cur_table(pts, u32) + pts->index;
	u32 old_entry = pts->entry;
	bool ret;

	/*
	 * Ensure the zero'd table content itself is visible before its PTE can
	 * be. release is a NOP on !SMP, but the HW is still doing an acquire.
	 */
	if (!IS_ENABLED(CONFIG_SMP))
		dma_wmb();
	ret = try_cmpxchg_release(entryp, &old_entry, table_entry);
	if (ret)
		pts->entry = table_entry;
	return ret;
}

#define PT_SUPPORTED_FEATURE(feature_nr) (PT_SUPPORTED_FEATURES & BIT(feature_nr))

static __always_inline bool pt_feature(const struct pt_common *common,
			      unsigned int feature_nr)
{
	if (PT_FORCE_ENABLED_FEATURES & BIT(feature_nr))
		return true;
	if (!PT_SUPPORTED_FEATURE(feature_nr))
		return false;
	return common->features & BIT(feature_nr);
}

static __always_inline bool pts_feature(const struct pt_state *pts,
			       unsigned int feature_nr)
{
	return pt_feature(pts->range->common, feature_nr);
}

/*
 * PT_WARN_ON is used for invariants that the kunit should be checking can't

Annotation

Implementation Notes