From: Suravee Suthikulanit <suravee.suthikulpanit@amd.com>
To: Tim Deegan <tim@xen.org>
Cc: Jan Beulich <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 18:13:37 -0500 [thread overview]
Message-ID: <51B65DA1.8030803@amd.com> (raw)
In-Reply-To: <20130610163145.GI8802@ocelot.phlegethon.org>
Hi All,
We should also check if the EventLogInt and PPRInt bits are set before actually
going into the log processing code. Also, I agree with Jan that we should not need
to disable the Event log and the PPR log in the IOMMU control register.
This could be handled simply through the status register.
Also, I think we can further simplify the logic for the workaround by having only
one loop instead of two. Here is the newly proposed changes for the patch. However,
I am still not sure if we should reschedule the tasklet instead of just using the
while loop here.
Thank you,
Suravee
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index b5a39a9..bd9913f 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -615,19 +615,8 @@ static void iommu_check_event_log(struct amd_iommu *iommu)
/*check event overflow */
entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-
- /* RW1C interrupt status bit */
- writel(IOMMU_STATUS_EVENT_LOG_INT_MASK,
- iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-
if ( iommu_get_bit(entry, IOMMU_STATUS_EVENT_OVERFLOW_SHIFT) )
iommu_reset_log(iommu, &iommu->event_log, set_iommu_event_log_control);
- else
- {
- entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
- iommu_set_bit(&entry, IOMMU_CONTROL_EVENT_LOG_INT_SHIFT);
- writel(entry, iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
- }
spin_unlock_irqrestore(&iommu->lock, flags);
}
@@ -689,26 +678,20 @@ static void iommu_check_ppr_log(struct amd_iommu *iommu)
/*check event overflow */
entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-
- /* RW1C interrupt status bit */
- writel(IOMMU_STATUS_PPR_LOG_INT_MASK,
- iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
-
if ( iommu_get_bit(entry, IOMMU_STATUS_PPR_LOG_OVERFLOW_SHIFT) )
iommu_reset_log(iommu, &iommu->ppr_log, set_iommu_ppr_log_control);
- else
- {
- entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
- iommu_set_bit(&entry, IOMMU_CONTROL_PPR_LOG_INT_SHIFT);
- writel(entry, iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
- }
spin_unlock_irqrestore(&iommu->lock, flags);
}
+#define IOMMU_INT_PENDING(x) ( (x & IOMMU_STATUS_EVENT_LOG_INT_MASK) || \
+ (x & IOMMU_STATUS_PPR_LOG_INT_MASK) )
+
static void do_amd_iommu_irq(unsigned long data)
{
struct amd_iommu *iommu;
+ u32 status, entry;
+ unsigned long flags;
if ( !iommu_found() )
{
@@ -722,33 +705,47 @@ static void do_amd_iommu_irq(unsigned long data)
* tasklet (instead of one per each IOMMUs).
*/
for_each_amd_iommu ( iommu ) {
- iommu_check_event_log(iommu);
+ /* Get the IOMMU status register */
+ spin_lock_irqsave(&iommu->lock, flags);
+ status = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ while ( IOMMU_INT_PENDING(status) )
+ {
+ entry = 0;
+
+ if ( status & IOMMU_STATUS_EVENT_LOG_INT_MASK )
+ {
+ iommu_check_event_log(iommu);
+ iommu_set_bit(&entry, IOMMU_STATUS_EVENT_LOG_INT_SHIFT);
+ }
- if ( iommu->ppr_log.buffer != NULL )
- iommu_check_ppr_log(iommu);
+ if ( (iommu->ppr_log.buffer != NULL)
+ && (status & IOMMU_STATUS_PPR_LOG_INT_MASK) )
+ {
+ iommu_check_ppr_log(iommu);
+ iommu_set_bit(&entry, IOMMU_STATUS_PPR_LOG_INT_SHIFT);
+ }
+
+ spin_lock_irqsave(&iommu->lock, flags);
+
+ /* RW1C interrupt status bit */
+ writel(entry, iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
+
+ /*
+ * Workaround for erratum787:
+ * Re-check to make sure the bit has been cleared.
+ */
+ status = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET);
+
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ }
}
}
static void iommu_interrupt_handler(int irq, void *dev_id,
struct cpu_user_regs *regs)
{
- u32 entry;
- unsigned long flags;
- struct amd_iommu *iommu = dev_id;
-
- spin_lock_irqsave(&iommu->lock, flags);
-
- /*
- * Silence interrupts from both event and PPR by clearing the
- * enable logging bits in the control register
- */
- entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
- iommu_clear_bit(&entry, IOMMU_CONTROL_EVENT_LOG_INT_SHIFT);
- iommu_clear_bit(&entry, IOMMU_CONTROL_PPR_LOG_INT_SHIFT);
- writel(entry, iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
-
- spin_unlock_irqrestore(&iommu->lock, flags);
-
/* It is the tasklet that will clear the logs and re-enable interrupts */
tasklet_schedule(&amd_iommu_irq_tasklet);
}
next prev parent reply other threads:[~2013-06-10 23:13 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
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 [this message]
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=51B65DA1.8030803@amd.com \
--to=suravee.suthikulpanit@amd.com \
--cc=JBeulich@suse.com \
--cc=tim@xen.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).