=== Полный контроль CPUID для bhyve

Контакт: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>

==== Обзор проекта

Текущая работа над этим проектом направлена на интеграцию существующей экспериментальной реализации (proof-of-concept) во FreeBSD и добавление следующих функций, улучшающих удобство использования:

- удобный метод настройки для переопределения отдельных битов, частей или даже целых функций CPUID по мере необходимости с сохранением остальной информации CPUID хоста или предопределённой конфигурации CPUID
- удобный метод настройки сигнатуры гипервизора, сообщаемой bhyve
- набор предопределённых конфигураций CPUID, основанных на общепринятых архитектурных уровнях x86, возможно, также включающий набор данных CPUID для нескольких реальных моделей CPU, а также удобный метод настройки для выбора одного из них для виртуальной машины

==== Изменения за последний квартал

===== Расширения bhyvectl
В прототипе конфигурации CPUID уже была реализована новая команда для bhyvectl, `--get-cpuid-cfg`, для запроса конфигурации CPUID виртуального CPU.

Теперь реализована ещё одна новая команда для bhyvectl, `--get-cpuid`, которая получает эмулируемые значения CPUID для виртуального CPU.

Существует несколько режимов работы `--get-cpuid`:

`bhyvectl --get-cpuid=<leaf>[,<index>]`:: Получает эмулируемое значение CPUID для отдельного листа CPUID и, опционально, индекса.
`bhyvectl --get-cpuid[=all]`:: Получает полный набор эмулируемых значений CPUID для всех поддерживаемых листов и всех поддерживаемых индексов.
`bhyvectl --get-cpuid=all,p`:: То же, что и выше, но вывод может быть разобран как набор параметров конфигурации CPUID для bhyve.
`bhyvectl --get-cpuid=all,s`:: То же, что и выше, но вывод является «разреженным», то есть печатаются только те листы и индексы CPUID, чьи значения на данном виртуальном CPU (с ключом `--cpu`) отличаются от того же листа и индекса на виртуальном CPU 0.

Последние два режима можно использовать для создания базовой конфигурации CPUID, основанной на эмуляции CPUID от bhyve, которую затем можно изменить по желанию.

===== Более гибкая настройка CPUID
Механизм конфигурации CPUID, реализованный в рамках прототипа, был переработан, чтобы обеспечить более гибкую и детальную настройку, не требующую указания всего набора информации CPUID.
Вот пример конфигурации:

-------------------
cpuid.0x00000001=edx|=0x00040000
cpuid.0x00000003=ecx=0x01234567,edx=0x89abcdef
vcpu.1.cpuid.0x00000003=ecx|=0x10000000
vcpu.2.cpuid.0x00000003=ecx|=0x20000000
vcpu.3.cpuid.0x00000003=ecx|=0x30000000
vcpu.4.cpuid.0x00000003=ecx|=0x40000000
vcpu.5.cpuid.0x00000003=ecx|=0x50000000
vcpu.6.cpuid.0x00000003=ecx|=0x60000000
vcpu.7.cpuid.0x00000003=ecx|=0x70000000
vcpu.8.cpuid.0x00000003=ecx|=0x80000000
vcpu.9.cpuid.0x00000003=ecx|=0x90000000
vcpu.10.cpuid.0x00000003=ecx|=0xa0000000
vcpu.11.cpuid.0x00000003=ecx|=0xb0000000
vcpu.12.cpuid.0x00000003=ecx|=0xc0000000
vcpu.13.cpuid.0x00000003=ecx|=0xd0000000
vcpu.14.cpuid.0x00000003=ecx|=0xe0000000
vcpu.15.cpuid.0x00000003=ecx|=0xf0000000
cpuid.0x0000000b,0=edx=0xffffffff
cpuid.0x0000000b,1=edx=0xeeeeeeee
cpuid.0x0000000b,2=edx=0xdddddddd
-------------------

Приведённая выше конфигурация CPUID включает функцию «Processor Serial Number» (0x00000001, бит 18 в EDX) на всех виртуальных CPU и устанавливает серийный номер по умолчанию 0x01234567, 0x89abcef.

На каждом виртуальном CPU, кроме vCPU 0, она перезаписывает одну цифру серийного номера идентификатором виртуального CPU, чтобы каждый виртуальный CPU имел уникальный серийный номер.

Последние три присваивания не имеют смысла.
Лист 0x0000000b содержит информацию о топологии во всех индексах, а регистр EDX всегда содержит x2APIC ID виртуального CPU.
Следовательно, эти последние три присваивания будут молча игнорироваться.

===== Использование архитектурных уровней x86

Теперь можно указать архитектурный уровень x86:

-------------------
cpuid.archlevel=v1
-------------------

Это отключит все возможности архитектурных уровней x86 от v2 до v3, ограничив набор возможностей CPU набором архитектурного уровня x86 v1.

==== Планы на следующий квартал

* Поддержка архитектурных уровней x86 должна стать более надёжной.
Хотя прямая настройка информации CPUID должна позволять изменять почти всё, для архитектурных уровней x86 следует проверять, действительно ли оборудование поддерживает все возможности, определённые в архитектурном уровне.
Установка архитектурного уровня, который не поддерживается CPU, должна быть запрещена или, по крайней мере, должно выдаваться предупреждение.

* Аналогично установке архитектурного уровня x86, будет реализован механизм для переопределения идентификации гипервизора без необходимости ручного изменения битов CPUID.

* Отправить весь код на рецензирование и включить во FreeBSD.

Спонсор: Фонд FreeBSD

//
// The FreeBSD Russian Documentation Project
//
// Original EN revision (18.04.2026): 62f27e3f42026437ef0afd0b5078f5e08e1b3abc
//
