libqos: extend feature bits to 64-bit
In VIRTIO 1.0 feature bits changed from 32-bit to 64-bit. (In fact, the transports allow even more feature bits but nothing uses more than 64 bits today.) Add 64-bit feature bit support to virtio-mmio and virtio-pci. This will be necessary for VIRTIO 1.0 support. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-Id: <20191023100425.12168-4-stefanha@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
60ce3a40fc
commit
a9340358f4
|
@ -40,22 +40,38 @@ static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t off)
|
|||
return qtest_readq(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
|
||||
}
|
||||
|
||||
static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d)
|
||||
static uint64_t qvirtio_mmio_get_features(QVirtioDevice *d)
|
||||
{
|
||||
QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
|
||||
uint64_t lo;
|
||||
uint64_t hi = 0;
|
||||
|
||||
qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 0);
|
||||
return qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
|
||||
lo = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
|
||||
|
||||
if (dev->version >= 2) {
|
||||
qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 1);
|
||||
hi = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
|
||||
}
|
||||
|
||||
return (hi << 32) | lo;
|
||||
}
|
||||
|
||||
static void qvirtio_mmio_set_features(QVirtioDevice *d, uint32_t features)
|
||||
static void qvirtio_mmio_set_features(QVirtioDevice *d, uint64_t features)
|
||||
{
|
||||
QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
|
||||
dev->features = features;
|
||||
qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 0);
|
||||
qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, features);
|
||||
|
||||
if (dev->version >= 2) {
|
||||
qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 1);
|
||||
qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES,
|
||||
features >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t qvirtio_mmio_get_guest_features(QVirtioDevice *d)
|
||||
static uint64_t qvirtio_mmio_get_guest_features(QVirtioDevice *d)
|
||||
{
|
||||
QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
|
||||
return dev->features;
|
||||
|
@ -149,8 +165,8 @@ static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
|
|||
vq->free_head = 0;
|
||||
vq->num_free = vq->size;
|
||||
vq->align = dev->page_size;
|
||||
vq->indirect = (dev->features & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0;
|
||||
vq->event = (dev->features & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0;
|
||||
vq->indirect = dev->features & (1ull << VIRTIO_RING_F_INDIRECT_DESC);
|
||||
vq->event = dev->features & (1ull << VIRTIO_RING_F_EVENT_IDX);
|
||||
|
||||
qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size);
|
||||
|
||||
|
|
|
@ -44,11 +44,11 @@ static void virtio_net_setup(QVirtioNet *interface)
|
|||
|
||||
features = qvirtio_get_features(vdev);
|
||||
features &= ~(QVIRTIO_F_BAD_FEATURE |
|
||||
(1u << VIRTIO_RING_F_INDIRECT_DESC) |
|
||||
(1u << VIRTIO_RING_F_EVENT_IDX));
|
||||
(1ull << VIRTIO_RING_F_INDIRECT_DESC) |
|
||||
(1ull << VIRTIO_RING_F_EVENT_IDX));
|
||||
qvirtio_set_features(vdev, features);
|
||||
|
||||
if (features & (1u << VIRTIO_NET_F_MQ)) {
|
||||
if (features & (1ull << VIRTIO_NET_F_MQ)) {
|
||||
interface->n_queues = qvirtio_config_readw(vdev, 8) * 2;
|
||||
} else {
|
||||
interface->n_queues = 2;
|
||||
|
|
|
@ -96,19 +96,19 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t off)
|
|||
return val;
|
||||
}
|
||||
|
||||
static uint32_t qvirtio_pci_get_features(QVirtioDevice *d)
|
||||
static uint64_t qvirtio_pci_get_features(QVirtioDevice *d)
|
||||
{
|
||||
QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
|
||||
return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_HOST_FEATURES);
|
||||
}
|
||||
|
||||
static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features)
|
||||
static void qvirtio_pci_set_features(QVirtioDevice *d, uint64_t features)
|
||||
{
|
||||
QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
|
||||
qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES, features);
|
||||
}
|
||||
|
||||
static uint32_t qvirtio_pci_get_guest_features(QVirtioDevice *d)
|
||||
static uint64_t qvirtio_pci_get_guest_features(QVirtioDevice *d)
|
||||
{
|
||||
QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
|
||||
return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES);
|
||||
|
@ -208,7 +208,7 @@ static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
|
|||
static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
|
||||
QGuestAllocator *alloc, uint16_t index)
|
||||
{
|
||||
uint32_t feat;
|
||||
uint64_t feat;
|
||||
uint64_t addr;
|
||||
QVirtQueuePCI *vqpci;
|
||||
QVirtioPCIDevice *qvpcidev = container_of(d, QVirtioPCIDevice, vdev);
|
||||
|
@ -222,8 +222,8 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
|
|||
vqpci->vq.free_head = 0;
|
||||
vqpci->vq.num_free = vqpci->vq.size;
|
||||
vqpci->vq.align = VIRTIO_PCI_VRING_ALIGN;
|
||||
vqpci->vq.indirect = (feat & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0;
|
||||
vqpci->vq.event = (feat & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0;
|
||||
vqpci->vq.indirect = feat & (1ull << VIRTIO_RING_F_INDIRECT_DESC);
|
||||
vqpci->vq.event = feat & (1ull << VIRTIO_RING_F_EVENT_IDX);
|
||||
|
||||
vqpci->msix_entry = -1;
|
||||
vqpci->msix_addr = 0;
|
||||
|
|
|
@ -33,12 +33,12 @@ uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr)
|
|||
return d->bus->config_readq(d, addr);
|
||||
}
|
||||
|
||||
uint32_t qvirtio_get_features(QVirtioDevice *d)
|
||||
uint64_t qvirtio_get_features(QVirtioDevice *d)
|
||||
{
|
||||
return d->bus->get_features(d);
|
||||
}
|
||||
|
||||
void qvirtio_set_features(QVirtioDevice *d, uint32_t features)
|
||||
void qvirtio_set_features(QVirtioDevice *d, uint64_t features)
|
||||
{
|
||||
d->features = features;
|
||||
d->bus->set_features(d, features);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "libqos/malloc.h"
|
||||
#include "standard-headers/linux/virtio_ring.h"
|
||||
|
||||
#define QVIRTIO_F_BAD_FEATURE 0x40000000
|
||||
#define QVIRTIO_F_BAD_FEATURE 0x40000000ull
|
||||
|
||||
typedef struct QVirtioBus QVirtioBus;
|
||||
|
||||
|
@ -52,13 +52,13 @@ struct QVirtioBus {
|
|||
uint64_t (*config_readq)(QVirtioDevice *d, uint64_t addr);
|
||||
|
||||
/* Get features of the device */
|
||||
uint32_t (*get_features)(QVirtioDevice *d);
|
||||
uint64_t (*get_features)(QVirtioDevice *d);
|
||||
|
||||
/* Set features of the device */
|
||||
void (*set_features)(QVirtioDevice *d, uint32_t features);
|
||||
void (*set_features)(QVirtioDevice *d, uint64_t features);
|
||||
|
||||
/* Get features of the guest */
|
||||
uint32_t (*get_guest_features)(QVirtioDevice *d);
|
||||
uint64_t (*get_guest_features)(QVirtioDevice *d);
|
||||
|
||||
/* Get status of the device */
|
||||
uint8_t (*get_status)(QVirtioDevice *d);
|
||||
|
@ -103,8 +103,8 @@ uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr);
|
|||
uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr);
|
||||
uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr);
|
||||
uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr);
|
||||
uint32_t qvirtio_get_features(QVirtioDevice *d);
|
||||
void qvirtio_set_features(QVirtioDevice *d, uint32_t features);
|
||||
uint64_t qvirtio_get_features(QVirtioDevice *d);
|
||||
void qvirtio_set_features(QVirtioDevice *d, uint64_t features);
|
||||
bool qvirtio_is_big_endian(QVirtioDevice *d);
|
||||
|
||||
void qvirtio_reset(QVirtioDevice *d);
|
||||
|
|
|
@ -119,7 +119,7 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
|
|||
QVirtioBlkReq req;
|
||||
uint64_t req_addr;
|
||||
uint64_t capacity;
|
||||
uint32_t features;
|
||||
uint64_t features;
|
||||
uint32_t free_head;
|
||||
uint8_t status;
|
||||
char *data;
|
||||
|
@ -352,7 +352,7 @@ static void indirect(void *obj, void *u_data, QGuestAllocator *t_alloc)
|
|||
QVRingIndirectDesc *indirect;
|
||||
uint64_t req_addr;
|
||||
uint64_t capacity;
|
||||
uint32_t features;
|
||||
uint64_t features;
|
||||
uint32_t free_head;
|
||||
uint8_t status;
|
||||
char *data;
|
||||
|
@ -467,7 +467,7 @@ static void msix(void *obj, void *u_data, QGuestAllocator *t_alloc)
|
|||
int n_size = TEST_IMAGE_SIZE / 2;
|
||||
uint64_t req_addr;
|
||||
uint64_t capacity;
|
||||
uint32_t features;
|
||||
uint64_t features;
|
||||
uint32_t free_head;
|
||||
uint8_t status;
|
||||
char *data;
|
||||
|
@ -574,7 +574,7 @@ static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc)
|
|||
QVirtioBlkReq req;
|
||||
uint64_t req_addr;
|
||||
uint64_t capacity;
|
||||
uint32_t features;
|
||||
uint64_t features;
|
||||
uint32_t free_head;
|
||||
uint32_t write_head;
|
||||
uint32_t desc_idx;
|
||||
|
|
Loading…
Reference in a new issue