qemu_capabilities.c 172.7 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 25 26
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>

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

50
#include <fcntl.h>
51 52 53
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
54
#include <stdarg.h>
55 56 57

#define VIR_FROM_THIS VIR_FROM_QEMU

58 59
VIR_LOG_INIT("qemu.qemu_capabilities");

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

72 73
              /* 5 */
              "name",
74 75 76 77 78
              "uuid",
              "domid",
              "vnet-hdr",
              "migrate-kvm-stdio",

79 80
              /* 10 */
              "migrate-qemu-tcp",
81 82 83 84 85
              "migrate-qemu-exec",
              "drive-cache-v2",
              "kvm",
              "drive-format",

86 87
              /* 15 */
              "vga",
88 89 90 91 92
              "0.10",
              "pci-device",
              "mem-path",
              "drive-serial",

93 94
              /* 20 */
              "xen-domid",
95 96 97 98 99
              "migrate-qemu-unix",
              "chardev",
              "enable-kvm",
              "monitor-json",

100 101
              /* 25 */
              "balloon",
102 103 104 105 106
              "device",
              "sdl",
              "smp-topology",
              "netdev",

107 108
              /* 30 */
              "rtc",
109
              "vhost-net",
110 111 112 113
              "rtc-td-hack",
              "no-hpet",
              "no-kvm-pit",

114 115
              /* 35 */
              "tdf",
116 117 118 119 120
              "pci-configfd",
              "nodefconfig",
              "boot-menu",
              "enable-kqemu",

121 122
              /* 40 */
              "fsdev",
123 124 125 126 127
              "nesting",
              "name-process",
              "drive-readonly",
              "smbios-type",

128 129
              /* 45 */
              "vga-qxl",
130 131 132 133 134
              "spice",
              "vga-none",
              "migrate-qemu-fd",
              "boot-index",

135 136
              /* 50 */
              "hda-duplex",
137 138 139 140 141
              "drive-aio",
              "pci-multibus",
              "pci-bootindex",
              "ccid-emulated",

142 143
              /* 55 */
              "ccid-passthru",
144 145 146 147
              "chardev-spicevmc",
              "device-spicevmc",
              "virtio-tx-alg",
              "device-qxl-vga",
148

149 150
              /* 60 */
              "pci-multifunction",
151
              "virtio-blk-pci.ioeventfd",
M
Michal Privoznik 已提交
152
              "sga",
153 154
              "virtio-blk-pci.event_idx",
              "virtio-net-pci.event_idx",
155

156 157
              /* 65 */
              "cache-directsync",
158 159 160 161 162
              "piix3-usb-uhci",
              "piix4-usb-uhci",
              "usb-ehci",
              "ich9-usb-ehci1",

163 164
              /* 70 */
              "vt82c686b-usb-uhci",
165 166
              "pci-ohci",
              "usb-redir",
M
Marc-André Lureau 已提交
167
              "usb-hub",
168
              "no-shutdown",
169

170 171
              /* 75 */
              "cache-unsafe",
172
              "rombar",
J
Jim Fehlig 已提交
173
              "ich9-ahci",
174
              "no-acpi",
175
              "fsdev-readonly",
176

177 178
              /* 80 */
              "virtio-blk-pci.scsi",
179
              "blk-sg-io",
O
Osier Yang 已提交
180
              "drive-copy-on-read",
181
              "cpu-host",
182
              "fsdev-writeout",
183

184 185
              /* 85 */
              "drive-iotune",
186
              "system_wakeup",
187
              "scsi-disk.channel",
188
              "scsi-block",
189
              "transaction",
190

191 192
              /* 90 */
              "block-job-sync",
193
              "block-job-async",
194
              "scsi-cd",
195
              "ide-cd",
196
              "no-user-config",
M
Marc-André Lureau 已提交
197

198 199
              /* 95 */
              "hda-micro",
200
              "dump-guest-memory",
G
Gerd Hoffmann 已提交
201
              "nec-usb-xhci",
202
              "virtio-s390",
203
              "balloon-event",
M
Marc-André Lureau 已提交
204

205 206
              /* 100 */
              "bridge",
207 208
              "lsi",
              "virtio-scsi-pci",
V
Viktor Mihajlovski 已提交
209
              "blockio",
210
              "disable-s3",
R
Richa Marwaha 已提交
211

212 213
              /* 105 */
              "disable-s4",
214
              "usb-redir.filter",
215 216
              "ide-drive.wwn",
              "scsi-disk.wwn",
217
              "seccomp-sandbox",
218

219 220
              /* 110 */
              "reboot-timeout",
221
              "dump-guest-core",
222
              "seamless-migration",
223
              "block-commit",
224
              "vnc",
225

226 227
              /* 115 */
              "drive-mirror",
228 229
              "usb-redir.bootindex",
              "usb-host.bootindex",
230
              "blockdev-snapshot-sync",
231 232
              "qxl",

233 234
              /* 120 */
              "VGA",
235 236 237
              "cirrus-vga",
              "vmware-svga",
              "device-video-primary",
238
              "s390-sclp",
239

240 241
              /* 125 */
              "usb-serial",
G
Guannan Ren 已提交
242
              "usb-net",
243
              "add-fd",
244
              "nbd-server",
245 246
              "virtio-rng",

247 248
              /* 130 */
              "rng-random",
249
              "rng-egd",
O
Olivia Yin 已提交
250 251
              "virtio-ccw",
              "dtb",
252
              "megasas",
J
Ján Tomko 已提交
253

254 255
              /* 135 */
              "ipv6-migration",
256
              "machine-opt",
L
Li Zhang 已提交
257
              "machine-usb-opt",
S
Stefan Berger 已提交
258 259
              "tpm-passthrough",
              "tpm-tis",
260

261 262
              /* 140 */
              "nvram",
H
Han Cheng 已提交
263 264 265 266 267
              "pci-bridge",
              "vfio-pci",
              "vfio-pci.bootindex",
              "scsi-generic",

268 269
              /* 145 */
              "scsi-generic.bootindex",
270
              "mem-merge",
271
              "vnc-websocket",
O
Osier Yang 已提交
272
              "drive-discard",
273
              "mlock",
274

275 276
              /* 150 */
              "vnc-share-policy",
277
              "device-del-event",
278
              "dmi-to-pci-bridge",
279 280
              "i440fx-pci-hole64-size",
              "q35-pci-hole64-size",
281

282 283
              /* 155 */
              "usb-storage",
284
              "usb-storage.removable",
285
              "virtio-mmio",
286
              "ich9-intel-hda",
287
              "kvm-pit-lost-tick-policy",
288

289 290
              /* 160 */
              "boot-strict",
291 292
              "pvpanic",
              "enable-fips",
293 294
              "spice-file-xfer-disable",
              "spiceport",
L
Li Zhang 已提交
295

296 297
              /* 165 */
              "usb-kbd",
298
              "host-pci-multidomain",
299
              "msg-timestamp",
300
              "active-commit",
301
              "change-backing-file",
302

303 304
              /* 170 */
              "memory-backend-ram",
305
              "numa",
306
              "memory-backend-file",
307
              "usb-audio",
308
              "rtc-reset-reinjection",
309

310 311
              /* 175 */
              "splash-timeout",
J
John Ferlan 已提交
312
              "iothread",
313
              "migrate-rdma",
314
              "ivshmem",
315
              "drive-iotune-max",
316

317 318
              /* 180 */
              "VGA.vgamem_mb",
319 320 321
              "vmware-svga.vgamem_mb",
              "qxl.vgamem_mb",
              "qxl-vga.vgamem_mb",
322
              "pc-dimm",
323

324 325
              /* 185 */
              "machine-vmport-opt",
326 327
              "aes-key-wrap",
              "dea-key-wrap",
M
Michal Privoznik 已提交
328
              "pci-serial",
329
              "aarch64-off",
330

331 332
              /* 190 */
              "vhost-user-multiqueue",
333
              "migration-event",
334
              "gpex-pcihost",
335
              "ioh3420",
336
              "x3130-upstream",
337

338 339
              /* 195 */
              "xio3130-downstream",
340
              "rtl8139",
341
              "e1000",
342
              "virtio-net",
343
              "gic-version",
344

345 346
              /* 200 */
              "incoming-defer",
M
Marc-André Lureau 已提交
347
              "virtio-gpu",
348
              "virtio-gpu.virgl",
349 350 351
              "virtio-keyboard",
              "virtio-mouse",

352 353
              /* 205 */
              "virtio-tablet",
354
              "virtio-input-host",
355
              "chardev-file-append",
356 357
              "ich9-disable-s3",
              "ich9-disable-s4",
358

359 360
              /* 210 */
              "vserport-change-event",
361
              "virtio-balloon-pci.deflate-on-oom",
362
              "mptsas1068",
363
              "spice-gl",
364 365
              "qxl.vram64_size_mb",

366 367
              /* 215 */
              "qxl-vga.vram64_size_mb",
368
              "chardev-logfile",
369
              "debug-threads",
370
              "secret",
371
              "pxb",
372

373 374
              /* 220 */
              "pxb-pcie",
375
              "device-tray-moved-event",
376
              "nec-usb-xhci-ports",
377
              "virtio-scsi-pci.iothread",
378
              "name-guest",
379

380 381
              /* 225 */
              "qxl.max_outputs",
382
              "qxl-vga.max_outputs",
383
              "spice-unix",
384
              "drive-detect-zeroes",
B
Boris Fiuczynski 已提交
385
              "tls-creds-x509",
386

387 388
              /* 230 */
              "display",
J
Ján Tomko 已提交
389
              "intel-iommu",
M
Michal Privoznik 已提交
390
              "smm",
391
              "virtio-pci-disable-legacy",
392
              "query-hotpluggable-cpus",
393

394 395
              /* 235 */
              "virtio-net.rx_queue_size",
396
              "machine-iommu",
397
              "virtio-vga",
398
              "drive-iotune-max-length",
399 400
              "ivshmem-plain",

401 402
              /* 240 */
              "ivshmem-doorbell",
403
              "query-qmp-schema",
404
              "gluster.debug_level",
405
              "vhost-scsi",
406
              "drive-iotune-group",
407

408 409
              /* 245 */
              "query-cpu-model-expansion",
410
              "virtio-net.host_mtu",
411
              "spice-rendernode",
412
              "nvdimm",
413
              "pcie-root-port",
414

415 416
              /* 250 */
              "query-cpu-definitions",
417
              "block-write-threshold",
418
              "query-named-block-nodes",
419
              "cpu-cache",
420
              "qemu-xhci",
421

422 423
              /* 255 */
              "kernel-irqchip",
424
              "kernel-irqchip.split",
425
              "intel-iommu.intremap",
426
              "intel-iommu.caching-mode",
427
              "intel-iommu.eim",
428

429 430
              /* 260 */
              "intel-iommu.device-iotlb",
431 432
              "virtio.iommu_platform",
              "virtio.ats",
433
              "loadparm",
434
              "spapr-pci-host-bridge",
435 436

              /* 265 */
437
              "spapr-pci-host-bridge.numa_node",
438 439
              "vnc-multi-servers",
              "virtio-net.tx_queue_size",
440
              "chardev-reconnect",
441
              "virtio-gpu.max_outputs",
J
John Ferlan 已提交
442 443 444

              /* 270 */
              "vxhs",
445
              "virtio-blk.num-queues",
446
              "machine.pseries.resize-hpt",
M
Marc-André Lureau 已提交
447
              "vmcoreinfo",
448
              "spapr-vty",
449 450
    );

451

452 453 454 455
struct virQEMUCapsMachineType {
    char *name;
    char *alias;
    unsigned int maxCpus;
456
    bool hotplugCpus;
457
};
458 459 460 461 462 463 464 465 466 467 468

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;
469 470
    /* Migratable host CPU definition used for updating guest CPU. */
    virCPUDefPtr migratable;
471 472 473 474
    /* 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;
475 476
};

477 478 479 480 481 482
/*
 * 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.
483 484
 *
 * And don't forget to update virQEMUCapsNewCopy.
485
 */
486
struct _virQEMUCaps {
487 488
    virObject object;

489 490
    bool usedQMP;

491
    char *binary;
492
    time_t ctime;
493
    time_t libvirtCtime;
494

495
    virBitmapPtr flags;
496 497 498

    unsigned int version;
    unsigned int kvmVersion;
499
    unsigned int libvirtVersion;
500
    char *package;
501

502
    virArch arch;
503

504 505
    virDomainCapsCPUModelsPtr kvmCPUModels;
    virDomainCapsCPUModelsPtr tcgCPUModels;
506 507

    size_t nmachineTypes;
508
    struct virQEMUCapsMachineType *machineTypes;
A
Andrea Bolognani 已提交
509 510 511

    size_t ngicCapabilities;
    virGICCapability *gicCapabilities;
512

513 514
    virQEMUCapsHostCPUData kvmCPU;
    virQEMUCapsHostCPUData tcgCPU;
515 516
};

517 518 519 520
struct virQEMUCapsSearchData {
    virArch arch;
};

521

522 523
static virClassPtr virQEMUCapsClass;
static void virQEMUCapsDispose(void *obj);
524

525
static int virQEMUCapsOnceInit(void)
526
{
527 528 529 530
    if (!(virQEMUCapsClass = virClassNew(virClassForObject(),
                                         "virQEMUCaps",
                                         sizeof(virQEMUCaps),
                                         virQEMUCapsDispose)))
531 532 533 534 535
        return -1;

    return 0;
}

536
VIR_ONCE_GLOBAL_INIT(virQEMUCaps)
537

538
static virArch virQEMUCapsArchFromString(const char *arch)
539 540 541 542 543
{
    if (STREQ(arch, "i386"))
        return VIR_ARCH_I686;
    if (STREQ(arch, "arm"))
        return VIR_ARCH_ARMV7L;
544 545
    if (STREQ(arch, "or32"))
        return VIR_ARCH_OR32;
546 547 548 549 550

    return virArchFromString(arch);
}


551
static const char *virQEMUCapsArchToString(virArch arch)
552 553 554 555 556
{
    if (arch == VIR_ARCH_I686)
        return "i386";
    else if (arch == VIR_ARCH_ARMV7L)
        return "arm";
557 558
    else if (arch == VIR_ARCH_OR32)
        return "or32";
559 560 561 562

    return virArchToString(arch);
}

563 564 565

/* Checks whether a domain with @guest arch can run natively on @host.
 */
566
bool
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
virQEMUCapsGuestIsNative(virArch host,
                         virArch guest)
{
    if (host == guest)
        return true;

    if (host == VIR_ARCH_X86_64 && guest == VIR_ARCH_I686)
        return true;

    if (host == VIR_ARCH_AARCH64 && guest == VIR_ARCH_ARMV7L)
        return true;

    if (ARCH_IS_PPC64(host) && ARCH_IS_PPC64(guest))
        return true;

    return false;
}


586 587 588 589 590 591 592 593 594
/* 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)
{
595 596 597
    if (virQEMUCapsGuestIsNative(hostarch, guestarch))
        guestarch = hostarch;

598 599 600 601 602 603
    /* Both ppc64 and ppc64le guests can use the ppc64 target */
    if (ARCH_IS_PPC64(guestarch))
        guestarch = VIR_ARCH_PPC64;

    return guestarch;
}
604

605
static virCommandPtr
606 607
virQEMUCapsProbeCommand(const char *qemu,
                        virQEMUCapsPtr qemuCaps,
608
                        uid_t runUid, gid_t runGid)
609 610 611
{
    virCommandPtr cmd = virCommandNew(qemu);

612 613
    if (qemuCaps) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG))
614
            virCommandAddArg(cmd, "-no-user-config");
615
        else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG))
616 617 618 619 620
            virCommandAddArg(cmd, "-nodefconfig");
    }

    virCommandAddEnvPassCommon(cmd);
    virCommandClearCaps(cmd);
621 622
    virCommandSetGID(cmd, runGid);
    virCommandSetUID(cmd, runUid);
623 624 625 626 627

    return cmd;
}


628
static void
629 630
virQEMUCapsSetDefaultMachine(virQEMUCapsPtr qemuCaps,
                             size_t defIdx)
631
{
632
    struct virQEMUCapsMachineType tmp = qemuCaps->machineTypes[defIdx];
633 634 635 636

    memmove(qemuCaps->machineTypes + 1,
            qemuCaps->machineTypes,
            sizeof(qemuCaps->machineTypes[0]) * defIdx);
637 638

    qemuCaps->machineTypes[0] = tmp;
639 640
}

641 642 643 644
/* Format is:
 * <machine> <desc> [(default)|(alias of <canonical>)]
 */
static int
645 646
virQEMUCapsParseMachineTypesStr(const char *output,
                                virQEMUCapsPtr qemuCaps)
647 648 649
{
    const char *p = output;
    const char *next;
650
    size_t defIdx = 0;
651 652 653

    do {
        const char *t;
654 655
        char *name;
        char *canonical = NULL;
656 657 658 659 660 661 662 663 664 665

        if ((next = strchr(p, '\n')))
            ++next;

        if (STRPREFIX(p, "Supported machines are:"))
            continue;

        if (!(t = strchr(p, ' ')) || (next && t >= next))
            continue;

666 667
        if (VIR_STRNDUP(name, p, t - p) < 0)
            return -1;
668 669

        p = t;
670
        if ((t = strstr(p, "(default)")) && (!next || t < next))
671
            defIdx = qemuCaps->nmachineTypes;
672 673 674

        if ((t = strstr(p, "(alias of ")) && (!next || t < next)) {
            p = t + strlen("(alias of ");
675 676
            if (!(t = strchr(p, ')')) || (next && t >= next)) {
                VIR_FREE(name);
677
                continue;
678
            }
679

680
            if (VIR_STRNDUP(canonical, p, t - p) < 0) {
681
                VIR_FREE(name);
682
                return -1;
683 684 685
            }
        }

686
        if (VIR_REALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes + 1) < 0) {
687 688
            VIR_FREE(name);
            VIR_FREE(canonical);
689
            return -1;
690
        }
691
        qemuCaps->nmachineTypes++;
692
        if (canonical) {
693 694
            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].name = canonical;
            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].alias = name;
695
        } else {
696 697
            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].name = name;
            qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].alias = NULL;
698
        }
699
        /* When parsing from command line we don't have information about maxCpus */
700
        qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].maxCpus = 0;
701
        qemuCaps->machineTypes[qemuCaps->nmachineTypes-1].hotplugCpus = false;
702 703
    } while ((p = next));

704

705
    if (defIdx)
706
        virQEMUCapsSetDefaultMachine(qemuCaps, defIdx);
707 708 709 710

    return 0;
}

711
static int
712 713
virQEMUCapsProbeMachineTypes(virQEMUCapsPtr qemuCaps,
                             uid_t runUid, gid_t runGid)
714 715
{
    char *output;
716 717
    int ret = -1;
    virCommandPtr cmd;
718
    int status;
719

720 721 722 723
    /* 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.
     */
724
    if (!virFileIsExecutable(qemuCaps->binary)) {
725
        virReportSystemError(errno, _("Cannot find QEMU binary %s"),
726
                             qemuCaps->binary);
727 728 729
        return -1;
    }

730
    cmd = virQEMUCapsProbeCommand(qemuCaps->binary, qemuCaps, runUid, runGid);
731
    virCommandAddArgList(cmd, "-M", "?", NULL);
732
    virCommandSetOutputBuffer(cmd, &output);
733

734 735
    /* Ignore failure from older qemu that did not understand '-M ?'.  */
    if (virCommandRun(cmd, &status) < 0)
736 737
        goto cleanup;

738
    if (virQEMUCapsParseMachineTypesStr(output, qemuCaps) < 0)
739
        goto cleanup;
740 741 742

    ret = 0;

743
 cleanup:
744 745
    VIR_FREE(output);
    virCommandFree(cmd);
746 747 748 749 750 751

    return ret;
}


typedef int
752 753
(*virQEMUCapsParseCPUModels)(const char *output,
                             virQEMUCapsPtr qemuCaps);
754 755 756 757 758 759 760

/* Format:
 *      <arch> <model>
 * qemu-0.13 encloses some model names in []:
 *      <arch> [<model>]
 */
static int
761 762
virQEMUCapsParseX86Models(const char *output,
                          virQEMUCapsPtr qemuCaps)
763 764 765
{
    const char *p = output;
    const char *next;
766 767 768 769
    virDomainCapsCPUModelsPtr cpus;

    if (!(cpus = virDomainCapsCPUModelsNew(0)))
        return -1;
770 771 772

    do {
        const char *t;
773
        size_t len;
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790

        if ((next = strchr(p, '\n')))
            next++;

        if (!(t = strchr(p, ' ')) || (next && t >= next))
            continue;

        if (!STRPREFIX(p, "x86"))
            continue;

        p = t;
        while (*p == ' ')
            p++;

        if (*p == '\0' || *p == '\n')
            continue;

791 792 793 794
        if (next)
            len = next - p - 1;
        else
            len = strlen(p);
795

796 797 798 799
        if (len > 2 && *p == '[' && p[len - 1] == ']') {
            p++;
            len -= 2;
        }
800

J
Jiri Denemark 已提交
801
        if (virDomainCapsCPUModelsAdd(cpus, p, len,
802
                                      VIR_DOMCAPS_CPU_USABLE_UNKNOWN, NULL) < 0)
803
            goto error;
804 805
    } while ((p = next));

806 807 808 809 810 811 812 813 814 815
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
        virDomainCapsCPUModelsPtr kvmCPUs;

        if (!(kvmCPUs = virDomainCapsCPUModelsCopy(cpus)))
            goto error;

        qemuCaps->kvmCPUModels = kvmCPUs;
    }
    qemuCaps->tcgCPUModels = cpus;

816
    return 0;
817

818 819 820
 error:
    virObjectUnref(cpus);
    return -1;
821 822
}

P
Prerna Saxena 已提交
823 824 825 826
/* ppc64 parser.
 * Format : PowerPC <machine> <description>
 */
static int
827 828
virQEMUCapsParsePPCModels(const char *output,
                          virQEMUCapsPtr qemuCaps)
P
Prerna Saxena 已提交
829 830 831
{
    const char *p = output;
    const char *next;
832 833 834 835
    virDomainCapsCPUModelsPtr cpus;

    if (!(cpus = virDomainCapsCPUModelsNew(0)))
        return -1;
P
Prerna Saxena 已提交
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858

    do {
        const char *t;

        if ((next = strchr(p, '\n')))
            next++;

        if (!STRPREFIX(p, "PowerPC "))
            continue;

        /* Skip the preceding sub-string "PowerPC " */
        p += 8;

        /*Malformed string, does not obey the format 'PowerPC <model> <desc>'*/
        if (!(t = strchr(p, ' ')) || (next && t >= next))
            continue;

        if (*p == '\0')
            break;

        if (*p == '\n')
            continue;

J
Jiri Denemark 已提交
859
        if (virDomainCapsCPUModelsAdd(cpus, p, t - p - 1,
860
                                      VIR_DOMCAPS_CPU_USABLE_UNKNOWN, NULL) < 0)
861
            goto error;
P
Prerna Saxena 已提交
862 863
    } while ((p = next));

864 865 866 867 868 869 870 871 872 873
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
        virDomainCapsCPUModelsPtr kvmCPUs;

        if (!(kvmCPUs = virDomainCapsCPUModelsCopy(cpus)))
            goto error;

        qemuCaps->kvmCPUModels = kvmCPUs;
    }
    qemuCaps->tcgCPUModels = cpus;

874
    return 0;
P
Prerna Saxena 已提交
875

876 877 878
 error:
    virObjectUnref(cpus);
    return -1;
P
Prerna Saxena 已提交
879
}
880

881
static int
882
virQEMUCapsProbeCPUModels(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid)
883 884 885
{
    char *output = NULL;
    int ret = -1;
886
    virQEMUCapsParseCPUModels parse;
887
    virCommandPtr cmd;
888

A
Andrea Bolognani 已提交
889
    if (ARCH_IS_X86(qemuCaps->arch)) {
890
        parse = virQEMUCapsParseX86Models;
A
Andrea Bolognani 已提交
891
    } else if (ARCH_IS_PPC64(qemuCaps->arch)) {
892
        parse = virQEMUCapsParsePPCModels;
893
    } else {
894
        VIR_DEBUG("don't know how to parse %s CPU models",
895
                  virArchToString(qemuCaps->arch));
896 897 898
        return 0;
    }

899
    cmd = virQEMUCapsProbeCommand(qemuCaps->binary, qemuCaps, runUid, runGid);
900
    virCommandAddArgList(cmd, "-cpu", "?", NULL);
901
    virCommandSetOutputBuffer(cmd, &output);
902

903
    if (virCommandRun(cmd, NULL) < 0)
904 905
        goto cleanup;

906
    if (parse(output, qemuCaps) < 0)
907 908 909 910
        goto cleanup;

    ret = 0;

911
 cleanup:
912
    VIR_FREE(output);
913
    virCommandFree(cmd);
914 915 916 917

    return ret;
}

918
static char *
919 920
virQEMUCapsFindBinary(const char *format,
                      const char *archstr)
921
{
922 923
    char *ret = NULL;
    char *binary = NULL;
924

925 926
    if (virAsprintf(&binary, format, archstr) < 0)
        goto out;
927 928 929

    ret = virFindFileInPath(binary);
    VIR_FREE(binary);
930 931
    if (ret && virFileIsExecutable(ret))
        goto out;
932

933
    VIR_FREE(ret);
934

935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
 out:
    return ret;
}

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

    /* First attempt: try the guest architecture as it is */
    archstr = virQEMUCapsArchToString(guestarch);
    if ((ret = virQEMUCapsFindBinary("qemu-system-%s", archstr)) != NULL)
        goto out;

    /* 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)
            goto out;
958
    }
959

960 961 962 963
    /* Third attempt, i686 only: try 'qemu' */
    if (guestarch == VIR_ARCH_I686) {
        if ((ret = virQEMUCapsFindBinary("%s", "qemu")) != NULL)
            goto out;
964
    }
965

966
 out:
967 968 969
    return ret;
}

970
static int
971
virQEMUCapsInitGuest(virCapsPtr caps,
972
                     virFileCachePtr cache,
973 974
                     virArch hostarch,
                     virArch guestarch)
975
{
976
    size_t i;
977 978
    char *kvmbin = NULL;
    char *binary = NULL;
979 980
    virQEMUCapsPtr qemubinCaps = NULL;
    virQEMUCapsPtr kvmbinCaps = NULL;
981 982
    int ret = -1;

J
Ján Tomko 已提交
983
    /* Check for existence of base emulator, or alternate base
984 985
     * which can be used with magic cpu choice
     */
986
    binary = virQEMUCapsFindBinaryForArch(hostarch, guestarch);
987

988
    /* Ignore binary if extracting version info fails */
989
    if (binary) {
990
        if (!(qemubinCaps = virQEMUCapsCacheLookup(cache, binary))) {
991 992 993 994
            virResetLastError();
            VIR_FREE(binary);
        }
    }
995 996

    /* qemu-kvm/kvm binaries can only be used if
997
     *  - host & guest arches match
998 999
     *  - hostarch is x86_64 and guest arch is i686 (needs -cpu qemu32)
     *  - hostarch is aarch64 and guest arch is armv7l (needs -cpu aarch64=off)
1000
     *  - hostarch and guestarch are both ppc64*
1001
     */
1002
    if (virQEMUCapsGuestIsNative(hostarch, guestarch)) {
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
        const char *kvmbins[] = {
            "/usr/libexec/qemu-kvm", /* RHEL */
            "qemu-kvm", /* Fedora */
            "kvm", /* Debian/Ubuntu */
            NULL,
        };

        /* x86 32-on-64 can be used with qemu-system-i386 and
         * qemu-system-x86_64, so if we don't find a specific kvm binary,
         * we can just fall back to the host arch native binary and
         * everything works fine.
         *
         * arm is different in that 32-on-64 _only_ works with
         * qemu-system-aarch64. So we have to add it to the kvmbins list
         */
1018
        if (hostarch == VIR_ARCH_AARCH64 && guestarch == VIR_ARCH_ARMV7L)
1019
            kvmbins[3] = "qemu-system-aarch64";
1020

1021
        for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
1022 1023 1024
            if (!kvmbins[i])
                continue;

1025
            kvmbin = virFindFileInPath(kvmbins[i]);
1026

1027 1028
            if (!kvmbin)
                continue;
1029

1030
            if (!(kvmbinCaps = virQEMUCapsCacheLookup(cache, kvmbin))) {
1031
                virResetLastError();
1032 1033 1034
                VIR_FREE(kvmbin);
                continue;
            }
1035

1036 1037
            if (!binary) {
                binary = kvmbin;
1038
                qemubinCaps = kvmbinCaps;
1039
                kvmbin = NULL;
1040
                kvmbinCaps = NULL;
1041
            }
1042
            break;
1043 1044 1045
        }
    }

1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
    ret = virQEMUCapsInitGuestFromBinary(caps,
                                         binary, qemubinCaps,
                                         kvmbin, kvmbinCaps,
                                         guestarch);

    VIR_FREE(binary);
    VIR_FREE(kvmbin);
    virObjectUnref(qemubinCaps);
    virObjectUnref(kvmbinCaps);

    return ret;
}

int
virQEMUCapsInitGuestFromBinary(virCapsPtr caps,
                               const char *binary,
                               virQEMUCapsPtr qemubinCaps,
                               const char *kvmbin,
                               virQEMUCapsPtr kvmbinCaps,
                               virArch guestarch)
{
    virCapsGuestPtr guest;
    bool haskvm = false;
    virCapsGuestMachinePtr *machines = NULL;
    size_t nmachines = 0;
    int ret = -1;
    bool hasdisksnapshot = false;

1074 1075 1076
    if (!binary)
        return 0;

1077
    if (virFileExists("/dev/kvm") &&
1078 1079
        (virQEMUCapsGet(qemubinCaps, QEMU_CAPS_KVM) ||
         virQEMUCapsGet(qemubinCaps, QEMU_CAPS_ENABLE_KVM) ||
1080
         kvmbin))
1081
        haskvm = true;
1082

1083
    if (virQEMUCapsGetMachineTypesCaps(qemubinCaps, &nmachines, &machines) < 0)
1084
        goto cleanup;
1085 1086 1087 1088

    /* We register kvm as the base emulator too, since we can
     * just give -no-kvm to disable acceleration if required */
    if ((guest = virCapabilitiesAddGuest(caps,
1089
                                         VIR_DOMAIN_OSTYPE_HVM,
1090
                                         guestarch,
1091 1092 1093 1094
                                         binary,
                                         NULL,
                                         nmachines,
                                         machines)) == NULL)
1095
        goto cleanup;
1096 1097 1098 1099

    machines = NULL;
    nmachines = 0;

A
Andrea Bolognani 已提交
1100 1101 1102
    /* CPU selection is always available, because all QEMU versions
     * we support can use at least '-cpu host' */
    if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false))
1103
        goto cleanup;
1104

1105
    if (virQEMUCapsGet(qemubinCaps, QEMU_CAPS_BOOTINDEX) &&
1106
        !virCapabilitiesAddGuestFeature(guest, "deviceboot", true, false))
1107
        goto cleanup;
1108

1109 1110 1111
    if (virQEMUCapsGet(qemubinCaps, QEMU_CAPS_DISK_SNAPSHOT))
        hasdisksnapshot = true;

1112 1113
    if (!virCapabilitiesAddGuestFeature(guest, "disksnapshot", hasdisksnapshot,
                                        false))
1114
        goto cleanup;
1115

D
Daniel P. Berrange 已提交
1116
    if (virCapabilitiesAddGuestDomain(guest,
1117
                                      VIR_DOMAIN_VIRT_QEMU,
D
Daniel P. Berrange 已提交
1118 1119 1120 1121
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
1122
        goto cleanup;
1123

D
Daniel P. Berrange 已提交
1124 1125
    if (haskvm) {
        virCapsGuestDomainPtr dom;
1126

D
Daniel P. Berrange 已提交
1127
        if (kvmbin &&
1128
            virQEMUCapsGetMachineTypesCaps(kvmbinCaps, &nmachines, &machines) < 0)
1129
            goto cleanup;
1130

D
Daniel P. Berrange 已提交
1131
        if ((dom = virCapabilitiesAddGuestDomain(guest,
1132
                                                 VIR_DOMAIN_VIRT_KVM,
D
Daniel P. Berrange 已提交
1133 1134 1135 1136
                                                 kvmbin ? kvmbin : binary,
                                                 NULL,
                                                 nmachines,
                                                 machines)) == NULL) {
1137
            goto cleanup;
D
Daniel P. Berrange 已提交
1138
        }
1139

D
Daniel P. Berrange 已提交
1140 1141
        machines = NULL;
        nmachines = 0;
1142
    }
1143

1144 1145 1146
    if ((ARCH_IS_X86(guestarch) || guestarch == VIR_ARCH_AARCH64) &&
        virCapabilitiesAddGuestFeature(guest, "acpi", true, true) == NULL) {
        goto cleanup;
1147 1148
    }

A
Andrea Bolognani 已提交
1149
    if (ARCH_IS_X86(guestarch) &&
1150
        virCapabilitiesAddGuestFeature(guest, "apic", true, false) == NULL) {
1151
        goto cleanup;
1152
    }
1153

1154
    if ((guestarch == VIR_ARCH_I686) &&
1155 1156
        (virCapabilitiesAddGuestFeature(guest, "pae", true, false) == NULL ||
         virCapabilitiesAddGuestFeature(guest, "nonpae", true, false) == NULL))
1157
        goto cleanup;
1158 1159 1160

    ret = 0;

1161
 cleanup:
1162 1163 1164

    virCapabilitiesFreeMachines(machines, nmachines);

1165
    return ret;
1166 1167 1168
}


1169
virCPUDefPtr
1170
virQEMUCapsProbeHostCPUForEmulator(virArch hostArch,
1171 1172 1173
                                   virQEMUCapsPtr qemuCaps,
                                   virDomainVirtType type)
{
1174 1175
    return virCPUGetHost(hostArch, VIR_CPU_TYPE_GUEST, NULL,
                         virQEMUCapsGetCPUDefinitions(qemuCaps, type));
1176 1177 1178
}


1179 1180
virCapsPtr
virQEMUCapsInit(virFileCachePtr cache)
1181 1182
{
    virCapsPtr caps;
1183
    size_t i;
T
Tal Kain 已提交
1184
    virArch hostarch = virArchFromHost();
1185

T
Tal Kain 已提交
1186
    if ((caps = virCapabilitiesNew(hostarch,
1187
                                   true, true)) == NULL)
1188
        goto error;
1189 1190 1191 1192 1193

    /* Some machines have problematic NUMA toplogy causing
     * unexpected failures. We don't want to break the QEMU
     * driver in this scenario, so log errors & carry on
     */
M
Martin Kletzander 已提交
1194
    if (virCapabilitiesInitNUMA(caps) < 0) {
1195
        virCapabilitiesFreeNUMAInfo(caps);
1196
        VIR_WARN("Failed to query host NUMA topology, disabling NUMA capabilities");
1197 1198
    }

1199 1200 1201
    if (virCapabilitiesInitCaches(caps) < 0)
        VIR_WARN("Failed to get host CPU cache info");

M
Martin Kletzander 已提交
1202
    if (!(caps->host.cpu = virCPUProbeHost(caps->host.arch)))
1203
        VIR_WARN("Failed to get host CPU");
1204

1205
    /* Add the power management features of the host */
1206
    if (virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0)
1207 1208
        VIR_WARN("Failed to get host power management capabilities");

M
Michal Privoznik 已提交
1209
    /* Add huge pages info */
1210
    if (virCapabilitiesInitPages(caps) < 0)
M
Michal Privoznik 已提交
1211 1212
        VIR_WARN("Failed to get pages info");

1213 1214 1215
    /* Add domain migration transport URIs */
    virCapabilitiesAddHostMigrateTransport(caps, "tcp");
    virCapabilitiesAddHostMigrateTransport(caps, "rdma");
1216

1217 1218 1219 1220
    /* 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
     */
1221
    for (i = 0; i < VIR_ARCH_LAST; i++)
1222
        if (virQEMUCapsInitGuest(caps, cache,
T
Tal Kain 已提交
1223
                                 hostarch,
1224
                                 i) < 0)
1225
            goto error;
1226 1227 1228

    return caps;

1229
 error:
1230
    virObjectUnref(caps);
1231 1232 1233 1234
    return NULL;
}


1235
static int
1236 1237 1238 1239
virQEMUCapsComputeCmdFlags(const char *help,
                           unsigned int version,
                           virQEMUCapsPtr qemuCaps,
                           bool check_yajl ATTRIBUTE_UNUSED)
1240 1241
{
    const char *p;
R
Richa Marwaha 已提交
1242
    const char *fsdev, *netdev;
1243
    const char *cache;
1244 1245

    if (strstr(help, "-no-kvm"))
1246
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_KVM);
1247
    if (strstr(help, "-enable-kvm"))
1248
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_ENABLE_KVM);
1249 1250
    if (strstr(help, ",process="))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NAME_PROCESS);
1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265

    cache = strstr(help, "cache=");
    if (cache && (p = strchr(cache, ']'))) {
        if (memmem(cache, p - cache, "directsync", sizeof("directsync") - 1))
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
        if (memmem(cache, p - cache, "unsafe", sizeof("unsafe") - 1))
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE);
    }
    if (strstr(help, "aio=threads|native"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_AIO);
    if (strstr(help, "copy-on-read=on|off"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ);
    if (strstr(help, "bps="))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE);

P
Paolo Bonzini 已提交
1266 1267
    if (strstr(help, "-display"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DISPLAY);
1268 1269 1270
    if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) {
        const char *nl = strstr(p, "\n");
        if ((p = strstr(p, "|none")) && p < nl)
1271
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_VGA_NONE);
1272 1273
    }
    if (strstr(help, "-spice"))
1274
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SPICE);
1275
    if (strstr(help, "-vnc"))
1276
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC);
1277
    if (strstr(help, "seamless-migration="))
1278
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION);
1279
    if (strstr(help, "boot=on"))
1280
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_BOOT);
1281
    if (strstr(help, "serial=s"))
1282
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL);
1283 1284
    if (strstr(help, "host=[seg:]bus"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_HOST_PCI_MULTIDOMAIN);
1285
    if (strstr(help, "-mem-path"))
1286
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MEM_PATH);
1287 1288 1289 1290
    if (strstr(help, "-chardev spicevmc"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC);
    if (strstr(help, "-chardev spiceport"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEPORT);
1291
    if (strstr(help, "-nodefconfig"))
1292
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NODEFCONFIG);
1293
    if (strstr(help, "-no-user-config"))
1294
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG);
1295 1296
    /* The trailing ' ' is important to avoid a bogus match */
    if (strstr(help, "-rtc "))
1297
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_RTC);
1298 1299
    /* to wit */
    if (strstr(help, "-rtc-td-hack"))
1300
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_RTC_TD_HACK);
1301
    if (strstr(help, "-no-hpet"))
1302
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_HPET);
1303
    if (strstr(help, "-no-acpi"))
1304
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI);
1305
    if (strstr(help, "-no-kvm-pit-reinjection"))
1306
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT);
1307
    if (strstr(help, "-tdf"))
1308
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_TDF);
1309
    if (strstr(help, "-enable-nesting"))
1310
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NESTING);
1311
    if (strstr(help, ",menu=on"))
1312
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_BOOT_MENU);
1313
    if (strstr(help, ",reboot-timeout=rb_time"))
1314
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_REBOOT_TIMEOUT);
1315 1316
    if (strstr(help, ",splash-time=sp_time"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SPLASH_TIMEOUT);
1317
    if ((fsdev = strstr(help, "-fsdev"))) {
1318
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV);
1319
        if (strstr(fsdev, "readonly"))
1320
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV_READONLY);
1321
        if (strstr(fsdev, "writeout"))
1322
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT);
1323
    }
1324
    if (strstr(help, "-smbios type"))
1325
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE);
1326
    if (strstr(help, "-sandbox"))
1327
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX);
1328

R
Richa Marwaha 已提交
1329
    if ((netdev = strstr(help, "-netdev"))) {
1330 1331
        /* Disable -netdev on 0.12 since although it exists,
         * the corresponding netdev_add/remove monitor commands
1332
         * do not, and we need them to be able to do hotplug. */
R
Richa Marwaha 已提交
1333 1334
        if (version >= 13000) {
            if (strstr(netdev, "bridge"))
1335
                virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE);
1336
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV);
R
Richa Marwaha 已提交
1337
        }
1338 1339 1340
    }

    if (strstr(help, "-sdl"))
1341
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_SDL);
1342

1343
    if (strstr(help, ",vhost="))
1344
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOST_NET);
1345

1346 1347
    /* Do not use -no-shutdown if qemu doesn't support it or SIGTERM handling
     * is most likely buggy when used with -no-shutdown (which applies for qemu
1348
     * 0.14.* and 0.15.0)
1349
     */
1350
    if (strstr(help, "-no-shutdown") && (version < 14000 || version > 15000))
1351
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN);
1352

1353
    if (strstr(help, "dump-guest-core=on|off"))
1354
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE);
1355

O
Olivia Yin 已提交
1356 1357 1358
    if (strstr(help, "-dtb"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DTB);

1359 1360 1361
    if (strstr(help, "-machine"))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_OPT);

1362 1363 1364
    /* While JSON mode was available in 0.12.0, it was too
     * incomplete to contemplate using. The 0.13.0 release
     * is good enough to use, even though it lacks one or
1365
     * two features. */
1366
#if WITH_YAJL
1367
    if (version >= 13000)
1368
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MONITOR_JSON);
1369 1370 1371 1372 1373
#else
    /* Starting with qemu 0.15 and newer, upstream qemu no longer
     * promises to keep the human interface stable, but requests that
     * we use QMP (the JSON interface) for everything.  If the user
     * forgot to include YAJL libraries when building their own
M
Martin Kletzander 已提交
1374
     * libvirt but is targeting a newer qemu, we are better off
1375
     * telling them to recompile (the spec file includes the
1376
     * dependency, so distros won't hit this).  This check is
1377
     * also in m4/virt-yajl.m4 (see $with_yajl).  */
1378
    if (version >= 15000) {
1379
        if (check_yajl) {
1380 1381 1382
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("this qemu binary requires libvirt to be "
                             "compiled with yajl"));
1383 1384
            return -1;
        }
1385
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV);
1386
    }
E
Eric Blake 已提交
1387
#endif
1388 1389

    if (version >= 13000)
1390
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION);
1391

1392
    if (version >= 1001000) {
J
Ján Tomko 已提交
1393
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION);
1394 1395
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_SHARE_POLICY);
    }
J
Ján Tomko 已提交
1396

1397
    return 0;
1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423
}

/* We parse the output of 'qemu -help' to get the QEMU
 * version number. The first bit is easy, just parse
 * 'QEMU PC emulator version x.y.z'
 * or
 * 'QEMU emulator version x.y.z'.
 *
 * With qemu-kvm, however, that is followed by a string
 * in parenthesis as follows:
 *  - qemu-kvm-x.y.z in stable releases
 *  - kvm-XX for kvm versions up to kvm-85
 *  - qemu-kvm-devel-XX for kvm version kvm-86 and later
 *
 * For qemu-kvm versions before 0.10.z, we need to detect
 * the KVM version number for some features. With 0.10.z
 * and later, we just need the QEMU version number and
 * whether it is KVM QEMU or mainline QEMU.
 */
#define QEMU_VERSION_STR_1  "QEMU emulator version"
#define QEMU_VERSION_STR_2  "QEMU PC emulator version"
#define QEMU_KVM_VER_PREFIX "(qemu-kvm-"
#define KVM_VER_PREFIX      "(kvm-"

#define SKIP_BLANKS(p) do { while ((*(p) == ' ') || (*(p) == '\t')) (p)++; } while (0)

1424 1425 1426 1427
int virQEMUCapsParseHelpStr(const char *qemu,
                            const char *help,
                            virQEMUCapsPtr qemuCaps,
                            unsigned int *version,
1428
                            bool *is_kvm,
1429
                            unsigned int *kvm_version,
1430 1431
                            bool check_yajl,
                            const char *qmperr)
1432 1433 1434
{
    unsigned major, minor, micro;
    const char *p = help;
1435
    char *strflags;
1436

1437 1438
    *version = *kvm_version = 0;
    *is_kvm = false;
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455

    if (STRPREFIX(p, QEMU_VERSION_STR_1))
        p += strlen(QEMU_VERSION_STR_1);
    else if (STRPREFIX(p, QEMU_VERSION_STR_2))
        p += strlen(QEMU_VERSION_STR_2);
    else
        goto fail;

    SKIP_BLANKS(p);

    major = virParseNumber(&p);
    if (major == -1 || *p != '.')
        goto fail;

    ++p;

    minor = virParseNumber(&p);
J
Jiri Denemark 已提交
1456
    if (minor == -1)
1457 1458
        goto fail;

J
Jiri Denemark 已提交
1459 1460 1461 1462 1463 1464 1465 1466
    if (*p != '.') {
        micro = 0;
    } else {
        ++p;
        micro = virParseNumber(&p);
        if (micro == -1)
            goto fail;
    }
1467 1468 1469 1470

    SKIP_BLANKS(p);

    if (STRPREFIX(p, QEMU_KVM_VER_PREFIX)) {
1471
        *is_kvm = true;
1472 1473 1474 1475
        p += strlen(QEMU_KVM_VER_PREFIX);
    } else if (STRPREFIX(p, KVM_VER_PREFIX)) {
        int ret;

1476
        *is_kvm = true;
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487
        p += strlen(KVM_VER_PREFIX);

        ret = virParseNumber(&p);
        if (ret == -1)
            goto fail;

        *kvm_version = ret;
    }

    *version = (major * 1000 * 1000) + (minor * 1000) + micro;

1488 1489 1490 1491 1492 1493 1494
    if (*version < 12000) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("QEMU version >= 0.12.00 is required, but %d.%d.%d found"),
                       major, minor, micro);
        goto cleanup;
    }

1495 1496 1497 1498
    /* Refuse to parse -help output for QEMU releases >= 1.2.0 that should be
     * using QMP probing.
     */
    if (*version >= 1002000) {
1499 1500 1501 1502 1503 1504 1505 1506 1507
        if (qmperr && *qmperr) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("QEMU / QMP failed: %s"),
                           qmperr);
        } else {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("QEMU %u.%u.%u is too new for help parsing"),
                           major, minor, micro);
        }
1508 1509 1510
        goto cleanup;
    }

1511
    if (virQEMUCapsComputeCmdFlags(help, *version,
1512
                                   qemuCaps, check_yajl) < 0)
1513
        goto cleanup;
1514

1515
    strflags = virBitmapToString(qemuCaps->flags, true, false);
1516 1517 1518
    VIR_DEBUG("Version %u.%u.%u, cooked version %u, flags %s",
              major, minor, micro, *version, NULLSTR(strflags));
    VIR_FREE(strflags);
1519 1520 1521 1522 1523 1524 1525 1526

    if (*kvm_version)
        VIR_DEBUG("KVM version %d detected", *kvm_version);
    else if (*is_kvm)
        VIR_DEBUG("qemu-kvm version %u.%u.%u detected", major, minor, micro);

    return 0;

1527
 fail:
1528
    p = strchr(help, '\n');
1529 1530
    if (!p)
        p = strchr(help, '\0');
1531

1532 1533 1534
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot parse %s version number in '%.*s'"),
                   qemu, (int) (p - help), help);
1535

1536
 cleanup:
1537 1538 1539
    return -1;
}

1540

1541
struct virQEMUCapsStringFlags {
1542 1543 1544 1545 1546
    const char *value;
    int flag;
};


1547 1548 1549
struct virQEMUCapsStringFlags virQEMUCapsCommands[] = {
    { "system_wakeup", QEMU_CAPS_WAKEUP },
    { "transaction", QEMU_CAPS_TRANSACTION },
1550
    { "block-stream", QEMU_CAPS_BLOCKJOB_ASYNC },
1551 1552 1553 1554 1555 1556 1557 1558 1559
    { "dump-guest-memory", QEMU_CAPS_DUMP_GUEST_MEMORY },
    { "query-spice", QEMU_CAPS_SPICE },
    { "query-kvm", QEMU_CAPS_KVM },
    { "block-commit", QEMU_CAPS_BLOCK_COMMIT },
    { "query-vnc", QEMU_CAPS_VNC },
    { "drive-mirror", QEMU_CAPS_DRIVE_MIRROR },
    { "blockdev-snapshot-sync", QEMU_CAPS_DISK_SNAPSHOT },
    { "add-fd", QEMU_CAPS_ADD_FD },
    { "nbd-server-start", QEMU_CAPS_NBD_SERVER },
1560
    { "change-backing-file", QEMU_CAPS_CHANGE_BACKING_FILE },
1561
    { "rtc-reset-reinjection", QEMU_CAPS_RTC_RESET_REINJECTION },
1562
    { "migrate-incoming", QEMU_CAPS_INCOMING_DEFER },
1563
    { "query-hotpluggable-cpus", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS },
1564 1565
    { "query-qmp-schema", QEMU_CAPS_QUERY_QMP_SCHEMA },
    { "query-cpu-model-expansion", QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION},
1566
    { "query-cpu-definitions", QEMU_CAPS_QUERY_CPU_DEFINITIONS},
1567
    { "query-named-block-nodes", QEMU_CAPS_QUERY_NAMED_BLOCK_NODES}
1568 1569
};

1570 1571 1572 1573
struct virQEMUCapsStringFlags virQEMUCapsMigration[] = {
    { "rdma-pin-all", QEMU_CAPS_MIGRATE_RDMA },
};

1574 1575 1576
struct virQEMUCapsStringFlags virQEMUCapsEvents[] = {
    { "BALLOON_CHANGE", QEMU_CAPS_BALLOON_EVENT },
    { "SPICE_MIGRATE_COMPLETED", QEMU_CAPS_SEAMLESS_MIGRATION },
1577
    { "DEVICE_DELETED", QEMU_CAPS_DEVICE_DEL_EVENT },
1578
    { "MIGRATION", QEMU_CAPS_MIGRATION_EVENT },
1579
    { "VSERPORT_CHANGE", QEMU_CAPS_VSERPORT_CHANGE },
1580
    { "DEVICE_TRAY_MOVED", QEMU_CAPS_DEVICE_TRAY_MOVED },
1581
    { "BLOCK_WRITE_THRESHOLD", QEMU_CAPS_BLOCK_WRITE_THRESHOLD },
1582 1583
};

1584
struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599
    { "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 },
1600
    { "virtio-blk-ccw", QEMU_CAPS_VIRTIO_CCW },
1601
    { "sclpconsole", QEMU_CAPS_SCLP_S390 },
1602
    { "lsi53c895a", QEMU_CAPS_SCSI_LSI },
1603
    { "virtio-scsi-pci", QEMU_CAPS_VIRTIO_SCSI },
1604 1605
    { "virtio-scsi-s390", QEMU_CAPS_VIRTIO_SCSI },
    { "virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI },
1606
    { "virtio-scsi-device", QEMU_CAPS_VIRTIO_SCSI },
1607
    { "megasas", QEMU_CAPS_SCSI_MEGASAS },
1608
    { "spicevmc", QEMU_CAPS_DEVICE_SPICEVMC },
1609
    { "qxl", QEMU_CAPS_DEVICE_QXL },
1610 1611 1612 1613
    { "sga", QEMU_CAPS_SGA },
    { "scsi-block", QEMU_CAPS_SCSI_BLOCK },
    { "scsi-cd", QEMU_CAPS_SCSI_CD },
    { "ide-cd", QEMU_CAPS_IDE_CD },
1614 1615 1616
    { "VGA", QEMU_CAPS_DEVICE_VGA },
    { "cirrus-vga", QEMU_CAPS_DEVICE_CIRRUS_VGA },
    { "vmware-svga", QEMU_CAPS_DEVICE_VMWARE_SVGA },
H
Han Cheng 已提交
1617 1618
    { "usb-serial", QEMU_CAPS_DEVICE_USB_SERIAL },
    { "usb-net", QEMU_CAPS_DEVICE_USB_NET },
1619
    { "virtio-rng-pci", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1620 1621
    { "virtio-rng-s390", QEMU_CAPS_DEVICE_VIRTIO_RNG },
    { "virtio-rng-ccw", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1622
    { "virtio-rng-device", QEMU_CAPS_DEVICE_VIRTIO_RNG },
1623
    { "rng-random", QEMU_CAPS_OBJECT_RNG_RANDOM },
1624
    { "rng-egd", QEMU_CAPS_OBJECT_RNG_EGD },
1625
    { "spapr-nvram", QEMU_CAPS_DEVICE_NVRAM },
1626
    { "pci-bridge", QEMU_CAPS_DEVICE_PCI_BRIDGE },
1627
    { "vfio-pci", QEMU_CAPS_DEVICE_VFIO_PCI },
H
Han Cheng 已提交
1628
    { "scsi-generic", QEMU_CAPS_DEVICE_SCSI_GENERIC },
1629
    { "i82801b11-bridge", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE },
1630
    { "usb-storage", QEMU_CAPS_DEVICE_USB_STORAGE },
1631
    { "virtio-mmio", QEMU_CAPS_DEVICE_VIRTIO_MMIO },
1632
    { "ich9-intel-hda", QEMU_CAPS_DEVICE_ICH9_INTEL_HDA },
H
Hu Tao 已提交
1633
    { "pvpanic", QEMU_CAPS_DEVICE_PANIC },
L
Li Zhang 已提交
1634
    { "usb-kbd", QEMU_CAPS_DEVICE_USB_KBD },
1635
    { "memory-backend-ram", QEMU_CAPS_OBJECT_MEMORY_RAM },
1636
    { "memory-backend-file", QEMU_CAPS_OBJECT_MEMORY_FILE },
1637
    { "usb-audio", QEMU_CAPS_OBJECT_USB_AUDIO },
J
John Ferlan 已提交
1638
    { "iothread", QEMU_CAPS_OBJECT_IOTHREAD},
1639
    { "ivshmem", QEMU_CAPS_DEVICE_IVSHMEM },
1640
    { "pc-dimm", QEMU_CAPS_DEVICE_PC_DIMM },
M
Michal Privoznik 已提交
1641
    { "pci-serial", QEMU_CAPS_DEVICE_PCI_SERIAL },
1642
    { "gpex-pcihost", QEMU_CAPS_OBJECT_GPEX},
1643
    { "ioh3420", QEMU_CAPS_DEVICE_IOH3420 },
1644
    { "x3130-upstream", QEMU_CAPS_DEVICE_X3130_UPSTREAM },
1645
    { "xio3130-downstream", QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM },
1646
    { "rtl8139", QEMU_CAPS_DEVICE_RTL8139 },
1647
    { "e1000", QEMU_CAPS_DEVICE_E1000 },
1648 1649 1650 1651
    { "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 已提交
1652 1653
    { "virtio-gpu-pci", QEMU_CAPS_DEVICE_VIRTIO_GPU },
    { "virtio-gpu-device", QEMU_CAPS_DEVICE_VIRTIO_GPU },
1654
    { "virtio-vga", QEMU_CAPS_DEVICE_VIRTIO_VGA },
1655 1656 1657 1658 1659 1660
    { "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 },
1661 1662
    { "virtio-input-host-device", QEMU_CAPS_VIRTIO_INPUT_HOST },
    { "virtio-input-host-pci", QEMU_CAPS_VIRTIO_INPUT_HOST },
1663
    { "mptsas1068", QEMU_CAPS_SCSI_MPTSAS1068 },
1664
    { "secret", QEMU_CAPS_OBJECT_SECRET },
1665
    { "pxb", QEMU_CAPS_DEVICE_PXB },
1666
    { "pxb-pcie", QEMU_CAPS_DEVICE_PXB_PCIE },
1667
    { "tls-creds-x509", QEMU_CAPS_OBJECT_TLS_CREDS_X509 },
J
Ján Tomko 已提交
1668
    { "intel-iommu", QEMU_CAPS_DEVICE_INTEL_IOMMU },
1669 1670
    { "ivshmem-plain", QEMU_CAPS_DEVICE_IVSHMEM_PLAIN },
    { "ivshmem-doorbell", QEMU_CAPS_DEVICE_IVSHMEM_DOORBELL },
1671
    { "vhost-scsi", QEMU_CAPS_DEVICE_VHOST_SCSI },
1672
    { "nvdimm", QEMU_CAPS_DEVICE_NVDIMM },
1673
    { "pcie-root-port", QEMU_CAPS_DEVICE_PCIE_ROOT_PORT },
1674
    { "qemu-xhci", QEMU_CAPS_DEVICE_QEMU_XHCI },
1675
    { "spapr-pci-host-bridge", QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE },
M
Marc-André Lureau 已提交
1676
    { "vmcoreinfo", QEMU_CAPS_DEVICE_VMCOREINFO },
1677
    { "spapr-vty", QEMU_CAPS_DEVICE_SPAPR_VTY },
1678 1679
};

1680 1681 1682 1683
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBalloon[] = {
    { "deflate-on-oom", QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE },
};

1684
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = {
1685 1686 1687 1688 1689 1690
    { "multifunction", QEMU_CAPS_PCI_MULTIFUNCTION },
    { "bootindex", QEMU_CAPS_BOOTINDEX },
    { "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 },
1691
    { "num-queues", QEMU_CAPS_VIRTIO_BLK_NUM_QUEUES },
1692 1693
};

1694
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioNet[] = {
1695 1696
    { "tx", QEMU_CAPS_VIRTIO_TX_ALG },
    { "event_idx", QEMU_CAPS_VIRTIO_NET_EVENT_IDX },
1697
    { "rx_queue_size", QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE },
1698
    { "tx_queue_size", QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE },
1699
    { "host_mtu", QEMU_CAPS_VIRTIO_NET_HOST_MTU },
1700 1701
};

1702 1703 1704 1705
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSpaprPCIHostBridge[] = {
    { "numa_node", QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE },
};

1706 1707 1708 1709
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioSCSI[] = {
    { "iothread", QEMU_CAPS_VIRTIO_SCSI_IOTHREAD },
};

1710
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsPCIAssign[] = {
1711 1712 1713 1714
    { "configfd", QEMU_CAPS_PCI_CONFIGFD },
    { "bootindex", QEMU_CAPS_PCI_BOOTINDEX },
};

1715
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVfioPCI[] = {
1716 1717 1718
    { "bootindex", QEMU_CAPS_VFIO_PCI_BOOTINDEX },
};

1719
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSCSIDisk[] = {
1720 1721 1722 1723
    { "channel", QEMU_CAPS_SCSI_DISK_CHANNEL },
    { "wwn", QEMU_CAPS_SCSI_DISK_WWN },
};

1724
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsIDEDrive[] = {
1725 1726 1727
    { "wwn", QEMU_CAPS_IDE_DRIVE_WWN },
};

1728
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsPiix4PM[] = {
1729 1730
    { "disable_s3", QEMU_CAPS_PIIX_DISABLE_S3 },
    { "disable_s4", QEMU_CAPS_PIIX_DISABLE_S4 },
1731 1732
};

1733
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBRedir[] = {
1734
    { "filter", QEMU_CAPS_USB_REDIR_FILTER },
1735 1736 1737
    { "bootindex", QEMU_CAPS_USB_REDIR_BOOTINDEX },
};

1738
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBHost[] = {
1739
    { "bootindex", QEMU_CAPS_USB_HOST_BOOTINDEX },
1740 1741
};

1742
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSCSIGeneric[] = {
H
Han Cheng 已提交
1743 1744 1745
    { "bootindex", QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX },
};

1746
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsI440FXPCIHost[] = {
1747 1748 1749
    { "pci-hole64-size", QEMU_CAPS_I440FX_PCI_HOLE64_SIZE },
};

1750
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsQ35PCIHost[] = {
1751 1752 1753
    { "pci-hole64-size", QEMU_CAPS_Q35_PCI_HOLE64_SIZE },
};

1754
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBStorage[] = {
1755 1756 1757
    { "removable", QEMU_CAPS_USB_STORAGE_REMOVABLE },
};

1758 1759 1760 1761
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsKVMPit[] = {
    { "lost_tick_policy", QEMU_CAPS_KVM_PIT_TICK_POLICY },
};

1762 1763 1764 1765 1766 1767 1768 1769 1770 1771
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVGA[] = {
    { "vgamem_mb", QEMU_CAPS_VGA_VGAMEM },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVmwareSvga[] = {
    { "vgamem_mb", QEMU_CAPS_VMWARE_SVGA_VGAMEM },
};

static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsQxl[] = {
    { "vgamem_mb", QEMU_CAPS_QXL_VGAMEM },
1772
    { "vram64_size_mb", QEMU_CAPS_QXL_VRAM64 },
1773
    { "max_outputs", QEMU_CAPS_QXL_MAX_OUTPUTS },
1774 1775
};

1776
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioGpu[] = {
1777
    { "virgl", QEMU_CAPS_VIRTIO_GPU_VIRGL },
1778
    { "max_outputs", QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS },
1779 1780
};

1781 1782 1783 1784 1785
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsICH9[] = {
    { "disable_s3", QEMU_CAPS_ICH9_DISABLE_S3 },
    { "disable_s4", QEMU_CAPS_ICH9_DISABLE_S4 },
};

1786 1787 1788 1789
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsUSBNECXHCI[] = {
    { "p3", QEMU_CAPS_NEC_USB_XHCI_PORTS },
};

1790 1791
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsIntelIOMMU[] = {
    { "intremap", QEMU_CAPS_INTEL_IOMMU_INTREMAP },
1792
    { "caching-mode", QEMU_CAPS_INTEL_IOMMU_CACHING_MODE },
1793
    { "eim", QEMU_CAPS_INTEL_IOMMU_EIM },
1794
    { "device-iotlb", QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB },
1795 1796
};

1797 1798
/* see documentation for virQEMUCapsQMPSchemaGetByPath for the query format */
static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
1799
    { "blockdev-add/arg-type/options/+gluster/debug-level", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
1800
    { "blockdev-add/arg-type/+gluster/debug", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
J
John Ferlan 已提交
1801
    { "blockdev-add/arg-type/+vxhs", QEMU_CAPS_VXHS},
1802 1803
};

1804
struct virQEMUCapsObjectTypeProps {
1805
    const char *type;
1806
    struct virQEMUCapsStringFlags *props;
1807
    size_t nprops;
1808
    int capsCondition;
1809 1810
};

1811 1812
static struct virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
    { "virtio-blk-pci", virQEMUCapsObjectPropsVirtioBlk,
1813 1814
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk),
      -1 },
1815
    { "virtio-net-pci", virQEMUCapsObjectPropsVirtioNet,
1816 1817
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet),
      -1 },
1818
    { "virtio-scsi-pci", virQEMUCapsObjectPropsVirtioSCSI,
1819 1820
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioSCSI),
      -1 },
1821
    { "virtio-blk-ccw", virQEMUCapsObjectPropsVirtioBlk,
1822 1823
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk),
      -1 },
1824
    { "virtio-net-ccw", virQEMUCapsObjectPropsVirtioNet,
1825 1826
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet),
      -1 },
1827
    { "virtio-scsi-ccw", virQEMUCapsObjectPropsVirtioSCSI,
1828 1829
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioSCSI),
      -1 },
1830
    { "virtio-blk-s390", virQEMUCapsObjectPropsVirtioBlk,
1831 1832
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBlk),
      -1 },
1833
    { "virtio-net-s390", virQEMUCapsObjectPropsVirtioNet,
1834 1835
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioNet),
      -1 },
1836
    { "pci-assign", virQEMUCapsObjectPropsPCIAssign,
1837 1838
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsPCIAssign),
      -1 },
1839
    { "kvm-pci-assign", virQEMUCapsObjectPropsPCIAssign,
1840 1841
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsPCIAssign),
      -1 },
1842
    { "vfio-pci", virQEMUCapsObjectPropsVfioPCI,
1843 1844
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVfioPCI),
      -1 },
1845
    { "scsi-disk", virQEMUCapsObjectPropsSCSIDisk,
1846 1847
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsSCSIDisk),
      -1 },
1848
    { "ide-drive", virQEMUCapsObjectPropsIDEDrive,
1849 1850
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsIDEDrive),
      -1 },
1851
    { "PIIX4_PM", virQEMUCapsObjectPropsPiix4PM,
1852 1853
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsPiix4PM),
      -1 },
1854
    { "usb-redir", virQEMUCapsObjectPropsUSBRedir,
1855 1856
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBRedir),
      -1 },
1857
    { "usb-host", virQEMUCapsObjectPropsUSBHost,
1858 1859
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBHost),
      -1 },
1860
    { "scsi-generic", virQEMUCapsObjectPropsSCSIGeneric,
1861 1862
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsSCSIGeneric),
      -1 },
1863
    { "i440FX-pcihost", virQEMUCapsObjectPropsI440FXPCIHost,
1864 1865
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsI440FXPCIHost),
      -1 },
1866
    { "q35-pcihost", virQEMUCapsObjectPropsQ35PCIHost,
1867 1868
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsQ35PCIHost),
      -1 },
1869
    { "usb-storage", virQEMUCapsObjectPropsUSBStorage,
1870 1871
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBStorage),
      -1 },
1872
    { "kvm-pit", virQEMUCapsObjectPropsKVMPit,
1873 1874
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsKVMPit),
      -1 },
1875
    { "VGA", virQEMUCapsObjectPropsVGA,
1876 1877
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVGA),
      -1 },
1878
    { "vmware-svga", virQEMUCapsObjectPropsVmwareSvga,
1879 1880
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVmwareSvga),
      -1 },
1881
    { "qxl", virQEMUCapsObjectPropsQxl,
1882 1883
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsQxl),
      -1 },
1884
    { "virtio-gpu-pci", virQEMUCapsObjectPropsVirtioGpu,
1885 1886
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioGpu),
      -1 },
1887
    { "virtio-gpu-device", virQEMUCapsObjectPropsVirtioGpu,
1888 1889
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioGpu),
      -1 },
1890
    { "ICH9-LPC", virQEMUCapsObjectPropsICH9,
1891 1892
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsICH9),
      -1 },
1893
    { "virtio-balloon-pci", virQEMUCapsObjectPropsVirtioBalloon,
1894 1895
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon),
      -1 },
1896
    { "virtio-balloon-ccw", virQEMUCapsObjectPropsVirtioBalloon,
1897 1898
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon),
      -1 },
1899
    { "virtio-balloon-device", virQEMUCapsObjectPropsVirtioBalloon,
1900 1901
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsVirtioBalloon),
      -1 },
1902
    { "nec-usb-xhci", virQEMUCapsObjectPropsUSBNECXHCI,
1903 1904
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsUSBNECXHCI),
      -1 },
1905 1906
    { "intel-iommu", virQEMUCapsObjectPropsIntelIOMMU,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsIntelIOMMU),
1907
      QEMU_CAPS_DEVICE_INTEL_IOMMU },
1908 1909 1910
    { "spapr-pci-host-bridge", virQEMUCapsObjectPropsSpaprPCIHostBridge,
      ARRAY_CARDINALITY(virQEMUCapsObjectPropsSpaprPCIHostBridge),
      QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE },
1911 1912
};

1913 1914 1915 1916 1917 1918
struct virQEMUCapsPropTypeObjects {
    const char *prop;
    int flag;
    const char **objects;
};

