pci-iommu_table.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include <linux/dma-mapping.h>
  2. #include <asm/iommu_table.h>
  3. #include <linux/string.h>
  4. #include <linux/kallsyms.h>
  5. #define DEBUG 1
  6. static struct iommu_table_entry * __init
  7. find_dependents_of(struct iommu_table_entry *start,
  8. struct iommu_table_entry *finish,
  9. struct iommu_table_entry *q)
  10. {
  11. struct iommu_table_entry *p;
  12. if (!q)
  13. return NULL;
  14. for (p = start; p < finish; p++)
  15. if (p->detect == q->depend)
  16. return p;
  17. return NULL;
  18. }
  19. void __init sort_iommu_table(struct iommu_table_entry *start,
  20. struct iommu_table_entry *finish) {
  21. struct iommu_table_entry *p, *q, tmp;
  22. for (p = start; p < finish; p++) {
  23. again:
  24. q = find_dependents_of(start, finish, p);
  25. /* We are bit sneaky here. We use the memory address to figure
  26. * out if the node we depend on is past our point, if so, swap.
  27. */
  28. if (q > p) {
  29. tmp = *p;
  30. memmove(p, q, sizeof(*p));
  31. *q = tmp;
  32. goto again;
  33. }
  34. }
  35. }
  36. #ifdef DEBUG
  37. void __init check_iommu_entries(struct iommu_table_entry *start,
  38. struct iommu_table_entry *finish)
  39. {
  40. struct iommu_table_entry *p, *q, *x;
  41. /* Simple cyclic dependency checker. */
  42. for (p = start; p < finish; p++) {
  43. q = find_dependents_of(start, finish, p);
  44. x = find_dependents_of(start, finish, q);
  45. if (p == x) {
  46. printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %pS depends on %pS and vice-versa. BREAKING IT.\n",
  47. p->detect, q->detect);
  48. /* Heavy handed way..*/
  49. x->depend = 0;
  50. }
  51. }
  52. for (p = start; p < finish; p++) {
  53. q = find_dependents_of(p, finish, p);
  54. if (q && q > p) {
  55. printk(KERN_ERR "EXECUTION ORDER INVALID! %pS should be called before %pS!\n",
  56. p->detect, q->detect);
  57. }
  58. }
  59. }
  60. #else
  61. inline void check_iommu_entries(struct iommu_table_entry *start,
  62. struct iommu_table_entry *finish)
  63. {
  64. }
  65. #endif