Skip to content

Commit 9e68447

Browse files
committed
Merge tag 'iommu-fixes-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU fixes from Joerg Roedel: "Two patches are in here which fix AMD IOMMU specific issues. One patch fixes a long-standing warning on resume because the amd_iommu_resume function enabled interrupts. The other patch fixes a deadlock in an error-path of the page-fault request handling code of the IOMMU driver. * tag 'iommu-fixes-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/amd: Fix deadlock in ppr-handling error path iommu/amd: Cache pdev pointer to root-bridge
2 parents eea5b55 + eee5353 commit 9e68447

File tree

3 files changed

+52
-35
lines changed

3 files changed

+52
-35
lines changed

drivers/iommu/amd_iommu.c

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -547,26 +547,12 @@ static void iommu_poll_events(struct amd_iommu *iommu)
547547
spin_unlock_irqrestore(&iommu->lock, flags);
548548
}
549549

550-
static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u32 head)
550+
static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw)
551551
{
552552
struct amd_iommu_fault fault;
553-
volatile u64 *raw;
554-
int i;
555553

556554
INC_STATS_COUNTER(pri_requests);
557555

558-
raw = (u64 *)(iommu->ppr_log + head);
559-
560-
/*
561-
* Hardware bug: Interrupt may arrive before the entry is written to
562-
* memory. If this happens we need to wait for the entry to arrive.
563-
*/
564-
for (i = 0; i < LOOP_TIMEOUT; ++i) {
565-
if (PPR_REQ_TYPE(raw[0]) != 0)
566-
break;
567-
udelay(1);
568-
}
569-
570556
if (PPR_REQ_TYPE(raw[0]) != PPR_REQ_FAULT) {
571557
pr_err_ratelimited("AMD-Vi: Unknown PPR request received\n");
572558
return;
@@ -578,12 +564,6 @@ static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u32 head)
578564
fault.tag = PPR_TAG(raw[0]);
579565
fault.flags = PPR_FLAGS(raw[0]);
580566

581-
/*
582-
* To detect the hardware bug we need to clear the entry
583-
* to back to zero.
584-
*/
585-
raw[0] = raw[1] = 0;
586-
587567
atomic_notifier_call_chain(&ppr_notifier, 0, &fault);
588568
}
589569

@@ -595,25 +575,62 @@ static void iommu_poll_ppr_log(struct amd_iommu *iommu)
595575
if (iommu->ppr_log == NULL)
596576
return;
597577

578+
/* enable ppr interrupts again */
579+
writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET);
580+
598581
spin_lock_irqsave(&iommu->lock, flags);
599582

600583
head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
601584
tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
602585

603586
while (head != tail) {
587+
volatile u64 *raw;
588+
u64 entry[2];
589+
int i;
604590

605-
/* Handle PPR entry */
606-
iommu_handle_ppr_entry(iommu, head);
591+
raw = (u64 *)(iommu->ppr_log + head);
592+
593+
/*
594+
* Hardware bug: Interrupt may arrive before the entry is
595+
* written to memory. If this happens we need to wait for the
596+
* entry to arrive.
597+
*/
598+
for (i = 0; i < LOOP_TIMEOUT; ++i) {
599+
if (PPR_REQ_TYPE(raw[0]) != 0)
600+
break;
601+
udelay(1);
602+
}
603+
604+
/* Avoid memcpy function-call overhead */
605+
entry[0] = raw[0];
606+
entry[1] = raw[1];
607607

608-
/* Update and refresh ring-buffer state*/
608+
/*
609+
* To detect the hardware bug we need to clear the entry
610+
* back to zero.
611+
*/
612+
raw[0] = raw[1] = 0UL;
613+
614+
/* Update head pointer of hardware ring-buffer */
609615
head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE;
610616
writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
617+
618+
/*
619+
* Release iommu->lock because ppr-handling might need to
620+
* re-aquire it
621+
*/
622+
spin_unlock_irqrestore(&iommu->lock, flags);
623+
624+
/* Handle PPR entry */
625+
iommu_handle_ppr_entry(iommu, entry);
626+
627+
spin_lock_irqsave(&iommu->lock, flags);
628+
629+
/* Refresh ring-buffer information */
630+
head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
611631
tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
612632
}
613633

614-
/* enable ppr interrupts again */
615-
writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET);
616-
617634
spin_unlock_irqrestore(&iommu->lock, flags);
618635
}
619636

drivers/iommu/amd_iommu_init.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
10291029
if (!iommu->dev)
10301030
return 1;
10311031

1032+
iommu->root_pdev = pci_get_bus_and_slot(iommu->dev->bus->number,
1033+
PCI_DEVFN(0, 0));
1034+
10321035
iommu->cap_ptr = h->cap_ptr;
10331036
iommu->pci_seg = h->pci_seg;
10341037
iommu->mmio_phys = h->mmio_phys;
@@ -1323,20 +1326,16 @@ static void iommu_apply_resume_quirks(struct amd_iommu *iommu)
13231326
{
13241327
int i, j;
13251328
u32 ioc_feature_control;
1326-
struct pci_dev *pdev = NULL;
1329+
struct pci_dev *pdev = iommu->root_pdev;
13271330

13281331
/* RD890 BIOSes may not have completely reconfigured the iommu */
1329-
if (!is_rd890_iommu(iommu->dev))
1332+
if (!is_rd890_iommu(iommu->dev) || !pdev)
13301333
return;
13311334

13321335
/*
13331336
* First, we need to ensure that the iommu is enabled. This is
13341337
* controlled by a register in the northbridge
13351338
*/
1336-
pdev = pci_get_bus_and_slot(iommu->dev->bus->number, PCI_DEVFN(0, 0));
1337-
1338-
if (!pdev)
1339-
return;
13401339

13411340
/* Select Northbridge indirect register 0x75 and enable writing */
13421341
pci_write_config_dword(pdev, 0x60, 0x75 | (1 << 7));
@@ -1346,8 +1345,6 @@ static void iommu_apply_resume_quirks(struct amd_iommu *iommu)
13461345
if (!(ioc_feature_control & 0x1))
13471346
pci_write_config_dword(pdev, 0x64, ioc_feature_control | 1);
13481347

1349-
pci_dev_put(pdev);
1350-
13511348
/* Restore the iommu BAR */
13521349
pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4,
13531350
iommu->stored_addr_lo);

drivers/iommu/amd_iommu_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,9 @@ struct amd_iommu {
481481
/* Pointer to PCI device of this IOMMU */
482482
struct pci_dev *dev;
483483

484+
/* Cache pdev to root device for resume quirks */
485+
struct pci_dev *root_pdev;
486+
484487
/* physical address of MMIO space */
485488
u64 mmio_phys;
486489
/* virtual address of MMIO space */

0 commit comments

Comments
 (0)