[PATCH v1 7/9] qemu: process: allow guest to use host-recommended CPU model

Collin Walling posted 9 patches 1 year, 1 month ago
[PATCH v1 7/9] qemu: process: allow guest to use host-recommended CPU model
Posted by Collin Walling 1 year, 1 month ago
A guest may enable the host-recommended CPU model via the following
domain XML:

  <cpu mode='host-recommended' check='partial'/>

Once the guest is running, the deprecated features will nest under
the <cpu> tag paired with the "disable" policy, e.g.:

  <cpu mode='custom' match='exact' check='partial'>
    <model fallback='forbid'>gen16a-base</model>
    <feature policy='require' name='aen'/>
    <feature policy='require' name='cmmnt'/>
    <feature policy='require' name='aefsi'/>
    <feature policy='require' name='diag318'/>
    <feature policy='disable' name='csske'/>
    <feature policy='require' name='mepoch'/>
    <feature policy='require' name='msa8'/>
    ...
    <feature policy='disable' name='te'/>
    <feature policy='require' name='cmm'/>
  </cpu>

Though existing guests must restart for the CPU model to update with
these changes, this at least removes a requirement of the user to
manually stay up-to-date on which features are recommended to be
disabled as future hardware updates come into play -- so long as the
hypervisor maintains the most up-to-date CPU model definitions.

Signed-off-by: Collin Walling <walling@linux.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
---
 src/cpu/cpu.c                                 |  1 +
 src/qemu/qemu_command.c                       |  4 +++
 src/qemu/qemu_process.c                       |  9 ++++--
 src/qemu/qemu_validate.c                      |  7 ++++
 ...c-cpu-kvm-ccw-virtio-8.1.s390x-latest.args | 32 +++++++++++++++++++
 .../s390-host-rec-cpu-kvm-ccw-virtio-8.1.xml  | 17 ++++++++++
 tests/qemuxml2argvtest.c                      |  2 ++
 ...ec-cpu-kvm-ccw-virtio-8.1.s390x-latest.xml | 25 +++++++++++++++
 tests/qemuxml2xmltest.c                       |  1 +
 9 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.s390x-latest.args
 create mode 100644 tests/qemuxml2argvdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.xml
 create mode 100644 tests/qemuxml2xmloutdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.s390x-latest.xml

diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 805aff1bf5..4ac34a5efb 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -981,6 +981,7 @@ virCPUTranslate(virArch arch,
 
     if (cpu->mode == VIR_CPU_MODE_HOST_MODEL ||
         cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH ||
+        cpu->mode == VIR_CPU_MODE_HOST_RECOMMENDED ||
         cpu->mode == VIR_CPU_MODE_MAXIMUM)
         return 0;
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a45e2fbb95..ace9deb246 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6294,6 +6294,10 @@ qemuBuildCpuModelArgStr(virQEMUDriver *driver,
         break;
 
     case VIR_CPU_MODE_HOST_RECOMMENDED:
+        if (ARCH_IS_S390(def->os.arch))
+            virBufferAddLit(buf, "host-recommended");
+        break;
+
     case VIR_CPU_MODE_LAST:
         break;
     }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7a1cdb0302..4ff8c1c87a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6303,6 +6303,7 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
     if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH &&
         def->cpu->mode != VIR_CPU_MODE_MAXIMUM) {
         g_autoptr(virDomainCapsCPUModels) cpuModels = NULL;
+        virQEMUCapsHostCPUType cpuType;
 
         if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
             virCPUCompare(hostarch,
@@ -6311,9 +6312,13 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
                           def->cpu, true) < 0)
             return -1;
 
+        if (def->cpu->mode == VIR_CPU_MODE_HOST_RECOMMENDED)
+            cpuType = VIR_QEMU_CAPS_HOST_CPU_RECOMMENDED;
+        else
+            cpuType = VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE;
+
         if (virCPUUpdate(def->os.arch, def->cpu,
-                         virQEMUCapsGetHostModel(qemuCaps, def->virtType,
-                                                 VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
+                         virQEMUCapsGetHostModel(qemuCaps, def->virtType, cpuType)) < 0)
             return -1;
 
         cpuModels = virQEMUCapsGetCPUModels(qemuCaps, def->virtType, NULL, NULL);
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 387c2f1fa8..a60445f686 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -373,6 +373,13 @@ qemuValidateDomainDefCpu(virQEMUDriver *driver,
             break;
 
         case VIR_CPU_MODE_HOST_RECOMMENDED:
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_STATIC_RECOMMENDED)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("host-recommended CPU is not supported by QEMU binary"));
+                return -1;
+            }
+            break;
+
         case VIR_CPU_MODE_CUSTOM:
         case VIR_CPU_MODE_LAST:
             break;
