Revision 8172539d

b/hw/s390-virtio-bus.c
101 101
    bus->dev_offs += dev_len;
102 102

  
103 103
    virtio_bind_device(vdev, &virtio_s390_bindings, dev);
104
    dev->host_features = vdev->get_features(vdev, dev->host_features);
104 105
    s390_virtio_device_sync(dev);
105 106

  
106 107
    return 0;
......
222 223
    cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
223 224

  
224 225
    /* Sync feature bitmap */
225
    if (dev->vdev->get_features) {
226
        stl_phys(cur_offs, dev->vdev->get_features(dev->vdev));
227
    }
226
    stl_phys(cur_offs, dev->host_features);
228 227

  
229 228
    dev->feat_offs = cur_offs + dev->feat_len;
230 229
    cur_offs += dev->feat_len * 2;
......
310 309
    kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token);
311 310
}
312 311

  
312
static unsigned virtio_s390_get_features(void *opaque)
313
{
314
    VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
315
    return dev->host_features;
316
}
317

  
313 318
/**************** S390 Virtio Bus Device Descriptions *******************/
314 319

  
315 320
static const VirtIOBindings virtio_s390_bindings = {
316 321
    .notify = virtio_s390_notify,
322
    .get_features = virtio_s390_get_features,
317 323
};
318 324

  
319 325
static VirtIOS390DeviceInfo s390_virtio_net = {
b/hw/s390-virtio-bus.h
40 40
    VirtIODevice *vdev;
41 41
    DriveInfo *dinfo;
42 42
    NICConf nic;
43
    uint32_t host_features;
43 44
} VirtIOS390Device;
44 45

  
45 46
typedef struct VirtIOS390Bus {
b/hw/syborg_virtio.c
25 25
#include "syborg.h"
26 26
#include "sysbus.h"
27 27
#include "virtio.h"
28
#include "virtio-net.h"
28 29
#include "sysemu.h"
29 30

  
30 31
//#define DEBUG_SYBORG_VIRTIO
......
66 67
    uint32_t int_enable;
67 68
    uint32_t id;
68 69
    NICConf nic;
70
    uint32_t host_features;
69 71
} SyborgVirtIOProxy;
70 72

  
71 73
static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)
......
86 88
        ret = s->id;
87 89
        break;
88 90
    case SYBORG_VIRTIO_HOST_FEATURES:
89
        ret = vdev->get_features(vdev);
90
        ret |= vdev->binding->get_features(s);
91
        ret = s->host_features;
91 92
        break;
92 93
    case SYBORG_VIRTIO_GUEST_FEATURES:
93 94
        ret = vdev->guest_features;
......
244 245

  
245 246
static unsigned syborg_virtio_get_features(void *opaque)
246 247
{
247
    unsigned ret = 0;
248
    ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
249
    return ret;
248
    SyborgVirtIOProxy *proxy = opaque;
249
    return proxy->host_features;
250 250
}
251 251

  
252 252
static VirtIOBindings syborg_virtio_bindings = {
......
272 272
    qemu_register_reset(virtio_reset, vdev);
273 273

  
274 274
    virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
275
    proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY);
276
    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
275 277
    return 0;
276 278
}
277 279

  
......
292 294
    .qdev.size  = sizeof(SyborgVirtIOProxy),
293 295
    .qdev.props = (Property[]) {
294 296
        DEFINE_NIC_PROPERTIES(SyborgVirtIOProxy, nic),
297
        DEFINE_VIRTIO_NET_FEATURES(SyborgVirtIOProxy, host_features),
295 298
        DEFINE_PROP_END_OF_LIST(),
296 299
    }
297 300
};
b/hw/virtio-balloon.c
124 124
    dev->actual = config.actual;
125 125
}
126 126

  
127
static uint32_t virtio_balloon_get_features(VirtIODevice *vdev)
127
static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
128 128
{
129
    return 0;
129
    return f;
130 130
}
131 131

  
132 132
static ram_addr_t virtio_balloon_to_target(void *opaque, ram_addr_t target)
b/hw/virtio-blk.c
432 432
    memcpy(config, &blkcfg, s->config_size);
433 433
}
434 434

  
435
static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
435
static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
436 436
{
437 437
    VirtIOBlock *s = to_virtio_blk(vdev);
438
    uint32_t features = 0;
439 438

  
440 439
    features |= (1 << VIRTIO_BLK_F_SEG_MAX);
441 440
    features |= (1 << VIRTIO_BLK_F_GEOMETRY);
442 441

  
443 442
    if (bdrv_enable_write_cache(s->bs))
444 443
        features |= (1 << VIRTIO_BLK_F_WCACHE);
445
#ifdef __linux__
446
    features |= (1 << VIRTIO_BLK_F_SCSI);
447
#endif
448 444
    if (strcmp(s->serial_str, "0"))
449 445
        features |= 1 << VIRTIO_BLK_F_IDENTIFY;
450 446
    
b/hw/virtio-blk.h
92 92
    uint32_t residual;
93 93
};
94 94

  
95
#ifdef __linux__
96
#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
97
        DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
