Page MenuHomeFreeBSD

bhyve/amd64: Add support for CPUID configuration
Needs ReviewPublic

Authored by rosenfeld_grumpf.hope-2000.org on Tue, Sep 29, 1:08 PM.
Tags
None
Referenced Files
F174306165: D60126.diff
Fri, Oct 2, 5:43 AM
F174246933: D60126.id187999.diff
Thu, Oct 1, 5:02 PM
Unknown Object (File)
Thu, Oct 1, 1:50 AM
Unknown Object (File)
Wed, Sep 30, 4:37 PM
Unknown Object (File)
Wed, Sep 30, 4:37 PM
Unknown Object (File)
Wed, Sep 30, 12:46 PM
Unknown Object (File)
Wed, Sep 30, 1:58 AM
Unknown Object (File)
Wed, Sep 30, 12:57 AM
Subscribers

Details

Reviewers
markj
chuck
emaste
Group Reviewers
bhyve
Summary

Generate CPUID entries from any given CPUID config options and modify the emulated CPUID configuration for all VCPUs accordingly.

CPUID options conform to the following form:

-o [vcpu.<vcpuid>.]cpuid.<action>=<parameter>

When a CPUID option is rooted under 'cpuid.' in the config tree, it defines an entry for the global CPUID configuration, which is applied to all VCPUs. Any CPUID option rooted under 'vcpu.<vcpuid>.cpuid.' defines a CPUID configuration entry specifically for the given VCPU.

CPUID generation works in several phases for each VCPU:

  • compile a list of global CPUID modification actions from the global 'cpuid' options (this is done only once)
  • compile a list of per-VCPU CPUID modifications actions from the 'vcpu.<vcpuid>.cpuid' options
  • build a CPUID configuration from the complete set of CPUID information emulated or passed through from the host CPU by VMM
  • apply the global CPUID modification actions followed by the per-VCPU modification actions to the CPUID configuration
  • perform a number of necessary checks and fixups on the modified CPUID configuration, like restoring APIC IDs, removing unreachable CPUID functions, checking for duplicates
  • check the modified CPUID configuration against a predefined set of constraints for valid register contents for particular functions and indexes, such as bits that are immutable, are clear-only, or which can only be numerically lowered
  • upload the final CPUID configuration for this VCPU to the VM

The most basic form of CPUID configuration parameter is the register modification action:

-o [vcpu.<vcpuid>.]cpuid.<leaf>[,<index>][+]=<register-action-list>

<leaf> specifies the CPUID leaf (aka "CPUID function") to create an entry for, with an optional index specified by <index>. Leaf and index correspond the EAX and ECX input register values, respectively, when a CPUID instruction is emulated for the guest.

<register-action-list> is a comma-separated list of actions for modifying the register values returned by CPUID for the specified leaf and index. Appending to an existing CPUID configuration parameter will automatically insert the comma.

Register operations take the following form:

<reg><op><value>

<reg> specifies one of the registers EAX, EBX, ECX, or EDX. <op> is one of "=" (assignment), "&=" (bit masking), or "|=" (bit setting). <value> specifies the value to use in the operation. If <value> starts with "~", the value will be inverted before it is applied to the register. There can be multiple operations applying to the same registers, they will be executed in the order specified.

There are also a number of "special actions" to set certain CPUID values in a more straightforward way:

  • cpuid.hypervisor: Hypervisor identification ("hyperv", "kvm", "vmware", "virtualbox", "xen", or a raw 12-character string)
  • cpuid.vendor: CPU vendor ("intel", "amd", or raw 12-character string)
  • cpuid.family: CPU family
  • cpuid.model: CPU model
  • cpuid.stepping: CPU stepping
  • cpuid.brand: CPU brand string (48 characters, leaves 0x80000002-5)
  • cpuid.pkgtype: the package type for AMD CPUs (only "am3" at this time)
  • cpuid.level: maximum supported CPUID function in the 0x00000000 range
  • cpuid.xlevel: maximum extended CPUID function in the 0x80000000 range
  • cpuid.linear: no. of address space bits for linear (virtual) addresses
  • cpuid.physical: no. of address space bits for physical addresses
  • cpuid.features: list of features to be enabled or disabled
  • cpuid.check: behaviour of the CPUID constraints checks ("none": perform no constraints checks, "warn": issue a warning for failing checks, "fail": fail VM startup if a check fails (default), "fix": modify the value to conform to the constraints (implies warn))
  • cpuid.fallback-style: The fallback method for inexistant/unsupported CPUID leaves, can be "intel" or "amd". Intel CPUs return the values for the highest valid CPUID leaf, while AMD CPUs return zeros. This is set automatic based on CPU vendor, but it may be overridden manually.

There are three sets of pre-defined CPUID configurations:

  • x86 architecture levels: x86-64-v4, x86-64-v3, x86-64-v2, x86-64-v1
  • Intel CPU models: icelake, cascadelake, skylake, broadwell, haswell, ivybridge, sandybridge, westmere, nehalem, core2duo, pentium4, coreduo, pentium3, pentium2, pentiumpro, pentium-mmx, pentium, 486
  • AMD CPU models: opteron-g5, opteron-g4, opteron-g3, opteron-g2, opteron-g1, athlon-64, athlon-xp, athlon, k6-3+, k6-3, k6-2, k6, k5, 486

A pre-defined CPUID configuration can be selected by adding the option "model=<config>" to the CPU configuration on the command line:

$ bhyve [...] -c 4,model=x86-64-v2 [...]

This would load x86-64-v2.cfg from /usr/share/bhyve/cpuid. Of course, the pre-defined CPUID configurations selected by this method can be further modified by using additional cpuid.<...> configuration options. It's also possible to create completely new CPUID configuration files and putting them into /usr/share/bhyve/cpuid.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 77452
Build 74335: arc lint + arc unit