From: Tim Deegan <tim@xen.org>
To: suravee.suthikulpanit@amd.com
Cc: JBeulich@suse.com, xen-devel@lists.xen.org
Subject: Re: [PATCH 2/2 V2] iommu/amd: Workaround for erratum 787
Date: Mon, 10 Jun 2013 10:35:32 +0100 [thread overview]
Message-ID: <20130610093532.GA8802@ocelot.phlegethon.org> (raw)
In-Reply-To: <1370840751-11277-2-git-send-email-suravee.suthikulpanit@amd.com>
At 00:05 -0500 on 10 Jun (1370822751), suravee.suthikulpanit@amd.com wrote:
> From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
>
> The IOMMU interrupt handling in bottom half must clear the PPR log interrupt
> and event log interrupt bits to re-enable the interrupt. This is done by
> writing 1 to the memory mapped register to clear the bit. Due to hardware bug,
> if the driver tries to clear this bit while the IOMMU hardware also setting
> this bit, the conflict will result with the bit being set. If the interrupt
> handling code does not make sure to clear this bit, subsequent changes in the
> event/PPR logs will no longer generating interrupts, and would result if
> buffer overflow. After clearing the bits, the driver must read back
> the register to verify.
Is there a risk of livelock here? That is, if some device is causing a
lot of IOMMU faults, a CPU could get stuck in this loop re-enabling
interrupts as fast as they are raised.
The solution suggested in the erratum seems better: if the bit is set
after clearing, process the interrupts again (i.e. run/schedule the
top-half handler). That way the bottom-half handler will definitely
terminate and the system can make some progress.
Cheers,
Tim.
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> ---
> V2 changes:
> - Coding style fixes
>
> xen/drivers/passthrough/amd/iommu_init.c | 36 ++++++++++++++++++++----------
> 1 file changed, 24 insertions(+), 12 deletions(-)
>
> diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
> index a85c63f..048a2e6 100644
> --- a/xen/drivers/passthrough/amd/iommu_init.c
> +++ b/xen/drivers/passthrough/amd/iommu_init.c
> @@ -616,15 +616,21 @@ static void iommu_check_event_log(struct amd_iommu *iommu)
>
> spin_lock_irqsave(&iommu->lock, flags);
>
> - /*check event overflow */
> entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
> + while (entry & (1 << IOMMU_STATUS_EVENT_LOG_INT_SHIFT))
> + {
> + /* Check event overflow */
> + if ( iommu_get_bit(entry, IOMMU_STATUS_EVENT_OVERFLOW_SHIFT) )
> + iommu_reset_log(iommu, &iommu->event_log, set_iommu_event_log_control);
>
> - if ( iommu_get_bit(entry, IOMMU_STATUS_EVENT_OVERFLOW_SHIFT) )
> - iommu_reset_log(iommu, &iommu->event_log, set_iommu_event_log_control);
> + /* RW1C interrupt status bit */
> + writel((1 << IOMMU_STATUS_EVENT_LOG_INT_SHIFT),
> + iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
>
> - /* RW1C interrupt status bit */
> - writel((1 << IOMMU_STATUS_EVENT_LOG_INT_SHIFT),
> - iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
> + /* Workaround for erratum787:
> + * Re-check to make sure the bit has been cleared */
> + entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
> + }
>
> spin_unlock_irqrestore(&iommu->lock, flags);
> }
> @@ -684,15 +690,21 @@ static void iommu_check_ppr_log(struct amd_iommu *iommu)
>
> spin_lock_irqsave(&iommu->lock, flags);
>
> - /*check event overflow */
> entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
> + while ( entry & (1 << IOMMU_STATUS_PPR_LOG_INT_SHIFT ) )
> + {
> + /* Check event overflow */
> + if ( iommu_get_bit(entry, IOMMU_STATUS_PPR_LOG_OVERFLOW_SHIFT) )
> + iommu_reset_log(iommu, &iommu->ppr_log, set_iommu_ppr_log_control);
>
> - if ( iommu_get_bit(entry, IOMMU_STATUS_PPR_LOG_OVERFLOW_SHIFT) )
> - iommu_reset_log(iommu, &iommu->ppr_log, set_iommu_ppr_log_control);
> + /* RW1C interrupt status bit */
> + writel((1 << IOMMU_STATUS_PPR_LOG_INT_SHIFT),
> + iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
>
> - /* RW1C interrupt status bit */
> - writel((1 << IOMMU_STATUS_PPR_LOG_INT_SHIFT),
> - iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
> + /* Workaround for erratum787:
> + * Re-check to make sure the bit has been cleared */
> + entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
> + }
>
> spin_unlock_irqrestore(&iommu->lock, flags);
> }
> --
> 1.7.10.4
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2013-06-10 9:35 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-10 5:05 [PATCH 1/2 V2] iommu/amd: Fix logic for clearing the IOMMU interrupt bits suravee.suthikulpanit
2013-06-10 5:05 ` [PATCH 2/2 V2] iommu/amd: Workaround for erratum 787 suravee.suthikulpanit
2013-06-10 9:35 ` Tim Deegan [this message]
2013-06-10 9:47 ` Jan Beulich
2013-06-10 10:40 ` Tim Deegan
2013-06-10 10:53 ` Jan Beulich
2013-06-10 12:43 ` Tim Deegan
2013-06-10 13:23 ` Jan Beulich
2013-06-10 13:41 ` Jan Beulich
2013-06-10 13:56 ` Tim Deegan
2013-06-10 13:55 ` Jan Beulich
2013-06-10 15:03 ` Jan Beulich
2013-06-10 16:31 ` Tim Deegan
2013-06-10 23:13 ` Suravee Suthikulanit
2013-06-11 6:45 ` Jan Beulich
2013-06-11 6:40 ` Jan Beulich
2013-06-11 8:53 ` Tim Deegan
2013-06-10 13:53 ` Suravee Suthikulanit
2013-06-10 13:59 ` Jan Beulich
2013-06-10 15:11 ` Suravee Suthikulanit
2013-06-10 15:21 ` Jan Beulich
2013-06-10 10:59 ` [PATCH 2/2 v3] " Jan Beulich
2013-06-11 6:47 ` [PATCH 2/2 v5] " Jan Beulich
2013-06-17 18:57 ` Suravee Suthikulanit
2013-06-10 10:05 ` [PATCH 1/2 V2] iommu/amd: Fix logic for clearing the IOMMU interrupt bits Jan Beulich
2013-06-10 10:56 ` [PATCH 1/2 v3] " Jan Beulich
2013-06-10 11:02 ` Jan Beulich
2013-06-10 12:18 ` Tim Deegan
2013-06-10 12:31 ` Jan Beulich
2013-06-10 13:58 ` Suravee Suthikulanit
2013-06-10 12:41 ` [PATCH 1/2 v4] " Jan Beulich
2013-06-10 12:46 ` Tim Deegan
2013-06-10 13:49 ` George Dunlap
2013-06-10 14:08 ` Jan Beulich
2013-06-11 6:47 ` [PATCH 1/2 v5] " Jan Beulich
2013-06-11 23:03 ` Suravee Suthikulanit
2013-06-12 6:24 ` Jan Beulich
2013-06-12 22:37 ` Suravee Suthikulpanit
2013-06-13 1:44 ` Suravee Suthikulpanit
2013-06-13 7:54 ` Jan Beulich
2013-06-13 13:48 ` Suravee Suthikulpanit
2013-06-13 14:20 ` George Dunlap
2013-06-13 14:30 ` Processed: " xen
2013-06-13 15:58 ` Jan Beulich
2013-06-13 16:34 ` Suravee Suthikulanit
2013-06-14 6:27 ` Jan Beulich
2013-06-14 6:40 ` Jan Beulich
2013-06-14 7:14 ` [PATCH] AMD IOMMU: make interrupt work again Jan Beulich
2013-06-14 16:10 ` Suravee Suthikulanit
2013-06-17 18:59 ` [PATCH 1/2 v5] iommu/amd: Fix logic for clearing the IOMMU interrupt bits Suravee Suthikulanit
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=20130610093532.GA8802@ocelot.phlegethon.org \
--to=tim@xen.org \
--cc=JBeulich@suse.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=xen-devel@lists.xen.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.