1919
static const char *virQEMUCapsVirtioPCIObjects[] = {
1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937
     "virtio-balloon-pci",
     "virtio-blk-pci",
     "virtio-scsi-pci",
     "virtio-serial-pci",
     "virtio-9p-pci",
     "virtio-net-pci",
     "virtio-rng-pci",
     "virtio-gpu-pci",
     "virtio-input-host-pci",
     "virtio-keyboard-pci",
     "virtio-mouse-pci",
     "virtio-tablet-pci",
     NULL
};

static struct virQEMUCapsPropTypeObjects virQEMUCapsPropObjects[] = {
    { "disable-legacy",
      QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY,
1938 1939 1940 1941 1942 1943 1944
      virQEMUCapsVirtioPCIObjects },
    { "iommu_platform",
      QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM,
      virQEMUCapsVirtioPCIObjects },
    { "ats",
      QEMU_CAPS_VIRTIO_PCI_ATS,
      virQEMUCapsVirtioPCIObjects },
1945 1946
};

1947 1948

static void
1949 1950 1951 1952 1953
virQEMUCapsProcessStringFlags(virQEMUCapsPtr qemuCaps,
                              size_t nflags,
                              struct virQEMUCapsStringFlags *flags,
                              size_t nvalues,
                              char *const*values)
1954 1955
{
    size_t i, j;
1956 1957
    for (i = 0; i < nflags; i++) {
        for (j = 0; j < nvalues; j++) {
1958
            if (STREQ(values[j], flags[i].value)) {
1959
                virQEMUCapsSet(qemuCaps, flags[i].flag);
1960 1961 1962 1963 1964 1965 1966
                break;
            }
        }
    }
}


1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982
static void
virQEMUCapsProcessProps(virQEMUCapsPtr qemuCaps,
                        size_t nprops,
                        struct virQEMUCapsPropTypeObjects *props,
                        const char *object,
                        size_t nvalues,
                        char *const*values)
{
    size_t i, j;

    for (i = 0; i < nprops; i++) {
        if (virQEMUCapsGet(qemuCaps, props[i].flag))
            continue;

        for (j = 0; j < nvalues; j++) {
            if (STREQ(values[j], props[i].prop)) {
1983
                if (virStringListHasString(props[i].objects, object))
1984 1985 1986 1987 1988 1989 1990 1991
                    virQEMUCapsSet(qemuCaps, props[i].flag);
                break;
            }
        }
    }
}


1992 1993 1994
#define OBJECT_TYPE_PREFIX "name \""

static int
1995 1996
virQEMUCapsParseDeviceStrObjectTypes(const char *str,
                                     char ***types)
1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
{
    const char *tmp = str;
    int ret = -1;
    size_t ntypelist = 0;
    char **typelist = NULL;

    *types = NULL;

    while ((tmp = strstr(tmp, OBJECT_TYPE_PREFIX))) {
        char *end;
        tmp += strlen(OBJECT_TYPE_PREFIX);
        end = strstr(tmp, "\"");
        if (!end) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Malformed QEMU device list string, missing quote"));
            goto cleanup;
        }

2015
        if (VIR_EXPAND_N(typelist, ntypelist, 1) < 0)
2016
            goto cleanup;
2017
        if (VIR_STRNDUP(typelist[ntypelist - 1], tmp, end-tmp) < 0)
2018 2019 2020 2021 2022 2023
            goto cleanup;
    }

    *types = typelist;
    ret = ntypelist;

2024
 cleanup:
2025
    if (ret < 0)
2026
        virStringListFreeCount(typelist, ntypelist);
2027 2028 2029 2030 2031
    return ret;
}


static int
2032 2033 2034
virQEMUCapsParseDeviceStrObjectProps(const char *str,
                                     const char *type,
                                     char ***props)
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067
{
    const char *tmp = str;
    int ret = -1;
    size_t nproplist = 0;
    char **proplist = NULL;

    VIR_DEBUG("Extract type %s", type);
    *props = NULL;

    while ((tmp = strchr(tmp, '\n'))) {
        char *end;
        tmp += 1;

        if (*tmp == '\0')
            break;

        if (STRPREFIX(tmp, OBJECT_TYPE_PREFIX))
            continue;

        if (!STRPREFIX(tmp, type))
            continue;

        tmp += strlen(type);
        if (*tmp != '.')
            continue;
        tmp++;

        end = strstr(tmp, "=");
        if (!end) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Malformed QEMU device list string, missing '='"));
            goto cleanup;
        }
2068
        if (VIR_EXPAND_N(proplist, nproplist, 1) < 0)
2069
            goto cleanup;
2070
        if (VIR_STRNDUP(proplist[nproplist - 1], tmp, end-tmp) < 0)
2071 2072 2073 2074 2075 2076
            goto cleanup;
    }

    *props = proplist;
    ret = nproplist;

2077
 cleanup:
2078
    if (ret < 0)
2079
        virStringListFreeCount(proplist, nproplist);
2080 2081 2082 2083 2084
    return ret;
}


int
2085
virQEMUCapsParseDeviceStr(virQEMUCapsPtr qemuCaps, const char *str)
2086 2087 2088 2089 2090
{
    int nvalues;
    char **values;
    size_t i;

2091
    if ((nvalues = virQEMUCapsParseDeviceStrObjectTypes(str, &values)) < 0)
2092
        return -1;
2093 2094 2095 2096
    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsObjectTypes),
                                  virQEMUCapsObjectTypes,
                                  nvalues, values);
2097
    virStringListFreeCount(values, nvalues);
2098

2099
    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsObjectProps); i++) {
2100 2101 2102 2103
        const char *type = virQEMUCapsObjectProps[i].type;
        if ((nvalues = virQEMUCapsParseDeviceStrObjectProps(str,
                                                            type,
                                                            &values)) < 0)
2104
            return -1;
2105 2106 2107 2108
        virQEMUCapsProcessStringFlags(qemuCaps,
                                      virQEMUCapsObjectProps[i].nprops,
                                      virQEMUCapsObjectProps[i].props,
                                      nvalues, values);
2109
        virStringListFreeCount(values, nvalues);
2110 2111 2112
    }

    /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
2113 2114
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC))
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC);
2115 2116 2117 2118 2119

    return 0;
}


E
Eric Blake 已提交
2120
static int
2121 2122
virQEMUCapsExtractDeviceStr(const char *qemu,
                            virQEMUCapsPtr qemuCaps,
2123
                            uid_t runUid, gid_t runGid)
2124
{
E
Eric Blake 已提交
2125
    char *output = NULL;
2126
    virCommandPtr cmd;
E
Eric Blake 已提交
2127
    int ret = -1;
2128

E
Eric Blake 已提交
2129 2130
    /* Cram together all device-related queries into one invocation;
     * the output format makes it possible to distinguish what we
2131 2132
     * need.  With qemu 0.13.0 and later, unrecognized '-device
     * bogus,?' cause an error in isolation, but are silently ignored
2133
     * in combination with '-device ?'.  Upstream qemu 0.12.x doesn't
2134 2135
     * understand '-device name,?', and always exits with status 1 for
     * the simpler '-device ?', so this function is really only useful
2136
     * if -help includes "device driver,?".  */
2137
    cmd = virQEMUCapsProbeCommand(qemu, qemuCaps, runUid, runGid);
2138 2139 2140 2141 2142 2143
    virCommandAddArgList(cmd,
                         "-device", "?",
                         "-device", "pci-assign,?",
                         "-device", "virtio-blk-pci,?",
                         "-device", "virtio-net-pci,?",
                         "-device", "scsi-disk,?",
2144
                         "-device", "PIIX4_PM,?",
2145
                         "-device", "usb-redir,?",
2146
                         "-device", "ide-drive,?",
2147
                         "-device", "usb-host,?",
H
Han Cheng 已提交
2148
                         "-device", "scsi-generic,?",
2149
                         "-device", "usb-storage,?",
2150 2151 2152 2153
                         "-device", "VGA,?",
                         "-device", "vmware-svga,?",
                         "-device", "qxl,?",
                         "-device", "qxl-vga,?",
2154
                         NULL);
2155
    /* qemu -help goes to stdout, but qemu -device ? goes to stderr.  */
E
Eric Blake 已提交
2156
    virCommandSetErrorBuffer(cmd, &output);
2157

2158
    if (virCommandRun(cmd, NULL) < 0)
2159 2160
        goto cleanup;

2161
    ret = virQEMUCapsParseDeviceStr(qemuCaps, output);
2162

2163
 cleanup:
E
Eric Blake 已提交
2164
    VIR_FREE(output);
2165
    virCommandFree(cmd);
E
Eric Blake 已提交
2166 2167 2168
    return ret;
}

2169

2170
int virQEMUCapsGetDefaultVersion(virCapsPtr caps,
2171
                                 virFileCachePtr capsCache,
2172
                                 unsigned int *version)
2173
{
2174
    virQEMUCapsPtr qemucaps;
T
Tal Kain 已提交
2175
    virArch hostarch;
2176
    virCapsDomainDataPtr capsdata;
2177 2178 2179 2180

    if (*version > 0)
        return 0;

T
Tal Kain 已提交
2181
    hostarch = virArchFromHost();
2182 2183 2184
    if (!(capsdata = virCapabilitiesDomainDataLookup(caps,
            VIR_DOMAIN_OSTYPE_HVM, hostarch, VIR_DOMAIN_VIRT_QEMU,
            NULL, NULL))) {
2185
        virReportError(VIR_ERR_INTERNAL_ERROR,
2186
                       _("Cannot find suitable emulator for %s"),
T
Tal Kain 已提交
2187
                       virArchToString(hostarch));
2188 2189 2190
        return -1;
    }

2191
    qemucaps = virQEMUCapsCacheLookup(capsCache, capsdata->emulator);
2192 2193
    VIR_FREE(capsdata);
    if (!qemucaps)
2194 2195
        return -1;

2196
    *version = virQEMUCapsGetVersion(qemucaps);
2197
    virObjectUnref(qemucaps);
2198 2199
    return 0;
}
2200 2201


2202 2203


2204 2205
virQEMUCapsPtr
virQEMUCapsNew(void)
2206
{
2207
    virQEMUCapsPtr qemuCaps;
2208

2209
    if (virQEMUCapsInitialize() < 0)
2210 2211
        return NULL;

2212
    if (!(qemuCaps = virObjectNew(virQEMUCapsClass)))
2213 2214
        return NULL;

2215
    if (!(qemuCaps->flags = virBitmapNew(QEMU_CAPS_LAST)))
2216
        goto error;
2217

2218
    return qemuCaps;
2219

2220
 error:
2221
    virObjectUnref(qemuCaps);
2222
    return NULL;
2223 2224 2225
}


2226
static int
2227 2228
virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
                           virQEMUCapsHostCPUDataPtr src)
2229
{
2230 2231
    if (src->info &&
        !(dst->info = qemuMonitorCPUModelInfoCopy(src->info)))
2232 2233
        return -1;

2234 2235
    if (src->reported &&
        !(dst->reported = virCPUDefCopy(src->reported)))
2236 2237
        return -1;

2238 2239 2240 2241
    if (src->migratable &&
        !(dst->migratable = virCPUDefCopy(src->migratable)))
        return -1;

2242 2243 2244 2245
    if (src->full &&
        !(dst->full = virCPUDefCopy(src->full)))
        return -1;

2246 2247 2248 2249
    return 0;
}


2250
static void
2251
virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
2252
{
2253 2254
    qemuMonitorCPUModelInfoFree(cpuData->info);
    virCPUDefFree(cpuData->reported);
2255
    virCPUDefFree(cpuData->migratable);
2256
    virCPUDefFree(cpuData->full);
2257 2258

    memset(cpuData, 0, sizeof(*cpuData));
2259 2260 2261
}


2262
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
2263
{
2264
    virQEMUCapsPtr ret = virQEMUCapsNew();
2265 2266 2267 2268 2269
    size_t i;

    if (!ret)
        return NULL;

2270 2271
    ret->usedQMP = qemuCaps->usedQMP;

2272 2273 2274 2275 2276
    if (VIR_STRDUP(ret->binary, qemuCaps->binary) < 0)
        goto error;

    ret->ctime = qemuCaps->ctime;

2277
    virBitmapCopy(ret->flags, qemuCaps->flags);
2278

2279 2280
    ret->version = qemuCaps->version;
    ret->kvmVersion = qemuCaps->kvmVersion;
2281 2282 2283 2284

    if (VIR_STRDUP(ret->package, qemuCaps->package) < 0)
        goto error;

2285
    ret->arch = qemuCaps->arch;
2286

2287 2288 2289 2290 2291 2292 2293 2294 2295
    if (qemuCaps->kvmCPUModels) {
        ret->kvmCPUModels = virDomainCapsCPUModelsCopy(qemuCaps->kvmCPUModels);
        if (!ret->kvmCPUModels)
            goto error;
    }

    if (qemuCaps->tcgCPUModels) {
        ret->tcgCPUModels = virDomainCapsCPUModelsCopy(qemuCaps->tcgCPUModels);
        if (!ret->tcgCPUModels)
2296
            goto error;
2297 2298
    }

2299 2300
    if (virQEMUCapsHostCPUDataCopy(&ret->kvmCPU, &qemuCaps->kvmCPU) < 0 ||
        virQEMUCapsHostCPUDataCopy(&ret->tcgCPU, &qemuCaps->tcgCPU) < 0)
2301 2302
        goto error;

2303
    if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
2304
        goto error;
2305
    ret->nmachineTypes = qemuCaps->nmachineTypes;
2306
    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2307 2308
        if (VIR_STRDUP(ret->machineTypes[i].name, qemuCaps->machineTypes[i].name) < 0 ||
            VIR_STRDUP(ret->machineTypes[i].alias, qemuCaps->machineTypes[i].alias) < 0)
2309
            goto error;
2310
        ret->machineTypes[i].maxCpus = qemuCaps->machineTypes[i].maxCpus;
2311
        ret->machineTypes[i].hotplugCpus = qemuCaps->machineTypes[i].hotplugCpus;
2312 2313
    }

2314 2315 2316 2317 2318 2319
    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];

2320 2321
    return ret;

2322
 error:
2323 2324 2325 2326 2327
    virObjectUnref(ret);
    return NULL;
}


2328
void virQEMUCapsDispose(void *obj)
2329
{
2330
    virQEMUCapsPtr qemuCaps = obj;
2331 2332
    size_t i;

2333
    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2334 2335
        VIR_FREE(qemuCaps->machineTypes[i].name);
        VIR_FREE(qemuCaps->machineTypes[i].alias);
2336
    }
2337
    VIR_FREE(qemuCaps->machineTypes);
2338

2339 2340
    virObjectUnref(qemuCaps->kvmCPUModels);
    virObjectUnref(qemuCaps->tcgCPUModels);
2341

2342
    virBitmapFree(qemuCaps->flags);
2343

2344
    VIR_FREE(qemuCaps->package);
2345
    VIR_FREE(qemuCaps->binary);
A
Andrea Bolognani 已提交
2346 2347

    VIR_FREE(qemuCaps->gicCapabilities);
2348

2349 2350
    virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
    virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
2351 2352
}

2353
void
2354
virQEMUCapsSet(virQEMUCapsPtr qemuCaps,
2355
               virQEMUCapsFlags flag)
2356
{
2357
    ignore_value(virBitmapSetBit(qemuCaps->flags, flag));
2358 2359 2360 2361
}


void
2362
virQEMUCapsSetList(virQEMUCapsPtr qemuCaps, ...)
2363 2364 2365 2366
{
    va_list list;
    int flag;

2367
    va_start(list, qemuCaps);
2368
    while ((flag = va_arg(list, int)) < QEMU_CAPS_LAST)
2369
        ignore_value(virBitmapSetBit(qemuCaps->flags, flag));
2370
    va_end(list);
2371 2372 2373 2374
}


void
2375
virQEMUCapsClear(virQEMUCapsPtr qemuCaps,
2376
                 virQEMUCapsFlags flag)
2377
{
2378
    ignore_value(virBitmapClearBit(qemuCaps->flags, flag));
2379 2380 2381
}


2382
char *virQEMUCapsFlagsString(virQEMUCapsPtr qemuCaps)
2383
{
2384
    return virBitmapToString(qemuCaps->flags, true, false);
2385 2386 2387 2388
}


bool
2389
virQEMUCapsGet(virQEMUCapsPtr qemuCaps,
2390
               virQEMUCapsFlags flag)
2391
{
J
Ján Tomko 已提交
2392
    return qemuCaps && virBitmapIsBitSet(qemuCaps->flags, flag);
2393
}
2394 2395


D
Daniel P. Berrange 已提交
2396 2397 2398
bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps,
                               virDomainDefPtr def)
{
2399 2400 2401
    /* x86_64 and i686 support PCI-multibus on all machine types
     * since forever */
    if (ARCH_IS_X86(qemuCaps->arch))
D
Daniel P. Berrange 已提交
2402 2403 2404
        return true;

    if (def->os.arch == VIR_ARCH_PPC ||
2405
        ARCH_IS_PPC64(def->os.arch)) {
D
Daniel P. Berrange 已提交
2406 2407 2408 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 2441
        /*
         * Usage of pci.0 naming:
         *
         *    ref405ep: no pci
         *       taihu: no pci
         *      bamboo: 1.1.0
         *       mac99: 2.0.0
         *     g3beige: 2.0.0
         *        prep: 1.4.0
         *     pseries: 2.0.0
         *   mpc8544ds: forever
         * virtex-m507: no pci
         *     ppce500: 1.6.0
         */

        if (qemuCaps->version >= 2000000)
            return true;

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

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

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

        if (STREQ(def->os.machine, "mpc8544ds"))
            return true;

        return false;
    }

2442 2443 2444
    /* If 'virt' supports PCI, it supports multibus.
     * No extra conditions here for simplicity.
     */
2445
    if (qemuDomainIsVirt(def))
2446
        return true;
2447

D
Daniel P. Berrange 已提交
2448 2449 2450 2451
    return false;
}


2452
const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps)
2453
{
2454
    return qemuCaps->binary;
2455 2456
}

2457 2458 2459 2460 2461 2462 2463 2464 2465

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


2466
virArch virQEMUCapsGetArch(virQEMUCapsPtr qemuCaps)
2467
{
2468
    return qemuCaps->arch;
2469 2470 2471
}


2472 2473 2474 2475 2476 2477 2478 2479
void
virQEMUCapsSetVersion(virQEMUCapsPtr qemuCaps,
                      unsigned int version)
{
    qemuCaps->version = version;
}


2480
unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps)
2481
{
2482
    return qemuCaps->version;
2483 2484 2485
}


2486
unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps)
2487
{
2488
    return qemuCaps->kvmVersion;
2489 2490 2491
}


2492 2493 2494 2495 2496 2497
const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps)
{
    return qemuCaps->package;
}


2498 2499
int
virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
2500
                             virDomainVirtType type,
2501
                             const char **name,
2502 2503
                             size_t count,
                             virDomainCapsCPUUsable usable)
2504
{
2505
    size_t i;
2506
    virDomainCapsCPUModelsPtr cpus = NULL;
2507

2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521
    if (type == VIR_DOMAIN_VIRT_KVM && qemuCaps->kvmCPUModels)
        cpus = qemuCaps->kvmCPUModels;
    else if (type == VIR_DOMAIN_VIRT_QEMU && qemuCaps->tcgCPUModels)
        cpus = qemuCaps->tcgCPUModels;

    if (!cpus) {
        if (!(cpus = virDomainCapsCPUModelsNew(count)))
            return -1;

        if (type == VIR_DOMAIN_VIRT_KVM)
            qemuCaps->kvmCPUModels = cpus;
        else
            qemuCaps->tcgCPUModels = cpus;
    }
2522 2523

    for (i = 0; i < count; i++) {
2524
        if (virDomainCapsCPUModelsAdd(cpus, name[i], -1, usable, NULL) < 0)
2525
            return -1;
2526
    }
2527

2528 2529 2530 2531
    return 0;
}


2532
virDomainCapsCPUModelsPtr
2533
virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
2534
                             virDomainVirtType type)
2535
{
2536
    if (type == VIR_DOMAIN_VIRT_KVM)
2537
        return qemuCaps->kvmCPUModels;
2538
    else
2539
        return qemuCaps->tcgCPUModels;
2540 2541 2542
}


2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553
static virQEMUCapsHostCPUDataPtr
virQEMUCapsGetHostCPUData(virQEMUCapsPtr qemuCaps,
                          virDomainVirtType type)
{
    if (type == VIR_DOMAIN_VIRT_KVM)
        return &qemuCaps->kvmCPU;
    else
        return &qemuCaps->tcgCPU;
}


2554
virCPUDefPtr
2555
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
2556 2557
                        virDomainVirtType type,
                        virQEMUCapsHostCPUType cpuType)
2558
{
2559 2560
    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);

2561 2562 2563
    switch (cpuType) {
    case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
        return cpuData->reported;
2564 2565 2566

    case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
        return cpuData->migratable;
2567 2568 2569 2570 2571

    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;
2572 2573 2574
    }

    return NULL;
2575 2576 2577
}


2578 2579 2580
static void
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
                        virDomainVirtType type,
2581
                        virCPUDefPtr reported,
2582 2583
                        virCPUDefPtr migratable,
                        virCPUDefPtr full)
2584
{
2585 2586
    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);

2587 2588
    cpuData->reported = reported;
    cpuData->migratable = migratable;
2589
    cpuData->full = full;
2590 2591 2592
}


2593 2594 2595 2596 2597 2598
bool
virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
                              virCapsPtr caps,
                              virDomainVirtType type,
                              virCPUMode mode)
{
2599 2600
    virDomainCapsCPUModelsPtr cpus;

2601 2602 2603 2604 2605 2606
    switch (mode) {
    case VIR_CPU_MODE_HOST_PASSTHROUGH:
        return type == VIR_DOMAIN_VIRT_KVM &&
               virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch);

    case VIR_CPU_MODE_HOST_MODEL:
2607 2608
        return !!virQEMUCapsGetHostModel(qemuCaps, type,
                                         VIR_QEMU_CAPS_HOST_CPU_REPORTED);
2609 2610

    case VIR_CPU_MODE_CUSTOM:
2611 2612 2613 2614 2615
        if (type == VIR_DOMAIN_VIRT_KVM)
            cpus = qemuCaps->kvmCPUModels;
        else
            cpus = qemuCaps->tcgCPUModels;
        return cpus && cpus->nmodels > 0;
2616 2617 2618 2619 2620 2621 2622 2623 2624

    case VIR_CPU_MODE_LAST:
        break;
    }

    return false;
}


