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, |
