Compare commits

..

8 Commits

Author SHA1 Message Date
Cole Robinson 54d3da1da5 CVE-2017-1000256: libvirt: TLS certificate verification disabled for clients (bz #1503687) 2017-12-04 12:16:49 -05:00
Cole Robinson faf5df2081 Fix TPM2 passthrough (bz #1486240)
Fix spice GL qemu:///system rendernode permissions (bz #1460804)
Fix on_reboot=destroy setting (bz #1476866)
Fix disk images in /dev/shm (bz #1482146)
2017-09-15 19:04:20 -04:00
Cole Robinson e5075407b1 Enable ZFS storage driver (bz #1471912)
Don't use cgroup mount points from /proc/mounts that are hidden (bz #1470593)
disk driver name=... should be optional (bz #1473091)
2017-08-04 16:11:19 -04:00
Cole Robinson 8c3f1e830e Fix resuming qemu VMs suspended before libvirt 3.2.0
Fix issues with AMD CPU models, and some others
2017-07-12 16:26:46 -04:00
Cole Robinson 58083f4418 Remove wireshark workaround 2017-06-14 10:47:37 -04:00
Cole Robinson 55a13fd521 Tweak condition for not starting in live environment (bz #1146232) 2017-05-31 17:28:27 -04:00
Cole Robinson 262bbf08f2 Fix aarch64 gic default for non-kvm VMs (bz #1449837)
Don't run libvirtd in live environment, to avoid network collision (bz #1146232)
2017-05-30 18:57:48 -04:00
Cole Robinson 0fe69a9b44 Rebased to version 3.2.1 2017-05-10 20:26:58 -04:00
50 changed files with 2561 additions and 2452 deletions
@@ -0,0 +1,122 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 14:05:55 +0200
Subject: [PATCH] tests: Check default GIC version for aarch64/virt TCG guests
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit b24eaf6210ebaf5dc8d29621063873c8419c517e)
---
.../qemuxml2argv-aarch64-gic-none-tcg.args | 19 ++++++++++++++++
.../qemuxml2argv-aarch64-gic-none-tcg.xml | 17 +++++++++++++++
tests/qemuxml2argvtest.c | 3 +++
.../qemuxml2xmlout-aarch64-gic-none-tcg.xml | 25 ++++++++++++++++++++++
tests/qemuxml2xmltest.c | 1 +
5 files changed, 65 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
new file mode 100644
index 000000000..975a01481
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
@@ -0,0 +1,19 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-aarch64 \
+-name guest \
+-S \
+-machine virt,accel=tcg,gic-version=3 \
+-cpu cortex-a57 \
+-m 1024 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 6ba410c5-1e5c-4d57-bee7-2228e7ffa32f \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-guest/monitor.sock,server,nowait \
+-no-acpi \
+-boot c
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
new file mode 100644
index 000000000..0aa33dbec
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
@@ -0,0 +1,17 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom'>
+ <model>cortex-a57</model>
+ </cpu>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index cc4fb91cd..362b140ac 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2250,6 +2250,9 @@ mymain(void)
DO_TEST_GIC("aarch64-gic-none-both", GIC_BOTH,
QEMU_CAPS_KVM, QEMU_CAPS_MACHINE_OPT,
QEMU_CAPS_MACH_VIRT_GIC_VERSION);
+ DO_TEST_GIC("aarch64-gic-none-tcg", GIC_BOTH,
+ QEMU_CAPS_MACHINE_OPT,
+ QEMU_CAPS_MACH_VIRT_GIC_VERSION);
DO_TEST_GIC("aarch64-gic-default", GIC_NONE,
QEMU_CAPS_KVM, QEMU_CAPS_MACHINE_OPT);
DO_TEST_GIC("aarch64-gic-default", GIC_NONE,
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
new file mode 100644
index 000000000..69510e281
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
@@ -0,0 +1,25 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <gic version='3'/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='allow'>cortex-a57</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index eae999dd6..aae632afe 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1073,6 +1073,7 @@ mymain(void)
DO_TEST_FULL("aarch64-gic-none-v2", WHEN_BOTH, GIC_V2, NONE);
DO_TEST_FULL("aarch64-gic-none-v3", WHEN_BOTH, GIC_V3, NONE);
DO_TEST_FULL("aarch64-gic-none-both", WHEN_BOTH, GIC_BOTH, NONE);
+ DO_TEST_FULL("aarch64-gic-none-tcg", WHEN_BOTH, GIC_BOTH, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_NONE, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_V2, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_V3, NONE);
@@ -0,0 +1,85 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 13:29:57 +0200
Subject: [PATCH] qemu: Use GICv2 for aarch64/virt TCG guests
There are currently some limitations in the emulated GICv3
that make it unsuitable as a default. Use GICv2 instead.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1450433
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit bc07101a7c2cd2ce07ad1ca28c47e0a7cde5625d)
---
src/qemu/qemu_domain.c | 23 +++++++++++++++++++++-
.../qemuxml2argv-aarch64-gic-none-tcg.args | 2 +-
.../qemuxml2xmlout-aarch64-gic-none-tcg.xml | 2 +-
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 589eb1889..891f8258a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2527,6 +2527,24 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
for (version = VIR_GIC_VERSION_LAST - 1;
version > VIR_GIC_VERSION_NONE;
version--) {
+
+ /* We want to use the highest available GIC version for guests;
+ * however, the emulated GICv3 is currently lacking a MSI controller,
+ * making it unsuitable for the pure PCIe topology we aim for.
+ *
+ * For that reason, we skip this step entirely for TCG guests,
+ * and rely on the code below to pick the default version, GICv2,
+ * which supports all the features we need.
+ *
+ * We'll want to revisit this once MSI support for GICv3 has been
+ * implemented in QEMU.
+ *
+ * See https://bugzilla.redhat.com/show_bug.cgi?id=1414081 */
+ if (version == VIR_GIC_VERSION_3 &&
+ def->virtType == VIR_DOMAIN_VIRT_QEMU) {
+ continue;
+ }
+
if (virQEMUCapsSupportsGICVersion(qemuCaps,
def->virtType,
version)) {
@@ -2544,8 +2562,11 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
/* Use the default GIC version if no version was specified */
if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON &&
- def->gic_version == VIR_GIC_VERSION_NONE)
+ def->gic_version == VIR_GIC_VERSION_NONE) {
+ VIR_DEBUG("Using GIC version %s (default)",
+ virGICVersionTypeToString(VIR_GIC_VERSION_DEFAULT));
def->gic_version = VIR_GIC_VERSION_DEFAULT;
+ }
}
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
index 975a01481..52b699696 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
@@ -7,7 +7,7 @@ QEMU_AUDIO_DRV=none \
/usr/bin/qemu-system-aarch64 \
-name guest \
-S \
--machine virt,accel=tcg,gic-version=3 \
+-machine virt,accel=tcg \
-cpu cortex-a57 \
-m 1024 \
-smp 1,sockets=1,cores=1,threads=1 \
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
index 69510e281..a0cd0b768 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
@@ -9,7 +9,7 @@
<boot dev='hd'/>
</os>
<features>
- <gic version='3'/>
+ <gic version='2'/>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='allow'>cortex-a57</model>
@@ -0,0 +1,67 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 14:38:08 +0200
Subject: [PATCH] gic: Remove VIR_GIC_VERSION_DEFAULT
The QEMU default is GICv2, and some of the code in libvirt
relies on the exact value. Stop pretending that's not the
case and use GICv2 explicitly where needed.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit 5645badd1fe04fee7237c2f95e7710e978e40770)
---
src/qemu/qemu_command.c | 6 +++---
src/qemu/qemu_domain.c | 7 +++----
src/util/virgic.h | 3 ---
3 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2d1328cf9..5feddc523 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7321,9 +7321,9 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
goto cleanup;
}
- /* The default GIC version should not be specified on the
- * QEMU commandline for backwards compatibility reasons */
- if (def->gic_version != VIR_GIC_VERSION_DEFAULT) {
+ /* The default GIC version (GICv2) should not be specified on
+ * the QEMU commandline for backwards compatibility reasons */
+ if (def->gic_version != VIR_GIC_VERSION_2) {
if (!virQEMUCapsGet(qemuCaps,
QEMU_CAPS_MACH_VIRT_GIC_VERSION)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 891f8258a..4a127cedf 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2560,12 +2560,11 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
def->features[VIR_DOMAIN_FEATURE_GIC] = VIR_TRISTATE_SWITCH_ON;
}
- /* Use the default GIC version if no version was specified */
+ /* Use the default GIC version (GICv2) if no version was specified */
if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON &&
def->gic_version == VIR_GIC_VERSION_NONE) {
- VIR_DEBUG("Using GIC version %s (default)",
- virGICVersionTypeToString(VIR_GIC_VERSION_DEFAULT));
- def->gic_version = VIR_GIC_VERSION_DEFAULT;
+ VIR_DEBUG("Using GIC version 2 (default)");
+ def->gic_version = VIR_GIC_VERSION_2;
}
}
diff --git a/src/util/virgic.h b/src/util/virgic.h
index 1c9efd60f..2d77fdd45 100644
--- a/src/util/virgic.h
+++ b/src/util/virgic.h
@@ -35,9 +35,6 @@ typedef enum {
VIR_ENUM_DECL(virGICVersion);
-/* Consider GIC v2 the default */
-# define VIR_GIC_VERSION_DEFAULT VIR_GIC_VERSION_2
-
typedef enum {
VIR_GIC_IMPLEMENTATION_NONE = 0,
VIR_GIC_IMPLEMENTATION_KERNEL = (1 << 1),
@@ -0,0 +1,198 @@
From: Laine Stump <laine@laine.org>
Date: Thu, 18 May 2017 14:16:27 -0400
Subject: [PATCH] Revert "qemu: propagate bridge MTU into qemu "host_mtu"
option"
This reverts commit 2841e675.
It turns out that adding the host_mtu field to the PCI capabilities in
the guest bumps the length of PCI capabilities beyond the 32 byte
boundary, so the virtio-net device gets 64 bytes of ioport space
instead of 32, which offsets the address of all the other following
devices. Migration doesn't work very well when the location and length
of PCI capabilities of devices is changed between source and
destination.
This means that we need to make sure that the absence/presence of
host_mtu on the qemu commandline always matches between source and
destination, which means that we need to make setting of host_mtu an
opt-in thing (it can't happen automatically when the bridge being used
has a non-default MTU, which is what commit 2841e675 implemented).
I do want to re-implement this feature with an <mtu auto='on'/>
setting, but probably won't backport that to any stable branches, so
I'm first reverting the original commit, and that revert can be pushed
to the few releases that have been made since the original (3.1.0 -
3.3.0)
Resolves: https://bugzilla.redhat.com/1449346
(cherry picked from commit 77780a29edace958a1f931d3281b962be4f5290e)
(cherry picked from commit a2f5e87dceb1725c16cd4df17a4b7381ecf65901)
---
src/qemu/qemu_command.c | 32 ++++++++++----------------------
src/qemu/qemu_command.h | 3 +--
src/qemu/qemu_hotplug.c | 5 ++---
src/qemu/qemu_interface.c | 5 ++---
src/qemu/qemu_interface.h | 3 +--
5 files changed, 16 insertions(+), 32 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5feddc523..3abfe7b55 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3629,8 +3629,7 @@ qemuBuildNicDevStr(virDomainDefPtr def,
int vlan,
unsigned int bootindex,
size_t vhostfdSize,
- virQEMUCapsPtr qemuCaps,
- unsigned int mtu)
+ virQEMUCapsPtr qemuCaps)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
const char *nic = net->model;
@@ -3754,23 +3753,13 @@ qemuBuildNicDevStr(virDomainDefPtr def,
virBufferAsprintf(&buf, ",rx_queue_size=%u", net->driver.virtio.rx_queue_size);
}
- if (usingVirtio && mtu) {
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) {
-
- virBufferAsprintf(&buf, ",host_mtu=%u", mtu);
-
- } else {
- /* log an error if mtu was requested specifically for this
- * interface, otherwise, if it's just what was reported by
- * the attached network, ignore it.
- */
- if (net->mtu) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("setting MTU is not supported with "
- "this QEMU binary"));
- goto error;
- }
+ if (usingVirtio && net->mtu) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("setting MTU is not supported with this QEMU binary"));
+ goto error;
}
+ virBufferAsprintf(&buf, ",host_mtu=%u", net->mtu);
}
if (vlan == -1)
@@ -8213,7 +8202,7 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
VIR_FREE(netdev);
if (!(nic = qemuBuildNicDevStr(def, net, -1, bootindex,
- queues, qemuCaps, net->mtu))) {
+ queues, qemuCaps))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Error generating NIC -device string"));
goto error;
@@ -8259,7 +8248,6 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
virDomainNetType actualType = virDomainNetGetActualType(net);
virNetDevBandwidthPtr actualBandwidth;
size_t i;
- unsigned int mtu = net->mtu;
if (!bootindex)
@@ -8314,7 +8302,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
if (qemuInterfaceBridgeConnect(def, driver, net,
- tapfd, &tapfdSize, &mtu) < 0)
+ tapfd, &tapfdSize) < 0)
goto cleanup;
break;
@@ -8494,7 +8482,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
}
if (qemuDomainSupportsNicdev(def, net)) {
if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
- vhostfdSize, qemuCaps, mtu)))
+ vhostfdSize, qemuCaps)))
goto cleanup;
virCommandAddArgList(cmd, "-device", nic, NULL);
} else {
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 7da92c8c9..09cb00ee9 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -101,8 +101,7 @@ char *qemuBuildNicDevStr(virDomainDefPtr def,
int vlan,
unsigned int bootindex,
size_t vhostfdSize,
- virQEMUCapsPtr qemuCaps,
- unsigned int mtu);
+ virQEMUCapsPtr qemuCaps);
char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f133d04a8..2a4159560 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -968,7 +968,6 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
bool charDevPlugged = false;
bool netdevPlugged = false;
bool hostPlugged = false;
- unsigned int mtu = net->mtu;
/* preallocate new slot for device */
if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
@@ -1025,7 +1024,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
goto cleanup;
memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
if (qemuInterfaceBridgeConnect(vm->def, driver, net,
- tapfd, &tapfdSize, &mtu) < 0)
+ tapfd, &tapfdSize) < 0)
goto cleanup;
iface_connected = true;
if (qemuInterfaceOpenVhostNet(vm->def, net, priv->qemuCaps,
@@ -1239,7 +1238,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
VIR_FORCE_CLOSE(vhostfd[i]);
if (!(nicstr = qemuBuildNicDevStr(vm->def, net, vlan, 0,
- queueSize, priv->qemuCaps, mtu)))
+ queueSize, priv->qemuCaps)))
goto try_remove;
qemuDomainObjEnterMonitor(driver, vm);
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index c5dca60f1..ce448d243 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -503,8 +503,7 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
int *tapfd,
- size_t *tapfdSize,
- unsigned int *mtu)
+ size_t *tapfdSize)
{
const char *brname;
int ret = -1;
@@ -545,7 +544,7 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def,
def->uuid, tunpath, tapfd, *tapfdSize,
virDomainNetGetActualVirtPortProfile(net),
virDomainNetGetActualVlan(net),
- net->mtu, mtu,
+ 0, NULL,
tap_create_flags) < 0) {
virDomainAuditNetDevice(def, net, tunpath, false);
goto cleanup;
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index ba74ac2cf..a7faa0b3d 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -51,8 +51,7 @@ int qemuInterfaceBridgeConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
int *tapfd,
- size_t *tapfdSize,
- unsigned int *mtu)
+ size_t *tapfdSize)
ATTRIBUTE_NONNULL(2);
int qemuInterfaceOpenVhostNet(virDomainDefPtr def,
@@ -0,0 +1,145 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 14:45:44 +0200
Subject: [PATCH] cpu: Introduce virCPUCopyMigratable
This new internal API makes a copy of virCPUDef while removing all
features which would block migration. It uses cpu_map.xml as a database
of such features, which should only be used as a fallback when we cannot
get the data from a hypervisor. The main goal of this API is to decouple
this filtering from virCPUUpdate so that the hypervisor driver can
filter the features according to the hypervisor.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 05e91c79f19e0be96526098d58a3498dac3f8529)
---
src/cpu/cpu.c | 31 +++++++++++++++++++++++++++++++
src/cpu/cpu.h | 8 ++++++++
src/cpu/cpu_x86.c | 25 +++++++++++++++++++++++++
src/libvirt_private.syms | 1 +
4 files changed, 65 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 93647a2ed..8a407ac18 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -1130,3 +1130,34 @@ virCPUExpandFeatures(virArch arch,
VIR_DEBUG("nfeatures=%zu", cpu->nfeatures);
return 0;
}
+
+
+/**
+ * virCPUCopyMigratable:
+ *
+ * @arch: CPU architecture
+ * @cpu: CPU definition to be copied
+ *
+ * Makes a copy of @cpu with all features which would block migration removed.
+ * If this doesn't make sense for a given architecture, the function returns a
+ * plain copy of @cpu (i.e., a copy with no features removed).
+ *
+ * Returns the copy of the CPU or NULL on error.
+ */
+virCPUDefPtr
+virCPUCopyMigratable(virArch arch,
+ virCPUDefPtr cpu)
+{
+ struct cpuArchDriver *driver;
+
+ VIR_DEBUG("arch=%s, cpu=%p, model=%s",
+ virArchToString(arch), cpu, NULLSTR(cpu->model));
+
+ if (!(driver = cpuGetSubDriver(arch)))
+ return NULL;
+
+ if (driver->copyMigratable)
+ return driver->copyMigratable(cpu);
+ else
+ return virCPUDefCopy(cpu);
+}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 8c238ad55..352445c40 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -118,6 +118,9 @@ typedef int
typedef int
(*virCPUArchExpandFeatures)(virCPUDefPtr cpu);
+typedef virCPUDefPtr
+(*virCPUArchCopyMigratable)(virCPUDefPtr cpu);
+
struct cpuArchDriver {
const char *name;
const virArch *arch;
@@ -138,6 +141,7 @@ struct cpuArchDriver {
virCPUArchTranslate translate;
virCPUArchConvertLegacy convertLegacy;
virCPUArchExpandFeatures expandFeatures;
+ virCPUArchCopyMigratable copyMigratable;
};
@@ -254,6 +258,10 @@ int
virCPUExpandFeatures(virArch arch,
virCPUDefPtr cpu);
+virCPUDefPtr
+virCPUCopyMigratable(virArch arch,
+ virCPUDefPtr cpu);
+
/* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
* have no real-life usage
*/
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 48648a7f4..a771b251e 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2903,6 +2903,30 @@ virCPUx86ExpandFeatures(virCPUDefPtr cpu)
}
+static virCPUDefPtr
+virCPUx86CopyMigratable(virCPUDefPtr cpu)
+{
+ virCPUDefPtr copy;
+ virCPUx86MapPtr map;
+
+ if (!(map = virCPUx86GetMap()))
+ return NULL;
+
+ if (!(copy = virCPUDefCopyWithoutModel(cpu)))
+ return NULL;
+
+ if (virCPUDefCopyModelFilter(copy, cpu, false,
+ x86FeatureIsMigratable, map) < 0)
+ goto error;
+
+ return copy;
+
+ error:
+ virCPUDefFree(copy);
+ return NULL;
+}
+
+
int
virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
const virCPUx86CPUID *cpuid)
@@ -2978,4 +3002,5 @@ struct cpuArchDriver cpuDriverX86 = {
.getModels = virCPUx86GetModels,
.translate = virCPUx86Translate,
.expandFeatures = virCPUx86ExpandFeatures,
+ .copyMigratable = virCPUx86CopyMigratable,
};
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b551cb86a..dc6db3b28 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1016,6 +1016,7 @@ virCPUCheckFeature;
virCPUCompare;
virCPUCompareXML;
virCPUConvertLegacy;
+virCPUCopyMigratable;
virCPUDataCheckFeature;
virCPUDataFormat;
virCPUDataFree;
@@ -1,177 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 15 Nov 2017 13:15:57 +0100
Subject: [PATCH] qemu: Move snapshot disk validation functions into one
Move the code so that both the new image and old image can be verified
in the same function.
(cherry picked from commit 8ffdeed455650557df531aafc66c20b31bd4e0c4)
---
src/qemu/qemu_driver.c | 91 ++++++++++++++++++++------------------------------
1 file changed, 36 insertions(+), 55 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1f9264639..57f0c2bf4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13793,17 +13793,19 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn,
static int
-qemuDomainSnapshotPrepareDiskExternalBackingInactive(virDomainDiskDefPtr disk)
+qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdisk,
+ virDomainDiskDefPtr domdisk)
{
- int actualType = virStorageSourceGetActualType(disk->src);
+ int domDiskType = virStorageSourceGetActualType(domdisk->src);
+ int snapDiskType = virStorageSourceGetActualType(snapdisk->src);
- switch ((virStorageType) actualType) {
+ switch ((virStorageType) domDiskType) {
case VIR_STORAGE_TYPE_BLOCK:
case VIR_STORAGE_TYPE_FILE:
- return 0;
+ break;
case VIR_STORAGE_TYPE_NETWORK:
- switch ((virStorageNetProtocol) disk->src->protocol) {
+ switch ((virStorageNetProtocol) domdisk->src->protocol) {
case VIR_STORAGE_NET_PROTOCOL_NONE:
case VIR_STORAGE_NET_PROTOCOL_NBD:
case VIR_STORAGE_NET_PROTOCOL_RBD:
@@ -13820,7 +13822,7 @@ qemuDomainSnapshotPrepareDiskExternalBackingInactive(virDomainDiskDefPtr disk)
virReportError(VIR_ERR_INTERNAL_ERROR,
_("external inactive snapshots are not supported on "
"'network' disks using '%s' protocol"),
- virStorageNetProtocolTypeToString(disk->src->protocol));
+ virStorageNetProtocolTypeToString(domdisk->src->protocol));
return -1;
}
break;
@@ -13831,7 +13833,23 @@ qemuDomainSnapshotPrepareDiskExternalBackingInactive(virDomainDiskDefPtr disk)
case VIR_STORAGE_TYPE_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("external inactive snapshots are not supported on "
- "'%s' disks"), virStorageTypeToString(actualType));
+ "'%s' disks"), virStorageTypeToString(domDiskType));
+ return -1;
+ }
+
+ switch ((virStorageType) snapDiskType) {
+ case VIR_STORAGE_TYPE_BLOCK:
+ case VIR_STORAGE_TYPE_FILE:
+ break;
+
+ case VIR_STORAGE_TYPE_NETWORK:
+ case VIR_STORAGE_TYPE_DIR:
+ case VIR_STORAGE_TYPE_VOLUME:
+ case VIR_STORAGE_TYPE_NONE:
+ case VIR_STORAGE_TYPE_LAST:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("external inactive snapshots are not supported on "
+ "'%s' disks"), virStorageTypeToString(snapDiskType));
return -1;
}
@@ -13840,33 +13858,27 @@ qemuDomainSnapshotPrepareDiskExternalBackingInactive(virDomainDiskDefPtr disk)
static int
-qemuDomainSnapshotPrepareDiskExternalBackingActive(virDomainDiskDefPtr disk)
+qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk,
+ virDomainDiskDefPtr domdisk)
{
- if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
+ int actualType = virStorageSourceGetActualType(snapdisk->src);
+
+ if (domdisk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("external active snapshots are not supported on scsi "
"passthrough devices"));
return -1;
}
- return 0;
-}
-
-
-static int
-qemuDomainSnapshotPrepareDiskExternalOverlayActive(virDomainSnapshotDiskDefPtr disk)
-{
- int actualType = virStorageSourceGetActualType(disk->src);
-
switch ((virStorageType) actualType) {
case VIR_STORAGE_TYPE_BLOCK:
case VIR_STORAGE_TYPE_FILE:
- return 0;
+ break;
case VIR_STORAGE_TYPE_NETWORK:
- switch ((virStorageNetProtocol) disk->src->protocol) {
+ switch ((virStorageNetProtocol) snapdisk->src->protocol) {
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
- return 0;
+ break;
case VIR_STORAGE_NET_PROTOCOL_NONE:
case VIR_STORAGE_NET_PROTOCOL_NBD:
@@ -13883,7 +13895,7 @@ qemuDomainSnapshotPrepareDiskExternalOverlayActive(virDomainSnapshotDiskDefPtr d
virReportError(VIR_ERR_INTERNAL_ERROR,
_("external active snapshots are not supported on "
"'network' disks using '%s' protocol"),
- virStorageNetProtocolTypeToString(disk->src->protocol));
+ virStorageNetProtocolTypeToString(snapdisk->src->protocol));
return -1;
}
@@ -13903,31 +13915,6 @@ qemuDomainSnapshotPrepareDiskExternalOverlayActive(virDomainSnapshotDiskDefPtr d
}
-static int
-qemuDomainSnapshotPrepareDiskExternalOverlayInactive(virDomainSnapshotDiskDefPtr disk)
-{
- int actualType = virStorageSourceGetActualType(disk->src);
-
- switch ((virStorageType) actualType) {
- case VIR_STORAGE_TYPE_BLOCK:
- case VIR_STORAGE_TYPE_FILE:
- return 0;
-
- case VIR_STORAGE_TYPE_NETWORK:
- case VIR_STORAGE_TYPE_DIR:
- case VIR_STORAGE_TYPE_VOLUME:
- case VIR_STORAGE_TYPE_NONE:
- case VIR_STORAGE_TYPE_LAST:
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("external inactive snapshots are not supported on "
- "'%s' disks"), virStorageTypeToString(actualType));
- return -1;
- }
-
- return 0;
-}
-
-
static int
qemuDomainSnapshotPrepareDiskExternal(virConnectPtr conn,
virDomainDiskDefPtr disk,
@@ -13945,16 +13932,10 @@ qemuDomainSnapshotPrepareDiskExternal(virConnectPtr conn,
if (virStorageTranslateDiskSourcePool(conn, disk) < 0)
return -1;
- if (qemuDomainSnapshotPrepareDiskExternalBackingInactive(disk) < 0)
- return -1;
-
- if (qemuDomainSnapshotPrepareDiskExternalOverlayInactive(snapdisk) < 0)
+ if (qemuDomainSnapshotPrepareDiskExternalInactive(snapdisk, disk) < 0)
return -1;
} else {
- if (qemuDomainSnapshotPrepareDiskExternalBackingActive(disk) < 0)
- return -1;
-
- if (qemuDomainSnapshotPrepareDiskExternalOverlayActive(snapdisk) < 0)
+ if (qemuDomainSnapshotPrepareDiskExternalActive(snapdisk, disk) < 0)
return -1;
}
@@ -0,0 +1,78 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 30 Mar 2017 13:50:44 +0200
Subject: [PATCH] qemu: Move common code in virQEMUCapsInitCPUModel one layer
up
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit d84b93fad51b190238e18b1daac82ea6e28869e9)
---
src/qemu/qemu_capabilities.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b1245ad5d..1a15750a3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3111,17 +3111,11 @@ virQEMUCapsCPUFilterFeatures(const char *name,
*/
static int
virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type,
+ qemuMonitorCPUModelInfoPtr modelInfo,
virCPUDefPtr cpu)
{
- qemuMonitorCPUModelInfoPtr modelInfo;
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM)
- modelInfo = qemuCaps->kvmCPUModelInfo;
- else
- modelInfo = qemuCaps->tcgCPUModelInfo;
-
if (!modelInfo) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing host CPU model info from QEMU capabilities "
@@ -3163,9 +3157,9 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
static int
virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
+ qemuMonitorCPUModelInfoPtr model,
virCPUDefPtr cpu)
{
- qemuMonitorCPUModelInfoPtr model;
virCPUDataPtr data = NULL;
unsigned long long sigFamily = 0;
unsigned long long sigModel = 0;
@@ -3174,11 +3168,6 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
int ret = -1;
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM)
- model = qemuCaps->kvmCPUModelInfo;
- else
- model = qemuCaps->tcgCPUModelInfo;
-
if (!model)
return 1;
@@ -3239,12 +3228,18 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr cpu)
{
+ qemuMonitorCPUModelInfoPtr model;
int ret = 1;
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ model = qemuCaps->kvmCPUModelInfo;
+ else
+ model = qemuCaps->tcgCPUModelInfo;
+
if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, cpu);
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu);
else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpu);
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu);
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -1,55 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 14 Nov 2017 15:34:46 +0100
Subject: [PATCH] qemu: block: Add function to check if storage source allows
concurrent access
Storage source format backing a shared device (e.g. running a cluster
filesystem) needs to support the sharing so that metadata are not
corrupted. Add a central function for checking this.
(cherry picked from commit 1fc3cd8731640aefc48bbd9fc489f21cb99c6f67)
---
src/qemu/qemu_block.c | 15 +++++++++++++++
src/qemu/qemu_block.h | 3 +++
2 files changed, 18 insertions(+)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 7fb12ea5a..4c0a5eb78 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -379,6 +379,21 @@ qemuBlockGetNodeData(virJSONValuePtr data)
}
+/**
+ * qemuBlockStorageSourceSupportsConcurrentAccess:
+ * @src: disk storage source
+ *
+ * Returns true if the given storage format supports concurrent access from two
+ * separate processes.
+ */
+bool
+qemuBlockStorageSourceSupportsConcurrentAccess(virStorageSourcePtr src)
+{
+ /* no need to check in backing chain since only RAW storage supports this */
+ return src->format == VIR_STORAGE_FILE_RAW;
+}
+
+
/**
* qemuBlockStorageSourceBuildHostsJSONSocketAddress:
* @src: disk storage source
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
index f0a2c9aa7..ebf3149ce 100644
--- a/src/qemu/qemu_block.h
+++ b/src/qemu/qemu_block.h
@@ -53,6 +53,9 @@ qemuBlockNodeNamesDetect(virQEMUDriverPtr driver,
virHashTablePtr
qemuBlockGetNodeData(virJSONValuePtr data);
+bool
+qemuBlockStorageSourceSupportsConcurrentAccess(virStorageSourcePtr src);
+
virJSONValuePtr
qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src);
@@ -0,0 +1,139 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 13:33:50 +0200
Subject: [PATCH] qemu: Add migratable parameter to virQEMUCapsInitCPUModel
The caller can ask for a migratable CPU model by passing true for the
new parameter.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 00e0cbcb567a57c7b5a145d7fd3fb662779f6bec)
---
src/qemu/qemu_capabilities.c | 36 +++++++++++++++++++++++++-----------
src/qemu/qemu_capspriv.h | 3 ++-
tests/cputest.c | 2 +-
3 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1a15750a3..b8e4e47b6 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3112,7 +3112,8 @@ virQEMUCapsCPUFilterFeatures(const char *name,
static int
virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
qemuMonitorCPUModelInfoPtr modelInfo,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
size_t i;
@@ -3140,8 +3141,12 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
if (VIR_STRDUP(feature->name, prop->name) < 0)
return -1;
- feature->policy = prop->value.boolean ? VIR_CPU_FEATURE_REQUIRE
- : VIR_CPU_FEATURE_DISABLE;
+
+ if (!prop->value.boolean ||
+ (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
+ feature->policy = VIR_CPU_FEATURE_DISABLE;
+ else
+ feature->policy = VIR_CPU_FEATURE_REQUIRE;
cpu->nfeatures++;
}
@@ -3158,7 +3163,8 @@ static int
virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
qemuMonitorCPUModelInfoPtr model,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
virCPUDataPtr data = NULL;
unsigned long long sigFamily = 0;
@@ -3179,9 +3185,13 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
switch (prop->type) {
case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
- if (prop->value.boolean &&
- virCPUx86DataAddFeature(data, prop->name) < 0)
+ if (!prop->value.boolean ||
+ (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
+ continue;
+
+ if (virCPUx86DataAddFeature(data, prop->name) < 0)
goto cleanup;
+
break;
case QEMU_MONITOR_CPU_PROPERTY_STRING:
@@ -3220,13 +3230,14 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
/**
* Returns 0 when host CPU model provided by QEMU was filled in qemuCaps,
- * 1 when the caller should fall back to using virCapsPtr->host.cpu,
+ * 1 when the caller should fall back to other methods
* -1 on error.
*/
int
virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
qemuMonitorCPUModelInfoPtr model;
int ret = 1;
@@ -3236,10 +3247,13 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
else
model = qemuCaps->tcgCPUModelInfo;
+ if (migratable && model && !model->migratability)
+ return 1;
+
if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu);
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu, migratable);
else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu);
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu, migratable);
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -3268,7 +3282,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
cpu->match = VIR_CPU_MATCH_EXACT;
cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu)) < 0) {
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
goto error;
} else if (rc == 1) {
VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly");
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index 61ccd4517..1baaaf334 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -81,7 +81,8 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
int
virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu);
+ virCPUDefPtr cpu,
+ bool migratable);
void
virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
diff --git a/tests/cputest.c b/tests/cputest.c
index 3d3e43f16..8c07cf4f6 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -709,7 +709,7 @@ cpuTestJSONCPUID(const void *arg)
cpu->match = VIR_CPU_MATCH_EXACT;
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
- if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu) != 0)
+ if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu, false) != 0)
goto cleanup;
ret = cpuTestCompareXML(data->arch, cpu, result, false);
@@ -1,146 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 14 Nov 2017 15:37:09 +0100
Subject: [PATCH] qemu: domain: Reject shared disk access if backing format
does not support it
Disk sharing between two VMs may corrupt the images if the format driver
does not support it. Check that the user declared use of a supported
storage format when they want to share the disk.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1511480
(cherry picked from commit 3b03a27cd00c2f032661d2bf8905795425752fc7)
---
src/qemu/qemu_domain.c | 29 +++++++++++++++++++++-
.../qemuxml2argv-disk-drive-shared-qcow.xml | 28 +++++++++++++++++++++
.../qemuxml2argv-disk-drive-shared.args | 2 +-
.../qemuxml2argv-disk-drive-shared.xml | 2 +-
tests/qemuxml2argvtest.c | 1 +
5 files changed, 59 insertions(+), 3 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-qcow.xml
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b98ffffae..42d17c1b0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -25,6 +25,7 @@
#include "qemu_domain.h"
#include "qemu_alias.h"
+#include "qemu_block.h"
#include "qemu_cgroup.h"
#include "qemu_command.h"
#include "qemu_process.h"
@@ -3299,6 +3300,29 @@ qemuDomainRedirdevDefValidate(const virDomainRedirdevDef *def)
}
+static int
+qemuDomainDeviceDefValidateDisk(const virDomainDiskDef *disk)
+{
+ if (disk->src->shared && !disk->src->readonly) {
+ if (disk->src->format <= VIR_STORAGE_FILE_AUTO) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("shared access for disk '%s' requires use of "
+ "explicitly specified disk format"), disk->dst);
+ return -1;
+ }
+
+ if (!qemuBlockStorageSourceSupportsConcurrentAccess(disk->src)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("shared access for disk '%s' requires use of "
+ "supported storage format"), disk->dst);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
static int
qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
const virDomainDef *def ATTRIBUTE_UNUSED,
@@ -3308,7 +3332,10 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
int ret = -1;
- if (dev->type == VIR_DOMAIN_DEVICE_NET) {
+ if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+ if (qemuDomainDeviceDefValidateDisk(dev->data.disk) < 0)
+ goto cleanup;
+ } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
const virDomainNetDef *net = dev->data.net;
if (net->guestIP.nroutes || net->guestIP.nips) {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-qcow.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-qcow.xml
new file mode 100644
index 000000000..ca88a944b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-qcow.xml
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <shareable/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args
index 502157bf8..326fde1b3 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args
@@ -19,7 +19,7 @@ server,nowait \
-no-acpi \
-boot c \
-usb \
--drive file=/dev/HostVG/QEMUGuest1,format=qcow2,if=none,id=drive-ide0-0-0,\
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0,\
serial=XYZXYZXYZYXXYZYZYXYZY,cache=none \
-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,media=cdrom,\
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml
index 9f7472378..677c2b0b7 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml
@@ -15,7 +15,7 @@
<devices>
<emulator>/usr/bin/qemu-system-i686</emulator>
<disk type='block' device='disk'>
- <driver name='qemu' type='qcow2'/>
+ <driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<shareable/>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 18f06e5aa..93f892229 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -895,6 +895,7 @@ mymain(void)
QEMU_CAPS_DRIVE_BOOT);
DO_TEST("disk-drive-shared",
QEMU_CAPS_DRIVE_SERIAL);
+ DO_TEST_PARSE_ERROR("disk-drive-shared-qcow", NONE);
DO_TEST("disk-drive-error-policy-stop",
QEMU_CAPS_MONITOR_JSON);
DO_TEST("disk-drive-error-policy-enospace",
@@ -0,0 +1,47 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:03:38 +0200
Subject: [PATCH] qemu: Introduce virQEMUCapsSetHostModel
A simple helper as a complement to virQEMUCapsGetHostModel.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit bffc3b9fe501ff122ad81ddf42ecdb69f70ff70a)
---
src/qemu/qemu_capabilities.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b8e4e47b6..f6020b86d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2419,6 +2419,18 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
}
+static void
+virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
+ virDomainVirtType type,
+ virCPUDefPtr cpu)
+{
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ qemuCaps->kvmCPUModel = cpu;
+ else
+ qemuCaps->tcgCPUModel = cpu;
+}
+
+
bool
virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
@@ -3295,10 +3307,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModel = cpu;
- else
- qemuCaps->tcgCPUModel = cpu;
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu);
cleanup:
virCPUDefFree(hostCPU);
@@ -1,63 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 15 Nov 2017 13:41:01 +0100
Subject: [PATCH] qemu: snapshot: Disallow snapshot of unsupported shared disks
Creating a snapshot would introduce a possibly unsupported member for
sharing into the backing chain. Add a check to prevent that from
happening.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1511480
(cherry picked from commit 9b2fbfa6f6b535b9f41a7503531d43d86d7a8868)
---
src/qemu/qemu_driver.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 57f0c2bf4..91119a494 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13792,6 +13792,24 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn,
}
+static int
+qemuDomainSnapshotPrepareDiskShared(virDomainSnapshotDiskDefPtr snapdisk,
+ virDomainDiskDefPtr domdisk)
+{
+ if (!domdisk->src->shared || domdisk->src->readonly)
+ return 0;
+
+ if (!qemuBlockStorageSourceSupportsConcurrentAccess(snapdisk->src)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("shared access for disk '%s' requires use of "
+ "supported storage format"), domdisk->dst);
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdisk,
virDomainDiskDefPtr domdisk)
@@ -13853,6 +13871,9 @@ qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdi
return -1;
}
+ if (qemuDomainSnapshotPrepareDiskShared(snapdisk, domdisk) < 0)
+ return -1;
+
return 0;
}
@@ -13911,6 +13932,9 @@ qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk
return -1;
}
+ if (qemuDomainSnapshotPrepareDiskShared(snapdisk, domdisk) < 0)
+ return -1;
+
return 0;
}
@@ -1,34 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 15 Nov 2017 14:33:11 +0100
Subject: [PATCH] qemu: Disallow pivot of shared disks to unsupported storage
Pivoting to a unsupported storage type might break the assumption that
shared disks will not corrupt metadata.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1511480
(cherry picked from commit 2b41c86294786c07f53afa633fe3dce703debc3c)
---
src/qemu/qemu_driver.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 91119a494..208ccc9bc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16325,6 +16325,16 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
goto cleanup;
}
+ /* When pivoting to a shareable disk we need to make sure that the disk can
+ * be safely shared, since block copy might have changed the format. */
+ if (disk->src->shared && !disk->src->readonly &&
+ !qemuBlockStorageSourceSupportsConcurrentAccess(disk->mirror)) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("can't pivot a shared disk to a storage volume not "
+ "supporting sharing"));
+ goto cleanup;
+ }
+
/* For active commit, the mirror is part of the already labeled
* chain. For blockcopy, we previously labeled only the top-level
* image; but if the user is reusing an external image that
@@ -0,0 +1,70 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:40:31 +0200
Subject: [PATCH] qemu: Move qemuCaps CPU data copying into a separate function
This introduces virQEMUCapsHostCPUDataCopy which will later be
refactored a bit and called twice from virQEMUCapsNewCopy.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 8be4346ca5ae4b568b3e8ce3de9cf46f2e94b416)
---
src/qemu/qemu_capabilities.c | 39 +++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f6020b86d..d17e0e8b8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2082,6 +2082,30 @@ virQEMUCapsNew(void)
}
+static int
+virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
+ virQEMUCapsPtr src)
+{
+ if (src->kvmCPUModel &&
+ !(dst->kvmCPUModel = virCPUDefCopy(src->kvmCPUModel)))
+ return -1;
+
+ if (src->tcgCPUModel &&
+ !(dst->tcgCPUModel = virCPUDefCopy(src->tcgCPUModel)))
+ return -1;
+
+ if (src->kvmCPUModelInfo &&
+ !(dst->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->kvmCPUModelInfo)))
+ return -1;
+
+ if (src->tcgCPUModelInfo &&
+ !(dst->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->tcgCPUModelInfo)))
+ return -1;
+
+ return 0;
+}
+
+
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
{
virQEMUCapsPtr ret = virQEMUCapsNew();
@@ -2119,20 +2143,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto error;
}
- if (qemuCaps->kvmCPUModel &&
- !(ret->kvmCPUModel = virCPUDefCopy(qemuCaps->kvmCPUModel)))
- goto error;
-
- if (qemuCaps->tcgCPUModel &&
- !(ret->tcgCPUModel = virCPUDefCopy(qemuCaps->tcgCPUModel)))
- goto error;
-
- if (qemuCaps->kvmCPUModelInfo &&
- !(ret->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(qemuCaps->kvmCPUModelInfo)))
- goto error;
-
- if (qemuCaps->tcgCPUModelInfo &&
- !(ret->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(qemuCaps->tcgCPUModelInfo)))
+ if (virQEMUCapsHostCPUDataCopy(ret, qemuCaps) < 0)
goto error;
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
@@ -0,0 +1,67 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:43:59 +0200
Subject: [PATCH] qemu: Introduce virQEMUCapsHostCPUDataClear
To keep freeing of host CPU data in one place.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit b0605e848724c5dc478382398b734398abff674c)
---
src/qemu/qemu_capabilities.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d17e0e8b8..2da53a60b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2106,6 +2106,21 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
}
+static void
+virQEMUCapsHostCPUDataClear(virQEMUCapsPtr qemuCaps)
+{
+ qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
+ qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
+ qemuCaps->kvmCPUModelInfo = NULL;
+ qemuCaps->tcgCPUModelInfo = NULL;
+
+ virCPUDefFree(qemuCaps->kvmCPUModel);
+ virCPUDefFree(qemuCaps->tcgCPUModel);
+ qemuCaps->kvmCPUModel = NULL;
+ qemuCaps->tcgCPUModel = NULL;
+}
+
+
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
{
virQEMUCapsPtr ret = virQEMUCapsNew();
@@ -2192,10 +2207,7 @@ void virQEMUCapsDispose(void *obj)
VIR_FREE(qemuCaps->gicCapabilities);
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
+ virQEMUCapsHostCPUDataClear(qemuCaps);
}
void
@@ -4068,15 +4080,7 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
VIR_FREE(qemuCaps->gicCapabilities);
qemuCaps->ngicCapabilities = 0;
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- qemuCaps->kvmCPUModelInfo = NULL;
- qemuCaps->tcgCPUModelInfo = NULL;
-
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
- qemuCaps->kvmCPUModel = NULL;
- qemuCaps->tcgCPUModel = NULL;
+ virQEMUCapsHostCPUDataClear(qemuCaps);
}
@@ -1,126 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 15 Nov 2017 15:02:58 +0100
Subject: [PATCH] qemu: caps: Add capability for 'share-rw' disk option
'share-rw' for the disk device configures qemu to allow concurrent
access to the backing storage.
The capability is checked in various supported disk frontend buses since
it does not make sense to partially backport it.
(cherry picked from commit 860a3c4bea1d24773d8a495f213d5de3ac48a462)
---
src/qemu/qemu_capabilities.c | 14 ++++++++++++++
src/qemu/qemu_capabilities.h | 10 ++++++++++
tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 1 +
tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 +
tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 +
5 files changed, 27 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index e7ea6f47c..2de84715e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -439,6 +439,16 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"virtio-net.tx_queue_size",
"chardev-reconnect",
"virtio-gpu.max_outputs",
+
+ /* 270 */
+ "vxhs",
+ "virtio-blk.num-queues",
+ "machine.pseries.resize-hpt",
+ "vmcoreinfo",
+ "spapr-vty",
+
+ /* 275 */
+ "disk-share-rw",
);
@@ -1702,6 +1712,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = {
{ "event_idx", QEMU_CAPS_VIRTIO_BLK_EVENT_IDX },
{ "scsi", QEMU_CAPS_VIRTIO_BLK_SCSI },
{ "logical_block_size", QEMU_CAPS_BLOCKIO },
+ { "share-rw", QEMU_CAPS_DISK_SHARE_RW },
};
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioNet[] = {
@@ -1732,10 +1743,12 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVfioPCI[] = {
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSCSIDisk[] = {
{ "channel", QEMU_CAPS_SCSI_DISK_CHANNEL },
{ "wwn", QEMU_CAPS_SCSI_DISK_WWN },
+ { "share-rw", QEMU_CAPS_DISK_SHARE_RW },
};
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsIDEDrive[] = {
{ "wwn", QEMU_CAPS_IDE_DRIVE_WWN },
+ { "share-rw", QEMU_CAPS_DISK_SHARE_RW },
};
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsPiix4PM[] = {
@@ -1766,6 +1779,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsQ35PCIHost[] = {
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBStorage[] = {
{ "removable", QEMU_CAPS_USB_STORAGE_REMOVABLE },
+ { "share-rw", QEMU_CAPS_DISK_SHARE_RW },
};
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsKVMPit[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index f32687d4a..9c92d6b46 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -426,6 +426,16 @@ typedef enum {
QEMU_CAPS_CHARDEV_RECONNECT, /* -chardev reconnect */
QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS, /* -device virtio-(vga|gpu-*),max-outputs= */
+ /* 270 */
+ QEMU_CAPS_VXHS, /* -drive file.driver=vxhs via query-qmp-schema */
+ QEMU_CAPS_VIRTIO_BLK_NUM_QUEUES, /* virtio-blk-*.num-queues */
+ QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT, /* -machine pseries,resize-hpt */
+ QEMU_CAPS_DEVICE_VMCOREINFO, /* -device vmcoreinfo */
+ QEMU_CAPS_DEVICE_SPAPR_VTY, /* -device spapr-vty */
+
+ /* 275 */
+ QEMU_CAPS_DISK_SHARE_RW, /* share-rw=on for concurrent disk access */
+
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml
index a373a6db6..9551907c6 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml
@@ -172,6 +172,7 @@
<flag name='vnc-multi-servers'/>
<flag name='chardev-reconnect'/>
<flag name='virtio-gpu.max_outputs'/>
+ <flag name='disk-share-rw'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
<package> (v2.9.0)</package>
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
index e80782cfb..0a6fbd077 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
@@ -137,6 +137,7 @@
<flag name='vnc-multi-servers'/>
<flag name='chardev-reconnect'/>
<flag name='virtio-gpu.max_outputs'/>
+ <flag name='disk-share-rw'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
<package></package>
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
index 3641d0332..1294ebdb3 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
@@ -220,6 +220,7 @@
<flag name='vnc-multi-servers'/>
<flag name='chardev-reconnect'/>
<flag name='virtio-gpu.max_outputs'/>
+ <flag name='disk-share-rw'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
<package> (v2.9.0)</package>
@@ -0,0 +1,342 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 18:15:26 +0200
Subject: [PATCH] qemu: Move qemuCaps host CPU data in a struct
We need to store several CPU related data structure for both KVM and
TCG. So instead of keeping two different copies of everything let's
make a virQEMUCapsHostCPUData struct and use it twice.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit b0a84ffb7f38f990120c231cfb74956a0ed10d95)
---
src/qemu/qemu_capabilities.c | 168 +++++++++++++++++++++----------------------
1 file changed, 82 insertions(+), 86 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2da53a60b..bbb234538 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -373,6 +373,19 @@ struct virQEMUCapsMachineType {
unsigned int maxCpus;
bool hotplugCpus;
};
+
+typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData;
+typedef virQEMUCapsHostCPUData *virQEMUCapsHostCPUDataPtr;
+struct _virQEMUCapsHostCPUData {
+ /* Only the "info" part is stored in the capabilities cache, the rest is
+ * re-computed from other fields and external data sources everytime we
+ * probe QEMU or load the cache.
+ */
+ qemuMonitorCPUModelInfoPtr info;
+ /* Host CPU definition reported in domain capabilities. */
+ virCPUDefPtr reported;
+};
+
/*
* Update the XML parser/formatter when adding more
* information to this struct so that it gets cached
@@ -407,15 +420,8 @@ struct _virQEMUCaps {
size_t ngicCapabilities;
virGICCapability *gicCapabilities;
- qemuMonitorCPUModelInfoPtr kvmCPUModelInfo;
- qemuMonitorCPUModelInfoPtr tcgCPUModelInfo;
-
- /* Anything below is not stored in the cache since the values are
- * re-computed from the other fields or external data sources every
- * time we probe QEMU or load the results from the cache.
- */
- virCPUDefPtr kvmCPUModel;
- virCPUDefPtr tcgCPUModel;
+ virQEMUCapsHostCPUData kvmCPU;
+ virQEMUCapsHostCPUData tcgCPU;
};
struct virQEMUCapsSearchData {
@@ -2083,23 +2089,15 @@ virQEMUCapsNew(void)
static int
-virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
- virQEMUCapsPtr src)
+virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
+ virQEMUCapsHostCPUDataPtr src)
{
- if (src->kvmCPUModel &&
- !(dst->kvmCPUModel = virCPUDefCopy(src->kvmCPUModel)))
+ if (src->info &&
+ !(dst->info = qemuMonitorCPUModelInfoCopy(src->info)))
return -1;
- if (src->tcgCPUModel &&
- !(dst->tcgCPUModel = virCPUDefCopy(src->tcgCPUModel)))
- return -1;
-
- if (src->kvmCPUModelInfo &&
- !(dst->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->kvmCPUModelInfo)))
- return -1;
-
- if (src->tcgCPUModelInfo &&
- !(dst->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->tcgCPUModelInfo)))
+ if (src->reported &&
+ !(dst->reported = virCPUDefCopy(src->reported)))
return -1;
return 0;
@@ -2107,17 +2105,12 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
static void
-virQEMUCapsHostCPUDataClear(virQEMUCapsPtr qemuCaps)
+virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
{
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- qemuCaps->kvmCPUModelInfo = NULL;
- qemuCaps->tcgCPUModelInfo = NULL;
-
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
- qemuCaps->kvmCPUModel = NULL;
- qemuCaps->tcgCPUModel = NULL;
+ qemuMonitorCPUModelInfoFree(cpuData->info);
+ virCPUDefFree(cpuData->reported);
+
+ memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2158,7 +2151,8 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto error;
}
- if (virQEMUCapsHostCPUDataCopy(ret, qemuCaps) < 0)
+ if (virQEMUCapsHostCPUDataCopy(&ret->kvmCPU, &qemuCaps->kvmCPU) < 0 ||
+ virQEMUCapsHostCPUDataCopy(&ret->tcgCPU, &qemuCaps->tcgCPU) < 0)
goto error;
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
@@ -2207,7 +2201,8 @@ void virQEMUCapsDispose(void *obj)
VIR_FREE(qemuCaps->gicCapabilities);
- virQEMUCapsHostCPUDataClear(qemuCaps);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
}
void
@@ -2431,14 +2426,24 @@ virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
}
+static virQEMUCapsHostCPUDataPtr
+virQEMUCapsGetHostCPUData(virQEMUCapsPtr qemuCaps,
+ virDomainVirtType type)
+{
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ return &qemuCaps->kvmCPU;
+ else
+ return &qemuCaps->tcgCPU;
+}
+
+
virCPUDefPtr
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- return qemuCaps->kvmCPUModel;
- else
- return qemuCaps->tcgCPUModel;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ return cpuData->reported;
}
@@ -2447,10 +2452,9 @@ virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr cpu)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModel = cpu;
- else
- qemuCaps->tcgCPUModel = cpu;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ cpuData->reported = cpu;
}
@@ -2841,24 +2845,28 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon,
bool tcg)
{
- qemuMonitorCPUModelInfoPtr *modelInfo;
+ qemuMonitorCPUModelInfoPtr modelInfo = NULL;
qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
virHashTablePtr hash = NULL;
const char *model;
qemuMonitorCPUModelExpansionType type;
+ virDomainVirtType virtType;
+ virQEMUCapsHostCPUDataPtr cpuData;
int ret = -1;
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
return 0;
if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
- modelInfo = &qemuCaps->tcgCPUModelInfo;
+ virtType = VIR_DOMAIN_VIRT_QEMU;
model = "max";
} else {
- modelInfo = &qemuCaps->kvmCPUModelInfo;
+ virtType = VIR_DOMAIN_VIRT_KVM;
model = "host";
}
+ cpuData = virQEMUCapsGetHostCPUData(qemuCaps, virtType);
+
/* Some x86_64 features defined in cpu_map.xml use spelling which differ
* from the one preferred by QEMU. Static expansion would give us only the
* preferred spelling, thus we need to do a full expansion on the result of
@@ -2869,14 +2877,14 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
else
type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
- if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, modelInfo) < 0)
- return -1;
+ if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, &modelInfo) < 0)
+ goto cleanup;
/* Try to check migratability of each feature. */
- if (*modelInfo &&
+ if (modelInfo &&
qemuMonitorGetCPUModelExpansion(mon, type, model, false,
&nonMigratable) < 0)
- goto error;
+ goto cleanup;
if (nonMigratable) {
qemuMonitorCPUPropertyPtr prop;
@@ -2884,12 +2892,12 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
size_t i;
if (!(hash = virHashCreate(0, NULL)))
- goto error;
+ goto cleanup;
- for (i = 0; i < (*modelInfo)->nprops; i++) {
- prop = (*modelInfo)->props + i;
+ for (i = 0; i < modelInfo->nprops; i++) {
+ prop = modelInfo->props + i;
if (virHashAddEntry(hash, prop->name, prop) < 0)
- goto error;
+ goto cleanup;
}
for (i = 0; i < nonMigratable->nprops; i++) {
@@ -2907,21 +2915,18 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
}
}
- (*modelInfo)->migratability = true;
+ modelInfo->migratability = true;
}
+ VIR_STEAL_PTR(cpuData->info, modelInfo);
ret = 0;
cleanup:
virHashFree(hash);
qemuMonitorCPUModelInfoFree(nonMigratable);
+ qemuMonitorCPUModelInfoFree(modelInfo);
return ret;
-
- error:
- qemuMonitorCPUModelInfoFree(*modelInfo);
- *modelInfo = NULL;
- goto cleanup;
}
struct tpmTypeToCaps {
@@ -3274,21 +3279,19 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virCPUDefPtr cpu,
bool migratable)
{
- qemuMonitorCPUModelInfoPtr model;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
int ret = 1;
- if (type == VIR_DOMAIN_VIRT_KVM)
- model = qemuCaps->kvmCPUModelInfo;
- else
- model = qemuCaps->tcgCPUModelInfo;
-
- if (migratable && model && !model->migratability)
+ if (migratable && cpuData->info && !cpuData->info->migratability)
return 1;
- if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu, migratable);
- else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu, migratable);
+ if (ARCH_IS_S390(qemuCaps->arch)) {
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, cpuData->info,
+ cpu, migratable);
+ } else if (ARCH_IS_X86(qemuCaps->arch)) {
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpuData->info,
+ cpu, migratable);
+ }
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -3348,10 +3351,9 @@ virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
qemuMonitorCPUModelInfoPtr modelInfo)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModelInfo = modelInfo;
- else
- qemuCaps->tcgCPUModelInfo = modelInfo;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ cpuData->info = modelInfo;
}
@@ -3810,18 +3812,11 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
virBufferPtr buf,
virDomainVirtType type)
{
- qemuMonitorCPUModelInfoPtr model;
- const char *typeStr;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+ qemuMonitorCPUModelInfoPtr model = cpuData->info;
+ const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg";
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM) {
- typeStr = "kvm";
- model = qemuCaps->kvmCPUModelInfo;
- } else {
- typeStr = "tcg";
- model = qemuCaps->tcgCPUModelInfo;
- }
-
if (!model)
return;
@@ -4080,7 +4075,8 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
VIR_FREE(qemuCaps->gicCapabilities);
qemuCaps->ngicCapabilities = 0;
- virQEMUCapsHostCPUDataClear(qemuCaps);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
}
@@ -1,133 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 15 Nov 2017 15:21:14 +0100
Subject: [PATCH] qemu: command: Mark <shared/> disks as such in qemu
Qemu has now an internal mechanism for locking images to fix specific
cases of disk corruption. This requires libvirt to mark the image as
shared so that qemu lifts certain restrictions.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1378242
(cherry picked from commit 28907b0043fbf71085a798372ab9c816ba043b93)
---
src/qemu/qemu_command.c | 4 +++
.../qemuxml2argv-disk-drive-shared-locking.args | 32 +++++++++++++++++
.../qemuxml2argv-disk-drive-shared-locking.xml | 42 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 ++
4 files changed, 80 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-locking.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-locking.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ae78cd17e..883525752 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2075,6 +2075,10 @@ qemuBuildDriveDevStr(const virDomainDef *def,
goto error;
}
+ if (disk->src->shared &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_SHARE_RW))
+ virBufferAddLit(&opt, ",share-rw=on");
+
if (!(drivealias = qemuAliasFromDisk(disk)))
goto error;
virBufferAsprintf(&opt, ",drive=%s,id=%s", drivealias, disk->info.alias);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-locking.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-locking.args
new file mode 100644
index 000000000..cdf17f26d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-locking.args
@@ -0,0 +1,32 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline \
+-no-acpi \
+-boot c \
+-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 \
+-usb \
+-drive file=/dev/ide,format=raw,if=none,id=drive-ide0-0-0,cache=none \
+-device ide-drive,bus=ide.0,unit=0,share-rw=on,drive=drive-ide0-0-0,\
+id=ide0-0-0 \
+-drive file=/dev/scsi,format=raw,if=none,id=drive-scsi0-0-0-0,cache=none \
+-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,share-rw=on,\
+drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \
+-drive file=/dev/virtio,format=raw,if=none,id=drive-virtio-disk0,cache=none \
+-device virtio-blk-pci,bus=pci.0,addr=0x4,share-rw=on,drive=drive-virtio-disk0,\
+id=virtio-disk0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-locking.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-locking.xml
new file mode 100644
index 000000000..dd48857a3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared-locking.xml
@@ -0,0 +1,42 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/ide'/>
+ <target dev='hda' bus='ide'/>
+ <shareable/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/scsi'/>
+ <target dev='sda' bus='scsi'/>
+ <shareable/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/virtio'/>
+ <target dev='vda' bus='virtio'/>
+ <shareable/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='scsi' index='0' model='virtio-scsi'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 93f892229..9585fdb70 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -896,6 +896,8 @@ mymain(void)
DO_TEST("disk-drive-shared",
QEMU_CAPS_DRIVE_SERIAL);
DO_TEST_PARSE_ERROR("disk-drive-shared-qcow", NONE);
+ DO_TEST("disk-drive-shared-locking",
+ QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_DISK_SHARE_RW);
DO_TEST("disk-drive-error-policy-stop",
QEMU_CAPS_MONITOR_JSON);
DO_TEST("disk-drive-error-policy-enospace",
@@ -0,0 +1,119 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 11:14:30 +0200
Subject: [PATCH] qemu: Prepare qemuCaps for multiple host CPU defs
Soon we will need to store multiple host CPU definitions in
virQEMUCapsHostCPUData and qemuCaps users will want to request the one
they need. This patch introduces virQEMUCapsHostCPUType enum which will
be used for specifying the requested CPU definition.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 1fe517c68df92eb7f379fa87cb0d29d566aad6f4)
---
src/qemu/qemu_capabilities.c | 16 ++++++++++++----
src/qemu/qemu_capabilities.h | 10 +++++++++-
src/qemu/qemu_command.c | 3 ++-
src/qemu/qemu_process.c | 6 ++++--
4 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index bbb234538..a6324a398 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2439,11 +2439,17 @@ virQEMUCapsGetHostCPUData(virQEMUCapsPtr qemuCaps,
virCPUDefPtr
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type)
+ virDomainVirtType type,
+ virQEMUCapsHostCPUType cpuType)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
- return cpuData->reported;
+ switch (cpuType) {
+ case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
+ return cpuData->reported;
+ }
+
+ return NULL;
}
@@ -2472,7 +2478,8 @@ virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch);
case VIR_CPU_MODE_HOST_MODEL:
- return !!virQEMUCapsGetHostModel(qemuCaps, type);
+ return !!virQEMUCapsGetHostModel(qemuCaps, type,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
case VIR_CPU_MODE_CUSTOM:
if (type == VIR_DOMAIN_VIRT_KVM)
@@ -5456,7 +5463,8 @@ virQEMUCapsFillDomainCPUCaps(virCapsPtr caps,
if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
VIR_CPU_MODE_HOST_MODEL)) {
- virCPUDefPtr cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype);
+ virCPUDefPtr cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
domCaps->cpu.hostModel = virCPUDefCopy(cpu);
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d44682f2a..88e27855b 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -449,8 +449,16 @@ int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
char ***names,
size_t *count);
+
+typedef enum {
+ /* Host CPU definition reported in domain capabilities. */
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED,
+} virQEMUCapsHostCPUType;
+
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type);
+ virDomainVirtType type,
+ virQEMUCapsHostCPUType cpuType);
+
bool virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
virDomainVirtType type,
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3abfe7b55..311edd13e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6879,7 +6879,8 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
if (def->cpu->mode == VIR_CPU_MODE_CUSTOM)
cpuDef = def->cpu;
else if (def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
- cpuDef = virQEMUCapsGetHostModel(qemuCaps, def->virtType);
+ cpuDef = virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
if (cpuDef) {
int svm = virCPUCheckFeature(def->os.arch, cpuDef, "svm");
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 26a668d27..07a88a3a7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5299,12 +5299,14 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
virCPUCompare(caps->host.arch,
- virQEMUCapsGetHostModel(qemuCaps, def->virtType),
+ virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED),
def->cpu, true) < 0)
return -1;
if (virCPUUpdate(def->os.arch, def->cpu,
- virQEMUCapsGetHostModel(qemuCaps, def->virtType)) < 0)
+ virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED)) < 0)
goto cleanup;
if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
@@ -0,0 +1,210 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 15:31:17 +0200
Subject: [PATCH] qemu: Pass migratable host CPU model to virCPUUpdate
We already know from QEMU which CPU features will block migration. Let's
use this information to make a migratable copy of the host CPU model and
use it for updating guest CPU specification. This will allow us to drop
feature filtering from virCPUUpdate where it was just a hack.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 56bd7edcb5dc878beffb80d4e6a9cfb812378ded)
---
src/qemu/qemu_capabilities.c | 57 +++++++++++++++++++++++++++++++++++++-------
src/qemu/qemu_capabilities.h | 2 ++
src/qemu/qemu_process.c | 2 +-
tests/cputest.c | 7 +++++-
4 files changed, 57 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a6324a398..7fc577546 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -384,6 +384,8 @@ struct _virQEMUCapsHostCPUData {
qemuMonitorCPUModelInfoPtr info;
/* Host CPU definition reported in domain capabilities. */
virCPUDefPtr reported;
+ /* Migratable host CPU definition used for updating guest CPU. */
+ virCPUDefPtr migratable;
};
/*
@@ -2100,6 +2102,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
!(dst->reported = virCPUDefCopy(src->reported)))
return -1;
+ if (src->migratable &&
+ !(dst->migratable = virCPUDefCopy(src->migratable)))
+ return -1;
+
return 0;
}
@@ -2109,6 +2115,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
{
qemuMonitorCPUModelInfoFree(cpuData->info);
virCPUDefFree(cpuData->reported);
+ virCPUDefFree(cpuData->migratable);
memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2447,6 +2454,9 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
switch (cpuType) {
case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
return cpuData->reported;
+
+ case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
+ return cpuData->migratable;
}
return NULL;
@@ -2456,11 +2466,13 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
static void
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu)
+ virCPUDefPtr reported,
+ virCPUDefPtr migratable)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
- cpuData->reported = cpu;
+ cpuData->reported = reported;
+ cpuData->migratable = migratable;
}
@@ -3307,26 +3319,39 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
}
+static virCPUDefPtr
+virQEMUCapsNewHostCPUModel(void)
+{
+ virCPUDefPtr cpu;
+
+ if (VIR_ALLOC(cpu) < 0)
+ return NULL;
+
+ cpu->type = VIR_CPU_TYPE_GUEST;
+ cpu->mode = VIR_CPU_MODE_CUSTOM;
+ cpu->match = VIR_CPU_MATCH_EXACT;
+ cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
+
+ return cpu;
+}
+
+
void
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
virDomainVirtType type)
{
virCPUDefPtr cpu = NULL;
+ virCPUDefPtr migCPU = NULL;
virCPUDefPtr hostCPU = NULL;
int rc;
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
return;
- if (VIR_ALLOC(cpu) < 0)
+ if (!(cpu = virQEMUCapsNewHostCPUModel()))
goto error;
- cpu->type = VIR_CPU_TYPE_GUEST;
- cpu->mode = VIR_CPU_MODE_CUSTOM;
- cpu->match = VIR_CPU_MATCH_EXACT;
- cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
-
if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
goto error;
} else if (rc == 1) {
@@ -3340,7 +3365,20 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- virQEMUCapsSetHostModel(qemuCaps, type, cpu);
+ if (!(migCPU = virQEMUCapsNewHostCPUModel()))
+ goto error;
+
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
+ goto error;
+ } else if (rc == 1) {
+ VIR_DEBUG("CPU migratability not provided by QEMU");
+
+ virCPUDefFree(migCPU);
+ if (!(migCPU = virCPUCopyMigratable(qemuCaps->arch, cpu)))
+ goto error;
+ }
+
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU);
cleanup:
virCPUDefFree(hostCPU);
@@ -3348,6 +3386,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
error:
virCPUDefFree(cpu);
+ virCPUDefFree(migCPU);
virResetLastError();
goto cleanup;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 88e27855b..31818c940 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -453,6 +453,8 @@ int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
typedef enum {
/* Host CPU definition reported in domain capabilities. */
VIR_QEMU_CAPS_HOST_CPU_REPORTED,
+ /* Migratable host CPU definition used for updating guest CPU. */
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE,
} virQEMUCapsHostCPUType;
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 07a88a3a7..e67736638 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5306,7 +5306,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED)) < 0)
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
goto cleanup;
if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
diff --git a/tests/cputest.c b/tests/cputest.c
index 8c07cf4f6..efa891dc1 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -393,6 +393,7 @@ cpuTestUpdate(const void *arg)
const struct data *data = arg;
int ret = -1;
virCPUDefPtr host = NULL;
+ virCPUDefPtr migHost = NULL;
virCPUDefPtr cpu = NULL;
char *result = NULL;
@@ -400,7 +401,10 @@ cpuTestUpdate(const void *arg)
!(cpu = cpuTestLoadXML(data->arch, data->name)))
goto cleanup;
- if (virCPUUpdate(host->arch, cpu, host) < 0)
+ if (!(migHost = virCPUCopyMigratable(data->arch, host)))
+ goto cleanup;
+
+ if (virCPUUpdate(host->arch, cpu, migHost) < 0)
goto cleanup;
if (virAsprintf(&result, "%s+%s", data->host, data->name) < 0)
@@ -411,6 +415,7 @@ cpuTestUpdate(const void *arg)
cleanup:
virCPUDefFree(host);
virCPUDefFree(cpu);
+ virCPUDefFree(migHost);
VIR_FREE(result);
return ret;
}
@@ -0,0 +1,49 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 15:00:21 +0200
Subject: [PATCH] cpu: Drop feature filtering from virCPUUpdate
Because of the changes done in the previous commit, @host is already a
migratable CPU and there's no need to do any additional filtering.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 232d87c7dd081d126a079fb45178e0be096cc680)
---
src/cpu/cpu_x86.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index a771b251e..53359ff9b 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2549,8 +2549,7 @@ x86Baseline(virCPUDefPtr *cpus,
static int
x86UpdateHostModel(virCPUDefPtr guest,
- const virCPUDef *host,
- virCPUx86MapPtr map)
+ const virCPUDef *host)
{
virCPUDefPtr updated = NULL;
size_t i;
@@ -2559,11 +2558,9 @@ x86UpdateHostModel(virCPUDefPtr guest,
if (!(updated = virCPUDefCopyWithoutModel(host)))
goto cleanup;
- /* Remove non-migratable features by default */
updated->type = VIR_CPU_TYPE_GUEST;
updated->mode = VIR_CPU_MODE_CUSTOM;
- if (virCPUDefCopyModelFilter(updated, host, true,
- x86FeatureIsMigratable, map) < 0)
+ if (virCPUDefCopyModel(updated, host, true) < 0)
goto cleanup;
if (guest->vendor_id) {
@@ -2627,7 +2624,7 @@ virCPUx86Update(virCPUDefPtr guest,
if (guest->mode == VIR_CPU_MODE_HOST_MODEL ||
guest->match == VIR_CPU_MATCH_MINIMUM)
- ret = x86UpdateHostModel(guest, host, map);
+ ret = x86UpdateHostModel(guest, host);
else
ret = 0;
@@ -0,0 +1,74 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 20:45:07 +0200
Subject: [PATCH] cpu: Introduce virCPUGetHostIsSupported
Sometimes we want to call virCPUGetHost only when it is implemented for
a given architecture to avoid logging expected and possibly misleading
errors. The new virCPUGetHostIsSupported API may be used to guard such
calls to virCPUGetHost.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit bf1a881715c905c67f7d38dcd5bd6c2afbff1f9b)
---
src/cpu/cpu.c | 20 ++++++++++++++++++++
src/cpu/cpu.h | 3 +++
src/libvirt_private.syms | 1 +
3 files changed, 24 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 8a407ac18..702b14dbb 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -357,6 +357,26 @@ virCPUDataFree(virCPUDataPtr data)
}
+/**
+ * virCPUGetHostIsSupported:
+ *
+ * @arch: CPU architecture
+ *
+ * Check whether virCPUGetHost is supported for @arch.
+ *
+ * Returns true if virCPUGetHost is supported, false otherwise.
+ */
+bool
+virCPUGetHostIsSupported(virArch arch)
+{
+ struct cpuArchDriver *driver;
+
+ VIR_DEBUG("arch=%s", virArchToString(arch));
+
+ return (driver = cpuGetSubDriver(arch)) && driver->getHost;
+}
+
+
/**
* virCPUGetHost:
*
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 352445c40..c6ca111e9 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -183,6 +183,9 @@ virCPUDataNew(virArch arch);
void
virCPUDataFree(virCPUDataPtr data);
+bool
+virCPUGetHostIsSupported(virArch arch);
+
virCPUDefPtr
virCPUGetHost(virArch arch,
virCPUType type,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dc6db3b28..2d8a9ddec 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1024,6 +1024,7 @@ virCPUDataNew;
virCPUDataParse;
virCPUExpandFeatures;
virCPUGetHost;
+virCPUGetHostIsSupported;
virCPUGetModels;
virCPUProbeHost;
virCPUTranslate;
@@ -0,0 +1,164 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 20:46:05 +0200
Subject: [PATCH] qemu: Use more data for comparing CPUs
With QEMU older than 2.9.0 libvirt uses CPUID instruction to determine
what CPU features are supported on the host. This was later used when
checking compatibility of guest CPUs. Since QEMU 2.9.0 we ask QEMU for
the host CPU data. But the two methods we use usually provide disjoint
sets of CPU features because QEMU/KVM does not support all features
provided by the host CPU and on the other hand it can enable some
feature even if the host CPU does not support them.
So if there is a domain which requires a CPU features disabled by
QEMU/KVM, libvirt will refuse to start it with QEMU > 2.9.0 as its guest
CPU is incompatible with the host CPU data we got from QEMU. But such
domain would happily start on older QEMU (of course, the features would
be missing the guest CPU). To fix this regression, we need to combine
both CPU feature sets when checking guest CPU compatibility.
https://bugzilla.redhat.com/show_bug.cgi?id=1439933
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 5b4a6adb5ca24a6cb91cdc55c31506fb278d3a91)
---
src/qemu/qemu_capabilities.c | 35 +++++++++++++++++++++++++++++++++--
src/qemu/qemu_capabilities.h | 4 ++++
src/qemu/qemu_process.c | 2 +-
3 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7fc577546..01bd4750c 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -386,6 +386,10 @@ struct _virQEMUCapsHostCPUData {
virCPUDefPtr reported;
/* Migratable host CPU definition used for updating guest CPU. */
virCPUDefPtr migratable;
+ /* CPU definition with features detected by libvirt using virCPUGetHost
+ * combined with features reported by QEMU. This is used for backward
+ * compatible comparison between a guest CPU and a host CPU. */
+ virCPUDefPtr full;
};
/*
@@ -2106,6 +2110,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
!(dst->migratable = virCPUDefCopy(src->migratable)))
return -1;
+ if (src->full &&
+ !(dst->full = virCPUDefCopy(src->full)))
+ return -1;
+
return 0;
}
@@ -2116,6 +2124,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
qemuMonitorCPUModelInfoFree(cpuData->info);
virCPUDefFree(cpuData->reported);
virCPUDefFree(cpuData->migratable);
+ virCPUDefFree(cpuData->full);
memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2457,6 +2466,11 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
return cpuData->migratable;
+
+ case VIR_QEMU_CAPS_HOST_CPU_FULL:
+ /* 'full' is non-NULL only if we have data from both QEMU and
+ * virCPUGetHost */
+ return cpuData->full ? cpuData->full : cpuData->reported;
}
return NULL;
@@ -2467,12 +2481,14 @@ static void
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr reported,
- virCPUDefPtr migratable)
+ virCPUDefPtr migratable,
+ virCPUDefPtr full)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
cpuData->reported = reported;
cpuData->migratable = migratable;
+ cpuData->full = full;
}
@@ -3344,6 +3360,8 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virCPUDefPtr cpu = NULL;
virCPUDefPtr migCPU = NULL;
virCPUDefPtr hostCPU = NULL;
+ virCPUDefPtr fullCPU = NULL;
+ size_t i;
int rc;
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
@@ -3363,6 +3381,18 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virQEMUCapsCPUFilterFeatures,
qemuCaps) < 0)
goto error;
+ } else if (type == VIR_DOMAIN_VIRT_KVM &&
+ virCPUGetHostIsSupported(qemuCaps->arch)) {
+ if (!(fullCPU = virCPUGetHost(qemuCaps->arch, VIR_CPU_TYPE_GUEST,
+ NULL, NULL, 0)))
+ goto error;
+
+ for (i = 0; i < cpu->nfeatures; i++) {
+ if (cpu->features[i].policy == VIR_CPU_FEATURE_REQUIRE &&
+ virCPUDefUpdateFeature(fullCPU, cpu->features[i].name,
+ VIR_CPU_FEATURE_REQUIRE) < 0)
+ goto error;
+ }
}
if (!(migCPU = virQEMUCapsNewHostCPUModel()))
@@ -3378,7 +3408,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU);
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU, fullCPU);
cleanup:
virCPUDefFree(hostCPU);
@@ -3387,6 +3417,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
error:
virCPUDefFree(cpu);
virCPUDefFree(migCPU);
+ virCPUDefFree(fullCPU);
virResetLastError();
goto cleanup;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 31818c940..4e9561c0a 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -455,6 +455,10 @@ typedef enum {
VIR_QEMU_CAPS_HOST_CPU_REPORTED,
/* Migratable host CPU definition used for updating guest CPU. */
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE,
+ /* CPU definition with features detected by libvirt using virCPUGetHost
+ * combined with features reported by QEMU. This is used for backward
+ * compatible comparison between a guest CPU and a host CPU. */
+ VIR_QEMU_CAPS_HOST_CPU_FULL,
} virQEMUCapsHostCPUType;
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e67736638..992a7174b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5300,7 +5300,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
virCPUCompare(caps->host.arch,
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED),
+ VIR_QEMU_CAPS_HOST_CPU_FULL),
def->cpu, true) < 0)
return -1;
@@ -0,0 +1,123 @@
From: Neal Gompa <ngompa13@gmail.com>
Date: Mon, 17 Jul 2017 11:32:46 -0400
Subject: [PATCH] spec: Add support for building the zfs storage driver
Where it can be supported in Fedora, the driver is built and made
available as a subpackage.
Signed-off-by: Neal Gompa <ngompa13@gmail.com>
(cherry picked from commit 9af764e86aef7dfb0191a9561bf1d1abf941da05)
---
libvirt.spec.in | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 079b5f386..46a3e97d1 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -71,6 +71,13 @@
%define with_storage_gluster 0%{!?_without_storage_gluster:1}
%define with_numactl 0%{!?_without_numactl:1}
+# F25+ has zfs-fuse
+%if 0%{?fedora} >= 25
+ %define with_storage_zfs 0%{!?_without_storage_zfs:1}
+%else
+ %define with_storage_zfs 0
+%endif
+
# A few optional bits off by default, we enable later
%define with_fuse 0%{!?_without_fuse:0}
%define with_cgconfig 0%{!?_without_cgconfig:0}
@@ -115,6 +122,12 @@
%endif
%endif
+# zfs-fuse is not available on some architectures
+%ifarch s390 s390x aarch64
+ %define with_storage_zfs 0
+%endif
+
+
# RHEL doesn't ship OpenVZ, VBox, UML, PowerHypervisor,
# VMware, libxenserver (xenapi), libxenlight (Xen 4.1 and newer),
# or HyperV.
@@ -373,6 +386,12 @@ BuildRequires: glusterfs-devel >= 3.4.1
%if %{with_storage_sheepdog}
BuildRequires: sheepdog
%endif
+%if %{with_storage_zfs}
+# Support any conforming implementation of zfs. On stock Fedora
+# this is zfs-fuse, but could be zfsonlinux upstream RPMs
+BuildRequires: /sbin/zfs
+BuildRequires: /sbin/zpool
+%endif
%if %{with_numactl}
# For QEMU/LXC numa info
BuildRequires: numactl-devel
@@ -705,6 +724,21 @@ sheepdog volumes using.
%endif
+%if %{with_storage_zfs}
+%package daemon-driver-storage-zfs
+Summary: Storage driver plugin for ZFS
+Group: Development/Libraries
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+# Support any conforming implementation of zfs
+Requires: /sbin/zfs
+Requires: /sbin/zpool
+
+%description daemon-driver-storage-zfs
+The storage driver backend adding implementation of the storage APIs for
+ZFS volumes.
+%endif
+
+
%package daemon-driver-storage
Summary: Storage driver plugin including all backends for the libvirtd daemon
Group: Development/Libraries
@@ -723,6 +757,9 @@ Requires: libvirt-daemon-driver-storage-rbd = %{version}-%{release}
%if %{with_storage_sheepdog}
Requires: libvirt-daemon-driver-storage-sheepdog = %{version}-%{release}
%endif
+%if %{with_storage_zfs}
+Requires: libvirt-daemon-driver-storage-zfs = %{version}-%{release}
+%endif
%description daemon-driver-storage
The storage driver plugin for the libvirtd daemon, providing
@@ -1180,6 +1217,12 @@ rm -rf .git
%define arg_storage_gluster --without-storage-gluster
%endif
+%if %{with_storage_zfs}
+ %define arg_storage_zfs --with-storage-zfs
+%else
+ %define arg_storage_zfs --without-storage-zfs
+%endif
+
%if %{with_numactl}
%define arg_numactl --with-numactl
%else
@@ -1288,7 +1331,7 @@ rm -f po/stamp-po
%{?arg_storage_rbd} \
%{?arg_storage_sheepdog} \
%{?arg_storage_gluster} \
- --without-storage-zfs \
+ %{?arg_storage_zfs} \
--without-storage-vstorage \
%{?arg_numactl} \
%{?arg_numad} \
@@ -1850,6 +1893,11 @@ exit 0
%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_sheepdog.so
%endif
+%if %{with_storage_zfs}
+%files daemon-driver-storage-zfs
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_zfs.so
+%endif
+
%if %{with_qemu}
%files daemon-driver-qemu
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/
@@ -1,36 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 20 Dec 2017 12:58:36 +0100
Subject: [PATCH] util: probe: Add quiet versions of the "PROBE" macro
PROBE macro adds a logging entry, when used in places seeing a lot of
traffic this can cause a significant slowdown.
(cherry picked from commit f06e488d5484031a76e7ed231c8fef8fa1181d2c)
---
src/util/virprobe.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/util/virprobe.h b/src/util/virprobe.h
index 7565954af..bd8c32964 100644
--- a/src/util/virprobe.h
+++ b/src/util/virprobe.h
@@ -90,11 +90,19 @@
PROBE_EXPAND(LIBVIRT_ ## NAME, \
VIR_ADD_CASTS(__VA_ARGS__)); \
}
+
+# define PROBE_QUIET(NAME, FMT, ...) \
+ if (LIBVIRT_ ## NAME ## _ENABLED()) { \
+ PROBE_EXPAND(LIBVIRT_ ## NAME, \
+ VIR_ADD_CASTS(__VA_ARGS__)); \
+ }
# else
# define PROBE(NAME, FMT, ...) \
VIR_INFO_INT(&virLogSelf, \
__FILE__, __LINE__, __func__, \
#NAME ": " FMT, __VA_ARGS__);
+
+# define PROBE_QUIET(NAME, FMT, ...)
# endif
#endif /* __VIR_PROBE_H__ */
+150
View File
@@ -0,0 +1,150 @@
From: Juan Hernandez <jhernand@redhat.com>
Date: Thu, 6 Jul 2017 17:03:31 +0200
Subject: [PATCH] Avoid hidden cgroup mount points
Currently the scan of the /proc/mounts file used to find cgroup mount
points doesn't take into account that mount points may hidden by other
mount points. For, example in certain Kubernetes environments the
/proc/mounts contains the following lines:
cgroup /sys/fs/cgroup/net_prio,net_cls cgroup ...
tmpfs /sys/fs/cgroup tmpfs ...
cgroup /sys/fs/cgroup/net_cls,net_prio cgroup ...
In this particular environment the first mount point is hidden by the
second one. The correct mount point is the third one, but libvirt will
never process it because it only checks the first mount point for each
controller (net_cls in this case). So libvirt will try to use the first
mount point, which doesn't actually exist, and the complete detection
process will fail.
To avoid that issue this patch changes the virCgroupDetectMountsFromFile
function so that when there are duplicates it takes the information from
the last line in /proc/mounts. This requires removing the previous
explicit condition to skip duplicates, and adding code to free the
memory used by the processing of duplicated lines.
Related-To: https://bugzilla.redhat.com/1468214
Related-To: https://github.com/kubevirt/libvirt/issues/4
Signed-off-by: Juan Hernandez <jhernand@redhat.com>
(cherry picked from commit dacd160d7479e0ec2d8a63f102145fd30636a1c8)
---
src/util/vircgroup.c | 23 ++++++++++++++---------
tests/vircgroupdata/kubevirt.mounts | 25 +++++++++++++++++++++++++
tests/vircgroupdata/kubevirt.parsed | 10 ++++++++++
tests/vircgrouptest.c | 1 +
4 files changed, 50 insertions(+), 9 deletions(-)
create mode 100644 tests/vircgroupdata/kubevirt.mounts
create mode 100644 tests/vircgroupdata/kubevirt.parsed
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 5aa1db5b1..a53908fc9 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -397,6 +397,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
const char *typestr = virCgroupControllerTypeToString(i);
int typelen = strlen(typestr);
char *tmp = entry.mnt_opts;
+ struct virCgroupController *controller = &group->controllers[i];
while (tmp) {
char *next = strchr(tmp, ',');
int len;
@@ -406,18 +407,22 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
} else {
len = strlen(tmp);
}
- /* NB, the same controller can appear >1 time in mount list
- * due to bind mounts from one location to another. Pick the
- * first entry only
- */
- if (typelen == len && STREQLEN(typestr, tmp, len) &&
- !group->controllers[i].mountPoint) {
+
+ if (typelen == len && STREQLEN(typestr, tmp, len)) {
char *linksrc;
struct stat sb;
char *tmp2;
- if (VIR_STRDUP(group->controllers[i].mountPoint,
- entry.mnt_dir) < 0)
+ /* Note that the lines in /proc/mounts have the same
+ * order than the mount operations, and that there may
+ * be duplicates due to bind mounts. This means
+ * that the same mount point may be processed more than
+ * once. We need to save the results of the last one,
+ * and we need to be careful to release the memory used
+ * by previous processing. */
+ VIR_FREE(controller->mountPoint);
+ VIR_FREE(controller->linkPoint);
+ if (VIR_STRDUP(controller->mountPoint, entry.mnt_dir) < 0)
goto error;
tmp2 = strrchr(entry.mnt_dir, '/');
@@ -453,7 +458,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
VIR_WARN("Expecting a symlink at %s for controller %s",
linksrc, typestr);
} else {
- group->controllers[i].linkPoint = linksrc;
+ controller->linkPoint = linksrc;
}
}
}
diff --git a/tests/vircgroupdata/kubevirt.mounts b/tests/vircgroupdata/kubevirt.mounts
new file mode 100644
index 000000000..ca036196b
--- /dev/null
+++ b/tests/vircgroupdata/kubevirt.mounts
@@ -0,0 +1,25 @@
+rootfs / rootfs rw 0 0
+proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
+udev /dev devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=1006404,mode=755 0 0
+devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0
+sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
+/dev/sda1 / ext4 rw,noatime,data=ordered 0 0
+tmpfs /run tmpfs rw,nodev,relatime,size=812296k,mode=755 0 0
+mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0
+shm /dev/shm tmpfs rw,nosuid,nodev,noexec,relatime 0 0
+debugfs /sys/kernel/debug debugfs rw,nosuid,nodev,noexec,relatime 0 0
+cgroup_root /sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,size=10240k,mode=755 0 0
+openrc /sys/fs/cgroup/openrc cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/lib64/rc/sh/cgroup-release-agent.sh,name=openrc 0 0
+cpuset /some/random/location/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
+cpuset /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
+cpu /sys/fs/cgroup/cpu cgroup rw,nosuid,nodev,noexec,relatime,cpu 0 0
+cpuacct /some/random/location/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0
+cpuacct /sys/fs/cgroup/cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0
+memory /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
+devices /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
+freezer /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
+blkio /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
+perf_event /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
+hugetlb /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
+binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0
+freezer /some/random/location/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
diff --git a/tests/vircgroupdata/kubevirt.parsed b/tests/vircgroupdata/kubevirt.parsed
new file mode 100644
index 000000000..694870723
--- /dev/null
+++ b/tests/vircgroupdata/kubevirt.parsed
@@ -0,0 +1,10 @@
+cpu /sys/fs/cgroup/cpu
+cpuacct /sys/fs/cgroup/cpuacct
+cpuset /sys/fs/cgroup/cpuset
+memory /sys/fs/cgroup/memory
+devices /sys/fs/cgroup/devices
+freezer /some/random/location/freezer
+blkio /sys/fs/cgroup/blkio
+net_cls <null>
+perf_event /sys/fs/cgroup/perf_event
+name=systemd <null>
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index f55ef74a1..cf0315f16 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -885,6 +885,7 @@ mymain(void)
DETECT_MOUNTS("cgroups3");
DETECT_MOUNTS("all-in-one");
DETECT_MOUNTS("no-cgroups");
+ DETECT_MOUNTS("kubevirt");
if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0)
ret = -1;
@@ -1,49 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 20 Dec 2017 13:09:07 +0100
Subject: [PATCH] qemu: monitor: Decrease logging verbosity
The PROBE macro used in qemuMonitorIOProcess and the VIR_DEBUG message
in qemuMonitorJSONIOProcess create a lot of logging churn when debug
logging is enabled during monitor communication.
The messages logged from the PROBE macro are rather useless since they
are reporting the partial state of receiving the reply from qemu. The
actual full reply is still logged in qemuMonitorJSONIOProcessLine once
the full message is received.
(cherry picked from commit f10bb3347b43d900ff361cda5fe1996782284991)
---
src/qemu/qemu_monitor.c | 4 ++--
src/qemu/qemu_monitor_json.c | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 19082d8bf..3def28852 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -434,8 +434,8 @@ qemuMonitorIOProcess(qemuMonitorPtr mon)
# endif
#endif
- PROBE(QEMU_MONITOR_IO_PROCESS,
- "mon=%p buf=%s len=%zu", mon, mon->buffer, mon->bufferOffset);
+ PROBE_QUIET(QEMU_MONITOR_IO_PROCESS, "mon=%p buf=%s len=%zu",
+ mon, mon->buffer, mon->bufferOffset);
if (mon->json)
len = qemuMonitorJSONIOProcess(mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index df5fb7c8f..461aae089 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -259,7 +259,10 @@ int qemuMonitorJSONIOProcess(qemuMonitorPtr mon,
}
}
+#if DEBUG_IO
VIR_DEBUG("Total used %d bytes out of %zd available in buffer", used, len);
+#endif
+
return used;
}
@@ -0,0 +1,53 @@
From: Jim Fehlig <jfehlig@suse.com>
Date: Tue, 18 Jul 2017 10:20:35 -0600
Subject: [PATCH] docs: schema: make disk driver name attribute optional
/domain/devices/disk/driver/@name is not a required or mandatory
attribute according to formatdomain, and indeed it was agreed on
IRC that the attribute is "optional for input, recommended (but
not required) for output". Currently the schema requires the
attribute, causing virt-xml-validate to fail on disk config where
the driver name is not explicitly specified. E.g.
# cat test.xml | grep -A 5 cdrom
<disk type='file' device='cdrom'>
<driver type='raw'/>
<target dev='hdb' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
# virt-xml-validate test.xml
Relax-NG validity error : Extra element devices in interleave
test.xml:21: element devices: Relax-NG validity error : Element domain failed to validate content
test.xml fails to validate
Relaxing the name attribute to be optional fixes the validation
# virt-xml-validate test.xml
test.xml validates
(cherry picked from commit b494e09d058f09b48d0fd8855edd557101294671)
---
docs/schemas/domaincommon.rng | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index edc225fe5..dfc7e2470 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1720,9 +1720,11 @@
</element>
</define>
<define name="driverFormat">
- <attribute name="name">
- <ref name="genericName"/>
- </attribute>
+ <optional>
+ <attribute name="name">
+ <ref name="genericName"/>
+ </attribute>
+ </optional>
<optional>
<attribute name='type'>
<choice>
@@ -1,63 +0,0 @@
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Sat, 27 Jan 2018 23:43:58 +0100
Subject: [PATCH] virlog: determine the hostname on startup CVE-2018-6764
At later point it might not be possible or even safe to use getaddrinfo(). It
can in turn result in a load of NSS module.
Notably, on a LXC container startup we may find ourselves with the guest
filesystem already having replaced the host one. Loading a NSS module
from the guest tree would allow a malicous guest to escape the
confinement of its container environment because libvirt will not yet
have locked it down.
(cherry picked from commit 759b4d1b0fe5f4d84d98b99153dfa7ac289dd167)
---
src/util/virlog.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/util/virlog.c b/src/util/virlog.c
index d45a451a7..05e0e199e 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -64,6 +64,7 @@
VIR_LOG_INIT("util.log");
static regex_t *virLogRegex;
+static char *virLogHostname;
#define VIR_LOG_DATE_REGEX "[0-9]{4}-[0-9]{2}-[0-9]{2}"
@@ -271,6 +272,12 @@ virLogOnceInit(void)
VIR_FREE(virLogRegex);
}
+ /* We get and remember the hostname early, because at later time
+ * it might not be possible to load NSS modules via getaddrinfo()
+ * (e.g. at container startup the host filesystem will not be
+ * accessible anymore. */
+ virLogHostname = virGetHostnameQuiet();
+
virLogUnlock();
return 0;
}
@@ -466,17 +473,14 @@ static int
virLogHostnameString(char **rawmsg,
char **msg)
{
- char *hostname = virGetHostnameQuiet();
char *hoststr;
- if (!hostname)
+ if (!virLogHostname)
return -1;
- if (virAsprintfQuiet(&hoststr, "hostname: %s", hostname) < 0) {
- VIR_FREE(hostname);
+ if (virAsprintfQuiet(&hoststr, "hostname: %s", virLogHostname) < 0) {
return -1;
}
- VIR_FREE(hostname);
if (virLogFormatString(msg, 0, NULL, VIR_LOG_INFO, hoststr) < 0) {
VIR_FREE(hoststr);
-27
View File
@@ -1,27 +0,0 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Wed, 7 Feb 2018 14:39:18 +0100
Subject: [PATCH] util: Fix syntax-check
Broken by 759b4d1b0fe5f4d84d98b99153dfa7ac289dd167.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit 6ce3acc129bfdbe7fd02bcb8bbe8af6d13903684)
---
src/util/virlog.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/util/virlog.c b/src/util/virlog.c
index 05e0e199e..056b53cda 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -478,9 +478,8 @@ virLogHostnameString(char **rawmsg,
if (!virLogHostname)
return -1;
- if (virAsprintfQuiet(&hoststr, "hostname: %s", virLogHostname) < 0) {
+ if (virAsprintfQuiet(&hoststr, "hostname: %s", virLogHostname) < 0)
return -1;
- }
if (virLogFormatString(msg, 0, NULL, VIR_LOG_INFO, hoststr) < 0) {
VIR_FREE(hoststr);
@@ -1,121 +0,0 @@
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Mon, 12 Feb 2018 10:03:08 +0000
Subject: [PATCH] log: fix deadlock obtaining hostname (related CVE-2018-6764)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The fix for CVE-2018-6764 introduced a potential deadlock scenario
that gets triggered by the NSS module when virGetHostname() calls
getaddrinfo to resolve the hostname:
#0 0x00007f6e714b57e7 in futex_wait
#1 futex_wait_simple
#2 __pthread_once_slow
#3 0x00007f6e71d16e7d in virOnce
#4 0x00007f6e71d0997c in virLogInitialize
#5 0x00007f6e71d0a09a in virLogVMessage
#6 0x00007f6e71d09ffd in virLogMessage
#7 0x00007f6e71d0db22 in virObjectNew
#8 0x00007f6e71d0dbf1 in virObjectLockableNew
#9 0x00007f6e71d0d3e5 in virMacMapNew
#10 0x00007f6e71cdc50a in findLease
#11 0x00007f6e71cdcc56 in _nss_libvirt_gethostbyname4_r
#12 0x00007f6e724631fc in gaih_inet
#13 0x00007f6e72464697 in __GI_getaddrinfo
#14 0x00007f6e71d19e81 in virGetHostnameImpl
#15 0x00007f6e71d1a057 in virGetHostnameQuiet
#16 0x00007f6e71d09936 in virLogOnceInit
#17 0x00007f6e71d09952 in virLogOnce
#18 0x00007f6e714b5829 in __pthread_once_slow
#19 0x00007f6e71d16e7d in virOnce
#20 0x00007f6e71d0997c in virLogInitialize
#21 0x00007f6e71d0a09a in virLogVMessage
#22 0x00007f6e71d09ffd in virLogMessage
#23 0x00007f6e71d0db22 in virObjectNew
#24 0x00007f6e71d0dbf1 in virObjectLockableNew
#25 0x00007f6e71d0d3e5 in virMacMapNew
#26 0x00007f6e71cdc50a in findLease
#27 0x00007f6e71cdc839 in _nss_libvirt_gethostbyname3_r
#28 0x00007f6e71cdc724 in _nss_libvirt_gethostbyname2_r
#29 0x00007f6e7248f72f in __gethostbyname2_r
#30 0x00007f6e7248f494 in gethostbyname2
#31 0x000056348c30c36d in hosts_keys
#32 0x000056348c30b7d2 in main
Fortunately the extra stuff virGetHostname does is totally irrelevant to
the needs of the logging code, so we can just inline a call to the
native hostname() syscall directly.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit c2dc6698c88fb591639e542c8ecb0076c54f3dfb)
---
cfg.mk | 2 +-
src/util/virlog.c | 20 ++++++++++++++------
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index 56cb14bd9..a4131592c 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -1158,7 +1158,7 @@ _src2=src/(util/vircommand|libvirt|lxc/lxc_controller|locking/lock_daemon|loggin
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
(^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$)
-exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/virutil\.c$$
+exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/vir(util|log)\.c$$
exclude_file_name_regexp--sc_prohibit_internal_functions = \
^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$
diff --git a/src/util/virlog.c b/src/util/virlog.c
index 056b53cda..f76fc2caf 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -64,7 +64,7 @@
VIR_LOG_INIT("util.log");
static regex_t *virLogRegex;
-static char *virLogHostname;
+static char virLogHostname[HOST_NAME_MAX+1];
#define VIR_LOG_DATE_REGEX "[0-9]{4}-[0-9]{2}-[0-9]{2}"
@@ -261,6 +261,8 @@ virLogPriorityString(virLogPriority lvl)
static int
virLogOnceInit(void)
{
+ int r;
+
if (virMutexInit(&virLogMutex) < 0)
return -1;
@@ -275,8 +277,17 @@ virLogOnceInit(void)
/* We get and remember the hostname early, because at later time
* it might not be possible to load NSS modules via getaddrinfo()
* (e.g. at container startup the host filesystem will not be
- * accessible anymore. */
- virLogHostname = virGetHostnameQuiet();
+ * accessible anymore.
+ * Must not use virGetHostname though as that causes re-entrancy
+ * problems if it triggers logging codepaths
+ */
+ r = gethostname(virLogHostname, sizeof(virLogHostname));
+ if (r == -1) {
+ ignore_value(virStrcpy(virLogHostname,
+ "(unknown)", sizeof(virLogHostname)));
+ } else {
+ NUL_TERMINATE(virLogHostname);
+ }
virLogUnlock();
return 0;
@@ -475,9 +486,6 @@ virLogHostnameString(char **rawmsg,
{
char *hoststr;
- if (!virLogHostname)
- return -1;
-
if (virAsprintfQuiet(&hoststr, "hostname: %s", virLogHostname) < 0)
return -1;
@@ -18,10 +18,10 @@ Wire it up in the qemu driver
5 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b7824512c..1f9264639 100644
index ce844bb04..555a1009b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -419,6 +419,8 @@ qemuSecurityInit(virQEMUDriverPtr driver)
@@ -417,6 +417,8 @@ qemuSecurityInit(virQEMUDriverPtr driver)
if (virQEMUDriverIsPrivileged(driver)) {
if (cfg->dynamicOwnership)
flags |= VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP;
@@ -31,7 +31,7 @@ index b7824512c..1f9264639 100644
cfg->user,
cfg->group,
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index ca7a6af6d..507be44a2 100644
index 922e48494..1f8d279bf 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -57,6 +57,7 @@ struct _virSecurityDACData {
@@ -73,7 +73,7 @@ index 846cefbb5..97681c961 100644
virSecurityManagerDACChownCallback chownCallback);
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index 95b995230..e43c99d4f 100644
index 6c777db1e..b2d04d4b9 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -146,7 +146,8 @@ virSecurityManagerNewDAC(const char *virtDriver,
@@ -95,7 +95,7 @@ index 95b995230..e43c99d4f 100644
return mgr;
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 01296d339..08fb89203 100644
index 238e66cd0..96937a892 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -36,6 +36,7 @@ typedef enum {
@@ -1,59 +0,0 @@
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 4 Jan 2018 11:11:53 +0100
Subject: [PATCH] qemuDomainAttachDeviceMknodHelper: Remove symlink before
creating it
https://bugzilla.redhat.com/show_bug.cgi?id=1528502
So imagine you have /dev/blah symlink which points to /dev/sda.
You attach /dev/blah as disk to your domain. Libvirt correctly
creates the /dev/blah -> /dev/sda symlink in the qemu namespace.
However, then you detach the disk, change the symlink so that it
points to /dev/sdb and tries to attach the disk again. This time,
however, the attach fails (well, qemu attaches wrong disk)
because the code assumes that symlinks don't change. Well they
do.
This is inspired by test fix written by Eduardo Habkost.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit db98e7f67ea0d7699410f514f01947cef5128a6c)
---
src/qemu/qemu_domain.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 42d17c1b0..e0f4aaafa 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8864,13 +8864,23 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid ATTRIBUTE_UNUSED,
if (isLink) {
VIR_DEBUG("Creating symlink %s -> %s", data->file, data->target);
+
+ /* First, unlink the symlink target. Symlinks change and
+ * therefore we have no guarantees that pre-existing
+ * symlink is still valid. */
+ if (unlink(data->file) < 0 &&
+ errno != ENOENT) {
+ virReportSystemError(errno,
+ _("Unable to remove symlink %s"),
+ data->file);
+ goto cleanup;
+ }
+
if (symlink(data->target, data->file) < 0) {
- if (errno != EEXIST) {
- virReportSystemError(errno,
- _("Unable to create symlink %s"),
- data->target);
- goto cleanup;
- }
+ virReportSystemError(errno,
+ _("Unable to create symlink %s (pointing to %s)"),
+ data->file, data->target);
+ goto cleanup;
} else {
delDevice = true;
}
@@ -17,10 +17,10 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1460804
1 file changed, 58 insertions(+)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 507be44a2..349dbe81d 100644
index 1f8d279bf..5f13bcee8 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1380,6 +1380,54 @@ virSecurityDACRestoreTPMFileLabel(virSecurityManagerPtr mgr,
@@ -1379,6 +1379,54 @@ virSecurityDACRestoreTPMFileLabel(virSecurityManagerPtr mgr,
}
@@ -75,7 +75,7 @@ index 507be44a2..349dbe81d 100644
static int
virSecurityDACSetInputLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
@@ -1491,6 +1539,11 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
@@ -1489,6 +1537,11 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
rc = -1;
}
@@ -87,7 +87,7 @@ index 507be44a2..349dbe81d 100644
for (i = 0; i < def->ninputs; i++) {
if (virSecurityDACRestoreInputLabel(mgr, def, def->inputs[i]) < 0)
rc = -1;
@@ -1611,6 +1664,11 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
@@ -1602,6 +1655,11 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
return -1;
}
@@ -1,110 +0,0 @@
From ce5aebeacd10a1c15cb3ee46a59c8b5ff235589e Mon Sep 17 00:00:00 2001
Message-Id: <ce5aebeacd10a1c15cb3ee46a59c8b5ff235589e.1530632895.git.crobinso@redhat.com>
From: Laine Stump <laine@laine.org>
Date: Wed, 25 Apr 2018 17:12:03 -0400
Subject: [PATCH] nwfilter: increase pcap buffer size to be compatible with
TPACKET_V3
When an nwfilter rule sets the parameter CTRL_IP_LEARNING to "dhcp",
this turns on the "dhcpsnoop" thread, which uses libpcap to monitor
traffic on the domain's tap device and extract the IP address from the
DHCP response.
If libpcap on the host is built with HAVE_TPACKET3 defined (to enable
support for TPACKET_V3), the dhcpsnoop code's initialization of the
libpcap socket would fail with the following error:
virNWFilterSnoopDHCPOpen:1134 : internal error: pcap_setfilter: can't remove kernel filter: Bad file descriptor
It turns out that this was because TPACKET_V3 requires a larger buffer
size than libvirt was setting (we were setting it to 128k). Changing
the buffer size to 256k eliminates the error, and the dhcpsnoop thread
once again works properly.
A fuller explanation of why TPACKET_V3 requires such a large buffer,
for future git spelunkers:
libpcap calls setsockopt(... SOL_PACKET, PACKET_RX_RING...) to setup a
ring buffer for receiving packets; two of the attributes sent to this
API are called tp_frame_size, and tp_frame_nr. If libpcap was built
with HAVE_TPACKET3 defined, tp_trame_size is set to MAXIMUM_SNAPLEN
(defined in libpcap sources as 262144) and tp_frame_nr is set to:
[the buffer size we set, i.e. PCAP_BUFFERSIZE i.e. 262144] / tp_frame_size.
So if PCAP_BUFFERSIZE < MAXIMUM_SNAPLEN, then tp_frame_nr (the number
of frames in the ring buffer) is 0, which is nonsensical. This same
value is later used as a multiplier to determine the size for a call
to malloc() (which would also fail).
(NB: if HAVE_TPACKET3 is *not* defined, then tp_frame_size is set to
the snaplen set by the user (in our case 576) plus a small amount to
account for ethernet headers, so 256k is far more than adequate)
Since the TPACKET_V3 code in libpcap actually reads multiple packets
into each frame, it's not a problem to have only a single frame
(especially when we are monitoring such infrequent traffic), so it's
okay to set this relatively small buffer size (in comparison to the
default, which is 2MB), which is important since every guest using
dhcp snooping in a nwfilter rule will hold 2 of these buffers for the
entire life of the guest.
Thanks to Christian Ehrhardt for discovering that buffer size was the
problem (this was not at all obvious from the error that was logged!)
Resolves: https://bugzilla.redhat.com/1547237
Fixes: https://bugs.launchpad.net/libvirt/+bug/1758037
Signed-off-by: Laine Stump <laine@laine.org>
Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> (V1)
Reviewed-by: John Ferlan <jferlan@redhat.com>
Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
src/nwfilter/nwfilter_dhcpsnoop.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c
index 6069e70460..50cfb944a2 100644
--- a/src/nwfilter/nwfilter_dhcpsnoop.c
+++ b/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -256,10 +256,21 @@ struct _virNWFilterDHCPDecodeJob {
# define DHCP_BURST_INTERVAL_S 10 /* sec */
/*
- * libpcap 1.5 requires a 128kb buffer
- * 128 kb is bigger than (DHCP_PKT_BURST * PCAP_PBUFSIZE / 2)
+ * NB: Any libpcap built with HAVE_TPACKET3 will require
+ * PCAP_BUFFERSIZE to be at least 262144 (although
+ * pcap_set_buffer_size() with a lower value will succeed, and the
+ * error will only show up later when pcap_setfilter() is called).
+ *
+ * It is possible that in the future libpcap could increase the
+ * minimum size even further, but due to the fact that each guest
+ * using dhcp snooping keeps 2 pcap sockets open (and thus 2 buffers
+ * allocated) for the life of the guest, we want to minimize the
+ * length of the buffer, so instead of leaving it at the default size
+ * (2MB), we are setting it to the minimum viable size and including
+ * this clue in the source to help quickly resolve the problem when/if
+ * it reoccurs.
*/
-# define PCAP_BUFFERSIZE (128 * 1024)
+# define PCAP_BUFFERSIZE (256 * 1024)
# define MAX_QUEUED_JOBS (DHCP_PKT_BURST + 2 * DHCP_PKT_RATE)
@@ -1114,6 +1125,11 @@ virNWFilterSnoopDHCPOpen(const char *ifname, virMacAddr *mac,
goto cleanup_nohandle;
}
+ /* IMPORTANT: If there is any failure of *any* pcap_* function
+ * during setup of the socket, look to the comment where
+ * PCAP_BUFFERSIZE is defined. It may be too small, even if the
+ * generated error doesn't imply that.
+ */
if (pcap_set_snaplen(handle, PCAP_PBUFSIZE) < 0 ||
pcap_set_buffer_size(handle, PCAP_BUFFERSIZE) < 0 ||
pcap_activate(handle) < 0) {
--
2.17.1
+63
View File
@@ -0,0 +1,63 @@
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 31 Jul 2017 16:55:58 +0200
Subject: [PATCH] qemu: Honour <on_reboot/>
https://bugzilla.redhat.com/show_bug.cgi?id=1476866
For some reason, we completely ignore <on_reboot/> setting for
domains. The implementation is simply not there. It never was.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 3ee9bdbe351c0b80d4c469571ef31df3f1b148ea)
---
src/qemu/qemu_process.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 992a7174b..7588212ba 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -487,6 +487,7 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectEventPtr event;
qemuDomainObjPrivatePtr priv;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ int ret = -1;
virObjectLock(vm);
@@ -498,12 +499,32 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
VIR_WARN("Failed to save status on vm %s", vm->def->name);
- virObjectUnlock(vm);
+ if (vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_DESTROY ||
+ vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_PRESERVE) {
- qemuDomainEventQueue(driver, event);
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Ignoring RESET event from inactive domain %s",
+ vm->def->name);
+ goto endjob;
+ }
+
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED,
+ QEMU_ASYNC_JOB_NONE, 0);
+ virDomainAuditStop(vm, "destroyed");
+ qemuDomainRemoveInactive(driver, vm);
+ endjob:
+ qemuDomainObjEndJob(driver, vm);
+ }
+ ret = 0;
+ cleanup:
+ virObjectUnlock(vm);
+ qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return 0;
+ return ret;
}
@@ -0,0 +1,113 @@
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 27 Apr 2017 16:29:21 +0200
Subject: [PATCH] qemuDomainBuildNamespace: Move /dev/* mountpoints later
When setting up mount namespace for a qemu domain the following
steps are executed:
1) get list of mountpoints under /dev/
2) move them to /var/run/libvirt/qemu/$domName.ext
3) start constructing new device tree under /var/run/libvirt/qemu/$domName.dev
4) move the mountpoint of the new device tree to /dev
5) restore original mountpoints from step 2)
Note the problem with this approach is that if some device in step
3) requires access to a mountpoint from step 2) it will fail as
the mountpoint is not there anymore. For instance consider the
following domain disk configuration:
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/dev/shm/vhostmd0'/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
</disk>
In this case operation fails as we are unable to create vhostmd0
in the new device tree because after step 2) there is no /dev/shm
anymore. Leave aside fact that we shouldn't try to create devices
living in other mountpoints. That's a separate bug that will be
addressed later.
Currently, the order described above is rearranged to:
1) get list of mountpoints under /dev/
2) start constructing new device tree under /var/run/libvirt/qemu/$domName.dev
3) move them to /var/run/libvirt/qemu/$domName.ext
4) move the mountpoint of the new device tree to /dev
5) restore original mountpoints from step 3)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Cedric Bosdonnat <cbosdonnat@suse.com>
(cherry picked from commit a7cc039dc796f541793955598377807af48341fb)
(cherry picked from commit 469bf7cb7a44a0798c63e4b5e4682d8e38bce66e)
---
src/qemu/qemu_domain.c | 48 ++++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4a127cedf..64f18f493 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7854,6 +7854,30 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
if (qemuDomainSetupDev(cfg, mgr, vm, devPath) < 0)
goto cleanup;
+ if (qemuDomainSetupAllDisks(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllHostdevs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllMemories(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllChardevs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupTPM(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllGraphics(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllInputs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllRNGs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
/* Save some mount points because we want to share them with the host */
for (i = 0; i < ndevMountsPath; i++) {
struct stat sb;
@@ -7881,30 +7905,6 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
goto cleanup;
}
- if (qemuDomainSetupAllDisks(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllHostdevs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllMemories(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllChardevs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupTPM(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllGraphics(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllInputs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllRNGs(cfg, vm, devPath) < 0)
- goto cleanup;
-
if (virFileMoveMount(devPath, "/dev") < 0)
goto cleanup;
@@ -24,7 +24,6 @@ This is assigned CVE-2017-1000256 / LSN-2017-0002
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 441d3eb6d1be940a67ce45a286602a967601b157)
(cherry picked from commit dc6c41798d1eb5c52c75365ffa22f7672709dfa7)
---
src/qemu/qemu_command.c | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args | 2 +-
@@ -32,10 +31,10 @@ Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9a27987d4..ae78cd17e 100644
index 311edd13e..141831635 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -718,7 +718,7 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
@@ -727,7 +727,7 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
if (virJSONValueObjectCreate(propsret,
"s:dir", path,
"s:endpoint", (isListen ? "server": "client"),
@@ -45,7 +44,7 @@ index 9a27987d4..ae78cd17e 100644
goto cleanup;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
index 5aff7734e..ab5f7e27f 100644
index b456cce30..003d11de7 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
@@ -26,7 +26,7 @@ server,nowait \
@@ -58,7 +57,7 @@ index 5aff7734e..ab5f7e27f 100644
tls-creds=objcharserial1_tls0 \
-device isa-serial,chardev=charserial1,id=serial1 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
index 91f1fe0cd..2567abbfa 100644
index 7f9fedb6c..a020ff006 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
@@ -31,7 +31,7 @@ localport=1111 \
@@ -1,74 +0,0 @@
From e18672ce9a5fff383992fd6e842d1cbe85c141ea Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 12 Dec 2017 16:23:40 +0100
Subject: [PATCH 10/19] util: add virFileReadHeaderQuiet wrapper around
virFileReadHeaderFD
CVE-2017-5715
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virfile.c | 19 +++++++++++++++++++
src/util/virfile.h | 2 ++
3 files changed, 22 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f30a04b145..29b73fa046 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1703,6 +1703,7 @@ virFileReadAll;
virFileReadAllQuiet;
virFileReadBufQuiet;
virFileReadHeaderFD;
+virFileReadHeaderQuiet;
virFileReadLimFD;
virFileReadLink;
virFileReadValueBitmap;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 2f28e83f44..269db995ff 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -1356,6 +1356,25 @@ virFileReadHeaderFD(int fd, int maxlen, char **buf)
}
+int
+virFileReadHeaderQuiet(const char *path,
+ int maxlen,
+ char **buf)
+{
+ int fd;
+ int len;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ len = virFileReadHeaderFD(fd, maxlen, buf);
+ VIR_FORCE_CLOSE(fd);
+
+ return len;
+}
+
+
/* A wrapper around saferead_lim that maps a failure due to
exceeding the maximum size limitation to EOVERFLOW. */
int
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 57ceb80721..657e7216fb 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -129,6 +129,8 @@ int virFileDeleteTree(const char *dir);
int virFileReadHeaderFD(int fd, int maxlen, char **buf)
ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(3);
+int virFileReadHeaderQuiet(const char *path, int maxlen, char **buf)
+ ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
int virFileReadLimFD(int fd, int maxlen, char **buf)
ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(3);
int virFileReadAll(const char *path, int maxlen, char **buf)
--
2.17.0
@@ -1,36 +0,0 @@
From a84e70ad247da5d3ad13615efd70b91951392aa1 Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 5 Jan 2018 17:43:03 +0100
Subject: [PATCH 12/19] cpu_x86: Copy CPU signature from ancestor
When specifying a new CPU model in cpu_map.xml as an extension to an
existing model, we forgot to copy the signature (family + model) from
the original CPU model.
We don't use this way of specifying CPU models, but it's still supported
and it becomes useful when someone wants to quickly hack up a CPU model
for testing or when creating additional variants of existing models to
help with fixing some spectral issues.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit b427cf4831d0ea7aac9dd1a3aa7682478356a483)
---
src/cpu/cpu_x86.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 2864454211..3b7a6f95fe 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -1206,6 +1206,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
VIR_FREE(name);
model->vendor = ancestor->vendor;
+ model->signature = ancestor->signature;
if (x86DataCopy(&model->data, &ancestor->data) < 0)
goto error;
}
--
2.17.0
@@ -1,97 +0,0 @@
From de12d97c029d6644bb42afaa38410c4263bef41f Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 12 Dec 2017 16:23:41 +0100
Subject: [PATCH 13/19] util: introduce virHostCPUGetMicrocodeVersion
This new API reads host's CPU microcode version from /proc/cpuinfo.
Unfortunately, there is no other way of reading microcode version which
would be usable from both system and session daemon.
CVE-2017-5715
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virhostcpu.c | 43 ++++++++++++++++++++++++++++++++++++++++
src/util/virhostcpu.h | 2 ++
3 files changed, 46 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 29b73fa046..0ecd58a12c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1811,6 +1811,7 @@ virHostCPUGetCount;
virHostCPUGetInfo;
virHostCPUGetKVMMaxVCPUs;
virHostCPUGetMap;
+virHostCPUGetMicrocodeVersion;
virHostCPUGetOnline;
virHostCPUGetOnlineBitmap;
virHostCPUGetPresentBitmap;
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index c485a97211..713fdec553 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -1206,3 +1206,46 @@ virHostCPUGetKVMMaxVCPUs(void)
return -1;
}
#endif /* HAVE_LINUX_KVM_H */
+
+
+#ifdef __linux__
+
+unsigned int
+virHostCPUGetMicrocodeVersion(void)
+{
+ char *outbuf = NULL;
+ char *cur;
+ unsigned int version = 0;
+
+ if (virFileReadHeaderQuiet(CPUINFO_PATH, 4096, &outbuf) < 0) {
+ char ebuf[1024];
+ VIR_DEBUG("Failed to read microcode version from %s: %s",
+ CPUINFO_PATH, virStrerror(errno, ebuf, sizeof(ebuf)));
+ return 0;
+ }
+
+ /* Account for format 'microcode : XXXX'*/
+ if (!(cur = strstr(outbuf, "microcode")) ||
+ !(cur = strchr(cur, ':')))
+ goto cleanup;
+ cur++;
+
+ /* Linux places the microcode revision in a 32-bit integer, so
+ * ui is fine for us too. */
+ if (virStrToLong_ui(cur, &cur, 0, &version) < 0)
+ goto cleanup;
+
+ cleanup:
+ VIR_FREE(outbuf);
+ return version;
+}
+
+#else
+
+unsigned int
+virHostCPUGetMicrocodeVersion(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
index 67033de842..f9f3359288 100644
--- a/src/util/virhostcpu.h
+++ b/src/util/virhostcpu.h
@@ -66,4 +66,6 @@ virBitmapPtr virHostCPUGetSiblingsList(unsigned int cpu);
int virHostCPUGetOnline(unsigned int cpu, bool *online);
+unsigned int virHostCPUGetMicrocodeVersion(void);
+
#endif /* __VIR_HOSTCPU_H__*/
--
2.17.0
@@ -1,51 +0,0 @@
From a0ad8c160ed81417e4d5b46adf3118df1b6b1b77 Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 13 Dec 2017 22:30:31 +0100
Subject: [PATCH 14/19] cpu_x86: Rename virCPUx86MapInitialize
The function will be used to initialize internal data of the x86 CPU
driver (including the CPU map).
CVE-2017-5715
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/cpu/cpu_x86.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 3b7a6f95fe..0cb0dcacb3 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -153,8 +153,8 @@ struct _virCPUx86Map {
};
static virCPUx86MapPtr cpuMap;
-int virCPUx86MapOnceInit(void);
-VIR_ONCE_GLOBAL_INIT(virCPUx86Map);
+int virCPUx86DriverOnceInit(void);
+VIR_ONCE_GLOBAL_INIT(virCPUx86Driver);
typedef enum {
@@ -1387,7 +1387,7 @@ virCPUx86LoadMap(void)
int
-virCPUx86MapOnceInit(void)
+virCPUx86DriverOnceInit(void)
{
if (!(cpuMap = virCPUx86LoadMap()))
return -1;
@@ -1399,7 +1399,7 @@ virCPUx86MapOnceInit(void)
static virCPUx86MapPtr
virCPUx86GetMap(void)
{
- if (virCPUx86MapInitialize() < 0)
+ if (virCPUx86DriverInitialize() < 0)
return NULL;
return cpuMap;
--
2.17.0
@@ -1,133 +0,0 @@
From c628c42493170bfd70f30d9fb56d0067e6e4828a Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 19 Jun 2018 16:47:20 +0100
Subject: [PATCH 15/19] conf: include x86 microcode version in virsh
capabiltiies
A microcode update can cause the CPUID bits to change; an example
from the past was the update that disabled TSX on several Haswell and
Broadwell machines.
In order to track the x86 microcode version in the QEMU capabilities,
we have to fetch it and store it in the host CPU. This also makes the
version visible in "virsh capabilities", which is a nice side effect.
CVE-2017-5715
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/conf/cpu_conf.c | 14 ++++++++++++++
src/conf/cpu_conf.h | 1 +
src/cpu/cpu_x86.c | 9 +++++++++
3 files changed, 24 insertions(+)
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index c21d11d244..3f3c25320e 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -127,6 +127,7 @@ virCPUDefCopyModelFilter(virCPUDefPtr dst,
VIR_STRDUP(dst->vendor_id, src->vendor_id) < 0 ||
VIR_ALLOC_N(dst->features, src->nfeatures) < 0)
return -1;
+ dst->microcodeVersion = src->microcodeVersion;
dst->nfeatures_max = src->nfeatures;
dst->nfeatures = 0;
@@ -178,6 +179,7 @@ virCPUDefStealModel(virCPUDefPtr dst,
VIR_STEAL_PTR(dst->model, src->model);
VIR_STEAL_PTR(dst->features, src->features);
+ dst->microcodeVersion = src->microcodeVersion;
dst->nfeatures_max = src->nfeatures_max;
src->nfeatures_max = 0;
dst->nfeatures = src->nfeatures;
@@ -379,6 +381,14 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
goto cleanup;
}
VIR_FREE(arch);
+
+ if (virXPathBoolean("boolean(./microcode[1]/@version)", ctxt) > 0 &&
+ virXPathUInt("string(./microcode[1]/@version)", ctxt,
+ &def->microcodeVersion) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("invalid microcode version"));
+ goto cleanup;
+ }
}
if (!(def->model = virXPathString("string(./model[1])", ctxt)) &&
@@ -723,6 +733,10 @@ virCPUDefFormatBuf(virBufferPtr buf,
if (formatModel && def->vendor)
virBufferEscapeString(buf, "<vendor>%s</vendor>\n", def->vendor);
+ if (def->type == VIR_CPU_TYPE_HOST && def->microcodeVersion)
+ virBufferAsprintf(buf, "<microcode version='%u'/>\n",
+ def->microcodeVersion);
+
if (def->sockets && def->cores && def->threads) {
virBufferAddLit(buf, "<topology");
virBufferAsprintf(buf, " sockets='%u'", def->sockets);
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index b44974f47e..a30ecf8681 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -133,6 +133,7 @@ struct _virCPUDef {
char *vendor_id; /* vendor id returned by CPUID in the guest */
int fallback; /* enum virCPUFallback */
char *vendor;
+ unsigned int microcodeVersion;
unsigned int sockets;
unsigned int cores;
unsigned int threads;
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 0cb0dcacb3..41aaa61c35 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -33,6 +33,7 @@
#include "virbuffer.h"
#include "virendian.h"
#include "virstring.h"
+#include "virhostcpu.h"
#define VIR_FROM_THIS VIR_FROM_CPU
@@ -153,6 +154,8 @@ struct _virCPUx86Map {
};
static virCPUx86MapPtr cpuMap;
+static unsigned int microcodeVersion;
+
int virCPUx86DriverOnceInit(void);
VIR_ONCE_GLOBAL_INIT(virCPUx86Driver);
@@ -1392,6 +1395,8 @@ virCPUx86DriverOnceInit(void)
if (!(cpuMap = virCPUx86LoadMap()))
return -1;
+ microcodeVersion = virHostCPUGetMicrocodeVersion();
+
return 0;
}
@@ -2409,6 +2414,9 @@ virCPUx86GetHost(virCPUDefPtr cpu,
virCPUDataPtr cpuData = NULL;
int ret = -1;
+ if (virCPUx86DriverInitialize() < 0)
+ goto cleanup;
+
if (!(cpuData = virCPUDataNew(archs[0])))
goto cleanup;
@@ -2417,6 +2425,7 @@ virCPUx86GetHost(virCPUDefPtr cpu,
goto cleanup;
ret = x86DecodeCPUData(cpu, cpuData, models, nmodels, NULL);
+ cpu->microcodeVersion = microcodeVersion;
cleanup:
virCPUx86DataFree(cpuData);
--
2.17.0
@@ -1,535 +0,0 @@
From a31edb693bb79f1ad8931db284f1dbceae178f27 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 19 Jun 2018 16:50:02 +0100
Subject: [PATCH 16/19] qemu: capabilities: force update if the microcode
version does not match
A microcode update can cause the CPUID bits to change; an example
from the past was the update that disabled TSX on several Haswell
and Broadwell machines.
Therefore, place microcode version in the virQEMUCaps struct and
XML, and rebuild the cache if the versions do not match.
CVE-2017-5715
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 40 ++++++++++++++++++-
src/qemu/qemu_capabilities.h | 6 ++-
src/qemu/qemu_capspriv.h | 6 +++
src/qemu/qemu_driver.c | 9 ++++-
.../caps_1.2.2.x86_64.xml | 1 +
.../caps_1.3.1.x86_64.xml | 1 +
.../caps_1.4.2.x86_64.xml | 1 +
.../caps_1.5.3.x86_64.xml | 1 +
.../caps_1.6.0.x86_64.xml | 1 +
.../caps_1.7.0.x86_64.xml | 1 +
.../caps_2.1.1.x86_64.xml | 1 +
.../caps_2.4.0.x86_64.xml | 1 +
.../caps_2.5.0.x86_64.xml | 1 +
.../caps_2.6.0-gicv2.aarch64.xml | 1 +
.../caps_2.6.0-gicv3.aarch64.xml | 1 +
.../caps_2.6.0.ppc64le.xml | 1 +
.../caps_2.6.0.x86_64.xml | 1 +
.../qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 +
.../caps_2.7.0.x86_64.xml | 1 +
.../qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 +
.../caps_2.8.0.x86_64.xml | 1 +
.../caps_2.9.0.ppc64le.xml | 1 +
.../qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 +
.../caps_2.9.0.x86_64.xml | 1 +
tests/qemucapabilitiestest.c | 14 +++++--
tests/qemucapsprobe.c | 2 +-
tests/testutilsqemu.c | 2 +-
27 files changed, 89 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2de84715ea..72b70ce750 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -500,6 +500,7 @@ struct _virQEMUCaps {
unsigned int version;
unsigned int kvmVersion;
unsigned int libvirtVersion;
+ unsigned int microcodeVersion;
char *package;
virArch arch;
@@ -2304,6 +2305,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
ret->version = qemuCaps->version;
ret->kvmVersion = qemuCaps->kvmVersion;
+ ret->microcodeVersion = qemuCaps->microcodeVersion;
if (VIR_STRDUP(ret->package, qemuCaps->package) < 0)
goto error;
@@ -3809,6 +3811,7 @@ struct _virQEMUCapsCachePriv {
uid_t runUid;
gid_t runGid;
virArch hostArch;
+ unsigned int microcodeVersion;
};
typedef struct _virQEMUCapsCachePriv virQEMUCapsCachePriv;
typedef virQEMUCapsCachePriv *virQEMUCapsCachePrivPtr;
@@ -3931,6 +3934,13 @@ virQEMUCapsLoadCache(virArch hostArch,
goto cleanup;
}
+ if (virXPathUInt("string(./microcodeVersion)", ctxt,
+ &qemuCaps->microcodeVersion) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing microcode version in QEMU capabilities cache"));
+ goto cleanup;
+ }
+
if (virXPathBoolean("boolean(./package)", ctxt) > 0) {
qemuCaps->package = virXPathString("string(./package)", ctxt);
if (!qemuCaps->package &&
@@ -4195,6 +4205,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
virBufferAsprintf(&buf, "<kvmVersion>%d</kvmVersion>\n",
qemuCaps->kvmVersion);
+ virBufferAsprintf(&buf, "<microcodeVersion>%u</microcodeVersion>\n",
+ qemuCaps->microcodeVersion);
+
if (qemuCaps->package)
virBufferAsprintf(&buf, "<package>%s</package>\n",
qemuCaps->package);
@@ -4336,6 +4349,16 @@ virQEMUCapsIsValid(void *data,
return false;
}
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
+ priv->microcodeVersion != qemuCaps->microcodeVersion) {
+ VIR_DEBUG("Outdated capabilities for '%s': microcode version changed "
+ "(%u vs %u)",
+ qemuCaps->binary,
+ priv->microcodeVersion,
+ qemuCaps->microcodeVersion);
+ return false;
+ }
+
return true;
}
@@ -5151,6 +5174,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
const char *libDir,
uid_t runUid,
gid_t runGid,
+ unsigned int microcodeVersion,
bool qmpOnly)
{
virQEMUCapsPtr qemuCaps;
@@ -5207,6 +5231,9 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
+ qemuCaps->microcodeVersion = microcodeVersion;
+
cleanup:
VIR_FREE(qmperr);
return qemuCaps;
@@ -5228,6 +5255,7 @@ virQEMUCapsNewData(const char *binary,
priv->libDir,
priv->runUid,
priv->runGid,
+ priv->microcodeVersion,
false);
}
@@ -5310,7 +5338,8 @@ virFileCachePtr
virQEMUCapsCacheNew(const char *libDir,
const char *cacheDir,
uid_t runUid,
- gid_t runGid)
+ gid_t runGid,
+ unsigned int microcodeVersion)
{
char *capsCacheDir = NULL;
virFileCachePtr cache = NULL;
@@ -5333,6 +5362,7 @@ virQEMUCapsCacheNew(const char *libDir,
priv->runUid = runUid;
priv->runGid = runGid;
+ priv->microcodeVersion = microcodeVersion;
cleanup:
VIR_FREE(capsCacheDir);
@@ -5810,3 +5840,11 @@ virQEMUCapsFillDomainCaps(virCapsPtr caps,
return -1;
return 0;
}
+
+
+void
+virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
+ unsigned int microcodeVersion)
+{
+ qemuCaps->microcodeVersion = microcodeVersion;
+}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 9c92d6b469..eea296c9c3 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -514,8 +514,10 @@ void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
const char *machineType);
virFileCachePtr virQEMUCapsCacheNew(const char *libDir,
- const char *cacheDir,
- uid_t uid, gid_t gid);
+ const char *cacheDir,
+ uid_t uid,
+ gid_t gid,
+ unsigned int microcodeVersion);
virQEMUCapsPtr virQEMUCapsCacheLookup(virFileCachePtr cache,
const char *binary);
virQEMUCapsPtr virQEMUCapsCacheLookupCopy(virFileCachePtr cache,
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index d05256bd35..38c14ffa01 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -36,6 +36,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
const char *libDir,
uid_t runUid,
gid_t runGid,
+ unsigned int microcodeVersion,
bool qmpOnly);
int virQEMUCapsLoadCache(virArch hostArch,
@@ -101,4 +102,9 @@ virQEMUCapsParseHelpStr(const char *qemu,
int
virQEMUCapsParseDeviceStr(virQEMUCapsPtr qemuCaps,
const char *str);
+
+void
+virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
+ unsigned int microcodeVersion);
+
#endif
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 208ccc9bc3..d8dc5388ea 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -631,6 +631,8 @@ qemuStateInitialize(bool privileged,
gid_t run_gid = -1;
char *hugepagePath = NULL;
size_t i;
+ virCPUDefPtr hostCPU = NULL;
+ unsigned int microcodeVersion = 0;
if (VIR_ALLOC(qemu_driver) < 0)
return -1;
@@ -853,10 +855,15 @@ qemuStateInitialize(bool privileged,
run_gid = cfg->group;
}
+ if ((hostCPU = virCPUProbeHost(virArchFromHost())))
+ microcodeVersion = hostCPU->microcodeVersion;
+ virCPUDefFree(hostCPU);
+
qemu_driver->qemuCapsCache = virQEMUCapsCacheNew(cfg->libDir,
cfg->cacheDir,
run_uid,
- run_gid);
+ run_gid,
+ microcodeVersion);
if (!qemu_driver->qemuCapsCache)
goto error;
diff --git a/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
index 956284d5d3..f3f66cd8f5 100644
--- a/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml
@@ -111,6 +111,7 @@
<flag name='query-cpu-definitions'/>
<version>1002002</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>26900</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='qemu64'/>
diff --git a/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
index 99384ce5e6..1c4d5ff4a4 100644
--- a/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml
@@ -129,6 +129,7 @@
<flag name='query-cpu-definitions'/>
<version>1003001</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>30198</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='qemu64'/>
diff --git a/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
index aea043c57d..a50383c259 100644
--- a/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml
@@ -130,6 +130,7 @@
<flag name='query-cpu-definitions'/>
<version>1004002</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>30915</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
index 6f860e4f25..ad3e122775 100644
--- a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml
@@ -142,6 +142,7 @@
<flag name='kernel-irqchip'/>
<version>1005003</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>47019</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
index e5dc8360de..7b2324d697 100644
--- a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml
@@ -147,6 +147,7 @@
<flag name='kernel-irqchip'/>
<version>1006000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>45248</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
index 86d87eaf0c..4ba509a753 100644
--- a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml
@@ -149,6 +149,7 @@
<flag name='kernel-irqchip'/>
<version>1007000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>50692</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
index 2fa551b1a0..416703ac89 100644
--- a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml
@@ -165,6 +165,7 @@
<flag name='kernel-irqchip'/>
<version>2001001</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>59488</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
index f97e4cb813..4550139e0c 100644
--- a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
@@ -190,6 +190,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2004000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>75653</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
index 2ba40fc494..6072438688 100644
--- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
@@ -196,6 +196,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2005000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>216775</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
index 0b34fa30d4..6fc0ab25e0 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
@@ -174,6 +174,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2006000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>228838</microcodeVersion>
<package></package>
<arch>aarch64</arch>
<cpu type='kvm' name='pxa262'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
index d41d578c7e..1846bf6a7c 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
@@ -174,6 +174,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2006000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>228838</microcodeVersion>
<package></package>
<arch>aarch64</arch>
<cpu type='kvm' name='pxa262'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
index f1c9fc98a4..199fc2cd22 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
+++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
@@ -169,6 +169,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2006000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>263602</microcodeVersion>
<package></package>
<arch>ppc64</arch>
<cpu type='kvm' name='default'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
index bdf006f6be..5897fbc0c9 100644
--- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
@@ -206,6 +206,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2006000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>227579</microcodeVersion>
<package></package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
index fe7bca93b9..4c208008be 100644
--- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
@@ -136,6 +136,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2007000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>217559</microcodeVersion>
<package></package>
<arch>s390x</arch>
<cpu type='kvm' name='host'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
index 3fd28f09fe..e3a154806c 100644
--- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml
@@ -209,6 +209,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2007000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>239276</microcodeVersion>
<package> (v2.7.0)</package>
<arch>x86_64</arch>
<cpu type='kvm' name='Opteron_G5'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
index 21bbb820d0..f13c783d44 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
@@ -138,6 +138,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2007093</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>242460</microcodeVersion>
<package></package>
<arch>s390x</arch>
<hostCPU type='kvm' model='zEC12.2-base' migratability='no'>
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
index 761f9d1415..f5bd1d7272 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
@@ -211,6 +211,7 @@
<flag name='virtio-gpu.max_outputs'/>
<version>2008000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>255931</microcodeVersion>
<package> (v2.8.0)</package>
<arch>x86_64</arch>
<cpu type='kvm' name='host' usable='yes'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml
index 9551907c66..2d1d0f9a89 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml
@@ -175,6 +175,7 @@
<flag name='disk-share-rw'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>347135</microcodeVersion>
<package> (v2.9.0)</package>
<arch>ppc64</arch>
<cpu type='kvm' name='default'/>
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
index 0a6fbd0776..3b733801f8 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
@@ -140,6 +140,7 @@
<flag name='disk-share-rw'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>265878</microcodeVersion>
<package></package>
<arch>s390x</arch>
<hostCPU type='kvm' model='z13.2-base' migratability='no'>
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
index 1294ebdb31..086594def5 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
@@ -223,6 +223,7 @@
<flag name='disk-share-rw'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
+ <microcodeVersion>321194</microcodeVersion>
<package> (v2.9.0)</package>
<arch>x86_64</arch>
<hostCPU type='kvm' model='base' migratability='yes'>
diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
index 3ae55fc62f..4608fffbb2 100644
--- a/tests/qemucapabilitiestest.c
+++ b/tests/qemucapabilitiestest.c
@@ -61,10 +61,16 @@ testQemuCaps(const void *opaque)
qemuMonitorTestGetMonitor(mon)) < 0)
goto cleanup;
- if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM) &&
- virQEMUCapsInitQMPMonitorTCG(capsActual,
- qemuMonitorTestGetMonitor(mon)) < 0)
- goto cleanup;
+ if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM)) {
+ if (virQEMUCapsInitQMPMonitorTCG(capsActual,
+ qemuMonitorTestGetMonitor(mon)) < 0)
+ goto cleanup;
+
+ /* Fill microcodeVersion with a "random" value which is the file
+ * length to provide a reproducible number for testing.
+ */
+ virQEMUCapsSetMicrocodeVersion(capsActual, virFileLength(repliesFile, -1));
+ }
if (!(actual = virQEMUCapsFormatCache(capsActual)))
goto cleanup;
diff --git a/tests/qemucapsprobe.c b/tests/qemucapsprobe.c
index 4b8d6229b4..a5f5a38b16 100644
--- a/tests/qemucapsprobe.c
+++ b/tests/qemucapsprobe.c
@@ -72,7 +72,7 @@ main(int argc, char **argv)
return EXIT_FAILURE;
if (!(caps = virQEMUCapsNewForBinaryInternal(VIR_ARCH_NONE, argv[1], "/tmp",
- -1, -1, true)))
+ -1, -1, 0, true)))
return EXIT_FAILURE;
virObjectUnref(caps);
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index 2c7124bf26..f8182033fc 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -603,7 +603,7 @@ int qemuTestDriverInit(virQEMUDriver *driver)
/* Using /dev/null for libDir and cacheDir automatically produces errors
* upon attempt to use any of them */
- driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0);
+ driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0, 0);
if (!driver->qemuCapsCache)
goto error;
--
2.17.0
@@ -1,142 +0,0 @@
From ac0e85360cd8f25160b67ee9fb45663d20f82c1d Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 19 Jun 2018 16:51:13 +0100
Subject: [PATCH 17/19] cpu: add CPU features and model for indirect branch
prediction protection
CVE-2017-5715
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/cpu/cpu_map.xml | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
index 8e7ac4973d..c31e7ce36a 100644
--- a/src/cpu/cpu_map.xml
+++ b/src/cpu/cpu_map.xml
@@ -283,6 +283,9 @@
<feature name='avx512-4fmaps'>
<cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000008'/>
</feature>
+ <feature name='spec-ctrl'>
+ <cpuid eax_in='0x07' ecx_in='0x00' edx='0x04000000'/>
+ </feature>
<!-- Processor Extended State Enumeration sub leaf 1 -->
<feature name='xsaveopt'>
@@ -411,6 +414,11 @@
<cpuid eax_in='0x80000007' edx='0x00000100'/>
</feature>
+ <!-- More AMD-specific features -->
+ <feature name='ibpb'>
+ <cpuid eax_in='0x80000008' ebx='0x00001000'/>
+ </feature>
+
<!-- models -->
<model name='486'>
<feature name='fpu'/>
@@ -857,6 +865,10 @@
<feature name='syscall'/>
<feature name='tsc'/>
</model>
+ <model name='Nehalem-IBRS'>
+ <model name='Nehalem'/>
+ <feature name='spec-ctrl'/>
+ </model>
<model name='Westmere'>
<signature family='6' model='44'/>
@@ -894,6 +906,10 @@
<feature name='syscall'/>
<feature name='tsc'/>
</model>
+ <model name='Westmere-IBRS'>
+ <model name='Westmere'/>
+ <feature name='spec-ctrl'/>
+ </model>
<model name='SandyBridge'>
<signature family='6' model='42'/>
@@ -937,6 +953,10 @@
<feature name='x2apic'/>
<feature name='xsave'/>
</model>
+ <model name='SandyBridge-IBRS'>
+ <model name='SandyBridge'/>
+ <feature name='spec-ctrl'/>
+ </model>
<model name='IvyBridge'>
<signature family='6' model='58'/>
@@ -986,6 +1006,10 @@
<feature name='x2apic'/>
<feature name='xsave'/>
</model>
+ <model name='IvyBridge-IBRS'>
+ <model name='IvyBridge'/>
+ <feature name='spec-ctrl'/>
+ </model>
<model name='Haswell-noTSX'>
<signature family='6' model='60'/>
@@ -1039,6 +1063,10 @@
<feature name='x2apic'/>
<feature name='xsave'/>
</model>
+ <model name='Haswell-noTSX-IBRS'>
+ <model name='Haswell-noTSX'/>
+ <feature name='spec-ctrl'/>
+ </model>
<model name='Haswell'>
<signature family='6' model='60'/>
@@ -1094,6 +1122,10 @@
<feature name='x2apic'/>
<feature name='xsave'/>
</model>
+ <model name='Haswell-IBRS'>
+ <model name='Haswell'/>
+ <feature name='spec-ctrl'/>
+ </model>
<model name='Broadwell-noTSX'>
<signature family='6' model='61'/>
@@ -1151,6 +1183,10 @@
<feature name='x2apic'/>
<feature name='xsave'/>
</model>
+ <model name='Broadwell-noTSX-IBRS'>
+ <model name='Broadwell-noTSX'/>
+ <feature name='spec-ctrl'/>
+ </model>
<model name='Broadwell'>
<signature family='6' model='61'/>
@@ -1210,6 +1246,10 @@
<feature name='x2apic'/>
<feature name='xsave'/>
</model>
+ <model name='Broadwell-IBRS'>
+ <model name='Broadwell'/>
+ <feature name='spec-ctrl'/>
+ </model>
<model name='Skylake-Client'>
<signature family='6' model='94'/>
@@ -1278,6 +1318,10 @@
<feature name='xsavec'/>
<feature name='xsaveopt'/>
</model>
+ <model name='Skylake-Client-IBRS'>
+ <model name='Skylake-Client'/>
+ <feature name='spec-ctrl'/>
+ </model>
<!-- AMD CPUs -->
<model name='athlon'>
--
2.17.0
@@ -1,37 +0,0 @@
From 9a252992aa81b4873b22f174de9d345f4289051c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Mon, 21 May 2018 23:05:07 +0100
Subject: [PATCH 18/19] cpu: define the 'ssbd' CPUID feature bit
(CVE-2018-3639)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
New microcode introduces the "Speculative Store Bypass Disable"
CPUID feature bit. This needs to be exposed to guest OS to allow
them to protect against CVE-2018-3639.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 1dbca2eccad58d91a5fd33962854f1a653638182)
---
src/cpu/cpu_map.xml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
index c31e7ce36a..87301dc0ef 100644
--- a/src/cpu/cpu_map.xml
+++ b/src/cpu/cpu_map.xml
@@ -286,6 +286,9 @@
<feature name='spec-ctrl'>
<cpuid eax_in='0x07' ecx_in='0x00' edx='0x04000000'/>
</feature>
+ <feature name='ssbd'>
+ <cpuid eax_in='0x07' ecx_in='0x00' edx='0x80000000'/>
+ </feature>
<!-- Processor Extended State Enumeration sub leaf 1 -->
<feature name='xsaveopt'>
--
2.17.0
@@ -1,46 +0,0 @@
From 7774fbbda1c886633eaf0015d6211fc0ad703bc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Mon, 21 May 2018 23:05:08 +0100
Subject: [PATCH 19/19] cpu: define the 'virt-ssbd' CPUID feature bit
(CVE-2018-3639)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some AMD processors only support a non-architectural means of
enabling Speculative Store Bypass Disable. To allow simplified
handling in virtual environments, hypervisors will expose an
architectural definition through CPUID bit 0x80000008_EBX[25].
This needs to be exposed to guest OS running on AMD x86 hosts to
allow them to protect against CVE-2018-3639.
Note that since this CPUID bit won't be present in the host CPUID
results on physical hosts, it will not be enabled automatically
in guests configured with "host-model" CPU unless using QEMU
version >= 2.9.0. Thus for older versions of QEMU, this feature
must be manually enabled using policy=force. Guests using the
"host-passthrough" CPU mode do not need special handling.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
---
src/cpu/cpu_map.xml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
index 87301dc0ef..e31c9ae86c 100644
--- a/src/cpu/cpu_map.xml
+++ b/src/cpu/cpu_map.xml
@@ -421,6 +421,9 @@
<feature name='ibpb'>
<cpuid eax_in='0x80000008' ebx='0x00001000'/>
</feature>
+ <feature name='virt-ssbd'>
+ <cpuid eax_in='0x80000008' ebx='0x02000000'/>
+ </feature>
<!-- models -->
<model name='486'>
--
2.17.0
+69 -87
View File
@@ -13,7 +13,7 @@
# Default to skipping autoreconf. Distros can change just this one line
# (or provide a command-line override) if they backport any patches that
# touch configure.ac or Makefile.am.
%{!?enable_autotools:%global enable_autotools 1}
%{!?enable_autotools:%global enable_autotools 0}
# The hypervisor drivers that run in libvirtd
@@ -185,11 +185,6 @@
%if 0%{?fedora}
%define with_wireshark 0%{!?_without_wireshark:1}
%endif
%if 0%{?fedora} || 0%{?rhel} > 7
%define wireshark_plugindir %(pkg-config --variable plugindir wireshark)
%else
%define wireshark_plugindir %{_libdir}/wireshark/plugins
%endif
# Enable libssh transport for new enough distros
%if 0%{?fedora}
@@ -244,58 +239,57 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 3.7.0
Release: 6%{?dist}%{?extra_release}
Version: 3.2.1
Release: 7%{?dist}%{?extra_release}
License: LGPLv2+
Group: Development/Libraries
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
URL: https://libvirt.org/
URL: http://libvirt.org/
%if %(echo %{version} | grep -q "\.0$"; echo $?) == 1
%define mainturl stable_updates/
%endif
Source: https://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.xz
Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.xz
# Fix aarch64 gic default for non-kvm VMs (bz #1449837)
Patch0001: 0001-tests-Check-default-GIC-version-for-aarch64-virt-TCG.patch
Patch0002: 0002-qemu-Use-GICv2-for-aarch64-virt-TCG-guests.patch
Patch0003: 0003-gic-Remove-VIR_GIC_VERSION_DEFAULT.patch
# Fix resuming qemu VMs suspended before libvirt 3.2.0
Patch0004: 0004-Revert-qemu-propagate-bridge-MTU-into-qemu-host_mtu-.patch
# Fix issues with AMD CPU models, and some others
Patch0005: 0005-cpu-Introduce-virCPUCopyMigratable.patch
Patch0006: 0006-qemu-Move-common-code-in-virQEMUCapsInitCPUModel-one.patch
Patch0007: 0007-qemu-Add-migratable-parameter-to-virQEMUCapsInitCPUM.patch
Patch0008: 0008-qemu-Introduce-virQEMUCapsSetHostModel.patch
Patch0009: 0009-qemu-Move-qemuCaps-CPU-data-copying-into-a-separate-.patch
Patch0010: 0010-qemu-Introduce-virQEMUCapsHostCPUDataClear.patch
Patch0011: 0011-qemu-Move-qemuCaps-host-CPU-data-in-a-struct.patch
Patch0012: 0012-qemu-Prepare-qemuCaps-for-multiple-host-CPU-defs.patch
Patch0013: 0013-qemu-Pass-migratable-host-CPU-model-to-virCPUUpdate.patch
Patch0014: 0014-cpu-Drop-feature-filtering-from-virCPUUpdate.patch
Patch0015: 0015-cpu-Introduce-virCPUGetHostIsSupported.patch
Patch0016: 0016-qemu-Use-more-data-for-comparing-CPUs.patch
# Enable ZFS storage driver (bz #1471912)
Patch0101: 0101-spec-Add-support-for-building-the-zfs-storage-driver.patch
# Don't use cgroup mount points from /proc/mounts that are hidden (bz
# #1470593)
Patch0102: 0102-Avoid-hidden-cgroup-mount-points.patch
# disk driver name=... should be optional (bz #1473091)
Patch0103: 0103-docs-schema-make-disk-driver-name-attribute-optional.patch
# Fix TPM2 passthrough (bz #1486240)
Patch0001: 0001-tpm-Use-dev-null-for-cancel-path-if-none-was-found.patch
Patch0104: 0104-tpm-Use-dev-null-for-cancel-path-if-none-was-found.patch
# Fix spice GL qemu:///system rendernode permissions (bz #1460804)
Patch0002: 0002-security-add-MANAGER_MOUNT_NAMESPACE-flag.patch
Patch0003: 0003-security-dac-relabel-spice-rendernode.patch
Patch0105: 0105-security-add-MANAGER_MOUNT_NAMESPACE-flag.patch
Patch0106: 0106-security-dac-relabel-spice-rendernode.patch
# Fix on_reboot=destroy setting (bz #1476866)
Patch0107: 0107-qemu-Honour-on_reboot.patch
# Fix disk images in /dev/shm (bz #1482146)
Patch0108: 0108-qemuDomainBuildNamespace-Move-dev-mountpoints-later.patch
# CVE-2017-1000256: libvirt: TLS certificate verification disabled for
# clients (bz #1503687)
Patch0004: 0004-qemu-ensure-TLS-clients-always-verify-the-server-cer.patch
# Fix qemu image locking with shared disks (bz #1513447)
Patch0005: 0005-qemu-Move-snapshot-disk-validation-functions-into-on.patch
Patch0006: 0006-qemu-block-Add-function-to-check-if-storage-source-a.patch
Patch0007: 0007-qemu-domain-Reject-shared-disk-access-if-backing-for.patch
Patch0008: 0008-qemu-snapshot-Disallow-snapshot-of-unsupported-share.patch
Patch0009: 0009-qemu-Disallow-pivot-of-shared-disks-to-unsupported-s.patch
Patch0010: 0010-qemu-caps-Add-capability-for-share-rw-disk-option.patch
Patch0011: 0011-qemu-command-Mark-shared-disks-as-such-in-qemu.patch
# CVE-2018-5748: resource exhaustion via qemuMonitorIORead() (bz #1535785)
Patch0101: 0101-util-probe-Add-quiet-versions-of-the-PROBE-macro.patch
Patch0102: 0102-qemu-monitor-Decrease-logging-verbosity.patch
# CVE-2018-6764: code injection via libvirt_lxc (bz #1542815)
Patch0103: 0103-virlog-determine-the-hostname-on-startup-CVE-2018-67.patch
Patch0104: 0104-util-Fix-syntax-check.patch
Patch0105: 0105-log-fix-deadlock-obtaining-hostname-related-CVE-2018.patch
# Fix hotplug disk failure (bz #1540872)
Patch0106: 0106-qemuDomainAttachDeviceMknodHelper-Remove-symlink-bef.patch
# nwfilter: increase pcap buffer size to be compatible with TPACKET_V3 (bz
# #1547237)
Patch0107: 0107-nwfilter-increase-pcap-buffer-size-to-be-compatible-.patch
# Spectre / SSBD
Patch1000: 1000-util-add-virFileReadHeaderQuiet-wrapper-around-virFi.patch
Patch1001: 1001-cpu_x86-Copy-CPU-signature-from-ancestor.patch
Patch1002: 1002-util-introduce-virHostCPUGetMicrocodeVersion.patch
Patch1003: 1003-cpu_x86-Rename-virCPUx86MapInitialize.patch
Patch1004: 1004-conf-include-x86-microcode-version-in-virsh-capabilt.patch
Patch1005: 1005-qemu-capabilities-force-update-if-the-microcode-vers.patch
Patch1006: 1006-cpu-add-CPU-features-and-model-for-indirect-branch-p.patch
Patch1007: 1007-cpu-define-the-ssbd-CPUID-feature-bit-CVE-2018-3639.patch
Patch1008: 1008-cpu-define-the-virt-ssbd-CPUID-feature-bit-CVE-2018-.patch
Patch0109: 0109-qemu-ensure-TLS-clients-always-verify-the-server-cer.patch
Requires: libvirt-daemon = %{version}-%{release}
Requires: libvirt-daemon-config-network = %{version}-%{release}
@@ -338,11 +332,7 @@ BuildRequires: libtool
BuildRequires: /usr/bin/pod2man
%endif
BuildRequires: git
%if 0%{?fedora} >= 27
BuildRequires: perl-interpreter
%else
BuildRequires: perl
%endif
BuildRequires: python
%if %{with_systemd}
BuildRequires: systemd-units
@@ -351,6 +341,7 @@ BuildRequires: systemd-units
BuildRequires: xen-devel
%endif
BuildRequires: libxml2-devel
BuildRequires: xhtml1-dtds
BuildRequires: libxslt
BuildRequires: readline-devel
BuildRequires: ncurses-devel
@@ -1434,7 +1425,13 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/connection-driver/*.a
rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/storage-backend/*.la
rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/storage-backend/*.a
%if %{with_wireshark}
rm -f $RPM_BUILD_ROOT%{wireshark_plugindir}/libvirt.la
%if 0%{fedora} >= 24
rm -f $RPM_BUILD_ROOT%{_libdir}/wireshark/plugins/libvirt.la
%else
rm -f $RPM_BUILD_ROOT%{_libdir}/wireshark/plugins/*/libvirt.la
mv $RPM_BUILD_ROOT%{_libdir}/wireshark/plugins/*/libvirt.so \
$RPM_BUILD_ROOT%{_libdir}/wireshark/plugins/libvirt.so
%endif
%endif
install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/lib/libvirt/dnsmasq/
@@ -1863,7 +1860,6 @@ exit 0
%{_mandir}/man8/libvirtd.8*
%{_mandir}/man8/virtlogd.8*
%{_mandir}/man8/virtlockd.8*
%{_mandir}/man7/virkey*.7*
%doc examples/polkit/*.rules
@@ -2109,7 +2105,7 @@ exit 0
%if %{with_wireshark}
%files wireshark
%{wireshark_plugindir}/libvirt.so
%{_libdir}/wireshark/plugins/libvirt.so
%endif
%files nss
@@ -2161,50 +2157,36 @@ exit 0
%changelog
* Tue Jul 03 2018 Cole Robinson <crobinso@redhat.com> - 3.7.0-6
- nwfilter: increase pcap buffer size to be compatible with TPACKET_V3 (bz
#1547237)
* Wed Jun 20 2018 Daniel P. Berrangé <berrange@redhat.com> - 3.7.0-5
- Add new CPU features for CVE-2017-5715 and CVE-2018-3639
* Tue Feb 13 2018 Cole Robinson <crobinso@redhat.com> - 3.7.0-4
- CVE-2018-5748: resource exhaustion via qemuMonitorIORead() (bz #1535785)
- CVE-2018-6764: code injection via libvirt_lxc (bz #1542815)
- Fix hotplug disk failure (bz #1540872)
* Mon Dec 04 2017 Cole Robinson <crobinso@redhat.com> - 3.7.0-3
* Mon Dec 04 2017 Cole Robinson <crobinso@redhat.com> - 3.2.1-7
- CVE-2017-1000256: libvirt: TLS certificate verification disabled for
clients (bz #1503687)
- Fix qemu image locking with shared disks (bz #1513447)
* Fri Sep 15 2017 Cole Robinson <crobinso@redhat.com> - 3.7.0-2
* Fri Sep 15 2017 Cole Robinson <crobinso@redhat.com> - 3.2.1-6
- Fix TPM2 passthrough (bz #1486240)
- Fix spice GL qemu:///system rendernode permissions (bz #1460804)
- Fix on_reboot=destroy setting (bz #1476866)
- Fix disk images in /dev/shm (bz #1482146)
* Mon Sep 4 2017 Daniel P. Berrange <berrange@redhat.com> - 3.7.0-1
- Rebase to version 3.7.0
* Fri Aug 04 2017 Cole Robinson <crobinso@redhat.com> - 3.2.1-5
- Enable ZFS storage driver (bz #1471912)
- Don't use cgroup mount points from /proc/mounts that are hidden (bz
#1470593)
- disk driver name=... should be optional (bz #1473091)
* Wed Aug 2 2017 Daniel P. Berrange <berrange@redhat.com> - 3.6.0-1
- Rebase to version 3.6.0
* Wed Jul 12 2017 Cole Robinson <crobinso@redhat.com> - 3.2.1-4
- Fix resuming qemu VMs suspended before libvirt 3.2.0
- Fix issues with AMD CPU models, and some others
* Sun Jul 30 2017 Florian Weimer <fweimer@redhat.com> - 3.5.0-4
- Rebuild with binutils fix for ppc64le (#1475636)
* Wed May 31 2017 Cole Robinson <crobinso@redhat.com> - 3.2.1-3
- Tweak condition for not starting in live environment (bz #1146232)
* Tue Jul 25 2017 Daniel P. Berrange <berrange@redhat.com> - 3.5.0-3
- Disabled RBD on i386, arm, ppc64 (rhbz #1474743)
* Tue May 30 2017 Cole Robinson <crobinso@redhat.com> - 3.2.1-2
- Fix aarch64 gic default for non-kvm VMs (bz #1449837)
- Don't run libvirtd in live environment, to avoid network collision (bz
#1146232)
* Mon Jul 17 2017 Cole Robinson <crobinso@redhat.com> - 3.5.0-2
- Rebuild for xen 4.9
* Thu Jul 6 2017 Daniel P. Berrange <berrange@redhat.com> - 3.5.0-1
- Rebase to version 3.5.0
* Fri Jun 2 2017 Daniel P. Berrange <berrange@redhat.com> - 3.4.0-1
- Rebase to version 3.4.0
* Mon May 8 2017 Daniel P. Berrange <berrange@redhat.com> - 3.3.0-1
- Rebase to version 3.3.0
* Wed May 10 2017 Cole Robinson <crobinso@redhat.com> - 3.2.1-1
- Rebased to version 3.2.1
* Mon Apr 3 2017 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-1
- Rebase to version 3.2.0
+1 -1
View File
@@ -1 +1 @@
SHA512 (libvirt-3.7.0.tar.xz) = b3f7021ef4c6954430f8fa503f0c49e3df4f662b228cb631ba2c2139ecec2307dde6cec05037cc28663e82ab1001296c20c5c68acd183cd364dd484a7746f498
SHA512 (libvirt-3.2.1.tar.xz) = 4ec4faceedcad3a5419e91444b0c83adcbed0ff6482fb53c058a75412064de69e09fd096de4a30b8c1149da6ba03287b10e8af925b01d725e655658035e43d9a