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>
This commit is contained in:
parent
b3da551389
commit
c9073238fc
@ -28,6 +28,7 @@
|
||||
#include "hw/isa/isa.h"
|
||||
#include "hw/qdev.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
/*
|
||||
Missing features:
|
||||
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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},
|
||||
|
Loading…
Reference in New Issue
Block a user