diff options
Diffstat (limited to 'hw')
73 files changed, 641 insertions, 327 deletions
diff --git a/hw/9pfs/virtio-9p-synth.c b/hw/9pfs/virtio-9p-synth.c index e75aa87..a0ab9a8 100644 --- a/hw/9pfs/virtio-9p-synth.c +++ b/hw/9pfs/virtio-9p-synth.c @@ -18,7 +18,7 @@ #include "fsdev/qemu-fsdev.h" #include "virtio-9p-synth.h" #include "qemu/rcu.h" - +#include "qemu/rcu_queue.h" #include <sys/stat.h> /* Root node for synth file system */ diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index 5310006..62af946 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -920,7 +920,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus, { qemu_irq isa_pci_irq, *isa_irqs; - *isa_bus = isa_bus_new(NULL, &s->pchip.reg_io); + *isa_bus = isa_bus_new(NULL, get_system_memory(), &s->pchip.reg_io); isa_pci_irq = *qemu_allocate_irqs(typhoon_set_isa_irq, s, 1); isa_irqs = i8259_init(*isa_bus, isa_pci_irq); isa_bus_irqs(*isa_bus, isa_irqs); diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 97dafca..c55fab8 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -158,7 +158,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem, if (object_property_find(cpuobj, "has_el3", NULL)) { object_property_set_bool(cpuobj, false, "has_el3", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } @@ -168,7 +168,7 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem, "reset-cbar", &error_abort); object_property_set_bool(cpuobj, true, "realized", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index f67570a..a92cdc3 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -248,7 +248,7 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) if (object_property_find(cpuobj, "has_el3", NULL)) { object_property_set_bool(cpuobj, false, "has_el3", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } @@ -259,7 +259,7 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) } object_property_set_bool(cpuobj, true, "realized", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ); diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index 8c48b68..949ae1e 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -500,14 +500,14 @@ static void integratorcp_init(MachineState *machine) if (object_property_find(cpuobj, "has_el3", NULL)) { object_property_set_bool(cpuobj, false, "has_el3", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } object_property_set_bool(cpuobj, true, "realized", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } diff --git a/hw/arm/realview.c b/hw/arm/realview.c index 50cb93d..ef2788d 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -108,7 +108,7 @@ static void realview_init(MachineState *machine, if (object_property_find(cpuobj, "has_el3", NULL)) { object_property_set_bool(cpuobj, false, "has_el3", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } @@ -116,14 +116,14 @@ static void realview_init(MachineState *machine, if (is_pb && is_mpcore) { object_property_set_int(cpuobj, periphbase, "reset-cbar", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } object_property_set_bool(cpuobj, true, "realized", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index b1dae77..624fdb0 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -213,14 +213,14 @@ static void versatile_init(MachineState *machine, int board_id) if (object_property_find(cpuobj, "has_el3", NULL)) { object_property_set_bool(cpuobj, false, "has_el3", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } object_property_set_bool(cpuobj, true, "realized", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 84415c8..5933454 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -223,7 +223,7 @@ static void init_cpus(const char *cpu_model, const char *privdev, } object_property_set_bool(cpuobj, true, "realized", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 06e6e24..5c37521 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -133,25 +133,25 @@ static void zynq_init(MachineState *machine) if (object_property_find(OBJECT(cpu), "has_el3", NULL)) { object_property_set_bool(OBJECT(cpu), false, "has_el3", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } } object_property_set_int(OBJECT(cpu), ZYNQ_BOARD_MIDR, "midr", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } object_property_set_int(OBJECT(cpu), MPCORE_PERIPHBASE, "reset-cbar", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } object_property_set_bool(OBJECT(cpu), true, "realized", &err); if (err) { - error_report("%s", error_get_pretty(err)); + error_report_err(err); exit(1); } diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index be957d1..cd41478 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -16,7 +16,9 @@ #include "qemu/iov.h" #include "qemu/thread.h" #include "qemu/error-report.h" +#include "hw/virtio/virtio-access.h" #include "hw/virtio/dataplane/vring.h" +#include "hw/virtio/dataplane/vring-accessors.h" #include "sysemu/block-backend.h" #include "hw/virtio/virtio-blk.h" #include "virtio-blk.h" @@ -75,7 +77,7 @@ static void complete_request_vring(VirtIOBlockReq *req, unsigned char status) VirtIOBlockDataPlane *s = req->dev->dataplane; stb_p(&req->in->status, status); - vring_push(&req->dev->dataplane->vring, &req->elem, + vring_push(s->vdev, &req->dev->dataplane->vring, &req->elem, req->qiov.size + sizeof(*req->in)); /* Suppress notification to guest by BH and its scheduled diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 1a8a176..cb71772 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -858,8 +858,7 @@ static void virtio_blk_migration_state_changed(Notifier *notifier, void *data) virtio_blk_data_plane_create(VIRTIO_DEVICE(s), &s->conf, &s->dataplane, &err); if (err != NULL) { - error_report("%s", error_get_pretty(err)); - error_free(err); + error_report_err(err); } } } diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 21842a0..267d8a8 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -40,6 +40,8 @@ #include "xen_blkif.h" #include "sysemu/blockdev.h" #include "sysemu/block-backend.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qstring.h" /* ------------------------------------------------------------- */ @@ -897,30 +899,23 @@ static int blk_connect(struct XenDevice *xendev) blkdev->dinfo = drive_get(IF_XEN, 0, index); if (!blkdev->dinfo) { Error *local_err = NULL; - BlockBackend *blk; - BlockDriver *drv; - BlockDriverState *bs; + QDict *options = NULL; - /* setup via xenbus -> create new block driver instance */ - xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); - blk = blk_new_with_bs(blkdev->dev, NULL); - if (!blk) { - return -1; + if (strcmp(blkdev->fileproto, "<unset>")) { + options = qdict_new(); + qdict_put(options, "driver", qstring_from_str(blkdev->fileproto)); } - blkdev->blk = blk; - bs = blk_bs(blk); - drv = bdrv_find_whitelisted_format(blkdev->fileproto, readonly); - if (bdrv_open(&bs, blkdev->filename, NULL, NULL, qflags, - drv, &local_err) != 0) { + /* setup via xenbus -> create new block driver instance */ + xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); + blkdev->blk = blk_new_open(blkdev->dev, blkdev->filename, NULL, options, + qflags, &local_err); + if (!blkdev->blk) { xen_be_printf(&blkdev->xendev, 0, "error: %s\n", error_get_pretty(local_err)); error_free(local_err); - blk_unref(blk); - blkdev->blk = NULL; return -1; } - assert(bs == blk_bs(blk)); } else { /* setup via qemu cmdline -> already setup for us */ xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); diff --git a/hw/char/serial.c b/hw/char/serial.c index 0491897..55011cf 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -906,8 +906,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase, s->chr = chr; serial_realize_core(s, &err); if (err != NULL) { - error_report("%s", error_get_pretty(err)); - error_free(err); + error_report_err(err); exit(1); } @@ -970,8 +969,7 @@ SerialState *serial_mm_init(MemoryRegion *address_space, serial_realize_core(s, &err); if (err != NULL) { - error_report("%s", error_get_pretty(err)); - error_free(err); + error_report_err(err); exit(1); } vmstate_register(NULL, base, &vmstate_serial, s); diff --git a/hw/core/loader.c b/hw/core/loader.c index fcd4705..e45dc0b 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -1062,7 +1062,7 @@ void *rom_ptr(hwaddr addr) return rom->data + (addr - rom->addr); } -void do_info_roms(Monitor *mon, const QDict *qdict) +void hmp_info_roms(Monitor *mon, const QDict *qdict) { Rom *rom; diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 10bf086..a02a4cb 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -823,6 +823,13 @@ static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev) return d; } +char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev) +{ + Object *obj = OBJECT(dev); + + return fw_path_provider_try_get_dev_path(obj, bus, dev); +} + static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size) { int l = 0; diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 3a53f20..ec923c8 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -2907,7 +2907,7 @@ static void cirrus_init_common(CirrusVGAState *s, Object *owner, bank, 1); } memory_region_add_subregion_overlap(system_memory, - isa_mem_base + 0x000a0000, + 0x000a0000, &s->low_mem_container, 1); memory_region_set_coalescing(&s->low_mem); diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c index 2b480bd..7f3c989 100644 --- a/hw/display/vga-isa.c +++ b/hw/display/vga-isa.c @@ -64,7 +64,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp) isa_register_portio_list(isadev, 0x1ce, vbe_ports, s, "vbe"); } memory_region_add_subregion_overlap(isa_address_space(isadev), - isa_mem_base + 0x000a0000, + 0x000a0000, vga_io_memory, 1); memory_region_set_coalescing(vga_io_memory); s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s); diff --git a/hw/display/vga.c b/hw/display/vga.c index 9c62fbf..c8c49ab 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -177,7 +177,6 @@ static void vga_update_memory_access(VGACommonState *s) size = 0x8000; break; } - base += isa_mem_base; memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram), "vga.chain4", &s->vram, offset, size); memory_region_add_subregion_overlap(s->legacy_address_space, base, @@ -2218,7 +2217,7 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports); memory_region_add_subregion_overlap(address_space, - isa_mem_base + 0x000a0000, + 0x000a0000, vga_io_memory, 1); memory_region_set_coalescing(vga_io_memory); diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 0a4282a..7da70ff 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -745,6 +745,9 @@ static inline bool vtd_is_interrupt_addr(hwaddr addr) /* Map dev to context-entry then do a paging-structures walk to do a iommu * translation. + * + * Called from RCU critical section. + * * @bus_num: The bus number * @devfn: The devfn, which is the combined of device and function number * @is_write: The access is a write operation diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index bb206da..bd92c69 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -552,9 +552,8 @@ static void get_real_device(AssignedDevice *pci_dev, Error **errp) snprintf(name, sizeof(name), "%sconfig", dir); if (pci_dev->configfd_name && *pci_dev->configfd_name) { - dev->config_fd = monitor_handle_fd_param2(cur_mon, - pci_dev->configfd_name, - &local_err); + dev->config_fd = monitor_fd_param(cur_mon, pci_dev->configfd_name, + &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -953,8 +952,7 @@ static void assigned_dev_update_irq_routing(PCIDevice *dev) r = assign_intx(assigned_dev, &err); if (r < 0) { - error_report("%s", error_get_pretty(err)); - error_free(err); + error_report_err(err); err = NULL; qdev_unplug(&dev->qdev, &err); assert(!err); @@ -1010,8 +1008,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev) assign_intx(assigned_dev, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); - error_free(local_err); + error_report_err(local_err); } } } @@ -1158,8 +1155,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev) assign_intx(assigned_dev, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); - error_free(local_err); + error_report_err(local_err); } } } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ed623e1..03dc007 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -41,6 +41,7 @@ #include "hw/pci/msi.h" #include "hw/sysbus.h" #include "sysemu/sysemu.h" +#include "sysemu/numa.h" #include "sysemu/kvm.h" #include "kvm_i386.h" #include "hw/xen/xen.h" @@ -414,7 +415,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, set_boot_dev(s, boot_device, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); + error_report_err(local_err); exit(1); } @@ -1040,8 +1041,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), icc_bridge, &error); if (error) { - error_report("%s", error_get_pretty(error)); - error_free(error); + error_report_err(error); exit(1); } } diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 38b42b0..de75cf0 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -208,7 +208,7 @@ static void pc_init1(MachineState *machine, } else { pci_bus = NULL; i440fx_state = NULL; - isa_bus = isa_bus_new(NULL, system_io); + isa_bus = isa_bus_new(NULL, get_system_memory(), system_io); no_hpet = 1; } isa_bus_irqs(isa_bus, gsi); diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c index 12d2137..f2e9ab6 100644 --- a/hw/i386/smbios.c +++ b/hw/i386/smbios.c @@ -908,7 +908,7 @@ void smbios_entry_add(QemuOpts *opts) qemu_opts_validate(opts, qemu_smbios_file_opts, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); + error_report_err(local_err); exit(1); } @@ -994,7 +994,7 @@ void smbios_entry_add(QemuOpts *opts) case 0: qemu_opts_validate(opts, qemu_smbios_type0_opts, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); + error_report_err(local_err); exit(1); } save_opt(&type0.vendor, opts, "vendor"); @@ -1014,7 +1014,7 @@ void smbios_entry_add(QemuOpts *opts) case 1: qemu_opts_validate(opts, qemu_smbios_type1_opts, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); + error_report_err(local_err); exit(1); } save_opt(&type1.manufacturer, opts, "manufacturer"); @@ -1036,7 +1036,7 @@ void smbios_entry_add(QemuOpts *opts) case 2: qemu_opts_validate(opts, qemu_smbios_type2_opts, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); + error_report_err(local_err); exit(1); } save_opt(&type2.manufacturer, opts, "manufacturer"); @@ -1049,7 +1049,7 @@ void smbios_entry_add(QemuOpts *opts) case 3: qemu_opts_validate(opts, qemu_smbios_type3_opts, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); + error_report_err(local_err); exit(1); } save_opt(&type3.manufacturer, opts, "manufacturer"); @@ -1061,7 +1061,7 @@ void smbios_entry_add(QemuOpts *opts) case 4: qemu_opts_validate(opts, qemu_smbios_type4_opts, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); + error_report_err(local_err); exit(1); } save_opt(&type4.sock_pfx, opts, "sock_pfx"); @@ -1074,7 +1074,7 @@ void smbios_entry_add(QemuOpts *opts) case 17: qemu_opts_validate(opts, qemu_smbios_type17_opts, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); + error_report_err(local_err); exit(1); } save_opt(&type17.loc_pfx, opts, "loc_pfx"); diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 1ebb58d..b4103fa 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -172,8 +172,7 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind) if (kind != IDE_CD) { blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255, &err); if (err) { - error_report("%s", error_get_pretty(err)); - error_free(err); + error_report_err(err); return -1; } } diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c index c51901b..0f5c025 100644 --- a/hw/intc/i8259.c +++ b/hw/intc/i8259.c @@ -429,7 +429,7 @@ static void pic_realize(DeviceState *dev, Error **errp) pc->parent_realize(dev, errp); } -void pic_info(Monitor *mon, const QDict *qdict) +void hmp_info_pic(Monitor *mon, const QDict *qdict) { int i; PICCommonState *s; @@ -447,7 +447,7 @@ void pic_info(Monitor *mon, const QDict *qdict) } } -void irq_info(Monitor *mon, const QDict *qdict) +void hmp_info_irq(Monitor *mon, const QDict *qdict) { #ifndef DEBUG_IRQ_COUNT monitor_printf(mon, "irq statistic code not compiled.\n"); diff --git a/hw/intc/lm32_pic.c b/hw/intc/lm32_pic.c index 72fc9ef..641ee47 100644 --- a/hw/intc/lm32_pic.c +++ b/hw/intc/lm32_pic.c @@ -43,7 +43,7 @@ struct LM32PicState { typedef struct LM32PicState LM32PicState; static LM32PicState *pic; -void lm32_do_pic_info(Monitor *mon, const QDict *qdict) +void lm32_hmp_info_pic(Monitor *mon, const QDict *qdict) { if (pic == NULL) { return; @@ -53,7 +53,7 @@ void lm32_do_pic_info(Monitor *mon, const QDict *qdict) pic->im, pic->ip, pic->irq_state); } -void lm32_irq_info(Monitor *mon, const QDict *qdict) +void lm32_hmp_info_irq(Monitor *mon, const QDict *qdict) { int i; uint32_t count; diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c index a7d9aa6..0dc440d 100644 --- a/hw/isa/i82378.c +++ b/hw/isa/i82378.c @@ -75,7 +75,8 @@ static int i82378_initfn(PCIDevice *pci) pci_config_set_interrupt_pin(pci_conf, 1); /* interrupt pin 0 */ - isabus = isa_bus_new(dev, pci_address_space_io(pci)); + isabus = isa_bus_new(dev, get_system_memory(), + pci_address_space_io(pci)); /* This device has: 2 82C59 (irq) diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c index cc85e53..825aa62 100644 --- a/hw/isa/isa-bus.c +++ b/hw/isa/isa-bus.c @@ -21,10 +21,8 @@ #include "hw/sysbus.h" #include "sysemu/sysemu.h" #include "hw/isa/isa.h" -#include "exec/address-spaces.h" static ISABus *isabus; -hwaddr isa_mem_base = 0; static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *isabus_get_fw_dev_path(DeviceState *dev); @@ -44,7 +42,8 @@ static const TypeInfo isa_bus_info = { .class_init = isa_bus_class_init, }; -ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io) +ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* address_space, + MemoryRegion *address_space_io) { if (isabus) { fprintf(stderr, "Can't create a second ISA bus\n"); @@ -56,6 +55,7 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io) } isabus = ISA_BUS(qbus_create(TYPE_ISA_BUS, dev, NULL)); + isabus->address_space = address_space; isabus->address_space_io = address_space_io; return isabus; } @@ -250,7 +250,11 @@ static char *isabus_get_fw_dev_path(DeviceState *dev) MemoryRegion *isa_address_space(ISADevice *dev) { - return get_system_memory(); + if (dev) { + return isa_bus_from_device(dev)->address_space; + } + + return isabus->address_space; } MemoryRegion *isa_address_space_io(ISADevice *dev) diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 530b074..231de74 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -575,7 +575,7 @@ static int ich9_lpc_init(PCIDevice *d) ICH9LPCState *lpc = ICH9_LPC_DEVICE(d); ISABus *isa_bus; - isa_bus = isa_bus_new(&d->qdev, get_system_io()); + isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), get_system_io()); pci_set_long(d->wmask + ICH9_LPC_PMBASE, ICH9_LPC_PMBASE_BASE_ADDRESS_MASK); diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 1aa17d7..a9916df 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -86,7 +86,8 @@ static int piix4_initfn(PCIDevice *dev) { PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev); - isa_bus_new(&d->dev.qdev, pci_address_space_io(dev)); + isa_bus_new(DEVICE(d), pci_address_space(dev), + pci_address_space_io(dev)); piix4_dev = &d->dev; qemu_register_reset(piix4_reset, d); return 0; diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 17510ce..b223526 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -429,7 +429,8 @@ static int vt82c686b_initfn(PCIDevice *d) uint8_t *wmask; int i; - isa_bus = isa_bus_new(&d->qdev, pci_address_space_io(d)); + isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), + pci_address_space_io(d)); pci_conf = d->config; pci_config_set_prog_interface(pci_conf, 0x0); diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 18cdc54..f27a087 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -22,6 +22,7 @@ #include "qemu/config-file.h" #include "qapi/visitor.h" #include "qemu/range.h" +#include "sysemu/numa.h" typedef struct pc_dimms_capacity { uint64_t size; diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 1f2fe5f..10fcca3 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -239,7 +239,11 @@ typedef struct GT64120State { uint32_t regs[GT_REGS]; PCI_MAPPING_ENTRY(PCI0IO); + PCI_MAPPING_ENTRY(PCI0M0); + PCI_MAPPING_ENTRY(PCI0M1); PCI_MAPPING_ENTRY(ISD); + MemoryRegion pci0_mem; + AddressSpace pci0_mem_as; } GT64120State; /* Adjust range to avoid touching space which isn't mappable via PCI */ @@ -290,25 +294,63 @@ static void gt64120_isd_mapping(GT64120State *s) static void gt64120_pci_mapping(GT64120State *s) { - /* Update IO mapping */ - if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD]) - { - /* Unmap old IO address */ - if (s->PCI0IO_length) - { - memory_region_del_subregion(get_system_memory(), &s->PCI0IO_mem); - object_unparent(OBJECT(&s->PCI0IO_mem)); - } - /* Map new IO address */ - s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21; - s->PCI0IO_length = ((s->regs[GT_PCI0IOHD] + 1) - (s->regs[GT_PCI0IOLD] & 0x7f)) << 21; - isa_mem_base = s->PCI0IO_start; - if (s->PCI0IO_length) { - memory_region_init_alias(&s->PCI0IO_mem, OBJECT(s), "isa_mmio", - get_system_io(), 0, s->PCI0IO_length); - memory_region_add_subregion(get_system_memory(), s->PCI0IO_start, - &s->PCI0IO_mem); - } + /* Update PCI0IO mapping */ + if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD]) { + /* Unmap old IO address */ + if (s->PCI0IO_length) { + memory_region_del_subregion(get_system_memory(), &s->PCI0IO_mem); + object_unparent(OBJECT(&s->PCI0IO_mem)); + } + /* Map new IO address */ + s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21; + s->PCI0IO_length = ((s->regs[GT_PCI0IOHD] + 1) - + (s->regs[GT_PCI0IOLD] & 0x7f)) << 21; + if (s->PCI0IO_length) { + memory_region_init_alias(&s->PCI0IO_mem, OBJECT(s), "pci0-io", + get_system_io(), 0, s->PCI0IO_length); + memory_region_add_subregion(get_system_memory(), s->PCI0IO_start, + &s->PCI0IO_mem); + } + } + + /* Update PCI0M0 mapping */ + if ((s->regs[GT_PCI0M0LD] & 0x7f) <= s->regs[GT_PCI0M0HD]) { + /* Unmap old MEM address */ + if (s->PCI0M0_length) { + memory_region_del_subregion(get_system_memory(), &s->PCI0M0_mem); + object_unparent(OBJECT(&s->PCI0M0_mem)); + } + /* Map new mem address */ + s->PCI0M0_start = s->regs[GT_PCI0M0LD] << 21; + s->PCI0M0_length = ((s->regs[GT_PCI0M0HD] + 1) - + (s->regs[GT_PCI0M0LD] & 0x7f)) << 21; + if (s->PCI0M0_length) { + memory_region_init_alias(&s->PCI0M0_mem, OBJECT(s), "pci0-mem0", + &s->pci0_mem, s->PCI0M0_start, + s->PCI0M0_length); + memory_region_add_subregion(get_system_memory(), s->PCI0M0_start, + &s->PCI0M0_mem); + } + } + + /* Update PCI0M1 mapping */ + if ((s->regs[GT_PCI0M1LD] & 0x7f) <= s->regs[GT_PCI0M1HD]) { + /* Unmap old MEM address */ + if (s->PCI0M1_length) { + memory_region_del_subregion(get_system_memory(), &s->PCI0M1_mem); + object_unparent(OBJECT(&s->PCI0M1_mem)); + } + /* Map new mem address */ + s->PCI0M1_start = s->regs[GT_PCI0M1LD] << 21; + s->PCI0M1_length = ((s->regs[GT_PCI0M1HD] + 1) - + (s->regs[GT_PCI0M1LD] & 0x7f)) << 21; + if (s->PCI0M1_length) { + memory_region_init_alias(&s->PCI0M1_mem, OBJECT(s), "pci0-mem1", + &s->pci0_mem, s->PCI0M1_start, + s->PCI0M1_length); + memory_region_add_subregion(get_system_memory(), s->PCI0M1_start, + &s->PCI0M1_mem); + } } } @@ -363,10 +405,12 @@ static void gt64120_writel (void *opaque, hwaddr addr, case GT_PCI0M0LD: s->regs[GT_PCI0M0LD] = val & 0x00007fff; s->regs[GT_PCI0M0REMAP] = val & 0x000007ff; + gt64120_pci_mapping(s); break; case GT_PCI0M1LD: s->regs[GT_PCI0M1LD] = val & 0x00007fff; s->regs[GT_PCI0M1REMAP] = val & 0x000007ff; + gt64120_pci_mapping(s); break; case GT_PCI1IOLD: s->regs[GT_PCI1IOLD] = val & 0x00007fff; @@ -380,12 +424,12 @@ static void gt64120_writel (void *opaque, hwaddr addr, s->regs[GT_PCI1M1LD] = val & 0x00007fff; s->regs[GT_PCI1M1REMAP] = val & 0x000007ff; break; + case GT_PCI0M0HD: + case GT_PCI0M1HD: case GT_PCI0IOHD: s->regs[saddr] = val & 0x0000007f; gt64120_pci_mapping(s); break; - case GT_PCI0M0HD: - case GT_PCI0M1HD: case GT_PCI1IOHD: case GT_PCI1M0HD: case GT_PCI1M1HD: @@ -1124,10 +1168,12 @@ PCIBus *gt64120_register(qemu_irq *pic) qdev_init_nofail(dev); d = GT64120_PCI_HOST_BRIDGE(dev); phb = PCI_HOST_BRIDGE(dev); + memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", UINT32_MAX); + address_space_init(&d->pci0_mem_as, &d->pci0_mem, "pci0-mem"); phb->bus = pci_register_bus(dev, "pci", gt64120_pci_set_irq, gt64120_pci_map_irq, pic, - get_system_memory(), + &d->pci0_mem, get_system_io(), PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS); memory_region_init_io(&d->ISD_mem, OBJECT(dev), &isd_mem_ops, d, "isd-mem", 0x1000); @@ -1142,11 +1188,6 @@ static int gt64120_init(SysBusDevice *dev) s = GT64120_PCI_HOST_BRIDGE(dev); - /* FIXME: This value is computed from registers during reset, but some - devices (e.g. VGA card) need to know it when they are registered. - This also mean that changing the register to change the mapping - does not fully work. */ - isa_mem_base = 0x10000000; qemu_register_reset(gt64120_reset, s); return 0; } diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 3f33093..ef5dd7d 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -60,13 +60,16 @@ static void main_cpu_reset(void *opaque) static uint64_t rtc_read(void *opaque, hwaddr addr, unsigned size) { - return cpu_inw(0x71); + uint8_t val; + address_space_read(&address_space_memory, 0x90000071, &val, 1); + return val; } static void rtc_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { - cpu_outw(0x71, val & 0xff); + uint8_t buf = val & 0xff; + address_space_write(&address_space_memory, 0x90000071, &buf, 1); } static const MemoryRegionOps rtc_ops = { @@ -120,12 +123,11 @@ static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr, (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size); } -static void mips_jazz_init(MemoryRegion *address_space, - MemoryRegion *address_space_io, - ram_addr_t ram_size, - const char *cpu_model, +static void mips_jazz_init(MachineState *machine, enum jazz_model_e jazz_model) { + MemoryRegion *address_space = get_system_memory(); + const char *cpu_model = machine->cpu_model; char *filename; int bios_size, n; MIPSCPU *cpu; @@ -134,7 +136,8 @@ static void mips_jazz_init(MemoryRegion *address_space, qemu_irq *rc4030, *i8259; rc4030_dma *dmas; void* rc4030_opaque; - MemoryRegion *isa = g_new(MemoryRegion, 1); + MemoryRegion *isa_mem = g_new(MemoryRegion, 1); + MemoryRegion *isa_io = g_new(MemoryRegion, 1); MemoryRegion *rtc = g_new(MemoryRegion, 1); MemoryRegion *i8042 = g_new(MemoryRegion, 1); MemoryRegion *dma_dummy = g_new(MemoryRegion, 1); @@ -179,7 +182,8 @@ static void mips_jazz_init(MemoryRegion *address_space, cc->do_unassigned_access = mips_jazz_do_unassigned_access; /* allocate RAM */ - memory_region_init_ram(ram, NULL, "mips_jazz.ram", ram_size, &error_abort); + memory_region_init_ram(ram, NULL, "mips_jazz.ram", machine->ram_size, + &error_abort); vmstate_register_ram_global(ram); memory_region_add_subregion(address_space, 0, ram); @@ -218,8 +222,14 @@ static void mips_jazz_init(MemoryRegion *address_space, memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 0x1000); memory_region_add_subregion(address_space, 0x8000d000, dma_dummy); + /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */ + memory_region_init(isa_io, NULL, "isa-io", 0x00010000); + memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000); + memory_region_add_subregion(address_space, 0x90000000, isa_io); + memory_region_add_subregion(address_space, 0x91000000, isa_mem); + isa_bus = isa_bus_new(NULL, isa_mem, isa_io); + /* ISA devices */ - isa_bus = isa_bus_new(NULL, address_space_io); i8259 = i8259_init(isa_bus, env->irq[4]); isa_bus_irqs(isa_bus, i8259); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); @@ -227,12 +237,6 @@ static void mips_jazz_init(MemoryRegion *address_space, pit = pit_init(isa_bus, 0x40, 0, NULL); pcspk_init(isa_bus, pit); - /* ISA IO space at 0x90000000 */ - memory_region_init_alias(isa, NULL, "isa_mmio", - get_system_io(), 0, 0x01000000); - memory_region_add_subregion(address_space, 0x90000000, isa); - isa_mem_base = 0x11000000; - /* Video card */ switch (jazz_model) { case JAZZ_MAGNUM: @@ -333,19 +337,13 @@ static void mips_jazz_init(MemoryRegion *address_space, static void mips_magnum_init(MachineState *machine) { - ram_addr_t ram_size = machine->ram_size; - const char *cpu_model = machine->cpu_model; - mips_jazz_init(get_system_memory(), get_system_io(), - ram_size, cpu_model, JAZZ_MAGNUM); + mips_jazz_init(machine, JAZZ_MAGNUM); } static void mips_pica61_init(MachineState *machine) { - ram_addr_t ram_size = machine->ram_size; - const char *cpu_model = machine->cpu_model; - mips_jazz_init(get_system_memory(), get_system_io(), - ram_size, cpu_model, JAZZ_PICA61); + mips_jazz_init(machine, JAZZ_PICA61); } static QEMUMachine mips_magnum_machine = { diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c index 1698f2d..52564be 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/mips_r4k.c @@ -165,7 +165,8 @@ void mips_r4k_init(MachineState *machine) MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios; MemoryRegion *iomem = g_new(MemoryRegion, 1); - MemoryRegion *isa = g_new(MemoryRegion, 1); + MemoryRegion *isa_io = g_new(MemoryRegion, 1); + MemoryRegion *isa_mem = g_new(MemoryRegion, 1); int bios_size; MIPSCPU *cpu; CPUMIPSState *env; @@ -267,20 +268,20 @@ void mips_r4k_init(MachineState *machine) cpu_mips_irq_init_cpu(env); cpu_mips_clock_init(env); + /* ISA bus: IO space at 0x14000000, mem space at 0x10000000 */ + memory_region_init_alias(isa_io, NULL, "isa-io", + get_system_io(), 0, 0x00010000); + memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000); + memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io); + memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem); + isa_bus = isa_bus_new(NULL, isa_mem, get_system_io()); + /* The PIC is attached to the MIPS CPU INT0 pin */ - isa_bus = isa_bus_new(NULL, get_system_io()); i8259 = i8259_init(isa_bus, env->irq[2]); isa_bus_irqs(isa_bus, i8259); rtc_init(isa_bus, 2000, NULL); - /* Register 64 KB of ISA IO space at 0x14000000 */ - memory_region_init_alias(isa, NULL, "isa_mmio", - get_system_io(), 0, 0x00010000); - memory_region_add_subregion(get_system_memory(), 0x14000000, isa); - - isa_mem_base = 0x10000000; - pit = pit_init(isa_bus, 0x40, 0, NULL); serial_hds_isa_init(isa_bus, MAX_SERIAL_PORTS); diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index 252ea5e..36f73e1 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -97,6 +97,11 @@ static void pci_bridge_dev_exitfn(PCIDevice *dev) pci_bridge_exitfn(dev); } +static void pci_bridge_dev_instance_finalize(Object *obj) +{ + shpc_free(PCI_DEVICE(obj)); +} + static void pci_bridge_dev_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { @@ -154,10 +159,11 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data) } static const TypeInfo pci_bridge_dev_info = { - .name = TYPE_PCI_BRIDGE_DEV, - .parent = TYPE_PCI_BRIDGE, - .instance_size = sizeof(PCIBridgeDev), - .class_init = pci_bridge_dev_class_init, + .name = TYPE_PCI_BRIDGE_DEV, + .parent = TYPE_PCI_BRIDGE, + .instance_size = sizeof(PCIBridgeDev), + .class_init = pci_bridge_dev_class_init, + .instance_finalize = pci_bridge_dev_instance_finalize, .interfaces = (InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c index f573875..832b6c7 100644 --- a/hw/pci-host/apb.c +++ b/hw/pci-host/apb.c @@ -205,6 +205,7 @@ static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) return &is->iommu_as; } +/* Called from RCU critical section */ static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr, bool is_write) { diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 1530038..8ea718e 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -635,7 +635,8 @@ static int piix3_initfn(PCIDevice *dev) { PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev); - isa_bus_new(DEVICE(d), pci_address_space_io(dev)); + isa_bus_new(DEVICE(d), get_system_memory(), + pci_address_space_io(dev)); memory_region_init_io(&d->rcr_mem, OBJECT(dev), &rcr_ops, d, "piix3-reset-control", 1); diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c index 0c09c72..beea6d2 100644 --- a/hw/pci/pci-hotplug-old.c +++ b/hw/pci/pci-hotplug-old.c @@ -132,8 +132,7 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter, dinfo->unit, false, -1, NULL, &local_err); if (!scsidev) { - error_report("%s", error_get_pretty(local_err)); - error_free(local_err); + error_report_err(local_err); return -1; } dinfo->unit = scsidev->id; @@ -267,7 +266,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, return dev; } -void pci_device_hot_add(Monitor *mon, const QDict *qdict) +void hmp_pci_add(Monitor *mon, const QDict *qdict) { PCIDevice *dev = NULL; const char *pci_addr = qdict_get_str(qdict, "pci_addr"); @@ -337,7 +336,7 @@ static int pci_device_hot_remove(Monitor *mon, const char *pci_addr) return 0; } -void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict) +void hmp_pci_del(Monitor *mon, const QDict *qdict) { pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr")); } diff --git a/hw/pci/pci-stub.c b/hw/pci/pci-stub.c index 1dda89b..5e564c3 100644 --- a/hw/pci/pci-stub.c +++ b/hw/pci/pci-stub.c @@ -34,7 +34,7 @@ static void pci_error_message(Monitor *mon) monitor_printf(mon, "PCI devices not supported\n"); } -int do_pcie_aer_inject_error(Monitor *mon, +int hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict, QObject **ret_data) { pci_error_message(mon); diff --git a/hw/pci/pci.c b/hw/pci/pci.c index d508930..31b222d 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2038,8 +2038,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, ret = pci_add_capability2(pdev, cap_id, offset, size, &local_err); if (local_err) { assert(ret < 0); - error_report("%s", error_get_pretty(local_err)); - error_free(local_err); + error_report_err(local_err); } else { /* success implies a positive offset in config space */ assert(ret > 0); diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index 1f4be16..5a25c32 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -962,7 +962,7 @@ static int pcie_aer_parse_error_string(const char *error_name, return -EINVAL; } -int do_pcie_aer_inject_error(Monitor *mon, +int hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *id = qdict_get_str(qdict, "id"); diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c index dfb4a2b..d8afba8 100644 --- a/hw/pci/pcie_host.c +++ b/hw/pci/pcie_host.c @@ -88,6 +88,8 @@ static void pcie_host_init(Object *obj) PCIExpressHost *e = PCIE_HOST_BRIDGE(obj); e->base_addr = PCIE_BASE_ADDR_UNMAPPED; + memory_region_init_io(&e->mmio, OBJECT(e), &pcie_mmcfg_ops, e, "pcie-mmcfg-mmio", + PCIE_MMCFG_SIZE_MAX); } void pcie_host_mmcfg_unmap(PCIExpressHost *e) @@ -104,8 +106,7 @@ void pcie_host_mmcfg_init(PCIExpressHost *e, uint32_t size) assert(size >= PCIE_MMCFG_SIZE_MIN); assert(size <= PCIE_MMCFG_SIZE_MAX); e->size = size; - memory_region_init_io(&e->mmio, OBJECT(e), &pcie_mmcfg_ops, e, - "pcie-mmcfg", e->size); + memory_region_set_size(&e->mmio, e->size); } void pcie_host_mmcfg_map(PCIExpressHost *e, hwaddr addr, @@ -121,10 +122,12 @@ void pcie_host_mmcfg_update(PCIExpressHost *e, hwaddr addr, uint32_t size) { + memory_region_transaction_begin(); pcie_host_mmcfg_unmap(e); if (enable) { pcie_host_mmcfg_map(e, addr, size); } + memory_region_transaction_commit(); } static const TypeInfo pcie_host_type_info = { diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c index 27c496e..5fd7f4b 100644 --- a/hw/pci/shpc.c +++ b/hw/pci/shpc.c @@ -663,13 +663,22 @@ void shpc_cleanup(PCIDevice *d, MemoryRegion *bar) SHPCDevice *shpc = d->shpc; d->cap_present &= ~QEMU_PCI_CAP_SHPC; memory_region_del_subregion(bar, &shpc->mmio); - object_unparent(OBJECT(&shpc->mmio)); /* TODO: cleanup config space changes? */ +} + +void shpc_free(PCIDevice *d) +{ + SHPCDevice *shpc = d->shpc; + if (!shpc) { + return; + } + object_unparent(OBJECT(&shpc->mmio)); g_free(shpc->config); g_free(shpc->cmask); g_free(shpc->wmask); g_free(shpc->w1cmask); g_free(shpc); + d->shpc = NULL; } void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index c377012..624b4ab 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -420,11 +420,14 @@ static void ppc_core99_init(MachineState *machine) if (machine->usb) { pci_create_simple(pci_bus, -1, "pci-ohci"); + /* U3 needs to use USB for input because Linux doesn't support via-cuda on PPC64 */ if (machine_arch == ARCH_MAC99_U3) { - usbdevice_create("keyboard"); - usbdevice_create("mouse"); + USBBus *usb_bus = usb_bus_find(-1); + + usb_create_simple(usb_bus, "usb-kbd"); + usb_create_simple(usb_bus, "usb-mouse"); } } diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 812d030..23cde20 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -25,6 +25,7 @@ * */ #include "sysemu/sysemu.h" +#include "sysemu/numa.h" #include "hw/hw.h" #include "hw/fw-path-provider.h" #include "elf.h" @@ -1533,9 +1534,12 @@ static void ppc_spapr_init(MachineState *machine) if (machine->usb) { pci_create_simple(phb->bus, -1, "pci-ohci"); + if (spapr->has_graphics) { - usbdevice_create("keyboard"); - usbdevice_create("mouse"); + USBBus *usb_bus = usb_bus_find(-1); + + usb_create_simple(usb_bus, "usb-kbd"); + usb_create_simple(usb_bus, "usb-mouse"); } } diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index da47474..ba003da 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -59,6 +59,7 @@ static sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn) return NULL; } +/* Called from RCU critical section */ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr, bool is_write) { diff --git a/hw/s390x/css.c b/hw/s390x/css.c index d0c5dde..9a13b00 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -584,7 +584,7 @@ static void copy_schib_from_guest(SCHIB *dest, const SCHIB *src) } } -int css_do_msch(SubchDev *sch, SCHIB *orig_schib) +int css_do_msch(SubchDev *sch, const SCHIB *orig_schib) { SCSW *s = &sch->curr_status.scsw; PMCW *p = &sch->curr_status.pmcw; @@ -801,7 +801,8 @@ out: return ret; } -static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw) +static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw, + int *irb_len) { int i; uint16_t stctl = src->scsw.ctrl & SCSW_CTRL_MASK_STCTL; @@ -815,6 +816,8 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw) for (i = 0; i < ARRAY_SIZE(dest->ecw); i++) { dest->ecw[i] = cpu_to_be32(src->ecw[i]); } + *irb_len = sizeof(*dest) - sizeof(dest->emw); + /* extended measurements enabled? */ if ((src->scsw.flags & SCSW_FLAGS_MASK_ESWF) || !(pmcw->flags & PMCW_FLAGS_MASK_TF) || @@ -832,26 +835,21 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src, PMCW *pmcw) dest->emw[i] = cpu_to_be32(src->emw[i]); } } + *irb_len = sizeof(*dest); } -int css_do_tsch(SubchDev *sch, IRB *target_irb) +int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len) { SCSW *s = &sch->curr_status.scsw; PMCW *p = &sch->curr_status.pmcw; uint16_t stctl; - uint16_t fctl; - uint16_t actl; IRB irb; - int ret; if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) { - ret = 3; - goto out; + return 3; } stctl = s->ctrl & SCSW_CTRL_MASK_STCTL; - fctl = s->ctrl & SCSW_CTRL_MASK_FCTL; - actl = s->ctrl & SCSW_CTRL_MASK_ACTL; /* Prepare the irb for the guest. */ memset(&irb, 0, sizeof(IRB)); @@ -876,7 +874,22 @@ int css_do_tsch(SubchDev *sch, IRB *target_irb) } } /* Store the irb to the guest. */ - copy_irb_to_guest(target_irb, &irb, p); + copy_irb_to_guest(target_irb, &irb, p, irb_len); + + return ((stctl & SCSW_STCTL_STATUS_PEND) == 0); +} + +void css_do_tsch_update_subch(SubchDev *sch) +{ + SCSW *s = &sch->curr_status.scsw; + PMCW *p = &sch->curr_status.pmcw; + uint16_t stctl; + uint16_t fctl; + uint16_t actl; + + stctl = s->ctrl & SCSW_CTRL_MASK_STCTL; + fctl = s->ctrl & SCSW_CTRL_MASK_FCTL; + actl = s->ctrl & SCSW_CTRL_MASK_ACTL; /* Clear conditions on subchannel, if applicable. */ if (stctl & SCSW_STCTL_STATUS_PEND) { @@ -913,11 +926,6 @@ int css_do_tsch(SubchDev *sch, IRB *target_irb) memset(sch->sense_data, 0 , sizeof(sch->sense_data)); } } - - ret = ((stctl & SCSW_STCTL_STATUS_PEND) == 0); - -out: - return ret; } static void copy_crw_to_guest(CRW *dest, const CRW *src) @@ -947,6 +955,26 @@ int css_do_stcrw(CRW *crw) return ret; } +static void copy_crw_from_guest(CRW *dest, const CRW *src) +{ + dest->flags = be16_to_cpu(src->flags); + dest->rsid = be16_to_cpu(src->rsid); +} + +void css_undo_stcrw(CRW *crw) +{ + CrwContainer *crw_cont; + + crw_cont = g_try_malloc0(sizeof(CrwContainer)); + if (!crw_cont) { + channel_subsys->crws_lost = true; + return; + } + copy_crw_from_guest(&crw_cont->crw, crw); + + QTAILQ_INSERT_HEAD(&channel_subsys->pending_crws, crw_cont, sibling); +} + int css_do_tpi(IOIntCode *int_code, int lowcore) { /* No pending interrupts for !KVM. */ diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 4ba8409..b57adbd 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -18,6 +18,7 @@ #include "hw/sysbus.h" #include "hw/s390x/virtio-ccw.h" #include "hw/s390x/css.h" +#include "ipl.h" #define KERN_IMAGE_START 0x010000UL #define KERN_PARM_AREA 0x010480UL @@ -50,14 +51,49 @@ typedef struct S390IPLState { /*< private >*/ SysBusDevice parent_obj; uint64_t start_addr; + uint64_t bios_start_addr; + bool enforce_bios; + IplParameterBlock iplb; + bool iplb_valid; + bool reipl_requested; /*< public >*/ char *kernel; char *initrd; char *cmdline; char *firmware; + uint8_t cssid; + uint8_t ssid; + uint16_t devno; } S390IPLState; +static const VMStateDescription vmstate_iplb = { + .name = "ipl/iplb", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT8_ARRAY(reserved1, IplParameterBlock, 110), + VMSTATE_UINT16(devno, IplParameterBlock), + VMSTATE_UINT8_ARRAY(reserved2, IplParameterBlock, 88), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_ipl = { + .name = "ipl", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT64(start_addr, S390IPLState), + VMSTATE_UINT64(bios_start_addr, S390IPLState), + VMSTATE_STRUCT(iplb, S390IPLState, 0, vmstate_iplb, IplParameterBlock), + VMSTATE_BOOL(iplb_valid, S390IPLState), + VMSTATE_UINT8(cssid, S390IPLState), + VMSTATE_UINT8(ssid, S390IPLState), + VMSTATE_UINT16(devno, S390IPLState), + VMSTATE_END_OF_LIST() + } +}; static int s390_ipl_init(SysBusDevice *dev) { @@ -65,11 +101,14 @@ static int s390_ipl_init(SysBusDevice *dev) uint64_t pentry = KERN_IMAGE_START; int kernel_size; - if (!ipl->kernel) { - int bios_size; - char *bios_filename; + int bios_size; + char *bios_filename; - /* Load zipl bootloader */ + /* + * Always load the bios if it was enforced, + * even if an external kernel has been defined. + */ + if (!ipl->kernel || ipl->enforce_bios) { if (bios_name == NULL) { bios_name = ipl->firmware; } @@ -79,12 +118,12 @@ static int s390_ipl_init(SysBusDevice *dev) hw_error("could not find stage1 bootloader\n"); } - bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL, - NULL, 1, ELF_MACHINE, 0); + bios_size = load_elf(bios_filename, NULL, NULL, &ipl->bios_start_addr, + NULL, NULL, 1, ELF_MACHINE, 0); if (bios_size < 0) { bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096); - ipl->start_addr = ZIPL_IMAGE_START; + ipl->bios_start_addr = ZIPL_IMAGE_START; if (bios_size > 4096) { hw_error("stage1 bootloader is > 4k\n"); } @@ -94,52 +133,59 @@ static int s390_ipl_init(SysBusDevice *dev) if (bios_size == -1) { hw_error("could not load bootloader '%s'\n", bios_name); } - return 0; - } - kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, - NULL, 1, ELF_MACHINE, 0); - if (kernel_size < 0) { - kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); - } - if (kernel_size < 0) { - fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel); - return -1; + /* default boot target is the bios */ + ipl->start_addr = ipl->bios_start_addr; } - /* - * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the - * kernel parameters here as well. Note: For old kernels (up to 3.2) - * we can not rely on the ELF entry point - it was 0x800 (the SALIPL - * loader) and it won't work. For this case we force it to 0x10000, too. - */ - if (pentry == KERN_IMAGE_START || pentry == 0x800) { - ipl->start_addr = KERN_IMAGE_START; - /* Overwrite parameters in the kernel image, which are "rom" */ - strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); - } else { - ipl->start_addr = pentry; - } - - if (ipl->initrd) { - ram_addr_t initrd_offset; - int initrd_size; - initrd_offset = INITRD_START; - while (kernel_size + 0x100000 > initrd_offset) { - initrd_offset += 0x100000; + if (ipl->kernel) { + kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, + NULL, 1, ELF_MACHINE, 0); + if (kernel_size < 0) { + kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); + } + if (kernel_size < 0) { + fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel); + return -1; } - initrd_size = load_image_targphys(ipl->initrd, initrd_offset, - ram_size - initrd_offset); - if (initrd_size == -1) { - fprintf(stderr, "qemu: could not load initrd '%s'\n", ipl->initrd); - exit(1); + /* + * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the + * kernel parameters here as well. Note: For old kernels (up to 3.2) + * we can not rely on the ELF entry point - it was 0x800 (the SALIPL + * loader) and it won't work. For this case we force it to 0x10000, too. + */ + if (pentry == KERN_IMAGE_START || pentry == 0x800) { + ipl->start_addr = KERN_IMAGE_START; + /* Overwrite parameters in the kernel image, which are "rom" */ + strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); + } else { + ipl->start_addr = pentry; } - /* we have to overwrite values in the kernel image, which are "rom" */ - stq_p(rom_ptr(INITRD_PARM_START), initrd_offset); - stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size); - } + if (ipl->initrd) { + ram_addr_t initrd_offset; + int initrd_size; + + initrd_offset = INITRD_START; + while (kernel_size + 0x100000 > initrd_offset) { + initrd_offset += 0x100000; + } + initrd_size = load_image_targphys(ipl->initrd, initrd_offset, + ram_size - initrd_offset); + if (initrd_size == -1) { + fprintf(stderr, "qemu: could not load initrd '%s'\n", + ipl->initrd); + exit(1); + } + /* + * we have to overwrite values in the kernel image, + * which are "rom" + */ + stq_p(rom_ptr(INITRD_PARM_START), initrd_offset); + stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size); + } + } return 0; } @@ -148,9 +194,82 @@ static Property s390_ipl_properties[] = { DEFINE_PROP_STRING("initrd", S390IPLState, initrd), DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline), DEFINE_PROP_STRING("firmware", S390IPLState, firmware), + DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false), DEFINE_PROP_END_OF_LIST(), }; +/* + * In addition to updating the iplstate, this function returns: + * - 0 if system was ipled with external kernel + * - -1 if no valid boot device was found + * - ccw id of the boot device otherwise + */ +static uint64_t s390_update_iplstate(CPUS390XState *env, S390IPLState *ipl) +{ + DeviceState *dev_st; + + if (ipl->iplb_valid) { + ipl->cssid = 0; + ipl->ssid = 0; + ipl->devno = ipl->iplb.devno; + goto out; + } + + if (ipl->kernel) { + return 0; + } + + dev_st = get_boot_device(0); + if (dev_st) { + VirtioCcwDevice *ccw_dev = (VirtioCcwDevice *) object_dynamic_cast( + OBJECT(qdev_get_parent_bus(dev_st)->parent), + TYPE_VIRTIO_CCW_DEVICE); + if (ccw_dev) { + ipl->cssid = ccw_dev->sch->cssid; + ipl->ssid = ccw_dev->sch->ssid; + ipl->devno = ccw_dev->sch->devno; + goto out; + } + } + + return -1; +out: + return ipl->cssid << 24 | ipl->ssid << 16 | ipl->devno; +} + +int s390_ipl_update_diag308(IplParameterBlock *iplb) +{ + S390IPLState *ipl; + + ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL)); + if (ipl) { + ipl->iplb = *iplb; + ipl->iplb_valid = true; + return 0; + } + return -1; +} + +IplParameterBlock *s390_ipl_get_iplb(void) +{ + S390IPLState *ipl; + + ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL)); + if (!ipl || !ipl->iplb_valid) { + return NULL; + } + return &ipl->iplb; +} + +void s390_reipl_request(void) +{ + S390IPLState *ipl; + + ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL)); + ipl->reipl_requested = true; + qemu_system_reset_request(); +} + static void s390_ipl_reset(DeviceState *dev) { S390IPLState *ipl = S390_IPL(dev); @@ -160,21 +279,14 @@ static void s390_ipl_reset(DeviceState *dev) env->psw.addr = ipl->start_addr; env->psw.mask = IPL_PSW_MASK; - if (!ipl->kernel) { - /* Tell firmware, if there is a preferred boot device */ - env->regs[7] = -1; - DeviceState *dev_st = get_boot_device(0); - if (dev_st) { - VirtioCcwDevice *ccw_dev = (VirtioCcwDevice *) object_dynamic_cast( - OBJECT(qdev_get_parent_bus(dev_st)->parent), - TYPE_VIRTIO_CCW_DEVICE); + if (!ipl->reipl_requested) { + ipl->iplb_valid = false; + } + ipl->reipl_requested = false; - if (ccw_dev) { - env->regs[7] = ccw_dev->sch->cssid << 24 | - ccw_dev->sch->ssid << 16 | - ccw_dev->sch->devno; - } - } + if (!ipl->kernel || ipl->iplb_valid) { + env->psw.addr = ipl->bios_start_addr; + env->regs[7] = s390_update_iplstate(env, ipl); } s390_cpu_set_state(CPU_STATE_OPERATING, cpu); @@ -188,6 +300,7 @@ static void s390_ipl_class_init(ObjectClass *klass, void *data) k->init = s390_ipl_init; dc->props = s390_ipl_properties; dc->reset = s390_ipl_reset; + dc->vmsd = &vmstate_ipl; } static const TypeInfo s390_ipl_info = { diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h new file mode 100644 index 0000000..70497bc --- /dev/null +++ b/hw/s390x/ipl.h @@ -0,0 +1,25 @@ +/* + * s390 IPL device + * + * Copyright 2015 IBM Corp. + * Author(s): Zhang Fan <bjfanzh@cn.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#ifndef HW_S390_IPL_H +#define HW_S390_IPL_H + +typedef struct IplParameterBlock { + uint8_t reserved1[110]; + uint16_t devno; + uint8_t reserved2[88]; +} IplParameterBlock; + +int s390_ipl_update_diag308(IplParameterBlock *iplb); +IplParameterBlock *s390_ipl_get_iplb(void); +void s390_reipl_request(void); + +#endif diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 9e5bc5b..08d8aa6 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -155,7 +155,9 @@ int clp_service_call(S390CPU *cpu, uint8_t r2) return 0; } - cpu_physical_memory_read(env->regs[r2], buffer, sizeof(*reqh)); + if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer, sizeof(*reqh))) { + return 0; + } reqh = (ClpReqHdr *)buffer; req_len = lduw_p(&reqh->len); if (req_len < 16 || req_len > 8184 || (req_len % 8 != 0)) { @@ -163,7 +165,10 @@ int clp_service_call(S390CPU *cpu, uint8_t r2) return 0; } - cpu_physical_memory_read(env->regs[r2], buffer, req_len + sizeof(*resh)); + if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer, + req_len + sizeof(*resh))) { + return 0; + } resh = (ClpRspHdr *)(buffer + req_len); res_len = lduw_p(&resh->len); if (res_len < 8 || res_len > 8176 || (res_len % 8 != 0)) { @@ -175,7 +180,10 @@ int clp_service_call(S390CPU *cpu, uint8_t r2) return 0; } - cpu_physical_memory_read(env->regs[r2], buffer, req_len + res_len); + if (s390_cpu_virt_mem_read(cpu, env->regs[r2], buffer, + req_len + res_len)) { + return 0; + } if (req_len != 32) { stw_p(&resh->rsp, CLP_RC_LEN); @@ -269,7 +277,10 @@ int clp_service_call(S390CPU *cpu, uint8_t r2) } out: - cpu_physical_memory_write(env->regs[r2], buffer, req_len + res_len); + if (s390_cpu_virt_mem_write(cpu, env->regs[r2], buffer, + req_len + res_len)) { + return 0; + } setcc(cpu, cc); return 0; } @@ -539,10 +550,10 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr) S390PCIBusDevice *pbdev; MemoryRegion *mr; int i; - uint64_t val; uint32_t fh; uint8_t pcias; uint8_t len; + uint8_t buffer[128]; if (env->psw.mask & PSW_MASK_PSTATE) { program_interrupt(env, PGM_PRIVILEGED, 6); @@ -590,9 +601,12 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr) return 0; } + if (s390_cpu_virt_mem_read(cpu, gaddr, buffer, len)) { + return 0; + } + for (i = 0; i < len / 8; i++) { - val = ldq_phys(&address_space_memory, gaddr + i * 8); - io_mem_write(mr, env->regs[r3] + i * 8, val, 8); + io_mem_write(mr, env->regs[r3] + i * 8, ldq_p(buffer + i * 8), 8); } setcc(cpu, ZPCI_PCI_LS_OK); @@ -709,7 +723,9 @@ int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba) return 0; } - cpu_physical_memory_read(fiba, (uint8_t *)&fib, sizeof(fib)); + if (s390_cpu_virt_mem_read(cpu, fiba, (uint8_t *)&fib, sizeof(fib))) { + return 0; + } switch (oc) { case ZPCI_MOD_FC_REG_INT: @@ -809,7 +825,10 @@ int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba) fib.fc |= 0x10; } - cpu_physical_memory_write(fiba, (uint8_t *)&fib, sizeof(fib)); + if (s390_cpu_virt_mem_write(cpu, fiba, (uint8_t *)&fib, sizeof(fib))) { + return 0; + } + setcc(cpu, cc); return 0; } diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 71bafe0..8f0ae59 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -126,7 +126,7 @@ static void ccw_init(MachineState *machine) css_bus = virtual_css_bus_init(); s390_sclp_init(); s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline, - machine->initrd_filename, "s390-ccw.img"); + machine->initrd_filename, "s390-ccw.img", true); s390_flic_init(); dev = qdev_create(NULL, TYPE_S390_PCI_HOST_BRIDGE); diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c index c215cd8..412e49b 100644 --- a/hw/s390x/s390-virtio.c +++ b/hw/s390x/s390-virtio.c @@ -128,7 +128,8 @@ static void s390_virtio_register_hcalls(void) void s390_init_ipl_dev(const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, - const char *firmware) + const char *firmware, + bool enforce_bios) { DeviceState *dev; @@ -141,6 +142,9 @@ void s390_init_ipl_dev(const char *kernel_filename, } qdev_prop_set_string(dev, "cmdline", kernel_cmdline); qdev_prop_set_string(dev, "firmware", firmware); + qdev_prop_set_bit(dev, "enforce_bios", enforce_bios); + object_property_add_child(qdev_get_machine(), "s390-ipl", + OBJECT(dev), NULL); qdev_init_nofail(dev); } @@ -221,7 +225,7 @@ static void s390_init(MachineState *machine) s390_bus = s390_virtio_bus_init(&my_ram_size); s390_sclp_init(); s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline, - machine->initrd_filename, ZIPL_FILENAME); + machine->initrd_filename, ZIPL_FILENAME, false); s390_flic_init(); /* register hypercalls */ diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h index 33847ae..75b67ed 100644 --- a/hw/s390x/s390-virtio.h +++ b/hw/s390x/s390-virtio.h @@ -26,7 +26,8 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys); void s390_init_ipl_dev(const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, - const char *firmware); + const char *firmware, + bool enforce_bios); void s390_create_virtio_net(BusState *bus, const char *name); void s390_nmi(NMIState *n, int cpu_index, Error **errp); #endif diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index dcb2bc5..618b0af 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -24,6 +24,7 @@ #include "hw/virtio/virtio-scsi.h" #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-access.h" +#include "hw/fw-path-provider.h" /* Features supported by host kernel. */ static const int kernel_feature_bits[] = { @@ -214,9 +215,11 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) } if (vs->conf.vhostfd) { - vhostfd = monitor_handle_fd_param(cur_mon, vs->conf.vhostfd); + vhostfd = monitor_fd_param(cur_mon, vs->conf.vhostfd, &err); if (vhostfd == -1) { - error_setg(errp, "vhost-scsi: unable to parse vhostfd"); + error_setg(errp, "vhost-scsi: unable to parse vhostfd: %s", + error_get_pretty(err)); + error_free(err); return; } } else { @@ -250,6 +253,12 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) return; } + /* At present, channel and lun both are 0 for bootable vhost-scsi disk */ + s->channel = 0; + s->lun = 0; + /* Note: we can also get the minimum tpgt from kernel */ + s->target = vs->conf.boot_tpgt; + error_setg(&s->migration_blocker, "vhost-scsi does not support migration"); migrate_add_blocker(s->migration_blocker); @@ -271,6 +280,19 @@ static void vhost_scsi_unrealize(DeviceState *dev, Error **errp) virtio_scsi_common_unrealize(dev, errp); } +/* + * Implementation of an interface to adjust firmware path + * for the bootindex property handling. + */ +static char *vhost_scsi_get_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + VHostSCSI *s = VHOST_SCSI(dev); + /* format: channel@channel/vhost-scsi@target,lun */ + return g_strdup_printf("channel@%x/%s@%x,%x", s->channel, + qdev_fw_name(dev), s->target, s->lun); +} + static Property vhost_scsi_properties[] = { DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSI, parent_obj.conf), DEFINE_PROP_END_OF_LIST(), @@ -280,6 +302,7 @@ static void vhost_scsi_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(klass); dc->props = vhost_scsi_properties; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); @@ -288,6 +311,15 @@ static void vhost_scsi_class_init(ObjectClass *klass, void *data) vdc->get_features = vhost_scsi_get_features; vdc->set_config = vhost_scsi_set_config; vdc->set_status = vhost_scsi_set_status; + fwc->get_dev_path = vhost_scsi_get_fw_dev_path; +} + +static void vhost_scsi_instance_init(Object *obj) +{ + VHostSCSI *dev = VHOST_SCSI(obj); + + device_add_bootindex_property(obj, &dev->bootindex, "bootindex", NULL, + DEVICE(dev), NULL); } static const TypeInfo vhost_scsi_info = { @@ -295,6 +327,11 @@ static const TypeInfo vhost_scsi_info = { .parent = TYPE_VIRTIO_SCSI_COMMON, .instance_size = sizeof(VHostSCSI), .class_init = vhost_scsi_class_init, + .instance_init = vhost_scsi_instance_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, }; static void virtio_register_types(void) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 03a1e8c..418d73b 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -94,7 +94,7 @@ void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req) { VirtIODevice *vdev = VIRTIO_DEVICE(req->vring->parent); - vring_push(&req->vring->vring, &req->elem, + vring_push(vdev, &req->vring->vring, &req->elem, req->qsgl.size + req->resp_iov.size); if (vring_should_notify(vdev, &req->vring->vring)) { diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index 12f44d2..d1d0847 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -301,7 +301,7 @@ static void r2d_init(MachineState *machine) "rtl8139", i==0 ? "2" : NULL); /* USB keyboard */ - usbdevice_create("keyboard"); + usb_create_simple(usb_bus_find(-1), "usb-kbd"); /* Todo: register on board registers */ memset(&boot_params, 0, sizeof(boot_params)); diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index ecd9dc1..09afccf 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -176,13 +176,13 @@ static void nvram_init(M48t59State *nvram, uint8_t *macaddr, static DeviceState *slavio_intctl; -void sun4m_pic_info(Monitor *mon, const QDict *qdict) +void sun4m_hmp_info_pic(Monitor *mon, const QDict *qdict) { if (slavio_intctl) slavio_pic_info(mon, slavio_intctl); } -void sun4m_irq_info(Monitor *mon, const QDict *qdict) +void sun4m_hmp_info_irq(Monitor *mon, const QDict *qdict) { if (slavio_intctl) slavio_irq_info(mon, slavio_intctl); diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 17cf61f..b310588 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -596,7 +596,8 @@ pci_ebus_init1(PCIDevice *pci_dev) { EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev); - isa_bus_new(&pci_dev->qdev, pci_address_space_io(pci_dev)); + isa_bus_new(DEVICE(pci_dev), get_system_memory(), + pci_address_space_io(pci_dev)); pci_dev->config[0x04] = 0x06; // command = bus master, pci mem pci_dev->config[0x05] = 0x00; diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs index 3fe4dff..0ccd477 100644 --- a/hw/usb/Makefile.objs +++ b/hw/usb/Makefile.objs @@ -5,7 +5,8 @@ common-obj-y += libhw.o # usb host adapters common-obj-$(CONFIG_USB_UHCI) += hcd-uhci.o common-obj-$(CONFIG_USB_OHCI) += hcd-ohci.o -common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o hcd-ehci-pci.o hcd-ehci-sysbus.o +common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o hcd-ehci-pci.o +common-obj-$(CONFIG_USB_EHCI_SYSBUS) += hcd-ehci-sysbus.o common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o diff --git a/hw/usb/bus.c b/hw/usb/bus.c index 986b2d8..91fc3e2 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -315,23 +315,33 @@ USBDevice *usb_create(USBBus *bus, const char *name) return USB_DEVICE(dev); } -USBDevice *usb_create_simple(USBBus *bus, const char *name) +static USBDevice *usb_try_create_simple(USBBus *bus, const char *name, + Error **errp) { - USBDevice *dev = usb_create(bus, name); - int rc; + Error *err = NULL; + USBDevice *dev; + dev = USB_DEVICE(qdev_try_create(&bus->qbus, name)); if (!dev) { - error_report("Failed to create USB device '%s'", name); + error_setg(errp, "Failed to create USB device '%s'", name); return NULL; } - rc = qdev_init(&dev->qdev); - if (rc < 0) { - error_report("Failed to initialize USB device '%s'", name); + object_property_set_bool(OBJECT(dev), true, "realized", &err); + if (err) { + error_setg(errp, "Failed to initialize USB device '%s': %s", + name, error_get_pretty(err)); + error_free(err); + object_unparent(OBJECT(dev)); return NULL; } return dev; } +USBDevice *usb_create_simple(USBBus *bus, const char *name) +{ + return usb_try_create_simple(bus, name, &error_abort); +} + static void usb_fill_port(USBPort *port, void *opaque, int index, USBPortOps *ops, int speedmask) { @@ -416,17 +426,17 @@ void usb_claim_port(USBDevice *dev, Error **errp) } } if (port == NULL) { - error_setg(errp, "Error: usb port %s (bus %s) not found (in use?)", + error_setg(errp, "usb port %s (bus %s) not found (in use?)", dev->port_path, bus->qbus.name); return; } } else { if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) { /* Create a new hub and chain it on */ - usb_create_simple(bus, "usb-hub"); + usb_try_create_simple(bus, "usb-hub", NULL); } if (bus->nfree == 0) { - error_setg(errp, "Error: tried to attach usb device %s to a bus " + error_setg(errp, "tried to attach usb device %s to a bus " "with no free ports", dev->product_desc); return; } @@ -627,7 +637,7 @@ static char *usb_get_fw_dev_path(DeviceState *qdev) return fw_path; } -void usb_info(Monitor *mon, const QDict *qdict) +void hmp_info_usb(Monitor *mon, const QDict *qdict) { USBBus *bus; USBDevice *dev; @@ -655,10 +665,12 @@ USBDevice *usbdevice_create(const char *cmdline) { USBBus *bus = usb_bus_find(-1 /* any */); LegacyUSBFactory *f = NULL; + Error *err = NULL; GSList *i; char driver[32]; const char *params; int len; + USBDevice *dev; params = strchr(cmdline,':'); if (params) { @@ -693,14 +705,28 @@ USBDevice *usbdevice_create(const char *cmdline) return NULL; } - if (!f->usbdevice_init) { + if (f->usbdevice_init) { + dev = f->usbdevice_init(bus, params); + } else { if (*params) { error_report("usbdevice %s accepts no params", driver); return NULL; } - return usb_create_simple(bus, f->name); + dev = usb_create(bus, f->name); + } + if (!dev) { + error_report("Failed to create USB device '%s'", f->name); + return NULL; } - return f->usbdevice_init(bus, params); + object_property_set_bool(OBJECT(dev), true, "realized", &err); + if (err) { + error_report("Failed to initialize USB device '%s': %s", + f->name, error_get_pretty(err)); + error_free(err); + object_unparent(OBJECT(dev)); + return NULL; + } + return dev; } static void usb_device_class_init(ObjectClass *klass, void *data) diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c index 390d475..9bf6730 100644 --- a/hw/usb/dev-bluetooth.c +++ b/hw/usb/dev-bluetooth.c @@ -530,21 +530,12 @@ static USBDevice *usb_bt_init(USBBus *bus, const char *cmdline) } else { hci = bt_new_hci(qemu_find_bt_vlan(0)); } - if (!hci) return NULL; + dev = usb_create(bus, name); - if (!dev) { - error_report("Failed to create USB device '%s'", name); - return NULL; - } s = DO_UPCAST(struct USBBtState, dev, dev); s->hci = hci; - if (qdev_init(&dev->qdev) < 0) { - error_report("Failed to initialize USB device '%s'", name); - return NULL; - } - return dev; } diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c index 5b95d5c..b27b1f4 100644 --- a/hw/usb/dev-network.c +++ b/hw/usb/dev-network.c @@ -1399,17 +1399,12 @@ static USBDevice *usb_net_init(USBBus *bus, const char *cmdline) idx = net_client_init(opts, 0, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); - error_free(local_err); + error_report_err(local_err); return NULL; } dev = usb_create(bus, "usb-net"); - if (!dev) { - return NULL; - } qdev_set_nic_properties(&dev->qdev, &nd_table[idx]); - qdev_init_nofail(&dev->qdev); return dev; } diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index 1cee450..67c2072 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -544,16 +544,11 @@ static USBDevice *usb_serial_init(USBBus *bus, const char *filename) return NULL; dev = usb_create(bus, "usb-serial"); - if (!dev) { - return NULL; - } qdev_prop_set_chr(&dev->qdev, "chardev", cdrv); if (vendorid) qdev_prop_set_uint16(&dev->qdev, "vendorid", vendorid); if (productid) qdev_prop_set_uint16(&dev->qdev, "productid", productid); - qdev_init_nofail(&dev->qdev); - return dev; } @@ -568,8 +563,6 @@ static USBDevice *usb_braille_init(USBBus *bus, const char *unused) dev = usb_create(bus, "usb-braille"); qdev_prop_set_chr(&dev->qdev, "chardev", cdrv); - qdev_init_nofail(&dev->qdev); - return dev; } diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 4539733..af2e1b9 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -706,17 +706,11 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename) /* create guest device */ dev = usb_create(bus, "usb-storage"); - if (!dev) { - return NULL; - } if (qdev_prop_set_drive(&dev->qdev, "drive", blk_by_legacy_dinfo(dinfo)) < 0) { object_unparent(OBJECT(dev)); return NULL; } - if (qdev_init(&dev->qdev) < 0) - return NULL; - return dev; } diff --git a/hw/usb/host-legacy.c b/hw/usb/host-legacy.c index 3cc9c42..422ed9a 100644 --- a/hw/usb/host-legacy.c +++ b/hw/usb/host-legacy.c @@ -128,7 +128,6 @@ USBDevice *usb_host_device_open(USBBus *bus, const char *devname) qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr); qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id); qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id); - qdev_init_nofail(&dev->qdev); return dev; fail: diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index cff4f7c..10f4735 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -878,8 +878,7 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev) usb_device_attach(udev, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); - error_free(local_err); + error_report_err(local_err); goto fail; } @@ -1637,7 +1636,7 @@ static void usb_host_auto_check(void *unused) timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000); } -void usb_host_info(Monitor *mon, const QDict *qdict) +void hmp_info_usbhost(Monitor *mon, const QDict *qdict) { libusb_device **devs = NULL; struct libusb_device_descriptor ddesc; diff --git a/hw/usb/host-stub.c b/hw/usb/host-stub.c index 28d8032..2eaaa83 100644 --- a/hw/usb/host-stub.c +++ b/hw/usb/host-stub.c @@ -35,7 +35,7 @@ #include "hw/usb.h" #include "monitor/monitor.h" -void usb_host_info(Monitor *mon, const QDict *qdict) +void hmp_info_usbhost(Monitor *mon, const QDict *qdict) { monitor_printf(mon, "USB host devices not supported\n"); } diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 962d3f5..2416de8 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -1273,8 +1273,7 @@ static void usbredir_do_attach(void *opaque) usb_device_attach(&dev->dev, &local_err); if (local_err) { - error_report("%s", error_get_pretty(local_err)); - error_free(local_err); + error_report_err(local_err); WARNING("rejecting device due to speed mismatch\n"); usbredir_reject_device(dev); } diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index d21c397..19b224a 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -2,7 +2,7 @@ common-obj-y += virtio-rng.o common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o common-obj-y += virtio-bus.o common-obj-y += virtio-mmio.o -common-obj-$(CONFIG_VIRTIO) += dataplane/ +obj-$(CONFIG_VIRTIO) += dataplane/ obj-y += virtio.o virtio-balloon.o obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o diff --git a/hw/virtio/dataplane/Makefile.objs b/hw/virtio/dataplane/Makefile.objs index 9a8cfc0..753a9ca 100644 --- a/hw/virtio/dataplane/Makefile.objs +++ b/hw/virtio/dataplane/Makefile.objs @@ -1 +1 @@ -common-obj-y += vring.o +obj-y += vring.o diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c index 78c6f45..0936f65 100644 --- a/hw/virtio/dataplane/vring.c +++ b/hw/virtio/dataplane/vring.c @@ -18,7 +18,9 @@ #include "hw/hw.h" #include "exec/memory.h" #include "exec/address-spaces.h" +#include "hw/virtio/virtio-access.h" #include "hw/virtio/dataplane/vring.h" +#include "hw/virtio/dataplane/vring-accessors.h" #include "qemu/error-report.h" /* vring_map can be coupled with vring_unmap or (if you still have the @@ -83,7 +85,7 @@ bool vring_setup(Vring *vring, VirtIODevice *vdev, int n) vring_init(&vring->vr, virtio_queue_get_num(vdev, n), vring_ptr, 4096); vring->last_avail_idx = virtio_queue_get_last_avail_idx(vdev, n); - vring->last_used_idx = vring->vr.used->idx; + vring->last_used_idx = vring_get_used_idx(vdev, vring); vring->signalled_used = 0; vring->signalled_used_valid = false; @@ -104,7 +106,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n) void vring_disable_notification(VirtIODevice *vdev, Vring *vring) { if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) { - vring->vr.used->flags |= VRING_USED_F_NO_NOTIFY; + vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY); } } @@ -117,10 +119,10 @@ bool vring_enable_notification(VirtIODevice *vdev, Vring *vring) if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { vring_avail_event(&vring->vr) = vring->vr.avail->idx; } else { - vring->vr.used->flags &= ~VRING_USED_F_NO_NOTIFY; + vring_clear_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY); } smp_mb(); /* ensure update is seen before reading avail_idx */ - return !vring_more_avail(vring); + return !vring_more_avail(vdev, vring); } /* This is stolen from linux/drivers/vhost/vhost.c:vhost_notify() */ @@ -134,12 +136,13 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring) smp_mb(); if ((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) && - unlikely(vring->vr.avail->idx == vring->last_avail_idx)) { + unlikely(!vring_more_avail(vdev, vring))) { return true; } if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) { - return !(vring->vr.avail->flags & VRING_AVAIL_F_NO_INTERRUPT); + return !(vring_get_avail_flags(vdev, vring) & + VRING_AVAIL_F_NO_INTERRUPT); } old = vring->signalled_used; v = vring->signalled_used_valid; @@ -202,9 +205,19 @@ static int get_desc(Vring *vring, VirtQueueElement *elem, return 0; } +static void copy_in_vring_desc(VirtIODevice *vdev, + const struct vring_desc *guest, + struct vring_desc *host) +{ + host->addr = virtio_ldq_p(vdev, &guest->addr); + host->len = virtio_ldl_p(vdev, &guest->len); + host->flags = virtio_lduw_p(vdev, &guest->flags); + host->next = virtio_lduw_p(vdev, &guest->next); +} + /* This is stolen from linux/drivers/vhost/vhost.c. */ -static int get_indirect(Vring *vring, VirtQueueElement *elem, - struct vring_desc *indirect) +static int get_indirect(VirtIODevice *vdev, Vring *vring, + VirtQueueElement *elem, struct vring_desc *indirect) { struct vring_desc desc; unsigned int i = 0, count, found = 0; @@ -244,7 +257,7 @@ static int get_indirect(Vring *vring, VirtQueueElement *elem, vring->broken = true; return -EFAULT; } - desc = *desc_ptr; + copy_in_vring_desc(vdev, desc_ptr, &desc); memory_region_unref(mr); /* Ensure descriptor has been loaded before accessing fields */ @@ -320,7 +333,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, /* Check it isn't doing very strange things with descriptor numbers. */ last_avail_idx = vring->last_avail_idx; - avail_idx = vring->vr.avail->idx; + avail_idx = vring_get_avail_idx(vdev, vring); barrier(); /* load indices now and not again later */ if (unlikely((uint16_t)(avail_idx - last_avail_idx) > num)) { @@ -341,7 +354,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, /* Grab the next descriptor number they're advertising, and increment * the index we've seen. */ - head = vring->vr.avail->ring[last_avail_idx % num]; + head = vring_get_avail_ring(vdev, vring, last_avail_idx % num); elem->index = head; @@ -365,13 +378,13 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, ret = -EFAULT; goto out; } - desc = vring->vr.desc[i]; + copy_in_vring_desc(vdev, &vring->vr.desc[i], &desc); /* Ensure descriptor is loaded before accessing fields */ barrier(); if (desc.flags & VRING_DESC_F_INDIRECT) { - ret = get_indirect(vring, elem, &desc); + ret = get_indirect(vdev, vring, elem, &desc); if (ret < 0) { goto out; } @@ -407,9 +420,9 @@ out: * * Stolen from linux/drivers/vhost/vhost.c. */ -void vring_push(Vring *vring, VirtQueueElement *elem, int len) +void vring_push(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem, + int len) { - struct vring_used_elem *used; unsigned int head = elem->index; uint16_t new; @@ -422,14 +435,16 @@ void vring_push(Vring *vring, VirtQueueElement *elem, int len) /* The virtqueue contains a ring of used buffers. Get a pointer to the * next entry in that used ring. */ - used = &vring->vr.used->ring[vring->last_used_idx % vring->vr.num]; - used->id = head; - used->len = len; + vring_set_used_ring_id(vdev, vring, vring->last_used_idx % vring->vr.num, + head); + vring_set_used_ring_len(vdev, vring, vring->last_used_idx % vring->vr.num, + len); /* Make sure buffer is written before we update index. */ smp_wmb(); - new = vring->vr.used->idx = ++vring->last_used_idx; + new = ++vring->last_used_idx; + vring_set_used_idx(vdev, vring, new); if (unlikely((int16_t)(new - vring->signalled_used) < (uint16_t)1)) { vring->signalled_used_valid = false; } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index dde1d73..604cb5b 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1238,6 +1238,8 @@ static void vhost_scsi_pci_instance_init(Object *obj) virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI); + object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), + "bootindex", &error_abort); } static const TypeInfo vhost_scsi_pci_info = { |