Skip to content

Commit

Permalink
hw/audio: Fix crashes when devices are used on ISA bus without DMA
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
huth authored and bonzini committed Mar 26, 2018
1 parent b3da551 commit c907323
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 7 deletions.
8 changes: 7 additions & 1 deletion hw/audio/cs4231a.c
Expand Up @@ -28,6 +28,7 @@
#include "hw/isa/isa.h"
#include "hw/qdev.h"
#include "qemu/timer.h"
#include "qapi/error.h"

/*
Missing features:
Expand Down Expand Up @@ -663,8 +664,13 @@ static void cs4231a_realizefn (DeviceState *dev, Error **errp)
CSState *s = CS4231A (dev);
IsaDmaClass *k;

isa_init_irq (d, &s->pic, s->irq);
s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->dma);
if (!s->isa_dma) {
error_setg(errp, "ISA controller does not support DMA");
return;
}

isa_init_irq(d, &s->pic, s->irq);
k = ISADMA_GET_CLASS(s->isa_dma);
k->register_channel(s->isa_dma, s->dma, cs_dma_read, s);

Expand Down
7 changes: 6 additions & 1 deletion hw/audio/gus.c
Expand Up @@ -241,6 +241,12 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
IsaDmaClass *k;
struct audsettings as;

s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma);
if (!s->isa_dma) {
error_setg(errp, "ISA controller does not support DMA");
return;
}

AUD_register_card ("gus", &s->card);

as.freq = s->freq;
Expand Down Expand Up @@ -272,7 +278,6 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
isa_register_portio_list(d, &s->portio_list2, (s->port + 0x100) & 0xf00,
gus_portio_list2, s, "gus");

s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma);
k = ISADMA_GET_CLASS(s->isa_dma);
k->register_channel(s->isa_dma, s->emu.gusdma, GUS_read_DMA, s);
s->emu.himemaddr = s->himem;
Expand Down
9 changes: 7 additions & 2 deletions hw/audio/sb16.c
Expand Up @@ -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);
Expand All @@ -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);

Expand Down
3 changes: 0 additions & 3 deletions scripts/device-crash-test
Expand Up @@ -218,10 +218,7 @@ ERROR_WHITELIST = [
{'exitcode':-6, 'log':r"Object .* is not an instance of type e500-ccsr", 'loglevel':logging.ERROR},
{'exitcode':-6, 'log':r"vmstate_register_with_alias_id: Assertion `!se->compat \|\| se->instance_id == 0' failed", 'loglevel':logging.ERROR},
{'exitcode':-6, 'device':'isa-fdc', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'gus', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'isa-serial', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'sb16', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'cs4231a', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'machine':'isapc', 'device':'.*-iommu', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'mioe3680_pci', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'pcm3680_pci', 'loglevel':logging.ERROR, 'expected':True},
Expand Down

0 comments on commit c907323

Please sign in to comment.