diff --git a/docs/specs/acpi_pci_hotplug.txt b/docs/specs/acpi_pci_hotplug.txt index f0f74a7c7c8d962d01a55b617825460e21f7e937..a839434f313d4320c0e94ba289f343b67797e9d2 100644 --- a/docs/specs/acpi_pci_hotplug.txt +++ b/docs/specs/acpi_pci_hotplug.txt @@ -15,23 +15,31 @@ PCI slot injection notification pending (IO port 0xae00-0xae03, 4-byte access): Slot injection notification pending. One bit per slot. Read by ACPI BIOS GPE.1 handler to notify OS of injection -events. +events. Read-only. PCI slot removal notification (IO port 0xae04-0xae07, 4-byte access): ----------------------------------------------------- Slot removal notification pending. One bit per slot. Read by ACPI BIOS GPE.1 handler to notify OS of removal -events. +events. Read-only. PCI device eject (IO port 0xae08-0xae0b, 4-byte access): ---------------------------------------- -Used by ACPI BIOS _EJ0 method to request device removal. One bit per slot. -Reads return 0. +Write: Used by ACPI BIOS _EJ0 method to request device removal. +One bit per slot. + +Read: Hotplug features register. Used by platform to identify features +available. Current base feature set (no bits set): + - Read-only "up" register @0xae00, 4-byte access, bit per slot + - Read-only "down" register @0xae04, 4-byte access, bit per slot + - Read/write "eject" register @0xae08, 4-byte access, + write: bit per slot eject, read: hotplug feature set + - Read-only hotplug capable register @0xae0c, 4-byte access, bit per slot PCI removability status (IO port 0xae0c-0xae0f, 4-byte access): ----------------------------------------------- Used by ACPI BIOS _RMV method to indicate removability status to OS. One -bit per slot. +bit per slot. Read-only diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 797ed245fcc768126b74a196846c0ead3a10f2b4..585da4e3eb937ee4583c40c72102da1a42dcc265 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -40,14 +40,15 @@ #define GPE_BASE 0xafe0 #define GPE_LEN 4 -#define PCI_BASE 0xae00 +#define PCI_UP_BASE 0xae00 +#define PCI_DOWN_BASE 0xae04 #define PCI_EJ_BASE 0xae08 #define PCI_RMV_BASE 0xae0c #define PIIX4_PCI_HOTPLUG_STATUS 2 struct pci_status { - uint32_t up; + uint32_t up; /* deprecated, maintained for migration compatibility */ uint32_t down; }; @@ -69,6 +70,7 @@ typedef struct PIIX4PMState { /* for pci hotplug */ struct pci_status pci0_status; uint32_t pci0_hotplug_enable; + uint32_t pci0_slot_device_present; } PIIX4PMState; static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s); @@ -204,6 +206,17 @@ static void pm_write_config(PCIDevice *d, pm_io_space_update((PIIX4PMState *)d); } +static void vmstate_pci_status_pre_save(void *opaque) +{ + struct pci_status *pci0_status = opaque; + PIIX4PMState *s = container_of(pci0_status, PIIX4PMState, pci0_status); + + /* We no longer track up, so build a safe value for migrating + * to a version that still does... of course these might get lost + * by an old buggy implementation, but we try. */ + pci0_status->up = s->pci0_slot_device_present & s->pci0_hotplug_enable; +} + static int vmstate_acpi_post_load(void *opaque, int version_id) { PIIX4PMState *s = opaque; @@ -240,6 +253,7 @@ static const VMStateDescription vmstate_pci_status = { .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, + .pre_save = vmstate_pci_status_pre_save, .fields = (VMStateField []) { VMSTATE_UINT32(up, struct pci_status), VMSTATE_UINT32(down, struct pci_status), @@ -268,13 +282,45 @@ static const VMStateDescription vmstate_acpi = { } }; +static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots) +{ + DeviceState *qdev, *next; + BusState *bus = qdev_get_parent_bus(&s->dev.qdev); + int slot = ffs(slots) - 1; + bool slot_free = true; + + /* Mark request as complete */ + s->pci0_status.down &= ~(1U << slot); + + QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) { + PCIDevice *dev = PCI_DEVICE(qdev); + PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); + if (PCI_SLOT(dev->devfn) == slot) { + if (pc->no_hotplug) { + slot_free = false; + } else { + qdev_free(qdev); + } + } + } + if (slot_free) { + s->pci0_slot_device_present &= ~(1U << slot); + } +} + static void piix4_update_hotplug(PIIX4PMState *s) { PCIDevice *dev = &s->dev; BusState *bus = qdev_get_parent_bus(&dev->qdev); DeviceState *qdev, *next; + /* Execute any pending removes during reset */ + while (s->pci0_status.down) { + acpi_piix_eject_slot(s, s->pci0_status.down); + } + s->pci0_hotplug_enable = ~0; + s->pci0_slot_device_present = 0; QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) { PCIDevice *pdev = PCI_DEVICE(qdev); @@ -282,8 +328,10 @@ static void piix4_update_hotplug(PIIX4PMState *s) int slot = PCI_SLOT(pdev->devfn); if (pc->no_hotplug) { - s->pci0_hotplug_enable &= ~(1 << slot); + s->pci0_hotplug_enable &= ~(1U << slot); } + + s->pci0_slot_device_present |= (1U << slot); } } @@ -448,60 +496,38 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val) PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val); } -static uint32_t pcihotplug_read(void *opaque, uint32_t addr) +static uint32_t pci_up_read(void *opaque, uint32_t addr) { - uint32_t val = 0; - struct pci_status *g = opaque; - switch (addr) { - case PCI_BASE: - val = g->up; - break; - case PCI_BASE + 4: - val = g->down; - break; - default: - break; - } + PIIX4PMState *s = opaque; + uint32_t val; - PIIX4_DPRINTF("pcihotplug read %x == %x\n", addr, val); + /* Manufacture an "up" value to cause a device check on any hotplug + * slot with a device. Extra device checks are harmless. */ + val = s->pci0_slot_device_present & s->pci0_hotplug_enable; + + PIIX4_DPRINTF("pci_up_read %x\n", val); return val; } -static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val) +static uint32_t pci_down_read(void *opaque, uint32_t addr) { - struct pci_status *g = opaque; - switch (addr) { - case PCI_BASE: - g->up = val; - break; - case PCI_BASE + 4: - g->down = val; - break; - } - - PIIX4_DPRINTF("pcihotplug write %x <== %d\n", addr, val); + PIIX4PMState *s = opaque; + uint32_t val = s->pci0_status.down; + + PIIX4_DPRINTF("pci_down_read %x\n", val); + return val; } -static uint32_t pciej_read(void *opaque, uint32_t addr) +static uint32_t pci_features_read(void *opaque, uint32_t addr) { - PIIX4_DPRINTF("pciej read %x\n", addr); + /* No feature defined yet */ + PIIX4_DPRINTF("pci_features_read %x\n", 0); return 0; } static void pciej_write(void *opaque, uint32_t addr, uint32_t val) { - BusState *bus = opaque; - DeviceState *qdev, *next; - int slot = ffs(val) - 1; - - QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) { - PCIDevice *dev = PCI_DEVICE(qdev); - PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); - if (PCI_SLOT(dev->devfn) == slot && !pc->no_hotplug) { - qdev_free(qdev); - } - } - + acpi_piix_eject_slot(opaque, val); PIIX4_DPRINTF("pciej write %x <== %d\n", addr, val); } @@ -513,29 +539,22 @@ static uint32_t pcirmv_read(void *opaque, uint32_t addr) return s->pci0_hotplug_enable; } -static void pcirmv_write(void *opaque, uint32_t addr, uint32_t val) -{ - return; -} - static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, PCIHotplugState state); static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) { - struct pci_status *pci0_status = &s->pci0_status; register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s); register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s); acpi_gpe_blk(&s->ar, GPE_BASE); - register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status); - register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status); + register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s); + register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s); - register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus); - register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, bus); + register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, s); + register_ioport_read(PCI_EJ_BASE, 4, 4, pci_features_read, s); - register_ioport_write(PCI_RMV_BASE, 4, 4, pcirmv_write, s); register_ioport_read(PCI_RMV_BASE, 4, 4, pcirmv_read, s); pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev); @@ -544,13 +563,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) static void enable_device(PIIX4PMState *s, int slot) { s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; - s->pci0_status.up |= (1 << slot); + s->pci0_slot_device_present |= (1U << slot); } static void disable_device(PIIX4PMState *s, int slot) { s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; - s->pci0_status.down |= (1 << slot); + s->pci0_status.down |= (1U << slot); } static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, @@ -564,11 +583,10 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, * it is present on boot, no hotplug event is necessary. We do send an * event when the device is disabled later. */ if (state == PCI_COLDPLUG_ENABLED) { + s->pci0_slot_device_present |= (1U << slot); return 0; } - s->pci0_status.up = 0; - s->pci0_status.down = 0; if (state == PCI_HOTPLUG_ENABLED) { enable_device(s, slot); } else { diff --git a/hw/ivshmem.c b/hw/ivshmem.c index df4f50a092f87858b3689277d9d82a9bf15bfea7..d48e5f99064e9b01ed0d445cf8e6b8d372aebd8c 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -509,11 +509,29 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) return; } +/* Select the MSI-X vectors used by device. + * ivshmem maps events to vectors statically, so + * we just enable all vectors on init and after reset. */ +static void ivshmem_use_msix(IVShmemState * s) +{ + int i; + + if (!msix_present(&s->dev)) { + return; + } + + for (i = 0; i < s->vectors; i++) { + msix_vector_use(&s->dev, i); + } +} + static void ivshmem_reset(DeviceState *d) { IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d); s->intrstatus = 0; + msix_reset(&s->dev); + ivshmem_use_msix(s); return; } @@ -544,12 +562,8 @@ static uint64_t ivshmem_get_size(IVShmemState * s) { return value; } -static void ivshmem_setup_msi(IVShmemState * s) { - - int i; - - /* allocate the MSI-X vectors */ - +static void ivshmem_setup_msi(IVShmemState * s) +{ memory_region_init(&s->msix_bar, "ivshmem-msix", 4096); if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) { pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, @@ -560,13 +574,10 @@ static void ivshmem_setup_msi(IVShmemState * s) { exit(1); } - /* 'activate' the vectors */ - for (i = 0; i < s->vectors; i++) { - msix_vector_use(&s->dev, i); - } - /* allocate QEMU char devices for receiving interrupts */ s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry)); + + ivshmem_use_msix(s); } static void ivshmem_save(QEMUFile* f, void *opaque) @@ -590,7 +601,7 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id) IVSHMEM_DPRINTF("ivshmem_load\n"); IVShmemState *proxy = opaque; - int ret, i; + int ret; if (version_id > 0) { return -EINVAL; @@ -608,9 +619,7 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id) if (ivshmem_has_feature(proxy, IVSHMEM_MSI)) { msix_load(&proxy->dev, f); - for (i = 0; i < proxy->vectors; i++) { - msix_vector_use(&proxy->dev, i); - } + ivshmem_use_msix(proxy); } else { proxy->intrstatus = qemu_get_be32(f); proxy->intrmask = qemu_get_be32(f); @@ -619,6 +628,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id) return 0; } +static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address, + uint32_t val, int len) +{ + pci_default_write_config(pci_dev, address, val, len); + msix_write_config(pci_dev, address, val, len); +} + static int pci_ivshmem_init(PCIDevice *dev) { IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); @@ -744,6 +760,8 @@ static int pci_ivshmem_init(PCIDevice *dev) } + s->dev.config_write = ivshmem_write_config; + return 0; } diff --git a/hw/pc_piix.c b/hw/pc_piix.c index fadca4c710cbe3f3bfc9bf204bb27cef905a96ad..5c08245fede26e615cb9277790cca0048e7c94b2 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -28,6 +28,7 @@ #include "pc.h" #include "apic.h" #include "pci.h" +#include "pci_ids.h" #include "net.h" #include "boards.h" #include "ide.h" @@ -359,50 +360,73 @@ static QEMUMachine pc_machine_v1_1 = { .is_default = 1, }; +#define PC_COMPAT_1_0 \ + {\ + .driver = "pc-sysfw",\ + .property = "rom_only",\ + .value = stringify(1),\ + }, {\ + .driver = "isa-fdc",\ + .property = "check_media_rate",\ + .value = "off",\ + }, {\ + .driver = "virtio-balloon-pci",\ + .property = "class",\ + .value = stringify(PCI_CLASS_MEMORY_RAM),\ + } + static QEMUMachine pc_machine_v1_0 = { .name = "pc-1.0", .desc = "Standard PC", .init = pc_init_pci, .max_cpus = 255, .compat_props = (GlobalProperty[]) { - { - .driver = "pc-sysfw", - .property = "rom_only", - .value = stringify(1), - }, { - .driver = "isa-fdc", - .property = "check_media_rate", - .value = "off", - }, + PC_COMPAT_1_0, { /* end of list */ } }, }; +#define PC_COMPAT_0_15 \ + PC_COMPAT_1_0 + static QEMUMachine pc_machine_v0_15 = { .name = "pc-0.15", .desc = "Standard PC", .init = pc_init_pci, .max_cpus = 255, .compat_props = (GlobalProperty[]) { - { - .driver = "pc-sysfw", - .property = "rom_only", - .value = stringify(1), - }, { - .driver = "isa-fdc", - .property = "check_media_rate", - .value = "off", - }, + PC_COMPAT_0_15, { /* end of list */ } }, }; +#define PC_COMPAT_0_14 \ + PC_COMPAT_0_15,\ + {\ + .driver = "virtio-blk-pci",\ + .property = "event_idx",\ + .value = "off",\ + },{\ + .driver = "virtio-serial-pci",\ + .property = "event_idx",\ + .value = "off",\ + },{\ + .driver = "virtio-net-pci",\ + .property = "event_idx",\ + .value = "off",\ + },{\ + .driver = "virtio-balloon-pci",\ + .property = "event_idx",\ + .value = "off",\ + } + static QEMUMachine pc_machine_v0_14 = { .name = "pc-0.14", .desc = "Standard PC", .init = pc_init_pci, .max_cpus = 255, .compat_props = (GlobalProperty[]) { + PC_COMPAT_0_14, { .driver = "qxl", .property = "revision", @@ -411,42 +435,30 @@ static QEMUMachine pc_machine_v0_14 = { .driver = "qxl-vga", .property = "revision", .value = stringify(2), - },{ - .driver = "virtio-blk-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-serial-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-net-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-balloon-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "isa-fdc", - .property = "check_media_rate", - .value = "off", - }, - { - .driver = "pc-sysfw", - .property = "rom_only", - .value = stringify(1), }, { /* end of list */ } }, }; +#define PC_COMPAT_0_13 \ + PC_COMPAT_0_14,\ + {\ + .driver = "PCI",\ + .property = "command_serr_enable",\ + .value = "off",\ + },{\ + .driver = "AC97",\ + .property = "use_broken_id",\ + .value = stringify(1),\ + } + static QEMUMachine pc_machine_v0_13 = { .name = "pc-0.13", .desc = "Standard PC", .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { + PC_COMPAT_0_13, { .driver = "virtio-9p-pci", .property = "vectors", @@ -459,59 +471,31 @@ static QEMUMachine pc_machine_v0_13 = { .driver = "vmware-svga", .property = "rombar", .value = stringify(0), - },{ - .driver = "PCI", - .property = "command_serr_enable", - .value = "off", - },{ - .driver = "virtio-blk-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-serial-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-net-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-balloon-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "AC97", - .property = "use_broken_id", - .value = stringify(1), - },{ - .driver = "isa-fdc", - .property = "check_media_rate", - .value = "off", - }, - { - .driver = "pc-sysfw", - .property = "rom_only", - .value = stringify(1), }, { /* end of list */ } }, }; +#define PC_COMPAT_0_12 \ + PC_COMPAT_0_13,\ + {\ + .driver = "virtio-serial-pci",\ + .property = "max_ports",\ + .value = stringify(1),\ + },{\ + .driver = "virtio-serial-pci",\ + .property = "vectors",\ + .value = stringify(0),\ + } + static QEMUMachine pc_machine_v0_12 = { .name = "pc-0.12", .desc = "Standard PC", .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { + PC_COMPAT_0_12, { - .driver = "virtio-serial-pci", - .property = "max_ports", - .value = stringify(1), - },{ - .driver = "virtio-serial-pci", - .property = "vectors", - .value = stringify(0), - },{ .driver = "VGA", .property = "rombar", .value = stringify(0), @@ -519,63 +503,27 @@ static QEMUMachine pc_machine_v0_12 = { .driver = "vmware-svga", .property = "rombar", .value = stringify(0), - },{ - .driver = "PCI", - .property = "command_serr_enable", - .value = "off", - },{ - .driver = "virtio-blk-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-serial-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-net-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-balloon-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "AC97", - .property = "use_broken_id", - .value = stringify(1), - },{ - .driver = "isa-fdc", - .property = "check_media_rate", - .value = "off", - }, - { - .driver = "pc-sysfw", - .property = "rom_only", - .value = stringify(1), }, { /* end of list */ } } }; +#define PC_COMPAT_0_11 \ + PC_COMPAT_0_12,\ + {\ + .driver = "virtio-blk-pci",\ + .property = "vectors",\ + .value = stringify(0),\ + } + static QEMUMachine pc_machine_v0_11 = { .name = "pc-0.11", .desc = "Standard PC, qemu 0.11", .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { + PC_COMPAT_0_11, { - .driver = "virtio-blk-pci", - .property = "vectors", - .value = stringify(0), - },{ - .driver = "virtio-serial-pci", - .property = "max_ports", - .value = stringify(1), - },{ - .driver = "virtio-serial-pci", - .property = "vectors", - .value = stringify(0), - },{ .driver = "ide-drive", .property = "ver", .value = "0.11", @@ -583,43 +531,6 @@ static QEMUMachine pc_machine_v0_11 = { .driver = "scsi-disk", .property = "ver", .value = "0.11", - },{ - .driver = "PCI", - .property = "rombar", - .value = stringify(0), - },{ - .driver = "PCI", - .property = "command_serr_enable", - .value = "off", - },{ - .driver = "virtio-blk-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-serial-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-net-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-balloon-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "AC97", - .property = "use_broken_id", - .value = stringify(1), - },{ - .driver = "isa-fdc", - .property = "check_media_rate", - .value = "off", - }, - { - .driver = "pc-sysfw", - .property = "rom_only", - .value = stringify(1), }, { /* end of list */ } } @@ -631,6 +542,7 @@ static QEMUMachine pc_machine_v0_10 = { .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { + PC_COMPAT_0_11, { .driver = "virtio-blk-pci", .property = "class", @@ -639,22 +551,10 @@ static QEMUMachine pc_machine_v0_10 = { .driver = "virtio-serial-pci", .property = "class", .value = stringify(PCI_CLASS_DISPLAY_OTHER), - },{ - .driver = "virtio-serial-pci", - .property = "max_ports", - .value = stringify(1), - },{ - .driver = "virtio-serial-pci", - .property = "vectors", - .value = stringify(0), },{ .driver = "virtio-net-pci", .property = "vectors", .value = stringify(0), - },{ - .driver = "virtio-blk-pci", - .property = "vectors", - .value = stringify(0), },{ .driver = "ide-drive", .property = "ver", @@ -663,43 +563,6 @@ static QEMUMachine pc_machine_v0_10 = { .driver = "scsi-disk", .property = "ver", .value = "0.10", - },{ - .driver = "PCI", - .property = "rombar", - .value = stringify(0), - },{ - .driver = "PCI", - .property = "command_serr_enable", - .value = "off", - },{ - .driver = "virtio-blk-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-serial-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-net-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "virtio-balloon-pci", - .property = "event_idx", - .value = "off", - },{ - .driver = "AC97", - .property = "use_broken_id", - .value = stringify(1), - },{ - .driver = "isa-fdc", - .property = "check_media_rate", - .value = "off", - }, - { - .driver = "pc-sysfw", - .property = "rom_only", - .value = stringify(1), }, { /* end of list */ } }, diff --git a/hw/pci_host.c b/hw/pci_host.c index 44c6c207a9fc1ebd23f3de795efe8fbec0bd38f5..804177891a6e36f801ed5a8d68e62a8b468fb534 100644 --- a/hw/pci_host.c +++ b/hw/pci_host.c @@ -101,6 +101,9 @@ static void pci_host_config_write(void *opaque, target_phys_addr_t addr, PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n", __func__, addr, len, val); + if (addr != 0 || len != 4) { + return; + } s->config_reg = val; } diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 179d9a6bb9edd9cdf7769b39cf6646c60983c8ac..09e84f59b6df93a28baa02b8f654112df41e8ac3 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -349,7 +349,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, isa_bus, pic, address_space_mem, address_space_io, ram_size, pci_hole_start, pci_hole_size, - pci_hole64_size, pci_hole64_size, + pci_hole64_start, pci_hole64_size, pci_memory, ram_memory); return b; } diff --git a/hw/vhost.c b/hw/vhost.c index 8d3ba5b608dc3041e81f999e9ef35e9ffd0c8a13..43664e7f4d8ac68b75b907ebce456ab2b817853f 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -31,11 +31,12 @@ static void vhost_dev_sync_region(struct vhost_dev *dev, vhost_log_chunk_t *to = dev->log + end / VHOST_LOG_CHUNK + 1; uint64_t addr = (start / VHOST_LOG_CHUNK) * VHOST_LOG_CHUNK; - assert(end / VHOST_LOG_CHUNK < dev->log_size); - assert(start / VHOST_LOG_CHUNK < dev->log_size); if (end < start) { return; } + assert(end / VHOST_LOG_CHUNK < dev->log_size); + assert(start / VHOST_LOG_CHUNK < dev->log_size); + for (;from < to; ++from) { vhost_log_chunk_t log; int bit; @@ -277,8 +278,9 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size) r = ioctl(dev->control, VHOST_SET_LOG_BASE, &log_base); assert(r >= 0); for (i = 0; i < dev->n_mem_sections; ++i) { - vhost_sync_dirty_bitmap(dev, &dev->mem_sections[i], - 0, (target_phys_addr_t)~0x0ull); + /* Sync only the range covered by the old log */ + vhost_sync_dirty_bitmap(dev, &dev->mem_sections[i], 0, + dev->log_size * VHOST_LOG_CHUNK - 1); } if (dev->log) { g_free(dev->log); diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index a0fb7c1b9ccf9734cd81bfb38c22a0e0dd9e8cad..4a4413d52c2bd0294974373f5e7b28a479c7d3e2 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -790,6 +790,11 @@ static int virtio_balloon_init_pci(PCIDevice *pci_dev) VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); VirtIODevice *vdev; + if (proxy->class_code != PCI_CLASS_OTHERS && + proxy->class_code != PCI_CLASS_MEMORY_RAM) { /* qemu < 1.1 */ + proxy->class_code = PCI_CLASS_OTHERS; + } + vdev = virtio_balloon_init(&pci_dev->qdev); if (!vdev) { return -1; @@ -906,6 +911,7 @@ static TypeInfo virtio_serial_info = { static Property virtio_balloon_properties[] = { DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), + DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), DEFINE_PROP_END_OF_LIST(), }; @@ -919,7 +925,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data) k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON; k->revision = VIRTIO_PCI_ABI_VERSION; - k->class_id = PCI_CLASS_MEMORY_RAM; + k->class_id = PCI_CLASS_OTHERS; dc->reset = virtio_pci_reset; dc->props = virtio_balloon_properties; }