On Tue, Apr 15, 2025 at 04:13:09AM -0400, Narayana Murty N wrote:
QEMU has historically used uppercase CPU model names like
"POWER8",
"POWER9", etc. However, starting with commit c5354f54aa60 ("ppc: make
cpu_model translation to type consistent"), QEMU began using lowercase
CPU model names (e.g., "power8") for newer POWER generations.
This commit is years old from QEMU 2.11.0.
What is special about power11 that we suddenly have a problem
with host-model today ?
This shift in naming convention causes host-model compatibility checks
to fail, as the logic in ppc64CheckCompatibilityMode was case-sensitive
and expected only uppercase model names.
This patch adds support for "power11" as a valid host-model. Also
updates the compatibility logic to treat host-model names case-insensitively,
enabling recognition of both legacy uppercase and newer lowercase formats.
To ensure compatibility checks work correctly across POWER CPU generations,
avoiding false mismatches due to case differences.
This patch feels like it is doing two different things in one
commit - adding 'power11' and changing behaviour of code to
be case insensitive. This likely ought to be separate commits,
with a better explanation of why we need the case insensitive
changes now, since the change on QEMU was 8 years ago.
Signed-off-by: Narayana Murty N <nnmlinux(a)linux.ibm.com>
---
src/cpu/cpu_ppc64.c | 11 +++----
...eries-cpu-compat-power11.ppc64-latest.args | 31 +++++++++++++++++++
...series-cpu-compat-power11.ppc64-latest.err | 1 +
...series-cpu-compat-power11.ppc64-latest.xml | 29 +++++++++++++++++
.../pseries-cpu-compat-power11.xml | 19 ++++++++++++
tests/qemuxmlconftest.c | 4 +++
tests/testutilshostcpus.h | 11 +++++++
tests/testutilsqemu.c | 4 +++
tests/testutilsqemu.h | 1 +
9 files changed, 105 insertions(+), 6 deletions(-)
create mode 100644 tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.args
create mode 100644 tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.err
create mode 100644 tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.xml
create mode 100644 tests/qemuxmlconfdata/pseries-cpu-compat-power11.xml
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
index 13f5fc9c2c..d1b9c52287 100644
--- a/src/cpu/cpu_ppc64.c
+++ b/src/cpu/cpu_ppc64.c
@@ -93,22 +93,21 @@ ppc64CheckCompatibilityMode(const char *host_model,
if (!compat_mode)
return VIR_CPU_COMPARE_IDENTICAL;
- /* Valid host CPUs: POWER6, POWER7, POWER8, POWER9, POWER10 */
- if (!STRPREFIX(host_model, "POWER") ||
+ /* Valid host CPUs: POWER6, POWER7, POWER8, POWER9, POWER10, power11 */
+ if (!STRCASEPREFIX(host_model, "POWER") ||
!(tmp = (char *) host_model + strlen("POWER")) ||
virStrToLong_i(tmp, NULL, 10, &host) < 0 ||
- host < 6 || host > 10) {
+ host < 6 || host > 11) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s",
_("Host CPU does not support compatibility modes"));
return VIR_CPU_COMPARE_ERROR;
}
-
- /* Valid compatibility modes: power6, power7, power8, power9, power10 */
+ /* Valid compatibility modes: power6, power7, power8, power9, power10, power11 */
if (!STRPREFIX(compat_mode, "power") ||
!(tmp = (char *) compat_mode + strlen("power")) ||
virStrToLong_i(tmp, NULL, 10, &compat) < 0 ||
- compat < 6 || compat > 10) {
+ compat < 6 || compat > 11) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown compatibility mode %1$s"),
compat_mode);
diff --git a/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.args
b/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.args
new file mode 100644
index 0000000000..a800f81905
--- /dev/null
+++ b/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.args
@@ -0,0 +1,31 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-ppc64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}'
\
+-machine
pseries,usb=off,dump-guest-core=off,memory-backend=ppc_spapr.ram,max-cpu-compat=power11 \
+-accel kvm \
+-cpu host \
+-m size=262144k \
+-object
'{"qom-type":"memory-backend-ram","id":"ppc_spapr.ram","size":268435456}'
\
+-overcommit mem-lock=off \
+-smp 4,sockets=4,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-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"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.err
b/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.err
new file mode 100644
index 0000000000..f2322ccea5
--- /dev/null
+++ b/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.err
@@ -0,0 +1 @@
+the CPU is incompatible with host CPU
diff --git a/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.xml
b/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.xml
new file mode 100644
index 0000000000..75c2b625c2
--- /dev/null
+++ b/tests/qemuxmlconfdata/pseries-cpu-compat-power11.ppc64-latest.xml
@@ -0,0 +1,29 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>4</vcpu>
+ <os>
+ <type arch='ppc64' machine='pseries'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='host-model' check='partial'>
+ <model fallback='allow'>power11</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-ppc64</emulator>
+ <controller type='usb' index='0' model='none'/>
+ <controller type='pci' index='0' model='pci-root'>
+ <model name='spapr-pci-host-bridge'/>
+ <target index='0'/>
+ </controller>
+ <audio id='1' type='none'/>
+ <memballoon model='none'/>
+ <panic model='pseries'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/pseries-cpu-compat-power11.xml
b/tests/qemuxmlconfdata/pseries-cpu-compat-power11.xml
new file mode 100644
index 0000000000..2dcdc651ef
--- /dev/null
+++ b/tests/qemuxmlconfdata/pseries-cpu-compat-power11.xml
@@ -0,0 +1,19 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>4</vcpu>
+ <os>
+ <type arch='ppc64' machine='pseries'>hvm</type>
+ </os>
+ <cpu mode='host-model'>
+ <model>power11</model>
+ </cpu>
+ <clock offset='utc'/>
+ <devices>
+ <emulator>/usr/bin/qemu-system-ppc64</emulator>
+ <controller type='usb' model='none'/>
+ <memballoon model="none"/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 3f916e5228..ee95733919 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2379,6 +2379,10 @@ mymain(void)
QEMU_CPU_DEF_POWER9);
DO_TEST_CAPS_LATEST_PPC64_HOSTCPU("pseries-cpu-compat-power10",
QEMU_CPU_DEF_POWER10);
+ DO_TEST_CAPS_LATEST_PPC64_HOSTCPU_FAILURE("pseries-cpu-compat-power11",
+ QEMU_CPU_DEF_POWER10);
+ DO_TEST_CAPS_LATEST_PPC64_HOSTCPU("pseries-cpu-compat-power11",
+ QEMU_CPU_DEF_POWER11);
qemuTestSetHostArch(&driver, VIR_ARCH_NONE);
diff --git a/tests/testutilshostcpus.h b/tests/testutilshostcpus.h
index 79c37baed4..6fd69e54db 100644
--- a/tests/testutilshostcpus.h
+++ b/tests/testutilshostcpus.h
@@ -123,6 +123,15 @@ static virCPUDef cpuPower10Data = {
.threads = 1,
};
+static virCPUDef cpuPower11Data = {
+ .type = VIR_CPU_TYPE_HOST,
+ .arch = VIR_ARCH_PPC64,
+ .model = (char *) "power11",
+ .sockets = 1,
+ .cores = 16,
+ .threads = 1,
+};
+
static virCPUDef cpuAarch64Data = {
.type = VIR_CPU_TYPE_HOST,
.arch = VIR_ARCH_AARCH64,
@@ -197,6 +206,8 @@ testUtilsHostCpusGetDefForModel(const char *model)
return virCPUDefCopy(&cpuPower9Data);
else if (STREQ(model, "POWER10"))
return virCPUDefCopy(&cpuPower10Data);
+ else if (STREQ(model, "power11"))
+ return virCPUDefCopy(&cpuPower11Data);
return NULL;
}
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index ecd761dff0..9038a37869 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -24,6 +24,7 @@ static virCPUDef *cpuHaswell;
static virCPUDef *cpuPower8;
static virCPUDef *cpuPower9;
static virCPUDef *cpuPower10;
+static virCPUDef *cpuPower11;
char *
virFindFileInPath(const char *file)
@@ -166,6 +167,7 @@ qemuTestGetCPUDef(qemuTestCPUDef d)
case QEMU_CPU_DEF_POWER8: return cpuPower8;
case QEMU_CPU_DEF_POWER9: return cpuPower9;
case QEMU_CPU_DEF_POWER10: return cpuPower10;
+ case QEMU_CPU_DEF_POWER11: return cpuPower11;
}
return NULL;
@@ -251,6 +253,7 @@ void qemuTestDriverFree(virQEMUDriver *driver)
virCPUDefFree(cpuPower8);
virCPUDefFree(cpuPower9);
virCPUDefFree(cpuPower10);
+ virCPUDefFree(cpuPower11);
}
@@ -303,6 +306,7 @@ int qemuTestDriverInit(virQEMUDriver *driver)
cpuPower8 = virCPUDefCopy(&cpuPower8Data);
cpuPower9 = virCPUDefCopy(&cpuPower9Data);
cpuPower10 = virCPUDefCopy(&cpuPower10Data);
+ cpuPower11 = virCPUDefCopy(&cpuPower11Data);
if (virMutexInit(&driver->lock) < 0)
return -1;
diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h
index 20135b8390..62943bb2d8 100644
--- a/tests/testutilsqemu.h
+++ b/tests/testutilsqemu.h
@@ -78,6 +78,7 @@ typedef enum {
QEMU_CPU_DEF_POWER8,
QEMU_CPU_DEF_POWER9,
QEMU_CPU_DEF_POWER10,
+ QEMU_CPU_DEF_POWER11,
} qemuTestCPUDef;
struct testQemuArgs {
--
2.48.1
With regards,
Daniel
--
|:
https://berrange.com -o-
https://www.flickr.com/photos/dberrange :|
|:
https://libvirt.org -o-
https://fstop138.berrange.com :|
|:
https://entangle-photo.org -o-
https://www.instagram.com/dberrange :|