summary refs log tree commit diff stats
path: root/tests/functional/test_x86_cpu_model_versions.py
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2024-09-05 18:01:51 +0100
committerPeter Maydell <peter.maydell@linaro.org>2024-09-05 18:01:51 +0100
commiteabebca69b7fca7cf85f6cd39ac58a7f04986b47 (patch)
tree5e7bcc92e509008cc5b761fa3fbb08e69075825c /tests/functional/test_x86_cpu_model_versions.py
parent7b87a25f49a301d3377f3e71e0b4a62540c6f6e4 (diff)
parentc3e24cff2b27d63ac4b56ac6d38ef1ae3a27d92f (diff)
downloadfocaccia-qemu-eabebca69b7fca7cf85f6cd39ac58a7f04986b47.tar.gz
focaccia-qemu-eabebca69b7fca7cf85f6cd39ac58a7f04986b47.zip
Merge tag 'pull-request-2024-09-04' of https://gitlab.com/thuth/qemu into staging
* Bump Avocado to version 103
* Introduce new functional test framework for Python-based tests
* Convert many Avocado tests to the new functional test framework

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmbYOEsRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbUDAA/+Kdlak/nCrK5gXDyDasfy86IxgMD0QlDR
# U0MOpQyfXbM2EJjwCUhmgo8pui8qV23dKzfCwbDmkjB7mJ+yKi2ZdiFEp6onq/ke
# aAdaaZwENtWcFglRD80TOSQX6oyeNmE/PuvJGG0BfwWXyyhaEa6kCdytEPORipQs
# lZ+ZndHgXtcM3roXtgI3kp2V1nY5LLCJ044UrasKRq2xWfD/Ken90uWP5/nMLV7f
# 7YLRUIb0sgV7IdjZiT1UkXJZRB7MatV7+OsojYbG8BPbQEvXqpryXMIeygHVR9a0
# yxNDUpTZR6JoS1IaLKkHh1mTM+L1JpFltKadKkXa0zqJHHSur7Tp0xVO/GeqCek4
# 9N8K4zw2CoO/AKmN8JjW5i4GnMrFMdcvxxNwLdRoVgYt4YA731wnHrbosXZOXcuv
# H0z8Tm6ueKvfBtrQErdvqsGrP/8FUYRqZP4H6XaaC+wEis++7OmVR2nlQ/gAyr6/
# mMJtmxqVHCIcEVjDu1jYltrW3BN2CcxN2M9gxyOScq2/Xmzqtaeb4iyjxeCUjIBW
# Pc4LXlSafIg3hPrdH3EKN275ev8cx/5jp8oEgXD5We25Mj3W930zde6/STXoX318
# NVNlbrIQjGjQN7rN5oxTFxTlIN8ax2tuuzpQDFvS/4bLyMYXcZ4I5gUrM5tvWTGv
# +0UN45pJ7Nk=
# =l6Ki
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 04 Sep 2024 11:36:59 BST
# gpg:                using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg:                issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* tag 'pull-request-2024-09-04' of https://gitlab.com/thuth/qemu: (42 commits)
  docs/devel/testing: Add documentation for functional tests
  docs/devel/testing: Rename avocado_qemu.Test class
  docs/devel/testing: Split the Avocado documentation into a separate file
  docs/devel: Split testing docs from the build docs and move to separate folder
  gitlab-ci: Add "check-functional" to the build tests
  tests/avocado: Remove unused QemuUserTest class
  tests/functional: Convert ARM bFLT linux-user avocado test
  tests/functional: Add QemuUserTest class
  tests/functional: Convert mips64el Fuloong2e avocado test (1/2)
  tests/functional: Convert Aarch64 Virt machine avocado tests
  tests/functional: Convert Aarch64 SBSA-Ref avocado tests
  tests/functional: Convert ARM Integrator/CP avocado tests
  tests/functional: Convert the linux_initrd avocado test into a standalone test
  tests/functional: Convert the rx_gdbsim avocado test into a standalone test
  tests/functional: Convert the acpi-bits test into a standalone test
  tests/functional: Convert the m68k nextcube test with tesseract
  tests/functional: Convert the ppc_hv avocado test into a standalone test
  tests/functional: Convert the ppc_amiga avocado test into a standalone test
  tests/functional: Convert most ppc avocado tests into standalone tests
  tests/functional: Convert the virtio_gpu avocado test into a standalone test
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests/functional/test_x86_cpu_model_versions.py')
-rwxr-xr-xtests/functional/test_x86_cpu_model_versions.py335
1 files changed, 335 insertions, 0 deletions
diff --git a/tests/functional/test_x86_cpu_model_versions.py b/tests/functional/test_x86_cpu_model_versions.py
new file mode 100755
index 0000000000..bd18acd44f
--- /dev/null
+++ b/tests/functional/test_x86_cpu_model_versions.py
@@ -0,0 +1,335 @@
+#!/usr/bin/env python3
+#
+# Basic validation of x86 versioned CPU models and CPU model aliases
+#
+#  Copyright (c) 2019 Red Hat Inc
+#
+# Author:
+#  Eduardo Habkost <ehabkost@redhat.com>
+#
+# 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/>.
+#
+
+import re
+
+from qemu_test import QemuSystemTest
+
+class X86CPUModelAliases(QemuSystemTest):
+    """
+    Validation of PC CPU model versions and CPU model aliases
+    """
+    def validate_aliases(self, cpus):
+        for c in cpus.values():
+            if 'alias-of' in c:
+                # all aliases must point to a valid CPU model name:
+                self.assertIn(c['alias-of'], cpus,
+                              '%s.alias-of (%s) is not a valid CPU model name' % (c['name'], c['alias-of']))
+                # aliases must not point to aliases
+                self.assertNotIn('alias-of', cpus[c['alias-of']],
+                                 '%s.alias-of (%s) points to another alias' % (c['name'], c['alias-of']))
+
+                # aliases must not be static
+                self.assertFalse(c['static'])
+
+    def validate_variant_aliases(self, cpus):
+        # -noTSX, -IBRS and -IBPB variants of CPU models are special:
+        # they shouldn't have their own versions:
+        self.assertNotIn("Haswell-noTSX-v1", cpus,
+                         "Haswell-noTSX shouldn't be versioned")
+        self.assertNotIn("Broadwell-noTSX-v1", cpus,
+                         "Broadwell-noTSX shouldn't be versioned")
+        self.assertNotIn("Nehalem-IBRS-v1", cpus,
+                         "Nehalem-IBRS shouldn't be versioned")
+        self.assertNotIn("Westmere-IBRS-v1", cpus,
+                         "Westmere-IBRS shouldn't be versioned")
+        self.assertNotIn("SandyBridge-IBRS-v1", cpus,
+                         "SandyBridge-IBRS shouldn't be versioned")
+        self.assertNotIn("IvyBridge-IBRS-v1", cpus,
+                         "IvyBridge-IBRS shouldn't be versioned")
+        self.assertNotIn("Haswell-noTSX-IBRS-v1", cpus,
+                         "Haswell-noTSX-IBRS shouldn't be versioned")
+        self.assertNotIn("Haswell-IBRS-v1", cpus,
+                         "Haswell-IBRS shouldn't be versioned")
+        self.assertNotIn("Broadwell-noTSX-IBRS-v1", cpus,
+                         "Broadwell-noTSX-IBRS shouldn't be versioned")
+        self.assertNotIn("Broadwell-IBRS-v1", cpus,
+                         "Broadwell-IBRS shouldn't be versioned")
+        self.assertNotIn("Skylake-Client-IBRS-v1", cpus,
+                         "Skylake-Client-IBRS shouldn't be versioned")
+        self.assertNotIn("Skylake-Server-IBRS-v1", cpus,
+                         "Skylake-Server-IBRS shouldn't be versioned")
+        self.assertNotIn("EPYC-IBPB-v1", cpus,
+                         "EPYC-IBPB shouldn't be versioned")
+
+    def test_4_0_alias_compatibility(self):
+        """
+        Check if pc-*-4.0 unversioned CPU model won't be reported as aliases
+        """
+        self.set_machine('pc-i440fx-4.0')
+        # pc-*-4.0 won't expose non-versioned CPU models as aliases
+        # We do this to help management software to keep compatibility
+        # with older QEMU versions that didn't have the versioned CPU model
+        self.vm.add_args('-S')
+        self.vm.launch()
+        cpus = dict((m['name'], m) for m in
+                    self.vm.cmd('query-cpu-definitions'))
+
+        self.assertFalse(cpus['Cascadelake-Server']['static'],
+                         'unversioned Cascadelake-Server CPU model must not be static')
+        self.assertNotIn('alias-of', cpus['Cascadelake-Server'],
+                         'Cascadelake-Server must not be an alias')
+        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
+                         'Cascadelake-Server-v1 must not be an alias')
+
+        self.assertFalse(cpus['qemu64']['static'],
+                         'unversioned qemu64 CPU model must not be static')
+        self.assertNotIn('alias-of', cpus['qemu64'],
+                         'qemu64 must not be an alias')
+        self.assertNotIn('alias-of', cpus['qemu64-v1'],
+                         'qemu64-v1 must not be an alias')
+
+        self.validate_variant_aliases(cpus)
+
+        # On pc-*-4.0, no CPU model should be reported as an alias:
+        for name,c in cpus.items():
+            self.assertNotIn('alias-of', c, "%s shouldn't be an alias" % (name))
+
+    def test_4_1_alias(self):
+        """
+        Check if unversioned CPU model is an alias pointing to right version
+        """
+        self.set_machine('pc-i440fx-4.1')
+        self.vm.add_args('-S')
+        self.vm.launch()
+
+        cpus = dict((m['name'], m) for m in
+                    self.vm.cmd('query-cpu-definitions'))
+
+        self.assertFalse(cpus['Cascadelake-Server']['static'],
+                         'unversioned Cascadelake-Server CPU model must not be static')
+        self.assertEqual(cpus['Cascadelake-Server'].get('alias-of'),
+                         'Cascadelake-Server-v1',
+                         'Cascadelake-Server must be an alias of Cascadelake-Server-v1')
+        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
+                         'Cascadelake-Server-v1 must not be an alias')
+
+        self.assertFalse(cpus['qemu64']['static'],
+                         'unversioned qemu64 CPU model must not be static')
+        self.assertEqual(cpus['qemu64'].get('alias-of'), 'qemu64-v1',
+                         'qemu64 must be an alias of qemu64-v1')
+        self.assertNotIn('alias-of', cpus['qemu64-v1'],
+                         'qemu64-v1 must not be an alias')
+
+        self.validate_variant_aliases(cpus)
+
+        # On pc-*-4.1, -noTSX and -IBRS models should be aliases:
+        self.assertEqual(cpus["Haswell"].get('alias-of'),
+                         "Haswell-v1",
+                         "Haswell must be an alias")
+        self.assertEqual(cpus["Haswell-noTSX"].get('alias-of'),
+                         "Haswell-v2",
+                         "Haswell-noTSX must be an alias")
+        self.assertEqual(cpus["Haswell-IBRS"].get('alias-of'),
+                         "Haswell-v3",
+                         "Haswell-IBRS must be an alias")
+        self.assertEqual(cpus["Haswell-noTSX-IBRS"].get('alias-of'),
+                         "Haswell-v4",
+                         "Haswell-noTSX-IBRS must be an alias")
+
+        self.assertEqual(cpus["Broadwell"].get('alias-of'),
+                         "Broadwell-v1",
+                         "Broadwell must be an alias")
+        self.assertEqual(cpus["Broadwell-noTSX"].get('alias-of'),
+                         "Broadwell-v2",
+                         "Broadwell-noTSX must be an alias")
+        self.assertEqual(cpus["Broadwell-IBRS"].get('alias-of'),
+                         "Broadwell-v3",
+                         "Broadwell-IBRS must be an alias")
+        self.assertEqual(cpus["Broadwell-noTSX-IBRS"].get('alias-of'),
+                         "Broadwell-v4",
+                         "Broadwell-noTSX-IBRS must be an alias")
+
+        self.assertEqual(cpus["Nehalem"].get('alias-of'),
+                         "Nehalem-v1",
+                         "Nehalem must be an alias")
+        self.assertEqual(cpus["Nehalem-IBRS"].get('alias-of'),
+                         "Nehalem-v2",
+                         "Nehalem-IBRS must be an alias")
+
+        self.assertEqual(cpus["Westmere"].get('alias-of'),
+                         "Westmere-v1",
+                         "Westmere must be an alias")
+        self.assertEqual(cpus["Westmere-IBRS"].get('alias-of'),
+                         "Westmere-v2",
+                         "Westmere-IBRS must be an alias")
+
+        self.assertEqual(cpus["SandyBridge"].get('alias-of'),
+                         "SandyBridge-v1",
+                         "SandyBridge must be an alias")
+        self.assertEqual(cpus["SandyBridge-IBRS"].get('alias-of'),
+                         "SandyBridge-v2",
+                         "SandyBridge-IBRS must be an alias")
+
+        self.assertEqual(cpus["IvyBridge"].get('alias-of'),
+                         "IvyBridge-v1",
+                         "IvyBridge must be an alias")
+        self.assertEqual(cpus["IvyBridge-IBRS"].get('alias-of'),
+                         "IvyBridge-v2",
+                         "IvyBridge-IBRS must be an alias")
+
+        self.assertEqual(cpus["Skylake-Client"].get('alias-of'),
+                         "Skylake-Client-v1",
+                         "Skylake-Client must be an alias")
+        self.assertEqual(cpus["Skylake-Client-IBRS"].get('alias-of'),
+                         "Skylake-Client-v2",
+                         "Skylake-Client-IBRS must be an alias")
+
+        self.assertEqual(cpus["Skylake-Server"].get('alias-of'),
+                         "Skylake-Server-v1",
+                         "Skylake-Server must be an alias")
+        self.assertEqual(cpus["Skylake-Server-IBRS"].get('alias-of'),
+                         "Skylake-Server-v2",
+                         "Skylake-Server-IBRS must be an alias")
+
+        self.assertEqual(cpus["EPYC"].get('alias-of'),
+                         "EPYC-v1",
+                         "EPYC must be an alias")
+        self.assertEqual(cpus["EPYC-IBPB"].get('alias-of'),
+                         "EPYC-v2",
+                         "EPYC-IBPB must be an alias")
+
+        self.validate_aliases(cpus)
+
+    def test_none_alias(self):
+        """
+        Check if unversioned CPU model is an alias pointing to some version
+        """
+        self.set_machine('none')
+        self.vm.add_args('-S')
+        self.vm.launch()
+
+        cpus = dict((m['name'], m) for m in
+                    self.vm.cmd('query-cpu-definitions'))
+
+        self.assertFalse(cpus['Cascadelake-Server']['static'],
+                         'unversioned Cascadelake-Server CPU model must not be static')
+        self.assertTrue(re.match('Cascadelake-Server-v[0-9]+', cpus['Cascadelake-Server']['alias-of']),
+                        'Cascadelake-Server must be an alias of versioned CPU model')
+        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
+                         'Cascadelake-Server-v1 must not be an alias')
+
+        self.assertFalse(cpus['qemu64']['static'],
+                         'unversioned qemu64 CPU model must not be static')
+        self.assertTrue(re.match('qemu64-v[0-9]+', cpus['qemu64']['alias-of']),
+                        'qemu64 must be an alias of versioned CPU model')
+        self.assertNotIn('alias-of', cpus['qemu64-v1'],
+                         'qemu64-v1 must not be an alias')
+
+        self.validate_aliases(cpus)
+
+
+class CascadelakeArchCapabilities(QemuSystemTest):
+    """
+    Validation of Cascadelake arch-capabilities
+    """
+    def get_cpu_prop(self, prop):
+        cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path')
+        return self.vm.cmd('qom-get', path=cpu_path, property=prop)
+
+    def test_4_1(self):
+        self.set_machine('pc-i440fx-4.1')
+        # machine-type only:
+        self.vm.add_args('-S')
+        self.set_vm_arg('-cpu',
+                        'Cascadelake-Server,x-force-features=on,check=off,'
+                        'enforce=off')
+        self.vm.launch()
+        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
+                         'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
+
+    def test_4_0(self):
+        self.set_machine('pc-i440fx-4.0')
+        self.vm.add_args('-S')
+        self.set_vm_arg('-cpu',
+                        'Cascadelake-Server,x-force-features=on,check=off,'
+                        'enforce=off')
+        self.vm.launch()
+        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
+                         'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
+
+    def test_set_4_0(self):
+        self.set_machine('pc-i440fx-4.0')
+        # command line must override machine-type if CPU model is not versioned:
+        self.vm.add_args('-S')
+        self.set_vm_arg('-cpu',
+                        'Cascadelake-Server,x-force-features=on,check=off,'
+                        'enforce=off,+arch-capabilities')
+        self.vm.launch()
+        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
+                        'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
+
+    def test_unset_4_1(self):
+        self.set_machine('pc-i440fx-4.1')
+        self.vm.add_args('-S')
+        self.set_vm_arg('-cpu',
+                        'Cascadelake-Server,x-force-features=on,check=off,'
+                        'enforce=off,-arch-capabilities')
+        self.vm.launch()
+        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
+                         'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
+
+    def test_v1_4_0(self):
+        self.set_machine('pc-i440fx-4.0')
+        # versioned CPU model overrides machine-type:
+        self.vm.add_args('-S')
+        self.set_vm_arg('-cpu',
+                        'Cascadelake-Server-v1,x-force-features=on,check=off,'
+                        'enforce=off')
+        self.vm.launch()
+        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
+                         'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
+
+    def test_v2_4_0(self):
+        self.set_machine('pc-i440fx-4.0')
+        self.vm.add_args('-S')
+        self.set_vm_arg('-cpu',
+                        'Cascadelake-Server-v2,x-force-features=on,check=off,'
+                        'enforce=off')
+        self.vm.launch()
+        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
+                        'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
+
+    def test_v1_set_4_0(self):
+        self.set_machine('pc-i440fx-4.0')
+        # command line must override machine-type and versioned CPU model:
+        self.vm.add_args('-S')
+        self.set_vm_arg('-cpu',
+                        'Cascadelake-Server-v1,x-force-features=on,check=off,'
+                        'enforce=off,+arch-capabilities')
+        self.vm.launch()
+        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
+                        'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
+
+    def test_v2_unset_4_1(self):
+        self.set_machine('pc-i440fx-4.1')
+        self.vm.add_args('-S')
+        self.set_vm_arg('-cpu',
+                        'Cascadelake-Server-v2,x-force-features=on,check=off,'
+                        'enforce=off,-arch-capabilities')
+        self.vm.launch()
+        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
+                         'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')
+
+if __name__ == '__main__':
+    QemuSystemTest.main()