|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |