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/