Page MenuHomeFreeBSD

bhyve/amd64: parse cpuid options
Needs ReviewPublic

Authored by rosenfeld_grumpf.hope-2000.org on Jul 26 2025, 11:23 AM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Oct 19, 8:15 PM
Unknown Object (File)
Sat, Oct 18, 1:09 AM
Unknown Object (File)
Sun, Oct 12, 4:57 PM
Unknown Object (File)
Thu, Oct 9, 6:51 PM
Unknown Object (File)
Thu, Oct 9, 4:28 PM
Unknown Object (File)
Thu, Oct 9, 4:28 PM
Unknown Object (File)
Thu, Oct 9, 2:52 PM
Unknown Object (File)
Sep 20 2025, 6:45 AM

Details

Reviewers
None
Group Reviewers
bhyve
Summary

Add support for cpuid options, parsing them into cpuid entries and
populate the cpuid configuration. They conform to the following form:

-o [vcpu.<vcpuid>.]cpuid.<function>[,<index>]=<eax>,<ebx>,<ecx>,<edx>

<function> specifies the cpuid function (aka "cpuid leaf") to create
an entry for, with an optional index specified by <index>. These are
the EAX and ECX register values to match when a CPUID instruction is
emulated for the guest. <eax>, <ebx>, <ecx>, and <edx> specify the
corresponding register values to be returned for the specified function
and index.

If a cpuid option specifies no vcpuid, that is it is rooted under
'cpuid.' in the config tree, it specifies an entry for the global cpuid
configuration, which isentry used for all VCPUs. Otherwise, if a vcpuid
is specified, that is the options rooted under 'vcpu.<vcpuid>.cpuid.',
it specifies an entry for cpuid configuration specific for the given
VCPU. The kernel only knows VCPU-specific cpuid configurations, so the
global cpuid configuration is merged into the VCPU-specific cpuid
configuration, but VCPU-specific cpuid entries always override any
global cpuid options for the same function/index.

cpuid options can be specified on the command line in any order.
Duplicates aren't allowed, although detection of duplicates is limited
by the mechanism of which '-o' options are parsed in bhyve.

In particular, consider the following cases:
1: bhyve [...] -o cpuid,0x00000123=0,0,0,0 -o cpuid=0x00000123=1,2,3,4 [...]
2: bhyve [...] -o cpuid,0x00000123=0,0,0,0 -o cpuid=0x123=1,2,3,4 [...]

The first case isn't a real duplicate entry as the bhyve option parsing
code only keeps the last value given for a particular option name string.

In the 2nd case, the option name string is different, thus they are two
separate options as far as the bhyve option parsing code is concerned
and both will be entered into the config nvlist. But the cpuid option
parser decodes both options into two different cpuid entries for the
same cpuid function, which will be detected as an error.

Note that if a non-legacy cpuid configuration is to be used, all CPUID
functions and indices must be specified, including all VCPU-specific
entries where they differ from one VCPU to another (such as for the
APIC ID, CPU topology information etc.). There is currently no way to
just override individual CPUID functions or just masking/setting
individual bits in a value returned, falling back to the legacy CPUID
emulation for functions/indices not specified.

Diff Detail

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

Event Timeline

corvink added inline comments.
usr.sbin/bhyve/amd64/bhyverun_machdep.c
594

Is this really required? We're fixing the whole array after merging again, so do we really have to do it twice?

Setting every single cpuid value seems to be a bunch of work for user. Especially, as user have to set every single bit correctly. What's the way forward for this? How will bhyve receive some default cpuid values?

Setting every single cpuid value seems to be a bunch of work for user. Especially, as user have to set every single bit correctly. What's the way forward for this? How will bhyve receive some default cpuid values?

This is just a minimal user interface that shows what can be done. While it's the most flexible way to configure CPUID for a VM, it's also the one that requires most attention to low-level details. It's far from being user-friendly in any meaning of the term.

I've given a short presentation of the CPUID work at bhyvecon 2025 in Zagreb, where I've outlined the ideas I have for this for the future. If you haven't seen it yet, here's the recording: https://www.youtube.com/watch?v=DPafGgfWaJU

usr.sbin/bhyve/amd64/bhyverun_machdep.c
594

You're probably right, although the CPU time wasted here is minimal. This code path is run only once when the first vcpu is initialized, but the 2nd call to fixup below is always run once for each vcpu. I need to check this again before I can remove it.

Remove extra call to bhyve_fixup_cpuid_config(). Improve the commit message.

Remove an extraneous whitespace in bhyve_merge_cpuid_config().