ia64/xen-unstable

changeset 16888:76601c290fa9

x86: First 1MB of memory should be mapped with 4kB mappings to avoid
conflict with fixed-range MTRRs. While there, we now map the VGA hole
as uncacheable.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jan 25 16:02:20 2008 +0000 (2008-01-25)
parents 923f2f736507
children c360bb765b25
files xen/arch/x86/boot/head.S xen/arch/x86/mm.c xen/arch/x86/setup.c xen/arch/x86/x86_32/mm.c
line diff
     1.1 --- a/xen/arch/x86/boot/head.S	Fri Jan 25 13:42:36 2008 +0000
     1.2 +++ b/xen/arch/x86/boot/head.S	Fri Jan 25 16:02:20 2008 +0000
     1.3 @@ -126,7 +126,7 @@ 1:      mov     %eax,(%edi)
     1.4          /* Initialise L3 xen-map page directory entry. */
     1.5          mov     $(sym_phys(l2_xenmap)+7),%eax
     1.6          mov     %eax,sym_phys(l3_xenmap) + (50*8)
     1.7 -        /* Hook indentity-map and xen-map L3 tables into PML4. */
     1.8 +        /* Hook identity-map and xen-map L3 tables into PML4. */
     1.9          mov     $(sym_phys(l3_identmap)+7),%eax
    1.10          mov     %eax,sym_phys(idle_pg_table) + (  0*8) /* PML4[  0]: 1:1 map */
    1.11          mov     %eax,sym_phys(idle_pg_table) + (262*8) /* PML4[262]: 1:1 map */
    1.12 @@ -162,6 +162,40 @@ 1:      stosl   /* low mappings cover up
    1.13          jne     1b
    1.14  #endif
    1.15  
    1.16 +        /* Initialize 4kB mappings of first 2MB or 4MB of memory. */
    1.17 +        mov     $sym_phys(l1_identmap),%edi
    1.18 +        mov     $0x263,%eax                  /* PRESENT+RW+A+D+SMALL_PAGES */
    1.19 +#if defined(__x86_64__)
    1.20 +        or      $0x100,%eax                  /* GLOBAL */
    1.21 +#endif
    1.22 +        xor     %ecx,%ecx
    1.23 +1:      stosl
    1.24 +#if CONFIG_PAGING_LEVELS >= 3
    1.25 +        add     $4,%edi
    1.26 +#endif
    1.27 +        add     $PAGE_SIZE,%eax
    1.28 +        inc     %ecx
    1.29 +        /* VGA hole (0xa0000-0xc0000) should be mapped UC. */
    1.30 +        cmp     $0xa0,%ecx
    1.31 +        jne     2f
    1.32 +        or      $0x10,%eax                   /* +PCD */
    1.33 +2:      cmp     $0xc0,%ecx
    1.34 +        jne     2f
    1.35 +        and     $~0x10,%eax                  /* -PCD */
    1.36 +2:      cmp     $L1_PAGETABLE_ENTRIES,%ecx
    1.37 +        jne     1b
    1.38 +        sub     $(PAGE_SIZE-0x63),%edi
    1.39 +#if defined(__x86_64__)
    1.40 +        mov     %edi,sym_phys(l2_identmap)
    1.41 +        mov     %edi,sym_phys(l2_xenmap)
    1.42 +#elif defined(CONFIG_X86_PAE)
    1.43 +        mov     %edi,sym_phys(idle_pg_table_l2)
    1.44 +        mov     %edi,sym_phys(idle_pg_table_l2) + (__PAGE_OFFSET>>18)
    1.45 +#else
    1.46 +        mov     %edi,sym_phys(idle_pg_table)
    1.47 +        mov     %edi,sym_phys(idle_pg_table) + (__PAGE_OFFSET>>20)
    1.48 +#endif
    1.49 +
    1.50          /* Copy bootstrap trampoline to low memory, below 1MB. */
    1.51          mov     $sym_phys(trampoline_start),%esi
    1.52          mov     $bootsym_phys(trampoline_start),%edi
     2.1 --- a/xen/arch/x86/mm.c	Fri Jan 25 13:42:36 2008 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Fri Jan 25 16:02:20 2008 +0000
     2.3 @@ -113,6 +113,15 @@
     2.4  #include <xsm/xsm.h>
     2.5  #include <xen/trace.h>
     2.6  
     2.7 +/*
     2.8 + * Mapping of first 2 or 4 megabytes of memory. This is mapped with 4kB
     2.9 + * mappings to avoid type conflicts with fixed-range MTRRs covering the
    2.10 + * lowest megabyte of physical memory. In any case the VGA hole should be
    2.11 + * mapped with type UC.
    2.12 + */
    2.13 +l1_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
    2.14 +    l1_identmap[L1_PAGETABLE_ENTRIES];
    2.15 +
    2.16  #define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
    2.17  
    2.18  /*
    2.19 @@ -3912,16 +3921,18 @@ void __set_fixmap(
    2.20  
    2.21  void memguard_init(void)
    2.22  {
    2.23 +    unsigned long start = max_t(unsigned long, xen_phys_start, 1UL << 20);
    2.24      map_pages_to_xen(
    2.25 -        (unsigned long)__va(xen_phys_start),
    2.26 -        xen_phys_start >> PAGE_SHIFT,
    2.27 -        (xenheap_phys_end - xen_phys_start) >> PAGE_SHIFT,
    2.28 +        (unsigned long)__va(start),
    2.29 +        start >> PAGE_SHIFT,
    2.30 +        (xenheap_phys_end - start) >> PAGE_SHIFT,
    2.31          __PAGE_HYPERVISOR|MAP_SMALL_PAGES);
    2.32  #ifdef __x86_64__
    2.33 +    BUG_ON(start != xen_phys_start);
    2.34      map_pages_to_xen(
    2.35          XEN_VIRT_START,
    2.36 -        xen_phys_start >> PAGE_SHIFT,
    2.37 -        (__pa(&_end) + PAGE_SIZE - 1 - xen_phys_start) >> PAGE_SHIFT,
    2.38 +        start >> PAGE_SHIFT,
    2.39 +        (__pa(&_end) + PAGE_SIZE - 1 - start) >> PAGE_SHIFT,
    2.40          __PAGE_HYPERVISOR|MAP_SMALL_PAGES);
    2.41  #endif
    2.42  }
     3.1 --- a/xen/arch/x86/setup.c	Fri Jan 25 13:42:36 2008 +0000
     3.2 +++ b/xen/arch/x86/setup.c	Fri Jan 25 16:02:20 2008 +0000
     3.3 @@ -258,8 +258,10 @@ static void __init srat_detect_node(int 
     3.4  static void __init bootstrap_map(unsigned long start, unsigned long end)
     3.5  {
     3.6      unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
     3.7 -    start = start & ~mask;
     3.8 +    start = max_t(unsigned long, start & ~mask, 16UL << 20);
     3.9      end   = (end + mask) & ~mask;
    3.10 +    if ( start >= end )
    3.11 +        return;
    3.12      if ( end > BOOTSTRAP_DIRECTMAP_END )
    3.13          panic("Cannot access memory beyond end of "
    3.14                "bootstrap direct-map area\n");
    3.15 @@ -642,7 +644,7 @@ void __init __start_xen(unsigned long mb
    3.16              l4_pgentry_t *pl4e;
    3.17              l3_pgentry_t *pl3e;
    3.18              l2_pgentry_t *pl2e;
    3.19 -            int i, j;
    3.20 +            int i, j, k;
    3.21  
    3.22              /* Select relocation address. */
    3.23              e = (e - (opt_xenheap_megabytes << 20)) & ~mask;
    3.24 @@ -678,12 +680,25 @@ void __init __start_xen(unsigned long mb
    3.25                          continue;
    3.26                      *pl3e = l3e_from_intpte(l3e_get_intpte(*pl3e) +
    3.27                                              xen_phys_start);
    3.28 +                    pl2e = l3e_to_l2e(*pl3e);
    3.29 +                    for ( k = 0; k < L2_PAGETABLE_ENTRIES; k++, pl2e++ )
    3.30 +                    {
    3.31 +                        /* Not present, PSE, or already relocated? */
    3.32 +                        if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ||
    3.33 +                             (l2e_get_flags(*pl2e) & _PAGE_PSE) ||
    3.34 +                             (l2e_get_pfn(*pl2e) > 0x1000) )
    3.35 +                            continue;
    3.36 +                        *pl2e = l2e_from_intpte(l2e_get_intpte(*pl2e) +
    3.37 +                                                xen_phys_start);
    3.38 +                    }
    3.39                  }
    3.40              }
    3.41  
    3.42              /* The only data mappings to be relocated are in the Xen area. */
    3.43              pl2e = __va(__pa(l2_xenmap));
    3.44 -            for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++, pl2e++ )
    3.45 +            *pl2e++ = l2e_from_pfn(xen_phys_start >> PAGE_SHIFT,
    3.46 +                                   PAGE_HYPERVISOR | _PAGE_PSE);
    3.47 +            for ( i = 1; i < L2_PAGETABLE_ENTRIES; i++, pl2e++ )
    3.48              {
    3.49                  if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
    3.50                      continue;
     4.1 --- a/xen/arch/x86/x86_32/mm.c	Fri Jan 25 13:42:36 2008 +0000
     4.2 +++ b/xen/arch/x86/x86_32/mm.c	Fri Jan 25 16:02:20 2008 +0000
     4.3 @@ -38,6 +38,8 @@ l2_pgentry_t __attribute__ ((__section__
     4.4      idle_pg_table_l2[L2_PAGETABLE_ENTRIES];
     4.5  #endif
     4.6  
     4.7 +extern l1_pgentry_t l1_identmap[L1_PAGETABLE_ENTRIES];
     4.8 +
     4.9  unsigned int PAGE_HYPERVISOR         = __PAGE_HYPERVISOR;
    4.10  unsigned int PAGE_HYPERVISOR_NOCACHE = __PAGE_HYPERVISOR_NOCACHE;
    4.11  
    4.12 @@ -90,6 +92,8 @@ void __init paging_init(void)
    4.13                    (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT) )
    4.14                  l2e_add_flags(idle_pg_table_l2[l2_linear_offset(v)],
    4.15                                _PAGE_GLOBAL);
    4.16 +        for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
    4.17 +            l1e_add_flags(l1_identmap[i], _PAGE_GLOBAL);
    4.18      }
    4.19  
    4.20      /*
    4.21 @@ -150,6 +154,8 @@ void __init zap_low_mappings(l2_pgentry_
    4.22              l2e_write(&dom0_l2[i], l2e_empty());
    4.23  
    4.24      /* Now zap mappings in the idle pagetables. */
    4.25 +    BUG_ON(l2e_get_pfn(idle_pg_table_l2[0]) != virt_to_mfn(l1_identmap));
    4.26 +    l2e_write_atomic(&idle_pg_table_l2[0], l2e_empty());
    4.27      destroy_xen_mappings(0, HYPERVISOR_VIRT_START);
    4.28  
    4.29      flush_all(FLUSH_TLB_GLOBAL);