[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86-64/MMCFG: correct base address computation for regions not starting at bus 0
# HG changeset patch # User Jan Beulich <jbeulich@xxxxxxxxxx> # Date 1311608539 -3600 # Node ID b07b6fa766562c990b1d1e59af032feda15c2edb # Parent aa54b8175954bd6ffeb3bcf72e782e133896b388 x86-64/MMCFG: correct base address computation for regions not starting at bus 0 As per the specification, the base address reported by ACPI is the one that would be used if the region started at bus 0. Hence the start_bus_number offset needs to be added not only to the virtual address, but also the physical one when establishing the mapping, and it then needs to be subtracted when obtaining the virtual address for doing accesses. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- diff -r aa54b8175954 -r b07b6fa76656 xen/arch/x86/x86_64/mmconfig_64.c --- a/xen/arch/x86/x86_64/mmconfig_64.c Mon Jul 25 16:41:33 2011 +0100 +++ b/xen/arch/x86/x86_64/mmconfig_64.c Mon Jul 25 16:42:19 2011 +0100 @@ -25,7 +25,7 @@ static struct mmcfg_virt *pci_mmcfg_virt; static int __initdata mmcfg_pci_segment_shift; -static char __iomem *get_virt(unsigned int seg, unsigned bus) +static char __iomem *get_virt(unsigned int seg, unsigned int *bus) { struct acpi_mcfg_allocation *cfg; int cfg_num; @@ -33,9 +33,11 @@ for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) { cfg = pci_mmcfg_virt[cfg_num].cfg; if (cfg->pci_segment == seg && - (cfg->start_bus_number <= bus) && - (cfg->end_bus_number >= bus)) + (cfg->start_bus_number <= *bus) && + (cfg->end_bus_number >= *bus)) { + *bus -= cfg->start_bus_number; return pci_mmcfg_virt[cfg_num].virt; + } } /* Fall back to type 0 */ @@ -46,7 +48,7 @@ { char __iomem *addr; - addr = get_virt(seg, bus); + addr = get_virt(seg, &bus); if (!addr) return NULL; return addr + ((bus << 20) | (devfn << 12)); @@ -121,8 +123,11 @@ if (virt + size < virt || virt + size > PCI_MCFG_VIRT_END) return NULL; - map_pages_to_xen(virt, cfg->address >> PAGE_SHIFT, - size >> PAGE_SHIFT, PAGE_HYPERVISOR_NOCACHE); + if (map_pages_to_xen(virt, + (cfg->address >> PAGE_SHIFT) + + (cfg->start_bus_number << (20 - PAGE_SHIFT)), + size >> PAGE_SHIFT, PAGE_HYPERVISOR_NOCACHE)) + return NULL; return (void __iomem *) virt; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |