ia64/xen-unstable

changeset 9241:9aefef31e040

Ignore pinning of other than root page directories. Disallow
creation of pagetables with 'va_unknown' page-directory backptrs.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Mar 12 19:37:00 2006 +0100 (2006-03-12)
parents 3983e4f1b054
children 57f21f67b532
files xen/arch/x86/mm.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/mm.c	Sun Mar 12 10:03:33 2006 +0100
     1.2 +++ b/xen/arch/x86/mm.c	Sun Mar 12 19:37:00 2006 +0100
     1.3 @@ -777,9 +777,7 @@ static inline int l1_backptr(
     1.4      unsigned long *backptr, unsigned long offset_in_l2, unsigned long l2_type)
     1.5  {
     1.6      unsigned long l2_backptr = l2_type & PGT_va_mask;
     1.7 -    BUG_ON(l2_backptr == PGT_va_unknown);
     1.8 -    if ( l2_backptr == PGT_va_mutable )
     1.9 -        return 0;
    1.10 +    ASSERT(l2_backptr != PGT_va_unknown);
    1.11      *backptr = 
    1.12          ((l2_backptr >> PGT_va_shift) << L3_PAGETABLE_SHIFT) | 
    1.13          (offset_in_l2 << L2_PAGETABLE_SHIFT);
    1.14 @@ -793,8 +791,7 @@ static inline int l1_backptr(
    1.15      unsigned long *backptr, unsigned long offset_in_l2, unsigned long l2_type)
    1.16  {
    1.17      unsigned long l2_backptr = l2_type & PGT_va_mask;
    1.18 -    BUG_ON(l2_backptr == PGT_va_unknown);
    1.19 -
    1.20 +    ASSERT(l2_backptr != PGT_va_unknown);
    1.21      *backptr = ((l2_backptr >> PGT_va_shift) << L3_PAGETABLE_SHIFT) | 
    1.22          (offset_in_l2 << L2_PAGETABLE_SHIFT);
    1.23      return 1;
    1.24 @@ -804,8 +801,7 @@ static inline int l2_backptr(
    1.25      unsigned long *backptr, unsigned long offset_in_l3, unsigned long l3_type)
    1.26  {
    1.27      unsigned long l3_backptr = l3_type & PGT_va_mask;
    1.28 -    BUG_ON(l3_backptr == PGT_va_unknown);
    1.29 -
    1.30 +    ASSERT(l3_backptr != PGT_va_unknown);
    1.31      *backptr = ((l3_backptr >> PGT_va_shift) << L4_PAGETABLE_SHIFT) | 
    1.32          (offset_in_l3 << L3_PAGETABLE_SHIFT);
    1.33      return 1;
    1.34 @@ -814,9 +810,6 @@ static inline int l2_backptr(
    1.35  static inline int l3_backptr(
    1.36      unsigned long *backptr, unsigned long offset_in_l4, unsigned long l4_type)
    1.37  {
    1.38 -    unsigned long l4_backptr = l4_type & PGT_va_mask;
    1.39 -    BUG_ON(l4_backptr == PGT_va_unknown);
    1.40 -
    1.41      *backptr = (offset_in_l4 << L4_PAGETABLE_SHIFT);
    1.42      return 1;
    1.43  }
    1.44 @@ -1438,13 +1431,6 @@ void put_page_type(struct page_info *pag
    1.45                  nx &= ~PGT_validated;
    1.46              }
    1.47          }
    1.48 -        else if ( unlikely(((nx & (PGT_pinned | PGT_count_mask)) == 
    1.49 -                            (PGT_pinned | 1)) &&
    1.50 -                           ((nx & PGT_type_mask) != PGT_writable_page)) )
    1.51 -        {
    1.52 -            /* Page is now only pinned. Make the back pointer mutable again. */
    1.53 -            nx |= PGT_va_mutable;
    1.54 -        }
    1.55      }
    1.56      while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
    1.57  }
    1.58 @@ -1527,20 +1513,17 @@ int get_page_type(struct page_info *page
    1.59                                  get_gpfn_from_mfn(page_to_mfn(page)));
    1.60                      return 0;
    1.61                  }
    1.62 -                else if ( (x & PGT_va_mask) == PGT_va_mutable )
    1.63 +                else
    1.64                  {
    1.65 -                    /* The va backpointer is mutable, hence we update it. */
    1.66 -                    nx &= ~PGT_va_mask;
    1.67 -                    nx |= type; /* we know the actual type is correct */
    1.68 -                }
    1.69 -                else if ( ((type & PGT_va_mask) != PGT_va_mutable) &&
    1.70 -                          ((type & PGT_va_mask) != (x & PGT_va_mask)) )
    1.71 -                {
    1.72 +                    ASSERT((type & PGT_va_mask) != (x & PGT_va_mask));
    1.73  #ifdef CONFIG_X86_PAE
    1.74                      /* We use backptr as extra typing. Cannot be unknown. */
    1.75                      if ( (type & PGT_type_mask) == PGT_l2_page_table )
    1.76                          return 0;
    1.77  #endif
    1.78 +                    /* Fixme: add code to propagate va_unknown to subtables. */
    1.79 +                    if ( (type & PGT_type_mask) >= PGT_l2_page_table )
    1.80 +                        return 0;
    1.81                      /* This table is possibly mapped at multiple locations. */
    1.82                      nx &= ~PGT_va_mask;
    1.83                      nx |= PGT_va_unknown;
    1.84 @@ -1818,12 +1801,17 @@ int do_mmuext_op(
    1.85          switch ( op.cmd )
    1.86          {
    1.87          case MMUEXT_PIN_L1_TABLE:
    1.88 -            type = PGT_l1_page_table | PGT_va_mutable;
    1.89 -
    1.90 -        pin_page:
    1.91 +        case MMUEXT_PIN_L2_TABLE:
    1.92 +        case MMUEXT_PIN_L3_TABLE:
    1.93 +        case MMUEXT_PIN_L4_TABLE:
    1.94 +            if ( (op.cmd - MMUEXT_PIN_L1_TABLE) != (CONFIG_PAGING_LEVELS - 1) )
    1.95 +                break;
    1.96 +
    1.97              if ( shadow_mode_refcounts(FOREIGNDOM) )
    1.98                  break;
    1.99  
   1.100 +            type = PGT_root_page_table;
   1.101 +
   1.102              okay = get_page_and_type_from_pagenr(mfn, type, FOREIGNDOM);
   1.103              if ( unlikely(!okay) )
   1.104              {
   1.105 @@ -1842,20 +1830,6 @@ int do_mmuext_op(
   1.106              
   1.107              break;
   1.108  
   1.109 -#ifndef CONFIG_X86_PAE /* Unsafe on PAE because of Xen-private mappings. */
   1.110 -        case MMUEXT_PIN_L2_TABLE:
   1.111 -            type = PGT_l2_page_table | PGT_va_mutable;
   1.112 -            goto pin_page;
   1.113 -#endif
   1.114 -
   1.115 -        case MMUEXT_PIN_L3_TABLE:
   1.116 -            type = PGT_l3_page_table | PGT_va_mutable;
   1.117 -            goto pin_page;
   1.118 -
   1.119 -        case MMUEXT_PIN_L4_TABLE:
   1.120 -            type = PGT_l4_page_table | PGT_va_mutable;
   1.121 -            goto pin_page;
   1.122 -
   1.123          case MMUEXT_UNPIN_TABLE:
   1.124              if ( shadow_mode_refcounts(d) )
   1.125                  break;
   1.126 @@ -3376,7 +3350,7 @@ int ptwr_do_page_fault(struct domain *d,
   1.127      
   1.128      /* Get the L2 index at which this L1 p.t. is always mapped. */
   1.129      l2_idx = page->u.inuse.type_info & PGT_va_mask;
   1.130 -    if ( unlikely(l2_idx >= PGT_va_unknown) )
   1.131 +    if ( unlikely(l2_idx == PGT_va_unknown) )
   1.132          goto emulate; /* Urk! This L1 is mapped in multiple L2 slots! */
   1.133      l2_idx >>= PGT_va_shift;
   1.134  
     2.1 --- a/xen/include/asm-x86/mm.h	Sun Mar 12 10:03:33 2006 +0100
     2.2 +++ b/xen/include/asm-x86/mm.h	Sun Mar 12 19:37:00 2006 +0100
     2.3 @@ -81,18 +81,14 @@ struct page_info
     2.4   /* The 11 most significant bits of virt address if this is a page table. */
     2.5  #define PGT_va_shift        16
     2.6  #define PGT_va_mask         (((1U<<11)-1)<<PGT_va_shift)
     2.7 - /* Is the back pointer still mutable (i.e. not fixed yet)? */
     2.8 -#define PGT_va_mutable      (((1U<<11)-1)<<PGT_va_shift)
     2.9   /* Is the back pointer unknown (e.g., p.t. is mapped at multiple VAs)? */
    2.10 -#define PGT_va_unknown      (((1U<<11)-2)<<PGT_va_shift)
    2.11 +#define PGT_va_unknown      (((1U<<11)-1)<<PGT_va_shift)
    2.12  #elif defined(__x86_64__)
    2.13   /* The 27 most significant bits of virt address if this is a page table. */
    2.14  #define PGT_va_shift        32
    2.15  #define PGT_va_mask         ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
    2.16 - /* Is the back pointer still mutable (i.e. not fixed yet)? */
    2.17 -#define PGT_va_mutable      ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
    2.18   /* Is the back pointer unknown (e.g., p.t. is mapped at multiple VAs)? */
    2.19 -#define PGT_va_unknown      ((unsigned long)((1U<<28)-2)<<PGT_va_shift)
    2.20 +#define PGT_va_unknown      ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
    2.21  #endif
    2.22  
    2.23   /* 16-bit count of uses of this frame as its current type. */