From fc4fd01b3315efa5b931f1489a297d2c1a97334b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 31 Jul 2019 19:05:39 +0200 Subject: [PATCH] 4.19-stable patches added patches: iommu-iova-fix-compilation-error-with-config_iommu_iova.patch iommu-vt-d-don-t-queue_iova-if-there-is-no-flush-queue.patch --- ...ilation-error-with-config_iommu_iova.patch | 32 +++ ...ueue_iova-if-there-is-no-flush-queue.patch | 186 ++++++++++++++++++ queue-4.19/series | 2 + 3 files changed, 220 insertions(+) create mode 100644 queue-4.19/iommu-iova-fix-compilation-error-with-config_iommu_iova.patch create mode 100644 queue-4.19/iommu-vt-d-don-t-queue_iova-if-there-is-no-flush-queue.patch diff --git a/queue-4.19/iommu-iova-fix-compilation-error-with-config_iommu_iova.patch b/queue-4.19/iommu-iova-fix-compilation-error-with-config_iommu_iova.patch new file mode 100644 index 00000000000..aa6939776e0 --- /dev/null +++ b/queue-4.19/iommu-iova-fix-compilation-error-with-config_iommu_iova.patch @@ -0,0 +1,32 @@ +From 201c1db90cd643282185a00770f12f95da330eca Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Tue, 23 Jul 2019 09:51:00 +0200 +Subject: iommu/iova: Fix compilation error with !CONFIG_IOMMU_IOVA + +From: Joerg Roedel + +commit 201c1db90cd643282185a00770f12f95da330eca upstream. + +The stub function for !CONFIG_IOMMU_IOVA needs to be +'static inline'. + +Fixes: effa467870c76 ('iommu/vt-d: Don't queue_iova() if there is no flush queue') +Signed-off-by: Joerg Roedel +Signed-off-by: Dmitry Safonov +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/iova.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/iova.h ++++ b/include/linux/iova.h +@@ -237,7 +237,7 @@ static inline void init_iova_domain(stru + { + } + +-bool has_iova_flush_queue(struct iova_domain *iovad) ++static inline bool has_iova_flush_queue(struct iova_domain *iovad) + { + return false; + } diff --git a/queue-4.19/iommu-vt-d-don-t-queue_iova-if-there-is-no-flush-queue.patch b/queue-4.19/iommu-vt-d-don-t-queue_iova-if-there-is-no-flush-queue.patch new file mode 100644 index 00000000000..95187bc83f5 --- /dev/null +++ b/queue-4.19/iommu-vt-d-don-t-queue_iova-if-there-is-no-flush-queue.patch @@ -0,0 +1,186 @@ +From effa467870c7612012885df4e246bdb8ffd8e44c Mon Sep 17 00:00:00 2001 +From: Dmitry Safonov +Date: Tue, 16 Jul 2019 22:38:05 +0100 +Subject: iommu/vt-d: Don't queue_iova() if there is no flush queue + +From: Dmitry Safonov + +commit effa467870c7612012885df4e246bdb8ffd8e44c upstream. + +Intel VT-d driver was reworked to use common deferred flushing +implementation. Previously there was one global per-cpu flush queue, +afterwards - one per domain. + +Before deferring a flush, the queue should be allocated and initialized. + +Currently only domains with IOMMU_DOMAIN_DMA type initialize their flush +queue. It's probably worth to init it for static or unmanaged domains +too, but it may be arguable - I'm leaving it to iommu folks. + +Prevent queuing an iova flush if the domain doesn't have a queue. +The defensive check seems to be worth to keep even if queue would be +initialized for all kinds of domains. And is easy backportable. + +On 4.19.43 stable kernel it has a user-visible effect: previously for +devices in si domain there were crashes, on sata devices: + + BUG: spinlock bad magic on CPU#6, swapper/0/1 + lock: 0xffff88844f582008, .magic: 00000000, .owner: /-1, .owner_cpu: 0 + CPU: 6 PID: 1 Comm: swapper/0 Not tainted 4.19.43 #1 + Call Trace: + + dump_stack+0x61/0x7e + spin_bug+0x9d/0xa3 + do_raw_spin_lock+0x22/0x8e + _raw_spin_lock_irqsave+0x32/0x3a + queue_iova+0x45/0x115 + intel_unmap+0x107/0x113 + intel_unmap_sg+0x6b/0x76 + __ata_qc_complete+0x7f/0x103 + ata_qc_complete+0x9b/0x26a + ata_qc_complete_multiple+0xd0/0xe3 + ahci_handle_port_interrupt+0x3ee/0x48a + ahci_handle_port_intr+0x73/0xa9 + ahci_single_level_irq_intr+0x40/0x60 + __handle_irq_event_percpu+0x7f/0x19a + handle_irq_event_percpu+0x32/0x72 + handle_irq_event+0x38/0x56 + handle_edge_irq+0x102/0x121 + handle_irq+0x147/0x15c + do_IRQ+0x66/0xf2 + common_interrupt+0xf/0xf + RIP: 0010:__do_softirq+0x8c/0x2df + +The same for usb devices that use ehci-pci: + BUG: spinlock bad magic on CPU#0, swapper/0/1 + lock: 0xffff88844f402008, .magic: 00000000, .owner: /-1, .owner_cpu: 0 + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.43 #4 + Call Trace: + + dump_stack+0x61/0x7e + spin_bug+0x9d/0xa3 + do_raw_spin_lock+0x22/0x8e + _raw_spin_lock_irqsave+0x32/0x3a + queue_iova+0x77/0x145 + intel_unmap+0x107/0x113 + intel_unmap_page+0xe/0x10 + usb_hcd_unmap_urb_setup_for_dma+0x53/0x9d + usb_hcd_unmap_urb_for_dma+0x17/0x100 + unmap_urb_for_dma+0x22/0x24 + __usb_hcd_giveback_urb+0x51/0xc3 + usb_giveback_urb_bh+0x97/0xde + tasklet_action_common.isra.4+0x5f/0xa1 + tasklet_action+0x2d/0x30 + __do_softirq+0x138/0x2df + irq_exit+0x7d/0x8b + smp_apic_timer_interrupt+0x10f/0x151 + apic_timer_interrupt+0xf/0x20 + + RIP: 0010:_raw_spin_unlock_irqrestore+0x17/0x39 + +Cc: David Woodhouse +Cc: Joerg Roedel +Cc: Lu Baolu +Cc: iommu@lists.linux-foundation.org +Cc: # 4.14+ +Fixes: 13cf01744608 ("iommu/vt-d: Make use of iova deferred flushing") +Signed-off-by: Dmitry Safonov +Reviewed-by: Lu Baolu +Signed-off-by: Joerg Roedel +[v4.14-port notes: +o minor conflict with untrusted IOMMU devices check under if-condition] +Signed-off-by: Dmitry Safonov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/intel-iommu.c | 2 +- + drivers/iommu/iova.c | 18 ++++++++++++++---- + include/linux/iova.h | 6 ++++++ + 3 files changed, 21 insertions(+), 5 deletions(-) + +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -3721,7 +3721,7 @@ static void intel_unmap(struct device *d + + freelist = domain_unmap(domain, start_pfn, last_pfn); + +- if (intel_iommu_strict) { ++ if (intel_iommu_strict || !has_iova_flush_queue(&domain->iovad)) { + iommu_flush_iotlb_psi(iommu, domain, start_pfn, + nrpages, !freelist, 0); + /* free iova */ +--- a/drivers/iommu/iova.c ++++ b/drivers/iommu/iova.c +@@ -65,9 +65,14 @@ init_iova_domain(struct iova_domain *iov + } + EXPORT_SYMBOL_GPL(init_iova_domain); + ++bool has_iova_flush_queue(struct iova_domain *iovad) ++{ ++ return !!iovad->fq; ++} ++ + static void free_iova_flush_queue(struct iova_domain *iovad) + { +- if (!iovad->fq) ++ if (!has_iova_flush_queue(iovad)) + return; + + if (timer_pending(&iovad->fq_timer)) +@@ -85,13 +90,14 @@ static void free_iova_flush_queue(struct + int init_iova_flush_queue(struct iova_domain *iovad, + iova_flush_cb flush_cb, iova_entry_dtor entry_dtor) + { ++ struct iova_fq __percpu *queue; + int cpu; + + atomic64_set(&iovad->fq_flush_start_cnt, 0); + atomic64_set(&iovad->fq_flush_finish_cnt, 0); + +- iovad->fq = alloc_percpu(struct iova_fq); +- if (!iovad->fq) ++ queue = alloc_percpu(struct iova_fq); ++ if (!queue) + return -ENOMEM; + + iovad->flush_cb = flush_cb; +@@ -100,13 +106,17 @@ int init_iova_flush_queue(struct iova_do + for_each_possible_cpu(cpu) { + struct iova_fq *fq; + +- fq = per_cpu_ptr(iovad->fq, cpu); ++ fq = per_cpu_ptr(queue, cpu); + fq->head = 0; + fq->tail = 0; + + spin_lock_init(&fq->lock); + } + ++ smp_wmb(); ++ ++ iovad->fq = queue; ++ + timer_setup(&iovad->fq_timer, fq_flush_timeout, 0); + atomic_set(&iovad->fq_timer_on, 0); + +--- a/include/linux/iova.h ++++ b/include/linux/iova.h +@@ -156,6 +156,7 @@ struct iova *reserve_iova(struct iova_do + void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); + void init_iova_domain(struct iova_domain *iovad, unsigned long granule, + unsigned long start_pfn); ++bool has_iova_flush_queue(struct iova_domain *iovad); + int init_iova_flush_queue(struct iova_domain *iovad, + iova_flush_cb flush_cb, iova_entry_dtor entry_dtor); + struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); +@@ -236,6 +237,11 @@ static inline void init_iova_domain(stru + { + } + ++bool has_iova_flush_queue(struct iova_domain *iovad) ++{ ++ return false; ++} ++ + static inline int init_iova_flush_queue(struct iova_domain *iovad, + iova_flush_cb flush_cb, + iova_entry_dtor entry_dtor) diff --git a/queue-4.19/series b/queue-4.19/series index 8ca42745346..e9b49af329b 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -14,3 +14,5 @@ media-cpia2_usb-first-wake-up-then-free-in-disconnect.patch media-pvrusb2-use-a-different-format-for-warnings.patch nfs-cleanup-if-nfs_match_client-is-interrupted.patch media-radio-raremono-change-devm_k-alloc-to-k-alloc.patch +iommu-vt-d-don-t-queue_iova-if-there-is-no-flush-queue.patch +iommu-iova-fix-compilation-error-with-config_iommu_iova.patch -- 2.47.3