[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCHv2 1 of 2] Move IOMMU faults handling into softirq for VT-d.



On 05/01/2012 15:25, "Dario Faggioli" <raistlin@xxxxxxxx> wrote:

> Dealing with interrupts from VT-d IOMMU(s) is deferred to a softirq-tasklet,
> raised by the actual IRQ handler. Since a new interrupt is not generated,
> even if further faults occur, until we cleared all the pending ones,
> there's no need of disabling IRQs, as the hardware does it by its own.
> Notice that this may cause the log to overflow, but none of the existing
> entry will be overwritten.
> 
> Signed-off-by: Dario Faggioli <dario.faggioli@xxxxxxxxxx>

Applied, thanks.

 -- Keir

> diff -r efaa28639a71 xen/drivers/passthrough/vtd/iommu.c
> --- a/xen/drivers/passthrough/vtd/iommu.c Wed Jan 04 16:12:44 2012 +0000
> +++ b/xen/drivers/passthrough/vtd/iommu.c Thu Jan 05 15:17:47 2012 +0100
> @@ -53,6 +53,8 @@ bool_t __read_mostly untrusted_msi;
>  
>  int nr_iommus;
>  
> +static struct tasklet vtd_fault_tasklet;
> +
>  static void setup_dom0_device(struct pci_dev *);
>  static void setup_dom0_rmrr(struct domain *d);
>  
> @@ -918,10 +920,8 @@ static void iommu_fault_status(u32 fault
>  }
>  
>  #define PRIMARY_FAULT_REG_LEN (16)
> -static void iommu_page_fault(int irq, void *dev_id,
> -                             struct cpu_user_regs *regs)
> +static void __do_iommu_page_fault(struct iommu *iommu)
>  {
> -    struct iommu *iommu = dev_id;
>      int reg, fault_index;
>      u32 fault_status;
>      unsigned long flags;
> @@ -996,6 +996,37 @@ clear_overflow:
>      }
>  }
>  
> +static void do_iommu_page_fault(unsigned long data)
> +{
> +    struct acpi_drhd_unit *drhd;
> +
> +    if ( list_empty(&acpi_drhd_units) )
> +    {
> +       INTEL_IOMMU_DEBUG("no device found, something must be very wrong!\n");
> +       return;
> +    }
> +
> +    /*
> +     * No matter from whom the interrupt came from, check all the
> +     * IOMMUs present in the system. This allows for having just one
> +     * tasklet (instead of one per each IOMMUs) and should be more than
> +     * fine, considering how rare the event of a fault should be.
> +     */
> +    for_each_drhd_unit ( drhd )
> +        __do_iommu_page_fault(drhd->iommu);
> +}
> +
> +static void iommu_page_fault(int irq, void *dev_id,
> +                             struct cpu_user_regs *regs)
> +{
> +    /*
> +     * Just flag the tasklet as runnable. This is fine, according to VT-d
> +     * specs since a new interrupt won't be generated until we clear all
> +     * the faults that caused this one to happen.
> +     */
> +    tasklet_schedule(&vtd_fault_tasklet);
> +}
> +
>  static void dma_msi_unmask(struct irq_desc *desc)
>  {
>      struct iommu *iommu = desc->action->dev_id;
> @@ -2144,6 +2175,8 @@ int __init intel_vtd_setup(void)
>          iommu->irq = ret;
>      }
>  
> +    softirq_tasklet_init(&vtd_fault_tasklet, do_iommu_page_fault, 0);
> +
>      if ( !iommu_qinval && iommu_intremap )
>      {
>          iommu_intremap = 0;



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.