Skip to content

Commit

Permalink
x86: add far read test to testmmiotrace
Browse files Browse the repository at this point in the history
Apparently pages far into an ioremapped region might not actually be
mapped during ioremap(). Add an optional read test to try to trigger a
multiply faulting MMIO access. Also add more messages to the kernel log
to help debugging.

This patch is based on a patch suggested by
Stuart Bennett <stuart@freedesktop.org>
who discovered bugs in mmiotrace related to normal kernel space faults.

Signed-off-by: Pekka Paalanen <pq@iki.fi>
Cc: Stuart Bennett <stuart@freedesktop.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Pekka Paalanen authored and Ingo Molnar committed Mar 2, 2009
1 parent fab852a commit 5ff9369
Showing 1 changed file with 28 additions and 7 deletions.
35 changes: 28 additions & 7 deletions arch/x86/mm/testmmiotrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@

static unsigned long mmio_address;
module_param(mmio_address, ulong, 0);
MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB.");
MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
"(or 8 MB if read_far is non-zero).");

static unsigned long read_far = 0x400100;
module_param(read_far, ulong, 0);
MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB "
"(default: 0x400100).");

static unsigned v16(unsigned i)
{
Expand All @@ -24,6 +30,7 @@ static unsigned v32(unsigned i)
static void do_write_test(void __iomem *p)
{
unsigned int i;
pr_info(MODULE_NAME ": write test.\n");
mmiotrace_printk("Write test.\n");

for (i = 0; i < 256; i++)
Expand All @@ -40,6 +47,7 @@ static void do_read_test(void __iomem *p)
{
unsigned int i;
unsigned errs[3] = { 0 };
pr_info(MODULE_NAME ": read test.\n");
mmiotrace_printk("Read test.\n");

for (i = 0; i < 256; i++)
Expand All @@ -58,21 +66,33 @@ static void do_read_test(void __iomem *p)
errs[0], errs[1], errs[2]);
}

static void do_test(void)
static void do_read_far_test(void __iomem *p)
{
pr_info(MODULE_NAME ": read far test.\n");
mmiotrace_printk("Read far test.\n");

ioread32(p + read_far);
}

static void do_test(unsigned long size)
{
void __iomem *p = ioremap_nocache(mmio_address, 0x4000);
void __iomem *p = ioremap_nocache(mmio_address, size);
if (!p) {
pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
return;
}
mmiotrace_printk("ioremap returned %p.\n", p);
do_write_test(p);
do_read_test(p);
if (read_far && read_far < size - 4)
do_read_far_test(p);
iounmap(p);
}

static int __init init(void)
{
unsigned long size = (read_far) ? (8 << 20) : (16 << 10);

if (mmio_address == 0) {
pr_err(MODULE_NAME ": you have to use the module argument "
"mmio_address.\n");
Expand All @@ -81,10 +101,11 @@ static int __init init(void)
return -ENXIO;
}

pr_warning(MODULE_NAME ": WARNING: mapping 16 kB @ 0x%08lx "
"in PCI address space, and writing "
"rubbish in there.\n", mmio_address);
do_test();
pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI "
"address space, and writing 16 kB of rubbish in there.\n",
size >> 10, mmio_address);
do_test(size);
pr_info(MODULE_NAME ": All done.\n");
return 0;
}

Expand Down

0 comments on commit 5ff9369

Please sign in to comment.