]> xenbits.xensource.com Git - people/liuw/xen.git/commitdiff
x86: disable CR0.WP while applying alternatives
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 25 Feb 2016 12:06:16 +0000 (13:06 +0100)
committerWei Liu <wei.liu2@citrix.com>
Tue, 15 Mar 2016 16:32:30 +0000 (16:32 +0000)
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 <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/alternative.c

index 9d54df1e52f9921a6e65a405d568e272b5f7c59b..0a0ce156e7a7463ded4b36c6cd7fc3b3ecb84ba0 100644 (file)
@@ -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)