From: Arjan van de Ven <[EMAIL PROTECTED]>
Subject: x86: test case for the RODATA config option

This patch adds a test module for the DEBUG_RODATA config
option to make sure change_page_attr() did indeed make
"const" data read only.

This testcase both tests the DEBUG_RODATA code as well as
the change_page_attr() code for correct operation.

When the tests/ patch gets merged, this module should move
to the tests/ directory.

Signed-off-by: Arjan van de Ven <[EMAIL PROTECTED]>
---
 arch/x86/Kconfig.debug        |    8 +++++
 arch/x86/kernel/Makefile_32   |    1 
 arch/x86/kernel/Makefile_64   |    2 +
 arch/x86/kernel/test_rodata.c |   65 ++++++++++++++++++++++++++++++++++++++++++
 arch/x86/mm/init_32.c         |    3 +
 arch/x86/mm/init_64.c         |    3 +
 6 files changed, 82 insertions(+)

Index: linux-2.6.24-rc8/arch/x86/Kconfig.debug
===================================================================
--- linux-2.6.24-rc8.orig/arch/x86/Kconfig.debug
+++ linux-2.6.24-rc8/arch/x86/Kconfig.debug
@@ -57,6 +57,14 @@ config DEBUG_RODATA
          portion of the kernel code won't be covered by a 2MB TLB anymore.
          If in doubt, say "N".
 
+config DEBUG_RODATA_TEST
+       tristate "Testcase for the DEBUG_RODATA feature"
+       depends on DEBUG_RODATA && m
+       help
+         This option enables a testcase for the DEBUG_RODATA
+         feature as well as for the change_page_attr() infrastructure.
+         If in doubt, say "N"
+
 config 4KSTACKS
        bool "Use 4Kb for kernel stacks instead of 8Kb"
        depends on DEBUG_KERNEL
Index: linux-2.6.24-rc8/arch/x86/mm/init_32.c
===================================================================
--- linux-2.6.24-rc8.orig/arch/x86/mm/init_32.c
+++ linux-2.6.24-rc8/arch/x86/mm/init_32.c
@@ -790,6 +790,9 @@ static int noinline do_test_wp_bit(void)
 
 #ifdef CONFIG_DEBUG_RODATA
 
+const int rodata_test_data;
+EXPORT_SYMBOL_GPL(rodata_test_data);
+
 void mark_rodata_ro(void)
 {
        unsigned long start = PFN_ALIGN(_text);
Index: linux-2.6.24-rc8/arch/x86/mm/init_64.c
===================================================================
--- linux-2.6.24-rc8.orig/arch/x86/mm/init_64.c
+++ linux-2.6.24-rc8/arch/x86/mm/init_64.c
@@ -590,6 +590,9 @@ void free_initmem(void)
 
 #ifdef CONFIG_DEBUG_RODATA
 
+const int rodata_test_data = 5;
+EXPORT_SYMBOL_GPL(rodata_test_data);
+
 void mark_rodata_ro(void)
 {
        unsigned long start = (unsigned long)_stext, end;
Index: linux-2.6.24-rc8/arch/x86/kernel/Makefile_64
===================================================================
--- linux-2.6.24-rc8.orig/arch/x86/kernel/Makefile_64
+++ linux-2.6.24-rc8/arch/x86/kernel/Makefile_64
@@ -39,6 +39,8 @@ obj-$(CONFIG_AUDIT)           += audit_64.o
 obj-$(CONFIG_MODULES)          += module_64.o
 obj-$(CONFIG_PCI)              += early-quirks.o
 
+obj-$(CONFIG_DEBUG_RODATA_TEST)        += test_rodata.o
+
 obj-y                          += topology.o
 obj-y                          += pcspeaker.o
 
Index: linux-2.6.24-rc8/arch/x86/kernel/test_rodata.c
===================================================================
--- /dev/null
+++ linux-2.6.24-rc8/arch/x86/kernel/test_rodata.c
@@ -0,0 +1,65 @@
+#include <linux/module.h>
+
+
+extern int rodata_test_data;
+
+int rodata_test_init(void)
+{
+       unsigned long result;
+       /* 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)\n");
+               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])\n"
+               "       mov %[zero], %[rslt]\n"
+               "1:\n"
+               ".section .fixup,\"ax\"\n"
+               "2:     jmp 1b\n"
+               ".previous\n"
+               ".section __ex_table,\"a\"\n"
+               "       .align 8\n"
+               "       .quad 0b,2b\n"
+               ".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\n");
+               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)\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+void rodata_test_exit(void)
+{
+}
+
+module_init(rodata_test_init);
+module_exit(rodata_test_exit);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Testcase for the DEBUG_RODATA infrastructure");
+MODULE_AUTHOR("Arjan van de Ven <[EMAIL PROTECTED]>");
Index: linux-2.6.24-rc8/arch/x86/kernel/Makefile_32
===================================================================
--- linux-2.6.24-rc8.orig/arch/x86/kernel/Makefile_32
+++ linux-2.6.24-rc8/arch/x86/kernel/Makefile_32
@@ -42,6 +42,7 @@ obj-$(CONFIG_EARLY_PRINTK)    += early_prin
 obj-$(CONFIG_HPET_TIMER)       += hpet.o
 obj-$(CONFIG_K8_NB)            += k8.o
 obj-$(CONFIG_MGEODE_LX)                += geode_32.o mfgpt_32.o
+obj-$(CONFIG_DEBUG_RODATA_TEST)        += test_rodata.o
 
 obj-$(CONFIG_VMI)              += vmi_32.o vmiclock_32.o
 obj-$(CONFIG_PARAVIRT)         += paravirt_32.o

-- 
If you want to reach me at my work email, use [EMAIL PROTECTED]
For development, discussion and tips for power savings, 
visit http://www.lesswatts.org
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to