Skip to content

Commit

Permalink
ahci.c: Don't assume AHCIState's parent is AHCIPCIState
Browse files Browse the repository at this point in the history
The AHCIState struct can either have AHCIPCIState or SysbusAHCIState
as a parent. The ahci_irq_lower() and ahci_irq_raise() functions
assume that it is always AHCIPCIState, which is not always the
case, which causes a seg fault. Verify what the container of AHCIState
is before setting the PCIDevice struct.

Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Acked-by: John Snow <jsnow@redhat.com>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
alistair23 authored and pm215 committed Sep 8, 2015
1 parent 5ea8b9c commit bb639f8
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 6 deletions.
13 changes: 7 additions & 6 deletions hw/ide/ahci.c
Expand Up @@ -121,9 +121,9 @@ static uint32_t ahci_port_read(AHCIState *s, int port, int offset)

static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
{
AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);
PCIDevice *pci_dev =
(PCIDevice *)object_dynamic_cast(OBJECT(d), TYPE_PCI_DEVICE);
DeviceState *dev_state = s->container;
PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
TYPE_PCI_DEVICE);

DPRINTF(0, "raise irq\n");

Expand All @@ -136,9 +136,9 @@ static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)

static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
{
AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);
PCIDevice *pci_dev =
(PCIDevice *)object_dynamic_cast(OBJECT(d), TYPE_PCI_DEVICE);
DeviceState *dev_state = s->container;
PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
TYPE_PCI_DEVICE);

DPRINTF(0, "lower irq\n");

Expand Down Expand Up @@ -1436,6 +1436,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
s->as = as;
s->ports = ports;
s->dev = g_new0(AHCIDevice, ports);
s->container = qdev;
ahci_reg_init(s);
/* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s,
Expand Down
2 changes: 2 additions & 0 deletions hw/ide/ahci.h
Expand Up @@ -287,6 +287,8 @@ struct AHCIDevice {
};

typedef struct AHCIState {
DeviceState *container;

AHCIDevice *dev;
AHCIControlRegs control_regs;
MemoryRegion mem;
Expand Down

0 comments on commit bb639f8

Please sign in to comment.