[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] MSI-X: enhancement
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1218631539 -3600 # Node ID 0638a5c2cc9f2053f6025edf3ddc5ff12300924d # Parent 644a9d219973b9b21fd0590eec38370f4fb8caae MSI-X: enhancement Signed-off-by: Yu Zhao <yu.zhao@xxxxxxxxx> --- tools/ioemu/hw/pass-through.h | 1 tools/ioemu/hw/pt-msi.c | 24 +++++------- tools/libxc/xc_physdev.c | 10 ++--- tools/libxc/xenctrl.h | 2 - xen/arch/x86/msi.c | 82 +++++++++++++++--------------------------- xen/arch/x86/physdev.c | 15 +++++-- xen/drivers/passthrough/io.c | 3 + xen/include/asm-x86/msi.h | 10 ++++- xen/include/public/physdev.h | 11 +++-- 9 files changed, 76 insertions(+), 82 deletions(-) diff -r 644a9d219973 -r 0638a5c2cc9f tools/ioemu/hw/pass-through.h --- a/tools/ioemu/hw/pass-through.h Wed Aug 13 13:42:30 2008 +0100 +++ b/tools/ioemu/hw/pass-through.h Wed Aug 13 13:45:39 2008 +0100 @@ -120,6 +120,7 @@ struct pt_msix_info { int enabled; int total_entries; int bar_index; + uint64_t table_base; uint32_t table_off; uint64_t mmio_base_addr; int mmio_index; diff -r 644a9d219973 -r 0638a5c2cc9f tools/ioemu/hw/pt-msi.c --- a/tools/ioemu/hw/pt-msi.c Wed Aug 13 13:42:30 2008 +0100 +++ b/tools/ioemu/hw/pt-msi.c Wed Aug 13 13:45:39 2008 +0100 @@ -38,8 +38,8 @@ int pt_msi_setup(struct pt_dev *dev) } if ( xc_physdev_map_pirq_msi(xc_handle, domid, AUTO_ASSIGN, &pirq, - dev->pci_dev->dev << 3 | dev->pci_dev->func, - dev->pci_dev->bus, 0, 1) ) + dev->pci_dev->dev << 3 | dev->pci_dev->func, + dev->pci_dev->bus, 0, 0) ) { PT_LOG("error map msi\n"); return -1; @@ -121,7 +121,8 @@ static int pt_msix_update_one(struct pt_ { ret = xc_physdev_map_pirq_msi(xc_handle, domid, AUTO_ASSIGN, &pirq, dev->pci_dev->dev << 3 | dev->pci_dev->func, - dev->pci_dev->bus, entry_nr, 0); + dev->pci_dev->bus, entry_nr, + dev->msix->table_base); if ( ret ) { PT_LOG("error map msix entry %x\n", entry_nr); @@ -183,7 +184,7 @@ static void pci_msix_writel(void *opaque entry = &msix->msix_entry[entry_nr]; offset = ((addr - msix->mmio_base_addr) % 16) / 4; - if ( offset != 3 && msix->enabled && entry->io_mem[3] & 0x1 ) + if ( offset != 3 && msix->enabled && !(entry->io_mem[3] & 0x1) ) { PT_LOG("can not update msix entry %d since MSI-X is already \ function now.\n", entry_nr); @@ -196,7 +197,7 @@ static void pci_msix_writel(void *opaque if ( offset == 3 ) { - if ( !(val & 0x1) ) + if ( msix->enabled && !(val & 0x1) ) pt_msix_update_one(dev, entry_nr); mask_physical_msix_entry(dev, entry_nr, entry->io_mem[3] & 0x1); } @@ -280,7 +281,6 @@ int pt_msix_init(struct pt_dev *dev, int uint8_t id; uint16_t control; int i, total_entries, table_off, bar_index; - uint64_t bar_base; struct pci_dev *pd = dev->pci_dev; id = pci_read_byte(pd, pos + PCI_CAP_LIST_ID); @@ -314,18 +314,14 @@ int pt_msix_init(struct pt_dev *dev, int table_off = pci_read_long(pd, pos + PCI_MSIX_TABLE); bar_index = dev->msix->bar_index = table_off & PCI_MSIX_BIR; table_off &= table_off & ~PCI_MSIX_BIR; - bar_base = pci_read_long(pd, 0x10 + 4 * bar_index); - if ( (bar_base & 0x6) == 0x4 ) - { - bar_base &= ~0xf; - bar_base += (uint64_t)pci_read_long(pd, 0x10 + 4 * (bar_index + 1)) << 32; - } - PT_LOG("get MSI-X table bar base %lx\n", bar_base); + dev->msix->table_base = dev->pci_dev->base_addr[bar_index]; + PT_LOG("get MSI-X table bar base %llx\n", + (unsigned long long)dev->msix->table_base); dev->msix->fd = open("/dev/mem", O_RDWR); dev->msix->phys_iomem_base = mmap(0, total_entries * 16, PROT_WRITE | PROT_READ, MAP_SHARED | MAP_LOCKED, - dev->msix->fd, bar_base + table_off); + dev->msix->fd, dev->msix->table_base + table_off); PT_LOG("mapping physical MSI-X table to %lx\n", (unsigned long)dev->msix->phys_iomem_base); return 0; diff -r 644a9d219973 -r 0638a5c2cc9f tools/libxc/xc_physdev.c --- a/tools/libxc/xc_physdev.c Wed Aug 13 13:42:30 2008 +0100 +++ b/tools/libxc/xc_physdev.c Wed Aug 13 13:45:39 2008 +0100 @@ -51,7 +51,7 @@ int xc_physdev_map_pirq_msi(int xc_handl int devfn, int bus, int entry_nr, - int msi_type) + uint64_t table_base) { int rc; struct physdev_map_pirq map; @@ -63,10 +63,10 @@ int xc_physdev_map_pirq_msi(int xc_handl map.type = MAP_PIRQ_TYPE_MSI; map.index = index; map.pirq = *pirq; - map.msi_info.devfn = devfn; - map.msi_info.bus = bus; - map.msi_info.entry_nr = entry_nr; - map.msi_info.msi = msi_type; + map.bus = bus; + map.devfn = devfn; + map.entry_nr = entry_nr; + map.table_base = table_base; rc = do_physdev_op(xc_handle, PHYSDEVOP_map_pirq, &map); diff -r 644a9d219973 -r 0638a5c2cc9f tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Wed Aug 13 13:42:30 2008 +0100 +++ b/tools/libxc/xenctrl.h Wed Aug 13 13:45:39 2008 +0100 @@ -917,7 +917,7 @@ int xc_physdev_map_pirq_msi(int xc_handl int devfn, int bus, int entry_nr, - int msi_type); + uint64_t table_base); int xc_physdev_unmap_pirq(int xc_handle, int domid, diff -r 644a9d219973 -r 0638a5c2cc9f xen/arch/x86/msi.c --- a/xen/arch/x86/msi.c Wed Aug 13 13:42:30 2008 +0100 +++ b/xen/arch/x86/msi.c Wed Aug 13 13:45:39 2008 +0100 @@ -490,28 +490,6 @@ static int msi_capability_init(struct pc return 0; } -static u64 pci_resource_start(struct pci_dev *dev, u8 bar_index) -{ - u64 bar_base; - u32 reg_val; - u8 bus = dev->bus; - u8 slot = PCI_SLOT(dev->devfn); - u8 func = PCI_FUNC(dev->devfn); - - reg_val = pci_conf_read32(bus, slot, func, - PCI_BASE_ADDRESS_0 + 4 * bar_index); - bar_base = reg_val & PCI_BASE_ADDRESS_MEM_MASK; - if ( ( reg_val & PCI_BASE_ADDRESS_MEM_TYPE_MASK ) == - PCI_BASE_ADDRESS_MEM_TYPE_64 ) - { - reg_val = pci_conf_read32(bus, slot, func, - PCI_BASE_ADDRESS_0 + 4 * (bar_index + 1)); - bar_base |= ((u64)reg_val) << 32; - } - - return bar_base; -} - /** * msix_capability_init - configure device's MSI-X capability * @dev: pointer to the pci_dev data structure of MSI-X device function @@ -522,7 +500,7 @@ static u64 pci_resource_start(struct pci * single MSI-X irq. A return of zero indicates the successful setup of * requested MSI-X entries with allocated irqs or non-zero for otherwise. **/ -static int msix_capability_init(struct pci_dev *dev, int vector, int entry_nr) +static int msix_capability_init(struct pci_dev *dev, struct msi_info *msi) { struct msi_desc *entry; int pos; @@ -549,7 +527,7 @@ static int msix_capability_init(struct p table_offset = pci_conf_read32(bus, slot, func, msix_table_offset_reg(pos)); bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; - phys_addr = pci_resource_start(dev, bir) + table_offset; + phys_addr = msi->table_base + table_offset; idx = msix_fixmap_alloc(); if ( idx < 0 ) { @@ -561,11 +539,11 @@ static int msix_capability_init(struct p entry->msi_attrib.type = PCI_CAP_ID_MSIX; entry->msi_attrib.is_64 = 1; - entry->msi_attrib.entry_nr = entry_nr; + entry->msi_attrib.entry_nr = msi->entry_nr; entry->msi_attrib.maskbit = 1; entry->msi_attrib.masked = 1; entry->msi_attrib.pos = pos; - entry->vector = vector; + entry->vector = msi->vector; entry->dev = dev; entry->mask_base = base; @@ -589,24 +567,25 @@ static int msix_capability_init(struct p * indicates the successful setup of an entry zero with the new MSI * irq or non-zero for otherwise. **/ -static int __pci_enable_msi(u8 bus, u8 devfn, int vector) +static int __pci_enable_msi(struct msi_info *msi) { int status; struct pci_dev *pdev; - pdev = pci_lock_pdev(bus, devfn); + pdev = pci_lock_pdev(msi->bus, msi->devfn); if ( !pdev ) return -ENODEV; - if ( find_msi_entry(pdev, vector, PCI_CAP_ID_MSI) ) + if ( find_msi_entry(pdev, msi->vector, PCI_CAP_ID_MSI) ) { spin_unlock(&pdev->lock); - dprintk(XENLOG_WARNING, "vector %d has already mapped to MSI on device \ - %02x:%02x.%01x.\n", vector, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + dprintk(XENLOG_WARNING, "vector %d has already mapped to MSI on " + "device %02x:%02x.%01x.\n", msi->vector, msi->bus, + PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn)); return 0; } - status = msi_capability_init(pdev, vector); + status = msi_capability_init(pdev, msi->vector); spin_unlock(&pdev->lock); return status; } @@ -659,37 +638,37 @@ static void __pci_disable_msi(int vector * of irqs available. Driver should use the returned value to re-send * its request. **/ -static int __pci_enable_msix(u8 bus, u8 devfn, int vector, int entry_nr) +static int __pci_enable_msix(struct msi_info *msi) { int status, pos, nr_entries; struct pci_dev *pdev; u16 control; - u8 slot = PCI_SLOT(devfn); - u8 func = PCI_FUNC(devfn); - - pdev = pci_lock_pdev(bus, devfn); + u8 slot = PCI_SLOT(msi->devfn); + u8 func = PCI_FUNC(msi->devfn); + + pdev = pci_lock_pdev(msi->bus, msi->devfn); if ( !pdev ) return -ENODEV; - pos = pci_find_cap_offset(bus, slot, func, PCI_CAP_ID_MSIX); - control = pci_conf_read16(bus, slot, func, msi_control_reg(pos)); + pos = pci_find_cap_offset(msi->bus, slot, func, PCI_CAP_ID_MSIX); + control = pci_conf_read16(msi->bus, slot, func, msi_control_reg(pos)); nr_entries = multi_msix_capable(control); - if (entry_nr > nr_entries) + if (msi->entry_nr > nr_entries) { spin_unlock(&pdev->lock); return -EINVAL; } - if ( find_msi_entry(pdev, vector, PCI_CAP_ID_MSIX) ) + if ( find_msi_entry(pdev, msi->vector, PCI_CAP_ID_MSIX) ) { spin_unlock(&pdev->lock); - dprintk(XENLOG_WARNING, "vector %d has already mapped to MSIX on \ - device %02x:%02x.%01x.\n", vector, bus, - PCI_SLOT(devfn), PCI_FUNC(devfn)); + dprintk(XENLOG_WARNING, "vector %d has already mapped to MSIX on " + "device %02x:%02x.%01x.\n", msi->vector, msi->bus, + PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn)); return 0; } - status = msix_capability_init(pdev, vector, entry_nr); + status = msix_capability_init(pdev, msi); spin_unlock(&pdev->lock); return status; } @@ -727,13 +706,12 @@ static void __pci_disable_msix(int vecto spin_unlock(&dev->lock); } -int pci_enable_msi(u8 bus, u8 devfn, int vector, int entry_nr, int msi) -{ - ASSERT(spin_is_locked(&irq_desc[vector].lock)); - if ( msi ) - return __pci_enable_msi(bus, devfn, vector); - else - return __pci_enable_msix(bus, devfn, vector, entry_nr); +int pci_enable_msi(struct msi_info *msi) +{ + ASSERT(spin_is_locked(&irq_desc[msi->vector].lock)); + + return msi->table_base ? __pci_enable_msix(msi) : + __pci_enable_msi(msi); } void pci_disable_msi(int vector) diff -r 644a9d219973 -r 0638a5c2cc9f xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Wed Aug 13 13:42:30 2008 +0100 +++ b/xen/arch/x86/physdev.c Wed Aug 13 13:45:39 2008 +0100 @@ -66,6 +66,7 @@ static int map_domain_pirq(struct domain { int ret = 0; int old_vector, old_pirq; + struct msi_info msi; if ( d == NULL ) return -EINVAL; @@ -115,10 +116,14 @@ static int map_domain_pirq(struct domain vector); desc->handler = &pci_msi_type; - ret = pci_enable_msi(map->msi_info.bus, - map->msi_info.devfn, vector, - map->msi_info.entry_nr, - map->msi_info.msi); + msi.bus = map->bus; + msi.devfn = map->devfn; + msi.entry_nr = map->entry_nr; + msi.table_base = map->table_base; + msi.vector = vector; + + ret = pci_enable_msi(&msi); + spin_unlock_irqrestore(&desc->lock, flags); if ( ret ) goto done; @@ -139,7 +144,7 @@ static int unmap_domain_pirq(struct doma int ret = 0; int vector; - if ( d == NULL || pirq < 0 || pirq > NR_PIRQS ) + if ( d == NULL || pirq < 0 || pirq >= NR_PIRQS ) return -EINVAL; if ( !IS_PRIV(current->domain) ) diff -r 644a9d219973 -r 0638a5c2cc9f xen/drivers/passthrough/io.c --- a/xen/drivers/passthrough/io.c Wed Aug 13 13:42:30 2008 +0100 +++ b/xen/drivers/passthrough/io.c Wed Aug 13 13:45:39 2008 +0100 @@ -74,6 +74,9 @@ int pt_irq_create_bind_vtd( if ( pt_irq_bind->irq_type == PT_IRQ_TYPE_MSI ) { int pirq = pt_irq_bind->machine_irq; + + if ( pirq < 0 || pirq >= NR_IRQS ) + return -EINVAL; if ( !(hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_VALID ) ) { diff -r 644a9d219973 -r 0638a5c2cc9f xen/include/asm-x86/msi.h --- a/xen/include/asm-x86/msi.h Wed Aug 13 13:42:30 2008 +0100 +++ b/xen/include/asm-x86/msi.h Wed Aug 13 13:45:39 2008 +0100 @@ -53,6 +53,14 @@ #else #define MAX_MSIX_PAGES 32 #endif + +struct msi_info { + int bus; + int devfn; + int vector; + int entry_nr; + uint64_t table_base; +}; struct msi_msg { u32 address_lo; /* low 32 bits of msi message address */ @@ -64,7 +72,7 @@ extern void mask_msi_irq(unsigned int ir extern void mask_msi_irq(unsigned int irq); extern void unmask_msi_irq(unsigned int irq); extern void set_msi_irq_affinity(unsigned int irq, cpumask_t mask); -extern int pci_enable_msi(u8 bus, u8 devfn, int vector, int entry_nr, int msi); +extern int pci_enable_msi(struct msi_info *msi); extern void pci_disable_msi(int vector); extern void pci_cleanup_msi(struct pci_dev *pdev); diff -r 644a9d219973 -r 0638a5c2cc9f xen/include/public/physdev.h --- a/xen/include/public/physdev.h Wed Aug 13 13:42:30 2008 +0100 +++ b/xen/include/public/physdev.h Wed Aug 13 13:45:39 2008 +0100 @@ -136,10 +136,13 @@ struct physdev_map_pirq { /* IN or OUT */ int pirq; /* IN */ - struct { - int bus, devfn, entry_nr; - int msi; /* 0 - MSIX 1 - MSI */ - } msi_info; + int bus; + /* IN */ + int devfn; + /* IN */ + int entry_nr; + /* IN */ + uint64_t table_base; }; typedef struct physdev_map_pirq physdev_map_pirq_t; DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |