LCOV - code coverage report
Current view: top level - arch/x86/kernel - pci-iommu_table.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 19 19 100.0 %
Date: 2021-04-22 12:43:58 Functions: 3 3 100.0 %

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

Generated by: LCOV version 1.14