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

Reply via email to