ia64/xen-unstable

changeset 4211:e4563b61d6d2

bitkeeper revision 1.1236.1.85 (423af065m4e0j4eXiTFvV-BrIlfC-A)

Linux 2.6 now always uses writable page tables (even SMP builds). Also
use native definitions for atomic read-modify-write operations on
ptes. Fixed instruction emulator in Xen.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Mar 18 15:14:45 2005 +0000 (2005-03-18)
parents 8f9f6106eaad
children 4dabdffc4a2a
files linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/page.h linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h tools/tests/test_x86_emulator.c xen/arch/x86/mm.c xen/arch/x86/x86_emulate.c xen/include/asm-x86/page.h xen/include/asm-x86/x86_32/page.h xen/include/asm-x86/x86_64/page.h
line diff
     1.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/page.h	Fri Mar 18 11:16:56 2005 +0000
     1.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/page.h	Fri Mar 18 15:14:45 2005 +0000
     1.3 @@ -116,17 +116,11 @@ static inline unsigned long pgd_val(pgd_
     1.4  }
     1.5  #define pgprot_val(x)	((x).pgprot)
     1.6  
     1.7 -static inline pte_t __pte(unsigned long x)
     1.8 -{
     1.9 -	if (x & 1) x = phys_to_machine(x);
    1.10 -	return ((pte_t) { (x) });
    1.11 -}
    1.12 +#define __pte(x) ({ unsigned long _x = (x); \
    1.13 +    (((_x)&1) ? ((pte_t) {phys_to_machine(_x)}) : ((pte_t) {(_x)})); })
    1.14  #define __pte_ma(x)	((pte_t) { (x) } )
    1.15 -static inline pgd_t __pgd(unsigned long x)
    1.16 -{
    1.17 -	if ((x & 1)) x = phys_to_machine(x);
    1.18 -	return ((pgd_t) { (x) });
    1.19 -}
    1.20 +#define __pgd(x) ({ unsigned long _x = (x); \
    1.21 +    (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
    1.22  #define __pgprot(x)	((pgprot_t) { (x) } )
    1.23  
    1.24  #endif /* !__ASSEMBLY__ */
     2.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Fri Mar 18 11:16:56 2005 +0000
     2.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Fri Mar 18 15:14:45 2005 +0000
     2.3 @@ -13,41 +13,13 @@
     2.4   * within a page table are directly modified.  Thus, the following
     2.5   * hook is made available.
     2.6   */
     2.7 +#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
     2.8 +#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
     2.9 +#define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval))
    2.10  #define set_pte_batched(pteptr, pteval) \
    2.11  	queue_l1_entry_update(pteptr, (pteval).pte_low)
    2.12  
    2.13 -#ifdef CONFIG_SMP
    2.14 -#define set_pte(pteptr, pteval) xen_l1_entry_update(pteptr, (pteval).pte_low)
    2.15 -#if 0
    2.16 -do { \
    2.17 -  (*(pteptr) = pteval); \
    2.18 -  HYPERVISOR_xen_version(0); \
    2.19 -} while (0)
    2.20 -#endif
    2.21 -#define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval)
    2.22 -#else
    2.23 -#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
    2.24 -#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
    2.25 -#endif
    2.26 -#define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval))
    2.27 -
    2.28 -/*
    2.29 - * A note on implementation of this atomic 'get-and-clear' operation.
    2.30 - * This is actually very simple because Xen Linux can only run on a single
    2.31 - * processor. Therefore, we cannot race other processors setting the 'accessed'
    2.32 - * or 'dirty' bits on a page-table entry.
    2.33 - * Even if pages are shared between domains, that is not a problem because
    2.34 - * each domain will have separate page tables, with their own versions of
    2.35 - * accessed & dirty state.
    2.36 - */
    2.37 -static inline pte_t ptep_get_and_clear(pte_t *xp)
    2.38 -{
    2.39 -	pte_t pte = *xp;
    2.40 -	if (pte.pte_low)
    2.41 -		set_pte(xp, __pte_ma(0));
    2.42 -	return pte;
    2.43 -}
    2.44 -
    2.45 +#define ptep_get_and_clear(xp)	__pte_ma(xchg(&(xp)->pte_low, 0))
    2.46  #define pte_same(a, b)		((a).pte_low == (b).pte_low)
    2.47  /*
    2.48   * We detect special mappings in one of two ways:
     3.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Fri Mar 18 11:16:56 2005 +0000
     3.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Fri Mar 18 15:14:45 2005 +0000
     3.3 @@ -89,9 +89,6 @@ void paging_init(void);
     3.4  # define VMALLOC_END	(FIXADDR_START-2*PAGE_SIZE)
     3.5  #endif
     3.6  
     3.7 -extern void *high_memory;
     3.8 -extern unsigned long vmalloc_earlyreserve;
     3.9 -
    3.10  /*
    3.11   * The 4MB page is guessing..  Detailed in the infamous "Chapter H"
    3.12   * of the Pentium details, but assuming intel did the straightforward
    3.13 @@ -214,7 +211,7 @@ extern unsigned long pg0[];
    3.14  /* pmd_present doesn't just test the _PAGE_PRESENT bit since wr.p.t.
    3.15     can temporarily clear it. */
    3.16  #define pmd_present(x)	(pmd_val(x))
    3.17 -/* pmd_clear below */
    3.18 +#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
    3.19  #define pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
    3.20  
    3.21  
    3.22 @@ -254,34 +251,20 @@ static inline pte_t pte_mkwrite(pte_t pt
    3.23  
    3.24  static inline int ptep_test_and_clear_dirty(pte_t *ptep)
    3.25  {
    3.26 -	pte_t pte = *ptep;
    3.27 -	int ret = pte_dirty(pte);
    3.28 -	if (ret)
    3.29 -		xen_l1_entry_update(ptep, pte_mkclean(pte).pte_low);
    3.30 -	return ret;
    3.31 +	if (!pte_dirty(*ptep))
    3.32 +		return 0;
    3.33 +	return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
    3.34  }
    3.35  
    3.36  static inline int ptep_test_and_clear_young(pte_t *ptep)
    3.37  {
    3.38 -	pte_t pte = *ptep;
    3.39 -	int ret = pte_young(pte);
    3.40 -	if (ret)
    3.41 -		xen_l1_entry_update(ptep, pte_mkold(pte).pte_low);
    3.42 -	return ret;
    3.43 +	if (!pte_young(*ptep))
    3.44 +		return 0;
    3.45 +	return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
    3.46  }
    3.47  
    3.48 -static inline void ptep_set_wrprotect(pte_t *ptep)
    3.49 -{
    3.50 -	pte_t pte = *ptep;
    3.51 -	if (pte_write(pte))
    3.52 -		set_pte(ptep, pte_wrprotect(pte));
    3.53 -}
    3.54 -static inline void ptep_mkdirty(pte_t *ptep)
    3.55 -{
    3.56 -	pte_t pte = *ptep;
    3.57 -	if (!pte_dirty(pte))
    3.58 -		xen_l1_entry_update(ptep, pte_mkdirty(pte).pte_low);
    3.59 -}
    3.60 +static inline void ptep_set_wrprotect(pte_t *ptep)		{ clear_bit(_PAGE_BIT_RW, &ptep->pte_low); }
    3.61 +static inline void ptep_mkdirty(pte_t *ptep)			{ set_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); }
    3.62  
    3.63  /*
    3.64   * Macro to mark a page protection value as "uncacheable".  On processors which do not support
    3.65 @@ -316,11 +299,6 @@ static inline pte_t pte_modify(pte_t pte
    3.66  
    3.67  #define page_pte(page) page_pte_prot(page, __pgprot(0))
    3.68  
    3.69 -#define pmd_clear(xp)	do {					\
    3.70 -	set_pmd(xp, __pmd(0));					\
    3.71 -	xen_flush_page_update_queue();				\
    3.72 -} while (0)
    3.73 -
    3.74  #define pmd_large(pmd) \
    3.75  ((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
    3.76  
    3.77 @@ -416,7 +394,6 @@ extern void noexec_setup(const char *str
    3.78   */
    3.79  #define update_mmu_cache(vma,address,pte) do { } while (0)
    3.80  #define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
    3.81 -
    3.82  #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
    3.83  	do {								  \
    3.84  		if (__dirty) {						  \
     4.1 --- a/tools/tests/test_x86_emulator.c	Fri Mar 18 11:16:56 2005 +0000
     4.2 +++ b/tools/tests/test_x86_emulator.c	Fri Mar 18 15:14:45 2005 +0000
     4.3 @@ -158,6 +158,21 @@ int main(int argc, char **argv)
     4.4          goto fail;
     4.5      printf("okay\n");
     4.6  
     4.7 +    printf("%-40s", "Testing btrl $0x1,(%edi)...");
     4.8 +    instr[0] = 0x0f; instr[1] = 0xba; instr[2] = 0x37; instr[3] = 0x01;
     4.9 +    res         = 0x2233445F;
    4.10 +    regs.eflags = 0x200;
    4.11 +    regs.eip    = (unsigned long)&instr[0];
    4.12 +    regs.edi    = (unsigned long)&res;
    4.13 +    cr2         = regs.edi;
    4.14 +    rc = x86_emulate_memop(&regs, cr2, &emulops, 4);    
    4.15 +    if ( (rc != 0) || 
    4.16 +         (res != 0x2233445D) ||
    4.17 +         ((regs.eflags&0x201) != 0x201) ||
    4.18 +         (regs.eip != (unsigned long)&instr[4]) )
    4.19 +        goto fail;
    4.20 +    printf("okay\n");
    4.21 +
    4.22      return 0;
    4.23  
    4.24   fail:
     5.1 --- a/xen/arch/x86/mm.c	Fri Mar 18 11:16:56 2005 +0000
     5.2 +++ b/xen/arch/x86/mm.c	Fri Mar 18 15:14:45 2005 +0000
     5.3 @@ -2560,18 +2560,15 @@ static struct x86_mem_emulator ptwr_mem_
     5.4  /* Write page fault handler: check if guest is trying to modify a PTE. */
     5.5  int ptwr_do_page_fault(unsigned long addr)
     5.6  {
     5.7 -    unsigned long    pte, pfn, l2e;
     5.8 -    struct pfn_info *page;
     5.9 -    l2_pgentry_t    *pl2e;
    5.10 -    int              which, cpu = smp_processor_id();
    5.11 -    u32              l2_idx;
    5.12 -
    5.13 -#ifdef __x86_64__
    5.14 -    return 0; /* Writable pagetables need fixing for x86_64. */
    5.15 -#endif
    5.16 +    unsigned long       pte, pfn, l2e;
    5.17 +    struct pfn_info    *page;
    5.18 +    l2_pgentry_t       *pl2e;
    5.19 +    int                 which, cpu = smp_processor_id();
    5.20 +    u32                 l2_idx;
    5.21 +    struct exec_domain *ed = current;
    5.22  
    5.23      /* Can't use linear_l2_table with external tables. */
    5.24 -    BUG_ON(shadow_mode_external(current->domain));
    5.25 +    BUG_ON(shadow_mode_external(ed->domain));
    5.26  
    5.27      /*
    5.28       * Attempt to read the PTE that maps the VA being accessed. By checking for
    5.29 @@ -2595,6 +2592,15 @@ int ptwr_do_page_fault(unsigned long add
    5.30          return 0;
    5.31      }
    5.32  
    5.33 +    /* x86/64: Writable pagetable code needs auditing. Use emulator for now. */
    5.34 +#if defined(__x86_64__)
    5.35 +    goto emulate;
    5.36 +#endif
    5.37 +
    5.38 +    /* Writable pagetables are not yet SMP safe. Use emulator for now. */
    5.39 +    if ( (ed->eid != 0) || (ed->ed_next_list != NULL) )
    5.40 +        goto emulate;
    5.41 +
    5.42      /* Get the L2 index at which this L1 p.t. is always mapped. */
    5.43      l2_idx = page->u.inuse.type_info & PGT_va_mask;
    5.44      if ( unlikely(l2_idx >= PGT_va_unknown) )
    5.45 @@ -2640,7 +2646,7 @@ int ptwr_do_page_fault(unsigned long add
    5.46       * If last batch made no updates then we are probably stuck. Emulate this 
    5.47       * update to ensure we make progress.
    5.48       */
    5.49 -    if ( (ptwr_info[cpu].ptinfo[which].prev_exec_domain == current) &&
    5.50 +    if ( (ptwr_info[cpu].ptinfo[which].prev_exec_domain == ed) &&
    5.51           (ptwr_info[cpu].ptinfo[which].prev_nr_updates  == 0) )
    5.52      {
    5.53          /* Force non-emul next time, or we can get stuck emulating forever. */
    5.54 @@ -2653,7 +2659,7 @@ int ptwr_do_page_fault(unsigned long add
    5.55      
    5.56      /* For safety, disconnect the L1 p.t. page from current space. */
    5.57      if ( (which == PTWR_PT_ACTIVE) && 
    5.58 -         likely(!shadow_mode_enabled(current->domain)) )
    5.59 +         likely(!shadow_mode_enabled(ed->domain)) )
    5.60      {
    5.61          *pl2e = mk_l2_pgentry(l2e & ~_PAGE_PRESENT);
    5.62          flush_tlb(); /* XXX Multi-CPU guests? */
     6.1 --- a/xen/arch/x86/x86_emulate.c	Fri Mar 18 11:16:56 2005 +0000
     6.2 +++ b/xen/arch/x86/x86_emulate.c	Fri Mar 18 15:14:45 2005 +0000
     6.3 @@ -18,12 +18,14 @@ typedef int16_t            s16;
     6.4  typedef int32_t            s32;
     6.5  typedef int64_t            s64;
     6.6  #include <public/xen.h>
     6.7 +#define DPRINTF(_f, _a...) printf( _f , ## _a )
     6.8  #else
     6.9  #include <xen/config.h>
    6.10  #include <xen/types.h>
    6.11  #include <xen/lib.h>
    6.12  #include <xen/mm.h>
    6.13  #include <asm/regs.h>
    6.14 +#define DPRINTF DPRINTK
    6.15  #endif
    6.16  #include <asm-x86/x86_emulate.h>
    6.17  
    6.18 @@ -226,22 +228,25 @@ struct operand {
    6.19  #define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)
    6.20  
    6.21  /* Before executing instruction: restore necessary bits in EFLAGS. */
    6.22 -/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~msk; */
    6.23  #define _PRE_EFLAGS(_sav, _msk, _tmp)           \
    6.24 +/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); */\
    6.25  "push %"_sav"; "                                \
    6.26  "movl %"_msk",%"_LO32 _tmp"; "                  \
    6.27  "andl %"_LO32 _tmp",("_STK"); "                 \
    6.28 +"pushf; "                                       \
    6.29  "notl %"_LO32 _tmp"; "                          \
    6.30 -"andl %"_LO32 _tmp",%"_sav"; "                  \
    6.31 -"pushf; "                                       \
    6.32  "andl %"_LO32 _tmp",("_STK"); "                 \
    6.33  "pop  %"_tmp"; "                                \
    6.34  "orl  %"_LO32 _tmp",("_STK"); "                 \
    6.35 -"popf; "
    6.36 +"popf; "                                        \
    6.37 +/* _sav &= ~msk; */                             \
    6.38 +"movl %"_msk",%"_LO32 _tmp"; "                  \
    6.39 +"notl %"_LO32 _tmp"; "                          \
    6.40 +"andl %"_LO32 _tmp",%"_sav"; "
    6.41  
    6.42  /* After executing instruction: write-back necessary bits in EFLAGS. */
    6.43 -/* _sav |= EFLAGS & _msk; */
    6.44  #define _POST_EFLAGS(_sav, _msk, _tmp)          \
    6.45 +/* _sav |= EFLAGS & _msk; */                    \
    6.46  "pushf; "                                       \
    6.47  "pop  %"_tmp"; "                                \
    6.48  "andl %"_msk",%"_LO32 _tmp"; "                  \
    6.49 @@ -370,8 +375,6 @@ do{ __asm__ __volatile__ (              
    6.50     (_type)_x; \
    6.51  })
    6.52  
    6.53 -#define DPRINTF(_f, _a...) printf( _f , ## _a )
    6.54 -
    6.55  void *
    6.56  decode_register(
    6.57      u8 modrm_reg, struct xen_regs *regs, int highbyte_regs)
    6.58 @@ -932,23 +935,23 @@ x86_emulate_memop(
    6.59          }
    6.60          break;
    6.61      case 0xa3: bt: /* bt */
    6.62 -        src.val &= (1UL << (1 << dst.bytes)) - 1; /* only subword offset */
    6.63 +        src.val &= (dst.bytes << 3) - 1; /* only subword offset */
    6.64          emulate_2op_SrcV_nobyte("bt", src, dst, _regs.eflags);
    6.65          break;
    6.66      case 0xb3: btr: /* btr */
    6.67 -        src.val &= (1UL << (1 << dst.bytes)) - 1; /* only subword offset */
    6.68 +        src.val &= (dst.bytes << 3) - 1; /* only subword offset */
    6.69          emulate_2op_SrcV_nobyte("btr", src, dst, _regs.eflags);
    6.70          break;
    6.71      case 0xab: bts: /* bts */
    6.72 -        src.val &= (1UL << (1 << dst.bytes)) - 1; /* only subword offset */
    6.73 +        src.val &= (dst.bytes << 3) - 1; /* only subword offset */
    6.74          emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
    6.75          break;
    6.76      case 0xbb: btc: /* btc */
    6.77 -        src.val &= (1UL << (1 << dst.bytes)) - 1; /* only subword offset */
    6.78 +        src.val &= (dst.bytes << 3) - 1; /* only subword offset */
    6.79          emulate_2op_SrcV_nobyte("btc", src, dst, _regs.eflags);
    6.80          break;
    6.81      case 0xba: /* Grp8 */
    6.82 -        switch ( modrm_reg >> 1 )
    6.83 +        switch ( modrm_reg & 3 )
    6.84          {
    6.85          case 0: goto bt;
    6.86          case 1: goto bts;
     7.1 --- a/xen/include/asm-x86/page.h	Fri Mar 18 11:16:56 2005 +0000
     7.2 +++ b/xen/include/asm-x86/page.h	Fri Mar 18 15:14:45 2005 +0000
     7.3 @@ -56,10 +56,23 @@ typedef struct { unsigned long pt_lo; } 
     7.4  #include <asm/bitops.h>
     7.5  #include <asm/flushtlb.h>
     7.6  
     7.7 -#define linear_pg_table ((l1_pgentry_t *)LINEAR_PT_VIRT_START)
     7.8 -#define linear_l2_table ((l2_pgentry_t *)(LINEAR_PT_VIRT_START+(LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
     7.9 -
    7.10 -#define va_to_l1mfn(_va) (l2_pgentry_val(linear_l2_table[_va>>L2_PAGETABLE_SHIFT]) >> PAGE_SHIFT)
    7.11 +#define linear_l1_table                                                 \
    7.12 +    ((l1_pgentry_t *)(LINEAR_PT_VIRT_START))
    7.13 +#define linear_l2_table                                                 \
    7.14 +    ((l2_pgentry_t *)(LINEAR_PT_VIRT_START +                            \
    7.15 +                     (LINEAR_PT_VIRT_START >> (PAGETABLE_ORDER<<0))))
    7.16 +#define linear_l3_table                                                 \
    7.17 +    ((l3_pgentry_t *)(LINEAR_PT_VIRT_START +                            \
    7.18 +                     (LINEAR_PT_VIRT_START >> (PAGETABLE_ORDER<<0)) +   \
    7.19 +                     (LINEAR_PT_VIRT_START >> (PAGETABLE_ORDER<<1))))
    7.20 +#define linear_l4_table                                                 \
    7.21 +    ((l4_pgentry_t *)(LINEAR_PT_VIRT_START +                            \
    7.22 +                     (LINEAR_PT_VIRT_START >> (PAGETABLE_ORDER<<0)) +   \
    7.23 +                     (LINEAR_PT_VIRT_START >> (PAGETABLE_ORDER<<1)) +   \
    7.24 +                     (LINEAR_PT_VIRT_START >> (PAGETABLE_ORDER<<2))))
    7.25 +#define linear_pg_table linear_l1_table
    7.26 +#define va_to_l1mfn(_va) \
    7.27 +    (l2_pgentry_val(linear_l2_table[_va>>L2_PAGETABLE_SHIFT]) >> PAGE_SHIFT)
    7.28  
    7.29  extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES];
    7.30  
     8.1 --- a/xen/include/asm-x86/x86_32/page.h	Fri Mar 18 11:16:56 2005 +0000
     8.2 +++ b/xen/include/asm-x86/x86_32/page.h	Fri Mar 18 15:14:45 2005 +0000
     8.3 @@ -7,8 +7,9 @@
     8.4  #define PAGE_SHIFT              L1_PAGETABLE_SHIFT
     8.5  #define ROOT_PAGETABLE_SHIFT    L2_PAGETABLE_SHIFT
     8.6  
     8.7 -#define L1_PAGETABLE_ENTRIES    1024
     8.8 -#define L2_PAGETABLE_ENTRIES    1024
     8.9 +#define PAGETABLE_ORDER         10
    8.10 +#define L1_PAGETABLE_ENTRIES    (1<<PAGETABLE_ORDER)
    8.11 +#define L2_PAGETABLE_ENTRIES    (1<<PAGETABLE_ORDER)
    8.12  #define ROOT_PAGETABLE_ENTRIES  L2_PAGETABLE_ENTRIES
    8.13  
    8.14  #define __PAGE_OFFSET           (0xFC400000)
     9.1 --- a/xen/include/asm-x86/x86_64/page.h	Fri Mar 18 11:16:56 2005 +0000
     9.2 +++ b/xen/include/asm-x86/x86_64/page.h	Fri Mar 18 15:14:45 2005 +0000
     9.3 @@ -9,10 +9,11 @@
     9.4  #define PAGE_SHIFT              L1_PAGETABLE_SHIFT
     9.5  #define ROOT_PAGETABLE_SHIFT    L4_PAGETABLE_SHIFT
     9.6  
     9.7 -#define L1_PAGETABLE_ENTRIES    512
     9.8 -#define L2_PAGETABLE_ENTRIES    512
     9.9 -#define L3_PAGETABLE_ENTRIES    512
    9.10 -#define L4_PAGETABLE_ENTRIES    512
    9.11 +#define PAGETABLE_ORDER         9
    9.12 +#define L1_PAGETABLE_ENTRIES    (1<<PAGETABLE_ORDER)
    9.13 +#define L2_PAGETABLE_ENTRIES    (1<<PAGETABLE_ORDER)
    9.14 +#define L3_PAGETABLE_ENTRIES    (1<<PAGETABLE_ORDER)
    9.15 +#define L4_PAGETABLE_ENTRIES    (1<<PAGETABLE_ORDER)
    9.16  #define ROOT_PAGETABLE_ENTRIES  L4_PAGETABLE_ENTRIES
    9.17  
    9.18  #define __PAGE_OFFSET           (0xFFFF830000000000)