From d176c495b6664b72dc1e595f6e89dc5648aa248b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 31 Jul 2009 12:25:41 +0200 Subject: [PATCH] qdev-ify virtio-blk. First user of the new drive property. With this patch applied host and guest config can be specified separately, like this: -drive if=none,id=disk1,file=/path/to/disk.img -device virtio-blk-pci,drive=disk1 You can set any property for virtio-blk-pci now. You can set the pci address via addr=. You can switch the device into 0.10 compat mode using class=0x0180. As this is per device you can have one 0.10 and one 0.11 virtio block device in a single virtual machine. Old syntax continues to work. Internally it does the same as the two lines above though. One side effect this has is a different initialization order, which might result in a different pci address being assigned by default. Long term plan here is to have this working for all block devices, i.e. once all scsi is properly qdev-ified you will be able to do something like this: -drive if=none,id=sda,file=/path/to/disk.img -device lsi,id=lsi,addr= -device scsi-disk,drive=sda,bus=lsi.0,lun= Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori Message-Id: --- hw/pc.c | 12 ------------ hw/pci-hotplug.c | 1 + hw/ppc440_bamboo.c | 11 ----------- hw/ppce500_mpc8544ds.c | 11 ----------- hw/virtio-blk.c | 10 ++++------ hw/virtio-pci.c | 12 ++++++++++-- hw/virtio.h | 3 ++- vl.c | 9 ++++++++- 8 files changed, 25 insertions(+), 44 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index bc9e646..6e5669c 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1409,18 +1409,6 @@ static void pc_init1(ram_addr_t ram_size, } } - /* Add virtio block devices */ - if (pci_enabled) { - int unit_id = 0; - - while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) { - pci_dev = pci_create("virtio-blk-pci", - dinfo->devaddr); - qdev_init(&pci_dev->qdev); - unit_id++; - } - } - /* Add virtio balloon device */ if (pci_enabled && virtio_balloon) { pci_dev = pci_create("virtio-balloon-pci", virtio_balloon_devaddr); diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index 43675e2..4da916c 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -136,6 +136,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, break; case IF_VIRTIO: dev = pci_create("virtio-blk-pci", devaddr); + qdev_prop_set_drive(&dev->qdev, "drive", dinfo); break; default: dev = NULL; diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c index 5011679..3c59f33 100644 --- a/hw/ppc440_bamboo.c +++ b/hw/ppc440_bamboo.c @@ -90,7 +90,6 @@ static void bamboo_init(ram_addr_t ram_size, { unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 }; PCIBus *pcibus; - PCIDevice *pci_dev; CPUState *env; uint64_t elf_entry; uint64_t elf_lowaddr; @@ -102,21 +101,11 @@ static void bamboo_init(ram_addr_t ram_size, target_ulong dt_base = 0; void *fdt; int i; - DriveInfo *dinfo; /* Setup CPU. */ env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1, cpu_model); if (pcibus) { - int unit_id = 0; - - /* Add virtio block devices. */ - while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) { - pci_dev = pci_create("virtio-blk-pci", dinfo->devaddr); - qdev_init(&pci_dev->qdev); - unit_id++; - } - /* Add virtio console devices */ for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { if (virtcon_hds[i]) { diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c index d154c7f..5120821 100644 --- a/hw/ppce500_mpc8544ds.c +++ b/hw/ppce500_mpc8544ds.c @@ -157,7 +157,6 @@ static void mpc8544ds_init(ram_addr_t ram_size, const char *cpu_model) { PCIBus *pci_bus; - PCIDevice *pci_dev; CPUState *env; uint64_t elf_entry; uint64_t elf_lowaddr; @@ -172,7 +171,6 @@ static void mpc8544ds_init(ram_addr_t ram_size, unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; qemu_irq *irqs, *mpic, *pci_irqs; SerialState * serial[2]; - DriveInfo *dinfo; /* Setup CPU */ env = cpu_ppc_init("e500v2_v30"); @@ -217,15 +215,6 @@ static void mpc8544ds_init(ram_addr_t ram_size, isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); if (pci_bus) { - int unit_id = 0; - - /* Add virtio block devices. */ - while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) { - pci_dev = pci_create("virtio-blk-pci", dinfo->devaddr); - qdev_init(&pci_dev->qdev); - unit_id++; - } - /* Register network interfaces. */ for (i = 0; i < nb_nics; i++) { pci_nic_init(&nd_table[i], "virtio", NULL); diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 5036b5b..c278d2e 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -414,29 +414,27 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id) return 0; } -VirtIODevice *virtio_blk_init(DeviceState *dev) +VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo) { VirtIOBlock *s; int cylinders, heads, secs; static int virtio_blk_id; - BlockDriverState *bs; char *ps; s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK, sizeof(struct virtio_blk_config), sizeof(VirtIOBlock)); - bs = qdev_init_bdrv(dev, IF_VIRTIO); s->vdev.get_config = virtio_blk_update_config; s->vdev.get_features = virtio_blk_get_features; s->vdev.reset = virtio_blk_reset; - s->bs = bs; + s->bs = dinfo->bdrv; s->rq = NULL; - if (strlen(ps = (char *)drive_get_serial(bs))) + if (strlen(ps = (char *)drive_get_serial(s->bs))) strncpy(s->serial_str, ps, sizeof(s->serial_str)); else snprintf(s->serial_str, sizeof(s->serial_str), "0"); - bs->private = dev; + s->bs->private = dev; bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs); bdrv_set_geometry_hint(s->bs, cylinders, heads, secs); diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 703f4fe..8cf4b57 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -17,7 +17,7 @@ #include "virtio.h" #include "pci.h" -//#include "sysemu.h" +#include "sysemu.h" #include "msix.h" #include "net.h" @@ -89,6 +89,7 @@ typedef struct { uint32_t addr; uint32_t class_code; uint32_t nvectors; + DriveInfo *dinfo; } VirtIOPCIProxy; /* virtio device */ @@ -432,7 +433,10 @@ static void virtio_blk_init_pci(PCIDevice *pci_dev) proxy->class_code != PCI_CLASS_STORAGE_OTHER) proxy->class_code = PCI_CLASS_STORAGE_SCSI; - vdev = virtio_blk_init(&pci_dev->qdev); + if (!proxy->dinfo) { + fprintf(stderr, "drive property not set\n"); + } + vdev = virtio_blk_init(&pci_dev->qdev, proxy->dinfo); virtio_init_pci(proxy, vdev, PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_DEVICE_ID_VIRTIO_BLOCK, @@ -502,6 +506,10 @@ static PCIDeviceInfo virtio_info[] = { .name = "class", .info = &qdev_prop_hex32, .offset = offsetof(VirtIOPCIProxy, class_code), + },{ + .name = "drive", + .info = &qdev_prop_drive, + .offset = offsetof(VirtIOPCIProxy, dinfo), }, {/* end of list */} }, diff --git a/hw/virtio.h b/hw/virtio.h index aa55677..c441a93 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -16,6 +16,7 @@ #include "hw.h" #include "qdev.h" +#include "sysemu.h" /* from Linux's linux/virtio_config.h */ @@ -161,7 +162,7 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding, void *opaque); /* Base devices. */ -VirtIODevice *virtio_blk_init(DeviceState *dev); +VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo); VirtIODevice *virtio_net_init(DeviceState *dev); VirtIODevice *virtio_console_init(DeviceState *dev); VirtIODevice *virtio_balloon_init(DeviceState *dev); diff --git a/vl.c b/vl.c index 5bf3051..9b390e7 100644 --- a/vl.c +++ b/vl.c @@ -2197,9 +2197,16 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, break; case IF_PFLASH: case IF_MTD: - case IF_VIRTIO: case IF_NONE: break; + case IF_VIRTIO: + /* add virtio block device */ + opts = qemu_opts_create(&qemu_device_opts, NULL, 0); + qemu_opt_set(opts, "driver", "virtio-blk-pci"); + qemu_opt_set(opts, "drive", dinfo->id); + if (devaddr) + qemu_opt_set(opts, "addr", devaddr); + break; case IF_COUNT: abort(); } -- 1.7.9.5