master
py 249 lines 11 KB
Raw
1 #!/usr/bin/env python3
2 #
3 # Basic validation of x86 versioned CPU models and CPU model aliases
4 #
5 # Copyright (c) 2019 Red Hat Inc
6 #
7 # Author:
8 # Eduardo Habkost <ehabkost@redhat.com>
9 #
10 # This library is free software; you can redistribute it and/or
11 # modify it under the terms of the GNU Lesser General Public
12 # License as published by the Free Software Foundation; either
13 # version 2.1 of the License, or (at your option) any later version.
14 #
15 # This library is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 # Lesser General Public License for more details.
19 #
20 # You should have received a copy of the GNU Lesser General Public
21 # License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 #
23
24 import re
25
26 from qemu_test import QemuSystemTest
27
28 class X86CPUModelAliases(QemuSystemTest):
29 """
30 Validation of PC CPU model versions and CPU model aliases
31 """
32 def validate_aliases(self, cpus):
33 for c in cpus.values():
34 if 'alias-of' in c:
35 # all aliases must point to a valid CPU model name:
36 self.assertIn(c['alias-of'], cpus,
37 '%s.alias-of (%s) is not a valid CPU model name' % (c['name'], c['alias-of']))
38 # aliases must not point to aliases
39 self.assertNotIn('alias-of', cpus[c['alias-of']],
40 '%s.alias-of (%s) points to another alias' % (c['name'], c['alias-of']))
41
42 # aliases must not be static
43 self.assertFalse(c['static'])
44
45 def validate_variant_aliases(self, cpus):
46 # -noTSX, -IBRS and -IBPB variants of CPU models are special:
47 # they shouldn't have their own versions:
48 self.assertNotIn("Haswell-noTSX-v1", cpus,
49 "Haswell-noTSX shouldn't be versioned")
50 self.assertNotIn("Broadwell-noTSX-v1", cpus,
51 "Broadwell-noTSX shouldn't be versioned")
52 self.assertNotIn("Nehalem-IBRS-v1", cpus,
53 "Nehalem-IBRS shouldn't be versioned")
54 self.assertNotIn("Westmere-IBRS-v1", cpus,
55 "Westmere-IBRS shouldn't be versioned")
56 self.assertNotIn("SandyBridge-IBRS-v1", cpus,
57 "SandyBridge-IBRS shouldn't be versioned")
58 self.assertNotIn("IvyBridge-IBRS-v1", cpus,
59 "IvyBridge-IBRS shouldn't be versioned")
60 self.assertNotIn("Haswell-noTSX-IBRS-v1", cpus,
61 "Haswell-noTSX-IBRS shouldn't be versioned")
62 self.assertNotIn("Haswell-IBRS-v1", cpus,
63 "Haswell-IBRS shouldn't be versioned")
64 self.assertNotIn("Broadwell-noTSX-IBRS-v1", cpus,
65 "Broadwell-noTSX-IBRS shouldn't be versioned")
66 self.assertNotIn("Broadwell-IBRS-v1", cpus,
67 "Broadwell-IBRS shouldn't be versioned")
68 self.assertNotIn("Skylake-Client-IBRS-v1", cpus,
69 "Skylake-Client-IBRS shouldn't be versioned")
70 self.assertNotIn("Skylake-Server-IBRS-v1", cpus,
71 "Skylake-Server-IBRS shouldn't be versioned")
72 self.assertNotIn("EPYC-IBPB-v1", cpus,
73 "EPYC-IBPB shouldn't be versioned")
74
75 def test_unversioned_alias(self):
76 """
77 Check if unversioned CPU model is an alias pointing to right version
78 """
79 self.set_machine('pc')
80 self.vm.add_args('-S')
81 self.vm.launch()
82
83 cpus = dict((m['name'], m) for m in
84 self.vm.cmd('query-cpu-definitions'))
85
86 self.assertFalse(cpus['Cascadelake-Server']['static'],
87 'unversioned Cascadelake-Server CPU model must not be static')
88 self.assertEqual(cpus['Cascadelake-Server'].get('alias-of'),
89 'Cascadelake-Server-v1',
90 'Cascadelake-Server must be an alias of Cascadelake-Server-v1')
91 self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
92 'Cascadelake-Server-v1 must not be an alias')
93
94 self.assertFalse(cpus['qemu64']['static'],
95 'unversioned qemu64 CPU model must not be static')
96 self.assertEqual(cpus['qemu64'].get('alias-of'), 'qemu64-v1',
97 'qemu64 must be an alias of qemu64-v1')
98 self.assertNotIn('alias-of', cpus['qemu64-v1'],
99 'qemu64-v1 must not be an alias')
100
101 self.validate_variant_aliases(cpus)
102
103 # On recent PC machines, -noTSX and -IBRS models should be aliases:
104 self.assertEqual(cpus["Haswell"].get('alias-of'),
105 "Haswell-v1",
106 "Haswell must be an alias")
107 self.assertEqual(cpus["Haswell-noTSX"].get('alias-of'),
108 "Haswell-v2",
109 "Haswell-noTSX must be an alias")
110 self.assertEqual(cpus["Haswell-IBRS"].get('alias-of'),
111 "Haswell-v3",
112 "Haswell-IBRS must be an alias")
113 self.assertEqual(cpus["Haswell-noTSX-IBRS"].get('alias-of'),
114 "Haswell-v4",
115 "Haswell-noTSX-IBRS must be an alias")
116
117 self.assertEqual(cpus["Broadwell"].get('alias-of'),
118 "Broadwell-v1",
119 "Broadwell must be an alias")
120 self.assertEqual(cpus["Broadwell-noTSX"].get('alias-of'),
121 "Broadwell-v2",
122 "Broadwell-noTSX must be an alias")
123 self.assertEqual(cpus["Broadwell-IBRS"].get('alias-of'),
124 "Broadwell-v3",
125 "Broadwell-IBRS must be an alias")
126 self.assertEqual(cpus["Broadwell-noTSX-IBRS"].get('alias-of'),
127 "Broadwell-v4",
128 "Broadwell-noTSX-IBRS must be an alias")
129
130 self.assertEqual(cpus["Nehalem"].get('alias-of'),
131 "Nehalem-v1",
132 "Nehalem must be an alias")
133 self.assertEqual(cpus["Nehalem-IBRS"].get('alias-of'),
134 "Nehalem-v2",
135 "Nehalem-IBRS must be an alias")
136
137 self.assertEqual(cpus["Westmere"].get('alias-of'),
138 "Westmere-v1",
139 "Westmere must be an alias")
140 self.assertEqual(cpus["Westmere-IBRS"].get('alias-of'),
141 "Westmere-v2",
142 "Westmere-IBRS must be an alias")
143
144 self.assertEqual(cpus["SandyBridge"].get('alias-of'),
145 "SandyBridge-v1",
146 "SandyBridge must be an alias")
147 self.assertEqual(cpus["SandyBridge-IBRS"].get('alias-of'),
148 "SandyBridge-v2",
149 "SandyBridge-IBRS must be an alias")
150
151 self.assertEqual(cpus["IvyBridge"].get('alias-of'),
152 "IvyBridge-v1",
153 "IvyBridge must be an alias")
154 self.assertEqual(cpus["IvyBridge-IBRS"].get('alias-of'),
155 "IvyBridge-v2",
156 "IvyBridge-IBRS must be an alias")
157
158 self.assertEqual(cpus["Skylake-Client"].get('alias-of'),
159 "Skylake-Client-v1",
160 "Skylake-Client must be an alias")
161 self.assertEqual(cpus["Skylake-Client-IBRS"].get('alias-of'),
162 "Skylake-Client-v2",
163 "Skylake-Client-IBRS must be an alias")
164
165 self.assertEqual(cpus["Skylake-Server"].get('alias-of'),
166 "Skylake-Server-v1",
167 "Skylake-Server must be an alias")
168 self.assertEqual(cpus["Skylake-Server-IBRS"].get('alias-of'),
169 "Skylake-Server-v2",
170 "Skylake-Server-IBRS must be an alias")
171
172 self.assertEqual(cpus["EPYC"].get('alias-of'),
173 "EPYC-v1",
174 "EPYC must be an alias")
175 self.assertEqual(cpus["EPYC-IBPB"].get('alias-of'),
176 "EPYC-v2",
177 "EPYC-IBPB must be an alias")
178
179 self.validate_aliases(cpus)
180
181 def test_none_alias(self):
182 """
183 Check if unversioned CPU model is an alias pointing to some version
184 """
185 self.set_machine('none')
186 self.vm.add_args('-S')
187 self.vm.launch()
188
189 cpus = dict((m['name'], m) for m in
190 self.vm.cmd('query-cpu-definitions'))
191
192 self.assertFalse(cpus['Cascadelake-Server']['static'],
193 'unversioned Cascadelake-Server CPU model must not be static')
194 self.assertTrue(re.match('Cascadelake-Server-v[0-9]+', cpus['Cascadelake-Server']['alias-of']),
195 'Cascadelake-Server must be an alias of versioned CPU model')
196 self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
197 'Cascadelake-Server-v1 must not be an alias')
198
199 self.assertFalse(cpus['qemu64']['static'],
200 'unversioned qemu64 CPU model must not be static')
201 self.assertTrue(re.match('qemu64-v[0-9]+', cpus['qemu64']['alias-of']),
202 'qemu64 must be an alias of versioned CPU model')
203 self.assertNotIn('alias-of', cpus['qemu64-v1'],
204 'qemu64-v1 must not be an alias')
205
206 self.validate_aliases(cpus)
207
208
209 class CascadelakeArchCapabilities(QemuSystemTest):
210 """
211 Validation of Cascadelake arch-capabilities
212 """
213 def get_cpu_prop(self, prop):
214 cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path')
215 return self.vm.cmd('qom-get', path=cpu_path, property=prop)
216
217 def test(self):
218 self.set_machine('pc')
219 # machine-type only:
220 self.vm.add_args('-S')
221 self.set_vm_arg('-cpu',
222 'Cascadelake-Server,x-force-features=on,check=off,'
223 'enforce=off')
224 self.vm.launch()
225 self.assertFalse(self.get_cpu_prop('arch-capabilities'),
226 'pc + Cascadelake-Server should not have arch-capabilities')
227
228 def test_unset(self):
229 self.set_machine('pc')
230 self.vm.add_args('-S')
231 self.set_vm_arg('-cpu',
232 'Cascadelake-Server,x-force-features=on,check=off,'
233 'enforce=off,-arch-capabilities')
234 self.vm.launch()
235 self.assertFalse(self.get_cpu_prop('arch-capabilities'),
236 'pc + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
237
238 def test_v2_unset(self):
239 self.set_machine('pc')
240 self.vm.add_args('-S')
241 self.set_vm_arg('-cpu',
242 'Cascadelake-Server-v2,x-force-features=on,check=off,'
243 'enforce=off,-arch-capabilities')
244 self.vm.launch()
245 self.assertFalse(self.get_cpu_prop('arch-capabilities'),
246 'pc + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')
247
248 if __name__ == '__main__':
249 QemuSystemTest.main()