Skip to content

Commit

Permalink
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
Browse files Browse the repository at this point in the history
pci,virtio

This further optimizes MSIX handling in virtio-pci.
Also included is pci cleanup by Paolo, and pci device
assignment fix by Alex.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

* mst/tags/for_anthony:
  pci-assign: Enable MSIX on device to match guest
  pci: use constants for devices under the 1B36 device ID, document them
  ivshmem: use symbolic constant for PCI ID, add to pci-ids.txt
  virtio-9p: use symbolic constant, add to pci-ids.txt
  reorganize pci-ids.txt
  docs: move pci-ids.txt to docs/specs/
  vhost: backend masking support
  vhost: set started flag while start is in progress
  virtio-net: set/clear vhost_started in reverse order
  virtio: backend virtqueue notifier masking
  virtio-pci: cache msix messages
  kvm: add stub for update msi route
  msix: add api to access msix message
  virtio: don't waste irqfds on control vqs
  • Loading branch information
Anthony Liguori committed Jan 14, 2013
2 parents 7adef3b + feb9a2a commit 8e9a868
Show file tree
Hide file tree
Showing 19 changed files with 437 additions and 100 deletions.
50 changes: 50 additions & 0 deletions docs/specs/pci-ids.txt
@@ -0,0 +1,50 @@

PCI IDs for qemu
================

Red Hat, Inc. donates a part of its device ID range to qemu, to be used for
virtual devices. The vendor IDs are 1af4 (formerly Qumranet ID) and 1b36.

Contact Gerd Hoffmann <kraxel@redhat.com> to get a device ID assigned
for your devices.

1af4 vendor ID
--------------

The 1000 -> 10ff device ID range is used as follows for virtio-pci devices.
Note that this allocation separate from the virtio device IDs, which are
maintained as part of the virtio specification.

1af4:1000 network device
1af4:1001 block device
1af4:1002 balloon device
1af4:1003 console device
1af4:1004 SCSI host bus adapter device
1af4:1005 entropy generator device
1af4:1009 9p filesystem device

1af4:10f0 Available for experimental usage without registration. Must get
to official ID when the code leaves the test lab (i.e. when seeking
1af4:10ff upstream merge or shipping a distro/product) to avoid conflicts.

1af4:1100 Used as PCI Subsystem ID for existing hardware devices emulated
by qemu.

1af4:1110 ivshmem device (shared memory, docs/specs/ivshmem_device_spec.txt)

All other device IDs are reserved.

1b36 vendor ID
--------------

The 0000 -> 00ff device ID range is used as follows for QEMU-specific
PCI devices (other than virtio):

1b36:0001 PCI-PCI bridge
1b36:0002 PCI serial port (16550A) adapter (docs/specs/pci-serial.txt)
1b36:0003 PCI Dual-port 16550A adapter (docs/specs/pci-serial.txt)
1b36:0004 PCI Quad-port 16550A adapter (docs/specs/pci-serial.txt)

All these devices are documented in docs/specs.

The 0100 device ID is used for the QXL video card device.
2 changes: 1 addition & 1 deletion hw/9pfs/virtio-9p-device.c
Expand Up @@ -170,7 +170,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)

k->init = virtio_9p_init_pci;
k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
k->device_id = 0x1009;
k->device_id = PCI_DEVICE_ID_VIRTIO_9P;
k->revision = VIRTIO_PCI_ABI_VERSION;
k->class_id = 0x2;
dc->props = virtio_9p_properties;
Expand Down
7 changes: 5 additions & 2 deletions hw/ivshmem.c
Expand Up @@ -29,6 +29,9 @@
#include <sys/mman.h>
#include <sys/types.h>

#define PCI_VENDOR_ID_IVSHMEM PCI_VENDOR_ID_REDHAT_QUMRANET
#define PCI_DEVICE_ID_IVSHMEM 0x1110

#define IVSHMEM_IOEVENTFD 0
#define IVSHMEM_MSI 1

Expand Down Expand Up @@ -800,8 +803,8 @@ static void ivshmem_class_init(ObjectClass *klass, void *data)

k->init = pci_ivshmem_init;
k->exit = pci_ivshmem_uninit;
k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
k->device_id = 0x1110;
k->vendor_id = PCI_VENDOR_ID_IVSHMEM;
k->device_id = PCI_DEVICE_ID_IVSHMEM;
k->class_id = PCI_CLASS_MEMORY_RAM;
dc->reset = ivshmem_reset;
dc->props = ivshmem_properties;
Expand Down
17 changes: 15 additions & 2 deletions hw/kvm/pci-assign.c
Expand Up @@ -1031,6 +1031,19 @@ static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
return (entry->ctrl & cpu_to_le32(0x1)) != 0;
}

/*
* When MSI-X is first enabled the vector table typically has all the
* vectors masked, so we can't use that as the obvious test to figure out
* how many vectors to initially enable. Instead we look at the data field
* because this is what worked for pci-assign for a long time. This makes
* sure the physical MSI-X state tracks the guest's view, which is important
* for some VF/PF and PF/fw communication channels.
*/
static bool assigned_dev_msix_skipped(MSIXTableEntry *entry)
{
return !entry->data;
}

