x86_cpu_model_versions.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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. import avocado_qemu
  23. import re
  24. class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
  25. """
  26. Validation of PC CPU model versions and CPU model aliases
  27. :avocado: tags=arch:x86_64
  28. """
  29. def validate_aliases(self, cpus):
  30. for c in cpus.values():
  31. if 'alias-of' in c:
  32. # all aliases must point to a valid CPU model name:
  33. self.assertIn(c['alias-of'], cpus,
  34. '%s.alias-of (%s) is not a valid CPU model name' % (c['name'], c['alias-of']))
  35. # aliases must not point to aliases
  36. self.assertNotIn('alias-of', cpus[c['alias-of']],
  37. '%s.alias-of (%s) points to another alias' % (c['name'], c['alias-of']))
  38. # aliases must not be static
  39. self.assertFalse(c['static'])
  40. def validate_variant_aliases(self, cpus):
  41. # -noTSX, -IBRS and -IBPB variants of CPU models are special:
  42. # they shouldn't have their own versions:
  43. self.assertNotIn("Haswell-noTSX-v1", cpus,
  44. "Haswell-noTSX shouldn't be versioned")
  45. self.assertNotIn("Broadwell-noTSX-v1", cpus,
  46. "Broadwell-noTSX shouldn't be versioned")
  47. self.assertNotIn("Nehalem-IBRS-v1", cpus,
  48. "Nehalem-IBRS shouldn't be versioned")
  49. self.assertNotIn("Westmere-IBRS-v1", cpus,
  50. "Westmere-IBRS shouldn't be versioned")
  51. self.assertNotIn("SandyBridge-IBRS-v1", cpus,
  52. "SandyBridge-IBRS shouldn't be versioned")
  53. self.assertNotIn("IvyBridge-IBRS-v1", cpus,
  54. "IvyBridge-IBRS shouldn't be versioned")
  55. self.assertNotIn("Haswell-noTSX-IBRS-v1", cpus,
  56. "Haswell-noTSX-IBRS shouldn't be versioned")
  57. self.assertNotIn("Haswell-IBRS-v1", cpus,
  58. "Haswell-IBRS shouldn't be versioned")
  59. self.assertNotIn("Broadwell-noTSX-IBRS-v1", cpus,
  60. "Broadwell-noTSX-IBRS shouldn't be versioned")
  61. self.assertNotIn("Broadwell-IBRS-v1", cpus,
  62. "Broadwell-IBRS shouldn't be versioned")
  63. self.assertNotIn("Skylake-Client-IBRS-v1", cpus,
  64. "Skylake-Client-IBRS shouldn't be versioned")
  65. self.assertNotIn("Skylake-Server-IBRS-v1", cpus,
  66. "Skylake-Server-IBRS shouldn't be versioned")
  67. self.assertNotIn("EPYC-IBPB-v1", cpus,
  68. "EPYC-IBPB shouldn't be versioned")
  69. def test_4_0_alias_compatibility(self):
  70. """
  71. Check if pc-*-4.0 unversioned CPU model won't be reported as aliases
  72. :avocado: tags=machine:pc-i440fx-4.0
  73. """
  74. # pc-*-4.0 won't expose non-versioned CPU models as aliases
  75. # We do this to help management software to keep compatibility
  76. # with older QEMU versions that didn't have the versioned CPU model
  77. self.vm.add_args('-S')
  78. self.vm.launch()
  79. cpus = dict((m['name'], m) for m in
  80. self.vm.cmd('query-cpu-definitions'))
  81. self.assertFalse(cpus['Cascadelake-Server']['static'],
  82. 'unversioned Cascadelake-Server CPU model must not be static')
  83. self.assertNotIn('alias-of', cpus['Cascadelake-Server'],
  84. 'Cascadelake-Server must not be an alias')
  85. self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
  86. 'Cascadelake-Server-v1 must not be an alias')
  87. self.assertFalse(cpus['qemu64']['static'],
  88. 'unversioned qemu64 CPU model must not be static')
  89. self.assertNotIn('alias-of', cpus['qemu64'],
  90. 'qemu64 must not be an alias')
  91. self.assertNotIn('alias-of', cpus['qemu64-v1'],
  92. 'qemu64-v1 must not be an alias')
  93. self.validate_variant_aliases(cpus)
  94. # On pc-*-4.0, no CPU model should be reported as an alias:
  95. for name,c in cpus.items():
  96. self.assertNotIn('alias-of', c, "%s shouldn't be an alias" % (name))
  97. def test_4_1_alias(self):
  98. """
  99. Check if unversioned CPU model is an alias pointing to right version
  100. :avocado: tags=machine:pc-i440fx-4.1
  101. """
  102. self.vm.add_args('-S')
  103. self.vm.launch()
  104. cpus = dict((m['name'], m) for m in
  105. self.vm.cmd('query-cpu-definitions'))
  106. self.assertFalse(cpus['Cascadelake-Server']['static'],
  107. 'unversioned Cascadelake-Server CPU model must not be static')
  108. self.assertEquals(cpus['Cascadelake-Server'].get('alias-of'), 'Cascadelake-Server-v1',
  109. 'Cascadelake-Server must be an alias of Cascadelake-Server-v1')
  110. self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
  111. 'Cascadelake-Server-v1 must not be an alias')
  112. self.assertFalse(cpus['qemu64']['static'],
  113. 'unversioned qemu64 CPU model must not be static')
  114. self.assertEquals(cpus['qemu64'].get('alias-of'), 'qemu64-v1',
  115. 'qemu64 must be an alias of qemu64-v1')
  116. self.assertNotIn('alias-of', cpus['qemu64-v1'],
  117. 'qemu64-v1 must not be an alias')
  118. self.validate_variant_aliases(cpus)
  119. # On pc-*-4.1, -noTSX and -IBRS models should be aliases:
  120. self.assertEquals(cpus["Haswell"].get('alias-of'),
  121. "Haswell-v1",
  122. "Haswell must be an alias")
  123. self.assertEquals(cpus["Haswell-noTSX"].get('alias-of'),
  124. "Haswell-v2",
  125. "Haswell-noTSX must be an alias")
  126. self.assertEquals(cpus["Haswell-IBRS"].get('alias-of'),
  127. "Haswell-v3",
  128. "Haswell-IBRS must be an alias")
  129. self.assertEquals(cpus["Haswell-noTSX-IBRS"].get('alias-of'),
  130. "Haswell-v4",
  131. "Haswell-noTSX-IBRS must be an alias")
  132. self.assertEquals(cpus["Broadwell"].get('alias-of'),
  133. "Broadwell-v1",
  134. "Broadwell must be an alias")
  135. self.assertEquals(cpus["Broadwell-noTSX"].get('alias-of'),
  136. "Broadwell-v2",
  137. "Broadwell-noTSX must be an alias")
  138. self.assertEquals(cpus["Broadwell-IBRS"].get('alias-of'),
  139. "Broadwell-v3",
  140. "Broadwell-IBRS must be an alias")
  141. self.assertEquals(cpus["Broadwell-noTSX-IBRS"].get('alias-of'),
  142. "Broadwell-v4",
  143. "Broadwell-noTSX-IBRS must be an alias")
  144. self.assertEquals(cpus["Nehalem"].get('alias-of'),
  145. "Nehalem-v1",
  146. "Nehalem must be an alias")
  147. self.assertEquals(cpus["Nehalem-IBRS"].get('alias-of'),
  148. "Nehalem-v2",
  149. "Nehalem-IBRS must be an alias")
  150. self.assertEquals(cpus["Westmere"].get('alias-of'),
  151. "Westmere-v1",
  152. "Westmere must be an alias")
  153. self.assertEquals(cpus["Westmere-IBRS"].get('alias-of'),
  154. "Westmere-v2",
  155. "Westmere-IBRS must be an alias")
  156. self.assertEquals(cpus["SandyBridge"].get('alias-of'),
  157. "SandyBridge-v1",
  158. "SandyBridge must be an alias")
  159. self.assertEquals(cpus["SandyBridge-IBRS"].get('alias-of'),
  160. "SandyBridge-v2",
  161. "SandyBridge-IBRS must be an alias")
  162. self.assertEquals(cpus["IvyBridge"].get('alias-of'),
  163. "IvyBridge-v1",
  164. "IvyBridge must be an alias")
  165. self.assertEquals(cpus["IvyBridge-IBRS"].get('alias-of'),
  166. "IvyBridge-v2",
  167. "IvyBridge-IBRS must be an alias")
  168. self.assertEquals(cpus["Skylake-Client"].get('alias-of'),
  169. "Skylake-Client-v1",
  170. "Skylake-Client must be an alias")
  171. self.assertEquals(cpus["Skylake-Client-IBRS"].get('alias-of'),
  172. "Skylake-Client-v2",
  173. "Skylake-Client-IBRS must be an alias")
  174. self.assertEquals(cpus["Skylake-Server"].get('alias-of'),
  175. "Skylake-Server-v1",
  176. "Skylake-Server must be an alias")
  177. self.assertEquals(cpus["Skylake-Server-IBRS"].get('alias-of'),
  178. "Skylake-Server-v2",
  179. "Skylake-Server-IBRS must be an alias")
  180. self.assertEquals(cpus["EPYC"].get('alias-of'),
  181. "EPYC-v1",
  182. "EPYC must be an alias")
  183. self.assertEquals(cpus["EPYC-IBPB"].get('alias-of'),
  184. "EPYC-v2",
  185. "EPYC-IBPB must be an alias")
  186. self.validate_aliases(cpus)
  187. def test_none_alias(self):
  188. """
  189. Check if unversioned CPU model is an alias pointing to some version
  190. :avocado: tags=machine:none
  191. """
  192. self.vm.add_args('-S')
  193. self.vm.launch()
  194. cpus = dict((m['name'], m) for m in
  195. self.vm.cmd('query-cpu-definitions'))
  196. self.assertFalse(cpus['Cascadelake-Server']['static'],
  197. 'unversioned Cascadelake-Server CPU model must not be static')
  198. self.assertTrue(re.match('Cascadelake-Server-v[0-9]+', cpus['Cascadelake-Server']['alias-of']),
  199. 'Cascadelake-Server must be an alias of versioned CPU model')
  200. self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
  201. 'Cascadelake-Server-v1 must not be an alias')
  202. self.assertFalse(cpus['qemu64']['static'],
  203. 'unversioned qemu64 CPU model must not be static')
  204. self.assertTrue(re.match('qemu64-v[0-9]+', cpus['qemu64']['alias-of']),
  205. 'qemu64 must be an alias of versioned CPU model')
  206. self.assertNotIn('alias-of', cpus['qemu64-v1'],
  207. 'qemu64-v1 must not be an alias')
  208. self.validate_aliases(cpus)
  209. class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
  210. """
  211. Validation of Cascadelake arch-capabilities
  212. :avocado: tags=arch:x86_64
  213. """
  214. def get_cpu_prop(self, prop):
  215. cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path')
  216. return self.vm.cmd('qom-get', path=cpu_path, property=prop)
  217. def test_4_1(self):
  218. """
  219. :avocado: tags=machine:pc-i440fx-4.1
  220. :avocado: tags=cpu:Cascadelake-Server
  221. """
  222. # machine-type only:
  223. self.vm.add_args('-S')
  224. self.set_vm_arg('-cpu',
  225. 'Cascadelake-Server,x-force-features=on,check=off,'
  226. 'enforce=off')
  227. self.vm.launch()
  228. self.assertFalse(self.get_cpu_prop('arch-capabilities'),
  229. 'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
  230. def test_4_0(self):
  231. """
  232. :avocado: tags=machine:pc-i440fx-4.0
  233. :avocado: tags=cpu:Cascadelake-Server
  234. """
  235. self.vm.add_args('-S')
  236. self.set_vm_arg('-cpu',
  237. 'Cascadelake-Server,x-force-features=on,check=off,'
  238. 'enforce=off')
  239. self.vm.launch()
  240. self.assertFalse(self.get_cpu_prop('arch-capabilities'),
  241. 'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
  242. def test_set_4_0(self):
  243. """
  244. :avocado: tags=machine:pc-i440fx-4.0
  245. :avocado: tags=cpu:Cascadelake-Server
  246. """
  247. # command line must override machine-type if CPU model is not versioned:
  248. self.vm.add_args('-S')
  249. self.set_vm_arg('-cpu',
  250. 'Cascadelake-Server,x-force-features=on,check=off,'
  251. 'enforce=off,+arch-capabilities')
  252. self.vm.launch()
  253. self.assertTrue(self.get_cpu_prop('arch-capabilities'),
  254. 'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
  255. def test_unset_4_1(self):
  256. """
  257. :avocado: tags=machine:pc-i440fx-4.1
  258. :avocado: tags=cpu:Cascadelake-Server
  259. """
  260. self.vm.add_args('-S')
  261. self.set_vm_arg('-cpu',
  262. 'Cascadelake-Server,x-force-features=on,check=off,'
  263. 'enforce=off,-arch-capabilities')
  264. self.vm.launch()
  265. self.assertFalse(self.get_cpu_prop('arch-capabilities'),
  266. 'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
  267. def test_v1_4_0(self):
  268. """
  269. :avocado: tags=machine:pc-i440fx-4.0
  270. :avocado: tags=cpu:Cascadelake-Server
  271. """
  272. # versioned CPU model overrides machine-type:
  273. self.vm.add_args('-S')
  274. self.set_vm_arg('-cpu',
  275. 'Cascadelake-Server-v1,x-force-features=on,check=off,'
  276. 'enforce=off')
  277. self.vm.launch()
  278. self.assertFalse(self.get_cpu_prop('arch-capabilities'),
  279. 'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
  280. def test_v2_4_0(self):
  281. """
  282. :avocado: tags=machine:pc-i440fx-4.0
  283. :avocado: tags=cpu:Cascadelake-Server
  284. """
  285. self.vm.add_args('-S')
  286. self.set_vm_arg('-cpu',
  287. 'Cascadelake-Server-v2,x-force-features=on,check=off,'
  288. 'enforce=off')
  289. self.vm.launch()
  290. self.assertTrue(self.get_cpu_prop('arch-capabilities'),
  291. 'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
  292. def test_v1_set_4_0(self):
  293. """
  294. :avocado: tags=machine:pc-i440fx-4.0
  295. :avocado: tags=cpu:Cascadelake-Server
  296. """
  297. # command line must override machine-type and versioned CPU model:
  298. self.vm.add_args('-S')
  299. self.set_vm_arg('-cpu',
  300. 'Cascadelake-Server-v1,x-force-features=on,check=off,'
  301. 'enforce=off,+arch-capabilities')
  302. self.vm.launch()
  303. self.assertTrue(self.get_cpu_prop('arch-capabilities'),
  304. 'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
  305. def test_v2_unset_4_1(self):
  306. """
  307. :avocado: tags=machine:pc-i440fx-4.1
  308. :avocado: tags=cpu:Cascadelake-Server
  309. """
  310. self.vm.add_args('-S')
  311. self.set_vm_arg('-cpu',
  312. 'Cascadelake-Server-v2,x-force-features=on,check=off,'
  313. 'enforce=off,-arch-capabilities')
  314. self.vm.launch()
  315. self.assertFalse(self.get_cpu_prop('arch-capabilities'),
  316. 'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')