[PATCH 0/9] qemu: Change CPU comparison algorithm for future models

When starting a domain we check whether the guest CPU definition is compatible with the host (i.e., when the host supports all features required both explicitly and by the specified CPU model) as long as check == 'partial', which is the default. We are doing so by checking our definition of the CPU model in the CPU map amending it with explicitly mentioned features and comparing it to features QEMU would enabled when started with -cpu host. But since our CPU model definitions often slightly differ from QEMU we may be checking features which are not actually needed and on the other hand not checking something that is part of the CPU model in QEMU. This patch changes the algorithm for CPU models added in the future (changing it for existing models could cause them to suddenly become incompatible with the host and domains using them would fail to start). The new algorithm uses information we probe from QEMU about features that block each model from being directly usable. If all those features are explicitly disabled in the CPU definition we consider the base model compatible with the host. Then we only need to check that all explicitly required features are supported by QEMU on the host to get the result for the whole CPU definition. After this we only use the model definitions (for newly added models) from CPU map for creating a CPU definition for host-model. Jiri Denemark (9): cpu_x86: Introduce <check> element for CPU models cpu_map: Use compat partial check for all x86 CPU models cpu: Introduce virCPUGetCheckMode qemu: Use g_autoptr in qemuConnectCompareHypervisorCPU qemu: Use virCPUCompare in qemuConnectCompareHypervisorCPU directly qemu: Separate partial CPU check into a function cpu: Introduce virCPUCompareUnusable qemu_capabilities: Introduce virQEMUCapsGetCPUBlockers qemu: Change CPU comparison algorithm for future models src/cpu/cpu.c | 104 ++++++++++++++++++ src/cpu/cpu.h | 17 +++ src/cpu/cpu_x86.c | 67 +++++++++++ src/cpu_map/x86_486.xml | 1 + src/cpu_map/x86_Broadwell-IBRS.xml | 1 + src/cpu_map/x86_Broadwell-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Broadwell-noTSX.xml | 1 + src/cpu_map/x86_Broadwell.xml | 1 + src/cpu_map/x86_Cascadelake-Server-noTSX.xml | 1 + src/cpu_map/x86_Cascadelake-Server.xml | 1 + src/cpu_map/x86_Conroe.xml | 1 + src/cpu_map/x86_Cooperlake.xml | 1 + src/cpu_map/x86_Dhyana.xml | 1 + src/cpu_map/x86_EPYC-Genoa.xml | 1 + src/cpu_map/x86_EPYC-IBPB.xml | 1 + src/cpu_map/x86_EPYC-Milan.xml | 1 + src/cpu_map/x86_EPYC-Rome.xml | 1 + src/cpu_map/x86_EPYC.xml | 1 + src/cpu_map/x86_GraniteRapids.xml | 1 + src/cpu_map/x86_Haswell-IBRS.xml | 1 + src/cpu_map/x86_Haswell-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Haswell-noTSX.xml | 1 + src/cpu_map/x86_Haswell.xml | 1 + src/cpu_map/x86_Icelake-Client-noTSX.xml | 1 + src/cpu_map/x86_Icelake-Client.xml | 1 + src/cpu_map/x86_Icelake-Server-noTSX.xml | 1 + src/cpu_map/x86_Icelake-Server.xml | 1 + src/cpu_map/x86_IvyBridge-IBRS.xml | 1 + src/cpu_map/x86_IvyBridge.xml | 1 + src/cpu_map/x86_Nehalem-IBRS.xml | 1 + src/cpu_map/x86_Nehalem.xml | 1 + src/cpu_map/x86_Opteron_G1.xml | 1 + src/cpu_map/x86_Opteron_G2.xml | 1 + src/cpu_map/x86_Opteron_G3.xml | 1 + src/cpu_map/x86_Opteron_G4.xml | 1 + src/cpu_map/x86_Opteron_G5.xml | 1 + src/cpu_map/x86_Penryn.xml | 1 + src/cpu_map/x86_SandyBridge-IBRS.xml | 1 + src/cpu_map/x86_SandyBridge.xml | 1 + src/cpu_map/x86_SapphireRapids.xml | 1 + src/cpu_map/x86_SierraForest.xml | 1 + src/cpu_map/x86_Skylake-Client-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Client.xml | 1 + src/cpu_map/x86_Skylake-Server-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Server.xml | 1 + src/cpu_map/x86_Snowridge.xml | 1 + src/cpu_map/x86_Westmere-IBRS.xml | 1 + src/cpu_map/x86_Westmere.xml | 1 + src/cpu_map/x86_athlon.xml | 1 + src/cpu_map/x86_core2duo.xml | 1 + src/cpu_map/x86_coreduo.xml | 1 + src/cpu_map/x86_cpu64-rhel5.xml | 1 + src/cpu_map/x86_cpu64-rhel6.xml | 1 + src/cpu_map/x86_kvm32.xml | 1 + src/cpu_map/x86_kvm64.xml | 1 + src/cpu_map/x86_n270.xml | 1 + src/cpu_map/x86_pentium.xml | 1 + src/cpu_map/x86_pentium2.xml | 1 + src/cpu_map/x86_pentium3.xml | 1 + src/cpu_map/x86_pentiumpro.xml | 1 + src/cpu_map/x86_phenom.xml | 1 + src/cpu_map/x86_qemu32.xml | 1 + src/cpu_map/x86_qemu64.xml | 1 + src/libvirt_private.syms | 2 + src/qemu/qemu_capabilities.c | 38 +++++++ src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_domain.c | 65 +++++++++++ src/qemu/qemu_domain.h | 7 ++ src/qemu/qemu_driver.c | 45 ++++---- src/qemu/qemu_process.c | 7 +- 72 files changed, 390 insertions(+), 28 deletions(-) -- 2.47.0

