[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] Qemu MSI Cleaning Up
On Thu, 22 Sep 2011, Haitao Shan wrote: > Hi, Ian, Keir, Jan, > > This patch does cleaning up of QEMU MSI handling. The fixes are: > 1. Changes made to MSI-X table mapping handling to eliminate the small > windows in which guest could have access to physical MSI-X table. > 2. MSI-X table is mapped as read-only to QEMU, as masking of MSI-X is > already in Xen now. > 3. For registers that coexists inside the MSI-X table (this could be > only PBA I think), value read from physical page would be returned. > > Could you please have review? > > Signed-off-by: Shan Haitao <haitao.shan@xxxxxxxxx> > > > diff --git a/hw/pass-through.c b/hw/pass-through.c > index 9c5620d..6ebed64 100644 > --- a/hw/pass-through.c > +++ b/hw/pass-through.c > @@ -92,6 +92,7 @@ > > #include <unistd.h> > #include <sys/ioctl.h> > +#include <assert.h> > > extern int gfx_passthru; > int igd_passthru = 0; > @@ -1103,6 +1104,7 @@ static void pt_iomem_map(PCIDevice *d, int i, > uint32_t e_phys, uint32_t e_size, > { > struct pt_dev *assigned_device = (struct pt_dev *)d; > uint32_t old_ebase = assigned_device->bases[i].e_physbase; > + uint32_t msix_last_pfn = 0, bar_last_pfn = 0; > int first_map = ( assigned_device->bases[i].e_size == 0 ); > int ret = 0; > > @@ -1118,39 +1120,127 @@ static void pt_iomem_map(PCIDevice *d, int i, > uint32_t e_phys, uint32_t e_size, > > if ( !first_map && old_ebase != -1 ) > { > - add_msix_mapping(assigned_device, i); > - /* Remove old mapping */ > - ret = xc_domain_memory_mapping(xc_handle, domid, > + if ( has_msix_mapping(assigned_device, i) ) > + { > + msix_last_pfn = (assigned_device->msix->mmio_base_addr - 1 + > + assigned_device->msix->total_entries * 16) >> > XC_PAGE_SHIFT; > + bar_last_pfn = (old_ebase + e_size - 1) >> XC_PAGE_SHIFT; > + > + unregister_iomem(assigned_device->msix->mmio_base_addr); > + > + if ( assigned_device->msix->table_off ) > + { > + ret = xc_domain_memory_mapping(xc_handle, domid, > + old_ebase >> XC_PAGE_SHIFT, > + assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT, > + (assigned_device->msix->mmio_base_addr >> XC_PAGE_SHIFT) > + - (old_ebase >> XC_PAGE_SHIFT), > + DPCI_REMOVE_MAPPING); > + if ( ret != 0 ) > + { > + PT_LOG("Error: remove old mapping failed!\n"); > + return; > + } > + } > + if ( msix_last_pfn != bar_last_pfn ) > + { > + assert(msix_last_pfn < bar_last_pfn); > + ret = xc_domain_memory_mapping(xc_handle, domid, > + msix_last_pfn + 1, > + (assigned_device->bases[i].access.maddr + > + assigned_device->msix->table_off + > + assigned_device->msix->total_entries * 16 + > + XC_PAGE_SIZE -1) >> XC_PAGE_SHIFT, > + bar_last_pfn - msix_last_pfn, > + DPCI_REMOVE_MAPPING); > + if ( ret != 0 ) > + { > + PT_LOG("Error: remove old mapping failed!\n"); > + return; > + } > + } > + } > + else > + { > + /* Remove old mapping */ > + ret = xc_domain_memory_mapping(xc_handle, domid, > old_ebase >> XC_PAGE_SHIFT, > assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT, > (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT, > DPCI_REMOVE_MAPPING); > - if ( ret != 0 ) > - { > - PT_LOG("Error: remove old mapping failed!\n"); > - return; > + if ( ret != 0 ) > + { > + PT_LOG("Error: remove old mapping failed!\n"); > + return; > + } > } > } > > /* map only valid guest address */ > if (e_phys != -1) > { > - /* Create new mapping */ > - ret = xc_domain_memory_mapping(xc_handle, domid, > + if ( has_msix_mapping(assigned_device, i) ) > + { > + assigned_device->msix->mmio_base_addr = > + assigned_device->bases[i].e_physbase > + + assigned_device->msix->table_off; > + > + msix_last_pfn = (assigned_device->msix->mmio_base_addr - 1 + > + assigned_device->msix->total_entries * 16) >> > XC_PAGE_SHIFT; > + bar_last_pfn = (e_phys + e_size - 1) >> XC_PAGE_SHIFT; > + > + > cpu_register_physical_memory(assigned_device->msix->mmio_base_addr, > + (assigned_device->msix->total_entries * 16 + XC_PAGE_SIZE - > 1) > + & XC_PAGE_MASK, > + assigned_device->msix->mmio_index); > > + if ( assigned_device->msix->table_off ) > + { > + ret = xc_domain_memory_mapping(xc_handle, domid, > + assigned_device->bases[i].e_physbase >> XC_PAGE_SHIFT, > + assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT, > + (assigned_device->msix->mmio_base_addr >> XC_PAGE_SHIFT) > + - (assigned_device->bases[i].e_physbase >> > XC_PAGE_SHIFT), > + DPCI_ADD_MAPPING); > + if ( ret != 0 ) > + { > + PT_LOG("Error: remove old mapping failed!\n"); > + return; the log message is wrong here: we are trying to create new mappings > + } > + } > + if ( msix_last_pfn != bar_last_pfn ) > + { > + assert(msix_last_pfn < bar_last_pfn); > + ret = xc_domain_memory_mapping(xc_handle, domid, > + msix_last_pfn + 1, > + (assigned_device->bases[i].access.maddr + > + assigned_device->msix->table_off + > + assigned_device->msix->total_entries * 16 + > + XC_PAGE_SIZE -1) >> XC_PAGE_SHIFT, > + bar_last_pfn - msix_last_pfn, > + DPCI_ADD_MAPPING); > + if ( ret != 0 ) > + { > + PT_LOG("Error: remove old mapping failed!\n"); > + return; same here > + } > + } > + } > + else > + { > + /* Create new mapping */ > + ret = xc_domain_memory_mapping(xc_handle, domid, > assigned_device->bases[i].e_physbase >> XC_PAGE_SHIFT, > assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT, > (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT, > DPCI_ADD_MAPPING); > > - if ( ret != 0 ) > - { > - PT_LOG("Error: create new mapping failed!\n"); > + if ( ret != 0 ) > + { > + PT_LOG("Error: create new mapping failed!\n"); > + } > } > > - ret = remove_msix_mapping(assigned_device, i); > - if ( ret != 0 ) > - PT_LOG("Error: remove MSI-X mmio mapping failed!\n"); > - > if ( old_ebase != e_phys && old_ebase != -1 ) > pt_msix_update_remap(assigned_device, i); > } The two mapping and unmapping big chuncks of code looks very similar apart from the DPCI_ADD_MAPPING/DPCI_REMOVE_MAPPING parameter. Could they be refactored into a single function called "change_msix_mappings"? This is more or less what I have in mind: change_msix_mappings(assigned_device, DPCI_REMOVE_MAPPING); update mmio_base_addr change_msix_mappings(assigned_device, DPCI_ADD_MAPPING); The rest looks OK to me. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |