]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/mini-os.git/commitdiff
minios: set text and rodata read-only, free unused pages 0 and 1
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 18 Jan 2008 15:22:17 +0000 (15:22 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 18 Jan 2008 15:22:17 +0000 (15:22 +0000)
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Makefile
arch/x86/minios-x86_32.lds
arch/x86/minios-x86_64.lds
arch/x86/mm.c
include/x86/arch_mm.h

index 26fe5ca8f69ae489b8dd9a1d95d1d8181243251b..a8670fbd45ff2f5ed18083330ed559c22da1df4e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -53,7 +53,7 @@ include minios.mk
 # Define some default flags for linking.
 LDLIBS := 
 LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
-LDFLAGS_FINAL := -N -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
+LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
 
 # Prefix for global API names. All other symbols are localised before
 # linking with EXTRA_OBJS.
index 09d84ad96f71abf16efbc497539700086dc44849..08ebe143287ed309dfb0d88a24d30cc6eeb465ff 100644 (file)
@@ -13,6 +13,8 @@ SECTIONS
   _etext = .;                  /* End of text section */
 
   .rodata : { *(.rodata) *(.rodata.*) }
+  . = ALIGN(4096);
+  _erodata = .;
 
   .data : {                    /* Data */
        *(.data)
index d30850a595f6872533d51bf7f4117b870ec2bf53..345c38640ccdfeb6825bfd5eb44ed46620357578 100644 (file)
@@ -13,6 +13,8 @@ SECTIONS
   _etext = .;                  /* End of text section */
 
   .rodata : { *(.rodata) *(.rodata.*) }
+  . = ALIGN(4096);
+  _erodata = .;
 
   .data : {                    /* Data */
        *(.data)
index 70143b3e1a2168ae00ff8c1e0a445ae774f98cfb..78e6c7638b78317215d4d9f08224f8d1b1aa87f9 100644 (file)
@@ -40,6 +40,7 @@
 #include <types.h>
 #include <lib.h>
 #include <xmalloc.h>
+#include <xen/memory.h>
 
 #ifdef MM_DEBUG
 #define DEBUG(_f, _a...) \
@@ -270,12 +271,73 @@ void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
         start_address += PAGE_SIZE;
     }
 
-    if (HYPERVISOR_update_va_mapping(0, (pte_t) {}, UVMF_INVLPG))
-        printk("Unable to unmap page 0\n");
-
     *start_pfn = pt_pfn;
 }
 
+extern void shared_info;
+static void set_readonly(void *text, void *etext)
+{
+    unsigned long start_address = ((unsigned long) text + PAGE_SIZE - 1) & PAGE_MASK;
+    unsigned long end_address = (unsigned long) etext;
+    static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
+    pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
+    unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
+    unsigned long offset;
+    int count = 0;
+
+    printk("setting %p-%p readonly\n", text, etext);
+
+    while (start_address + PAGE_SIZE <= end_address) {
+        tab = (pgentry_t *)start_info.pt_base;
+        mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
+
+#if defined(__x86_64__)
+        offset = l4_table_offset(start_address);
+        page = tab[offset];
+        mfn = pte_to_mfn(page);
+        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
+#endif
+#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
+        offset = l3_table_offset(start_address);
+        page = tab[offset];
+        mfn = pte_to_mfn(page);
+        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
+#endif
+        offset = l2_table_offset(start_address);        
+        page = tab[offset];
+        mfn = pte_to_mfn(page);
+        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
+
+        offset = l1_table_offset(start_address);
+
+       if (start_address != (unsigned long)&shared_info) {
+           mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
+           mmu_updates[count].val = tab[offset] & ~_PAGE_RW;
+           count++;
+       } else
+           printk("skipped %p\n", start_address);
+
+        start_address += PAGE_SIZE;
+
+        if (count == L1_PAGETABLE_ENTRIES || start_address + PAGE_SIZE > end_address)
+        {
+            if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0)
+            {
+                printk("PTE could not be updated\n");
+                do_exit();
+            }
+            count = 0;
+        }
+    }
+
+    {
+       mmuext_op_t op = {
+           .cmd = MMUEXT_TLB_FLUSH_ALL,
+       };
+       int count;
+       HYPERVISOR_mmuext_op(&op, 1, &count, DOMID_SELF);
+    }
+}
 
 void mem_test(unsigned long *start_add, unsigned long *end_add)
 {
@@ -405,6 +467,23 @@ void *map_frames(unsigned long *f, unsigned long n)
     }
 }
 
+static void clear_bootstrap(void)
+{
+    struct xen_memory_reservation reservation;
+    xen_pfn_t mfns[] = { virt_to_mfn(0), virt_to_mfn(&shared_info) };
+    int n = sizeof(mfns)/sizeof(*mfns);
+    pte_t nullpte = { };
+
+    if (HYPERVISOR_update_va_mapping(0, nullpte, UVMF_INVLPG))
+       printk("Unable to unmap page 0\n");
+
+    set_xen_guest_handle(reservation.extent_start, mfns);
+    reservation.nr_extents = n;
+    reservation.extent_order = 0;
+    reservation.domid = DOMID_SELF;
+    if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation) != n)
+       printk("Unable to free bootstrap pages\n");
+}
 
 void arch_init_p2m(unsigned long max_pfn)
 {
@@ -455,6 +534,7 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
 
     printk("  _text:        %p\n", &_text);
     printk("  _etext:       %p\n", &_etext);
+    printk("  _erodata:     %p\n", &_erodata);
     printk("  _edata:       %p\n", &_edata);
     printk("  stack start:  %p\n", stack);
     printk("  _end:         %p\n", &_end);
@@ -468,8 +548,9 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
     printk("  max_pfn:      %lx\n", max_pfn);
 
     build_pagetable(&start_pfn, &max_pfn);
+    clear_bootstrap();
+    set_readonly(&_text, &_erodata);
 
     *start_pfn_p = start_pfn;
     *max_pfn_p = max_pfn;
 }
-
index ddf132f1be7649df2ed10dca6246d6e41e50e200..5c7f06147190caa60f010d94fa5d5e5311cff624 100644 (file)
@@ -189,7 +189,7 @@ typedef unsigned long maddr_t;
 #endif
 
 extern unsigned long *phys_to_machine_mapping;
-extern char _text, _etext, _edata, _end;
+extern char _text, _etext, _erodata, _edata, _end;
 #define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
 static __inline__ maddr_t phys_to_machine(paddr_t phys)
 {