2625 2626 2627
int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
                                   size_t *nmachines,
                                   virCapsGuestMachinePtr **machines)
2628 2629 2630 2631
{
    size_t i;

    *machines = NULL;
2632
    *nmachines = qemuCaps->nmachineTypes;
2633

2634 2635 2636 2637
    if (*nmachines &&
        VIR_ALLOC_N(*machines, qemuCaps->nmachineTypes) < 0)
        goto error;

2638
    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2639 2640
        virCapsGuestMachinePtr mach;
        if (VIR_ALLOC(mach) < 0)
2641
            goto error;
2642
        (*machines)[i] = mach;
2643 2644 2645
        if (qemuCaps->machineTypes[i].alias) {
            if (VIR_STRDUP(mach->name, qemuCaps->machineTypes[i].alias) < 0 ||
                VIR_STRDUP(mach->canonical, qemuCaps->machineTypes[i].name) < 0)
2646
                goto error;
2647
        } else {
2648
            if (VIR_STRDUP(mach->name, qemuCaps->machineTypes[i].name) < 0)
2649
                goto error;
2650
        }
2651
        mach->maxCpus = qemuCaps->machineTypes[i].maxCpus;
2652 2653
    }

2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691
    /* 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;
            }
            if (VIR_STRDUP(mach->name, machine->canonical) < 0)
                goto error;
            mach->maxCpus = machine->maxCpus;
            i++;
        }
        i++;
    }

2692 2693
    return 0;

2694
 error:
2695 2696 2697 2698 2699 2700 2701
    virCapabilitiesFreeMachines(*machines, *nmachines);
    *nmachines = 0;
    *machines = NULL;
    return -1;
}


2702 2703 2704 2705 2706 2707 2708 2709
/**
 * 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.
 */
2710 2711
const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps,
                                           const char *name)
2712 2713 2714
{
    size_t i;

2715 2716
    if (!name || !qemuCaps)
        return name;
2717

2718
    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2719
        if (!qemuCaps->machineTypes[i].alias)
2720
            continue;
2721 2722
        if (STREQ(qemuCaps->machineTypes[i].alias, name))
            return qemuCaps->machineTypes[i].name;
2723 2724 2725 2726
    }

    return name;
}
2727 2728


2729 2730 2731 2732 2733 2734 2735 2736 2737
int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps,
                                 const char *name)
{
    size_t i;

    if (!name)
        return 0;

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
2738
        if (!qemuCaps->machineTypes[i].maxCpus)
2739
            continue;
2740 2741
        if (STREQ(qemuCaps->machineTypes[i].name, name))
            return qemuCaps->machineTypes[i].maxCpus;
2742 2743 2744 2745 2746 2747
    }

    return 0;
}


2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761
bool virQEMUCapsGetMachineHotplugCpus(virQEMUCapsPtr qemuCaps,
                                      const char *name)
{
    size_t i;

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
        if (STREQ_NULLABLE(qemuCaps->machineTypes[i].name, name))
            return qemuCaps->machineTypes[i].hotplugCpus;
    }

    return false;
}


2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785
/**
 * 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;
}


2786
static int
2787 2788
virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps,
                            qemuMonitorPtr mon)
2789 2790 2791 2792 2793 2794 2795
{
    char **commands = NULL;
    int ncommands;

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

2796 2797 2798 2799
    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsCommands),
                                  virQEMUCapsCommands,
                                  ncommands, commands);
2800
    virStringListFreeCount(commands, ncommands);
2801

2802 2803 2804 2805
    /* QMP add-fd was introduced in 1.2, but did not support
     * management control of set numbering, and did not have a
     * counterpart -add-fd command line option.  We require the
     * add-fd features from 1.3 or later.  */
2806
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ADD_FD)) {
2807 2808 2809 2810 2811 2812 2813
        int fd = open("/dev/null", O_RDONLY);
        if (fd < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unable to probe for add-fd"));
            return -1;
        }
        if (qemuMonitorAddFd(mon, 0, fd, "/dev/null") < 0)
2814
            virQEMUCapsClear(qemuCaps, QEMU_CAPS_ADD_FD);
2815 2816 2817
        VIR_FORCE_CLOSE(fd);
    }

2818 2819 2820 2821 2822 2823
    /* Probe for active commit of qemu 2.1 (for now, we are choosing
     * to ignore the fact that qemu 2.0 can also do active commit) */
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCK_COMMIT) &&
        qemuMonitorSupportsActiveCommit(mon))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_ACTIVE_COMMIT);

2824 2825 2826 2827 2828
    return 0;
}


static int
2829 2830
virQEMUCapsProbeQMPEvents(virQEMUCapsPtr qemuCaps,
                          qemuMonitorPtr mon)
2831 2832 2833 2834 2835 2836 2837
{
    char **events = NULL;
    int nevents;

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

2838 2839 2840 2841
    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsEvents),
                                  virQEMUCapsEvents,
                                  nevents, events);
2842
    virStringListFreeCount(events, nevents);
2843 2844 2845 2846 2847

    return 0;
}


2848
static int
2849 2850
virQEMUCapsProbeQMPObjects(virQEMUCapsPtr qemuCaps,
                           qemuMonitorPtr mon)
2851 2852 2853 2854 2855 2856 2857
{
    int nvalues;
    char **values;
    size_t i;

    if ((nvalues = qemuMonitorGetObjectTypes(mon, &values)) < 0)
        return -1;
2858 2859 2860 2861
    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsObjectTypes),
                                  virQEMUCapsObjectTypes,
                                  nvalues, values);
2862
    virStringListFreeCount(values, nvalues);
2863

2864
    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsObjectProps); i++) {
2865
        const char *type = virQEMUCapsObjectProps[i].type;
2866 2867 2868 2869 2870
        int cap = virQEMUCapsObjectProps[i].capsCondition;

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

2871 2872 2873 2874
        if ((nvalues = qemuMonitorGetObjectProps(mon,
                                                 type,
                                                 &values)) < 0)
            return -1;
2875 2876 2877 2878
        virQEMUCapsProcessStringFlags(qemuCaps,
                                      virQEMUCapsObjectProps[i].nprops,
                                      virQEMUCapsObjectProps[i].props,
                                      nvalues, values);
2879 2880 2881 2882
        virQEMUCapsProcessProps(qemuCaps,
                                ARRAY_CARDINALITY(virQEMUCapsPropObjects),
                                virQEMUCapsPropObjects, type,
                                nvalues, values);
2883
        virStringListFreeCount(values, nvalues);
2884 2885 2886
    }

    /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
2887 2888
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC))
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC);
2889 2890 2891 2892 2893 2894

    return 0;
}


static int
2895 2896
virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps,
                                qemuMonitorPtr mon)
2897 2898 2899 2900 2901
{
    qemuMonitorMachineInfoPtr *machines = NULL;
    int nmachines = 0;
    int ret = -1;
    size_t i;
2902
    size_t defIdx = 0;
2903 2904

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

2907
    if (VIR_ALLOC_N(qemuCaps->machineTypes, nmachines) < 0)
2908 2909
        goto cleanup;

2910
    for (i = 0; i < nmachines; i++) {
2911
        struct virQEMUCapsMachineType *mach;
2912 2913
        if (STREQ(machines[i]->name, "none"))
            continue;
2914 2915 2916 2917 2918

        mach = &(qemuCaps->machineTypes[qemuCaps->nmachineTypes++]);

        if (VIR_STRDUP(mach->alias, machines[i]->alias) < 0 ||
            VIR_STRDUP(mach->name, machines[i]->name) < 0)
2919
            goto cleanup;
2920 2921

        mach->maxCpus = machines[i]->maxCpus;
2922
        mach->hotplugCpus = machines[i]->hotplugCpus;
2923

2924
        if (machines[i]->isDefault)
2925
            defIdx = qemuCaps->nmachineTypes - 1;
2926
    }
2927 2928

    if (defIdx)
2929
        virQEMUCapsSetDefaultMachine(qemuCaps, defIdx);
2930 2931 2932

    ret = 0;

2933
 cleanup:
2934
    for (i = 0; i < nmachines; i++)
2935 2936 2937 2938 2939 2940
        qemuMonitorMachineInfoFree(machines[i]);
    VIR_FREE(machines);
    return ret;
}


2941
int
2942
virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps,
2943 2944
                                  qemuMonitorPtr mon,
                                  bool tcg)
2945
{
2946
    virDomainCapsCPUModelsPtr models;
2947 2948 2949 2950
    qemuMonitorCPUDefInfoPtr *cpus;
    int ncpus;
    int ret = -1;
    size_t i;
2951

2952 2953 2954
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_DEFINITIONS))
        return 0;

2955
    if ((ncpus = qemuMonitorGetCPUDefinitions(mon, &cpus)) < 0)
2956 2957
        return -1;

2958
    if (!(models = virDomainCapsCPUModelsNew(ncpus)))
2959
        goto cleanup;
2960

2961 2962 2963 2964 2965
    if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
        qemuCaps->tcgCPUModels = models;
    else
        qemuCaps->kvmCPUModels = models;

2966
    for (i = 0; i < ncpus; i++) {
2967 2968 2969 2970 2971 2972 2973
        virDomainCapsCPUUsable usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;

        if (cpus[i]->usable == VIR_TRISTATE_BOOL_YES)
            usable = VIR_DOMCAPS_CPU_USABLE_YES;
        else if (cpus[i]->usable == VIR_TRISTATE_BOOL_NO)
            usable = VIR_DOMCAPS_CPU_USABLE_NO;

2974
        if (virDomainCapsCPUModelsAddSteal(models, &cpus[i]->name, usable,
2975
                                           &cpus[i]->blockers) < 0)
2976 2977 2978 2979 2980 2981 2982 2983 2984 2985
            goto cleanup;
    }

    ret = 0;

 cleanup:
    for (i = 0; i < ncpus; i++)
        qemuMonitorCPUDefInfoFree(cpus[i]);
    VIR_FREE(cpus);
    return ret;
2986 2987
}

2988 2989
static int
virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
2990 2991
                           qemuMonitorPtr mon,
                           bool tcg)
2992
{
2993
    qemuMonitorCPUModelInfoPtr modelInfo = NULL;
2994 2995
    qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
    virHashTablePtr hash = NULL;
2996
    const char *model;
2997
    qemuMonitorCPUModelExpansionType type;
2998 2999
    virDomainVirtType virtType;
    virQEMUCapsHostCPUDataPtr cpuData;
3000
    int ret = -1;
3001 3002

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
3003 3004
        return 0;

3005
    if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
3006
        virtType = VIR_DOMAIN_VIRT_QEMU;
3007 3008
        model = "max";
    } else {
3009
        virtType = VIR_DOMAIN_VIRT_KVM;
3010 3011 3012
        model = "host";
    }

3013 3014
    cpuData = virQEMUCapsGetHostCPUData(qemuCaps, virtType);

3015 3016 3017 3018 3019 3020 3021 3022 3023 3024
    /* 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
     * preferred spelling, thus we need to do a full expansion on the result of
     * the initial static expansion to get all variants of all features.
     */
    if (ARCH_IS_X86(qemuCaps->arch))
        type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL;
    else
        type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;

3025 3026
    if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, &modelInfo) < 0)
        goto cleanup;
3027 3028

    /* Try to check migratability of each feature. */
3029
    if (modelInfo &&
3030 3031
        qemuMonitorGetCPUModelExpansion(mon, type, model, false,
                                        &nonMigratable) < 0)
3032
        goto cleanup;
3033 3034 3035 3036 3037 3038 3039

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

        if (!(hash = virHashCreate(0, NULL)))
3040
            goto cleanup;
3041

3042 3043
        for (i = 0; i < modelInfo->nprops; i++) {
            prop = modelInfo->props + i;
3044
            if (virHashAddEntry(hash, prop->name, prop) < 0)
3045
                goto cleanup;
3046 3047 3048 3049 3050 3051 3052 3053 3054
        }

        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;

3055
            if (prop->value.boolean) {
3056
                prop->migratable = VIR_TRISTATE_BOOL_YES;
3057 3058 3059 3060
            } else if (nmProp->value.boolean) {
                prop->value.boolean = true;
                prop->migratable = VIR_TRISTATE_BOOL_NO;
            }
3061 3062
        }

3063
        modelInfo->migratability = true;
3064 3065
    }

3066
    VIR_STEAL_PTR(cpuData->info, modelInfo);
3067 3068 3069 3070 3071
    ret = 0;

 cleanup:
    virHashFree(hash);
    qemuMonitorCPUModelInfoFree(nonMigratable);
3072
    qemuMonitorCPUModelInfoFree(modelInfo);
3073 3074

    return ret;
3075 3076
}

3077 3078
struct tpmTypeToCaps {
    int type;
3079
    virQEMUCapsFlags caps;
3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099
};

static const struct tpmTypeToCaps virQEMUCapsTPMTypesToCaps[] = {
    {
        .type = VIR_DOMAIN_TPM_TYPE_PASSTHROUGH,
        .caps = QEMU_CAPS_DEVICE_TPM_PASSTHROUGH,
    },
};

const struct tpmTypeToCaps virQEMUCapsTPMModelsToCaps[] = {
    {
        .type = VIR_DOMAIN_TPM_MODEL_TIS,
        .caps = QEMU_CAPS_DEVICE_TPM_TIS,
    },
};

static int
virQEMUCapsProbeQMPTPM(virQEMUCapsPtr qemuCaps,
                       qemuMonitorPtr mon)
{
3100 3101
    int nentries;
    size_t i;
3102
    char **entries = NULL;
S
Stefan Berger 已提交
3103

3104 3105 3106 3107 3108 3109 3110
    if ((nentries = qemuMonitorGetTPMModels(mon, &entries)) < 0)
        return -1;

    if (nentries > 0) {
        for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsTPMModelsToCaps); i++) {
            const char *needle = virDomainTPMModelTypeToString(
                virQEMUCapsTPMModelsToCaps[i].type);
3111
            if (virStringListHasString((const char **) entries, needle))
3112 3113 3114 3115
                virQEMUCapsSet(qemuCaps,
                               virQEMUCapsTPMModelsToCaps[i].caps);
        }
    }
3116
    virStringListFree(entries);
3117 3118 3119 3120 3121 3122 3123 3124

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

    if (nentries > 0) {
        for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsTPMTypesToCaps); i++) {
            const char *needle = virDomainTPMBackendTypeToString(
                virQEMUCapsTPMTypesToCaps[i].type);
3125
            if (virStringListHasString((const char **) entries, needle))
3126 3127 3128
                virQEMUCapsSet(qemuCaps, virQEMUCapsTPMTypesToCaps[i].caps);
        }
    }
3129
    virStringListFree(entries);
3130 3131 3132 3133

    return 0;
}

3134

3135
static int
3136 3137
virQEMUCapsProbeQMPKVMState(virQEMUCapsPtr qemuCaps,
                            qemuMonitorPtr mon)
3138 3139 3140 3141
{
    bool enabled = false;
    bool present = false;

3142
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
3143 3144 3145 3146 3147 3148
        return 0;

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

    /* The QEMU_CAPS_KVM flag was initially set according to the QEMU
3149
     * reporting the recognition of 'query-kvm' QMP command. That merely
N
Nehal J Wani 已提交
3150
     * indicates existence of the command though, not whether KVM support
3151 3152 3153 3154 3155 3156
     * is actually available, nor whether it is enabled by default.
     *
     * If it is not present we need to clear the flag, and if it is
     * not enabled by default we need to change the flag.
     */
    if (!present) {
3157
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_KVM);
3158
    } else if (!enabled) {
3159 3160
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_KVM);
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_ENABLE_KVM);
3161 3162 3163 3164 3165
    }

    return 0;
}

3166 3167 3168 3169 3170 3171 3172 3173
struct virQEMUCapsCommandLineProps {
    const char *option;
    const char *param;
    int flag;
};

static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
    { "machine", "mem-merge", QEMU_CAPS_MEM_MERGE },
3174
    { "machine", "vmport", QEMU_CAPS_MACHINE_VMPORT_OPT },
O
Osier Yang 已提交
3175
    { "drive", "discard", QEMU_CAPS_DRIVE_DISCARD },
3176
    { "drive", "detect-zeroes", QEMU_CAPS_DRIVE_DETECT_ZEROES },
3177
    { "realtime", "mlock", QEMU_CAPS_REALTIME_MLOCK },
3178
    { "boot-opts", "strict", QEMU_CAPS_BOOT_STRICT },
3179
    { "boot-opts", "reboot-timeout", QEMU_CAPS_REBOOT_TIMEOUT },
3180
    { "boot-opts", "splash-time", QEMU_CAPS_SPLASH_TIMEOUT },
3181
    { "spice", "disable-agent-file-xfer", QEMU_CAPS_SPICE_FILE_XFER_DISABLE },
3182
    { "msg", "timestamp", QEMU_CAPS_MSG_TIMESTAMP },
3183
    { "numa", NULL, QEMU_CAPS_NUMA },
3184
    { "drive", "throttling.bps-total-max", QEMU_CAPS_DRIVE_IOTUNE_MAX},
3185 3186
    { "machine", "aes-key-wrap", QEMU_CAPS_AES_KEY_WRAP },
    { "machine", "dea-key-wrap", QEMU_CAPS_DEA_KEY_WRAP },
3187
    { "chardev", "append", QEMU_CAPS_CHARDEV_FILE_APPEND },
3188
    { "spice", "gl", QEMU_CAPS_SPICE_GL },
3189
    { "chardev", "logfile", QEMU_CAPS_CHARDEV_LOGFILE },
3190
    { "name", "debug-threads", QEMU_CAPS_NAME_DEBUG_THREADS },
3191
    { "name", "guest", QEMU_CAPS_NAME_GUEST },
3192
    { "spice", "unix", QEMU_CAPS_SPICE_UNIX },
3193
    { "drive", "throttling.bps-total-max-length", QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH },
3194
    { "drive", "throttling.group", QEMU_CAPS_DRIVE_IOTUNE_GROUP },
3195
    { "spice", "rendernode", QEMU_CAPS_SPICE_RENDERNODE },
3196
    { "machine", "kernel_irqchip", QEMU_CAPS_MACHINE_KERNEL_IRQCHIP },
3197
    { "machine", "loadparm", QEMU_CAPS_LOADPARM },
3198
    { "vnc", "vnc", QEMU_CAPS_VNC_MULTI_SERVERS },
3199
    { "chardev", "reconnect", QEMU_CAPS_CHARDEV_RECONNECT },
3200 3201 3202 3203 3204 3205
};

static int
virQEMUCapsProbeQMPCommandLine(virQEMUCapsPtr qemuCaps,
                               qemuMonitorPtr mon)
{
3206
    bool found = false;
3207 3208 3209 3210 3211 3212 3213
    int nvalues;
    char **values;
    size_t i, j;

    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsCommandLine); i++) {
        if ((nvalues = qemuMonitorGetCommandLineOptionParameters(mon,
                                                                 virQEMUCapsCommandLine[i].option,
3214 3215
                                                                 &values,
                                                                 &found)) < 0)
3216
            return -1;
3217 3218 3219 3220

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

3221
        for (j = 0; j < nvalues; j++) {
3222
            if (STREQ_NULLABLE(virQEMUCapsCommandLine[i].param, values[j])) {
3223 3224 3225 3226
                virQEMUCapsSet(qemuCaps, virQEMUCapsCommandLine[i].flag);
                break;
            }
        }
3227
        virStringListFree(values);
3228 3229 3230 3231
    }

    return 0;
}
3232

3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246
static int
virQEMUCapsProbeQMPMigrationCapabilities(virQEMUCapsPtr qemuCaps,
                                         qemuMonitorPtr mon)
{
    char **caps = NULL;
    int ncaps;

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

    virQEMUCapsProcessStringFlags(qemuCaps,
                                  ARRAY_CARDINALITY(virQEMUCapsMigration),
                                  virQEMUCapsMigration,
                                  ncaps, caps);
3247
    virStringListFreeCount(caps, ncaps);
3248 3249 3250 3251

    return 0;
}

A
Andrea Bolognani 已提交
3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271
/**
 * 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;

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

3272
    virQEMUCapsSetGICCapabilities(qemuCaps, caps, ncaps);
A
Andrea Bolognani 已提交
3273 3274 3275 3276

    return 0;
}

3277

3278
bool
3279
virQEMUCapsCPUFilterFeatures(const char *name,
3280
                             void *opaque)
3281
{
3282
    virArch *arch = opaque;
3283

3284
    if (!ARCH_IS_X86(*arch))
3285 3286
        return true;

3287 3288 3289 3290 3291 3292 3293 3294 3295
    if (STREQ(name, "cmt") ||
        STREQ(name, "mbm_total") ||
        STREQ(name, "mbm_local"))
        return false;

    return true;
}


3296 3297 3298 3299 3300 3301 3302
/**
 * 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
virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
3303
                            qemuMonitorCPUModelInfoPtr modelInfo,
3304 3305
                            virCPUDefPtr cpu,
                            bool migratable)
3306
{
3307
    size_t i;
3308

3309
    if (!modelInfo) {
3310
        virReportError(VIR_ERR_INTERNAL_ERROR,
3311 3312 3313 3314
                       _("missing host CPU model info from QEMU capabilities "
                         "for binary %s"),
                       qemuCaps->binary);
        return -1;
3315
    }
J
Jiri Denemark 已提交
3316

3317 3318
    if (VIR_STRDUP(cpu->model, modelInfo->name) < 0 ||
        VIR_ALLOC_N(cpu->features, modelInfo->nprops) < 0)
3319
        return -1;
3320 3321 3322 3323 3324

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

    for (i = 0; i < modelInfo->nprops; i++) {
3325 3326
        virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures;
        qemuMonitorCPUPropertyPtr prop = modelInfo->props + i;
3327

3328 3329
        if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
            continue;
3330

3331 3332
        if (VIR_STRDUP(feature->name, prop->name) < 0)
            return -1;
3333 3334 3335 3336 3337 3338

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

3342 3343
    return 0;
}
3344

3345

3346 3347 3348 3349 3350 3351 3352 3353
/**
 * 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,
3354
                           qemuMonitorCPUModelInfoPtr model,
3355 3356
                           virCPUDefPtr cpu,
                           bool migratable)
3357 3358 3359 3360
{
    virCPUDataPtr data = NULL;
    unsigned long long sigFamily = 0;
    unsigned long long sigModel = 0;
3361
    unsigned long long sigStepping = 0;
3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375
    int ret = -1;
    size_t i;

    if (!model)
        return 1;

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

    for (i = 0; i < model->nprops; i++) {
        qemuMonitorCPUPropertyPtr prop = model->props + i;

        switch (prop->type) {
        case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
3376 3377 3378 3379 3380
            if (!prop->value.boolean ||
                (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
                continue;

            if (virCPUx86DataAddFeature(data, prop->name) < 0)
3381
                goto cleanup;
3382

3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395
            break;

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

        case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
            if (STREQ(prop->name, "family"))
                sigFamily = prop->value.number;
            else if (STREQ(prop->name, "model"))
                sigModel = prop->value.number;
3396 3397
            else if (STREQ(prop->name, "stepping"))
                sigStepping = prop->value.number;
3398 3399 3400 3401 3402 3403 3404
            break;

        case QEMU_MONITOR_CPU_PROPERTY_LAST:
            break;
        }
    }

3405
    if (virCPUx86DataSetSignature(data, sigFamily, sigModel, sigStepping) < 0)
3406 3407
        goto cleanup;

3408
    if (cpuDecode(cpu, data, virQEMUCapsGetCPUDefinitions(qemuCaps, type)) < 0)
3409 3410 3411 3412 3413 3414 3415 3416 3417 3418
        goto cleanup;

    ret = 0;

 cleanup:
    virCPUDataFree(data);
    return ret;
}


3419 3420
/**
 * Returns  0 when host CPU model provided by QEMU was filled in qemuCaps,
3421
 *          1 when the caller should fall back to other methods
3422 3423
 *         -1 on error.
 */