diff --git a/tests/qemuxml2argvdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.s390x-latest.args b/tests/qemuxml2argvdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.s390x-latest.args
new file mode 100644
index 0000000000..78546380d7
--- /dev/null
+++ b/tests/qemuxml2argvdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.s390x-latest.args
@@ -0,0 +1,32 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-test \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-test/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-test/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-test/.config \
+/usr/bin/qemu-system-s390x \
+-name guest=test,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-test/master-key.aes"}' \
+-machine s390-ccw-virtio-8.1,usb=off,dump-guest-core=off,memory-backend=s390.ram \
+-accel kvm \
+-cpu gen16a-base,nnpa=on,aen=on,cmmnt=on,vxpdeh=on,aefsi=on,diag318=on,csske=off,mepoch=on,msa9=on,msa8=on,msa7=on,msa6=on,msa5=on,msa4=on,msa3=on,msa2=on,msa1=on,sthyi=on,edat=on,ri=on,deflate=on,edat2=on,etoken=on,vx=on,ipter=on,pai=on,paie=on,mepochptff=on,ap=on,vxeh=on,vxpd=on,esop=on,msa9_pckmo=on,vxeh2=on,esort=on,apqi=on,apft=on,els=on,iep=on,apqci=on,cte=off,ais=on,bpb=off,gs=on,ppa15=on,zpci=on,rdp=on,sea_esop2=on,beareh=on,te=off,cmm=on,vxpdeh2=on \
+-m size=262144k \
+-object '{"qom-type":"memory-backend-ram","id":"s390.ram","size":268435456}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 9aa4b45c-b9dd-45ef-91fe-862b27b4231f \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"virtio-balloon-ccw","id":"balloon0","devno":"fe.0.0000"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.xml b/tests/qemuxml2argvdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.xml
new file mode 100644
index 0000000000..cacc1933dd
--- /dev/null
+++ b/tests/qemuxml2argvdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.xml
@@ -0,0 +1,17 @@
+<domain type='kvm'>
+  <name>test</name>
+  <uuid>9aa4b45c-b9dd-45ef-91fe-862b27b4231f</uuid>
+  <memory>262144</memory>
+  <currentMemory>262144</currentMemory>
+  <os>
+    <type arch='s390x' machine='s390-ccw-virtio-8.1'>hvm</type>
+  </os>
+  <cpu mode='host-recommended'/>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-s390x</emulator>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 2d06e2a0d1..4c3b698b83 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2295,6 +2295,8 @@ mymain(void)
     DO_TEST_CAPS_ARCH_LATEST("s390-async-teardown-disabled", "s390x");
     DO_TEST_CAPS_ARCH_VER("s390-async-teardown-disabled", "s390x", "6.0.0");
 
+    DO_TEST_CAPS_ARCH_LATEST("s390-host-rec-cpu-kvm-ccw-virtio-8.1", "s390x");
+
     qemuTestDriverFree(&driver);
     virFileWrapperClearPrefixes();
 
diff --git a/tests/qemuxml2xmloutdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.s390x-latest.xml b/tests/qemuxml2xmloutdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.s390x-latest.xml
new file mode 100644
index 0000000000..177694afe8
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/s390-host-rec-cpu-kvm-ccw-virtio-8.1.s390x-latest.xml
@@ -0,0 +1,25 @@
+<domain type='kvm'>
+  <name>test</name>
+  <uuid>9aa4b45c-b9dd-45ef-91fe-862b27b4231f</uuid>
+  <memory unit='KiB'>262144</memory>
+  <currentMemory unit='KiB'>262144</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='s390x' machine='s390-ccw-virtio-8.1'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <cpu mode='host-recommended' check='partial'/>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-s390x</emulator>
+    <controller type='pci' index='0' model='pci-root'/>
+    <audio id='1' type='none'/>
+    <memballoon model='virtio'>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0000'/>
+    </memballoon>
+    <panic model='s390'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 72f976358f..1038fa8f07 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -941,6 +941,7 @@ mymain(void)
     DO_TEST_CAPS_ARCH_LATEST("s390-default-cpu-tcg-ccw-virtio-2.7", "s390x");
     DO_TEST_CAPS_ARCH_LATEST("s390-default-cpu-kvm-ccw-virtio-4.2", "s390x");
     DO_TEST_CAPS_ARCH_LATEST("s390-default-cpu-tcg-ccw-virtio-4.2", "s390x");
+    DO_TEST_CAPS_ARCH_LATEST("s390-host-rec-cpu-kvm-ccw-virtio-8.1", "s390x");
     DO_TEST_CAPS_ARCH_LATEST("x86_64-default-cpu-kvm-pc-4.2", "x86_64");
     DO_TEST_CAPS_ARCH_LATEST("x86_64-default-cpu-tcg-pc-4.2", "x86_64");
     DO_TEST_CAPS_ARCH_LATEST("x86_64-default-cpu-kvm-q35-4.2", "x86_64");
-- 
2.41.0