qemu_capabilities.c 186.8 KB
Newer Older
1 2 3
/*
 * qemu_capabilities.c: QEMU capabilities generation
 *
4
 * Copyright (C) 2006-2016 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17
 * Copyright (C) 2006 Daniel P. Berrange
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library.  If not, see
O
Osier Yang 已提交
19
 * <http://www.gnu.org/licenses/>.
20 21 22 23 24
 */

#include <config.h>

#include "qemu_capabilities.h"
25
#include "viralloc.h"
26
#include "vircrypto.h"
27
#include "virlog.h"
28
#include "virerror.h"
E
Eric Blake 已提交
29
#include "virfile.h"
30
#include "virfilecache.h"
31 32
#include "virpidfile.h"
#include "virprocess.h"
33
#include "cpu/cpu.h"
34
#include "cpu/cpu_x86.h"
35
#include "domain_conf.h"
36
#include "vircommand.h"
37
#include "virbitmap.h"
38
#include "virnodesuspend.h"
39
#include "virnuma.h"
40
#include "virhostcpu.h"
41
#include "qemu_monitor.h"
42
#include "virstring.h"
43
#include "qemu_hostdev.h"
44
#include "qemu_domain.h"
45
#define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
46
#include "qemu_capspriv.h"
47
#include "qemu_qapi.h"
48
#include "qemu_process.h"
49
#include "qemu_firmware.h"
J
Ján Tomko 已提交
50
#include "virutil.h"
51

52
#include <fcntl.h>
53 54
#include <sys/stat.h>
#include <unistd.h>
55
#include <stdarg.h>
56
#include <sys/utsname.h>
57 58 59

#define VIR_FROM_THIS VIR_FROM_QEMU

60 61
VIR_LOG_INIT("qemu.qemu_capabilities");

62 63 64 65
/* While not public, these strings must not change. They
 * are used in domain status files which are read on
 * daemon restarts
 */
66 67
VIR_ENUM_IMPL(virQEMUCaps,
              QEMU_CAPS_LAST, /* virQEMUCaps grouping marker */
68
              /* 0 */
69 70 71 72
              "vnc-colon",
              "no-reboot",
              "drive",
              "drive-boot",
73
              "name",
74

75
              /* 5 */
76 77 78 79
              "uuid",
              "domid",
              "vnet-hdr",
              "migrate-kvm-stdio",
80
              "migrate-qemu-tcp",
81

82
              /* 10 */
83 84 85 86
              "migrate-qemu-exec",
              "drive-cache-v2",
              "kvm",
              "drive-format",
87
              "vga",
88

89
              /* 15 */
90 91 92 93
              "0.10",
              "pci-device",
              "mem-path",
              "drive-serial",
94
              "xen-domid",
95

96
              /* 20 */
97 98 99 100
              "migrate-qemu-unix",
              "chardev",
              "enable-kvm",
              "monitor-json",
101
              "balloon",
102

103
              /* 25 */
104 105 106 107
              "device",
              "sdl",
              "smp-topology",
              "netdev",
108
              "rtc",
109

110
              /* 30 */
111
              "vhost-net",
112 113 114
              "rtc-td-hack",
              "no-hpet",
              "no-kvm-pit",
115
              "tdf",
116

117
              /* 35 */
118 119 120
              "pci-configfd",
              "nodefconfig",
              "boot-menu",
121
              "fsdev",
122
              "nesting",
123 124

              /* 40 */
125 126 127
              "name-process",
              "drive-readonly",
              "smbios-type",
128
              "vga-qxl",
129
              "spice",
130 131

              /* 45 */
132 133 134
              "vga-none",
              "migrate-qemu-fd",
              "boot-index",
135
              "hda-duplex",
136
              "drive-aio",
137 138

              /* 50 */
139 140 141
              "pci-multibus",
              "pci-bootindex",
              "ccid-emulated",
142
              "ccid-passthru",
143
              "chardev-spicevmc",
144 145

              /* 55 */
146 147 148
              "device-spicevmc",
              "virtio-tx-alg",
              "device-qxl-vga",
149
              "pci-multifunction",
150
              "virtio-blk-pci.ioeventfd",
151 152

              /* 60 */
M
Michal Privoznik 已提交
153
              "sga",
154 155
              "virtio-blk-pci.event_idx",
              "virtio-net-pci.event_idx",
156
              "cache-directsync",
157
              "piix3-usb-uhci",
158 159

              /* 65 */
160 161 162
              "piix4-usb-uhci",
              "usb-ehci",
              "ich9-usb-ehci1",
163
              "vt82c686b-usb-uhci",
164
              "pci-ohci",
165 166

              /* 70 */
167
              "usb-redir",
M
Marc-André Lureau 已提交
168
              "usb-hub",
169
              "no-shutdown",
170
              "cache-unsafe",
171
              "rombar",
172 173

              /* 75 */
J
Jim Fehlig 已提交
174
              "ich9-ahci",
175
              "no-acpi",
176
              "fsdev-readonly",
177
              "virtio-blk-pci.scsi",
178
              "blk-sg-io",
179 180

              /* 80 */
O
Osier Yang 已提交
181
              "drive-copy-on-read",
182
              "cpu-host",
183
              "fsdev-writeout",
184
              "drive-iotune",
185
              "system_wakeup",
186 187

              /* 85 */
188
              "scsi-disk.channel",
189
              "scsi-block",
190
              "transaction",
191
              "block-job-sync",
192
              "block-job-async",
193 194

              /* 90 */
195
              "scsi-cd",
196
              "ide-cd",
197
              "no-user-config",
198
              "hda-micro",
199
              "dump-guest-memory",
200 201

              /* 95 */
G
Gerd Hoffmann 已提交
202
              "nec-usb-xhci",
203
              "virtio-s390",
204
              "balloon-event",
205
              "bridge",
206
              "lsi",
207 208

              /* 100 */
209
              "virtio-scsi-pci",
V
Viktor Mihajlovski 已提交
210
              "blockio",
211
              "disable-s3",
212
              "disable-s4",
213
              "usb-redir.filter",
214 215

              /* 105 */
216 217
              "ide-drive.wwn",
              "scsi-disk.wwn",
218
              "seccomp-sandbox",
219
              "reboot-timeout",
220
              "dump-guest-core",
221 222

              /* 110 */
223
              "seamless-migration",
224
              "block-commit",
225
              "vnc",
226
              "drive-mirror",
227
              "usb-redir.bootindex",
228 229

              /* 115 */
230
              "usb-host.bootindex",
231
              "blockdev-snapshot-sync",
232
              "qxl",
233
              "VGA",
234
              "cirrus-vga",
235 236

              /* 120 */
237 238
              "vmware-svga",
              "device-video-primary",
239
              "s390-sclp",
240
              "usb-serial",
G
Guannan Ren 已提交
241
              "usb-net",
242 243

              /* 125 */
244
              "add-fd",
245
              "nbd-server",
246
              "virtio-rng",
247
              "rng-random",
248
              "rng-egd",
249 250

              /* 130 */
O
Olivia Yin 已提交
251 252
              "virtio-ccw",
              "dtb",
253
              "megasas",
254
              "ipv6-migration",
255
              "machine-opt",
256 257

              /* 135 */
L
Li Zhang 已提交
258
              "machine-usb-opt",
S
Stefan Berger 已提交
259 260
              "tpm-passthrough",
              "tpm-tis",
261
              "nvram",
H
Han Cheng 已提交
262
              "pci-bridge",
263 264

              /* 140 */
H
Han Cheng 已提交
265 266 267
              "vfio-pci",
              "vfio-pci.bootindex",
              "scsi-generic",
268
              "scsi-generic.bootindex",
269
              "mem-merge",
270 271

              /* 145 */
272
              "vnc-websocket",
O
Osier Yang 已提交
273
              "drive-discard",
274
              "mlock",
275
              "vnc-share-policy",
276
              "device-del-event",
277 278

              /* 150 */
279
              "dmi-to-pci-bridge",
280 281
              "i440fx-pci-hole64-size",
              "q35-pci-hole64-size",
282
              "usb-storage",
283
              "usb-storage.removable",
284 285

              /* 155 */
286
              "virtio-mmio",
287
              "ich9-intel-hda",
288
              "kvm-pit-lost-tick-policy",
289
              "boot-strict",
290
              "pvpanic",
291 292

              /* 160 */
293
              "enable-fips",
294 295
              "spice-file-xfer-disable",
              "spiceport",
296
              "usb-kbd",
297
              "host-pci-multidomain",
298 299

              /* 165 */
300
              "msg-timestamp",
301
              "active-commit",
302
              "change-backing-file",
303
              "memory-backend-ram",
304
              "numa",
305 306

              /* 170 */
307
              "memory-backend-file",
308
              "usb-audio",
309
              "rtc-reset-reinjection",
310
              "splash-timeout",
J
John Ferlan 已提交
311
              "iothread",
312 313

              /* 175 */
314
              "migrate-rdma",
315
              "ivshmem",
316
              "drive-iotune-max",
317
              "VGA.vgamem_mb",
318
              "vmware-svga.vgamem_mb",
319 320

              /* 180 */
321 322
              "qxl.vgamem_mb",
              "qxl-vga.vgamem_mb",
323
              "pc-dimm",
324
              "machine-vmport-opt",
325
              "aes-key-wrap",
326 327

              /* 185 */
328
              "dea-key-wrap",
M
Michal Privoznik 已提交
329
              "pci-serial",
330
              "aarch64-off",
331
              "vhost-user-multiqueue",
332
              "migration-event",
333 334

              /* 190 */
335
              "gpex-pcihost",
336
              "ioh3420",
337
              "x3130-upstream",
338
              "xio3130-downstream",
339
              "rtl8139",
340 341

              /* 195 */
342
              "e1000",
343
              "virtio-net",
344
              "gic-version",
345
              "incoming-defer",
M
Marc-André Lureau 已提交
346
              "virtio-gpu",
347 348

              /* 200 */
349
              "virtio-gpu.virgl",
350 351
              "virtio-keyboard",
              "virtio-mouse",
352
              "virtio-tablet",
353
              "virtio-input-host",
354 355

              /* 205 */
356
              "chardev-file-append",
357 358
              "ich9-disable-s3",
              "ich9-disable-s4",
359
              "vserport-change-event",
360
              "virtio-balloon-pci.deflate-on-oom",
361 362

              /* 210 */
363
              "mptsas1068",
364
              "spice-gl",
365
              "qxl.vram64_size_mb",
366
              "qxl-vga.vram64_size_mb",
367
              "chardev-logfile",
368 369

              /* 215 */
370
              "debug-threads",
371
              "secret",
372
              "pxb",
373
              "pxb-pcie",
374
              "device-tray-moved-event",
375 376

              /* 220 */
377
              "nec-usb-xhci-ports",
378
              "virtio-scsi-pci.iothread",
379
              "name-guest",
380
              "qxl.max_outputs",
381
              "qxl-vga.max_outputs",
382 383

              /* 225 */
384
              "spice-unix",
385
              "drive-detect-zeroes",
B
Boris Fiuczynski 已提交
386
              "tls-creds-x509",
387
              "display",
J
Ján Tomko 已提交
388
              "intel-iommu",
389 390

              /* 230 */
M
Michal Privoznik 已提交
391
              "smm",
392
              "virtio-pci-disable-legacy",
393
              "query-hotpluggable-cpus",
394
              "virtio-net.rx_queue_size",
395
              "machine-iommu",
396 397

              /* 235 */
398
              "virtio-vga",
399
              "drive-iotune-max-length",
400
              "ivshmem-plain",
401
              "ivshmem-doorbell",
402
              "query-qmp-schema",
403 404

              /* 240 */
405
              "gluster.debug_level",
406
              "vhost-scsi",
407
              "drive-iotune-group",
408
              "query-cpu-model-expansion",
409
              "virtio-net.host_mtu",
410 411

              /* 245 */
412
              "spice-rendernode",
413
              "nvdimm",
414
              "pcie-root-port",
415
              "query-cpu-definitions",
416
              "block-write-threshold",
417 418

              /* 250 */
419
              "query-named-block-nodes",
420
              "cpu-cache",
421
              "qemu-xhci",
422
              "kernel-irqchip",
423
              "kernel-irqchip.split",
424 425

              /* 255 */
426
              "intel-iommu.intremap",
427
              "intel-iommu.caching-mode",
428
              "intel-iommu.eim",
429
              "intel-iommu.device-iotlb",
430
              "virtio.iommu_platform",
431 432

              /* 260 */
433
              "virtio.ats",
434
              "loadparm",
435
              "spapr-pci-host-bridge",
436
              "spapr-pci-host-bridge.numa_node",
437
              "vnc-multi-servers",
438 439

              /* 265 */
440
              "virtio-net.tx_queue_size",
441
              "chardev-reconnect",
442
              "virtio-gpu.max_outputs",
J
John Ferlan 已提交
443
              "vxhs",
444
              "virtio-blk.num-queues",
445 446

              /* 270 */
447
              "machine.pseries.resize-hpt",
M
Marc-André Lureau 已提交
448
              "vmcoreinfo",
449
              "spapr-vty",
450
              "sclplmconsole",
451
              "numa.dist",
452 453

              /* 275 */
454
              "disk-share-rw",
455
              "iscsi.password-secret",
456
              "isa-serial",
457
              "pl011",
458
              "machine.pseries.max-cpu-compat",
459 460

              /* 280 */
461
              "dump-completed",
462
              "virtio-gpu-ccw",
463 464 465
              "virtio-keyboard-ccw",
              "virtio-mouse-ccw",
              "virtio-tablet-ccw",
466 467

              /* 285 */
468
              "qcow2-luks",
469
              "pcie-pci-bridge",
470
              "seccomp-blacklist",
471
              "query-cpus-fast",
472
              "disk-write-cache",
473 474

              /* 290 */
475
              "nbd-tls",
476
              "tpm-crb",
477
              "pr-manager-helper",
478
              "qom-list-properties",
479
              "memory-backend-file.discard-data",
480 481

              /* 295 */
482
              "virtual-css-bridge",
483 484
              "virtual-css-bridge.cssid-unrestricted",
              "vfio-ccw",
485
              "sdl-gl",
486
              "screendump_device",
487 488

              /* 300 */
489
              "hda-output",
490
              "blockdev-del",
491
              "vmgenid",
492
              "vhost-vsock",
493
              "chardev-fd-pass",
494 495

              /* 305 */
496
              "tpm-emulator",
497 498
              "mch",
              "mch.extended-tseg-mbytes",
499
              "sev-guest",
500
              "machine.pseries.cap-hpt-max-page-size",
501 502

              /* 310 */
503
              "machine.pseries.cap-htm",
504
              "usb-storage.werror",
505
              "egl-headless",
506
              "vfio-pci.display",
507
              "blockdev",
508 509

              /* 315 */
B
Boris Fiuczynski 已提交
510
              "vfio-ap",
Y
Yi Min Zhao 已提交
511
              "zpci",
512
              "memory-backend-memfd",
513
              "memory-backend-memfd.hugetlb",
514
              "iothread.poll-max-ns",
515 516

              /* 320 */
517
              "machine.pseries.cap-nested-hv",
518 519
              "egl-headless.rendernode",
              "memory-backend-file.align",
520
              "memory-backend-file.pmem",
521
              "nvdimm.unarmed",
522 523

              /* 325 */
524
              "scsi-disk.device_id",
525
              "virtio-pci-non-transitional",
526
              "overcommit",
527
              "query-current-machine",
528
              "machine.virt.iommu",
529 530 531 532

              /* 330 */
              "bitmap-merge",
              "nbd-bitmap",
533
              "x86-max-cpu",
534
              "cpu-unavailable-features",
535
              "canonical-cpu-features",
536 537 538

              /* 335 */
              "bochs-display",
539
              "migration-file-drop-cache",
540
              "dbus-vmstate",
541 542
              "vhost-user-gpu",
              "vhost-user-vga",
543 544 545

              /* 340 */
              "incremental-backup",
546
              "query-cpu-model-baseline",
547
              "query-cpu-model-comparison",
J
Jonathon Jongsma 已提交
548
              "ramfb",
549
              "machine.pseries.cap-ccf-assist",
550 551 552

              /* 345 */
              "arm-max-cpu",
553
              "blockdev-file-dynamic-auto-read-only",
554
              "savevm-monitor-nodes",
555
              "drive-nvme",
556
              "smp-dies",
557 558 559

              /* 350 */
              "i8042",
560
              "rng-builtin",
561
              "virtio-net.failover",
562
              "tpm-spapr",
563
              "cpu.kvm-no-adjvtime",
564 565 566

              /* 355 */
              "vhost-user-fs",
567
              "query-named-block-nodes.flat",
568
              "blockdev-snapshot.allow-write-only-overlay",
569 570
    );

571

572 573 574
typedef struct _virQEMUCapsMachineType virQEMUCapsMachineType;
typedef virQEMUCapsMachineType *virQEMUCapsMachineTypePtr;
struct _virQEMUCapsMachineType {
575 576 577
    char *name;
    char *alias;
    unsigned int maxCpus;
578
    bool hotplugCpus;
579
    bool qemuDefault;
J
Jiri Denemark 已提交
580
    char *defaultCPU;
581
};
582 583 584 585 586 587 588 589 590 591 592

typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData;
typedef virQEMUCapsHostCPUData *virQEMUCapsHostCPUDataPtr;
struct _virQEMUCapsHostCPUData {
    /* Only the "info" part is stored in the capabilities cache, the rest is
     * re-computed from other fields and external data sources everytime we
     * probe QEMU or load the cache.
     */
    qemuMonitorCPUModelInfoPtr info;
    /* Host CPU definition reported in domain capabilities. */
    virCPUDefPtr reported;
593 594
    /* Migratable host CPU definition used for updating guest CPU. */
    virCPUDefPtr migratable;
595 596 597 598
    /* CPU definition with features detected by libvirt using virCPUGetHost
     * combined with features reported by QEMU. This is used for backward
     * compatible comparison between a guest CPU and a host CPU. */
    virCPUDefPtr full;
599 600
};

601 602 603
typedef struct _virQEMUCapsAccel virQEMUCapsAccel;
typedef virQEMUCapsAccel *virQEMUCapsAccelPtr;
struct _virQEMUCapsAccel {
604 605
    size_t nmachineTypes;
    virQEMUCapsMachineTypePtr machineTypes;
606 607 608 609
    virQEMUCapsHostCPUData hostCPU;
    qemuMonitorCPUDefsPtr cpuModels;
};

610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629

typedef struct _virQEMUDomainCapsCache virQEMUDomainCapsCache;
typedef virQEMUDomainCapsCache *virQEMUDomainCapsCachePtr;
struct _virQEMUDomainCapsCache {
    virObjectLockable parent;

    virHashTablePtr cache;
};

G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDomainCapsCache, virObjectUnref);

static virClassPtr virQEMUDomainCapsCacheClass;
static void virQEMUDomainCapsCacheDispose(void *obj)
{
    virQEMUDomainCapsCachePtr cache = obj;

    virHashFree(cache->cache);
}


630 631 632 633 634 635
/*
 * Update the XML parser/formatter when adding more
 * information to this struct so that it gets cached
 * correctly. It does not have to be ABI-stable, as
 * the cache will be discarded & repopulated if the
 * timestamp on the libvirtd binary changes.
636 637
 *
 * And don't forget to update virQEMUCapsNewCopy.
638
 */
639
struct _virQEMUCaps {
640
    virObject parent;
641

642
    bool kvmSupportsNesting;
643

644
    char *binary;
645
    time_t ctime;
646
    time_t libvirtCtime;
647
    bool invalidation;
648

649
    virBitmapPtr flags;
650 651 652

    unsigned int version;
    unsigned int kvmVersion;
653
    unsigned int libvirtVersion;
654
    unsigned int microcodeVersion;
655
    char *package;
656
    char *kernelVersion;
657

658
    virArch arch;
659

660
    virQEMUDomainCapsCachePtr domCapsCache;
661

A
Andrea Bolognani 已提交
662 663
    size_t ngicCapabilities;
    virGICCapability *gicCapabilities;
664

665 666
    virSEVCapability *sevCapabilities;

667 668 669
    /* Capabilities which may differ depending on the accelerator. */
    virQEMUCapsAccel kvm;
    virQEMUCapsAccel tcg;
670 671
};

672 673
struct virQEMUCapsSearchData {
    virArch arch;
674
    const char *binaryFilter;
675 676
};

677

678 679
static virClassPtr virQEMUCapsClass;
static void virQEMUCapsDispose(void *obj);
680

681
static int virQEMUCapsOnceInit(void)
682
{
683
    if (!VIR_CLASS_NEW(virQEMUCaps, virClassForObject()))
684 685
        return -1;

686 687 688
    if (!(VIR_CLASS_NEW(virQEMUDomainCapsCache, virClassForObjectLockable())))
        return -1;

689 690 691
    return 0;
}

692
VIR_ONCE_GLOBAL_INIT(virQEMUCaps);
693

694
virArch virQEMUCapsArchFromString(const char *arch)
695 696 697 698 699
{
    if (STREQ(arch, "i386"))
        return VIR_ARCH_I686;
    if (STREQ(arch, "arm"))
        return VIR_ARCH_ARMV7L;
700 701
    if (STREQ(arch, "or32"))
        return VIR_ARCH_OR32;
702 703 704 705 706

    return virArchFromString(arch);
}


707
const char *virQEMUCapsArchToString(virArch arch)
708 709 710
{
    if (arch == VIR_ARCH_I686)
        return "i386";
S
Stefan Schallenberg 已提交
711
    else if (arch == VIR_ARCH_ARMV6L || arch == VIR_ARCH_ARMV7L)
712
        return "arm";
713 714
    else if (arch == VIR_ARCH_OR32)
        return "or32";
715 716 717 718

    return virArchToString(arch);
}

719 720 721

/* Checks whether a domain with @guest arch can run natively on @host.
 */
722
bool
723 724 725
virQEMUCapsGuestIsNative(virArch host,
                         virArch guest)
{
726
    /* host & guest arches match */
727 728 729
    if (host == guest)
        return true;

730
    /* hostarch is x86_64 and guest arch is i686 (needs -cpu qemu32) */
731 732 733
    if (host == VIR_ARCH_X86_64 && guest == VIR_ARCH_I686)
        return true;

734
    /* hostarch is aarch64 and guest arch is armv7l (needs -cpu aarch64=off) */
735 736 737
    if (host == VIR_ARCH_AARCH64 && guest == VIR_ARCH_ARMV7L)
        return true;

738
    /* hostarch and guestarch are both ppc64 */
739 740 741 742 743 744 745
    if (ARCH_IS_PPC64(host) && ARCH_IS_PPC64(guest))
        return true;

    return false;
}


746 747 748 749 750 751 752 753 754
/* Given a host and guest architectures, find a suitable QEMU target.
 *
 * This is meant to be used as a second attempt if qemu-system-$guestarch
 * can't be found, eg. on a x86_64 host you want to use qemu-system-i386,
 * if available, instead of qemu-system-x86_64 to run i686 guests */
static virArch
virQEMUCapsFindTarget(virArch hostarch,
                      virArch guestarch)
{
755 756 757
    if (virQEMUCapsGuestIsNative(hostarch, guestarch))
        guestarch = hostarch;

758 759 760 761 762 763
    /* Both ppc64 and ppc64le guests can use the ppc64 target */
    if (ARCH_IS_PPC64(guestarch))
        guestarch = VIR_ARCH_PPC64;

    return guestarch;
}
764

765

766 767 768 769 770 771 772 773 774 775 776
static virQEMUCapsAccelPtr
virQEMUCapsGetAccel(virQEMUCapsPtr qemuCaps,
                    virDomainVirtType type)
{
    if (type == VIR_DOMAIN_VIRT_KVM)
        return &qemuCaps->kvm;

    return &qemuCaps->tcg;
}


777
static void
778
virQEMUCapsSetDefaultMachine(virQEMUCapsAccelPtr caps,
779
                             size_t defIdx)
780
{
781
    virQEMUCapsMachineType tmp = caps->machineTypes[defIdx];
782

783 784 785
    memmove(caps->machineTypes + 1,
            caps->machineTypes,
            sizeof(caps->machineTypes[0]) * defIdx);
786

787
    caps->machineTypes[0] = tmp;
788 789
}

790

791
static char *
792 793
virQEMUCapsFindBinary(const char *format,
                      const char *archstr)
794
{
795 796
    char *ret = NULL;
    char *binary = NULL;
797

798
    binary = g_strdup_printf(format, archstr);
799 800 801

    ret = virFindFileInPath(binary);
    VIR_FREE(binary);
802 803 804 805 806 807 808 809 810 811 812
    return ret;
}

static char *
virQEMUCapsFindBinaryForArch(virArch hostarch,
                             virArch guestarch)
{
    char *ret = NULL;
    const char *archstr;
    virArch target;

813 814 815 816 817 818
    /* armv7l guests can only take advantage of KVM on aarch64 hosts by
     * using the qemu-system-aarch64 binary, so look for that one first
     * to avoid using qemu-system-arm (and thus TCG) instead */
    if (hostarch == VIR_ARCH_AARCH64 && guestarch == VIR_ARCH_ARMV7L) {
        archstr = virQEMUCapsArchToString(hostarch);
        if ((ret = virQEMUCapsFindBinary("qemu-system-%s", archstr)) != NULL)
819
            return ret;
820 821
    }

822 823 824
    /* First attempt: try the guest architecture as it is */
    archstr = virQEMUCapsArchToString(guestarch);
    if ((ret = virQEMUCapsFindBinary("qemu-system-%s", archstr)) != NULL)
825
        return ret;
826 827 828 829 830 831

    /* Second attempt: try looking up by target instead */
    target = virQEMUCapsFindTarget(hostarch, guestarch);
    if (target != guestarch) {
        archstr = virQEMUCapsArchToString(target);
        if ((ret = virQEMUCapsFindBinary("qemu-system-%s", archstr)) != NULL)
832
            return ret;
833
    }
834 835 836 837

    return ret;
}

838 839 840 841

char *
virQEMUCapsGetDefaultEmulator(virArch hostarch,
                              virArch guestarch)
842 843
{
    char *binary = NULL;
J
Ján Tomko 已提交
844
    /* Check for existence of base emulator, or alternate base
845 846
     * which can be used with magic cpu choice
     */
847
    binary = virQEMUCapsFindBinaryForArch(hostarch, guestarch);
848

849 850
    /* RHEL doesn't follow the usual naming for QEMU binaries and ships
     * a single binary named qemu-kvm outside of $PATH instead */
851 852
    if (virQEMUCapsGuestIsNative(hostarch, guestarch) && !binary)
        binary = g_strdup("/usr/libexec/qemu-kvm");
853

854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
    return binary;
}


static int
virQEMUCapsInitGuest(virCapsPtr caps,
                     virFileCachePtr cache,
                     virArch hostarch,
                     virArch guestarch)
{
    char *binary = NULL;
    virQEMUCapsPtr qemuCaps = NULL;
    int ret = -1;

    binary = virQEMUCapsGetDefaultEmulator(hostarch, guestarch);

870
    /* Ignore binary if extracting version info fails */
871
    if (binary) {
872
        if (!(qemuCaps = virQEMUCapsCacheLookup(cache, binary))) {
873 874 875 876
            virResetLastError();
            VIR_FREE(binary);
        }
    }
877

878
    ret = virQEMUCapsInitGuestFromBinary(caps,
879
                                         binary, qemuCaps,
880 881 882
                                         guestarch);

    VIR_FREE(binary);
883
    virObjectUnref(qemuCaps);
884 885 886 887

    return ret;
}

888 889 890 891 892 893 894

static int
virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
                               size_t *nmachines,
                               virCapsGuestMachinePtr **machines)
{
    size_t i;
895 896 897 898 899 900 901 902
    virQEMUCapsAccelPtr accel;

    /* Guest capabilities do not report TCG vs. KVM caps separately. We just
     * take the set of machine types we probed first. */
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
        accel = &qemuCaps->kvm;
    else
        accel = &qemuCaps->tcg;
903 904

    *machines = NULL;
905
    *nmachines = accel->nmachineTypes;
906 907

    if (*nmachines &&
908
        VIR_ALLOC_N(*machines, accel->nmachineTypes) < 0)
909 910
        goto error;

911
    for (i = 0; i < accel->nmachineTypes; i++) {
912 913 914 915
        virCapsGuestMachinePtr mach;
        if (VIR_ALLOC(mach) < 0)
            goto error;
        (*machines)[i] = mach;
916 917 918
        if (accel->machineTypes[i].alias) {
            mach->name = g_strdup(accel->machineTypes[i].alias);
            mach->canonical = g_strdup(accel->machineTypes[i].name);
919
        } else {
920
            mach->name = g_strdup(accel->machineTypes[i].name);
921
        }
922
        mach->maxCpus = accel->machineTypes[i].maxCpus;
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971
    }

    /* Make sure all canonical machine types also have their own entry so that
     * /capabilities/guest/arch[@name='...']/machine/text() XPath selects all
     * supported machine types.
     */
    i = 0;
    while (i < *nmachines) {
        size_t j;
        bool found = false;
        virCapsGuestMachinePtr machine = (*machines)[i];

        if (!machine->canonical) {
            i++;
            continue;
        }

        for (j = 0; j < *nmachines; j++) {
            if (STREQ(machine->canonical, (*machines)[j]->name)) {
                found = true;
                break;
            }
        }

        if (!found) {
            virCapsGuestMachinePtr mach;
            if (VIR_ALLOC(mach) < 0)
                goto error;
            if (VIR_INSERT_ELEMENT_COPY(*machines, i, *nmachines, mach) < 0) {
                VIR_FREE(mach);
                goto error;
            }
            mach->name = g_strdup(machine->canonical);
            mach->maxCpus = machine->maxCpus;
            i++;
        }
        i++;
    }

    return 0;

 error:
    virCapabilitiesFreeMachines(*machines, *nmachines);
    *nmachines = 0;
    *machines = NULL;
    return -1;
}


