ia64/xen-unstable

changeset 3099:79c81628d802

bitkeeper revision 1.1159.187.6 (41a4d15eNLlT3wCGjZ2RZQx7hDushg)

Behave properly with grows-down data segments. Maybe some cleaning up
and merging with Michael Fetterman's patches required. :-)
author kaf24@scramble.cl.cam.ac.uk
date Wed Nov 24 18:22:22 2004 +0000 (2004-11-24)
parents 6b22a56f55d3
children 85d6a1145160
files xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_32/seg_fixup.c
line diff
     1.1 --- a/xen/arch/x86/x86_32/mm.c	Wed Nov 24 13:37:40 2004 +0000
     1.2 +++ b/xen/arch/x86/x86_32/mm.c	Wed Nov 24 18:22:22 2004 +0000
     1.3 @@ -190,16 +190,38 @@ int check_descriptor(unsigned long *d)
     1.4      limit++; /* We add one because limit is inclusive. */
     1.5      if ( (b & _SEGMENT_G) )
     1.6          limit <<= 12;
     1.7 -    if ( ((base + limit) <= base) || 
     1.8 -         ((base + limit) > PAGE_OFFSET) )
     1.9 +
    1.10 +    if ( (b & (3<<10)) == 1 )
    1.11 +    {
    1.12 +        /*
    1.13 +         * Grows-down limit check. 
    1.14 +         * NB. limit == 0xFFFFF provides no access      (if G=1).
    1.15 +         *     limit == 0x00000 provides 4GB-4kB access (if G=1).
    1.16 +         */
    1.17 +        if ( (base + limit) > base )
    1.18 +        {
    1.19 +            limit = -(base & PAGE_MASK);
    1.20 +            goto truncate;
    1.21 +        }
    1.22 +    }
    1.23 +    else
    1.24      {
    1.25 -        /* Need to truncate. Calculate and poke a best-effort limit. */
    1.26 -        limit = PAGE_OFFSET - base;
    1.27 -        if ( (b & _SEGMENT_G) )
    1.28 -            limit >>= 12;
    1.29 -        limit--;
    1.30 -        d[0] &= ~0x0ffff; d[0] |= limit & 0x0ffff;
    1.31 -        d[1] &= ~0xf0000; d[1] |= limit & 0xf0000;
    1.32 +        /*
    1.33 +         * Grows-up limit check.
    1.34 +         * NB. limit == 0xFFFFF provides 4GB access (if G=1).
    1.35 +         *     limit == 0x00000 provides 4kB access (if G=1).
    1.36 +         */
    1.37 +        if ( ((base + limit) <= base) || 
    1.38 +             ((base + limit) > PAGE_OFFSET) )
    1.39 +        {
    1.40 +            limit = PAGE_OFFSET - base;
    1.41 +        truncate:
    1.42 +            if ( !(b & _SEGMENT_G) )
    1.43 +                goto bad; /* too dangerous; too hard to work out... */
    1.44 +            limit = (limit >> 12) - 1;
    1.45 +            d[0] &= ~0x0ffff; d[0] |= limit & 0x0ffff;
    1.46 +            d[1] &= ~0xf0000; d[1] |= limit & 0xf0000;
    1.47 +        }
    1.48      }
    1.49  
    1.50   good:
     2.1 --- a/xen/arch/x86/x86_32/seg_fixup.c	Wed Nov 24 13:37:40 2004 +0000
     2.2 +++ b/xen/arch/x86/x86_32/seg_fixup.c	Wed Nov 24 18:22:22 2004 +0000
     2.3 @@ -225,8 +225,7 @@ int fixup_seg(u16 seg, int positive_acce
     2.4          if ( ((base + limit) < PAGE_SIZE) && positive_access )
     2.5          {
     2.6              /* Flip to expands-up. */
     2.7 -            limit >>= 12;
     2.8 -            limit -= (-PAGE_OFFSET/PAGE_SIZE) + 2;
     2.9 +            limit = PAGE_OFFSET - base;
    2.10              goto flip;
    2.11          }
    2.12      }
    2.13 @@ -236,8 +235,7 @@ int fixup_seg(u16 seg, int positive_acce
    2.14          if ( ((PAGE_OFFSET - (base + limit)) < PAGE_SIZE) && !positive_access )
    2.15          {
    2.16              /* Flip to expands-down. */
    2.17 -            limit >>= 12;
    2.18 -            limit += (-PAGE_OFFSET/PAGE_SIZE) + 0;
    2.19 +            limit = -(base & PAGE_MASK);
    2.20              goto flip;
    2.21          }
    2.22      }
    2.23 @@ -249,9 +247,10 @@ int fixup_seg(u16 seg, int positive_acce
    2.24      return 0;
    2.25  
    2.26   flip:
    2.27 +    limit = (limit >> 12) - 1;
    2.28      a &= ~0x0ffff; a |= limit & 0x0ffff;
    2.29      b &= ~0xf0000; b |= limit & 0xf0000;
    2.30 -    b ^= 1 << 10;
    2.31 +    b ^= 1 << 10; /* grows-up <-> grows-down */
    2.32      /* NB. These can't fault. Checked readable above; must also be writable. */
    2.33      table[2*idx+0] = a;
    2.34      table[2*idx+1] = b;