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 | ||