3424
int
3425
virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
3426
                        virDomainVirtType type,
3427 3428
                        virCPUDefPtr cpu,
                        bool migratable)
3429
{
3430
    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
3431 3432
    int ret = 1;

3433
    if (migratable && cpuData->info && !cpuData->info->migratability)
3434 3435
        return 1;

3436 3437 3438 3439 3440 3441 3442
    if (ARCH_IS_S390(qemuCaps->arch)) {
        ret = virQEMUCapsInitCPUModelS390(qemuCaps, cpuData->info,
                                          cpu, migratable);
    } else if (ARCH_IS_X86(qemuCaps->arch)) {
        ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpuData->info,
                                         cpu, migratable);
    }
3443

3444 3445 3446
    if (ret == 0)
        cpu->fallback = VIR_CPU_FALLBACK_FORBID;

3447
    return ret;
3448 3449 3450
}


3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467
static virCPUDefPtr
virQEMUCapsNewHostCPUModel(void)
{
    virCPUDefPtr cpu;

    if (VIR_ALLOC(cpu) < 0)
        return NULL;

    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;
}


3468 3469
void
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
3470
                            virArch hostArch,
3471
                            virDomainVirtType type)
3472 3473
{
    virCPUDefPtr cpu = NULL;
3474
    virCPUDefPtr migCPU = NULL;
3475
    virCPUDefPtr hostCPU = NULL;
3476 3477
    virCPUDefPtr fullCPU = NULL;
    size_t i;
3478
    int rc;
3479

3480
    if (!virQEMUCapsGuestIsNative(hostArch, qemuCaps->arch))
3481 3482
        return;

3483
    if (!(cpu = virQEMUCapsNewHostCPUModel()))
3484 3485
        goto error;

3486
    if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
3487 3488
        goto error;
    } else if (rc == 1) {
3489
        VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly");
3490

3491
        hostCPU = virQEMUCapsProbeHostCPUForEmulator(hostArch, qemuCaps, type);
3492 3493
        if (!hostCPU ||
            virCPUDefCopyModelFilter(cpu, hostCPU, true,
3494
                                     virQEMUCapsCPUFilterFeatures,
3495
                                     &qemuCaps->arch) < 0)
3496
            goto error;
3497 3498 3499
    } else if (type == VIR_DOMAIN_VIRT_KVM &&
               virCPUGetHostIsSupported(qemuCaps->arch)) {
        if (!(fullCPU = virCPUGetHost(qemuCaps->arch, VIR_CPU_TYPE_GUEST,
3500
                                      NULL, NULL)))
3501 3502 3503 3504 3505 3506 3507 3508
            goto error;

        for (i = 0; i < cpu->nfeatures; i++) {
            if (cpu->features[i].policy == VIR_CPU_FEATURE_REQUIRE &&
                virCPUDefUpdateFeature(fullCPU, cpu->features[i].name,
                                       VIR_CPU_FEATURE_REQUIRE) < 0)
                goto error;
        }
3509 3510
    }

3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523
    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;
    }

3524
    virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU, fullCPU);
3525

3526 3527
 cleanup:
    virCPUDefFree(hostCPU);
3528 3529 3530 3531
    return;

 error:
    virCPUDefFree(cpu);
3532
    virCPUDefFree(migCPU);
3533
    virCPUDefFree(fullCPU);
3534
    virResetLastError();
3535
    goto cleanup;
3536 3537 3538
}


3539 3540 3541 3542 3543
void
virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
                           virDomainVirtType type,
                           qemuMonitorCPUModelInfoPtr modelInfo)
{
3544 3545 3546
    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);

    cpuData->info = modelInfo;
3547 3548 3549
}


3550 3551
static int
virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
3552 3553
                                xmlXPathContextPtr ctxt,
                                virDomainVirtType virtType)
3554 3555 3556
{
    char *str = NULL;
    xmlNodePtr hostCPUNode;
3557
    xmlNodePtr *nodes = NULL;
3558 3559 3560 3561 3562
    xmlNodePtr oldnode = ctxt->node;
    qemuMonitorCPUModelInfoPtr hostCPU = NULL;
    int ret = -1;
    size_t i;
    int n;
3563
    int val;
3564

3565 3566 3567 3568 3569 3570
    if (virtType == VIR_DOMAIN_VIRT_KVM)
        hostCPUNode = virXPathNode("./hostCPU[@type='kvm']", ctxt);
    else
        hostCPUNode = virXPathNode("./hostCPU[@type='tcg']", ctxt);

    if (!hostCPUNode) {
3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584
        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;
    }

3585 3586 3587 3588 3589 3590 3591 3592 3593
    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);

3594 3595
    ctxt->node = hostCPUNode;

3596
    if ((n = virXPathNodeSet("./property", ctxt, &nodes)) > 0) {
3597 3598 3599 3600 3601 3602
        if (VIR_ALLOC_N(hostCPU->props, n) < 0)
            goto cleanup;

        hostCPU->nprops = n;

        for (i = 0; i < n; i++) {
3603 3604 3605 3606 3607
            qemuMonitorCPUPropertyPtr prop = hostCPU->props + i;

            ctxt->node = nodes[i];

            if (!(prop->name = virXMLPropString(ctxt->node, "name"))) {
3608 3609
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing 'name' attribute for a host CPU"
3610
                                 " model property in QEMU capabilities cache"));
3611 3612 3613
                goto cleanup;
            }

3614
            if (!(str = virXMLPropString(ctxt->node, "type")) ||
3615
                (val = qemuMonitorCPUPropertyTypeFromString(str)) < 0) {
3616
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3617 3618
                               _("missing or invalid CPU model property type "
                                 "in QEMU capabilities cache"));
3619 3620 3621
                goto cleanup;
            }
            VIR_FREE(str);
3622

3623
            prop->type = val;
3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654
            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;
            }
3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667

            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);
            }
3668 3669 3670
        }
    }

3671
    virQEMUCapsSetCPUModelInfo(qemuCaps, virtType, hostCPU);
3672 3673 3674 3675 3676 3677
    hostCPU = NULL;
    ret = 0;

 cleanup:
    ctxt->node = oldnode;
    VIR_FREE(str);
3678
    VIR_FREE(nodes);
3679 3680 3681 3682 3683
    qemuMonitorCPUModelInfoFree(hostCPU);
    return ret;
}


3684 3685
static int
virQEMUCapsLoadCPUModels(virQEMUCapsPtr qemuCaps,
3686 3687
                         xmlXPathContextPtr ctxt,
                         virDomainVirtType type)
3688
{
3689
    virDomainCapsCPUModelsPtr cpus = NULL;
3690 3691 3692 3693 3694
    xmlNodePtr *nodes = NULL;
    char *str = NULL;
    size_t i;
    int n;
    int ret = -1;
3695 3696 3697 3698
    xmlNodePtr node;
    xmlNodePtr *blockerNodes = NULL;
    char **blockers = NULL;
    int nblockers;
3699

3700 3701 3702 3703 3704 3705
    if (type == VIR_DOMAIN_VIRT_KVM)
        n = virXPathNodeSet("./cpu[@type='kvm']", ctxt, &nodes);
    else
        n = virXPathNodeSet("./cpu[@type='tcg']", ctxt, &nodes);

    if (n < 0) {
3706 3707 3708 3709 3710 3711 3712 3713 3714 3715
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities cpus"));
        goto cleanup;
    }

    if (n == 0) {
        ret = 0;
        goto cleanup;
    }

3716
    if (!(cpus = virDomainCapsCPUModelsNew(n)))
3717 3718
        goto cleanup;

3719 3720 3721 3722 3723
    if (type == VIR_DOMAIN_VIRT_KVM)
        qemuCaps->kvmCPUModels = cpus;
    else
        qemuCaps->tcgCPUModels = cpus;

3724
    for (i = 0; i < n; i++) {
3725 3726 3727 3728 3729 3730 3731 3732 3733 3734
        int usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;

        if ((str = virXMLPropString(nodes[i], "usable")) &&
            (usable = virDomainCapsCPUUsableTypeFromString(str)) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unknown value '%s' in attribute 'usable'"), str);
            goto cleanup;
        }
        VIR_FREE(str);

3735 3736 3737 3738 3739 3740
        if (!(str = virXMLPropString(nodes[i], "name"))) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("missing cpu name in QEMU capabilities cache"));
            goto cleanup;
        }

3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765
        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"));
            goto cleanup;
        }

        if (nblockers > 0) {
            size_t j;

            if (VIR_ALLOC_N(blockers, nblockers + 1) < 0)
                goto cleanup;

            for (j = 0; j < nblockers; j++) {
                if (!(blockers[j] = virXMLPropString(blockerNodes[j], "name"))) {
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("missing blocker name in QEMU "
                                     "capabilities cache"));
                    goto cleanup;
                }
            }
3766
            VIR_FREE(blockerNodes);
3767 3768 3769
        }

        if (virDomainCapsCPUModelsAddSteal(cpus, &str, usable, &blockers) < 0)
3770 3771 3772 3773 3774 3775 3776 3777
            goto cleanup;
    }

    ret = 0;

 cleanup:
    VIR_FREE(nodes);
    VIR_FREE(str);
3778 3779
    VIR_FREE(blockerNodes);
    virStringListFree(blockers);
3780 3781 3782 3783
    return ret;
}


3784 3785 3786 3787 3788 3789 3790 3791 3792 3793
struct _virQEMUCapsCachePriv {
    char *libDir;
    uid_t runUid;
    gid_t runGid;
    virArch hostArch;
};
typedef struct _virQEMUCapsCachePriv virQEMUCapsCachePriv;
typedef virQEMUCapsCachePriv *virQEMUCapsCachePrivPtr;


3794
static void
3795
virQEMUCapsCachePrivFree(void *privData)
3796
{
3797 3798
    virQEMUCapsCachePrivPtr priv = privData;

3799 3800 3801 3802 3803
    VIR_FREE(priv->libDir);
    VIR_FREE(priv);
}


3804 3805 3806 3807 3808 3809
/*
 * Parsing a doc that looks like
 *
 * <qemuCaps>
 *   <qemuctime>234235253</qemuctime>
 *   <selfctime>234235253</selfctime>
3810
 *   <selfvers>1002016</selfvers>
3811 3812 3813 3814 3815 3816
 *   <usedQMP/>
 *   <flag name='foo'/>
 *   <flag name='bar'/>
 *   ...
 *   <cpu name="pentium3"/>
 *   ...
3817
 *   <machine name="pc-1.0" alias="pc" hotplugCpus='yes' maxCpus="4"/>
3818 3819 3820
 *   ...
 * </qemuCaps>
 */
3821
int
3822
virQEMUCapsLoadCache(virArch hostArch,
3823
                     virQEMUCapsPtr qemuCaps,
3824
                     const char *filename)
3825 3826 3827 3828 3829 3830 3831
{
    xmlDocPtr doc = NULL;
    int ret = -1;
    size_t i;
    int n;
    xmlNodePtr *nodes = NULL;
    xmlXPathContextPtr ctxt = NULL;
J
Ján Tomko 已提交
3832
    char *str = NULL;
3833
    long long int l;
3834
    unsigned long lu;
3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858

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

    if (!(ctxt = xmlXPathNewContext(doc))) {
        virReportOOMError();
        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;
    }

    if (virXPathLongLong("string(./qemuctime)", ctxt, &l) < 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("missing qemuctime in QEMU capabilities XML"));
        goto cleanup;
    }
3859
    qemuCaps->ctime = (time_t)l;
3860 3861 3862 3863 3864 3865

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

3868
    qemuCaps->libvirtVersion = 0;
3869
    if (virXPathULong("string(./selfvers)", ctxt, &lu) == 0)
3870
        qemuCaps->libvirtVersion = lu;
3871

3872 3873 3874 3875 3876 3877 3878 3879 3880
    qemuCaps->usedQMP = virXPathBoolean("count(./usedQMP) > 0",
                                        ctxt) > 0;

    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);
3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892
    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;
3893
        }
3894 3895
        VIR_FREE(str);
        virQEMUCapsSet(qemuCaps, flag);
3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910
    }
    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;
    }

3911 3912 3913 3914 3915 3916
    if (virXPathBoolean("boolean(./package)", ctxt) > 0) {
        qemuCaps->package = virXPathString("string(./package)", ctxt);
        if (!qemuCaps->package &&
            VIR_STRDUP(qemuCaps->package, "") < 0)
            goto cleanup;
    }
3917

3918 3919 3920 3921 3922 3923 3924 3925 3926 3927
    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 已提交
3928
    VIR_FREE(str);
3929

3930 3931
    if (virQEMUCapsLoadHostCPUModelInfo(qemuCaps, ctxt, VIR_DOMAIN_VIRT_KVM) < 0 ||
        virQEMUCapsLoadHostCPUModelInfo(qemuCaps, ctxt, VIR_DOMAIN_VIRT_QEMU) < 0)
3932 3933
        goto cleanup;

3934 3935
    if (virQEMUCapsLoadCPUModels(qemuCaps, ctxt, VIR_DOMAIN_VIRT_KVM) < 0 ||
        virQEMUCapsLoadCPUModels(qemuCaps, ctxt, VIR_DOMAIN_VIRT_QEMU) < 0)
3936 3937 3938 3939 3940 3941 3942 3943 3944
        goto cleanup;

    if ((n = virXPathNodeSet("./machine", ctxt, &nodes)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to parse qemu capabilities machines"));
        goto cleanup;
    }
    if (n > 0) {
        qemuCaps->nmachineTypes = n;
3945
        if (VIR_ALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes) < 0)
3946 3947 3948
            goto cleanup;

        for (i = 0; i < n; i++) {
3949
            if (!(qemuCaps->machineTypes[i].name = virXMLPropString(nodes[i], "name"))) {
3950 3951 3952 3953
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing machine name in QEMU capabilities cache"));
                goto cleanup;
            }
3954
            qemuCaps->machineTypes[i].alias = virXMLPropString(nodes[i], "alias");
3955 3956 3957

            str = virXMLPropString(nodes[i], "maxCpus");
            if (str &&
3958
                virStrToLong_ui(str, NULL, 10, &(qemuCaps->machineTypes[i].maxCpus)) < 0) {
3959 3960 3961 3962
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("malformed machine cpu count in QEMU capabilities cache"));
                goto cleanup;
            }
J
Ján Tomko 已提交
3963
            VIR_FREE(str);
3964 3965 3966 3967 3968

            str = virXMLPropString(nodes[i], "hotplugCpus");
            if (STREQ_NULLABLE(str, "yes"))
                qemuCaps->machineTypes[i].hotplugCpus = true;
            VIR_FREE(str);
3969 3970 3971 3972
        }
    }
    VIR_FREE(nodes);

A
Andrea Bolognani 已提交
3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 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 4035 4036 4037 4038
    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);

4039 4040
    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
4041

4042
    ret = 0;
4043
 cleanup:
J
Ján Tomko 已提交
4044
    VIR_FREE(str);
4045 4046 4047 4048 4049 4050 4051
    VIR_FREE(nodes);
    xmlXPathFreeContext(ctxt);
    xmlFreeDoc(doc);
    return ret;
}


4052 4053
static void
virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
4054 4055
                                  virBufferPtr buf,
                                  virDomainVirtType type)
4056
{
4057 4058 4059
    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
    qemuMonitorCPUModelInfoPtr model = cpuData->info;
    const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg";
4060 4061
    size_t i;

4062 4063 4064
    if (!model)
        return;

4065 4066 4067 4068
    virBufferAsprintf(buf,
                      "<hostCPU type='%s' model='%s' migratability='%s'>\n",
                      typeStr, model->name,
                      model->migratability ? "yes" : "no");
4069 4070 4071
    virBufferAdjustIndent(buf, 2);

    for (i = 0; i < model->nprops; i++) {
4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094
        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;
        }
4095 4096 4097 4098 4099

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

4100
        virBufferAddLit(buf, "/>\n");
4101 4102 4103 4104 4105 4106 4107
    }

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


4108 4109
static void
virQEMUCapsFormatCPUModels(virQEMUCapsPtr qemuCaps,
4110 4111
                           virBufferPtr buf,
                           virDomainVirtType type)
4112
{
4113 4114
    virDomainCapsCPUModelsPtr cpus;
    const char *typeStr;
4115 4116
    size_t i;

4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128
    if (type == VIR_DOMAIN_VIRT_KVM) {
        typeStr = "kvm";
        cpus = qemuCaps->kvmCPUModels;
    } else {
        typeStr = "tcg";
        cpus = qemuCaps->tcgCPUModels;
    }

    if (!cpus)
        return;

    for (i = 0; i < cpus->nmodels; i++) {
4129 4130
        virDomainCapsCPUModelPtr cpu = cpus->models + i;

4131
        virBufferAsprintf(buf, "<cpu type='%s' ", typeStr);
4132 4133 4134 4135 4136
        virBufferEscapeString(buf, "name='%s'", cpu->name);
        if (cpu->usable) {
            virBufferAsprintf(buf, " usable='%s'",
                              virDomainCapsCPUUsableTypeToString(cpu->usable));
        }
4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151

        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");
        }
4152 4153 4154 4155
    }
}


4156
char *
4157
virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
4158 4159
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4160
    char *ret = NULL;
4161 4162 4163
    size_t i;

    virBufferAddLit(&buf, "<qemuCaps>\n");
4164
    virBufferAdjustIndent(&buf, 2);
4165

4166
    virBufferAsprintf(&buf, "<qemuctime>%llu</qemuctime>\n",
4167
                      (long long) qemuCaps->ctime);
4168
    virBufferAsprintf(&buf, "<selfctime>%llu</selfctime>\n",
4169
                      (long long) qemuCaps->libvirtCtime);
4170
    virBufferAsprintf(&buf, "<selfvers>%lu</selfvers>\n",
4171
                      (unsigned long) qemuCaps->libvirtVersion);
4172 4173

    if (qemuCaps->usedQMP)
4174
        virBufferAddLit(&buf, "<usedQMP/>\n");
4175 4176 4177

    for (i = 0; i < QEMU_CAPS_LAST; i++) {
        if (virQEMUCapsGet(qemuCaps, i)) {
4178
            virBufferAsprintf(&buf, "<flag name='%s'/>\n",
4179 4180 4181 4182
                              virQEMUCapsTypeToString(i));
        }
    }

4183
    virBufferAsprintf(&buf, "<version>%d</version>\n",
4184 4185
                      qemuCaps->version);

4186
    virBufferAsprintf(&buf, "<kvmVersion>%d</kvmVersion>\n",
4187 4188
                      qemuCaps->kvmVersion);

4189 4190 4191 4192
    if (qemuCaps->package)
        virBufferAsprintf(&buf, "<package>%s</package>\n",
                          qemuCaps->package);

4193
    virBufferAsprintf(&buf, "<arch>%s</arch>\n",
4194 4195
                      virArchToString(qemuCaps->arch));

4196 4197
    virQEMUCapsFormatHostCPUModelInfo(qemuCaps, &buf, VIR_DOMAIN_VIRT_KVM);
    virQEMUCapsFormatHostCPUModelInfo(qemuCaps, &buf, VIR_DOMAIN_VIRT_QEMU);
4198

4199 4200
    virQEMUCapsFormatCPUModels(qemuCaps, &buf, VIR_DOMAIN_VIRT_KVM);
    virQEMUCapsFormatCPUModels(qemuCaps, &buf, VIR_DOMAIN_VIRT_QEMU);
4201 4202

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
4203
        virBufferEscapeString(&buf, "<machine name='%s'",
4204 4205
                              qemuCaps->machineTypes[i].name);
        if (qemuCaps->machineTypes[i].alias)
4206
            virBufferEscapeString(&buf, " alias='%s'",
4207
                              qemuCaps->machineTypes[i].alias);
4208 4209
        if (qemuCaps->machineTypes[i].hotplugCpus)
            virBufferAddLit(&buf, " hotplugCpus='yes'");
4210
        virBufferAsprintf(&buf, " maxCpus='%u'/>\n",
4211
                          qemuCaps->machineTypes[i].maxCpus);
4212 4213
    }

A
Andrea Bolognani 已提交
4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229
    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");
    }

4230
    virBufferAdjustIndent(&buf, -2);
4231 4232
    virBufferAddLit(&buf, "</qemuCaps>\n");

4233 4234 4235 4236 4237 4238 4239 4240
    if (virBufferCheckError(&buf) == 0)
        ret = virBufferContentAndReset(&buf);

    return ret;
}


static int
4241 4242 4243
virQEMUCapsSaveFile(void *data,
                    const char *filename,
                    void *privData ATTRIBUTE_UNUSED)
4244
{
4245
    virQEMUCapsPtr qemuCaps = data;
4246 4247
    char *xml = NULL;
    int ret = -1;
4248

4249
    xml = virQEMUCapsFormatCache(qemuCaps);
4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260

    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,
4261
              (long long)qemuCaps->libvirtCtime);
4262 4263 4264 4265 4266 4267 4268 4269

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


4270
static bool
4271 4272
virQEMUCapsIsValid(void *data,
                   void *privData)
4273
{
4274 4275
    virQEMUCapsPtr qemuCaps = data;
    virQEMUCapsCachePrivPtr priv = privData;
4276
    bool kvmUsable;
4277
    struct stat sb;
4278 4279 4280 4281

    if (!qemuCaps->binary)
        return true;

4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293
    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;
    }

