qemu/tests/avocado/x86_cpu_model_versions.py
<<
>>
Prefs
   1#
   2# Basic validation of x86 versioned CPU models and CPU model aliases
   3#
   4#  Copyright (c) 2019 Red Hat Inc
   5#
   6# Author:
   7#  Eduardo Habkost <ehabkost@redhat.com>
   8#
   9# This library is free software; you can redistribute it and/or
  10# modify it under the terms of the GNU Lesser General Public
  11# License as published by the Free Software Foundation; either
  12# version 2.1 of the License, or (at your option) any later version.
  13#
  14# This library is distributed in the hope that it will be useful,
  15# but WITHOUT ANY WARRANTY; without even the implied warranty of
  16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17# Lesser General Public License for more details.
  18#
  19# You should have received a copy of the GNU Lesser General Public
  20# License along with this library; if not, see <http://www.gnu.org/licenses/>.
  21#
  22
  23
  24import avocado_qemu
  25import re
  26
  27class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
  28    """
  29    Validation of PC CPU model versions and CPU model aliases
  30
  31    :avocado: tags=arch:x86_64
  32    """
  33    def validate_aliases(self, cpus):
  34        for c in cpus.values():
  35            if 'alias-of' in c:
  36                # all aliases must point to a valid CPU model name:
  37                self.assertIn(c['alias-of'], cpus,
  38                              '%s.alias-of (%s) is not a valid CPU model name' % (c['name'], c['alias-of']))
  39                # aliases must not point to aliases
  40                self.assertNotIn('alias-of', cpus[c['alias-of']],
  41                                 '%s.alias-of (%s) points to another alias' % (c['name'], c['alias-of']))
  42
  43                # aliases must not be static
  44                self.assertFalse(c['static'])
  45
  46    def validate_variant_aliases(self, cpus):
  47        # -noTSX, -IBRS and -IBPB variants of CPU models are special:
  48        # they shouldn't have their own versions:
  49        self.assertNotIn("Haswell-noTSX-v1", cpus,
  50                         "Haswell-noTSX shouldn't be versioned")
  51        self.assertNotIn("Broadwell-noTSX-v1", cpus,
  52                         "Broadwell-noTSX shouldn't be versioned")
  53        self.assertNotIn("Nehalem-IBRS-v1", cpus,
  54                         "Nehalem-IBRS shouldn't be versioned")
  55        self.assertNotIn("Westmere-IBRS-v1", cpus,
  56                         "Westmere-IBRS shouldn't be versioned")
  57        self.assertNotIn("SandyBridge-IBRS-v1", cpus,
  58                         "SandyBridge-IBRS shouldn't be versioned")
  59        self.assertNotIn("IvyBridge-IBRS-v1", cpus,
  60                         "IvyBridge-IBRS shouldn't be versioned")
  61        self.assertNotIn("Haswell-noTSX-IBRS-v1", cpus,
  62                         "Haswell-noTSX-IBRS shouldn't be versioned")
  63        self.assertNotIn("Haswell-IBRS-v1", cpus,
  64                         "Haswell-IBRS shouldn't be versioned")
  65        self.assertNotIn("Broadwell-noTSX-IBRS-v1", cpus,
  66                         "Broadwell-noTSX-IBRS shouldn't be versioned")
  67        self.assertNotIn("Broadwell-IBRS-v1", cpus,
  68                         "Broadwell-IBRS shouldn't be versioned")
  69        self.assertNotIn("Skylake-Client-IBRS-v1", cpus,
  70                         "Skylake-Client-IBRS shouldn't be versioned")
  71        self.assertNotIn("Skylake-Server-IBRS-v1", cpus,
  72                         "Skylake-Server-IBRS shouldn't be versioned")
  73        self.assertNotIn("EPYC-IBPB-v1", cpus,
  74                         "EPYC-IBPB shouldn't be versioned")
  75
  76    def test_4_0_alias_compatibility(self):
  77        """
  78        Check if pc-*-4.0 unversioned CPU model won't be reported as aliases
  79
  80        :avocado: tags=machine:pc-i440fx-4.0
  81        """
  82        # pc-*-4.0 won't expose non-versioned CPU models as aliases
  83        # We do this to help management software to keep compatibility
  84        # with older QEMU versions that didn't have the versioned CPU model
  85        self.vm.add_args('-S')
  86        self.vm.launch()
  87        cpus = dict((m['name'], m) for m in self.vm.command('query-cpu-definitions'))
  88
  89        self.assertFalse(cpus['Cascadelake-Server']['static'],
  90                         'unversioned Cascadelake-Server CPU model must not be static')
  91        self.assertNotIn('alias-of', cpus['Cascadelake-Server'],
  92                         'Cascadelake-Server must not be an alias')
  93        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
  94                         'Cascadelake-Server-v1 must not be an alias')
  95
  96        self.assertFalse(cpus['qemu64']['static'],
  97                         'unversioned qemu64 CPU model must not be static')
  98        self.assertNotIn('alias-of', cpus['qemu64'],
  99                         'qemu64 must not be an alias')
 100        self.assertNotIn('alias-of', cpus['qemu64-v1'],
 101                         'qemu64-v1 must not be an alias')
 102
 103        self.validate_variant_aliases(cpus)
 104
 105        # On pc-*-4.0, no CPU model should be reported as an alias:
 106        for name,c in cpus.items():
 107            self.assertNotIn('alias-of', c, "%s shouldn't be an alias" % (name))
 108
 109    def test_4_1_alias(self):
 110        """
 111        Check if unversioned CPU model is an alias pointing to right version
 112
 113        :avocado: tags=machine:pc-i440fx-4.1
 114        """
 115        self.vm.add_args('-S')
 116        self.vm.launch()
 117
 118        cpus = dict((m['name'], m) for m in self.vm.command('query-cpu-definitions'))
 119
 120        self.assertFalse(cpus['Cascadelake-Server']['static'],
 121                         'unversioned Cascadelake-Server CPU model must not be static')
 122        self.assertEquals(cpus['Cascadelake-Server'].get('alias-of'), 'Cascadelake-Server-v1',
 123                          'Cascadelake-Server must be an alias of Cascadelake-Server-v1')
 124        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
 125                         'Cascadelake-Server-v1 must not be an alias')
 126
 127        self.assertFalse(cpus['qemu64']['static'],
 128                         'unversioned qemu64 CPU model must not be static')
 129        self.assertEquals(cpus['qemu64'].get('alias-of'), 'qemu64-v1',
 130                          'qemu64 must be an alias of qemu64-v1')
 131        self.assertNotIn('alias-of', cpus['qemu64-v1'],
 132                         'qemu64-v1 must not be an alias')
 133
 134        self.validate_variant_aliases(cpus)
 135
 136        # On pc-*-4.1, -noTSX and -IBRS models should be aliases:
 137        self.assertEquals(cpus["Haswell"].get('alias-of'),
 138                          "Haswell-v1",
 139                         "Haswell must be an alias")
 140        self.assertEquals(cpus["Haswell-noTSX"].get('alias-of'),
 141                          "Haswell-v2",
 142                         "Haswell-noTSX must be an alias")
 143        self.assertEquals(cpus["Haswell-IBRS"].get('alias-of'),
 144                          "Haswell-v3",
 145                         "Haswell-IBRS must be an alias")
 146        self.assertEquals(cpus["Haswell-noTSX-IBRS"].get('alias-of'),
 147                          "Haswell-v4",
 148                         "Haswell-noTSX-IBRS must be an alias")
 149
 150        self.assertEquals(cpus["Broadwell"].get('alias-of'),
 151                          "Broadwell-v1",
 152                         "Broadwell must be an alias")
 153        self.assertEquals(cpus["Broadwell-noTSX"].get('alias-of'),
 154                          "Broadwell-v2",
 155                         "Broadwell-noTSX must be an alias")
 156        self.assertEquals(cpus["Broadwell-IBRS"].get('alias-of'),
 157                          "Broadwell-v3",
 158                         "Broadwell-IBRS must be an alias")
 159        self.assertEquals(cpus["Broadwell-noTSX-IBRS"].get('alias-of'),
 160                          "Broadwell-v4",
 161                         "Broadwell-noTSX-IBRS must be an alias")
 162
 163        self.assertEquals(cpus["Nehalem"].get('alias-of'),
 164                          "Nehalem-v1",
 165                         "Nehalem must be an alias")
 166        self.assertEquals(cpus["Nehalem-IBRS"].get('alias-of'),
 167                          "Nehalem-v2",
 168                         "Nehalem-IBRS must be an alias")
 169
 170        self.assertEquals(cpus["Westmere"].get('alias-of'),
 171                          "Westmere-v1",
 172                         "Westmere must be an alias")
 173        self.assertEquals(cpus["Westmere-IBRS"].get('alias-of'),
 174                          "Westmere-v2",
 175                         "Westmere-IBRS must be an alias")
 176
 177        self.assertEquals(cpus["SandyBridge"].get('alias-of'),
 178                          "SandyBridge-v1",
 179                         "SandyBridge must be an alias")
 180        self.assertEquals(cpus["SandyBridge-IBRS"].get('alias-of'),
 181                          "SandyBridge-v2",
 182                         "SandyBridge-IBRS must be an alias")
 183
 184        self.assertEquals(cpus["IvyBridge"].get('alias-of'),
 185                          "IvyBridge-v1",
 186                         "IvyBridge must be an alias")
 187        self.assertEquals(cpus["IvyBridge-IBRS"].get('alias-of'),
 188                          "IvyBridge-v2",
 189                         "IvyBridge-IBRS must be an alias")
 190
 191        self.assertEquals(cpus["Skylake-Client"].get('alias-of'),
 192                          "Skylake-Client-v1",
 193                         "Skylake-Client must be an alias")
 194        self.assertEquals(cpus["Skylake-Client-IBRS"].get('alias-of'),
 195                          "Skylake-Client-v2",
 196                         "Skylake-Client-IBRS must be an alias")
 197
 198        self.assertEquals(cpus["Skylake-Server"].get('alias-of'),
 199                          "Skylake-Server-v1",
 200                         "Skylake-Server must be an alias")
 201        self.assertEquals(cpus["Skylake-Server-IBRS"].get('alias-of'),
 202                          "Skylake-Server-v2",
 203                         "Skylake-Server-IBRS must be an alias")
 204
 205        self.assertEquals(cpus["EPYC"].get('alias-of'),
 206                          "EPYC-v1",
 207                         "EPYC must be an alias")
 208        self.assertEquals(cpus["EPYC-IBPB"].get('alias-of'),
 209                          "EPYC-v2",
 210                         "EPYC-IBPB must be an alias")
 211
 212        self.validate_aliases(cpus)
 213
 214    def test_none_alias(self):
 215        """
 216        Check if unversioned CPU model is an alias pointing to some version
 217
 218        :avocado: tags=machine:none
 219        """
 220        self.vm.add_args('-S')
 221        self.vm.launch()
 222
 223        cpus = dict((m['name'], m) for m in self.vm.command('query-cpu-definitions'))
 224
 225        self.assertFalse(cpus['Cascadelake-Server']['static'],
 226                         'unversioned Cascadelake-Server CPU model must not be static')
 227        self.assertTrue(re.match('Cascadelake-Server-v[0-9]+', cpus['Cascadelake-Server']['alias-of']),
 228                        'Cascadelake-Server must be an alias of versioned CPU model')
 229        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
 230                         'Cascadelake-Server-v1 must not be an alias')
 231
 232        self.assertFalse(cpus['qemu64']['static'],
 233                         'unversioned qemu64 CPU model must not be static')
 234        self.assertTrue(re.match('qemu64-v[0-9]+', cpus['qemu64']['alias-of']),
 235                        'qemu64 must be an alias of versioned CPU model')
 236        self.assertNotIn('alias-of', cpus['qemu64-v1'],
 237                         'qemu64-v1 must not be an alias')
 238
 239        self.validate_aliases(cpus)
 240
 241
 242class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
 243    """
 244    Validation of Cascadelake arch-capabilities
 245
 246    :avocado: tags=arch:x86_64
 247    """
 248    def get_cpu_prop(self, prop):
 249        cpu_path = self.vm.command('query-cpus-fast')[0].get('qom-path')
 250        return self.vm.command('qom-get', path=cpu_path, property=prop)
 251
 252    def test_4_1(self):
 253        """
 254        :avocado: tags=machine:pc-i440fx-4.1
 255        :avocado: tags=cpu:Cascadelake-Server
 256        """
 257        # machine-type only:
 258        self.vm.add_args('-S')
 259        self.set_vm_arg('-cpu',
 260                        'Cascadelake-Server,x-force-features=on,check=off,'
 261                        'enforce=off')
 262        self.vm.launch()
 263        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
 264                         'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
 265
 266    def test_4_0(self):
 267        """
 268        :avocado: tags=machine:pc-i440fx-4.0
 269        :avocado: tags=cpu:Cascadelake-Server
 270        """
 271        self.vm.add_args('-S')
 272        self.set_vm_arg('-cpu',
 273                        'Cascadelake-Server,x-force-features=on,check=off,'
 274                        'enforce=off')
 275        self.vm.launch()
 276        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
 277                         'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
 278
 279    def test_set_4_0(self):
 280        """
 281        :avocado: tags=machine:pc-i440fx-4.0
 282        :avocado: tags=cpu:Cascadelake-Server
 283        """
 284        # command line must override machine-type if CPU model is not versioned:
 285        self.vm.add_args('-S')
 286        self.set_vm_arg('-cpu',
 287                        'Cascadelake-Server,x-force-features=on,check=off,'
 288                        'enforce=off,+arch-capabilities')
 289        self.vm.launch()
 290        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
 291                        'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
 292
 293    def test_unset_4_1(self):
 294        """
 295        :avocado: tags=machine:pc-i440fx-4.1
 296        :avocado: tags=cpu:Cascadelake-Server
 297        """
 298        self.vm.add_args('-S')
 299        self.set_vm_arg('-cpu',
 300                        'Cascadelake-Server,x-force-features=on,check=off,'
 301                        'enforce=off,-arch-capabilities')
 302        self.vm.launch()
 303        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
 304                         'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
 305
 306    def test_v1_4_0(self):
 307        """
 308        :avocado: tags=machine:pc-i440fx-4.0
 309        :avocado: tags=cpu:Cascadelake-Server
 310        """
 311        # versioned CPU model overrides machine-type:
 312        self.vm.add_args('-S')
 313        self.set_vm_arg('-cpu',
 314                        'Cascadelake-Server-v1,x-force-features=on,check=off,'
 315                        'enforce=off')
 316        self.vm.launch()
 317        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
 318                         'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
 319
 320    def test_v2_4_0(self):
 321        """
 322        :avocado: tags=machine:pc-i440fx-4.0
 323        :avocado: tags=cpu:Cascadelake-Server
 324        """
 325        self.vm.add_args('-S')
 326        self.set_vm_arg('-cpu',
 327                        'Cascadelake-Server-v2,x-force-features=on,check=off,'
 328                        'enforce=off')
 329        self.vm.launch()
 330        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
 331                        'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
 332
 333    def test_v1_set_4_0(self):
 334        """
 335        :avocado: tags=machine:pc-i440fx-4.0
 336        :avocado: tags=cpu:Cascadelake-Server
 337        """
 338        # command line must override machine-type and versioned CPU model:
 339        self.vm.add_args('-S')
 340        self.set_vm_arg('-cpu',
 341                        'Cascadelake-Server-v1,x-force-features=on,check=off,'
 342                        'enforce=off,+arch-capabilities')
 343        self.vm.launch()
 344        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
 345                        'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
 346
 347    def test_v2_unset_4_1(self):
 348        """
 349        :avocado: tags=machine:pc-i440fx-4.1
 350        :avocado: tags=cpu:Cascadelake-Server
 351        """
 352        self.vm.add_args('-S')
 353        self.set_vm_arg('-cpu',
 354                        'Cascadelake-Server-v2,x-force-features=on,check=off,'
 355                        'enforce=off,-arch-capabilities')
 356        self.vm.launch()
 357        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
 358                         'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')
 359