root/arch/x86/kernel/pci-iommu_table.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_dependents_of
  2. sort_iommu_table
  3. check_iommu_entries
  4. check_iommu_entries

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

/* [<][>][^][v][top][bottom][index][help] */