diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-02 21:54:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-02 21:54:45 -0500 |
commit | d548e65904ae43b0637d200a2441fc94e0589c30 (patch) | |
tree | bc19ab13a760684d96e6e61121d5a978e1fae2b6 | |
parent | 77d0b194b2df04a1992f882d96ff4e2bd8bb8fe0 (diff) | |
parent | a691ffb46edd7cb12a17ff0965ab59dbc95f48de (diff) |
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio/vhost updates from Michael Tsirkin:
"Features, fixes, cleanups:
- discard in virtio blk
- misc fixes and cleanups"
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
vhost: correct the related warning message
vhost: split structs into a separate header file
virtio: remove deprecated VIRTIO_PCI_CONFIG()
vhost/vsock: switch to a mutex for vhost_vsock_hash
virtio_blk: add discard and write zeroes support
-rw-r--r-- | drivers/block/virtio_blk.c | 83 | ||||
-rw-r--r-- | drivers/vhost/scsi.c | 4 | ||||
-rw-r--r-- | drivers/vhost/vsock.c | 16 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci_legacy.c | 6 | ||||
-rw-r--r-- | include/uapi/linux/vhost.h | 113 | ||||
-rw-r--r-- | include/uapi/linux/vhost_types.h | 128 | ||||
-rw-r--r-- | include/uapi/linux/virtio_blk.h | 54 |
7 files changed, 279 insertions, 125 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 912c4265e592..b16a887bbd02 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #define PART_BITS 4 | 19 | #define PART_BITS 4 |
20 | #define VQ_NAME_LEN 16 | 20 | #define VQ_NAME_LEN 16 |
21 | #define MAX_DISCARD_SEGMENTS 256u | ||
21 | 22 | ||
22 | static int major; | 23 | static int major; |
23 | static DEFINE_IDA(vd_index_ida); | 24 | static DEFINE_IDA(vd_index_ida); |
@@ -172,10 +173,48 @@ static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr, | |||
172 | return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC); | 173 | return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC); |
173 | } | 174 | } |
174 | 175 | ||
176 | static int virtblk_setup_discard_write_zeroes(struct request *req, bool unmap) | ||
177 | { | ||
178 | unsigned short segments = blk_rq_nr_discard_segments(req); | ||
179 | unsigned short n = 0; | ||
180 | struct virtio_blk_discard_write_zeroes *range; | ||
181 | struct bio *bio; | ||
182 | u32 flags = 0; | ||
183 | |||
184 | if (unmap) | ||
185 | flags |= VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP; | ||
186 | |||
187 | range = kmalloc_array(segments, sizeof(*range), GFP_ATOMIC); | ||
188 | if (!range) | ||
189 | return -ENOMEM; | ||
190 | |||
191 | __rq_for_each_bio(bio, req) { | ||
192 | u64 sector = bio->bi_iter.bi_sector; | ||
193 | u32 num_sectors = bio->bi_iter.bi_size >> SECTOR_SHIFT; | ||
194 | |||
195 | range[n].flags = cpu_to_le32(flags); | ||
196 | range[n].num_sectors = cpu_to_le32(num_sectors); | ||
197 | range[n].sector = cpu_to_le64(sector); | ||
198 | n++; | ||
199 | } | ||
200 | |||
201 | req->special_vec.bv_page = virt_to_page(range); | ||
202 | req->special_vec.bv_offset = offset_in_page(range); | ||
203 | req->special_vec.bv_len = sizeof(*range) * segments; | ||
204 | req->rq_flags |= RQF_SPECIAL_PAYLOAD; | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
175 | static inline void virtblk_request_done(struct request *req) | 209 | static inline void virtblk_request_done(struct request *req) |
176 | { | 210 | { |
177 | struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); | 211 | struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); |
178 | 212 | ||
213 | if (req->rq_flags & RQF_SPECIAL_PAYLOAD) { | ||
214 | kfree(page_address(req->special_vec.bv_page) + | ||
215 | req->special_vec.bv_offset); | ||
216 | } | ||
217 | |||
179 | switch (req_op(req)) { | 218 | switch (req_op(req)) { |
180 | case REQ_OP_SCSI_IN: | 219 | case REQ_OP_SCSI_IN: |
181 | case REQ_OP_SCSI_OUT: | 220 | case REQ_OP_SCSI_OUT: |
@@ -239,6 +278,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
239 | int qid = hctx->queue_num; | 278 | int qid = hctx->queue_num; |
240 | int err; | 279 | int err; |
241 | bool notify = false; | 280 | bool notify = false; |
281 | bool unmap = false; | ||
242 | u32 type; | 282 | u32 type; |
243 | 283 | ||
244 | BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); | 284 | BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); |
@@ -251,6 +291,13 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
251 | case REQ_OP_FLUSH: | 291 | case REQ_OP_FLUSH: |
252 | type = VIRTIO_BLK_T_FLUSH; | 292 | type = VIRTIO_BLK_T_FLUSH; |
253 | break; | 293 | break; |
294 | case REQ_OP_DISCARD: | ||
295 | type = VIRTIO_BLK_T_DISCARD; | ||
296 | break; | ||
297 | case REQ_OP_WRITE_ZEROES: | ||
298 | type = VIRTIO_BLK_T_WRITE_ZEROES; | ||
299 | unmap = !(req->cmd_flags & REQ_NOUNMAP); | ||
300 | break; | ||
254 | case REQ_OP_SCSI_IN: | 301 | case REQ_OP_SCSI_IN: |
255 | case REQ_OP_SCSI_OUT: | 302 | case REQ_OP_SCSI_OUT: |
256 | type = VIRTIO_BLK_T_SCSI_CMD; | 303 | type = VIRTIO_BLK_T_SCSI_CMD; |
@@ -270,6 +317,12 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
270 | 317 | ||
271 | blk_mq_start_request(req); | 318 | blk_mq_start_request(req); |
272 | 319 | ||
320 | if (type == VIRTIO_BLK_T_DISCARD || type == VIRTIO_BLK_T_WRITE_ZEROES) { | ||
321 | err = virtblk_setup_discard_write_zeroes(req, unmap); | ||
322 | if (err) | ||
323 | return BLK_STS_RESOURCE; | ||
324 | } | ||
325 | |||
273 | num = blk_rq_map_sg(hctx->queue, req, vbr->sg); | 326 | num = blk_rq_map_sg(hctx->queue, req, vbr->sg); |
274 | if (num) { | 327 | if (num) { |
275 | if (rq_data_dir(req) == WRITE) | 328 | if (rq_data_dir(req) == WRITE) |
@@ -817,6 +870,32 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
817 | if (!err && opt_io_size) | 870 | if (!err && opt_io_size) |
818 | blk_queue_io_opt(q, blk_size * opt_io_size); | 871 | blk_queue_io_opt(q, blk_size * opt_io_size); |
819 | 872 | ||
873 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_DISCARD)) { | ||
874 | q->limits.discard_granularity = blk_size; | ||
875 | |||
876 | virtio_cread(vdev, struct virtio_blk_config, | ||
877 | discard_sector_alignment, &v); | ||
878 | q->limits.discard_alignment = v ? v << SECTOR_SHIFT : 0; | ||
879 | |||
880 | virtio_cread(vdev, struct virtio_blk_config, | ||
881 | max_discard_sectors, &v); | ||
882 | blk_queue_max_discard_sectors(q, v ? v : UINT_MAX); | ||
883 | |||
884 | virtio_cread(vdev, struct virtio_blk_config, max_discard_seg, | ||
885 | &v); | ||
886 | blk_queue_max_discard_segments(q, | ||
887 | min_not_zero(v, | ||
888 | MAX_DISCARD_SEGMENTS)); | ||
889 | |||
890 | blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); | ||
891 | } | ||
892 | |||
893 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_WRITE_ZEROES)) { | ||
894 | virtio_cread(vdev, struct virtio_blk_config, | ||
895 | max_write_zeroes_sectors, &v); | ||
896 | blk_queue_max_write_zeroes_sectors(q, v ? v : UINT_MAX); | ||
897 | } | ||
898 | |||
820 | virtblk_update_capacity(vblk, false); | 899 | virtblk_update_capacity(vblk, false); |
821 | virtio_device_ready(vdev); | 900 | virtio_device_ready(vdev); |
822 | 901 | ||
@@ -910,14 +989,14 @@ static unsigned int features_legacy[] = { | |||
910 | VIRTIO_BLK_F_SCSI, | 989 | VIRTIO_BLK_F_SCSI, |
911 | #endif | 990 | #endif |
912 | VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, | 991 | VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, |
913 | VIRTIO_BLK_F_MQ, | 992 | VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES, |
914 | } | 993 | } |
915 | ; | 994 | ; |
916 | static unsigned int features[] = { | 995 | static unsigned int features[] = { |
917 | VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, | 996 | VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, |
918 | VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, | 997 | VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, |
919 | VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, | 998 | VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, |
920 | VIRTIO_BLK_F_MQ, | 999 | VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES, |
921 | }; | 1000 | }; |
922 | 1001 | ||
923 | static struct virtio_driver virtio_blk = { | 1002 | static struct virtio_driver virtio_blk = { |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index a08472ae5b1b..8e10ab436d1f 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -884,7 +884,7 @@ vhost_scsi_get_req(struct vhost_virtqueue *vq, struct vhost_scsi_ctx *vc, | |||
884 | 884 | ||
885 | if (unlikely(!copy_from_iter_full(vc->req, vc->req_size, | 885 | if (unlikely(!copy_from_iter_full(vc->req, vc->req_size, |
886 | &vc->out_iter))) { | 886 | &vc->out_iter))) { |
887 | vq_err(vq, "Faulted on copy_from_iter\n"); | 887 | vq_err(vq, "Faulted on copy_from_iter_full\n"); |
888 | } else if (unlikely(*vc->lunp != 1)) { | 888 | } else if (unlikely(*vc->lunp != 1)) { |
889 | /* virtio-scsi spec requires byte 0 of the lun to be 1 */ | 889 | /* virtio-scsi spec requires byte 0 of the lun to be 1 */ |
890 | vq_err(vq, "Illegal virtio-scsi lun: %u\n", *vc->lunp); | 890 | vq_err(vq, "Illegal virtio-scsi lun: %u\n", *vc->lunp); |
@@ -1436,7 +1436,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs, | |||
1436 | se_tpg = &tpg->se_tpg; | 1436 | se_tpg = &tpg->se_tpg; |
1437 | ret = target_depend_item(&se_tpg->tpg_group.cg_item); | 1437 | ret = target_depend_item(&se_tpg->tpg_group.cg_item); |
1438 | if (ret) { | 1438 | if (ret) { |
1439 | pr_warn("configfs_depend_item() failed: %d\n", ret); | 1439 | pr_warn("target_depend_item() failed: %d\n", ret); |
1440 | kfree(vs_tpg); | 1440 | kfree(vs_tpg); |
1441 | mutex_unlock(&tpg->tv_tpg_mutex); | 1441 | mutex_unlock(&tpg->tv_tpg_mutex); |
1442 | goto out; | 1442 | goto out; |
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 98ed5be132c6..bc42d38ae031 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c | |||
@@ -27,14 +27,14 @@ enum { | |||
27 | }; | 27 | }; |
28 | 28 | ||
29 | /* Used to track all the vhost_vsock instances on the system. */ | 29 | /* Used to track all the vhost_vsock instances on the system. */ |
30 | static DEFINE_SPINLOCK(vhost_vsock_lock); | 30 | static DEFINE_MUTEX(vhost_vsock_mutex); |
31 | static DEFINE_READ_MOSTLY_HASHTABLE(vhost_vsock_hash, 8); | 31 | static DEFINE_READ_MOSTLY_HASHTABLE(vhost_vsock_hash, 8); |
32 | 32 | ||
33 | struct vhost_vsock { | 33 | struct vhost_vsock { |
34 | struct vhost_dev dev; | 34 | struct vhost_dev dev; |
35 | struct vhost_virtqueue vqs[2]; | 35 | struct vhost_virtqueue vqs[2]; |
36 | 36 | ||
37 | /* Link to global vhost_vsock_hash, writes use vhost_vsock_lock */ | 37 | /* Link to global vhost_vsock_hash, writes use vhost_vsock_mutex */ |
38 | struct hlist_node hash; | 38 | struct hlist_node hash; |
39 | 39 | ||
40 | struct vhost_work send_pkt_work; | 40 | struct vhost_work send_pkt_work; |
@@ -51,7 +51,7 @@ static u32 vhost_transport_get_local_cid(void) | |||
51 | return VHOST_VSOCK_DEFAULT_HOST_CID; | 51 | return VHOST_VSOCK_DEFAULT_HOST_CID; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* Callers that dereference the return value must hold vhost_vsock_lock or the | 54 | /* Callers that dereference the return value must hold vhost_vsock_mutex or the |
55 | * RCU read lock. | 55 | * RCU read lock. |
56 | */ | 56 | */ |
57 | static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) | 57 | static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) |
@@ -584,10 +584,10 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) | |||
584 | { | 584 | { |
585 | struct vhost_vsock *vsock = file->private_data; | 585 | struct vhost_vsock *vsock = file->private_data; |
586 | 586 | ||
587 | spin_lock_bh(&vhost_vsock_lock); | 587 | mutex_lock(&vhost_vsock_mutex); |
588 | if (vsock->guest_cid) | 588 | if (vsock->guest_cid) |
589 | hash_del_rcu(&vsock->hash); | 589 | hash_del_rcu(&vsock->hash); |
590 | spin_unlock_bh(&vhost_vsock_lock); | 590 | mutex_unlock(&vhost_vsock_mutex); |
591 | 591 | ||
592 | /* Wait for other CPUs to finish using vsock */ | 592 | /* Wait for other CPUs to finish using vsock */ |
593 | synchronize_rcu(); | 593 | synchronize_rcu(); |
@@ -631,10 +631,10 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid) | |||
631 | return -EINVAL; | 631 | return -EINVAL; |
632 | 632 | ||
633 | /* Refuse if CID is already in use */ | 633 | /* Refuse if CID is already in use */ |
634 | spin_lock_bh(&vhost_vsock_lock); | 634 | mutex_lock(&vhost_vsock_mutex); |
635 | other = vhost_vsock_get(guest_cid); | 635 | other = vhost_vsock_get(guest_cid); |
636 | if (other && other != vsock) { | 636 | if (other && other != vsock) { |
637 | spin_unlock_bh(&vhost_vsock_lock); | 637 | mutex_unlock(&vhost_vsock_mutex); |
638 | return -EADDRINUSE; | 638 | return -EADDRINUSE; |
639 | } | 639 | } |
640 | 640 | ||
@@ -643,7 +643,7 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid) | |||
643 | 643 | ||
644 | vsock->guest_cid = guest_cid; | 644 | vsock->guest_cid = guest_cid; |
645 | hash_add_rcu(vhost_vsock_hash, &vsock->hash, guest_cid); | 645 | hash_add_rcu(vhost_vsock_hash, &vsock->hash, guest_cid); |
646 | spin_unlock_bh(&vhost_vsock_lock); | 646 | mutex_unlock(&vhost_vsock_mutex); |
647 | 647 | ||
648 | return 0; | 648 | return 0; |
649 | } | 649 | } |
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index de062fb201bc..eff9ddc7c4ab 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c | |||
@@ -52,7 +52,8 @@ static void vp_get(struct virtio_device *vdev, unsigned offset, | |||
52 | { | 52 | { |
53 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 53 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
54 | void __iomem *ioaddr = vp_dev->ioaddr + | 54 | void __iomem *ioaddr = vp_dev->ioaddr + |
55 | VIRTIO_PCI_CONFIG(vp_dev) + offset; | 55 | VIRTIO_PCI_CONFIG_OFF(vp_dev->msix_enabled) + |
56 | offset; | ||
56 | u8 *ptr = buf; | 57 | u8 *ptr = buf; |
57 | int i; | 58 | int i; |
58 | 59 | ||
@@ -67,7 +68,8 @@ static void vp_set(struct virtio_device *vdev, unsigned offset, | |||
67 | { | 68 | { |
68 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 69 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
69 | void __iomem *ioaddr = vp_dev->ioaddr + | 70 | void __iomem *ioaddr = vp_dev->ioaddr + |
70 | VIRTIO_PCI_CONFIG(vp_dev) + offset; | 71 | VIRTIO_PCI_CONFIG_OFF(vp_dev->msix_enabled) + |
72 | offset; | ||
71 | const u8 *ptr = buf; | 73 | const u8 *ptr = buf; |
72 | int i; | 74 | int i; |
73 | 75 | ||
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h index 84c3de89696a..40d028eed645 100644 --- a/include/uapi/linux/vhost.h +++ b/include/uapi/linux/vhost.h | |||
@@ -11,94 +11,9 @@ | |||
11 | * device configuration. | 11 | * device configuration. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/vhost_types.h> | ||
14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
15 | #include <linux/compiler.h> | ||
16 | #include <linux/ioctl.h> | 16 | #include <linux/ioctl.h> |
17 | #include <linux/virtio_config.h> | ||
18 | #include <linux/virtio_ring.h> | ||
19 | |||
20 | struct vhost_vring_state { | ||
21 | unsigned int index; | ||
22 | unsigned int num; | ||
23 | }; | ||
24 | |||
25 | struct vhost_vring_file { | ||
26 | unsigned int index; | ||
27 | int fd; /* Pass -1 to unbind from file. */ | ||
28 | |||
29 | }; | ||
30 | |||
31 | struct vhost_vring_addr { | ||
32 | unsigned int index; | ||
33 | /* Option flags. */ | ||
34 | unsigned int flags; | ||
35 | /* Flag values: */ | ||
36 | /* Whether log address is valid. If set enables logging. */ | ||
37 | #define VHOST_VRING_F_LOG 0 | ||
38 | |||
39 | /* Start of array of descriptors (virtually contiguous) */ | ||
40 | __u64 desc_user_addr; | ||
41 | /* Used structure address. Must be 32 bit aligned */ | ||
42 | __u64 used_user_addr; | ||
43 | /* Available structure address. Must be 16 bit aligned */ | ||
44 | __u64 avail_user_addr; | ||
45 | /* Logging support. */ | ||
46 | /* Log writes to used structure, at offset calculated from specified | ||
47 | * address. Address must be 32 bit aligned. */ | ||
48 | __u64 log_guest_addr; | ||
49 | }; | ||
50 | |||
51 | /* no alignment requirement */ | ||
52 | struct vhost_iotlb_msg { | ||
53 | __u64 iova; | ||
54 | __u64 size; | ||
55 | __u64 uaddr; | ||
56 | #define VHOST_ACCESS_RO 0x1 | ||
57 | #define VHOST_ACCESS_WO 0x2 | ||
58 | #define VHOST_ACCESS_RW 0x3 | ||
59 | __u8 perm; | ||
60 | #define VHOST_IOTLB_MISS 1 | ||
61 | #define VHOST_IOTLB_UPDATE 2 | ||
62 | #define VHOST_IOTLB_INVALIDATE 3 | ||
63 | #define VHOST_IOTLB_ACCESS_FAIL 4 | ||
64 | __u8 type; | ||
65 | }; | ||
66 | |||
67 | #define VHOST_IOTLB_MSG 0x1 | ||
68 | #define VHOST_IOTLB_MSG_V2 0x2 | ||
69 | |||
70 | struct vhost_msg { | ||
71 | int type; | ||
72 | union { | ||
73 | struct vhost_iotlb_msg iotlb; | ||
74 | __u8 padding[64]; | ||
75 | }; | ||
76 | }; | ||
77 | |||
78 | struct vhost_msg_v2 { | ||
79 | __u32 type; | ||
80 | __u32 reserved; | ||
81 | union { | ||
82 | struct vhost_iotlb_msg iotlb; | ||
83 | __u8 padding[64]; | ||
84 | }; | ||
85 | }; | ||
86 | |||
87 | struct vhost_memory_region { | ||
88 | __u64 guest_phys_addr; | ||
89 | __u64 memory_size; /* bytes */ | ||
90 | __u64 userspace_addr; | ||
91 | __u64 flags_padding; /* No flags are currently specified. */ | ||
92 | }; | ||
93 | |||
94 | /* All region addresses and sizes must be 4K aligned. */ | ||
95 | #define VHOST_PAGE_SIZE 0x1000 | ||
96 | |||
97 | struct vhost_memory { | ||
98 | __u32 nregions; | ||
99 | __u32 padding; | ||
100 | struct vhost_memory_region regions[0]; | ||
101 | }; | ||
102 | 17 | ||
103 | /* ioctls */ | 18 | /* ioctls */ |
104 | 19 | ||
@@ -186,31 +101,7 @@ struct vhost_memory { | |||
186 | * device. This can be used to stop the ring (e.g. for migration). */ | 101 | * device. This can be used to stop the ring (e.g. for migration). */ |
187 | #define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file) | 102 | #define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file) |
188 | 103 | ||
189 | /* Feature bits */ | 104 | /* VHOST_SCSI specific defines */ |
190 | /* Log all write descriptors. Can be changed while device is active. */ | ||
191 | #define VHOST_F_LOG_ALL 26 | ||
192 | /* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */ | ||
193 | #define VHOST_NET_F_VIRTIO_NET_HDR 27 | ||
194 | |||
195 | /* VHOST_SCSI specific definitions */ | ||
196 | |||
197 | /* | ||
198 | * Used by QEMU userspace to ensure a consistent vhost-scsi ABI. | ||
199 | * | ||
200 | * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate + | ||
201 | * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage | ||
202 | * ABI Rev 1: January 2013. Ignore vhost_tpgt filed in struct vhost_scsi_target. | ||
203 | * All the targets under vhost_wwpn can be seen and used by guset. | ||
204 | */ | ||
205 | |||
206 | #define VHOST_SCSI_ABI_VERSION 1 | ||
207 | |||
208 | struct vhost_scsi_target { | ||
209 | int abi_version; | ||
210 | char vhost_wwpn[224]; /* TRANSPORT_IQN_LEN */ | ||
211 | unsigned short vhost_tpgt; | ||
212 | unsigned short reserved; | ||
213 | }; | ||
214 | 105 | ||
215 | #define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target) | 106 | #define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target) |
216 | #define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target) | 107 | #define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target) |
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h new file mode 100644 index 000000000000..c907290ff065 --- /dev/null +++ b/include/uapi/linux/vhost_types.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
2 | #ifndef _LINUX_VHOST_TYPES_H | ||
3 | #define _LINUX_VHOST_TYPES_H | ||
4 | /* Userspace interface for in-kernel virtio accelerators. */ | ||
5 | |||
6 | /* vhost is used to reduce the number of system calls involved in virtio. | ||
7 | * | ||
8 | * Existing virtio net code is used in the guest without modification. | ||
9 | * | ||
10 | * This header includes interface used by userspace hypervisor for | ||
11 | * device configuration. | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/compiler.h> | ||
16 | #include <linux/virtio_config.h> | ||
17 | #include <linux/virtio_ring.h> | ||
18 | |||
19 | struct vhost_vring_state { | ||
20 | unsigned int index; | ||
21 | unsigned int num; | ||
22 | }; | ||
23 | |||
24 | struct vhost_vring_file { | ||
25 | unsigned int index; | ||
26 | int fd; /* Pass -1 to unbind from file. */ | ||
27 | |||
28 | }; | ||
29 | |||
30 | struct vhost_vring_addr { | ||
31 | unsigned int index; | ||
32 | /* Option flags. */ | ||
33 | unsigned int flags; | ||
34 | /* Flag values: */ | ||
35 | /* Whether log address is valid. If set enables logging. */ | ||
36 | #define VHOST_VRING_F_LOG 0 | ||
37 | |||
38 | /* Start of array of descriptors (virtually contiguous) */ | ||
39 | __u64 desc_user_addr; | ||
40 | /* Used structure address. Must be 32 bit aligned */ | ||
41 | __u64 used_user_addr; | ||
42 | /* Available structure address. Must be 16 bit aligned */ | ||
43 | __u64 avail_user_addr; | ||
44 | /* Logging support. */ | ||
45 | /* Log writes to used structure, at offset calculated from specified | ||
46 | * address. Address must be 32 bit aligned. */ | ||
47 | __u64 log_guest_addr; | ||
48 | }; | ||
49 | |||
50 | /* no alignment requirement */ | ||
51 | struct vhost_iotlb_msg { | ||
52 | __u64 iova; | ||
53 | __u64 size; | ||
54 | __u64 uaddr; | ||
55 | #define VHOST_ACCESS_RO 0x1 | ||
56 | #define VHOST_ACCESS_WO 0x2 | ||
57 | #define VHOST_ACCESS_RW 0x3 | ||
58 | __u8 perm; | ||
59 | #define VHOST_IOTLB_MISS 1 | ||
60 | #define VHOST_IOTLB_UPDATE 2 | ||
61 | #define VHOST_IOTLB_INVALIDATE 3 | ||
62 | #define VHOST_IOTLB_ACCESS_FAIL 4 | ||
63 | __u8 type; | ||
64 | }; | ||
65 | |||
66 | #define VHOST_IOTLB_MSG 0x1 | ||
67 | #define VHOST_IOTLB_MSG_V2 0x2 | ||
68 | |||
69 | struct vhost_msg { | ||
70 | int type; | ||
71 | union { | ||
72 | struct vhost_iotlb_msg iotlb; | ||
73 | __u8 padding[64]; | ||
74 | }; | ||
75 | }; | ||
76 | |||
77 | struct vhost_msg_v2 { | ||
78 | __u32 type; | ||
79 | __u32 reserved; | ||
80 | union { | ||
81 | struct vhost_iotlb_msg iotlb; | ||
82 | __u8 padding[64]; | ||
83 | }; | ||
84 | }; | ||
85 | |||
86 | struct vhost_memory_region { | ||
87 | __u64 guest_phys_addr; | ||
88 | __u64 memory_size; /* bytes */ | ||
89 | __u64 userspace_addr; | ||
90 | __u64 flags_padding; /* No flags are currently specified. */ | ||
91 | }; | ||
92 | |||
93 | /* All region addresses and sizes must be 4K aligned. */ | ||
94 | #define VHOST_PAGE_SIZE 0x1000 | ||
95 | |||
96 | struct vhost_memory { | ||
97 | __u32 nregions; | ||
98 | __u32 padding; | ||
99 | struct vhost_memory_region regions[0]; | ||
100 | }; | ||
101 | |||
102 | /* VHOST_SCSI specific definitions */ | ||
103 | |||
104 | /* | ||
105 | * Used by QEMU userspace to ensure a consistent vhost-scsi ABI. | ||
106 | * | ||
107 | * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate + | ||
108 | * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage | ||
109 | * ABI Rev 1: January 2013. Ignore vhost_tpgt field in struct vhost_scsi_target. | ||
110 | * All the targets under vhost_wwpn can be seen and used by guset. | ||
111 | */ | ||
112 | |||
113 | #define VHOST_SCSI_ABI_VERSION 1 | ||
114 | |||
115 | struct vhost_scsi_target { | ||
116 | int abi_version; | ||
117 | char vhost_wwpn[224]; /* TRANSPORT_IQN_LEN */ | ||
118 | unsigned short vhost_tpgt; | ||
119 | unsigned short reserved; | ||
120 | }; | ||
121 | |||
122 | /* Feature bits */ | ||
123 | /* Log all write descriptors. Can be changed while device is active. */ | ||
124 | #define VHOST_F_LOG_ALL 26 | ||
125 | /* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */ | ||
126 | #define VHOST_NET_F_VIRTIO_NET_HDR 27 | ||
127 | |||
128 | #endif | ||
diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_blk.h index 9ebe4d968dd5..0f99d7b49ede 100644 --- a/include/uapi/linux/virtio_blk.h +++ b/include/uapi/linux/virtio_blk.h | |||
@@ -38,6 +38,8 @@ | |||
38 | #define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ | 38 | #define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ |
39 | #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ | 39 | #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ |
40 | #define VIRTIO_BLK_F_MQ 12 /* support more than one vq */ | 40 | #define VIRTIO_BLK_F_MQ 12 /* support more than one vq */ |
41 | #define VIRTIO_BLK_F_DISCARD 13 /* DISCARD is supported */ | ||
42 | #define VIRTIO_BLK_F_WRITE_ZEROES 14 /* WRITE ZEROES is supported */ | ||
41 | 43 | ||
42 | /* Legacy feature bits */ | 44 | /* Legacy feature bits */ |
43 | #ifndef VIRTIO_BLK_NO_LEGACY | 45 | #ifndef VIRTIO_BLK_NO_LEGACY |
@@ -86,6 +88,39 @@ struct virtio_blk_config { | |||
86 | 88 | ||
87 | /* number of vqs, only available when VIRTIO_BLK_F_MQ is set */ | 89 | /* number of vqs, only available when VIRTIO_BLK_F_MQ is set */ |
88 | __u16 num_queues; | 90 | __u16 num_queues; |
91 | |||
92 | /* the next 3 entries are guarded by VIRTIO_BLK_F_DISCARD */ | ||
93 | /* | ||
94 | * The maximum discard sectors (in 512-byte sectors) for | ||
95 | * one segment. | ||
96 | */ | ||
97 | __u32 max_discard_sectors; | ||
98 | /* | ||
99 | * The maximum number of discard segments in a | ||
100 | * discard command. | ||
101 | */ | ||
102 | __u32 max_discard_seg; | ||
103 | /* Discard commands must be aligned to this number of sectors. */ | ||
104 | __u32 discard_sector_alignment; | ||
105 | |||
106 | /* the next 3 entries are guarded by VIRTIO_BLK_F_WRITE_ZEROES */ | ||
107 | /* | ||
108 | * The maximum number of write zeroes sectors (in 512-byte sectors) in | ||
109 | * one segment. | ||
110 | */ | ||
111 | __u32 max_write_zeroes_sectors; | ||
112 | /* | ||
113 | * The maximum number of segments in a write zeroes | ||
114 | * command. | ||
115 | */ | ||
116 | __u32 max_write_zeroes_seg; | ||
117 | /* | ||
118 | * Set if a VIRTIO_BLK_T_WRITE_ZEROES request may result in the | ||
119 | * deallocation of one or more of the sectors. | ||
120 | */ | ||
121 | __u8 write_zeroes_may_unmap; | ||
122 | |||
123 | __u8 unused1[3]; | ||
89 | } __attribute__((packed)); | 124 | } __attribute__((packed)); |
90 | 125 | ||
91 | /* | 126 | /* |
@@ -114,6 +149,12 @@ struct virtio_blk_config { | |||
114 | /* Get device ID command */ | 149 | /* Get device ID command */ |
115 | #define VIRTIO_BLK_T_GET_ID 8 | 150 | #define VIRTIO_BLK_T_GET_ID 8 |
116 | 151 | ||
152 | /* Discard command */ | ||
153 | #define VIRTIO_BLK_T_DISCARD 11 | ||
154 | |||
155 | /* Write zeroes command */ | ||
156 | #define VIRTIO_BLK_T_WRITE_ZEROES 13 | ||
157 | |||
117 | #ifndef VIRTIO_BLK_NO_LEGACY | 158 | #ifndef VIRTIO_BLK_NO_LEGACY |
118 | /* Barrier before this op. */ | 159 | /* Barrier before this op. */ |
119 | #define VIRTIO_BLK_T_BARRIER 0x80000000 | 160 | #define VIRTIO_BLK_T_BARRIER 0x80000000 |
@@ -133,6 +174,19 @@ struct virtio_blk_outhdr { | |||
133 | __virtio64 sector; | 174 | __virtio64 sector; |
134 | }; | 175 | }; |
135 | 176 | ||
177 | /* Unmap this range (only valid for write zeroes command) */ | ||
178 | #define VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP 0x00000001 | ||
179 | |||
180 | /* Discard/write zeroes range for each request. */ | ||
181 | struct virtio_blk_discard_write_zeroes { | ||
182 | /* discard/write zeroes start sector */ | ||
183 | __le64 sector; | ||
184 | /* number of discard/write zeroes sectors */ | ||
185 | __le32 num_sectors; | ||
186 | /* flags for this range */ | ||
187 | __le32 flags; | ||
188 | }; | ||
189 | |||
136 | #ifndef VIRTIO_BLK_NO_LEGACY | 190 | #ifndef VIRTIO_BLK_NO_LEGACY |
137 | struct virtio_scsi_inhdr { | 191 | struct virtio_scsi_inhdr { |
138 | __virtio32 errors; | 192 | __virtio32 errors; |