Merge ~paelzer/ubuntu/+source/qemu:lp-1913395-s390x-vfio-dma-limit-GROOVY into ubuntu/+source/qemu:ubuntu/groovy-devel

Proposed by Christian Ehrhardt 
Status: Merged
Approved by: Christian Ehrhardt 
Approved revision: dadc43e834ec8b2f5a882a03602579eea639aa81
Merge reported by: Christian Ehrhardt 
Merged at revision: dadc43e834ec8b2f5a882a03602579eea639aa81
Proposed branch: ~paelzer/ubuntu/+source/qemu:lp-1913395-s390x-vfio-dma-limit-GROOVY
Merge into: ubuntu/+source/qemu:ubuntu/groovy-devel
Diff against target: 745 lines (+693/-0)
8 files modified
debian/changelog (+6/-0)
debian/patches/series (+6/-0)
debian/patches/ubuntu/lp-1913395-1-linux-headers-update-against-5.10-rc1.patch (+45/-0)
debian/patches/ubuntu/lp-1913395-2-vfio-Create-shared-routine-for-scanning-info-capabil.patch (+64/-0)
debian/patches/ubuntu/lp-1913395-3-vfio-Find-DMA-available-capability.patch (+75/-0)
debian/patches/ubuntu/lp-1913395-4-0004-s390x-pci-Add-routine-to-get-the-vfio-dma-available.patch (+120/-0)
debian/patches/ubuntu/lp-1913395-5-s390x-pci-Honor-DMA-limits-set-by-vfio.patch (+324/-0)
debian/patches/ubuntu/lp-1913395-6-s390x-fix-build-for-without-default-devices.patch (+53/-0)
Reviewer Review Type Date Requested Status
Robie Basak sru Approve
Canonical Server Pending
git-ubuntu developers Pending
Review via email: mp+397012@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :
Revision history for this message
Robie Basak (racb) :
review: Approve (sru)
Revision history for this message
Robie Basak (racb) wrote :

Approved groovy commit dadc43e834ec8b2f5a882a03602579eea639aa81 tree 67c74dde74430b942da94de0db97293ca6e2edcf

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Bugs 1903864 + 1913395 got combined and rebased onto the latest security upload.
Content is still the same.