static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
{
AssignedDevice *adev = DO_UPCAST(AssignedDevice, dev, pci_dev);
Expand All @@ -1041,7 +1054,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)

/* Get the usable entry number for allocating */
for (i = 0; i < adev->msix_max; i++, entry++) {
if (assigned_dev_msix_masked(entry)) {
if (assigned_dev_msix_skipped(entry)) {
continue;
}
entries_nr++;
Expand Down Expand Up @@ -1070,7 +1083,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
for (i = 0; i < adev->msix_max; i++, entry++) {
adev->msi_virq[i] = -1;

if (assigned_dev_msix_masked(entry)) {
if (assigned_dev_msix_skipped(entry)) {
continue;
}

Expand Down
2 changes: 1 addition & 1 deletion hw/pci/msix.c
Expand Up @@ -27,7 +27,7 @@
#define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8)
#define MSIX_MASKALL_MASK (PCI_MSIX_FLAGS_MASKALL >> 8)

static MSIMessage msix_get_message(PCIDevice *dev, unsigned vector)
MSIMessage msix_get_message(PCIDevice *dev, unsigned vector)
{
uint8_t *table_entry = dev->msix_table + vector * PCI_MSIX_ENTRY_SIZE;
MSIMessage msg;
Expand Down
1 change: 1 addition & 0 deletions hw/pci/msix.h
Expand Up @@ -5,6 +5,7 @@
#include "hw/pci/pci.h"

void msix_set_message(PCIDevice *dev, int vector, MSIMessage msg);
MSIMessage msix_get_message(PCIDevice *dev, unsigned int vector);
int msix_init(PCIDevice *dev, unsigned short nentries,
MemoryRegion *table_bar, uint8_t table_bar_nr,
unsigned table_offset, MemoryRegion *pba_bar,
Expand Down
8 changes: 8 additions & 0 deletions hw/pci/pci.h
Expand Up @@ -77,6 +77,14 @@
#define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003
#define PCI_DEVICE_ID_VIRTIO_SCSI 0x1004
#define PCI_DEVICE_ID_VIRTIO_RNG 0x1005
#define PCI_DEVICE_ID_VIRTIO_9P 0x1009

#define PCI_VENDOR_ID_REDHAT 0x1b36
#define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001
#define PCI_DEVICE_ID_REDHAT_SERIAL 0x0002
#define PCI_DEVICE_ID_REDHAT_SERIAL2 0x0003
#define PCI_DEVICE_ID_REDHAT_SERIAL4 0x0004
#define PCI_DEVICE_ID_REDHAT_QXL 0x0100

#define FMT_PCIBUS PRIx64

Expand Down
8 changes: 2 additions & 6 deletions hw/pci_bridge_dev.c
Expand Up @@ -27,10 +27,6 @@
#include "exec/memory.h"
#include "pci/pci_bus.h"

#define REDHAT_PCI_VENDOR_ID 0x1b36
#define PCI_BRIDGE_DEV_VENDOR_ID REDHAT_PCI_VENDOR_ID
#define PCI_BRIDGE_DEV_DEVICE_ID 0x1

struct PCIBridgeDev {
PCIBridge bridge;
MemoryRegion bar;
Expand Down Expand Up @@ -146,8 +142,8 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
k->init = pci_bridge_dev_initfn;
k->exit = pci_bridge_dev_exitfn;
k->config_write = pci_bridge_dev_write_config;
k->vendor_id = PCI_BRIDGE_DEV_VENDOR_ID;
k->device_id = PCI_BRIDGE_DEV_DEVICE_ID;
k->vendor_id = PCI_VENDOR_ID_REDHAT;
k->device_id = PCI_DEVICE_ID_REDHAT_BRIDGE;
k->class_id = PCI_CLASS_BRIDGE_PCI;
k->is_bridge = 1,
dc->desc = "Standard PCI Bridge";
Expand Down
12 changes: 6 additions & 6 deletions hw/serial-pci.c
Expand Up @@ -185,8 +185,8 @@ static void serial_pci_class_initfn(ObjectClass *klass, void *data)
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
pc->init = serial_pci_init;
pc->exit = serial_pci_exit;
pc->vendor_id = 0x1b36; /* Red Hat */
pc->device_id = 0x0002;
pc->vendor_id = PCI_VENDOR_ID_REDHAT;
pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL;
pc->revision = 1;
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_serial;
Expand All @@ -199,8 +199,8 @@ static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
pc->init = multi_serial_pci_init;
pc->exit = multi_serial_pci_exit;
pc->vendor_id = 0x1b36; /* Red Hat */
pc->device_id = 0x0003;
pc->vendor_id = PCI_VENDOR_ID_REDHAT;
pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL2;
pc->revision = 1;
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_multi_serial;
Expand All @@ -213,8 +213,8 @@ static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
pc->init = multi_serial_pci_init;
pc->exit = multi_serial_pci_exit;
pc->vendor_id = 0x1b36; /* Red Hat */
pc->device_id = 0x0004;
pc->vendor_id = PCI_VENDOR_ID_REDHAT;
pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL4;
pc->revision = 1;
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_multi_serial;
Expand Down

0 comments on commit 8e9a868

Please sign in to comment.