[libvirt PATCH v3 0/3] qemuProcessUpdateGuestCPU: Check host cpu for forbidden features

V1: https://listman.redhat.com/archives/libvir-list/2021-February/msg01275.ht= ml V2: https://listman.redhat.com/archives/libvir-list/2021-February/msg01289.ht= ml Changes since V2: * Factored out into seperate function in src/cpu/cpu.c * Made virCPUDefFindFeature work on const pointers Tim Wiederhake (3): virCPUDefFindFeature: Make first argument const ptr cpu: Introduce virCPUCheckForbiddenFeatures qemuProcessUpdateGuestCPU: Check host cpu for forbidden features src/conf/cpu_conf.c | 2 +- src/conf/cpu_conf.h | 2 +- src/cpu/cpu.c | 37 +++++++++++++++++++++++++++++++++++++ src/cpu/cpu.h | 6 ++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_process.c | 10 ++++++++++ 6 files changed, 56 insertions(+), 2 deletions(-) --=20 2.26.2

Signed-off-by: Tim Wiederhake <twiederh@redhat.com> --- src/conf/cpu_conf.c | 2 +- src/conf/cpu_conf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index 380a74691d..43629068c3 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -933,7 +933,7 @@ virCPUDefAddFeatureIfMissing(virCPUDefPtr def, virCPUFeatureDefPtr -virCPUDefFindFeature(virCPUDefPtr def, +virCPUDefFindFeature(const virCPUDef *def, const char *name) { size_t i; diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h index 7ab198d370..ee4b34007e 100644 --- a/src/conf/cpu_conf.h +++ b/src/conf/cpu_conf.h @@ -236,7 +236,7 @@ virCPUDefAddFeatureIfMissing(virCPUDefPtr def, int policy); virCPUFeatureDefPtr -virCPUDefFindFeature(virCPUDefPtr def, +virCPUDefFindFeature(const virCPUDef *def, const char *name); int -- 2.26.2

Signed-off-by: Tim Wiederhake <twiederh@redhat.com> --- src/cpu/cpu.c | 37 +++++++++++++++++++++++++++++++++++++ src/cpu/cpu.h | 6 ++++++ src/libvirt_private.syms | 1 + 3 files changed, 44 insertions(+) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index dfedf5bbf0..3fd7035f7a 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -690,6 +690,43 @@ virCPUCheckFeature(virArch arch, } +/** + * virCPUCheckForbiddenFeatures: + * + * @guest: CPU definition + * @host: CPU definition + * + * Checks that @host enables no feature explicitly disabled by @guest. + * + * Returns 0 on success or -1 on error. + */ +int +virCPUCheckForbiddenFeatures(virCPUDefPtr guest, const virCPUDef *host) +{ + size_t i; + for (i = 0; i < guest->nfeatures; ++i) { + virCPUFeatureDefPtr feature; + + if (guest->features[i].policy != VIR_CPU_FEATURE_FORBID) + continue; + + feature = virCPUDefFindFeature(host, guest->features[i].name); + if (!feature) + continue; + + if (feature->policy == VIR_CPU_FEATURE_DISABLE) + continue; + + virReportError(VIR_ERR_CPU_INCOMPATIBLE, + _("Host CPU provides forbidden feature '%s'"), + guest->features[i].name); + return -1; + } + + return 0; +} + + /** * virCPUDataCheckFeature: * diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index ff4fb7e103..0b00f0b98d 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -228,6 +228,12 @@ virCPUCheckFeature(virArch arch, ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +int +virCPUCheckForbiddenFeatures(virCPUDefPtr guest, + const virCPUDef *host) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + + int virCPUDataCheckFeature(const virCPUData *data, const char *feature) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 526dcee11a..fa8859a6e3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1420,6 +1420,7 @@ cpuEncode; virCPUArchIsSupported; virCPUBaseline; virCPUCheckFeature; +virCPUCheckForbiddenFeatures; virCPUCompare; virCPUCompareXML; virCPUConvertLegacy; -- 2.26.2

See https://bugzilla.redhat.com/show_bug.cgi?id=1840770 Signed-off-by: Tim Wiederhake <twiederh@redhat.com> --- src/qemu/qemu_process.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index fedd1f56b1..b74afedd07 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6125,6 +6125,16 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def, if (virCPUConvertLegacy(hostarch, def->cpu) < 0) return -1; + if (def->cpu->check != VIR_CPU_CHECK_NONE) { + virCPUDefPtr host; + + host = virQEMUCapsGetHostModel(qemuCaps, def->virtType, + VIR_QEMU_CAPS_HOST_CPU_FULL); + + if (host && virCPUCheckForbiddenFeatures(def->cpu, host) < 0) + return -1; + } + /* nothing to update for host-passthrough / maximum */ if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH && def->cpu->mode != VIR_CPU_MODE_MAXIMUM) { -- 2.26.2

On Tue, Mar 23, 2021 at 11:01:52 +0100, Tim Wiederhake wrote:
V1: https://listman.redhat.com/archives/libvir-list/2021-February/msg01275.ht= ml V2: https://listman.redhat.com/archives/libvir-list/2021-February/msg01289.ht= ml
Changes since V2: * Factored out into seperate function in src/cpu/cpu.c * Made virCPUDefFindFeature work on const pointers
Tim Wiederhake (3): virCPUDefFindFeature: Make first argument const ptr cpu: Introduce virCPUCheckForbiddenFeatures qemuProcessUpdateGuestCPU: Check host cpu for forbidden features
src/conf/cpu_conf.c | 2 +- src/conf/cpu_conf.h | 2 +- src/cpu/cpu.c | 37 +++++++++++++++++++++++++++++++++++++ src/cpu/cpu.h | 6 ++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_process.c | 10 ++++++++++ 6 files changed, 56 insertions(+), 2 deletions(-)
--=20 2.26.2
Reviewed-by: Jiri Denemark <jdenemar@redhat.com> and pushed, thanks.
participants (2)
-
Jiri Denemark
-
Tim Wiederhake