eeh_cache.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * PCI address cache; allows the lookup of PCI devices based on I/O address
  4. *
  5. * Copyright IBM Corporation 2004
  6. * Copyright Linas Vepstas <linas@austin.ibm.com> 2004
  7. */
  8. #include <linux/list.h>
  9. #include <linux/pci.h>
  10. #include <linux/rbtree.h>
  11. #include <linux/slab.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/atomic.h>
  14. #include <asm/pci-bridge.h>
  15. #include <asm/debugfs.h>
  16. #include <asm/ppc-pci.h>
  17. /**
  18. * DOC: Overview
  19. *
  20. * The pci address cache subsystem. This subsystem places
  21. * PCI device address resources into a red-black tree, sorted
  22. * according to the address range, so that given only an i/o
  23. * address, the corresponding PCI device can be **quickly**
  24. * found. It is safe to perform an address lookup in an interrupt
  25. * context; this ability is an important feature.
  26. *
  27. * Currently, the only customer of this code is the EEH subsystem;
  28. * thus, this code has been somewhat tailored to suit EEH better.
  29. * In particular, the cache does *not* hold the addresses of devices
  30. * for which EEH is not enabled.
  31. *
  32. * (Implementation Note: The RB tree seems to be better/faster
  33. * than any hash algo I could think of for this problem, even
  34. * with the penalty of slow pointer chases for d-cache misses).
  35. */
  36. struct pci_io_addr_range {
  37. struct rb_node rb_node;
  38. resource_size_t addr_lo;
  39. resource_size_t addr_hi;
  40. struct eeh_dev *edev;
  41. struct pci_dev *pcidev;
  42. unsigned long flags;
  43. };
  44. static struct pci_io_addr_cache {
  45. struct rb_root rb_root;
  46. spinlock_t piar_lock;
  47. } pci_io_addr_cache_root;
  48. static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr)
  49. {
  50. struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node;
  51. while (n) {
  52. struct pci_io_addr_range *piar;
  53. piar = rb_entry(n, struct pci_io_addr_range, rb_node);
  54. if (addr < piar->addr_lo)
  55. n = n->rb_left;
  56. else if (addr > piar->addr_hi)
  57. n = n->rb_right;
  58. else
  59. return piar->edev;
  60. }
  61. return NULL;
  62. }
  63. /**
  64. * eeh_addr_cache_get_dev - Get device, given only address
  65. * @addr: mmio (PIO) phys address or i/o port number
  66. *
  67. * Given an mmio phys address, or a port number, find a pci device
  68. * that implements this address. I/O port numbers are assumed to be offset
  69. * from zero (that is, they do *not* have pci_io_addr added in).
  70. * It is safe to call this function within an interrupt.
  71. */
  72. struct eeh_dev *eeh_addr_cache_get_dev(unsigned long addr)
  73. {
  74. struct eeh_dev *edev;
  75. unsigned long flags;
  76. spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
  77. edev = __eeh_addr_cache_get_device(addr);
  78. spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
  79. return edev;
  80. }
  81. #ifdef DEBUG
  82. /*
  83. * Handy-dandy debug print routine, does nothing more
  84. * than print out the contents of our addr cache.
  85. */
  86. static void eeh_addr_cache_print(struct pci_io_addr_cache *cache)
  87. {
  88. struct rb_node *n;
  89. int cnt = 0;
  90. n = rb_first(&cache->rb_root);
  91. while (n) {
  92. struct pci_io_addr_range *piar;
  93. piar = rb_entry(n, struct pci_io_addr_range, rb_node);
  94. pr_info("PCI: %s addr range %d [%pap-%pap]: %s\n",
  95. (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
  96. &piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev));
  97. cnt++;
  98. n = rb_next(n);
  99. }
  100. }
  101. #endif
  102. /* Insert address range into the rb tree. */
  103. static struct pci_io_addr_range *
  104. eeh_addr_cache_insert(struct pci_dev *dev, resource_size_t alo,
  105. resource_size_t ahi, unsigned long flags)
  106. {
  107. struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node;
  108. struct rb_node *parent = NULL;
  109. struct pci_io_addr_range *piar;
  110. /* Walk tree, find a place to insert into tree */
  111. while (*p) {
  112. parent = *p;
  113. piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
  114. if (ahi < piar->addr_lo) {
  115. p = &parent->rb_left;
  116. } else if (alo > piar->addr_hi) {
  117. p = &parent->rb_right;
  118. } else {
  119. if (dev != piar->pcidev ||
  120. alo != piar->addr_lo || ahi != piar->addr_hi) {
  121. pr_warn("PIAR: overlapping address range\n");
  122. }
  123. return piar;
  124. }
  125. }
  126. piar = kzalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
  127. if (!piar)
  128. return NULL;
  129. piar->addr_lo = alo;
  130. piar->addr_hi = ahi;
  131. piar->edev = pci_dev_to_eeh_dev(dev);
  132. piar->pcidev = dev;
  133. piar->flags = flags;
  134. eeh_edev_dbg(piar->edev, "PIAR: insert range=[%pap:%pap]\n",
  135. &alo, &ahi);
  136. rb_link_node(&piar->rb_node, parent, p);
  137. rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
  138. return piar;
  139. }
  140. static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
  141. {
  142. struct eeh_dev *edev;
  143. int i;
  144. edev = pci_dev_to_eeh_dev(dev);
  145. if (!edev) {
  146. pr_warn("PCI: no EEH dev found for %s\n",
  147. pci_name(dev));
  148. return;
  149. }
  150. /* Skip any devices for which EEH is not enabled. */
  151. if (!edev->pe) {
  152. dev_dbg(&dev->dev, "EEH: Skip building address cache\n");
  153. return;
  154. }
  155. /*
  156. * Walk resources on this device, poke the first 7 (6 normal BAR and 1
  157. * ROM BAR) into the tree.
  158. */
  159. for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
  160. resource_size_t start = pci_resource_start(dev,i);
  161. resource_size_t end = pci_resource_end(dev,i);
  162. unsigned long flags = pci_resource_flags(dev,i);
  163. /* We are interested only bus addresses, not dma or other stuff */
  164. if (0 == (flags & (IORESOURCE_IO | IORESOURCE_MEM)))
  165. continue;
  166. if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
  167. continue;
  168. eeh_addr_cache_insert(dev, start, end, flags);
  169. }
  170. }
  171. /**
  172. * eeh_addr_cache_insert_dev - Add a device to the address cache
  173. * @dev: PCI device whose I/O addresses we are interested in.
  174. *
  175. * In order to support the fast lookup of devices based on addresses,
  176. * we maintain a cache of devices that can be quickly searched.
  177. * This routine adds a device to that cache.
  178. */
  179. void eeh_addr_cache_insert_dev(struct pci_dev *dev)
  180. {
  181. unsigned long flags;
  182. spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
  183. __eeh_addr_cache_insert_dev(dev);
  184. spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
  185. }
  186. static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev)
  187. {
  188. struct rb_node *n;
  189. restart:
  190. n = rb_first(&pci_io_addr_cache_root.rb_root);
  191. while (n) {
  192. struct pci_io_addr_range *piar;
  193. piar = rb_entry(n, struct pci_io_addr_range, rb_node);
  194. if (piar->pcidev == dev) {
  195. eeh_edev_dbg(piar->edev, "PIAR: remove range=[%pap:%pap]\n",
  196. &piar->addr_lo, &piar->addr_hi);
  197. rb_erase(n, &pci_io_addr_cache_root.rb_root);
  198. kfree(piar);
  199. goto restart;
  200. }
  201. n = rb_next(n);
  202. }
  203. }
  204. /**
  205. * eeh_addr_cache_rmv_dev - remove pci device from addr cache
  206. * @dev: device to remove
  207. *
  208. * Remove a device from the addr-cache tree.
  209. * This is potentially expensive, since it will walk
  210. * the tree multiple times (once per resource).
  211. * But so what; device removal doesn't need to be that fast.
  212. */
  213. void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
  214. {
  215. unsigned long flags;
  216. spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
  217. __eeh_addr_cache_rmv_dev(dev);
  218. spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
  219. }
  220. /**
  221. * eeh_addr_cache_init - Initialize a cache of I/O addresses
  222. *
  223. * Initialize a cache of pci i/o addresses. This cache will be used to
  224. * find the pci device that corresponds to a given address.
  225. */
  226. void eeh_addr_cache_init(void)
  227. {
  228. spin_lock_init(&pci_io_addr_cache_root.piar_lock);
  229. }
  230. static int eeh_addr_cache_show(struct seq_file *s, void *v)
  231. {
  232. struct pci_io_addr_range *piar;
  233. struct rb_node *n;
  234. unsigned long flags;
  235. spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
  236. for (n = rb_first(&pci_io_addr_cache_root.rb_root); n; n = rb_next(n)) {
  237. piar = rb_entry(n, struct pci_io_addr_range, rb_node);
  238. seq_printf(s, "%s addr range [%pap-%pap]: %s\n",
  239. (piar->flags & IORESOURCE_IO) ? "i/o" : "mem",
  240. &piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev));
  241. }
  242. spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
  243. return 0;
  244. }
  245. DEFINE_SHOW_ATTRIBUTE(eeh_addr_cache);
  246. void eeh_cache_debugfs_init(void)
  247. {
  248. debugfs_create_file_unsafe("eeh_address_cache", 0400,
  249. powerpc_debugfs_root, NULL,
  250. &eeh_addr_cache_fops);
  251. }