mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
qemu: Report better host-model CPUs in domain caps
One of the main reasons for introducing host-model CPU definition in a domain capabilities XML was the inability to express disabled features in a host capabilities XML. That is, when a host CPU is, e.g., Haswell without x2apic support, host capabilities XML will have to report it as Westmere + a bunch of additional features., but we really want to use Haswell - x2apic when creating a host-model CPU. Unfortunately, I somehow forgot to do the last step and the code would just copy the CPU definition found in the host capabilities XML. This changed recently for new QEMU versions which allow us to query host CPU, but any slightly older QEMU will not benefit from any change I did. This patch makes sure the right CPU model is filled in the domain capabilities even with old QEMU. The issue was reported in https://bugzilla.redhat.com/show_bug.cgi?id=1426456 Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
4f23862f46
commit
e958fb5b15
@ -1074,6 +1074,26 @@ virQEMUCapsProbeHostCPU(virCapsPtr caps)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virCPUDefPtr
|
||||||
|
virQEMUCapsProbeHostCPUForEmulator(virCapsPtr caps,
|
||||||
|
virQEMUCapsPtr qemuCaps,
|
||||||
|
virDomainVirtType type)
|
||||||
|
{
|
||||||
|
size_t nmodels;
|
||||||
|
char **models;
|
||||||
|
virCPUDefPtr cpu;
|
||||||
|
|
||||||
|
if (virQEMUCapsGetCPUDefinitions(qemuCaps, type, &models, &nmodels) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cpu = virCPUGetHost(caps->host.arch, VIR_CPU_TYPE_GUEST, NULL,
|
||||||
|
(const char **) models, nmodels);
|
||||||
|
|
||||||
|
virStringListFreeCount(models, nmodels);
|
||||||
|
return cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virQEMUCapsInitPages(virCapsPtr caps)
|
virQEMUCapsInitPages(virCapsPtr caps)
|
||||||
{
|
{
|
||||||
@ -3207,6 +3227,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
|||||||
virDomainVirtType type)
|
virDomainVirtType type)
|
||||||
{
|
{
|
||||||
virCPUDefPtr cpu = NULL;
|
virCPUDefPtr cpu = NULL;
|
||||||
|
virCPUDefPtr hostCPU = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
|
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
|
||||||
@ -3223,11 +3244,11 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
|||||||
if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu)) < 0) {
|
if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu)) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
} else if (rc == 1) {
|
} else if (rc == 1) {
|
||||||
VIR_DEBUG("No host CPU model info from QEMU; using host capabilities");
|
VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly");
|
||||||
if (!caps->host.cpu || !caps->host.cpu->model)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (virCPUDefCopyModelFilter(cpu, caps->host.cpu, true,
|
hostCPU = virQEMUCapsProbeHostCPUForEmulator(caps, qemuCaps, type);
|
||||||
|
if (!hostCPU ||
|
||||||
|
virCPUDefCopyModelFilter(cpu, hostCPU, true,
|
||||||
virQEMUCapsCPUFilterFeatures,
|
virQEMUCapsCPUFilterFeatures,
|
||||||
qemuCaps) < 0)
|
qemuCaps) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -3238,11 +3259,14 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
|||||||
else
|
else
|
||||||
qemuCaps->tcgCPUModel = cpu;
|
qemuCaps->tcgCPUModel = cpu;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virCPUDefFree(hostCPU);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
virCPUDefFree(cpu);
|
virCPUDefFree(cpu);
|
||||||
virResetLastError();
|
virResetLastError();
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,4 +87,9 @@ void
|
|||||||
virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
|
virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
|
||||||
virDomainVirtType type,
|
virDomainVirtType type,
|
||||||
qemuMonitorCPUModelInfoPtr modelInfo);
|
qemuMonitorCPUModelInfoPtr modelInfo);
|
||||||
|
|
||||||
|
virCPUDefPtr
|
||||||
|
virQEMUCapsProbeHostCPUForEmulator(virCapsPtr caps,
|
||||||
|
virQEMUCapsPtr qemuCaps,
|
||||||
|
virDomainVirtType type);
|
||||||
#endif
|
#endif
|
||||||
|
@ -284,6 +284,7 @@ test_libraries += libqemumonitortestutils.la \
|
|||||||
qemuxml2xmlmock.la \
|
qemuxml2xmlmock.la \
|
||||||
qemucaps2xmlmock.la \
|
qemucaps2xmlmock.la \
|
||||||
qemucapsprobemock.la \
|
qemucapsprobemock.la \
|
||||||
|
qemucpumock.la \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif WITH_QEMU
|
endif WITH_QEMU
|
||||||
|
|
||||||
@ -549,10 +550,16 @@ libqemutestdriver_la_SOURCES =
|
|||||||
libqemutestdriver_la_LDFLAGS = $(QEMULIB_LDFLAGS)
|
libqemutestdriver_la_LDFLAGS = $(QEMULIB_LDFLAGS)
|
||||||
libqemutestdriver_la_LIBADD = $(qemu_LDADDS)
|
libqemutestdriver_la_LIBADD = $(qemu_LDADDS)
|
||||||
|
|
||||||
|
qemucpumock_la_SOURCES = \
|
||||||
|
qemucpumock.c
|
||||||
|
qemucpumock_la_CFLAGS = $(AM_CFLAGS)
|
||||||
|
qemucpumock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
|
||||||
|
qemucpumock_la_LIBADD = $(MOCKLIBS_LIBS)
|
||||||
|
|
||||||
qemuxml2argvtest_SOURCES = \
|
qemuxml2argvtest_SOURCES = \
|
||||||
qemuxml2argvtest.c testutilsqemu.c testutilsqemu.h \
|
qemuxml2argvtest.c testutilsqemu.c testutilsqemu.h \
|
||||||
testutils.c testutils.h
|
testutils.c testutils.h
|
||||||
qemuxml2argvtest_LDADD = $(qemu_LDADDS) $(LDADDS) $(LIBXML_LIBS)
|
qemuxml2argvtest_LDADD = libqemutestdriver.la $(LDADDS) $(LIBXML_LIBS)
|
||||||
|
|
||||||
qemuxml2argvmock_la_SOURCES = \
|
qemuxml2argvmock_la_SOURCES = \
|
||||||
qemuxml2argvmock.c
|
qemuxml2argvmock.c
|
||||||
@ -949,7 +956,7 @@ domaincapstest_LDADD = $(LDADDS)
|
|||||||
|
|
||||||
if WITH_QEMU
|
if WITH_QEMU
|
||||||
domaincapstest_SOURCES += testutilsqemu.c testutilsqemu.h
|
domaincapstest_SOURCES += testutilsqemu.c testutilsqemu.h
|
||||||
domaincapstest_LDADD += $(qemu_LDADDS) $(GNULIB_LIBS)
|
domaincapstest_LDADD += libqemutestdriver.la $(GNULIB_LIBS)
|
||||||
endif WITH_QEMU
|
endif WITH_QEMU
|
||||||
|
|
||||||
if WITH_LIBXL
|
if WITH_LIBXL
|
||||||
|
@ -491,4 +491,10 @@ mymain(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WITH_QEMU
|
||||||
|
VIRT_TEST_MAIN_PRELOAD(mymain,
|
||||||
|
abs_builddir "/.libs/domaincapsmock.so",
|
||||||
|
abs_builddir "/.libs/qemucpumock.so")
|
||||||
|
#else
|
||||||
VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/domaincapsmock.so")
|
VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/domaincapsmock.so")
|
||||||
|
#endif
|
||||||
|
35
tests/qemucpumock.c
Normal file
35
tests/qemucpumock.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include "qemu/qemu_capabilities.h"
|
||||||
|
#define __QEMU_CAPSRIV_H_ALLOW__
|
||||||
|
#include "qemu/qemu_capspriv.h"
|
||||||
|
#undef __QEMU_CAPSRIV_H_ALLOW__
|
||||||
|
|
||||||
|
|
||||||
|
virCPUDefPtr
|
||||||
|
virQEMUCapsProbeHostCPUForEmulator(virCapsPtr caps,
|
||||||
|
virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
|
||||||
|
virDomainVirtType type ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
if (!caps || !caps->host.cpu || !caps->host.cpu->model)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return virCPUDefCopy(caps->host.cpu);
|
||||||
|
}
|
@ -2473,8 +2473,10 @@ mymain(void)
|
|||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/qemuxml2argvmock.so",
|
VIRT_TEST_MAIN_PRELOAD(mymain,
|
||||||
abs_builddir "/.libs/virrandommock.so")
|
abs_builddir "/.libs/qemuxml2argvmock.so",
|
||||||
|
abs_builddir "/.libs/virrandommock.so",
|
||||||
|
abs_builddir "/.libs/qemucpumock.so")
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user