972 973 974
int
virQEMUCapsInitGuestFromBinary(virCapsPtr caps,
                               const char *binary,
975
                               virQEMUCapsPtr qemuCaps,
976 977 978 979 980 981 982
                               virArch guestarch)
{
    virCapsGuestPtr guest;
    virCapsGuestMachinePtr *machines = NULL;
    size_t nmachines = 0;
    int ret = -1;

983 984 985
    if (!binary)
        return 0;

986
    if (virQEMUCapsGetMachineTypesCaps(qemuCaps, &nmachines, &machines) < 0)
987
        goto cleanup;
988 989 990 991

    /* We register kvm as the base emulator too, since we can
     * just give -no-kvm to disable acceleration if required */
    if ((guest = virCapabilitiesAddGuest(caps,
992
                                         VIR_DOMAIN_OSTYPE_HVM,
993
                                         guestarch,
994 995 996 997
                                         binary,
                                         NULL,
                                         nmachines,
                                         machines)) == NULL)
998
        goto cleanup;
999 1000 1001 1002

    machines = NULL;
    nmachines = 0;

A
Andrea Bolognani 已提交
1003 1004
    /* CPU selection is always available, because all QEMU versions
     * we support can use at least '-cpu host' */
1005 1006 1007 1008
    virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_CPUSELECTION);
    virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_DEVICEBOOT);
    virCapabilitiesAddGuestFeatureWithToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_DISKSNAPSHOT,
                                             true, false);
1009

D
Daniel P. Berrange 已提交
1010
    if (virCapabilitiesAddGuestDomain(guest,
1011
                                      VIR_DOMAIN_VIRT_QEMU,
D
Daniel P. Berrange 已提交
1012 1013 1014 1015
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
1016
        goto cleanup;
1017

1018
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
1019 1020 1021 1022 1023 1024
        if (virCapabilitiesAddGuestDomain(guest,
                                          VIR_DOMAIN_VIRT_KVM,
                                          NULL,
                                          NULL,
                                          0,
                                          NULL) == NULL) {
1025
            goto cleanup;
D
Daniel P. Berrange 已提交
1026
        }
1027
    }
1028

1029 1030 1031
    if ((ARCH_IS_X86(guestarch) || guestarch == VIR_ARCH_AARCH64))
        virCapabilitiesAddGuestFeatureWithToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_ACPI,
                                                 true, true);
1032

1033 1034 1035
    if (ARCH_IS_X86(guestarch))
        virCapabilitiesAddGuestFeatureWithToggle(guest, VIR_CAPS_GUEST_FEATURE_TYPE_APIC,
                                                 true, false);
1036

1037 1038 1039 1040
    if (guestarch == VIR_ARCH_I686) {
        virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_PAE);
        virCapabilitiesAddGuestFeature(guest, VIR_CAPS_GUEST_FEATURE_TYPE_NONPAE);
    }
1041 1042 1043

    ret = 0;

1044
 cleanup:
1045 1046 1047

    virCapabilitiesFreeMachines(machines, nmachines);

1048
    return ret;
1049 1050 1051
}


1052
virCPUDefPtr
1053 1054
virQEMUCapsProbeHostCPU(virArch hostArch,
                        virDomainCapsCPUModelsPtr models)
1055
{
1056
    return virCPUGetHost(hostArch, VIR_CPU_TYPE_GUEST, NULL, models);
1057 1058 1059
}


1060 1061
virCapsPtr
virQEMUCapsInit(virFileCachePtr cache)
1062 1063
{
    virCapsPtr caps;
1064
    size_t i;
T
Tal Kain 已提交
1065
    virArch hostarch = virArchFromHost();
1066

T
Tal Kain 已提交
1067
    if ((caps = virCapabilitiesNew(hostarch,
1068
                                   true, true)) == NULL)
1069
        goto error;
1070

1071 1072 1073
    if (virCapabilitiesInitCaches(caps) < 0)
        VIR_WARN("Failed to get host CPU cache info");

1074
    /* Add the power management features of the host */
1075
    if (virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0)
1076 1077
        VIR_WARN("Failed to get host power management capabilities");

1078 1079 1080
    /* Add IOMMU info */
    virCapabilitiesHostInitIOMMU(caps);

M
Michal Privoznik 已提交
1081
    /* Add huge pages info */
1082
    if (virCapabilitiesInitPages(caps) < 0)
M
Michal Privoznik 已提交
1083 1084
        VIR_WARN("Failed to get pages info");

1085 1086 1087
    /* Add domain migration transport URIs */
    virCapabilitiesAddHostMigrateTransport(caps, "tcp");
    virCapabilitiesAddHostMigrateTransport(caps, "rdma");
1088

1089 1090 1091 1092
    /* QEMU can support pretty much every arch that exists,
     * so just probe for them all - we gracefully fail
     * if a qemu-system-$ARCH binary can't be found
     */
1093
    for (i = 0; i < VIR_ARCH_LAST; i++)
1094
        if (virQEMUCapsInitGuest(caps, cache,
T
Tal Kain 已提交
1095
                                 hostarch,
1096
                                 i) < 0)
1097
            goto error;
1098 1099 1100

    return caps;

1101
 error:
1102
    virObjectUnref(caps);
1103 1104 1105 1106
    return NULL;
}


1107
struct virQEMUCapsStringFlags {
1108 1109 1110 1111 1112
    const char *value;
    int flag;
};


1113 1114 1115 1116 1117
struct virQEMUCapsStringFlags virQEMUCapsCommands[] = {
    { "dump-guest-memory", QEMU_CAPS_DUMP_GUEST_MEMORY },
    { "query-spice", QEMU_CAPS_SPICE },
    { "query-vnc", QEMU_CAPS_VNC },
    { "nbd-server-start", QEMU_CAPS_NBD_SERVER },
1118
    { "change-backing-file", QEMU_CAPS_CHANGE_BACKING_FILE },
1119
    { "rtc-reset-reinjection", QEMU_CAPS_RTC_RESET_REINJECTION },
1120
    { "migrate-incoming", QEMU_CAPS_INCOMING_DEFER },
1121
    { "query-hotpluggable-cpus", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS },
1122
    { "query-qmp-schema", QEMU_CAPS_QUERY_QMP_SCHEMA },
1123 1124 1125
    { "query-cpu-model-expansion", QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION },
    { "query-cpu-definitions", QEMU_CAPS_QUERY_CPU_DEFINITIONS },
    { "query-named-block-nodes", QEMU_CAPS_QUERY_NAMED_BLOCK_NODES },
1126
    { "query-cpus-fast", QEMU_CAPS_QUERY_CPUS_FAST },
1127
    { "qom-list-properties", QEMU_CAPS_QOM_LIST_PROPERTIES },
1128
    { "blockdev-del", QEMU_CAPS_BLOCKDEV_DEL },
1129
    { "query-current-machine", QEMU_CAPS_QUERY_CURRENT_MACHINE },
1130
    { "block-dirty-bitmap-merge", QEMU_CAPS_BITMAP_MERGE },
1131
    { "query-cpu-model-baseline", QEMU_CAPS_QUERY_CPU_MODEL_BASELINE },
1132
    { "query-cpu-model-comparison", QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON },
1133 1134
};

1135 1136 1137 1138
struct virQEMUCapsStringFlags virQEMUCapsMigration[] = {
    { "rdma-pin-all", QEMU_CAPS_MIGRATE_RDMA },
};

1139
/* Use virQEMUCapsQMPSchemaQueries for querying parameters of events */
1140
struct virQEMUCapsStringFlags virQEMUCapsEvents[] = {
1141
    { "MIGRATION", QEMU_CAPS_MIGRATION_EVENT },
1142
    { "VSERPORT_CHANGE", QEMU_CAPS_VSERPORT_CHANGE },
1143
    { "BLOCK_WRITE_THRESHOLD", QEMU_CAPS_BLOCK_WRITE_THRESHOLD },
1144
    { "DUMP_COMPLETED", QEMU_CAPS_DUMP_COMPLETED },
1145 1146
};

1147
struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162
    { "hda-duplex", QEMU_CAPS_HDA_DUPLEX },
    { "hda-micro", QEMU_CAPS_HDA_MICRO },
    { "ccid-card-emulated", QEMU_CAPS_CCID_EMULATED },
    { "ccid-card-passthru", QEMU_CAPS_CCID_PASSTHRU },
    { "piix3-usb-uhci", QEMU_CAPS_PIIX3_USB_UHCI },
    { "piix4-usb-uhci", QEMU_CAPS_PIIX4_USB_UHCI },
    { "usb-ehci", QEMU_CAPS_USB_EHCI },
    { "ich9-usb-ehci1", QEMU_CAPS_ICH9_USB_EHCI1 },
    { "vt82c686b-usb-uhci", QEMU_CAPS_VT82C686B_USB_UHCI },
    { "pci-ohci", QEMU_CAPS_PCI_OHCI },
    { "nec-usb-xhci", QEMU_CAPS_NEC_USB_XHCI },
    { "usb-redir", QEMU_CAPS_USB_REDIR },
    { "usb-hub", QEMU_CAPS_USB_HUB },
    { "ich9-ahci", QEMU_CAPS_ICH9_AHCI },
    { "virtio-blk-s390", QEMU_CAPS_VIRTIO_S390 },
1163
    { "virtio-blk-ccw", QEMU_CAPS_VIRTIO_CCW },
1164
    { "sclpconsole", QEMU_CAPS_DEVICE_SCLPCONSOLE },
1165
    { "lsi53c895a", QEMU_CAPS_SCSI_LSI },
1166
    { "virtio-scsi-pci", QEMU_CAPS_VIRTIO_SCSI },
1167 1168
    { "virtio-scsi-s390", QEMU_CAPS_VIRTIO_SCSI },
    { "virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI },
1169
    { "virtio-scsi-device", QEMU_CAPS_VIRTIO_SCSI },
1170
    { "megasas", QEMU_CAPS_SCSI_MEGASAS },
1171
    { "qxl", QEMU_CAPS_DEVICE_QXL },
1172 1173
    { "sga", QEMU_CAPS_SGA },
    { "scsi-block", QEMU_CAPS_SCSI_BLOCK },
1174 1175 1176
    { "VGA", QEMU_CAPS_DEVICE_VGA },
    { "cirrus-vga", QEMU_CAPS_DEVICE_CIRRUS_VGA },
    { "vmware-svga", QEMU_CAPS_DEVICE_VMWARE_SVGA },
H
Han Cheng 已提交
1177
    { "usb-serial", QEMU_CAPS_DEVICE_USB_SERIAL },
1178
    { "virtio-rng-pci", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1179 1180
    { "virtio-rng-s390", QEMU_CAPS_DEVICE_VIRTIO_RNG },
    { "virtio-rng-ccw", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1181
    { "virtio-rng-device", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1182
    { "rng-random", QEMU_CAPS_OBJECT_RNG_RANDOM },
1183
    { "rng-egd", QEMU_CAPS_OBJECT_RNG_EGD },
1184
    { "spapr-nvram", QEMU_CAPS_DEVICE_NVRAM },
1185
    { "pci-bridge", QEMU_CAPS_DEVICE_PCI_BRIDGE },
1186
    { "vfio-pci", QEMU_CAPS_DEVICE_VFIO_PCI },
1187
    { "i82801b11-bridge", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE },
1188
    { "usb-storage", QEMU_CAPS_DEVICE_USB_STORAGE },
1189
    { "virtio-mmio", QEMU_CAPS_DEVICE_VIRTIO_MMIO },
1190
    { "ich9-intel-hda", QEMU_CAPS_DEVICE_ICH9_INTEL_HDA },
H
Hu Tao 已提交
1191
    { "pvpanic", QEMU_CAPS_DEVICE_PANIC },
L
Li Zhang 已提交
1192
    { "usb-kbd", QEMU_CAPS_DEVICE_USB_KBD },
1193
    { "memory-backend-ram", QEMU_CAPS_OBJECT_MEMORY_RAM },
1194
    { "memory-backend-file", QEMU_CAPS_OBJECT_MEMORY_FILE },
1195
    { "usb-audio", QEMU_CAPS_OBJECT_USB_AUDIO },
J
John Ferlan 已提交
1196
    { "iothread", QEMU_CAPS_OBJECT_IOTHREAD},
1197
    { "ivshmem", QEMU_CAPS_DEVICE_IVSHMEM },
1198
    { "pc-dimm", QEMU_CAPS_DEVICE_PC_DIMM },
M
Michal Privoznik 已提交
1199
    { "pci-serial", QEMU_CAPS_DEVICE_PCI_SERIAL },
1200
    { "gpex-pcihost", QEMU_CAPS_OBJECT_GPEX},
1201
    { "ioh3420", QEMU_CAPS_DEVICE_IOH3420 },
1202
    { "x3130-upstream", QEMU_CAPS_DEVICE_X3130_UPSTREAM },
1203
    { "xio3130-downstream", QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM },
1204
    { "rtl8139", QEMU_CAPS_DEVICE_RTL8139 },
1205
    { "e1000", QEMU_CAPS_DEVICE_E1000 },
1206 1207 1208 1209
    { "virtio-net-pci", QEMU_CAPS_DEVICE_VIRTIO_NET },
    { "virtio-net-ccw", QEMU_CAPS_DEVICE_VIRTIO_NET },
    { "virtio-net-s390", QEMU_CAPS_DEVICE_VIRTIO_NET },
    { "virtio-net-device", QEMU_CAPS_DEVICE_VIRTIO_NET },
M
Marc-André Lureau 已提交
1210 1211
    { "virtio-gpu-pci", QEMU_CAPS_DEVICE_VIRTIO_GPU },
    { "virtio-gpu-device", QEMU_CAPS_DEVICE_VIRTIO_GPU },
1212
    { "virtio-vga", QEMU_CAPS_DEVICE_VIRTIO_VGA },
1213 1214 1215 1216 1217 1218
    { "virtio-keyboard-device", QEMU_CAPS_VIRTIO_KEYBOARD },
    { "virtio-keyboard-pci", QEMU_CAPS_VIRTIO_KEYBOARD },
    { "virtio-mouse-device", QEMU_CAPS_VIRTIO_MOUSE },
    { "virtio-mouse-pci", QEMU_CAPS_VIRTIO_MOUSE },
    { "virtio-tablet-device", QEMU_CAPS_VIRTIO_TABLET },
    { "virtio-tablet-pci", QEMU_CAPS_VIRTIO_TABLET },
1219 1220
    { "virtio-input-host-device", QEMU_CAPS_VIRTIO_INPUT_HOST },
    { "virtio-input-host-pci", QEMU_CAPS_VIRTIO_INPUT_HOST },
1221
    { "mptsas1068", QEMU_CAPS_SCSI_MPTSAS1068 },
1222
    { "secret", QEMU_CAPS_OBJECT_SECRET },
1223
    { "pxb", QEMU_CAPS_DEVICE_PXB },
1224
    { "pxb-pcie", QEMU_CAPS_DEVICE_PXB_PCIE },
1225
    { "tls-creds-x509", QEMU_CAPS_OBJECT_TLS_CREDS_X509 },
J
Ján Tomko 已提交
1226
    { "intel-iommu", QEMU_CAPS_DEVICE_INTEL_IOMMU },
1227 1228
    { "ivshmem-plain", QEMU_CAPS_DEVICE_IVSHMEM_PLAIN },
    { "ivshmem-doorbell", QEMU_CAPS_DEVICE_IVSHMEM_DOORBELL },
1229
    { "vhost-scsi", QEMU_CAPS_DEVICE_VHOST_SCSI },
1230
    { "nvdimm", QEMU_CAPS_DEVICE_NVDIMM },
1231
    { "pcie-root-port", QEMU_CAPS_DEVICE_PCIE_ROOT_PORT },
1232
    { "qemu-xhci", QEMU_CAPS_DEVICE_QEMU_XHCI },
1233
    { "spapr-pci-host-bridge", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE },
M
Marc-André Lureau 已提交
1234
    { "vmcoreinfo", QEMU_CAPS_DEVICE_VMCOREINFO },
1235
    { "spapr-vty", QEMU_CAPS_DEVICE_SPAPR_VTY },
1236
    { "sclplmconsole", QEMU_CAPS_DEVICE_SCLPLMCONSOLE },
1237
    { "isa-serial", QEMU_CAPS_DEVICE_ISA_SERIAL },
1238
    { "pl011", QEMU_CAPS_DEVICE_PL011 },
1239
    { "virtio-gpu-ccw", QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW },
1240 1241 1242
    { "virtio-keyboard-ccw", QEMU_CAPS_DEVICE_VIRTIO_KEYBOARD_CCW },
    { "virtio-mouse-ccw", QEMU_CAPS_DEVICE_VIRTIO_MOUSE_CCW },
    { "virtio-tablet-ccw", QEMU_CAPS_DEVICE_VIRTIO_TABLET_CCW },
1243
    { "pcie-pci-bridge", QEMU_CAPS_DEVICE_PCIE_PCI_BRIDGE },
1244
    { "pr-manager-helper", QEMU_CAPS_PR_MANAGER_HELPER },
1245
    { "virtual-css-bridge", QEMU_CAPS_CCW },
1246
    { "vfio-ccw", QEMU_CAPS_DEVICE_VFIO_CCW },
1247
    { "hda-output", QEMU_CAPS_HDA_OUTPUT },
1248
    { "vmgenid", QEMU_CAPS_DEVICE_VMGENID },
1249
    { "vhost-vsock-device", QEMU_CAPS_DEVICE_VHOST_VSOCK },
1250
    { "mch", QEMU_CAPS_DEVICE_MCH },
1251
    { "sev-guest", QEMU_CAPS_SEV_GUEST },
B
Boris Fiuczynski 已提交
1252
    { "vfio-ap", QEMU_CAPS_DEVICE_VFIO_AP },
Y
Yi Min Zhao 已提交
1253
    { "zpci", QEMU_CAPS_DEVICE_ZPCI },
1254
    { "memory-backend-memfd", QEMU_CAPS_OBJECT_MEMORY_MEMFD },
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
    { "virtio-blk-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-blk-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-net-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-net-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "vhost-scsi-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "vhost-scsi-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-rng-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-rng-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-9p-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-9p-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-balloon-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-balloon-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "vhost-vsock-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "vhost-vsock-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-input-host-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-input-host-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-scsi-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-scsi-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-serial-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
    { "virtio-serial-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL },
1275
    { "max-x86_64-cpu", QEMU_CAPS_X86_MAX_CPU },
1276
    { "bochs-display", QEMU_CAPS_DEVICE_BOCHS_DISPLAY },
1277
    { "dbus-vmstate", QEMU_CAPS_DBUS_VMSTATE },
1278 1279
    { "vhost-user-gpu", QEMU_CAPS_DEVICE_VHOST_USER_GPU },
    { "vhost-user-vga", QEMU_CAPS_DEVICE_VHOST_USER_VGA },
J
Jonathon Jongsma 已提交
1280
    { "ramfb", QEMU_CAPS_DEVICE_RAMFB },
1281
    { "max-arm-cpu", QEMU_CAPS_ARM_MAX_CPU },
1282
    { "i8042", QEMU_CAPS_DEVICE_I8042 },
1283
    { "rng-builtin", QEMU_CAPS_OBJECT_RNG_BUILTIN },
1284
    { "tpm-spapr", QEMU_CAPS_DEVICE_TPM_SPAPR },
1285
    { "vhost-user-fs-device", QEMU_CAPS_DEVICE_VHOST_USER_FS },
1286 1287
};

1288
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = {
1289
    { "deflate-on-oom", QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE },
1290 1291 1292
    { "disable-legacy", QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY },
    { "iommu_platform", QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM },
    { "ats", QEMU_CAPS_VIRTIO_PCI_ATS },
1293 1294
};

1295
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBlk[] = {
1296 1297 1298 1299
    { "ioeventfd", QEMU_CAPS_VIRTIO_IOEVENTFD },
    { "event_idx", QEMU_CAPS_VIRTIO_BLK_EVENT_IDX },
    { "scsi", QEMU_CAPS_VIRTIO_BLK_SCSI },
    { "logical_block_size", QEMU_CAPS_BLOCKIO },
1300
    { "num-queues", QEMU_CAPS_VIRTIO_BLK_NUM_QUEUES },
1301
    { "share-rw", QEMU_CAPS_DISK_SHARE_RW },
1302 1303 1304
    { "disable-legacy", QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY },
    { "iommu_platform", QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM },
    { "ats", QEMU_CAPS_VIRTIO_PCI_ATS },
1305
    { "write-cache", QEMU_CAPS_DISK_WRITE_CACHE },
1306 1307
};

1308
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioNet[] = {
1309 1310
    { "tx", QEMU_CAPS_VIRTIO_TX_ALG },
    { "event_idx", QEMU_CAPS_VIRTIO_NET_EVENT_IDX },
1311
    { "rx_queue_size", QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE },
1312
    { "tx_queue_size", QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE },
1313
    { "host_mtu", QEMU_CAPS_VIRTIO_NET_HOST_MTU },
1314 1315 1316
    { "disable-legacy", QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY },
    { "iommu_platform", QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM },
    { "ats", QEMU_CAPS_VIRTIO_PCI_ATS },
1317
    { "failover", QEMU_CAPS_VIRTIO_NET_FAILOVER },
1318 1319
};

1320
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsSpaprPCIHostBridge[] = {
1321 1322 1323
    { "numa_node", QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE },
};

1324
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioSCSI[] = {
1325
    { "iothread", QEMU_CAPS_VIRTIO_SCSI_IOTHREAD },
1326 1327 1328
    { "disable-legacy", QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY },
    { "iommu_platform", QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM },
    { "ats", QEMU_CAPS_VIRTIO_PCI_ATS },
1329 1330
};

1331
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVfioPCI[] = {
1332
    { "display", QEMU_CAPS_VFIO_PCI_DISPLAY },
1333 1334
};

1335
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsSCSIDisk[] = {
1336 1337
    { "channel", QEMU_CAPS_SCSI_DISK_CHANNEL },
    { "wwn", QEMU_CAPS_SCSI_DISK_WWN },
1338
    { "share-rw", QEMU_CAPS_DISK_SHARE_RW },
1339
    { "write-cache", QEMU_CAPS_DISK_WRITE_CACHE },
1340
    { "device_id", QEMU_CAPS_SCSI_DISK_DEVICE_ID },
1341 1342
};

1343
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsIDEDrive[] = {
1344
    { "wwn", QEMU_CAPS_IDE_DRIVE_WWN },
1345
    { "share-rw", QEMU_CAPS_DISK_SHARE_RW },
1346
    { "write-cache", QEMU_CAPS_DISK_WRITE_CACHE },
1347 1348
};

1349
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsPiix4PM[] = {
1350 1351
    { "disable_s3", QEMU_CAPS_PIIX_DISABLE_S3 },
    { "disable_s4", QEMU_CAPS_PIIX_DISABLE_S4 },
1352 1353
};

1354
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsUSBRedir[] = {
1355
    { "filter", QEMU_CAPS_USB_REDIR_FILTER },
1356 1357
};

1358
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsI440FXPCIHost[] = {
1359 1360 1361
    { "pci-hole64-size", QEMU_CAPS_I440FX_PCI_HOLE64_SIZE },
};

1362
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsQ35PCIHost[] = {
1363 1364 1365
    { "pci-hole64-size", QEMU_CAPS_Q35_PCI_HOLE64_SIZE },
};

1366
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsUSBStorage[] = {
1367
    { "removable", QEMU_CAPS_USB_STORAGE_REMOVABLE },
1368
    { "share-rw", QEMU_CAPS_DISK_SHARE_RW },
1369
    { "write-cache", QEMU_CAPS_DISK_WRITE_CACHE },
1370
    { "werror", QEMU_CAPS_USB_STORAGE_WERROR },
1371 1372
};

1373
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsKVMPit[] = {
1374 1375 1376
    { "lost_tick_policy", QEMU_CAPS_KVM_PIT_TICK_POLICY },
};

1377
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVGA[] = {
1378 1379 1380
    { "vgamem_mb", QEMU_CAPS_VGA_VGAMEM },
};

1381
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVmwareSvga[] = {
1382 1383 1384
    { "vgamem_mb", QEMU_CAPS_VMWARE_SVGA_VGAMEM },
};

1385
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsQxl[] = {
1386
    { "vgamem_mb", QEMU_CAPS_QXL_VGAMEM },
1387
    { "vram64_size_mb", QEMU_CAPS_QXL_VRAM64 },
1388
    { "max_outputs", QEMU_CAPS_QXL_MAX_OUTPUTS },
1389 1390
};

1391
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioGpu[] = {
1392
    { "virgl", QEMU_CAPS_VIRTIO_GPU_VIRGL },
1393
    { "max_outputs", QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS },
1394 1395 1396
    { "disable-legacy", QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY },
    { "iommu_platform", QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM },
    { "ats", QEMU_CAPS_VIRTIO_PCI_ATS },
1397 1398
};

1399
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsICH9[] = {
1400 1401 1402 1403
    { "disable_s3", QEMU_CAPS_ICH9_DISABLE_S3 },
    { "disable_s4", QEMU_CAPS_ICH9_DISABLE_S4 },
};

1404
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsUSBNECXHCI[] = {
1405 1406 1407
    { "p3", QEMU_CAPS_NEC_USB_XHCI_PORTS },
};

1408
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsIntelIOMMU[] = {
1409
    { "intremap", QEMU_CAPS_INTEL_IOMMU_INTREMAP },
1410
    { "caching-mode", QEMU_CAPS_INTEL_IOMMU_CACHING_MODE },
1411
    { "eim", QEMU_CAPS_INTEL_IOMMU_EIM },
1412
    { "device-iotlb", QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB },
1413 1414
};

1415 1416 1417 1418
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtualCSSBridge[] = {
    { "cssid-unrestricted", QEMU_CAPS_CCW_CSSID_UNRESTRICTED },
};

1419 1420 1421 1422
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsMCH[] = {
    { "extended-tseg-mbytes", QEMU_CAPS_MCH_EXTENDED_TSEG_MBYTES },
};

1423 1424 1425 1426
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsNVDIMM[] = {
    { "unarmed", QEMU_CAPS_DEVICE_NVDIMM_UNARMED },
};

1427
/* see documentation for virQEMUQAPISchemaPathGet for the query format */
1428
static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
1429
    { "blockdev-add/arg-type/options/+gluster/debug-level", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
1430
    { "blockdev-add/arg-type/+gluster/debug", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
J
John Ferlan 已提交
1431
    { "blockdev-add/arg-type/+vxhs", QEMU_CAPS_VXHS},
1432
    { "blockdev-add/arg-type/+iscsi/password-secret", QEMU_CAPS_ISCSI_PASSWORD_SECRET },
1433
    { "blockdev-add/arg-type/+qcow2/encrypt/+luks/key-secret", QEMU_CAPS_QCOW2_LUKS },
1434
    { "nbd-server-start/arg-type/tls-creds", QEMU_CAPS_NBD_TLS },
1435
    { "screendump/arg-type/device", QEMU_CAPS_SCREENDUMP_DEVICE },
1436
    { "block-commit/arg-type/*top",  QEMU_CAPS_ACTIVE_COMMIT },
1437
    { "query-iothreads/ret-type/poll-max-ns", QEMU_CAPS_IOTHREAD_POLLING },
1438
    { "query-display-options/ret-type/+egl-headless/rendernode", QEMU_CAPS_EGL_HEADLESS_RENDERNODE },
1439
    { "nbd-server-add/arg-type/bitmap", QEMU_CAPS_NBD_BITMAP },
1440
    { "blockdev-add/arg-type/+file/drop-cache", QEMU_CAPS_MIGRATION_FILE_DROP_CACHE },
1441
    { "blockdev-add/arg-type/+file/$dynamic-auto-read-only", QEMU_CAPS_BLOCK_FILE_AUTO_READONLY_DYNAMIC },
1442
    { "human-monitor-command/$savevm-monitor-nodes", QEMU_CAPS_SAVEVM_MONITOR_NODES },
1443
    { "blockdev-add/arg-type/+nvme", QEMU_CAPS_DRIVE_NVME },
1444
    { "query-named-block-nodes/arg-type/flat", QEMU_CAPS_QMP_QUERY_NAMED_BLOCK_NODES_FLAT },
1445
    { "blockdev-snapshot/$allow-write-only-overlay", QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY },
1446 1447
};

1448 1449
typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
struct _virQEMUCapsObjectTypeProps {
1450
    const char *type;
1451
    struct virQEMUCapsStringFlags *props;
1452
    size_t nprops;
1453
    int capsCondition;
1454 1455
};

1456 1457 1458 1459 1460
typedef int (*virQEMUCapsObjectTypePropsCB)(qemuMonitorPtr mon,
                                            const char *type,
                                            char ***props);

static virQEMUCapsObjectTypeProps virQEMUCapsDeviceProps[] = {
1461
    { "virtio-blk-pci", virQEMUCapsDevicePropsVirtioBlk,
1462
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioBlk),
1463
      -1 },
1464
    { "virtio-net-pci", virQEMUCapsDevicePropsVirtioNet,
1465
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioNet),
1466
      QEMU_CAPS_DEVICE_VIRTIO_NET },
1467
    { "virtio-scsi-pci", virQEMUCapsDevicePropsVirtioSCSI,
1468
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioSCSI),
1469
      QEMU_CAPS_VIRTIO_SCSI },
1470
    { "virtio-blk-ccw", virQEMUCapsDevicePropsVirtioBlk,
1471
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioBlk),
1472
      QEMU_CAPS_VIRTIO_CCW },
1473
    { "virtio-net-ccw", virQEMUCapsDevicePropsVirtioNet,
1474
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioNet),
1475
      QEMU_CAPS_DEVICE_VIRTIO_NET },
1476
    { "virtio-scsi-ccw", virQEMUCapsDevicePropsVirtioSCSI,
1477
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioSCSI),
1478
      QEMU_CAPS_VIRTIO_SCSI },
1479
    { "virtio-blk-s390", virQEMUCapsDevicePropsVirtioBlk,
1480
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioBlk),
1481
      QEMU_CAPS_VIRTIO_S390 },
