> From: Jan Beulich <jbeul...@suse.com>
> Sent: Wednesday, June 9, 2021 5:29 PM
> 
> If there is any way for one fault to be left set in the recording
> registers, there's no reason there couldn't also be multiple ones. If
> PPF set set (being the OR or all F fields), simply loop over the entire
> range of fault recording registers, clearing F everywhere.
> 
> Since PPF is a r/o bit, also remove it from DMA_FSTS_FAULTS (arguably
> the constant's name is ambiguous as well).
> 
> Signed-off-by: Jan Beulich <jbeul...@suse.com>

Reviewed-by: Kevin Tian <kevin.t...@intel.com>

> 
> --- a/xen/drivers/passthrough/vtd/iommu.c
> +++ b/xen/drivers/passthrough/vtd/iommu.c
> @@ -2094,13 +2094,23 @@ static int __hwdom_init setup_hwdom_devi
> 
>  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);
>  }
> 
> --- 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 */

Reply via email to