2 # Basic validation of x86 versioned CPU models and CPU model aliases
4 # Copyright (c) 2019 Red Hat Inc
7 # Eduardo Habkost <ehabkost@redhat.com>
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.
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.
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/>.
27 class X86CPUModelAliases(avocado_qemu
.QemuSystemTest
):
29 Validation of PC CPU model versions and CPU model aliases
31 :avocado: tags=arch:x86_64
33 def validate_aliases(self
, cpus
):
34 for c
in cpus
.values():
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']))
43 # aliases must not be static
44 self
.assertFalse(c
['static'])
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")
76 def test_4_0_alias_compatibility(self
):
78 Check if pc-*-4.0 unversioned CPU model won't be reported as aliases
80 :avocado: tags=machine:pc-i440fx-4.0
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')
87 cpus
= dict((m
['name'], m
) for m
in
88 self
.vm
.cmd('query-cpu-definitions'))
90 self
.assertFalse(cpus
['Cascadelake-Server']['static'],
91 'unversioned Cascadelake-Server CPU model must not be static')
92 self
.assertNotIn('alias-of', cpus
['Cascadelake-Server'],
93 'Cascadelake-Server must not be an alias')
94 self
.assertNotIn('alias-of', cpus
['Cascadelake-Server-v1'],
95 'Cascadelake-Server-v1 must not be an alias')
97 self
.assertFalse(cpus
['qemu64']['static'],
98 'unversioned qemu64 CPU model must not be static')
99 self
.assertNotIn('alias-of', cpus
['qemu64'],
100 'qemu64 must not be an alias')
101 self
.assertNotIn('alias-of', cpus
['qemu64-v1'],
102 'qemu64-v1 must not be an alias')
104 self
.validate_variant_aliases(cpus
)
106 # On pc-*-4.0, no CPU model should be reported as an alias:
107 for name
,c
in cpus
.items():
108 self
.assertNotIn('alias-of', c
, "%s shouldn't be an alias" % (name
))
110 def test_4_1_alias(self
):
112 Check if unversioned CPU model is an alias pointing to right version
114 :avocado: tags=machine:pc-i440fx-4.1
116 self
.vm
.add_args('-S')
119 cpus
= dict((m
['name'], m
) for m
in
120 self
.vm
.cmd('query-cpu-definitions'))
122 self
.assertFalse(cpus
['Cascadelake-Server']['static'],
123 'unversioned Cascadelake-Server CPU model must not be static')
124 self
.assertEqual(cpus
['Cascadelake-Server'].get('alias-of'),
125 'Cascadelake-Server-v1',
126 'Cascadelake-Server must be an alias of Cascadelake-Server-v1')
127 self
.assertNotIn('alias-of', cpus
['Cascadelake-Server-v1'],
128 'Cascadelake-Server-v1 must not be an alias')
130 self
.assertFalse(cpus
['qemu64']['static'],
131 'unversioned qemu64 CPU model must not be static')
132 self
.assertEqual(cpus
['qemu64'].get('alias-of'), 'qemu64-v1',
133 'qemu64 must be an alias of qemu64-v1')
134 self
.assertNotIn('alias-of', cpus
['qemu64-v1'],
135 'qemu64-v1 must not be an alias')
137 self
.validate_variant_aliases(cpus
)
139 # On pc-*-4.1, -noTSX and -IBRS models should be aliases:
140 self
.assertEqual(cpus
["Haswell"].get('alias-of'),
142 "Haswell must be an alias")
143 self
.assertEqual(cpus
["Haswell-noTSX"].get('alias-of'),
145 "Haswell-noTSX must be an alias")
146 self
.assertEqual(cpus
["Haswell-IBRS"].get('alias-of'),
148 "Haswell-IBRS must be an alias")
149 self
.assertEqual(cpus
["Haswell-noTSX-IBRS"].get('alias-of'),
151 "Haswell-noTSX-IBRS must be an alias")
153 self
.assertEqual(cpus
["Broadwell"].get('alias-of'),
155 "Broadwell must be an alias")
156 self
.assertEqual(cpus
["Broadwell-noTSX"].get('alias-of'),
158 "Broadwell-noTSX must be an alias")
159 self
.assertEqual(cpus
["Broadwell-IBRS"].get('alias-of'),
161 "Broadwell-IBRS must be an alias")
162 self
.assertEqual(cpus
["Broadwell-noTSX-IBRS"].get('alias-of'),
164 "Broadwell-noTSX-IBRS must be an alias")
166 self
.assertEqual(cpus
["Nehalem"].get('alias-of'),
168 "Nehalem must be an alias")
169 self
.assertEqual(cpus
["Nehalem-IBRS"].get('alias-of'),
171 "Nehalem-IBRS must be an alias")
173 self
.assertEqual(cpus
["Westmere"].get('alias-of'),
175 "Westmere must be an alias")
176 self
.assertEqual(cpus
["Westmere-IBRS"].get('alias-of'),
178 "Westmere-IBRS must be an alias")
180 self
.assertEqual(cpus
["SandyBridge"].get('alias-of'),
182 "SandyBridge must be an alias")
183 self
.assertEqual(cpus
["SandyBridge-IBRS"].get('alias-of'),
185 "SandyBridge-IBRS must be an alias")
187 self
.assertEqual(cpus
["IvyBridge"].get('alias-of'),
189 "IvyBridge must be an alias")
190 self
.assertEqual(cpus
["IvyBridge-IBRS"].get('alias-of'),
192 "IvyBridge-IBRS must be an alias")
194 self
.assertEqual(cpus
["Skylake-Client"].get('alias-of'),
196 "Skylake-Client must be an alias")
197 self
.assertEqual(cpus
["Skylake-Client-IBRS"].get('alias-of'),
199 "Skylake-Client-IBRS must be an alias")
201 self
.assertEqual(cpus
["Skylake-Server"].get('alias-of'),
203 "Skylake-Server must be an alias")
204 self
.assertEqual(cpus
["Skylake-Server-IBRS"].get('alias-of'),
206 "Skylake-Server-IBRS must be an alias")
208 self
.assertEqual(cpus
["EPYC"].get('alias-of'),
210 "EPYC must be an alias")
211 self
.assertEqual(cpus
["EPYC-IBPB"].get('alias-of'),
213 "EPYC-IBPB must be an alias")
215 self
.validate_aliases(cpus
)
217 def test_none_alias(self
):
219 Check if unversioned CPU model is an alias pointing to some version
221 :avocado: tags=machine:none
223 self
.vm
.add_args('-S')
226 cpus
= dict((m
['name'], m
) for m
in
227 self
.vm
.cmd('query-cpu-definitions'))
229 self
.assertFalse(cpus
['Cascadelake-Server']['static'],
230 'unversioned Cascadelake-Server CPU model must not be static')
231 self
.assertTrue(re
.match('Cascadelake-Server-v[0-9]+', cpus
['Cascadelake-Server']['alias-of']),
232 'Cascadelake-Server must be an alias of versioned CPU model')
233 self
.assertNotIn('alias-of', cpus
['Cascadelake-Server-v1'],
234 'Cascadelake-Server-v1 must not be an alias')
236 self
.assertFalse(cpus
['qemu64']['static'],
237 'unversioned qemu64 CPU model must not be static')
238 self
.assertTrue(re
.match('qemu64-v[0-9]+', cpus
['qemu64']['alias-of']),
239 'qemu64 must be an alias of versioned CPU model')
240 self
.assertNotIn('alias-of', cpus
['qemu64-v1'],
241 'qemu64-v1 must not be an alias')
243 self
.validate_aliases(cpus
)
246 class CascadelakeArchCapabilities(avocado_qemu
.QemuSystemTest
):
248 Validation of Cascadelake arch-capabilities
250 :avocado: tags=arch:x86_64
252 def get_cpu_prop(self
, prop
):
253 cpu_path
= self
.vm
.cmd('query-cpus-fast')[0].get('qom-path')
254 return self
.vm
.cmd('qom-get', path
=cpu_path
, property=prop
)
258 :avocado: tags=machine:pc-i440fx-4.1
259 :avocado: tags=cpu:Cascadelake-Server
262 self
.vm
.add_args('-S')
263 self
.set_vm_arg('-cpu',
264 'Cascadelake-Server,x-force-features=on,check=off,'
267 self
.assertFalse(self
.get_cpu_prop('arch-capabilities'),
268 'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
272 :avocado: tags=machine:pc-i440fx-4.0
273 :avocado: tags=cpu:Cascadelake-Server
275 self
.vm
.add_args('-S')
276 self
.set_vm_arg('-cpu',
277 'Cascadelake-Server,x-force-features=on,check=off,'
280 self
.assertFalse(self
.get_cpu_prop('arch-capabilities'),
281 'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
283 def test_set_4_0(self
):
285 :avocado: tags=machine:pc-i440fx-4.0
286 :avocado: tags=cpu:Cascadelake-Server
288 # command line must override machine-type if CPU model is not versioned:
289 self
.vm
.add_args('-S')
290 self
.set_vm_arg('-cpu',
291 'Cascadelake-Server,x-force-features=on,check=off,'
292 'enforce=off,+arch-capabilities')
294 self
.assertTrue(self
.get_cpu_prop('arch-capabilities'),
295 'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
297 def test_unset_4_1(self
):
299 :avocado: tags=machine:pc-i440fx-4.1
300 :avocado: tags=cpu:Cascadelake-Server
302 self
.vm
.add_args('-S')
303 self
.set_vm_arg('-cpu',
304 'Cascadelake-Server,x-force-features=on,check=off,'
305 'enforce=off,-arch-capabilities')
307 self
.assertFalse(self
.get_cpu_prop('arch-capabilities'),
308 'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
310 def test_v1_4_0(self
):
312 :avocado: tags=machine:pc-i440fx-4.0
313 :avocado: tags=cpu:Cascadelake-Server
315 # versioned CPU model overrides machine-type:
316 self
.vm
.add_args('-S')
317 self
.set_vm_arg('-cpu',
318 'Cascadelake-Server-v1,x-force-features=on,check=off,'
321 self
.assertFalse(self
.get_cpu_prop('arch-capabilities'),
322 'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
324 def test_v2_4_0(self
):
326 :avocado: tags=machine:pc-i440fx-4.0
327 :avocado: tags=cpu:Cascadelake-Server
329 self
.vm
.add_args('-S')
330 self
.set_vm_arg('-cpu',
331 'Cascadelake-Server-v2,x-force-features=on,check=off,'
334 self
.assertTrue(self
.get_cpu_prop('arch-capabilities'),
335 'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
337 def test_v1_set_4_0(self
):
339 :avocado: tags=machine:pc-i440fx-4.0
340 :avocado: tags=cpu:Cascadelake-Server
342 # command line must override machine-type and versioned CPU model:
343 self
.vm
.add_args('-S')
344 self
.set_vm_arg('-cpu',
345 'Cascadelake-Server-v1,x-force-features=on,check=off,'
346 'enforce=off,+arch-capabilities')
348 self
.assertTrue(self
.get_cpu_prop('arch-capabilities'),
349 'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
351 def test_v2_unset_4_1(self
):
353 :avocado: tags=machine:pc-i440fx-4.1
354 :avocado: tags=cpu:Cascadelake-Server
356 self
.vm
.add_args('-S')
357 self
.set_vm_arg('-cpu',
358 'Cascadelake-Server-v2,x-force-features=on,check=off,'
359 'enforce=off,-arch-capabilities')
361 self
.assertFalse(self
.get_cpu_prop('arch-capabilities'),
362 'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')