tests/acceptance: Fix LGPL information in the file headers
[qemu.git] / tests / acceptance / x86_cpu_model_versions.py
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.Test):
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.Test):
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')[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 """
256 # machine-type only:
257 self.vm.add_args('-S')
258 self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off')
259 self.vm.launch()
260 self.assertFalse(self.get_cpu_prop('arch-capabilities'),
261 'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
262
263 def test_4_0(self):
264 """
265 :avocado: tags=machine:pc-i440fx-4.0
266 """
267 self.vm.add_args('-S')
268 self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off')
269 self.vm.launch()
270 self.assertFalse(self.get_cpu_prop('arch-capabilities'),
271 'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
272
273 def test_set_4_0(self):
274 """
275 :avocado: tags=machine:pc-i440fx-4.0
276 """
277 # command line must override machine-type if CPU model is not versioned:
278 self.vm.add_args('-S')
279 self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off,+arch-capabilities')
280 self.vm.launch()
281 self.assertTrue(self.get_cpu_prop('arch-capabilities'),
282 'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
283
284 def test_unset_4_1(self):
285 """
286 :avocado: tags=machine:pc-i440fx-4.1
287 """
288 self.vm.add_args('-S')
289 self.vm.add_args('-cpu', 'Cascadelake-Server,x-force-features=on,check=off,enforce=off,-arch-capabilities')
290 self.vm.launch()
291 self.assertFalse(self.get_cpu_prop('arch-capabilities'),
292 'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
293
294 def test_v1_4_0(self):
295 """
296 :avocado: tags=machine:pc-i440fx-4.0
297 """
298 # versioned CPU model overrides machine-type:
299 self.vm.add_args('-S')
300 self.vm.add_args('-cpu', 'Cascadelake-Server-v1,x-force-features=on,check=off,enforce=off')
301 self.vm.launch()
302 self.assertFalse(self.get_cpu_prop('arch-capabilities'),
303 'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
304
305 def test_v2_4_0(self):
306 """
307 :avocado: tags=machine:pc-i440fx-4.0
308 """
309 self.vm.add_args('-S')
310 self.vm.add_args('-cpu', 'Cascadelake-Server-v2,x-force-features=on,check=off,enforce=off')
311 self.vm.launch()
312 self.assertTrue(self.get_cpu_prop('arch-capabilities'),
313 'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
314
315 def test_v1_set_4_0(self):
316 """
317 :avocado: tags=machine:pc-i440fx-4.0
318 """
319 # command line must override machine-type and versioned CPU model:
320 self.vm.add_args('-S')
321 self.vm.add_args('-cpu', 'Cascadelake-Server-v1,x-force-features=on,check=off,enforce=off,+arch-capabilities')
322 self.vm.launch()
323 self.assertTrue(self.get_cpu_prop('arch-capabilities'),
324 'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
325
326 def test_v2_unset_4_1(self):
327 """
328 :avocado: tags=machine:pc-i440fx-4.1
329 """
330 self.vm.add_args('-S')
331 self.vm.add_args('-cpu', 'Cascadelake-Server-v2,x-force-features=on,check=off,enforce=off,-arch-capabilities')
332 self.vm.launch()
333 self.assertFalse(self.get_cpu_prop('arch-capabilities'),
334 'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')