1 | The following changes since commit 88afdc92b644120e0182c8567e1b1d236e471b12: | 1 | The following changes since commit 661c2e1ab29cd9c4d268ae3f44712e8d421c0e56: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2021-09-05 15:48:42 +0100) | 3 | scripts/checkpatch: Fix a typo (2025-03-04 09:30:26 +0800) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://gitlab.com/stefanha/qemu.git tags/block-pull-request | 7 | https://gitlab.com/stefanha/qemu.git tags/block-pull-request |
8 | 8 | ||
9 | for you to fetch changes up to 9bd2788f49c331b02372cc257b11e4c984d39708: | 9 | for you to fetch changes up to 2ad638a3d160923ef3dbf87c73944e6e44bdc724: |
10 | 10 | ||
11 | block/nvme: Only report VFIO error on failed retry (2021-09-07 09:08:24 +0100) | 11 | block/qed: fix use-after-free by nullifying timer pointer after free (2025-03-06 10:19:54 +0800) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Pull request | 14 | Pull request |
15 | 15 | ||
16 | Userspace NVMe driver patches. | 16 | QED need_check_timer use-after-free fix |
17 | 17 | ||
18 | ---------------------------------------------------------------- | 18 | ---------------------------------------------------------------- |
19 | 19 | ||
20 | Philippe Mathieu-Daudé (11): | 20 | Denis Rastyogin (1): |
21 | block/nvme: Use safer trace format string | 21 | block/qed: fix use-after-free by nullifying timer pointer after free |
22 | util/vfio-helpers: Let qemu_vfio_verify_mappings() use error_report() | ||
23 | util/vfio-helpers: Replace qemu_mutex_lock() calls with | ||
24 | QEMU_LOCK_GUARD | ||
25 | util/vfio-helpers: Remove unreachable code in qemu_vfio_dma_map() | ||
26 | block/nvme: Have nvme_create_queue_pair() report errors consistently | ||
27 | util/vfio-helpers: Pass Error handle to qemu_vfio_dma_map() | ||
28 | util/vfio-helpers: Extract qemu_vfio_water_mark_reached() | ||
29 | util/vfio-helpers: Use error_setg in qemu_vfio_find_[fixed/temp]_iova | ||
30 | util/vfio-helpers: Simplify qemu_vfio_dma_map() returning directly | ||
31 | util/vfio-helpers: Let qemu_vfio_do_mapping() propagate Error | ||
32 | block/nvme: Only report VFIO error on failed retry | ||
33 | 22 | ||
34 | include/qemu/vfio-helpers.h | 2 +- | 23 | block/qed.c | 1 + |
35 | block/nvme.c | 29 +++++++---- | 24 | 1 file changed, 1 insertion(+) |
36 | util/vfio-helpers.c | 99 ++++++++++++++++++++----------------- | ||
37 | block/trace-events | 2 +- | ||
38 | 4 files changed, 76 insertions(+), 56 deletions(-) | ||
39 | 25 | ||
40 | -- | 26 | -- |
41 | 2.31.1 | 27 | 2.48.1 |
42 | |||
43 | |||
44 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | Fix when building with -Wshorten-64-to-32: | ||
4 | |||
5 | warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32] | ||
6 | |||
7 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
9 | Message-id: 20210902070025.197072-2-philmd@redhat.com | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | block/trace-events | 2 +- | ||
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/block/trace-events b/block/trace-events | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block/trace-events | ||
18 | +++ b/block/trace-events | ||
19 | @@ -XXX,XX +XXX,XX @@ nvme_dsm(void *s, uint64_t offset, uint64_t bytes) "s %p offset 0x%"PRIx64" byte | ||
20 | nvme_dsm_done(void *s, uint64_t offset, uint64_t bytes, int ret) "s %p offset 0x%"PRIx64" bytes %"PRId64" ret %d" | ||
21 | nvme_dma_map_flush(void *s) "s %p" | ||
22 | nvme_free_req_queue_wait(void *s, unsigned q_index) "s %p q #%u" | ||
23 | -nvme_create_queue_pair(unsigned q_index, void *q, unsigned size, void *aio_context, int fd) "index %u q %p size %u aioctx %p fd %d" | ||
24 | +nvme_create_queue_pair(unsigned q_index, void *q, size_t size, void *aio_context, int fd) "index %u q %p size %zu aioctx %p fd %d" | ||
25 | nvme_free_queue_pair(unsigned q_index, void *q) "index %u q %p" | ||
26 | nvme_cmd_map_qiov(void *s, void *cmd, void *req, void *qiov, int entries) "s %p cmd %p req %p qiov %p entries %d" | ||
27 | nvme_cmd_map_qiov_pages(void *s, int i, uint64_t page) "s %p page[%d] 0x%"PRIx64 | ||
28 | -- | ||
29 | 2.31.1 | ||
30 | |||
31 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | Instead of displaying the error on stderr, use error_report() | ||
4 | which also report to the monitor. | ||
5 | |||
6 | Reviewed-by: Fam Zheng <fam@euphon.net> | ||
7 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
8 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
9 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
10 | Message-id: 20210902070025.197072-3-philmd@redhat.com | ||
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
12 | --- | ||
13 | util/vfio-helpers.c | 4 ++-- | ||
14 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
15 | |||
16 | diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/util/vfio-helpers.c | ||
19 | +++ b/util/vfio-helpers.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static bool qemu_vfio_verify_mappings(QEMUVFIOState *s) | ||
21 | if (QEMU_VFIO_DEBUG) { | ||
22 | for (i = 0; i < s->nr_mappings - 1; ++i) { | ||
23 | if (!(s->mappings[i].host < s->mappings[i + 1].host)) { | ||
24 | - fprintf(stderr, "item %d not sorted!\n", i); | ||
25 | + error_report("item %d not sorted!", i); | ||
26 | qemu_vfio_dump_mappings(s); | ||
27 | return false; | ||
28 | } | ||
29 | if (!(s->mappings[i].host + s->mappings[i].size <= | ||
30 | s->mappings[i + 1].host)) { | ||
31 | - fprintf(stderr, "item %d overlap with next!\n", i); | ||
32 | + error_report("item %d overlap with next!", i); | ||
33 | qemu_vfio_dump_mappings(s); | ||
34 | return false; | ||
35 | } | ||
36 | -- | ||
37 | 2.31.1 | ||
38 | |||
39 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | Simplify qemu_vfio_dma_[un]map() handlers by replacing a pair of | ||
4 | qemu_mutex_lock/qemu_mutex_unlock calls by the WITH_QEMU_LOCK_GUARD | ||
5 | macro. | ||
6 | |||
7 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
9 | Message-id: 20210902070025.197072-4-philmd@redhat.com | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | util/vfio-helpers.c | 9 +++------ | ||
13 | 1 file changed, 3 insertions(+), 6 deletions(-) | ||
14 | |||
15 | diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/util/vfio-helpers.c | ||
18 | +++ b/util/vfio-helpers.c | ||
19 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
20 | assert(QEMU_PTR_IS_ALIGNED(host, qemu_real_host_page_size)); | ||
21 | assert(QEMU_IS_ALIGNED(size, qemu_real_host_page_size)); | ||
22 | trace_qemu_vfio_dma_map(s, host, size, temporary, iova); | ||
23 | - qemu_mutex_lock(&s->lock); | ||
24 | + QEMU_LOCK_GUARD(&s->lock); | ||
25 | mapping = qemu_vfio_find_mapping(s, host, &index); | ||
26 | if (mapping) { | ||
27 | iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host); | ||
28 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
29 | *iova = iova0; | ||
30 | } | ||
31 | out: | ||
32 | - qemu_mutex_unlock(&s->lock); | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | @@ -XXX,XX +XXX,XX @@ void qemu_vfio_dma_unmap(QEMUVFIOState *s, void *host) | ||
37 | } | ||
38 | |||
39 | trace_qemu_vfio_dma_unmap(s, host); | ||
40 | - qemu_mutex_lock(&s->lock); | ||
41 | + QEMU_LOCK_GUARD(&s->lock); | ||
42 | m = qemu_vfio_find_mapping(s, host, &index); | ||
43 | if (!m) { | ||
44 | - goto out; | ||
45 | + return; | ||
46 | } | ||
47 | qemu_vfio_undo_mapping(s, m, NULL); | ||
48 | -out: | ||
49 | - qemu_mutex_unlock(&s->lock); | ||
50 | } | ||
51 | |||
52 | static void qemu_vfio_reset(QEMUVFIOState *s) | ||
53 | -- | ||
54 | 2.31.1 | ||
55 | |||
56 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | qemu_vfio_add_mapping() returns a pointer to an indexed entry | ||
4 | in pre-allocated QEMUVFIOState::mappings[], thus can not be NULL. | ||
5 | Remove the pointless check. | ||
6 | |||
7 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
9 | Message-id: 20210902070025.197072-5-philmd@redhat.com | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | util/vfio-helpers.c | 4 ---- | ||
13 | 1 file changed, 4 deletions(-) | ||
14 | |||
15 | diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/util/vfio-helpers.c | ||
18 | +++ b/util/vfio-helpers.c | ||
19 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
20 | } | ||
21 | |||
22 | mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0); | ||
23 | - if (!mapping) { | ||
24 | - ret = -ENOMEM; | ||
25 | - goto out; | ||
26 | - } | ||
27 | assert(qemu_vfio_verify_mappings(s)); | ||
28 | ret = qemu_vfio_do_mapping(s, host, size, iova0); | ||
29 | if (ret) { | ||
30 | -- | ||
31 | 2.31.1 | ||
32 | |||
33 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | nvme_create_queue_pair() does not return a boolean value (indicating | ||
4 | eventual error) but a pointer, and is inconsistent in how it fills the | ||
5 | error handler. To fulfill callers expectations, always set an error | ||
6 | message on failure. | ||
7 | |||
8 | Reported-by: Auger Eric <eric.auger@redhat.com> | ||
9 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
10 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
11 | Message-id: 20210902070025.197072-6-philmd@redhat.com | ||
12 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
13 | --- | ||
14 | block/nvme.c | 3 +++ | ||
15 | 1 file changed, 3 insertions(+) | ||
16 | |||
17 | diff --git a/block/nvme.c b/block/nvme.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/block/nvme.c | ||
20 | +++ b/block/nvme.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s, | ||
22 | |||
23 | q = g_try_new0(NVMeQueuePair, 1); | ||
24 | if (!q) { | ||
25 | + error_setg(errp, "Cannot allocate queue pair"); | ||
26 | return NULL; | ||
27 | } | ||
28 | trace_nvme_create_queue_pair(idx, q, size, aio_context, | ||
29 | @@ -XXX,XX +XXX,XX @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s, | ||
30 | qemu_real_host_page_size); | ||
31 | q->prp_list_pages = qemu_try_memalign(qemu_real_host_page_size, bytes); | ||
32 | if (!q->prp_list_pages) { | ||
33 | + error_setg(errp, "Cannot allocate PRP page list"); | ||
34 | goto fail; | ||
35 | } | ||
36 | memset(q->prp_list_pages, 0, bytes); | ||
37 | @@ -XXX,XX +XXX,XX @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s, | ||
38 | r = qemu_vfio_dma_map(s->vfio, q->prp_list_pages, bytes, | ||
39 | false, &prp_list_iova); | ||
40 | if (r) { | ||
41 | + error_setg_errno(errp, -r, "Cannot map buffer for DMA"); | ||
42 | goto fail; | ||
43 | } | ||
44 | q->free_req_head = -1; | ||
45 | -- | ||
46 | 2.31.1 | ||
47 | |||
48 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | Currently qemu_vfio_dma_map() displays errors on stderr. | ||
4 | When using management interface, this information is simply | ||
5 | lost. Pass qemu_vfio_dma_map() an Error** handle so it can | ||
6 | propagate the error to callers. | ||
7 | |||
8 | Reviewed-by: Fam Zheng <fam@euphon.net> | ||
9 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
10 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
11 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
12 | Message-id: 20210902070025.197072-7-philmd@redhat.com | ||
13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
14 | --- | ||
15 | include/qemu/vfio-helpers.h | 2 +- | ||
16 | block/nvme.c | 22 +++++++++++----------- | ||
17 | util/vfio-helpers.c | 10 ++++++---- | ||
18 | 3 files changed, 18 insertions(+), 16 deletions(-) | ||
19 | |||
20 | diff --git a/include/qemu/vfio-helpers.h b/include/qemu/vfio-helpers.h | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/include/qemu/vfio-helpers.h | ||
23 | +++ b/include/qemu/vfio-helpers.h | ||
24 | @@ -XXX,XX +XXX,XX @@ typedef struct QEMUVFIOState QEMUVFIOState; | ||
25 | QEMUVFIOState *qemu_vfio_open_pci(const char *device, Error **errp); | ||
26 | void qemu_vfio_close(QEMUVFIOState *s); | ||
27 | int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
28 | - bool temporary, uint64_t *iova_list); | ||
29 | + bool temporary, uint64_t *iova_list, Error **errp); | ||
30 | int qemu_vfio_dma_reset_temporary(QEMUVFIOState *s); | ||
31 | void qemu_vfio_dma_unmap(QEMUVFIOState *s, void *host); | ||
32 | void *qemu_vfio_pci_map_bar(QEMUVFIOState *s, int index, | ||
33 | diff --git a/block/nvme.c b/block/nvme.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/block/nvme.c | ||
36 | +++ b/block/nvme.c | ||
37 | @@ -XXX,XX +XXX,XX @@ static bool nvme_init_queue(BDRVNVMeState *s, NVMeQueue *q, | ||
38 | return false; | ||
39 | } | ||
40 | memset(q->queue, 0, bytes); | ||
41 | - r = qemu_vfio_dma_map(s->vfio, q->queue, bytes, false, &q->iova); | ||
42 | + r = qemu_vfio_dma_map(s->vfio, q->queue, bytes, false, &q->iova, errp); | ||
43 | if (r) { | ||
44 | - error_setg(errp, "Cannot map queue"); | ||
45 | - return false; | ||
46 | + error_prepend(errp, "Cannot map queue: "); | ||
47 | } | ||
48 | - return true; | ||
49 | + return r == 0; | ||
50 | } | ||
51 | |||
52 | static void nvme_free_queue_pair(NVMeQueuePair *q) | ||
53 | @@ -XXX,XX +XXX,XX @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s, | ||
54 | qemu_co_queue_init(&q->free_req_queue); | ||
55 | q->completion_bh = aio_bh_new(aio_context, nvme_process_completion_bh, q); | ||
56 | r = qemu_vfio_dma_map(s->vfio, q->prp_list_pages, bytes, | ||
57 | - false, &prp_list_iova); | ||
58 | + false, &prp_list_iova, errp); | ||
59 | if (r) { | ||
60 | - error_setg_errno(errp, -r, "Cannot map buffer for DMA"); | ||
61 | + error_prepend(errp, "Cannot map buffer for DMA: "); | ||
62 | goto fail; | ||
63 | } | ||
64 | q->free_req_head = -1; | ||
65 | @@ -XXX,XX +XXX,XX @@ static bool nvme_identify(BlockDriverState *bs, int namespace, Error **errp) | ||
66 | error_setg(errp, "Cannot allocate buffer for identify response"); | ||
67 | goto out; | ||
68 | } | ||
69 | - r = qemu_vfio_dma_map(s->vfio, id, id_size, true, &iova); | ||
70 | + r = qemu_vfio_dma_map(s->vfio, id, id_size, true, &iova, errp); | ||
71 | if (r) { | ||
72 | - error_setg(errp, "Cannot map buffer for DMA"); | ||
73 | + error_prepend(errp, "Cannot map buffer for DMA: "); | ||
74 | goto out; | ||
75 | } | ||
76 | |||
77 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd, | ||
78 | try_map: | ||
79 | r = qemu_vfio_dma_map(s->vfio, | ||
80 | qiov->iov[i].iov_base, | ||
81 | - len, true, &iova); | ||
82 | + len, true, &iova, NULL); | ||
83 | if (r == -ENOSPC) { | ||
84 | /* | ||
85 | * In addition to the -ENOMEM error, the VFIO_IOMMU_MAP_DMA | ||
86 | @@ -XXX,XX +XXX,XX @@ static void nvme_aio_unplug(BlockDriverState *bs) | ||
87 | static void nvme_register_buf(BlockDriverState *bs, void *host, size_t size) | ||
88 | { | ||
89 | int ret; | ||
90 | + Error *local_err = NULL; | ||
91 | BDRVNVMeState *s = bs->opaque; | ||
92 | |||
93 | - ret = qemu_vfio_dma_map(s->vfio, host, size, false, NULL); | ||
94 | + ret = qemu_vfio_dma_map(s->vfio, host, size, false, NULL, &local_err); | ||
95 | if (ret) { | ||
96 | /* FIXME: we may run out of IOVA addresses after repeated | ||
97 | * bdrv_register_buf/bdrv_unregister_buf, because nvme_vfio_dma_unmap | ||
98 | * doesn't reclaim addresses for fixed mappings. */ | ||
99 | - error_report("nvme_register_buf failed: %s", strerror(-ret)); | ||
100 | + error_reportf_err(local_err, "nvme_register_buf failed: "); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c | ||
105 | index XXXXXXX..XXXXXXX 100644 | ||
106 | --- a/util/vfio-helpers.c | ||
107 | +++ b/util/vfio-helpers.c | ||
108 | @@ -XXX,XX +XXX,XX @@ static void qemu_vfio_ram_block_added(RAMBlockNotifier *n, void *host, | ||
109 | size_t size, size_t max_size) | ||
110 | { | ||
111 | QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier); | ||
112 | + Error *local_err = NULL; | ||
113 | int ret; | ||
114 | |||
115 | trace_qemu_vfio_ram_block_added(s, host, max_size); | ||
116 | - ret = qemu_vfio_dma_map(s, host, max_size, false, NULL); | ||
117 | + ret = qemu_vfio_dma_map(s, host, max_size, false, NULL, &local_err); | ||
118 | if (ret) { | ||
119 | - error_report("qemu_vfio_dma_map(%p, %zu) failed: %s", host, max_size, | ||
120 | - strerror(-ret)); | ||
121 | + error_reportf_err(local_err, | ||
122 | + "qemu_vfio_dma_map(%p, %zu) failed: ", | ||
123 | + host, max_size); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | @@ -XXX,XX +XXX,XX @@ qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova) | ||
128 | * mapping status within this area is not allowed). | ||
129 | */ | ||
130 | int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
131 | - bool temporary, uint64_t *iova) | ||
132 | + bool temporary, uint64_t *iova, Error **errp) | ||
133 | { | ||
134 | int ret = 0; | ||
135 | int index; | ||
136 | -- | ||
137 | 2.31.1 | ||
138 | |||
139 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | Extract qemu_vfio_water_mark_reached() for readability, | ||
4 | and have it provide an error hint it its Error* handle. | ||
5 | |||
6 | Suggested-by: Klaus Jensen <k.jensen@samsung.com> | ||
7 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
9 | Message-id: 20210902070025.197072-8-philmd@redhat.com | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | util/vfio-helpers.c | 17 ++++++++++++++++- | ||
13 | 1 file changed, 16 insertions(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/util/vfio-helpers.c | ||
18 | +++ b/util/vfio-helpers.c | ||
19 | @@ -XXX,XX +XXX,XX @@ qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova) | ||
20 | return -ENOMEM; | ||
21 | } | ||
22 | |||
23 | +/** | ||
24 | + * qemu_vfio_water_mark_reached: | ||
25 | + * | ||
26 | + * Returns %true if high watermark has been reached, %false otherwise. | ||
27 | + */ | ||
28 | +static bool qemu_vfio_water_mark_reached(QEMUVFIOState *s, size_t size, | ||
29 | + Error **errp) | ||
30 | +{ | ||
31 | + if (s->high_water_mark - s->low_water_mark + 1 < size) { | ||
32 | + error_setg(errp, "iova exhausted (water mark reached)"); | ||
33 | + return true; | ||
34 | + } | ||
35 | + return false; | ||
36 | +} | ||
37 | + | ||
38 | /* Map [host, host + size) area into a contiguous IOVA address space, and store | ||
39 | * the result in @iova if not NULL. The caller need to make sure the area is | ||
40 | * aligned to page size, and mustn't overlap with existing mapping areas (split | ||
41 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
42 | if (mapping) { | ||
43 | iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host); | ||
44 | } else { | ||
45 | - if (s->high_water_mark - s->low_water_mark + 1 < size) { | ||
46 | + if (qemu_vfio_water_mark_reached(s, size, errp)) { | ||
47 | ret = -ENOMEM; | ||
48 | goto out; | ||
49 | } | ||
50 | -- | ||
51 | 2.31.1 | ||
52 | |||
53 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | Both qemu_vfio_find_fixed_iova() and qemu_vfio_find_temp_iova() | ||
4 | return an errno which is unused (or overwritten). Have them propagate | ||
5 | eventual errors to callers, returning a boolean (which is what the | ||
6 | Error API recommends, see commit e3fe3988d78 "error: Document Error | ||
7 | API usage rules" for rationale). | ||
8 | |||
9 | Suggested-by: Klaus Jensen <k.jensen@samsung.com> | ||
10 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
11 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
12 | Message-id: 20210902070025.197072-9-philmd@redhat.com | ||
13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
14 | --- | ||
15 | util/vfio-helpers.c | 24 ++++++++++++++---------- | ||
16 | 1 file changed, 14 insertions(+), 10 deletions(-) | ||
17 | |||
18 | diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/util/vfio-helpers.c | ||
21 | +++ b/util/vfio-helpers.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static bool qemu_vfio_verify_mappings(QEMUVFIOState *s) | ||
23 | return true; | ||
24 | } | ||
25 | |||
26 | -static int | ||
27 | -qemu_vfio_find_fixed_iova(QEMUVFIOState *s, size_t size, uint64_t *iova) | ||
28 | +static bool qemu_vfio_find_fixed_iova(QEMUVFIOState *s, size_t size, | ||
29 | + uint64_t *iova, Error **errp) | ||
30 | { | ||
31 | int i; | ||
32 | |||
33 | @@ -XXX,XX +XXX,XX @@ qemu_vfio_find_fixed_iova(QEMUVFIOState *s, size_t size, uint64_t *iova) | ||
34 | s->usable_iova_ranges[i].end - s->low_water_mark + 1 == 0) { | ||
35 | *iova = s->low_water_mark; | ||
36 | s->low_water_mark += size; | ||
37 | - return 0; | ||
38 | + return true; | ||
39 | } | ||
40 | } | ||
41 | - return -ENOMEM; | ||
42 | + error_setg(errp, "fixed iova range not found"); | ||
43 | + | ||
44 | + return false; | ||
45 | } | ||
46 | |||
47 | -static int | ||
48 | -qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova) | ||
49 | +static bool qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, | ||
50 | + uint64_t *iova, Error **errp) | ||
51 | { | ||
52 | int i; | ||
53 | |||
54 | @@ -XXX,XX +XXX,XX @@ qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova) | ||
55 | s->high_water_mark - s->usable_iova_ranges[i].start + 1 == 0) { | ||
56 | *iova = s->high_water_mark - size; | ||
57 | s->high_water_mark = *iova; | ||
58 | - return 0; | ||
59 | + return true; | ||
60 | } | ||
61 | } | ||
62 | - return -ENOMEM; | ||
63 | + error_setg(errp, "temporary iova range not found"); | ||
64 | + | ||
65 | + return false; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
70 | goto out; | ||
71 | } | ||
72 | if (!temporary) { | ||
73 | - if (qemu_vfio_find_fixed_iova(s, size, &iova0)) { | ||
74 | + if (!qemu_vfio_find_fixed_iova(s, size, &iova0, errp)) { | ||
75 | ret = -ENOMEM; | ||
76 | goto out; | ||
77 | } | ||
78 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
79 | } | ||
80 | qemu_vfio_dump_mappings(s); | ||
81 | } else { | ||
82 | - if (qemu_vfio_find_temp_iova(s, size, &iova0)) { | ||
83 | + if (!qemu_vfio_find_temp_iova(s, size, &iova0, errp)) { | ||
84 | ret = -ENOMEM; | ||
85 | goto out; | ||
86 | } | ||
87 | -- | ||
88 | 2.31.1 | ||
89 | |||
90 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | To simplify qemu_vfio_dma_map(): | ||
4 | - reduce 'ret' (returned value) scope by returning errno directly, | ||
5 | - remove the goto 'out' label. | ||
6 | |||
7 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
9 | Message-id: 20210902070025.197072-10-philmd@redhat.com | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | util/vfio-helpers.c | 23 ++++++++++------------- | ||
13 | 1 file changed, 10 insertions(+), 13 deletions(-) | ||
14 | |||
15 | diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/util/vfio-helpers.c | ||
18 | +++ b/util/vfio-helpers.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static bool qemu_vfio_water_mark_reached(QEMUVFIOState *s, size_t size, | ||
20 | int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
21 | bool temporary, uint64_t *iova, Error **errp) | ||
22 | { | ||
23 | - int ret = 0; | ||
24 | int index; | ||
25 | IOVAMapping *mapping; | ||
26 | uint64_t iova0; | ||
27 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
28 | if (mapping) { | ||
29 | iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host); | ||
30 | } else { | ||
31 | + int ret; | ||
32 | + | ||
33 | if (qemu_vfio_water_mark_reached(s, size, errp)) { | ||
34 | - ret = -ENOMEM; | ||
35 | - goto out; | ||
36 | + return -ENOMEM; | ||
37 | } | ||
38 | if (!temporary) { | ||
39 | if (!qemu_vfio_find_fixed_iova(s, size, &iova0, errp)) { | ||
40 | - ret = -ENOMEM; | ||
41 | - goto out; | ||
42 | + return -ENOMEM; | ||
43 | } | ||
44 | |||
45 | mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0); | ||
46 | assert(qemu_vfio_verify_mappings(s)); | ||
47 | ret = qemu_vfio_do_mapping(s, host, size, iova0); | ||
48 | - if (ret) { | ||
49 | + if (ret < 0) { | ||
50 | qemu_vfio_undo_mapping(s, mapping, NULL); | ||
51 | - goto out; | ||
52 | + return ret; | ||
53 | } | ||
54 | qemu_vfio_dump_mappings(s); | ||
55 | } else { | ||
56 | if (!qemu_vfio_find_temp_iova(s, size, &iova0, errp)) { | ||
57 | - ret = -ENOMEM; | ||
58 | - goto out; | ||
59 | + return -ENOMEM; | ||
60 | } | ||
61 | ret = qemu_vfio_do_mapping(s, host, size, iova0); | ||
62 | - if (ret) { | ||
63 | - goto out; | ||
64 | + if (ret < 0) { | ||
65 | + return ret; | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
70 | if (iova) { | ||
71 | *iova = iova0; | ||
72 | } | ||
73 | -out: | ||
74 | - return ret; | ||
75 | + return 0; | ||
76 | } | ||
77 | |||
78 | /* Reset the high watermark and free all "temporary" mappings. */ | ||
79 | -- | ||
80 | 2.31.1 | ||
81 | |||
82 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | Pass qemu_vfio_do_mapping() an Error* argument so it can propagate | ||
4 | any error to callers. Replace error_report() which only report | ||
5 | to the monitor by the more generic error_setg_errno(). | ||
6 | |||
7 | Reviewed-by: Fam Zheng <fam@euphon.net> | ||
8 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
9 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | ||
10 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
11 | Message-id: 20210902070025.197072-11-philmd@redhat.com | ||
12 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
13 | --- | ||
14 | util/vfio-helpers.c | 8 ++++---- | ||
15 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
16 | |||
17 | diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/util/vfio-helpers.c | ||
20 | +++ b/util/vfio-helpers.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static IOVAMapping *qemu_vfio_add_mapping(QEMUVFIOState *s, | ||
22 | |||
23 | /* Do the DMA mapping with VFIO. */ | ||
24 | static int qemu_vfio_do_mapping(QEMUVFIOState *s, void *host, size_t size, | ||
25 | - uint64_t iova) | ||
26 | + uint64_t iova, Error **errp) | ||
27 | { | ||
28 | struct vfio_iommu_type1_dma_map dma_map = { | ||
29 | .argsz = sizeof(dma_map), | ||
30 | @@ -XXX,XX +XXX,XX @@ static int qemu_vfio_do_mapping(QEMUVFIOState *s, void *host, size_t size, | ||
31 | trace_qemu_vfio_do_mapping(s, host, iova, size); | ||
32 | |||
33 | if (ioctl(s->container, VFIO_IOMMU_MAP_DMA, &dma_map)) { | ||
34 | - error_report("VFIO_MAP_DMA failed: %s", strerror(errno)); | ||
35 | + error_setg_errno(errp, errno, "VFIO_MAP_DMA failed"); | ||
36 | return -errno; | ||
37 | } | ||
38 | return 0; | ||
39 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
40 | |||
41 | mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0); | ||
42 | assert(qemu_vfio_verify_mappings(s)); | ||
43 | - ret = qemu_vfio_do_mapping(s, host, size, iova0); | ||
44 | + ret = qemu_vfio_do_mapping(s, host, size, iova0, errp); | ||
45 | if (ret < 0) { | ||
46 | qemu_vfio_undo_mapping(s, mapping, NULL); | ||
47 | return ret; | ||
48 | @@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, | ||
49 | if (!qemu_vfio_find_temp_iova(s, size, &iova0, errp)) { | ||
50 | return -ENOMEM; | ||
51 | } | ||
52 | - ret = qemu_vfio_do_mapping(s, host, size, iova0); | ||
53 | + ret = qemu_vfio_do_mapping(s, host, size, iova0, errp); | ||
54 | if (ret < 0) { | ||
55 | return ret; | ||
56 | } | ||
57 | -- | ||
58 | 2.31.1 | ||
59 | |||
60 | diff view generated by jsdifflib |
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | 1 | From: Denis Rastyogin <gerben@altlinux.org> |
---|---|---|---|
2 | 2 | ||
3 | We expect the first qemu_vfio_dma_map() to fail (indicating | 3 | This error was discovered by fuzzing qemu-img. |
4 | DMA mappings exhaustion, see commit 15a730e7a3a). Do not | ||
5 | report the first failure as error, since we are going to | ||
6 | flush the mappings and retry. | ||
7 | 4 | ||
8 | This removes spurious error message displayed on the monitor: | 5 | In the QED block driver, the need_check_timer timer is freed in |
6 | bdrv_qed_detach_aio_context, but the pointer to the timer is not | ||
7 | set to NULL. This can lead to a use-after-free scenario | ||
8 | in bdrv_qed_drain_begin(). | ||
9 | 9 | ||
10 | (qemu) c | 10 | The need_check_timer pointer is set to NULL after freeing the timer. |
11 | (qemu) qemu-kvm: VFIO_MAP_DMA failed: No space left on device | 11 | Which helps catch this condition when checking in bdrv_qed_drain_begin(). |
12 | (qemu) info status | ||
13 | VM status: running | ||
14 | 12 | ||
15 | Reported-by: Tingting Mao <timao@redhat.com> | 13 | Closes: https://gitlab.com/qemu-project/qemu/-/issues/2852 |
16 | Reviewed-by: Klaus Jensen <k.jensen@samsung.com> | 14 | Signed-off-by: Denis Rastyogin <gerben@altlinux.org> |
17 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | 15 | Message-ID: <20250304083927.37681-1-gerben@altlinux.org> |
18 | Message-id: 20210902070025.197072-12-philmd@redhat.com | ||
19 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 16 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
20 | --- | 17 | --- |
21 | block/nvme.c | 8 +++++++- | 18 | block/qed.c | 1 + |
22 | 1 file changed, 7 insertions(+), 1 deletion(-) | 19 | 1 file changed, 1 insertion(+) |
23 | 20 | ||
24 | diff --git a/block/nvme.c b/block/nvme.c | 21 | diff --git a/block/qed.c b/block/qed.c |
25 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
26 | --- a/block/nvme.c | 23 | --- a/block/qed.c |
27 | +++ b/block/nvme.c | 24 | +++ b/block/qed.c |
28 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd, | 25 | @@ -XXX,XX +XXX,XX @@ static void bdrv_qed_detach_aio_context(BlockDriverState *bs) |
29 | uint64_t *pagelist = req->prp_list_page; | 26 | |
30 | int i, j, r; | 27 | qed_cancel_need_check_timer(s); |
31 | int entries = 0; | 28 | timer_free(s->need_check_timer); |
32 | + Error *local_err = NULL, **errp = NULL; | 29 | + s->need_check_timer = NULL; |
33 | |||
34 | assert(qiov->size); | ||
35 | assert(QEMU_IS_ALIGNED(qiov->size, s->page_size)); | ||
36 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd, | ||
37 | try_map: | ||
38 | r = qemu_vfio_dma_map(s->vfio, | ||
39 | qiov->iov[i].iov_base, | ||
40 | - len, true, &iova, NULL); | ||
41 | + len, true, &iova, errp); | ||
42 | if (r == -ENOSPC) { | ||
43 | /* | ||
44 | * In addition to the -ENOMEM error, the VFIO_IOMMU_MAP_DMA | ||
45 | @@ -XXX,XX +XXX,XX @@ try_map: | ||
46 | goto fail; | ||
47 | } | ||
48 | } | ||
49 | + errp = &local_err; | ||
50 | + | ||
51 | goto try_map; | ||
52 | } | ||
53 | if (r) { | ||
54 | @@ -XXX,XX +XXX,XX @@ fail: | ||
55 | * because they are already mapped before calling this function; for | ||
56 | * temporary mappings, a later nvme_cmd_(un)map_qiov will reclaim by | ||
57 | * calling qemu_vfio_dma_reset_temporary when necessary. */ | ||
58 | + if (local_err) { | ||
59 | + error_reportf_err(local_err, "Cannot map buffer for DMA: "); | ||
60 | + } | ||
61 | return r; | ||
62 | } | 30 | } |
63 | 31 | ||
32 | static void bdrv_qed_attach_aio_context(BlockDriverState *bs, | ||
64 | -- | 33 | -- |
65 | 2.31.1 | 34 | 2.48.1 |
66 | |||
67 | diff view generated by jsdifflib |