1*a67da3beSAsias He #include "kvm/virtio-scsi.h" 2*a67da3beSAsias He #include "kvm/virtio-pci-dev.h" 3*a67da3beSAsias He #include "kvm/disk-image.h" 4*a67da3beSAsias He #include "kvm/kvm.h" 5*a67da3beSAsias He #include "kvm/pci.h" 6*a67da3beSAsias He #include "kvm/ioeventfd.h" 7*a67da3beSAsias He #include "kvm/guest_compat.h" 8*a67da3beSAsias He #include "kvm/virtio-pci.h" 9*a67da3beSAsias He #include "kvm/virtio.h" 10*a67da3beSAsias He 11*a67da3beSAsias He #include <linux/kernel.h> 12*a67da3beSAsias He #include <linux/virtio_scsi.h> 13*a67da3beSAsias He #include <linux/vhost.h> 14*a67da3beSAsias He 15*a67da3beSAsias He #define VIRTIO_SCSI_QUEUE_SIZE 128 16*a67da3beSAsias He #define NUM_VIRT_QUEUES 3 17*a67da3beSAsias He 18*a67da3beSAsias He static LIST_HEAD(sdevs); 19*a67da3beSAsias He static int compat_id = -1; 20*a67da3beSAsias He 21*a67da3beSAsias He struct scsi_dev { 22*a67da3beSAsias He struct virt_queue vqs[NUM_VIRT_QUEUES]; 23*a67da3beSAsias He struct virtio_scsi_config config; 24*a67da3beSAsias He struct vhost_scsi_target target; 25*a67da3beSAsias He u32 features; 26*a67da3beSAsias He int vhost_fd; 27*a67da3beSAsias He struct virtio_device vdev; 28*a67da3beSAsias He struct list_head list; 29*a67da3beSAsias He struct kvm *kvm; 30*a67da3beSAsias He }; 31*a67da3beSAsias He 32*a67da3beSAsias He static void set_config(struct kvm *kvm, void *dev, u8 data, u32 offset) 33*a67da3beSAsias He { 34*a67da3beSAsias He struct scsi_dev *sdev = dev; 35*a67da3beSAsias He 36*a67da3beSAsias He ((u8 *)(&sdev->config))[offset] = data; 37*a67da3beSAsias He } 38*a67da3beSAsias He 39*a67da3beSAsias He static u8 get_config(struct kvm *kvm, void *dev, u32 offset) 40*a67da3beSAsias He { 41*a67da3beSAsias He struct scsi_dev *sdev = dev; 42*a67da3beSAsias He 43*a67da3beSAsias He return ((u8 *)(&sdev->config))[offset]; 44*a67da3beSAsias He } 45*a67da3beSAsias He 46*a67da3beSAsias He static u32 get_host_features(struct kvm *kvm, void *dev) 47*a67da3beSAsias He { 48*a67da3beSAsias He return 1UL << VIRTIO_RING_F_EVENT_IDX | 49*a67da3beSAsias He 1UL << VIRTIO_RING_F_INDIRECT_DESC; 50*a67da3beSAsias He } 51*a67da3beSAsias He 52*a67da3beSAsias He static void set_guest_features(struct kvm *kvm, void *dev, u32 features) 53*a67da3beSAsias He { 54*a67da3beSAsias He struct scsi_dev *sdev = dev; 55*a67da3beSAsias He 56*a67da3beSAsias He sdev->features = features; 57*a67da3beSAsias He } 58*a67da3beSAsias He 59*a67da3beSAsias He static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn) 60*a67da3beSAsias He { 61*a67da3beSAsias He struct vhost_vring_state state = { .index = vq }; 62*a67da3beSAsias He struct vhost_vring_addr addr; 63*a67da3beSAsias He struct scsi_dev *sdev = dev; 64*a67da3beSAsias He struct virt_queue *queue; 65*a67da3beSAsias He void *p; 66*a67da3beSAsias He int r; 67*a67da3beSAsias He 68*a67da3beSAsias He compat__remove_message(compat_id); 69*a67da3beSAsias He 70*a67da3beSAsias He queue = &sdev->vqs[vq]; 71*a67da3beSAsias He queue->pfn = pfn; 72*a67da3beSAsias He p = guest_pfn_to_host(kvm, queue->pfn); 73*a67da3beSAsias He 74*a67da3beSAsias He vring_init(&queue->vring, VIRTIO_SCSI_QUEUE_SIZE, p, VIRTIO_PCI_VRING_ALIGN); 75*a67da3beSAsias He 76*a67da3beSAsias He if (sdev->vhost_fd == 0) 77*a67da3beSAsias He return 0; 78*a67da3beSAsias He 79*a67da3beSAsias He state.num = queue->vring.num; 80*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_NUM, &state); 81*a67da3beSAsias He if (r < 0) 82*a67da3beSAsias He die_perror("VHOST_SET_VRING_NUM failed"); 83*a67da3beSAsias He state.num = 0; 84*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_BASE, &state); 85*a67da3beSAsias He if (r < 0) 86*a67da3beSAsias He die_perror("VHOST_SET_VRING_BASE failed"); 87*a67da3beSAsias He 88*a67da3beSAsias He addr = (struct vhost_vring_addr) { 89*a67da3beSAsias He .index = vq, 90*a67da3beSAsias He .desc_user_addr = (u64)(unsigned long)queue->vring.desc, 91*a67da3beSAsias He .avail_user_addr = (u64)(unsigned long)queue->vring.avail, 92*a67da3beSAsias He .used_user_addr = (u64)(unsigned long)queue->vring.used, 93*a67da3beSAsias He }; 94*a67da3beSAsias He 95*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_ADDR, &addr); 96*a67da3beSAsias He if (r < 0) 97*a67da3beSAsias He die_perror("VHOST_SET_VRING_ADDR failed"); 98*a67da3beSAsias He 99*a67da3beSAsias He return 0; 100*a67da3beSAsias He } 101*a67da3beSAsias He 102*a67da3beSAsias He static void notify_vq_gsi(struct kvm *kvm, void *dev, u32 vq, u32 gsi) 103*a67da3beSAsias He { 104*a67da3beSAsias He struct vhost_vring_file file; 105*a67da3beSAsias He struct scsi_dev *sdev = dev; 106*a67da3beSAsias He struct kvm_irqfd irq; 107*a67da3beSAsias He int r; 108*a67da3beSAsias He 109*a67da3beSAsias He if (sdev->vhost_fd == 0) 110*a67da3beSAsias He return; 111*a67da3beSAsias He 112*a67da3beSAsias He irq = (struct kvm_irqfd) { 113*a67da3beSAsias He .gsi = gsi, 114*a67da3beSAsias He .fd = eventfd(0, 0), 115*a67da3beSAsias He }; 116*a67da3beSAsias He file = (struct vhost_vring_file) { 117*a67da3beSAsias He .index = vq, 118*a67da3beSAsias He .fd = irq.fd, 119*a67da3beSAsias He }; 120*a67da3beSAsias He 121*a67da3beSAsias He r = ioctl(kvm->vm_fd, KVM_IRQFD, &irq); 122*a67da3beSAsias He if (r < 0) 123*a67da3beSAsias He die_perror("KVM_IRQFD failed"); 124*a67da3beSAsias He 125*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_CALL, &file); 126*a67da3beSAsias He if (r < 0) 127*a67da3beSAsias He die_perror("VHOST_SET_VRING_CALL failed"); 128*a67da3beSAsias He 129*a67da3beSAsias He if (vq > 0) 130*a67da3beSAsias He return; 131*a67da3beSAsias He 132*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SCSI_SET_ENDPOINT, &sdev->target); 133*a67da3beSAsias He if (r != 0) 134*a67da3beSAsias He die("VHOST_SCSI_SET_ENDPOINT failed %d", errno); 135*a67da3beSAsias He } 136*a67da3beSAsias He 137*a67da3beSAsias He static void notify_vq_eventfd(struct kvm *kvm, void *dev, u32 vq, u32 efd) 138*a67da3beSAsias He { 139*a67da3beSAsias He struct scsi_dev *sdev = dev; 140*a67da3beSAsias He struct vhost_vring_file file = { 141*a67da3beSAsias He .index = vq, 142*a67da3beSAsias He .fd = efd, 143*a67da3beSAsias He }; 144*a67da3beSAsias He int r; 145*a67da3beSAsias He 146*a67da3beSAsias He if (sdev->vhost_fd == 0) 147*a67da3beSAsias He return; 148*a67da3beSAsias He 149*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SET_VRING_KICK, &file); 150*a67da3beSAsias He if (r < 0) 151*a67da3beSAsias He die_perror("VHOST_SET_VRING_KICK failed"); 152*a67da3beSAsias He } 153*a67da3beSAsias He 154*a67da3beSAsias He static int notify_vq(struct kvm *kvm, void *dev, u32 vq) 155*a67da3beSAsias He { 156*a67da3beSAsias He return 0; 157*a67da3beSAsias He } 158*a67da3beSAsias He 159*a67da3beSAsias He static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq) 160*a67da3beSAsias He { 161*a67da3beSAsias He struct scsi_dev *sdev = dev; 162*a67da3beSAsias He 163*a67da3beSAsias He return sdev->vqs[vq].pfn; 164*a67da3beSAsias He } 165*a67da3beSAsias He 166*a67da3beSAsias He static int get_size_vq(struct kvm *kvm, void *dev, u32 vq) 167*a67da3beSAsias He { 168*a67da3beSAsias He return VIRTIO_SCSI_QUEUE_SIZE; 169*a67da3beSAsias He } 170*a67da3beSAsias He 171*a67da3beSAsias He static int set_size_vq(struct kvm *kvm, void *dev, u32 vq, int size) 172*a67da3beSAsias He { 173*a67da3beSAsias He return size; 174*a67da3beSAsias He } 175*a67da3beSAsias He 176*a67da3beSAsias He static struct virtio_ops scsi_dev_virtio_ops = (struct virtio_ops) { 177*a67da3beSAsias He .set_config = set_config, 178*a67da3beSAsias He .get_config = get_config, 179*a67da3beSAsias He .get_host_features = get_host_features, 180*a67da3beSAsias He .set_guest_features = set_guest_features, 181*a67da3beSAsias He .init_vq = init_vq, 182*a67da3beSAsias He .get_pfn_vq = get_pfn_vq, 183*a67da3beSAsias He .get_size_vq = get_size_vq, 184*a67da3beSAsias He .set_size_vq = set_size_vq, 185*a67da3beSAsias He .notify_vq = notify_vq, 186*a67da3beSAsias He .notify_vq_gsi = notify_vq_gsi, 187*a67da3beSAsias He .notify_vq_eventfd = notify_vq_eventfd, 188*a67da3beSAsias He }; 189*a67da3beSAsias He 190*a67da3beSAsias He static void virtio_scsi_vhost_init(struct kvm *kvm, struct scsi_dev *sdev) 191*a67da3beSAsias He { 192*a67da3beSAsias He struct vhost_memory *mem; 193*a67da3beSAsias He u64 features; 194*a67da3beSAsias He int r; 195*a67da3beSAsias He 196*a67da3beSAsias He sdev->vhost_fd = open("/dev/vhost-scsi", O_RDWR); 197*a67da3beSAsias He if (sdev->vhost_fd < 0) 198*a67da3beSAsias He die_perror("Failed openning vhost-scsi device"); 199*a67da3beSAsias He 200*a67da3beSAsias He mem = calloc(1, sizeof(*mem) + sizeof(struct vhost_memory_region)); 201*a67da3beSAsias He if (mem == NULL) 202*a67da3beSAsias He die("Failed allocating memory for vhost memory map"); 203*a67da3beSAsias He 204*a67da3beSAsias He mem->nregions = 1; 205*a67da3beSAsias He mem->regions[0] = (struct vhost_memory_region) { 206*a67da3beSAsias He .guest_phys_addr = 0, 207*a67da3beSAsias He .memory_size = kvm->ram_size, 208*a67da3beSAsias He .userspace_addr = (unsigned long)kvm->ram_start, 209*a67da3beSAsias He }; 210*a67da3beSAsias He 211*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SET_OWNER); 212*a67da3beSAsias He if (r != 0) 213*a67da3beSAsias He die_perror("VHOST_SET_OWNER failed"); 214*a67da3beSAsias He 215*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_GET_FEATURES, &features); 216*a67da3beSAsias He if (r != 0) 217*a67da3beSAsias He die_perror("VHOST_GET_FEATURES failed"); 218*a67da3beSAsias He 219*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SET_FEATURES, &features); 220*a67da3beSAsias He if (r != 0) 221*a67da3beSAsias He die_perror("VHOST_SET_FEATURES failed"); 222*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SET_MEM_TABLE, mem); 223*a67da3beSAsias He if (r != 0) 224*a67da3beSAsias He die_perror("VHOST_SET_MEM_TABLE failed"); 225*a67da3beSAsias He 226*a67da3beSAsias He sdev->vdev.use_vhost = true; 227*a67da3beSAsias He 228*a67da3beSAsias He free(mem); 229*a67da3beSAsias He } 230*a67da3beSAsias He 231*a67da3beSAsias He 232*a67da3beSAsias He static int virtio_scsi_init_one(struct kvm *kvm, struct disk_image *disk) 233*a67da3beSAsias He { 234*a67da3beSAsias He struct scsi_dev *sdev; 235*a67da3beSAsias He 236*a67da3beSAsias He if (!disk) 237*a67da3beSAsias He return -EINVAL; 238*a67da3beSAsias He 239*a67da3beSAsias He sdev = calloc(1, sizeof(struct scsi_dev)); 240*a67da3beSAsias He if (sdev == NULL) 241*a67da3beSAsias He return -ENOMEM; 242*a67da3beSAsias He 243*a67da3beSAsias He *sdev = (struct scsi_dev) { 244*a67da3beSAsias He .config = (struct virtio_scsi_config) { 245*a67da3beSAsias He .num_queues = NUM_VIRT_QUEUES - 2, 246*a67da3beSAsias He .seg_max = VIRTIO_SCSI_CDB_SIZE - 2, 247*a67da3beSAsias He .max_sectors = 65535, 248*a67da3beSAsias He .cmd_per_lun = 128, 249*a67da3beSAsias He .sense_size = VIRTIO_SCSI_SENSE_SIZE, 250*a67da3beSAsias He .cdb_size = VIRTIO_SCSI_CDB_SIZE, 251*a67da3beSAsias He .max_channel = 0, 252*a67da3beSAsias He .max_target = 0, 253*a67da3beSAsias He .max_lun = 16383, 254*a67da3beSAsias He .event_info_size = sizeof(struct virtio_scsi_event), 255*a67da3beSAsias He }, 256*a67da3beSAsias He .kvm = kvm, 257*a67da3beSAsias He }; 258*a67da3beSAsias He strncpy((char *)&sdev->target.vhost_wwpn, disk->wwpn, sizeof(sdev->target.vhost_wwpn)); 259*a67da3beSAsias He sdev->target.vhost_tpgt = strtol(disk->tpgt, NULL, 0); 260*a67da3beSAsias He 261*a67da3beSAsias He virtio_init(kvm, sdev, &sdev->vdev, &scsi_dev_virtio_ops, 262*a67da3beSAsias He VIRTIO_PCI, PCI_DEVICE_ID_VIRTIO_SCSI, VIRTIO_ID_SCSI, PCI_CLASS_BLK); 263*a67da3beSAsias He 264*a67da3beSAsias He list_add_tail(&sdev->list, &sdevs); 265*a67da3beSAsias He 266*a67da3beSAsias He virtio_scsi_vhost_init(kvm, sdev); 267*a67da3beSAsias He 268*a67da3beSAsias He if (compat_id == -1) 269*a67da3beSAsias He compat_id = virtio_compat_add_message("virtio-scsi", "CONFIG_VIRTIO_SCSI"); 270*a67da3beSAsias He 271*a67da3beSAsias He return 0; 272*a67da3beSAsias He } 273*a67da3beSAsias He 274*a67da3beSAsias He static int virtio_scsi_exit_one(struct kvm *kvm, struct scsi_dev *sdev) 275*a67da3beSAsias He { 276*a67da3beSAsias He int r; 277*a67da3beSAsias He 278*a67da3beSAsias He r = ioctl(sdev->vhost_fd, VHOST_SCSI_CLEAR_ENDPOINT, &sdev->target); 279*a67da3beSAsias He if (r != 0) 280*a67da3beSAsias He die("VHOST_SCSI_CLEAR_ENDPOINT failed %d", errno); 281*a67da3beSAsias He 282*a67da3beSAsias He list_del(&sdev->list); 283*a67da3beSAsias He free(sdev); 284*a67da3beSAsias He 285*a67da3beSAsias He return 0; 286*a67da3beSAsias He } 287*a67da3beSAsias He 288*a67da3beSAsias He int virtio_scsi_init(struct kvm *kvm) 289*a67da3beSAsias He { 290*a67da3beSAsias He int i, r = 0; 291*a67da3beSAsias He 292*a67da3beSAsias He for (i = 0; i < kvm->nr_disks; i++) { 293*a67da3beSAsias He if (!kvm->disks[i]->wwpn) 294*a67da3beSAsias He continue; 295*a67da3beSAsias He r = virtio_scsi_init_one(kvm, kvm->disks[i]); 296*a67da3beSAsias He if (r < 0) 297*a67da3beSAsias He goto cleanup; 298*a67da3beSAsias He } 299*a67da3beSAsias He 300*a67da3beSAsias He return 0; 301*a67da3beSAsias He cleanup: 302*a67da3beSAsias He return virtio_scsi_exit(kvm); 303*a67da3beSAsias He } 304*a67da3beSAsias He 305*a67da3beSAsias He int virtio_scsi_exit(struct kvm *kvm) 306*a67da3beSAsias He { 307*a67da3beSAsias He while (!list_empty(&sdevs)) { 308*a67da3beSAsias He struct scsi_dev *sdev; 309*a67da3beSAsias He 310*a67da3beSAsias He sdev = list_first_entry(&sdevs, struct scsi_dev, list); 311*a67da3beSAsias He virtio_scsi_exit_one(kvm, sdev); 312*a67da3beSAsias He } 313*a67da3beSAsias He 314*a67da3beSAsias He return 0; 315*a67da3beSAsias He } 316