Samuel Thibault
2008-Jan-18 14:06 UTC
[Xen-devel] [PATCH] minios: set text and rodata read-only, free unused pages 0 and 1
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) { _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel