aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-01-18 15:22:17 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-01-18 15:22:17 +0000
commitc1ea56152af43af8fa0d6ead7ab22ebd065e63ae (patch)
tree14f1d475305f6cf5a116de14c78057edd0939b07
parent2c7a4f62dc6e21ebd25b64c09f249e7773cf1f59 (diff)
downloadxen-c1ea56152af43af8fa0d6ead7ab22ebd065e63ae.tar.gz
xen-c1ea56152af43af8fa0d6ead7ab22ebd065e63ae.tar.bz2
xen-c1ea56152af43af8fa0d6ead7ab22ebd065e63ae.zip
minios: set text and rodata read-only, free unused pages 0 and 1
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
-rw-r--r--extras/mini-os/Makefile2
-rw-r--r--extras/mini-os/arch/x86/minios-x86_32.lds2
-rw-r--r--extras/mini-os/arch/x86/minios-x86_64.lds2
-rw-r--r--extras/mini-os/arch/x86/mm.c89
-rw-r--r--extras/mini-os/include/x86/arch_mm.h2
5 files changed, 91 insertions, 6 deletions
diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile
index 26fe5ca8f6..a8670fbd45 100644
--- a/extras/mini-os/Makefile
+++ b/extras/mini-os/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.
diff --git a/extras/mini-os/arch/x86/minios-x86_32.lds b/extras/mini-os/arch/x86/minios-x86_32.lds
index 09d84ad96f..08ebe14328 100644
--- a/extras/mini-os/arch/x86/minios-x86_32.lds
+++ b/extras/mini-os/arch/x86/minios-x86_32.lds
@@ -13,6 +13,8 @@ SECTIONS
_etext = .; /* End of text section */
.rodata : { *(.rodata) *(.rodata.*) }
+ . = ALIGN(4096);
+ _erodata = .;
.data : { /* Data */
*(.data)
diff --git a/extras/mini-os/arch/x86/minios-x86_64.lds b/extras/mini-os/arch/x86/minios-x86_64.lds
index d30850a595..345c38640c 100644
--- a/extras/mini-os/arch/x86/minios-x86_64.lds
+++ b/extras/mini-os/arch/x86/minios-x86_64.lds
@@ -13,6 +13,8 @@ SECTIONS
_etext = .; /* End of text section */
.rodata : { *(.rodata) *(.rodata.*) }
+ . = ALIGN(4096);
+ _erodata = .;
.data : { /* Data */
*(.data)
diff --git a/extras/mini-os/arch/x86/mm.c b/extras/mini-os/arch/x86/mm.c
index 70143b3e1a..78e6c7638b 100644
--- a/extras/mini-os/arch/x86/mm.c
+++ b/extras/mini-os/arch/x86/mm.c
@@ -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;
}
-
diff --git a/extras/mini-os/include/x86/arch_mm.h b/extras/mini-os/include/x86/arch_mm.h
index ddf132f1be..5c7f061471 100644
--- a/extras/mini-os/include/x86/arch_mm.h
+++ b/extras/mini-os/include/x86/arch_mm.h
@@ -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)
{