1 /*
2 * cputest.c: Test the libvirtd internal CPU APIs
3 *
4 * Copyright (C) 2010-2014 Red Hat, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
21 #include <config.h>
22
23 #include <unistd.h>
24
25 #include <sys/types.h>
26 #include <fcntl.h>
27
28 #include "internal.h"
29 #include "virxml.h"
30 #include "viralloc.h"
31 #include "virbuffer.h"
32 #include "testutils.h"
33 #include "cpu_conf.h"
34 #include "cpu/cpu.h"
35 #include "cpu/cpu_x86.h"
36 #include "cpu/cpu_map.h"
37 #include "virstring.h"
38
39 #if WITH_QEMU
40 # include "testutilsqemu.h"
41 # include "qemumonitortestutils.h"
42 # define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
43 # include "qemu/qemu_capspriv.h"
44 #endif
45
46 #define VIR_FROM_THIS VIR_FROM_CPU
47
48 enum cpuTestBoolWithError {
49 FAIL = -1,
50 NO = 0,
51 YES = 1
52 };
53
54
55 struct data {
56 virArch arch;
57 const char *host;
58 const char *name;
59 virDomainCapsCPUModels *models;
60 const char *modelsName;
61 unsigned int flags;
62 int result;
63 };
64
65 #if WITH_QEMU
66 static virQEMUDriver driver;
67 #endif
68
69
70 static virCPUDef *
cpuTestLoadXML(virArch arch,const char * name)71 cpuTestLoadXML(virArch arch, const char *name)
72 {
73 g_autofree char *xml = NULL;
74 g_autoptr(xmlDoc) doc = NULL;
75 g_autoptr(xmlXPathContext) ctxt = NULL;
76 virCPUDef *cpu = NULL;
77
78 xml = g_strdup_printf("%s/cputestdata/%s-%s.xml", abs_srcdir,
79 virArchToString(arch), name);
80
81 if (!(doc = virXMLParseFileCtxt(xml, &ctxt)))
82 return NULL;
83
84 virCPUDefParseXML(ctxt, NULL, VIR_CPU_TYPE_AUTO, &cpu, false);
85
86 return cpu;
87 }
88
89
90 static virCPUDef **
cpuTestLoadMultiXML(virArch arch,const char * name,unsigned int * count)91 cpuTestLoadMultiXML(virArch arch,
92 const char *name,
93 unsigned int *count)
94 {
95 g_autofree char *xml = NULL;
96 g_autoptr(xmlDoc) doc = NULL;
97 g_autoptr(xmlXPathContext) ctxt = NULL;
98 g_autofree xmlNodePtr *nodes = NULL;
99 virCPUDef **cpus = NULL;
100 int n;
101 size_t i;
102
103 xml = g_strdup_printf("%s/cputestdata/%s-%s.xml", abs_srcdir,
104 virArchToString(arch), name);
105
106 if (!(doc = virXMLParseFileCtxt(xml, &ctxt)))
107 return NULL;
108
109 n = virXPathNodeSet("/cpuTest/cpu", ctxt, &nodes);
110 if (n <= 0) {
111 fprintf(stderr, "\nNo /cpuTest/cpu elements found in %s\n", xml);
112 return NULL;
113 }
114
115 cpus = g_new0(virCPUDef *, n);
116
117 for (i = 0; i < n; i++) {
118 ctxt->node = nodes[i];
119 if (virCPUDefParseXML(ctxt, NULL, VIR_CPU_TYPE_HOST, &cpus[i],
120 false) < 0)
121 goto error;
122 }
123
124 *count = n;
125
126 return cpus;
127
128 error:
129 for (i = 0; i < n; i++)
130 virCPUDefFree(cpus[i]);
131 VIR_FREE(cpus);
132 return NULL;
133 }
134
135
136 static int
cpuTestCompareXML(virArch arch,virCPUDef * cpu,const char * name)137 cpuTestCompareXML(virArch arch,
138 virCPUDef *cpu,
139 const char *name)
140 {
141 g_autofree char *xml = NULL;
142 g_autofree char *actual = NULL;
143
144 xml = g_strdup_printf("%s/cputestdata/%s-%s.xml", abs_srcdir,
145 virArchToString(arch), name);
146
147 if (!(actual = virCPUDefFormat(cpu, NULL)))
148 return -1;
149
150 if (virTestCompareToFile(actual, xml) < 0)
151 return -1;
152
153 return 0;
154 }
155
156
157 static const char *
cpuTestCompResStr(virCPUCompareResult result)158 cpuTestCompResStr(virCPUCompareResult result)
159 {
160 switch (result) {
161 case VIR_CPU_COMPARE_ERROR: return "ERROR";
162 case VIR_CPU_COMPARE_INCOMPATIBLE: return "INCOMPATIBLE";
163 case VIR_CPU_COMPARE_IDENTICAL: return "IDENTICAL";
164 case VIR_CPU_COMPARE_SUPERSET: return "SUPERSET";
165 case VIR_CPU_COMPARE_LAST: break;
166 }
167
168 return "unknown";
169 }
170
171
172 static const char *
cpuTestBoolWithErrorStr(enum cpuTestBoolWithError result)173 cpuTestBoolWithErrorStr(enum cpuTestBoolWithError result)
174 {
175 switch (result) {
176 case FAIL: return "FAIL";
177 case NO: return "NO";
178 case YES: return "YES";
179 }
180
181 return "unknown";
182 }
183
184
185 static int
cpuTestCompare(const void * arg)186 cpuTestCompare(const void *arg)
187 {
188 const struct data *data = arg;
189 g_autoptr(virCPUDef) host = NULL;
190 g_autoptr(virCPUDef) cpu = NULL;
191 virCPUCompareResult result;
192
193 if (!(host = cpuTestLoadXML(data->arch, data->host)) ||
194 !(cpu = cpuTestLoadXML(data->arch, data->name)))
195 return -1;
196
197 result = virCPUCompare(host->arch, host, cpu, false);
198 if (data->result == VIR_CPU_COMPARE_ERROR)
199 virResetLastError();
200
201 if (data->result != result) {
202 VIR_TEST_VERBOSE("\nExpected result %s, got %s",
203 cpuTestCompResStr(data->result),
204 cpuTestCompResStr(result));
205 /* Pad to line up with test name ... in virTestRun */
206 VIR_TEST_VERBOSE("%74s", "... ");
207 return -1;
208 }
209
210 return 0;
211 }
212
213
214 static int
cpuTestGuestCPU(const void * arg)215 cpuTestGuestCPU(const void *arg)
216 {
217 const struct data *data = arg;
218 int ret = -2;
219 g_autoptr(virCPUDef) host = NULL;
220 g_autoptr(virCPUDef) cpu = NULL;
221 virCPUCompareResult cmpResult;
222 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
223 g_autofree char *result = NULL;
224
225 if (!(host = cpuTestLoadXML(data->arch, data->host)) ||
226 !(cpu = cpuTestLoadXML(data->arch, data->name)))
227 goto cleanup;
228
229 if (virCPUConvertLegacy(host->arch, cpu) < 0)
230 goto cleanup;
231
232 cmpResult = virCPUCompare(host->arch, host, cpu, false);
233 if (cmpResult == VIR_CPU_COMPARE_ERROR ||
234 cmpResult == VIR_CPU_COMPARE_INCOMPATIBLE) {
235 ret = -1;
236 goto cleanup;
237 }
238
239 if (virCPUUpdate(host->arch, cpu, host) < 0 ||
240 virCPUTranslate(host->arch, cpu, data->models) < 0) {
241 ret = -1;
242 goto cleanup;
243 }
244
245 virBufferAsprintf(&buf, "%s+%s", data->host, data->name);
246 if (data->modelsName)
247 virBufferAsprintf(&buf, ",%s", data->modelsName);
248 virBufferAddLit(&buf, "-result");
249
250 result = virBufferContentAndReset(&buf);
251
252 if (cpuTestCompareXML(data->arch, cpu, result) < 0)
253 goto cleanup;
254
255 ret = 0;
256
257 cleanup:
258 if (ret == data->result) {
259 /* We got the result we expected, whether it was
260 * a success or a failure */
261 virResetLastError();
262 ret = 0;
263 } else {
264 VIR_TEST_VERBOSE("\nExpected result %d, got %d",
265 data->result, ret);
266 /* Pad to line up with test name ... in virTestRun */
267 VIR_TEST_VERBOSE("%74s", "... ");
268 ret = -1;
269 }
270
271 return ret;
272 }
273
274
275 static int
cpuTestBaseline(const void * arg)276 cpuTestBaseline(const void *arg)
277 {
278 const struct data *data = arg;
279 int ret = -1;
280 virCPUDef **cpus = NULL;
281 virCPUDef *baseline = NULL;
282 unsigned int ncpus = 0;
283 g_autofree char *result = NULL;
284 const char *suffix;
285 size_t i;
286
287 if (!(cpus = cpuTestLoadMultiXML(data->arch, data->name, &ncpus)))
288 goto cleanup;
289
290 baseline = virCPUBaseline(data->arch, cpus, ncpus, NULL, NULL,
291 !!(data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE));
292
293 if (baseline &&
294 (data->flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
295 virCPUExpandFeatures(data->arch, baseline) < 0) {
296 virCPUDefFree(baseline);
297 baseline = NULL;
298 }
299
300 if (data->result < 0) {
301 virResetLastError();
302 if (!baseline) {
303 ret = 0;
304 } else {
305 VIR_TEST_VERBOSE("\n%-70s... ",
306 "virCPUBaseline was expected to fail but it succeeded");
307 }
308 goto cleanup;
309 }
310 if (!baseline)
311 goto cleanup;
312
313 if (data->flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
314 suffix = "expanded";
315 else if (data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE)
316 suffix = "migratable";
317 else
318 suffix = "result";
319 result = g_strdup_printf("%s-%s", data->name, suffix);
320
321 if (cpuTestCompareXML(data->arch, baseline, result) < 0)
322 goto cleanup;
323
324 for (i = 0; i < ncpus; i++) {
325 virCPUCompareResult cmp;
326
327 cmp = virCPUCompare(cpus[i]->arch, cpus[i], baseline, false);
328 if (cmp != VIR_CPU_COMPARE_SUPERSET &&
329 cmp != VIR_CPU_COMPARE_IDENTICAL) {
330 VIR_TEST_VERBOSE("\nbaseline CPU is incompatible with CPU %zu",
331 i);
332 VIR_TEST_VERBOSE("%74s", "... ");
333 ret = -1;
334 goto cleanup;
335 }
336 }
337
338 ret = 0;
339
340 cleanup:
341 if (cpus) {
342 for (i = 0; i < ncpus; i++)
343 virCPUDefFree(cpus[i]);
344 VIR_FREE(cpus);
345 }
346 virCPUDefFree(baseline);
347 return ret;
348 }
349
350
351 static int
cpuTestUpdate(const void * arg)352 cpuTestUpdate(const void *arg)
353 {
354 const struct data *data = arg;
355 g_autoptr(virCPUDef) host = NULL;
356 g_autoptr(virCPUDef) migHost = NULL;
357 g_autoptr(virCPUDef) cpu = NULL;
358 g_autofree char *result = NULL;
359
360 if (!(host = cpuTestLoadXML(data->arch, data->host)) ||
361 !(cpu = cpuTestLoadXML(data->arch, data->name)))
362 return -1;
363
364 if (!(migHost = virCPUCopyMigratable(data->arch, host)))
365 return -1;
366
367 if (virCPUUpdate(host->arch, cpu, migHost) < 0)
368 return -1;
369
370 result = g_strdup_printf("%s+%s", data->host, data->name);
371
372 return cpuTestCompareXML(data->arch, cpu, result);
373 }
374
375
376 static int
cpuTestHasFeature(const void * arg)377 cpuTestHasFeature(const void *arg)
378 {
379 const struct data *data = arg;
380 g_autoptr(virCPUDef) host = NULL;
381 g_autoptr(virCPUData) hostData = NULL;
382 int result;
383
384 if (!(host = cpuTestLoadXML(data->arch, data->host)))
385 return -1;
386
387 if (cpuEncode(host->arch, host, NULL, &hostData,
388 NULL, NULL, NULL, NULL) < 0)
389 return -1;
390
391 result = virCPUCheckFeature(host->arch, host, data->name);
392
393 if (data->result == result)
394 result = virCPUDataCheckFeature(hostData, data->name);
395
396 if (data->result == -1)
397 virResetLastError();
398
399 if (data->result != result) {
400 VIR_TEST_VERBOSE("\nExpected result %s, got %s",
401 cpuTestBoolWithErrorStr(data->result),
402 cpuTestBoolWithErrorStr(result));
403 /* Pad to line up with test name ... in virTestRun */
404 VIR_TEST_VERBOSE("%74s", "... ");
405 return -1;
406 }
407
408 return 0;
409 }
410
411
412 typedef enum {
413 /* No JSON data from QEMU. */
414 JSON_NONE,
415 /* Only a reply from query-cpu-model-expansion QMP command. */
416 JSON_HOST,
417 /* Replies from both query-cpu-model-expansion and query-cpu-definitions
418 * QMP commands.
419 */
420 JSON_MODELS,
421 /* Same as JSON_MODELS, but the reply from query-cpu-definitions has to
422 * be parsed for providing the correct result. This happens when the
423 * CPU model detected by libvirt has non-empty unavailable-features array
424 * in query-cpu-definitions reply or when the CPU model detected from CPUID
425 * differs from the one we get from QEMU and we need to translate them for
426 * comparison. Such tests require QEMU driver to be enabled.
427 */
428 JSON_MODELS_REQUIRED,
429 } cpuTestCPUIDJson;
430
431 #if WITH_QEMU
432 static virQEMUCaps *
cpuTestMakeQEMUCaps(const struct data * data)433 cpuTestMakeQEMUCaps(const struct data *data)
434 {
435 g_autoptr(virQEMUCaps) qemuCaps = NULL;
436 g_autoptr(qemuMonitorTest) testMon = NULL;
437 g_autoptr(qemuMonitorCPUModelInfo) model = NULL;
438 g_autoptr(virCPUDef) cpu = NULL;
439 bool fail_no_props = true;
440 g_autofree char *json = NULL;
441
442 json = g_strdup_printf("%s/cputestdata/%s-cpuid-%s.json", abs_srcdir,
443 virArchToString(data->arch), data->host);
444
445 if (!(testMon = qemuMonitorTestNewFromFile(json, driver.xmlopt, true)))
446 return NULL;
447
448 qemuMonitorTestAllowUnusedCommands(testMon);
449
450 cpu = virCPUDefNew();
451
452 cpu->model = g_strdup("host");
453
454 if (ARCH_IS_S390(data->arch))
455 fail_no_props = false;
456
457 if (qemuMonitorGetCPUModelExpansion(qemuMonitorTestGetMonitor(testMon),
458 QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC,
459 cpu, true, fail_no_props, &model) < 0)
460 return NULL;
461
462 if (!(qemuCaps = virQEMUCapsNew()))
463 return NULL;
464
465 virQEMUCapsSet(qemuCaps, QEMU_CAPS_KVM);
466 if (data->flags == JSON_MODELS ||
467 data->flags == JSON_MODELS_REQUIRED)
468 virQEMUCapsSet(qemuCaps, QEMU_CAPS_QUERY_CPU_DEFINITIONS);
469
470 virQEMUCapsSetArch(qemuCaps, data->arch);
471 virQEMUCapsSetCPUModelInfo(qemuCaps, VIR_DOMAIN_VIRT_KVM, model);
472 model = NULL;
473
474 if (virQEMUCapsProbeCPUDefinitionsTest(qemuCaps,
475 qemuMonitorTestGetMonitor(testMon)) < 0)
476 return NULL;
477
478 return g_steal_pointer(&qemuCaps);
479 }
480
481
482 static int
cpuTestGetCPUModels(const struct data * data,virDomainCapsCPUModels ** models)483 cpuTestGetCPUModels(const struct data *data,
484 virDomainCapsCPUModels **models)
485 {
486 g_autoptr(virQEMUCaps) qemuCaps = NULL;
487
488 *models = NULL;
489
490 if (data->flags != JSON_MODELS &&
491 data->flags != JSON_MODELS_REQUIRED)
492 return 0;
493
494 if (!(qemuCaps = cpuTestMakeQEMUCaps(data)))
495 return -1;
496
497 *models = virQEMUCapsGetCPUModels(qemuCaps, VIR_DOMAIN_VIRT_KVM, NULL, NULL);
498
499 return 0;
500 }
501
502 #else /* if WITH_QEMU */
503
504 static int
cpuTestGetCPUModels(const struct data * data,virDomainCapsCPUModels ** models)505 cpuTestGetCPUModels(const struct data *data,
506 virDomainCapsCPUModels **models)
507 {
508 *models = NULL;
509
510 if (data->flags == JSON_MODELS_REQUIRED)
511 return EXIT_AM_SKIP;
512
513 return 0;
514 }
515
516 #endif
517
518
519 static int
cpuTestCPUID(bool guest,const void * arg)520 cpuTestCPUID(bool guest, const void *arg)
521 {
522 const struct data *data = arg;
523 g_autoptr(virCPUData) hostData = NULL;
524 g_autofree char *hostFile = NULL;
525 g_autofree char *host = NULL;
526 g_autoptr(virCPUDef) cpu = NULL;
527 g_autofree char *result = NULL;
528 g_autoptr(virDomainCapsCPUModels) models = NULL;
529
530 hostFile = g_strdup_printf("%s/cputestdata/%s-cpuid-%s.xml", abs_srcdir,
531 virArchToString(data->arch), data->host);
532
533 if (virTestLoadFile(hostFile, &host) < 0 ||
534 !(hostData = virCPUDataParse(host)))
535 return -1;
536
537 cpu = virCPUDefNew();
538 cpu->arch = hostData->arch;
539 if (guest) {
540 cpu->type = VIR_CPU_TYPE_GUEST;
541 cpu->match = VIR_CPU_MATCH_EXACT;
542 cpu->fallback = VIR_CPU_FALLBACK_FORBID;
543 } else {
544 cpu->type = VIR_CPU_TYPE_HOST;
545 }
546
547 if (guest) {
548 int rc;
549
550 rc = cpuTestGetCPUModels(data, &models);
551 if (rc != 0)
552 return rc;
553 }
554
555 if (cpuDecode(cpu, hostData, models) < 0)
556 return -1;
557
558 result = g_strdup_printf("cpuid-%s-%s", data->host, guest ? "guest" : "host");
559
560 return cpuTestCompareXML(data->arch, cpu, result);
561 }
562
563
564 static int
cpuTestHostCPUID(const void * arg)565 cpuTestHostCPUID(const void *arg)
566 {
567 return cpuTestCPUID(false, arg);
568 }
569
570
571 static int
cpuTestGuestCPUID(const void * arg)572 cpuTestGuestCPUID(const void *arg)
573 {
574 return cpuTestCPUID(true, arg);
575 }
576
577
578 static int
cpuTestCompareSignature(const struct data * data,virCPUData * hostData)579 cpuTestCompareSignature(const struct data *data,
580 virCPUData *hostData)
581 {
582 g_autofree char *result = NULL;
583 g_autofree char *sigStr = NULL;
584 unsigned long signature;
585 unsigned int family;
586 unsigned int model;
587 unsigned int stepping;
588
589 signature = virCPUx86DataGetSignature(hostData, &family, &model, &stepping);
590
591 result = g_strdup_printf("%s/cputestdata/%s-cpuid-%s.sig", abs_srcdir,
592 virArchToString(data->arch), data->host);
593
594 sigStr = g_strdup_printf("%1$06lx\n" "family: %2$3u (0x%2$02x)\n"
595 "model: %3$3u (0x%3$02x)\n" "stepping: %4$3u (0x%4$02x)\n",
596 signature, family, model, stepping);
597
598 return virTestCompareToFile(sigStr, result);
599 }
600
601
602 static int
cpuTestCPUIDSignature(const void * arg)603 cpuTestCPUIDSignature(const void *arg)
604 {
605 const struct data *data = arg;
606 g_autoptr(virCPUData) hostData = NULL;
607 g_autofree char *hostFile = NULL;
608 g_autofree char *host = NULL;
609
610 hostFile = g_strdup_printf("%s/cputestdata/%s-cpuid-%s.xml", abs_srcdir,
611 virArchToString(data->arch), data->host);
612
613 if (virTestLoadFile(hostFile, &host) < 0 ||
614 !(hostData = virCPUDataParse(host)))
615 return -1;
616
617 return cpuTestCompareSignature(data, hostData);
618 }
619
620
621 static int
cpuTestUpdateLiveCompare(virArch arch,virCPUDef * actual,virCPUDef * expected)622 cpuTestUpdateLiveCompare(virArch arch,
623 virCPUDef *actual,
624 virCPUDef *expected)
625 {
626 size_t i, j;
627 int ret = 0;
628
629 if (virCPUExpandFeatures(arch, actual) < 0 ||
630 virCPUExpandFeatures(arch, expected) < 0)
631 return -1;
632
633 if (STRNEQ(actual->model, expected->model)) {
634 VIR_TEST_VERBOSE("Actual CPU model '%s', expected '%s'",
635 actual->model, expected->model);
636 return -1;
637 }
638
639 i = j = 0;
640 while (i < actual->nfeatures || j < expected->nfeatures) {
641 virCPUFeatureDef *featAct = NULL;
642 virCPUFeatureDef *featExp = NULL;
643 int cmp;
644
645 if (i < actual->nfeatures)
646 featAct = actual->features + i;
647
648 if (j < expected->nfeatures)
649 featExp = expected->features + j;
650
651 /*
652 * Act < Exp => cmp < 0 (missing entry in Exp)
653 * Act = Exp => cmp = 0
654 * Act > Exp => cmp > 0 (missing entry in Act)
655 *
656 * NULL > name for any name != NULL
657 */
658 if (featAct && featExp)
659 cmp = strcmp(featAct->name, featExp->name);
660 else
661 cmp = featExp ? 1 : -1;
662
663 if (cmp <= 0)
664 i++;
665 if (cmp >= 0)
666 j++;
667
668 /* Possible combinations of cmp, featAct->policy, and featExp->policy:
669 * cmp Act Exp result
670 * ---------------------------------
671 * 0 dis dis ok
672 * 0 dis req missing
673 * 0 req dis extra
674 * 0 req req ok
675 * ---------------------------------
676 * - dis X ok # ignoring extra disabled features
677 * - req X extra
678 * ---------------------------------
679 * + X dis extra
680 * + X req missing
681 */
682 if ((cmp == 0 &&
683 featAct->policy == VIR_CPU_FEATURE_DISABLE &&
684 featExp->policy == VIR_CPU_FEATURE_REQUIRE) ||
685 (cmp > 0 &&
686 featExp->policy == VIR_CPU_FEATURE_REQUIRE)) {
687 VIR_TEST_VERBOSE("Actual CPU lacks feature '%s'",
688 featExp->name);
689 ret = -1;
690 continue;
691 }
692
693 if ((cmp == 0 &&
694 featAct->policy == VIR_CPU_FEATURE_REQUIRE &&
695 featExp->policy == VIR_CPU_FEATURE_DISABLE) ||
696 (cmp < 0 &&
697 featAct->policy == VIR_CPU_FEATURE_REQUIRE) ||
698 (cmp > 0 &&
699 featExp->policy == VIR_CPU_FEATURE_DISABLE)) {
700 VIR_TEST_VERBOSE("Actual CPU has extra feature '%s'",
701 cmp <= 0 ? featAct->name : featExp->name);
702 ret = -1;
703 }
704 }
705
706 return ret;
707 }
708
709
710 static int
cpuTestUpdateLive(const void * arg)711 cpuTestUpdateLive(const void *arg)
712 {
713 const struct data *data = arg;
714 g_autofree char *cpuFile = NULL;
715 g_autoptr(virCPUDef) cpu = NULL;
716 g_autofree char *enabledFile = NULL;
717 g_autofree char *enabled = NULL;
718 g_autoptr(virCPUData) enabledData = NULL;
719 g_autofree char *disabledFile = NULL;
720 g_autofree char *disabled = NULL;
721 g_autoptr(virCPUData) disabledData = NULL;
722 g_autofree char *expectedFile = NULL;
723 g_autoptr(virCPUDef) expected = NULL;
724 g_autoptr(virDomainCapsCPUModels) hvModels = NULL;
725 g_autoptr(virDomainCapsCPUModels) models = NULL;
726
727 cpuFile = g_strdup_printf("cpuid-%s-guest", data->host);
728 if (!(cpu = cpuTestLoadXML(data->arch, cpuFile)))
729 return -1;
730
731 enabledFile = g_strdup_printf("%s/cputestdata/%s-cpuid-%s-enabled.xml",
732 abs_srcdir, virArchToString(data->arch), data->host);
733 if (virTestLoadFile(enabledFile, &enabled) < 0 ||
734 !(enabledData = virCPUDataParse(enabled)))
735 return -1;
736
737 disabledFile = g_strdup_printf("%s/cputestdata/%s-cpuid-%s-disabled.xml",
738 abs_srcdir, virArchToString(data->arch), data->host);
739 if (virTestLoadFile(disabledFile, &disabled) < 0 ||
740 !(disabledData = virCPUDataParse(disabled)))
741 return -1;
742
743 expectedFile = g_strdup_printf("cpuid-%s-json", data->host);
744 if (!(expected = cpuTestLoadXML(data->arch, expectedFile)))
745 return -1;
746
747 /* In case the host CPU signature does not exactly match any CPU model in
748 * src/cpu_map, the CPU model we detect from CPUID may differ from the one
749 * we compute by asking QEMU. Since this test expands both CPU models and
750 * compares their features, we can try to translate the 'actual' CPU to
751 * use the CPU model from 'expected'.
752 */
753 if (STRNEQ(cpu->model, expected->model)) {
754 virDomainCapsCPUModel *hvModel;
755 char **blockers = NULL;
756 virDomainCapsCPUUsable usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;
757 int rc;
758
759 if (!(models = virDomainCapsCPUModelsNew(0)))
760 return -1;
761
762 rc = cpuTestGetCPUModels(data, &hvModels);
763 if (rc != 0)
764 return rc;
765
766 hvModel = virDomainCapsCPUModelsGet(hvModels, expected->model);
767
768 if (hvModel) {
769 blockers = hvModel->blockers;
770 usable = hvModel->usable;
771 }
772
773 if (virDomainCapsCPUModelsAdd(models, expected->model,
774 usable, blockers, false) < 0)
775 return -1;
776
777 cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
778 ignore_value(virCPUTranslate(data->arch, cpu, models));
779 cpu->fallback = VIR_CPU_FALLBACK_FORBID;
780 }
781
782 if (virCPUUpdateLive(data->arch, cpu, enabledData, disabledData) < 0)
783 return -1;
784
785 return cpuTestUpdateLiveCompare(data->arch, cpu, expected);
786 }
787
788
789 #if WITH_QEMU
790 static int
cpuTestJSONCPUID(const void * arg)791 cpuTestJSONCPUID(const void *arg)
792 {
793 const struct data *data = arg;
794 g_autoptr(virQEMUCaps) qemuCaps = NULL;
795 g_autoptr(virCPUDef) cpu = NULL;
796 g_autofree char *result = NULL;
797
798 result = g_strdup_printf("cpuid-%s-json", data->host);
799
800 if (!(qemuCaps = cpuTestMakeQEMUCaps(data)))
801 return -1;
802
803 cpu = virCPUDefNew();
804 cpu->arch = data->arch;
805 cpu->type = VIR_CPU_TYPE_GUEST;
806 cpu->match = VIR_CPU_MATCH_EXACT;
807 cpu->fallback = VIR_CPU_FALLBACK_FORBID;
808
809 if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu, false) != 0)
810 return -1;
811
812 return cpuTestCompareXML(data->arch, cpu, result);
813 }
814
815
816 static int
cpuTestJSONSignature(const void * arg)817 cpuTestJSONSignature(const void *arg)
818 {
819 const struct data *data = arg;
820 g_autoptr(virQEMUCaps) qemuCaps = NULL;
821 g_autoptr(virCPUData) hostData = NULL;
822 qemuMonitorCPUModelInfo *modelInfo;
823
824 if (!(qemuCaps = cpuTestMakeQEMUCaps(data)))
825 return -1;
826
827 modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, VIR_DOMAIN_VIRT_KVM);
828 if (!(hostData = virQEMUCapsGetCPUModelX86Data(qemuCaps, modelInfo, false)))
829 return -1;
830
831 return cpuTestCompareSignature(data, hostData);
832 }
833 #endif
834
835
836 static const char *model486_list[] = { "486", NULL };
837 static const char *nomodel_list[] = { "nomodel", NULL };
838 static const char *models_list[] = { "qemu64", "core2duo", "Nehalem", NULL };
839 static const char *haswell_list[] = { "SandyBridge", "Haswell", NULL };
840 static const char *ppc_models_list[] = { "POWER6", "POWER7", "POWER8", NULL };
841
842 static virDomainCapsCPUModels *
cpuTestInitModels(const char ** list)843 cpuTestInitModels(const char **list)
844 {
845 virDomainCapsCPUModels *cpus;
846 const char **model;
847
848 if (!(cpus = virDomainCapsCPUModelsNew(0)))
849 return NULL;
850
851 for (model = list; *model; model++) {
852 if (virDomainCapsCPUModelsAdd(cpus, *model,
853 VIR_DOMCAPS_CPU_USABLE_UNKNOWN, NULL, false) < 0)
854 goto error;
855 }
856
857 return cpus;
858
859 error:
860 virObjectUnref(cpus);
861 return NULL;
862 }
863
864
865 static int
mymain(void)866 mymain(void)
867 {
868 virDomainCapsCPUModels *model486 = NULL;
869 virDomainCapsCPUModels *nomodel = NULL;
870 virDomainCapsCPUModels *models = NULL;
871 virDomainCapsCPUModels *haswell = NULL;
872 virDomainCapsCPUModels *ppc_models = NULL;
873 int ret = 0;
874
875 #if WITH_QEMU
876 if (qemuTestDriverInit(&driver) < 0)
877 return EXIT_FAILURE;
878
879 virEventRegisterDefaultImpl();
880 #endif
881
882 if (!(model486 = cpuTestInitModels(model486_list)) ||
883 !(nomodel = cpuTestInitModels(nomodel_list)) ||
884 !(models = cpuTestInitModels(models_list)) ||
885 !(haswell = cpuTestInitModels(haswell_list)) ||
886 !(ppc_models = cpuTestInitModels(ppc_models_list))) {
887 ret = -1;
888 goto cleanup;
889 }
890
891 #define DO_TEST(arch, api, name, host, cpu, \
892 models, flags, result) \
893 do { \
894 struct data data = { \
895 arch, host, cpu, models, \
896 models == NULL ? NULL : #models, \
897 flags, result \
898 }; \
899 g_autofree char *testLabel = NULL; \
900 \
901 testLabel = g_strdup_printf("%s(%s): %s", #api, \
902 virArchToString(arch), name); \
903 \
904 virTestRunLog(&ret, testLabel, api, &data); \
905 } while (0)
906
907 #define DO_TEST_COMPARE(arch, host, cpu, result) \
908 DO_TEST(arch, cpuTestCompare, \
909 host "/" cpu " (" #result ")", \
910 host, cpu, NULL, 0, result)
911
912 #define DO_TEST_UPDATE_ONLY(arch, host, cpu) \
913 DO_TEST(arch, cpuTestUpdate, \
914 cpu " on " host, \
915 host, cpu, NULL, 0, 0)
916
917 #define DO_TEST_UPDATE(arch, host, cpu, result) \
918 do { \
919 DO_TEST_UPDATE_ONLY(arch, host, cpu); \
920 DO_TEST_COMPARE(arch, host, host "+" cpu, result); \
921 } while (0)
922
923 #define DO_TEST_BASELINE(arch, name, flags, result) \
924 do { \
925 const char *suffix = ""; \
926 g_autofree char *label = NULL; \
927 if ((flags) & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) \
928 suffix = " (expanded)"; \
929 if ((flags) & VIR_CONNECT_BASELINE_CPU_MIGRATABLE) \
930 suffix = " (migratable)"; \
931 label = g_strdup_printf("%s%s", name, suffix); \
932 DO_TEST(arch, cpuTestBaseline, label, NULL, \
933 "baseline-" name, NULL, flags, result); \
934 } while (0)
935
936 #define DO_TEST_HASFEATURE(arch, host, feature, result) \
937 DO_TEST(arch, cpuTestHasFeature, \
938 host "/" feature " (" #result ")", \
939 host, feature, NULL, 0, result)
940
941 #define DO_TEST_GUESTCPU(arch, host, cpu, models, result) \
942 DO_TEST(arch, cpuTestGuestCPU, \
943 host "/" cpu " (" #models ")", \
944 host, cpu, models, 0, result)
945
946 #if WITH_QEMU
947 # define DO_TEST_JSON(arch, host, json) \
948 do { \
949 if (json == JSON_MODELS) { \
950 DO_TEST(arch, cpuTestGuestCPUID, host, host, \
951 NULL, NULL, 0, 0); \
952 } \
953 if (json != JSON_NONE) { \
954 DO_TEST(arch, cpuTestJSONCPUID, host, host, \
955 NULL, NULL, json, 0); \
956 DO_TEST(arch, cpuTestJSONSignature, host, host, \
957 NULL, NULL, 0, 0); \
958 } \
959 } while (0)
960 #else
961 # define DO_TEST_JSON(arch, host, json)
962 #endif
963
964 #define DO_TEST_CPUID(arch, host, json) \
965 do { \
966 DO_TEST(arch, cpuTestHostCPUID, host, host, \
967 NULL, NULL, 0, 0); \
968 DO_TEST(arch, cpuTestGuestCPUID, host, host, \
969 NULL, NULL, json, 0); \
970 DO_TEST(arch, cpuTestCPUIDSignature, host, host, \
971 NULL, NULL, 0, 0); \
972 DO_TEST_JSON(arch, host, json); \
973 if (json != JSON_NONE) { \
974 DO_TEST(arch, cpuTestUpdateLive, host, host, \
975 NULL, NULL, json, 0); \
976 } \
977 } while (0)
978
979 /* host to host comparison */
980 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host", VIR_CPU_COMPARE_IDENTICAL);
981 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-better", VIR_CPU_COMPARE_INCOMPATIBLE);
982 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-worse", VIR_CPU_COMPARE_SUPERSET);
983 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-amd-fake", VIR_CPU_COMPARE_INCOMPATIBLE);
984 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-incomp-arch", VIR_CPU_COMPARE_INCOMPATIBLE);
985 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "host-no-vendor", VIR_CPU_COMPARE_IDENTICAL);
986 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host-no-vendor", "host", VIR_CPU_COMPARE_INCOMPATIBLE);
987
988 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "host", VIR_CPU_COMPARE_IDENTICAL);
989 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "host-better", VIR_CPU_COMPARE_INCOMPATIBLE);
990 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "host-worse", VIR_CPU_COMPARE_INCOMPATIBLE);
991 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "host-incomp-arch", VIR_CPU_COMPARE_INCOMPATIBLE);
992 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "host-no-vendor", VIR_CPU_COMPARE_IDENTICAL);
993 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host-no-vendor", "host", VIR_CPU_COMPARE_INCOMPATIBLE);
994
995 /* guest to host comparison */
996 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "bogus-model", VIR_CPU_COMPARE_ERROR);
997 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "bogus-feature", VIR_CPU_COMPARE_ERROR);
998 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "min", VIR_CPU_COMPARE_SUPERSET);
999 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "pentium3", VIR_CPU_COMPARE_SUPERSET);
1000 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact", VIR_CPU_COMPARE_SUPERSET);
1001 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact-forbid", VIR_CPU_COMPARE_INCOMPATIBLE);
1002 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact-forbid-extra", VIR_CPU_COMPARE_SUPERSET);
1003 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact-disable", VIR_CPU_COMPARE_SUPERSET);
1004 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact-disable2", VIR_CPU_COMPARE_SUPERSET);
1005 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact-disable-extra", VIR_CPU_COMPARE_SUPERSET);
1006 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact-require", VIR_CPU_COMPARE_SUPERSET);
1007 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact-require-extra", VIR_CPU_COMPARE_INCOMPATIBLE);
1008 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "exact-force", VIR_CPU_COMPARE_SUPERSET);
1009 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "strict", VIR_CPU_COMPARE_INCOMPATIBLE);
1010 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "strict-full", VIR_CPU_COMPARE_IDENTICAL);
1011 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "strict-disable", VIR_CPU_COMPARE_IDENTICAL);
1012 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "strict-force-extra", VIR_CPU_COMPARE_IDENTICAL);
1013 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "guest", VIR_CPU_COMPARE_SUPERSET);
1014 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host", "pentium3-amd", VIR_CPU_COMPARE_INCOMPATIBLE);
1015 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host-amd", "pentium3-amd", VIR_CPU_COMPARE_SUPERSET);
1016 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host-worse", "penryn-force", VIR_CPU_COMPARE_IDENTICAL);
1017 DO_TEST_COMPARE(VIR_ARCH_X86_64, "host-SandyBridge", "exact-force-Haswell", VIR_CPU_COMPARE_IDENTICAL);
1018
1019 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-strict", VIR_CPU_COMPARE_IDENTICAL);
1020 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-exact", VIR_CPU_COMPARE_INCOMPATIBLE);
1021 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-legacy", VIR_CPU_COMPARE_IDENTICAL);
1022 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-legacy-incompatible", VIR_CPU_COMPARE_INCOMPATIBLE);
1023 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-legacy-bad", VIR_CPU_COMPARE_ERROR);
1024 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-compat-none", VIR_CPU_COMPARE_IDENTICAL);
1025 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-compat-valid", VIR_CPU_COMPARE_IDENTICAL);
1026 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-compat-bad", VIR_CPU_COMPARE_ERROR);
1027 DO_TEST_COMPARE(VIR_ARCH_PPC64, "host", "guest-compat-incompatible", VIR_CPU_COMPARE_INCOMPATIBLE);
1028
1029 /* guest updates for migration
1030 * automatically compares host CPU with the result */
1031 DO_TEST_UPDATE(VIR_ARCH_X86_64, "host", "min", VIR_CPU_COMPARE_IDENTICAL);
1032 DO_TEST_UPDATE(VIR_ARCH_X86_64, "host", "pentium3", VIR_CPU_COMPARE_IDENTICAL);
1033 DO_TEST_UPDATE(VIR_ARCH_X86_64, "host", "guest", VIR_CPU_COMPARE_SUPERSET);
1034 DO_TEST_UPDATE(VIR_ARCH_X86_64, "host", "host-model", VIR_CPU_COMPARE_IDENTICAL);
1035 DO_TEST_UPDATE(VIR_ARCH_X86_64, "host", "host-model-nofallback", VIR_CPU_COMPARE_IDENTICAL);
1036 DO_TEST_UPDATE(VIR_ARCH_X86_64, "host-invtsc", "host-model", VIR_CPU_COMPARE_SUPERSET);
1037 DO_TEST_UPDATE_ONLY(VIR_ARCH_X86_64, "host", "host-passthrough");
1038 DO_TEST_UPDATE_ONLY(VIR_ARCH_X86_64, "host", "host-passthrough-features");
1039
1040 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest", VIR_CPU_COMPARE_IDENTICAL);
1041 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest-nofallback", VIR_CPU_COMPARE_INCOMPATIBLE);
1042 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest-legacy", VIR_CPU_COMPARE_IDENTICAL);
1043 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest-legacy-incompatible", VIR_CPU_COMPARE_INCOMPATIBLE);
1044 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest-legacy-bad", VIR_CPU_COMPARE_ERROR);
1045 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest-compat-none", VIR_CPU_COMPARE_IDENTICAL);
1046 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest-compat-valid", VIR_CPU_COMPARE_IDENTICAL);
1047 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest-compat-bad", VIR_CPU_COMPARE_ERROR);
1048 DO_TEST_UPDATE(VIR_ARCH_PPC64, "host", "guest-compat-incompatible", VIR_CPU_COMPARE_INCOMPATIBLE);
1049
1050 /* computing baseline CPUs */
1051 DO_TEST_BASELINE(VIR_ARCH_X86_64, "incompatible-vendors", 0, -1);
1052 DO_TEST_BASELINE(VIR_ARCH_X86_64, "no-vendor", 0, 0);
1053 DO_TEST_BASELINE(VIR_ARCH_X86_64, "some-vendors", 0, 0);
1054 DO_TEST_BASELINE(VIR_ARCH_X86_64, "1", 0, 0);
1055 DO_TEST_BASELINE(VIR_ARCH_X86_64, "2", 0, 0);
1056 DO_TEST_BASELINE(VIR_ARCH_X86_64, "3", 0, 0);
1057 DO_TEST_BASELINE(VIR_ARCH_X86_64, "3", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0);
1058 DO_TEST_BASELINE(VIR_ARCH_X86_64, "4", 0, 0);
1059 DO_TEST_BASELINE(VIR_ARCH_X86_64, "4", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0);
1060 DO_TEST_BASELINE(VIR_ARCH_X86_64, "5", 0, 0);
1061 DO_TEST_BASELINE(VIR_ARCH_X86_64, "5", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0);
1062 DO_TEST_BASELINE(VIR_ARCH_X86_64, "6", 0, 0);
1063 DO_TEST_BASELINE(VIR_ARCH_X86_64, "6", VIR_CONNECT_BASELINE_CPU_MIGRATABLE, 0);
1064 DO_TEST_BASELINE(VIR_ARCH_X86_64, "7", 0, 0);
1065 DO_TEST_BASELINE(VIR_ARCH_X86_64, "8", 0, 0);
1066
1067 DO_TEST_BASELINE(VIR_ARCH_PPC64, "incompatible-vendors", 0, -1);
1068 DO_TEST_BASELINE(VIR_ARCH_PPC64, "no-vendor", 0, 0);
1069 DO_TEST_BASELINE(VIR_ARCH_PPC64, "incompatible-models", 0, -1);
1070 DO_TEST_BASELINE(VIR_ARCH_PPC64, "same-model", 0, 0);
1071 DO_TEST_BASELINE(VIR_ARCH_PPC64, "legacy", 0, -1);
1072
1073 /* CPU features */
1074 DO_TEST_HASFEATURE(VIR_ARCH_X86_64, "host", "vmx", YES);
1075 DO_TEST_HASFEATURE(VIR_ARCH_X86_64, "host", "lm", YES);
1076 DO_TEST_HASFEATURE(VIR_ARCH_X86_64, "host", "sse4.1", YES);
1077 DO_TEST_HASFEATURE(VIR_ARCH_X86_64, "host", "3dnowext", NO);
1078 DO_TEST_HASFEATURE(VIR_ARCH_X86_64, "host", "skinit", NO);
1079 DO_TEST_HASFEATURE(VIR_ARCH_X86_64, "host", "foo", FAIL);
1080
1081 /* computing guest data and decoding the data into a guest CPU XML */
1082 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "guest", NULL, 0);
1083 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host-better", "pentium3", NULL, 0);
1084 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host-worse", "guest", NULL, 0);
1085 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "strict-force-extra", NULL, 0);
1086 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "penryn-force", NULL, 0);
1087 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "guest", model486, 0);
1088 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "guest", models, 0);
1089 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "guest", nomodel, -1);
1090 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "guest-nofallback", models, -1);
1091 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "host+host-model", models, 0);
1092 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host", "host+host-model-nofallback", models, -1);
1093 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host-Haswell-noTSX", "Haswell", haswell, 0);
1094 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host-Haswell-noTSX", "Haswell-noTSX", haswell, 0);
1095 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host-Haswell-noTSX", "Haswell-noTSX-nofallback", haswell, -1);
1096 DO_TEST_GUESTCPU(VIR_ARCH_X86_64, "host-Haswell-noTSX", "Haswell-noTSX", NULL, 0);
1097
1098 DO_TEST_GUESTCPU(VIR_ARCH_PPC64, "host", "guest", ppc_models, 0);
1099 DO_TEST_GUESTCPU(VIR_ARCH_PPC64, "host", "guest-nofallback", ppc_models, -1);
1100 DO_TEST_GUESTCPU(VIR_ARCH_PPC64, "host", "guest-legacy", ppc_models, 0);
1101 DO_TEST_GUESTCPU(VIR_ARCH_PPC64, "host", "guest-legacy-incompatible", ppc_models, -1);
1102 DO_TEST_GUESTCPU(VIR_ARCH_PPC64, "host", "guest-legacy-bad", ppc_models, -1);
1103
1104 DO_TEST_CPUID(VIR_ARCH_X86_64, "A10-5800K", JSON_HOST);
1105 DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-D510", JSON_NONE);
1106 DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-N450", JSON_NONE);
1107 DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-P5362", JSON_MODELS_REQUIRED);
1108 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-650", JSON_MODELS_REQUIRED);
1109 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-2500", JSON_HOST);
1110 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-2540M", JSON_MODELS);
1111 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-4670T", JSON_HOST);
1112 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-6600", JSON_HOST);
1113 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-2600", JSON_HOST);
1114 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-2600-xsaveopt", JSON_MODELS_REQUIRED);
1115 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-3520M", JSON_NONE);
1116 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-3740QM", JSON_HOST);
1117 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-3770", JSON_HOST);
1118 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-4600U", JSON_HOST);
1119 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-4510U", JSON_HOST);
1120 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U", JSON_HOST);
1121 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U-arat", JSON_HOST);
1122 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U-ibrs", JSON_HOST);
1123 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-7600U", JSON_MODELS);
1124 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-7700", JSON_MODELS);
1125 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-8550U", JSON_MODELS);
1126 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-8700", JSON_MODELS);
1127 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core2-E6850", JSON_HOST);
1128 DO_TEST_CPUID(VIR_ARCH_X86_64, "Core2-Q9500", JSON_NONE);
1129 DO_TEST_CPUID(VIR_ARCH_X86_64, "Hygon-C86-7185-32-core", JSON_HOST);
1130 DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7601-32-Core", JSON_HOST);
1131 DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7601-32-Core-ibpb", JSON_MODELS_REQUIRED);
1132 DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7502-32-Core", JSON_MODELS);
1133 DO_TEST_CPUID(VIR_ARCH_X86_64, "FX-8150", JSON_NONE);
1134 DO_TEST_CPUID(VIR_ARCH_X86_64, "Opteron-1352", JSON_NONE);
1135 DO_TEST_CPUID(VIR_ARCH_X86_64, "Opteron-2350", JSON_HOST);
1136 DO_TEST_CPUID(VIR_ARCH_X86_64, "Opteron-6234", JSON_HOST);
1137 DO_TEST_CPUID(VIR_ARCH_X86_64, "Opteron-6282", JSON_NONE);
1138 DO_TEST_CPUID(VIR_ARCH_X86_64, "Pentium-P6100", JSON_NONE);
1139 DO_TEST_CPUID(VIR_ARCH_X86_64, "Phenom-B95", JSON_HOST);
1140 DO_TEST_CPUID(VIR_ARCH_X86_64, "Ryzen-7-1800X-Eight-Core", JSON_HOST);
1141 DO_TEST_CPUID(VIR_ARCH_X86_64, "Ryzen-9-3900X-12-Core", JSON_MODELS);
1142 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-5110", JSON_NONE);
1143 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E3-1225-v5", JSON_MODELS);
1144 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E3-1245-v5", JSON_MODELS);
1145 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2609-v3", JSON_MODELS);
1146 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2623-v4", JSON_MODELS);
1147 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2630-v3", JSON_HOST);
1148 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2630-v4", JSON_MODELS);
1149 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2650", JSON_MODELS);
1150 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2650-v3", JSON_HOST);
1151 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2650-v4", JSON_MODELS);
1152 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7-4820", JSON_HOST);
1153 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7-4830", JSON_MODELS_REQUIRED);
1154 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7-8890-v3", JSON_MODELS);
1155 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7540", JSON_MODELS);
1156 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Gold-5115", JSON_MODELS);
1157 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Gold-6130", JSON_MODELS);
1158 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Gold-6148", JSON_HOST);
1159 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Platinum-8268", JSON_HOST);
1160 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Platinum-9242", JSON_MODELS);
1161 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-W3520", JSON_HOST);
1162 DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-X5460", JSON_NONE);
1163 DO_TEST_CPUID(VIR_ARCH_X86_64, "Ice-Lake-Server", JSON_MODELS);
1164 DO_TEST_CPUID(VIR_ARCH_X86_64, "Cooperlake", JSON_MODELS);
1165
1166 cleanup:
1167 #if WITH_QEMU
1168 qemuTestDriverFree(&driver);
1169 #endif
1170
1171 virObjectUnref(model486);
1172 virObjectUnref(nomodel);
1173 virObjectUnref(models);
1174 virObjectUnref(haswell);
1175 virObjectUnref(ppc_models);
1176
1177 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
1178 }
1179
1180 VIR_TEST_MAIN(mymain)
1181