Blame view

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