qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

x86_cpu_model_versions.py (15950B)


      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 
     24 import avocado_qemu
     25 import re
     26 
     27 class 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 
    242 class 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')