libvirt CPU feature 的 policy 有 force、require、optional、disable、forbid 五种。disable 是虚拟 CPU 不支持该特性,forbid 是宿主机支持该特性时创建会失败。

现象

在 libvirt XML 中配置 CPU feature:

<cpu>
  <model>EPYC</model>
  <feature name="pclmuldq" policy="disable"/>
  <feature name="aes" policy="disable"/>
  <feature name="sha-ni" policy="disable"/>
  <feature name="monitor" policy="disable"/>
  <feature name="svm" policy="disable"/>
  <feature name="npt" policy="disable"/>   【物理机支撑 npt 的】
  <topology cores="1" sockets="1" threads="1"/>
</cpu>

物理 CPU 是有 npt 的,virsh create 的时候就报错,而且这是 disable 也报错。

足以说明,不是 CPU 问题,而是 libvirt 不支持问题:

2025-06-24 12:50:13,539 WARNING -140207347541760- cmd [virsh create /data/vmxml/vm-example.xml] on [local] failed: ret[1] out[] err[error: Failed to create domain from /data/vmxml/vm-example.xml
error: unsupported configuration: unknown CPU feature: npt]. exec_time is [0.089]s

排查

在 commandline 中禁用 npt 是可以创建虚拟机的

<qemu:commandline>
  <qemu:arg value="-cpu"/>
  <qemu:arg value="EPYC,vendor=AuthenticAMD,model_id=Example CPU 7380 32-core Processor,-x2apic,-hypervisor,-topoext,-npt,-nrip-save,-monitor,-svm"/>
</qemu:commandline>

说明什么?

说明是 libvirt 的问题,libvirt 校验不通过,这个 libvirt 版本压根不认识 npt 这个 feature。

forbid 的时候,如果宿主机支持该特性,真的会 virsh create 失败

<cpu>
  <model>EPYC</model>
  <feature name="pclmuldq" policy="disable"/>
  <feature name="aes" policy="disable"/>
  <feature name="sha-ni" policy="disable"/>
  <feature name="monitor" policy="disable"/>
  <feature name="svm" policy="disable"/>
  <feature name="npt" policy="forbid"/>   【禁用真不行】
  <topology cores="1" sockets="1" threads="1"/>
</cpu>
root@host:/data/vmxml# virsh destroy vm-example; virsh create vm-example.xml
Domain vm-example destroyed

error: Failed to create domain from vm-example.xml
error: the CPU is incompatible with host CPU: Host CPU provides forbidden features: npt

根因

feature 的 policy 五种取值

根据 libvirt 官方文档,feature 元素的 policy 属性有以下五种取值:

force(强制)

虚拟 CPU 将声明该功能受支持,无论主机 CPU 是否支持该功能。

require(需要)

除非主机 CPU 支持该功能,或者虚拟机管理程序能够模拟该功能,否则来宾创建将失败。

optional(自选)

当且仅当主机 CPU 支持该功能时,虚拟 CPU 才会支持该功能。

disable(禁用)

虚拟 CPU 不支持此功能。

forbid(禁止)

如果宿主机支持该功能,来宾创建将失败。

关键区别

  • disable:虚拟 CPU 不支持该特性,但宿主机支持与否无所谓,创建不会因此失败;
  • forbid:如果宿主机支持该特性,创建会失败。

为什么 disable npt 也报错

unknown CPU feature: npt 说明这个 libvirt 版本压根不认识 npt 这个 feature。

这是 libvirt 版本问题,不是 CPU 问题。

小结

  • libvirt CPU feature 的 policy 有 force、require、optional、disable、forbid 五种;
  • disable 是虚拟 CPU 不支持该特性,宿主机支持与否无所谓;
  • forbid 是宿主机支持该特性时创建会失败;
  • unknown CPU feature 是 libvirt 版本不认识该 feature,不是 CPU 问题;
  • 在 commandline 中禁用 npt 可以创建虚拟机,说明是 libvirt 校验不通过。