CPU models in the CPU map may be marked with <check partial="compat"/> to indicate a backward compatible partial check (comparing our definition of the model with the host CPU) should be performed. Other models will be checked using just runnability info from QEMU. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/cpu/cpu_x86.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 7cf158e25b..70893f8a62 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -150,6 +150,7 @@ struct _virCPUx86Model { char *name; bool decodeHost; bool decodeGuest; + bool compatCheck; virCPUx86Vendor *vendor; virCPUx86Signatures *signatures; virCPUx86Data data; @@ -1463,6 +1464,36 @@ x86ModelCompare(virCPUx86Model *model1, } +static int +x86ModelParseCheck(virCPUx86Model *model, + xmlXPathContextPtr ctxt) +{ + g_autofree char *check = NULL; + int rc; + + if ((rc = virXPathBoolean("boolean(./check)", ctxt)) <= 0) + return rc; + + check = virXPathString("string(./check/@partial)", ctxt); + if (!check) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing check/@partial in CPU model %1$s"), + model->name); + return -1; + } + + if (STRNEQ(check, "compat")) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid check/@partial value '%1$s' in CPU model %2$s"), + check, model->name); + return -1; + } + + model->compatCheck = true; + return 0; +} + + static int x86ModelParseDecode(virCPUx86Model *model, xmlXPathContextPtr ctxt) @@ -1693,6 +1724,9 @@ x86ModelParse(xmlXPathContextPtr ctxt, model = g_new0(virCPUx86Model, 1); model->name = g_strdup(name); + if (x86ModelParseCheck(model, ctxt) < 0) + return -1; + if (x86ModelParseDecode(model, ctxt) < 0) return -1; -- 2.47.0

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/cpu_map/x86_486.xml | 1 + src/cpu_map/x86_Broadwell-IBRS.xml | 1 + src/cpu_map/x86_Broadwell-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Broadwell-noTSX.xml | 1 + src/cpu_map/x86_Broadwell.xml | 1 + src/cpu_map/x86_Cascadelake-Server-noTSX.xml | 1 + src/cpu_map/x86_Cascadelake-Server.xml | 1 + src/cpu_map/x86_Conroe.xml | 1 + src/cpu_map/x86_Cooperlake.xml | 1 + src/cpu_map/x86_Dhyana.xml | 1 + src/cpu_map/x86_EPYC-Genoa.xml | 1 + src/cpu_map/x86_EPYC-IBPB.xml | 1 + src/cpu_map/x86_EPYC-Milan.xml | 1 + src/cpu_map/x86_EPYC-Rome.xml | 1 + src/cpu_map/x86_EPYC.xml | 1 + src/cpu_map/x86_GraniteRapids.xml | 1 + src/cpu_map/x86_Haswell-IBRS.xml | 1 + src/cpu_map/x86_Haswell-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Haswell-noTSX.xml | 1 + src/cpu_map/x86_Haswell.xml | 1 + src/cpu_map/x86_Icelake-Client-noTSX.xml | 1 + src/cpu_map/x86_Icelake-Client.xml | 1 + src/cpu_map/x86_Icelake-Server-noTSX.xml | 1 + src/cpu_map/x86_Icelake-Server.xml | 1 + src/cpu_map/x86_IvyBridge-IBRS.xml | 1 + src/cpu_map/x86_IvyBridge.xml | 1 + src/cpu_map/x86_Nehalem-IBRS.xml | 1 + src/cpu_map/x86_Nehalem.xml | 1 + src/cpu_map/x86_Opteron_G1.xml | 1 + src/cpu_map/x86_Opteron_G2.xml | 1 + src/cpu_map/x86_Opteron_G3.xml | 1 + src/cpu_map/x86_Opteron_G4.xml | 1 + src/cpu_map/x86_Opteron_G5.xml | 1 + src/cpu_map/x86_Penryn.xml | 1 + src/cpu_map/x86_SandyBridge-IBRS.xml | 1 + src/cpu_map/x86_SandyBridge.xml | 1 + src/cpu_map/x86_SapphireRapids.xml | 1 + src/cpu_map/x86_SierraForest.xml | 1 + src/cpu_map/x86_Skylake-Client-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Client.xml | 1 + src/cpu_map/x86_Skylake-Server-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Server.xml | 1 + src/cpu_map/x86_Snowridge.xml | 1 + src/cpu_map/x86_Westmere-IBRS.xml | 1 + src/cpu_map/x86_Westmere.xml | 1 + src/cpu_map/x86_athlon.xml | 1 + src/cpu_map/x86_core2duo.xml | 1 + src/cpu_map/x86_coreduo.xml | 1 + src/cpu_map/x86_cpu64-rhel5.xml | 1 + src/cpu_map/x86_cpu64-rhel6.xml | 1 + src/cpu_map/x86_kvm32.xml | 1 + src/cpu_map/x86_kvm64.xml | 1 + src/cpu_map/x86_n270.xml | 1 + src/cpu_map/x86_pentium.xml | 1 + src/cpu_map/x86_pentium2.xml | 1 + src/cpu_map/x86_pentium3.xml | 1 + src/cpu_map/x86_pentiumpro.xml | 1 + src/cpu_map/x86_phenom.xml | 1 + src/cpu_map/x86_qemu32.xml | 1 + src/cpu_map/x86_qemu64.xml | 1 + 62 files changed, 62 insertions(+) diff --git a/src/cpu_map/x86_486.xml b/src/cpu_map/x86_486.xml index d05b277392..7aeac147ae 100644 --- a/src/cpu_map/x86_486.xml +++ b/src/cpu_map/x86_486.xml @@ -1,5 +1,6 @@ <cpus> <model name='486'> + <check partial='compat'/> <decode host='on' guest='on'/> <feature name='fpu'/> <feature name='pse'/> diff --git a/src/cpu_map/x86_Broadwell-IBRS.xml b/src/cpu_map/x86_Broadwell-IBRS.xml index 4845931420..a52db94023 100644 --- a/src/cpu_map/x86_Broadwell-IBRS.xml +++ b/src/cpu_map/x86_Broadwell-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Broadwell-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='61'/> <!-- 0306d0 --> <signature family='6' model='71'/> <!-- 040670 --> diff --git a/src/cpu_map/x86_Broadwell-noTSX-IBRS.xml b/src/cpu_map/x86_Broadwell-noTSX-IBRS.xml index b1e7aa5d5e..2f4aaeb079 100644 --- a/src/cpu_map/x86_Broadwell-noTSX-IBRS.xml +++ b/src/cpu_map/x86_Broadwell-noTSX-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Broadwell-noTSX-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='61'/> <!-- 0306d0 --> <signature family='6' model='71'/> <!-- 040670 --> diff --git a/src/cpu_map/x86_Broadwell-noTSX.xml b/src/cpu_map/x86_Broadwell-noTSX.xml index 24aa6a37bd..82f2d6d9cc 100644 --- a/src/cpu_map/x86_Broadwell-noTSX.xml +++ b/src/cpu_map/x86_Broadwell-noTSX.xml @@ -1,5 +1,6 @@ <cpus> <model name='Broadwell-noTSX'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='61'/> <!-- 0306d0 --> <signature family='6' model='71'/> <!-- 040670 --> diff --git a/src/cpu_map/x86_Broadwell.xml b/src/cpu_map/x86_Broadwell.xml index 1b27489db2..53e762f74e 100644 --- a/src/cpu_map/x86_Broadwell.xml +++ b/src/cpu_map/x86_Broadwell.xml @@ -1,5 +1,6 @@ <cpus> <model name='Broadwell'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='61'/> <!-- 0306d0 --> <signature family='6' model='71'/> <!-- 040670 --> diff --git a/src/cpu_map/x86_Cascadelake-Server-noTSX.xml b/src/cpu_map/x86_Cascadelake-Server-noTSX.xml index d1d49fdd58..3c2325562f 100644 --- a/src/cpu_map/x86_Cascadelake-Server-noTSX.xml +++ b/src/cpu_map/x86_Cascadelake-Server-noTSX.xml @@ -1,5 +1,6 @@ <cpus> <model name='Cascadelake-Server-noTSX'> + <check partial='compat'/> <decode host='on' guest='off'/> <signature family='6' model='85' stepping='5-7'/> <!-- 050654 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Cascadelake-Server.xml b/src/cpu_map/x86_Cascadelake-Server.xml index 09840ce52f..1463982add 100644 --- a/src/cpu_map/x86_Cascadelake-Server.xml +++ b/src/cpu_map/x86_Cascadelake-Server.xml @@ -1,5 +1,6 @@ <cpus> <model name='Cascadelake-Server'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='85' stepping='5-7'/> <!-- 050654 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Conroe.xml b/src/cpu_map/x86_Conroe.xml index 955297ffc3..b187dd5034 100644 --- a/src/cpu_map/x86_Conroe.xml +++ b/src/cpu_map/x86_Conroe.xml @@ -1,5 +1,6 @@ <cpus> <model name='Conroe'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='15'/> <!-- 0006f0 --> <signature family='6' model='22'/> <!-- 010660 --> diff --git a/src/cpu_map/x86_Cooperlake.xml b/src/cpu_map/x86_Cooperlake.xml index 8f37df60de..acb46eaf8a 100644 --- a/src/cpu_map/x86_Cooperlake.xml +++ b/src/cpu_map/x86_Cooperlake.xml @@ -1,5 +1,6 @@ <cpus> <model name='Cooperlake'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='85' stepping='10-11'/> <!-- 05065b --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Dhyana.xml b/src/cpu_map/x86_Dhyana.xml index cfde07f99f..4ee32877f7 100644 --- a/src/cpu_map/x86_Dhyana.xml +++ b/src/cpu_map/x86_Dhyana.xml @@ -1,5 +1,6 @@ <cpus> <model name='Dhyana'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='24' model='0'/> <!-- 900f00 --> <vendor name='Hygon'/> diff --git a/src/cpu_map/x86_EPYC-Genoa.xml b/src/cpu_map/x86_EPYC-Genoa.xml index 3e765b89b1..d87a01fd16 100644 --- a/src/cpu_map/x86_EPYC-Genoa.xml +++ b/src/cpu_map/x86_EPYC-Genoa.xml @@ -1,5 +1,6 @@ <cpus> <model name='EPYC-Genoa'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='25' model='17'/> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_EPYC-IBPB.xml b/src/cpu_map/x86_EPYC-IBPB.xml index fc5aadf52e..bb1eedf567 100644 --- a/src/cpu_map/x86_EPYC-IBPB.xml +++ b/src/cpu_map/x86_EPYC-IBPB.xml @@ -1,5 +1,6 @@ <cpus> <model name='EPYC-IBPB'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='23' model='1'/> <!-- 800f10 --> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_EPYC-Milan.xml b/src/cpu_map/x86_EPYC-Milan.xml index 3055e175fa..6849ded9aa 100644 --- a/src/cpu_map/x86_EPYC-Milan.xml +++ b/src/cpu_map/x86_EPYC-Milan.xml @@ -1,5 +1,6 @@ <cpus> <model name='EPYC-Milan'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='25' model='1'/> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_EPYC-Rome.xml b/src/cpu_map/x86_EPYC-Rome.xml index e54d0a48d8..355f8368ce 100644 --- a/src/cpu_map/x86_EPYC-Rome.xml +++ b/src/cpu_map/x86_EPYC-Rome.xml @@ -1,5 +1,6 @@ <cpus> <model name='EPYC-Rome'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='23' model='49'/> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_EPYC.xml b/src/cpu_map/x86_EPYC.xml index 3b406de37a..9b47fbba5b 100644 --- a/src/cpu_map/x86_EPYC.xml +++ b/src/cpu_map/x86_EPYC.xml @@ -1,5 +1,6 @@ <cpus> <model name='EPYC'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='23' model='1'/> <!-- 800f10 --> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_GraniteRapids.xml b/src/cpu_map/x86_GraniteRapids.xml index 9a94476459..68491a7bc1 100644 --- a/src/cpu_map/x86_GraniteRapids.xml +++ b/src/cpu_map/x86_GraniteRapids.xml @@ -1,5 +1,6 @@ <cpus> <model name='GraniteRapids'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='173'/> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Haswell-IBRS.xml b/src/cpu_map/x86_Haswell-IBRS.xml index 0fed6fbb78..e5b88758ad 100644 --- a/src/cpu_map/x86_Haswell-IBRS.xml +++ b/src/cpu_map/x86_Haswell-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Haswell-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='60'/> <!-- 0306c0 --> <signature family='6' model='63'/> <!-- 0306f0 --> diff --git a/src/cpu_map/x86_Haswell-noTSX-IBRS.xml b/src/cpu_map/x86_Haswell-noTSX-IBRS.xml index f7bc81ba4d..0a2e7dc17c 100644 --- a/src/cpu_map/x86_Haswell-noTSX-IBRS.xml +++ b/src/cpu_map/x86_Haswell-noTSX-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Haswell-noTSX-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='60'/> <!-- 0306c0 --> <signature family='6' model='63'/> <!-- 0306f0 --> diff --git a/src/cpu_map/x86_Haswell-noTSX.xml b/src/cpu_map/x86_Haswell-noTSX.xml index 7d17911917..9e16212c04 100644 --- a/src/cpu_map/x86_Haswell-noTSX.xml +++ b/src/cpu_map/x86_Haswell-noTSX.xml @@ -1,5 +1,6 @@ <cpus> <model name='Haswell-noTSX'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='60'/> <!-- 0306c0 --> <signature family='6' model='63'/> <!-- 0306f0 --> diff --git a/src/cpu_map/x86_Haswell.xml b/src/cpu_map/x86_Haswell.xml index b121e15d4d..3e52976240 100644 --- a/src/cpu_map/x86_Haswell.xml +++ b/src/cpu_map/x86_Haswell.xml @@ -1,5 +1,6 @@ <cpus> <model name='Haswell'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='60'/> <!-- 0306c0 --> <signature family='6' model='63'/> <!-- 0306f0 --> diff --git a/src/cpu_map/x86_Icelake-Client-noTSX.xml b/src/cpu_map/x86_Icelake-Client-noTSX.xml index 217adba4f2..3c61372ca3 100644 --- a/src/cpu_map/x86_Icelake-Client-noTSX.xml +++ b/src/cpu_map/x86_Icelake-Client-noTSX.xml @@ -1,5 +1,6 @@ <cpus> <model name='Icelake-Client-noTSX'> + <check partial='compat'/> <decode host='on' guest='off'/> <signature family='6' model='126'/> <!-- 0706e0 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Icelake-Client.xml b/src/cpu_map/x86_Icelake-Client.xml index b725227f46..dd777f36b7 100644 --- a/src/cpu_map/x86_Icelake-Client.xml +++ b/src/cpu_map/x86_Icelake-Client.xml @@ -1,5 +1,6 @@ <cpus> <model name='Icelake-Client'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='126'/> <!-- 0706e0 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Icelake-Server-noTSX.xml b/src/cpu_map/x86_Icelake-Server-noTSX.xml index 36596433cb..d8dd8f4933 100644 --- a/src/cpu_map/x86_Icelake-Server-noTSX.xml +++ b/src/cpu_map/x86_Icelake-Server-noTSX.xml @@ -1,5 +1,6 @@ <cpus> <model name='Icelake-Server-noTSX'> + <check partial='compat'/> <decode host='on' guest='off'/> <signature family='6' model='106'/> <!-- 0606A5 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Icelake-Server.xml b/src/cpu_map/x86_Icelake-Server.xml index 1e7ff355d5..69dd32fb2d 100644 --- a/src/cpu_map/x86_Icelake-Server.xml +++ b/src/cpu_map/x86_Icelake-Server.xml @@ -1,5 +1,6 @@ <cpus> <model name='Icelake-Server'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='106'/> <!-- 0606A5 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_IvyBridge-IBRS.xml b/src/cpu_map/x86_IvyBridge-IBRS.xml index 324152f856..e2e01694cd 100644 --- a/src/cpu_map/x86_IvyBridge-IBRS.xml +++ b/src/cpu_map/x86_IvyBridge-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='IvyBridge-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='58'/> <!-- 0306a0 --> <signature family='6' model='62'/> <!-- 0306e0 --> diff --git a/src/cpu_map/x86_IvyBridge.xml b/src/cpu_map/x86_IvyBridge.xml index 49d587afab..546c2eedb8 100644 --- a/src/cpu_map/x86_IvyBridge.xml +++ b/src/cpu_map/x86_IvyBridge.xml @@ -1,5 +1,6 @@ <cpus> <model name='IvyBridge'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='58'/> <!-- 0306a0 --> <signature family='6' model='62'/> <!-- 0306e0 --> diff --git a/src/cpu_map/x86_Nehalem-IBRS.xml b/src/cpu_map/x86_Nehalem-IBRS.xml index ac05a349db..22c2e0f59e 100644 --- a/src/cpu_map/x86_Nehalem-IBRS.xml +++ b/src/cpu_map/x86_Nehalem-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Nehalem-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='26'/> <!-- 0106a0 --> <signature family='6' model='30'/> <!-- 0106e0 --> diff --git a/src/cpu_map/x86_Nehalem.xml b/src/cpu_map/x86_Nehalem.xml index 74b85701e8..40903a92b3 100644 --- a/src/cpu_map/x86_Nehalem.xml +++ b/src/cpu_map/x86_Nehalem.xml @@ -1,5 +1,6 @@ <cpus> <model name='Nehalem'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='26'/> <!-- 0106a0 --> <signature family='6' model='30'/> <!-- 0106e0 --> diff --git a/src/cpu_map/x86_Opteron_G1.xml b/src/cpu_map/x86_Opteron_G1.xml index 57648ca93f..32c7fc9ca2 100644 --- a/src/cpu_map/x86_Opteron_G1.xml +++ b/src/cpu_map/x86_Opteron_G1.xml @@ -1,5 +1,6 @@ <cpus> <model name='Opteron_G1'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='15' model='6'/> <!-- 100e60 --> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_Opteron_G2.xml b/src/cpu_map/x86_Opteron_G2.xml index db961b0067..01a4d69613 100644 --- a/src/cpu_map/x86_Opteron_G2.xml +++ b/src/cpu_map/x86_Opteron_G2.xml @@ -1,5 +1,6 @@ <cpus> <model name='Opteron_G2'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='15' model='6'/> <!-- 100e60 --> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_Opteron_G3.xml b/src/cpu_map/x86_Opteron_G3.xml index cf00af8698..d2871b4b56 100644 --- a/src/cpu_map/x86_Opteron_G3.xml +++ b/src/cpu_map/x86_Opteron_G3.xml @@ -1,5 +1,6 @@ <cpus> <model name='Opteron_G3'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='15' model='6'/> <!-- 100e60 --> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_Opteron_G4.xml b/src/cpu_map/x86_Opteron_G4.xml index a7fc8d5828..527124a372 100644 --- a/src/cpu_map/x86_Opteron_G4.xml +++ b/src/cpu_map/x86_Opteron_G4.xml @@ -1,5 +1,6 @@ <cpus> <model name='Opteron_G4'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='21' model='1'/> <!-- 600f10 --> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_Opteron_G5.xml b/src/cpu_map/x86_Opteron_G5.xml index ff775bdcef..8f51c713aa 100644 --- a/src/cpu_map/x86_Opteron_G5.xml +++ b/src/cpu_map/x86_Opteron_G5.xml @@ -1,5 +1,6 @@ <cpus> <model name='Opteron_G5'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='21' model='2'/> <!-- 600f20 --> <vendor name='AMD'/> diff --git a/src/cpu_map/x86_Penryn.xml b/src/cpu_map/x86_Penryn.xml index b31f96fa43..0c6adb9037 100644 --- a/src/cpu_map/x86_Penryn.xml +++ b/src/cpu_map/x86_Penryn.xml @@ -1,5 +1,6 @@ <cpus> <model name='Penryn'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='23'/> <!-- 010670 --> <signature family='6' model='29'/> <!-- 0106d0 --> diff --git a/src/cpu_map/x86_SandyBridge-IBRS.xml b/src/cpu_map/x86_SandyBridge-IBRS.xml index d2071f3367..1601763584 100644 --- a/src/cpu_map/x86_SandyBridge-IBRS.xml +++ b/src/cpu_map/x86_SandyBridge-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='SandyBridge-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='42'/> <!-- 0206a0 --> <signature family='6' model='45'/> <!-- 0206d0 --> diff --git a/src/cpu_map/x86_SandyBridge.xml b/src/cpu_map/x86_SandyBridge.xml index c5d342e0d0..7ae867180e 100644 --- a/src/cpu_map/x86_SandyBridge.xml +++ b/src/cpu_map/x86_SandyBridge.xml @@ -1,5 +1,6 @@ <cpus> <model name='SandyBridge'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='42'/> <!-- 0206a0 --> <signature family='6' model='45'/> <!-- 0206d0 --> diff --git a/src/cpu_map/x86_SapphireRapids.xml b/src/cpu_map/x86_SapphireRapids.xml index 1e53b30dd3..6377175fe0 100644 --- a/src/cpu_map/x86_SapphireRapids.xml +++ b/src/cpu_map/x86_SapphireRapids.xml @@ -1,5 +1,6 @@ <cpus> <model name='SapphireRapids'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='143'/> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_SierraForest.xml b/src/cpu_map/x86_SierraForest.xml index caa6956e94..ea4989f329 100644 --- a/src/cpu_map/x86_SierraForest.xml +++ b/src/cpu_map/x86_SierraForest.xml @@ -1,5 +1,6 @@ <cpus> <model name='SierraForest'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='175'/> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Skylake-Client-IBRS.xml b/src/cpu_map/x86_Skylake-Client-IBRS.xml index 892aef2031..0b1df8fc5a 100644 --- a/src/cpu_map/x86_Skylake-Client-IBRS.xml +++ b/src/cpu_map/x86_Skylake-Client-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Skylake-Client-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='94'/> <!-- 0506e0 --> <signature family='6' model='78'/> <!-- 0406e0 --> diff --git a/src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml b/src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml index 63e5a02296..8884bb4bae 100644 --- a/src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml +++ b/src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Skylake-Client-noTSX-IBRS'> + <check partial='compat'/> <decode host='on' guest='off'/> <signature family='6' model='94'/> <!-- 0506e0 --> <signature family='6' model='78'/> <!-- 0406e0 --> diff --git a/src/cpu_map/x86_Skylake-Client.xml b/src/cpu_map/x86_Skylake-Client.xml index 83cc6780c7..8d8ab41ddd 100644 --- a/src/cpu_map/x86_Skylake-Client.xml +++ b/src/cpu_map/x86_Skylake-Client.xml @@ -1,5 +1,6 @@ <cpus> <model name='Skylake-Client'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='94'/> <!-- 0506e0 --> <signature family='6' model='78'/> <!-- 0406e0 --> diff --git a/src/cpu_map/x86_Skylake-Server-IBRS.xml b/src/cpu_map/x86_Skylake-Server-IBRS.xml index 84f67c6278..8a4552f60b 100644 --- a/src/cpu_map/x86_Skylake-Server-IBRS.xml +++ b/src/cpu_map/x86_Skylake-Server-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Skylake-Server-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='85' stepping='0-4'/> <!-- 050654 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml b/src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml index 081e30f5ad..e469da286e 100644 --- a/src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml +++ b/src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Skylake-Server-noTSX-IBRS'> + <check partial='compat'/> <decode host='on' guest='off'/> <signature family='6' model='85' stepping='0-4'/> <!-- 050654 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Skylake-Server.xml b/src/cpu_map/x86_Skylake-Server.xml index e814b8dcf3..e7ad70e812 100644 --- a/src/cpu_map/x86_Skylake-Server.xml +++ b/src/cpu_map/x86_Skylake-Server.xml @@ -1,5 +1,6 @@ <cpus> <model name='Skylake-Server'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='85' stepping='0-4'/> <!-- 050654 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Snowridge.xml b/src/cpu_map/x86_Snowridge.xml index b254c7d71e..8b3690adb3 100644 --- a/src/cpu_map/x86_Snowridge.xml +++ b/src/cpu_map/x86_Snowridge.xml @@ -1,5 +1,6 @@ <cpus> <model name='Snowridge'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='134'/> <!-- 080665 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Westmere-IBRS.xml b/src/cpu_map/x86_Westmere-IBRS.xml index 5d2fd81b8d..2130bec8ce 100644 --- a/src/cpu_map/x86_Westmere-IBRS.xml +++ b/src/cpu_map/x86_Westmere-IBRS.xml @@ -1,5 +1,6 @@ <cpus> <model name='Westmere-IBRS'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='44'/> <!-- 0206c0 --> <vendor name='Intel'/> diff --git a/src/cpu_map/x86_Westmere.xml b/src/cpu_map/x86_Westmere.xml index abbfb186b4..102af0b46b 100644 --- a/src/cpu_map/x86_Westmere.xml +++ b/src/cpu_map/x86_Westmere.xml @@ -1,5 +1,6 @@ <cpus> <model name='Westmere'> + <check partial='compat'/> <decode host='on' guest='on'/> <signature family='6' model='44'/> <!-- 0206c0 --> <signature family='6' model='47'/> <!-- 0206f0 --> diff --git a/src/cpu_map/x86_athlon.xml b/src/cpu_map/x86_athlon.xml index 81c43c81e8..38259e0c46 100644 --- a/src/cpu_map/x86_athlon.xml +++ b/src/cpu_map/x86_athlon.xml @@ -1,5 +1,6 @@ <cpus> <model name='athlon'> + <check partial='compat'/> <decode host='on' guest='on'/> <vendor name='AMD'/> <feature name='3dnow'/> diff --git a/src/cpu_map/x86_core2duo.xml b/src/cpu_map/x86_core2duo.xml index ea23a6c662..623ad40559 100644 --- a/src/cpu_map/x86_core2duo.xml +++ b/src/cpu_map/x86_core2duo.xml @@ -1,5 +1,6 @@ <cpus> <model name='core2duo'> + <check partial='compat'/> <decode host='on' guest='on'/> <vendor name='Intel'/> <feature name='apic'/> diff --git a/src/cpu_map/x86_coreduo.xml b/src/cpu_map/x86_coreduo.xml index 24900e637f..e934213705 100644 --- a/src/cpu_map/x86_coreduo.xml +++ b/src/cpu_map/x86_coreduo.xml @@ -1,5 +1,6 @@ <cpus> <model name='coreduo'> + <check partial='compat'/> <decode host='on' guest='on'/> <vendor name='Intel'/> <feature name='apic'/> diff --git a/src/cpu_map/x86_cpu64-rhel5.xml b/src/cpu_map/x86_cpu64-rhel5.xml index 7402b7603c..f331047474 100644 --- a/src/cpu_map/x86_cpu64-rhel5.xml +++ b/src/cpu_map/x86_cpu64-rhel5.xml @@ -1,5 +1,6 @@ <cpus> <model name='cpu64-rhel5'> + <check partial='compat'/> <decode host='off' guest='off'/> <feature name='apic'/> <feature name='clflush'/> diff --git a/src/cpu_map/x86_cpu64-rhel6.xml b/src/cpu_map/x86_cpu64-rhel6.xml index 061939c733..b05620563e 100644 --- a/src/cpu_map/x86_cpu64-rhel6.xml +++ b/src/cpu_map/x86_cpu64-rhel6.xml @@ -1,5 +1,6 @@ <cpus> <model name='cpu64-rhel6'> + <check partial='compat'/> <decode host='off' guest='off'/> <feature name='apic'/> <feature name='clflush'/> diff --git a/src/cpu_map/x86_kvm32.xml b/src/cpu_map/x86_kvm32.xml index ac28c53bd0..1f2de9d477 100644 --- a/src/cpu_map/x86_kvm32.xml +++ b/src/cpu_map/x86_kvm32.xml @@ -1,5 +1,6 @@ <cpus> <model name='kvm32'> + <check partial='compat'/> <decode host='on' guest='on'/> <feature name='apic'/> <feature name='clflush'/> diff --git a/src/cpu_map/x86_kvm64.xml b/src/cpu_map/x86_kvm64.xml index 970a8e73d5..f6fcf1f94c 100644 --- a/src/cpu_map/x86_kvm64.xml +++ b/src/cpu_map/x86_kvm64.xml @@ -1,5 +1,6 @@ <cpus> <model name='kvm64'> + <check partial='compat'/> <decode host='on' guest='on'/> <feature name='apic'/> <feature name='clflush'/> diff --git a/src/cpu_map/x86_n270.xml b/src/cpu_map/x86_n270.xml index 5507d2ea3b..fd088902fb 100644 --- a/src/cpu_map/x86_n270.xml +++ b/src/cpu_map/x86_n270.xml @@ -1,5 +1,6 @@ <cpus> <model name='n270'> + <check partial='compat'/> <decode host='on' guest='on'/> <vendor name='Intel'/> <feature name='apic'/> diff --git a/src/cpu_map/x86_pentium.xml b/src/cpu_map/x86_pentium.xml index f0a8982115..a3d1063510 100644 --- a/src/cpu_map/x86_pentium.xml +++ b/src/cpu_map/x86_pentium.xml @@ -1,5 +1,6 @@ <cpus> <model name='pentium'> + <check partial='compat'/> <decode host='on' guest='on'/> <feature name='cx8'/> <feature name='de'/> diff --git a/src/cpu_map/x86_pentium2.xml b/src/cpu_map/x86_pentium2.xml index aeba082297..0d0cc97e1a 100644 --- a/src/cpu_map/x86_pentium2.xml +++ b/src/cpu_map/x86_pentium2.xml @@ -1,5 +1,6 @@ <cpus> <model name='pentium2'> + <check partial='compat'/> <decode host='on' guest='on'/> <feature name='cmov'/> <feature name='cx8'/> diff --git a/src/cpu_map/x86_pentium3.xml b/src/cpu_map/x86_pentium3.xml index ab85d2967f..fd249e29f9 100644 --- a/src/cpu_map/x86_pentium3.xml +++ b/src/cpu_map/x86_pentium3.xml @@ -1,5 +1,6 @@ <cpus> <model name='pentium3'> + <check partial='compat'/> <decode host='on' guest='on'/> <feature name='cmov'/> <feature name='cx8'/> diff --git a/src/cpu_map/x86_pentiumpro.xml b/src/cpu_map/x86_pentiumpro.xml index b6e061187c..f3d18db033 100644 --- a/src/cpu_map/x86_pentiumpro.xml +++ b/src/cpu_map/x86_pentiumpro.xml @@ -1,5 +1,6 @@ <cpus> <model name='pentiumpro'> + <check partial='compat'/> <decode host='on' guest='on'/> <feature name='apic'/> <feature name='cmov'/> diff --git a/src/cpu_map/x86_phenom.xml b/src/cpu_map/x86_phenom.xml index f0f8ece57a..8141236233 100644 --- a/src/cpu_map/x86_phenom.xml +++ b/src/cpu_map/x86_phenom.xml @@ -1,5 +1,6 @@ <cpus> <model name='phenom'> + <check partial='compat'/> <decode host='on' guest='on'/> <vendor name='AMD'/> <feature name='3dnow'/> diff --git a/src/cpu_map/x86_qemu32.xml b/src/cpu_map/x86_qemu32.xml index f3fb1959be..adb51a04d6 100644 --- a/src/cpu_map/x86_qemu32.xml +++ b/src/cpu_map/x86_qemu32.xml @@ -1,5 +1,6 @@ <cpus> <model name='qemu32'> + <check partial='compat'/> <decode host='on' guest='on'/> <feature name='apic'/> <feature name='cmov'/> diff --git a/src/cpu_map/x86_qemu64.xml b/src/cpu_map/x86_qemu64.xml index 0fe207a2b4..cbb78211a6 100644 --- a/src/cpu_map/x86_qemu64.xml +++ b/src/cpu_map/x86_qemu64.xml @@ -1,5 +1,6 @@ <cpus> <model name='qemu64'> + <check partial='compat'/> <decode host='on' guest='on'/> <!-- These are supported only by TCG. KVM supports them only if the host does. So we leave them out: -- 2.47.0

On x86 the function returns whether an old style compat check mode should be used for a specified CPU model according to the CPU map. All other architectures will always use compat mode. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/cpu/cpu.c | 31 +++++++++++++++++++++++++++++++ src/cpu/cpu.h | 10 ++++++++++ src/cpu/cpu_x86.c | 33 +++++++++++++++++++++++++++++++++ src/libvirt_private.syms | 1 + 4 files changed, 75 insertions(+) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index a2518d7cc7..1734561215 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1241,6 +1241,37 @@ virCPUDataGetHost(void) } +/** + * virCPUGetCheckMode: + * @arch: CPU architecture + * @cpu: CPU definition + * @compat: where to store compatible partial checking is required + * + * Gets the mode required for "partial" check of the CPU definition @cpu + * based on the CPU model used. On success @compat will be set to true if + * a compatible check needs to be done, false otherwise. + * + * Returns 0 on success, -1 otherwise. + */ +int +virCPUGetCheckMode(virArch arch, + const virCPUDef *cpu, + bool *compat) +{ + struct cpuArchDriver *driver; + + if (!(driver = cpuGetSubDriver(arch))) + return -1; + + if (!driver->getCheckMode) { + *compat = true; + return 0; + } + + return driver->getCheckMode(cpu->model, compat); +} + + /** * virCPUArchIsSupported: * diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index d092b4f3f0..ceb6eb0944 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -136,6 +136,10 @@ typedef virCPUCompareResult typedef virCPUData * (*virCPUArchDataGetHost)(void); +typedef int +(*virCPUArchGetCheckMode)(const char *modelName, + bool *compat); + struct cpuArchDriver { const char *name; const virArch *arch; @@ -163,6 +167,7 @@ struct cpuArchDriver { virCPUArchDataAddFeature dataAddFeature; virCPUArchDataIsIdentical dataIsIdentical; virCPUArchDataGetHost dataGetHost; + virCPUArchGetCheckMode getCheckMode; }; @@ -307,6 +312,11 @@ virCPUDataIsIdentical(const virCPUData *a, virCPUData* virCPUDataGetHost(void); +int +virCPUGetCheckMode(virArch arch, + const virCPUDef *cpu, + bool *compat); + bool virCPUArchIsSupported(virArch arch); diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 70893f8a62..97d6e00007 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -3608,6 +3608,38 @@ virCPUx86GetAddedFeatures(const char *modelName, } +/** + * virCPUx86GetCheckMode: + * @modelName: CPU model + * @compat: where to store compatible partial checking is required + * + * Gets the mode required for "partial" check of a CPU definition which uses + * the @modelName. On success @compat will be set to true if a compatible + * check needs to be done, false otherwise. + * + * Returns 0 on success, -1 otherwise. + */ +static int +virCPUx86GetCheckMode(const char *modelName, + bool *compat) +{ + virCPUx86Map *map; + virCPUx86Model *model; + + if (!(map = virCPUx86GetMap())) + return -1; + + if (!(model = x86ModelFind(map, modelName))) { + virReportError(VIR_ERR_INVALID_ARG, + _("unknown CPU model %1$s"), modelName); + return -1; + } + + *compat = model->compatCheck; + return 0; +} + + struct cpuArchDriver cpuDriverX86 = { .name = "x86", .arch = archs, @@ -3640,4 +3672,5 @@ struct cpuArchDriver cpuDriverX86 = { (defined(__linux__) || defined(__FreeBSD__)) .dataGetHost = virCPUx86DataGetHost, #endif + .getCheckMode = virCPUx86GetCheckMode, }; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e09fb98596..551cea989b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1538,6 +1538,7 @@ virCPUDataNewCopy; virCPUDataParse; virCPUDataParseNode; virCPUExpandFeatures; +virCPUGetCheckMode; virCPUGetHost; virCPUGetHostIsSupported; virCPUGetModels; -- 2.47.0

Let's get rid of the only explicitly freed variable left in qemuConnectCompareHypervisorCPU. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f27c21ca8c..62a44bf6e7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11597,14 +11597,13 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, const char *xmlCPU, unsigned int flags) { - int ret = VIR_CPU_COMPARE_ERROR; virQEMUDriver *driver = conn->privateData; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autoptr(virQEMUCaps) qemuCaps = NULL; bool failIncompatible; bool validateXML; virCPUDef *hvCPU; - virCPUDef *cpu = NULL; + g_autoptr(virCPUDef) cpu = NULL; virArch arch; virDomainVirtType virttype; @@ -11613,7 +11612,7 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, VIR_CPU_COMPARE_ERROR); if (virConnectCompareHypervisorCPUEnsureACL(conn) < 0) - goto cleanup; + return VIR_CPU_COMPARE_ERROR; failIncompatible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE); validateXML = !!(flags & VIR_CONNECT_COMPARE_CPU_VALIDATE_XML); @@ -11625,7 +11624,7 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, machine, &arch, &virttype, NULL); if (!qemuCaps) - goto cleanup; + return VIR_CPU_COMPARE_ERROR; hvCPU = virQEMUCapsGetHostModel(qemuCaps, virttype, VIR_QEMU_CAPS_HOST_CPU_REPORTED); @@ -11635,17 +11634,19 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, _("QEMU '%1$s' does not support reporting CPU model for virttype '%2$s'"), virQEMUCapsGetBinary(qemuCaps), virDomainVirtTypeToString(virttype)); - goto cleanup; + return VIR_CPU_COMPARE_ERROR; } if (ARCH_IS_X86(arch)) { - ret = virCPUCompareXML(arch, hvCPU, xmlCPU, failIncompatible, - validateXML); - } else if (ARCH_IS_S390(arch) && - virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON)) { + return virCPUCompareXML(arch, hvCPU, xmlCPU, failIncompatible, + validateXML); + } + + if (ARCH_IS_S390(arch) && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON)) { if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu, validateXML) < 0) - goto cleanup; + return VIR_CPU_COMPARE_ERROR; if (!cpu->model) { if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) { @@ -11655,21 +11656,18 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, } else { virReportError(VIR_ERR_INVALID_ARG, "%s", _("cpu parameter is missing a model name")); - goto cleanup; + return VIR_CPU_COMPARE_ERROR; } } - ret = qemuConnectCPUModelComparison(qemuCaps, cfg->libDir, - cfg->user, cfg->group, - hvCPU, cpu, failIncompatible); - } else { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("comparing with the hypervisor CPU is not supported for arch %1$s"), - virArchToString(arch)); + return qemuConnectCPUModelComparison(qemuCaps, cfg->libDir, + cfg->user, cfg->group, + hvCPU, cpu, failIncompatible); } - cleanup: - virCPUDefFree(cpu); - return ret; + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("comparing with the hypervisor CPU is not supported for arch %1$s"), + virArchToString(arch)); + return VIR_CPU_COMPARE_ERROR; } -- 2.47.0

The function already parses CPU XML on s390. By parsing it consistently on all architecture we can switch to virCPUCompare and easily replace it with a QEMU specific helper in the following patch. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 62a44bf6e7..36ec0c0590 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11637,17 +11637,15 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, return VIR_CPU_COMPARE_ERROR; } - if (ARCH_IS_X86(arch)) { - return virCPUCompareXML(arch, hvCPU, xmlCPU, failIncompatible, - validateXML); - } + if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu, + validateXML) < 0) + return VIR_CPU_COMPARE_ERROR; + + if (ARCH_IS_X86(arch)) + return virCPUCompare(arch, hvCPU, cpu, failIncompatible); if (ARCH_IS_S390(arch) && virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON)) { - if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu, - validateXML) < 0) - return VIR_CPU_COMPARE_ERROR; - if (!cpu->model) { if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) { cpu->model = g_strdup("host"); -- 2.47.0

The new qemuDomainCheckCPU function is used as a replacement for virCPUCompare to make sure all callers use the same comparison algorithm. As a side effect qemuConnectCompareHypervisorCPU now properly reports CPU compatibility for CPU model that are considered runnable by QEMU even if our definition of the model disagrees. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 7 +++++++ src/qemu/qemu_driver.c | 7 +++++-- src/qemu/qemu_process.c | 7 ++----- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index fda4439b0b..8ada3db115 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -13223,3 +13223,43 @@ qemuDomainStorageUpdatePhysical(virQEMUDriverConfig *cfg, return ret; } + + +/** + * qemuDomainCheckCPU: + * @arch: CPU architecture + * @virtType: domain type (KVM vs. TCG) + * @qemuCaps: QEMU capabilities + * @cpu: CPU definition to check against "host CPU" + * @compatCPU: type of CPU used for old style check + * @failIncompatible: return an error instead of VIR_CPU_COMPARE_INCOMPATIBLE + * + * Perform a "partial" check of the @cpu against a "host CPU". Old style check + * used with all existing CPU models uses cpu_map definition of the model in + * @cpu and compares it to the host CPU fetched @qemuCaps according to + * @compatCPU. + * + * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when + * the two CPUs are incompatible, VIR_CPU_COMPARE_IDENTICAL when the two CPUs + * are identical, VIR_CPU_COMPARE_SUPERSET when the @cpu CPU is a superset of + * the @host CPU. If @failIncompatible is true, the function will return + * VIR_CPU_COMPARE_ERROR (and set VIR_ERR_CPU_INCOMPATIBLE error) when the + * two CPUs are incompatible. + */ +virCPUCompareResult +qemuDomainCheckCPU(virArch arch, + virDomainVirtType virtType, + virQEMUCaps *qemuCaps, + virCPUDef *cpu, + virQEMUCapsHostCPUType compatCPU, + bool failIncompatible) +{ + virCPUDef *host; + + if (virQEMUCapsIsCPUUsable(qemuCaps, virtType, cpu)) + return VIR_CPU_COMPARE_SUPERSET; + + host = virQEMUCapsGetHostModel(qemuCaps, virtType, compatCPU); + + return virCPUCompare(arch, host, cpu, failIncompatible); +} diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index c29ecdf238..a19314b48b 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -1176,3 +1176,10 @@ int qemuDomainStorageUpdatePhysical(virQEMUDriverConfig *cfg, virDomainObj *vm, virStorageSource *src); +virCPUCompareResult +qemuDomainCheckCPU(virArch arch, + virDomainVirtType virtType, + virQEMUCaps *qemuCaps, + virCPUDef *cpu, + virQEMUCapsHostCPUType compatCPU, + bool failIncompatible); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 36ec0c0590..72211da137 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11641,8 +11641,11 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, validateXML) < 0) return VIR_CPU_COMPARE_ERROR; - if (ARCH_IS_X86(arch)) - return virCPUCompare(arch, hvCPU, cpu, failIncompatible); + if (ARCH_IS_X86(arch)) { + return qemuDomainCheckCPU(arch, virttype, qemuCaps, cpu, + VIR_QEMU_CAPS_HOST_CPU_REPORTED, + failIncompatible); + } if (ARCH_IS_S390(arch) && virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON)) { diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 72fc750d28..0815bffe3c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6268,11 +6268,8 @@ qemuProcessUpdateGuestCPU(virDomainDef *def, virCPUFeaturePolicy removedPolicy = VIR_CPU_FEATURE_DISABLE; if (def->cpu->check == VIR_CPU_CHECK_PARTIAL && - !virQEMUCapsIsCPUUsable(qemuCaps, def->virtType, def->cpu) && - virCPUCompare(hostarch, - virQEMUCapsGetHostModel(qemuCaps, def->virtType, - VIR_QEMU_CAPS_HOST_CPU_FULL), - def->cpu, true) < 0) + qemuDomainCheckCPU(hostarch, def->virtType, qemuCaps, def->cpu, + VIR_QEMU_CAPS_HOST_CPU_FULL, true) < 0) return -1; /* When starting a fresh domain we disable all features removed from -- 2.47.0

As opposed to the existing virCPUCompare{,XML} this function does not use CPU model definitions from CPU map. It relies on CPU model usability info from a hypervisor with a list of blockers that make the selected CPU model unusable. Explicitly requested features are checked against the hypervisor's view of a host CPU. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/cpu/cpu.c | 73 ++++++++++++++++++++++++++++++++++++++++ src/cpu/cpu.h | 7 ++++ src/libvirt_private.syms | 1 + 3 files changed, 81 insertions(+) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 1734561215..2b0d641e78 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -167,6 +167,79 @@ virCPUCompare(virArch arch, } +/** virCPUCompareUnusable: + * @arch: CPU architecture + * @host: host CPU reported by the hypervisor + * @cpu: CPU to be compared with @host + * @blockers: NULL terminated list of features blocking usability of the CPU model from @cpu + * @failIncompatible: return an error instead of VIR_CPU_COMPARE_INCOMPATIBLE + * + * Check if @cpu can be run on @host when we know model used by @cpu is + * considered unusable by the hypervisor because it requires some features + * that cannot be provided on the host (the list of them is passed as + * @blockers) and/or @cpu requests additional features. The @cpu definition + * can still be compatible with @host if all @blockers are explicitly disabled + * and all explicitly requested features are supported by @host. + * + * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when + * the @cpu cannot be created on @host, or VIR_CPU_COMPARE_SUPERSET when the + * @cpu is compatible with @host CPU. If @failIncompatible is true, the + * function will return VIR_CPU_COMPARE_ERROR (and set VIR_ERR_CPU_INCOMPATIBLE + * error) when the two CPUs are incompatible. + */ +int +virCPUCompareUnusable(virArch arch, + const virCPUDef *host, + const virCPUDef *cpu, + char **blockers, + bool failIncompatible) +{ + g_autoptr(virCPUDef) expanded = NULL; + g_auto(virBuffer) features = VIR_BUFFER_INITIALIZER; + g_autofree char *str = NULL; + virCPUFeatureDef *feat; + char **blocker; + size_t i; + + for (blocker = blockers; *blocker; blocker++) { + if (!(feat = virCPUDefFindFeature(cpu, *blocker)) || + feat->policy != VIR_CPU_FEATURE_DISABLE) { + virBufferAddStr(&features, *blocker); + virBufferAddLit(&features, ", "); + } + } + + expanded = virCPUDefCopy(host); + if (virCPUExpandFeatures(arch, expanded) < 0) + return VIR_CPU_COMPARE_ERROR; + + for (i = 0; i < cpu->nfeatures; i++) { + if (cpu->features[i].policy != VIR_CPU_FEATURE_REQUIRE) + continue; + + if (!(feat = virCPUDefFindFeature(expanded, cpu->features[i].name)) || + feat->policy != VIR_CPU_FEATURE_REQUIRE) { + virBufferAddStr(&features, cpu->features[i].name); + virBufferAddLit(&features, ", "); + } + } + virBufferTrim(&features, ", "); + + if ((str = virBufferContentAndReset(&features))) { + if (failIncompatible) { + virReportError(VIR_ERR_CPU_INCOMPATIBLE, + _("Host CPU does not provide required features: %1$s"), + str); + return VIR_CPU_COMPARE_ERROR; + } + + return VIR_CPU_COMPARE_INCOMPATIBLE; + } + + return VIR_CPU_COMPARE_SUPERSET; +} + + /** * cpuDecode: * diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index ceb6eb0944..ff68c5da2d 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -185,6 +185,13 @@ virCPUCompare(virArch arch, bool failIncompatible) ATTRIBUTE_NONNULL(3); +int +virCPUCompareUnusable(virArch arch, + const virCPUDef *host, + const virCPUDef *cpu, + char **blockers, + bool failIncompatible); + int cpuDecode (virCPUDef *cpu, const virCPUData *data, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 551cea989b..c1542847f4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1524,6 +1524,7 @@ virCPUBaseline; virCPUCheckFeature; virCPUCheckForbiddenFeatures; virCPUCompare; +virCPUCompareUnusable; virCPUCompareXML; virCPUConvertLegacy; virCPUCopyMigratable; -- 2.47.0

A function for accessing a list of features blocking CPU model usability. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_capabilities.c | 38 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 4 ++++ 2 files changed, 42 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e1e28e5cd1..b5fa738bd8 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2507,6 +2507,44 @@ virQEMUCapsIsCPUUsable(virQEMUCaps *qemuCaps, } +/** + * virQEMUCapsGetCPUBlockers: + * @qemuCaps: QEMU capabilities + * @type: virtualization type + * @cpu: CPU model + * @blockers: where to store the list of features + * + * Get a list of features that prevent @cpu from being usable. The pointer to + * the list will be stored in @blockers and the caller must not free it. The + * pointer is valid as long as there is an active reference to @qemuCaps. + * + * Returns 0 on success, -1 when @cpu is not found in @qemuCaps. + */ +int +virQEMUCapsGetCPUBlockers(virQEMUCaps *qemuCaps, + virDomainVirtType type, + const char *cpu, + char ***blockers) +{ + qemuMonitorCPUDefs *defs; + size_t i; + + defs = virQEMUCapsGetAccel(qemuCaps, type)->cpuModels; + + if (!defs) + return -1; + + for (i = 0; i < defs->ncpus; i++) { + if (STREQ(defs->cpus[i].name, cpu)) { + *blockers = defs->cpus[i].blockers; + return 0; + } + } + + return -1; +} + + bool virQEMUCapsIsMachineDeprecated(virQEMUCaps *qemuCaps, virDomainVirtType type, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 284b07b64e..54c7e30903 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -795,6 +795,10 @@ bool virQEMUCapsIsCPUDeprecated(virQEMUCaps *qemuCaps, bool virQEMUCapsIsCPUUsable(virQEMUCaps *qemuCaps, virDomainVirtType type, virCPUDef *cpu); +int virQEMUCapsGetCPUBlockers(virQEMUCaps *qemuCaps, + virDomainVirtType type, + const char *cpu, + char ***blockers); bool virQEMUCapsIsMachineDeprecated(virQEMUCaps *qemuCaps, virDomainVirtType type, const char *machine); -- 2.47.0

When starting a domain we check whether the guest CPU definition is compatible with the host (i.e., when the host supports all features required both explicitly and by the specified CPU model) as long as check == 'partial', which is the default. We are doing so by checking our definition of the CPU model in the CPU map amending it with explicitly mentioned features and comparing it to features QEMU would enabled when started with -cpu host. But since our CPU model definitions often slightly differ from QEMU we may be checking features which are not actually needed and on the other hand not checking something that is part of the CPU model in QEMU. This patch changes the algorithm for CPU models added in the future (changing it for existing models could cause them to suddenly become incompatible with the host and domains using them would fail to start). The new algorithm uses information we probe from QEMU about features that block each model from being directly usable. If all those features are explicitly disabled in the CPU definition we consider the base model compatible with the host. Then we only need to check that all explicitly required features are supported by QEMU on the host to get the result for the whole CPU definition. After this we only use the model definitions (for newly added models) from CPU map for creating a CPU definition for host-model. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 8ada3db115..7b702cfc6b 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -13234,10 +13234,16 @@ qemuDomainStorageUpdatePhysical(virQEMUDriverConfig *cfg, * @compatCPU: type of CPU used for old style check * @failIncompatible: return an error instead of VIR_CPU_COMPARE_INCOMPATIBLE * - * Perform a "partial" check of the @cpu against a "host CPU". Old style check - * used with all existing CPU models uses cpu_map definition of the model in - * @cpu and compares it to the host CPU fetched @qemuCaps according to - * @compatCPU. + * Perform a "partial" check of the @cpu against a "host CPU". + * + * Old style check used with all existing CPU models uses cpu_map definition of + * the model in @cpu and compares it to the host CPU fetched @qemuCaps + * according to @compatCPU. + * + * For future CPU models (without <check partial='compat'/>) only explicitly + * requested features are checked against the host CPU definition provided by + * QEMU and the usability (with a list of blocking features) info for the base + * CPU model. Our definition of the mode in cpu_map is ignored completely. * * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when * the two CPUs are incompatible, VIR_CPU_COMPARE_IDENTICAL when the two CPUs @@ -13254,12 +13260,31 @@ qemuDomainCheckCPU(virArch arch, virQEMUCapsHostCPUType compatCPU, bool failIncompatible) { - virCPUDef *host; + virCPUDef *hypervisorCPU; + bool compat = false; + char **blockers = NULL; if (virQEMUCapsIsCPUUsable(qemuCaps, virtType, cpu)) return VIR_CPU_COMPARE_SUPERSET; - host = virQEMUCapsGetHostModel(qemuCaps, virtType, compatCPU); + hypervisorCPU = virQEMUCapsGetHostModel(qemuCaps, virtType, + VIR_QEMU_CAPS_HOST_CPU_REPORTED); + + /* Force compat check if the CPU model is not found in qemuCaps or + * we don't have host CPU data from QEMU */ + if (!cpu->model || + hypervisorCPU->fallback != VIR_CPU_FALLBACK_FORBID || + virQEMUCapsGetCPUBlockers(qemuCaps, virtType, + cpu->model, &blockers) < 0) + compat = true; + else if (virCPUGetCheckMode(arch, cpu, &compat) < 0) + return VIR_CPU_COMPARE_ERROR; + + if (compat) { + virCPUDef *host = virQEMUCapsGetHostModel(qemuCaps, virtType, compatCPU); + return virCPUCompare(arch, host, cpu, failIncompatible); + } - return virCPUCompare(arch, host, cpu, failIncompatible); + return virCPUCompareUnusable(arch, hypervisorCPU, cpu, + blockers, failIncompatible); } -- 2.47.0

On a Thursday in 2024, Jiri Denemark wrote:
When starting a domain we check whether the guest CPU definition is compatible with the host (i.e., when the host supports all features required both explicitly and by the specified CPU model) as long as check == 'partial', which is the default.
We are doing so by checking our definition of the CPU model in the CPU map amending it with explicitly mentioned features and comparing it to features QEMU would enabled when started with -cpu host. But since our CPU model definitions often slightly differ from QEMU we may be checking features which are not actually needed and on the other hand not checking something that is part of the CPU model in QEMU.
This patch changes the algorithm for CPU models added in the future (changing it for existing models could cause them to suddenly become incompatible with the host and domains using them would fail to start). The new algorithm uses information we probe from QEMU about features that block each model from being directly usable. If all those features are explicitly disabled in the CPU definition we consider the base model compatible with the host. Then we only need to check that all explicitly required features are supported by QEMU on the host to get the result for the whole CPU definition.
After this we only use the model definitions (for newly added models) from CPU map for creating a CPU definition for host-model.
Jiri Denemark (9): cpu_x86: Introduce <check> element for CPU models cpu_map: Use compat partial check for all x86 CPU models cpu: Introduce virCPUGetCheckMode qemu: Use g_autoptr in qemuConnectCompareHypervisorCPU qemu: Use virCPUCompare in qemuConnectCompareHypervisorCPU directly qemu: Separate partial CPU check into a function cpu: Introduce virCPUCompareUnusable qemu_capabilities: Introduce virQEMUCapsGetCPUBlockers qemu: Change CPU comparison algorithm for future models
src/cpu/cpu.c | 104 ++++++++++++++++++ src/cpu/cpu.h | 17 +++ src/cpu/cpu_x86.c | 67 +++++++++++ src/cpu_map/x86_486.xml | 1 + src/cpu_map/x86_Broadwell-IBRS.xml | 1 + src/cpu_map/x86_Broadwell-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Broadwell-noTSX.xml | 1 + src/cpu_map/x86_Broadwell.xml | 1 + src/cpu_map/x86_Cascadelake-Server-noTSX.xml | 1 + src/cpu_map/x86_Cascadelake-Server.xml | 1 + src/cpu_map/x86_Conroe.xml | 1 + src/cpu_map/x86_Cooperlake.xml | 1 + src/cpu_map/x86_Dhyana.xml | 1 + src/cpu_map/x86_EPYC-Genoa.xml | 1 + src/cpu_map/x86_EPYC-IBPB.xml | 1 + src/cpu_map/x86_EPYC-Milan.xml | 1 + src/cpu_map/x86_EPYC-Rome.xml | 1 + src/cpu_map/x86_EPYC.xml | 1 + src/cpu_map/x86_GraniteRapids.xml | 1 + src/cpu_map/x86_Haswell-IBRS.xml | 1 + src/cpu_map/x86_Haswell-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Haswell-noTSX.xml | 1 + src/cpu_map/x86_Haswell.xml | 1 + src/cpu_map/x86_Icelake-Client-noTSX.xml | 1 + src/cpu_map/x86_Icelake-Client.xml | 1 + src/cpu_map/x86_Icelake-Server-noTSX.xml | 1 + src/cpu_map/x86_Icelake-Server.xml | 1 + src/cpu_map/x86_IvyBridge-IBRS.xml | 1 + src/cpu_map/x86_IvyBridge.xml | 1 + src/cpu_map/x86_Nehalem-IBRS.xml | 1 + src/cpu_map/x86_Nehalem.xml | 1 + src/cpu_map/x86_Opteron_G1.xml | 1 + src/cpu_map/x86_Opteron_G2.xml | 1 + src/cpu_map/x86_Opteron_G3.xml | 1 + src/cpu_map/x86_Opteron_G4.xml | 1 + src/cpu_map/x86_Opteron_G5.xml | 1 + src/cpu_map/x86_Penryn.xml | 1 + src/cpu_map/x86_SandyBridge-IBRS.xml | 1 + src/cpu_map/x86_SandyBridge.xml | 1 + src/cpu_map/x86_SapphireRapids.xml | 1 + src/cpu_map/x86_SierraForest.xml | 1 + src/cpu_map/x86_Skylake-Client-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Client.xml | 1 + src/cpu_map/x86_Skylake-Server-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml | 1 + src/cpu_map/x86_Skylake-Server.xml | 1 + src/cpu_map/x86_Snowridge.xml | 1 + src/cpu_map/x86_Westmere-IBRS.xml | 1 + src/cpu_map/x86_Westmere.xml | 1 + src/cpu_map/x86_athlon.xml | 1 + src/cpu_map/x86_core2duo.xml | 1 + src/cpu_map/x86_coreduo.xml | 1 + src/cpu_map/x86_cpu64-rhel5.xml | 1 + src/cpu_map/x86_cpu64-rhel6.xml | 1 + src/cpu_map/x86_kvm32.xml | 1 + src/cpu_map/x86_kvm64.xml | 1 + src/cpu_map/x86_n270.xml | 1 + src/cpu_map/x86_pentium.xml | 1 + src/cpu_map/x86_pentium2.xml | 1 + src/cpu_map/x86_pentium3.xml | 1 + src/cpu_map/x86_pentiumpro.xml | 1 + src/cpu_map/x86_phenom.xml | 1 + src/cpu_map/x86_qemu32.xml | 1 + src/cpu_map/x86_qemu64.xml | 1 + src/libvirt_private.syms | 2 + src/qemu/qemu_capabilities.c | 38 +++++++ src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_domain.c | 65 +++++++++++ src/qemu/qemu_domain.h | 7 ++ src/qemu/qemu_driver.c | 45 ++++---- src/qemu/qemu_process.c | 7 +- 72 files changed, 390 insertions(+), 28 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Jiri Denemark
-
Ján Tomko