All of lore.kernel.org
 help / color / mirror / Atom feed
From: Samuel Thibault <samuel.thibault@eu.citrix.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] minios: set text and rodata read-only, free unused pages 0 and 1
Date: Fri, 18 Jan 2008 14:06:23 +0000	[thread overview]
Message-ID: <20080118140623.GC24773@implementation.uk.xensource.com> (raw)

minios: set text and rodata read-only, free unused pages 0 and 1

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>

diff -r b0e2c382ffb2 extras/mini-os/Makefile
--- a/extras/mini-os/Makefile	Thu Jan 17 16:22:30 2008 +0000
+++ b/extras/mini-os/Makefile	Fri Jan 18 14:04:05 2008 +0000
@@ -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.
diff -r b0e2c382ffb2 extras/mini-os/arch/x86/minios-x86_32.lds
--- a/extras/mini-os/arch/x86/minios-x86_32.lds	Thu Jan 17 16:22:30 2008 +0000
+++ b/extras/mini-os/arch/x86/minios-x86_32.lds	Fri Jan 18 14:04:05 2008 +0000
@@ -13,6 +13,8 @@ SECTIONS
   _etext = .;			/* End of text section */
 
   .rodata : { *(.rodata) *(.rodata.*) }
+  . = ALIGN(4096);
+  _erodata = .;
 
   .data : {			/* Data */
 	*(.data)
diff -r b0e2c382ffb2 extras/mini-os/arch/x86/minios-x86_64.lds
--- a/extras/mini-os/arch/x86/minios-x86_64.lds	Thu Jan 17 16:22:30 2008 +0000
+++ b/extras/mini-os/arch/x86/minios-x86_64.lds	Fri Jan 18 14:04:05 2008 +0000
@@ -13,6 +13,8 @@ SECTIONS
   _etext = .;			/* End of text section */
 
   .rodata : { *(.rodata) *(.rodata.*) }
+  . = ALIGN(4096);
+  _erodata = .;
 
   .data : {			/* Data */
 	*(.data)
diff -r b0e2c382ffb2 extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c	Thu Jan 17 16:22:30 2008 +0000
+++ b/extras/mini-os/arch/x86/mm.c	Fri Jan 18 14:04:05 2008 +0000
@@ -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 *star
         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, unsig
     }
 }
 
+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_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_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;
 }
-
diff -r b0e2c382ffb2 extras/mini-os/include/x86/arch_mm.h
--- a/extras/mini-os/include/x86/arch_mm.h	Thu Jan 17 16:22:30 2008 +0000
+++ b/extras/mini-os/include/x86/arch_mm.h	Fri Jan 18 14:04:05 2008 +0000
@@ -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)
 {

                 reply	other threads:[~2008-01-18 14:06 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080118140623.GC24773@implementation.uk.xensource.com \
    --to=samuel.thibault@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.