qemu-kvm: pci-assign: Mapping fixes
cover qemu-kvm: pci-assign: Mapping fixes
The promised cleanups.
Jan Kiszka (3):
qemu-kvm: pci-assign: Clean up free_assigned_device
qemu-kvm: pci-assign: Remove dead code from assigned_dev_iomem_map
qemu-kvm: pci-assign: Consolidate and fix slow mmio region mappings
hw/device-assignment.c | 139 ++++++++++++++++++----------------------------- 1 files changed, 53 insertions(+), 86 deletions(-)
PATCH 1/3 qemu-kvm: pci-assign: Clean up free_assigned_device
From: Jan Kiszka <[email protected]>
The dev argument is never NULL for all free_assigned_device use cases. So remove the check and one indention level.
--- hw/device-assignment.c | 70 +++++++++++++++++++++++------------------------ 1 files changed, 34 insertions(+), 36 deletions(-)
hw/device-assignment.c +34 -36
@@ -801,52 +801,50 @@ static void free_dev_irq_entries(AssignedDevice *dev)static void free_assigned_device (AssignedDevice *dev) { -if (dev) { -int i; - -for (i =0 ; i < dev->real_device.region_number; i++) { -PCIRegion *pci_region = &dev->real_device.regions[i]; -AssignedDevRegion *region = &dev->v_addrs[i]; +int i; -if (!pci_region->valid) -continue ; +for (i =0 ; i < dev->real_device.region_number; i++) { +PCIRegion *pci_region = &dev->real_device.regions[i]; +AssignedDevRegion *region = &dev->v_addrs[i]; -if (pci_region->type &IORESOURCE_IO ) { -if (pci_region->resource_fd <0 ) { -kvm_remove_ioperm_data (region->u.r_baseport, - region->r_size); +if (!pci_region->valid) { +continue ; + } +if (pci_region->type &IORESOURCE_IO ) { +if (pci_region->resource_fd <0 ) { +kvm_remove_ioperm_data (region->u.r_baseport, region->r_size); + } + }else if (pci_region->type &IORESOURCE_MEM ) { +if (region->u.r_virtbase) { +if (region->memory_index) { +cpu_register_physical_memory (region->e_physbase, + region->e_size, +IO_MEM_UNASSIGNED ); +qemu_ram_unmap (region->memory_index); } - }else if (pci_region->type &IORESOURCE_MEM ) { -if (region->u.r_virtbase) { -if (region->memory_index) { -cpu_register_physical_memory (region->e_physbase, - region->e_size, -IO_MEM_UNASSIGNED ); -qemu_ram_unmap (region->memory_index); - } -if (munmap (region->u.r_virtbase, - (pci_region->size +0xFFF ) &0xFFFFF000 )) -fprintf (stderr, -"Failed to unmap assigned device region: %s\n" , -strerror (errno)); +if (munmap (region->u.r_virtbase, + (pci_region->size +0xFFF ) &0xFFFFF000 )) { +fprintf (stderr, +"Failed to unmap assigned device region: %s\n" , +strerror (errno)); } } -if (pci_region->resource_fd >=0 ) { -close (pci_region->resource_fd); - } } - -if (dev->cap.available &ASSIGNED_DEVICE_CAP_MSIX ) -assigned_dev_unregister_msix_mmio (dev); - -if (dev->real_device.config_fd >=0 ) { -close (dev->real_device.config_fd); +if (pci_region->resource_fd >=0 ) { +close (pci_region->resource_fd); } + } + +if (dev->cap.available &ASSIGNED_DEVICE_CAP_MSIX ) { +assigned_dev_unregister_msix_mmio (dev); + } +if (dev->real_device.config_fd >=0 ) { +close (dev->real_device.config_fd); + }#ifdef KVM_CAP_IRQ_ROUTING -free_dev_irq_entries (dev); +free_dev_irq_entries (dev);#endif - } }static uint32_t calc_assigned_dev_id (uint16_t seg,uint8_t bus,uint8_t devfn)
Signature · 1 line
1.7.1
PATCH 2/3 qemu-kvm: pci-assign: Remove dead code from assigned_dev_iomem_map
In reply to Jan KiszkaFrom: Jan Kiszka <[email protected]>
ret is only set to 0 and then left untouched.
--- hw/device-assignment.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-)
hw/device-assignment.c +0 -6
@@ -273,7 +273,6 @@ static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num,AssignedDevice *r_dev =DO_UPCAST (AssignedDevice, dev, pci_dev);AssignedDevRegion *region = &r_dev->v_addrs[region_num];PCIRegion *real_region = &r_dev->real_device.regions[region_num]; -int ret =0 ;DEBUG ("e_phys=%08" FMT_PCIBUS " r_virt=%p type=%d len=%08" FMT_PCIBUS " region_num=%d \n" , e_phys, region->u.r_virtbase, type, e_size, region_num);
@@ -294,11 +293,6 @@ static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num, TARGET_PAGE_SIZE, r_dev->mmio_index); } } - -if (ret !=0 ) { -fprintf (stderr,"%s: Error: create new mapping failed\n" , __func__); -exit (1 ); - } } static void assigned_dev_ioport_map(PCIDevice *pci_dev, int region_num,
Signature · 1 line
1.7.1
PATCH 3/3 qemu-kvm: pci-assign: Consolidate and fix slow mmio region mappings
In reply to Jan KiszkaFrom: Jan Kiszka <[email protected]>
By registering the io-memory for slow regions already in assigned_dev_register_regions we can achieve several cleanups and fixes:
- use assigned_dev_iomem_map for both normal and slow mappings
- release slow io-region on clean up
- avoid unregistering zero-size regions (i.e. yet unmapped ones) which causes abort() these days
--- hw/device-assignment.c | 65 ++++++++++++++--------------------------------- 1 files changed, 20 insertions(+), 45 deletions(-)
hw/device-assignment.c +20 -45
@@ -242,31 +242,6 @@ static CPUReadMemoryFunc * const slow_bar_read[] = { &slow_bar_readl }; -static void assigned_dev_iomem_map_slow (PCIDevice *pci_dev,int region_num, -pcibus_t e_phys,pcibus_t e_size, -int type) -{ -AssignedDevice *r_dev =DO_UPCAST (AssignedDevice, dev, pci_dev); -AssignedDevRegion *region = &r_dev->v_addrs[region_num]; -PCIRegion *real_region = &r_dev->real_device.regions[region_num]; -int m; - -DEBUG ("%s" ,"slow map\n" ); - m =cpu_register_io_memory (slow_bar_read, slow_bar_write, region, -DEVICE_NATIVE_ENDIAN ); -cpu_register_physical_memory (e_phys, e_size, m); - -/* MSI-X MMIO page */ -if ((e_size >0 ) && - real_region->base_addr <= r_dev->msix_table_addr && - real_region->base_addr + real_region->size >= r_dev->msix_table_addr) { -int offset = r_dev->msix_table_addr - real_region->base_addr; - -cpu_register_physical_memory (e_phys + offset, -TARGET_PAGE_SIZE , r_dev->mmio_index); - } -} -static void assigned_dev_iomem_map (PCIDevice *pci_dev,int region_num,pcibus_t e_phys,pcibus_t e_size,int type) {
@@ -531,21 +506,10 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,/* handle memory io regions */ if (cur_region->type &IORESOURCE_MEM ) { -int slow_map =0 ;int t = cur_region->type &IORESOURCE_PREFETCH ?PCI_BASE_ADDRESS_MEM_PREFETCH :PCI_BASE_ADDRESS_SPACE_MEMORY ; -if (cur_region->size &0xFFF ) { -fprintf (stderr,"PCI region %d at address 0x%llx " -"has size 0x%x, which is not a multiple of 4K. " -"You might experience some performance hit " -"due to that.\n" , - i, (unsigned long long )cur_region->base_addr, - cur_region->size); - slow_map =1 ; - } -/* map physical memory */ pci_dev->v_addrs[i].e_physbase = cur_region->base_addr; pci_dev->v_addrs[i].u.r_virtbase = mmap(NULL, cur_region->size,
@@ -569,8 +533,18 @@ static int assigned_dev_register_regions(PCIRegion *io_regions, pci_dev->v_addrs[i].u.r_virtbase += (cur_region->base_addr &0xFFF ); - -if (!slow_map) { +if (cur_region->size &0xFFF ) { +fprintf (stderr,"PCI region %d at address 0x%llx " +"has size 0x%x, which is not a multiple of 4K. " +"You might experience some performance hit " +"due to that.\n" , + i, (unsigned long long )cur_region->base_addr, + cur_region->size); + pci_dev->v_addrs[i].memory_index = +cpu_register_io_memory (slow_bar_read, slow_bar_write, + &pci_dev->v_addrs[i], +DEVICE_NATIVE_ENDIAN ); + }else {void *virtbase = pci_dev->v_addrs[i].u.r_virtbase;char name[32 ]; snprintf(name, sizeof(name), "%s.bar%d",
@@ -580,13 +554,10 @@ static int assigned_dev_register_regions(PCIRegion *io_regions, &pci_dev->dev.qdev, name, cur_region->size, virtbase); - }else - pci_dev->v_addrs[i].memory_index =0 ; + } -pci_register_bar ((PCIDevice *) pci_dev, i, - cur_region->size, t, - slow_map ? assigned_dev_iomem_map_slow - : assigned_dev_iomem_map); +pci_register_bar ((PCIDevice *) pci_dev, i, cur_region->size, t, + assigned_dev_iomem_map);continue ; }else {/* handle port io regions */
@@ -810,10 +781,14 @@ static void free_assigned_device(AssignedDevice *dev) } }else if (pci_region->type &IORESOURCE_MEM ) {if (region->u.r_virtbase) { -if (region->memory_index) { +if (region->e_size >0 ) {cpu_register_physical_memory (region->e_physbase, region->e_size,IO_MEM_UNASSIGNED ); + } +if (region->r_size &0xFFF ) { +cpu_unregister_io_memory (region->memory_index); + }else {qemu_ram_unmap (region->memory_index); } if (munmap(region->u.r_virtbase,
Signature · 1 line
1.7.1
Quoted 4 lines · Jan Kiszka
The promised cleanups.
Quoted 8 lines
Jan Kiszka (3):
qemu-kvm: pci-assign: Clean upfree_assigned_device
qemu-kvm: pci-assign: Remove dead code fromassigned_dev_iomem_map
qemu-kvm: pci-assign: Consolidate and fix slow mmio region mappingshw/device-assignment.c | 139 ++++++++++++++++++----------------------------- 1 files changed, 53 insertions(+), 86 deletions(-)
Looks good to me.
Avi Kivity
AppliedQuoted 8 lines · Jan Kiszka
The promised cleanups.
Jan Kiszka (3):
qemu-kvm: pci-assign: Clean upfree_assigned_device
qemu-kvm: pci-assign: Remove dead code fromassigned_dev_iomem_map
qemu-kvm: pci-assign: Consolidate and fix slow mmio region mappings
Applied, thanks.
Signature · 1 line
error compiling committee.c: too many arguments to function