aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2008-10-22 22:55:31 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-01-07 14:12:32 -0500
commite8de1481fd7126ee9e93d6889da6f00c05e1e019 (patch)
tree3e0e564f6aff2f8f0f66bdf37dc2eb87d6e17cde /include
parent23616941914917cf25b94789856b5326b68d8ee8 (diff)
resource: allow MMIO exclusivity for device drivers
Device drivers that use pci_request_regions() (and similar APIs) have a reasonable expectation that they are the only ones accessing their device. As part of the e1000e hunt, we were afraid that some userland (X or some bootsplash stuff) was mapping the MMIO region that the driver thought it had exclusively via /dev/mem or via various sysfs resource mappings. This patch adds the option for device drivers to cause their reserved regions to the "banned from /dev/mem use" list, so now both kernel memory and device-exclusive MMIO regions are banned. NOTE: This is only active when CONFIG_STRICT_DEVMEM is set. In addition to the config option, a kernel parameter iomem=relaxed is provided for the cases where developers want to diagnose, in the field, drivers issues from userspace. Reviewed-by: Matthew Wilcox <willy@linux.intel.com> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/ioport.h11
-rw-r--r--include/linux/pci.h3
2 files changed, 11 insertions, 3 deletions
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
140extern struct resource * __request_region(struct resource *, 144extern 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,
175extern void __devm_release_region(struct device *dev, struct resource *parent, 179extern 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);
177extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size); 181extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size);
182extern 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
688int __must_check pci_request_regions(struct pci_dev *, const char *); 688int __must_check pci_request_regions(struct pci_dev *, const char *);
689int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *);
689void pci_release_regions(struct pci_dev *); 690void pci_release_regions(struct pci_dev *);
690int __must_check pci_request_region(struct pci_dev *, int, const char *); 691int __must_check pci_request_region(struct pci_dev *, int, const char *);
692int __must_check pci_request_region_exclusive(struct pci_dev *, int, const char *);
691void pci_release_region(struct pci_dev *, int); 693void pci_release_region(struct pci_dev *, int);
692int pci_request_selected_regions(struct pci_dev *, int, const char *); 694int pci_request_selected_regions(struct pci_dev *, int, const char *);
695int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *);
693void pci_release_selected_regions(struct pci_dev *, int); 696void pci_release_selected_regions(struct pci_dev *, int);
694 697
695/* drivers/pci/bus.c */ 698/* drivers/pci/bus.c */