direct-io.hg
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. :-)
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;