Commit | Line | Data |
---|---|---|
edeed305 AV |
1 | /* |
2 | * test_rodata.c: functional test for mark_rodata_ro function | |
3 | * | |
4 | * (C) Copyright 2008 Intel Corporation | |
5 | * Author: Arjan van de Ven <arjan@linux.intel.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation; version 2 | |
10 | * of the License. | |
11 | */ | |
12 | #include <linux/module.h> | |
7bfeab9a | 13 | #include <asm/cacheflush.h> |
edeed305 | 14 | #include <asm/sections.h> |
edeed305 AV |
15 | |
16 | int rodata_test(void) | |
17 | { | |
18 | unsigned long result; | |
19 | unsigned long start, end; | |
20 | ||
21 | /* test 1: read the value */ | |
22 | /* If this test fails, some previous testrun has clobbered the state */ | |
23 | if (!rodata_test_data) { | |
24 | printk(KERN_ERR "rodata_test: test 1 fails (start data)\n"); | |
25 | return -ENODEV; | |
26 | } | |
27 | ||
28 | /* test 2: write to the variable; this should fault */ | |
29 | /* | |
30 | * If this test fails, we managed to overwrite the data | |
31 | * | |
32 | * This is written in assembly to be able to catch the | |
33 | * exception that is supposed to happen in the correct | |
34 | * case | |
35 | */ | |
36 | ||
37 | result = 1; | |
38 | asm volatile( | |
39 | "0: mov %[zero],(%[rodata_test])\n" | |
40 | " mov %[zero], %[rslt]\n" | |
41 | "1:\n" | |
42 | ".section .fixup,\"ax\"\n" | |
43 | "2: jmp 1b\n" | |
44 | ".previous\n" | |
45 | ".section __ex_table,\"a\"\n" | |
46 | " .align 16\n" | |
47 | #ifdef CONFIG_X86_32 | |
48 | " .long 0b,2b\n" | |
49 | #else | |
50 | " .quad 0b,2b\n" | |
51 | #endif | |
52 | ".previous" | |
53 | : [rslt] "=r" (result) | |
54 | : [rodata_test] "r" (&rodata_test_data), [zero] "r" (0UL) | |
55 | ); | |
56 | ||
57 | ||
58 | if (!result) { | |
59 | printk(KERN_ERR "rodata_test: test data was not read only\n"); | |
60 | return -ENODEV; | |
61 | } | |
62 | ||
63 | /* test 3: check the value hasn't changed */ | |
64 | /* If this test fails, we managed to overwrite the data */ | |
65 | if (!rodata_test_data) { | |
66 | printk(KERN_ERR "rodata_test: Test 3 failes (end data)\n"); | |
67 | return -ENODEV; | |
68 | } | |
69 | /* test 4: check if the rodata section is 4Kb aligned */ | |
70 | start = (unsigned long)__start_rodata; | |
71 | end = (unsigned long)__end_rodata; | |
72 | if (start & (PAGE_SIZE - 1)) { | |
73 | printk(KERN_ERR "rodata_test: .rodata is not 4k aligned\n"); | |
74 | return -ENODEV; | |
75 | } | |
76 | if (end & (PAGE_SIZE - 1)) { | |
77 | printk(KERN_ERR "rodata_test: .rodata end is not 4k aligned\n"); | |
78 | return -ENODEV; | |
79 | } | |
80 | ||
81 | return 0; | |
82 | } | |
83 | ||
84 | MODULE_LICENSE("GPL"); | |
85 | MODULE_DESCRIPTION("Testcase for the DEBUG_RODATA infrastructure"); | |
86 | MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>"); |