1482
    { "virtio-net-s390", virQEMUCapsDevicePropsVirtioNet,
1483
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioNet),
1484
      QEMU_CAPS_DEVICE_VIRTIO_NET },
1485
    { "vfio-pci", virQEMUCapsDevicePropsVfioPCI,
1486
      G_N_ELEMENTS(virQEMUCapsDevicePropsVfioPCI),
1487
      QEMU_CAPS_DEVICE_VFIO_PCI },
1488
    { "scsi-hd", virQEMUCapsDevicePropsSCSIDisk,
1489
      G_N_ELEMENTS(virQEMUCapsDevicePropsSCSIDisk),
1490
      -1 },
1491
    { "ide-hd", virQEMUCapsDevicePropsIDEDrive,
1492
      G_N_ELEMENTS(virQEMUCapsDevicePropsIDEDrive),
1493
      -1 },
1494
    { "PIIX4_PM", virQEMUCapsDevicePropsPiix4PM,
1495
      G_N_ELEMENTS(virQEMUCapsDevicePropsPiix4PM),
1496
      -1 },
1497
    { "usb-redir", virQEMUCapsDevicePropsUSBRedir,
1498
      G_N_ELEMENTS(virQEMUCapsDevicePropsUSBRedir),
1499
      QEMU_CAPS_USB_REDIR },
1500
    { "i440FX-pcihost", virQEMUCapsDevicePropsI440FXPCIHost,
1501
      G_N_ELEMENTS(virQEMUCapsDevicePropsI440FXPCIHost),
1502
      -1 },
1503
    { "q35-pcihost", virQEMUCapsDevicePropsQ35PCIHost,
1504
      G_N_ELEMENTS(virQEMUCapsDevicePropsQ35PCIHost),
1505
      -1 },
1506
    { "usb-storage", virQEMUCapsDevicePropsUSBStorage,
1507
      G_N_ELEMENTS(virQEMUCapsDevicePropsUSBStorage),
1508
      QEMU_CAPS_DEVICE_USB_STORAGE },
1509
    { "kvm-pit", virQEMUCapsDevicePropsKVMPit,
1510
      G_N_ELEMENTS(virQEMUCapsDevicePropsKVMPit),
1511
      -1 },
1512
    { "VGA", virQEMUCapsDevicePropsVGA,
1513
      G_N_ELEMENTS(virQEMUCapsDevicePropsVGA),
1514
      QEMU_CAPS_DEVICE_VGA },
1515
    { "vmware-svga", virQEMUCapsDevicePropsVmwareSvga,
1516
      G_N_ELEMENTS(virQEMUCapsDevicePropsVmwareSvga),
1517
      QEMU_CAPS_DEVICE_VMWARE_SVGA },
1518
    { "qxl", virQEMUCapsDevicePropsQxl,
1519
      G_N_ELEMENTS(virQEMUCapsDevicePropsQxl),
1520
      QEMU_CAPS_DEVICE_QXL },
1521
    { "virtio-gpu-pci", virQEMUCapsDevicePropsVirtioGpu,
1522
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioGpu),
1523
      QEMU_CAPS_DEVICE_VIRTIO_GPU },
1524
    { "virtio-gpu-device", virQEMUCapsDevicePropsVirtioGpu,
1525
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioGpu),
1526
      QEMU_CAPS_DEVICE_VIRTIO_GPU },
1527
    { "ICH9-LPC", virQEMUCapsDevicePropsICH9,
1528
      G_N_ELEMENTS(virQEMUCapsDevicePropsICH9),
1529
      -1 },
1530
    { "virtio-balloon-pci", virQEMUCapsDevicePropsVirtioBalloon,
1531
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioBalloon),
1532
      -1 },
1533
    { "virtio-balloon-ccw", virQEMUCapsDevicePropsVirtioBalloon,
1534
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioBalloon),
1535
      -1 },
1536
    { "virtio-balloon-device", virQEMUCapsDevicePropsVirtioBalloon,
1537
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioBalloon),
1538
      -1 },
1539
    { "nec-usb-xhci", virQEMUCapsDevicePropsUSBNECXHCI,
1540
      G_N_ELEMENTS(virQEMUCapsDevicePropsUSBNECXHCI),
1541
      QEMU_CAPS_NEC_USB_XHCI },
1542
    { "intel-iommu", virQEMUCapsDevicePropsIntelIOMMU,
1543
      G_N_ELEMENTS(virQEMUCapsDevicePropsIntelIOMMU),
1544
      QEMU_CAPS_DEVICE_INTEL_IOMMU },
1545
    { "spapr-pci-host-bridge", virQEMUCapsDevicePropsSpaprPCIHostBridge,
1546
      G_N_ELEMENTS(virQEMUCapsDevicePropsSpaprPCIHostBridge),
1547
      QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE },
1548
    { "virtio-gpu-ccw", virQEMUCapsDevicePropsVirtioGpu,
1549
      G_N_ELEMENTS(virQEMUCapsDevicePropsVirtioGpu),
1550
      QEMU_CAPS_DEVICE_VIRTIO_GPU_CCW },
1551
    { "virtual-css-bridge", virQEMUCapsObjectPropsVirtualCSSBridge,
1552
      G_N_ELEMENTS(virQEMUCapsObjectPropsVirtualCSSBridge),
1553
      QEMU_CAPS_CCW },
1554
    { "mch", virQEMUCapsDevicePropsMCH,
1555
      G_N_ELEMENTS(virQEMUCapsDevicePropsMCH),
1556
      QEMU_CAPS_DEVICE_MCH },
1557
    { "nvdimm", virQEMUCapsDevicePropsNVDIMM,
1558
      G_N_ELEMENTS(virQEMUCapsDevicePropsNVDIMM),
1559
      QEMU_CAPS_DEVICE_NVDIMM },
1560 1561
};

1562 1563
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMemoryBackendFile[] = {
    { "discard-data", QEMU_CAPS_OBJECT_MEMORY_FILE_DISCARD },
1564
    { "align", QEMU_CAPS_OBJECT_MEMORY_FILE_ALIGN },
1565
    { "pmem", QEMU_CAPS_OBJECT_MEMORY_FILE_PMEM },
1566 1567
};

1568 1569 1570 1571
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMemoryBackendMemfd[] = {
    { "hugetlb", QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB },
};

1572
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMaxCPU[] = {
1573
    { "unavailable-features", QEMU_CAPS_CPU_UNAVAILABLE_FEATURES },
1574
    { "kvm-no-adjvtime", QEMU_CAPS_CPU_KVM_NO_ADJVTIME },
1575 1576
};

1577 1578
static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
    { "memory-backend-file", virQEMUCapsObjectPropsMemoryBackendFile,
1579
      G_N_ELEMENTS(virQEMUCapsObjectPropsMemoryBackendFile),
1580
      QEMU_CAPS_OBJECT_MEMORY_FILE },
1581
    { "memory-backend-memfd", virQEMUCapsObjectPropsMemoryBackendMemfd,
1582
      G_N_ELEMENTS(virQEMUCapsObjectPropsMemoryBackendMemfd),
1583
      QEMU_CAPS_OBJECT_MEMORY_MEMFD },
1584 1585
    { "max-x86_64-cpu", virQEMUCapsObjectPropsMaxCPU,
      G_N_ELEMENTS(virQEMUCapsObjectPropsMaxCPU),
1586
      QEMU_CAPS_X86_MAX_CPU },
1587 1588 1589
    { "max-arm-cpu", virQEMUCapsObjectPropsMaxCPU,
      G_N_ELEMENTS(virQEMUCapsObjectPropsMaxCPU),
      QEMU_CAPS_ARM_MAX_CPU },
1590 1591
};

1592
static struct virQEMUCapsStringFlags virQEMUCapsMachinePropsPSeries[] = {
1593 1594 1595
    { "cap-hpt-max-page-size", QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE },
    { "cap-htm", QEMU_CAPS_MACHINE_PSERIES_CAP_HTM },
    { "cap-nested-hv", QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV },
1596
    { "cap-ccf-assist", QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST },
1597 1598
};

1599 1600 1601 1602
static struct virQEMUCapsStringFlags virQEMUCapsMachinePropsVirt[] = {
    { "iommu", QEMU_CAPS_MACHINE_VIRT_IOMMU },
};

1603
static virQEMUCapsObjectTypeProps virQEMUCapsMachineProps[] = {
1604
    { "pseries", virQEMUCapsMachinePropsPSeries,
1605
      G_N_ELEMENTS(virQEMUCapsMachinePropsPSeries),
1606
      -1 },
1607
    { "virt", virQEMUCapsMachinePropsVirt,
1608
      G_N_ELEMENTS(virQEMUCapsMachinePropsVirt),
1609
      -1 },
1610
};
1611 1612

static void
1613 1614 1615 1616 1617
virQEMUCapsProcessStringFlags(virQEMUCapsPtr qemuCaps,
                              size_t nflags,
                              struct virQEMUCapsStringFlags *flags,
                              size_t nvalues,
                              char *const*values)
1618 1619
{
    size_t i, j;
1620
    for (i = 0; i < nflags; i++) {
1621 1622 1623
        if (virQEMUCapsGet(qemuCaps, flags[i].flag))
            continue;

1624
        for (j = 0; j < nvalues; j++) {
1625
            if (STREQ(values[j], flags[i].value)) {
1626
                virQEMUCapsSet(qemuCaps, flags[i].flag);
1627 1628 1629 1630 1631 1632 1633
                break;
            }
        }
    }
}


1634
int virQEMUCapsGetDefaultVersion(virCapsPtr caps,
1635
                                 virFileCachePtr capsCache,
1636
                                 unsigned int *version)
1637
{
1638
    virQEMUCapsPtr qemucaps;
T
Tal Kain 已提交
1639
    virArch hostarch;
1640
    virCapsDomainDataPtr capsdata;
1641 1642 1643 1644

    if (*version > 0)
        return 0;

T
Tal Kain 已提交
1645
    hostarch = virArchFromHost();
1646 1647 1648
    if (!(capsdata = virCapabilitiesDomainDataLookup(caps,
            VIR_DOMAIN_OSTYPE_HVM, hostarch, VIR_DOMAIN_VIRT_QEMU,
            NULL, NULL))) {
1649
        virReportError(VIR_ERR_INTERNAL_ERROR,
1650
                       _("Cannot find suitable emulator for %s"),
T
Tal Kain 已提交
1651
                       virArchToString(hostarch));
1652 1653 1654
        return -1;
    }

1655
    qemucaps = virQEMUCapsCacheLookup(capsCache, capsdata->emulator);
1656 1657
    VIR_FREE(capsdata);
    if (!qemucaps)
1658 1659
        return -1;

1660
    *version = virQEMUCapsGetVersion(qemucaps);
1661
    virObjectUnref(qemucaps);
1662 1663
    return 0;
}
1664 1665


1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
static virQEMUDomainCapsCachePtr
virQEMUDomainCapsCacheNew(void)
{
    g_autoptr(virQEMUDomainCapsCache) cache = NULL;

    if (virQEMUCapsInitialize() < 0)
        return NULL;

    if (!(cache = virObjectLockableNew(virQEMUDomainCapsCacheClass)))
        return NULL;

    if (!(cache->cache = virHashCreate(5, virObjectFreeHashData)))
        return NULL;

    return g_steal_pointer(&cache);
}
1682 1683


1684 1685
virQEMUCapsPtr
virQEMUCapsNew(void)
1686
{
1687
    virQEMUCapsPtr qemuCaps;
1688

1689
    if (virQEMUCapsInitialize() < 0)
1690 1691
        return NULL;

1692
    if (!(qemuCaps = virObjectNew(virQEMUCapsClass)))
1693 1694
        return NULL;

1695
    qemuCaps->invalidation = true;
1696
    if (!(qemuCaps->flags = virBitmapNew(QEMU_CAPS_LAST)))
1697
        goto error;
1698

1699
    if (!(qemuCaps->domCapsCache = virQEMUDomainCapsCacheNew()))
1700 1701
        goto error;

1702
    return qemuCaps;
1703

1704
 error:
1705
    virObjectUnref(qemuCaps);
1706
    return NULL;
1707 1708 1709
}


1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720
virQEMUCapsPtr
virQEMUCapsNewBinary(const char *binary)
{
    virQEMUCapsPtr qemuCaps = virQEMUCapsNew();

    qemuCaps->binary = g_strdup(binary);

    return qemuCaps;
}


1721 1722 1723 1724 1725 1726 1727 1728
void
virQEMUCapsSetInvalidation(virQEMUCapsPtr qemuCaps,
                           bool enabled)
{
    qemuCaps->invalidation = enabled;
}


1729
static int
1730 1731
virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
                           virQEMUCapsHostCPUDataPtr src)
1732
{
1733 1734
    if (src->info &&
        !(dst->info = qemuMonitorCPUModelInfoCopy(src->info)))
1735 1736
        return -1;

1737 1738
    if (src->reported &&
        !(dst->reported = virCPUDefCopy(src->reported)))
1739 1740
        return -1;

1741 1742 1743 1744
    if (src->migratable &&
        !(dst->migratable = virCPUDefCopy(src->migratable)))
        return -1;

1745 1746 1747 1748
    if (src->full &&
        !(dst->full = virCPUDefCopy(src->full)))
        return -1;

1749 1750 1751 1752
    return 0;
}


1753
static void
1754
virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
1755
{
1756
    qemuMonitorCPUModelInfoFree(cpuData->info);
1757
    virCPUDefFree(cpuData->reported);
1758
    virCPUDefFree(cpuData->migratable);
1759
    virCPUDefFree(cpuData->full);
1760 1761

    memset(cpuData, 0, sizeof(*cpuData));
1762 1763 1764
}


1765 1766 1767 1768
static int
virQEMUCapsSEVInfoCopy(virSEVCapabilityPtr *dst,
                       virSEVCapabilityPtr src)
{
J
Ján Tomko 已提交
1769
    g_autoptr(virSEVCapability) tmp = NULL;
1770

1771
    if (VIR_ALLOC(tmp) < 0)
1772 1773
        return -1;

1774 1775 1776
    tmp->pdh = g_strdup(src->pdh);
    tmp->cert_chain = g_strdup(src->cert_chain);

1777 1778 1779
    tmp->cbitpos = src->cbitpos;
    tmp->reduced_phys_bits = src->reduced_phys_bits;

1780
    *dst = g_steal_pointer(&tmp);
1781 1782 1783 1784
    return 0;
}


1785
static void
1786 1787
virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccelPtr dst,
                                 virQEMUCapsAccelPtr src)
1788 1789 1790 1791 1792 1793 1794 1795 1796
{
    size_t i;

    dst->machineTypes = g_new0(virQEMUCapsMachineType, src->nmachineTypes);

    dst->nmachineTypes = src->nmachineTypes;
    for (i = 0; i < src->nmachineTypes; i++) {
        dst->machineTypes[i].name = g_strdup(src->machineTypes[i].name);
        dst->machineTypes[i].alias = g_strdup(src->machineTypes[i].alias);
J
Jiri Denemark 已提交
1797
        dst->machineTypes[i].defaultCPU = g_strdup(src->machineTypes[i].defaultCPU);
1798 1799 1800 1801 1802 1803 1804
        dst->machineTypes[i].maxCpus = src->machineTypes[i].maxCpus;
        dst->machineTypes[i].hotplugCpus = src->machineTypes[i].hotplugCpus;
        dst->machineTypes[i].qemuDefault = src->machineTypes[i].qemuDefault;
    }
}


1805 1806 1807 1808
static int
virQEMUCapsAccelCopy(virQEMUCapsAccelPtr dst,
                     virQEMUCapsAccelPtr src)
{
1809 1810
    virQEMUCapsAccelCopyMachineTypes(dst, src);

1811 1812 1813 1814 1815 1816 1817 1818 1819
    if (virQEMUCapsHostCPUDataCopy(&dst->hostCPU, &src->hostCPU) < 0)
        return -1;

    dst->cpuModels = qemuMonitorCPUDefsCopy(src->cpuModels);

    return 0;
}


1820
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
1821
{
1822
    virQEMUCapsPtr ret = virQEMUCapsNewBinary(qemuCaps->binary);
1823 1824 1825 1826 1827
    size_t i;

    if (!ret)
        return NULL;

1828
    ret->invalidation = qemuCaps->invalidation;
1829
    ret->kvmSupportsNesting = qemuCaps->kvmSupportsNesting;
1830

1831 1832
    ret->ctime = qemuCaps->ctime;

1833
    virBitmapCopy(ret->flags, qemuCaps->flags);
1834

1835 1836
    ret->version = qemuCaps->version;
    ret->kvmVersion = qemuCaps->kvmVersion;
1837
    ret->microcodeVersion = qemuCaps->microcodeVersion;
1838

1839 1840
    ret->package = g_strdup(qemuCaps->package);
    ret->kernelVersion = g_strdup(qemuCaps->kernelVersion);
1841

1842
    ret->arch = qemuCaps->arch;
1843

1844 1845
    if (virQEMUCapsAccelCopy(&ret->kvm, &qemuCaps->kvm) < 0 ||
        virQEMUCapsAccelCopy(&ret->tcg, &qemuCaps->tcg) < 0)
1846 1847
        goto error;

1848 1849 1850 1851 1852 1853
    if (VIR_ALLOC_N(ret->gicCapabilities, qemuCaps->ngicCapabilities) < 0)
        goto error;
    ret->ngicCapabilities = qemuCaps->ngicCapabilities;
    for (i = 0; i < qemuCaps->ngicCapabilities; i++)
        ret->gicCapabilities[i] = qemuCaps->gicCapabilities[i];

1854 1855 1856 1857 1858
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST) &&
        virQEMUCapsSEVInfoCopy(&ret->sevCapabilities,
                               qemuCaps->sevCapabilities) < 0)
        goto error;

1859 1860
    return ret;

1861
 error:
1862 1863 1864 1865 1866
    virObjectUnref(ret);
    return NULL;
}


1867 1868 1869
static void
virQEMUCapsAccelClear(virQEMUCapsAccelPtr caps)
{
1870 1871 1872 1873 1874
    size_t i;

    for (i = 0; i < caps->nmachineTypes; i++) {
        VIR_FREE(caps->machineTypes[i].name);
        VIR_FREE(caps->machineTypes[i].alias);
J
Jiri Denemark 已提交
1875
        VIR_FREE(caps->machineTypes[i].defaultCPU);
1876 1877 1878
    }
    VIR_FREE(caps->machineTypes);

1879
    virQEMUCapsHostCPUDataClear(&caps->hostCPU);
1880
    qemuMonitorCPUDefsFree(caps->cpuModels);
1881 1882 1883
}


1884
void virQEMUCapsDispose(void *obj)
1885
{
1886
    virQEMUCapsPtr qemuCaps = obj;
1887

1888
    virObjectUnref(qemuCaps->domCapsCache);
1889
    virBitmapFree(qemuCaps->flags);
1890

1891
    VIR_FREE(qemuCaps->package);
1892
    VIR_FREE(qemuCaps->kernelVersion);
1893
    VIR_FREE(qemuCaps->binary);
A
Andrea Bolognani 已提交
1894 1895

    VIR_FREE(qemuCaps->gicCapabilities);
1896

1897 1898
    virSEVCapabilitiesFree(qemuCaps->sevCapabilities);

1899 1900
    virQEMUCapsAccelClear(&qemuCaps->kvm);
    virQEMUCapsAccelClear(&qemuCaps->tcg);
1901 1902
}

1903
void
1904
virQEMUCapsSet(virQEMUCapsPtr qemuCaps,
1905
               virQEMUCapsFlags flag)
1906
{
1907
    ignore_value(virBitmapSetBit(qemuCaps->flags, flag));
1908 1909 1910
}


C
Cole Robinson 已提交
1911 1912 1913 1914
void
virQEMUCapsSetList(virQEMUCapsPtr qemuCaps, ...)
{
    va_list list;
1915
    int flag;
C
Cole Robinson 已提交
1916 1917

    va_start(list, qemuCaps);
1918 1919
    while ((flag = va_arg(list, int)) < QEMU_CAPS_LAST)
        virQEMUCapsSet(qemuCaps, flag);
1920
    va_end(list);
1921 1922 1923 1924
}


void
1925
virQEMUCapsClear(virQEMUCapsPtr qemuCaps,
1926
                 virQEMUCapsFlags flag)
1927
{
1928
    ignore_value(virBitmapClearBit(qemuCaps->flags, flag));
1929 1930 1931
}


1932
char *virQEMUCapsFlagsString(virQEMUCapsPtr qemuCaps)
1933
{
1934
    return virBitmapToString(qemuCaps->flags, true, false);
1935 1936 1937 1938
}


bool
1939
virQEMUCapsGet(virQEMUCapsPtr qemuCaps,
1940
               virQEMUCapsFlags flag)
1941
{
J
Ján Tomko 已提交
1942
    return qemuCaps && virBitmapIsBitSet(qemuCaps->flags, flag);
1943
}
1944 1945


D
Daniel P. Berrange 已提交
1946
bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps,
1947
                               const virDomainDef *def)
D
Daniel P. Berrange 已提交
1948
{
1949 1950
    /* x86_64 and i686 support PCI-multibus on all machine types
     * since forever */
1951
    if (ARCH_IS_X86(def->os.arch))
D
Daniel P. Berrange 已提交
1952 1953 1954
        return true;

    if (def->os.arch == VIR_ARCH_PPC ||
1955
        ARCH_IS_PPC64(def->os.arch)) {
D
Daniel P. Berrange 已提交
1956 1957 1958 1959 1960
        /*
         * Usage of pci.0 naming:
         *
         *    ref405ep: no pci
         *       taihu: no pci
1961
         *      bamboo: 1.1.0 (<= 1.5.0, so basically forever)
D
Daniel P. Berrange 已提交
1962 1963
         *       mac99: 2.0.0
         *     g3beige: 2.0.0
1964
         *        prep: 1.4.0 (<= 1.5.0, so basically forever)
D
Daniel P. Berrange 已提交
1965 1966 1967 1968 1969 1970
         *     pseries: 2.0.0
         *   mpc8544ds: forever
         * virtex-m507: no pci
         *     ppce500: 1.6.0
         */

1971 1972 1973 1974 1975 1976 1977 1978
        /* We do not store the qemu version in domain status XML.
         * Hope the user is using a QEMU new enough to use 'pci.0',
         * otherwise the results of this function will be wrong
         * for domains already running at the time of daemon
         * restart */
        if (qemuCaps->version == 0)
            return true;

D
Daniel P. Berrange 已提交
1979 1980 1981 1982 1983 1984 1985
        if (qemuCaps->version >= 2000000)
            return true;

        if (qemuCaps->version >= 1006000 &&
            STREQ(def->os.machine, "ppce500"))
            return true;

1986 1987 1988
        if (STREQ(def->os.machine, "bamboo") ||
            STREQ(def->os.machine, "mpc8544ds") ||
            STREQ(def->os.machine, "prep")) {
D
Daniel P. Berrange 已提交
1989
            return true;
1990
        }
D
Daniel P. Berrange 已提交
1991 1992 1993 1994

        return false;
    }

1995 1996 1997 1998
    /* S390 supports PCI-multibus. */
    if (ARCH_IS_S390(def->os.arch))
        return true;

1999 2000 2001 2002
    /* If the virt machine, both on ARM and RISC-V, supports PCI,
     * then it also supports multibus */
    if (qemuDomainIsARMVirt(def) ||
        qemuDomainIsRISCVVirt(def)) {
2003
        return true;
2004
    }
2005

D
Daniel P. Berrange 已提交
2006 2007 2008 2009
    return false;
}


2010
const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps)
2011
{
2012
    return qemuCaps->binary;
2013 2014
}

2015 2016 2017 2018 2019 2020 2021 2022 2023

void
virQEMUCapsSetArch(virQEMUCapsPtr qemuCaps,
                   virArch arch)
{
    qemuCaps->arch = arch;
}


2024
virArch virQEMUCapsGetArch(virQEMUCapsPtr qemuCaps)
2025
{
2026
    return qemuCaps->arch;
2027 2028 2029
}


2030
unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps)
2031
{
2032
    return qemuCaps->version;
2033 2034 2035
}


2036
unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps)
2037
{
2038
    return qemuCaps->kvmVersion;
2039 2040 2041
}


2042 2043 2044 2045 2046 2047
const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps)
{
    return qemuCaps->package;
}


2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082
struct virQEMUCapsSearchDomcapsData {
    const char *path;
    const char *machine;
    virArch arch;
    virDomainVirtType virttype;
};


static int
virQEMUCapsSearchDomcaps(const void *payload,
                         const void *name G_GNUC_UNUSED,
                         const void *opaque)
{
    virDomainCapsPtr domCaps = (virDomainCapsPtr) payload;
    struct virQEMUCapsSearchDomcapsData *data = (struct virQEMUCapsSearchDomcapsData *) opaque;

    if (STREQ_NULLABLE(data->path, domCaps->path) &&
        STREQ_NULLABLE(data->machine, domCaps->machine) &&
        data->arch == domCaps->arch &&
        data->virttype == domCaps->virttype)
        return 1;

    return 0;
}


virDomainCapsPtr
virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps,
                              const char *machine,
                              virArch arch,
                              virDomainVirtType virttype,
                              virArch hostarch,
                              bool privileged,
                              virFirmwarePtr *firmwares,
                              size_t nfirmwares)
2083
{
2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123
    virQEMUDomainCapsCachePtr cache = qemuCaps->domCapsCache;
    virDomainCapsPtr domCaps = NULL;
    const char *path = virQEMUCapsGetBinary(qemuCaps);
    struct virQEMUCapsSearchDomcapsData data = {
        .path = path,
        .machine = machine,
        .arch = arch,
        .virttype = virttype,
    };

    virObjectLock(cache);

    domCaps = virHashSearch(cache->cache, virQEMUCapsSearchDomcaps, &data, NULL);

    if (!domCaps) {
        g_autoptr(virDomainCaps) tempDomCaps = NULL;
        g_autofree char *key = NULL;

        /* hash miss, build new domcaps */
        if (!(tempDomCaps = virDomainCapsNew(path, machine,
                                             arch, virttype)))
            goto cleanup;

        if (virQEMUCapsFillDomainCaps(qemuCaps, hostarch, tempDomCaps,
                                      privileged, firmwares, nfirmwares) < 0)
            goto cleanup;

        key = g_strdup_printf("%d:%d:%s:%s", arch, virttype,
                              NULLSTR(machine), path);

        if (virHashAddEntry(cache->cache, key, tempDomCaps) < 0)
            goto cleanup;

        domCaps = g_steal_pointer(&tempDomCaps);
    }

    virObjectRef(domCaps);
 cleanup:
    virObjectUnlock(cache);
    return domCaps;
2124 2125 2126
}


2127 2128
int
virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
2129
                             virDomainVirtType type,
2130
                             const char **name,
2131 2132
                             size_t count,
                             virDomainCapsCPUUsable usable)
