virtio: add feature checking helpers
Add a helper function for checking whether a bit is set in the guest features for a vdev as well as one that works on a feature bit set. Convert code that open-coded this: It cleans up the code and makes it easier to extend the guest feature bits. 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
							
								
									0cd09c3a6c
								
							
						
					
					
						commit
						ef546f1275
					
				@ -733,7 +733,6 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
 | 
				
			|||||||
static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 | 
					static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtIOBlock *s = VIRTIO_BLK(vdev);
 | 
					    VirtIOBlock *s = VIRTIO_BLK(vdev);
 | 
				
			||||||
    uint32_t features;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
 | 
					    if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
 | 
				
			||||||
                                    VIRTIO_CONFIG_S_DRIVER_OK))) {
 | 
					                                    VIRTIO_CONFIG_S_DRIVER_OK))) {
 | 
				
			||||||
@ -744,8 +743,6 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    features = vdev->guest_features;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send
 | 
					    /* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send
 | 
				
			||||||
     * cache flushes.  Thus, the "auto writethrough" behavior is never
 | 
					     * cache flushes.  Thus, the "auto writethrough" behavior is never
 | 
				
			||||||
     * necessary for guests that support the VIRTIO_BLK_F_CONFIG_WCE feature.
 | 
					     * necessary for guests that support the VIRTIO_BLK_F_CONFIG_WCE feature.
 | 
				
			||||||
@ -761,10 +758,10 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * s->blk would erroneously be placed in writethrough mode.
 | 
					     * s->blk would erroneously be placed in writethrough mode.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
 | 
					    if (!virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) {
 | 
				
			||||||
        aio_context_acquire(blk_get_aio_context(s->blk));
 | 
					        aio_context_acquire(blk_get_aio_context(s->blk));
 | 
				
			||||||
        blk_set_enable_write_cache(s->blk,
 | 
					        blk_set_enable_write_cache(s->blk,
 | 
				
			||||||
                                   !!(features & (1 << VIRTIO_BLK_F_WCE)));
 | 
					                                   virtio_has_feature(vdev, VIRTIO_BLK_F_WCE));
 | 
				
			||||||
        aio_context_release(blk_get_aio_context(s->blk));
 | 
					        aio_context_release(blk_get_aio_context(s->blk));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,7 @@ static VirtIOSerialPort *find_port_by_name(char *name)
 | 
				
			|||||||
static bool use_multiport(VirtIOSerial *vser)
 | 
					static bool use_multiport(VirtIOSerial *vser)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtIODevice *vdev = VIRTIO_DEVICE(vser);
 | 
					    VirtIODevice *vdev = VIRTIO_DEVICE(vser);
 | 
				
			||||||
    return vdev->guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
 | 
					    return virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static size_t write_to_port(VirtIOSerialPort *port,
 | 
					static size_t write_to_port(VirtIOSerialPort *port,
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    memcpy(&netcfg, config, n->config_size);
 | 
					    memcpy(&netcfg, config, n->config_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(vdev->guest_features >> VIRTIO_NET_F_CTRL_MAC_ADDR & 1) &&
 | 
					    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
 | 
				
			||||||
        memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
 | 
					        memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
 | 
				
			||||||
        memcpy(n->mac, netcfg.mac, ETH_ALEN);
 | 
					        memcpy(n->mac, netcfg.mac, ETH_ALEN);
 | 
				
			||||||
        qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
 | 
					        qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
 | 
				
			||||||
@ -305,7 +305,7 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
 | 
				
			|||||||
    info->multicast_table = str_list;
 | 
					    info->multicast_table = str_list;
 | 
				
			||||||
    info->vlan_table = get_vlan_table(n);
 | 
					    info->vlan_table = get_vlan_table(n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!((1 << VIRTIO_NET_F_CTRL_VLAN) & vdev->guest_features)) {
 | 
					    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VLAN)) {
 | 
				
			||||||
        info->vlan = RX_STATE_ALL;
 | 
					        info->vlan = RX_STATE_ALL;
 | 
				
			||||||
    } else if (!info->vlan_table) {
 | 
					    } else if (!info->vlan_table) {
 | 
				
			||||||
        info->vlan = RX_STATE_NONE;
 | 
					        info->vlan = RX_STATE_NONE;
 | 
				
			||||||
@ -519,9 +519,12 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
 | 
				
			|||||||
    VirtIONet *n = VIRTIO_NET(vdev);
 | 
					    VirtIONet *n = VIRTIO_NET(vdev);
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtio_net_set_multiqueue(n, !!(features & (1 << VIRTIO_NET_F_MQ)));
 | 
					    virtio_net_set_multiqueue(n,
 | 
				
			||||||
 | 
					                              __virtio_has_feature(features, VIRTIO_NET_F_MQ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
 | 
					    virtio_net_set_mrg_rx_bufs(n,
 | 
				
			||||||
 | 
					                               __virtio_has_feature(features,
 | 
				
			||||||
 | 
					                                                    VIRTIO_NET_F_MRG_RXBUF));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (n->has_vnet_hdr) {
 | 
					    if (n->has_vnet_hdr) {
 | 
				
			||||||
        n->curr_guest_offloads =
 | 
					        n->curr_guest_offloads =
 | 
				
			||||||
@ -538,7 +541,7 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
 | 
				
			|||||||
        vhost_net_ack_features(get_vhost_net(nc->peer), features);
 | 
					        vhost_net_ack_features(get_vhost_net(nc->peer), features);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((1 << VIRTIO_NET_F_CTRL_VLAN) & features) {
 | 
					    if (__virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN)) {
 | 
				
			||||||
        memset(n->vlans, 0, MAX_VLAN >> 3);
 | 
					        memset(n->vlans, 0, MAX_VLAN >> 3);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        memset(n->vlans, 0xff, MAX_VLAN >> 3);
 | 
					        memset(n->vlans, 0xff, MAX_VLAN >> 3);
 | 
				
			||||||
@ -585,7 +588,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
 | 
				
			|||||||
    uint64_t offloads;
 | 
					    uint64_t offloads;
 | 
				
			||||||
    size_t s;
 | 
					    size_t s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
 | 
					    if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
 | 
				
			||||||
        return VIRTIO_NET_ERR;
 | 
					        return VIRTIO_NET_ERR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1378,7 +1381,7 @@ static void virtio_net_save_device(VirtIODevice *vdev, QEMUFile *f)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
 | 
					    if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
 | 
				
			||||||
        qemu_put_be64(f, n->curr_guest_offloads);
 | 
					        qemu_put_be64(f, n->curr_guest_offloads);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1486,7 +1489,7 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
 | 
					    if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
 | 
				
			||||||
        n->curr_guest_offloads = qemu_get_be64(f);
 | 
					        n->curr_guest_offloads = qemu_get_be64(f);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
 | 
					        n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
 | 
				
			||||||
@ -1513,8 +1516,8 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
 | 
				
			|||||||
        qemu_get_subqueue(n->nic, i)->link_down = link_down;
 | 
					        qemu_get_subqueue(n->nic, i)->link_down = link_down;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (vdev->guest_features & (0x1 << VIRTIO_NET_F_GUEST_ANNOUNCE) &&
 | 
					    if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE) &&
 | 
				
			||||||
        vdev->guest_features & (0x1 << VIRTIO_NET_F_CTRL_VQ)) {
 | 
					        virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) {
 | 
				
			||||||
        n->announce_counter = SELF_ANNOUNCE_ROUNDS;
 | 
					        n->announce_counter = SELF_ANNOUNCE_ROUNDS;
 | 
				
			||||||
        timer_mod(n->announce_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL));
 | 
					        timer_mod(n->announce_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -145,7 +145,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * TODO: always disable this workaround for virtio 1.0 devices.
 | 
					     * TODO: always disable this workaround for virtio 1.0 devices.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    if ((vdev->guest_features & (1 << VIRTIO_F_ANY_LAYOUT)) == 0) {
 | 
					    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
 | 
				
			||||||
        req_size = req->elem.out_sg[0].iov_len;
 | 
					        req_size = req->elem.out_sg[0].iov_len;
 | 
				
			||||||
        resp_size = req->elem.in_sg[0].iov_len;
 | 
					        resp_size = req->elem.in_sg[0].iov_len;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -749,7 +749,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
 | 
				
			|||||||
    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
 | 
					    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
 | 
				
			||||||
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 | 
					    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
 | 
					    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
 | 
				
			||||||
        dev->type != TYPE_ROM) {
 | 
					        dev->type != TYPE_ROM) {
 | 
				
			||||||
        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
 | 
					        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
 | 
				
			||||||
                               sense.asc | (sense.ascq << 8));
 | 
					                               sense.asc | (sense.ascq << 8));
 | 
				
			||||||
@ -770,7 +770,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
 | 
				
			|||||||
        blk_op_block_all(sd->conf.blk, s->blocker);
 | 
					        blk_op_block_all(sd->conf.blk, s->blocker);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
 | 
					    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
 | 
				
			||||||
        virtio_scsi_push_event(s, sd,
 | 
					        virtio_scsi_push_event(s, sd,
 | 
				
			||||||
                               VIRTIO_SCSI_T_TRANSPORT_RESET,
 | 
					                               VIRTIO_SCSI_T_TRANSPORT_RESET,
 | 
				
			||||||
                               VIRTIO_SCSI_EVT_RESET_RESCAN);
 | 
					                               VIRTIO_SCSI_EVT_RESET_RESCAN);
 | 
				
			||||||
@ -784,7 +784,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
 | 
				
			|||||||
    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 | 
					    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 | 
				
			||||||
    SCSIDevice *sd = SCSI_DEVICE(dev);
 | 
					    SCSIDevice *sd = SCSI_DEVICE(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
 | 
					    if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
 | 
				
			||||||
        virtio_scsi_push_event(s, sd,
 | 
					        virtio_scsi_push_event(s, sd,
 | 
				
			||||||
                               VIRTIO_SCSI_T_TRANSPORT_RESET,
 | 
					                               VIRTIO_SCSI_T_TRANSPORT_RESET,
 | 
				
			||||||
                               VIRTIO_SCSI_EVT_RESET_REMOVED);
 | 
					                               VIRTIO_SCSI_EVT_RESET_REMOVED);
 | 
				
			||||||
 | 
				
			|||||||
@ -105,7 +105,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
 | 
				
			|||||||
/* Disable guest->host notifies */
 | 
					/* Disable guest->host notifies */
 | 
				
			||||||
void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
 | 
					void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
 | 
					    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
 | 
				
			||||||
        vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
 | 
					        vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -116,7 +116,7 @@ void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
bool vring_enable_notification(VirtIODevice *vdev, Vring *vring)
 | 
					bool vring_enable_notification(VirtIODevice *vdev, Vring *vring)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
 | 
					    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
 | 
				
			||||||
        vring_avail_event(&vring->vr) = vring->vr.avail->idx;
 | 
					        vring_avail_event(&vring->vr) = vring->vr.avail->idx;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        vring_clear_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
 | 
					        vring_clear_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
 | 
				
			||||||
@ -135,12 +135,12 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
 | 
				
			|||||||
     * interrupts. */
 | 
					     * interrupts. */
 | 
				
			||||||
    smp_mb();
 | 
					    smp_mb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
 | 
					    if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
 | 
				
			||||||
        unlikely(!vring_more_avail(vdev, vring))) {
 | 
					        unlikely(!vring_more_avail(vdev, vring))) {
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
 | 
					    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
 | 
				
			||||||
        return !(vring_get_avail_flags(vdev, vring) &
 | 
					        return !(vring_get_avail_flags(vdev, vring) &
 | 
				
			||||||
                 VRING_AVAIL_F_NO_INTERRUPT);
 | 
					                 VRING_AVAIL_F_NO_INTERRUPT);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -401,7 +401,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* On success, increment avail index. */
 | 
					    /* On success, increment avail index. */
 | 
				
			||||||
    vring->last_avail_idx++;
 | 
					    vring->last_avail_idx++;
 | 
				
			||||||
    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
 | 
					    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
 | 
				
			||||||
        vring_avail_event(&vring->vr) = vring->last_avail_idx;
 | 
					        vring_avail_event(&vring->vr) = vring->last_avail_idx;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -69,7 +69,7 @@ static inline void reset_stats(VirtIOBalloon *dev)
 | 
				
			|||||||
static bool balloon_stats_supported(const VirtIOBalloon *s)
 | 
					static bool balloon_stats_supported(const VirtIOBalloon *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 | 
					    VirtIODevice *vdev = VIRTIO_DEVICE(s);
 | 
				
			||||||
    return vdev->guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ);
 | 
					    return virtio_has_feature(vdev, VIRTIO_BALLOON_F_STATS_VQ);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool balloon_stats_enabled(const VirtIOBalloon *s)
 | 
					static bool balloon_stats_enabled(const VirtIOBalloon *s)
 | 
				
			||||||
 | 
				
			|||||||
@ -217,7 +217,7 @@ static inline void vring_set_avail_event(VirtQueue *vq, uint16_t val)
 | 
				
			|||||||
void virtio_queue_set_notification(VirtQueue *vq, int enable)
 | 
					void virtio_queue_set_notification(VirtQueue *vq, int enable)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    vq->notification = enable;
 | 
					    vq->notification = enable;
 | 
				
			||||||
    if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
 | 
					    if (virtio_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
 | 
				
			||||||
        vring_set_avail_event(vq, vring_avail_idx(vq));
 | 
					        vring_set_avail_event(vq, vring_avail_idx(vq));
 | 
				
			||||||
    } else if (enable) {
 | 
					    } else if (enable) {
 | 
				
			||||||
        vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
 | 
					        vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
 | 
				
			||||||
@ -468,7 +468,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
 | 
				
			|||||||
    max = vq->vring.num;
 | 
					    max = vq->vring.num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
 | 
					    i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
 | 
				
			||||||
    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
 | 
					    if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
 | 
				
			||||||
        vring_set_avail_event(vq, vq->last_avail_idx);
 | 
					        vring_set_avail_event(vq, vq->last_avail_idx);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -826,12 +826,12 @@ static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
 | 
				
			|||||||
    /* We need to expose used array entries before checking used event. */
 | 
					    /* We need to expose used array entries before checking used event. */
 | 
				
			||||||
    smp_mb();
 | 
					    smp_mb();
 | 
				
			||||||
    /* Always notify when queue is empty (when feature acknowledge) */
 | 
					    /* Always notify when queue is empty (when feature acknowledge) */
 | 
				
			||||||
    if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
 | 
					    if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
 | 
				
			||||||
         !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {
 | 
					        !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx) {
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
 | 
					    if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
 | 
				
			||||||
        return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
 | 
					        return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -231,6 +231,17 @@ static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
 | 
				
			|||||||
    *features &= ~(1 << fbit);
 | 
					    *features &= ~(1 << fbit);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(fbit < 32);
 | 
				
			||||||
 | 
					    return !!(features & (1 << fbit));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return __virtio_has_feature(vdev->guest_features, fbit);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool virtio_is_big_endian(VirtIODevice *vdev)
 | 
					static inline bool virtio_is_big_endian(VirtIODevice *vdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
 | 
					    assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user