aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/kvm/kvm_virtio.c11
-rw-r--r--drivers/s390/kvm/virtio_ccw.c20
2 files changed, 18 insertions, 13 deletions
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 6711e65764b5..2ea6165366b6 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -443,29 +443,30 @@ static int __init test_devices_support(unsigned long addr)
443} 443}
444/* 444/*
445 * Init function for virtio 445 * Init function for virtio
446 * devices are in a single page above top of "normal" mem 446 * devices are in a single page above top of "normal" + standby mem
447 */ 447 */
448static int __init kvm_devices_init(void) 448static int __init kvm_devices_init(void)
449{ 449{
450 int rc; 450 int rc;
451 unsigned long total_memory_size = sclp_get_rzm() * sclp_get_rnmax();
451 452
452 if (!MACHINE_IS_KVM) 453 if (!MACHINE_IS_KVM)
453 return -ENODEV; 454 return -ENODEV;
454 455
455 if (test_devices_support(real_memory_size) < 0) 456 if (test_devices_support(total_memory_size) < 0)
456 return -ENODEV; 457 return -ENODEV;
457 458
458 rc = vmem_add_mapping(real_memory_size, PAGE_SIZE); 459 rc = vmem_add_mapping(total_memory_size, PAGE_SIZE);
459 if (rc) 460 if (rc)
460 return rc; 461 return rc;
461 462
462 kvm_devices = (void *) real_memory_size; 463 kvm_devices = (void *) total_memory_size;
463 464
464 kvm_root = root_device_register("kvm_s390"); 465 kvm_root = root_device_register("kvm_s390");
465 if (IS_ERR(kvm_root)) { 466 if (IS_ERR(kvm_root)) {
466 rc = PTR_ERR(kvm_root); 467 rc = PTR_ERR(kvm_root);
467 printk(KERN_ERR "Could not register kvm_s390 root device"); 468 printk(KERN_ERR "Could not register kvm_s390 root device");
468 vmem_remove_mapping(real_memory_size, PAGE_SIZE); 469 vmem_remove_mapping(total_memory_size, PAGE_SIZE);
469 return rc; 470 return rc;
470 } 471 }
471 472
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
index fb877b59ec57..779dc5136291 100644
--- a/drivers/s390/kvm/virtio_ccw.c
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -31,6 +31,7 @@
31#include <asm/irq.h> 31#include <asm/irq.h>
32#include <asm/cio.h> 32#include <asm/cio.h>
33#include <asm/ccwdev.h> 33#include <asm/ccwdev.h>
34#include <asm/virtio-ccw.h>
34 35
35/* 36/*
36 * virtio related functions 37 * virtio related functions
@@ -77,12 +78,9 @@ struct virtio_ccw_vq_info {
77 void *queue; 78 void *queue;
78 struct vq_info_block *info_block; 79 struct vq_info_block *info_block;
79 struct list_head node; 80 struct list_head node;
81 long cookie;
80}; 82};
81 83
82#define KVM_VIRTIO_CCW_RING_ALIGN 4096
83
84#define KVM_S390_VIRTIO_CCW_NOTIFY 3
85
86#define CCW_CMD_SET_VQ 0x13 84#define CCW_CMD_SET_VQ 0x13
87#define CCW_CMD_VDEV_RESET 0x33 85#define CCW_CMD_VDEV_RESET 0x33
88#define CCW_CMD_SET_IND 0x43 86#define CCW_CMD_SET_IND 0x43
@@ -135,8 +133,11 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev,
135 do { 133 do {
136 spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags); 134 spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags);
137 ret = ccw_device_start(vcdev->cdev, ccw, intparm, 0, 0); 135 ret = ccw_device_start(vcdev->cdev, ccw, intparm, 0, 0);
138 if (!ret) 136 if (!ret) {
137 if (!vcdev->curr_io)
138 vcdev->err = 0;
139 vcdev->curr_io |= flag; 139 vcdev->curr_io |= flag;
140 }
140 spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags); 141 spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags);
141 cpu_relax(); 142 cpu_relax();
142 } while (ret == -EBUSY); 143 } while (ret == -EBUSY);
@@ -145,15 +146,18 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev,
145} 146}
146 147
147static inline long do_kvm_notify(struct subchannel_id schid, 148static inline long do_kvm_notify(struct subchannel_id schid,
148 unsigned long queue_index) 149 unsigned long queue_index,
150 long cookie)
149{ 151{
150 register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; 152 register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY;
151 register struct subchannel_id __schid asm("2") = schid; 153 register struct subchannel_id __schid asm("2") = schid;
152 register unsigned long __index asm("3") = queue_index; 154 register unsigned long __index asm("3") = queue_index;
153 register long __rc asm("2"); 155 register long __rc asm("2");
156 register long __cookie asm("4") = cookie;
154 157
155 asm volatile ("diag 2,4,0x500\n" 158 asm volatile ("diag 2,4,0x500\n"
156 : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index) 159 : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index),
160 "d"(__cookie)
157 : "memory", "cc"); 161 : "memory", "cc");
158 return __rc; 162 return __rc;
159} 163}
@@ -166,7 +170,7 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq)
166 170
167 vcdev = to_vc_device(info->vq->vdev); 171 vcdev = to_vc_device(info->vq->vdev);
168 ccw_device_get_schid(vcdev->cdev, &schid); 172 ccw_device_get_schid(vcdev->cdev, &schid);
169 do_kvm_notify(schid, vq->index); 173 info->cookie = do_kvm_notify(schid, vq->index, info->cookie);
170} 174}
171 175
172static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, 176static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev,