direct-io.hg

changeset 14354:a4ca6a264fee

xen: Generic linear pagetable support for x86 PV guests.
Any linear mapping is permitted, except for L3-PAE-maps-L3-PAE,
which makes no sense even on native.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Mar 12 14:52:11 2007 +0000 (2007-03-12)
parents b01d4f415f5f
children 68282f4b3e0f
files xen/arch/x86/mm.c
line diff
     1.1 --- a/xen/arch/x86/mm.c	Mon Mar 12 14:47:00 2007 +0000
     1.2 +++ b/xen/arch/x86/mm.c	Mon Mar 12 14:52:11 2007 +0000
     1.3 @@ -529,22 +529,22 @@ static int get_page_and_type_from_pagenr
     1.4   *     frame if it is mapped by a different root table. This is sufficient and
     1.5   *     also necessary to allow validation of a root table mapping itself.
     1.6   */
     1.7 -#define define_get_linear_pagetable(name1, name2)                           \
     1.8 +#define define_get_linear_pagetable(level)                                  \
     1.9  static int                                                                  \
    1.10 -get_##name1##_linear_pagetable(                                             \
    1.11 -    name1##_pgentry_t pde, unsigned long pde_pfn, struct domain *d)         \
    1.12 +get_##level##_linear_pagetable(                                             \
    1.13 +    level##_pgentry_t pde, unsigned long pde_pfn, struct domain *d)         \
    1.14  {                                                                           \
    1.15      unsigned long x, y;                                                     \
    1.16      struct page_info *page;                                                 \
    1.17      unsigned long pfn;                                                      \
    1.18                                                                              \
    1.19 -    if ( (name2##_get_flags(pde) & _PAGE_RW) )                              \
    1.20 +    if ( (level##e_get_flags(pde) & _PAGE_RW) )                             \
    1.21      {                                                                       \
    1.22          MEM_LOG("Attempt to create linear p.t. with write perms");          \
    1.23          return 0;                                                           \
    1.24      }                                                                       \
    1.25                                                                              \
    1.26 -    if ( (pfn = name2##_get_pfn(pde)) != pde_pfn )                          \
    1.27 +    if ( (pfn = level##e_get_pfn(pde)) != pde_pfn )                         \
    1.28      {                                                                       \
    1.29          /* Make sure the mapped frame belongs to the correct domain. */     \
    1.30          if ( unlikely(!get_page_from_pagenr(pfn, d)) )                      \
    1.31 @@ -560,7 +560,7 @@ get_##name1##_linear_pagetable(         
    1.32              x = y;                                                          \
    1.33              if ( unlikely((x & PGT_count_mask) == PGT_count_mask) ||        \
    1.34                   unlikely((x & (PGT_type_mask|PGT_validated)) !=            \
    1.35 -                          (PGT_##name1##_page_table|PGT_validated)) )       \
    1.36 +                          (PGT_##level##_page_table|PGT_validated)) )       \
    1.37              {                                                               \
    1.38                  put_page(page);                                             \
    1.39                  return 0;                                                   \
    1.40 @@ -571,12 +571,6 @@ get_##name1##_linear_pagetable(         
    1.41                                                                              \
    1.42      return 1;                                                               \
    1.43  }
    1.44 -#if !defined(CONFIG_X86_PAE)
    1.45 -define_get_linear_pagetable(root,root)
    1.46 -#endif
    1.47 -#if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
    1.48 -define_get_linear_pagetable(l2,l2e)
    1.49 -#endif
    1.50  
    1.51  int
    1.52  get_page_from_l1e(
    1.53 @@ -638,7 +632,8 @@ get_page_from_l1e(
    1.54  
    1.55  
    1.56  /* NB. Virtual address 'l2e' maps to a machine address within frame 'pfn'. */
    1.57 -static int 
    1.58 +define_get_linear_pagetable(l2);
    1.59 +static int
    1.60  get_page_from_l2e(
    1.61      l2_pgentry_t l2e, unsigned long pfn, struct domain *d)
    1.62  {
    1.63 @@ -655,20 +650,15 @@ get_page_from_l2e(
    1.64  
    1.65      rc = get_page_and_type_from_pagenr(l2e_get_pfn(l2e), PGT_l1_page_table, d);
    1.66      if ( unlikely(!rc) )
    1.67 -    {
    1.68 -#if CONFIG_PAGING_LEVELS == 2
    1.69 -        rc = get_root_linear_pagetable(l2e, pfn, d);
    1.70 -#else
    1.71          rc = get_l2_linear_pagetable(l2e, pfn, d);
    1.72 -#endif
    1.73 -    }
    1.74  
    1.75      return rc;
    1.76  }
    1.77  
    1.78  
    1.79  #if CONFIG_PAGING_LEVELS >= 3
    1.80 -static int 
    1.81 +define_get_linear_pagetable(l3);
    1.82 +static int
    1.83  get_page_from_l3e(
    1.84      l3_pgentry_t l3e, unsigned long pfn, struct domain *d)
    1.85  {
    1.86 @@ -684,12 +674,16 @@ get_page_from_l3e(
    1.87      }
    1.88  
    1.89      rc = get_page_and_type_from_pagenr(l3e_get_pfn(l3e), PGT_l2_page_table, d);
    1.90 +    if ( unlikely(!rc) )
    1.91 +        rc = get_l3_linear_pagetable(l3e, pfn, d);
    1.92 +
    1.93      return rc;
    1.94  }
    1.95  #endif /* 3 level */
    1.96  
    1.97  #if CONFIG_PAGING_LEVELS >= 4
    1.98 -static int 
    1.99 +define_get_linear_pagetable(l4);
   1.100 +static int
   1.101  get_page_from_l4e(
   1.102      l4_pgentry_t l4e, unsigned long pfn, struct domain *d)
   1.103  {
   1.104 @@ -705,9 +699,8 @@ get_page_from_l4e(
   1.105      }
   1.106  
   1.107      rc = get_page_and_type_from_pagenr(l4e_get_pfn(l4e), PGT_l3_page_table, d);
   1.108 -
   1.109      if ( unlikely(!rc) )
   1.110 -        rc = get_root_linear_pagetable(l4e, pfn, d);
   1.111 +        rc = get_l4_linear_pagetable(l4e, pfn, d);
   1.112  
   1.113      return rc;
   1.114  }