Tagged and Uploaded

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Uploaded, setting state to "merged"

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index cb26d31..96557d5 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,9 @@
6+qemu (1:5.0-5ubuntu9.4) groovy; urgency=medium
7+
8+ * d/p/u/lp-1913395-*: qemu s390x/pci: Honor vfio DMA limiting (LP: #1913395)
9+
10+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Wed, 27 Jan 2021 14:38:21 +0100
11+
12 qemu (1:5.0-5ubuntu9.3) groovy; urgency=medium
13
14 * d/p/ubuntu/lp-1907656-s390x-s390-virtio-ccw-Reset-PCI-devices-during-subsy:
15diff --git a/debian/patches/series b/debian/patches/series
16index 3ddd537..869eb98 100644
17--- a/debian/patches/series
18+++ b/debian/patches/series
19@@ -99,3 +99,9 @@ ubuntu/CVE-2020-25723.patch
20 ubuntu/CVE-2020-27616.patch
21 ubuntu/CVE-2020-27617.patch
22 ubuntu/lp-1907656-s390x-s390-virtio-ccw-Reset-PCI-devices-during-subsy.patch
23+ubuntu/lp-1913395-1-linux-headers-update-against-5.10-rc1.patch
24+ubuntu/lp-1913395-2-vfio-Create-shared-routine-for-scanning-info-capabil.patch
25+ubuntu/lp-1913395-3-vfio-Find-DMA-available-capability.patch
26+ubuntu/lp-1913395-4-0004-s390x-pci-Add-routine-to-get-the-vfio-dma-available.patch
27+ubuntu/lp-1913395-5-s390x-pci-Honor-DMA-limits-set-by-vfio.patch
28+ubuntu/lp-1913395-6-s390x-fix-build-for-without-default-devices.patch
29diff --git a/debian/patches/ubuntu/lp-1913395-1-linux-headers-update-against-5.10-rc1.patch b/debian/patches/ubuntu/lp-1913395-1-linux-headers-update-against-5.10-rc1.patch
30new file mode 100644
31index 0000000..183b58a
32--- /dev/null
33+++ b/debian/patches/ubuntu/lp-1913395-1-linux-headers-update-against-5.10-rc1.patch
34@@ -0,0 +1,45 @@
35+From f4a2cda8fe3ca404690ddb509d46d66fe81b30da Mon Sep 17 00:00:00 2001
36+From: Matthew Rosato <mjrosato@linux.ibm.com>
37+Date: Tue, 26 Jan 2021 10:24:34 -0500
38+Subject: [PATCH 1/6] linux-headers: update against 5.10-rc1
39+
40+commit 3650b228f83adda7e5ee532e2b90429c03f7b9ec
41+
42+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
43+[aw: drop pvrdma_ring.h changes to avoid revert of d73415a31547 ("qemu/atomic.h: rename atomic_ to qatomic_")]
44+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
45+[mr: Backport: reduce header sync to only what is required for DMA limit fix]
46+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
47+
48+Origin: backport, https://git.qemu.org/?p=qemu.git;a=commit;h=53ba2eee52bff5a746e96835539a1079f6bcadd1
49+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1913395
50+Last-Update: 2021-01-27
51+
52+---
53+ linux-headers/linux/vfio.h | 15 +++++++++++++++
54+ 1 file changed, 15 insertions(+)
55+
56+--- a/linux-headers/linux/vfio.h
57++++ b/linux-headers/linux/vfio.h
58+@@ -1039,6 +1039,21 @@ struct vfio_iommu_type1_info_cap_migrati
59+ __u64 max_dirty_bitmap_size; /* in bytes */
60+ };
61+
62++/*
63++ * The DMA available capability allows to report the current number of
64++ * simultaneously outstanding DMA mappings that are allowed.
65++ *
66++ * The structure below defines version 1 of this capability.
67++ *
68++ * avail: specifies the current number of outstanding DMA mappings allowed.
69++ */
70++#define VFIO_IOMMU_TYPE1_INFO_DMA_AVAIL 3
71++
72++struct vfio_iommu_type1_info_dma_avail {
73++ struct vfio_info_cap_header header;
74++ __u32 avail;
75++};
76++
77+ #define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
78+
79+ /**
80diff --git a/debian/patches/ubuntu/lp-1913395-2-vfio-Create-shared-routine-for-scanning-info-capabil.patch b/debian/patches/ubuntu/lp-1913395-2-vfio-Create-shared-routine-for-scanning-info-capabil.patch
81new file mode 100644
82index 0000000..98441c4
83--- /dev/null
84+++ b/debian/patches/ubuntu/lp-1913395-2-vfio-Create-shared-routine-for-scanning-info-capabil.patch
85@@ -0,0 +1,64 @@
86+From 3ab7a0b40d4be5ade3b61d4afd1518193b199423 Mon Sep 17 00:00:00 2001
87+From: Matthew Rosato <mjrosato@linux.ibm.com>
88+Date: Mon, 26 Oct 2020 11:34:32 -0400
89+Subject: [PATCH] vfio: Create shared routine for scanning info capabilities
90+MIME-Version: 1.0
91+Content-Type: text/plain; charset=UTF-8
92+Content-Transfer-Encoding: 8bit
93+
94+Rather than duplicating the same loop in multiple locations,
95+create a static function to do the work.
96+
97+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
98+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
99+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
100+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
101+
102+Origin: upstream, https://git.qemu.org/?p=qemu.git;a=commit;h=3ab7a0b40d4b
103+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1913395
104+Last-Update: 2021-01-27
105+
106+---
107+ hw/vfio/common.c | 21 +++++++++++++--------
108+ 1 file changed, 13 insertions(+), 8 deletions(-)
109+
110+--- a/hw/vfio/common.c
111++++ b/hw/vfio/common.c
112+@@ -826,17 +826,12 @@ static void vfio_listener_release(VFIOCo
113+ }
114+ }
115+
116+-struct vfio_info_cap_header *
117+-vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id)
118++static struct vfio_info_cap_header *
119++vfio_get_cap(void *ptr, uint32_t cap_offset, uint16_t id)
120+ {
121+ struct vfio_info_cap_header *hdr;
122+- void *ptr = info;
123+-
124+- if (!(info->flags & VFIO_REGION_INFO_FLAG_CAPS)) {
125+- return NULL;
126+- }
127+
128+- for (hdr = ptr + info->cap_offset; hdr != ptr; hdr = ptr + hdr->next) {
129++ for (hdr = ptr + cap_offset; hdr != ptr; hdr = ptr + hdr->next) {
130+ if (hdr->id == id) {
131+ return hdr;
132+ }
133+@@ -845,6 +840,16 @@ vfio_get_region_info_cap(struct vfio_reg
134+ return NULL;
135+ }
136+
137++struct vfio_info_cap_header *
138++vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id)
139++{
140++ if (!(info->flags & VFIO_REGION_INFO_FLAG_CAPS)) {
141++ return NULL;
142++ }
143++
144++ return vfio_get_cap((void *)info, info->cap_offset, id);
145++}
146++
147+ static int vfio_setup_region_sparse_mmaps(VFIORegion *region,
148+ struct vfio_region_info *info)
149+ {
150diff --git a/debian/patches/ubuntu/lp-1913395-3-vfio-Find-DMA-available-capability.patch b/debian/patches/ubuntu/lp-1913395-3-vfio-Find-DMA-available-capability.patch
151new file mode 100644
152index 0000000..b47bbbe
153--- /dev/null
154+++ b/debian/patches/ubuntu/lp-1913395-3-vfio-Find-DMA-available-capability.patch
155@@ -0,0 +1,75 @@
156+From 7486a62845b1e12011dd99973e4739f69d57cd38 Mon Sep 17 00:00:00 2001
157+From: Matthew Rosato <mjrosato@linux.ibm.com>
158+Date: Mon, 26 Oct 2020 11:34:33 -0400
159+Subject: [PATCH] vfio: Find DMA available capability
160+
161+The underlying host may be limiting the number of outstanding DMA
162+requests for type 1 IOMMU. Add helper functions to check for the
163+DMA available capability and retrieve the current number of DMA
164+mappings allowed.
165+
166+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
167+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
168+[aw: vfio_get_info_dma_avail moved inside CONFIG_LINUX]
169+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
170+
171+Origin: upstream, https://git.qemu.org/?p=qemu.git;a=commit;h=7486a62845b1
172+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1913395
173+Last-Update: 2021-01-27
174+
175+---
176+ hw/vfio/common.c | 31 +++++++++++++++++++++++++++++++
177+ include/hw/vfio/vfio-common.h | 2 ++
178+ 2 files changed, 33 insertions(+)
179+
180+--- a/hw/vfio/common.c
181++++ b/hw/vfio/common.c
182+@@ -850,6 +850,37 @@ vfio_get_region_info_cap(struct vfio_reg
183+ return vfio_get_cap((void *)info, info->cap_offset, id);
184+ }
185+
186++static struct vfio_info_cap_header *
187++vfio_get_iommu_type1_info_cap(struct vfio_iommu_type1_info *info, uint16_t id)
188++{
189++ if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) {
190++ return NULL;
191++ }
192++
193++ return vfio_get_cap((void *)info, info->cap_offset, id);
194++}
195++
196++bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info,
197++ unsigned int *avail)
198++{
199++ struct vfio_info_cap_header *hdr;
200++ struct vfio_iommu_type1_info_dma_avail *cap;
201++
202++ /* If the capability cannot be found, assume no DMA limiting */
203++ hdr = vfio_get_iommu_type1_info_cap(info,
204++ VFIO_IOMMU_TYPE1_INFO_DMA_AVAIL);
205++ if (hdr == NULL) {
206++ return false;
207++ }
208++
209++ if (avail != NULL) {
210++ cap = (void *) hdr;
211++ *avail = cap->avail;
212++ }
213++
214++ return true;
215++}
216++
217+ static int vfio_setup_region_sparse_mmaps(VFIORegion *region,
218+ struct vfio_region_info *info)
219+ {
220+--- a/include/hw/vfio/vfio-common.h
221++++ b/include/hw/vfio/vfio-common.h
222+@@ -191,6 +191,8 @@ int vfio_get_dev_region_info(VFIODevice
223+ bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type);
224+ struct vfio_info_cap_header *
225+ vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id);
226++bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info,
227++ unsigned int *avail);
228+ #endif
229+ extern const MemoryListener vfio_prereg_listener;
230+
231diff --git a/debian/patches/ubuntu/lp-1913395-4-0004-s390x-pci-Add-routine-to-get-the-vfio-dma-available.patch b/debian/patches/ubuntu/lp-1913395-4-0004-s390x-pci-Add-routine-to-get-the-vfio-dma-available.patch
232new file mode 100644
233index 0000000..149ebac
234--- /dev/null
235+++ b/debian/patches/ubuntu/lp-1913395-4-0004-s390x-pci-Add-routine-to-get-the-vfio-dma-available.patch
236@@ -0,0 +1,120 @@
237+From eaf387f141a6fc08cab59752b75e2a9c731754df Mon Sep 17 00:00:00 2001
238+From: Matthew Rosato <mjrosato@linux.ibm.com>
239+Date: Mon, 26 Oct 2020 11:34:34 -0400
240+Subject: [PATCH 4/6] s390x/pci: Add routine to get the vfio dma available
241+ count
242+
243+Create new files for separating out vfio-specific work for s390
244+pci. Add the first such routine, which issues VFIO_IOMMU_GET_INFO
245+ioctl to collect the current dma available count.
246+
247+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
248+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
249+[aw: Fix non-Linux build with CONFIG_LINUX]
250+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
251+[mr: Backport: Replace meson changes with Makefile changes]
252+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
253+
254+Origin: backport, https://git.qemu.org/?p=qemu.git;a=commit;h=cd7498d07fbb20fa04790ff7ee168a8a8d01cb30
255+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1913395
256+Last-Update: 2021-01-27
257+
258+---
259+ hw/s390x/Makefile.objs | 1 +
260+ hw/s390x/s390-pci-vfio.c | 54 ++++++++++++++++++++++++++++++++++++++++
261+ include/hw/s390x/s390-pci-vfio.h | 24 ++++++++++++++++++
262+ 3 files changed, 79 insertions(+)
263+ create mode 100644 hw/s390x/s390-pci-vfio.c
264+ create mode 100644 include/hw/s390x/s390-pci-vfio.h
265+
266+--- a/hw/s390x/Makefile.objs
267++++ b/hw/s390x/Makefile.objs
268+@@ -35,3 +35,4 @@ obj-$(CONFIG_KVM) += pv.o
269+ obj-y += s390-ccw.o
270+ obj-y += ap-device.o
271+ obj-y += ap-bridge.o
272++obj-$(CONFIG_LINUX) += s390-pci-vfio.o
273+--- /dev/null
274++++ b/hw/s390x/s390-pci-vfio.c
275+@@ -0,0 +1,54 @@
276++/*
277++ * s390 vfio-pci interfaces
278++ *
279++ * Copyright 2020 IBM Corp.
280++ * Author(s): Matthew Rosato <mjrosato@linux.ibm.com>
281++ *
282++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
283++ * your option) any later version. See the COPYING file in the top-level
284++ * directory.
285++ */
286++
287++#include "qemu/osdep.h"
288++
289++#include <sys/ioctl.h>
290++
291++#include "hw/s390x/s390-pci-vfio.h"
292++#include "hw/vfio/vfio-common.h"
293++
294++/*
295++ * Get the current DMA available count from vfio. Returns true if vfio is
296++ * limiting DMA requests, false otherwise. The current available count read
297++ * from vfio is returned in avail.
298++ */
299++bool s390_pci_update_dma_avail(int fd, unsigned int *avail)
300++{
301++ g_autofree struct vfio_iommu_type1_info *info;
302++ uint32_t argsz;
303++
304++ assert(avail);
305++
306++ argsz = sizeof(struct vfio_iommu_type1_info);
307++ info = g_malloc0(argsz);
308++
309++ /*
310++ * If the specified argsz is not large enough to contain all capabilities
311++ * it will be updated upon return from the ioctl. Retry until we have
312++ * a big enough buffer to hold the entire capability chain.
313++ */
314++retry:
315++ info->argsz = argsz;
316++
317++ if (ioctl(fd, VFIO_IOMMU_GET_INFO, info)) {
318++ return false;
319++ }
320++
321++ if (info->argsz > argsz) {
322++ argsz = info->argsz;
323++ info = g_realloc(info, argsz);
324++ goto retry;
325++ }
326++
327++ /* If the capability exists, update with the current value */
328++ return vfio_get_info_dma_avail(info, avail);
329++}
330+--- /dev/null
331++++ b/include/hw/s390x/s390-pci-vfio.h
332+@@ -0,0 +1,24 @@
333++/*
334++ * s390 vfio-pci interfaces
335++ *
336++ * Copyright 2020 IBM Corp.
337++ * Author(s): Matthew Rosato <mjrosato@linux.ibm.com>
338++ *
339++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
340++ * your option) any later version. See the COPYING file in the top-level
341++ * directory.
342++ */
343++
344++#ifndef HW_S390_PCI_VFIO_H
345++#define HW_S390_PCI_VFIO_H
346++
347++#ifdef CONFIG_LINUX
348++bool s390_pci_update_dma_avail(int fd, unsigned int *avail);
349++#else
350++static inline bool s390_pci_update_dma_avail(int fd, unsigned int *avail)
351++{
352++ return false;
353++}
354++#endif
355++
356++#endif
357diff --git a/debian/patches/ubuntu/lp-1913395-5-s390x-pci-Honor-DMA-limits-set-by-vfio.patch b/debian/patches/ubuntu/lp-1913395-5-s390x-pci-Honor-DMA-limits-set-by-vfio.patch
358new file mode 100644
359index 0000000..a8607f3
360--- /dev/null
361+++ b/debian/patches/ubuntu/lp-1913395-5-s390x-pci-Honor-DMA-limits-set-by-vfio.patch
362@@ -0,0 +1,324 @@
363+From ac3bee0a6906719d3ef3cbdaf5f986deb3ab20dc Mon Sep 17 00:00:00 2001
364+From: Matthew Rosato <mjrosato@linux.ibm.com>
365+Date: Mon, 26 Oct 2020 11:34:35 -0400
366+Subject: [PATCH 5/6] s390x/pci: Honor DMA limits set by vfio
367+
368+When an s390 guest is using lazy unmapping, it can result in a very
369+large number of oustanding DMA requests, far beyond the default
370+limit configured for vfio. Let's track DMA usage similar to vfio
371+in the host, and trigger the guest to flush their DMA mappings
372+before vfio runs out.
373+
374+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
375+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
376+[aw: non-Linux build fixes]
377+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
378+[mr: Backport: Adjust for conflicts with missing header reorganization patch]
379+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
380+
381+Origin: backport, https://git.qemu.org/?p=qemu.git;a=commit;h=37fa32de707340f3a93959ad5a1ebc41ba1520ee
382+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1913395
383+Last-Update: 2021-01-27
384+
385+---
386+ hw/s390x/s390-pci-bus.c | 16 +++++++++-----
387+ hw/s390x/s390-pci-bus.h | 9 ++++++++
388+ hw/s390x/s390-pci-inst.c | 45 ++++++++++++++++++++++++++++++++++------
389+ hw/s390x/s390-pci-inst.h | 3 +++
390+ hw/s390x/s390-pci-vfio.c | 43 ++++++++++++++++++++++++++++++++++++++
391+ include/hw/s390x/s390-pci-vfio.h | 12 +++++++++++
392+ 6 files changed, 117 insertions(+), 11 deletions(-)
393+
394+--- a/hw/s390x/s390-pci-bus.c
395++++ b/hw/s390x/s390-pci-bus.c
396+@@ -17,6 +17,7 @@
397+ #include "cpu.h"
398+ #include "s390-pci-bus.h"
399+ #include "s390-pci-inst.h"
400++#include "hw/s390x/s390-pci-vfio.h"
401+ #include "hw/pci/pci_bus.h"
402+ #include "hw/qdev-properties.h"
403+ #include "hw/pci/pci_bridge.h"
404+@@ -773,6 +774,7 @@ static void s390_pcihost_realize(DeviceS
405+ s->bus_no = 0;
406+ QTAILQ_INIT(&s->pending_sei);
407+ QTAILQ_INIT(&s->zpci_devs);
408++ QTAILQ_INIT(&s->zpci_dma_limit);
409+
410+ css_register_io_adapters(CSS_IO_ADAPTER_PCI, true, false,
411+ S390_ADAPTER_SUPPRESSIBLE, &local_err);
412+@@ -953,17 +955,18 @@ static void s390_pcihost_plug(HotplugHan
413+ }
414+ }
415+
416++ pbdev->pdev = pdev;
417++ pbdev->iommu = s390_pci_get_iommu(s, pci_get_bus(pdev), pdev->devfn);
418++ pbdev->iommu->pbdev = pbdev;
419++ pbdev->state = ZPCI_FS_DISABLED;
420++
421+ if (object_dynamic_cast(OBJECT(dev), "vfio-pci")) {
422+ pbdev->fh |= FH_SHM_VFIO;
423++ pbdev->iommu->dma_limit = s390_pci_start_dma_count(s, pbdev);
424+ } else {
425+ pbdev->fh |= FH_SHM_EMUL;
426+ }
427+
428+- pbdev->pdev = pdev;
429+- pbdev->iommu = s390_pci_get_iommu(s, pci_get_bus(pdev), pdev->devfn);
430+- pbdev->iommu->pbdev = pbdev;
431+- pbdev->state = ZPCI_FS_DISABLED;
432+-
433+ if (s390_pci_msix_init(pbdev)) {
434+ error_setg(errp, "MSI-X support is mandatory "
435+ "in the S390 architecture");
436+@@ -1016,6 +1019,9 @@ static void s390_pcihost_unplug(HotplugH
437+ pbdev->fid = 0;
438+ QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
439+ g_hash_table_remove(s->zpci_table, &pbdev->idx);
440++ if (pbdev->iommu->dma_limit) {
441++ s390_pci_end_dma_count(s, pbdev->iommu->dma_limit);
442++ }
443+ object_property_set_bool(OBJECT(dev), false, "realized", NULL);
444+ }
445+ }
446+--- a/hw/s390x/s390-pci-bus.h
447++++ b/hw/s390x/s390-pci-bus.h
448+@@ -265,6 +265,13 @@ typedef struct S390IOTLBEntry {
449+ uint64_t perm;
450+ } S390IOTLBEntry;
451+
452++typedef struct S390PCIDMACount {
453++ int id;
454++ int users;
455++ uint32_t avail;
456++ QTAILQ_ENTRY(S390PCIDMACount) link;
457++} S390PCIDMACount;
458++
459+ typedef struct S390PCIBusDevice S390PCIBusDevice;
460+ typedef struct S390PCIIOMMU {
461+ Object parent_obj;
462+@@ -277,6 +284,7 @@ typedef struct S390PCIIOMMU {
463+ uint64_t pba;
464+ uint64_t pal;
465+ GHashTable *iotlb;
466++ S390PCIDMACount *dma_limit;
467+ } S390PCIIOMMU;
468+
469+ typedef struct S390PCIIOMMUTable {
470+@@ -352,6 +360,7 @@ typedef struct S390pciState {
471+ GHashTable *zpci_table;
472+ QTAILQ_HEAD(, SeiContainer) pending_sei;
473+ QTAILQ_HEAD(, S390PCIBusDevice) zpci_devs;
474++ QTAILQ_HEAD(, S390PCIDMACount) zpci_dma_limit;
475+ } S390pciState;
476+
477+ S390pciState *s390_get_phb(void);
478+--- a/hw/s390x/s390-pci-inst.c
479++++ b/hw/s390x/s390-pci-inst.c
480+@@ -32,6 +32,20 @@
481+ } \
482+ } while (0)
483+
484++static inline void inc_dma_avail(S390PCIIOMMU *iommu)
485++{
486++ if (iommu->dma_limit) {
487++ iommu->dma_limit->avail++;
488++ }
489++}
490++
491++static inline void dec_dma_avail(S390PCIIOMMU *iommu)
492++{
493++ if (iommu->dma_limit) {
494++ iommu->dma_limit->avail--;
495++ }
496++}
497++
498+ static void s390_set_status_code(CPUS390XState *env,
499+ uint8_t r, uint64_t status_code)
500+ {
501+@@ -572,7 +586,8 @@ int pcistg_service_call(S390CPU *cpu, ui
502+ return 0;
503+ }
504+
505+-static void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *entry)
506++static uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu,
507++ S390IOTLBEntry *entry)
508+ {
509+ S390IOTLBEntry *cache = g_hash_table_lookup(iommu->iotlb, &entry->iova);
510+ IOMMUTLBEntry notify = {
511+@@ -585,14 +600,15 @@ static void s390_pci_update_iotlb(S390PC
512+
513+ if (entry->perm == IOMMU_NONE) {
514+ if (!cache) {
515+- return;
516++ goto out;
517+ }
518+ g_hash_table_remove(iommu->iotlb, &entry->iova);
519++ inc_dma_avail(iommu);
520+ } else {
521+ if (cache) {
522+ if (cache->perm == entry->perm &&
523+ cache->translated_addr == entry->translated_addr) {
524+- return;
525++ goto out;
526+ }
527+
528+ notify.perm = IOMMU_NONE;
529+@@ -606,9 +622,13 @@ static void s390_pci_update_iotlb(S390PC
530+ cache->len = PAGE_SIZE;
531+ cache->perm = entry->perm;
532+ g_hash_table_replace(iommu->iotlb, &cache->iova, cache);
533++ dec_dma_avail(iommu);
534+ }
535+
536+ memory_region_notify_iommu(&iommu->iommu_mr, 0, notify);
537++
538++out:
539++ return iommu->dma_limit ? iommu->dma_limit->avail : 1;
540+ }
541+
542+ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
543+@@ -620,6 +640,7 @@ int rpcit_service_call(S390CPU *cpu, uin
544+ S390PCIIOMMU *iommu;
545+ S390IOTLBEntry entry;
546+ hwaddr start, end;
547++ uint32_t dma_avail;
548+
549+ if (env->psw.mask & PSW_MASK_PSTATE) {
550+ s390_program_interrupt(env, PGM_PRIVILEGED, ra);
551+@@ -658,6 +679,11 @@ int rpcit_service_call(S390CPU *cpu, uin
552+ }
553+
554+ iommu = pbdev->iommu;
555++ if (iommu->dma_limit) {
556++ dma_avail = iommu->dma_limit->avail;
557++ } else {
558++ dma_avail = 1;
559++ }
560+ if (!iommu->g_iota) {
561+ error = ERR_EVENT_INVALAS;
562+ goto err;
563+@@ -675,8 +701,9 @@ int rpcit_service_call(S390CPU *cpu, uin
564+ }
565+
566+ start += entry.len;
567+- while (entry.iova < start && entry.iova < end) {
568+- s390_pci_update_iotlb(iommu, &entry);
569++ while (entry.iova < start && entry.iova < end &&
570++ (dma_avail > 0 || entry.perm == IOMMU_NONE)) {
571++ dma_avail = s390_pci_update_iotlb(iommu, &entry);
572+ entry.iova += PAGE_SIZE;
573+ entry.translated_addr += PAGE_SIZE;
574+ }
575+@@ -689,7 +716,13 @@ err:
576+ s390_pci_generate_error_event(error, pbdev->fh, pbdev->fid, start, 0);
577+ } else {
578+ pbdev->fmb.counter[ZPCI_FMB_CNT_RPCIT]++;
579+- setcc(cpu, ZPCI_PCI_LS_OK);
580++ if (dma_avail > 0) {
581++ setcc(cpu, ZPCI_PCI_LS_OK);
582++ } else {
583++ /* vfio DMA mappings are exhausted, trigger a RPCIT */
584++ setcc(cpu, ZPCI_PCI_LS_ERR);
585++ s390_set_status_code(env, r1, ZPCI_RPCIT_ST_INSUFF_RES);
586++ }
587+ }
588+ return 0;
589+ }
590+--- a/hw/s390x/s390-pci-inst.h
591++++ b/hw/s390x/s390-pci-inst.h
592+@@ -254,6 +254,9 @@ typedef struct ClpReqRspQueryPciGrp {
593+ #define ZPCI_STPCIFC_ST_INVAL_DMAAS 28
594+ #define ZPCI_STPCIFC_ST_ERROR_RECOVER 40
595+
596++/* Refresh PCI Translations status codes */
597++#define ZPCI_RPCIT_ST_INSUFF_RES 16
598++
599+ /* FIB function controls */
600+ #define ZPCI_FIB_FC_ENABLED 0x80
601+ #define ZPCI_FIB_FC_ERROR 0x40
602+--- a/hw/s390x/s390-pci-vfio.c
603++++ b/hw/s390x/s390-pci-vfio.c
604+@@ -13,7 +13,9 @@
605+
606+ #include <sys/ioctl.h>
607+
608++#include "s390-pci-bus.h"
609+ #include "hw/s390x/s390-pci-vfio.h"
610++#include "hw/vfio/pci.h"
611+ #include "hw/vfio/vfio-common.h"
612+
613+ /*
614+@@ -52,3 +54,44 @@ retry:
615+ /* If the capability exists, update with the current value */
616+ return vfio_get_info_dma_avail(info, avail);
617+ }
618++
619++S390PCIDMACount *s390_pci_start_dma_count(S390pciState *s,
620++ S390PCIBusDevice *pbdev)
621++{
622++ S390PCIDMACount *cnt;
623++ uint32_t avail;
624++ VFIOPCIDevice *vpdev = container_of(pbdev->pdev, VFIOPCIDevice, pdev);
625++ int id;
626++
627++ assert(vpdev);
628++
629++ id = vpdev->vbasedev.group->container->fd;
630++
631++ if (!s390_pci_update_dma_avail(id, &avail)) {
632++ return NULL;
633++ }
634++
635++ QTAILQ_FOREACH(cnt, &s->zpci_dma_limit, link) {
636++ if (cnt->id == id) {
637++ cnt->users++;
638++ return cnt;
639++ }
640++ }
641++
642++ cnt = g_new0(S390PCIDMACount, 1);
643++ cnt->id = id;
644++ cnt->users = 1;
645++ cnt->avail = avail;
646++ QTAILQ_INSERT_TAIL(&s->zpci_dma_limit, cnt, link);
647++ return cnt;
648++}
649++
650++void s390_pci_end_dma_count(S390pciState *s, S390PCIDMACount *cnt)
651++{
652++ assert(cnt);
653++
654++ cnt->users--;
655++ if (cnt->users == 0) {
656++ QTAILQ_REMOVE(&s->zpci_dma_limit, cnt, link);
657++ }
658++}
659+--- a/include/hw/s390x/s390-pci-vfio.h
660++++ b/include/hw/s390x/s390-pci-vfio.h
661+@@ -12,13 +12,25 @@
662+ #ifndef HW_S390_PCI_VFIO_H
663+ #define HW_S390_PCI_VFIO_H
664+
665++#include "../../../hw/s390x/s390-pci-bus.h"
666++
667+ #ifdef CONFIG_LINUX
668+ bool s390_pci_update_dma_avail(int fd, unsigned int *avail);
669++S390PCIDMACount *s390_pci_start_dma_count(S390pciState *s,
670++ S390PCIBusDevice *pbdev);
671++void s390_pci_end_dma_count(S390pciState *s, S390PCIDMACount *cnt);
672+ #else
673+ static inline bool s390_pci_update_dma_avail(int fd, unsigned int *avail)
674+ {
675+ return false;
676+ }
677++static inline S390PCIDMACount *s390_pci_start_dma_count(S390pciState *s,
678++ S390PCIBusDevice *pbdev)
679++{
680++ return NULL;
681++}
682++static inline void s390_pci_end_dma_count(S390pciState *s,
683++ S390PCIDMACount *cnt) { }
684+ #endif
685+
686+ #endif
687diff --git a/debian/patches/ubuntu/lp-1913395-6-s390x-fix-build-for-without-default-devices.patch b/debian/patches/ubuntu/lp-1913395-6-s390x-fix-build-for-without-default-devices.patch
688new file mode 100644
689index 0000000..478f71a
690--- /dev/null
691+++ b/debian/patches/ubuntu/lp-1913395-6-s390x-fix-build-for-without-default-devices.patch
692@@ -0,0 +1,53 @@
693+From 2fb44bb505d5e732ca508aec477dc5ce334c4757 Mon Sep 17 00:00:00 2001
694+From: Cornelia Huck <cohuck@redhat.com>
695+Date: Tue, 3 Nov 2020 13:32:37 +0100
696+Subject: [PATCH 6/6] s390x: fix build for --without-default-devices
697+MIME-Version: 1.0
698+Content-Type: text/plain; charset=UTF-8
699+Content-Transfer-Encoding: 8bit
700+
701+s390-pci-vfio.c calls into the vfio code, so we need it to be
702+built conditionally on vfio (which implies CONFIG_LINUX).
703+
704+Fixes: cd7498d07fbb ("s390x/pci: Add routine to get the vfio dma available count")
705+Reported-by: Philippe Mathieu-Daudé <philmd@redhat.com>
706+Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
707+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
708+Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
709+Message-Id: <20201103123237.718242-1-cohuck@redhat.com>
710+Acked-by: Greg Kurz <groug@kaod.org>
711+Tested-by: Greg Kurz <groug@kaod.org>
712+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
713+[mr: Backport: not using meson, CONFIG_DEVICES doesn't exist]
714+Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
715+
716+Origin: backport, https://git.qemu.org/?p=qemu.git;a=commit;h=77280d33bc9cfdbfb5b5d462259d644f5aefe9b3
717+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1913395
718+Last-Update: 2021-01-27
719+
720+---
721+ hw/s390x/Makefile.objs | 2 +-
722+ include/hw/s390x/s390-pci-vfio.h | 3 ++-
723+ 2 files changed, 3 insertions(+), 2 deletions(-)
724+
725+--- a/hw/s390x/Makefile.objs
726++++ b/hw/s390x/Makefile.objs
727+@@ -35,4 +35,4 @@ obj-$(CONFIG_KVM) += pv.o
728+ obj-y += s390-ccw.o
729+ obj-y += ap-device.o
730+ obj-y += ap-bridge.o
731+-obj-$(CONFIG_LINUX) += s390-pci-vfio.o
732++obj-$(CONFIG_VFIO) += s390-pci-vfio.o
733+--- a/include/hw/s390x/s390-pci-vfio.h
734++++ b/include/hw/s390x/s390-pci-vfio.h
735+@@ -13,8 +13,9 @@
736+ #define HW_S390_PCI_VFIO_H
737+
738+ #include "../../../hw/s390x/s390-pci-bus.h"
739++#include "config-devices.h"
740+
741+-#ifdef CONFIG_LINUX
742++#ifdef CONFIG_VFIO
743+ bool s390_pci_update_dma_avail(int fd, unsigned int *avail);
744+ S390PCIDMACount *s390_pci_start_dma_count(S390pciState *s,
745+ S390PCIBusDevice *pbdev);

Subscribers

People subscribed via source and target branches