2133
{
2134
    size_t i;
2135
    size_t start;
2136 2137
    virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, type);
    qemuMonitorCPUDefsPtr defs = accel->cpuModels;
2138 2139 2140

    if (defs) {
        start = defs->ncpus;
2141

2142 2143 2144 2145 2146 2147
        if (VIR_EXPAND_N(defs->cpus, defs->ncpus, count) < 0)
            return -1;
    } else {
        start = 0;

        if (!(defs = qemuMonitorCPUDefsNew(count)))
2148 2149
            return -1;

2150
        accel->cpuModels = defs;
2151
    }
2152 2153

    for (i = 0; i < count; i++) {
2154 2155 2156 2157
        qemuMonitorCPUDefInfoPtr cpu = defs->cpus + start + i;

        cpu->usable = usable;
        cpu->name = g_strdup(name[i]);
2158
    }
2159

2160 2161 2162 2163
    return 0;
}


2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192
static virDomainCapsCPUModelsPtr
virQEMUCapsCPUDefsToModels(qemuMonitorCPUDefsPtr defs,
                           const char **modelWhitelist,
                           const char **modelBlacklist)
{
    g_autoptr(virDomainCapsCPUModels) cpuModels = NULL;
    size_t i;

    if (!(cpuModels = virDomainCapsCPUModelsNew(defs->ncpus)))
        return NULL;

    for (i = 0; i < defs->ncpus; i++) {
        qemuMonitorCPUDefInfoPtr cpu = defs->cpus + i;

        if (modelWhitelist && !virStringListHasString(modelWhitelist, cpu->name))
            continue;

        if (modelBlacklist && virStringListHasString(modelBlacklist, cpu->name))
            continue;

        if (virDomainCapsCPUModelsAdd(cpuModels, cpu->name, cpu->usable,
                                      cpu->blockers) < 0)
            return NULL;
    }

    return g_steal_pointer(&cpuModels);
}


2193
virDomainCapsCPUModelsPtr
2194 2195 2196 2197
virQEMUCapsGetCPUModels(virQEMUCapsPtr qemuCaps,
                        virDomainVirtType type,
                        const char **modelWhitelist,
                        const char **modelBlacklist)
2198
{
2199
    qemuMonitorCPUDefsPtr defs;
2200

2201
    if (!(defs = virQEMUCapsGetAccel(qemuCaps, type)->cpuModels))
2202 2203
        return NULL;

2204
    return virQEMUCapsCPUDefsToModels(defs, modelWhitelist, modelBlacklist);
2205 2206 2207
}


2208
virCPUDefPtr
2209
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
2210 2211
                        virDomainVirtType type,
                        virQEMUCapsHostCPUType cpuType)
2212
{
2213
    virQEMUCapsHostCPUDataPtr cpuData;
2214

2215
    cpuData = &virQEMUCapsGetAccel(qemuCaps, type)->hostCPU;
2216 2217 2218
    switch (cpuType) {
    case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
        return cpuData->reported;
2219 2220 2221

    case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
        return cpuData->migratable;
2222 2223 2224 2225 2226

    case VIR_QEMU_CAPS_HOST_CPU_FULL:
        /* 'full' is non-NULL only if we have data from both QEMU and
         * virCPUGetHost */
        return cpuData->full ? cpuData->full : cpuData->reported;
2227 2228 2229
    }

    return NULL;
2230 2231 2232
}


2233 2234 2235
static void
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
                        virDomainVirtType type,
2236
                        virCPUDefPtr reported,
2237 2238
                        virCPUDefPtr migratable,
                        virCPUDefPtr full)
2239
{
2240
    virQEMUCapsHostCPUDataPtr cpuData;
2241

2242
    cpuData = &virQEMUCapsGetAccel(qemuCaps, type)->hostCPU;
2243 2244
    cpuData->reported = reported;
    cpuData->migratable = migratable;
2245
    cpuData->full = full;
2246 2247 2248
}


2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285
bool
virQEMUCapsIsArchSupported(virQEMUCapsPtr qemuCaps,
                           virArch arch)
{
    if (arch == qemuCaps->arch)
        return true;

    if (qemuCaps->arch == VIR_ARCH_X86_64 && arch == VIR_ARCH_I686)
        return true;

    if (qemuCaps->arch == VIR_ARCH_AARCH64 && arch == VIR_ARCH_ARMV7L)
        return true;

    if (qemuCaps->arch == VIR_ARCH_ARMV7L && arch == VIR_ARCH_ARMV6L)
        return true;

    if (qemuCaps->arch == VIR_ARCH_PPC64 && arch == VIR_ARCH_PPC64LE)
        return true;

    return false;
}


bool
virQEMUCapsIsVirtTypeSupported(virQEMUCapsPtr qemuCaps,
                               virDomainVirtType virtType)
{
    if (virtType == VIR_DOMAIN_VIRT_QEMU)
        return true;

    if (virtType == VIR_DOMAIN_VIRT_KVM &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
        return true;

    return false;
}

2286 2287 2288 2289 2290 2291 2292
const char *s390HostPassthroughOnlyMachines[] = {
    "s390-ccw-virtio-2.4",
    "s390-ccw-virtio-2.5",
    "s390-ccw-virtio-2.6",
    "s390-ccw-virtio-2.7",
    NULL
};
2293

2294 2295
bool
virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
2296
                              virArch hostarch,
2297
                              virDomainVirtType type,
2298
                              virCPUMode mode,
2299
                              const char *machineType)
2300
{
2301
    qemuMonitorCPUDefsPtr cpus;
2302

2303 2304 2305 2306 2307 2308 2309 2310 2311 2312
    /* CPU models (except for "host") are not supported by QEMU for on s390
     * KVM domains with old machine types regardless on QEMU version. */
    if (ARCH_IS_S390(qemuCaps->arch) &&
        type == VIR_DOMAIN_VIRT_KVM &&
        mode != VIR_CPU_MODE_HOST_PASSTHROUGH &&
        machineType &&
        g_strv_contains(s390HostPassthroughOnlyMachines, machineType)) {
        return false;
    }

2313 2314 2315
    switch (mode) {
    case VIR_CPU_MODE_HOST_PASSTHROUGH:
        return type == VIR_DOMAIN_VIRT_KVM &&
2316
               virQEMUCapsGuestIsNative(hostarch, qemuCaps->arch);
2317 2318

    case VIR_CPU_MODE_HOST_MODEL:
2319 2320
        return !!virQEMUCapsGetHostModel(qemuCaps, type,
                                         VIR_QEMU_CAPS_HOST_CPU_REPORTED);
2321 2322

    case VIR_CPU_MODE_CUSTOM:
2323
        cpus = virQEMUCapsGetAccel(qemuCaps, type)->cpuModels;
2324
        return cpus && cpus->ncpus > 0;
2325 2326 2327 2328 2329 2330 2331 2332 2333

    case VIR_CPU_MODE_LAST:
        break;
    }

    return false;
}


2334 2335 2336 2337 2338 2339 2340 2341
/**
 * virQEMUCapsGetCanonicalMachine:
 * @qemuCaps: qemu capabilities object
 * @name: machine name
 *
 * Resolves aliased machine names to the actual machine name. If qemuCaps isn't
 * present @name is returned.
 */
2342 2343
const char *
virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps,
2344
                               virDomainVirtType virtType,
2345
                               const char *name)
2346
{
2347
    virQEMUCapsAccelPtr accel;
2348 2349
    size_t i;

2350 2351
    if (!name || !qemuCaps)
        return name;
2352

2353 2354 2355 2356
    accel = virQEMUCapsGetAccel(qemuCaps, virtType);

    for (i = 0; i < accel->nmachineTypes; i++) {
        if (!accel->machineTypes[i].alias)
2357
            continue;
2358 2359
        if (STREQ(accel->machineTypes[i].alias, name))
            return accel->machineTypes[i].name;
2360 2361 2362 2363
    }

    return name;
}
2364 2365


2366 2367
int
virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps,
2368
                             virDomainVirtType virtType,
2369
                             const char *name)
2370
{
2371
    virQEMUCapsAccelPtr accel;
2372 2373 2374 2375 2376
    size_t i;

    if (!name)
        return 0;

2377 2378 2379 2380
    accel = virQEMUCapsGetAccel(qemuCaps, virtType);

    for (i = 0; i < accel->nmachineTypes; i++) {
        if (!accel->machineTypes[i].maxCpus)
2381
            continue;
2382 2383
        if (STREQ(accel->machineTypes[i].name, name))
            return accel->machineTypes[i].maxCpus;
2384 2385 2386 2387 2388 2389
    }

    return 0;
}


2390 2391
bool
virQEMUCapsGetMachineHotplugCpus(virQEMUCapsPtr qemuCaps,
2392
                                 virDomainVirtType virtType,
2393
                                 const char *name)
2394
{
2395
    virQEMUCapsAccelPtr accel;
2396 2397
    size_t i;

2398 2399 2400 2401 2402
    accel = virQEMUCapsGetAccel(qemuCaps, virtType);

    for (i = 0; i < accel->nmachineTypes; i++) {
        if (STREQ_NULLABLE(accel->machineTypes[i].name, name))
            return accel->machineTypes[i].hotplugCpus;
2403 2404 2405 2406 2407 2408
    }

    return false;
}


2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440
const char *
virQEMUCapsGetMachineDefaultCPU(virQEMUCapsPtr qemuCaps,
                                const char *name,
                                virDomainVirtType type)
{
    virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, type);
    qemuMonitorCPUDefsPtr defs = accel->cpuModels;
    const char *cpuType = NULL;
    size_t i;

    if (!name || !defs)
        return NULL;

    for (i = 0; i < accel->nmachineTypes; i++) {
        if (STREQ(accel->machineTypes[i].name, name)) {
            cpuType = accel->machineTypes[i].defaultCPU;
            break;
        }
    }

    if (!cpuType)
        return NULL;

    for (i = 0; i < defs->ncpus; i++) {
        if (STREQ_NULLABLE(defs->cpus[i].type, cpuType))
            return defs->cpus[i].name;
    }

    return NULL;
}


2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464
/**
 * virQEMUCapsSetGICCapabilities:
 * @qemuCaps: QEMU capabilities
 * @capabilities: GIC capabilities
 * @ncapabilities: number of GIC capabilities
 *
 * Set the GIC capabilities for @qemuCaps.
 *
 * The ownership of @capabilities is taken away from the caller, ie. this
 * function will not make a copy of @capabilities, so releasing that memory
 * after it's been called is a bug.
 */
void
virQEMUCapsSetGICCapabilities(virQEMUCapsPtr qemuCaps,
                              virGICCapability *capabilities,
                              size_t ncapabilities)
{
    VIR_FREE(qemuCaps->gicCapabilities);

    qemuCaps->gicCapabilities = capabilities;
    qemuCaps->ngicCapabilities = ncapabilities;
}


2465 2466 2467 2468 2469 2470 2471
virSEVCapabilityPtr
virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps)
{
    return qemuCaps->sevCapabilities;
}


2472
static int
2473 2474
virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps,
                            qemuMonitorPtr mon)
2475 2476 2477 2478 2479 2480 2481
{
    char **commands = NULL;
    int ncommands;

    if ((ncommands = qemuMonitorGetCommands(mon, &commands)) < 0)
        return -1;

2482
    virQEMUCapsProcessStringFlags(qemuCaps,
2483
                                  G_N_ELEMENTS(virQEMUCapsCommands),
2484 2485
                                  virQEMUCapsCommands,
                                  ncommands, commands);
2486
    virStringListFreeCount(commands, ncommands);
2487

2488 2489 2490
    /* Probe for active commit of qemu 2.1. We don't need to query directly
     * if we have QMP schema support */
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_QMP_SCHEMA) &&
2491 2492 2493
        qemuMonitorSupportsActiveCommit(mon))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_ACTIVE_COMMIT);

2494 2495 2496 2497 2498
    return 0;
}


static int
2499 2500
virQEMUCapsProbeQMPEvents(virQEMUCapsPtr qemuCaps,
                          qemuMonitorPtr mon)
2501 2502 2503 2504
{
    char **events = NULL;
    int nevents;

2505
    /* we can probe events also from the QMP schema so we can skip this here */
2506
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_QMP_SCHEMA))
2507
        return 0;
2508 2509 2510

    if ((nevents = qemuMonitorGetEvents(mon, &events)) < 0)
        return -1;
2511

2512
    virQEMUCapsProcessStringFlags(qemuCaps,
2513
                                  G_N_ELEMENTS(virQEMUCapsEvents),
2514 2515
                                  virQEMUCapsEvents,
                                  nevents, events);
2516
    virStringListFreeCount(events, nevents);
2517 2518 2519 2520

    return 0;
}

2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549
static int
virQEMUCapsProbeQMPGenericProps(virQEMUCapsPtr qemuCaps,
                                qemuMonitorPtr mon,
                                virQEMUCapsObjectTypeProps *props,
                                size_t nprops,
                                virQEMUCapsObjectTypePropsCB propsGetCB)
{
    int nvalues;
    char **values;
    size_t i;

    for (i = 0; i < nprops; i++) {
        const char *type = props[i].type;
        int cap = props[i].capsCondition;

        if (cap >= 0 && !virQEMUCapsGet(qemuCaps, cap))
            continue;

        if ((nvalues = propsGetCB(mon, type, &values)) < 0)
            return -1;
        virQEMUCapsProcessStringFlags(qemuCaps,
                                      props[i].nprops,
                                      props[i].props,
                                      nvalues, values);
        virStringListFreeCount(values, nvalues);
    }

    return 0;
}
2550

2551
static int
2552
virQEMUCapsProbeQMPDevices(virQEMUCapsPtr qemuCaps,
2553
                           qemuMonitorPtr mon)
2554 2555 2556 2557 2558 2559
{
    int nvalues;
    char **values;

    if ((nvalues = qemuMonitorGetObjectTypes(mon, &values)) < 0)
        return -1;
2560
    virQEMUCapsProcessStringFlags(qemuCaps,
2561
                                  G_N_ELEMENTS(virQEMUCapsObjectTypes),
2562 2563
                                  virQEMUCapsObjectTypes,
                                  nvalues, values);
2564
    virStringListFreeCount(values, nvalues);
2565

2566 2567 2568
    if (virQEMUCapsProbeQMPGenericProps(qemuCaps,
                                        mon,
                                        virQEMUCapsDeviceProps,
2569
                                        G_N_ELEMENTS(virQEMUCapsDeviceProps),
2570 2571
                                        qemuMonitorGetDeviceProps) < 0)
        return -1;
2572

2573 2574 2575 2576
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QOM_LIST_PROPERTIES) &&
        virQEMUCapsProbeQMPGenericProps(qemuCaps,
                                        mon,
                                        virQEMUCapsObjectProps,
2577
                                        G_N_ELEMENTS(virQEMUCapsObjectProps),
2578 2579 2580
                                        qemuMonitorGetObjectProps) < 0)
        return -1;

2581 2582 2583 2584
    return 0;
}


2585 2586 2587 2588 2589 2590 2591 2592 2593 2594
/* Historically QEMU x86 targets defaulted to 'pc' machine type but
 * in future x86_64 might switch to 'q35'. Such a change is considered
 * an ABI break from libvirt's POV. Other QEMU targets may not declare
 * a default machine at all, causing libvirt to use the first reported
 * machine in the list.
 *
 * Here we record a preferred default machine for all arches, so
 * that we're not vulnerable to changes in QEMU defaults or machine
 * list ordering.
 */
2595
static const char *preferredMachines[] =
2596
{
2597 2598
    NULL, /* VIR_ARCH_NONE (not a real arch :) */
    "clipper", /* VIR_ARCH_ALPHA */
S
Stefan Schallenberg 已提交
2599
    "integratorcp", /* VIR_ARCH_ARMV6L */
2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626
    "integratorcp", /* VIR_ARCH_ARMV7L */
    "integratorcp", /* VIR_ARCH_ARMV7B */

    "integratorcp", /* VIR_ARCH_AARCH64 */
    "axis-dev88", /* VIR_ARCH_CRIS */
    "pc", /* VIR_ARCH_I686 */
    NULL, /* VIR_ARCH_ITANIUM (doesn't exist in QEMU any more) */
    "lm32-evr", /* VIR_ARCH_LM32 */

    "mcf5208evb", /* VIR_ARCH_M68K */
    "petalogix-s3adsp1800", /* VIR_ARCH_MICROBLAZE */
    "petalogix-s3adsp1800", /* VIR_ARCH_MICROBLAZEEL */
    "malta", /* VIR_ARCH_MIPS */
    "malta", /* VIR_ARCH_MIPSEL */

    "malta", /* VIR_ARCH_MIPS64 */
    "malta", /* VIR_ARCH_MIPS64EL */
    "or1k-sim", /* VIR_ARCH_OR32 */
    NULL, /* VIR_ARCH_PARISC (no QEMU impl) */
    NULL, /* VIR_ARCH_PARISC64 (no QEMU impl) */

    "g3beige", /* VIR_ARCH_PPC */
    "g3beige", /* VIR_ARCH_PPCLE */
    "pseries", /* VIR_ARCH_PPC64 */
    "pseries", /* VIR_ARCH_PPC64LE */
    "bamboo", /* VIR_ARCH_PPCEMB */

L
Lubomir Rintel 已提交
2627 2628
    "spike_v1.10", /* VIR_ARCH_RISCV32 */
    "spike_v1.10", /* VIR_ARCH_RISCV64 */
2629 2630 2631
    NULL, /* VIR_ARCH_S390 (no QEMU impl) */
    "s390-ccw-virtio", /* VIR_ARCH_S390X */
    "shix", /* VIR_ARCH_SH4 */
L
Lubomir Rintel 已提交
2632

2633 2634 2635 2636 2637
    "shix", /* VIR_ARCH_SH4EB */
    "SS-5", /* VIR_ARCH_SPARC */
    "sun4u", /* VIR_ARCH_SPARC64 */
    "puv3", /* VIR_ARCH_UNICORE32 */
    "pc", /* VIR_ARCH_X86_64 */
L
Lubomir Rintel 已提交
2638

2639 2640
    "sim", /* VIR_ARCH_XTENSA */
    "sim", /* VIR_ARCH_XTENSAEB */
2641
};
2642
G_STATIC_ASSERT(G_N_ELEMENTS(preferredMachines) == VIR_ARCH_LAST);
2643 2644


2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673
void
virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps,
                      virDomainVirtType virtType,
                      const char *name,
                      const char *alias,
                      const char *defaultCPU,
                      int maxCpus,
                      bool hotplugCpus,
                      bool isDefault)
{
    virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType);
    virQEMUCapsMachineTypePtr mach;

    accel->machineTypes = g_renew(virQEMUCapsMachineType,
                                  accel->machineTypes,
                                  ++accel->nmachineTypes);

    mach = &(accel->machineTypes[accel->nmachineTypes - 1]);

    mach->alias = g_strdup(alias);
    mach->name = g_strdup(name);
    mach->defaultCPU = g_strdup(defaultCPU);

    mach->maxCpus = maxCpus;
    mach->hotplugCpus = hotplugCpus;

    mach->qemuDefault = isDefault;
}

2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689
/**
 * virQEMUCapsHasMachines:
 * @qemuCaps: qemu capabilities object
 *
 * Returns true if @qemuCaps has at least one machine type defined. This is
 * called by the test suite to figure out whether to populate fake machine types
 * into the list.
 */
bool
virQEMUCapsHasMachines(virQEMUCapsPtr qemuCaps)
{

    return !!qemuCaps->kvm.nmachineTypes || !!qemuCaps->tcg.nmachineTypes;
}


2690
static int
2691
virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps,
2692
                                virDomainVirtType virtType,
2693
                                qemuMonitorPtr mon)
2694 2695 2696 2697
{
    qemuMonitorMachineInfoPtr *machines = NULL;
    int nmachines = 0;
    size_t i;
2698 2699 2700
    ssize_t defIdx = -1;
    ssize_t preferredIdx = -1;
    const char *preferredMachine = preferredMachines[qemuCaps->arch];
2701
    virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType);
2702 2703

    if ((nmachines = qemuMonitorGetMachines(mon, &machines)) < 0)
2704
        return -1;
2705

2706
    for (i = 0; i < nmachines; i++) {
2707 2708
        if (STREQ(machines[i]->name, "none"))
            continue;
2709

2710 2711 2712 2713 2714 2715 2716 2717
        virQEMUCapsAddMachine(qemuCaps,
                              virtType,
                              machines[i]->name,
                              machines[i]->alias,
                              machines[i]->defaultCPU,
                              machines[i]->maxCpus,
                              machines[i]->hotplugCpus,
                              machines[i]->isDefault);
2718

2719
        if (preferredMachine &&
2720 2721
            (STREQ_NULLABLE(machines[i]->alias, preferredMachine) ||
             STREQ(machines[i]->name, preferredMachine))) {
2722
            preferredIdx = accel->nmachineTypes - 1;
2723 2724
        }

2725
        if (machines[i]->isDefault)
2726
            defIdx = accel->nmachineTypes - 1;
2727
    }
2728

2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740
    /*
     * We'll prefer to use our own historical default machine
     * to avoid mgmt apps seeing semantics changes when QEMU
     * alters its defaults.
     *
     * Our preferred machine might have been compiled out of
     * QEMU at build time though, so we still fallback to honouring
     * QEMU's reported default in that case
     */
    if (preferredIdx == -1)
        preferredIdx = defIdx;
    if (preferredIdx != -1)
2741
        virQEMUCapsSetDefaultMachine(accel, preferredIdx);
2742

2743
    for (i = 0; i < nmachines; i++)
2744 2745
        qemuMonitorMachineInfoFree(machines[i]);
    VIR_FREE(machines);
2746
    return 0;
2747 2748 2749
}


2750
bool
2751
virQEMUCapsIsMachineSupported(virQEMUCapsPtr qemuCaps,
2752
                              virDomainVirtType virtType,
2753 2754
                              const char *canonical_machine)
{
2755
    virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType);
2756 2757
    size_t i;

2758 2759
    for (i = 0; i < accel->nmachineTypes; i++) {
        if (STREQ(canonical_machine, accel->machineTypes[i].name))
2760 2761 2762 2763 2764 2765
            return true;
    }
    return false;
}


2766 2767
static int
virQEMUCapsProbeQMPMachineProps(virQEMUCapsPtr qemuCaps,
2768
                                virDomainVirtType virtType,
2769 2770 2771 2772 2773 2774 2775 2776 2777
                                qemuMonitorPtr mon)
{
    char **values;
    int nvalues;
    size_t i;

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QOM_LIST_PROPERTIES))
        return 0;

2778
    for (i = 0; i < G_N_ELEMENTS(virQEMUCapsMachineProps); i++) {
2779
        virQEMUCapsObjectTypeProps props = virQEMUCapsMachineProps[i];
2780
        const char *canon = virQEMUCapsGetCanonicalMachine(qemuCaps, virtType, props.type);
2781
        g_autofree char *type = NULL;
2782

2783
        if (!virQEMUCapsIsMachineSupported(qemuCaps, virtType, canon))
2784 2785
            continue;

2786 2787
        /* The QOM type for machine types is the machine type name
         * followed by the -machine suffix */
2788
        type = g_strdup_printf("%s-machine", canon);
2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804

        if ((nvalues = qemuMonitorGetObjectProps(mon, type, &values)) < 0)
            return -1;

        virQEMUCapsProcessStringFlags(qemuCaps,
                                      props.nprops,
                                      props.props,
                                      nvalues, values);

        virStringListFreeCount(values, nvalues);
    }

    return 0;
}


2805 2806 2807 2808
static int
virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
                               virArch arch,
                               qemuMonitorCPUDefsPtr *cpuDefs)
2809
{
2810
    g_autoptr(qemuMonitorCPUDefs) defs = NULL;
2811
    size_t i;
2812

2813
    *cpuDefs = NULL;
2814

2815
    if (qemuMonitorGetCPUDefinitions(mon, &defs) < 0)
2816 2817
        return -1;

2818 2819
    if (!defs)
        return 0;
2820

2821 2822
    /* QEMU 2.11 for Power renamed all CPU models to lower case, we need to
     * translate them back to libvirt's upper case model names. */
2823
    if (ARCH_IS_PPC64(arch)) {
2824 2825 2826 2827
        VIR_AUTOSTRINGLIST libvirtModels = NULL;
        char **name;

        if (virCPUGetModels(arch, &libvirtModels) < 0)
2828
            return -1;
2829 2830

        for (name = libvirtModels; name && *name; name++) {
2831
            for (i = 0; i < defs->ncpus; i++) {
2832
                if (STRCASENEQ(defs->cpus[i].name, *name))
2833 2834
                    continue;

2835 2836
                VIR_FREE(defs->cpus[i].name);
                defs->cpus[i].name = g_strdup(*name);
2837 2838 2839 2840
            }
        }
    }

2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858
    *cpuDefs = g_steal_pointer(&defs);
    return 0;
}


int
virQEMUCapsFetchCPUModels(qemuMonitorPtr mon,
                          virArch arch,
                          virDomainCapsCPUModelsPtr *cpuModels)
{
    g_autoptr(qemuMonitorCPUDefs) defs = NULL;

    *cpuModels = NULL;

    if (virQEMUCapsFetchCPUDefinitions(mon, arch, &defs) < 0)
        return -1;

    if (defs && !(*cpuModels = virQEMUCapsCPUDefsToModels(defs, NULL, NULL)))
2859
        return -1;
2860

2861
    return 0;
2862 2863
}

2864

2865
static int
2866
virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps,
2867 2868
                                  virQEMUCapsAccelPtr accel,
                                  qemuMonitorPtr mon)
2869 2870 2871 2872
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_DEFINITIONS))
        return 0;

2873
    if (virQEMUCapsFetchCPUDefinitions(mon, qemuCaps->arch, &accel->cpuModels) < 0)
2874 2875 2876 2877 2878 2879
        return -1;

    return 0;
}


2880 2881 2882 2883
int
virQEMUCapsProbeCPUDefinitionsTest(virQEMUCapsPtr qemuCaps,
                                   qemuMonitorPtr mon)
{
2884
    return virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, &qemuCaps->kvm, mon);
2885 2886 2887
}


2888 2889
static int
virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
2890
                           virQEMUCapsAccelPtr accel,
2891
                           qemuMonitorPtr mon,
2892
                           virDomainVirtType virtType)
2893
{
2894
    const char *model = virtType == VIR_DOMAIN_VIRT_KVM ? "host" : "max";
2895
    qemuMonitorCPUModelInfoPtr modelInfo = NULL;
2896 2897
    qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
    virHashTablePtr hash = NULL;
2898
    virCPUDefPtr cpu;
2899
    qemuMonitorCPUModelExpansionType type;
2900
    bool fail_no_props = true;
2901
    int ret = -1;
2902 2903

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
2904 2905
        return 0;

2906
    cpu = virCPUDefNew();
2907

2908 2909
    cpu->model = g_strdup(model);

2910 2911
    /* Some x86_64 features defined in cpu_map.xml use spelling which differ
     * from the one preferred by QEMU. Static expansion would give us only the
2912 2913 2914 2915
     * preferred spelling. With new QEMU we always use the QEMU's canonical
     * names of all features and translate between them and our names. But for
     * older version of QEMU we need to do a full expansion on the result of
     * the initial static expansion to get all variants of feature names.
2916
     */
2917
    if (ARCH_IS_X86(qemuCaps->arch) &&
2918
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CANONICAL_CPU_FEATURES)) {
2919
        type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL;
2920 2921 2922
    } else if (ARCH_IS_ARM(qemuCaps->arch)) {
        type = QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL;
    } else {
2923
        type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
2924
    }
2925

2926 2927 2928 2929 2930 2931
    /* Older s390 models do not report a feature set */
    if (ARCH_IS_S390(qemuCaps->arch))
        fail_no_props = false;

    if (qemuMonitorGetCPUModelExpansion(mon, type, cpu, true, fail_no_props,
                                        &modelInfo) < 0)
2932
        goto cleanup;
2933 2934

    /* Try to check migratability of each feature. */
2935
    if (modelInfo &&
2936
        qemuMonitorGetCPUModelExpansion(mon, type, cpu, false, fail_no_props,
2937
                                        &nonMigratable) < 0)
2938
        goto cleanup;
2939 2940 2941 2942 2943 2944 2945

    if (nonMigratable) {
        qemuMonitorCPUPropertyPtr prop;
        qemuMonitorCPUPropertyPtr nmProp;
        size_t i;

        if (!(hash = virHashCreate(0, NULL)))
2946
            goto cleanup;
2947

2948 2949
        for (i = 0; i < modelInfo->nprops; i++) {
            prop = modelInfo->props + i;
2950
            if (virHashAddEntry(hash, prop->name, prop) < 0)
2951
                goto cleanup;
2952 2953 2954 2955 2956 2957 2958 2959 2960
        }

        for (i = 0; i < nonMigratable->nprops; i++) {
            nmProp = nonMigratable->props + i;
            if (!(prop = virHashLookup(hash, nmProp->name)) ||
                prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN ||
                prop->type != nmProp->type)
                continue;

2961
            if (prop->value.boolean) {
2962
                prop->migratable = VIR_TRISTATE_BOOL_YES;
2963 2964 2965 2966
            } else if (nmProp->value.boolean) {
                prop->value.boolean = true;
                prop->migratable = VIR_TRISTATE_BOOL_NO;
            }
2967 2968
        }

2969
        modelInfo->migratability = true;
2970 2971
    }

2972
    accel->hostCPU.info = g_steal_pointer(&modelInfo);
2973 2974 2975 2976 2977
    ret = 0;

 cleanup:
    virHashFree(hash);
    qemuMonitorCPUModelInfoFree(nonMigratable);
2978
    qemuMonitorCPUModelInfoFree(modelInfo);
2979
    virCPUDefFree(cpu);
2980 2981

    return ret;
2982 2983
}

2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997

/**
 * Get NULL terminated list of features supported by QEMU.
 *
 * Returns -1 on error,
 *          0 on success (@features will be NULL if QEMU does not support this),
 *          1 when @features is filled in, but migratability info is not available.
 */
int
virQEMUCapsGetCPUFeatures(virQEMUCapsPtr qemuCaps,
                          virDomainVirtType virtType,
                          bool migratable,
                          char ***features)
{
2998
    qemuMonitorCPUModelInfoPtr modelInfo;
2999 3000 3001 3002 3003 3004
    char **list;
    size_t i;
    size_t n;
    int ret = -1;

    *features = NULL;
3005
    modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, virtType);
3006

3007
    if (!modelInfo)
3008 3009
        return 0;

3010
    if (VIR_ALLOC_N(list, modelInfo->nprops + 1) < 0)
3011 3012 3013
        return -1;

    n = 0;
3014 3015
    for (i = 0; i < modelInfo->nprops; i++) {
        qemuMonitorCPUPropertyPtr prop = modelInfo->props + i;
3016 3017 3018 3019

        if (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO)
            continue;

3020
        list[n++] = g_strdup(virQEMUCapsCPUFeatureFromQEMU(qemuCaps, prop->name));
3021 3022
    }

3023
    *features = g_steal_pointer(&list);
3024
    if (migratable && !modelInfo->migratability)
3025 3026 3027 3028 3029 3030 3031 3032 3033
        ret = 1;
    else
        ret = 0;

    virStringListFree(list);
    return ret;
}


3034 3035
struct tpmTypeToCaps {
    int type;
3036
    virQEMUCapsFlags caps;
3037 3038 3039 3040 3041 3042 3043
};

static const struct tpmTypeToCaps virQEMUCapsTPMTypesToCaps[] = {
    {
        .type = VIR_DOMAIN_TPM_TYPE_PASSTHROUGH,
        .caps = QEMU_CAPS_DEVICE_TPM_PASSTHROUGH,
    },
3044 3045 3046 3047
    {
        .type = VIR_DOMAIN_TPM_TYPE_EMULATOR,
        .caps = QEMU_CAPS_DEVICE_TPM_EMULATOR,
    },
3048 3049 3050 3051 3052 3053 3054
};

const struct tpmTypeToCaps virQEMUCapsTPMModelsToCaps[] = {
    {
        .type = VIR_DOMAIN_TPM_MODEL_TIS,
        .caps = QEMU_CAPS_DEVICE_TPM_TIS,
    },
3055 3056 3057 3058
    {
        .type = VIR_DOMAIN_TPM_MODEL_CRB,
        .caps = QEMU_CAPS_DEVICE_TPM_CRB,
    },
3059 3060 3061 3062
    {
        .type = VIR_DOMAIN_TPM_MODEL_SPAPR,
        .caps = QEMU_CAPS_DEVICE_TPM_SPAPR,
    },
3063 3064 3065 3066 3067 3068
};

static int
virQEMUCapsProbeQMPTPM(virQEMUCapsPtr qemuCaps,
                       qemuMonitorPtr mon)
{
3069 3070
    int nentries;
    size_t i;
3071
    char **entries = NULL;
S
Stefan Berger 已提交
3072

3073 3074 3075 3076
    if ((nentries = qemuMonitorGetTPMModels(mon, &entries)) < 0)
        return -1;

    if (nentries > 0) {
3077
        for (i = 0; i < G_N_ELEMENTS(virQEMUCapsTPMModelsToCaps); i++) {
3078 3079
            const char *needle = virDomainTPMModelTypeToString(
                virQEMUCapsTPMModelsToCaps[i].type);
3080
            if (virStringListHasString((const char **)entries, needle))
3081 3082 3083 3084
                virQEMUCapsSet(qemuCaps,
                               virQEMUCapsTPMModelsToCaps[i].caps);
        }
    }
3085
    virStringListFree(entries);
3086 3087 3088 3089 3090

    if ((nentries = qemuMonitorGetTPMTypes(mon, &entries)) < 0)
        return -1;

    if (nentries > 0) {
3091
        for (i = 0; i < G_N_ELEMENTS(virQEMUCapsTPMTypesToCaps); i++) {
3092 3093
            const char *needle = virDomainTPMBackendTypeToString(
                virQEMUCapsTPMTypesToCaps[i].type);
3094
            if (virStringListHasString((const char **)entries, needle))
3095 3096 3097
                virQEMUCapsSet(qemuCaps, virQEMUCapsTPMTypesToCaps[i].caps);
        }
    }
3098
    virStringListFree(entries);
3099 3100 3101 3102

    return 0;
}

3103

3104
static int
3105 3106
virQEMUCapsProbeQMPKVMState(virQEMUCapsPtr qemuCaps,
                            qemuMonitorPtr mon)
3107 3108 3109 3110 3111 3112 3113
{
    bool enabled = false;
    bool present = false;

    if (qemuMonitorGetKVMState(mon, &enabled, &present) < 0)
        return -1;

A
Andrea Bolognani 已提交
3114 3115
    if (present && enabled)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_KVM);
3116 3117 3118 3119

    return 0;
}

3120 3121 3122 3123 3124 3125 3126 3127
struct virQEMUCapsCommandLineProps {
    const char *option;
    const char *param;
    int flag;
};

static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
    { "machine", "mem-merge", QEMU_CAPS_MEM_MERGE },
3128
    { "machine", "vmport", QEMU_CAPS_MACHINE_VMPORT_OPT },
O
Osier Yang 已提交
3129
    { "drive", "discard", QEMU_CAPS_DRIVE_DISCARD },
3130
    { "drive", "detect-zeroes", QEMU_CAPS_DRIVE_DETECT_ZEROES },
3131
    { "boot-opts", "strict", QEMU_CAPS_BOOT_STRICT },
3132
    { "boot-opts", "reboot-timeout", QEMU_CAPS_REBOOT_TIMEOUT },
3133
    { "boot-opts", "splash-time", QEMU_CAPS_SPLASH_TIMEOUT },
3134
    { "spice", "disable-agent-file-xfer", QEMU_CAPS_SPICE_FILE_XFER_DISABLE },
3135
    { "msg", "timestamp", QEMU_CAPS_MSG_TIMESTAMP },
3136
    { "numa", NULL, QEMU_CAPS_NUMA },
3137
    { "drive", "throttling.bps-total-max", QEMU_CAPS_DRIVE_IOTUNE_MAX},
3138 3139
    { "machine", "aes-key-wrap", QEMU_CAPS_AES_KEY_WRAP },
    { "machine", "dea-key-wrap", QEMU_CAPS_DEA_KEY_WRAP },
3140
    { "chardev", "append", QEMU_CAPS_CHARDEV_FILE_APPEND },
3141
    { "spice", "gl", QEMU_CAPS_SPICE_GL },
3142
    { "chardev", "logfile", QEMU_CAPS_CHARDEV_LOGFILE },
3143
    { "name", "debug-threads", QEMU_CAPS_NAME_DEBUG_THREADS },
3144
    { "name", "guest", QEMU_CAPS_NAME_GUEST },
3145
    { "spice", "unix", QEMU_CAPS_SPICE_UNIX },
3146
    { "drive", "throttling.bps-total-max-length", QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH },
3147
    { "drive", "throttling.group", QEMU_CAPS_DRIVE_IOTUNE_GROUP },
3148
    { "spice", "rendernode", QEMU_CAPS_SPICE_RENDERNODE },
3149
    { "machine", "kernel_irqchip", QEMU_CAPS_MACHINE_KERNEL_IRQCHIP },
3150
    { "machine", "loadparm", QEMU_CAPS_LOADPARM },
3151
    { "vnc", "vnc", QEMU_CAPS_VNC_MULTI_SERVERS },
3152
    { "chardev", "reconnect", QEMU_CAPS_CHARDEV_RECONNECT },
3153
    { "sandbox", "enable", QEMU_CAPS_SECCOMP_SANDBOX },
3154
    { "sandbox", "elevateprivileges", QEMU_CAPS_SECCOMP_BLACKLIST },
3155
    { "chardev", "fd", QEMU_CAPS_CHARDEV_FD_PASS },
3156
    { "overcommit", NULL, QEMU_CAPS_OVERCOMMIT },
3157
    { "smp-opts", "dies", QEMU_CAPS_SMP_DIES },
3158 3159 3160 3161 3162 3163
};

static int
virQEMUCapsProbeQMPCommandLine(virQEMUCapsPtr qemuCaps,
                               qemuMonitorPtr mon)
{
3164
    bool found = false;
3165 3166 3167 3168
    int nvalues;
    char **values;
    size_t i, j;

3169
    for (i = 0; i < G_N_ELEMENTS(virQEMUCapsCommandLine); i++) {
3170 3171
        if ((nvalues = qemuMonitorGetCommandLineOptionParameters(mon,
                                                                 virQEMUCapsCommandLine[i].option,
3172 3173
                                                                 &values,
                                                                 &found)) < 0)
3174
            return -1;
3175 3176 3177 3178

        if (found && !virQEMUCapsCommandLine[i].param)
            virQEMUCapsSet(qemuCaps, virQEMUCapsCommandLine[i].flag);

3179
        for (j = 0; j < nvalues; j++) {
3180
            if (STREQ_NULLABLE(virQEMUCapsCommandLine[i].param, values[j])) {
3181 3182 3183 3184
                virQEMUCapsSet(qemuCaps, virQEMUCapsCommandLine[i].flag);
                break;
            }
        }
3185
        virStringListFree(values);
3186 3187 3188 3189
    }

    return 0;
}
3190

3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201
static int
virQEMUCapsProbeQMPMigrationCapabilities(virQEMUCapsPtr qemuCaps,
                                         qemuMonitorPtr mon)
{
    char **caps = NULL;
    int ncaps;

    if ((ncaps = qemuMonitorGetMigrationCapabilities(mon, &caps)) < 0)
        return -1;

    virQEMUCapsProcessStringFlags(qemuCaps,
3202
                                  G_N_ELEMENTS(virQEMUCapsMigration),
3203 3204
                                  virQEMUCapsMigration,
                                  ncaps, caps);
3205
    virStringListFreeCount(caps, ncaps);
3206 3207 3208 3209

    return 0;
}

A
Andrea Bolognani 已提交
3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226
/**
 * virQEMUCapsProbeQMPGICCapabilities:
 * @qemuCaps: QEMU binary capabilities
 * @mon: QEMU monitor
 *
 * Use @mon to obtain information about the GIC capabilities for the
 * corresponding QEMU binary, and store them in @qemuCaps.
 *
 * Returns: 0 on success, <0 on failure
 */
static int
virQEMUCapsProbeQMPGICCapabilities(virQEMUCapsPtr qemuCaps,
                                   qemuMonitorPtr mon)
{
    virGICCapability *caps = NULL;
    int ncaps;

3227 3228 3229 3230 3231
    if (!(qemuCaps->arch == VIR_ARCH_AARCH64 ||
          qemuCaps->arch == VIR_ARCH_ARMV6L ||
          qemuCaps->arch == VIR_ARCH_ARMV7L))
        return 0;

A
Andrea Bolognani 已提交
3232 3233 3234
    if ((ncaps = qemuMonitorGetGICCapabilities(mon, &caps)) < 0)
        return -1;

3235
    virQEMUCapsSetGICCapabilities(qemuCaps, caps, ncaps);
A
Andrea Bolognani 已提交
3236 3237 3238 3239

    return 0;
}

3240

3241 3242 3243 3244
static int
virQEMUCapsProbeQMPSEVCapabilities(virQEMUCapsPtr qemuCaps,
                                   qemuMonitorPtr mon)
{
3245
    int rc = -1;
3246 3247
    virSEVCapability *caps = NULL;

3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST))
        return 0;

    if ((rc = qemuMonitorGetSEVCapabilities(mon, &caps)) < 0)
        return -1;

    /* SEV isn't actually supported */
    if (rc == 0) {
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_SEV_GUEST);
        return 0;
    }
3259

3260 3261
    virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
    qemuCaps->sevCapabilities = caps;
3262
    return 0;
3263 3264 3265
}


J
Jiri Denemark 已提交
3266 3267 3268 3269 3270
/*
 * Filter for features which should never be passed to QEMU. Either because
 * QEMU never supported them or they were dropped as they never did anything
 * useful.
 */
3271
bool
3272
virQEMUCapsCPUFilterFeatures(const char *name,
3273
                             virCPUFeaturePolicy policy G_GNUC_UNUSED,
3274
                             void *opaque)
3275
{
3276
    virArch *arch = opaque;
3277

3278
    if (!ARCH_IS_X86(*arch))
3279 3280
        return true;

3281 3282
    if (STREQ(name, "cmt") ||
        STREQ(name, "mbm_total") ||
J
Jiri Denemark 已提交
3283 3284 3285
        STREQ(name, "mbm_local") ||
        STREQ(name, "osxsave") ||
        STREQ(name, "ospke"))
3286 3287 3288 3289 3290 3291
        return false;

    return true;
}


3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325
typedef struct _virQEMUCapsCPUFeatureTranslationTable virQEMUCapsCPUFeatureTranslationTable;
typedef virQEMUCapsCPUFeatureTranslationTable *virQEMUCapsCPUFeatureTranslationTablePtr;
struct _virQEMUCapsCPUFeatureTranslationTable {
    const char *libvirt;
    const char *qemu;
};

virQEMUCapsCPUFeatureTranslationTable virQEMUCapsCPUFeaturesX86[] = {
    {"cmp_legacy", "cmp-legacy"},
    {"ds_cpl", "ds-cpl"},
    {"fxsr_opt", "fxsr-opt"},
    {"kvm_pv_eoi", "kvm-pv-eoi"},
    {"kvm_pv_unhalt", "kvm-pv-unhalt"},
    {"lahf_lm", "lahf-lm"},
    {"nodeid_msr", "nodeid-msr"},
    {"pclmuldq", "pclmulqdq"},
    {"perfctr_core", "perfctr-core"},
    {"perfctr_nb", "perfctr-nb"},
    {"tsc_adjust", "tsc-adjust"},
    {NULL, NULL}
};


static const char *
virQEMUCapsCPUFeatureTranslate(virQEMUCapsPtr qemuCaps,
                               const char *feature,
                               bool reversed)
{
    virQEMUCapsCPUFeatureTranslationTablePtr table = NULL;
    virQEMUCapsCPUFeatureTranslationTablePtr entry;

    if (ARCH_IS_X86(qemuCaps->arch))
        table = virQEMUCapsCPUFeaturesX86;

3326 3327 3328
    if (!table ||
        !feature ||
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CANONICAL_CPU_FEATURES))
3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357
        return feature;

    for (entry = table; entry->libvirt; entry++) {
        const char *key = reversed ? entry->qemu : entry->libvirt;

        if (STREQ(feature, key))
            return reversed ? entry->libvirt : entry->qemu;
    }

    return feature;
}


const char *
virQEMUCapsCPUFeatureToQEMU(virQEMUCapsPtr qemuCaps,
                            const char *feature)
{
    return virQEMUCapsCPUFeatureTranslate(qemuCaps, feature, false);
}


const char *
virQEMUCapsCPUFeatureFromQEMU(virQEMUCapsPtr qemuCaps,
                              const char *feature)
{
    return virQEMUCapsCPUFeatureTranslate(qemuCaps, feature, true);
}


3358 3359 3360
/**
 * Returns  0 when host CPU model provided by QEMU was filled in qemuCaps,
 *          1 when the caller should fall back to using virCapsPtr->host.cpu,
3361
 *          2 when cpu model info is not supported for this configuration,
3362 3363 3364 3365
 *         -1 on error.
 */
static int
virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
3366
                            virDomainVirtType type,
3367
                            qemuMonitorCPUModelInfoPtr modelInfo,
3368 3369
                            virCPUDefPtr cpu,
                            bool migratable)
3370
{
3371
    size_t i;
3372

3373
    if (!modelInfo) {
3374 3375 3376 3377 3378 3379 3380 3381
        if (type == VIR_DOMAIN_VIRT_KVM) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("missing host CPU model info from QEMU "
                             "capabilities for binary %s"),
                           qemuCaps->binary);
            return -1;
        }
        return 2;
3382
    }
J
Jiri Denemark 已提交
3383

3384 3385
    cpu->model = g_strdup(modelInfo->name);
    if (VIR_ALLOC_N(cpu->features, modelInfo->nprops) < 0)
3386
        return -1;
3387 3388 3389 3390 3391

    cpu->nfeatures_max = modelInfo->nprops;
    cpu->nfeatures = 0;

    for (i = 0; i < modelInfo->nprops; i++) {
3392 3393
        virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures;
        qemuMonitorCPUPropertyPtr prop = modelInfo->props + i;
3394
        const char *name = virQEMUCapsCPUFeatureFromQEMU(qemuCaps, prop->name);
3395

3396 3397
        if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
            continue;
3398

3399
        feature->name = g_strdup(name);
3400 3401 3402 3403 3404 3405

        if (!prop->value.boolean ||
            (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
            feature->policy = VIR_CPU_FEATURE_DISABLE;
        else
            feature->policy = VIR_CPU_FEATURE_REQUIRE;
3406 3407 3408
        cpu->nfeatures++;
    }

3409 3410
    return 0;
}
3411

3412

3413
virCPUDataPtr
3414 3415
virQEMUCapsGetCPUModelX86Data(virQEMUCapsPtr qemuCaps,
                              qemuMonitorCPUModelInfoPtr model,
3416
                              bool migratable)
3417 3418 3419
{
    unsigned long long sigFamily = 0;
    unsigned long long sigModel = 0;
3420
    unsigned long long sigStepping = 0;
3421 3422
    virCPUDataPtr data = NULL;
    virCPUDataPtr ret = NULL;
3423 3424 3425 3426 3427 3428 3429
    size_t i;

    if (!(data = virCPUDataNew(VIR_ARCH_X86_64)))
        goto cleanup;

    for (i = 0; i < model->nprops; i++) {
        qemuMonitorCPUPropertyPtr prop = model->props + i;
3430
        const char *name = virQEMUCapsCPUFeatureFromQEMU(qemuCaps, prop->name);
3431 3432 3433

        switch (prop->type) {
        case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
3434 3435 3436 3437
            if (!prop->value.boolean ||
                (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
                continue;

3438
            if (virCPUDataAddFeature(data, name) < 0)
3439
                goto cleanup;
3440

3441 3442 3443
            break;

        case QEMU_MONITOR_CPU_PROPERTY_STRING:
3444
            if (STREQ(name, "vendor") &&
3445 3446 3447 3448 3449
                virCPUx86DataSetVendor(data, prop->value.string) < 0)
                goto cleanup;
            break;

        case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
3450
            if (STREQ(name, "family"))
3451
                sigFamily = prop->value.number;
3452
            else if (STREQ(name, "model"))
3453
                sigModel = prop->value.number;
3454
            else if (STREQ(name, "stepping"))
3455
                sigStepping = prop->value.number;
3456 3457 3458 3459 3460 3461 3462
            break;

        case QEMU_MONITOR_CPU_PROPERTY_LAST:
            break;
        }
    }

3463
    if (virCPUx86DataSetSignature(data, sigFamily, sigModel, sigStepping) < 0)
3464 3465
        goto cleanup;

3466
    ret = g_steal_pointer(&data);
3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485

 cleanup:
    virCPUDataFree(data);
    return ret;
}


/**
 * Returns  0 when host CPU model provided by QEMU was filled in qemuCaps,
 *          1 when the caller should fall back to using virCapsPtr->host.cpu,
 *         -1 on error.
 */
static int
virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
                           virDomainVirtType type,
                           qemuMonitorCPUModelInfoPtr model,
                           virCPUDefPtr cpu,
                           bool migratable)
{
3486
    g_autoptr(virDomainCapsCPUModels) cpuModels = NULL;
3487 3488 3489 3490 3491 3492
    virCPUDataPtr data = NULL;
    int ret = -1;

    if (!model)
        return 1;

3493
    if (!(data = virQEMUCapsGetCPUModelX86Data(qemuCaps, model, migratable)))
3494 3495
        goto cleanup;

3496
    cpuModels = virQEMUCapsGetCPUModels(qemuCaps, type, NULL, NULL);
3497 3498

    if (cpuDecode(cpu, data, cpuModels) < 0)
3499 3500 3501 3502 3503 3504 3505 3506 3507 3508
        goto cleanup;

    ret = 0;

 cleanup:
    virCPUDataFree(data);
    return ret;
}


3509 3510
/**
 * Returns  0 when host CPU model provided by QEMU was filled in qemuCaps,
3511 3512
 *          1 when the caller should fall back to other methods,
 *          2 when cpu model info is not supported for this configuration,
3513 3514
 *         -1 on error.
 */
3515
int
3516
virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
3517
                        virDomainVirtType type,
3518 3519
                        virCPUDefPtr cpu,
                        bool migratable)
3520
{
3521
    qemuMonitorCPUModelInfoPtr modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, type);
3522 3523
    int ret = 1;

3524
    if (migratable && modelInfo && !modelInfo->migratability)
3525 3526
        return 1;

3527
    if (ARCH_IS_S390(qemuCaps->arch)) {
3528
        ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, modelInfo,
3529 3530
                                          cpu, migratable);
    } else if (ARCH_IS_X86(qemuCaps->arch)) {
3531
        ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, modelInfo,
3532 3533
                                         cpu, migratable);
    }
3534

3535 3536 3537
    if (ret == 0)
        cpu->fallback = VIR_CPU_FALLBACK_FORBID;

3538
    return ret;
3539 3540 3541
}


3542 3543 3544
static virCPUDefPtr
virQEMUCapsNewHostCPUModel(void)
{
3545
    virCPUDefPtr cpu = virCPUDefNew();
3546 3547 3548 3549 3550 3551 3552 3553 3554 3555

    cpu->type = VIR_CPU_TYPE_GUEST;
    cpu->mode = VIR_CPU_MODE_CUSTOM;
    cpu->match = VIR_CPU_MATCH_EXACT;
    cpu->fallback = VIR_CPU_FALLBACK_ALLOW;

    return cpu;
}


3556 3557
void
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
3558
                            virArch hostArch,
3559
                            virDomainVirtType type)
3560 3561
{
    virCPUDefPtr cpu = NULL;
3562
    virCPUDefPtr cpuExpanded = NULL;
3563
    virCPUDefPtr migCPU = NULL;
3564
    virCPUDefPtr hostCPU = NULL;
3565 3566
    virCPUDefPtr fullCPU = NULL;
    size_t i;
3567
    int rc;
3568

3569
    if (!virQEMUCapsGuestIsNative(hostArch, qemuCaps->arch))
3570 3571
        return;

3572
    if (!(cpu = virQEMUCapsNewHostCPUModel()))
3573 3574
        goto error;

3575
    if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
3576 3577
        goto error;
    } else if (rc == 1) {
3578 3579
        g_autoptr(virDomainCapsCPUModels) cpuModels = NULL;

3580
        VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly");
3581

3582
        cpuModels = virQEMUCapsGetCPUModels(qemuCaps, type, NULL, NULL);
3583 3584
        hostCPU = virQEMUCapsProbeHostCPU(hostArch, cpuModels);

3585 3586
        if (!hostCPU ||
            virCPUDefCopyModelFilter(cpu, hostCPU, true,
3587
                                     virQEMUCapsCPUFilterFeatures,
3588
                                     &qemuCaps->arch) < 0)
3589
            goto error;
3590 3591 3592 3593 3594
    } else if (rc == 2) {
        VIR_DEBUG("QEMU does not provide CPU model for arch=%s virttype=%s",
                  virArchToString(qemuCaps->arch),
                  virDomainVirtTypeToString(type));
        goto error;
3595 3596
    } else if (type == VIR_DOMAIN_VIRT_KVM &&
               virCPUGetHostIsSupported(qemuCaps->arch)) {
3597
        if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL)))
3598 3599
            goto error;

3600 3601 3602 3603 3604 3605 3606
        if (!(cpuExpanded = virCPUDefCopy(cpu)) ||
            virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0)
            goto error;

        for (i = 0; i < cpuExpanded->nfeatures; i++) {
            if (cpuExpanded->features[i].policy == VIR_CPU_FEATURE_REQUIRE &&
                virCPUDefUpdateFeature(fullCPU, cpuExpanded->features[i].name,
3607 3608 3609
                                       VIR_CPU_FEATURE_REQUIRE) < 0)
                goto error;
        }
3610 3611
    }

3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624
    if (!(migCPU = virQEMUCapsNewHostCPUModel()))
        goto error;

    if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
        goto error;
    } else if (rc == 1) {
        VIR_DEBUG("CPU migratability not provided by QEMU");

        virCPUDefFree(migCPU);
        if (!(migCPU = virCPUCopyMigratable(qemuCaps->arch, cpu)))
            goto error;
    }

3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639
    if (ARCH_IS_X86(qemuCaps->arch) &&
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES)) {
        if (cpu &&
            virCPUDefFilterFeatures(cpu, virCPUx86FeatureFilterDropMSR, NULL) < 0)
            goto error;

        if (migCPU &&
            virCPUDefFilterFeatures(migCPU, virCPUx86FeatureFilterDropMSR, NULL) < 0)
            goto error;

        if (fullCPU &&
            virCPUDefFilterFeatures(fullCPU, virCPUx86FeatureFilterDropMSR, NULL) < 0)
            goto error;
    }

3640
    virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU, fullCPU);
3641

3642
 cleanup:
3643
    virCPUDefFree(cpuExpanded);
3644
    virCPUDefFree(hostCPU);
3645 3646 3647 3648
    return;

 error:
    virCPUDefFree(cpu);
3649
    virCPUDefFree(migCPU);
3650
    virCPUDefFree(fullCPU);
3651
    virResetLastError();
3652
    goto cleanup;
3653 3654 3655
}


3656 3657 3658 3659
qemuMonitorCPUModelInfoPtr
virQEMUCapsGetCPUModelInfo(virQEMUCapsPtr qemuCaps,
                           virDomainVirtType type)
{
3660
    return virQEMUCapsGetAccel(qemuCaps, type)->hostCPU.info;
3661 3662 3663
}


3664 3665 3666 3667 3668
void
virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
                           virDomainVirtType type,
                           qemuMonitorCPUModelInfoPtr modelInfo)
{
3669
    virQEMUCapsGetAccel(qemuCaps, type)->hostCPU.info = modelInfo;
3670 3671 3672
}


3673
static int
3674
virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsAccelPtr caps,
3675
                                xmlXPathContextPtr ctxt,
3676
                                const char *typeStr)
3677 3678 3679
{
    char *str = NULL;
    xmlNodePtr hostCPUNode;
3680
    xmlNodePtr *nodes = NULL;
3681
    VIR_XPATH_NODE_AUTORESTORE(ctxt);
3682
    qemuMonitorCPUModelInfoPtr hostCPU = NULL;
3683
    g_autofree char *xpath = g_strdup_printf("./hostCPU[@type='%s']", typeStr);
3684 3685 3686
    int ret = -1;
    size_t i;
    int n;
3687
    int val;
3688

3689
    if (!(hostCPUNode = virXPathNode(xpath, ctxt))) {
3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703
        ret = 0;
        goto cleanup;
    }

    if (VIR_ALLOC(hostCPU) < 0)
        goto cleanup;

    if (!(hostCPU->name = virXMLPropString(hostCPUNode, "model"))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing host CPU model name in QEMU "
                         "capabilities cache"));
        goto cleanup;
    }

3704 3705 3706 3707 3708 3709 3710 3711 3712
    if (!(str = virXMLPropString(hostCPUNode, "migratability")) ||
        (val = virTristateBoolTypeFromString(str)) <= 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("invalid migratability value for host CPU model"));
        goto cleanup;
    }
    hostCPU->migratability = val == VIR_TRISTATE_BOOL_YES;
    VIR_FREE(str);

3713 3714
    ctxt->node = hostCPUNode;

3715
    if ((n = virXPathNodeSet("./property", ctxt, &nodes)) > 0) {
3716 3717 3718 3719 3720 3721
        if (VIR_ALLOC_N(hostCPU->props, n) < 0)
            goto cleanup;

        hostCPU->nprops = n;

        for (i = 0; i < n; i++) {
3722 3723 3724 3725 3726
            qemuMonitorCPUPropertyPtr prop = hostCPU->props + i;

            ctxt->node = nodes[i];

            if (!(prop->name = virXMLPropString(ctxt->node, "name"))) {
3727 3728
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing 'name' attribute for a host CPU"
3729
                                 " model property in QEMU capabilities cache"));
3730 3731 3732
                goto cleanup;
            }

3733
            if (!(str = virXMLPropString(ctxt->node, "type")) ||
3734
                (val = qemuMonitorCPUPropertyTypeFromString(str)) < 0) {
3735
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3736 3737
                               _("missing or invalid CPU model property type "
                                 "in QEMU capabilities cache"));
3738 3739 3740
                goto cleanup;
            }
            VIR_FREE(str);
3741

3742
            prop->type = val;
3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773
            switch (prop->type) {
            case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
                if (virXPathBoolean("./@value='true'", ctxt))
                    prop->value.boolean = true;
                break;

            case QEMU_MONITOR_CPU_PROPERTY_STRING:
                prop->value.string = virXMLPropString(ctxt->node, "value");
                if (!prop->value.string) {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("invalid string value for '%s' host CPU "
                                     "model property in QEMU capabilities cache"),
                                   prop->name);
                    goto cleanup;
                }
                break;

            case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
                if (virXPathLongLong("string(./@value)", ctxt,
                                     &prop->value.number) < 0) {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("invalid number value for '%s' host CPU "
                                     "model property in QEMU capabilities cache"),
                                   prop->name);
                    goto cleanup;
                }
                break;

            case QEMU_MONITOR_CPU_PROPERTY_LAST:
                break;
            }
3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786

            if ((str = virXMLPropString(ctxt->node, "migratable"))) {
                if ((val = virTristateBoolTypeFromString(str)) <= 0) {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unknown migratable value for '%s' host "
                                     "CPU model property"),
                                   prop->name);
                    goto cleanup;
                }

                prop->migratable = val;
                VIR_FREE(str);
            }
3787 3788 3789
        }
    }

3790
    caps->hostCPU.info = g_steal_pointer(&hostCPU);
3791 3792 3793 3794
    ret = 0;

 cleanup:
    VIR_FREE(str);
3795
    VIR_FREE(nodes);
3796 3797 3798 3799 3800
    qemuMonitorCPUModelInfoFree(hostCPU);
    return ret;
}


3801
static int
3802
virQEMUCapsLoadCPUModels(virQEMUCapsAccelPtr caps,
3803
                         xmlXPathContextPtr ctxt,
3804
                         const char *typeStr)
3805
{
3806
    g_autoptr(qemuMonitorCPUDefs) defs = NULL;
3807
    g_autofree xmlNodePtr * nodes = NULL;
3808
    g_autofree char *xpath = g_strdup_printf("./cpu[@type='%s']", typeStr);
3809 3810
    size_t i;
    int n;
3811
    xmlNodePtr node;
3812

3813
    if ((n = virXPathNodeSet(xpath, ctxt, &nodes)) < 0) {
3814 3815
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities cpus"));
3816
        return -1;
3817 3818
    }

3819 3820
    if (n == 0)
        return 0;
3821

3822
    if (!(defs = qemuMonitorCPUDefsNew(n)))
3823
        return -1;
3824 3825

    for (i = 0; i < n; i++) {
3826
        qemuMonitorCPUDefInfoPtr cpu = defs->cpus + i;
3827
        int usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;
3828 3829 3830 3831 3832 3833
        g_autofree char * strUsable = NULL;
        g_autofree xmlNodePtr * blockerNodes = NULL;
        int nblockers;

        if ((strUsable = virXMLPropString(nodes[i], "usable")) &&
            (usable = virDomainCapsCPUUsableTypeFromString(strUsable)) < 0) {
3834
            virReportError(VIR_ERR_INTERNAL_ERROR,
3835 3836 3837
                           _("unknown value '%s' in attribute 'usable'"),
                           strUsable);
            return -1;
3838
        }
3839
        cpu->usable = usable;
3840

3841
        if (!(cpu->name = virXMLPropString(nodes[i], "name"))) {
3842 3843
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("missing cpu name in QEMU capabilities cache"));
3844
            return -1;
3845 3846
        }

3847 3848
        cpu->type = virXMLPropString(nodes[i], "typename");

3849 3850 3851 3852 3853 3854 3855 3856
        node = ctxt->node;
        ctxt->node = nodes[i];
        nblockers = virXPathNodeSet("./blocker", ctxt, &blockerNodes);
        ctxt->node = node;

        if (nblockers < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("failed to parse CPU blockers in QEMU capabilities"));
3857
            return -1;
3858 3859 3860 3861 3862
        }

        if (nblockers > 0) {
            size_t j;

3863
            if (VIR_ALLOC_N(cpu->blockers, nblockers + 1) < 0)
3864
                return -1;
3865 3866

            for (j = 0; j < nblockers; j++) {
3867
                if (!(cpu->blockers[j] = virXMLPropString(blockerNodes[j], "name"))) {
3868 3869 3870
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("missing blocker name in QEMU "
                                     "capabilities cache"));
3871
                    return -1;
3872 3873 3874
                }
            }
        }
3875 3876
    }

3877
    caps->cpuModels = g_steal_pointer(&defs);
3878
    return 0;
3879 3880 3881
}


3882
static int
3883 3884 3885
virQEMUCapsLoadMachines(virQEMUCapsAccelPtr caps,
                        xmlXPathContextPtr ctxt,
                        const char *typeStr)
3886
{
3887
    g_autofree char *xpath = g_strdup_printf("./machine[@type='%s']", typeStr);
3888 3889 3890 3891 3892
    g_autofree xmlNodePtr *nodes = NULL;
    char *str = NULL;
    size_t i;
    int n;

3893
    if ((n = virXPathNodeSet(xpath, ctxt, &nodes)) < 0) {
3894 3895 3896 3897 3898 3899 3900 3901
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities machines"));
        return -1;
    }

    if (n == 0)
        return 0;

3902 3903
    caps->nmachineTypes = n;
    if (VIR_ALLOC_N(caps->machineTypes, caps->nmachineTypes) < 0)
3904 3905 3906
        return -1;

    for (i = 0; i < n; i++) {
3907
        if (!(caps->machineTypes[i].name = virXMLPropString(nodes[i], "name"))) {
3908 3909 3910 3911
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("missing machine name in QEMU capabilities cache"));
            return -1;
        }
3912
        caps->machineTypes[i].alias = virXMLPropString(nodes[i], "alias");
3913 3914 3915

        str = virXMLPropString(nodes[i], "maxCpus");
        if (str &&
3916
            virStrToLong_ui(str, NULL, 10, &(caps->machineTypes[i].maxCpus)) < 0) {
3917 3918 3919 3920 3921 3922 3923 3924
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed machine cpu count in QEMU capabilities cache"));
            return -1;
        }
        VIR_FREE(str);

        str = virXMLPropString(nodes[i], "hotplugCpus");
        if (STREQ_NULLABLE(str, "yes"))
3925
            caps->machineTypes[i].hotplugCpus = true;
3926 3927 3928 3929
        VIR_FREE(str);

        str = virXMLPropString(nodes[i], "default");
        if (STREQ_NULLABLE(str, "yes"))
3930
            caps->machineTypes[i].qemuDefault = true;
3931
        VIR_FREE(str);
J
Jiri Denemark 已提交
3932 3933

        caps->machineTypes[i].defaultCPU = virXMLPropString(nodes[i], "defaultCPU");
3934 3935 3936 3937 3938 3939
    }

    return 0;
}


3940 3941 3942 3943 3944
static int
virQEMUCapsLoadAccel(virQEMUCapsPtr qemuCaps,
                     xmlXPathContextPtr ctxt,
                     virDomainVirtType type)
{
3945 3946 3947 3948
    virQEMUCapsAccelPtr caps = virQEMUCapsGetAccel(qemuCaps, type);
    const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg";

    if (virQEMUCapsLoadHostCPUModelInfo(caps, ctxt, typeStr) < 0)
3949 3950
        return -1;

3951
    if (virQEMUCapsLoadCPUModels(caps, ctxt, typeStr) < 0)
3952 3953
        return -1;

3954 3955 3956
    if (virQEMUCapsLoadMachines(caps, ctxt, typeStr) < 0)
        return -1;

3957 3958 3959 3960
    return 0;
}


3961 3962 3963 3964 3965
struct _virQEMUCapsCachePriv {
    char *libDir;
    uid_t runUid;
    gid_t runGid;
    virArch hostArch;
3966
    unsigned int microcodeVersion;
3967
    char *kernelVersion;
3968 3969 3970 3971

    /* cache whether /dev/kvm is usable as runUid:runGuid */
    virTristateBool kvmUsable;
    time_t kvmCtime;
3972 3973 3974 3975 3976
};
typedef struct _virQEMUCapsCachePriv virQEMUCapsCachePriv;
typedef virQEMUCapsCachePriv *virQEMUCapsCachePrivPtr;


3977
static void
3978
virQEMUCapsCachePrivFree(void *privData)
3979
{
3980 3981
    virQEMUCapsCachePrivPtr priv = privData;

3982
    VIR_FREE(priv->libDir);
3983
    VIR_FREE(priv->kernelVersion);
3984 3985 3986 3987
    VIR_FREE(priv);
}


3988 3989 3990
static int
virQEMUCapsParseSEVInfo(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt)
{
J
Ján Tomko 已提交
3991
    g_autoptr(virSEVCapability) sev = NULL;
3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST))
        return 0;

    if (virXPathBoolean("boolean(./sev)", ctxt) == 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing SEV platform data in QEMU "
                         "capabilities cache"));
        return -1;
    }

    if (VIR_ALLOC(sev) < 0)
        return -1;

    if (virXPathUInt("string(./sev/cbitpos)", ctxt, &sev->cbitpos) < 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing or malformed SEV cbitpos information "
                         "in QEMU capabilities cache"));
        return -1;
    }

    if (virXPathUInt("string(./sev/reducedPhysBits)", ctxt,
                     &sev->reduced_phys_bits) < 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing or malformed SEV reducedPhysBits information "
                         "in QEMU capabilities cache"));
        return -1;
    }

    if (!(sev->pdh = virXPathString("string(./sev/pdh)", ctxt)))  {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing SEV pdh information "
                         "in QEMU capabilities cache"));
        return -1;
    }

    if (!(sev->cert_chain = virXPathString("string(./sev/certChain)", ctxt))) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing SEV certChain information "
                         "in QEMU capabilities cache"));
        return -1;
    }

4035
    qemuCaps->sevCapabilities = g_steal_pointer(&sev);
4036 4037 4038 4039
    return 0;
}


4040 4041 4042 4043
/*
 * Parsing a doc that looks like
 *
 * <qemuCaps>
4044
 *   <emulator>/some/path</emulator>
4045 4046
 *   <qemuctime>234235253</qemuctime>
 *   <selfctime>234235253</selfctime>
4047
 *   <selfvers>1002016</selfvers>
4048 4049 4050 4051 4052
 *   <flag name='foo'/>
 *   <flag name='bar'/>
 *   ...
 *   <cpu name="pentium3"/>
 *   ...
4053
 *   <machine name="pc-1.0" alias="pc" hotplugCpus='yes' maxCpus="4" default="yes"/>
4054 4055 4056
 *   ...
 * </qemuCaps>
 */
4057
int
4058
virQEMUCapsLoadCache(virArch hostArch,
4059
                     virQEMUCapsPtr qemuCaps,
4060
                     const char *filename)
4061 4062 4063 4064 4065 4066 4067
{
    xmlDocPtr doc = NULL;
    int ret = -1;
    size_t i;
    int n;
    xmlNodePtr *nodes = NULL;
    xmlXPathContextPtr ctxt = NULL;
J
Ján Tomko 已提交
4068
    char *str = NULL;
4069
    long long int l;
4070
    unsigned long lu;
4071 4072 4073 4074

    if (!(doc = virXMLParseFile(filename)))
        goto cleanup;

4075
    if (!(ctxt = virXMLXPathContextNew(doc)))
4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087
        goto cleanup;

    ctxt->node = xmlDocGetRootElement(doc);

    if (STRNEQ((const char *)ctxt->node->name, "qemuCaps")) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("unexpected root element <%s>, "
                         "expecting <qemuCaps>"),
                       ctxt->node->name);
        goto cleanup;
    }

4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099
    if (!(str = virXPathString("string(./emulator)", ctxt))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing emulator in QEMU capabilities cache"));
        goto cleanup;
    }
    if (STRNEQ(str, qemuCaps->binary)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Expected caps for '%s' but saw '%s'"),
                       qemuCaps->binary, str);
        goto cleanup;
    }
    VIR_FREE(str);
4100 4101 4102 4103 4104
    if (virXPathLongLong("string(./qemuctime)", ctxt, &l) < 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing qemuctime in QEMU capabilities XML"));
        goto cleanup;
    }
4105
    qemuCaps->ctime = (time_t)l;
4106 4107 4108 4109 4110 4111

    if (virXPathLongLong("string(./selfctime)", ctxt, &l) < 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing selfctime in QEMU capabilities XML"));
        goto cleanup;
    }
4112
    qemuCaps->libvirtCtime = (time_t)l;
4113

4114
    qemuCaps->libvirtVersion = 0;
4115
    if (virXPathULong("string(./selfvers)", ctxt, &lu) == 0)
4116
        qemuCaps->libvirtVersion = lu;
4117

4118 4119 4120 4121 4122 4123
    if ((n = virXPathNodeSet("./flag", ctxt, &nodes)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities flags"));
        goto cleanup;
    }
    VIR_DEBUG("Got flags %d", n);
4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135
    for (i = 0; i < n; i++) {
        int flag;
        if (!(str = virXMLPropString(nodes[i], "name"))) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("missing flag name in QEMU capabilities cache"));
            goto cleanup;
        }
        flag = virQEMUCapsTypeFromString(str);
        if (flag < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unknown qemu capabilities flag %s"), str);
            goto cleanup;
4136
        }
4137 4138
        VIR_FREE(str);
        virQEMUCapsSet(qemuCaps, flag);
4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153
    }
    VIR_FREE(nodes);

    if (virXPathUInt("string(./version)", ctxt, &qemuCaps->version) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing version in QEMU capabilities cache"));
        goto cleanup;
    }

    if (virXPathUInt("string(./kvmVersion)", ctxt, &qemuCaps->kvmVersion) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing version in QEMU capabilities cache"));
        goto cleanup;
    }

4154 4155 4156 4157 4158 4159 4160
    if (virXPathUInt("string(./microcodeVersion)", ctxt,
                     &qemuCaps->microcodeVersion) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing microcode version in QEMU capabilities cache"));
        goto cleanup;
    }

4161 4162
    if (virXPathBoolean("boolean(./package)", ctxt) > 0) {
        qemuCaps->package = virXPathString("string(./package)", ctxt);
4163 4164
        if (!qemuCaps->package)
            qemuCaps->package = g_strdup("");
4165
    }
4166

4167 4168 4169 4170 4171 4172
    if (virXPathBoolean("boolean(./kernelVersion)", ctxt) > 0) {
        qemuCaps->kernelVersion = virXPathString("string(./kernelVersion)", ctxt);
        if (!qemuCaps->kernelVersion)
            goto cleanup;
    }

4173 4174 4175 4176 4177 4178 4179 4180 4181 4182
    if (!(str = virXPathString("string(./arch)", ctxt))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing arch in QEMU capabilities cache"));
        goto cleanup;
    }
    if (!(qemuCaps->arch = virArchFromString(str))) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown arch %s in QEMU capabilities cache"), str);
        goto cleanup;
    }
J
Ján Tomko 已提交
4183
    VIR_FREE(str);
4184

4185 4186
    if (virQEMUCapsLoadAccel(qemuCaps, ctxt, VIR_DOMAIN_VIRT_KVM) < 0 ||
        virQEMUCapsLoadAccel(qemuCaps, ctxt, VIR_DOMAIN_VIRT_QEMU) < 0)
4187 4188
        goto cleanup;

A
Andrea Bolognani 已提交
4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254
    if ((n = virXPathNodeSet("./gic", ctxt, &nodes)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities gic"));
        goto cleanup;
    }
    if (n > 0) {
        unsigned int uintValue;
        bool boolValue;

        qemuCaps->ngicCapabilities = n;
        if (VIR_ALLOC_N(qemuCaps->gicCapabilities, n) < 0)
            goto cleanup;

        for (i = 0; i < n; i++) {
            virGICCapabilityPtr cap = &qemuCaps->gicCapabilities[i];

            if (!(str = virXMLPropString(nodes[i], "version"))) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing GIC version "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (virStrToLong_ui(str, NULL, 10, &uintValue) < 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("malformed GIC version "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            cap->version = uintValue;
            VIR_FREE(str);

            if (!(str = virXMLPropString(nodes[i], "kernel"))) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing in-kernel GIC information "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (!(boolValue = STREQ(str, "yes")) && STRNEQ(str, "no")) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("malformed in-kernel GIC information "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (boolValue)
                cap->implementation |= VIR_GIC_IMPLEMENTATION_KERNEL;
            VIR_FREE(str);

            if (!(str = virXMLPropString(nodes[i], "emulated"))) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing emulated GIC information "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (!(boolValue = STREQ(str, "yes")) && STRNEQ(str, "no")) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("malformed emulated GIC information "
                                 "in QEMU capabilities cache"));
                goto cleanup;
            }
            if (boolValue)
                cap->implementation |= VIR_GIC_IMPLEMENTATION_EMULATED;
            VIR_FREE(str);
        }
    }
    VIR_FREE(nodes);

4255 4256 4257
    if (virQEMUCapsParseSEVInfo(qemuCaps, ctxt) < 0)
        goto cleanup;

4258 4259
    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
4260

4261 4262 4263
    if (virXPathBoolean("boolean(./kvmSupportsNesting)", ctxt) > 0)
        qemuCaps->kvmSupportsNesting = true;

4264
    ret = 0;
4265
 cleanup:
J
Ján Tomko 已提交
4266
    VIR_FREE(str);
4267 4268 4269 4270 4271 4272 4273
    VIR_FREE(nodes);
    xmlXPathFreeContext(ctxt);
    xmlFreeDoc(doc);
    return ret;
}


4274
static void
4275
virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsAccelPtr caps,
4276
                                  virBufferPtr buf,
4277
                                  const char *typeStr)
4278
{
4279
    qemuMonitorCPUModelInfoPtr model = caps->hostCPU.info;
4280 4281
    size_t i;

4282 4283 4284
    if (!model)
        return;

4285 4286 4287 4288
    virBufferAsprintf(buf,
                      "<hostCPU type='%s' model='%s' migratability='%s'>\n",
                      typeStr, model->name,
                      model->migratability ? "yes" : "no");
4289 4290 4291
    virBufferAdjustIndent(buf, 2);

    for (i = 0; i < model->nprops; i++) {
4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314
        qemuMonitorCPUPropertyPtr prop = model->props + i;

        virBufferAsprintf(buf, "<property name='%s' type='%s' ",
                          prop->name,
                          qemuMonitorCPUPropertyTypeToString(prop->type));

        switch (prop->type) {
        case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
            virBufferAsprintf(buf, "value='%s'",
                              prop->value.boolean ? "true" : "false");
            break;

        case QEMU_MONITOR_CPU_PROPERTY_STRING:
            virBufferEscapeString(buf, "value='%s'", prop->value.string);
            break;

        case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
            virBufferAsprintf(buf, "value='%lld'", prop->value.number);
            break;

        case QEMU_MONITOR_CPU_PROPERTY_LAST:
            break;
        }
4315 4316 4317 4318 4319

        if (prop->migratable > 0)
            virBufferAsprintf(buf, " migratable='%s'",
                              virTristateBoolTypeToString(prop->migratable));

4320
        virBufferAddLit(buf, "/>\n");
4321 4322 4323 4324 4325 4326 4327
    }

    virBufferAdjustIndent(buf, -2);
    virBufferAddLit(buf, "</hostCPU>\n");
}


4328
static void
4329
virQEMUCapsFormatCPUModels(virQEMUCapsAccelPtr caps,
4330
                           virBufferPtr buf,
4331
                           const char *typeStr)
4332
{
4333
    qemuMonitorCPUDefsPtr defs = caps->cpuModels;
4334 4335
    size_t i;

4336
    if (!defs)
4337 4338
        return;

4339 4340
    for (i = 0; i < defs->ncpus; i++) {
        qemuMonitorCPUDefInfoPtr cpu = defs->cpus + i;
4341

4342
        virBufferAsprintf(buf, "<cpu type='%s' ", typeStr);
4343
        virBufferEscapeString(buf, "name='%s'", cpu->name);
4344
        virBufferEscapeString(buf, " typename='%s'", cpu->type);
4345 4346 4347 4348
        if (cpu->usable) {
            virBufferAsprintf(buf, " usable='%s'",
                              virDomainCapsCPUUsableTypeToString(cpu->usable));
        }
4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363

        if (cpu->blockers) {
            size_t j;

            virBufferAddLit(buf, ">\n");
            virBufferAdjustIndent(buf, 2);

            for (j = 0; cpu->blockers[j]; j++)
                virBufferAsprintf(buf, "<blocker name='%s'/>\n", cpu->blockers[j]);

            virBufferAdjustIndent(buf, -2);
            virBufferAddLit(buf, "</cpu>\n");
        } else {
            virBufferAddLit(buf, "/>\n");
        }
4364 4365 4366 4367
    }
}


4368
static void
4369 4370 4371
virQEMUCapsFormatMachines(virQEMUCapsAccelPtr caps,
                          virBufferPtr buf,
                          const char *typeStr)
4372 4373 4374
{
    size_t i;

4375 4376 4377 4378
    for (i = 0; i < caps->nmachineTypes; i++) {
        virBufferAsprintf(buf, "<machine type='%s'", typeStr);
        virBufferEscapeString(buf, " name='%s'",
                              caps->machineTypes[i].name);
4379
        virBufferEscapeString(buf, " alias='%s'",
4380 4381
                              caps->machineTypes[i].alias);
        if (caps->machineTypes[i].hotplugCpus)
4382 4383
            virBufferAddLit(buf, " hotplugCpus='yes'");
        virBufferAsprintf(buf, " maxCpus='%u'",
4384 4385
                          caps->machineTypes[i].maxCpus);
        if (caps->machineTypes[i].qemuDefault)
4386
            virBufferAddLit(buf, " default='yes'");
J
Jiri Denemark 已提交
4387 4388
        virBufferEscapeString(buf, " defaultCPU='%s'",
                              caps->machineTypes[i].defaultCPU);
4389 4390 4391 4392 4393
        virBufferAddLit(buf, "/>\n");
    }
}


4394 4395 4396 4397 4398
static void
virQEMUCapsFormatAccel(virQEMUCapsPtr qemuCaps,
                       virBufferPtr buf,
                       virDomainVirtType type)
{
4399 4400 4401 4402 4403
    virQEMUCapsAccelPtr caps = virQEMUCapsGetAccel(qemuCaps, type);
    const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg";

    virQEMUCapsFormatHostCPUModelInfo(caps, buf, typeStr);
    virQEMUCapsFormatCPUModels(caps, buf, typeStr);
4404 4405
    virQEMUCapsFormatMachines(caps, buf, typeStr);

4406 4407 4408
}


4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426
static void
virQEMUCapsFormatSEVInfo(virQEMUCapsPtr qemuCaps, virBufferPtr buf)
{
    virSEVCapabilityPtr sev = virQEMUCapsGetSEVCapabilities(qemuCaps);

    virBufferAddLit(buf, "<sev>\n");
    virBufferAdjustIndent(buf, 2);
    virBufferAsprintf(buf, "<cbitpos>%u</cbitpos>\n", sev->cbitpos);
    virBufferAsprintf(buf, "<reducedPhysBits>%u</reducedPhysBits>\n",
                      sev->reduced_phys_bits);
    virBufferEscapeString(buf, "<pdh>%s</pdh>\n", sev->pdh);
    virBufferEscapeString(buf, "<certChain>%s</certChain>\n",
                          sev->cert_chain);
    virBufferAdjustIndent(buf, -2);
    virBufferAddLit(buf, "</sev>\n");
}


4427
char *
4428
virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
4429 4430
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4431
    char *ret = NULL;
4432 4433 4434
    size_t i;

    virBufferAddLit(&buf, "<qemuCaps>\n");
4435
    virBufferAdjustIndent(&buf, 2);
4436

4437 4438
    virBufferEscapeString(&buf, "<emulator>%s</emulator>\n",
                          qemuCaps->binary);
4439
    virBufferAsprintf(&buf, "<qemuctime>%llu</qemuctime>\n",
4440
                      (long long)qemuCaps->ctime);
4441
    virBufferAsprintf(&buf, "<selfctime>%llu</selfctime>\n",
4442
                      (long long)qemuCaps->libvirtCtime);
4443
    virBufferAsprintf(&buf, "<selfvers>%lu</selfvers>\n",
4444
                      (unsigned long)qemuCaps->libvirtVersion);
4445 4446 4447

    for (i = 0; i < QEMU_CAPS_LAST; i++) {
        if (virQEMUCapsGet(qemuCaps, i)) {
4448
            virBufferAsprintf(&buf, "<flag name='%s'/>\n",
4449 4450 4451 4452
                              virQEMUCapsTypeToString(i));
        }
    }

4453
    virBufferAsprintf(&buf, "<version>%d</version>\n",
4454 4455
                      qemuCaps->version);

4456
    virBufferAsprintf(&buf, "<kvmVersion>%d</kvmVersion>\n",
4457 4458
                      qemuCaps->kvmVersion);

4459 4460 4461
    virBufferAsprintf(&buf, "<microcodeVersion>%u</microcodeVersion>\n",
                      qemuCaps->microcodeVersion);

4462 4463 4464 4465
    if (qemuCaps->package)
        virBufferAsprintf(&buf, "<package>%s</package>\n",
                          qemuCaps->package);

4466 4467 4468 4469
    if (qemuCaps->kernelVersion)
        virBufferAsprintf(&buf, "<kernelVersion>%s</kernelVersion>\n",
                          qemuCaps->kernelVersion);

4470
    virBufferAsprintf(&buf, "<arch>%s</arch>\n",
4471 4472
                      virArchToString(qemuCaps->arch));

4473
    virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_KVM);
4474 4475
    virQEMUCapsFormatAccel(qemuCaps, &buf, VIR_DOMAIN_VIRT_QEMU);

A
Andrea Bolognani 已提交
4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491
    for (i = 0; i < qemuCaps->ngicCapabilities; i++) {
        virGICCapabilityPtr cap;
        bool kernel;
        bool emulated;

        cap = &qemuCaps->gicCapabilities[i];
        kernel = (cap->implementation & VIR_GIC_IMPLEMENTATION_KERNEL);
        emulated = (cap->implementation & VIR_GIC_IMPLEMENTATION_EMULATED);

        virBufferAsprintf(&buf,
                          "<gic version='%d' kernel='%s' emulated='%s'/>\n",
                          cap->version,
                          kernel ? "yes" : "no",
                          emulated ? "yes" : "no");
    }

4492 4493 4494
    if (qemuCaps->sevCapabilities)
        virQEMUCapsFormatSEVInfo(qemuCaps, &buf);

4495 4496 4497
    if (qemuCaps->kvmSupportsNesting)
        virBufferAddLit(&buf, "<kvmSupportsNesting/>\n");

4498
    virBufferAdjustIndent(&buf, -2);
4499 4500
    virBufferAddLit(&buf, "</qemuCaps>\n");

4501
    ret = virBufferContentAndReset(&buf);
4502 4503 4504 4505 4506 4507

    return ret;
}


static int
4508 4509
virQEMUCapsSaveFile(void *data,
                    const char *filename,
J
Ján Tomko 已提交
4510
                    void *privData G_GNUC_UNUSED)
4511
{
4512
    virQEMUCapsPtr qemuCaps = data;
4513 4514
    char *xml = NULL;
    int ret = -1;
4515

4516
    xml = virQEMUCapsFormatCache(qemuCaps);
4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527

    if (virFileWriteStr(filename, xml, 0600) < 0) {
        virReportSystemError(errno,
                             _("Failed to save '%s' for '%s'"),
                             filename, qemuCaps->binary);
        goto cleanup;
    }

    VIR_DEBUG("Saved caps '%s' for '%s' with (%lld, %lld)",
              filename, qemuCaps->binary,
              (long long)qemuCaps->ctime,
4528
              (long long)qemuCaps->libvirtCtime);
4529 4530 4531 4532 4533 4534 4535 4536

    ret = 0;
 cleanup:
    VIR_FREE(xml);
    return ret;
}


4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548
/* Check the kernel module parameters 'nested' file to determine if enabled
 *
 *   Intel: 'kvm_intel' uses 'Y'
 *   AMD:   'kvm_amd' uses '1'
 *   PPC64: 'kvm_hv' uses 'Y'
 *   S390:  'kvm' uses '1'
 */
