diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | arch/x86/mm/init_32.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 3 | ||||
-rw-r--r-- | drivers/pci/pci.c | 107 | ||||
-rw-r--r-- | include/linux/ioport.h | 11 | ||||
-rw-r--r-- | include/linux/pci.h | 3 | ||||
-rw-r--r-- | kernel/resource.c | 61 |
9 files changed, 176 insertions, 19 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 0b3f6711d2f1..0072fabb1dd1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -918,6 +918,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
918 | 918 | ||
919 | inttest= [IA64] | 919 | inttest= [IA64] |
920 | 920 | ||
921 | iomem= Disable strict checking of access to MMIO memory | ||
922 | strict regions from userspace. | ||
923 | relaxed | ||
924 | |||
921 | iommu= [x86] | 925 | iommu= [x86] |
922 | off | 926 | off |
923 | force | 927 | force |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 544d724caeee..88f1b10de3be 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -328,6 +328,8 @@ int devmem_is_allowed(unsigned long pagenr) | |||
328 | { | 328 | { |
329 | if (pagenr <= 256) | 329 | if (pagenr <= 256) |
330 | return 1; | 330 | return 1; |
331 | if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) | ||
332 | return 0; | ||
331 | if (!page_is_ram(pagenr)) | 333 | if (!page_is_ram(pagenr)) |
332 | return 1; | 334 | return 1; |
333 | return 0; | 335 | return 0; |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 54c437e96541..23f68e77ad1f 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -888,6 +888,8 @@ int devmem_is_allowed(unsigned long pagenr) | |||
888 | { | 888 | { |
889 | if (pagenr <= 256) | 889 | if (pagenr <= 256) |
890 | return 1; | 890 | return 1; |
891 | if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) | ||
892 | return 0; | ||
891 | if (!page_is_ram(pagenr)) | 893 | if (!page_is_ram(pagenr)) |
892 | return 1; | 894 | return 1; |
893 | return 0; | 895 | return 0; |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index d4639facd1bd..91817d0afcaf 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -4807,7 +4807,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
4807 | } | 4807 | } |
4808 | } | 4808 | } |
4809 | 4809 | ||
4810 | err = pci_request_selected_regions(pdev, | 4810 | err = pci_request_selected_regions_exclusive(pdev, |
4811 | pci_select_bars(pdev, IORESOURCE_MEM), | 4811 | pci_select_bars(pdev, IORESOURCE_MEM), |
4812 | e1000e_driver_name); | 4812 | e1000e_driver_name); |
4813 | if (err) | 4813 | if (err) |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 388440e0d222..d5cdccf27a69 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -620,6 +620,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
620 | vma->vm_pgoff += start >> PAGE_SHIFT; | 620 | vma->vm_pgoff += start >> PAGE_SHIFT; |
621 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; | 621 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; |
622 | 622 | ||
623 | if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(start)) | ||
624 | return -EINVAL; | ||
625 | |||
623 | return pci_mmap_page_range(pdev, vma, mmap_type, write_combine); | 626 | return pci_mmap_page_range(pdev, vma, mmap_type, write_combine); |
624 | } | 627 | } |
625 | 628 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2cfa41e367a7..47663dc0daf7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1395,7 +1395,8 @@ void pci_release_region(struct pci_dev *pdev, int bar) | |||
1395 | * Returns 0 on success, or %EBUSY on error. A warning | 1395 | * Returns 0 on success, or %EBUSY on error. A warning |
1396 | * message is also printed on failure. | 1396 | * message is also printed on failure. |
1397 | */ | 1397 | */ |
1398 | int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | 1398 | static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_name, |
1399 | int exclusive) | ||
1399 | { | 1400 | { |
1400 | struct pci_devres *dr; | 1401 | struct pci_devres *dr; |
1401 | 1402 | ||
@@ -1408,8 +1409,9 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | |||
1408 | goto err_out; | 1409 | goto err_out; |
1409 | } | 1410 | } |
1410 | else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { | 1411 | else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { |
1411 | if (!request_mem_region(pci_resource_start(pdev, bar), | 1412 | if (!__request_mem_region(pci_resource_start(pdev, bar), |
1412 | pci_resource_len(pdev, bar), res_name)) | 1413 | pci_resource_len(pdev, bar), res_name, |
1414 | exclusive)) | ||
1413 | goto err_out; | 1415 | goto err_out; |
1414 | } | 1416 | } |
1415 | 1417 | ||
@@ -1428,6 +1430,47 @@ err_out: | |||
1428 | } | 1430 | } |
1429 | 1431 | ||
1430 | /** | 1432 | /** |
1433 | * pci_request_region - Reserved PCI I/O and memory resource | ||
1434 | * @pdev: PCI device whose resources are to be reserved | ||
1435 | * @bar: BAR to be reserved | ||
1436 | * @res_name: Name to be associated with resource. | ||
1437 | * | ||
1438 | * Mark the PCI region associated with PCI device @pdev BR @bar as | ||
1439 | * being reserved by owner @res_name. Do not access any | ||
1440 | * address inside the PCI regions unless this call returns | ||
1441 | * successfully. | ||
1442 | * | ||
1443 | * Returns 0 on success, or %EBUSY on error. A warning | ||
1444 | * message is also printed on failure. | ||
1445 | */ | ||
1446 | int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | ||
1447 | { | ||
1448 | return __pci_request_region(pdev, bar, res_name, 0); | ||
1449 | } | ||
1450 | |||
1451 | /** | ||
1452 | * pci_request_region_exclusive - Reserved PCI I/O and memory resource | ||
1453 | * @pdev: PCI device whose resources are to be reserved | ||
1454 | * @bar: BAR to be reserved | ||
1455 | * @res_name: Name to be associated with resource. | ||
1456 | * | ||
1457 | * Mark the PCI region associated with PCI device @pdev BR @bar as | ||
1458 | * being reserved by owner @res_name. Do not access any | ||
1459 | * address inside the PCI regions unless this call returns | ||
1460 | * successfully. | ||
1461 | * | ||
1462 | * Returns 0 on success, or %EBUSY on error. A warning | ||
1463 | * message is also printed on failure. | ||
1464 | * | ||
1465 | * The key difference that _exclusive makes it that userspace is | ||
1466 | * explicitly not allowed to map the resource via /dev/mem or | ||
1467 | * sysfs. | ||
1468 | */ | ||
1469 | int pci_request_region_exclusive(struct pci_dev *pdev, int bar, const char *res_name) | ||
1470 | { | ||
1471 | return __pci_request_region(pdev, bar, res_name, IORESOURCE_EXCLUSIVE); | ||
1472 | } | ||
1473 | /** | ||
1431 | * pci_release_selected_regions - Release selected PCI I/O and memory resources | 1474 | * pci_release_selected_regions - Release selected PCI I/O and memory resources |
1432 | * @pdev: PCI device whose resources were previously reserved | 1475 | * @pdev: PCI device whose resources were previously reserved |
1433 | * @bars: Bitmask of BARs to be released | 1476 | * @bars: Bitmask of BARs to be released |
@@ -1444,20 +1487,14 @@ void pci_release_selected_regions(struct pci_dev *pdev, int bars) | |||
1444 | pci_release_region(pdev, i); | 1487 | pci_release_region(pdev, i); |
1445 | } | 1488 | } |
1446 | 1489 | ||
1447 | /** | 1490 | int __pci_request_selected_regions(struct pci_dev *pdev, int bars, |
1448 | * pci_request_selected_regions - Reserve selected PCI I/O and memory resources | 1491 | const char *res_name, int excl) |
1449 | * @pdev: PCI device whose resources are to be reserved | ||
1450 | * @bars: Bitmask of BARs to be requested | ||
1451 | * @res_name: Name to be associated with resource | ||
1452 | */ | ||
1453 | int pci_request_selected_regions(struct pci_dev *pdev, int bars, | ||
1454 | const char *res_name) | ||
1455 | { | 1492 | { |
1456 | int i; | 1493 | int i; |
1457 | 1494 | ||
1458 | for (i = 0; i < 6; i++) | 1495 | for (i = 0; i < 6; i++) |
1459 | if (bars & (1 << i)) | 1496 | if (bars & (1 << i)) |
1460 | if(pci_request_region(pdev, i, res_name)) | 1497 | if (__pci_request_region(pdev, i, res_name, excl)) |
1461 | goto err_out; | 1498 | goto err_out; |
1462 | return 0; | 1499 | return 0; |
1463 | 1500 | ||
@@ -1469,6 +1506,26 @@ err_out: | |||
1469 | return -EBUSY; | 1506 | return -EBUSY; |
1470 | } | 1507 | } |
1471 | 1508 | ||
1509 | |||
1510 | /** | ||
1511 | * pci_request_selected_regions - Reserve selected PCI I/O and memory resources | ||
1512 | * @pdev: PCI device whose resources are to be reserved | ||
1513 | * @bars: Bitmask of BARs to be requested | ||
1514 | * @res_name: Name to be associated with resource | ||
1515 | */ | ||
1516 | int pci_request_selected_regions(struct pci_dev *pdev, int bars, | ||
1517 | const char *res_name) | ||
1518 | { | ||
1519 | return __pci_request_selected_regions(pdev, bars, res_name, 0); | ||
1520 | } | ||
1521 | |||
1522 | int pci_request_selected_regions_exclusive(struct pci_dev *pdev, | ||
1523 | int bars, const char *res_name) | ||
1524 | { | ||
1525 | return __pci_request_selected_regions(pdev, bars, res_name, | ||
1526 | IORESOURCE_EXCLUSIVE); | ||
1527 | } | ||
1528 | |||
1472 | /** | 1529 | /** |
1473 | * pci_release_regions - Release reserved PCI I/O and memory resources | 1530 | * pci_release_regions - Release reserved PCI I/O and memory resources |
1474 | * @pdev: PCI device whose resources were previously reserved by pci_request_regions | 1531 | * @pdev: PCI device whose resources were previously reserved by pci_request_regions |
@@ -1502,6 +1559,29 @@ int pci_request_regions(struct pci_dev *pdev, const char *res_name) | |||
1502 | } | 1559 | } |
1503 | 1560 | ||
1504 | /** | 1561 | /** |
1562 | * pci_request_regions_exclusive - Reserved PCI I/O and memory resources | ||
1563 | * @pdev: PCI device whose resources are to be reserved | ||
1564 | * @res_name: Name to be associated with resource. | ||
1565 | * | ||
1566 | * Mark all PCI regions associated with PCI device @pdev as | ||
1567 | * being reserved by owner @res_name. Do not access any | ||
1568 | * address inside the PCI regions unless this call returns | ||
1569 | * successfully. | ||
1570 | * | ||
1571 | * pci_request_regions_exclusive() will mark the region so that | ||
1572 | * /dev/mem and the sysfs MMIO access will not be allowed. | ||
1573 | * | ||
1574 | * Returns 0 on success, or %EBUSY on error. A warning | ||
1575 | * message is also printed on failure. | ||
1576 | */ | ||
1577 | int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) | ||
1578 | { | ||
1579 | return pci_request_selected_regions_exclusive(pdev, | ||
1580 | ((1 << 6) - 1), res_name); | ||
1581 | } | ||
1582 | |||
1583 | |||
1584 | /** | ||
1505 | * pci_set_master - enables bus-mastering for device dev | 1585 | * pci_set_master - enables bus-mastering for device dev |
1506 | * @dev: the PCI device to enable | 1586 | * @dev: the PCI device to enable |
1507 | * | 1587 | * |
@@ -2149,10 +2229,13 @@ EXPORT_SYMBOL(pci_find_capability); | |||
2149 | EXPORT_SYMBOL(pci_bus_find_capability); | 2229 | EXPORT_SYMBOL(pci_bus_find_capability); |
2150 | EXPORT_SYMBOL(pci_release_regions); | 2230 | EXPORT_SYMBOL(pci_release_regions); |
2151 | EXPORT_SYMBOL(pci_request_regions); | 2231 | EXPORT_SYMBOL(pci_request_regions); |
2232 | EXPORT_SYMBOL(pci_request_regions_exclusive); | ||
2152 | EXPORT_SYMBOL(pci_release_region); | 2233 | EXPORT_SYMBOL(pci_release_region); |
2153 | EXPORT_SYMBOL(pci_request_region); | 2234 | EXPORT_SYMBOL(pci_request_region); |
2235 | EXPORT_SYMBOL(pci_request_region_exclusive); | ||
2154 | EXPORT_SYMBOL(pci_release_selected_regions); | 2236 | EXPORT_SYMBOL(pci_release_selected_regions); |
2155 | EXPORT_SYMBOL(pci_request_selected_regions); | 2237 | EXPORT_SYMBOL(pci_request_selected_regions); |
2238 | EXPORT_SYMBOL(pci_request_selected_regions_exclusive); | ||
2156 | EXPORT_SYMBOL(pci_set_master); | 2239 | EXPORT_SYMBOL(pci_set_master); |
2157 | EXPORT_SYMBOL(pci_set_mwi); | 2240 | EXPORT_SYMBOL(pci_set_mwi); |
2158 | EXPORT_SYMBOL(pci_try_set_mwi); | 2241 | EXPORT_SYMBOL(pci_try_set_mwi); |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 041e95aac2bf..f6bb2ca8e3ba 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -49,6 +49,7 @@ struct resource_list { | |||
49 | #define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */ | 49 | #define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */ |
50 | #define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */ | 50 | #define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */ |
51 | 51 | ||
52 | #define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */ | ||
52 | #define IORESOURCE_DISABLED 0x10000000 | 53 | #define IORESOURCE_DISABLED 0x10000000 |
53 | #define IORESOURCE_UNSET 0x20000000 | 54 | #define IORESOURCE_UNSET 0x20000000 |
54 | #define IORESOURCE_AUTO 0x40000000 | 55 | #define IORESOURCE_AUTO 0x40000000 |
@@ -133,13 +134,16 @@ static inline unsigned long resource_type(struct resource *res) | |||
133 | } | 134 | } |
134 | 135 | ||
135 | /* Convenience shorthand with allocation */ | 136 | /* Convenience shorthand with allocation */ |
136 | #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name)) | 137 | #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0) |
137 | #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name)) | 138 | #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl) |
139 | #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0) | ||
140 | #define request_mem_region_exclusive(start,n,name) \ | ||
141 | __request_region(&iomem_resource, (start), (n), (name), IORESOURCE_EXCLUSIVE) | ||
138 | #define rename_region(region, newname) do { (region)->name = (newname); } while (0) | 142 | #define rename_region(region, newname) do { (region)->name = (newname); } while (0) |
139 | 143 | ||
140 | extern struct resource * __request_region(struct resource *, | 144 | extern struct resource * __request_region(struct resource *, |
141 | resource_size_t start, | 145 | resource_size_t start, |
142 | resource_size_t n, const char *name); | 146 | resource_size_t n, const char *name, int relaxed); |
143 | 147 | ||
144 | /* Compatibility cruft */ | 148 | /* Compatibility cruft */ |
145 | #define release_region(start,n) __release_region(&ioport_resource, (start), (n)) | 149 | #define release_region(start,n) __release_region(&ioport_resource, (start), (n)) |
@@ -175,6 +179,7 @@ extern struct resource * __devm_request_region(struct device *dev, | |||
175 | extern void __devm_release_region(struct device *dev, struct resource *parent, | 179 | extern void __devm_release_region(struct device *dev, struct resource *parent, |
176 | resource_size_t start, resource_size_t n); | 180 | resource_size_t start, resource_size_t n); |
177 | extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size); | 181 | extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size); |
182 | extern int iomem_is_exclusive(u64 addr); | ||
178 | 183 | ||
179 | #endif /* __ASSEMBLY__ */ | 184 | #endif /* __ASSEMBLY__ */ |
180 | #endif /* _LINUX_IOPORT_H */ | 185 | #endif /* _LINUX_IOPORT_H */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 59a3dc2059d3..bfcb39ca8879 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -686,10 +686,13 @@ void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), | |||
686 | int (*)(struct pci_dev *, u8, u8)); | 686 | int (*)(struct pci_dev *, u8, u8)); |
687 | #define HAVE_PCI_REQ_REGIONS 2 | 687 | #define HAVE_PCI_REQ_REGIONS 2 |
688 | int __must_check pci_request_regions(struct pci_dev *, const char *); | 688 | int __must_check pci_request_regions(struct pci_dev *, const char *); |
689 | int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *); | ||
689 | void pci_release_regions(struct pci_dev *); | 690 | void pci_release_regions(struct pci_dev *); |
690 | int __must_check pci_request_region(struct pci_dev *, int, const char *); | 691 | int __must_check pci_request_region(struct pci_dev *, int, const char *); |
692 | int __must_check pci_request_region_exclusive(struct pci_dev *, int, const char *); | ||
691 | void pci_release_region(struct pci_dev *, int); | 693 | void pci_release_region(struct pci_dev *, int); |
692 | int pci_request_selected_regions(struct pci_dev *, int, const char *); | 694 | int pci_request_selected_regions(struct pci_dev *, int, const char *); |
695 | int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *); | ||
693 | void pci_release_selected_regions(struct pci_dev *, int); | 696 | void pci_release_selected_regions(struct pci_dev *, int); |
694 | 697 | ||
695 | /* drivers/pci/bus.c */ | 698 | /* drivers/pci/bus.c */ |
diff --git a/kernel/resource.c b/kernel/resource.c index e633106b12f6..ca6a1536b205 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -623,7 +623,7 @@ resource_size_t resource_alignment(struct resource *res) | |||
623 | */ | 623 | */ |
624 | struct resource * __request_region(struct resource *parent, | 624 | struct resource * __request_region(struct resource *parent, |
625 | resource_size_t start, resource_size_t n, | 625 | resource_size_t start, resource_size_t n, |
626 | const char *name) | 626 | const char *name, int flags) |
627 | { | 627 | { |
628 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 628 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
629 | 629 | ||
@@ -634,6 +634,7 @@ struct resource * __request_region(struct resource *parent, | |||
634 | res->start = start; | 634 | res->start = start; |
635 | res->end = start + n - 1; | 635 | res->end = start + n - 1; |
636 | res->flags = IORESOURCE_BUSY; | 636 | res->flags = IORESOURCE_BUSY; |
637 | res->flags |= flags; | ||
637 | 638 | ||
638 | write_lock(&resource_lock); | 639 | write_lock(&resource_lock); |
639 | 640 | ||
@@ -679,7 +680,7 @@ int __check_region(struct resource *parent, resource_size_t start, | |||
679 | { | 680 | { |
680 | struct resource * res; | 681 | struct resource * res; |
681 | 682 | ||
682 | res = __request_region(parent, start, n, "check-region"); | 683 | res = __request_region(parent, start, n, "check-region", 0); |
683 | if (!res) | 684 | if (!res) |
684 | return -EBUSY; | 685 | return -EBUSY; |
685 | 686 | ||
@@ -776,7 +777,7 @@ struct resource * __devm_request_region(struct device *dev, | |||
776 | dr->start = start; | 777 | dr->start = start; |
777 | dr->n = n; | 778 | dr->n = n; |
778 | 779 | ||
779 | res = __request_region(parent, start, n, name); | 780 | res = __request_region(parent, start, n, name, 0); |
780 | if (res) | 781 | if (res) |
781 | devres_add(dev, dr); | 782 | devres_add(dev, dr); |
782 | else | 783 | else |
@@ -876,3 +877,57 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size) | |||
876 | 877 | ||
877 | return err; | 878 | return err; |
878 | } | 879 | } |
880 | |||
881 | #ifdef CONFIG_STRICT_DEVMEM | ||
882 | static int strict_iomem_checks = 1; | ||
883 | #else | ||
884 | static int strict_iomem_checks; | ||
885 | #endif | ||
886 | |||
887 | /* | ||
888 | * check if an address is reserved in the iomem resource tree | ||
889 | * returns 1 if reserved, 0 if not reserved. | ||
890 | */ | ||
891 | int iomem_is_exclusive(u64 addr) | ||
892 | { | ||
893 | struct resource *p = &iomem_resource; | ||
894 | int err = 0; | ||
895 | loff_t l; | ||
896 | int size = PAGE_SIZE; | ||
897 | |||
898 | if (!strict_iomem_checks) | ||
899 | return 0; | ||
900 | |||
901 | addr = addr & PAGE_MASK; | ||
902 | |||
903 | read_lock(&resource_lock); | ||
904 | for (p = p->child; p ; p = r_next(NULL, p, &l)) { | ||
905 | /* | ||
906 | * We can probably skip the resources without | ||
907 | * IORESOURCE_IO attribute? | ||
908 | */ | ||
909 | if (p->start >= addr + size) | ||
910 | break; | ||
911 | if (p->end < addr) | ||
912 | continue; | ||
913 | if (p->flags & IORESOURCE_BUSY && | ||
914 | p->flags & IORESOURCE_EXCLUSIVE) { | ||
915 | err = 1; | ||
916 | break; | ||
917 | } | ||
918 | } | ||
919 | read_unlock(&resource_lock); | ||
920 | |||
921 | return err; | ||
922 | } | ||
923 | |||
924 | static int __init strict_iomem(char *str) | ||
925 | { | ||
926 | if (strstr(str, "relaxed")) | ||
927 | strict_iomem_checks = 0; | ||
928 | if (strstr(str, "strict")) | ||
929 | strict_iomem_checks = 1; | ||
930 | return 1; | ||
931 | } | ||
932 | |||
933 | __setup("iomem=", strict_iomem); | ||