From: Andrew Cooper Date: Thu, 25 Feb 2016 12:06:16 +0000 (+0100) Subject: x86: disable CR0.WP while applying alternatives X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~1680 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=36c672b559d35e088b181c67538b1ed5bacb0da5;p=xen.git x86: disable CR0.WP while applying alternatives In preparation for marking .text as read-only, care needs to be taken not to fault while applying alternatives. Swapping back to RW mappings is a possibility, but would require additional TLB management. A temporary disabling of CR0.WP is cleaner. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich --- diff --git a/xen/arch/x86/alternative.c b/xen/arch/x86/alternative.c index 9d54df1e52..0a0ce156e7 100644 --- a/xen/arch/x86/alternative.c +++ b/xen/arch/x86/alternative.c @@ -147,11 +147,15 @@ static void __init apply_alternatives(struct alt_instr *start, struct alt_instr struct alt_instr *a; u8 *instr, *replacement; u8 insnbuf[MAX_PATCH_LEN]; + unsigned long cr0 = read_cr0(); ASSERT(!local_irq_is_enabled()); printk(KERN_INFO "alt table %p -> %p\n", start, end); + /* Disable WP to allow application of alternatives to read-only pages. */ + write_cr0(cr0 & ~X86_CR0_WP); + /* * The scan order should be from start to end. A later scanned * alternative code can overwrite a previous scanned alternative code. @@ -181,6 +185,9 @@ static void __init apply_alternatives(struct alt_instr *start, struct alt_instr a->instrlen - a->replacementlen); text_poke_early(instr, insnbuf, a->instrlen); } + + /* Reinstate WP. */ + write_cr0(cr0); } void __init alternative_instructions(void)