aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/lguest/lguest_device.c11
-rw-r--r--drivers/s390/kvm/kvm_virtio.c11
-rw-r--r--drivers/virtio/virtio.c5
-rw-r--r--drivers/virtio/virtio_pci.c10
4 files changed, 20 insertions, 17 deletions
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 1a8de57289eb..54fdc2aa4806 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -98,16 +98,17 @@ static u32 lg_get_features(struct virtio_device *vdev)
98 return features; 98 return features;
99} 99}
100 100
101static void lg_set_features(struct virtio_device *vdev, u32 features) 101static void lg_finalize_features(struct virtio_device *vdev)
102{ 102{
103 unsigned int i; 103 unsigned int i, bits;
104 struct lguest_device_desc *desc = to_lgdev(vdev)->desc; 104 struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
105 /* Second half of bitmap is features we accept. */ 105 /* Second half of bitmap is features we accept. */
106 u8 *out_features = lg_features(desc) + desc->feature_len; 106 u8 *out_features = lg_features(desc) + desc->feature_len;
107 107
108 memset(out_features, 0, desc->feature_len); 108 memset(out_features, 0, desc->feature_len);
109 for (i = 0; i < min(desc->feature_len * 8, 32); i++) { 109 bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
110 if (features & (1 << i)) 110 for (i = 0; i < bits; i++) {
111 if (test_bit(i, vdev->features))
111 out_features[i / 8] |= (1 << (i % 8)); 112 out_features[i / 8] |= (1 << (i % 8));
112 } 113 }
113} 114}
@@ -297,7 +298,7 @@ static void lg_del_vq(struct virtqueue *vq)
297/* The ops structure which hooks everything together. */ 298/* The ops structure which hooks everything together. */
298static struct virtio_config_ops lguest_config_ops = { 299static struct virtio_config_ops lguest_config_ops = {
299 .get_features = lg_get_features, 300 .get_features = lg_get_features,
300 .set_features = lg_set_features, 301 .finalize_features = lg_finalize_features,
301 .get = lg_get, 302 .get = lg_get,
302 .set = lg_set, 303 .set = lg_set,
303 .get_status = lg_get_status, 304 .get_status = lg_get_status,
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index d41f234bb2c2..5953510e7d5f 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -88,16 +88,17 @@ static u32 kvm_get_features(struct virtio_device *vdev)
88 return features; 88 return features;
89} 89}
90 90
91static void kvm_set_features(struct virtio_device *vdev, u32 features) 91static void kvm_finalize_features(struct virtio_device *vdev)
92{ 92{
93 unsigned int i; 93 unsigned int i, bits;
94 struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; 94 struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
95 /* Second half of bitmap is features we accept. */ 95 /* Second half of bitmap is features we accept. */
96 u8 *out_features = kvm_vq_features(desc) + desc->feature_len; 96 u8 *out_features = kvm_vq_features(desc) + desc->feature_len;
97 97
98 memset(out_features, 0, desc->feature_len); 98 memset(out_features, 0, desc->feature_len);
99 for (i = 0; i < min(desc->feature_len * 8, 32); i++) { 99 bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
100 if (features & (1 << i)) 100 for (i = 0; i < bits; i++) {
101 if (test_bit(i, vdev->features))
101 out_features[i / 8] |= (1 << (i % 8)); 102 out_features[i / 8] |= (1 << (i % 8));
102 } 103 }
103} 104}
@@ -223,7 +224,7 @@ static void kvm_del_vq(struct virtqueue *vq)
223 */ 224 */
224static struct virtio_config_ops kvm_vq_configspace_ops = { 225static struct virtio_config_ops kvm_vq_configspace_ops = {
225 .get_features = kvm_get_features, 226 .get_features = kvm_get_features,
226 .set_features = kvm_set_features, 227 .finalize_features = kvm_finalize_features,
227 .get = kvm_get, 228 .get = kvm_get,
228 .set = kvm_set, 229 .set = kvm_set,
229 .get_status = kvm_get_status, 230 .get_status = kvm_get_status,
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index baf103361e3a..5b78fd0aff0a 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -113,7 +113,7 @@ static int virtio_dev_probe(struct device *_d)
113 set_bit(f, dev->features); 113 set_bit(f, dev->features);
114 } 114 }
115 115
116 /* Transport features are always preserved to pass to set_features. */ 116 /* Transport features always preserved to pass to finalize_features. */
117 for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) 117 for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++)
118 if (device_features & (1 << i)) 118 if (device_features & (1 << i))
119 set_bit(i, dev->features); 119 set_bit(i, dev->features);
@@ -122,8 +122,7 @@ static int virtio_dev_probe(struct device *_d)
122 if (err) 122 if (err)
123 add_status(dev, VIRTIO_CONFIG_S_FAILED); 123 add_status(dev, VIRTIO_CONFIG_S_FAILED);
124 else { 124 else {
125 /* They should never have set feature bits beyond 32 */ 125 dev->config->finalize_features(dev);
126 dev->config->set_features(dev, dev->features[0]);
127 add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); 126 add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
128 } 127 }
129 return err; 128 return err;
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index eae7236310e4..9855975a72a3 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -94,12 +94,14 @@ static u32 vp_get_features(struct virtio_device *vdev)
94 return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); 94 return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
95} 95}
96 96
97/* virtio config->set_features() implementation */ 97/* virtio config->finalize_features() implementation */
98static void vp_set_features(struct virtio_device *vdev, u32 features) 98static void vp_finalize_features(struct virtio_device *vdev)
99{ 99{
100 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 100 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
101 101
102 iowrite32(features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); 102 /* We only support 32 feature bits. */
103 BUILD_BUG_ON(ARRAY_SIZE(vdev->features) != 1);
104 iowrite32(vdev->features[0], vp_dev->ioaddr+VIRTIO_PCI_GUEST_FEATURES);
103} 105}
104 106
105/* virtio config->get() implementation */ 107/* virtio config->get() implementation */
@@ -297,7 +299,7 @@ static struct virtio_config_ops virtio_pci_config_ops = {
297 .find_vq = vp_find_vq, 299 .find_vq = vp_find_vq,
298 .del_vq = vp_del_vq, 300 .del_vq = vp_del_vq,
299 .get_features = vp_get_features, 301 .get_features = vp_get_features,
300 .set_features = vp_set_features, 302 .finalize_features = vp_finalize_features,
301}; 303};
302 304
303/* the PCI probing function */ 305/* the PCI probing function */