4294 4295 4296 4297 4298 4299
    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;
4300 4301
    }

4302
    if (sb.st_ctime != qemuCaps->ctime) {
4303 4304 4305
        VIR_DEBUG("Outdated capabilities for '%s': QEMU binary changed "
                  "(%lld vs %lld)",
                  qemuCaps->binary,
4306
                  (long long) sb.st_ctime, (long long) qemuCaps->ctime);
4307 4308 4309 4310
        return false;
    }

    kvmUsable = virFileAccessibleAs("/dev/kvm", R_OK | W_OK,
4311
                                    priv->runUid, priv->runGid) == 0;
4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_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;
    }

    return true;
}


4334 4335
#define QEMU_SYSTEM_PREFIX "qemu-system-"

4336
static int
4337
virQEMUCapsInitHelp(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid, const char *qmperr)
4338
{
4339
    virCommandPtr cmd = NULL;
4340
    bool is_kvm;
4341
    char *help = NULL;
4342 4343
    int ret = -1;
    const char *tmp;
4344

4345
    VIR_DEBUG("qemuCaps=%p", qemuCaps);
4346

4347
    tmp = strstr(qemuCaps->binary, QEMU_SYSTEM_PREFIX);
4348 4349
    if (tmp) {
        tmp += strlen(QEMU_SYSTEM_PREFIX);
4350

4351
        qemuCaps->arch = virQEMUCapsArchFromString(tmp);
4352
    } else {
4353
        qemuCaps->arch = virArchFromHost();
4354 4355
    }

4356
    cmd = virQEMUCapsProbeCommand(qemuCaps->binary, NULL, runUid, runGid);
4357 4358 4359 4360
    virCommandAddArgList(cmd, "-help", NULL);
    virCommandSetOutputBuffer(cmd, &help);

    if (virCommandRun(cmd, NULL) < 0)
4361
        goto cleanup;
4362

4363 4364 4365 4366 4367
    if (virQEMUCapsParseHelpStr(qemuCaps->binary,
                                help, qemuCaps,
                                &qemuCaps->version,
                                &is_kvm,
                                &qemuCaps->kvmVersion,
4368 4369
                                false,
                                qmperr) < 0)
4370
        goto cleanup;
4371

4372 4373 4374 4375 4376 4377 4378
    /* Older QEMU versions reported -no-acpi in the output of -help even
     * though it was not supported by the architecture. The issue has since
     * been fixed, but to maintain compatibility with all release we still
     * need to filter out the capability for architectures that we know
     * don't support the feature, eg. anything but x86 and aarch64 */
    if (!ARCH_IS_X86(qemuCaps->arch) &&
        qemuCaps->arch != VIR_ARCH_AARCH64) {
4379
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_NO_ACPI);
4380
    }
4381

4382
    /* virQEMUCapsExtractDeviceStr will only set additional caps if qemu
4383
     * understands the 0.13.0+ notion of "-device driver,".  */
J
Ján Tomko 已提交
4384
    if (strstr(help, "-device driver,?") &&
4385 4386
        virQEMUCapsExtractDeviceStr(qemuCaps->binary,
                                    qemuCaps, runUid, runGid) < 0) {
4387
        goto cleanup;
4388
    }
4389

4390
    if (virQEMUCapsProbeCPUModels(qemuCaps, runUid, runGid) < 0)
4391
        goto cleanup;
4392

4393
    if (virQEMUCapsProbeMachineTypes(qemuCaps, runUid, runGid) < 0)
4394
        goto cleanup;
4395

4396
    ret = 0;
4397
 cleanup:
4398
    virCommandFree(cmd);
4399
    VIR_FREE(help);
4400 4401 4402 4403
    return ret;
}


4404
static void virQEMUCapsMonitorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
4405 4406
                                     virDomainObjPtr vm ATTRIBUTE_UNUSED,
                                     void *opaque ATTRIBUTE_UNUSED)
4407 4408 4409 4410
{
}

static qemuMonitorCallbacks callbacks = {
4411 4412
    .eofNotify = virQEMUCapsMonitorNotify,
    .errorNotify = virQEMUCapsMonitorNotify,
4413 4414 4415 4416 4417 4418 4419
};


/* Capabilities that we assume are always enabled
 * for QEMU >= 1.2.0
 */
static void
4420
virQEMUCapsInitQMPBasic(virQEMUCapsPtr qemuCaps)
4421
{
4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_MEM_PATH);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_MONITOR_JSON);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_SDL);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_RTC);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOST_NET);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NODEFCONFIG);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_BOOT_MENU);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NAME_PROCESS);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_VGA_NONE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_AIO);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV_READONLY);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_WAKEUP);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX);
O
Olivia Yin 已提交
4448
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DTB);
J
Ján Tomko 已提交
4449
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION);
4450 4451
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_OPT);
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE);
4452
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_SHARE_POLICY);
4453
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_HOST_PCI_MULTIDOMAIN);
P
Paolo Bonzini 已提交
4454
    virQEMUCapsSet(qemuCaps, QEMU_CAPS_DISPLAY);
4455 4456
}

4457 4458 4459 4460 4461 4462 4463 4464 4465

/**
 * virQEMUCapsInitQMPArch:
 * @qemuCaps: QEMU capabilities
 * @mon: QEMU monitor
 *
 * Initialize the architecture for @qemuCaps by asking @mon.
 *
 * Returns: 0 on success, <0 on failure
4466 4467
 */
static int
4468
virQEMUCapsInitQMPArch(virQEMUCapsPtr qemuCaps,
4469 4470 4471 4472 4473 4474
                            qemuMonitorPtr mon)
{
    char *archstr = NULL;
    int ret = -1;

    if (!(archstr = qemuMonitorGetTargetArch(mon)))
4475
        goto cleanup;
4476 4477 4478 4479 4480 4481 4482

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

4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496
    ret = 0;

 cleanup:
    VIR_FREE(archstr);
    return ret;
}


/**
 * virQEMUCapsInitQMPBasicArch:
 * @qemuCaps: QEMU capabilities
 *
 * Initialize @qemuCaps with basic architecture-dependent capabilities.
 */
4497
void
4498 4499
virQEMUCapsInitQMPBasicArch(virQEMUCapsPtr qemuCaps)
{
4500 4501 4502
    /* ACPI only works on x86 and aarch64 */
    if (ARCH_IS_X86(qemuCaps->arch) ||
        qemuCaps->arch == VIR_ARCH_AARCH64) {
4503
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI);
4504 4505 4506 4507
    }

    /* HPET and KVM PIT are x86 specific */
    if (ARCH_IS_X86(qemuCaps->arch)) {
J
Ján Tomko 已提交
4508
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_HPET);
4509 4510 4511
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT);
    }
}
4512

4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552

/**
 * virQEMUCapsQMPSchemaObjectGetType:
 * @field: name of the object containing the requested type
 * @name: name of the requested type
 * @namefield: name of the object property holding @name
 *
 * Helper that selects the type of a QMP schema object member or it's variant
 * member. Returns the type string on success or NULL on error.
 */
static const char *
virQEMUCapsQMPSchemaObjectGetType(const char *field,
                                  const char *name,
                                  const char *namefield,
                                  virJSONValuePtr elem)
{
    virJSONValuePtr arr;
    virJSONValuePtr cur;
    const char *curname;
    const char *type;
    size_t i;

    if (!(arr = virJSONValueObjectGetArray(elem, field)))
        return NULL;

    for (i = 0; i < virJSONValueArraySize(arr); i++) {
        if (!(cur = virJSONValueArrayGet(arr, i)) ||
            !(curname = virJSONValueObjectGetString(cur, namefield)) ||
            !(type = virJSONValueObjectGetString(cur, "type")))
            continue;

        if (STREQ(name, curname))
            return type;
    }

    return NULL;
}


static virJSONValuePtr
4553
virQEMUCapsQMPSchemaTraverse(const char *baseName,
4554 4555 4556 4557 4558 4559 4560
                             char **query,
                             virHashTablePtr schema)
{
    virJSONValuePtr base;
    const char *metatype;

    do {
4561
        if (!(base = virHashLookup(schema, baseName)))
4562 4563 4564 4565 4566 4567 4568 4569 4570 4571
            return NULL;

        if (!*query)
            return base;

        if (!(metatype = virJSONValueObjectGetString(base, "meta-type")))
            return NULL;

        /* flatten arrays by default */
        if (STREQ(metatype, "array")) {
4572
            if (!(baseName = virJSONValueObjectGetString(base, "element-type")))
4573 4574 4575 4576 4577
                return NULL;

            continue;
        } else if (STREQ(metatype, "object")) {
            if (**query == '+')
4578
                baseName = virQEMUCapsQMPSchemaObjectGetType("variants",
4579 4580 4581
                                                             *query + 1,
                                                             "case", base);
            else
4582
                baseName = virQEMUCapsQMPSchemaObjectGetType("members",
4583 4584 4585
                                                             *query,
                                                             "name", base);

4586
            if (!baseName)
4587 4588 4589
                return NULL;
        } else if (STREQ(metatype, "command") ||
                   STREQ(metatype, "event")) {
4590
            if (!(baseName = virJSONValueObjectGetString(base, *query)))
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 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646
                return NULL;
        } else {
            /* alternates, basic types and enums can't be entered */
            return NULL;
        }

        query++;
    } while (*query);

    return base;
}


/**
 * virQEMUCapsQMPSchemaGetByPath:
 * @query: string specifying the required data type (see below)
 * @schema: hash table containing the schema data
 * @entry: filled with the located schema object requested by @query
 *
 * Retrieves the requested schema entry specified by @query to @entry. The
 * @query parameter has the following syntax which is very closely tied to the
 * qemu schema syntax entries separated by slashes with a few special characters:
 *
 * "command_or_event/attribute/subattribute/+variant_discriminator/subattribute"
 *
 * command_or_event: name of the event or attribute to introspect
 * attribute: selects whether arguments or return type should be introspected
 *            ("arg-type" or "ret-type" for commands, "arg-type" for events)
 * subattribute: specifies member name of object types
 * +variant_discriminator: In the case of unionized objects, select a
 *                         specific case to introspect.
 *
 * Array types are automatically flattened to the singular type. Alternate
 * types are currently not supported.
 *
 * The above types can be chained arbitrarily using slashes to construct any
 * path into the schema tree.
 *
 * Returns 0 on success (including if the requested schema was not found) and
 * fills @entry appropriately. On failure returns -1 and sets an appropriate
 * error message.
 */
static int
virQEMUCapsQMPSchemaGetByPath(const char *query,
                              virHashTablePtr schema,
                              virJSONValuePtr *entry)
{
    char **elems = NULL;

    *entry = NULL;

    if (!(elems = virStringSplit(query, "/", 0)))
        return -1;

    if (!*elems) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed query string"));
4647
        virStringListFree(elems);
4648 4649 4650 4651 4652
        return -1;
    }

    *entry = virQEMUCapsQMPSchemaTraverse(*elems, elems + 1, schema);

4653
    virStringListFree(elems);
4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693
    return 0;
}


static bool
virQEMUCapsQMPSchemaQueryPath(const char *query,
                              virHashTablePtr schema)
{
    virJSONValuePtr entry;

    if (virQEMUCapsQMPSchemaGetByPath(query, schema, &entry))
        return false;

    return !!entry;
}


static int
virQEMUCapsProbeQMPSchemaCapabilities(virQEMUCapsPtr qemuCaps,
                                      qemuMonitorPtr mon)
{
    struct virQEMUCapsStringFlags *entry;
    virHashTablePtr schema;
    size_t i;

    if (!(schema = qemuMonitorQueryQMPSchema(mon)))
        return -1;

    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsQMPSchemaQueries); i++) {
        entry = virQEMUCapsQMPSchemaQueries + i;

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

    virHashFree(schema);
    return 0;
}


4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705
int
virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
                          qemuMonitorPtr mon)
{
    int ret = -1;
    int major, minor, micro;
    char *package = NULL;

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

    if (qemuMonitorSetCapabilities(mon) < 0) {
        VIR_DEBUG("Failed to set monitor capabilities %s",
4706
                  virGetLastErrorMessage());
4707 4708 4709 4710 4711 4712 4713 4714
        ret = 0;
        goto cleanup;
    }

    if (qemuMonitorGetVersion(mon,
                              &major, &minor, &micro,
                              &package) < 0) {
        VIR_DEBUG("Failed to query monitor version %s",
4715
                  virGetLastErrorMessage());
4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729
        ret = 0;
        goto cleanup;
    }

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

    if (major < 1 || (major == 1 && minor < 2)) {
        VIR_DEBUG("Not new enough for QMP capabilities detection");
        ret = 0;
        goto cleanup;
    }

    qemuCaps->version = major * 1000000 + minor * 1000 + micro;
4730
    qemuCaps->package = package;
4731 4732 4733 4734
    qemuCaps->usedQMP = true;

    virQEMUCapsInitQMPBasic(qemuCaps);

4735
    if (virQEMUCapsInitQMPArch(qemuCaps, mon) < 0)
4736 4737
        goto cleanup;

4738 4739
    virQEMUCapsInitQMPBasicArch(qemuCaps);

4740 4741 4742 4743 4744 4745 4746 4747
    /* USB option is supported v1.3.0 onwards */
    if (qemuCaps->version >= 1003000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT);

    /* WebSockets were introduced between 1.3.0 and 1.3.1 */
    if (qemuCaps->version >= 1003001)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET);

4748 4749 4750 4751 4752 4753
    /* -chardev spiceport is supported from 1.4.0, but usable through
     * qapi only since 1.5.0, however, it still cannot be queried
     * for as a capability */
    if (qemuCaps->version >= 1005000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEPORT);

4754 4755 4756
    if (qemuCaps->version >= 1006000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);

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

4761 4762 4763 4764 4765 4766
    /* -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);

4767 4768 4769
    /* vhost-user supports multi-queue from v2.4.0 onwards,
     * but there is no way to query for that capability */
    if (qemuCaps->version >= 2004000)
J
Ján Tomko 已提交
4770
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE);
4771

M
Michal Privoznik 已提交
4772 4773 4774 4775
    /* smm option is supported from v2.4.0 */
    if (qemuCaps->version >= 2004000)
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT);

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

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

4784 4785 4786 4787 4788 4789 4790
    /* 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);
    }

4791 4792
    if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
        goto cleanup;
J
Jiri Denemark 已提交
4793 4794 4795 4796 4797

    /* Some capabilities may differ depending on KVM state */
    if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0)
        goto cleanup;

4798 4799 4800 4801 4802 4803
    if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPObjects(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPMachineTypes(qemuCaps, mon) < 0)
        goto cleanup;
4804
    if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon, false) < 0)
4805 4806 4807 4808 4809
        goto cleanup;
    if (virQEMUCapsProbeQMPTPM(qemuCaps, mon) < 0)
        goto cleanup;
    if (virQEMUCapsProbeQMPCommandLine(qemuCaps, mon) < 0)
        goto cleanup;
4810 4811
    if (virQEMUCapsProbeQMPMigrationCapabilities(qemuCaps, mon) < 0)
        goto cleanup;
4812 4813 4814
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_QMP_SCHEMA) &&
        virQEMUCapsProbeQMPSchemaCapabilities(qemuCaps, mon) < 0)
        goto cleanup;
4815
    if (virQEMUCapsProbeQMPHostCPU(qemuCaps, mon, false) < 0)
4816
        goto cleanup;
4817

4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828
    /* '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);
    }

A
Andrea Bolognani 已提交
4829 4830 4831 4832 4833 4834
    /* GIC capabilities, eg. available GIC versions */
    if ((qemuCaps->arch == VIR_ARCH_AARCH64 ||
         qemuCaps->arch == VIR_ARCH_ARMV7L) &&
        virQEMUCapsProbeQMPGICCapabilities(qemuCaps, mon) < 0)
        goto cleanup;

4835 4836 4837 4838 4839 4840 4841
    /* 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. */
    if (qemuCaps->version < 2009000 &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM))
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM);

4842 4843 4844 4845
    if (ARCH_IS_X86(qemuCaps->arch) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
        virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_CACHE);

4846
    ret = 0;
4847
 cleanup:
4848 4849 4850
    return ret;
}

4851

4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864
int
virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
                             qemuMonitorPtr mon)
{
    int ret = -1;

    if (qemuMonitorSetCapabilities(mon) < 0) {
        VIR_DEBUG("Failed to set monitor capabilities %s",
                  virGetLastErrorMessage());
        ret = 0;
        goto cleanup;
    }

4865 4866 4867
    if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon, true) < 0)
        goto cleanup;

4868 4869 4870
    if (virQEMUCapsProbeQMPHostCPU(qemuCaps, mon, true) < 0)
        goto cleanup;

4871 4872 4873 4874 4875 4876
    ret = 0;
 cleanup:
    return ret;
}


4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888
typedef struct _virQEMUCapsInitQMPCommand virQEMUCapsInitQMPCommand;
typedef virQEMUCapsInitQMPCommand *virQEMUCapsInitQMPCommandPtr;
struct _virQEMUCapsInitQMPCommand {
    char *binary;
    uid_t runUid;
    gid_t runGid;
    char **qmperr;
    char *monarg;
    char *monpath;
    char *pidfile;
    virCommandPtr cmd;
    qemuMonitorPtr mon;
4889
    virDomainChrSourceDef config;
4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961
    pid_t pid;
    virDomainObjPtr vm;
};


static void
virQEMUCapsInitQMPCommandAbort(virQEMUCapsInitQMPCommandPtr cmd)
{
    if (cmd->mon)
        virObjectUnlock(cmd->mon);
    qemuMonitorClose(cmd->mon);
    cmd->mon = NULL;

    virCommandAbort(cmd->cmd);
    virCommandFree(cmd->cmd);
    cmd->cmd = NULL;

    if (cmd->monpath)
        ignore_value(unlink(cmd->monpath));

    virDomainObjEndAPI(&cmd->vm);

    if (cmd->pid != 0) {
        char ebuf[1024];

        VIR_DEBUG("Killing QMP caps process %lld", (long long) cmd->pid);
        if (virProcessKill(cmd->pid, SIGKILL) < 0 && errno != ESRCH)
            VIR_ERROR(_("Failed to kill process %lld: %s"),
                      (long long) cmd->pid,
                      virStrerror(errno, ebuf, sizeof(ebuf)));

        VIR_FREE(*cmd->qmperr);
    }
    if (cmd->pidfile)
        unlink(cmd->pidfile);
    cmd->pid = 0;
}


static void
virQEMUCapsInitQMPCommandFree(virQEMUCapsInitQMPCommandPtr cmd)
{
    if (!cmd)
        return;

    virQEMUCapsInitQMPCommandAbort(cmd);
    VIR_FREE(cmd->binary);
    VIR_FREE(cmd->monpath);
    VIR_FREE(cmd->monarg);
    VIR_FREE(cmd->pidfile);
    VIR_FREE(cmd);
}


static virQEMUCapsInitQMPCommandPtr
virQEMUCapsInitQMPCommandNew(char *binary,
                             const char *libDir,
                             uid_t runUid,
                             gid_t runGid,
                             char **qmperr)
{
    virQEMUCapsInitQMPCommandPtr cmd = NULL;

    if (VIR_ALLOC(cmd) < 0)
        goto error;

    if (VIR_STRDUP(cmd->binary, binary) < 0)
        goto error;

    cmd->runUid = runUid;
    cmd->runGid = runGid;
    cmd->qmperr = qmperr;
4962

4963 4964 4965
    /* the ".sock" sufix is important to avoid a possible clash with a qemu
     * domain called "capabilities"
     */
4966 4967 4968 4969 4970
    if (virAsprintf(&cmd->monpath, "%s/%s", libDir,
                    "capabilities.monitor.sock") < 0)
        goto error;
    if (virAsprintf(&cmd->monarg, "unix:%s,server,nowait", cmd->monpath) < 0)
        goto error;
4971

4972 4973
    /* ".pidfile" suffix is used rather than ".pid" to avoid a possible clash
     * with a qemu domain called "capabilities"
4974 4975 4976
     * Normally we'd use runDir for pid files, but because we're using
     * -daemonize we need QEMU to be allowed to create them, rather
     * than libvirtd. So we're using libDir which QEMU can write to
4977
     */
4978 4979
    if (virAsprintf(&cmd->pidfile, "%s/%s", libDir, "capabilities.pidfile") < 0)
        goto error;
4980

4981
    virPidFileForceCleanupPath(cmd->pidfile);
4982

4983 4984 4985
    cmd->config.type = VIR_DOMAIN_CHR_TYPE_UNIX;
    cmd->config.data.nix.path = cmd->monpath;
    cmd->config.data.nix.listen = false;
4986

4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999
    return cmd;

 error:
    virQEMUCapsInitQMPCommandFree(cmd);
    return NULL;
}


/* Returns -1 on fatal error,
 *          0 on success,
 *          1 when probing QEMU failed
 */
static int
5000 5001
virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr cmd,
                             bool forceTCG)
5002 5003
{
    virDomainXMLOptionPtr xmlopt = NULL;
5004
    const char *machine;
5005 5006 5007
    int status = 0;
    int ret = -1;

5008 5009 5010 5011 5012 5013 5014
    if (forceTCG)
        machine = "none,accel=tcg";
    else
        machine = "none,accel=kvm:tcg";

    VIR_DEBUG("Try to probe capabilities of '%s' via QMP, machine %s",
              cmd->binary, machine);
5015

5016 5017 5018 5019 5020 5021 5022
    /*
     * We explicitly need to use -daemonize here, rather than
     * virCommandDaemonize, because we need to synchronize
     * with QEMU creating its monitor socket API. Using
     * daemonize guarantees control won't return to libvirt
     * until the socket is present.
     */
5023 5024 5025 5026 5027
    cmd->cmd = virCommandNewArgList(cmd->binary,
                                    "-S",
                                    "-no-user-config",
                                    "-nodefaults",
                                    "-nographic",
5028
                                    "-machine", machine,
5029 5030 5031 5032 5033 5034 5035 5036 5037 5038
                                    "-qmp", cmd->monarg,
                                    "-pidfile", cmd->pidfile,
                                    "-daemonize",
                                    NULL);
    virCommandAddEnvPassCommon(cmd->cmd);
    virCommandClearCaps(cmd->cmd);
    virCommandSetGID(cmd->cmd, cmd->runGid);
    virCommandSetUID(cmd->cmd, cmd->runUid);

    virCommandSetErrorBuffer(cmd->cmd, cmd->qmperr);
5039

5040
    /* Log, but otherwise ignore, non-zero status.  */
5041
    if (virCommandRun(cmd->cmd, &status) < 0)
5042 5043 5044
        goto cleanup;

    if (status != 0) {
5045
        VIR_DEBUG("QEMU %s exited with status %d: %s",
5046 5047
                  cmd->binary, status, *cmd->qmperr);
        goto ignore;
5048 5049
    }

5050 5051 5052
    if (virPidFileReadPath(cmd->pidfile, &cmd->pid) < 0) {
        VIR_DEBUG("Failed to read pidfile %s", cmd->pidfile);
        goto ignore;
5053 5054
    }

5055
    if (!(xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL, NULL, NULL)) ||
5056
        !(cmd->vm = virDomainObjNew(xmlopt)))
5057 5058
        goto cleanup;

5059
    cmd->vm->pid = cmd->pid;
5060

5061
    if (!(cmd->mon = qemuMonitorOpen(cmd->vm, &cmd->config, true,
5062
                                     0, &callbacks, NULL)))
5063
        goto ignore;
5064

5065
    virObjectLock(cmd->mon);
5066 5067 5068

    ret = 0;

5069
 cleanup:
5070 5071
    if (!cmd->mon)
        virQEMUCapsInitQMPCommandAbort(cmd);
5072
    virObjectUnref(xmlopt);
5073

5074
    return ret;
5075

5076 5077 5078 5079
 ignore:
    ret = 1;
    goto cleanup;
}
5080

5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096

static int
virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
                   const char *libDir,
                   uid_t runUid,
                   gid_t runGid,
                   char **qmperr)
{
    virQEMUCapsInitQMPCommandPtr cmd = NULL;
    int ret = -1;
    int rc;

    if (!(cmd = virQEMUCapsInitQMPCommandNew(qemuCaps->binary, libDir,
                                             runUid, runGid, qmperr)))
        goto cleanup;

5097
    if ((rc = virQEMUCapsInitQMPCommandRun(cmd, false)) != 0) {
5098 5099 5100
        if (rc == 1)
            ret = 0;
        goto cleanup;
5101
    }
5102 5103 5104 5105

    if (virQEMUCapsInitQMPMonitor(qemuCaps, cmd->mon) < 0)
        goto cleanup;

5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
        virQEMUCapsInitQMPCommandAbort(cmd);
        if ((rc = virQEMUCapsInitQMPCommandRun(cmd, true)) != 0) {
            if (rc == 1)
                ret = 0;
            goto cleanup;
        }

        if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, cmd->mon) < 0)
            goto cleanup;
    }

5118 5119 5120 5121
    ret = 0;

 cleanup:
    virQEMUCapsInitQMPCommandFree(cmd);
5122 5123 5124 5125
    return ret;
}


5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136
#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 },
    };

5137
    virLogMessage(&virLogSelf,
5138 5139 5140 5141
                  VIR_LOG_WARN,
                  __FILE__, __LINE__, __func__,
                  meta,
                  _("Failed to probe capabilities for %s: %s"),
5142
                  binary, virGetLastErrorMessage());
5143 5144 5145
}


5146
virQEMUCapsPtr
5147
virQEMUCapsNewForBinaryInternal(virArch hostArch,
5148
                                const char *binary,
5149 5150 5151 5152
                                const char *libDir,
                                uid_t runUid,
                                gid_t runGid,
                                bool qmpOnly)
5153
{
5154
    virQEMUCapsPtr qemuCaps;
5155
    struct stat sb;
5156
    char *qmperr = NULL;
5157

5158 5159 5160
    if (!(qemuCaps = virQEMUCapsNew()))
        goto error;

5161 5162
    if (VIR_STRDUP(qemuCaps->binary, binary) < 0)
        goto error;
5163 5164 5165 5166 5167 5168 5169 5170

    /* 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;
    }
5171
    qemuCaps->ctime = sb.st_ctime;
5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182

    /* 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;
    }

5183 5184
    if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid, &qmperr) < 0) {
        virQEMUCapsLogProbeFailure(binary);
5185
        goto error;
5186
    }
5187

5188 5189 5190 5191 5192 5193 5194
    if (qmpOnly && !qemuCaps->usedQMP) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to probe QEMU binary with QMP: %s"),
                       qmperr ? qmperr : _("unknown error"));
        virQEMUCapsLogProbeFailure(binary);
        goto error;
    }
5195

5196 5197 5198 5199 5200
    if (!qemuCaps->usedQMP &&
        virQEMUCapsInitHelp(qemuCaps, runUid, runGid, qmperr) < 0) {
        virQEMUCapsLogProbeFailure(binary);
        goto error;
    }
5201

5202 5203
    qemuCaps->libvirtCtime = virGetSelfLastChanged();
    qemuCaps->libvirtVersion = LIBVIR_VERSION_NUMBER;
5204

5205 5206
    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
    virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
5207

5208
 cleanup:
5209
    VIR_FREE(qmperr);
5210
    return qemuCaps;
5211

5212
 error:
5213 5214
    virObjectUnref(qemuCaps);
    qemuCaps = NULL;
5215
    goto cleanup;
5216 5217
}

5218 5219 5220
static void *
virQEMUCapsNewData(const char *binary,
                   void *privData)
5221
{
5222 5223 5224 5225 5226 5227 5228 5229 5230
    virQEMUCapsCachePrivPtr priv = privData;

    return virQEMUCapsNewForBinaryInternal(priv->hostArch,
                                           binary,
                                           priv->libDir,
                                           priv->runUid,
                                           priv->runGid,
                                           false);
}
5231 5232


5233 5234 5235 5236 5237 5238 5239
static void *
virQEMUCapsLoadFile(const char *filename,
                    const char *binary,
                    void *privData)
{
    virQEMUCapsPtr qemuCaps = virQEMUCapsNew();
    virQEMUCapsCachePrivPtr priv = privData;
5240

5241 5242
    if (!qemuCaps)
        return NULL;
5243

5244 5245 5246 5247 5248 5249 5250
    if (VIR_STRDUP(qemuCaps->binary, binary) < 0)
        goto error;

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

 cleanup:
5251 5252 5253 5254
    return qemuCaps;

 error:
    virObjectUnref(qemuCaps);
5255 5256
    qemuCaps = NULL;
    goto cleanup;
5257 5258
}

5259

5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292
struct virQEMUCapsMachineTypeFilter {
    const char *machineType;
    virQEMUCapsFlags *flags;
    size_t nflags;
};

static const struct virQEMUCapsMachineTypeFilter virQEMUCapsMachineFilter[] = {
    /* { "blah", virQEMUCapsMachineBLAHFilter,
         ARRAY_CARDINALITY(virQEMUCapsMachineBLAHFilter) }, */
    { "", NULL, 0 },
};


void
virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps,
                               const char *machineType)
{
    size_t i;

    if (!machineType)
        return;

    for (i = 0; i < ARRAY_CARDINALITY(virQEMUCapsMachineFilter); i++) {
        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]);
    }

5293 5294
    if (!virQEMUCapsGetMachineHotplugCpus(qemuCaps, machineType))
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS);
5295 5296 5297
}


5298 5299 5300 5301 5302 5303 5304 5305 5306 5307
virFileCacheHandlers qemuCapsCacheHandlers = {
    .isValid = virQEMUCapsIsValid,
    .newData = virQEMUCapsNewData,
    .loadFile = virQEMUCapsLoadFile,
    .saveFile = virQEMUCapsSaveFile,
    .privFree = virQEMUCapsCachePrivFree,
};


virFileCachePtr
5308
virQEMUCapsCacheNew(const char *libDir,
5309
                    const char *cacheDir,
5310 5311
                    uid_t runUid,
                    gid_t runGid)
5312
{
5313 5314 5315
    char *capsCacheDir = NULL;
    virFileCachePtr cache = NULL;
    virQEMUCapsCachePrivPtr priv = NULL;
5316

5317
    if (virAsprintf(&capsCacheDir, "%s/capabilities", cacheDir) < 0)
5318
        goto error;
5319 5320

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

5323
    if (VIR_ALLOC(priv) < 0)
5324
        goto error;
5325
    virFileCacheSetPriv(cache, priv);
5326

5327
    if (VIR_STRDUP(priv->libDir, libDir) < 0)
5328 5329
        goto error;

5330
    priv->hostArch = virArchFromHost();
5331

5332 5333
    priv->runUid = runUid;
    priv->runGid = runGid;
5334

5335 5336
 cleanup:
    VIR_FREE(capsCacheDir);
5337 5338
    return cache;

5339
 error:
5340 5341 5342
    virObjectUnref(cache);
    cache = NULL;
    goto cleanup;
5343 5344 5345
}


5346
virQEMUCapsPtr
5347
virQEMUCapsCacheLookup(virFileCachePtr cache,
5348
                       const char *binary)
5349
{
5350
    virQEMUCapsPtr ret = NULL;
5351

5352
    ret = virFileCacheLookup(cache, binary);
5353 5354

    VIR_DEBUG("Returning caps %p for %s", ret, binary);
5355 5356 5357 5358
    return ret;
}


5359
virQEMUCapsPtr
5360
virQEMUCapsCacheLookupCopy(virFileCachePtr cache,
5361
                           const char *binary,
5362
                           const char *machineType)
5363
{
5364
    virQEMUCapsPtr qemuCaps = virQEMUCapsCacheLookup(cache, binary);
5365
    virQEMUCapsPtr ret;
5366

5367
    if (!qemuCaps)
5368 5369
        return NULL;

5370 5371
    ret = virQEMUCapsNewCopy(qemuCaps);
    virObjectUnref(qemuCaps);
5372 5373 5374 5375

    if (!ret)
        return NULL;

5376
    virQEMUCapsFilterByMachineType(ret, machineType);
5377 5378 5379 5380
    return ret;
}


5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393
static int
virQEMUCapsCompareArch(const void *payload,
                       const void *name ATTRIBUTE_UNUSED,
                       const void *opaque)
{
    struct virQEMUCapsSearchData *data = (struct virQEMUCapsSearchData *) opaque;
    const virQEMUCaps *qemuCaps = payload;

    return qemuCaps->arch == data->arch;
}


virQEMUCapsPtr
5394
virQEMUCapsCacheLookupByArch(virFileCachePtr cache,
5395 5396 5397
                             virArch arch)
{
    virQEMUCapsPtr ret = NULL;
5398
    virArch target;
5399 5400
    struct virQEMUCapsSearchData data = { .arch = arch };

5401
    ret = virFileCacheLookupByFunc(cache, virQEMUCapsCompareArch, &data);
5402 5403 5404 5405 5406 5407
    if (!ret) {
        /* If the first attempt at finding capabilities has failed, try
         * again using the QEMU target as lookup key instead */
        target = virQEMUCapsFindTarget(virArchFromHost(), data.arch);
        if (target != data.arch) {
            data.arch = target;
5408
            ret = virFileCacheLookupByFunc(cache, virQEMUCapsCompareArch, &data);
5409 5410
        }
    }
5411

5412
    if (!ret) {
5413 5414 5415 5416 5417
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unable to find any emulator to serve '%s' "
                         "architecture"), virArchToString(arch));
    }

5418 5419
    VIR_DEBUG("Returning caps %p for arch %s", ret, virArchToString(arch));

5420 5421 5422 5423
    return ret;
}


5424 5425 5426 5427 5428 5429 5430
bool
virQEMUCapsSupportsVmport(virQEMUCapsPtr qemuCaps,
                          const virDomainDef *def)
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_VMPORT_OPT))
        return false;

5431 5432
    return qemuDomainIsI440FX(def) ||
        qemuDomainIsQ35(def) ||
5433 5434 5435 5436
        STREQ(def->os.machine, "isapc");
}


M
Michal Privoznik 已提交
5437 5438 5439 5440 5441 5442 5443
bool
virQEMUCapsSupportsSMM(virQEMUCapsPtr qemuCaps,
                       const virDomainDef *def)
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT))
        return false;

5444
    return qemuDomainIsQ35(def);
M
Michal Privoznik 已提交
5445 5446 5447
}


5448 5449 5450 5451 5452 5453 5454
bool
virQEMUCapsIsMachineSupported(virQEMUCapsPtr qemuCaps,
                              const char *canonical_machine)
{
    size_t i;

    for (i = 0; i < qemuCaps->nmachineTypes; i++) {
5455
        if (STREQ(canonical_machine, qemuCaps->machineTypes[i].name))
5456 5457 5458 5459
            return true;
    }
    return false;
}
5460 5461 5462 5463 5464 5465 5466


const char *
virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps)
{
    if (!qemuCaps->nmachineTypes)
        return NULL;
5467
    return qemuCaps->machineTypes[0].name;
5468
}
5469 5470


5471
static int
5472
virQEMUCapsFillDomainLoaderCaps(virDomainCapsLoaderPtr capsLoader,
5473 5474
                                virFirmwarePtr *firmwares,
                                size_t nfirmwares)
5475
{
5476 5477
    size_t i;

5478
    capsLoader->supported = true;
5479

5480
    if (VIR_ALLOC_N(capsLoader->values.values, nfirmwares) < 0)
5481 5482
        return -1;

5483 5484
    for (i = 0; i < nfirmwares; i++) {
        const char *filename = firmwares[i]->name;
5485 5486 5487 5488 5489 5490

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

5491
        if (VIR_STRDUP(capsLoader->values.values[capsLoader->values.nvalues],
5492 5493
                       filename) < 0)
            return -1;
5494
        capsLoader->values.nvalues++;
5495 5496
    }

5497
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
5498 5499
                             VIR_DOMAIN_LOADER_TYPE_ROM);

5500 5501
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->type,
                             VIR_DOMAIN_LOADER_TYPE_PFLASH);
5502 5503


5504 5505 5506
    VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->readonly,
                             VIR_TRISTATE_BOOL_YES,
                             VIR_TRISTATE_BOOL_NO);
5507
    return 0;
5508 5509 5510
}


5511
static int
5512
virQEMUCapsFillDomainOSCaps(virDomainCapsOSPtr os,
5513 5514
                            virFirmwarePtr *firmwares,
                            size_t nfirmwares)
5515
{
5516
    virDomainCapsLoaderPtr capsLoader = &os->loader;
5517

5518
    os->supported = true;
5519
    if (virQEMUCapsFillDomainLoaderCaps(capsLoader, firmwares, nfirmwares) < 0)
5520 5521
        return -1;
    return 0;
5522 5523 5524
}


5525 5526 5527 5528 5529
static int
virQEMUCapsFillDomainCPUCaps(virCapsPtr caps,
                             virQEMUCapsPtr qemuCaps,
                             virDomainCapsPtr domCaps)
{
5530 5531
    if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
                                      VIR_CPU_MODE_HOST_PASSTHROUGH))
5532 5533
        domCaps->cpu.hostPassthrough = true;

5534
    if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
5535
                                      VIR_CPU_MODE_HOST_MODEL)) {
5536 5537
        virCPUDefPtr cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
                                                   VIR_QEMU_CAPS_HOST_CPU_REPORTED);
5538 5539
        domCaps->cpu.hostModel = virCPUDefCopy(cpu);
    }
5540 5541 5542 5543 5544

    if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
                                      VIR_CPU_MODE_CUSTOM)) {
        virDomainCapsCPUModelsPtr filtered = NULL;
        char **models = NULL;
5545
        const char *blacklist[] = { "host", NULL };
5546

J
Jiri Denemark 已提交
5547
        if (virCPUGetModels(domCaps->arch, &models) >= 0) {
5548 5549 5550 5551 5552 5553 5554 5555
            virDomainCapsCPUModelsPtr cpus;

            if (domCaps->virttype == VIR_DOMAIN_VIRT_KVM)
                cpus = qemuCaps->kvmCPUModels;
            else
                cpus = qemuCaps->tcgCPUModels;

            filtered = virDomainCapsCPUModelsFilter(cpus,
5556 5557
                                                    (const char **) models,
                                                    blacklist);
5558
            virStringListFree(models);
5559 5560
        }
        domCaps->cpu.custom = filtered;
5561
    }
5562 5563 5564 5565 5566

    return 0;
}


5567
static int
5568
virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
5569
                                    const char *machine,
5570 5571
                                    virDomainCapsDeviceDiskPtr disk)
{
5572
    disk->supported = true;
5573 5574 5575
    /* QEMU supports all of these */
    VIR_DOMAIN_CAPS_ENUM_SET(disk->diskDevice,
                             VIR_DOMAIN_DISK_DEVICE_DISK,
5576 5577
                             VIR_DOMAIN_DISK_DEVICE_CDROM,
                             VIR_DOMAIN_DISK_DEVICE_LUN);
5578 5579

    /* PowerPC pseries based VMs do not support floppy device */
5580
    if (!qemuDomainMachineIsPSeries(machine, qemuCaps->arch))
5581
        VIR_DOMAIN_CAPS_ENUM_SET(disk->diskDevice, VIR_DOMAIN_DISK_DEVICE_FLOPPY);
5582

5583 5584 5585
    if (qemuDomainMachineHasBuiltinIDE(machine))
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_IDE);

5586 5587 5588 5589 5590
    VIR_DOMAIN_CAPS_ENUM_SET(disk->bus,
                             VIR_DOMAIN_DISK_BUS_SCSI,
                             VIR_DOMAIN_DISK_BUS_VIRTIO,
                             /* VIR_DOMAIN_DISK_BUS_SD */);

5591
    /* PowerPC pseries based VMs do not support floppy device */
5592
    if (!qemuDomainMachineIsPSeries(machine, qemuCaps->arch))
5593 5594
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_FDC);

5595 5596
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE))
        VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_USB);
5597 5598 5599 5600

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

5601
    return 0;
5602 5603 5604
}


5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621
static int
virQEMUCapsFillDomainDeviceGraphicsCaps(virQEMUCapsPtr qemuCaps,
                                        virDomainCapsDeviceGraphicsPtr dev)
{
    dev->supported = true;

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL))
        VIR_DOMAIN_CAPS_ENUM_SET(dev->type, VIR_DOMAIN_GRAPHICS_TYPE_SDL);
    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);

    return 0;
}


5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633
static int
virQEMUCapsFillDomainDeviceVideoCaps(virQEMUCapsPtr qemuCaps,
                                     virDomainCapsDeviceVideoPtr dev)
{
    dev->supported = true;

    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);
5634
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL))
5635 5636 5637 5638 5639 5640 5641 5642
        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);

    return 0;
}


5643
static int
5644 5645 5646 5647 5648 5649
virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
                                       virDomainCapsDeviceHostdevPtr hostdev)
{
    bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();
    bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();

5650
    hostdev->supported = true;
5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663
    /* 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,
                             VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB,
                             VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI);
J
Ján Tomko 已提交
5664
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC))
5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678
        VIR_DOMAIN_CAPS_ENUM_SET(hostdev->subsysType,
                                 VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI);

    /* 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);
    }

J
Ján Tomko 已提交
5679
    if (supportsPassthroughKVM) {
5680 5681 5682 5683
        VIR_DOMAIN_CAPS_ENUM_SET(hostdev->pciBackend,
                                 VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT,
                                 VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM);
    }
5684
    return 0;
5685 5686 5687
}


5688 5689 5690 5691 5692 5693 5694
/**
 * virQEMUCapsSupportsGICVersion:
 * @qemuCaps: QEMU capabilities
 * @virtType: domain type
 * @version: GIC version
 *
 * Checks the QEMU binary with capabilities @qemuCaps supports a specific
5695 5696
 * GIC version for a domain of type @virtType. If @qemuCaps is NULL, the GIC
 * @version is considered unsupported.
5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707
 *
 * Returns: true if the binary supports the requested GIC version, false
 *          otherwise
 */
bool
virQEMUCapsSupportsGICVersion(virQEMUCapsPtr qemuCaps,
                              virDomainVirtType virtType,
                              virGICVersion version)
{
    size_t i;

5708 5709 5710
    if (!qemuCaps)
        return false;

5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729
    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;
}


5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753
/**
 * 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.
 *
 * Returns: 0 on success, <0 on failure
 */
static int
virQEMUCapsFillDomainFeatureGICCaps(virQEMUCapsPtr qemuCaps,
                                    virDomainCapsPtr domCaps)
{
    virDomainCapsFeatureGICPtr gic = &domCaps->gic;
5754
    virGICVersion version;
5755

5756
    if (!qemuDomainMachineIsVirt(domCaps->machine, domCaps->arch))
5757 5758
        return 0;

5759 5760 5761 5762 5763 5764
    for (version = VIR_GIC_VERSION_LAST - 1;
         version > VIR_GIC_VERSION_NONE;
         version--) {
        if (!virQEMUCapsSupportsGICVersion(qemuCaps,
                                           domCaps->virttype,
                                           version))
5765 5766 5767 5768
            continue;

        gic->supported = true;
        VIR_DOMAIN_CAPS_ENUM_SET(gic->version,
5769
                                 version);
5770 5771 5772 5773 5774 5775
    }

    return 0;
}


5776
int
5777 5778
virQEMUCapsFillDomainCaps(virCapsPtr caps,
                          virDomainCapsPtr domCaps,
5779
                          virQEMUCapsPtr qemuCaps,
5780
                          virFirmwarePtr *firmwares,
5781
                          size_t nfirmwares)
5782
{
5783
    virDomainCapsOSPtr os = &domCaps->os;
5784 5785
    virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
    virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
5786
    virDomainCapsDeviceGraphicsPtr graphics = &domCaps->graphics;
5787
    virDomainCapsDeviceVideoPtr video = &domCaps->video;
5788

5789 5790
    domCaps->maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps,
                                                     domCaps->machine);
5791
    if (domCaps->virttype == VIR_DOMAIN_VIRT_KVM) {
5792 5793 5794 5795 5796 5797
        int hostmaxvcpus;

        if ((hostmaxvcpus = virHostCPUGetKVMMaxVCPUs()) < 0)
            return -1;

        domCaps->maxvcpus = MIN(domCaps->maxvcpus, hostmaxvcpus);
5798
    }
5799

5800
    if (virQEMUCapsFillDomainOSCaps(os, firmwares, nfirmwares) < 0 ||
5801
        virQEMUCapsFillDomainCPUCaps(caps, qemuCaps, domCaps) < 0 ||
5802 5803 5804
        virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps,
                                            domCaps->machine, disk) < 0 ||
        virQEMUCapsFillDomainDeviceGraphicsCaps(qemuCaps, graphics) < 0 ||
5805
        virQEMUCapsFillDomainDeviceVideoCaps(qemuCaps, video) < 0 ||
5806 5807
        virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev) < 0 ||
        virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps) < 0)
5808 5809
        return -1;
    return 0;
5810
}