diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-16 16:14:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-16 16:14:46 -0500 |
commit | 18c83d2c0390fd0e8336ad090a047c56037d19f5 (patch) | |
tree | 7042614cea7b22d5b0fa35ee7a4fa95124008246 | |
parent | 051089a2eed9a9977080774f3793ff2688cd3878 (diff) | |
parent | c1d0c3f623ada808904dec676da0126f5b800630 (diff) |
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio updates from Michael Tsirkin:
"Fixes in qemu, vhost and virtio"
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
fw_cfg: fix the command line module name
vhost/vsock: fix uninitialized vhost_vsock->guest_cid
vhost: fix end of range for access_ok
vhost/scsi: Use safe iteration in vhost_scsi_complete_cmd_work()
virtio_balloon: fix deadlock on OOM
-rw-r--r-- | drivers/firmware/qemu_fw_cfg.c | 8 | ||||
-rw-r--r-- | drivers/vhost/scsi.c | 4 | ||||
-rw-r--r-- | drivers/vhost/vhost.c | 4 | ||||
-rw-r--r-- | drivers/vhost/vsock.c | 2 | ||||
-rw-r--r-- | drivers/virtio/virtio_balloon.c | 24 | ||||
-rw-r--r-- | include/linux/balloon_compaction.h | 35 | ||||
-rw-r--r-- | mm/balloon_compaction.c | 28 |
7 files changed, 84 insertions, 21 deletions
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 0e2011636fbb..5cfe39f7a45f 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c | |||
@@ -10,9 +10,9 @@ | |||
10 | * and select subsets of aarch64), a Device Tree node (on arm), or using | 10 | * and select subsets of aarch64), a Device Tree node (on arm), or using |
11 | * a kernel module (or command line) parameter with the following syntax: | 11 | * a kernel module (or command line) parameter with the following syntax: |
12 | * | 12 | * |
13 | * [fw_cfg.]ioport=<size>@<base>[:<ctrl_off>:<data_off>] | 13 | * [qemu_fw_cfg.]ioport=<size>@<base>[:<ctrl_off>:<data_off>] |
14 | * or | 14 | * or |
15 | * [fw_cfg.]mmio=<size>@<base>[:<ctrl_off>:<data_off>] | 15 | * [qemu_fw_cfg.]mmio=<size>@<base>[:<ctrl_off>:<data_off>] |
16 | * | 16 | * |
17 | * where: | 17 | * where: |
18 | * <size> := size of ioport or mmio range | 18 | * <size> := size of ioport or mmio range |
@@ -21,9 +21,9 @@ | |||
21 | * <data_off> := (optional) offset of data register | 21 | * <data_off> := (optional) offset of data register |
22 | * | 22 | * |
23 | * e.g.: | 23 | * e.g.: |
24 | * fw_cfg.ioport=2@0x510:0:1 (the default on x86) | 24 | * qemu_fw_cfg.ioport=2@0x510:0:1 (the default on x86) |
25 | * or | 25 | * or |
26 | * fw_cfg.mmio=0xA@0x9020000:8:0 (the default on arm) | 26 | * qemu_fw_cfg.mmio=0xA@0x9020000:8:0 (the default on arm) |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 35e929f132e8..1bc9be829fb4 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -519,7 +519,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | |||
519 | vs_completion_work); | 519 | vs_completion_work); |
520 | DECLARE_BITMAP(signal, VHOST_SCSI_MAX_VQ); | 520 | DECLARE_BITMAP(signal, VHOST_SCSI_MAX_VQ); |
521 | struct virtio_scsi_cmd_resp v_rsp; | 521 | struct virtio_scsi_cmd_resp v_rsp; |
522 | struct vhost_scsi_cmd *cmd; | 522 | struct vhost_scsi_cmd *cmd, *t; |
523 | struct llist_node *llnode; | 523 | struct llist_node *llnode; |
524 | struct se_cmd *se_cmd; | 524 | struct se_cmd *se_cmd; |
525 | struct iov_iter iov_iter; | 525 | struct iov_iter iov_iter; |
@@ -527,7 +527,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | |||
527 | 527 | ||
528 | bitmap_zero(signal, VHOST_SCSI_MAX_VQ); | 528 | bitmap_zero(signal, VHOST_SCSI_MAX_VQ); |
529 | llnode = llist_del_all(&vs->vs_completion_list); | 529 | llnode = llist_del_all(&vs->vs_completion_list); |
530 | llist_for_each_entry(cmd, llnode, tvc_completion_list) { | 530 | llist_for_each_entry_safe(cmd, t, llnode, tvc_completion_list) { |
531 | se_cmd = &cmd->tvc_se_cmd; | 531 | se_cmd = &cmd->tvc_se_cmd; |
532 | 532 | ||
533 | pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__, | 533 | pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__, |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index d6dbb28245e6..33ac2b186b85 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -1175,7 +1175,7 @@ static int iotlb_access_ok(struct vhost_virtqueue *vq, | |||
1175 | { | 1175 | { |
1176 | const struct vhost_umem_node *node; | 1176 | const struct vhost_umem_node *node; |
1177 | struct vhost_umem *umem = vq->iotlb; | 1177 | struct vhost_umem *umem = vq->iotlb; |
1178 | u64 s = 0, size, orig_addr = addr; | 1178 | u64 s = 0, size, orig_addr = addr, last = addr + len - 1; |
1179 | 1179 | ||
1180 | if (vhost_vq_meta_fetch(vq, addr, len, type)) | 1180 | if (vhost_vq_meta_fetch(vq, addr, len, type)) |
1181 | return true; | 1181 | return true; |
@@ -1183,7 +1183,7 @@ static int iotlb_access_ok(struct vhost_virtqueue *vq, | |||
1183 | while (len > s) { | 1183 | while (len > s) { |
1184 | node = vhost_umem_interval_tree_iter_first(&umem->umem_tree, | 1184 | node = vhost_umem_interval_tree_iter_first(&umem->umem_tree, |
1185 | addr, | 1185 | addr, |
1186 | addr + len - 1); | 1186 | last); |
1187 | if (node == NULL || node->start > addr) { | 1187 | if (node == NULL || node->start > addr) { |
1188 | vhost_iotlb_miss(vq, addr, access); | 1188 | vhost_iotlb_miss(vq, addr, access); |
1189 | return false; | 1189 | return false; |
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index c9de9c41aa97..5a5e981bd8e4 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c | |||
@@ -518,6 +518,8 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) | |||
518 | goto out; | 518 | goto out; |
519 | } | 519 | } |
520 | 520 | ||
521 | vsock->guest_cid = 0; /* no CID assigned yet */ | ||
522 | |||
521 | atomic_set(&vsock->queued_replies, 0); | 523 | atomic_set(&vsock->queued_replies, 0); |
522 | 524 | ||
523 | vqs[VSOCK_VQ_TX] = &vsock->vqs[VSOCK_VQ_TX]; | 525 | vqs[VSOCK_VQ_TX] = &vsock->vqs[VSOCK_VQ_TX]; |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index f0b3a0b9d42f..7960746f7597 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -143,16 +143,17 @@ static void set_page_pfns(struct virtio_balloon *vb, | |||
143 | 143 | ||
144 | static unsigned fill_balloon(struct virtio_balloon *vb, size_t num) | 144 | static unsigned fill_balloon(struct virtio_balloon *vb, size_t num) |
145 | { | 145 | { |
146 | struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; | ||
147 | unsigned num_allocated_pages; | 146 | unsigned num_allocated_pages; |
147 | unsigned num_pfns; | ||
148 | struct page *page; | ||
149 | LIST_HEAD(pages); | ||
148 | 150 | ||
149 | /* We can only do one array worth at a time. */ | 151 | /* We can only do one array worth at a time. */ |
150 | num = min(num, ARRAY_SIZE(vb->pfns)); | 152 | num = min(num, ARRAY_SIZE(vb->pfns)); |
151 | 153 | ||
152 | mutex_lock(&vb->balloon_lock); | 154 | for (num_pfns = 0; num_pfns < num; |
153 | for (vb->num_pfns = 0; vb->num_pfns < num; | 155 | num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { |
154 | vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { | 156 | struct page *page = balloon_page_alloc(); |
155 | struct page *page = balloon_page_enqueue(vb_dev_info); | ||
156 | 157 | ||
157 | if (!page) { | 158 | if (!page) { |
158 | dev_info_ratelimited(&vb->vdev->dev, | 159 | dev_info_ratelimited(&vb->vdev->dev, |
@@ -162,6 +163,19 @@ static unsigned fill_balloon(struct virtio_balloon *vb, size_t num) | |||
162 | msleep(200); | 163 | msleep(200); |
163 | break; | 164 | break; |
164 | } | 165 | } |
166 | |||
167 | balloon_page_push(&pages, page); | ||
168 | } | ||
169 | |||
170 | mutex_lock(&vb->balloon_lock); | ||
171 | |||
172 | vb->num_pfns = 0; | ||
173 | |||
174 | while ((page = balloon_page_pop(&pages))) { | ||
175 | balloon_page_enqueue(&vb->vb_dev_info, page); | ||
176 | |||
177 | vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE; | ||
178 | |||
165 | set_page_pfns(vb, vb->pfns + vb->num_pfns, page); | 179 | set_page_pfns(vb, vb->pfns + vb->num_pfns, page); |
166 | vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE; | 180 | vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE; |
167 | if (!virtio_has_feature(vb->vdev, | 181 | if (!virtio_has_feature(vb->vdev, |
diff --git a/include/linux/balloon_compaction.h b/include/linux/balloon_compaction.h index fbbe6da40fed..53051f3d8f25 100644 --- a/include/linux/balloon_compaction.h +++ b/include/linux/balloon_compaction.h | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/gfp.h> | 50 | #include <linux/gfp.h> |
51 | #include <linux/err.h> | 51 | #include <linux/err.h> |
52 | #include <linux/fs.h> | 52 | #include <linux/fs.h> |
53 | #include <linux/list.h> | ||
53 | 54 | ||
54 | /* | 55 | /* |
55 | * Balloon device information descriptor. | 56 | * Balloon device information descriptor. |
@@ -67,7 +68,9 @@ struct balloon_dev_info { | |||
67 | struct inode *inode; | 68 | struct inode *inode; |
68 | }; | 69 | }; |
69 | 70 | ||
70 | extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info); | 71 | extern struct page *balloon_page_alloc(void); |
72 | extern void balloon_page_enqueue(struct balloon_dev_info *b_dev_info, | ||
73 | struct page *page); | ||
71 | extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info); | 74 | extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info); |
72 | 75 | ||
73 | static inline void balloon_devinfo_init(struct balloon_dev_info *balloon) | 76 | static inline void balloon_devinfo_init(struct balloon_dev_info *balloon) |
@@ -193,4 +196,34 @@ static inline gfp_t balloon_mapping_gfp_mask(void) | |||
193 | } | 196 | } |
194 | 197 | ||
195 | #endif /* CONFIG_BALLOON_COMPACTION */ | 198 | #endif /* CONFIG_BALLOON_COMPACTION */ |
199 | |||
200 | /* | ||
201 | * balloon_page_push - insert a page into a page list. | ||
202 | * @head : pointer to list | ||
203 | * @page : page to be added | ||
204 | * | ||
205 | * Caller must ensure the page is private and protect the list. | ||
206 | */ | ||
207 | static inline void balloon_page_push(struct list_head *pages, struct page *page) | ||
208 | { | ||
209 | list_add(&page->lru, pages); | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * balloon_page_pop - remove a page from a page list. | ||
214 | * @head : pointer to list | ||
215 | * @page : page to be added | ||
216 | * | ||
217 | * Caller must ensure the page is private and protect the list. | ||
218 | */ | ||
219 | static inline struct page *balloon_page_pop(struct list_head *pages) | ||
220 | { | ||
221 | struct page *page = list_first_entry_or_null(pages, struct page, lru); | ||
222 | |||
223 | if (!page) | ||
224 | return NULL; | ||
225 | |||
226 | list_del(&page->lru); | ||
227 | return page; | ||
228 | } | ||
196 | #endif /* _LINUX_BALLOON_COMPACTION_H */ | 229 | #endif /* _LINUX_BALLOON_COMPACTION_H */ |
diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c index 68d28924ba79..ef858d547e2d 100644 --- a/mm/balloon_compaction.c +++ b/mm/balloon_compaction.c | |||
@@ -11,22 +11,37 @@ | |||
11 | #include <linux/balloon_compaction.h> | 11 | #include <linux/balloon_compaction.h> |
12 | 12 | ||
13 | /* | 13 | /* |
14 | * balloon_page_alloc - allocates a new page for insertion into the balloon | ||
15 | * page list. | ||
16 | * | ||
17 | * Driver must call it to properly allocate a new enlisted balloon page. | ||
18 | * Driver must call balloon_page_enqueue before definitively removing it from | ||
19 | * the guest system. This function returns the page address for the recently | ||
20 | * allocated page or NULL in the case we fail to allocate a new page this turn. | ||
21 | */ | ||
22 | struct page *balloon_page_alloc(void) | ||
23 | { | ||
24 | struct page *page = alloc_page(balloon_mapping_gfp_mask() | | ||
25 | __GFP_NOMEMALLOC | __GFP_NORETRY); | ||
26 | return page; | ||
27 | } | ||
28 | EXPORT_SYMBOL_GPL(balloon_page_alloc); | ||
29 | |||
30 | /* | ||
14 | * balloon_page_enqueue - allocates a new page and inserts it into the balloon | 31 | * balloon_page_enqueue - allocates a new page and inserts it into the balloon |
15 | * page list. | 32 | * page list. |
16 | * @b_dev_info: balloon device descriptor where we will insert a new page to | 33 | * @b_dev_info: balloon device descriptor where we will insert a new page to |
34 | * @page: new page to enqueue - allocated using balloon_page_alloc. | ||
17 | * | 35 | * |
18 | * Driver must call it to properly allocate a new enlisted balloon page | 36 | * Driver must call it to properly enqueue a new allocated balloon page |
19 | * before definitively removing it from the guest system. | 37 | * before definitively removing it from the guest system. |
20 | * This function returns the page address for the recently enqueued page or | 38 | * This function returns the page address for the recently enqueued page or |
21 | * NULL in the case we fail to allocate a new page this turn. | 39 | * NULL in the case we fail to allocate a new page this turn. |
22 | */ | 40 | */ |
23 | struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info) | 41 | void balloon_page_enqueue(struct balloon_dev_info *b_dev_info, |
42 | struct page *page) | ||
24 | { | 43 | { |
25 | unsigned long flags; | 44 | unsigned long flags; |
26 | struct page *page = alloc_page(balloon_mapping_gfp_mask() | | ||
27 | __GFP_NOMEMALLOC | __GFP_NORETRY); | ||
28 | if (!page) | ||
29 | return NULL; | ||
30 | 45 | ||
31 | /* | 46 | /* |
32 | * Block others from accessing the 'page' when we get around to | 47 | * Block others from accessing the 'page' when we get around to |
@@ -39,7 +54,6 @@ struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info) | |||
39 | __count_vm_event(BALLOON_INFLATE); | 54 | __count_vm_event(BALLOON_INFLATE); |
40 | spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); | 55 | spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); |
41 | unlock_page(page); | 56 | unlock_page(page); |
42 | return page; | ||
43 | } | 57 | } |
44 | EXPORT_SYMBOL_GPL(balloon_page_enqueue); | 58 | EXPORT_SYMBOL_GPL(balloon_page_enqueue); |
45 | 59 | ||