bitkeeper revision 1.1236.34.1 (4236a41axFD_nz4Avu26J6WLiOHu7w)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 15 Mar 2005 09:00:10 +0000 (09:00 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 15 Mar 2005 09:00:10 +0000 (09:00 +0000)
Fix descriptor checking that I broke. Allow conforming code segments -
they are harmless.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/x86_32/mm.c
xen/arch/x86/x86_64/mm.c

index 2f3ce50c5cbce68b56e72648467a3cce8849a126..8c8897a2831dae34bbde10b9820c0b36b08eb580 100644 (file)
@@ -274,10 +274,25 @@ int check_descriptor(struct desc_struct *d)
     if ( (b & _SEGMENT_G) )
         limit <<= 12;
 
-    switch ( b & (_SEGMENT_CODE | _SEGMENT_EC) )
+    if ( (b & (_SEGMENT_CODE | _SEGMENT_EC)) == _SEGMENT_EC )
     {
-    case 0: /* Data segment, grows-up */
         /*
+         * DATA, GROWS-DOWN.
+         * Grows-down limit check. 
+         * NB. limit == 0xFFFFF provides no access      (if G=1).
+         *     limit == 0x00000 provides 4GB-4kB access (if G=1).
+         */
+        if ( (base + limit) > base )
+        {
+            limit = -(base & PAGE_MASK);
+            goto truncate;
+        }
+    }
+    else
+    {
+        /*
+         * DATA, GROWS-UP. 
+         * CODE (CONFORMING AND NON-CONFORMING).
          * Grows-up limit check.
          * NB. limit == 0xFFFFF provides 4GB access (if G=1).
          *     limit == 0x00000 provides 4kB access (if G=1).
@@ -293,23 +308,6 @@ int check_descriptor(struct desc_struct *d)
             d->a &= ~0x0ffff; d->a |= limit & 0x0ffff;
             d->b &= ~0xf0000; d->b |= limit & 0xf0000;
         }
-        goto good;
-    case _SEGMENT_EC: /* Data segment, grows-down */
-        /*
-         * Grows-down limit check. 
-         * NB. limit == 0xFFFFF provides no access      (if G=1).
-         *     limit == 0x00000 provides 4GB-4kB access (if G=1).
-         */
-        if ( (base + limit) > base )
-        {
-            limit = -(base & PAGE_MASK);
-            goto truncate;
-        }
-        goto good;
-    case _SEGMENT_CODE: /* Code segment, non-conforming */
-        goto good;
-    case _SEGMENT_CODE|_SEGMENT_EC: /* Code segment, conforming */
-        goto bad;
     }
 
  good:
index aeee7fc0ba6f39fdf1507ad96fd8cf6e6963d7c6..bc61aeb2fe1995427ba984c8bedba18a1b8d9c96 100644 (file)
@@ -287,14 +287,9 @@ int check_descriptor(struct desc_struct *d)
     if ( (b & _SEGMENT_DPL) != 3 )
         goto bad;
 
-    /* Most code and data segments are okay. No base/limit checking. */
+    /* All code and data segments are okay. No base/limit checking. */
     if ( (b & _SEGMENT_S) )
-    {
-        /* Disallow conforming code segments. I'm not sure they're safe. */
-        if ( (b & (_SEGMENT_CODE|_SEGMENT_EC)) == (_SEGMENT_CODE|_SEGMENT_EC) )
-            goto bad;
         goto good;
-    }
 
     /* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */
     if ( (b & _SEGMENT_TYPE) == 0x000 )