On 08/12/2016 09:33 AM, Jiri Denemark wrote:
To have a single place where we decide whether a guest can run
natively
on a host.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_capabilities.c | 43 +++++++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 16 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 58a96d4..aeea3a3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -428,6 +428,29 @@ static const char *virQEMUCapsArchToString(virArch arch)
return virArchToString(arch);
}
+
+/* Checks whether a domain with @guest arch can run natively on @host.
+ */
+static bool
+virQEMUCapsGuestIsNative(virArch host,
+ virArch guest)
+{
+ if (host == guest)
+ return true;
+
+ if (host == VIR_ARCH_X86_64 && guest == VIR_ARCH_I686)
+ return true;
+
+ if (host == VIR_ARCH_AARCH64 && guest == VIR_ARCH_ARMV7L)
+ return true;
+
+ if (ARCH_IS_PPC64(host) && ARCH_IS_PPC64(guest))
+ return true;
+
+ return false;
+}
+
+
/* Given a host and guest architectures, find a suitable QEMU target.
*
* This is meant to be used as a second attempt if qemu-system-$guestarch
@@ -441,12 +464,8 @@ virQEMUCapsFindTarget(virArch hostarch,
if (ARCH_IS_PPC64(guestarch))
guestarch = VIR_ARCH_PPC64;
- /* armv7l guests on aarch64 hosts can use the aarch64 target
- * i686 guests on x86_64 hosts can use the x86_64 target */
- if ((guestarch == VIR_ARCH_ARMV7L && hostarch == VIR_ARCH_AARCH64) ||
- (guestarch == VIR_ARCH_I686 && hostarch == VIR_ARCH_X86_64)) {
- return hostarch;
- }
+ if (virQEMUCapsGuestIsNative(hostarch, guestarch))
+ guestarch = hostarch;
return guestarch;
}
@@ -807,7 +826,6 @@ virQEMUCapsInitGuest(virCapsPtr caps,
char *binary = NULL;
virQEMUCapsPtr qemubinCaps = NULL;
virQEMUCapsPtr kvmbinCaps = NULL;
- bool native_kvm, x86_32on64_kvm, arm_32on64_kvm, ppc64_kvm;
int ret = -1;
/* Check for existence of base emulator, or alternate base
@@ -829,14 +847,7 @@ virQEMUCapsInitGuest(virCapsPtr caps,
* - hostarch is aarch64 and guest arch is armv7l (needs -cpu aarch64=off)
* - hostarch and guestarch are both ppc64*
*/
- native_kvm = (hostarch == guestarch);
- x86_32on64_kvm = (hostarch == VIR_ARCH_X86_64 &&
- guestarch == VIR_ARCH_I686);
- arm_32on64_kvm = (hostarch == VIR_ARCH_AARCH64 &&
- guestarch == VIR_ARCH_ARMV7L);
- ppc64_kvm = (ARCH_IS_PPC64(hostarch) && ARCH_IS_PPC64(guestarch));
-
- if (native_kvm || x86_32on64_kvm || arm_32on64_kvm || ppc64_kvm) {
+ if (virQEMUCapsGuestIsNative(hostarch, guestarch)) {
const char *kvmbins[] = {
"/usr/libexec/qemu-kvm", /* RHEL */
"qemu-kvm", /* Fedora */
@@ -852,7 +863,7 @@ virQEMUCapsInitGuest(virCapsPtr caps,
* arm is different in that 32-on-64 _only_ works with
* qemu-system-aarch64. So we have to add it to the kvmbins list
*/
- if (arm_32on64_kvm)
+ if (hostarch == VIR_ARCH_AARCH64 && guestarch == VIR_ARCH_ARMV7L)
kvmbins[3] = "qemu-system-aarch64";
for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
Noted by Coverity in this module - existing I think as well, it's just
that the change piqued Coverity's interest in analyzing things...
At the top of this function we have a:
/* Ignore binary if extracting version info fails */
if (binary) {
if (!(qemubinCaps = virQEMUCapsCacheLookup(cache, binary))) {
virResetLastError();
...
Then there's the replace if condition w/ virQEMUCapsGuestIsNative
followed by a:
ret = virQEMUCapsInitGuestFromBinary(caps,
binary, qemubinCaps,
kvmbin, kvmbinCaps,
guestarch);
where it's noted that virQEMUCapsInitGuestFromBinary will dereference
qemubinCaps in the call to virQEMUCapsGetMachineTypesCaps and it's
possible that qemubinCaps is NULL if "binary" is set. The analysis
doesn't go into the virQEMUCapsGuestIsNative condition. It's also
notable that if !binary is checked in virQEMUCapsInitGuestFromBinary, so
this is somewhat of an "edge" condition.
Whether this is even possible - I'm not even sure!