tools/testing/selftests/kvm/x86/amx_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/x86/amx_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/x86/amx_test.c
Extension
.c
Size
9725 bytes
Lines
342
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tile_config {
	u8  palette_id;
	u8  start_row;
	u8  reserved[RESERVED_BYTES];
	u16 colsb[MAX_TILES];
	u8  rows[MAX_TILES];
};

struct tile_data {
	u8 data[NUM_TILES * TILE_SIZE];
};

struct xtile_info {
	u16 bytes_per_tile;
	u16 bytes_per_row;
	u16 max_names;
	u16 max_rows;
	u32 xsave_offset;
	u32 xsave_size;
};

static struct xtile_info xtile;

static inline void __ldtilecfg(void *cfg)
{
	asm volatile(".byte 0xc4,0xe2,0x78,0x49,0x00"
		     : : "a"(cfg));
}

static inline void __tileloadd(void *tile)
{
	asm volatile(".byte 0xc4,0xe2,0x7b,0x4b,0x04,0x10"
		     : : "a"(tile), "d"(0));
}

static inline int tileloadd_safe(void *tile)
{
	return kvm_asm_safe(".byte 0xc4,0xe2,0x7b,0x4b,0x04,0x10",
			    "a"(tile), "d"(0));
}

static inline void __tilerelease(void)
{
	asm volatile(".byte 0xc4, 0xe2, 0x78, 0x49, 0xc0" ::);
}

static inline void __xsavec(struct xstate *xstate, u64 rfbm)
{
	u32 rfbm_lo = rfbm;
	u32 rfbm_hi = rfbm >> 32;

	asm volatile("xsavec (%%rdi)"
		     : : "D" (xstate), "a" (rfbm_lo), "d" (rfbm_hi)
		     : "memory");
}

static void check_xtile_info(void)
{
	GUEST_ASSERT((xgetbv(0) & XFEATURE_MASK_XTILE) == XFEATURE_MASK_XTILE);

	GUEST_ASSERT(this_cpu_has_p(X86_PROPERTY_XSTATE_MAX_SIZE_XCR0));
	GUEST_ASSERT(this_cpu_property(X86_PROPERTY_XSTATE_MAX_SIZE_XCR0) <= XSAVE_SIZE);

	xtile.xsave_offset = this_cpu_property(X86_PROPERTY_XSTATE_TILE_OFFSET);
	GUEST_ASSERT(xtile.xsave_offset == 2816);
	xtile.xsave_size = this_cpu_property(X86_PROPERTY_XSTATE_TILE_SIZE);
	GUEST_ASSERT(xtile.xsave_size == 8192);
	GUEST_ASSERT(sizeof(struct tile_data) >= xtile.xsave_size);

	GUEST_ASSERT(this_cpu_has_p(X86_PROPERTY_AMX_MAX_PALETTE_TABLES));
	GUEST_ASSERT(this_cpu_property(X86_PROPERTY_AMX_MAX_PALETTE_TABLES) >=
		     PALETTE_TABLE_INDEX);

	GUEST_ASSERT(this_cpu_has_p(X86_PROPERTY_AMX_NR_TILE_REGS));
	xtile.max_names = this_cpu_property(X86_PROPERTY_AMX_NR_TILE_REGS);
	GUEST_ASSERT(xtile.max_names == 8);
	xtile.bytes_per_tile = this_cpu_property(X86_PROPERTY_AMX_BYTES_PER_TILE);
	GUEST_ASSERT(xtile.bytes_per_tile == 1024);
	xtile.bytes_per_row = this_cpu_property(X86_PROPERTY_AMX_BYTES_PER_ROW);
	GUEST_ASSERT(xtile.bytes_per_row == 64);
	xtile.max_rows = this_cpu_property(X86_PROPERTY_AMX_MAX_ROWS);
	GUEST_ASSERT(xtile.max_rows == 16);
}

static void set_tilecfg(struct tile_config *cfg)
{
	int i;

	/* Only palette id 1 */
	cfg->palette_id = 1;

Annotation

Implementation Notes