acpi_piix4: Disallow write to up/down PCI hotplug registers

The write side of these registers is never used and actually can't be
used as defined because any read/modify/write sequence from the guest
potentially races with qemu.  Drop the write support and define these
as read-only registers.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
master
Alex Williamson 2012-04-05 11:07:08 -06:00 committed by Michael S. Tsirkin
parent 2ba1d381c2
commit ba737541ed
2 changed files with 15 additions and 31 deletions

View File

@ -15,14 +15,14 @@ PCI slot injection notification pending (IO port 0xae00-0xae03, 4-byte access):
Slot injection notification pending. One bit per slot. Slot injection notification pending. One bit per slot.
Read by ACPI BIOS GPE.1 handler to notify OS of injection 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): PCI slot removal notification (IO port 0xae04-0xae07, 4-byte access):
----------------------------------------------------- -----------------------------------------------------
Slot removal notification pending. One bit per slot. Slot removal notification pending. One bit per slot.
Read by ACPI BIOS GPE.1 handler to notify OS of removal 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): PCI device eject (IO port 0xae08-0xae0b, 4-byte access):
---------------------------------------- ----------------------------------------

View File

@ -40,7 +40,8 @@
#define GPE_BASE 0xafe0 #define GPE_BASE 0xafe0
#define GPE_LEN 4 #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_EJ_BASE 0xae08
#define PCI_RMV_BASE 0xae0c #define PCI_RMV_BASE 0xae0c
@ -448,38 +449,22 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
PIIX4_DPRINTF("gpe write %x <== %d\n", addr, 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; PIIX4PMState *s = opaque;
struct pci_status *g = opaque; uint32_t val = s->pci0_status.up;
switch (addr) {
case PCI_BASE:
val = g->up;
break;
case PCI_BASE + 4:
val = g->down;
break;
default:
break;
}
PIIX4_DPRINTF("pcihotplug read %x == %x\n", addr, val); PIIX4_DPRINTF("pci_up_read %x\n", val);
return 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; PIIX4PMState *s = opaque;
switch (addr) { uint32_t val = s->pci0_status.down;
case PCI_BASE:
g->up = val;
break;
case PCI_BASE + 4:
g->down = val;
break;
}
PIIX4_DPRINTF("pcihotplug write %x <== %d\n", addr, val); PIIX4_DPRINTF("pci_down_read %x\n", val);
return val;
} }
static uint32_t pciej_read(void *opaque, uint32_t addr) static uint32_t pciej_read(void *opaque, uint32_t addr)
@ -523,14 +508,13 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) 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_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s); register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s);
acpi_gpe_blk(&s->ar, GPE_BASE); acpi_gpe_blk(&s->ar, GPE_BASE);
register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status); register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s);
register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status); 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_write(PCI_EJ_BASE, 4, 4, pciej_write, bus);
register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, bus); register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, bus);