diff options
-rw-r--r-- | drivers/s390/kvm/kvm_virtio.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 47a7e6200b26..9f55ce6f3c78 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
@@ -78,27 +78,32 @@ static unsigned desc_size(const struct kvm_device_desc *desc) | |||
78 | + desc->config_len; | 78 | + desc->config_len; |
79 | } | 79 | } |
80 | 80 | ||
81 | /* | 81 | /* This gets the device's feature bits. */ |
82 | * This tests (and acknowleges) a feature bit. | 82 | static u32 kvm_get_features(struct virtio_device *vdev) |
83 | */ | ||
84 | static bool kvm_feature(struct virtio_device *vdev, unsigned fbit) | ||
85 | { | 83 | { |
84 | unsigned int i; | ||
85 | u32 features = 0; | ||
86 | struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; | 86 | struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; |
87 | u8 *features; | 87 | u8 *in_features = kvm_vq_features(desc); |
88 | 88 | ||
89 | if (fbit / 8 > desc->feature_len) | 89 | for (i = 0; i < min(desc->feature_len * 8, 32); i++) |
90 | return false; | 90 | if (in_features[i / 8] & (1 << (i % 8))) |
91 | features |= (1 << i); | ||
92 | return features; | ||
93 | } | ||
91 | 94 | ||
92 | features = kvm_vq_features(desc); | 95 | static void kvm_set_features(struct virtio_device *vdev, u32 features) |
93 | if (!(features[fbit / 8] & (1 << (fbit % 8)))) | 96 | { |
94 | return false; | 97 | unsigned int i; |
98 | struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; | ||
99 | /* Second half of bitmap is features we accept. */ | ||
100 | u8 *out_features = kvm_vq_features(desc) + desc->feature_len; | ||
95 | 101 | ||
96 | /* | 102 | memset(out_features, 0, desc->feature_len); |
97 | * We set the matching bit in the other half of the bitmap to tell the | 103 | for (i = 0; i < min(desc->feature_len * 8, 32); i++) { |
98 | * Host we want to use this feature. | 104 | if (features & (1 << i)) |
99 | */ | 105 | out_features[i / 8] |= (1 << (i % 8)); |
100 | features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8)); | 106 | } |
101 | return true; | ||
102 | } | 107 | } |
103 | 108 | ||
104 | /* | 109 | /* |
@@ -221,7 +226,8 @@ static void kvm_del_vq(struct virtqueue *vq) | |||
221 | * The config ops structure as defined by virtio config | 226 | * The config ops structure as defined by virtio config |
222 | */ | 227 | */ |
223 | static struct virtio_config_ops kvm_vq_configspace_ops = { | 228 | static struct virtio_config_ops kvm_vq_configspace_ops = { |
224 | .feature = kvm_feature, | 229 | .get_features = kvm_get_features, |
230 | .set_features = kvm_set_features, | ||
225 | .get = kvm_get, | 231 | .get = kvm_get, |
226 | .set = kvm_set, | 232 | .set = kvm_set, |
227 | .get_status = kvm_get_status, | 233 | .get_status = kvm_get_status, |