On Mon, May 27, 2013 at 11:48:11AM +0800, Lingzhu Xiang wrote: > On 05/09/2013 06:26 AM, gregkh@xxxxxxxxxxxxxxxxxxx wrote: > > > >The patch below does not apply to the 3.9-stable tree. > >If someone wants it applied there, or to any other stable or longterm > >tree, then please email the backport, including the original git commit > >id to <stable@xxxxxxxxxxxxxxx>. > > > >thanks, > > > >greg k-h > > > >------------------ original commit in Linus's tree ------------------ > > > > From d3263bc29706e42f74d8800807c2dedf320d77f1 Mon Sep 17 00:00:00 2001 > >From: Joerg Roedel <joro@xxxxxxxxxx> > >Date: Thu, 18 Apr 2013 17:55:04 +0200 > >Subject: [PATCH] iommu/amd: Workaround for ERBT1312 > > > >Work around an IOMMU hardware bug where clearing the > >EVT_INT or PPR_INT bit in the status register may race with > >the hardware trying to set it again. When not handled the > >bit might not be cleared and we lose all future event or ppr > >interrupts. > > > >Reported-by: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> > >Cc: stable@xxxxxxxxxxxxxxx > >Signed-off-by: Joerg Roedel <joro@xxxxxxxxxx> > > > >diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c > >index f42793d..27792f8 100644 > >--- a/drivers/iommu/amd_iommu.c > >+++ b/drivers/iommu/amd_iommu.c > >@@ -700,14 +700,23 @@ retry: > > > > static void iommu_poll_events(struct amd_iommu *iommu) > > { > >- u32 head, tail; > >+ u32 head, tail, status; > > unsigned long flags; > > > >- /* enable event interrupts again */ > >- writel(MMIO_STATUS_EVT_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); > >- > > spin_lock_irqsave(&iommu->lock, flags); > > > >+ /* enable event interrupts again */ > >+ do { > >+ /* > >+ * Workaround for Erratum ERBT1312 > >+ * Clearing the EVT_INT bit may race in the hardware, so read > >+ * it again and make sure it was really cleared > >+ */ > >+ status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); > >+ writel(MMIO_STATUS_EVT_INT_MASK, > >+ iommu->mmio_base + MMIO_STATUS_OFFSET); > >+ } while (status & MMIO_STATUS_EVT_INT_MASK); > >+ > > head = readl(iommu->mmio_base + MMIO_EVT_HEAD_OFFSET); > > tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); > > > >@@ -744,16 +753,25 @@ static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw) > > static void iommu_poll_ppr_log(struct amd_iommu *iommu) > > { > > unsigned long flags; > >- u32 head, tail; > >+ u32 head, tail, status; > > > > if (iommu->ppr_log == NULL) > > return; > > > >- /* enable ppr interrupts again */ > >- writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); > >- > > spin_lock_irqsave(&iommu->lock, flags); > > > >+ /* enable ppr interrupts again */ > >+ do { > >+ /* > >+ * Workaround for Erratum ERBT1312 > >+ * Clearing the PPR_INT bit may race in the hardware, so read > >+ * it again and make sure it was really cleared > >+ */ > >+ status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); > >+ writel(MMIO_STATUS_PPR_INT_MASK, > >+ iommu->mmio_base + MMIO_STATUS_OFFSET); > >+ } while (status & MMIO_STATUS_PPR_INT_MASK); > >+ > > head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); > > tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); > > > > > >-- > > This patch can be applied cleanly after cherry picking > 925fe08bce38d1ff052fe2209b9e2b8d5fbb7f98. Thanks, I've now done that. greg k-h -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html