diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/block/nvme.c | 1 | ||||
| -rw-r--r-- | hw/block/virtio-blk.c | 18 | ||||
| -rw-r--r-- | hw/display/cg3.c | 1 | ||||
| -rw-r--r-- | hw/display/qxl-logger.c | 16 | ||||
| -rw-r--r-- | hw/display/tcx.c | 1 | ||||
| -rw-r--r-- | hw/i386/kvm/pci-assign.c | 39 | ||||
| -rw-r--r-- | hw/input/Makefile.objs | 1 | ||||
| -rw-r--r-- | hw/input/virtio-input-host.c | 188 | ||||
| -rw-r--r-- | hw/input/virtio-input.c | 8 | ||||
| -rw-r--r-- | hw/isa/piix4.c | 8 | ||||
| -rw-r--r-- | hw/isa/vt82c686.c | 47 | ||||
| -rw-r--r-- | hw/pci-host/piix.c | 57 | ||||
| -rw-r--r-- | hw/pci/pci.c | 4 | ||||
| -rw-r--r-- | hw/virtio/virtio-pci.c | 43 | ||||
| -rw-r--r-- | hw/virtio/virtio-pci.h | 10 | ||||
| -rw-r--r-- | hw/watchdog/wdt_i6300esb.c | 14 | ||||
| -rw-r--r-- | hw/xen/xen_pt.c | 61 | ||||
| -rw-r--r-- | hw/xen/xen_pt.h | 12 | ||||
| -rw-r--r-- | hw/xen/xen_pt_config_init.c | 7 | ||||
| -rw-r--r-- | hw/xen/xen_pt_msi.c | 24 |
20 files changed, 413 insertions, 147 deletions
diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 4b6d5e6078..c6a6a0e49a 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -154,6 +154,7 @@ static uint16_t nvme_dma_read_prp(NvmeCtrl *n, uint8_t *ptr, uint32_t len, qemu_sglist_destroy(&qsg); return NVME_INVALID_FIELD | NVME_DNR; } + qemu_sglist_destroy(&qsg); return NVME_SUCCESS; } diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index cd539aa11c..6aefda4bf2 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -499,8 +499,7 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) iov_discard_front(&iov, &out_num, sizeof(req->out)); - if (in_num < 1 || - in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) { + if (in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) { error_report("virtio-blk request inhdr too short"); exit(1); } @@ -651,16 +650,21 @@ static void virtio_blk_dma_restart_cb(void *opaque, int running, static void virtio_blk_reset(VirtIODevice *vdev) { VirtIOBlock *s = VIRTIO_BLK(vdev); - - if (s->dataplane) { - virtio_blk_data_plane_stop(s->dataplane); - } + AioContext *ctx; /* * This should cancel pending requests, but can't do nicely until there * are per-device request lists. */ - blk_drain_all(); + ctx = blk_get_aio_context(s->blk); + aio_context_acquire(ctx); + blk_drain(s->blk); + + if (s->dataplane) { + virtio_blk_data_plane_stop(s->dataplane); + } + aio_context_release(ctx); + blk_set_enable_write_cache(s->blk, s->original_wce); } diff --git a/hw/display/cg3.c b/hw/display/cg3.c index b94e5e0d78..34dcbc3119 100644 --- a/hw/display/cg3.c +++ b/hw/display/cg3.c @@ -303,6 +303,7 @@ static void cg3_realizefn(DeviceState *dev, Error **errp) if (fcode_filename) { ret = load_image_targphys(fcode_filename, s->prom_addr, FCODE_MAX_ROM_SIZE); + g_free(fcode_filename); if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) { error_report("cg3: could not load prom '%s'", CG3_ROM_FILE); } diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c index c900c2ca4f..d944d3fdb5 100644 --- a/hw/display/qxl-logger.c +++ b/hw/display/qxl-logger.c @@ -22,7 +22,7 @@ #include "qemu/timer.h" #include "qxl.h" -static const char *qxl_type[] = { +static const char *const qxl_type[] = { [ QXL_CMD_NOP ] = "nop", [ QXL_CMD_DRAW ] = "draw", [ QXL_CMD_UPDATE ] = "update", @@ -31,7 +31,7 @@ static const char *qxl_type[] = { [ QXL_CMD_SURFACE ] = "surface", }; -static const char *qxl_draw_type[] = { +static const char *const qxl_draw_type[] = { [ QXL_DRAW_NOP ] = "nop", [ QXL_DRAW_FILL ] = "fill", [ QXL_DRAW_OPAQUE ] = "opaque", @@ -48,7 +48,7 @@ static const char *qxl_draw_type[] = { [ QXL_DRAW_ALPHA_BLEND ] = "alpha-blend", }; -static const char *qxl_draw_effect[] = { +static const char *const qxl_draw_effect[] = { [ QXL_EFFECT_BLEND ] = "blend", [ QXL_EFFECT_OPAQUE ] = "opaque", [ QXL_EFFECT_REVERT_ON_DUP ] = "revert-on-dup", @@ -59,12 +59,12 @@ static const char *qxl_draw_effect[] = { [ QXL_EFFECT_OPAQUE_BRUSH ] = "opaque-brush", }; -static const char *qxl_surface_cmd[] = { +static const char *const qxl_surface_cmd[] = { [ QXL_SURFACE_CMD_CREATE ] = "create", [ QXL_SURFACE_CMD_DESTROY ] = "destroy", }; -static const char *spice_surface_fmt[] = { +static const char *const spice_surface_fmt[] = { [ SPICE_SURFACE_FMT_INVALID ] = "invalid", [ SPICE_SURFACE_FMT_1_A ] = "alpha/1", [ SPICE_SURFACE_FMT_8_A ] = "alpha/8", @@ -74,14 +74,14 @@ static const char *spice_surface_fmt[] = { [ SPICE_SURFACE_FMT_32_ARGB ] = "ARGB/32", }; -static const char *qxl_cursor_cmd[] = { +static const char *const qxl_cursor_cmd[] = { [ QXL_CURSOR_SET ] = "set", [ QXL_CURSOR_MOVE ] = "move", [ QXL_CURSOR_HIDE ] = "hide", [ QXL_CURSOR_TRAIL ] = "trail", }; -static const char *spice_cursor_type[] = { +static const char *const spice_cursor_type[] = { [ SPICE_CURSOR_TYPE_ALPHA ] = "alpha", [ SPICE_CURSOR_TYPE_MONO ] = "mono", [ SPICE_CURSOR_TYPE_COLOR4 ] = "color4", @@ -91,7 +91,7 @@ static const char *spice_cursor_type[] = { [ SPICE_CURSOR_TYPE_COLOR32 ] = "color32", }; -static const char *qxl_v2n(const char *n[], size_t l, int v) +static const char *qxl_v2n(const char *const n[], size_t l, int v) { if (v >= l || !n[v]) { return "???"; diff --git a/hw/display/tcx.c b/hw/display/tcx.c index a0b6bc58de..6acdc2d282 100644 --- a/hw/display/tcx.c +++ b/hw/display/tcx.c @@ -1018,6 +1018,7 @@ static void tcx_realizefn(DeviceState *dev, Error **errp) if (fcode_filename) { ret = load_image_targphys(fcode_filename, s->prom_addr, FCODE_MAX_ROM_SIZE); + g_free(fcode_filename); if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) { error_report("tcx: could not load prom '%s'", TCX_ROM_FILE); } diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index 9db7c77605..74d22f4fd2 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -141,6 +141,9 @@ typedef struct AssignedDevice { int32_t bootindex; } AssignedDevice; +#define TYPE_PCI_ASSIGN "kvm-pci-assign" +#define PCI_ASSIGN(obj) OBJECT_CHECK(AssignedDevice, (obj), TYPE_PCI_ASSIGN) + static void assigned_dev_update_irq_routing(PCIDevice *dev); static void assigned_dev_load_option_rom(AssignedDevice *dev); @@ -257,7 +260,7 @@ static const MemoryRegionOps slow_bar_ops = { static void assigned_dev_iomem_setup(PCIDevice *pci_dev, int region_num, pcibus_t e_size) { - AssignedDevice *r_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *r_dev = PCI_ASSIGN(pci_dev); AssignedDevRegion *region = &r_dev->v_addrs[region_num]; PCIRegion *real_region = &r_dev->real_device.regions[region_num]; @@ -289,7 +292,7 @@ static const MemoryRegionOps assigned_dev_ioport_ops = { static void assigned_dev_ioport_setup(PCIDevice *pci_dev, int region_num, pcibus_t size) { - AssignedDevice *r_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *r_dev = PCI_ASSIGN(pci_dev); AssignedDevRegion *region = &r_dev->v_addrs[region_num]; region->e_size = size; @@ -303,7 +306,7 @@ static void assigned_dev_ioport_setup(PCIDevice *pci_dev, int region_num, static uint32_t assigned_dev_pci_read(PCIDevice *d, int pos, int len) { - AssignedDevice *pci_dev = DO_UPCAST(AssignedDevice, dev, d); + AssignedDevice *pci_dev = PCI_ASSIGN(d); uint32_t val; ssize_t ret; int fd = pci_dev->real_device.config_fd; @@ -328,7 +331,7 @@ static uint8_t assigned_dev_pci_read_byte(PCIDevice *d, int pos) static void assigned_dev_pci_write(PCIDevice *d, int pos, uint32_t val, int len) { - AssignedDevice *pci_dev = DO_UPCAST(AssignedDevice, dev, d); + AssignedDevice *pci_dev = PCI_ASSIGN(d); ssize_t ret; int fd = pci_dev->real_device.config_fd; @@ -946,7 +949,7 @@ static void deassign_device(AssignedDevice *dev) */ static void assigned_dev_update_irq_routing(PCIDevice *dev) { - AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, dev); + AssignedDevice *assigned_dev = PCI_ASSIGN(dev); Error *err = NULL; int r; @@ -961,7 +964,7 @@ static void assigned_dev_update_irq_routing(PCIDevice *dev) static void assigned_dev_update_msi(PCIDevice *pci_dev) { - AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap + PCI_MSI_FLAGS); int r; @@ -1015,7 +1018,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev) static void assigned_dev_update_msi_msg(PCIDevice *pci_dev) { - AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap + PCI_MSI_FLAGS); @@ -1048,7 +1051,7 @@ static bool assigned_dev_msix_skipped(MSIXTableEntry *entry) static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) { - AssignedDevice *adev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *adev = PCI_ASSIGN(pci_dev); uint16_t entries_nr = 0; int i, r = 0; MSIXTableEntry *entry = adev->msix_table; @@ -1113,7 +1116,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) static void assigned_dev_update_msix(PCIDevice *pci_dev) { - AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); uint16_t ctrl_word = pci_get_word(pci_dev->config + pci_dev->msix_cap + PCI_MSIX_FLAGS); int r; @@ -1163,7 +1166,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev) static uint32_t assigned_dev_pci_read_config(PCIDevice *pci_dev, uint32_t address, int len) { - AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); uint32_t virt_val = pci_default_read_config(pci_dev, address, len); uint32_t real_val, emulate_mask, full_emulation_mask; @@ -1184,7 +1187,7 @@ static uint32_t assigned_dev_pci_read_config(PCIDevice *pci_dev, static void assigned_dev_pci_write_config(PCIDevice *pci_dev, uint32_t address, uint32_t val, int len) { - AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev); uint16_t old_cmd = pci_get_word(pci_dev->config + PCI_COMMAND); uint32_t emulate_mask, full_emulation_mask; int ret; @@ -1244,7 +1247,7 @@ static void assigned_dev_setup_cap_read(AssignedDevice *dev, uint32_t offset, static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp) { - AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *dev = PCI_ASSIGN(pci_dev); PCIRegion *pci_region = dev->real_device.regions; int ret, pos; Error *local_err = NULL; @@ -1684,8 +1687,8 @@ static const VMStateDescription vmstate_assigned_device = { static void reset_assigned_device(DeviceState *dev) { - PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev); - AssignedDevice *adev = DO_UPCAST(AssignedDevice, dev, pci_dev); + PCIDevice *pci_dev = PCI_DEVICE(dev); + AssignedDevice *adev = PCI_ASSIGN(pci_dev); char reset_file[64]; const char reset[] = "1"; int fd, ret; @@ -1740,7 +1743,7 @@ static void reset_assigned_device(DeviceState *dev) static void assigned_realize(struct PCIDevice *pci_dev, Error **errp) { - AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *dev = PCI_ASSIGN(pci_dev); uint8_t e_intx; int r; Error *local_err = NULL; @@ -1836,7 +1839,7 @@ exit_with_error: static void assigned_exitfn(struct PCIDevice *pci_dev) { - AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev); + AssignedDevice *dev = PCI_ASSIGN(pci_dev); deassign_device(dev); free_assigned_device(dev); @@ -1845,7 +1848,7 @@ static void assigned_exitfn(struct PCIDevice *pci_dev) static void assigned_dev_instance_init(Object *obj) { PCIDevice *pci_dev = PCI_DEVICE(obj); - AssignedDevice *d = DO_UPCAST(AssignedDevice, dev, PCI_DEVICE(obj)); + AssignedDevice *d = PCI_ASSIGN(pci_dev); device_add_bootindex_property(obj, &d->bootindex, "bootindex", NULL, @@ -1879,7 +1882,7 @@ static void assign_class_init(ObjectClass *klass, void *data) } static const TypeInfo assign_info = { - .name = "kvm-pci-assign", + .name = TYPE_PCI_ASSIGN, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(AssignedDevice), .class_init = assign_class_init, diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs index 0dae71052d..624ba7ea40 100644 --- a/hw/input/Makefile.objs +++ b/hw/input/Makefile.objs @@ -11,6 +11,7 @@ common-obj-$(CONFIG_VMMOUSE) += vmmouse.o ifeq ($(CONFIG_LINUX),y) common-obj-$(CONFIG_VIRTIO) += virtio-input.o common-obj-$(CONFIG_VIRTIO) += virtio-input-hid.o +common-obj-$(CONFIG_VIRTIO) += virtio-input-host.o endif obj-$(CONFIG_MILKYMIST) += milkymist-softusb.o diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c new file mode 100644 index 0000000000..f7e3d844e6 --- /dev/null +++ b/hw/input/virtio-input-host.c @@ -0,0 +1,188 @@ +/* + * 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. + */ + +#include "qemu-common.h" +#include "qemu/sockets.h" + +#include "hw/qdev.h" +#include "hw/virtio/virtio.h" +#include "hw/virtio/virtio-input.h" + +#include "standard-headers/linux/input.h" + +/* ----------------------------------------------------------------- */ + +static struct virtio_input_config virtio_input_host_config[] = { + { /* empty list */ }, +}; + +static void virtio_input_host_event(void *opaque) +{ + VirtIOInputHost *vih = opaque; + VirtIOInput *vinput = VIRTIO_INPUT(vih); + struct virtio_input_event virtio; + struct input_event evdev; + int rc; + + for (;;) { + rc = read(vih->fd, &evdev, sizeof(evdev)); + if (rc != sizeof(evdev)) { + break; + } + + virtio.type = cpu_to_le16(evdev.type); + virtio.code = cpu_to_le16(evdev.code); + virtio.value = cpu_to_le32(evdev.value); + virtio_input_send(vinput, &virtio); + } +} + +static void virtio_input_bits_config(VirtIOInputHost *vih, + int type, int count) +{ + virtio_input_config bits; + int rc, i, size = 0; + + memset(&bits, 0, sizeof(bits)); + rc = ioctl(vih->fd, EVIOCGBIT(type, count/8), bits.u.bitmap); + if (rc < 0) { + return; + } + + for (i = 0; i < count/8; i++) { + if (bits.u.bitmap[i]) { + size = i+1; + } + } + if (size == 0) { + return; + } + + bits.select = VIRTIO_INPUT_CFG_EV_BITS; + bits.subsel = type; + bits.size = size; + virtio_input_add_config(VIRTIO_INPUT(vih), &bits); +} + +static void virtio_input_host_realize(DeviceState *dev, Error **errp) +{ + VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev); + VirtIOInput *vinput = VIRTIO_INPUT(dev); + virtio_input_config id; + struct input_id ids; + int rc, ver; + + if (!vih->evdev) { + error_setg(errp, "evdev property is required"); + return; + } + + vih->fd = open(vih->evdev, O_RDWR); + if (vih->fd < 0) { + error_setg_file_open(errp, errno, vih->evdev); + return; + } + qemu_set_nonblock(vih->fd); + + rc = ioctl(vih->fd, EVIOCGVERSION, &ver); + if (rc < 0) { + error_setg(errp, "%s: is not an evdev device", vih->evdev); + goto err_close; + } + + rc = ioctl(vih->fd, EVIOCGRAB, 1); + if (rc < 0) { + error_setg_errno(errp, errno, "%s: failed to get exclusive access", + vih->evdev); + goto err_close; + } + + memset(&id, 0, sizeof(id)); + ioctl(vih->fd, EVIOCGNAME(sizeof(id.u.string)-1), id.u.string); + id.select = VIRTIO_INPUT_CFG_ID_NAME; + id.size = strlen(id.u.string); + virtio_input_add_config(vinput, &id); + + if (ioctl(vih->fd, EVIOCGID, &ids) == 0) { + memset(&id, 0, sizeof(id)); + id.select = VIRTIO_INPUT_CFG_ID_DEVIDS; + id.size = sizeof(struct virtio_input_devids); + id.u.ids.bustype = cpu_to_le16(ids.bustype); + id.u.ids.vendor = cpu_to_le16(ids.vendor); + id.u.ids.product = cpu_to_le16(ids.product); + id.u.ids.version = cpu_to_le16(ids.version); + virtio_input_add_config(vinput, &id); + } + + virtio_input_bits_config(vih, EV_KEY, KEY_CNT); + virtio_input_bits_config(vih, EV_REL, REL_CNT); + virtio_input_bits_config(vih, EV_ABS, ABS_CNT); + virtio_input_bits_config(vih, EV_MSC, MSC_CNT); + virtio_input_bits_config(vih, EV_SW, SW_CNT); + + qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih); + return; + +err_close: + close(vih->fd); + vih->fd = -1; + return; +} + +static void virtio_input_host_unrealize(DeviceState *dev, Error **errp) +{ + VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev); + + if (vih->fd > 0) { + qemu_set_fd_handler(vih->fd, NULL, NULL, NULL); + close(vih->fd); + } +} + +static const VMStateDescription vmstate_virtio_input_host = { + .name = "virtio-input-host", + .unmigratable = 1, +}; + +static Property virtio_input_host_properties[] = { + DEFINE_PROP_STRING("evdev", VirtIOInputHost, evdev), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_input_host_class_init(ObjectClass *klass, void *data) +{ + VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &vmstate_virtio_input_host; + dc->props = virtio_input_host_properties; + vic->realize = virtio_input_host_realize; + vic->unrealize = virtio_input_host_unrealize; +} + +static void virtio_input_host_init(Object *obj) +{ + VirtIOInput *vinput = VIRTIO_INPUT(obj); + + virtio_input_init_config(vinput, virtio_input_host_config); +} + +static const TypeInfo virtio_input_host_info = { + .name = TYPE_VIRTIO_INPUT_HOST, + .parent = TYPE_VIRTIO_INPUT, + .instance_size = sizeof(VirtIOInputHost), + .instance_init = virtio_input_host_init, + .class_init = virtio_input_host_class_init, +}; + +/* ----------------------------------------------------------------- */ + +static void virtio_register_types(void) +{ + type_register_static(&virtio_input_host_info); +} + +type_init(virtio_register_types) diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index c4f4b3c150..7f5b8d6000 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -216,7 +216,7 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp) } virtio_input_idstr_config(vinput, VIRTIO_INPUT_CFG_ID_SERIAL, - vinput->input.serial); + vinput->serial); QTAILQ_FOREACH(cfg, &vinput->cfg_list, node) { if (vinput->cfg_size < cfg->config.size) { @@ -248,11 +248,17 @@ static void virtio_input_device_unrealize(DeviceState *dev, Error **errp) virtio_cleanup(vdev); } +static Property virtio_input_properties[] = { + DEFINE_PROP_STRING("serial", VirtIOInput, serial), + DEFINE_PROP_END_OF_LIST(), +}; + static void virtio_input_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + dc->props = virtio_input_properties; set_bit(DEVICE_CATEGORY_INPUT, dc->categories); vdc->realize = virtio_input_device_realize; vdc->unrealize = virtio_input_device_unrealize; diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index d9522b1f45..2c59e91fff 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -34,6 +34,10 @@ typedef struct PIIX4State { PCIDevice dev; } PIIX4State; +#define TYPE_PIIX4_PCI_DEVICE "PIIX4" +#define PIIX4_PCI_DEVICE(obj) \ + OBJECT_CHECK(PIIX4State, (obj), TYPE_PIIX4_PCI_DEVICE) + static void piix4_reset(void *opaque) { PIIX4State *d = opaque; @@ -84,7 +88,7 @@ static const VMStateDescription vmstate_piix4 = { static void piix4_realize(PCIDevice *dev, Error **errp) { - PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev); + PIIX4State *d = PIIX4_PCI_DEVICE(dev); isa_bus_new(DEVICE(d), pci_address_space(dev), pci_address_space_io(dev)); @@ -121,7 +125,7 @@ static void piix4_class_init(ObjectClass *klass, void *data) } static const TypeInfo piix4_info = { - .name = "PIIX4", + .name = TYPE_PIIX4_PCI_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PIIX4State), .class_init = piix4_class_init, diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index b2ba870427..252e1d7145 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -47,6 +47,10 @@ typedef struct VT82C686BState { SuperIOConfig superio_conf; } VT82C686BState; +#define TYPE_VT82C686B_DEVICE "VT82C686B" +#define VT82C686B_DEVICE(obj) \ + OBJECT_CHECK(VT82C686BState, (obj), TYPE_VT82C686B_DEVICE) + static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, unsigned size) { @@ -114,7 +118,7 @@ static void vt82c686b_reset(void * opaque) { PCIDevice *d = opaque; uint8_t *pci_conf = d->config; - VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d); + VT82C686BState *vt82c = VT82C686B_DEVICE(d); pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | @@ -142,7 +146,7 @@ static void vt82c686b_reset(void * opaque) static void vt82c686b_write_config(PCIDevice * d, uint32_t address, uint32_t val, int len) { - VT82C686BState *vt686 = DO_UPCAST(VT82C686BState, dev, d); + VT82C686BState *vt686 = VT82C686B_DEVICE(d); DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n", address, val, len); @@ -172,6 +176,18 @@ typedef struct VT686MC97State { PCIDevice dev; } VT686MC97State; +#define TYPE_VT82C686B_PM_DEVICE "VT82C686B_PM" +#define VT82C686B_PM_DEVICE(obj) \ + OBJECT_CHECK(VT686PMState, (obj), TYPE_VT82C686B_PM_DEVICE) + +#define TYPE_VT82C686B_MC97_DEVICE "VT82C686B_MC97" +#define VT82C686B_MC97_DEVICE(obj) \ + OBJECT_CHECK(VT686MC97State, (obj), TYPE_VT82C686B_MC97_DEVICE) + +#define TYPE_VT82C686B_AC97_DEVICE "VT82C686B_AC97" +#define VT82C686B_AC97_DEVICE(obj) \ + OBJECT_CHECK(VT686AC97State, (obj), TYPE_VT82C686B_AC97_DEVICE) + static void pm_update_sci(VT686PMState *s) { int sci_level, pmsts; @@ -247,7 +263,7 @@ static const VMStateDescription vmstate_acpi = { static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) { - VT686AC97State *s = DO_UPCAST(VT686AC97State, dev, dev); + VT686AC97State *s = VT82C686B_AC97_DEVICE(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -261,7 +277,7 @@ void vt82c686b_ac97_init(PCIBus *bus, int devfn) { PCIDevice *dev; - dev = pci_create(bus, devfn, "VT82C686B_AC97"); + dev = pci_create(bus, devfn, TYPE_VT82C686B_AC97_DEVICE); qdev_init_nofail(&dev->qdev); } @@ -280,7 +296,7 @@ static void via_ac97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_ac97_info = { - .name = "VT82C686B_AC97", + .name = TYPE_VT82C686B_AC97_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(VT686AC97State), .class_init = via_ac97_class_init, @@ -288,7 +304,7 @@ static const TypeInfo via_ac97_info = { static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp) { - VT686MC97State *s = DO_UPCAST(VT686MC97State, dev, dev); + VT686MC97State *s = VT82C686B_MC97_DEVICE(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -301,7 +317,7 @@ void vt82c686b_mc97_init(PCIBus *bus, int devfn) { PCIDevice *dev; - dev = pci_create(bus, devfn, "VT82C686B_MC97"); + dev = pci_create(bus, devfn, TYPE_VT82C686B_MC97_DEVICE); qdev_init_nofail(&dev->qdev); } @@ -320,7 +336,7 @@ static void via_mc97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_mc97_info = { - .name = "VT82C686B_MC97", + .name = TYPE_VT82C686B_MC97_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(VT686MC97State), .class_init = via_mc97_class_init, @@ -329,7 +345,7 @@ static const TypeInfo via_mc97_info = { /* vt82c686 pm init */ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) { - VT686PMState *s = DO_UPCAST(VT686PMState, dev, dev); + VT686PMState *s = VT82C686B_PM_DEVICE(dev); uint8_t *pci_conf; pci_conf = s->dev.config; @@ -365,10 +381,10 @@ I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, PCIDevice *dev; VT686PMState *s; - dev = pci_create(bus, devfn, "VT82C686B_PM"); + dev = pci_create(bus, devfn, TYPE_VT82C686B_PM_DEVICE); qdev_prop_set_uint32(&dev->qdev, "smb_io_base", smb_io_base); - s = DO_UPCAST(VT686PMState, dev, dev); + s = VT82C686B_PM_DEVICE(dev); qdev_init_nofail(&dev->qdev); @@ -398,7 +414,7 @@ static void via_pm_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_pm_info = { - .name = "VT82C686B_PM", + .name = TYPE_VT82C686B_PM_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(VT686PMState), .class_init = via_pm_class_init, @@ -417,7 +433,7 @@ static const VMStateDescription vmstate_via = { /* init the PCI-to-ISA bridge */ static void vt82c686b_realize(PCIDevice *d, Error **errp) { - VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d); + VT82C686BState *vt82c = VT82C686B_DEVICE(d); uint8_t *pci_conf; ISABus *isa_bus; uint8_t *wmask; @@ -451,7 +467,8 @@ ISABus *vt82c686b_init(PCIBus *bus, int devfn) { PCIDevice *d; - d = pci_create_simple_multifunction(bus, devfn, true, "VT82C686B"); + d = pci_create_simple_multifunction(bus, devfn, true, + TYPE_VT82C686B_DEVICE); return ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0")); } @@ -477,7 +494,7 @@ static void via_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_info = { - .name = "VT82C686B", + .name = TYPE_VT82C686B_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(VT82C686BState), .class_init = via_class_init, diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index ed2424c4cd..ad55f99663 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -91,6 +91,10 @@ typedef struct PIIX3State { MemoryRegion rcr_mem; } PIIX3State; +#define TYPE_PIIX3_PCI_DEVICE "pci-piix3" +#define PIIX3_PCI_DEVICE(obj) \ + OBJECT_CHECK(PIIX3State, (obj), TYPE_PIIX3_PCI_DEVICE) + #define TYPE_I440FX_PCI_DEVICE "i440FX" #define I440FX_PCI_DEVICE(obj) \ OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE) @@ -368,13 +372,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, * connected to the IOAPIC directly. * These additional routes can be discovered through ACPI. */ if (xen_enabled()) { - piix3 = DO_UPCAST(PIIX3State, dev, - pci_create_simple_multifunction(b, -1, true, "PIIX3-xen")); + PCIDevice *pci_dev = pci_create_simple_multifunction(b, + -1, true, "PIIX3-xen"); + piix3 = PIIX3_PCI_DEVICE(pci_dev); pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, XEN_PIIX_NUM_PIRQS); } else { - piix3 = DO_UPCAST(PIIX3State, dev, - pci_create_simple_multifunction(b, -1, true, "PIIX3")); + PCIDevice *pci_dev = pci_create_simple_multifunction(b, + -1, true, "PIIX3"); + piix3 = PIIX3_PCI_DEVICE(pci_dev); pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS); pci_bus_set_route_irq_fn(b, piix3_route_intx_pin_to_irq); @@ -480,7 +486,7 @@ static void piix3_write_config(PCIDevice *dev, { pci_default_write_config(dev, address, val, len); if (ranges_overlap(address, len, PIIX_PIRQC, 4)) { - PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev); + PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev); int pic_irq; pci_bus_fire_intx_routing_notifier(piix3->dev.bus); @@ -634,7 +640,7 @@ static const MemoryRegionOps rcr_ops = { static void piix3_realize(PCIDevice *dev, Error **errp) { - PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev); + PIIX3State *d = PIIX3_PCI_DEVICE(dev); isa_bus_new(DEVICE(d), get_system_memory(), pci_address_space_io(dev)); @@ -647,7 +653,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp) qemu_register_reset(piix3_reset, d); } -static void piix3_class_init(ObjectClass *klass, void *data) +static void pci_piix3_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -656,7 +662,6 @@ static void piix3_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_piix3; dc->hotpluggable = false; k->realize = piix3_realize; - k->config_write = piix3_write_config; k->vendor_id = PCI_VENDOR_ID_INTEL; /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; @@ -668,38 +673,37 @@ static void piix3_class_init(ObjectClass *klass, void *data) dc->cannot_instantiate_with_device_add_yet = true; } +static const TypeInfo piix3_pci_type_info = { + .name = TYPE_PIIX3_PCI_DEVICE, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PIIX3State), + .abstract = true, + .class_init = pci_piix3_class_init, +}; + +static void piix3_class_init(ObjectClass *klass, void *data) +{ + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->config_write = piix3_write_config; +} + static const TypeInfo piix3_info = { .name = "PIIX3", - .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(PIIX3State), + .parent = TYPE_PIIX3_PCI_DEVICE, .class_init = piix3_class_init, }; static void piix3_xen_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - dc->desc = "ISA bridge"; - dc->vmsd = &vmstate_piix3; - dc->hotpluggable = false; - k->realize = piix3_realize; k->config_write = piix3_write_config_xen; - k->vendor_id = PCI_VENDOR_ID_INTEL; - /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ - k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; - k->class_id = PCI_CLASS_BRIDGE_ISA; - /* - * Reason: part of PIIX3 southbridge, needs to be wired up by - * pc_piix.c's pc_init1() - */ - dc->cannot_instantiate_with_device_add_yet = true; }; static const TypeInfo piix3_xen_info = { .name = "PIIX3-xen", - .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(PIIX3State), + .parent = TYPE_PIIX3_PCI_DEVICE, .class_init = piix3_xen_class_init, }; @@ -772,6 +776,7 @@ static const TypeInfo i440fx_pcihost_info = { static void i440fx_register_types(void) { type_register_static(&i440fx_info); + type_register_static(&piix3_pci_type_info); type_register_static(&piix3_info); type_register_static(&piix3_xen_info); type_register_static(&i440fx_pcihost_info); diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 45394cfe32..442f822f42 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -428,6 +428,10 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size) for (i = 0; i < size; ++i) { if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i] & ~s->w1cmask[i]) { + error_report("%s: Bad config data: i=0x%x read: %x device: %x " + "cmask: %x wmask: %x w1cmask:%x", __func__, + i, config[i], s->config[i], + s->cmask[i], s->wmask[i], s->w1cmask[i]); g_free(config); return -EINVAL; } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index d7cf34cee9..70bc6d801e 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1900,8 +1900,7 @@ static const TypeInfo virtio_rng_pci_info = { /* virtio-input-pci */ -static Property virtio_input_hid_pci_properties[] = { - DEFINE_VIRTIO_INPUT_PROPERTIES(VirtIOInputPCI, vdev.input), +static Property virtio_input_pci_properties[] = { DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), DEFINE_PROP_END_OF_LIST(), }; @@ -1924,19 +1923,13 @@ static void virtio_input_pci_class_init(ObjectClass *klass, void *data) VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); + dc->props = virtio_input_pci_properties; k->realize = virtio_input_pci_realize; set_bit(DEVICE_CATEGORY_INPUT, dc->categories); pcidev_k->class_id = PCI_CLASS_INPUT_OTHER; } -static void virtio_input_hid_pci_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->props = virtio_input_hid_pci_properties; -} - static void virtio_input_hid_kbd_pci_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); @@ -1955,22 +1948,33 @@ static void virtio_input_hid_mouse_pci_class_init(ObjectClass *klass, static void virtio_keyboard_initfn(Object *obj) { VirtIOInputHIDPCI *dev = VIRTIO_INPUT_HID_PCI(obj); - object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_KEYBOARD); - object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_KEYBOARD); } static void virtio_mouse_initfn(Object *obj) { VirtIOInputHIDPCI *dev = VIRTIO_INPUT_HID_PCI(obj); - object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_MOUSE); - object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_MOUSE); } static void virtio_tablet_initfn(Object *obj) { VirtIOInputHIDPCI *dev = VIRTIO_INPUT_HID_PCI(obj); - object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_TABLET); - object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_TABLET); +} + +static void virtio_host_initfn(Object *obj) +{ + VirtIOInputHostPCI *dev = VIRTIO_INPUT_HOST_PCI(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_INPUT_HOST); } static const TypeInfo virtio_input_pci_info = { @@ -1985,7 +1989,6 @@ static const TypeInfo virtio_input_hid_pci_info = { .name = TYPE_VIRTIO_INPUT_HID_PCI, .parent = TYPE_VIRTIO_INPUT_PCI, .instance_size = sizeof(VirtIOInputHIDPCI), - .class_init = virtio_input_hid_pci_class_init, .abstract = true, }; @@ -2012,6 +2015,13 @@ static const TypeInfo virtio_tablet_pci_info = { .instance_init = virtio_tablet_initfn, }; +static const TypeInfo virtio_host_pci_info = { + .name = TYPE_VIRTIO_INPUT_HOST_PCI, + .parent = TYPE_VIRTIO_INPUT_PCI, + .instance_size = sizeof(VirtIOInputHostPCI), + .instance_init = virtio_host_initfn, +}; + /* virtio-pci-bus */ static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, @@ -2058,6 +2068,7 @@ static void virtio_pci_register_types(void) type_register_static(&virtio_keyboard_pci_info); type_register_static(&virtio_mouse_pci_info); type_register_static(&virtio_tablet_pci_info); + type_register_static(&virtio_host_pci_info); type_register_static(&virtio_pci_bus_info); type_register_static(&virtio_pci_info); #ifdef CONFIG_VIRTFS diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index 96025ca205..05d9d243f6 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -43,6 +43,7 @@ typedef struct VHostSCSIPCI VHostSCSIPCI; typedef struct VirtIORngPCI VirtIORngPCI; typedef struct VirtIOInputPCI VirtIOInputPCI; typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI; +typedef struct VirtIOInputHostPCI VirtIOInputHostPCI; typedef struct VirtIOGPUPCI VirtIOGPUPCI; /* virtio-pci-bus */ @@ -263,6 +264,15 @@ struct VirtIOInputHIDPCI { VirtIOInputHID vdev; }; +#define TYPE_VIRTIO_INPUT_HOST_PCI "virtio-input-host-pci" +#define VIRTIO_INPUT_HOST_PCI(obj) \ + OBJECT_CHECK(VirtIOInputHostPCI, (obj), TYPE_VIRTIO_INPUT_HOST_PCI) + +struct VirtIOInputHostPCI { + VirtIOPCIProxy parent_obj; + VirtIOInputHost vdev; +}; + /* * virtio-gpu-pci: This extends VirtioPCIProxy. */ diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c index 4ebdbb8586..cfa2b1be13 100644 --- a/hw/watchdog/wdt_i6300esb.c +++ b/hw/watchdog/wdt_i6300esb.c @@ -103,6 +103,10 @@ struct I6300State { typedef struct I6300State I6300State; +#define TYPE_WATCHDOG_I6300ESB_DEVICE "i6300esb" +#define WATCHDOG_I6300ESB_DEVICE(obj) \ + OBJECT_CHECK(I6300State, (obj), TYPE_WATCHDOG_I6300ESB_DEVICE) + /* This function is called when the watchdog has either been enabled * (hence it starts counting down) or has been keep-alived. */ @@ -150,7 +154,7 @@ static void i6300esb_disable_timer(I6300State *d) static void i6300esb_reset(DeviceState *dev) { PCIDevice *pdev = PCI_DEVICE(dev); - I6300State *d = DO_UPCAST(I6300State, dev, pdev); + I6300State *d = WATCHDOG_I6300ESB_DEVICE(pdev); i6300esb_debug("I6300State = %p\n", d); @@ -213,7 +217,7 @@ static void i6300esb_timer_expired(void *vp) static void i6300esb_config_write(PCIDevice *dev, uint32_t addr, uint32_t data, int len) { - I6300State *d = DO_UPCAST(I6300State, dev, dev); + I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev); int old; i6300esb_debug("addr = %x, data = %x, len = %d\n", addr, data, len); @@ -241,7 +245,7 @@ static void i6300esb_config_write(PCIDevice *dev, uint32_t addr, static uint32_t i6300esb_config_read(PCIDevice *dev, uint32_t addr, int len) { - I6300State *d = DO_UPCAST(I6300State, dev, dev); + I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev); uint32_t data; i6300esb_debug ("addr = %x, len = %d\n", addr, len); @@ -416,7 +420,7 @@ static const VMStateDescription vmstate_i6300esb = { static void i6300esb_realize(PCIDevice *dev, Error **errp) { - I6300State *d = DO_UPCAST(I6300State, dev, dev); + I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev); i6300esb_debug("I6300State = %p\n", d); @@ -451,7 +455,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data) } static const TypeInfo i6300esb_info = { - .name = "i6300esb", + .name = TYPE_WATCHDOG_I6300ESB_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(I6300State), .class_init = i6300esb_class_init, diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 9afcda8e21..ed5fcaec0d 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -125,7 +125,7 @@ int xen_pt_bar_offset_to_index(uint32_t offset) static uint32_t xen_pt_pci_read_config(PCIDevice *d, uint32_t addr, int len) { - XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d); + XenPCIPassthroughState *s = XEN_PT_DEVICE(d); uint32_t val = 0; XenPTRegGroup *reg_grp_entry = NULL; XenPTReg *reg_entry = NULL; @@ -230,7 +230,7 @@ exit: static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { - XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d); + XenPCIPassthroughState *s = XEN_PT_DEVICE(d); int index = 0; XenPTRegGroup *reg_grp_entry = NULL; int rc = 0; @@ -249,10 +249,18 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, /* check unused BAR register */ index = xen_pt_bar_offset_to_index(addr); - if ((index >= 0) && (val > 0 && val < XEN_PT_BAR_ALLF) && - (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED)) { - XEN_PT_WARN(d, "Guest attempt to set address to unused Base Address " - "Register. (addr: 0x%02x, len: %d)\n", addr, len); + if ((index >= 0) && (val != 0)) { + uint32_t chk = val; + + if (index == PCI_ROM_SLOT) + chk |= (uint32_t)~PCI_ROM_ADDRESS_MASK; + + if ((chk != XEN_PT_BAR_ALLF) && + (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED)) { + XEN_PT_WARN(d, "Guest attempt to set address to unused " + "Base Address Register. (addr: 0x%02x, len: %d)\n", + addr, len); + } } /* find register group entry */ @@ -607,8 +615,8 @@ static void xen_pt_region_update(XenPCIPassthroughState *s, guest_port, machine_port, size, op); if (rc) { - XEN_PT_ERR(d, "%s ioport mapping failed! (rc: %i)\n", - adding ? "create new" : "remove old", rc); + XEN_PT_ERR(d, "%s ioport mapping failed! (err: %i)\n", + adding ? "create new" : "remove old", errno); } } else { pcibus_t guest_addr = sec->offset_within_address_space; @@ -621,8 +629,8 @@ static void xen_pt_region_update(XenPCIPassthroughState *s, XEN_PFN(size + XC_PAGE_SIZE - 1), op); if (rc) { - XEN_PT_ERR(d, "%s mem mapping failed! (rc: %i)\n", - adding ? "create new" : "remove old", rc); + XEN_PT_ERR(d, "%s mem mapping failed! (err: %i)\n", + adding ? "create new" : "remove old", errno); } } } @@ -679,7 +687,7 @@ static const MemoryListener xen_pt_io_listener = { static int xen_pt_initfn(PCIDevice *d) { - XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d); + XenPCIPassthroughState *s = XEN_PT_DEVICE(d); int rc = 0; uint8_t machine_irq = 0; uint16_t cmd = 0; @@ -736,14 +744,11 @@ static int xen_pt_initfn(PCIDevice *d) rc = xc_physdev_map_pirq(xen_xc, xen_domid, machine_irq, &pirq); if (rc < 0) { - XEN_PT_ERR(d, "Mapping machine irq %u to pirq %i failed, (rc: %d)\n", - machine_irq, pirq, rc); + XEN_PT_ERR(d, "Mapping machine irq %u to pirq %i failed, (err: %d)\n", + machine_irq, pirq, errno); /* Disable PCI intx assertion (turn on bit10 of devctl) */ - xen_host_pci_set_word(&s->real_device, - PCI_COMMAND, - pci_get_word(s->dev.config + PCI_COMMAND) - | PCI_COMMAND_INTX_DISABLE); + cmd |= PCI_COMMAND_INTX_DISABLE; machine_irq = 0; s->machine_irq = 0; } else { @@ -761,19 +766,17 @@ static int xen_pt_initfn(PCIDevice *d) PCI_SLOT(d->devfn), e_intx); if (rc < 0) { - XEN_PT_ERR(d, "Binding of interrupt %i failed! (rc: %d)\n", - e_intx, rc); + XEN_PT_ERR(d, "Binding of interrupt %i failed! (err: %d)\n", + e_intx, errno); /* Disable PCI intx assertion (turn on bit10 of devctl) */ - xen_host_pci_set_word(&s->real_device, PCI_COMMAND, - *(uint16_t *)(&s->dev.config[PCI_COMMAND]) - | PCI_COMMAND_INTX_DISABLE); + cmd |= PCI_COMMAND_INTX_DISABLE; xen_pt_mapped_machine_irq[machine_irq]--; if (xen_pt_mapped_machine_irq[machine_irq] == 0) { if (xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq)) { XEN_PT_ERR(d, "Unmapping of machine interrupt %i failed!" - " (rc: %d)\n", machine_irq, rc); + " (err: %d)\n", machine_irq, errno); } } s->machine_irq = 0; @@ -797,7 +800,7 @@ out: static void xen_pt_unregister_device(PCIDevice *d) { - XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d); + XenPCIPassthroughState *s = XEN_PT_DEVICE(d); uint8_t machine_irq = s->machine_irq; uint8_t intx = xen_pt_pci_intx(s); int rc; @@ -811,9 +814,9 @@ static void xen_pt_unregister_device(PCIDevice *d) 0 /* isa_irq */); if (rc < 0) { XEN_PT_ERR(d, "unbinding of interrupt INT%c failed." - " (machine irq: %i, rc: %d)" + " (machine irq: %i, err: %d)" " But bravely continuing on..\n", - 'a' + intx, machine_irq, rc); + 'a' + intx, machine_irq, errno); } } @@ -831,9 +834,9 @@ static void xen_pt_unregister_device(PCIDevice *d) rc = xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq); if (rc < 0) { - XEN_PT_ERR(d, "unmapping of interrupt %i failed. (rc: %d)" + XEN_PT_ERR(d, "unmapping of interrupt %i failed. (err: %d)" " But bravely continuing on..\n", - machine_irq, rc); + machine_irq, errno); } } } @@ -868,7 +871,7 @@ static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data) }; static const TypeInfo xen_pci_passthrough_info = { - .name = "xen-pci-passthrough", + .name = TYPE_XEN_PT_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(XenPCIPassthroughState), .class_init = xen_pci_passthrough_class_init, diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h index 4bba559763..393f36ccbf 100644 --- a/hw/xen/xen_pt.h +++ b/hw/xen/xen_pt.h @@ -31,11 +31,15 @@ void xen_pt_log(const PCIDevice *d, const char *f, ...) GCC_FMT_ATTR(2, 3); /* Helper */ #define XEN_PFN(x) ((x) >> XC_PAGE_SHIFT) -typedef struct XenPTRegInfo XenPTRegInfo; +typedef const struct XenPTRegInfo XenPTRegInfo; typedef struct XenPTReg XenPTReg; typedef struct XenPCIPassthroughState XenPCIPassthroughState; +#define TYPE_XEN_PT_DEVICE "xen-pci-passthrough" +#define XEN_PT_DEVICE(obj) \ + OBJECT_CHECK(XenPCIPassthroughState, (obj), TYPE_XEN_PT_DEVICE) + /* function type for config reg */ typedef int (*xen_pt_conf_reg_init) (XenPCIPassthroughState *, XenPTRegInfo *, uint32_t real_offset, @@ -133,11 +137,11 @@ struct XenPTReg { uint32_t data; /* emulated value */ }; -typedef struct XenPTRegGroupInfo XenPTRegGroupInfo; +typedef const struct XenPTRegGroupInfo XenPTRegGroupInfo; /* emul reg group size initialize method */ typedef int (*xen_pt_reg_size_init_fn) - (XenPCIPassthroughState *, const XenPTRegGroupInfo *, + (XenPCIPassthroughState *, XenPTRegGroupInfo *, uint32_t base_offset, uint8_t *size); /* emulated register group information */ @@ -152,7 +156,7 @@ struct XenPTRegGroupInfo { /* emul register group management table */ typedef struct XenPTRegGroup { QLIST_ENTRY(XenPTRegGroup) entries; - const XenPTRegGroupInfo *reg_grp; + XenPTRegGroupInfo *reg_grp; uint32_t base_offset; uint8_t size; QLIST_HEAD(, XenPTReg) reg_tbl_list; diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index f3cf069b60..dd37be38a4 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -96,8 +96,7 @@ XenPTReg *xen_pt_find_reg(XenPTRegGroup *reg_grp, uint32_t address) } static uint32_t get_throughable_mask(const XenPCIPassthroughState *s, - const XenPTRegInfo *reg, - uint32_t valid_mask) + XenPTRegInfo *reg, uint32_t valid_mask) { uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); @@ -729,8 +728,8 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = { .offset = PCI_ROM_ADDRESS, .size = 4, .init_val = 0x00000000, - .ro_mask = 0x000007FE, - .emu_mask = 0xFFFFF800, + .ro_mask = ~PCI_ROM_ADDRESS_MASK & ~PCI_ROM_ADDRESS_ENABLE, + .emu_mask = (uint32_t)PCI_ROM_ADDRESS_MASK, .init = xen_pt_bar_reg_init, .u.dw.read = xen_pt_long_reg_read, .u.dw.write = xen_pt_exp_rom_bar_reg_write, diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c index 68db6233dc..263e0514a2 100644 --- a/hw/xen/xen_pt_msi.c +++ b/hw/xen/xen_pt_msi.c @@ -132,8 +132,8 @@ static int msi_msix_setup(XenPCIPassthroughState *s, msix_entry, table_base); if (rc) { XEN_PT_ERR(&s->dev, - "Mapping of MSI%s (rc: %i, vec: %#x, entry %#x)\n", - is_msix ? "-X" : "", rc, gvec, msix_entry); + "Mapping of MSI%s (err: %i, vec: %#x, entry %#x)\n", + is_msix ? "-X" : "", errno, gvec, msix_entry); return rc; } } @@ -166,12 +166,12 @@ static int msi_msix_update(XenPCIPassthroughState *s, pirq, gflags, table_addr); if (rc) { - XEN_PT_ERR(d, "Updating of MSI%s failed. (rc: %d)\n", - is_msix ? "-X" : "", rc); + XEN_PT_ERR(d, "Updating of MSI%s failed. (err: %d)\n", + is_msix ? "-X" : "", errno); if (xc_physdev_unmap_pirq(xen_xc, xen_domid, *old_pirq)) { - XEN_PT_ERR(d, "Unmapping of MSI%s pirq %d failed.\n", - is_msix ? "-X" : "", *old_pirq); + XEN_PT_ERR(d, "Unmapping of MSI%s pirq %d failed. (err: %d)\n", + is_msix ? "-X" : "", *old_pirq, errno); } *old_pirq = XEN_PT_UNASSIGNED_PIRQ; } @@ -199,8 +199,8 @@ static int msi_msix_disable(XenPCIPassthroughState *s, is_msix ? "-X" : "", pirq, gvec); rc = xc_domain_unbind_msi_irq(xen_xc, xen_domid, gvec, pirq, gflags); if (rc) { - XEN_PT_ERR(d, "Unbinding of MSI%s failed. (pirq: %d, gvec: %#x)\n", - is_msix ? "-X" : "", pirq, gvec); + XEN_PT_ERR(d, "Unbinding of MSI%s failed. (err: %d, pirq: %d, gvec: %#x)\n", + is_msix ? "-X" : "", errno, pirq, gvec); return rc; } } @@ -208,8 +208,8 @@ static int msi_msix_disable(XenPCIPassthroughState *s, XEN_PT_LOG(d, "Unmap MSI%s pirq %d\n", is_msix ? "-X" : "", pirq); rc = xc_physdev_unmap_pirq(xen_xc, xen_domid, pirq); if (rc) { - XEN_PT_ERR(d, "Unmapping of MSI%s pirq %d failed. (rc: %i)\n", - is_msix ? "-X" : "", pirq, rc); + XEN_PT_ERR(d, "Unmapping of MSI%s pirq %d failed. (err: %i)\n", + is_msix ? "-X" : "", pirq, errno); return rc; } @@ -385,8 +385,8 @@ int xen_pt_msix_update_remap(XenPCIPassthroughState *s, int bar_index) ret = xc_domain_unbind_pt_irq(xen_xc, xen_domid, entry->pirq, PT_IRQ_TYPE_MSI, 0, 0, 0, 0); if (ret) { - XEN_PT_ERR(&s->dev, "unbind MSI-X entry %d failed\n", - entry->pirq); + XEN_PT_ERR(&s->dev, "unbind MSI-X entry %d failed (err: %d)\n", + entry->pirq, errno); } entry->updated = true; } |