static bool
virQEMUCapsKVMSupportsNesting(void)
{
    static char const * const kmod[] = {"kvm_intel", "kvm_amd",
                                        "kvm_hv", "kvm"};
4549
    g_autofree char *value = NULL;
4550 4551 4552
    int rc;
    size_t i;

4553
    for (i = 0; i < G_N_ELEMENTS(kmod); i++) {
4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571
        VIR_FREE(value);
        rc = virFileReadValueString(&value, "/sys/module/%s/parameters/nested",
                                    kmod[i]);
        if (rc == -2)
            continue;
        if (rc < 0) {
            virResetLastError();
            return false;
        }

        if (value[0] == 'Y' || value[0] == 'y' || value[0] == '1')
            return true;
    }

    return false;
}


4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619
/* Determine whether '/dev/kvm' is usable as QEMU user:QEMU group. */
static bool
virQEMUCapsKVMUsable(virQEMUCapsCachePrivPtr priv)
{
    struct stat sb;
    static const char *kvm_device = "/dev/kvm";
    virTristateBool value;
    virTristateBool cached_value = priv->kvmUsable;
    time_t kvm_ctime;
    time_t cached_kvm_ctime = priv->kvmCtime;

    if (stat(kvm_device, &sb) < 0) {
        if (errno != ENOENT) {
            virReportSystemError(errno,
                                 _("Failed to stat %s"), kvm_device);
        }
        return false;
    }
    kvm_ctime = sb.st_ctime;

    if (kvm_ctime != cached_kvm_ctime) {
        VIR_DEBUG("%s has changed (%lld vs %lld)", kvm_device,
                  (long long)kvm_ctime, (long long)cached_kvm_ctime);
        cached_value = VIR_TRISTATE_BOOL_ABSENT;
    }

    if (cached_value != VIR_TRISTATE_BOOL_ABSENT)
        return cached_value == VIR_TRISTATE_BOOL_YES;

    if (virFileAccessibleAs(kvm_device, R_OK | W_OK,
                            priv->runUid, priv->runGid) == 0) {
        value = VIR_TRISTATE_BOOL_YES;
    } else {
        value = VIR_TRISTATE_BOOL_NO;
    }

    /* There is a race window between 'stat' and
     * 'virFileAccessibleAs'. However, since we're only interested in
     * detecting changes *after* the virFileAccessibleAs check, we can
     * neglect this here.
     */
    priv->kvmCtime = kvm_ctime;
    priv->kvmUsable = value;

    return value == VIR_TRISTATE_BOOL_YES;
}


4620
static bool
4621 4622
virQEMUCapsIsValid(void *data,
                   void *privData)
4623
{
4624 4625
    virQEMUCapsPtr qemuCaps = data;
    virQEMUCapsCachePrivPtr priv = privData;
4626
    bool kvmUsable;
4627
    struct stat sb;
4628
    bool kvmSupportsNesting;
4629

4630 4631 4632
    if (!qemuCaps->invalidation)
        return true;

4633 4634 4635
    if (!qemuCaps->binary)
        return true;

4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647
    if (qemuCaps->libvirtCtime != virGetSelfLastChanged() ||
        qemuCaps->libvirtVersion != LIBVIR_VERSION_NUMBER) {
        VIR_DEBUG("Outdated capabilities for '%s': libvirt changed "
                  "(%lld vs %lld, %lu vs %lu)",
                  qemuCaps->binary,
                  (long long)qemuCaps->libvirtCtime,
                  (long long)virGetSelfLastChanged(),
                  (unsigned long)qemuCaps->libvirtVersion,
                  (unsigned long)LIBVIR_VERSION_NUMBER);
        return false;
    }

4648 4649 4650 4651 4652 4653
    if (stat(qemuCaps->binary, &sb) < 0) {
        char ebuf[1024];
        VIR_DEBUG("Failed to stat QEMU binary '%s': %s",
                  qemuCaps->binary,
                  virStrerror(errno, ebuf, sizeof(ebuf)));
        return false;
4654 4655
    }

4656
    if (sb.st_ctime != qemuCaps->ctime) {
4657 4658 4659
        VIR_DEBUG("Outdated capabilities for '%s': QEMU binary changed "
                  "(%lld vs %lld)",
                  qemuCaps->binary,
4660
                  (long long)sb.st_ctime, (long long)qemuCaps->ctime);
4661 4662 4663
        return false;
    }

4664 4665 4666 4667 4668 4669 4670 4671
    if (!virQEMUCapsGuestIsNative(priv->hostArch, qemuCaps->arch)) {
        VIR_DEBUG("Guest arch (%s) is not native to host arch (%s), "
                  "skipping KVM-related checks",
                  virArchToString(qemuCaps->arch),
                  virArchToString(priv->hostArch));
        return true;
    }

4672
    kvmUsable = virQEMUCapsKVMUsable(priv);
4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
        kvmUsable) {
        VIR_DEBUG("KVM was not enabled when probing '%s', "
                  "but it should be usable now",
                  qemuCaps->binary);
        return false;
    }

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
        !kvmUsable) {
        VIR_DEBUG("KVM was enabled when probing '%s', "
                  "but it is not available now",
                  qemuCaps->binary);
        return false;
    }

4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
        if (priv->microcodeVersion != qemuCaps->microcodeVersion) {
            VIR_DEBUG("Outdated capabilities for '%s': microcode version "
                      "changed (%u vs %u)",
                      qemuCaps->binary,
                      priv->microcodeVersion,
                      qemuCaps->microcodeVersion);
            return false;
        }

        if (STRNEQ_NULLABLE(priv->kernelVersion, qemuCaps->kernelVersion)) {
            VIR_DEBUG("Outdated capabilities for '%s': kernel version changed "
                      "('%s' vs '%s')",
                      qemuCaps->binary,
                      priv->kernelVersion,
                      qemuCaps->kernelVersion);
            return false;
        }
4708 4709 4710 4711 4712 4713 4714 4715

        kvmSupportsNesting = virQEMUCapsKVMSupportsNesting();
        if (kvmSupportsNesting != qemuCaps->kvmSupportsNesting) {
            VIR_DEBUG("Outdated capabilities for '%s': kvm kernel nested "
                      "value changed from %d",
                     qemuCaps->binary, qemuCaps->kvmSupportsNesting);
            return false;
        }
4716 4717
    }

4718 4719 4720 4721
    return true;
}


4722 4723 4724 4725 4726 4727 4728 4729
/**
 * virQEMUCapsInitQMPArch:
 * @qemuCaps: QEMU capabilities
 * @mon: QEMU monitor
 *
 * Initialize the architecture for @qemuCaps by asking @mon.
 *
 * Returns: 0 on success, <0 on failure
4730 4731
 */
static int
4732
virQEMUCapsInitQMPArch(virQEMUCapsPtr qemuCaps,
4733 4734 4735 4736 4737 4738
                            qemuMonitorPtr mon)
{
    char *archstr = NULL;
    int ret = -1;

    if (!(archstr = qemuMonitorGetTargetArch(mon)))
4739
        goto cleanup;
4740 4741 4742 4743 4744 4745 4746

    if ((qemuCaps->arch = virQEMUCapsArchFromString(archstr)) == VIR_ARCH_NONE) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Unknown QEMU arch %s"), archstr);
        goto cleanup;
    }

4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760
    ret = 0;

 cleanup:
    VIR_FREE(archstr);
    return ret;
}


/**
 * virQEMUCapsInitQMPBasicArch:
 * @qemuCaps: QEMU capabilities
 *
 * Initialize @qemuCaps with basic architecture-dependent capabilities.
 */
4761
void
4762 4763
virQEMUCapsInitQMPBasicArch(virQEMUCapsPtr qemuCaps)
{
4764 4765 4766
    /* ACPI only works on x86 and aarch64 */
    if (ARCH_IS_X86(qemuCaps->arch) ||
        qemuCaps->arch == VIR_ARCH_AARCH64) {
4767
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI);
4768 4769
    }

J
Ján Tomko 已提交
4770 4771
    /* HPET is x86 specific */
    if (ARCH_IS_X86(qemuCaps->arch))
J
Ján Tomko 已提交
4772
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_HPET);
4773
}
4774

4775

4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842
/**
 * virQEMUCapsInitQMPVersionCaps:
 * @qemuCaps: QEMU capabilities
 *
 * Add all QEMU capabilities based on version of QEMU.
 */
static void
virQEMUCapsInitQMPVersionCaps(virQEMUCapsPtr qemuCaps)
{
    if (qemuCaps->version >= 1006000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);

    /* vmport option is supported v2.2.0 onwards */
    if (qemuCaps->version >= 2002000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_VMPORT_OPT);

    /* -cpu ...,aarch64=off supported in v2.3.0 and onwards. But it
       isn't detectable via qmp at this point */
    if (qemuCaps->arch == VIR_ARCH_AARCH64 &&
        qemuCaps->version >= 2003000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_AARCH64_OFF);

    /* vhost-user supports multi-queue from v2.4.0 onwards,
     * but there is no way to query for that capability */
    if (qemuCaps->version >= 2004000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE);

    /* smm option is supported from v2.4.0 */
    if (qemuCaps->version >= 2004000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT);

    /* sdl -gl option is supported from v2.4.0 (qemu commit id 0b71a5d5) */
    if (qemuCaps->version >= 2004000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SDL_GL);

    /* Since 2.4.50 ARM virt machine supports gic-version option */
    if (qemuCaps->version >= 2004050)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACH_VIRT_GIC_VERSION);

    /* no way to query if -machine kernel_irqchip supports split */
    if (qemuCaps->version >= 2006000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP_SPLIT);

    /* HPT resizing is supported since QEMU 2.10 on ppc64; unfortunately
     * there's no sane way to probe for it */
    if (qemuCaps->version >= 2010000 &&
        ARCH_IS_PPC64(qemuCaps->arch)) {
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
    }

    /* '-display egl-headless' cmdline option is supported since QEMU 2.10, but
     * there's no way to probe it */
    if (qemuCaps->version >= 2010000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_EGL_HEADLESS);

    /* no way to query for -numa dist */
    if (qemuCaps->version >= 2010000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NUMA_DIST);

    /* no way to query max-cpu-compat */
    if (qemuCaps->version >= 2010000 &&
        ARCH_IS_PPC64(qemuCaps->arch)) {
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT);
    }
}


4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857
/**
 * virQEMUCapsInitProcessCapsInterlock:
 * @qemuCaps: QEMU capabilities
 *
 * A capability which requires a different capability being present in order
 * for libvirt to be able to drive it properly should be processed here.
 */
void
virQEMUCapsInitProcessCapsInterlock(virQEMUCapsPtr qemuCaps)
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV))
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP);
}


4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882
/**
 * virQEMUCapsInitProcessCaps:
 * @qemuCaps: QEMU capabilities
 *
 * Some capability bits are enabled or disabled according to specific logic.
 * This function collects all capability processing after the capabilities
 * are detected.
 */
static void
virQEMUCapsInitProcessCaps(virQEMUCapsPtr qemuCaps)
{
    /* 'intel-iommu' shows up as a device since 2.2.0, but can
     * not be used with -device until 2.7.0. Before that it
     * requires -machine iommu=on. So we must clear the device
     * capability we detected on older QEMUs
     */
    if (qemuCaps->version < 2007000 &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU)) {
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU);
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_IOMMU);
    }

    /* Prealloc on NVDIMMs is broken on older QEMUs leading to
     * user data corruption. If we are dealing with such version
     * of QEMU pretend we don't know how to NVDIMM. */
4883
    if (qemuCaps->version < 2009000)
4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM);

    if (ARCH_IS_X86(qemuCaps->arch) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_CACHE);

    if (ARCH_IS_S390(qemuCaps->arch)) {
        /* Legacy assurance for QEMU_CAPS_CCW */
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCW) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_CCW))
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_CCW);
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCW_CSSID_UNRESTRICTED))
            virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_VFIO_CCW);
    }

4899 4900
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CANONICAL_CPU_FEATURES);
P
Peter Krempa 已提交
4901 4902 4903 4904 4905 4906 4907

    /* To avoid guest ABI regression, blockdev shall be enabled only when
     * we are able to pass the custom 'device_id' for SCSI disks and cdroms. */
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCK_FILE_AUTO_READONLY_DYNAMIC) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_DEVICE_ID) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_SAVEVM_MONITOR_NODES))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKDEV);
4908 4909

    virQEMUCapsInitProcessCapsInterlock(qemuCaps);
4910 4911 4912
}


4913 4914 4915 4916 4917
static int
virQEMUCapsProbeQMPSchemaCapabilities(virQEMUCapsPtr qemuCaps,
                                      qemuMonitorPtr mon)
{
    struct virQEMUCapsStringFlags *entry;
4918 4919
    virJSONValuePtr schemareply;
    virHashTablePtr schema = NULL;
4920 4921
    size_t i;

4922 4923 4924
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_QMP_SCHEMA))
        return 0;

4925
    if (!(schemareply = qemuMonitorQueryQMPSchema(mon)))
4926 4927
        return -1;

4928 4929 4930 4931
    if (!(schema = virQEMUQAPISchemaConvert(schemareply)))
        return -1;
    schemareply = NULL;

4932
    for (i = 0; i < G_N_ELEMENTS(virQEMUCapsQMPSchemaQueries); i++) {
4933 4934
        entry = virQEMUCapsQMPSchemaQueries + i;

4935
        if (virQEMUQAPISchemaPathExists(entry->value, schema))
4936 4937 4938
            virQEMUCapsSet(qemuCaps, entry->flag);
    }

4939
    /* probe also for basic event support */
4940
    for (i = 0; i < G_N_ELEMENTS(virQEMUCapsEvents); i++) {
4941 4942 4943 4944 4945 4946
        entry = virQEMUCapsEvents + i;

        if (virQEMUQAPISchemaPathExists(entry->value, schema))
            virQEMUCapsSet(qemuCaps, entry->flag);
    }

4947 4948 4949 4950
    virHashFree(schema);
    return 0;
}

J
Ján Tomko 已提交
4951
#define QEMU_MIN_MAJOR 1
J
Ján Tomko 已提交
4952
#define QEMU_MIN_MINOR 5
J
Ján Tomko 已提交
4953
#define QEMU_MIN_MICRO 0
4954

4955 4956 4957 4958 4959
int
virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
                          qemuMonitorPtr mon)
{
    int major, minor, micro;
4960
    g_autofree char *package = NULL;
4961 4962
    virQEMUCapsAccelPtr accel;
    virDomainVirtType type;
4963 4964 4965

    /* @mon is supposed to be locked by callee */

4966
    if (qemuMonitorGetVersion(mon, &major, &minor, &micro, &package) < 0)
4967
        return -1;
4968 4969 4970 4971

    VIR_DEBUG("Got version %d.%d.%d (%s)",
              major, minor, micro, NULLSTR(package));

J
Ján Tomko 已提交
4972 4973 4974 4975 4976 4977
    if (major < QEMU_MIN_MAJOR ||
        (major == QEMU_MIN_MAJOR && minor < QEMU_MIN_MINOR)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("QEMU version >= %d.%d.%d is required, but %d.%d.%d found"),
                       QEMU_MIN_MAJOR, QEMU_MIN_MINOR, QEMU_MIN_MICRO,
                       major, minor, micro);
4978
        return -1;
4979 4980 4981
    }

    qemuCaps->version = major * 1000000 + minor * 1000 + micro;
4982
    qemuCaps->package = g_steal_pointer(&package);
4983

4984
    if (virQEMUCapsInitQMPArch(qemuCaps, mon) < 0)
4985
        return -1;
4986

4987 4988
    virQEMUCapsInitQMPBasicArch(qemuCaps);

4989 4990
    /* initiate all capapbilities based on qemu version */
    virQEMUCapsInitQMPVersionCaps(qemuCaps);
4991

4992
    if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
4993
        return -1;
J
Jiri Denemark 已提交
4994 4995 4996

    /* Some capabilities may differ depending on KVM state */
    if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0)
4997
        return -1;
J
Jiri Denemark 已提交
4998

4999 5000 5001 5002 5003 5004 5005
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
        type = VIR_DOMAIN_VIRT_KVM;
    else
        type = VIR_DOMAIN_VIRT_QEMU;

    accel = virQEMUCapsGetAccel(qemuCaps, type);

5006
    if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0)
5007
        return -1;
5008
    if (virQEMUCapsProbeQMPDevices(qemuCaps, mon) < 0)
5009
        return -1;
5010
    if (virQEMUCapsProbeQMPMachineTypes(qemuCaps, type, mon) < 0)
5011
        return -1;
5012
    if (virQEMUCapsProbeQMPMachineProps(qemuCaps, type, mon) < 0)
5013
        return -1;
5014
    if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, accel, mon) < 0)
5015
        return -1;
5016
    if (virQEMUCapsProbeQMPTPM(qemuCaps, mon) < 0)
5017
        return -1;
5018
    if (virQEMUCapsProbeQMPCommandLine(qemuCaps, mon) < 0)
5019
        return -1;
5020
    if (virQEMUCapsProbeQMPMigrationCapabilities(qemuCaps, mon) < 0)
5021
        return -1;
5022
    if (virQEMUCapsProbeQMPSchemaCapabilities(qemuCaps, mon) < 0)
5023
        return -1;
5024
    if (virQEMUCapsProbeQMPGICCapabilities(qemuCaps, mon) < 0)
5025
        return -1;
5026
    if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0)
5027
        return -1;
5028

5029
    virQEMUCapsInitProcessCaps(qemuCaps);
5030

5031 5032 5033
    /* The following probes rely on other previously probed capabilities.
     * No capabilities bits should be set below this point. */

5034
    if (virQEMUCapsProbeQMPHostCPU(qemuCaps, accel, mon, type) < 0)
5035 5036
        return -1;

5037
    return 0;
5038 5039
}

5040

5041
int
5042
virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps,
5043 5044
                             qemuMonitorPtr mon)
{
5045 5046 5047
    virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, VIR_DOMAIN_VIRT_QEMU);

    if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, accel, mon) < 0)
5048
        return -1;
5049

5050
    if (virQEMUCapsProbeQMPHostCPU(qemuCaps, accel, mon, VIR_DOMAIN_VIRT_QEMU) < 0)
5051
        return -1;
5052

5053
    if (virQEMUCapsProbeQMPMachineTypes(qemuCaps, VIR_DOMAIN_VIRT_QEMU, mon) < 0)
5054
        return -1;
5055

5056
    return 0;
5057 5058 5059
}


5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079
#define MESSAGE_ID_CAPS_PROBE_FAILURE "8ae2f3fb-2dbe-498e-8fbd-012d40afa361"

static void
virQEMUCapsLogProbeFailure(const char *binary)
{
    virLogMetadata meta[] = {
        { .key = "MESSAGE_ID", .s = MESSAGE_ID_CAPS_PROBE_FAILURE, .iv = 0 },
        { .key = "LIBVIRT_QEMU_BINARY", .s = binary, .iv = 0 },
        { .key = NULL },
    };

    virLogMessage(&virLogSelf,
                  VIR_LOG_WARN,
                  __FILE__, __LINE__, __func__,
                  meta,
                  _("Failed to probe capabilities for %s: %s"),
                  binary, virGetLastErrorMessage());
}


5080
static int
5081 5082 5083 5084 5085
virQEMUCapsInitQMPSingle(virQEMUCapsPtr qemuCaps,
                         const char *libDir,
                         uid_t runUid,
                         gid_t runGid,
                         bool onlyTCG)
5086
{
5087
    qemuProcessQMPPtr proc = NULL;
5088 5089
    int ret = -1;

5090
    if (!(proc = qemuProcessQMPNew(qemuCaps->binary, libDir,
5091
                                   runUid, runGid, onlyTCG)))
5092 5093
        goto cleanup;

5094
    if (qemuProcessQMPStart(proc) < 0)
5095 5096
        goto cleanup;

5097 5098 5099 5100
    if (onlyTCG)
        ret = virQEMUCapsInitQMPMonitorTCG(qemuCaps, proc->mon);
    else
        ret = virQEMUCapsInitQMPMonitor(qemuCaps, proc->mon);
5101 5102

 cleanup:
5103 5104 5105
    if (ret < 0)
        virQEMUCapsLogProbeFailure(qemuCaps->binary);

5106
    qemuProcessQMPFree(proc);
5107 5108 5109 5110
    return ret;
}


5111 5112 5113 5114
static int
virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
                   const char *libDir,
                   uid_t runUid,
5115
                   gid_t runGid)
5116
{
5117
    if (virQEMUCapsInitQMPSingle(qemuCaps, libDir, runUid, runGid, false) < 0)
5118 5119 5120 5121 5122 5123 5124 5125
        return -1;

    /*
     * If KVM was enabled during the first probe, we need to explicitly probe
     * for TCG capabilities by asking the same binary again and turning KVM
     * off.
     */
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
5126
        virQEMUCapsInitQMPSingle(qemuCaps, libDir, runUid, runGid, true) < 0)
5127 5128 5129 5130 5131 5132
        return -1;

    return 0;
}


5133
virQEMUCapsPtr
5134
virQEMUCapsNewForBinaryInternal(virArch hostArch,
5135
                                const char *binary,
5136 5137 5138
                                const char *libDir,
                                uid_t runUid,
                                gid_t runGid,
5139
                                unsigned int microcodeVersion,
J
Ján Tomko 已提交
5140
                                const char *kernelVersion)
5141
{
5142
    virQEMUCapsPtr qemuCaps;
5143 5144
    struct stat sb;

5145
    if (!(qemuCaps = virQEMUCapsNewBinary(binary)))
5146 5147
        goto error;

5148 5149 5150 5151 5152 5153 5154
    /* We would also want to check faccessat if we cared about ACLs,
     * but we don't.  */
    if (stat(binary, &sb) < 0) {
        virReportSystemError(errno, _("Cannot check QEMU binary %s"),
                             binary);
        goto error;
    }
5155
    qemuCaps->ctime = sb.st_ctime;
5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166

    /* Make sure the binary we are about to try exec'ing exists.
     * Technically we could catch the exec() failure, but that's
     * in a sub-process so it's hard to feed back a useful error.
     */
    if (!virFileIsExecutable(binary)) {
        virReportSystemError(errno, _("QEMU binary %s is not executable"),
                             binary);
        goto error;
    }

5167
    if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid) < 0)
5168 5169
        goto error;

5170 5171
    qemuCaps->libvirtCtime = virGetSelfLastChanged();
    qemuCaps->libvirtVersion = LIBVIR_VERSION_NUMBER;
5172

5173 5174
    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
5175

5176
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
5177 5178
        qemuCaps->microcodeVersion = microcodeVersion;

5179
        qemuCaps->kernelVersion = g_strdup(kernelVersion);
5180 5181

        qemuCaps->kvmSupportsNesting = virQEMUCapsKVMSupportsNesting();
5182 5183
    }

5184
    return qemuCaps;
5185

5186
 error:
5187
    virObjectUnref(qemuCaps);
5188
    return NULL;
5189 5190
}

5191 5192 5193
static void *
virQEMUCapsNewData(const char *binary,
                   void *privData)
5194
{
5195 5196 5197 5198 5199 5200 5201
    virQEMUCapsCachePrivPtr priv = privData;

    return virQEMUCapsNewForBinaryInternal(priv->hostArch,
                                           binary,
                                           priv->libDir,
                                           priv->runUid,
                                           priv->runGid,
5202
                                           virHostCPUGetMicrocodeVersion(),
J
Ján Tomko 已提交
5203
                                           priv->kernelVersion);
5204
}
5205 5206


5207 5208 5209 5210 5211
static void *
virQEMUCapsLoadFile(const char *filename,
                    const char *binary,
                    void *privData)
{
5212
    virQEMUCapsPtr qemuCaps = virQEMUCapsNewBinary(binary);
5213
    virQEMUCapsCachePrivPtr priv = privData;
5214

5215 5216
    if (!qemuCaps)
        return NULL;
5217

5218 5219 5220
    if (virQEMUCapsLoadCache(priv->hostArch, qemuCaps, filename) < 0)
        goto error;

5221 5222 5223 5224
    return qemuCaps;

 error:
    virObjectUnref(qemuCaps);
5225
    return NULL;
5226 5227
}

5228

5229 5230 5231 5232 5233 5234 5235 5236
struct virQEMUCapsMachineTypeFilter {
    const char *machineType;
    virQEMUCapsFlags *flags;
    size_t nflags;
};

static const struct virQEMUCapsMachineTypeFilter virQEMUCapsMachineFilter[] = {
    /* { "blah", virQEMUCapsMachineBLAHFilter,
5237
         G_N_ELEMENTS(virQEMUCapsMachineBLAHFilter) }, */
5238 5239 5240 5241 5242 5243
    { "", NULL, 0 },
};


void
virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
5244
                               virDomainVirtType virtType,
5245 5246 5247 5248 5249 5250 5251
                               const char *machineType)
{
    size_t i;

    if (!machineType)
        return;

5252
    for (i = 0; i < G_N_ELEMENTS(virQEMUCapsMachineFilter); i++) {
5253 5254 5255 5256 5257 5258 5259 5260 5261 5262
        const struct virQEMUCapsMachineTypeFilter *filter = &virQEMUCapsMachineFilter[i];
        size_t j;

        if (STRNEQ(filter->machineType, machineType))
            continue;

        for (j = 0; j < filter->nflags; j++)
            virQEMUCapsClear(qemuCaps, filter->flags[j]);
    }

5263
    if (!virQEMUCapsGetMachineHotplugCpus(qemuCaps, virtType, machineType))
5264
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS);
5265 5266 5267
}


5268 5269 5270 5271 5272 5273 5274 5275 5276 5277
virFileCacheHandlers qemuCapsCacheHandlers = {
    .isValid = virQEMUCapsIsValid,
    .newData = virQEMUCapsNewData,
    .loadFile = virQEMUCapsLoadFile,
    .saveFile = virQEMUCapsSaveFile,
    .privFree = virQEMUCapsCachePrivFree,
};


virFileCachePtr
5278
virQEMUCapsCacheNew(const char *libDir,
5279
                    const char *cacheDir,
5280
                    uid_t runUid,
5281
                    gid_t runGid)
5282
{
5283 5284 5285
    char *capsCacheDir = NULL;
    virFileCachePtr cache = NULL;
    virQEMUCapsCachePrivPtr priv = NULL;
5286
    struct utsname uts;
5287

5288
    capsCacheDir = g_strdup_printf("%s/capabilities", cacheDir);
5289 5290

    if (!(cache = virFileCacheNew(capsCacheDir, "xml", &qemuCapsCacheHandlers)))
5291
        goto error;
5292

5293
    if (VIR_ALLOC(priv) < 0)
5294
        goto error;
5295
    virFileCacheSetPriv(cache, priv);
5296

5297
    priv->libDir = g_strdup(libDir);
5298

5299
    priv->hostArch = virArchFromHost();
5300

5301 5302
    priv->runUid = runUid;
    priv->runGid = runGid;
5303
    priv->kvmUsable = VIR_TRISTATE_BOOL_ABSENT;
5304

5305 5306
    if (uname(&uts) == 0)
        priv->kernelVersion = g_strdup_printf("%s %s", uts.release, uts.version);
5307

5308 5309
 cleanup:
    VIR_FREE(capsCacheDir);
5310 5311
    return cache;

5312
 error:
5313 5314 5315
    virObjectUnref(cache);
    cache = NULL;
    goto cleanup;
5316 5317 5318
}


5319
virQEMUCapsPtr
5320
virQEMUCapsCacheLookup(virFileCachePtr cache,
5321
                       const char *binary)
5322
{
5323
    virQEMUCapsCachePrivPtr priv = virFileCacheGetPriv(cache);
5324
    virQEMUCapsPtr ret = NULL;
5325

5326 5327
    priv->microcodeVersion = virHostCPUGetMicrocodeVersion();

5328
    ret = virFileCacheLookup(cache, binary);
5329 5330

    VIR_DEBUG("Returning caps %p for %s", ret, binary);
5331 5332 5333 5334
    return ret;
}


5335
virQEMUCapsPtr
5336
virQEMUCapsCacheLookupCopy(virFileCachePtr cache,
5337
                           virDomainVirtType virtType,
5338
                           const char *binary,
5339
                           const char *machineType)
5340
{
5341
    virQEMUCapsPtr qemuCaps = virQEMUCapsCacheLookup(cache, binary);
5342
    virQEMUCapsPtr ret;
5343

5344
    if (!qemuCaps)
5345 5346
        return NULL;

5347 5348
    ret = virQEMUCapsNewCopy(qemuCaps);
    virObjectUnref(qemuCaps);
5349 5350 5351 5352

    if (!ret)
        return NULL;

5353
    virQEMUCapsFilterByMachineType(ret, virtType, machineType);
5354 5355 5356 5357
    return ret;
}


