Skip to content
This repository has been archived by the owner on Jan 28, 2023. It is now read-only.

Commit

Permalink
doc: API: Add HAX_VCPU_IOCTL_SET_CPUID
Browse files Browse the repository at this point in the history
Android Emulator may dynamically extend the CPUID feature set of VCPU
at guest runtime via x86_cpu_update_enable_features()
($AOSP/external/qemu/target/i386/cpu.c). It will invoke this IOCTL to
set guest CPUID features, which is statically initialized in HAXM.

The HAX_VCPU_IOCTL_SET_CPUID specification includes following aspects:

* IOCTL definition and description
* Parameters
* Error codes
* Interface availability

Signed-off-by: Wenchao Wang <[email protected]>
  • Loading branch information
wcwang committed Mar 24, 2020
1 parent 43e854e commit 6f733a3
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ itself as well as the host environment.
#define HAX_CAP_TUNNEL_PAGE (1 << 5)
#define HAX_CAP_DEBUG (1 << 7)
#define HAX_CAP_IMPLICIT_RAMBLOCK (1 << 8)
#define HAX_CAP_CPUID (1 << 9)
```
* (Output) `wstatus`: The first set of capability flags reported to the
caller. The following bits may be set, while others are reserved:
Expand Down Expand Up @@ -124,6 +125,7 @@ feature.
* `HAX_CAP_64BIT_SETRAM`: If set, `HAX_VM_IOCTL_SET_RAM2` is available.
* `HAX_CAP_IMPLICIT_RAMBLOCK`: If set, `HAX_VM_IOCTL_SET_RAM2` supports the
`HAX_RAM_INFO_STANDALONE` flag.
* `HAX_CAP_CPUID`: If set, `HAX_VCPU_IOCTL_SET_CPUID` is available.
* (Output) `win_refcount`: (Windows only)
* (Output) `mem_quota`: If the global memory cap setting is enabled (q.v.
`HAX_IOCTL_SET_MEMLIMIT`), reports the current quota on memory allocation (the
Expand Down Expand Up @@ -689,3 +691,75 @@ Injects an interrupt into this VCPU.
* Error codes:
* `STATUS_INVALID_PARAMETER` (Windows): The input buffer provided by the
caller is smaller than the size of `uint32_t`.

#### HAX\_VCPU\_IOCTL\_SET\_CPUID
Defines the VCPU responses to the CPU identification (CPUID) instructions.

HAXM initializes a minimal feature set for guest VCPUs in kernel space. This
ensures that most modern CPUs can support these basic CPUID features. Only the
supported CPUID instructions in the feature set will be passed to the physical
CPU for processing.

This IOCTL is used to dynamically adjust the supported feature set of CPUID for
guest VCPUs so as to leverage the latest features from modern CPUs. The features
to be enabled will be incorporated into the feature set, while the features to
be disabled will be removed. If the physical CPU does not support some specified
CPUID features, the enabling operation will be ignored. Usually, this IOCTL is
invoked when the VM is initially configured.

All VCPUs share the same feature set in a VM. This can avoid confusion caused by
the case that when VCPU has multiple cores, different VCPUs executing the same
instruction will produce different results. Send this IOCTL to any VCPU to set
CPUID features, then all VCPUs will change accordingly.

* Since: Capability `HAX_CAP_CPUID`
* Parameter: `struct hax_cpuid cpuid`, where
```
struct hax_cpuid {
uint32_t total;
uint32_t pad;
hax_cpuid_entry entries[0];
} __attribute__ ((__packed__));
```
where
```
#define HAX_MAX_CPUID_ENTRIES 0x40
struct hax_cpuid_entry {
uint32_t function;
uint32_t index;
uint32_t flags;
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
uint32_t pad[3];
} __attribute__ ((__packed__));
```
`hax_cpuid` is a variable-length type. The accessible memory of `entries` is
decided by the actual allocation from user space. For macOS, the argument of
user data should pass the address of the pointer to `hax_cpuid` when `ioctl()`
is invoked.
* (Input) `total`: Number of CPUIDs in entries. The valid value should be in
the range (0, `HAX_MAX_CPUID_ENTRIES`].
* (Input) `pad`: Ignored.
* (Input) `entries`: Array of `struct hax_cpuid_entry`. This array contains
the CPUID feature set of the guest VCPU that is pre-configured by the VM in user
space.

For each entry in `struct hax_cpuid_entry`
* (Input) `function`: CPUID function code, i.e., initial EAX value.
* (Input) `index`: Sub-leaf index.
* (Input) `flags`: Feature flags.
* (Input) `eax`: EAX register value.
* (Input) `ebx`: EBX register value.
* (Input) `ecx`: ECX register value.
* (Input) `edx`: EDX register value.
* (Input) `pad`: Ignored.
* Error codes:
* `STATUS_INVALID_PARAMETER` (Windows): The input buffer provided by the
caller is smaller than the size of `struct hax_cpuid`.
* `STATUS_UNSUCCESSFUL` (Windows): Failed to set CPUID features.
* `-E2BIG` (macOS): The input value of `total` is greater than
`HAX_MAX_CPUID_ENTRIES`.
* `-EFAULT` (macOS): Failed to copy contents in `entries` to the memory in
kernel space.

0 comments on commit 6f733a3

Please sign in to comment.