Fix x86/64 pagetable initialisation so that only things that
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 24 Aug 2005 15:22:44 +0000 (15:22 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 24 Aug 2005 15:22:44 +0000 (15:22 +0000)
need to be are mapped read-only.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c
xen/arch/x86/mm.c

index f4c35e4a6bb7ab94237fc8422aa437f8b33a9c82..0618209c9ff3d092c6084cd5dd710b390d99e058 100644 (file)
@@ -441,6 +441,31 @@ static inline void __set_pte(pte_t *dst, pte_t val)
        *dst = val;
 }
 
+static inline int make_readonly(unsigned long paddr)
+{
+    int readonly = 0;
+
+    /* Make new page tables read-only. */
+    if ((paddr < ((table_start << PAGE_SHIFT) + tables_space)) &&
+        (paddr >= (table_start << PAGE_SHIFT)))
+        readonly = 1;
+
+    /* Make old page tables read-only. */
+    if ((paddr < ((xen_start_info.pt_base - __START_KERNEL_map) +
+                  (xen_start_info.nr_pt_frames << PAGE_SHIFT))) &&
+        (paddr >= (xen_start_info.pt_base - __START_KERNEL_map)))
+        readonly = 1;
+
+    /*
+     * No need for writable mapping of kernel image. This also ensures that
+     * page and descriptor tables embedded inside don't have writable mappings.
+     */
+    if ((paddr >= __pa_symbol(&_text)) && (paddr < __pa_symbol(&_end)))
+        readonly = 1;
+
+    return readonly;
+}
+
 void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
 { 
         long i, j, k; 
@@ -477,9 +502,7 @@ void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
                         pte = alloc_low_page(&pte_phys);
                         pte_save = pte;
                         for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += PTE_SIZE) {
-                                if (paddr < (table_start << PAGE_SHIFT) 
-                                    + tables_space)
-                                {
+                                if (make_readonly(paddr)) {
                                         __set_pte(pte, 
                                                 __pte(paddr | (_KERNPG_TABLE & ~_PAGE_RW)));
                                         continue;
index 476db18885a6cd03f165b571973d22211757617a..0141937ad219763adc56d7b5731bdbdfbb77be69 100644 (file)
@@ -1449,8 +1449,10 @@ int get_page_type(struct pfn_info *page, unsigned long type)
                     if ( ((x & PGT_type_mask) != PGT_l2_page_table) ||
                          ((type & PGT_type_mask) != PGT_l1_page_table) )
                         MEM_LOG("Bad type (saw %" PRtype_info
-                                "!= exp %" PRtype_info ") for pfn %lx",
-                                x, type, page_to_pfn(page));
+                                "!= exp %" PRtype_info ") "
+                                "for mfn %lx (pfn %x)",
+                                x, type, page_to_pfn(page),
+                                machine_to_phys_mapping[page_to_pfn(page)]);
                     return 0;
                 }
                 else if ( (x & PGT_va_mask) == PGT_va_mutable )