| From foo@baz Tue Oct 16 12:18:53 CEST 2018 |
| From: Yu Zhao <yuzhao@google.com> |
| Date: Tue, 11 Sep 2018 15:14:04 -0600 |
| Subject: sound: enable interrupt after dma buffer initialization |
| |
| From: Yu Zhao <yuzhao@google.com> |
| |
| [ Upstream commit b61749a89f826eb61fc59794d9e4697bd246eb61 ] |
| |
| In snd_hdac_bus_init_chip(), we enable interrupt before |
| snd_hdac_bus_init_cmd_io() initializing dma buffers. If irq has |
| been acquired and irq handler uses the dma buffer, kernel may crash |
| when interrupt comes in. |
| |
| Fix the problem by postponing enabling irq after dma buffer |
| initialization. And warn once on null dma buffer pointer during the |
| initialization. |
| |
| Reviewed-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Yu Zhao <yuzhao@google.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| sound/hda/hdac_controller.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| --- a/sound/hda/hdac_controller.c |
| +++ b/sound/hda/hdac_controller.c |
| @@ -40,6 +40,8 @@ static void azx_clear_corbrp(struct hdac |
| */ |
| void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) |
| { |
| + WARN_ON_ONCE(!bus->rb.area); |
| + |
| spin_lock_irq(&bus->reg_lock); |
| /* CORB set up */ |
| bus->corb.addr = bus->rb.addr; |
| @@ -478,13 +480,15 @@ bool snd_hdac_bus_init_chip(struct hdac_ |
| /* reset controller */ |
| azx_reset(bus, full_reset); |
| |
| - /* initialize interrupts */ |
| + /* clear interrupts */ |
| azx_int_clear(bus); |
| - azx_int_enable(bus); |
| |
| /* initialize the codec command I/O */ |
| snd_hdac_bus_init_cmd_io(bus); |
| |
| + /* enable interrupts after CORB/RIRB buffers are initialized above */ |
| + azx_int_enable(bus); |
| + |
| /* program the position buffer */ |
| if (bus->use_posbuf && bus->posbuf.addr) { |
| snd_hdac_chip_writel(bus, DPLBASE, (u32)bus->posbuf.addr); |