Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp1960364pxj; Sun, 16 May 2021 09:32:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzjGaKsCMWUNIL2lySdc0K2OSiZT+D0UZW4ymbpi4bKyqfcBwqbkOkSur+kkFsvdU4YZQ1m X-Received: by 2002:a92:1a04:: with SMTP id a4mr8334121ila.38.1621182770455; Sun, 16 May 2021 09:32:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621182770; cv=none; d=google.com; s=arc-20160816; b=amw0xeHloMvwpHS1dkUgFIq/6tMxwByirLMVhXFJXzkrdgQaVj3fs5fgmvQDUstdn5 nPLSh9iHGS1pW+4XEeL1Ied2C/DlzKOj3wxGP29IBS51HQxeZ2BKAEUaZ0+HkNWsEnyz Sju6+5h6ITNHvGxUqfdPGcA0QucC7uvXpHa5BOLpmJv2DQV3DWI09hGqChJV7LhAlWId YkjFa2wAtmtJwRaf8ZPdVt0mn3g24z/wg7n6wCPFjH5EuXxeeQ7mgc5p0EMkUMvKSbF7 wazOzeuArJ0IYj6wlz1sIHT04Hr9/uQC2S0vfnVyXHxE63DT02+oBlqUi7lPTA3Ni7GU n1ZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:user-agent:references:in-reply-to :subject:cc:to:from:message-id:date; bh=lnHSK9INk4AloqJ4d9d7vNH7sCUhGTIHLePvTevqk6Y=; b=FUuB1Dix2hkKclPy0LMKHkh/I6hvQZQ4NLjD5XCG+sZamabJjSKBsLqJXAem4sLLZK u0UbLkvEPf9DNDmrvolk2fjO9Id6LAxgnsdKWUH7VCmnBLJOURhHROYEgK8RDXhs3hMQ hrU46q4lMkKioIo3qYtdLaRCyj2b0eLuwD37frDyK9tuFZgxyAp051KhQxlnVwFrHTQ/ REFh+yVwIMKWrM8HwTvHgAv1/9tlzrE54kTGXH/Gsom/Jsfh0j5Ff3hc6qbt6lJjrrD+ AjeGA/KdCHK3Yh1Gnyq+RBWfEwFjk5xHowzA1fSbsu3TVW1y20RXN8hIFdgpGa5YgNt5 RmzQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b9si14836103ior.14.2021.05.16.09.32.37; Sun, 16 May 2021 09:32:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232177AbhEPMIk (ORCPT + 99 others); Sun, 16 May 2021 08:08:40 -0400 Received: from mx2.suse.de ([195.135.220.15]:51810 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230185AbhEPMIj (ORCPT ); Sun, 16 May 2021 08:08:39 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 23CC0AF45; Sun, 16 May 2021 12:07:24 +0000 (UTC) Date: Sun, 16 May 2021 14:07:23 +0200 Message-ID: From: Takashi Iwai To: Sergey Senozhatsky Cc: Jaroslav Kysela , Takashi Iwai , "Gustavo A. R. Silva" , Leon Romanovsky , alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org Subject: Re: ALSA: intel8x0: div by zero in snd_intel8x0_update() In-Reply-To: References: User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.8 Emacs/25.3 (x86_64-suse-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, 16 May 2021 13:23:21 +0200, Sergey Senozhatsky wrote: > > On (21/05/16 11:49), Takashi Iwai wrote: > > Subject: [PATCH] ALSA: intel8x0: Don't update period unless prepared > > > > The interrupt handler of intel8x0 calls snd_intel8x0_update() whenever > > the hardware sets the corresponding status bit for each stream. This > > works fine for most cases as long as the hardware behaves properly. > > But when the hardware gives a wrong bit set, this leads to a NULL > > dereference Oops, and reportedly, this seems what happened on a VM. > > VM, yes. I didn't see NULL derefs, my VMs crash because of div by > zero in `% size`. Ah, right, I'll fix the description. > > For fixing the crash, this patch adds a internal flag indicating that > > the stream is ready to be updated, and check it (as well as the flag > > being in suspended) to ignore such spurious update. > > I reproduced the "spurious IRQ" case, and the patch handled it correctly > (VM did not crash). > > > Cc: > > Reported-by: Sergey Senozhatsky > > Signed-off-by: Takashi Iwai > > I'll keep running test, but seems that it works as intended > > Tested-by: Sergey Senozhatsky OK, below is the revised patch I'm going to apply. Thanks! Takashi -- 8< -- From: Takashi Iwai Subject: [PATCH v2] ALSA: intel8x0: Don't update period unless prepared The interrupt handler of intel8x0 calls snd_intel8x0_update() whenever the hardware sets the corresponding status bit for each stream. This works fine for most cases as long as the hardware behaves properly. But when the hardware gives a wrong bit set, this leads to a zero- division Oops, and reportedly, this seems what happened on a VM. For fixing the crash, this patch adds a internal flag indicating that the stream is ready to be updated, and check it (as well as the flag being in suspended) to ignore such spurious update. Cc: Reported-and-tested-by: Sergey Senozhatsky Signed-off-by: Takashi Iwai --- v1->v2: fixed description, updated tested-by tag sound/pci/intel8x0.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 35903d1a1cbd..5b124c4ad572 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -331,6 +331,7 @@ struct ichdev { unsigned int ali_slot; /* ALI DMA slot */ struct ac97_pcm *pcm; int pcm_open_flag; + unsigned int prepared:1; unsigned int suspended: 1; }; @@ -691,6 +692,9 @@ static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ich int status, civ, i, step; int ack = 0; + if (!ichdev->prepared || ichdev->suspended) + return; + spin_lock_irqsave(&chip->reg_lock, flags); status = igetbyte(chip, port + ichdev->roff_sr); civ = igetbyte(chip, port + ICH_REG_OFF_CIV); @@ -881,6 +885,7 @@ static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream, if (ichdev->pcm_open_flag) { snd_ac97_pcm_close(ichdev->pcm); ichdev->pcm_open_flag = 0; + ichdev->prepared = 0; } err = snd_ac97_pcm_open(ichdev->pcm, params_rate(hw_params), params_channels(hw_params), @@ -902,6 +907,7 @@ static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream) if (ichdev->pcm_open_flag) { snd_ac97_pcm_close(ichdev->pcm); ichdev->pcm_open_flag = 0; + ichdev->prepared = 0; } return 0; } @@ -976,6 +982,7 @@ static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream) ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; } snd_intel8x0_setup_periods(chip, ichdev); + ichdev->prepared = 1; return 0; } -- 2.26.2