virtio: feature bit manipulation helpers
Add virtio_{add,clear}_feature helper functions for manipulating a feature bits variable. This has some benefits over open coding: - add check that the bit is in a sane range - make it obvious at a glance what is going on - have a central point to change when we want to extend feature bits Convert existing code manipulating features to use the new helpers. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
a590fd5ba8
commit
0cd09c3a6c
@ -23,7 +23,7 @@
|
||||
|
||||
static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
|
||||
{
|
||||
features |= 1 << VIRTIO_9P_MOUNT_TAG;
|
||||
virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
|
||||
return features;
|
||||
}
|
||||
|
||||
|
@ -711,20 +711,20 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
|
||||
{
|
||||
VirtIOBlock *s = VIRTIO_BLK(vdev);
|
||||
|
||||
features |= (1 << VIRTIO_BLK_F_SEG_MAX);
|
||||
features |= (1 << VIRTIO_BLK_F_GEOMETRY);
|
||||
features |= (1 << VIRTIO_BLK_F_TOPOLOGY);
|
||||
features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
|
||||
features |= (1 << VIRTIO_BLK_F_SCSI);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
|
||||
|
||||
if (s->conf.config_wce) {
|
||||
features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
|
||||
}
|
||||
if (blk_enable_write_cache(s->blk)) {
|
||||
features |= (1 << VIRTIO_BLK_F_WCE);
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_WCE);
|
||||
}
|
||||
if (blk_is_read_only(s->blk)) {
|
||||
features |= 1 << VIRTIO_BLK_F_RO;
|
||||
virtio_add_feature(&features, VIRTIO_BLK_F_RO);
|
||||
}
|
||||
|
||||
return features;
|
||||
|
@ -475,7 +475,7 @@ static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
|
||||
vser = VIRTIO_SERIAL(vdev);
|
||||
|
||||
if (vser->bus.max_nr_ports > 1) {
|
||||
features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
|
||||
virtio_add_feature(&features, VIRTIO_CONSOLE_F_MULTIPORT);
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
@ -446,23 +446,23 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
|
||||
VirtIONet *n = VIRTIO_NET(vdev);
|
||||
NetClientState *nc = qemu_get_queue(n->nic);
|
||||
|
||||
features |= (1 << VIRTIO_NET_F_MAC);
|
||||
virtio_add_feature(&features, VIRTIO_NET_F_MAC);
|
||||
|
||||
if (!peer_has_vnet_hdr(n)) {
|
||||
features &= ~(0x1 << VIRTIO_NET_F_CSUM);
|
||||
features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);
|
||||
features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);
|
||||
features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);
|
||||
|
||||
features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM);
|
||||
features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4);
|
||||
features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6);
|
||||
features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
|
||||
}
|
||||
|
||||
if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
|
||||
features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO);
|
||||
features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
|
||||
}
|
||||
|
||||
if (!get_vhost_net(nc->peer)) {
|
||||
@ -477,11 +477,11 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
|
||||
|
||||
/* Linux kernel 2.6.25. It understood MAC (as everyone must),
|
||||
* but also these: */
|
||||
features |= (1 << VIRTIO_NET_F_MAC);
|
||||
features |= (1 << VIRTIO_NET_F_CSUM);
|
||||
features |= (1 << VIRTIO_NET_F_HOST_TSO4);
|
||||
features |= (1 << VIRTIO_NET_F_HOST_TSO6);
|
||||
features |= (1 << VIRTIO_NET_F_HOST_ECN);
|
||||
virtio_add_feature(&features, VIRTIO_NET_F_MAC);
|
||||
virtio_add_feature(&features, VIRTIO_NET_F_CSUM);
|
||||
virtio_add_feature(&features, VIRTIO_NET_F_HOST_TSO4);
|
||||
virtio_add_feature(&features, VIRTIO_NET_F_HOST_TSO6);
|
||||
virtio_add_feature(&features, VIRTIO_NET_F_HOST_ECN);
|
||||
|
||||
return features;
|
||||
}
|
||||
@ -1552,7 +1552,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
|
||||
void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
|
||||
{
|
||||
int i, config_size = 0;
|
||||
host_features |= (1 << VIRTIO_NET_F_MAC);
|
||||
virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
|
||||
for (i = 0; feature_sizes[i].flags != 0; i++) {
|
||||
if (host_features & feature_sizes[i].flags) {
|
||||
config_size = MAX(feature_sizes[i].end, config_size);
|
||||
|
@ -743,8 +743,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
|
||||
dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
|
||||
dev->host_features[0]);
|
||||
|
||||
dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
|
||||
dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;
|
||||
virtio_add_feature(&dev->host_features[0], VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
virtio_add_feature(&dev->host_features[0], VIRTIO_F_BAD_FEATURE);
|
||||
|
||||
css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
|
||||
parent->hotplugged, 1);
|
||||
|
@ -349,7 +349,7 @@ static void virtio_mmio_device_plugged(DeviceState *opaque)
|
||||
{
|
||||
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
|
||||
|
||||
proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
proxy->host_features = virtio_bus_get_vdev_features(&proxy->bus,
|
||||
proxy->host_features);
|
||||
}
|
||||
|
@ -952,8 +952,8 @@ static void virtio_pci_device_plugged(DeviceState *d)
|
||||
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
|
||||
}
|
||||
|
||||
proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
|
||||
proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
|
||||
virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
virtio_add_feature(&proxy->host_features, VIRTIO_F_BAD_FEATURE);
|
||||
proxy->host_features = virtio_bus_get_vdev_features(bus,
|
||||
proxy->host_features);
|
||||
}
|
||||
|
@ -219,6 +219,18 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||
void virtio_queue_notify_vq(VirtQueue *vq);
|
||||
void virtio_irq(VirtQueue *vq);
|
||||
|
||||
static inline void virtio_add_feature(uint32_t *features, unsigned int fbit)
|
||||
{
|
||||
assert(fbit < 32);
|
||||
*features |= (1 << fbit);
|
||||
}
|
||||
|
||||
static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
|
||||
{
|
||||
assert(fbit < 32);
|
||||
*features &= ~(1 << fbit);
|
||||
}
|
||||
|
||||
static inline bool virtio_is_big_endian(VirtIODevice *vdev)
|
||||
{
|
||||
assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
|
||||
|
Loading…
Reference in New Issue
Block a user