/* xfd=0, enable amx */
wrmsr(MSR_IA32_XFD, 0);
GUEST_SYNC(2);
GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == 0);
set_tilecfg(amx_cfg);
__ldtilecfg(amx_cfg);
GUEST_SYNC(3); /* Check save/restore when trap to userspace */
__tileloadd(tiledata);
GUEST_SYNC(4);
__tilerelease();
GUEST_SYNC(5); /* * After XSAVEC, XTILEDATA is cleared in the xstate_bv but is set in * the xcomp_bv.
*/
xstate->header.xstate_bv = XFEATURE_MASK_XTILE_DATA;
__xsavec(xstate, XFEATURE_MASK_XTILE_DATA);
GUEST_ASSERT(!(xstate->header.xstate_bv & XFEATURE_MASK_XTILE_DATA));
GUEST_ASSERT(xstate->header.xcomp_bv & XFEATURE_MASK_XTILE_DATA);
/* * XTILEDATA is cleared in xstate_bv but set in xcomp_bv, this property * remains the same even when amx tiledata is disabled by IA32_XFD.
*/
xstate->header.xstate_bv = XFEATURE_MASK_XTILE_DATA;
__xsavec(xstate, XFEATURE_MASK_XTILE_DATA);
GUEST_ASSERT(!(xstate->header.xstate_bv & XFEATURE_MASK_XTILE_DATA));
GUEST_ASSERT((xstate->header.xcomp_bv & XFEATURE_MASK_XTILE_DATA));
/* * Note, all off-by-default features must be enabled before anything * caches KVM_GET_SUPPORTED_CPUID, e.g. before using kvm_cpu_has().
*/
vm_xsave_require_permission(XFEATURE_MASK_XTILE_DATA);
/* Create VM */
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
TEST_ASSERT(kvm_cpu_has_p(X86_PROPERTY_XSTATE_MAX_SIZE), "KVM should enumerate max XSAVE size when XSAVE is supported");
xsave_restore_size = kvm_cpu_property(X86_PROPERTY_XSTATE_MAX_SIZE);
for (;;) {
vcpu_run(vcpu);
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
switch (get_ucall(vcpu, &uc)) { case UCALL_ABORT:
REPORT_GUEST_ASSERT(uc); /* NOT REACHED */ case UCALL_SYNC: switch (uc.args[1]) { case 1: case 2: case 3: case 5: case 6: case 7: case 8:
fprintf(stderr, "GUEST_SYNC(%ld)\n", uc.args[1]); break; case 4: case 10:
fprintf(stderr, "GUEST_SYNC(%ld), check save/restore status\n", uc.args[1]);
/* Compacted mode, get amx offset by xsave area * size subtract 8K amx size.
*/
amx_offset = xsave_restore_size - NUM_TILES*TILE_SIZE;
state = vcpu_save_state(vcpu); void *amx_start = (void *)state->xsave + amx_offset; void *tiles_data = (void *)addr_gva2hva(vm, tiledata); /* Only check TMM0 register, 1 tile */
ret = memcmp(amx_start, tiles_data, TILE_SIZE);
TEST_ASSERT(ret == 0, "memcmp failed, ret=%d", ret);
kvm_x86_state_cleanup(state); break; case 9:
fprintf(stderr, "GUEST_SYNC(%ld), #NM exception and enable amx\n", uc.args[1]); break;
} break; case UCALL_DONE:
fprintf(stderr, "UCALL_DONE\n"); goto done; default:
TEST_FAIL("Unknown ucall %lu", uc.cmd);
}
state = vcpu_save_state(vcpu);
memset(®s1, 0, sizeof(regs1));
vcpu_regs_get(vcpu, ®s1);
kvm_vm_release(vm);
/* Restore state in a new VM. */
vcpu = vm_recreate_with_one_vcpu(vm);
vcpu_load_state(vcpu, state);
kvm_x86_state_cleanup(state);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.