After tilerelease instruction, AMX tiles are in INIT state. According to Intel SDM vol 1. 13.10: "If RFBM[i] = 1, XSTATE_BV[i] is set to the value of XINUSE[i].", XSTATE_BV[18] should be cleared after xsavec.
On the other hand, according to Intel SDM vol 1. 13.4.3: "If XCOMP_BV[i] = 1, state component i is located at a byte offset locationI from the base address of the XSAVE area". Since at the time of xsavec, XCR0[18] is set indicating AMX tile data component is still enabled, xcomp_bv[18] should be set.
Complete the checks by adding the assert to xcomp_bv[18] after xsavec.
Signed-off-by: Mingwei Zhang mizhang@google.com --- tools/testing/selftests/kvm/x86_64/amx_test.c | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/kvm/x86_64/amx_test.c b/tools/testing/selftests/kvm/x86_64/amx_test.c index b2369f956fea..18203e399e9d 100644 --- a/tools/testing/selftests/kvm/x86_64/amx_test.c +++ b/tools/testing/selftests/kvm/x86_64/amx_test.c @@ -41,6 +41,12 @@
#define XSAVE_HDR_OFFSET 512
+struct xstate_header { + u64 xfeatures; + u64 xcomp_bv; + u64 reserved[6]; +} __packed; + struct xsave_data { u8 area[XSAVE_SIZE]; } __aligned(64); @@ -160,12 +166,26 @@ static void set_tilecfg(struct tile_config *cfg)
static void set_xstatebv(void *data, uint64_t bv) { - *(uint64_t *)(data + XSAVE_HDR_OFFSET) = bv; + struct xstate_header *header = + (struct xstate_header *)(data + XSAVE_HDR_OFFSET); + + header->xfeatures = bv; }
static u64 get_xstatebv(void *data) { - return *(u64 *)(data + XSAVE_HDR_OFFSET); + struct xstate_header *header = + (struct xstate_header *)(data + XSAVE_HDR_OFFSET); + + return header->xfeatures; +} + +static u64 get_xcompbv(void *data) +{ + struct xstate_header *header = + (struct xstate_header *)(data + XSAVE_HDR_OFFSET); + + return header->xcomp_bv; }
static void init_regs(void) @@ -204,10 +224,14 @@ static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg, GUEST_SYNC(4); __tilerelease(); GUEST_SYNC(5); - /* bit 18 not in the XSTATE_BV after xsavec() */ + /* + * After xsavec() bit 18 is cleared in the XSTATE_BV but is set in + * the XCOMP_BV. + */ set_xstatebv(xsave_data, XFEATURE_MASK_XTILEDATA); __xsavec(xsave_data, XFEATURE_MASK_XTILEDATA); GUEST_ASSERT((get_xstatebv(xsave_data) & XFEATURE_MASK_XTILEDATA) == 0); + GUEST_ASSERT((get_xcompbv(xsave_data) & XFEATURE_MASK_XTILEDATA) == XFEATURE_MASK_XTILEDATA);
/* xfd=0x40000, disable amx tiledata */ wrmsr(MSR_IA32_XFD, XFEATURE_MASK_XTILEDATA);