[libvirt] libvirtd crash with host cpu model qemu64

I have an L1 nested VM with the following cpu # lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 2 On-line CPU(s) list: 0,1 Thread(s) per core: 1 Core(s) per socket: 1 Socket(s): 2 NUMA node(s): 1 Vendor ID: AuthenticAMD CPU family: 6 Model: 2 Model name: QEMU Virtual CPU version 0.14 Stepping: 3 CPU MHz: 3092.210 BogoMIPS: 6184.42 Virtualization: AMD-V Hypervisor vendor: KVM Virtualization type: full L1d cache: 64K L1i cache: 64K L2 cache: 512K NUMA node0 CPU(s): 0,1 Flags: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx lm nopl pni cx16 popcnt hypervisor lahf_lm svm abm sse4a 3dnowprefetch vmmcall When starting an L2 VM with <cpu mode="host-model">, libvirtd in the L1 VM crashes Program received signal SIGSEGV, Segmentation fault. 0x00007ffff739bf33 in x86DataCpuid (cpuid=0x8, cpuid=0x8, data=data@entry=0x7fffb800ee78) at cpu/cpu_x86.c:287 287 for (i = 0; i < data->len; i++) { (gdb) bt f0 0x00007ffff739bf33 in x86DataCpuid (cpuid=0x8, cpuid=0x8, data=data@entry=0x7fffb800ee78) at cpu/cpu_x86.c:287 f1 virCPUx86DataAddCPUID (data=data@entry=0x7fffb800ee78, cpuid=0x8) at cpu/cpu_x86.c:355 f2 0x00007ffff739ef47 in x86Compute (host=<optimized out>, cpu=0x7fffb8000cc0, guest=0x7fffecca7348, message=<optimized out>) at cpu/cpu_x86.c:1580 f3 0x00007fffd2b38e53 in qemuBuildCpuModelArgStr (migrating=false, hasHwVirt=<synthetic pointer>, qemuCaps=0x7fffb8001040, buf=0x7fffecca7360, def=0x7fffc400ce20, driver=0x1c) at qemu/qemu_command.c:6283 f4 qemuBuildCpuCommandLine (cmd=cmd@entry=0x7fffb8002f60, driver=driver@entry=0x7fffc80882c0, def=def@entry=0x7fffc400ce20, qemuCaps=qemuCaps@entry=0x7fffb8001040, migrating=<optimized out>) at qemu/qemu_command.c:6445 In frame 2, &host_model->vendor->cpuid is passed to virCPUx86DataAddCPUID(), but (gdb) p *host_model $23 = {name = 0x7fffb800ec50 "qemu64", vendor = 0x0, signature = 0, data = { len = 2, data = 0x7fffb800e720}} With vendor = 0x0, &host_model->vendor->cpuid evaluates to 8, which is not a nice value to pass to virCPUx86DataAddCPUID(). I've hacked around the problem by checking for a non-null host->vendor before calling virCPUx86DataAddCPUID, but I get the feeling it is just that - a hack. Comments on the attached patch, or suggestions for an alternate fix, are kindly welcomed :-). Regards, Jim

Any comments on this? I'm not sure if the below patch is sufficient, or models such as qemu64 need to include vendor information. Thanks! Regards, Jim On 08/05/2016 03:38 PM, Jim Fehlig wrote:
I have an L1 nested VM with the following cpu
# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 2 On-line CPU(s) list: 0,1 Thread(s) per core: 1 Core(s) per socket: 1 Socket(s): 2 NUMA node(s): 1 Vendor ID: AuthenticAMD CPU family: 6 Model: 2 Model name: QEMU Virtual CPU version 0.14 Stepping: 3 CPU MHz: 3092.210 BogoMIPS: 6184.42 Virtualization: AMD-V Hypervisor vendor: KVM Virtualization type: full L1d cache: 64K L1i cache: 64K L2 cache: 512K NUMA node0 CPU(s): 0,1 Flags: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx lm nopl pni cx16 popcnt hypervisor lahf_lm svm abm sse4a 3dnowprefetch vmmcall
When starting an L2 VM with <cpu mode="host-model">, libvirtd in the L1 VM crashes
Program received signal SIGSEGV, Segmentation fault. 0x00007ffff739bf33 in x86DataCpuid (cpuid=0x8, cpuid=0x8, data=data@entry=0x7fffb800ee78) at cpu/cpu_x86.c:287 287 for (i = 0; i < data->len; i++) { (gdb) bt f0 0x00007ffff739bf33 in x86DataCpuid (cpuid=0x8, cpuid=0x8, data=data@entry=0x7fffb800ee78) at cpu/cpu_x86.c:287 f1 virCPUx86DataAddCPUID (data=data@entry=0x7fffb800ee78, cpuid=0x8) at cpu/cpu_x86.c:355 f2 0x00007ffff739ef47 in x86Compute (host=<optimized out>, cpu=0x7fffb8000cc0, guest=0x7fffecca7348, message=<optimized out>) at cpu/cpu_x86.c:1580 f3 0x00007fffd2b38e53 in qemuBuildCpuModelArgStr (migrating=false, hasHwVirt=<synthetic pointer>, qemuCaps=0x7fffb8001040, buf=0x7fffecca7360, def=0x7fffc400ce20, driver=0x1c) at qemu/qemu_command.c:6283 f4 qemuBuildCpuCommandLine (cmd=cmd@entry=0x7fffb8002f60, driver=driver@entry=0x7fffc80882c0, def=def@entry=0x7fffc400ce20, qemuCaps=qemuCaps@entry=0x7fffb8001040, migrating=<optimized out>) at qemu/qemu_command.c:6445
In frame 2, &host_model->vendor->cpuid is passed to virCPUx86DataAddCPUID(), but
(gdb) p *host_model $23 = {name = 0x7fffb800ec50 "qemu64", vendor = 0x0, signature = 0, data = { len = 2, data = 0x7fffb800e720}}
With vendor = 0x0, &host_model->vendor->cpuid evaluates to 8, which is not a nice value to pass to virCPUx86DataAddCPUID(). I've hacked around the problem by checking for a non-null host->vendor before calling virCPUx86DataAddCPUID, but I get the feeling it is just that - a hack.
Comments on the attached patch, or suggestions for an alternate fix, are kindly welcomed :-).
Regards, Jim
From 341445ce85d91a105f8183f22226d9d90853b27b Mon Sep 17 00:00:00 2001 From: Jim Fehlig <jfehlig@suse.com> Date: Fri, 5 Aug 2016 15:23:47 -0600 Subject: [PATCH] cpu_x86: fix libvirtd crash when host cpu is 'qemu64'
When starting an L2 nested VM with <cpu mode="host-model"> on an L1 VM with cpu 'qemu64', libvirtd crashes with
Program received signal SIGSEGV, Segmentation fault. 0x00007ffff739bf33 in x86DataCpuid (cpuid=0x8, cpuid=0x8, data=data@entry=0x7fffb800ee78) at cpu/cpu_x86.c:287 287 for (i = 0; i < data->len; i++) { (gdb) bt f0 0x00007ffff739bf33 in x86DataCpuid (cpuid=0x8, cpuid=0x8, data=data@entry=0x7fffb800ee78) at cpu/cpu_x86.c:287 f1 virCPUx86DataAddCPUID (data=data@entry=0x7fffb800ee78, cpuid=0x8) at cpu/cpu_x86.c:355 f2 0x00007ffff739ef47 in x86Compute (host=<optimized out>, cpu=0x7fffb8000cc0, guest=0x7fffecca7348, message=<optimized out>) at cpu/cpu_x86.c:1580 f3 0x00007fffd2b38e53 in qemuBuildCpuModelArgStr (migrating=false, hasHwVirt=<synthetic pointer>, qemuCaps=0x7fffb8001040, buf=0x7fffecca7360, def=0x7fffc400ce20, driver=0x1c) at qemu/qemu_command.c:6283 f4 qemuBuildCpuCommandLine (cmd=cmd@entry=0x7fffb8002f60, driver=driver@entry=0x7fffc80882c0, def=def@entry=0x7fffc400ce20, qemuCaps=qemuCaps@entry=0x7fffb8001040, migrating=<optimized out>) at qemu/qemu_command.c:6445
In frame 2, &host_model->vendor->cpuid is passed to virCPUx86DataAddCPUID(), but
(gdb) p *host_model $23 = {name = 0x7fffb800ec50 "qemu64", vendor = 0x0, signature = 0, data = { len = 2, data = 0x7fffb800e720}}
With vendor = 0x0, &host_model->vendor->cpuid evaluates to 8, which is not a nice value to pass to virCPUx86DataAddCPUID(). Check for a non-null host_model->vendor before calling virCPUx86DataAddCPUID().
Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/cpu/cpu_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index d9646eb..09eaaa2 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -1576,7 +1576,7 @@ x86Compute(virCPUDefPtr host, if (!(guest_model = x86ModelCopy(host_model))) goto error;
- if (cpu->vendor && + if (cpu->vendor && host_model->vendor && virCPUx86DataAddCPUID(&guest_model->data, &host_model->vendor->cpuid) < 0) goto error; -- 2.1.4

On 05.08.2016 23:38, Jim Fehlig wrote:
<snip/> With vendor = 0x0, &host_model->vendor->cpuid evaluates to 8, which is not a nice value to pass to virCPUx86DataAddCPUID(). Check for a non-null host_model->vendor before calling virCPUx86DataAddCPUID().
Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/cpu/cpu_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index d9646eb..09eaaa2 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -1576,7 +1576,7 @@ x86Compute(virCPUDefPtr host, if (!(guest_model = x86ModelCopy(host_model))) goto error;
- if (cpu->vendor && + if (cpu->vendor && host_model->vendor && virCPUx86DataAddCPUID(&guest_model->data, &host_model->vendor->cpuid) < 0) goto error;
Looks reasonable to me. If there's no host vendor, we shouldn't add the CPU to our database. ACK if you write some sensible commit message to your patch. Michal

On 08/11/2016 02:27 AM, Michal Privoznik wrote:
On 05.08.2016 23:38, Jim Fehlig wrote:
<snip/> With vendor = 0x0, &host_model->vendor->cpuid evaluates to 8, which is not a nice value to pass to virCPUx86DataAddCPUID(). Check for a non-null host_model->vendor before calling virCPUx86DataAddCPUID().
Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/cpu/cpu_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index d9646eb..09eaaa2 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -1576,7 +1576,7 @@ x86Compute(virCPUDefPtr host, if (!(guest_model = x86ModelCopy(host_model))) goto error;
- if (cpu->vendor && + if (cpu->vendor && host_model->vendor && virCPUx86DataAddCPUID(&guest_model->data, &host_model->vendor->cpuid) < 0) goto error;
Looks reasonable to me. If there's no host vendor, we shouldn't add the CPU to our database.
ACK if you write some sensible commit message to your patch.
Thanks. I've finally gotten around to fixing the commit message and pushing the patch. Regards, Jim
participants (2)
-
Jim Fehlig
-
Michal Privoznik