3

In order to be able to script VM generation on our Debian 11 QEMU/KVM hosts I wrote a little python script which uses virt-install to setup new virtual machines (with OS Ubuntu 22.04). In those VMs created programmatically, however, I was not able to use Git on HTTPS repos without explicit GNUTLS_CPUID_OVERRIDE=0x1; I always received error: git-remote-https died of signal 4 (also other commands which involved GNUTLS

In manually created VMs I could successfully clone, however, so I started comparing the respective settings and was finally able to find the problem: it is the concrete CPU mode. Working VMs (manually created via virt-manager) use host-passthrough, while those VMs that are created using my script (and thus virt-install) use host-model (which yields EPYC ROME while running).

  1. Apparently there is a difference in the default values virt-manager and virt-install use - is that true?

  2. I assume that GNUTLS erroneously assumes a specific CPU feature to be available and then tries to use it which leads to a segfault or similar. Is the CPU feature detection of QEMU flawed for my "EPYC ROME" CPUs?

Thanks in advance!

Apollo13
  • 103

1 Answers1

0

kvm-qemu can pretend to be slightly different model of a CPU, and libvirt understands this. As a VM host operator, the primary use case of this is compatibility of live migrations.

man 7 signal shows that 4 is SIGILL, Illegal Instruction. While you may want to check that the binary is compatible for your architecture, most likely it is doing some relatively new fancy instructions the CPU may or may not have.

GnuTLS has runtime detection of optimized instructions for faster performance, you found environment variable GNUTLS_CPUID_OVERRIDE that overrides this. The list in the documentation suggests at some instructions that might be missing:

That environment variable can be used to explicitly enable/disable the use of certain CPU capabilities. Note that CPU detection cannot be overridden, i.e., VIA options cannot be enabled on an Intel CPU. The currently available options are:

0x1: Disable all run-time detected optimizations
0x2: Enable AES-NI
0x4: Enable SSSE3
0x8: Enable PCLMUL
0x10: Enable AVX
0x20: Enable SHA_NI
0x100000: Enable VIA padlock
0x200000: Enable VIA PHE
0x400000: Enable VIA PHE SHA512

libvirt with CPU of host-model will run most capable model that libvirt knows, but this is not going to match the CPU perfectly. Yes, it is possible that whatever CPU libvirt presents does not match the assumptions GnuTLS is making. Especially when this is a problem that might only appear at run time, on specific guest configurations.

host-passthrough allows the host CPU as is. If you do not care about live migrations, this real CPU is likely to be something that has been tested.

Whatever various libvirt software defaults to, because you know you care about CPU, override the default. virt-install --cpu host-passthrough or edit the domain once created.

A mystery still remains: what instruction? Use a debugger.

Find a simple test case program where GnuTLS crashes. (Or find a core dump file from when it crashed before.)

gdb --args git  # replace "git" with simple test case

(gdb) run

(gdb) layout asm

And page down to the end to see the illegal instruction. With it, you could:

  • Tweak the libvirt domain to add it in but not need passthrough
  • Use a more targeted GNUTLS_CPUID_OVERRIDE only excluding the problem instruction
  • File a bug with GnuTLS requesting improved CPU detection
John Mahowald
  • 36,071