@@ -97,6 +97,7 @@ itself as well as the host environment.
97
97
#define HAX_CAP_TUNNEL_PAGE (1 << 5)
98
98
#define HAX_CAP_DEBUG (1 << 7)
99
99
#define HAX_CAP_IMPLICIT_RAMBLOCK (1 << 8)
100
+ #define HAX_CAP_CPUID (1 << 9)
100
101
```
101
102
* (Output) ` wstatus ` : The first set of capability flags reported to the
102
103
caller. The following bits may be set, while others are reserved:
@@ -124,6 +125,7 @@ feature.
124
125
* ` HAX_CAP_64BIT_SETRAM ` : If set, ` HAX_VM_IOCTL_SET_RAM2 ` is available.
125
126
* ` HAX_CAP_IMPLICIT_RAMBLOCK ` : If set, ` HAX_VM_IOCTL_SET_RAM2 ` supports the
126
127
` HAX_RAM_INFO_STANDALONE ` flag.
128
+ * ` HAX_CAP_CPUID ` : If set, ` HAX_VCPU_IOCTL_SET_CPUID ` is available.
127
129
* (Output) ` win_refcount ` : (Windows only)
128
130
* (Output) ` mem_quota ` : If the global memory cap setting is enabled (q.v.
129
131
` HAX_IOCTL_SET_MEMLIMIT ` ), reports the current quota on memory allocation (the
@@ -689,3 +691,75 @@ Injects an interrupt into this VCPU.
689
691
* Error codes:
690
692
* ` STATUS_INVALID_PARAMETER ` (Windows): The input buffer provided by the
691
693
caller is smaller than the size of ` uint32_t ` .
694
+
695
+ #### HAX\_ VCPU\_ IOCTL\_ SET\_ CPUID
696
+ Defines the VCPU responses to the CPU identification (CPUID) instructions.
697
+
698
+ HAXM initializes a minimal feature set for guest VCPUs in kernel space. This
699
+ ensures that most modern CPUs can support these basic CPUID features. Only the
700
+ supported CPUID instructions in the feature set will be passed to the physical
701
+ CPU for processing.
702
+
703
+ This IOCTL is used to dynamically adjust the supported feature set of CPUID for
704
+ guest VCPUs so as to leverage the latest features from modern CPUs. The features
705
+ to be enabled will be incorporated into the feature set, while the features to
706
+ be disabled will be removed. If the physical CPU does not support some specified
707
+ CPUID features, the enabling operation will be ignored. Usually, this IOCTL is
708
+ invoked when the VM is initially configured.
709
+
710
+ All VCPUs share the same feature set in a VM. This can avoid confusion caused by
711
+ the case that when VCPU has multiple cores, different VCPUs executing the same
712
+ instruction will produce different results. Send this IOCTL to any VCPU to set
713
+ CPUID features, then all VCPUs will change accordingly.
714
+
715
+ * Since: Capability ` HAX_CAP_CPUID `
716
+ * Parameter: ` struct hax_cpuid cpuid ` , where
717
+ ```
718
+ struct hax_cpuid {
719
+ uint32_t total;
720
+ uint32_t pad;
721
+ hax_cpuid_entry entries[0];
722
+ } __attribute__ ((__packed__));
723
+ ```
724
+ where
725
+ ```
726
+ #define HAX_MAX_CPUID_ENTRIES 0x40
727
+ struct hax_cpuid_entry {
728
+ uint32_t function;
729
+ uint32_t index;
730
+ uint32_t flags;
731
+ uint32_t eax;
732
+ uint32_t ebx;
733
+ uint32_t ecx;
734
+ uint32_t edx;
735
+ uint32_t pad[3];
736
+ } __attribute__ ((__packed__));
737
+ ```
738
+ ` hax_cpuid ` is a variable-length type. The accessible memory of ` entries ` is
739
+ decided by the actual allocation from user space. For macOS, the argument of
740
+ user data should pass the address of the pointer to ` hax_cpuid ` when ` ioctl() `
741
+ is invoked.
742
+ * (Input) ` total ` : Number of CPUIDs in entries. The valid value should be in
743
+ the range (0, ` HAX_MAX_CPUID_ENTRIES ` ] .
744
+ * (Input) ` pad ` : Ignored.
745
+ * (Input) ` entries ` : Array of ` struct hax_cpuid_entry ` . This array contains
746
+ the CPUID feature set of the guest VCPU that is pre-configured by the VM in user
747
+ space.
748
+
749
+ For each entry in ` struct hax_cpuid_entry `
750
+ * (Input) ` function ` : CPUID function code, i.e., initial EAX value.
751
+ * (Input) ` index ` : Sub-leaf index.
752
+ * (Input) ` flags ` : Feature flags.
753
+ * (Input) ` eax ` : EAX register value.
754
+ * (Input) ` ebx ` : EBX register value.
755
+ * (Input) ` ecx ` : ECX register value.
756
+ * (Input) ` edx ` : EDX register value.
757
+ * (Input) ` pad ` : Ignored.
758
+ * Error codes:
759
+ * ` STATUS_INVALID_PARAMETER ` (Windows): The input buffer provided by the
760
+ caller is smaller than the size of ` struct hax_cpuid ` .
761
+ * ` STATUS_UNSUCCESSFUL ` (Windows): Failed to set CPUID features.
762
+ * ` -E2BIG ` (macOS): The input value of ` total ` is greater than
763
+ ` HAX_MAX_CPUID_ENTRIES ` .
764
+ * ` -EFAULT ` (macOS): Failed to copy contents in ` entries ` to the memory in
765
+ kernel space.
0 commit comments