virtio-pci: reduce modern_mem_bar size
Currently each VQ Notification Virtio Capability is allocated on a different page. The idea is to enable split drivers within guests, however there are no known plans to do that. The allocation will result in a 8MB BAR, more than various guest firmwares pre-allocates for PCI Bridges hotplug process. Reserve 4 bytes per VQ by default and add a new parameter "page-per-vq" to be used with split drivers. Signed-off-by: Marcel Apfelbaum <marcel@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
14c985cffa
commit
d9997d89a4
|
@ -294,6 +294,12 @@ static void virtio_pci_ioeventfd_set_disabled(DeviceState *d, bool disabled)
|
||||||
|
|
||||||
#define QEMU_VIRTIO_PCI_QUEUE_MEM_MULT 0x1000
|
#define QEMU_VIRTIO_PCI_QUEUE_MEM_MULT 0x1000
|
||||||
|
|
||||||
|
static inline int virtio_pci_queue_mem_mult(struct VirtIOPCIProxy *proxy)
|
||||||
|
{
|
||||||
|
return (proxy->flags & VIRTIO_PCI_FLAG_PAGE_PER_VQ) ?
|
||||||
|
QEMU_VIRTIO_PCI_QUEUE_MEM_MULT : 4;
|
||||||
|
}
|
||||||
|
|
||||||
static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
|
static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
|
||||||
int n, bool assign)
|
int n, bool assign)
|
||||||
{
|
{
|
||||||
|
@ -307,7 +313,7 @@ static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,
|
||||||
MemoryRegion *modern_mr = &proxy->notify.mr;
|
MemoryRegion *modern_mr = &proxy->notify.mr;
|
||||||
MemoryRegion *modern_notify_mr = &proxy->notify_pio.mr;
|
MemoryRegion *modern_notify_mr = &proxy->notify_pio.mr;
|
||||||
MemoryRegion *legacy_mr = &proxy->bar;
|
MemoryRegion *legacy_mr = &proxy->bar;
|
||||||
hwaddr modern_addr = QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *
|
hwaddr modern_addr = virtio_pci_queue_mem_mult(proxy) *
|
||||||
virtio_get_queue_index(vq);
|
virtio_get_queue_index(vq);
|
||||||
hwaddr legacy_addr = VIRTIO_PCI_QUEUE_NOTIFY;
|
hwaddr legacy_addr = VIRTIO_PCI_QUEUE_NOTIFY;
|
||||||
|
|
||||||
|
@ -1370,7 +1376,8 @@ static void virtio_pci_notify_write(void *opaque, hwaddr addr,
|
||||||
uint64_t val, unsigned size)
|
uint64_t val, unsigned size)
|
||||||
{
|
{
|
||||||
VirtIODevice *vdev = opaque;
|
VirtIODevice *vdev = opaque;
|
||||||
unsigned queue = addr / QEMU_VIRTIO_PCI_QUEUE_MEM_MULT;
|
VirtIOPCIProxy *proxy = VIRTIO_PCI(DEVICE(vdev)->parent_bus->parent);
|
||||||
|
unsigned queue = addr / virtio_pci_queue_mem_mult(proxy);
|
||||||
|
|
||||||
if (queue < VIRTIO_QUEUE_MAX) {
|
if (queue < VIRTIO_QUEUE_MAX) {
|
||||||
virtio_queue_notify(vdev, queue);
|
virtio_queue_notify(vdev, queue);
|
||||||
|
@ -1609,7 +1616,7 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
|
||||||
struct virtio_pci_notify_cap notify = {
|
struct virtio_pci_notify_cap notify = {
|
||||||
.cap.cap_len = sizeof notify,
|
.cap.cap_len = sizeof notify,
|
||||||
.notify_off_multiplier =
|
.notify_off_multiplier =
|
||||||
cpu_to_le32(QEMU_VIRTIO_PCI_QUEUE_MEM_MULT),
|
cpu_to_le32(virtio_pci_queue_mem_mult(proxy)),
|
||||||
};
|
};
|
||||||
struct virtio_pci_cfg_cap cfg = {
|
struct virtio_pci_cfg_cap cfg = {
|
||||||
.cap.cap_len = sizeof cfg,
|
.cap.cap_len = sizeof cfg,
|
||||||
|
@ -1744,8 +1751,7 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
|
||||||
proxy->device.type = VIRTIO_PCI_CAP_DEVICE_CFG;
|
proxy->device.type = VIRTIO_PCI_CAP_DEVICE_CFG;
|
||||||
|
|
||||||
proxy->notify.offset = 0x3000;
|
proxy->notify.offset = 0x3000;
|
||||||
proxy->notify.size =
|
proxy->notify.size = virtio_pci_queue_mem_mult(proxy) * VIRTIO_QUEUE_MAX;
|
||||||
QEMU_VIRTIO_PCI_QUEUE_MEM_MULT * VIRTIO_QUEUE_MAX;
|
|
||||||
proxy->notify.type = VIRTIO_PCI_CAP_NOTIFY_CFG;
|
proxy->notify.type = VIRTIO_PCI_CAP_NOTIFY_CFG;
|
||||||
|
|
||||||
proxy->notify_pio.offset = 0x0;
|
proxy->notify_pio.offset = 0x0;
|
||||||
|
@ -1754,8 +1760,8 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
|
||||||
|
|
||||||
/* subclasses can enforce modern, so do this unconditionally */
|
/* subclasses can enforce modern, so do this unconditionally */
|
||||||
memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci",
|
memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci",
|
||||||
2 * QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *
|
/* PCI BAR regions must be powers of 2 */
|
||||||
VIRTIO_QUEUE_MAX);
|
pow2ceil(proxy->notify.offset + proxy->notify.size));
|
||||||
|
|
||||||
memory_region_init_alias(&proxy->modern_cfg,
|
memory_region_init_alias(&proxy->modern_cfg,
|
||||||
OBJECT(proxy),
|
OBJECT(proxy),
|
||||||
|
@ -1833,6 +1839,8 @@ static Property virtio_pci_properties[] = {
|
||||||
VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT, false),
|
VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT, false),
|
||||||
DEFINE_PROP_BIT("x-disable-pcie", VirtIOPCIProxy, flags,
|
DEFINE_PROP_BIT("x-disable-pcie", VirtIOPCIProxy, flags,
|
||||||
VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT, false),
|
VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT, false),
|
||||||
|
DEFINE_PROP_BIT("page-per-vq", VirtIOPCIProxy, flags,
|
||||||
|
VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT, false),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ enum {
|
||||||
VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
|
VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
|
||||||
VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
|
VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
|
||||||
VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
|
VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
|
||||||
|
VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Need to activate work-arounds for buggy guests at vmstate load. */
|
/* Need to activate work-arounds for buggy guests at vmstate load. */
|
||||||
|
@ -84,6 +85,10 @@ enum {
|
||||||
#define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \
|
#define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \
|
||||||
(1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT)
|
(1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT)
|
||||||
|
|
||||||
|
/* page per vq flag to be used by split drivers within guests */
|
||||||
|
#define VIRTIO_PCI_FLAG_PAGE_PER_VQ \
|
||||||
|
(1 << VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MSIMessage msg;
|
MSIMessage msg;
|
||||||
int virq;
|
int virq;
|
||||||
|
|
|
@ -2,7 +2,11 @@
|
||||||
#define HW_COMPAT_H
|
#define HW_COMPAT_H
|
||||||
|
|
||||||
#define HW_COMPAT_2_7 \
|
#define HW_COMPAT_2_7 \
|
||||||
/* empty */
|
{\
|
||||||
|
.driver = "virtio-pci",\
|
||||||
|
.property = "page-per-vq",\
|
||||||
|
.value = "on",\
|
||||||
|
},
|
||||||
|
|
||||||
#define HW_COMPAT_2_6 \
|
#define HW_COMPAT_2_6 \
|
||||||
{\
|
{\
|
||||||
|
|
Loading…
Reference in New Issue