Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

virtio_pci_modern: allow configuring extended features

The virtio specifications allows for up to 128 bits for the
device features. Soon we are going to use some of the 'extended'
bits features (above 64) for the virtio_net driver.

Extend the virtio pci modern driver to support configuring the full
virtio features range, replacing the unrolled loops reading and
writing the features space with explicit one bounded to the actual
features space size in word and implementing the get_extended_features
callback.

Note that in vp_finalize_features() we only need to cache the lower
64 features bits, to process the transport features.

Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

Paolo Abeni 69b94615 e7d4c1c5

+84 -38
+5 -5
drivers/virtio/virtio_pci_modern.c
··· 22 22 23 23 #define VIRTIO_AVQ_SGS_MAX 4 24 24 25 - static u64 vp_get_features(struct virtio_device *vdev) 25 + static void vp_get_features(struct virtio_device *vdev, u64 *features) 26 26 { 27 27 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 28 28 29 - return vp_modern_get_features(&vp_dev->mdev); 29 + vp_modern_get_extended_features(&vp_dev->mdev, features); 30 30 } 31 31 32 32 static int vp_avq_index(struct virtio_device *vdev, u16 *index, u16 *num) ··· 437 437 if (vp_check_common_size(vdev)) 438 438 return -EINVAL; 439 439 440 - vp_modern_set_features(&vp_dev->mdev, vdev->features); 440 + vp_modern_set_extended_features(&vp_dev->mdev, vdev->features_array); 441 441 442 442 return 0; 443 443 } ··· 1234 1234 .find_vqs = vp_modern_find_vqs, 1235 1235 .del_vqs = vp_del_vqs, 1236 1236 .synchronize_cbs = vp_synchronize_vectors, 1237 - .get_features = vp_get_features, 1237 + .get_extended_features = vp_get_features, 1238 1238 .finalize_features = vp_finalize_features, 1239 1239 .bus_name = vp_bus_name, 1240 1240 .set_vq_affinity = vp_set_vq_affinity, ··· 1254 1254 .find_vqs = vp_modern_find_vqs, 1255 1255 .del_vqs = vp_del_vqs, 1256 1256 .synchronize_cbs = vp_synchronize_vectors, 1257 - .get_features = vp_get_features, 1257 + .get_extended_features = vp_get_features, 1258 1258 .finalize_features = vp_finalize_features, 1259 1259 .bus_name = vp_bus_name, 1260 1260 .set_vq_affinity = vp_set_vq_affinity,
+40 -29
drivers/virtio/virtio_pci_modern_dev.c
··· 388 388 EXPORT_SYMBOL_GPL(vp_modern_remove); 389 389 390 390 /* 391 - * vp_modern_get_features - get features from device 391 + * vp_modern_get_extended_features - get features from device 392 392 * @mdev: the modern virtio-pci device 393 + * @features: the features array to be filled 393 394 * 394 - * Returns the features read from the device 395 + * Fill the specified features array with the features read from the device 395 396 */ 396 - u64 vp_modern_get_features(struct virtio_pci_modern_device *mdev) 397 + void vp_modern_get_extended_features(struct virtio_pci_modern_device *mdev, 398 + u64 *features) 397 399 { 398 400 struct virtio_pci_common_cfg __iomem *cfg = mdev->common; 401 + int i; 399 402 400 - u64 features; 403 + virtio_features_zero(features); 404 + for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { 405 + u64 cur; 401 406 402 - vp_iowrite32(0, &cfg->device_feature_select); 403 - features = vp_ioread32(&cfg->device_feature); 404 - vp_iowrite32(1, &cfg->device_feature_select); 405 - features |= ((u64)vp_ioread32(&cfg->device_feature) << 32); 406 - 407 - return features; 407 + vp_iowrite32(i, &cfg->device_feature_select); 408 + cur = vp_ioread32(&cfg->device_feature); 409 + features[i >> 1] |= cur << (32 * (i & 1)); 410 + } 408 411 } 409 - EXPORT_SYMBOL_GPL(vp_modern_get_features); 412 + EXPORT_SYMBOL_GPL(vp_modern_get_extended_features); 410 413 411 414 /* 412 415 * vp_modern_get_driver_features - get driver features from device 413 416 * @mdev: the modern virtio-pci device 417 + * @features: the features array to be filled 414 418 * 415 - * Returns the driver features read from the device 419 + * Fill the specified features array with the driver features read from the 420 + * device 416 421 */ 417 - u64 vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev) 422 + void 423 + vp_modern_get_driver_extended_features(struct virtio_pci_modern_device *mdev, 424 + u64 *features) 418 425 { 419 426 struct virtio_pci_common_cfg __iomem *cfg = mdev->common; 427 + int i; 420 428 421 - u64 features; 429 + virtio_features_zero(features); 430 + for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { 431 + u64 cur; 422 432 423 - vp_iowrite32(0, &cfg->guest_feature_select); 424 - features = vp_ioread32(&cfg->guest_feature); 425 - vp_iowrite32(1, &cfg->guest_feature_select); 426 - features |= ((u64)vp_ioread32(&cfg->guest_feature) << 32); 427 - 428 - return features; 433 + vp_iowrite32(i, &cfg->guest_feature_select); 434 + cur = vp_ioread32(&cfg->guest_feature); 435 + features[i >> 1] |= cur << (32 * (i & 1)); 436 + } 429 437 } 430 - EXPORT_SYMBOL_GPL(vp_modern_get_driver_features); 438 + EXPORT_SYMBOL_GPL(vp_modern_get_driver_extended_features); 431 439 432 440 /* 433 - * vp_modern_set_features - set features to device 441 + * vp_modern_set_extended_features - set features to device 434 442 * @mdev: the modern virtio-pci device 435 443 * @features: the features set to device 436 444 */ 437 - void vp_modern_set_features(struct virtio_pci_modern_device *mdev, 438 - u64 features) 445 + void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev, 446 + const u64 *features) 439 447 { 440 448 struct virtio_pci_common_cfg __iomem *cfg = mdev->common; 449 + int i; 441 450 442 - vp_iowrite32(0, &cfg->guest_feature_select); 443 - vp_iowrite32((u32)features, &cfg->guest_feature); 444 - vp_iowrite32(1, &cfg->guest_feature_select); 445 - vp_iowrite32(features >> 32, &cfg->guest_feature); 451 + for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { 452 + u32 cur = features[i >> 1] >> (32 * (i & 1)); 453 + 454 + vp_iowrite32(i, &cfg->guest_feature_select); 455 + vp_iowrite32(cur, &cfg->guest_feature); 456 + } 446 457 } 447 - EXPORT_SYMBOL_GPL(vp_modern_set_features); 458 + EXPORT_SYMBOL_GPL(vp_modern_set_extended_features); 448 459 449 460 /* 450 461 * vp_modern_generation - get the device genreation
+39 -4
include/linux/virtio_pci_modern.h
··· 3 3 #define _LINUX_VIRTIO_PCI_MODERN_H 4 4 5 5 #include <linux/pci.h> 6 + #include <linux/virtio_config.h> 6 7 #include <linux/virtio_pci.h> 7 8 8 9 /** ··· 96 95 vp_iowrite32(val >> 32, hi); 97 96 } 98 97 99 - u64 vp_modern_get_features(struct virtio_pci_modern_device *mdev); 100 - u64 vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev); 101 - void vp_modern_set_features(struct virtio_pci_modern_device *mdev, 102 - u64 features); 98 + void 99 + vp_modern_get_driver_extended_features(struct virtio_pci_modern_device *mdev, 100 + u64 *features); 101 + void vp_modern_get_extended_features(struct virtio_pci_modern_device *mdev, 102 + u64 *features); 103 + void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev, 104 + const u64 *features); 105 + 106 + static inline u64 107 + vp_modern_get_features(struct virtio_pci_modern_device *mdev) 108 + { 109 + u64 features_array[VIRTIO_FEATURES_DWORDS]; 110 + 111 + vp_modern_get_extended_features(mdev, features_array); 112 + return features_array[0]; 113 + } 114 + 115 + static inline u64 116 + vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev) 117 + { 118 + u64 features_array[VIRTIO_FEATURES_DWORDS]; 119 + int i; 120 + 121 + vp_modern_get_driver_extended_features(mdev, features_array); 122 + for (i = 1; i < VIRTIO_FEATURES_DWORDS; ++i) 123 + WARN_ON_ONCE(features_array[i]); 124 + return features_array[0]; 125 + } 126 + 127 + static inline void 128 + vp_modern_set_features(struct virtio_pci_modern_device *mdev, u64 features) 129 + { 130 + u64 features_array[VIRTIO_FEATURES_DWORDS]; 131 + 132 + virtio_features_from_u64(features_array, features); 133 + vp_modern_set_extended_features(mdev, features_array); 134 + } 135 + 103 136 u32 vp_modern_generation(struct virtio_pci_modern_device *mdev); 104 137 u8 vp_modern_get_status(struct virtio_pci_modern_device *mdev); 105 138 void vp_modern_set_status(struct virtio_pci_modern_device *mdev,