[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] VT-d: improve RMRR validity checking
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1264065121 0 # Node ID 961acb357740507248fb5f6e502625c39e923177 # Parent acd7d3f06d9aea147dcd7ea3830574cb64bce41b VT-d: improve RMRR validity checking Currently, Xen checks RMRR range and disables VT-d if RMRR range is set incorrectly in BIOS rigorously. But, actually we can ignore the RMRR if the device under its scope are not pci discoverable, because the RMRR won't be used by non-existed or disabled devices. This patch ignores the RMRR if the device under its scope are not pci discoverable, and only checks the validity of RMRRs that are actually used. In order to avoid duplicate pci device detection code, this patch defines a function pci_device_detect for it. Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx> --- xen/drivers/passthrough/pci.c | 21 ++++++++++--- xen/drivers/passthrough/vtd/dmar.c | 56 +++++++++++++++++++++++++++++-------- xen/include/xen/pci.h | 1 3 files changed, 61 insertions(+), 17 deletions(-) diff -r acd7d3f06d9a -r 961acb357740 xen/drivers/passthrough/pci.c --- a/xen/drivers/passthrough/pci.c Thu Jan 21 09:11:06 2010 +0000 +++ b/xen/drivers/passthrough/pci.c Thu Jan 21 09:12:01 2010 +0000 @@ -362,6 +362,21 @@ out: } /* + * detect pci device, return 0 if it exists, or return 0 + */ +int pci_device_detect(u8 bus, u8 dev, u8 func) +{ + u32 vendor; + + vendor = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID); + /* some broken boards return 0 or ~0 if a slot is empty: */ + if ( (vendor == 0xffffffff) || (vendor == 0x00000000) || + (vendor == 0x0000ffff) || (vendor == 0xffff0000) ) + return 0; + return 1; +} + +/* * scan pci devices to add all existed PCI devices to alldevs_list, * and setup pci hierarchy in array bus2bridge. This function is only * called in VT-d hardware setup @@ -372,7 +387,6 @@ int __init scan_pci_devices(void) int bus, dev, func; u8 sec_bus, sub_bus; int type; - u32 l; spin_lock(&pcidevs_lock); for ( bus = 0; bus < 256; bus++ ) @@ -381,10 +395,7 @@ int __init scan_pci_devices(void) { for ( func = 0; func < 8; func++ ) { - l = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID); - /* some broken boards return 0 or ~0 if a slot is empty: */ - if ( (l == 0xffffffff) || (l == 0x00000000) || - (l == 0x0000ffff) || (l == 0xffff0000) ) + if ( pci_device_detect(bus, dev, func) == 0 ) continue; pdev = alloc_pdev(bus, PCI_DEVFN(dev, func)); diff -r acd7d3f06d9a -r 961acb357740 xen/drivers/passthrough/vtd/dmar.c --- a/xen/drivers/passthrough/vtd/dmar.c Thu Jan 21 09:11:06 2010 +0000 +++ b/xen/drivers/passthrough/vtd/dmar.c Thu Jan 21 09:12:01 2010 +0000 @@ -410,14 +410,6 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent u64 base_addr = rmrr->base_address, end_addr = rmrr->end_address; int ret = 0; - if ( base_addr >= end_addr ) - { - dprintk(XENLOG_ERR VTDPREFIX, - "RMRR error: base_addr %"PRIx64" end_address %"PRIx64"\n", - base_addr, end_addr); - return -EFAULT; - } - #ifdef CONFIG_X86 /* This check is here simply to detect when RMRR values are * not properly represented in the system memory map and @@ -441,9 +433,6 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent rmrru->base_address = base_addr; rmrru->end_address = end_addr; - dprintk(XENLOG_INFO VTDPREFIX, - " RMRR region: base_addr %"PRIx64" end_address %"PRIx64"\n", - rmrru->base_address, rmrru->end_address); dev_scope_start = (void *)(rmrr + 1); dev_scope_end = ((void *)rmrr) + header->length; @@ -453,7 +442,50 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent if ( ret || (rmrru->scope.devices_cnt == 0) ) xfree(rmrru); else - acpi_register_rmrr_unit(rmrru); + { + u8 b, d, f; + int i, ignore = 0; + + for ( i = 0; i < rmrru->scope.devices_cnt; i++ ) + { + b = PCI_BUS(rmrru->scope.devices[i]); + d = PCI_SLOT(rmrru->scope.devices[i]); + f = PCI_FUNC(rmrru->scope.devices[i]); + + if ( pci_device_detect(b, d, f) == 0 ) + ignore = 1; + else + { + ignore = 0; + break; + } + } + + if ( ignore ) + { + dprintk(XENLOG_WARNING VTDPREFIX, + " Ignore the RMRR (%"PRIx64", %"PRIx64") due to " + "devices under its scope are not PCI discoverable!\n", + rmrru->base_address, rmrru->end_address); + xfree(rmrru); + } + else if ( base_addr > end_addr ) + { + dprintk(XENLOG_WARNING VTDPREFIX, + " The RMRR (%"PRIx64", %"PRIx64") is incorrect!\n", + rmrru->base_address, rmrru->end_address); + xfree(rmrru); + ret = -EFAULT; + } + else + { + dprintk(XENLOG_INFO VTDPREFIX, + " RMRR region: base_addr %"PRIx64" end_address %"PRIx64"\n", + rmrru->base_address, rmrru->end_address); + acpi_register_rmrr_unit(rmrru); + } + } + return ret; } diff -r acd7d3f06d9a -r 961acb357740 xen/include/xen/pci.h --- a/xen/include/xen/pci.h Thu Jan 21 09:11:06 2010 +0000 +++ b/xen/include/xen/pci.h Thu Jan 21 09:12:01 2010 +0000 @@ -74,6 +74,7 @@ enum { DEV_TYPE_PCI, }; +int pci_device_detect(u8 bus, u8 dev, u8 func); int scan_pci_devices(void); int pdev_type(u8 bus, u8 devfn); int find_upstream_bridge(u8 *bus, u8 *devfn, u8 *secbus); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |