bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

TSS switching


From: Marcus Brinkmann
Subject: TSS switching
Date: Sun, 7 Oct 2001 23:50:46 +0200
User-agent: Mutt/1.3.22i

Hi,

I want to start a new thread for this.  Below is my current patch to fix the
I/O permission code.  All of it works.  However, it is broken nevertheless:
Although the user tss is correctly (AFAICS) setup, it doesn't come
effective:  The program is killed with Illegal Instruction.  I am at my wits
end, as the code seems to be correct and I don't know how to debug it
further.

I verified that the switch_ktss() function in i386/i386/pcb.c sees the correct
user tss and that the bitmap is correct.  As far as I can say, it does the
right thing in this case.  Also, the io_tss_init() function in
i386/i386/iopb.c seems to correctly initialize the user tss.

This is still the old interface and thread based.  To make it task based, we
either need to insert a TSS in all threads of the task (that would be
foolish), or to make TSS specific to a task (which fits best with current
switching implementation), or we need to do what Linux does and make TSS cpu
specific only, and always update the same TSS with the information from the
current thread/task (like I/O bitmap or LDT).  I think it might be very
simple to make TSS task based (assuming we get the user tss stuff working),
but I don't think doing what Linux does would be too hard, either.  (Linux
copies the bitmask if either the old or the new task has one.  We switch the
TSS in the same cases).

Thanks,
Marcus

* No changelog yet  (but it has no bitmap for the kernel tss, that works).
Also, except the changes already known, I fixed the user tss initialization
(it seems to me that barrier was not included in the segment limit
calculation, but that's not what the Intel docus request).

diff -x CVS -ru gnu/cvs/gnumach/i386/i386/iopb.c 
gnu/hurd/gnumach/gnumach-20011005/i386/i386/iopb.c
--- gnu/cvs/gnumach/i386/i386/iopb.c    Sun Oct  7 23:30:11 2001
+++ gnu/hurd/gnumach/gnumach-20011005/i386/i386/iopb.c  Sun Oct  7 23:09:01 2001
@@ -238,7 +238,7 @@
        boolean_t       access_all)     /* allow access or not */
 {
        vm_offset_t     addr = (vm_offset_t) io_tss;
-       vm_size_t       size = (char *)&io_tss->barrier - (char *)io_tss;
+       vm_size_t       limit = (char *)&io_tss->barrier - (char *)io_tss;
 
        bzero(&io_tss->tss, sizeof(struct i386_tss));
        io_tss->tss.io_bit_map_offset
@@ -252,12 +251,9 @@
        io_bitmap_init(io_tss->bitmap, access_all);
        io_tss->barrier = ~0;
        queue_init(&io_tss->io_port_list);
-       io_tss->iopb_desc[0] = ((size-1) & 0xffff)
-               | ((addr & 0xffff) << 16);
-       io_tss->iopb_desc[1] = ((addr & 0x00ff0000) >> 16)
-               | ((ACC_TSS|ACC_PL_K|ACC_P) << 8)
-               | ((size-1) & 0x000f0000)
-               | (addr & 0xff000000);
+
+       fill_descriptor(&io_tss->iopb_desc, addr, limit,
+                       ACC_PL_K|ACC_TSS|ACC_P, 0);
 }
 
 /*
@@ -270,7 +266,7 @@
        register iopb_tss_t ts;
 
        ts = (iopb_tss_t) kalloc(sizeof (struct iopb_tss));
-       io_tss_init(ts, TRUE);          /* XXX */
+       io_tss_init(ts, FALSE);
        return ts;
 }
 
@@ -307,11 +303,21 @@
 /*
  * Add an IO mapping to a thread.
  */
+#ifdef i386
+kern_return_t
+i386_io_port_add(
+       thread_t        thread,
+       device_t        d)
+#else
 kern_return_t
 i386_io_port_add(
        thread_t        thread,
        mach_device_t   device)
+#endif
 {
+#ifdef i386
+       mach_device_t   device = d->emul_data;
+#endif
        pcb_t           pcb;
        iopb_tss_t      io_tss, new_io_tss;
        io_port_t       io_port;
@@ -357,7 +363,7 @@
                simple_unlock(&iopb_lock);
 
                new_io_tss = (iopb_tss_t) kalloc(sizeof(struct iopb_tss));
-               io_tss_init(new_io_tss, TRUE);  /* XXX */
+               io_tss_init(new_io_tss, FALSE);
 
                goto Retry;
            }
@@ -406,11 +412,21 @@
 /*
  * Remove an IO mapping from a thread.
  */
+#ifdef i386
+kern_return_t
+i386_io_port_remove(thread, d)
+       thread_t        thread;
+       device_t        d;
+#else
 kern_return_t
 i386_io_port_remove(thread, device)
        thread_t        thread;
        mach_device_t   device;
+#endif
 {
+#ifdef i386
+       mach_device_t   device = d->emul_data;
+#endif
        pcb_t           pcb;
        iopb_tss_t      io_tss;
        io_port_t       io_port;
diff -x CVS -ru gnu/cvs/gnumach/i386/i386/iopb.h 
gnu/hurd/gnumach/gnumach-20011005/i386/i386/iopb.h
--- gnu/cvs/gnumach/i386/i386/iopb.h    Sun Oct  7 23:30:12 2001
+++ gnu/hurd/gnumach/gnumach-20011005/i386/i386/iopb.h  Sun Oct  7 22:50:05 2001
@@ -30,6 +30,8 @@
 #include <i386/tss.h>
 #include <kern/queue.h>
 
+#include "seg.h"
+
 /*
  * IO permission bitmap.
  *
@@ -51,9 +53,9 @@
 struct iopb_tss {
        struct i386_tss tss;            /* task state segment */
        isa_iopb        bitmap;         /* bitmap of mapped IO ports */
-       unsigned int    barrier;        /* bitmap barrier for CPU slop */
+       unsigned char   barrier;        /* bitmap barrier for CPU slop */
        queue_head_t    io_port_list;   /* list of mapped IO ports */
-       int             iopb_desc[2];   /* descriptor for this TSS */
+       struct real_descriptor iopb_desc;       /* descriptor for this TSS */
 };
 
 typedef        struct iopb_tss *iopb_tss_t;
diff -x CVS -ru gnu/cvs/gnumach/i386/i386/ktss.c 
gnu/hurd/gnumach/gnumach-20011005/i386/i386/ktss.c
--- gnu/cvs/gnumach/i386/i386/ktss.c    Sun Oct  7 23:30:12 2001
+++ gnu/hurd/gnumach/gnumach-20011005/i386/i386/ktss.c  Sun Oct  7 23:10:54 2001
@@ -44,16 +44,16 @@
 
        /* Initialize the master TSS descriptor.  */
        fill_gdt_descriptor(KERNEL_TSS,
-                           kvtolin(&ktss), sizeof(ktss)+65536/8+1-1,
+                           kvtolin(&ktss), sizeof(ktss)-1,
                            ACC_PL_K|ACC_TSS, 0);
 
        /* Initialize the master TSS.  */
        ktss.ss0 = KERNEL_DS;
        ktss.esp0 = (unsigned)(exception_stack+1024);
-       ktss.io_bit_map_offset = sizeof(ktss);
 
-       /* Set the last byte in the I/O bitmap to all 1's.  */
-       ((unsigned char*)&ktss)[sizeof(ktss)+65536/8] = 0xff;
+       /* If the I/O bitmap base address is outside of the segment
+          size, all accesses are forbidden.  */
+       ktss.io_bit_map_offset = sizeof(ktss);
 
        /* Load the TSS.  */
        ltr(KERNEL_TSS);
diff -x CVS -ru gnu/cvs/gnumach/i386/i386/locore.S 
gnu/hurd/gnumach/gnumach-20011005/i386/i386/locore.S
--- gnu/cvs/gnumach/i386/i386/locore.S  Sun Oct  7 23:30:53 2001
+++ gnu/hurd/gnumach/gnumach-20011005/i386/i386/locore.S        Mon Oct  1 
14:20:14 2001
@@ -1753,10 +1753,8 @@
 
 
 /*
- * Allocate enough space for a kernel TSS with a complete I/O bitmap,
- * for making v86-mode BIOS calls.  XXX
+ * Allocate enough space for a kernel TSS.
  */
        .data
        .globl  EXT(ktss)
-       .comm   EXT(ktss),0x68+65536/8+1
-
+       .comm   EXT(ktss),0x68
diff -x CVS -ru gnu/cvs/gnumach/i386/i386/pcb.c 
gnu/hurd/gnumach/gnumach-20011005/i386/i386/pcb.c
--- gnu/cvs/gnumach/i386/i386/pcb.c     Fri Apr 24 21:49:34 1998
+++ gnu/hurd/gnumach/gnumach-20011005/i386/i386/pcb.c   Sun Oct  7 23:22:42 2001
@@ -162,7 +162,7 @@
             * Set the IO permissions.  Use this thread`s TSS.
             */
            *gdt_desc_p(mycpu,USER_TSS)
-               = *(struct real_descriptor *)tss->iopb_desc;
+             = tss->iopb_desc;
            tss->tss.esp0 = pcb_stack_top;
            set_tr(USER_TSS);
            gdt_desc_p(mycpu,KERNEL_TSS)->access &= ~ ACC_TSS_BUSY;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]