ia64/xen-unstable

changeset 16804:8101b65014e8

minios: set text and rodata read-only, free unused pages 0 and 1
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jan 18 15:22:17 2008 +0000 (2008-01-18)
parents 62fc84adc8ed
children 2d6a0ee25f2a
files extras/mini-os/Makefile extras/mini-os/arch/x86/minios-x86_32.lds extras/mini-os/arch/x86/minios-x86_64.lds extras/mini-os/arch/x86/mm.c extras/mini-os/include/x86/arch_mm.h
line diff
     1.1 --- a/extras/mini-os/Makefile	Fri Jan 18 13:43:26 2008 +0000
     1.2 +++ b/extras/mini-os/Makefile	Fri Jan 18 15:22:17 2008 +0000
     1.3 @@ -53,7 +53,7 @@ include minios.mk
     1.4  # Define some default flags for linking.
     1.5  LDLIBS := 
     1.6  LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
     1.7 -LDFLAGS_FINAL := -N -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
     1.8 +LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
     1.9  
    1.10  # Prefix for global API names. All other symbols are localised before
    1.11  # linking with EXTRA_OBJS.
     2.1 --- a/extras/mini-os/arch/x86/minios-x86_32.lds	Fri Jan 18 13:43:26 2008 +0000
     2.2 +++ b/extras/mini-os/arch/x86/minios-x86_32.lds	Fri Jan 18 15:22:17 2008 +0000
     2.3 @@ -13,6 +13,8 @@ SECTIONS
     2.4    _etext = .;			/* End of text section */
     2.5  
     2.6    .rodata : { *(.rodata) *(.rodata.*) }
     2.7 +  . = ALIGN(4096);
     2.8 +  _erodata = .;
     2.9  
    2.10    .data : {			/* Data */
    2.11  	*(.data)
     3.1 --- a/extras/mini-os/arch/x86/minios-x86_64.lds	Fri Jan 18 13:43:26 2008 +0000
     3.2 +++ b/extras/mini-os/arch/x86/minios-x86_64.lds	Fri Jan 18 15:22:17 2008 +0000
     3.3 @@ -13,6 +13,8 @@ SECTIONS
     3.4    _etext = .;			/* End of text section */
     3.5  
     3.6    .rodata : { *(.rodata) *(.rodata.*) }
     3.7 +  . = ALIGN(4096);
     3.8 +  _erodata = .;
     3.9  
    3.10    .data : {			/* Data */
    3.11  	*(.data)
     4.1 --- a/extras/mini-os/arch/x86/mm.c	Fri Jan 18 13:43:26 2008 +0000
     4.2 +++ b/extras/mini-os/arch/x86/mm.c	Fri Jan 18 15:22:17 2008 +0000
     4.3 @@ -40,6 +40,7 @@
     4.4  #include <types.h>
     4.5  #include <lib.h>
     4.6  #include <xmalloc.h>
     4.7 +#include <xen/memory.h>
     4.8  
     4.9  #ifdef MM_DEBUG
    4.10  #define DEBUG(_f, _a...) \
    4.11 @@ -270,12 +271,73 @@ void build_pagetable(unsigned long *star
    4.12          start_address += PAGE_SIZE;
    4.13      }
    4.14  
    4.15 -    if (HYPERVISOR_update_va_mapping(0, (pte_t) {}, UVMF_INVLPG))
    4.16 -        printk("Unable to unmap page 0\n");
    4.17 -
    4.18      *start_pfn = pt_pfn;
    4.19  }
    4.20  
    4.21 +extern void shared_info;
    4.22 +static void set_readonly(void *text, void *etext)
    4.23 +{
    4.24 +    unsigned long start_address = ((unsigned long) text + PAGE_SIZE - 1) & PAGE_MASK;
    4.25 +    unsigned long end_address = (unsigned long) etext;
    4.26 +    static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
    4.27 +    pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
    4.28 +    unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
    4.29 +    unsigned long offset;
    4.30 +    int count = 0;
    4.31 +
    4.32 +    printk("setting %p-%p readonly\n", text, etext);
    4.33 +
    4.34 +    while (start_address + PAGE_SIZE <= end_address) {
    4.35 +        tab = (pgentry_t *)start_info.pt_base;
    4.36 +        mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
    4.37 +
    4.38 +#if defined(__x86_64__)
    4.39 +        offset = l4_table_offset(start_address);
    4.40 +        page = tab[offset];
    4.41 +        mfn = pte_to_mfn(page);
    4.42 +        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
    4.43 +#endif
    4.44 +#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
    4.45 +        offset = l3_table_offset(start_address);
    4.46 +        page = tab[offset];
    4.47 +        mfn = pte_to_mfn(page);
    4.48 +        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
    4.49 +#endif
    4.50 +        offset = l2_table_offset(start_address);        
    4.51 +        page = tab[offset];
    4.52 +        mfn = pte_to_mfn(page);
    4.53 +        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
    4.54 +
    4.55 +        offset = l1_table_offset(start_address);
    4.56 +
    4.57 +	if (start_address != (unsigned long)&shared_info) {
    4.58 +	    mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
    4.59 +	    mmu_updates[count].val = tab[offset] & ~_PAGE_RW;
    4.60 +	    count++;
    4.61 +	} else
    4.62 +	    printk("skipped %p\n", start_address);
    4.63 +
    4.64 +        start_address += PAGE_SIZE;
    4.65 +
    4.66 +        if (count == L1_PAGETABLE_ENTRIES || start_address + PAGE_SIZE > end_address)
    4.67 +        {
    4.68 +            if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0)
    4.69 +            {
    4.70 +                printk("PTE could not be updated\n");
    4.71 +                do_exit();
    4.72 +            }
    4.73 +            count = 0;
    4.74 +        }
    4.75 +    }
    4.76 +
    4.77 +    {
    4.78 +	mmuext_op_t op = {
    4.79 +	    .cmd = MMUEXT_TLB_FLUSH_ALL,
    4.80 +	};
    4.81 +	int count;
    4.82 +	HYPERVISOR_mmuext_op(&op, 1, &count, DOMID_SELF);
    4.83 +    }
    4.84 +}
    4.85  
    4.86  void mem_test(unsigned long *start_add, unsigned long *end_add)
    4.87  {
    4.88 @@ -405,6 +467,23 @@ void *map_frames(unsigned long *f, unsig
    4.89      }
    4.90  }
    4.91  
    4.92 +static void clear_bootstrap(void)
    4.93 +{
    4.94 +    struct xen_memory_reservation reservation;
    4.95 +    xen_pfn_t mfns[] = { virt_to_mfn(0), virt_to_mfn(&shared_info) };
    4.96 +    int n = sizeof(mfns)/sizeof(*mfns);
    4.97 +    pte_t nullpte = { };
    4.98 +
    4.99 +    if (HYPERVISOR_update_va_mapping(0, nullpte, UVMF_INVLPG))
   4.100 +	printk("Unable to unmap page 0\n");
   4.101 +
   4.102 +    set_xen_guest_handle(reservation.extent_start, mfns);
   4.103 +    reservation.nr_extents = n;
   4.104 +    reservation.extent_order = 0;
   4.105 +    reservation.domid = DOMID_SELF;
   4.106 +    if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation) != n)
   4.107 +	printk("Unable to free bootstrap pages\n");
   4.108 +}
   4.109  
   4.110  void arch_init_p2m(unsigned long max_pfn)
   4.111  {
   4.112 @@ -455,6 +534,7 @@ void arch_init_mm(unsigned long* start_p
   4.113  
   4.114      printk("  _text:        %p\n", &_text);
   4.115      printk("  _etext:       %p\n", &_etext);
   4.116 +    printk("  _erodata:     %p\n", &_erodata);
   4.117      printk("  _edata:       %p\n", &_edata);
   4.118      printk("  stack start:  %p\n", stack);
   4.119      printk("  _end:         %p\n", &_end);
   4.120 @@ -468,8 +548,9 @@ void arch_init_mm(unsigned long* start_p
   4.121      printk("  max_pfn:      %lx\n", max_pfn);
   4.122  
   4.123      build_pagetable(&start_pfn, &max_pfn);
   4.124 +    clear_bootstrap();
   4.125 +    set_readonly(&_text, &_erodata);
   4.126  
   4.127      *start_pfn_p = start_pfn;
   4.128      *max_pfn_p = max_pfn;
   4.129  }
   4.130 -
     5.1 --- a/extras/mini-os/include/x86/arch_mm.h	Fri Jan 18 13:43:26 2008 +0000
     5.2 +++ b/extras/mini-os/include/x86/arch_mm.h	Fri Jan 18 15:22:17 2008 +0000
     5.3 @@ -189,7 +189,7 @@ typedef unsigned long maddr_t;
     5.4  #endif
     5.5  
     5.6  extern unsigned long *phys_to_machine_mapping;
     5.7 -extern char _text, _etext, _edata, _end;
     5.8 +extern char _text, _etext, _erodata, _edata, _end;
     5.9  #define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
    5.10  static __inline__ maddr_t phys_to_machine(paddr_t phys)
    5.11  {