98
        DEFINE_PROP_BIT("scsi", _state, _field, VIRTIO_BLK_F_SCSI, true)
99
#else
100
#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
101
        DEFINE_VIRTIO_COMMON_FEATURES(_state, _field)
102
#endif
95 103
#endif
b/hw/virtio-console.c
51 51
{
52 52
}
53 53

  
54
static uint32_t virtio_console_get_features(VirtIODevice *vdev)
54
static uint32_t virtio_console_get_features(VirtIODevice *vdev, uint32_t f)
55 55
{
56
    return 0;
56
    return f;
57 57
}
58 58

  
59 59
static int vcon_can_read(void *opaque)
b/hw/virtio-net.c
147 147
    return n->has_ufo;
148 148
}
149 149

  
150
static uint32_t virtio_net_get_features(VirtIODevice *vdev)
150
static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
151 151
{
152 152
    VirtIONet *n = to_virtio_net(vdev);
153
    uint32_t features = (1 << VIRTIO_NET_F_MAC) |
154
                        (1 << VIRTIO_NET_F_MRG_RXBUF) |
155
                        (1 << VIRTIO_NET_F_STATUS) |
156
                        (1 << VIRTIO_NET_F_CTRL_VQ) |
157
                        (1 << VIRTIO_NET_F_CTRL_RX) |
158
                        (1 << VIRTIO_NET_F_CTRL_VLAN) |
159
                        (1 << VIRTIO_NET_F_CTRL_RX_EXTRA);
160 153

  
161 154
    if (peer_has_vnet_hdr(n)) {
162 155
        tap_using_vnet_hdr(n->nic->nc.peer, 1);
156
    } else {
157
        features &= ~(0x1 << VIRTIO_NET_F_CSUM);
158
        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);
159
        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);
160
        features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN);
161

  
162
        features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM);
163
        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4);
164
        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6);
165
        features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN);
166
    }
163 167

  
164
        features |= (1 << VIRTIO_NET_F_CSUM);
165
        features |= (1 << VIRTIO_NET_F_HOST_TSO4);
166
        features |= (1 << VIRTIO_NET_F_HOST_TSO6);
167
        features |= (1 << VIRTIO_NET_F_HOST_ECN);
168

  
169
        features |= (1 << VIRTIO_NET_F_GUEST_CSUM);
170
        features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
171
        features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
172
        features |= (1 << VIRTIO_NET_F_GUEST_ECN);
173

  
174
        if (peer_has_ufo(n)) {
175
            features |= (1 << VIRTIO_NET_F_GUEST_UFO);
176
            features |= (1 << VIRTIO_NET_F_HOST_UFO);
177
        }
168
    if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
169
        features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO);
170
        features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);
178 171
    }
179 172

  
180 173
    return features;
......
192 185
    features |= (1 << VIRTIO_NET_F_HOST_TSO6);
193 186
    features |= (1 << VIRTIO_NET_F_HOST_ECN);
194 187

  
195
    return features & virtio_net_get_features(vdev);
188
    return features;
196 189
}
197 190

  
198 191
static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
b/hw/virtio-net.h
153 153
 #define VIRTIO_NET_CTRL_VLAN_ADD             0
154 154
 #define VIRTIO_NET_CTRL_VLAN_DEL             1
155 155

  
156
#define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
157
        DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
158
        DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
159
        DEFINE_PROP_BIT("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \
160
        DEFINE_PROP_BIT("mac", _state, _field, VIRTIO_NET_F_MAC, true), \
161
        DEFINE_PROP_BIT("gso", _state, _field, VIRTIO_NET_F_GSO, true), \
162
        DEFINE_PROP_BIT("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \
163
        DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
164
        DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
165
        DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
166
        DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
167
        DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
168
        DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \
169
        DEFINE_PROP_BIT("host_ufo", _state, _field, VIRTIO_NET_F_HOST_UFO, true), \
170
        DEFINE_PROP_BIT("mrg_rxbuf", _state, _field, VIRTIO_NET_F_MRG_RXBUF, true), \
171
        DEFINE_PROP_BIT("status", _state, _field, VIRTIO_NET_F_STATUS, true), \
172
        DEFINE_PROP_BIT("ctrl_vq", _state, _field, VIRTIO_NET_F_CTRL_VQ, true), \
173
        DEFINE_PROP_BIT("ctrl_rx", _state, _field, VIRTIO_NET_F_CTRL_RX, true), \
174
        DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
175
        DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true)
156 176
#endif
b/hw/virtio-pci.c
16 16
#include <inttypes.h>
17 17

  
18 18
#include "virtio.h"
19
#include "virtio-blk.h"
20
#include "virtio-net.h"
19 21
#include "pci.h"
20 22
#include "sysemu.h"
21 23
#include "msix.h"
......
92 94
    uint32_t nvectors;
93 95
    DriveInfo *dinfo;
94 96
    NICConf nic;
97
    uint32_t host_features;
95 98
} VirtIOPCIProxy;
96 99

  
97 100
/* virtio device */
......
175 178
	/* Guest does not negotiate properly?  We have to assume nothing. */
176 179
	if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
177 180
	    if (vdev->bad_features)
178
		val = vdev->bad_features(vdev);
181
		val = proxy->host_features & vdev->bad_features(vdev);
179 182
	    else
180 183
		val = 0;
181 184
	}
......
235 238

  
236 239
    switch (addr) {
237 240
    case VIRTIO_PCI_HOST_FEATURES:
238
        ret = vdev->get_features(vdev);
239
        ret |= vdev->binding->get_features(proxy);
241
        ret = proxy->host_features;
240 242
        break;
241 243
    case VIRTIO_PCI_GUEST_FEATURES:
242 244
        ret = vdev->guest_features;
......
382 384

  
383 385
static unsigned virtio_pci_get_features(void *opaque)
384 386
{
385
    unsigned ret = 0;
386
    ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
387
    ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
388
    ret |= (1 << VIRTIO_F_BAD_FEATURE);
389
    return ret;
387
    VirtIOPCIProxy *proxy = opaque;
388
    return proxy->host_features;
390 389
}
391 390

  
392 391
static const VirtIOBindings virtio_pci_bindings = {
......
442 441
                           virtio_map);
443 442

  
444 443
    virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
444
    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
445
    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
446
    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
445 447
}
446 448

  
447 449
static int virtio_blk_init_pci(PCIDevice *pci_dev)
......
553 555
            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
554 556
            DEFINE_PROP_DRIVE("drive", VirtIOPCIProxy, dinfo),
555 557
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
558
            DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
556 559
            DEFINE_PROP_END_OF_LIST(),
557 560
        },
558 561
        .qdev.reset = virtio_pci_reset,
......
564 567
        .romfile    = "pxe-virtio.bin",
565 568
        .qdev.props = (Property[]) {
566 569
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
570
            DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
567 571
            DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
568 572
            DEFINE_PROP_END_OF_LIST(),
569 573
        },
......
575 579
        .exit      = virtio_exit_pci,
576 580
        .qdev.props = (Property[]) {
577 581
            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
582
            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
578 583
            DEFINE_PROP_END_OF_LIST(),
579 584
        },
580 585
        .qdev.reset = virtio_pci_reset,
......
583 588
        .qdev.size = sizeof(VirtIOPCIProxy),
584 589
        .init      = virtio_balloon_init_pci,
585 590
        .exit      = virtio_exit_pci,
591
        .qdev.props = (Property[]) {
592
            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
593
            DEFINE_PROP_END_OF_LIST(),
594
        },
586 595
        .qdev.reset = virtio_pci_reset,
587 596
    },{
588 597
        /* end of list */
b/hw/virtio.c
652 652
{
653 653
    int num, i, ret;
654 654
    uint32_t features;
655
    uint32_t supported_features = vdev->get_features(vdev) |
655
    uint32_t supported_features =
656 656
        vdev->binding->get_features(vdev->binding_opaque);
657 657

  
658 658
    if (vdev->binding->load_config) {
b/hw/virtio.h
105 105
    void *config;
106 106
    uint16_t config_vector;
107 107
    int nvectors;
108
    uint32_t (*get_features)(VirtIODevice *vdev);
108
    uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
109 109
    uint32_t (*bad_features)(VirtIODevice *vdev);
110 110
    void (*set_features)(VirtIODevice *vdev, uint32_t val);
111 111
    void (*get_config)(VirtIODevice *vdev, uint8_t *config);
......
176 176

  
177 177
void virtio_net_exit(VirtIODevice *vdev);
178 178

  
179
#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
180
	DEFINE_PROP_BIT("indirect_desc", _state, _field, \
181
			VIRTIO_RING_F_INDIRECT_DESC, true)
182

  
183

  
179 184
#endif

Also available in: Unified diff