public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Vivek Goyal <vgoyal@redhat.com>
To: Neil Horman <nhorman@tuxdriver.com>
Cc: iommu@lists.linux-foundation.org, joerg.roedel@amd.com,
	hbabu@us.ibm.com, kexec@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	"Eric W. Biederman" <ebiederm@xmission.com>
Subject: Re: [PATCH] amd iommu: force flush of iommu prior during shutdown
Date: Wed, 31 Mar 2010 11:54:30 -0400	[thread overview]
Message-ID: <20100331155430.GF14011@redhat.com> (raw)
In-Reply-To: <20100331152417.GB13406@hmsreliant.think-freely.org>

On Wed, Mar 31, 2010 at 11:24:17AM -0400, Neil Horman wrote:
> Flush iommu during shutdown
> 
> When using an iommu, its possible, if a kdump kernel boot follows a primary
> kernel crash, that dma operations might still be in flight from the previous
> kernel during the kdump kernel boot.  This can lead to memory corruption,
> crashes, and other erroneous behavior, specifically I've seen it manifest during
> a kdump boot as endless iommu error log entries of the form:
> AMD-Vi: Event logged [IO_PAGE_FAULT device=00:14.1 domain=0x000d
> address=0x000000000245a0c0 flags=0x0070]
> 
> Followed by an inability to access hard drives, and various other resources.
> 
> I've written this fix for it.  In short it just forces a flush of the in flight
> dma operations on shutdown, so that the new kernel is certain not to have any
> in-flight dmas trying to complete after we've reset all the iommu page tables,
> causing the above errors.  I've tested it and it fixes the problem for me quite
> well.

CCing Eric also.

Neil, this is interesting. In the past we noticed similar issues,
especially on PPC. But I was told that we could not clear the iommu
mapping entries as we had no control on in flight DMA and if a DMA comes
later after clearing an entry and entry is not present, it is an error.

Hence one of the suggestions was not to clear iommu mapping entries but
reserve some for kdump operation and use those in kdump kernel.

So this call amd_iommu_flush_all_devices() will be able to tell devices
that don't do any more DMAs and hence it is safe to reprogram iommu
mapping entries.

Thanks
Vivek
 
> 
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> 
> 
> amd_iommu_init.c |   25 ++++++++++++++++++++++---
> 1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
> index 9dc91b4..8fbdf58 100644
> --- a/arch/x86/kernel/amd_iommu_init.c
> +++ b/arch/x86/kernel/amd_iommu_init.c
> @@ -265,8 +265,26 @@ static void iommu_enable(struct amd_iommu *iommu)
>  	iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
>  }
>  
> -static void iommu_disable(struct amd_iommu *iommu)
> +static void iommu_disable(struct amd_iommu *iommu, bool flush)
>  {
> +
> +	/*
> +	 * This ensures that all in-flight dmas for this iommu
> +	 * are complete prior to shutting it down
> +	 * its a bit racy, but I think its ok, given that if we're flushing
> +	 * we're in a shutdown path (either a graceful shutdown or a
> +	 * crash leading to a kdump boot.  That means we're down to one
> +	 * cpu, and the other system hardware isn't going to issue
> +	 * subsequent dma operations.
> +	 * Also note that we gate the flusing on the flush boolean because
> +	 * the enable_iommus path uses this function and we can't flush any
> +	 * data in that path until later when the iommus are fully initialized
> +	 */
> +	if (flush) {
> +		amd_iommu_flush_all_devices();
> +		amd_iommu_flush_all_domains();
> +	}
> +
>  	/* Disable command buffer */
>  	iommu_feature_disable(iommu, CONTROL_CMDBUF_EN);
>  
> @@ -276,6 +294,7 @@ static void iommu_disable(struct amd_iommu *iommu)
>  
>  	/* Disable IOMMU hardware itself */
>  	iommu_feature_disable(iommu, CONTROL_IOMMU_EN);
> +
>  }
>  
>  /*
> @@ -1114,7 +1133,7 @@ static void enable_iommus(void)
>  	struct amd_iommu *iommu;
>  
>  	for_each_iommu(iommu) {
> -		iommu_disable(iommu);
> +		iommu_disable(iommu, false);
>  		iommu_set_device_table(iommu);
>  		iommu_enable_command_buffer(iommu);
>  		iommu_enable_event_buffer(iommu);
> @@ -1129,7 +1148,7 @@ static void disable_iommus(void)
>  	struct amd_iommu *iommu;
>  
>  	for_each_iommu(iommu)
> -		iommu_disable(iommu);
> +		iommu_disable(iommu, true);
>  }
>  
>  /*

  reply	other threads:[~2010-03-31 15:55 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-31 15:24 [PATCH] amd iommu: force flush of iommu prior during shutdown Neil Horman
2010-03-31 15:54 ` Vivek Goyal [this message]
2010-03-31 18:28   ` Neil Horman
2010-03-31 18:57     ` Eric W. Biederman
2010-03-31 19:18       ` Neil Horman
2010-03-31 19:51         ` Eric W. Biederman
2010-03-31 20:27           ` Neil Horman
2010-04-01  4:04             ` Eric W. Biederman
2010-04-01 12:49               ` Neil Horman
2010-04-01 14:29             ` Joerg Roedel
2010-04-01 14:47               ` Neil Horman
2010-04-01 15:56                 ` Joerg Roedel
2010-04-01 17:11                   ` Neil Horman
2010-04-01 20:14                     ` Joerg Roedel
2010-04-02  0:00                       ` Neil Horman
2010-04-02  0:30                         ` Chris Wright
2010-04-02  1:23                           ` [PATCH 1/2] x86/amd-iommu: enable iommu before attaching devices Chris Wright
2010-04-02  1:31                             ` [PATCH 2/2] x86/amd-iommu: warn when issuing command to uninitiailed cmd buffer Chris Wright
2010-04-02  1:35                             ` [PATCH 1/2] x86/amd-iommu: enable iommu before attaching devices Neil Horman
2010-04-02  1:38                               ` Chris Wright
2010-04-02  9:11                             ` Joerg Roedel
2010-04-02 23:59                               ` Chris Wright
2010-04-02 15:59                             ` Vivek Goyal
2010-04-02 22:38                               ` Chris Wright
2010-04-02 22:55                                 ` Eric W. Biederman
2010-04-02 23:57                                   ` Chris Wright
2010-04-03 17:38                               ` Joerg Roedel
2010-04-05 14:17                                 ` Vivek Goyal
2010-04-05 14:32                                   ` Joerg Roedel
2010-04-05 15:34                             ` Neil Horman
2010-03-31 18:43   ` [PATCH] amd iommu: force flush of iommu prior during shutdown Eric W. Biederman
2010-03-31 21:25 ` Chris Wright
2010-04-01  1:13   ` Neil Horman
2010-04-01  1:39     ` Chris Wright
2010-04-01  2:24     ` Vivek Goyal
2010-04-01 12:53       ` Neil Horman
2010-04-01 15:02         ` Vivek Goyal
2010-04-01 15:13           ` Neil Horman
2010-04-01  2:44   ` Vivek Goyal
2010-04-01  7:10     ` Chris Wright
2010-04-01 12:56       ` Neil Horman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100331155430.GF14011@redhat.com \
    --to=vgoyal@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=hbabu@us.ibm.com \
    --cc=iommu@lists.linux-foundation.org \
    --cc=joerg.roedel@amd.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nhorman@tuxdriver.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox