* [PATCH 0/6] pci-assign: Multiple fixes and cleanups
@ 2011-11-16 20:45 Alex Williamson
2011-11-16 20:45 ` [PATCH 1/6] pci-assign: Fix device removal Alex Williamson
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Alex Williamson @ 2011-11-16 20:45 UTC (permalink / raw)
To: kvm; +Cc: jan.kiszka, alex.williamson, yongjie.ren
These patches are all independent. Patch 1 & 2 fix serious
usability bugs. Patches 3-6 are more subtle things that
Markus was able to find with Coverity.
Patch 1 fixes https://bugs.launchpad.net/qemu/+bug/875723
I also tested https://bugs.launchpad.net/qemu/+bug/877155
but I'm unable to reproduce. An 82576 VF works just fine
in a Windows 2008 guest with this patch series. Thanks,
Alex
---
Alex Williamson (6):
pci-assign: Harden I/O port test
pci-assign: Remove bogus PCIe lnkcap wmask setting
pci-assign: Fix PCIe lnkcap
pci-assign: Fix PCI_EXP_FLAGS_TYPE shift
pci-assign: Fix I/O port
pci-assign: Fix device removal
hw/device-assignment.c | 137 ++++++++++++++++++++----------------------------
1 files changed, 57 insertions(+), 80 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 1/6] pci-assign: Fix device removal 2011-11-16 20:45 [PATCH 0/6] pci-assign: Multiple fixes and cleanups Alex Williamson @ 2011-11-16 20:45 ` Alex Williamson 2011-11-16 20:45 ` [PATCH 2/6] pci-assign: Fix I/O port Alex Williamson ` (5 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Alex Williamson @ 2011-11-16 20:45 UTC (permalink / raw) To: kvm; +Cc: jan.kiszka, alex.williamson, yongjie.ren We're destroying the memory container before we remove the subregions it holds. This fixes: https://bugs.launchpad.net/qemu/+bug/875723 Signed-off-by: Alex Williamson <alex.williamson@redhat.com> --- hw/device-assignment.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 11efd16..cde0681 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -677,10 +677,23 @@ static void free_assigned_device(AssignedDevice *dev) kvm_remove_ioport_region(region->u.r_baseport, region->r_size, dev->dev.qdev.hotplugged); } + memory_region_del_subregion(®ion->container, + ®ion->real_iomem); + memory_region_destroy(®ion->real_iomem); + memory_region_destroy(®ion->container); } else if (pci_region->type & IORESOURCE_MEM) { if (region->u.r_virtbase) { memory_region_del_subregion(®ion->container, ®ion->real_iomem); + + /* Remove MSI-X table subregion */ + if (pci_region->base_addr <= dev->msix_table_addr && + pci_region->base_addr + pci_region->size > + dev->msix_table_addr) { + memory_region_del_subregion(®ion->container, + &dev->mmio); + } + memory_region_destroy(®ion->real_iomem); memory_region_destroy(®ion->container); if (munmap(region->u.r_virtbase, ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/6] pci-assign: Fix I/O port 2011-11-16 20:45 [PATCH 0/6] pci-assign: Multiple fixes and cleanups Alex Williamson 2011-11-16 20:45 ` [PATCH 1/6] pci-assign: Fix device removal Alex Williamson @ 2011-11-16 20:45 ` Alex Williamson 2011-11-16 20:45 ` [PATCH 3/6] pci-assign: Fix PCI_EXP_FLAGS_TYPE shift Alex Williamson ` (4 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Alex Williamson @ 2011-11-16 20:45 UTC (permalink / raw) To: kvm; +Cc: jan.kiszka, alex.williamson, yongjie.ren The old_portio structure seems broken. Throw it away and switch to the new style. This was hitting an assert when trying to make use of I/O port regions. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> --- hw/device-assignment.c | 103 ++++++++++++++++-------------------------------- 1 files changed, 35 insertions(+), 68 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index cde0681..571a097 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -65,100 +65,76 @@ static void assigned_dev_load_option_rom(AssignedDevice *dev); static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev); -static uint32_t assigned_dev_ioport_rw(AssignedDevRegion *dev_region, - uint32_t addr, int len, uint32_t *val) +static uint64_t assigned_dev_ioport_rw(AssignedDevRegion *dev_region, + target_phys_addr_t addr, int size, + uint64_t *data) { - uint32_t ret = 0; - uint32_t offset = addr; + uint64_t val = 0; int fd = dev_region->region->resource_fd; if (fd >= 0) { - if (val) { - DEBUG("pwrite val=%x, len=%d, e_phys=%x, offset=%x\n", - *val, len, addr, offset); - if (pwrite(fd, val, len, offset) != len) { + if (data) { + DEBUG("pwrite data=%x, size=%d, e_phys=%x, addr=%x\n", + *data, size, addr, addr); + if (pwrite(fd, data, size, addr) != size) { fprintf(stderr, "%s - pwrite failed %s\n", __func__, strerror(errno)); } } else { - if (pread(fd, &ret, len, offset) != len) { + if (pread(fd, &val, size, addr) != size) { fprintf(stderr, "%s - pread failed %s\n", __func__, strerror(errno)); - ret = (1UL << (len * 8)) - 1; + val = (1UL << (size * 8)) - 1; } - DEBUG("pread ret=%x, len=%d, e_phys=%x, offset=%x\n", - ret, len, addr, offset); + DEBUG("pread val=%x, size=%d, e_phys=%x, addr=%x\n", + val, size, addr, addr); } } else { - uint32_t port = offset + dev_region->u.r_baseport; + uint32_t port = addr + dev_region->u.r_baseport; - if (val) { - DEBUG("out val=%x, len=%d, e_phys=%x, host=%x\n", - *val, len, addr, port); - switch (len) { + if (data) { + DEBUG("out data=%x, size=%d, e_phys=%x, host=%x\n", + *data, size, addr, port); + switch (size) { case 1: - outb(*val, port); + outb(*data, port); break; case 2: - outw(*val, port); + outw(*data, port); break; case 4: - outl(*val, port); + outl(*data, port); break; } } else { - switch (len) { + switch (size) { case 1: - ret = inb(port); + val = inb(port); break; case 2: - ret = inw(port); + val = inw(port); break; case 4: - ret = inl(port); + val = inl(port); break; } - DEBUG("in val=%x, len=%d, e_phys=%x, host=%x\n", - ret, len, addr, port); + DEBUG("in data=%x, size=%d, e_phys=%x, host=%x\n", + val, size, addr, port); } } - return ret; -} - -static void assigned_dev_ioport_writeb(void *opaque, uint32_t addr, - uint32_t value) -{ - assigned_dev_ioport_rw(opaque, addr, 1, &value); - return; -} - -static void assigned_dev_ioport_writew(void *opaque, uint32_t addr, - uint32_t value) -{ - assigned_dev_ioport_rw(opaque, addr, 2, &value); - return; -} - -static void assigned_dev_ioport_writel(void *opaque, uint32_t addr, - uint32_t value) -{ - assigned_dev_ioport_rw(opaque, addr, 4, &value); - return; -} - -static uint32_t assigned_dev_ioport_readb(void *opaque, uint32_t addr) -{ - return assigned_dev_ioport_rw(opaque, addr, 1, NULL); + return val; } -static uint32_t assigned_dev_ioport_readw(void *opaque, uint32_t addr) +static void assigned_dev_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { - return assigned_dev_ioport_rw(opaque, addr, 2, NULL); + assigned_dev_ioport_rw(opaque, addr, size, &data); } -static uint32_t assigned_dev_ioport_readl(void *opaque, uint32_t addr) +static uint64_t assigned_dev_ioport_read(void *opaque, + target_phys_addr_t addr, unsigned size) { - return assigned_dev_ioport_rw(opaque, addr, 4, NULL); + return assigned_dev_ioport_rw(opaque, addr, size, NULL); } static uint32_t slow_bar_readb(void *opaque, target_phys_addr_t addr) @@ -258,18 +234,9 @@ static void assigned_dev_iomem_setup(PCIDevice *pci_dev, int region_num, } } -static const MemoryRegionPortio assigned_dev_old_portio[] = { - { 0x10000, 1, .read = assigned_dev_ioport_readb, }, - { 0x10000, 2, .read = assigned_dev_ioport_readw, }, - { 0x10000, 4, .read = assigned_dev_ioport_readl, }, - { 0x10000, 1, .write = assigned_dev_ioport_writeb, }, - { 0x10000, 2, .write = assigned_dev_ioport_writew, }, - { 0x10000, 4, .write = assigned_dev_ioport_writel, }, - PORTIO_END_OF_LIST() -}; - static const MemoryRegionOps assigned_dev_ioport_ops = { - .old_portio = assigned_dev_old_portio, + .read = assigned_dev_ioport_read, + .write = assigned_dev_ioport_write, .endianness = DEVICE_NATIVE_ENDIAN, }; ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/6] pci-assign: Fix PCI_EXP_FLAGS_TYPE shift 2011-11-16 20:45 [PATCH 0/6] pci-assign: Multiple fixes and cleanups Alex Williamson 2011-11-16 20:45 ` [PATCH 1/6] pci-assign: Fix device removal Alex Williamson 2011-11-16 20:45 ` [PATCH 2/6] pci-assign: Fix I/O port Alex Williamson @ 2011-11-16 20:45 ` Alex Williamson 2011-11-16 20:46 ` [PATCH 4/6] pci-assign: Fix PCIe lnkcap Alex Williamson ` (3 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Alex Williamson @ 2011-11-16 20:45 UTC (permalink / raw) To: kvm; +Cc: jan.kiszka, alex.williamson, yongjie.ren Coverity found that we're doing (uint16_t)type & 0xf0 >> 8. This is obviously always 0x0, so our attempt to filter out some device types thinks everything is an endpoint. Fix shift amount. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> --- hw/device-assignment.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 571a097..ec302d2 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1294,7 +1294,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) assigned_dev_setup_cap_read(dev, pos, size); type = pci_get_word(pci_dev->config + pos + PCI_EXP_FLAGS); - type = (type & PCI_EXP_FLAGS_TYPE) >> 8; + type = (type & PCI_EXP_FLAGS_TYPE) >> 4; if (type != PCI_EXP_TYPE_ENDPOINT && type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) { fprintf(stderr, ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/6] pci-assign: Fix PCIe lnkcap 2011-11-16 20:45 [PATCH 0/6] pci-assign: Multiple fixes and cleanups Alex Williamson ` (2 preceding siblings ...) 2011-11-16 20:45 ` [PATCH 3/6] pci-assign: Fix PCI_EXP_FLAGS_TYPE shift Alex Williamson @ 2011-11-16 20:46 ` Alex Williamson 2011-11-16 20:46 ` [PATCH 5/6] pci-assign: Remove bogus PCIe lnkcap wmask setting Alex Williamson ` (2 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Alex Williamson @ 2011-11-16 20:46 UTC (permalink / raw) To: kvm; +Cc: jan.kiszka, alex.williamson, yongjie.ren Another Coverity found issue, lnkcap is a 32bit register and we're masking bits 16 & 17. Fix to uin32_t. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> --- hw/device-assignment.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index ec302d2..dd92ce0 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1240,8 +1240,8 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) if ((pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_EXP, 0))) { uint8_t version, size = 0; - uint16_t type, devctl, lnkcap, lnksta; - uint32_t devcap; + uint16_t type, devctl, lnksta; + uint32_t devcap, lnkcap; version = pci_get_byte(pci_dev->config + pos + PCI_EXP_FLAGS); version &= PCI_EXP_FLAGS_VERS; @@ -1326,11 +1326,11 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) pci_set_word(pci_dev->config + pos + PCI_EXP_DEVSTA, 0); /* Link capabilities, expose links and latencues, clear reporting */ - lnkcap = pci_get_word(pci_dev->config + pos + PCI_EXP_LNKCAP); + lnkcap = pci_get_long(pci_dev->config + pos + PCI_EXP_LNKCAP); lnkcap &= (PCI_EXP_LNKCAP_SLS | PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_ASPMS | PCI_EXP_LNKCAP_L0SEL | PCI_EXP_LNKCAP_L1EL); - pci_set_word(pci_dev->config + pos + PCI_EXP_LNKCAP, lnkcap); + pci_set_long(pci_dev->config + pos + PCI_EXP_LNKCAP, lnkcap); pci_set_word(pci_dev->wmask + pos + PCI_EXP_LNKCAP, PCI_EXP_LNKCTL_ASPMC | PCI_EXP_LNKCTL_RCB | PCI_EXP_LNKCTL_CCC | PCI_EXP_LNKCTL_ES | ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/6] pci-assign: Remove bogus PCIe lnkcap wmask setting 2011-11-16 20:45 [PATCH 0/6] pci-assign: Multiple fixes and cleanups Alex Williamson ` (3 preceding siblings ...) 2011-11-16 20:46 ` [PATCH 4/6] pci-assign: Fix PCIe lnkcap Alex Williamson @ 2011-11-16 20:46 ` Alex Williamson 2011-11-16 20:46 ` [PATCH 6/6] pci-assign: Harden I/O port test Alex Williamson 2011-11-17 9:26 ` [PATCH 0/6] pci-assign: Multiple fixes and cleanups Avi Kivity 6 siblings, 0 replies; 8+ messages in thread From: Alex Williamson @ 2011-11-16 20:46 UTC (permalink / raw) To: kvm; +Cc: jan.kiszka, alex.williamson, yongjie.ren All the fields of lnkcap are read-only and this is setting it with mask values from LNKCTL. Just below it, we indicate link control is read only, so this appears to be a stray chunk left in from development. Trivial comment fix while we're here. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> --- hw/device-assignment.c | 6 +----- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index dd92ce0..0160de7 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1312,7 +1312,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) pci_set_long(pci_dev->config + pos + PCI_EXP_DEVCAP, devcap); /* device control: clear all error reporting enable bits, leaving - * leaving only a few host values. Note, these are + * only a few host values. Note, these are * all writable, but not passed to hw. */ devctl = pci_get_word(pci_dev->config + pos + PCI_EXP_DEVCTL); @@ -1331,10 +1331,6 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) PCI_EXP_LNKCAP_ASPMS | PCI_EXP_LNKCAP_L0SEL | PCI_EXP_LNKCAP_L1EL); pci_set_long(pci_dev->config + pos + PCI_EXP_LNKCAP, lnkcap); - pci_set_word(pci_dev->wmask + pos + PCI_EXP_LNKCAP, - PCI_EXP_LNKCTL_ASPMC | PCI_EXP_LNKCTL_RCB | - PCI_EXP_LNKCTL_CCC | PCI_EXP_LNKCTL_ES | - PCI_EXP_LNKCTL_CLKREQ_EN | PCI_EXP_LNKCTL_HAWD); /* Link control, pass existing read-only copy. Should be writable? */ ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/6] pci-assign: Harden I/O port test 2011-11-16 20:45 [PATCH 0/6] pci-assign: Multiple fixes and cleanups Alex Williamson ` (4 preceding siblings ...) 2011-11-16 20:46 ` [PATCH 5/6] pci-assign: Remove bogus PCIe lnkcap wmask setting Alex Williamson @ 2011-11-16 20:46 ` Alex Williamson 2011-11-17 9:26 ` [PATCH 0/6] pci-assign: Multiple fixes and cleanups Avi Kivity 6 siblings, 0 replies; 8+ messages in thread From: Alex Williamson @ 2011-11-16 20:46 UTC (permalink / raw) To: kvm; +Cc: jan.kiszka, alex.williamson, yongjie.ren Markus Armbruster points out that we're missing a < 0 check from pread while trying to probe for pci-sysfs io-port resource support. We don't expect a short read, but we should harden the test to abort if we get one so we're not potentially looking at a stale errno. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> --- hw/device-assignment.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 0160de7..7e6f972 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -434,8 +434,9 @@ static int assigned_dev_register_regions(PCIRegion *io_regions, * kernels return EIO. New kernels only allow 1/2/4 byte reads * so should return EINVAL for a 3 byte read */ ret = pread(pci_dev->v_addrs[i].region->resource_fd, &val, 3, 0); - if (ret == 3) { - fprintf(stderr, "I/O port resource supports 3 byte read?!\n"); + if (ret >= 0) { + fprintf(stderr, "Unexpected return from I/O port read: %d\n", + ret); abort(); } else if (errno != EINVAL) { fprintf(stderr, "Using raw in/out ioport access (sysfs - %s)\n", ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 0/6] pci-assign: Multiple fixes and cleanups 2011-11-16 20:45 [PATCH 0/6] pci-assign: Multiple fixes and cleanups Alex Williamson ` (5 preceding siblings ...) 2011-11-16 20:46 ` [PATCH 6/6] pci-assign: Harden I/O port test Alex Williamson @ 2011-11-17 9:26 ` Avi Kivity 6 siblings, 0 replies; 8+ messages in thread From: Avi Kivity @ 2011-11-17 9:26 UTC (permalink / raw) To: Alex Williamson; +Cc: kvm, jan.kiszka, yongjie.ren On 11/16/2011 10:45 PM, Alex Williamson wrote: > These patches are all independent. Patch 1 & 2 fix serious > usability bugs. Patches 3-6 are more subtle things that > Markus was able to find with Coverity. > > Patch 1 fixes https://bugs.launchpad.net/qemu/+bug/875723 > > I also tested https://bugs.launchpad.net/qemu/+bug/877155 > but I'm unable to reproduce. An 82576 VF works just fine > in a Windows 2008 guest with this patch series. Thanks, > Applied, thanks. -- error compiling committee.c: too many arguments to function ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2011-11-17 9:27 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-11-16 20:45 [PATCH 0/6] pci-assign: Multiple fixes and cleanups Alex Williamson 2011-11-16 20:45 ` [PATCH 1/6] pci-assign: Fix device removal Alex Williamson 2011-11-16 20:45 ` [PATCH 2/6] pci-assign: Fix I/O port Alex Williamson 2011-11-16 20:45 ` [PATCH 3/6] pci-assign: Fix PCI_EXP_FLAGS_TYPE shift Alex Williamson 2011-11-16 20:46 ` [PATCH 4/6] pci-assign: Fix PCIe lnkcap Alex Williamson 2011-11-16 20:46 ` [PATCH 5/6] pci-assign: Remove bogus PCIe lnkcap wmask setting Alex Williamson 2011-11-16 20:46 ` [PATCH 6/6] pci-assign: Harden I/O port test Alex Williamson 2011-11-17 9:26 ` [PATCH 0/6] pci-assign: Multiple fixes and cleanups Avi Kivity
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.