On 1/7/22 10:31, Yang Zhong wrote:
+static void x86_xsave_req_perm(void)
+{
+ unsigned long bitmask;
+
+ long rc = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_GUEST_PERM,
+ XSTATE_XTILE_DATA_BIT);
+ if (rc) {
+ /*
+ * The older kernel version(<5.15) can't support
+ * ARCH_REQ_XCOMP_GUEST_PERM and directly return.
+ */
+ return;
+ }
+
+ rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_GUEST_PERM, &bitmask);
+ if (rc) {
+ error_report("prctl(ARCH_GET_XCOMP_GUEST_PERM) error: %ld", rc);
+ } else if (!(bitmask & XFEATURE_XTILE_MASK)) {
+ error_report("prctl(ARCH_REQ_XCOMP_GUEST_PERM) failure "
+ "and bitmask=0x%lx", bitmask);
+ exit(EXIT_FAILURE);
+ }
+}
+
void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version)
{
int i;
@@ -124,6 +150,8 @@ void x86_cpus_init(X86MachineState *x86ms, int
default_cpu_version)
MachineState *ms = MACHINE(x86ms);
MachineClass *mc = MACHINE_GET_CLASS(x86ms);
+ /* Request AMX pemission for guest */
+ x86_xsave_req_perm();
x86_cpu_set_default_version(default_cpu_version);
This should be done before creating a CPU with support for state
component 18. It happens in kvm_init_vcpu, with the following call stack:
kvm_init_vcpu
kvm_vcpu_thread_fn
kvm_start_vcpu_thread
qemu_init_vcpu
x86_cpu_realizefn
The issue however is that this has to be done before
KVM_GET_SUPPORTED_CPUID and KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2).
For the former, you can assume that anything returned by
ARCH_GET_XCOMP_GUEST_PERM will be returned by KVM_GET_SUPPORTED_CPUID in
CPUID[0xD].EDX:EAX, so you can:
- add it to kvm_arch_get_supported_cpuid