5358 5359
static int
virQEMUCapsCompareArch(const void *payload,
J
Ján Tomko 已提交
5360
                       const void *name G_GNUC_UNUSED,
5361 5362
                       const void *opaque)
{
5363
    struct virQEMUCapsSearchData *data = (struct virQEMUCapsSearchData *)opaque;
5364 5365
    const virQEMUCaps *qemuCaps = payload;

5366 5367 5368 5369 5370 5371 5372 5373 5374
    if (qemuCaps->arch != data->arch)
        return false;

    if (data->binaryFilter &&
        !strstr(qemuCaps->binary, data->binaryFilter)) {
        return false;
    }

    return true;
5375 5376 5377 5378
}


virQEMUCapsPtr
5379
virQEMUCapsCacheLookupByArch(virFileCachePtr cache,
5380 5381
                             virArch arch)
{
5382
    virQEMUCapsCachePrivPtr priv = virFileCacheGetPriv(cache);
5383
    virQEMUCapsPtr ret = NULL;
5384 5385 5386 5387
    const char *binaryFilters[] = {
        "qemu-system-",
        NULL,
    };
5388 5389 5390 5391
    virArch archs[] = {
        arch,
        virQEMUCapsFindTarget(virArchFromHost(), arch),
    };
5392
    size_t i;
5393 5394
    size_t j;

5395 5396
    priv->microcodeVersion = virHostCPUGetMicrocodeVersion();

5397 5398
    for (i = 0; i < G_N_ELEMENTS(binaryFilters); i++) {
        for (j = 0; j < G_N_ELEMENTS(archs); j++) {
5399 5400 5401 5402
            struct virQEMUCapsSearchData data = {
                .arch = archs[j],
                .binaryFilter = binaryFilters[i],
            };
5403

5404 5405 5406 5407
            ret = virFileCacheLookupByFunc(cache, virQEMUCapsCompareArch, &data);
            if (ret)
                goto done;
        }
5408 5409
    }

5410 5411 5412 5413 5414
    virReportError(VIR_ERR_INVALID_ARG,
                   _("unable to find any emulator to serve '%s' "
                     "architecture"), virArchToString(arch));

 done:
5415 5416
    VIR_DEBUG("Returning caps %p for arch %s", ret, virArchToString(arch));

5417 5418 5419 5420
    return ret;
}


5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449
/**
 * virQEMUCapsCacheLookupDefault:
 * @cache: QEMU capabilities cache
 * @binary: optional path to QEMU binary
 * @archStr: optional guest architecture
 * @virttypeStr: optional virt type
 * @machine: optional machine type
 * @retArch: if non-NULL, guest architecture will be returned here
 * @retVirttype: if non-NULL, domain virt type will be returned here
 * @retMachine: if non-NULL, canonical machine type will be returned here
 *
 * Looks up the QEMU binary specified by @binary and @archStr, checks it can
 * provide the required @virttypeStr and @machine and returns its capabilities.
 * Sensible defaults are used for any argument which is NULL (the function can
 * even be called with all NULL arguments).
 *
 * Returns QEMU capabilities matching the requirements, NULL on error.
 */
virQEMUCapsPtr
virQEMUCapsCacheLookupDefault(virFileCachePtr cache,
                              const char *binary,
                              const char *archStr,
                              const char *virttypeStr,
                              const char *machine,
                              virArch *retArch,
                              virDomainVirtType *retVirttype,
                              const char **retMachine)
{
    int virttype = VIR_DOMAIN_VIRT_NONE;
5450 5451
    virArch hostarch = virArchFromHost();
    virArch arch = hostarch;
5452 5453 5454
    virDomainVirtType capsType;
    virQEMUCapsPtr qemuCaps = NULL;
    virQEMUCapsPtr ret = NULL;
5455 5456
    virArch arch_from_caps;
    g_autofree char *probedbinary = NULL;
5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471

    if (virttypeStr &&
        (virttype = virDomainVirtTypeFromString(virttypeStr)) < 0) {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unknown virttype: %s"), virttypeStr);
        goto cleanup;
    }

    if (archStr &&
        (arch = virArchFromString(archStr)) == VIR_ARCH_NONE) {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unknown architecture: %s"), archStr);
        goto cleanup;
    }

5472 5473 5474 5475
    if (!binary) {
        probedbinary = virQEMUCapsGetDefaultEmulator(hostarch, arch);
        binary = probedbinary;
    }
5476

5477 5478
    if (!(qemuCaps = virQEMUCapsCacheLookup(cache, binary)))
        goto cleanup;
5479

5480
    arch_from_caps = virQEMUCapsGetArch(qemuCaps);
5481

5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492
    if (arch_from_caps != arch &&
        !((ARCH_IS_X86(arch) && ARCH_IS_X86(arch_from_caps)) ||
          (ARCH_IS_PPC(arch) && ARCH_IS_PPC(arch_from_caps)) ||
          (ARCH_IS_ARM(arch) && ARCH_IS_ARM(arch_from_caps)) ||
          (ARCH_IS_S390(arch) && ARCH_IS_S390(arch_from_caps)))) {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("architecture from emulator '%s' doesn't "
                         "match given architecture '%s'"),
                       virArchToString(arch_from_caps),
                       virArchToString(arch));
        goto cleanup;
5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509
    }

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
        capsType = VIR_DOMAIN_VIRT_KVM;
    else
        capsType = VIR_DOMAIN_VIRT_QEMU;

    if (virttype == VIR_DOMAIN_VIRT_NONE)
        virttype = capsType;

    if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("KVM is not supported by '%s' on this host"),
                       binary);
        goto cleanup;
    }

5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523
    if (machine) {
        /* Turn @machine into canonical name */
        machine = virQEMUCapsGetCanonicalMachine(qemuCaps, virttype, machine);

        if (!virQEMUCapsIsMachineSupported(qemuCaps, virttype, machine)) {
            virReportError(VIR_ERR_INVALID_ARG,
                           _("the machine '%s' is not supported by emulator '%s'"),
                           machine, binary);
            goto cleanup;
        }
    } else {
        machine = virQEMUCapsGetPreferredMachine(qemuCaps, virttype);
    }

5524 5525 5526 5527 5528 5529 5530
    if (retArch)
        *retArch = arch;
    if (retVirttype)
        *retVirttype = virttype;
    if (retMachine)
        *retMachine = machine;

5531
    ret = g_steal_pointer(&qemuCaps);
5532 5533 5534 5535 5536 5537

 cleanup:
    virObjectUnref(qemuCaps);
    return ret;
}

5538 5539 5540 5541 5542 5543 5544
bool
virQEMUCapsSupportsVmport(virQEMUCapsPtr qemuCaps,
                          const virDomainDef *def)
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_VMPORT_OPT))
        return false;

5545 5546
    return qemuDomainIsI440FX(def) ||
        qemuDomainIsQ35(def) ||
5547 5548 5549 5550
        STREQ(def->os.machine, "isapc");
}


5551 5552 5553 5554
/*
 * The preferred machine to use if none is listed explicitly
 * Note that this may differ from QEMU's own default machine
 */
5555
const char *
5556
virQEMUCapsGetPreferredMachine(virQEMUCapsPtr qemuCaps,
5557
                               virDomainVirtType virtType)
5558
{
5559 5560 5561
    virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType);

    if (!accel->nmachineTypes)
5562
        return NULL;
5563
    return accel->machineTypes[0].name;
5564
}
5565 5566


5567
static int
5568
virQEMUCapsFillDomainLoaderCaps(virDomainCapsLoaderPtr capsLoader,
5569
                                bool secure,
5570 5571
                                virFirmwarePtr *firmwares,
                                size_t nfirmwares)
5572
{
5573 5574
    size_t i;

5575
    capsLoader->supported = VIR_TRISTATE_BOOL_YES;
5576 5577
    capsLoader->type.report = true;
    capsLoader->readonly.report = true;
5578
    capsLoader->secure.report = true;
5579

5580
    if (VIR_ALLOC_N(capsLoader->values.values, nfirmwares) < 0)
5581 5582
        return -1;

5583 5584
    for (i = 0; i < nfirmwares; i++) {
        const char *filename = firmwares[i]->name;
5585
        size_t j;
5586 5587 5588 5589 5590 5591

        if (!virFileExists(filename)) {
            VIR_DEBUG("loader filename=%s does not exist", filename);
            continue;
        }

5592 5593 5594 5595 5596 5597 5598 5599 5600
        /* Put only unique FW images onto the list */
        for (j = 0; j < capsLoader->values.nvalues; j++) {
            if (STREQ(filename, capsLoader->values.values[j]))
                break;
        }

        if (j != capsLoader->values.nvalues)
            continue;

5601
        capsLoader->values.values[capsLoader->values.nvalues] = g_strdup(filename);
5602
        capsLoader->values.nvalues++;
5603 5604
    }

5605
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
5606 5607
                             VIR_DOMAIN_LOADER_TYPE_ROM);

5608 5609
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
                             VIR_DOMAIN_LOADER_TYPE_PFLASH);
5610 5611


5612 5613 5614
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->readonly,
                             VIR_TRISTATE_BOOL_YES,
                             VIR_TRISTATE_BOOL_NO);
5615 5616 5617 5618 5619 5620 5621 5622

    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->secure,
                             VIR_TRISTATE_BOOL_NO);

    if (secure)
        VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->secure,
                                 VIR_TRISTATE_BOOL_YES);

5623
    return 0;
5624 5625 5626
}


5627
static int
5628
virQEMUCapsFillDomainOSCaps(virDomainCapsOSPtr os,
5629 5630 5631
                            const char *machine,
                            virArch arch,
                            bool privileged,
5632 5633
                            virFirmwarePtr *firmwares,
                            size_t nfirmwares)
5634
{
5635
    virDomainCapsLoaderPtr capsLoader = &os->loader;
5636 5637
    uint64_t autoFirmwares = 0;
    bool secure = false;
5638 5639 5640
    virFirmwarePtr *firmwaresAlt = NULL;
    size_t nfirmwaresAlt = 0;
    int ret = -1;
5641

5642
    os->supported = VIR_TRISTATE_BOOL_YES;
5643 5644
    os->firmware.report = true;

5645
    if (qemuFirmwareGetSupported(machine, arch, privileged,
5646 5647
                                 &autoFirmwares, &secure,
                                 &firmwaresAlt, &nfirmwaresAlt) < 0)
5648 5649 5650 5651 5652 5653 5654
        return -1;

    if (autoFirmwares & (1ULL << VIR_DOMAIN_OS_DEF_FIRMWARE_BIOS))
        VIR_DOMAIN_CAPS_ENUM_SET(os->firmware, VIR_DOMAIN_OS_DEF_FIRMWARE_BIOS);
    if (autoFirmwares & (1ULL << VIR_DOMAIN_OS_DEF_FIRMWARE_EFI))
        VIR_DOMAIN_CAPS_ENUM_SET(os->firmware, VIR_DOMAIN_OS_DEF_FIRMWARE_EFI);

5655 5656 5657 5658 5659 5660 5661 5662 5663
    if (virQEMUCapsFillDomainLoaderCaps(capsLoader, secure,
                                        firmwaresAlt ? firmwaresAlt : firmwares,
                                        firmwaresAlt ? nfirmwaresAlt : nfirmwares) < 0)
        goto cleanup;

    ret = 0;
 cleanup:
    virFirmwareFreeList(firmwaresAlt, nfirmwaresAlt);
    return ret;
5664 5665 5666
}


5667
static void
5668 5669
virQEMUCapsFillDomainCPUCaps(virQEMUCapsPtr qemuCaps,
                             virArch hostarch,
5670 5671
                             virDomainCapsPtr domCaps)
{
5672
    if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
5673 5674
                                      VIR_CPU_MODE_HOST_PASSTHROUGH,
                                      domCaps->machine))
5675 5676
        domCaps->cpu.hostPassthrough = true;

5677
    if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
5678 5679
                                      VIR_CPU_MODE_HOST_MODEL,
                                      domCaps->machine)) {
5680 5681
        virCPUDefPtr cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
                                                   VIR_QEMU_CAPS_HOST_CPU_REPORTED);
5682 5683
        domCaps->cpu.hostModel = virCPUDefCopy(cpu);
    }
5684

5685
    if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
5686 5687
                                      VIR_CPU_MODE_CUSTOM,
                                      domCaps->machine)) {
5688
        const char *blacklist[] = { "host", NULL };
5689
        VIR_AUTOSTRINGLIST models = NULL;
5690

J
Jiri Denemark 已提交
5691
        if (virCPUGetModels(domCaps->arch, &models) >= 0) {
5692 5693 5694 5695
            domCaps->cpu.custom = virQEMUCapsGetCPUModels(qemuCaps,
                                                          domCaps->virttype,
                                                          (const char **)models,
                                                          blacklist);
5696 5697
        } else {
            domCaps->cpu.custom = NULL;
5698
        }
5699
    }
5700 5701 5702
}


5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715
struct virQEMUCapsDomainFeatureCapabilityTuple {
    virDomainCapsFeature domcap;
    virQEMUCapsFlags qemucap;
};

/**
 * This maps the qemu features to the entries in <features> of the domain
 * capability XML.
 * */
static const struct virQEMUCapsDomainFeatureCapabilityTuple domCapsTuples[] = {
    { VIR_DOMAIN_CAPS_FEATURE_IOTHREADS, QEMU_CAPS_OBJECT_IOTHREAD },
    { VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO, QEMU_CAPS_DEVICE_VMCOREINFO },
    { VIR_DOMAIN_CAPS_FEATURE_GENID, QEMU_CAPS_DEVICE_VMGENID },
5716
    { VIR_DOMAIN_CAPS_FEATURE_BACKING_STORE_INPUT, QEMU_CAPS_BLOCKDEV },
5717
    { VIR_DOMAIN_CAPS_FEATURE_BACKUP, QEMU_CAPS_INCREMENTAL_BACKUP },
5718 5719 5720
};


5721
static void
5722 5723
virQEMUCapsFillDomainFeaturesFromQEMUCaps(virQEMUCapsPtr qemuCaps,
                                          virDomainCapsPtr domCaps)
5724
{
5725 5726 5727 5728 5729
    size_t i;

    for (i = 0; i < G_N_ELEMENTS(domCapsTuples); i++) {
        if (virQEMUCapsGet(qemuCaps, domCapsTuples[i].qemucap))
            domCaps->features[domCapsTuples[i].domcap] = VIR_TRISTATE_BOOL_YES;
5730 5731
        else
            domCaps->features[domCapsTuples[i].domcap] = VIR_TRISTATE_BOOL_NO;
5732
    }
5733 5734 5735
}


5736
static void
5737
virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
5738
                                    const char *machine,
5739 5740
                                    virDomainCapsDeviceDiskPtr disk)
{
5741
    disk->supported = VIR_TRISTATE_BOOL_YES;
5742 5743 5744 5745
    disk->diskDevice.report = true;
    disk->bus.report = true;
    disk->model.report = true;

5746 5747 5748
    /* QEMU supports all of these */
    VIR_DOMAIN_CAPS_ENUM_SET(disk->diskDevice,
                             VIR_DOMAIN_DISK_DEVICE_DISK,
5749 5750
                             VIR_DOMAIN_DISK_DEVICE_CDROM,
                             VIR_DOMAIN_DISK_DEVICE_LUN);
5751 5752

    /* PowerPC pseries based VMs do not support floppy device */
5753
    if (!qemuDomainMachineIsPSeries(machine, qemuCaps->arch)) {
5754
        VIR_DOMAIN_CAPS_ENUM_SET(disk->diskDevice, VIR_DOMAIN_DISK_DEVICE_FLOPPY);
5755 5756
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_FDC);
    }
5757

5758
    if (qemuDomainMachineHasBuiltinIDE(machine, qemuCaps->arch))
5759 5760
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_IDE);

5761 5762 5763 5764 5765 5766 5767
    VIR_DOMAIN_CAPS_ENUM_SET(disk->bus,
                             VIR_DOMAIN_DISK_BUS_SCSI,
                             VIR_DOMAIN_DISK_BUS_VIRTIO,
                             /* VIR_DOMAIN_DISK_BUS_SD */);

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE))
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_USB);
5768 5769 5770 5771

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI))
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_SATA);

5772 5773 5774 5775 5776 5777 5778 5779 5780
    /* disk->model values */
    VIR_DOMAIN_CAPS_ENUM_SET(disk->model, VIR_DOMAIN_DISK_MODEL_VIRTIO);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL)) {
        VIR_DOMAIN_CAPS_ENUM_SET(disk->model,
                                 VIR_DOMAIN_DISK_MODEL_VIRTIO_TRANSITIONAL);
        VIR_DOMAIN_CAPS_ENUM_SET(disk->model,
                                 VIR_DOMAIN_DISK_MODEL_VIRTIO_NON_TRANSITIONAL);
    }
5781 5782 5783
}


5784
static void
5785 5786 5787
virQEMUCapsFillDomainDeviceGraphicsCaps(virQEMUCapsPtr qemuCaps,
                                        virDomainCapsDeviceGraphicsPtr dev)
{
5788
    dev->supported = VIR_TRISTATE_BOOL_YES;
5789
    dev->type.report = true;
5790

J
Ján Tomko 已提交
5791
    VIR_DOMAIN_CAPS_ENUM_SET(dev->type, VIR_DOMAIN_GRAPHICS_TYPE_SDL);
5792 5793 5794 5795 5796 5797 5798
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->type, VIR_DOMAIN_GRAPHICS_TYPE_VNC);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->type, VIR_DOMAIN_GRAPHICS_TYPE_SPICE);
}


5799
static void
5800 5801 5802
virQEMUCapsFillDomainDeviceVideoCaps(virQEMUCapsPtr qemuCaps,
                                     virDomainCapsDeviceVideoPtr dev)
{
5803
    dev->supported = VIR_TRISTATE_BOOL_YES;
5804
    dev->modelType.report = true;
5805

5806
    VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_NONE);
5807 5808 5809 5810 5811 5812
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_VGA);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_CIRRUS);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_VMVGA);
5813
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL))
5814 5815 5816
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_QXL);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_VIRTIO);
5817 5818
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_BOCHS_DISPLAY))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_BOCHS);
5819 5820
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_RAMFB))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->modelType, VIR_DOMAIN_VIDEO_TYPE_RAMFB);
5821 5822 5823
}


5824
static void
5825 5826 5827 5828 5829
virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
                                       virDomainCapsDeviceHostdevPtr hostdev)
{
    bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();

5830
    hostdev->supported = VIR_TRISTATE_BOOL_YES;
5831 5832 5833 5834 5835 5836
    hostdev->mode.report = true;
    hostdev->startupPolicy.report = true;
    hostdev->subsysType.report = true;
    hostdev->capsType.report = true;
    hostdev->pciBackend.report = true;

5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847
    /* VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES is for containers only */
    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->mode,
                             VIR_DOMAIN_HOSTDEV_MODE_SUBSYS);

    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->startupPolicy,
                             VIR_DOMAIN_STARTUP_POLICY_DEFAULT,
                             VIR_DOMAIN_STARTUP_POLICY_MANDATORY,
                             VIR_DOMAIN_STARTUP_POLICY_REQUISITE,
                             VIR_DOMAIN_STARTUP_POLICY_OPTIONAL);

    VIR_DOMAIN_CAPS_ENUM_SET(hostdev->subsysType,
5848 5849
                             VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI,
                             VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI);
5850

5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX4_USB_UHCI) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_EHCI) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_VT82C686B_USB_UHCI) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI)) {
        VIR_DOMAIN_CAPS_ENUM_SET(hostdev->subsysType,
                                 VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB);
    }

5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875
    /* No virDomainHostdevCapsType for QEMU */
    virDomainCapsEnumClear(&hostdev->capsType);

    virDomainCapsEnumClear(&hostdev->pciBackend);
    if (supportsPassthroughVFIO &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
        VIR_DOMAIN_CAPS_ENUM_SET(hostdev->pciBackend,
                                 VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT,
                                 VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO);
    }
}


5876
static void
5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898
virQEMUCapsFillDomainDeviceRNGCaps(virQEMUCapsPtr qemuCaps,
                                   virDomainCapsDeviceRNGPtr rng)
{
    rng->supported = VIR_TRISTATE_BOOL_YES;
    rng->model.report = true;
    rng->backendModel.report = true;

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_RNG)) {
        VIR_DOMAIN_CAPS_ENUM_SET(rng->model, VIR_DOMAIN_RNG_MODEL_VIRTIO);

        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL) ||
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY)) {
            VIR_DOMAIN_CAPS_ENUM_SET(rng->model,
                                     VIR_DOMAIN_RNG_MODEL_VIRTIO_TRANSITIONAL,
                                     VIR_DOMAIN_RNG_MODEL_VIRTIO_NON_TRANSITIONAL);
        }
    }

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_EGD))
        VIR_DOMAIN_CAPS_ENUM_SET(rng->backendModel, VIR_DOMAIN_RNG_BACKEND_EGD);
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_RANDOM))
        VIR_DOMAIN_CAPS_ENUM_SET(rng->backendModel, VIR_DOMAIN_RNG_BACKEND_RANDOM);
H
Han Han 已提交
5899 5900
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_BUILTIN))
        VIR_DOMAIN_CAPS_ENUM_SET(rng->backendModel, VIR_DOMAIN_RNG_BACKEND_BUILTIN);
5901 5902 5903
}


5904 5905 5906 5907 5908 5909 5910
/**
 * virQEMUCapsSupportsGICVersion:
 * @qemuCaps: QEMU capabilities
 * @virtType: domain type
 * @version: GIC version
 *
 * Checks the QEMU binary with capabilities @qemuCaps supports a specific
5911 5912
 * GIC version for a domain of type @virtType. If @qemuCaps is NULL, the GIC
 * @version is considered unsupported.
5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923
 *
 * Returns: true if the binary supports the requested GIC version, false
 *          otherwise
 */
bool
virQEMUCapsSupportsGICVersion(virQEMUCapsPtr qemuCaps,
                              virDomainVirtType virtType,
                              virGICVersion version)
{
    size_t i;

5924 5925 5926
    if (!qemuCaps)
        return false;

5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945
    for (i = 0; i < qemuCaps->ngicCapabilities; i++) {
        virGICCapabilityPtr cap = &(qemuCaps->gicCapabilities[i]);

        if (cap->version != version)
            continue;

        if (virtType == VIR_DOMAIN_VIRT_KVM &&
            cap->implementation & VIR_GIC_IMPLEMENTATION_KERNEL)
            return true;

        if (virtType == VIR_DOMAIN_VIRT_QEMU &&
            cap->implementation & VIR_GIC_IMPLEMENTATION_EMULATED)
            return true;
    }

    return false;
}


5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962
/**
 * virQEMUCapsFillDomainFeatureGICCaps:
 * @qemuCaps: QEMU capabilities
 * @domCaps: domain capabilities
 *
 * Take the information about GIC capabilities that has been obtained
 * using the 'query-gic-capabilities' QMP command and stored in @qemuCaps
 * and convert it to a form suitable for @domCaps.
 *
 * @qemuCaps contains complete information about the GIC capabilities for
 * the corresponding QEMU binary, stored as custom objects; @domCaps, on
 * the other hand, should only contain information about the GIC versions
 * available for the specific combination of architecture, machine type
 * and virtualization type. Moreover, a common format is used to store
 * information about enumerations in @domCaps, so further processing is
 * required.
 */
5963
static void
5964 5965 5966 5967
virQEMUCapsFillDomainFeatureGICCaps(virQEMUCapsPtr qemuCaps,
                                    virDomainCapsPtr domCaps)
{
    virDomainCapsFeatureGICPtr gic = &domCaps->gic;
5968
    virGICVersion version;
5969

5970 5971
    gic->supported = VIR_TRISTATE_BOOL_NO;

5972
    if (!qemuDomainMachineIsARMVirt(domCaps->machine, domCaps->arch))
5973
        return;
5974

5975 5976 5977 5978 5979 5980
    for (version = VIR_GIC_VERSION_LAST - 1;
         version > VIR_GIC_VERSION_NONE;
         version--) {
        if (!virQEMUCapsSupportsGICVersion(qemuCaps,
                                           domCaps->virttype,
                                           version))
5981 5982
            continue;

5983
        gic->supported = VIR_TRISTATE_BOOL_YES;
5984
        gic->version.report = true;
5985
        VIR_DOMAIN_CAPS_ENUM_SET(gic->version,
5986
                                 version);
5987 5988 5989 5990
    }
}


5991 5992 5993 5994 5995 5996 5997 5998 5999
/**
 * virQEMUCapsFillDomainFeatureSEVCaps:
 * @qemuCaps: QEMU capabilities
 * @domCaps: domain capabilities
 *
 * Take the information about SEV capabilities that has been obtained
 * using the 'query-sev-capabilities' QMP command and stored in @qemuCaps
 * and convert it to a form suitable for @domCaps.
 */
6000
static void
6001 6002 6003 6004 6005 6006
virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCapsPtr qemuCaps,
                                    virDomainCapsPtr domCaps)
{
    virSEVCapability *cap = qemuCaps->sevCapabilities;

    if (!cap)
6007
        return;
6008

6009
    domCaps->sev = g_new0(virSEVCapability, 1);
6010

6011 6012 6013 6014
    domCaps->sev->pdh = g_strdup(cap->pdh);
    domCaps->sev->cert_chain = g_strdup(cap->cert_chain);
    domCaps->sev->cbitpos = cap->cbitpos;
    domCaps->sev->reduced_phys_bits = cap->reduced_phys_bits;
6015 6016 6017
}


6018
int
6019 6020
virQEMUCapsFillDomainCaps(virQEMUCapsPtr qemuCaps,
                          virArch hostarch,
6021
                          virDomainCapsPtr domCaps,
6022
                          bool privileged,
6023
                          virFirmwarePtr *firmwares,
6024
                          size_t nfirmwares)
6025
{
6026
    virDomainCapsOSPtr os = &domCaps->os;
6027 6028
    virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
    virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
6029
    virDomainCapsDeviceGraphicsPtr graphics = &domCaps->graphics;
6030
    virDomainCapsDeviceVideoPtr video = &domCaps->video;
6031
    virDomainCapsDeviceRNGPtr rng = &domCaps->rng;
6032

6033
    virQEMUCapsFillDomainFeaturesFromQEMUCaps(qemuCaps, domCaps);
6034

6035
    domCaps->maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps,
6036
                                                     domCaps->virttype,
6037
                                                     domCaps->machine);
6038
    if (domCaps->virttype == VIR_DOMAIN_VIRT_KVM) {
6039 6040 6041 6042 6043 6044
        int hostmaxvcpus;

        if ((hostmaxvcpus = virHostCPUGetKVMMaxVCPUs()) < 0)
            return -1;

        domCaps->maxvcpus = MIN(domCaps->maxvcpus, hostmaxvcpus);
6045
    }
6046

6047 6048 6049 6050
    if (virQEMUCapsFillDomainOSCaps(os,
                                    domCaps->machine,
                                    domCaps->arch,
                                    privileged,
6051
                                    firmwares, nfirmwares) < 0)
6052
        return -1;
6053

6054
    virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps);
6055 6056 6057 6058 6059 6060 6061 6062
    virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, domCaps->machine, disk);
    virQEMUCapsFillDomainDeviceGraphicsCaps(qemuCaps, graphics);
    virQEMUCapsFillDomainDeviceVideoCaps(qemuCaps, video);
    virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev);
    virQEMUCapsFillDomainDeviceRNGCaps(qemuCaps, rng);
    virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps);
    virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps);

6063
    return 0;
6064
}
6065 6066 6067 6068 6069 6070 6071 6072


void
virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps,
                               unsigned int microcodeVersion)
{
    qemuCaps->microcodeVersion = microcodeVersion;
}
6073 6074


6075 6076 6077 6078 6079 6080 6081 6082 6083
static void
virQEMUCapsStripMachineAliasesForVirtType(virQEMUCapsPtr qemuCaps,
                                          virDomainVirtType virtType)
{
    virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType);
    size_t i;

    for (i = 0; i < accel->nmachineTypes; i++) {
        virQEMUCapsMachineTypePtr mach = &accel->machineTypes[i];
6084
        g_autofree char *name = g_steal_pointer(&mach->alias);
6085

6086 6087 6088 6089
        if (name) {
            virQEMUCapsAddMachine(qemuCaps, virtType, name, NULL, mach->defaultCPU,
                                  mach->maxCpus, mach->hotplugCpus, mach->qemuDefault);
        }
6090 6091 6092 6093
    }
}


6094 6095 6096 6097
/**
 * virQEMUCapsStripMachineAliases:
 * @qemuCaps: capabilities object to process
 *
6098 6099 6100 6101
 * Replace all aliases by the copy of the machine type they point to without
 * actually having to modify the name. This allows us to add tests with the
 * aliased machine without having to change the output files all the time.
 *
6102 6103 6104 6105 6106 6107
 * Remove all aliases so that the tests depending on the latest capabilities
 * file can be stable when new files are added.
 */
void
virQEMUCapsStripMachineAliases(virQEMUCapsPtr qemuCaps)
{
6108 6109
    virQEMUCapsStripMachineAliasesForVirtType(qemuCaps, VIR_DOMAIN_VIRT_KVM);
    virQEMUCapsStripMachineAliasesForVirtType(qemuCaps, VIR_DOMAIN_VIRT_QEMU);
6110
}