~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/mm/testmmiotrace.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
  4  */
  5 
  6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  7 
  8 #include <linux/module.h>
  9 #include <linux/io.h>
 10 #include <linux/mmiotrace.h>
 11 #include <linux/security.h>
 12 
 13 static unsigned long mmio_address;
 14 module_param_hw(mmio_address, ulong, iomem, 0);
 15 MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
 16                                 "(or 8 MB if read_far is non-zero).");
 17 
 18 static unsigned long read_far = 0x400100;
 19 module_param(read_far, ulong, 0);
 20 MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB "
 21                                 "(default: 0x400100).");
 22 
 23 static unsigned v16(unsigned i)
 24 {
 25         return i * 12 + 7;
 26 }
 27 
 28 static unsigned v32(unsigned i)
 29 {
 30         return i * 212371 + 13;
 31 }
 32 
 33 static void do_write_test(void __iomem *p)
 34 {
 35         unsigned int i;
 36         pr_info("write test.\n");
 37         mmiotrace_printk("Write test.\n");
 38 
 39         for (i = 0; i < 256; i++)
 40                 iowrite8(i, p + i);
 41 
 42         for (i = 1024; i < (5 * 1024); i += 2)
 43                 iowrite16(v16(i), p + i);
 44 
 45         for (i = (5 * 1024); i < (16 * 1024); i += 4)
 46                 iowrite32(v32(i), p + i);
 47 }
 48 
 49 static void do_read_test(void __iomem *p)
 50 {
 51         unsigned int i;
 52         unsigned errs[3] = { 0 };
 53         pr_info("read test.\n");
 54         mmiotrace_printk("Read test.\n");
 55 
 56         for (i = 0; i < 256; i++)
 57                 if (ioread8(p + i) != i)
 58                         ++errs[0];
 59 
 60         for (i = 1024; i < (5 * 1024); i += 2)
 61                 if (ioread16(p + i) != v16(i))
 62                         ++errs[1];
 63 
 64         for (i = (5 * 1024); i < (16 * 1024); i += 4)
 65                 if (ioread32(p + i) != v32(i))
 66                         ++errs[2];
 67 
 68         mmiotrace_printk("Read errors: 8-bit %d, 16-bit %d, 32-bit %d.\n",
 69                                                 errs[0], errs[1], errs[2]);
 70 }
 71 
 72 static void do_read_far_test(void __iomem *p)
 73 {
 74         pr_info("read far test.\n");
 75         mmiotrace_printk("Read far test.\n");
 76 
 77         ioread32(p + read_far);
 78 }
 79 
 80 static void do_test(unsigned long size)
 81 {
 82         void __iomem *p = ioremap(mmio_address, size);
 83         if (!p) {
 84                 pr_err("could not ioremap, aborting.\n");
 85                 return;
 86         }
 87         mmiotrace_printk("ioremap returned %p.\n", p);
 88         do_write_test(p);
 89         do_read_test(p);
 90         if (read_far && read_far < size - 4)
 91                 do_read_far_test(p);
 92         iounmap(p);
 93 }
 94 
 95 /*
 96  * Tests how mmiotrace behaves in face of multiple ioremap / iounmaps in
 97  * a short time. We had a bug in deferred freeing procedure which tried
 98  * to free this region multiple times (ioremap can reuse the same address
 99  * for many mappings).
100  */
101 static void do_test_bulk_ioremapping(void)
102 {
103         void __iomem *p;
104         int i;
105 
106         for (i = 0; i < 10; ++i) {
107                 p = ioremap(mmio_address, PAGE_SIZE);
108                 if (p)
109                         iounmap(p);
110         }
111 
112         /* Force freeing. If it will crash we will know why. */
113         synchronize_rcu();
114 }
115 
116 static int __init init(void)
117 {
118         unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
119         int ret = security_locked_down(LOCKDOWN_MMIOTRACE);
120 
121         if (ret)
122                 return ret;
123 
124         if (mmio_address == 0) {
125                 pr_err("you have to use the module argument mmio_address.\n");
126                 pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n");
127                 return -ENXIO;
128         }
129 
130         pr_warn("WARNING: mapping %lu kB @ 0x%08lx in PCI address space, "
131                 "and writing 16 kB of rubbish in there.\n",
132                 size >> 10, mmio_address);
133         do_test(size);
134         do_test_bulk_ioremapping();
135         pr_info("All done.\n");
136         return 0;
137 }
138 
139 static void __exit cleanup(void)
140 {
141         pr_debug("unloaded.\n");
142 }
143 
144 module_init(init);
145 module_exit(cleanup);
146 MODULE_LICENSE("GPL");
147 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php