In case libvirtd cannot detect host CPU model (which may happen if it
runs inside a virtual machine), the daemon is likely to segfault when
starting a new qemu domain. It segfaults when domain XML asks for host
(either model or passthrough) CPU or does not ask for any specific CPU
model at all.
---
src/qemu/qemu_command.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 99d7129..5633dfd 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3508,22 +3508,13 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
*hasHwVirt = false;
- if (def->cpu &&
- (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
- if (!(cpu = virCPUDefCopy(def->cpu)))
- goto cleanup;
- if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
- !migrating &&
- cpuUpdate(cpu, host) < 0)
- goto cleanup;
- }
-
if (STREQ(def->os.arch, "i686"))
default_model = "qemu32";
else
default_model = "qemu64";
- if (cpu) {
+ if (def->cpu &&
+ (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
virCPUCompareResult cmp;
const char *preferred;
int hasSVM;
@@ -3539,6 +3530,14 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
goto cleanup;
}
+ if (!(cpu = virCPUDefCopy(def->cpu)))
+ goto cleanup;
+
+ if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
+ !migrating &&
+ cpuUpdate(cpu, host) < 0)
+ goto cleanup;
+
cmp = cpuGuestData(host, cpu, &data);
switch (cmp) {
case VIR_CPU_COMPARE_INCOMPATIBLE:
@@ -3647,7 +3646,8 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
ret = 0;
cleanup:
- cpuDataFree(host->arch, data);
+ if (host)
+ cpuDataFree(host->arch, data);
virCPUDefFree(guest);
virCPUDefFree(cpu);
--
1.7.8.4