--- zzzz-none-000/linux-2.6.19.2/arch/i386/kernel/alternative.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5504/linux-2.6.19.2/arch/i386/kernel/alternative.c 2007-01-19 14:42:56.000000000 +0000 @@ -3,6 +3,7 @@ #include #include #include +#include static int no_replacement = 0; static int smp_alt_once = 0; @@ -142,6 +143,12 @@ u8 *instr; int diff, i, k; +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; + + pax_open_kernel(cr0); +#endif + DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); for (a = start; a < end; a++) { BUG_ON(a->replacementlen > a->instrlen); @@ -156,16 +163,21 @@ __FUNCTION__, a->instr, instr); } #endif - memcpy(instr, a->replacement, a->replacementlen); + memcpy(instr + __KERNEL_TEXT_OFFSET, a->replacement, a->replacementlen); diff = a->instrlen - a->replacementlen; /* Pad the rest with nops */ for (i = a->replacementlen; diff > 0; diff -= k, i += k) { k = diff; if (k > ASM_NOP_MAX) k = ASM_NOP_MAX; - memcpy(a->instr + i, noptable[k], k); + memcpy(a->instr + i + __KERNEL_TEXT_OFFSET, noptable[k], k); } } + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + } #ifdef CONFIG_SMP @@ -174,50 +186,96 @@ { struct alt_instr *a; +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; + + pax_open_kernel(cr0); +#endif + DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end); for (a = start; a < end; a++) { memcpy(a->replacement + a->replacementlen, - a->instr, + a->instr + __KERNEL_TEXT_OFFSET, a->instrlen); } + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + } static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end) { struct alt_instr *a; +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; + + pax_open_kernel(cr0); +#endif + for (a = start; a < end; a++) { - memcpy(a->instr, + memcpy(a->instr + __KERNEL_TEXT_OFFSET, a->replacement + a->replacementlen, a->instrlen); } + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + } static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) { - u8 **ptr; + u8 *ptr; + +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; - for (ptr = start; ptr < end; ptr++) { - if (*ptr < text) + pax_open_kernel(cr0); +#endif + + for (; start < end; start++) { + ptr = *start + __KERNEL_TEXT_OFFSET; + if (ptr < text) continue; - if (*ptr > text_end) + if (ptr > text_end) continue; - **ptr = 0xf0; /* lock prefix */ + *ptr = 0xf0; /* lock prefix */ }; + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + } static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) { unsigned char **noptable = find_nop_table(); - u8 **ptr; + u8 *ptr; + +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; + + pax_open_kernel(cr0); +#endif - for (ptr = start; ptr < end; ptr++) { - if (*ptr < text) + for (; start < end; start++) { + ptr = *start + __KERNEL_TEXT_OFFSET; + if (ptr < text) continue; - if (*ptr > text_end) + if (ptr > text_end) continue; - **ptr = noptable[1][0]; + *ptr = noptable[1][0]; }; + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + } struct smp_alt_module {