aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/kvm/kvm_virtio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/kvm/kvm_virtio.c')
-rw-r--r--drivers/s390/kvm/kvm_virtio.c58
1 files changed, 29 insertions, 29 deletions
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 47a7e6200b26..5ab34340919b 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -31,11 +31,6 @@
31 */ 31 */
32static void *kvm_devices; 32static void *kvm_devices;
33 33
34/*
35 * Unique numbering for kvm devices.
36 */
37static unsigned int dev_index;
38
39struct kvm_device { 34struct kvm_device {
40 struct virtio_device vdev; 35 struct virtio_device vdev;
41 struct kvm_device_desc *desc; 36 struct kvm_device_desc *desc;
@@ -78,27 +73,32 @@ static unsigned desc_size(const struct kvm_device_desc *desc)
78 + desc->config_len; 73 + desc->config_len;
79} 74}
80 75
81/* 76/* This gets the device's feature bits. */
82 * This tests (and acknowleges) a feature bit. 77static u32 kvm_get_features(struct virtio_device *vdev)
83 */
84static bool kvm_feature(struct virtio_device *vdev, unsigned fbit)
85{ 78{
79 unsigned int i;
80 u32 features = 0;
86 struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; 81 struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
87 u8 *features; 82 u8 *in_features = kvm_vq_features(desc);
88 83
89 if (fbit / 8 > desc->feature_len) 84 for (i = 0; i < min(desc->feature_len * 8, 32); i++)
90 return false; 85 if (in_features[i / 8] & (1 << (i % 8)))
86 features |= (1 << i);
87 return features;
88}
91 89
92 features = kvm_vq_features(desc); 90static void kvm_set_features(struct virtio_device *vdev, u32 features)
93 if (!(features[fbit / 8] & (1 << (fbit % 8)))) 91{
94 return false; 92 unsigned int i;
93 struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
94 /* Second half of bitmap is features we accept. */
95 u8 *out_features = kvm_vq_features(desc) + desc->feature_len;
95 96
96 /* 97 memset(out_features, 0, desc->feature_len);
97 * We set the matching bit in the other half of the bitmap to tell the 98 for (i = 0; i < min(desc->feature_len * 8, 32); i++) {
98 * Host we want to use this feature. 99 if (features & (1 << i))
99 */ 100 out_features[i / 8] |= (1 << (i % 8));
100 features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8)); 101 }
101 return true;
102} 102}
103 103
104/* 104/*
@@ -221,7 +221,8 @@ static void kvm_del_vq(struct virtqueue *vq)
221 * The config ops structure as defined by virtio config 221 * The config ops structure as defined by virtio config
222 */ 222 */
223static struct virtio_config_ops kvm_vq_configspace_ops = { 223static struct virtio_config_ops kvm_vq_configspace_ops = {
224 .feature = kvm_feature, 224 .get_features = kvm_get_features,
225 .set_features = kvm_set_features,
225 .get = kvm_get, 226 .get = kvm_get,
226 .set = kvm_set, 227 .set = kvm_set,
227 .get_status = kvm_get_status, 228 .get_status = kvm_get_status,
@@ -244,26 +245,25 @@ static struct device kvm_root = {
244 * adds a new device and register it with virtio 245 * adds a new device and register it with virtio
245 * appropriate drivers are loaded by the device model 246 * appropriate drivers are loaded by the device model
246 */ 247 */
247static void add_kvm_device(struct kvm_device_desc *d) 248static void add_kvm_device(struct kvm_device_desc *d, unsigned int offset)
248{ 249{
249 struct kvm_device *kdev; 250 struct kvm_device *kdev;
250 251
251 kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); 252 kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
252 if (!kdev) { 253 if (!kdev) {
253 printk(KERN_EMERG "Cannot allocate kvm dev %u\n", 254 printk(KERN_EMERG "Cannot allocate kvm dev %u type %u\n",
254 dev_index++); 255 offset, d->type);
255 return; 256 return;
256 } 257 }
257 258
258 kdev->vdev.dev.parent = &kvm_root; 259 kdev->vdev.dev.parent = &kvm_root;
259 kdev->vdev.index = dev_index++;
260 kdev->vdev.id.device = d->type; 260 kdev->vdev.id.device = d->type;
261 kdev->vdev.config = &kvm_vq_configspace_ops; 261 kdev->vdev.config = &kvm_vq_configspace_ops;
262 kdev->desc = d; 262 kdev->desc = d;
263 263
264 if (register_virtio_device(&kdev->vdev) != 0) { 264 if (register_virtio_device(&kdev->vdev) != 0) {
265 printk(KERN_ERR "Failed to register kvm device %u\n", 265 printk(KERN_ERR "Failed to register kvm device %u type %u\n",
266 kdev->vdev.index); 266 offset, d->type);
267 kfree(kdev); 267 kfree(kdev);
268 } 268 }
269} 269}
@@ -283,7 +283,7 @@ static void scan_devices(void)
283 if (d->type == 0) 283 if (d->type == 0)
284 break; 284 break;
285 285
286 add_kvm_device(d); 286 add_kvm_device(d, i);
287 } 287 }
288} 288}
289 289