diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 0342daaa3c..f3524a1def 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -2094,13 +2094,23 @@ static int __hwdom_init setup_hwdom_device(u8 devfn, struct pci_dev *pdev) void clear_fault_bits(struct vtd_iommu *iommu) { - u64 val; unsigned long flags; spin_lock_irqsave(&iommu->register_lock, flags); - val = dmar_readq(iommu->reg, cap_fault_reg_offset(iommu->cap) + 8); - dmar_writeq(iommu->reg, cap_fault_reg_offset(iommu->cap) + 8, val); + + if ( dmar_readl(iommu->reg, DMAR_FSTS_REG) & DMA_FSTS_PPF ) + { + unsigned int reg = cap_fault_reg_offset(iommu->cap); + unsigned int end = reg + cap_num_fault_regs(iommu->cap); + + do { + dmar_writel(iommu->reg, reg + 12, DMA_FRCD_F); + reg += PRIMARY_FAULT_REG_LEN; + } while ( reg < end ); + } + dmar_writel(iommu->reg, DMAR_FSTS_REG, DMA_FSTS_FAULTS); + spin_unlock_irqrestore(&iommu->register_lock, flags); } diff --git a/xen/drivers/passthrough/vtd/iommu.h b/xen/drivers/passthrough/vtd/iommu.h index cd516ac5f8..02390cb84b 100644 --- a/xen/drivers/passthrough/vtd/iommu.h +++ b/xen/drivers/passthrough/vtd/iommu.h @@ -174,9 +174,8 @@ #define DMA_FSTS_IQE (1u << 4) #define DMA_FSTS_ICE (1u << 5) #define DMA_FSTS_ITE (1u << 6) -#define DMA_FSTS_FAULTS (DMA_FSTS_PFO | DMA_FSTS_PPF | DMA_FSTS_AFO | \ - DMA_FSTS_APF | DMA_FSTS_IQE | DMA_FSTS_ICE | \ - DMA_FSTS_ITE) +#define DMA_FSTS_FAULTS (DMA_FSTS_PFO | DMA_FSTS_AFO | DMA_FSTS_APF | \ + DMA_FSTS_IQE | DMA_FSTS_ICE | DMA_FSTS_ITE) #define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff) /* FRCD_REG, 32 bits access */