diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 519d2c5173..50f8084426 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -210,7 +210,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "rng-random", /* 130 */ "rng-egd", - "virtio-ccw" + "virtio-ccw", + "dtb", ); struct _virQEMUCaps { @@ -1086,6 +1087,9 @@ virQEMUCapsComputeCmdFlags(const char *help, if (strstr(help, "dump-guest-core=on|off")) virQEMUCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE); + if (strstr(help, "-dtb")) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DTB); + /* * Handling of -incoming arg with varying features * -incoming tcp (kvm >= 79, qemu >= 0.10.0) @@ -2310,6 +2314,7 @@ virQEMUCapsInitQMPBasic(virQEMUCapsPtr qemuCaps) virQEMUCapsSet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE); virQEMUCapsSet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX); virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT); + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DTB); } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index da06e27b86..b0f8c5b6d6 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -172,6 +172,7 @@ enum virQEMUCapsFlags { virtio rng */ QEMU_CAPS_OBJECT_RNG_EGD = 131, /* EGD protocol daemon for rng */ QEMU_CAPS_VIRTIO_CCW = 132, /* -device virtio-*-ccw */ + QEMU_CAPS_DTB = 133, /* -dtb file */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4891b65262..8626b629b9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6152,6 +6152,15 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArgList(cmd, "-initrd", def->os.initrd, NULL); if (def->os.cmdline) virCommandAddArgList(cmd, "-append", def->os.cmdline, NULL); + if (def->os.dtb) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DTB)) { + virCommandAddArgList(cmd, "-dtb", def->os.dtb, NULL); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("dtb is not supported with this QEMU binary")); + goto error; + } + } } else { virCommandAddArgList(cmd, "-bootloader", def->os.bootloader, NULL); } @@ -9239,6 +9248,10 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps, WANT_VALUE(); if (!(def->os.cmdline = strdup(val))) goto no_memory; + } else if (STREQ(arg, "-dtb")) { + WANT_VALUE(); + if (!(def->os.dtb = strdup(val))) + goto no_memory; } else if (STREQ(arg, "-boot")) { const char *token = NULL; WANT_VALUE(); diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index 842cdc9afd..059fa861f5 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -811,7 +811,8 @@ mymain(void) QEMU_CAPS_DEVICE_CIRRUS_VGA, QEMU_CAPS_DEVICE_VMWARE_SVGA, QEMU_CAPS_DEVICE_USB_SERIAL, - QEMU_CAPS_DEVICE_USB_NET); + QEMU_CAPS_DEVICE_USB_NET, + QEMU_CAPS_DTB); DO_TEST("qemu-1.2.0", 1002000, 0, 0, QEMU_CAPS_VNC_COLON, QEMU_CAPS_NO_REBOOT, @@ -910,7 +911,8 @@ mymain(void) QEMU_CAPS_DEVICE_VMWARE_SVGA, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_USB_SERIAL, - QEMU_CAPS_DEVICE_USB_NET); + QEMU_CAPS_DEVICE_USB_NET, + QEMU_CAPS_DTB); DO_TEST("qemu-kvm-1.2.0", 1002000, 1, 0, QEMU_CAPS_VNC_COLON, QEMU_CAPS_NO_REBOOT, @@ -1014,7 +1016,8 @@ mymain(void) QEMU_CAPS_DEVICE_VMWARE_SVGA, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, QEMU_CAPS_DEVICE_USB_SERIAL, - QEMU_CAPS_DEVICE_USB_NET); + QEMU_CAPS_DEVICE_USB_NET, + QEMU_CAPS_DTB); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-ppc-dtb.args b/tests/qemuxml2argvdata/qemuxml2argv-ppc-dtb.args new file mode 100644 index 0000000000..93e8f9ca08 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-ppc-dtb.args @@ -0,0 +1,6 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/bin/qemu-system-ppc -S -M ppce500v2 -m 256 -smp 1 -nographic \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-kernel /media/ram/uImage -initrd /media/ram/ramdisk \ +-append 'root=/dev/ram rw console=ttyS0,115200' -dtb /media/ram/test.dtb \ +-usb -net none -serial pty -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-ppc-dtb.xml b/tests/qemuxml2argvdata/qemuxml2argv-ppc-dtb.xml new file mode 100644 index 0000000000..36746216a0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-ppc-dtb.xml @@ -0,0 +1,28 @@ + + QEMUGuest1 + 49545eb3-75e1-2d0a-acdd-f0294406c99e + 262144 + 262144 + 1 + + hvm + /media/ram/uImage + /media/ram/ramdisk + root=/dev/ram rw console=ttyS0,115200 + /media/ram/test.dtb + + + destroy + restart + destroy + + /usr/bin/qemu-system-ppc + + + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index e76d84491a..44bfe678c8 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -916,6 +916,8 @@ mymain(void) QEMU_CAPS_VIRTIO_S390, QEMU_CAPS_DEVICE_VIRTIO_RNG, QEMU_CAPS_OBJECT_RNG_RANDOM); + DO_TEST("ppc-dtb", QEMU_CAPS_KVM, QEMU_CAPS_DTB); + virObjectUnref(driver.config); virObjectUnref(driver.caps); virObjectUnref(driver.xmlconf); diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index 4e13db915f..db15ee66aa 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -92,6 +92,36 @@ error: return -1; } +static int testQemuAddPPCGuest(virCapsPtr caps) +{ + static const char *machine[] = { "g3beige", + "mac99", + "prep", + "ppce500v2" }; + virCapsGuestMachinePtr *machines = NULL; + virCapsGuestPtr guest; + + machines = virCapabilitiesAllocMachines(machine, 1); + if (!machines) + goto error; + + guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_PPC, + "/usr/bin/qemu-system-ppc", NULL, + 1, machines); + if (!guest) + goto error; + + if (!virCapabilitiesAddGuestDomain(guest, "qemu", NULL, NULL, 0, NULL)) + goto error; + + return 0; + +error: + /* No way to free a guest? */ + virCapabilitiesFreeMachines(machines, 1); + return -1; +} + static int testQemuAddS390Guest(virCapsPtr caps) { static const char *s390_machines[] = { "s390-virtio", @@ -242,6 +272,9 @@ virCapsPtr testQemuCapsInit(void) { if (testQemuAddPPC64Guest(caps)) goto cleanup; + if (testQemuAddPPCGuest(caps)) + goto cleanup; + if (testQemuAddS390Guest(caps)) goto cleanup;