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 optimizes MSIX handling in virtio-pci.
Also included is pci express capability bugfix.

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

* mst/tags/for_anthony:
  virtio-pci: don't poll masked vectors
  msix: expose access to masked/pending state
  msi: add API to get notified about pending bit poll
  pcie: Fix bug in pcie_ext_cap_set_next
  virtio: make bindings typesafe
  • Loading branch information
Anthony Liguori committed Jan 2, 2013
2 parents a97ff30 + 89d62be commit 079944e
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 61 deletions.
19 changes: 15 additions & 4 deletions hw/pci/msix.c
Expand Up @@ -65,7 +65,7 @@ static int msix_is_pending(PCIDevice *dev, int vector)
return *msix_pending_byte(dev, vector) & msix_pending_mask(vector);
}

static void msix_set_pending(PCIDevice *dev, int vector)
void msix_set_pending(PCIDevice *dev, unsigned int vector)
{
*msix_pending_byte(dev, vector) |= msix_pending_mask(vector);
}
Expand All @@ -75,13 +75,13 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
*msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
}

static bool msix_vector_masked(PCIDevice *dev, int vector, bool fmask)
static bool msix_vector_masked(PCIDevice *dev, unsigned int vector, bool fmask)
{
unsigned offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
return fmask || dev->msix_table[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
}

static bool msix_is_masked(PCIDevice *dev, int vector)
bool msix_is_masked(PCIDevice *dev, unsigned int vector)
{
return msix_vector_masked(dev, vector, dev->msix_function_masked);
}
Expand Down Expand Up @@ -191,6 +191,11 @@ static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr,
unsigned size)
{
PCIDevice *dev = opaque;
if (dev->msix_vector_poll_notifier) {
unsigned vector_start = addr * 8;
unsigned vector_end = MIN(addr + size * 8, dev->msix_entries_nr);
dev->msix_vector_poll_notifier(dev, vector_start, vector_end);
}

return pci_get_long(dev->msix_pba + addr);
}
Expand Down Expand Up @@ -513,14 +518,16 @@ static void msix_unset_notifier_for_vector(PCIDevice *dev, unsigned int vector)

int msix_set_vector_notifiers(PCIDevice *dev,
MSIVectorUseNotifier use_notifier,
MSIVectorReleaseNotifier release_notifier)
MSIVectorReleaseNotifier release_notifier,
MSIVectorPollNotifier poll_notifier)
{
int vector, ret;

assert(use_notifier && release_notifier);

dev->msix_vector_use_notifier = use_notifier;
dev->msix_vector_release_notifier = release_notifier;
dev->msix_vector_poll_notifier = poll_notifier;

if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
(MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
Expand All @@ -531,6 +538,9 @@ int msix_set_vector_notifiers(PCIDevice *dev,
}
}
}
if (dev->msix_vector_poll_notifier) {
dev->msix_vector_poll_notifier(dev, 0, dev->msix_entries_nr);
}
return 0;

undo:
Expand All @@ -557,4 +567,5 @@ void msix_unset_vector_notifiers(PCIDevice *dev)
}
dev->msix_vector_use_notifier = NULL;
dev->msix_vector_release_notifier = NULL;
dev->msix_vector_poll_notifier = NULL;
}
6 changes: 5 additions & 1 deletion hw/pci/msix.h
Expand Up @@ -26,6 +26,9 @@ void msix_load(PCIDevice *dev, QEMUFile *f);
int msix_enabled(PCIDevice *dev);
int msix_present(PCIDevice *dev);

bool msix_is_masked(PCIDevice *dev, unsigned vector);
void msix_set_pending(PCIDevice *dev, unsigned vector);

int msix_vector_use(PCIDevice *dev, unsigned vector);
void msix_vector_unuse(PCIDevice *dev, unsigned vector);
void msix_unuse_all_vectors(PCIDevice *dev);
Expand All @@ -36,6 +39,7 @@ void msix_reset(PCIDevice *dev);

int msix_set_vector_notifiers(PCIDevice *dev,
MSIVectorUseNotifier use_notifier,
MSIVectorReleaseNotifier release_notifier);
MSIVectorReleaseNotifier release_notifier,
MSIVectorPollNotifier poll_notifier);
void msix_unset_vector_notifiers(PCIDevice *dev);
#endif
4 changes: 4 additions & 0 deletions hw/pci/pci.h
Expand Up @@ -187,6 +187,9 @@ typedef void (*PCIINTxRoutingNotifier)(PCIDevice *dev);
typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector,
MSIMessage msg);
typedef void (*MSIVectorReleaseNotifier)(PCIDevice *dev, unsigned int vector);
typedef void (*MSIVectorPollNotifier)(PCIDevice *dev,
unsigned int vector_start,
unsigned int vector_end);

struct PCIDevice {
DeviceState qdev;
Expand Down Expand Up @@ -271,6 +274,7 @@ struct PCIDevice {
/* MSI-X notifiers */
MSIVectorUseNotifier msix_vector_use_notifier;
MSIVectorReleaseNotifier msix_vector_release_notifier;
MSIVectorPollNotifier msix_vector_poll_notifier;
};

void pci_register_bar(PCIDevice *pci_dev, int region_num,
Expand Down
2 changes: 1 addition & 1 deletion hw/pci/pcie.c
Expand Up @@ -494,7 +494,7 @@ uint16_t pcie_find_capability(PCIDevice *dev, uint16_t cap_id)

static void pcie_ext_cap_set_next(PCIDevice *dev, uint16_t pos, uint16_t next)
{
uint16_t header = pci_get_long(dev->config + pos);
uint32_t header = pci_get_long(dev->config + pos);
assert(!(next & (PCI_EXT_CAP_ALIGN - 1)));
header = (header & ~PCI_EXT_CAP_NEXT_MASK) |
((next << PCI_EXT_CAP_NEXT_SHIFT) & PCI_EXT_CAP_NEXT_MASK);
Expand Down
24 changes: 19 additions & 5 deletions hw/s390-virtio-bus.c
Expand Up @@ -138,7 +138,7 @@ static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)

bus->dev_offs += dev_len;

virtio_bind_device(vdev, &virtio_s390_bindings, dev);
virtio_bind_device(vdev, &virtio_s390_bindings, DEVICE(dev));
dev->host_features = vdev->get_features(vdev, dev->host_features);
s390_virtio_device_sync(dev);
s390_virtio_reset_idx(dev);
Expand Down Expand Up @@ -364,18 +364,32 @@ VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
return NULL;
}

static void virtio_s390_notify(void *opaque, uint16_t vector)
/* DeviceState to VirtIOS390Device. Note: used on datapath,
* be careful and test performance if you change this.
*/
static inline VirtIOS390Device *to_virtio_s390_device_fast(DeviceState *d)
{
return container_of(d, VirtIOS390Device, qdev);
}

/* DeviceState to VirtIOS390Device. TODO: use QOM. */
static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d)
{
return container_of(d, VirtIOS390Device, qdev);
}

static void virtio_s390_notify(DeviceState *d, uint16_t vector)
{
VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
VirtIOS390Device *dev = to_virtio_s390_device_fast(d);
uint64_t token = s390_virtio_device_vq_token(dev, vector);
S390CPU *cpu = s390_cpu_addr2state(0);

s390_virtio_irq(cpu, 0, token);
}

static unsigned virtio_s390_get_features(void *opaque)
static unsigned virtio_s390_get_features(DeviceState *d)
{
VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
VirtIOS390Device *dev = to_virtio_s390_device(d);
return dev->host_features;
}

Expand Down
2 changes: 1 addition & 1 deletion hw/vfio_pci.c
Expand Up @@ -698,7 +698,7 @@ static void vfio_enable_msix(VFIODevice *vdev)
vdev->interrupt = VFIO_INT_MSIX;

if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
vfio_msix_vector_release)) {
vfio_msix_vector_release, NULL)) {
error_report("vfio: msix_set_vector_notifiers failed\n");
}

Expand Down

0 comments on commit 079944e

Please sign in to comment.