|
|
43fe83 |
From 9a68121178334ac95dd057c98a3b8922a243fb93 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <9a68121178334ac95dd057c98a3b8922a243fb93.1383922567.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
43fe83 |
Date: Fri, 8 Nov 2013 12:33:35 +0100
|
|
|
43fe83 |
Subject: [PATCH] qemu: process: Validate specific CPUID flags of a guest
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=1008989
|
|
|
43fe83 |
|
|
|
43fe83 |
When starting a VM the qemu process may filter out some requested
|
|
|
43fe83 |
features of a domain as it's not supported either by the host or by
|
|
|
43fe83 |
qemu. Libvirt didn't check if this happened which might end up in
|
|
|
43fe83 |
changing of the guest ABI when migrating.
|
|
|
43fe83 |
|
|
|
43fe83 |
The proof of concept implementation adds the check for the recently
|
|
|
43fe83 |
introduced kvm_pv_unhalt cpuid feature bit. This feature depends on both
|
|
|
43fe83 |
qemu and host kernel support and thus increase the possibility of guest
|
|
|
43fe83 |
ABI breakage.
|
|
|
43fe83 |
|
|
|
43fe83 |
(cherry picked from commit d94b7817719b064849818b9ba6c37e403b7c003c)
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/qemu/qemu_process.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
43fe83 |
1 file changed, 46 insertions(+)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
43fe83 |
index e0097df..40e3754 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_process.c
|
|
|
43fe83 |
+++ b/src/qemu/qemu_process.c
|
|
|
43fe83 |
@@ -43,6 +43,7 @@
|
|
|
43fe83 |
#include "qemu_bridge_filter.h"
|
|
|
43fe83 |
#include "qemu_migration.h"
|
|
|
43fe83 |
|
|
|
43fe83 |
+#include "cpu/cpu.h"
|
|
|
43fe83 |
#include "datatypes.h"
|
|
|
43fe83 |
#include "virlog.h"
|
|
|
43fe83 |
#include "virerror.h"
|
|
|
43fe83 |
@@ -3437,6 +3438,47 @@ qemuValidateCpuMax(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
|
|
|
43fe83 |
return true;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static bool
|
|
|
43fe83 |
+qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ virDomainDefPtr def = vm->def;
|
|
|
43fe83 |
+ virArch arch = def->os.arch;
|
|
|
43fe83 |
+ virCPUDataPtr guestcpu = NULL;
|
|
|
43fe83 |
+ qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
43fe83 |
+ bool ret = false;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ switch (arch) {
|
|
|
43fe83 |
+ case VIR_ARCH_I686:
|
|
|
43fe83 |
+ case VIR_ARCH_X86_64:
|
|
|
43fe83 |
+ qemuDomainObjEnterMonitor(driver, vm);
|
|
|
43fe83 |
+ guestcpu = qemuMonitorGetGuestCPU(priv->mon, arch);
|
|
|
43fe83 |
+ qemuDomainObjExitMonitor(driver, vm);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (!(guestcpu))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_DOMAIN_FEATURE_STATE_ON) {
|
|
|
43fe83 |
+ if (!cpuHasFeature(guestcpu, VIR_CPU_x86_KVM_PV_UNHALT)) {
|
|
|
43fe83 |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
43fe83 |
+ _("host doesn't support paravirtual spinlocks"));
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ break;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ default:
|
|
|
43fe83 |
+ break;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ ret = true;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+cleanup:
|
|
|
43fe83 |
+ cpuDataFree(guestcpu);
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
int qemuProcessStart(virConnectPtr conn,
|
|
|
43fe83 |
virQEMUDriverPtr driver,
|
|
|
43fe83 |
virDomainObjPtr vm,
|
|
|
43fe83 |
@@ -3904,6 +3946,10 @@ int qemuProcessStart(virConnectPtr conn,
|
|
|
43fe83 |
priv->agentError = true;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+ VIR_DEBUG("Detecting if required emulator features are present");
|
|
|
43fe83 |
+ if (!qemuProcessVerifyGuestCPU(driver, vm))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
VIR_DEBUG("Detecting VCPU PIDs");
|
|
|
43fe83 |
if (qemuProcessDetectVcpuPIDs(driver, vm) < 0)
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.4.2
|
|
|
43fe83 |
|