summaryrefslogtreecommitdiffstats
path: root/hw/audio/sb16.c
diff options
context:
space:
mode:
authorThomas Huth2018-03-16 10:51:31 +0100
committerPaolo Bonzini2018-03-26 14:37:13 +0200
commitc9073238fcb647644b329705ad54734ad1f0b1a3 (patch)
tree2fffdfbc57aeae407c4fce428ddbcf7ce3a15f16 /hw/audio/sb16.c
parentfdc: Exit if ISA controller does not support DMA (diff)
downloadqemu-c9073238fcb647644b329705ad54734ad1f0b1a3.tar.gz
qemu-c9073238fcb647644b329705ad54734ad1f0b1a3.tar.xz
qemu-c9073238fcb647644b329705ad54734ad1f0b1a3.zip
hw/audio: Fix crashes when devices are used on ISA bus without DMA
The cs4231a, gus and sb16 sound cards crash QEMU when the user tries to instantiate them on a machine with DMA-less ISA bus (for example with "qemu-system-mips64el -M mips -device sb16"). Add proper checks to the realize functions to avoid the crashes. Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <1521193892-15552-4-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/audio/sb16.c')
-rw-r--r--hw/audio/sb16.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 31de264ab7..5a4d32364e 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1371,6 +1371,13 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
SB16State *s = SB16 (dev);
IsaDmaClass *k;
+ s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
+ s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma);
+ if (!s->isa_dma || !s->isa_hdma) {
+ error_setg(errp, "ISA controller does not support DMA");
+ return;
+ }
+
isa_init_irq (isadev, &s->pic, s->irq);
s->mixer_regs[0x80] = magic_of_irq (s->irq);
@@ -1389,11 +1396,9 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
isa_register_portio_list(isadev, &s->portio_list, s->port,
sb16_ioport_list, s, "sb16");
- s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
k = ISADMA_GET_CLASS(s->isa_hdma);
k->register_channel(s->isa_hdma, s->hdma, SB_read_DMA, s);
- s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma);
k = ISADMA_GET_CLASS(s->isa_dma);
k->register_channel(s->isa_dma, s->dma, SB_read_DMA, s);