bug-hurd
[Top][All Lists]
Advanced

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

Re: [bug #15295] Mach lets processes write to I/O ports


From: Samuel Thibault
Subject: Re: [bug #15295] Mach lets processes write to I/O ports
Date: Sun, 8 Jan 2006 16:34:47 +0100
User-agent: Mutt/1.5.9i-nntp

Hi,

Here is the patchset inline, for review:

2005-12-26  Samuel Thibault <samuel.thibault@ens-lyon.org>

        * iopb.c: Include "vm_param.h" for kvtolin().
        (io_tss_init): Fix address and limit of user TSS.

diff -urp gnumach-20050801/build-dbg/machine/iopb.c 
gnumach-mine/build-dbg/machine/iopb.c
--- gnumach-20050801/build-dbg/machine/iopb.c   2005-05-01 18:04:47.000000000 
+0200
+++ gnumach-mine/build-dbg/machine/iopb.c       2005-12-26 19:50:22.000000000 
+0100
@@ -43,6 +43,7 @@
 #include "iopb.h"
 #include "seg.h"
 #include "gdt.h"
+#include "vm_param.h"
 
 /*
  * A set of ports for an IO device.
@@ -242,8 +243,8 @@ io_tss_init(
        iopb_tss_t      io_tss,
        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_offset_t     addr = kvtolin (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,11 +253,11 @@ io_tss_init(
        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)
+       io_tss->iopb_desc[0] = (limit & 0xffff)
                | ((addr & 0xffff) << 16);
        io_tss->iopb_desc[1] = ((addr & 0x00ff0000) >> 16)
                | ((ACC_TSS|ACC_PL_K|ACC_P) << 8)
-               | ((size-1) & 0x000f0000)
+               | (limit & 0x000f0000)
                | (addr & 0xff000000);
 }
 
2006-01-02  Samuel Thibault <samuel.thibault@ens-lyon.org>

        * iopb.c(iopb_create): Set default IO permissions to none.
        * ktss.c(ktss_init): Same as above.

diff -urp gnumach-mine-1-user_tss/i386/i386/iopb.c 
gnumach-mine-2-default_noio/i386/i386/iopb.c
--- gnumach-mine-1-user_tss/i386/i386/iopb.c    2006-01-02 18:38:29.000000000 
+0100
+++ gnumach-mine-2-default_noio/i386/i386/iopb.c        2006-01-02 
18:38:31.000000000 +0100
@@ -271,7 +271,7 @@ iopb_create(void)
        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;
 }
 
@@ -358,7 +358,7 @@ i386_io_port_add(
                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;
            }
diff -urp gnumach-mine-1-user_tss/i386/i386/ktss.c 
gnumach-mine-2-default_noio/i386/i386/ktss.c
--- gnumach-mine-1-user_tss/i386/i386/ktss.c    2006-01-02 18:35:08.000000000 
+0100
+++ gnumach-mine-2-default_noio/i386/i386/ktss.c        2005-12-26 
22:33:26.000000000 +0100
@@ -52,8 +52,8 @@ ktss_init()
        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;
+       /* Set all bytes in the I/O bitmap to all 1's.  */
+       memset(((unsigned char*)&ktss)+sizeof(ktss), 0xff, 65536/8+1);
 
        /* Load the TSS.  */
        ltr(KERNEL_TSS);
2006-01-02  Samuel Thibault <samuel.thibault@ens-lyon.org>

        * iopb.c(i386_io_port_add): Fix getting device parameter.
        (i386_io_port_remove): Same as above.

diff -urp gnumach-mine-2-default_noio/i386/i386/iopb.c 
gnumach-mine-3-device_port_fix/i386/i386/iopb.c
--- gnumach-mine-2-default_noio/i386/i386/iopb.c        2006-01-02 
18:38:31.000000000 +0100
+++ gnumach-mine-3-device_port_fix/i386/i386/iopb.c     2006-01-02 
18:42:45.000000000 +0100
@@ -308,12 +308,22 @@
 /*
  * 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
 {
        pcb_t           pcb;
+#ifdef i386
+       mach_device_t   device = d->emul_data;
+#endif
        iopb_tss_t      io_tss, new_io_tss;
        io_port_t       io_port;
        io_use_t        iu, old_iu;
@@ -407,12 +417,22 @@
 /*
  * 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
 {
        pcb_t           pcb;
+#ifdef i386
+       mach_device_t   device = d->emul_data;
+#endif
        iopb_tss_t      io_tss;
        io_port_t       io_port;
        io_use_t        iu;
2006-01-02  Samuel Thibault <samuel.thibault@ens-lyon.org>

        * iopl.c(iopl_port_list): Add timer controler port.

diff -urp gnumach-mine-3-device_port_fix/i386/i386at/iopl.c 
gnumach-mine-4-more_ports/i386/i386at/iopl.c
--- gnumach-mine-3-device_port_fix/i386/i386at/iopl.c   2006-01-02 
18:43:09.000000000 +0100
+++ gnumach-mine-4-more_ports/i386/i386at/iopl.c        2006-01-02 
18:45:17.000000000 +0100
@@ -47,7 +47,7 @@
  */
 io_reg_t iopl_port_list[] = {
        /* timer 2 */
-       0x42,
+       0x42, 0x43,
        /* speaker output */
        0x61,
        /* ATI - savage */

2006-01-02  Samuel Thibault <samuel.thibault@ens-lyon.org>

        * kd.c(vga_port_list): Rename to...
        (kd_port_list): this, set static, add timer and speaker ports.

diff -urp gnumach-mine-3-device_port_fix/i386/i386at/kd.c 
gnumach-mine-4-more_ports/i386/i386at/kd.c
--- gnumach-mine-3-device_port_fix/i386/i386at/kd.c     2006-01-02 
18:43:12.000000000 +0100
+++ gnumach-mine-4-more_ports/i386/i386at/kd.c  2006-01-02 19:14:48.000000000 
+0100
@@ -348,7 +348,9 @@
 /*
  * IO port sets for different controllers.
  */
-io_reg_t vga_port_list[] = {
+static io_reg_t kd_port_list[] = {
+       0x42, 0x43,     /* Timer */
+       0x61,           /* Speaker */
        0x3b4, 0x3b5, 0x3b8, 0x3b9, 0x3ba,      /* MDA/EGA */
        0x3d4, 0x3d5, 0x3d8, 0x3d9, 0x3da,      /* CGA/EGA */
        0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7,
@@ -362,7 +364,7 @@ kd_io_map_open(device)
        mach_device_t   device;
 {
        kd_io_device = device;
-       io_port_create(device, vga_port_list);
+       io_port_create(device, kd_port_list);
 }
 
 kd_io_map_close()
2006-01-02  Samuel Thibault <samuel.thibault@ens-lyon.org>

        * iopb.c: IO ports permissions are now task-based.
        (i386_io_port_add): Fix TSS access and locking accordingly.
        (i386_io_port_remove): Same as above.
        (i386_io_port_list): Same as above.
        (iopb_check_mapping): Same as above.
        * pcb.c(switch_ktss): Now takes next thread as parameter for TSS switch
        to be task-based.
        (stack_handoff): Fix parameter of switch_ktss calls.
        (switch_context): Same as above.
        (pcb_module_init): Move iopb initialization to new
        machine_task_module_init() function.
        (pcb_terminate): Move iopb termination to new machine_task_termination()
        function.
        (machine_task_module_init): New function.
        (machine_task_init): New function.
        (machine_task_terminate): New function.
        (machine_task_collect): New function.
        (thread_setstatus): TSS is now task-based, fix TSS and locking
        accordingly.
        (thread_getstatus): Same as above.
        * io_emulate.c(emulate_io): Fix parameter of switch_ktss call.
        * thread.h(i386_machine_state): Move io_tss member to...
        (machine_task): this new structure.
        * user_ldt.c(i386_set_ldt): Fix parameter of switch_ktss call.

diff -urp gnumach-mine-4-more_ports/i386/i386/iopb.c 
gnumach-mine-5-io_per_task/i386/i386/iopb.c
--- gnumach-mine-4-more_ports/i386/i386/iopb.c  2006-01-02 18:42:45.000000000 
+0100
+++ gnumach-mine-5-io_per_task/i386/i386/iopb.c 2005-12-29 23:42:34.000000000 
+0100
@@ -65,8 +65,8 @@
 
 /*
  * Cross-reference:
- *     all threads that have IO ports mapped
- *     all IO ports that have threads mapped
+ *     all tasks that have IO ports mapped
+ *     all IO ports that have tasks mapped
  */
 struct io_use {
        queue_chain_t   psq;    /* Links from port set */
@@ -306,7 +306,7 @@
 }
 
 /*
- * Add an IO mapping to a thread.
+ * Add an IO mapping to a task.
  */
 #ifdef i386
 kern_return_t
@@ -320,7 +320,7 @@ i386_io_port_add(
        mach_device_t   device)
 #endif
 {
-       pcb_t           pcb;
+       task_t          task;
 #ifdef i386
        mach_device_t   device = d->emul_data;
 #endif
@@ -332,7 +332,7 @@ i386_io_port_add(
         || device == DEVICE_NULL)
            return KERN_INVALID_ARGUMENT;
 
-       pcb = thread->pcb;
+       task = thread->task;
 
        new_io_tss = 0;
        iu = (io_use_t) kalloc(sizeof(struct io_use));
@@ -355,16 +355,16 @@ i386_io_port_add(
 
        /* Have the IO port. */
 
-       /* Make sure the thread has a TSS. */
+       /* Make sure the task has a TSS. */
 
-       simple_lock(&pcb->lock);
-       io_tss = pcb->ims.io_tss;
+       task_lock(task);
+       io_tss = task->machine.io_tss;
        if (io_tss == 0) {
            if (new_io_tss == 0) {
                /*
                 * Allocate an IO-tss.
                 */
-               simple_unlock(&pcb->lock);
+               task_unlock(task);
                simple_unlock(&iopb_lock);
 
                new_io_tss = (iopb_tss_t) kalloc(sizeof(struct iopb_tss));
@@ -373,7 +373,12 @@ i386_io_port_add(
                goto Retry;
            }
            io_tss = new_io_tss;
-           pcb->ims.io_tss = io_tss;
+           task->machine.io_tss = io_tss;
+
+           /* Update hardware if needed.  */
+           if (task == current_thread()->task)
+               switch_ktss(thread);
+
            new_io_tss = 0;
        }
 
@@ -386,7 +391,7 @@ i386_io_port_add(
                /*
                 * Already mapped.
                 */
-               simple_unlock(&pcb->lock);
+               task_unlock(task);
                simple_unlock(&iopb_lock);
 
                kfree((vm_offset_t)iu, sizeof(struct io_use));
@@ -405,7 +410,7 @@ i386_io_port_add(
        queue_enter(&io_tss->io_port_list, iu, io_use_t, tsq);
        io_bitmap_set(io_tss->bitmap, io_port->io_port_list);
 
-       simple_unlock(&pcb->lock);
+       task_unlock(task);
        simple_unlock(&iopb_lock);
 
        if (new_io_tss)
@@ -415,7 +420,7 @@ i386_io_port_add(
 }
 
 /*
- * Remove an IO mapping from a thread.
+ * Remove an IO mapping from a task.
  */
 #ifdef i386
 kern_return_t
@@ -429,7 +434,7 @@ i386_io_port_remove(thread, device)
        mach_device_t   device;
 #endif
 {
-       pcb_t           pcb;
+       task_t          task;
 #ifdef i386
        mach_device_t   device = d->emul_data;
 #endif
@@ -441,7 +446,7 @@ i386_io_port_remove(thread, device)
         || device == DEVICE_NULL)
            return KERN_INVALID_ARGUMENT;
 
-       pcb = thread->pcb;
+       task = thread->task;
 
        simple_lock(&iopb_lock);
 
@@ -456,10 +461,10 @@ i386_io_port_remove(thread, device)
            return KERN_INVALID_ARGUMENT;
        }
 
-       simple_lock(&pcb->lock);
-       io_tss = pcb->ims.io_tss;
+       task_lock(task);
+       io_tss = task->machine.io_tss;
        if (io_tss == 0) {
-           simple_unlock(&pcb->lock);
+           task_unlock(task);
            simple_unlock(&iopb_lock);
            return KERN_INVALID_ARGUMENT;       /* not mapped */
        }
@@ -477,7 +482,7 @@ i386_io_port_remove(thread, device)
                queue_remove(&io_port->io_use_list, iu, io_use_t, psq);
                queue_remove(&io_tss->io_port_list, iu, io_use_t, tsq);
 
-               simple_unlock(&pcb->lock);
+               task_unlock(task);
                simple_unlock(&iopb_lock);
 
                kfree((vm_offset_t)iu, sizeof(struct io_use));
@@ -486,6 +491,9 @@ i386_io_port_remove(thread, device)
            }
        }
 
+       task_unlock(task);
+       simple_unlock(&iopb_lock);
+
        /*
         * No mapping.
         */
@@ -493,7 +501,7 @@ i386_io_port_remove(thread, device)
 }
 
 /*
- * Return the IO ports mapped into a thread.
+ * Return the IO ports mapped into a task.
  */
 extern ipc_port_t      mach_convert_device_to_port(/* device_t */);
 
@@ -503,7 +511,7 @@ i386_io_port_list(thread, list, list_cou
        mach_device_t   **list;
        unsigned int    *list_count;
 {
-       register pcb_t  pcb;
+       task_t          task;
        register iopb_tss_t io_tss;
        unsigned int    count, alloc_count;
        mach_device_t   *devices;
@@ -514,7 +522,7 @@ i386_io_port_list(thread, list, list_cou
        if (thread == THREAD_NULL)
            return KERN_INVALID_ARGUMENT;
 
-       pcb = thread->pcb;
+       task = thread->task;
 
        alloc_count = 16;               /* a guess */
 
@@ -537,8 +545,8 @@ i386_io_port_list(thread, list, list_cou
            count = 0;
 
            simple_lock(&iopb_lock);
-           simple_lock(&pcb->lock);
-           io_tss = pcb->ims.io_tss;
+           task_lock(task);
+           io_tss = task->machine.io_tss;
            if (io_tss != 0) {
                register io_use_t iu;
 
@@ -550,7 +558,7 @@ i386_io_port_list(thread, list, list_cou
                    }
                }
            }
-           simple_unlock(&pcb->lock);
+           task_unlock(task);
            simple_unlock(&iopb_lock);
        } while (count > alloc_count);
 
@@ -596,7 +604,7 @@ i386_io_port_list(thread, list, list_cou
 }
 
 /*
- * Check whether an IO device is mapped to a particular thread.
+ * Check whether an IO device is mapped to a particular task.
  * Used to support the 'iopl' device automatic mapping.
  */
 boolean_t
@@ -604,11 +612,11 @@ iopb_check_mapping(thread, device)
        thread_t        thread;
        mach_device_t   device;
 {
-       pcb_t           pcb;
+       task_t          task;
        io_port_t       io_port;
        io_use_t        iu;
 
-       pcb = thread->pcb;
+       task = thread->task;
 
        simple_lock(&iopb_lock);
 
@@ -622,15 +630,18 @@ iopb_check_mapping(thread, device)
 
        /* Look up the mapping in the device`s mapping list. */
 
+       task_lock(task);
        queue_iterate(&io_port->io_use_list, iu, io_use_t, psq) {
-           if (iu->ts == pcb->ims.io_tss) {
+           if (iu->ts == task->machine.io_tss) {
                /*
                 * Device is mapped.
                 */
+               task_unlock(task);
                simple_unlock(&iopb_lock);
                return TRUE;
            }
        }
+       task_unlock(task);
        simple_unlock(&iopb_lock);
        return FALSE;
 }
diff -urp gnumach-mine-4-more_ports/i386/i386/pcb.c 
gnumach-mine-5-io_per_task/i386/i386/pcb.c
--- gnumach-mine-4-more_ports/i386/i386/pcb.c   2006-01-02 18:42:57.000000000 
+0100
+++ gnumach-mine-5-io_per_task/i386/i386/pcb.c  2005-12-31 00:04:21.000000000 
+0100
@@ -131,12 +131,13 @@
 #define        gdt_desc_p(mycpu,sel) \
        ((struct real_descriptor *)&curr_gdt(mycpu)[sel_idx(sel)])
 
-void switch_ktss(pcb)
-       register pcb_t  pcb;
+void switch_ktss(thread)
+       register thread_t       thread;
 {
        int                     mycpu = cpu_number();
+       register pcb_t          pcb = thread->pcb;
     {
-       register iopb_tss_t     tss = pcb->ims.io_tss;
+       register iopb_tss_t     tss = thread->task->machine.io_tss;
        vm_offset_t             pcb_stack_top;
 
        /*
@@ -234,7 +235,7 @@ void stack_handoff(old, new)
        /*
         *      Load the rest of the user state for the new thread
         */
-       switch_ktss(new->pcb);
+       switch_ktss(new);
 
        /*
         *      Switch to new thread
@@ -259,7 +260,7 @@ void stack_handoff(old, new)
 void load_context(new)
        register thread_t       new;
 {
-       switch_ktss(new->pcb);
+       switch_ktss(new);
        Load_context(new);
 }
 
@@ -296,7 +297,7 @@ thread_t switch_context(old, continuatio
        /*
         *      Load the rest of the user state for the new thread
         */
-       switch_ktss(new->pcb);
+       switch_ktss(new);
 
        return Switch_context(old, continuation, new);
 }
@@ -309,7 +310,6 @@ void pcb_module_init()
                         0, "i386 pcb state");
 
        fpu_module_init();
-       iopb_init();
 }
 
 void pcb_init(thread)
@@ -353,8 +353,6 @@ void pcb_terminate(thread)
        counter(if (--c_threads_current < c_threads_min)
                        c_threads_min = c_threads_current);
 
-       if (pcb->ims.io_tss != 0)
-               iopb_destroy(pcb->ims.io_tss);
        if (pcb->ims.ifps != 0)
                fp_free(pcb->ims.ifps);
        if (pcb->ims.ldt != 0)
@@ -374,6 +372,30 @@ void pcb_collect(thread)
 {
 }
 
+void machine_task_module_init(void)
+{
+       iopb_init();
+}
+
+void machine_task_init(new_task)
+       task_t new_task;
+{
+       new_task->machine.io_tss = 0;
+}
+
+void machine_task_terminate(task)
+       task_t task;
+{
+       if (task->machine.io_tss != 0)
+               iopb_destroy(task->machine.io_tss);
+}
+
+void machine_task_collect(task)
+       task_t task;
+{
+       /* TODO: compare io_tss with 0xff, XXX: not if it is still in use, and
+        * beware of races with threads adding io perms!  */
+}
 
 /*
  *     thread_setstatus:
@@ -508,28 +530,40 @@ kern_return_t thread_setstatus(thread, f
             */
            case i386_ISA_PORT_MAP_STATE: {
                register struct i386_isa_port_map_state *state;
-               register iopb_tss_t     tss;
+               register iopb_tss_t     tss, old_tss;
+               task_t                  task;
 
                if (count < i386_ISA_PORT_MAP_STATE_COUNT)
                        return(KERN_INVALID_ARGUMENT);
 
-#if 0
                /*
                 *      If the thread has no ktss yet,
                 *      we must allocate one.
                 */
 
                state = (struct i386_isa_port_map_state *) tstate;
-               tss = thread->pcb->ims.io_tss;
+               task = thread->task;
+               task_lock(task);
+               tss = task->machine.io_tss;
                if (tss == 0) {
+                       task_unlock(task);
                        tss = iopb_create();
-                       thread->pcb->ims.io_tss = tss;
+                       task_lock(task);
+                       old_tss = task->machine.io_tss;
+                       if (old_tss == 0) {
+                               task->machine.io_tss = tss;
+                       } else {
+                               task_unlock(task);
+                               iopb_destroy(tss);
+                               tss = old_tss;
+                               task_lock(task);
+                       }
                }
 
                bcopy((char *) state->pm,
                      (char *) tss->bitmap,
                      sizeof state->pm);
-#endif
+               task_unlock(task);
                break;
            }
 
@@ -666,16 +700,21 @@ kern_return_t thread_getstatus(thread, f
            case i386_ISA_PORT_MAP_STATE: {
                register struct i386_isa_port_map_state *state;
                register iopb_tss_t tss;
+               task_t task;
 
                if (*count < i386_ISA_PORT_MAP_STATE_COUNT)
                        return(KERN_INVALID_ARGUMENT);
 
                state = (struct i386_isa_port_map_state *) tstate;
-               tss = thread->pcb->ims.io_tss;
+               task = thread->task;
+               task_lock(task);
+               tss = task->machine.io_tss;
 
                if (tss == 0) {
                    int i;
 
+                   task_unlock(task);
+
                    /*
                     *  The thread has no ktss, so no IO permissions.
                     */
@@ -690,6 +729,7 @@ kern_return_t thread_getstatus(thread, f
                    bcopy((char *) tss->bitmap,
                          (char *) state->pm,
                          sizeof state->pm);
+                   task_unlock(task);
                }
 
                *count = i386_ISA_PORT_MAP_STATE_COUNT;
diff -urp gnumach-mine-4-more_ports/i386/i386/io_emulate.c 
gnumach-mine-5-io_per_task/i386/i386/io_emulate.c
--- gnumach-mine-4-more_ports/i386/i386/io_emulate.c    2006-01-02 
18:41:46.000000000 +0100
+++ gnumach-mine-5-io_per_task/i386/i386/io_emulate.c   2005-12-28 
17:40:28.000000000 +0100
@@ -102,7 +102,7 @@ emulate_io(regs, opcode, io_port)
         * Make the thread use its IO_TSS to get the IO permissions;
         * it may not have had one before this.
         */
-       switch_ktss(thread->pcb);
+       switch_ktss(thread);
 
        return EM_IO_RETRY;
 }
diff -urp gnumach-mine-4-more_ports/i386/i386/thread.h 
gnumach-mine-5-io_per_task/i386/i386/thread.h
--- gnumach-mine-4-more_ports/i386/i386/thread.h        2006-01-02 
18:43:01.000000000 +0100
+++ gnumach-mine-5-io_per_task/i386/i386/thread.h       2005-12-28 
17:44:13.000000000 +0100
@@ -157,12 +157,15 @@
  */
 
 struct i386_machine_state {
-       iopb_tss_t              io_tss;
        struct user_ldt *       ldt;
        struct i386_fpsave_state *ifps;
        struct v86_assist_state v86s;
 };
 
+typedef struct machine_task {
+       iopb_tss_t              io_tss;
+} machine_task_t;
+
 typedef struct pcb {
        struct i386_interrupt_state iis[2];     /* interrupt and NMI */
        struct i386_saved_state iss;
diff -urp gnumach-mine-4-more_ports/i386/i386/user_ldt.c 
gnumach-mine-5-io_per_task/i386/i386/user_ldt.c
--- gnumach-mine-4-more_ports/i386/i386/user_ldt.c      2006-01-02 
18:43:04.000000000 +0100
+++ gnumach-mine-5-io_per_task/i386/i386/user_ldt.c     2005-12-28 
17:40:37.000000000 +0100
@@ -247,7 +247,7 @@ i386_set_ldt(thread, first_selector, des
             * make sure it is properly set.
             */
            if (thread == current_thread())
-               switch_ktss(pcb);
+               switch_ktss(thread);
        }
 
        /*


2006-01-02  Samuel Thibault <samuel.thibault@ens-lyon.org>

        * iopl.c(iopl_emulate): TSS is now task-based, fix TSS and locking
        accordingly.

diff -urp gnumach-mine-4-more_ports/i386/i386at/iopl.c 
gnumach-mine-5-io_per_task/i386/i386at/iopl.c
--- gnumach-mine-4-more_ports/i386/i386at/iopl.c        2006-01-02 
18:45:17.000000000 +0100
+++ gnumach-mine-5-io_per_task/i386/i386at/iopl.c       2006-01-02 
16:30:19.000000000 +0100
@@ -217,10 +217,15 @@ iopl_emulate(regs, opcode, io_port)
        int     io_port;
 {
        iopb_tss_t      iopb;
+       task_t          task;
 
-       iopb = current_thread()->pcb->ims.io_tss;
-       if (iopb == 0)
+       task = current_thread()->task;
+       task_lock(task);
+       iopb = task->machine.io_tss;
+       if (iopb == 0) {
+           task_unlock(task);
            return FALSE;               /* no IO mapped */
+       }
 
        /*
         * Handle outb to the timer control port,
@@ -235,11 +240,14 @@ iopl_emulate(regs, opcode, io_port)
             && (opcode == 0xe6 || opcode == 0xee)      /* outb */
             && (io_byte & 0xc0) == 0x80)               /* timer 2 */
            {
+               task_unlock(task);
                outb(io_port, io_byte);
                return TRUE;
            }
+           task_unlock(task);
            return FALSE;       /* invalid IO to port 42 */
        }
+       task_unlock(task);
 
        /*
         * If the thread has the IOPL device mapped, and


2006-01-02  Samuel Thibault <samuel.thibault@ens-lyon.org>

        * task.c(task_init): Call new machine_task_module_init() function.
        (task_create): Call new machine_task_init() function.
        (task_deallocate): Call new machine_task_terminate() function.
        (task_collect_scan): Call new machine_task_collect() function.
        * task.h: Include <machine/thread.h> for machine_task_t.
        (task): Add new machine member.

diff -urp gnumach-mine-4-more_ports/kern/task.c 
gnumach-mine-5-io_per_task/kern/task.c
--- gnumach-mine-4-more_ports/kern/task.c       2006-01-02 18:43:17.000000000 
+0100
+++ gnumach-mine-5-io_per_task/kern/task.c      2005-12-28 17:10:07.000000000 
+0100
@@ -78,6 +78,7 @@ void task_init(void)
                        0, "tasks");
 
        eml_init();
+       machine_task_module_init ();
 
        /*
         * Create the kernel task as the first task.
@@ -160,6 +161,7 @@ kern_return_t task_create(
 #if    NET_ATM
        new_task->nw_ep_owned = 0;
 #endif
+       machine_task_init (new_task);
 
        new_task->total_user_time.seconds = 0;
        new_task->total_user_time.microseconds = 0;
@@ -247,6 +249,8 @@ void task_deallocate(
        }
 #endif /* NORMA_TASK */
 
+       machine_task_terminate (task);
+
        eml_task_deallocate(task);
 
        pset = task->processor_set;
@@ -1126,6 +1130,7 @@ void task_collect_scan(void)
                        pset_unlock(pset);
                        simple_unlock(&all_psets_lock);
 
+                       machine_task_collect (task);
                        pmap_collect(task->map->pmap);
 
                        if (prev_task != TASK_NULL)
diff -urp gnumach-mine-4-more_ports/kern/task.h 
gnumach-mine-5-io_per_task/kern/task.h
--- gnumach-mine-4-more_ports/kern/task.h       2006-01-02 18:43:22.000000000 
+0100
+++ gnumach-mine-5-io_per_task/kern/task.h      2005-12-28 17:44:11.000000000 
+0100
@@ -49,6 +49,7 @@
 #include <kern/pc_sample.h>
 #include <kern/processor.h>
 #include <kern/syscall_emulation.h>
+#include <machine/thread.h>
 #include <vm/vm_map.h>
 
 #if    NET_ATM
@@ -117,6 +118,9 @@ struct task {
 #if    NET_ATM
        nw_ep_owned_t   nw_ep_owned;
 #endif /* NET_ATM */
+
+       /* Hardware specific data.  */
+       machine_task_t  machine;
 };
 
 #define task_lock(task)                simple_lock(&(task)->lock)
2006-01-07  Samuel Thibault  <samuel.thibault@ens-lyon.org>

        * iopb.c: Include <device/io_req.h> for io_req_t.  New "io" device.
        (ioopen): New function.
        (ioclose): Likewise.
        (io_bitmap_set): Treat special (-1) bit list as "all ports".
        (io_bitmap_clear): Likewise.

diff -urp gnumach-mine-5-io_per_task/i386/i386/iopb.c 
gnumach-mine-6-io_device/i386/i386/iopb.c
--- gnumach-mine-5-io_per_task/i386/i386/iopb.c 2005-12-29 23:42:34.000000000 
+0100
+++ gnumach-mine-6-io_device/i386/i386/iopb.c   2006-01-07 00:19:24.000000000 
+0100
@@ -38,6 +38,7 @@
 #include <kern/thread.h>
 
 #include <device/dev_hdr.h>
+#include <device/io_req.h>
 
 #include "io_port.h"
 #include "iopb.h"
@@ -82,6 +83,32 @@
 decl_simple_lock_data(, iopb_lock)
 
 /*
+ * Special "all I/O ports" device.
+ */
+mach_device_t  io_device = 0;
+
+int ioopen(dev, flag, ior)
+       int dev;
+       int flag;
+       io_req_t ior;
+{
+       io_device = ior->io_device;
+
+       io_port_create(io_device, (io_reg_t *)(-1));
+       return (0);
+}
+
+int
+ioclose(dev, flags)
+       int dev;
+       int flags;
+{
+       io_port_destroy(io_device);
+       io_device = 0;
+       return 0;
+}
+
+/*
  * Initialize the package.
  */
 void
@@ -130,9 +157,12 @@ io_bitmap_set(
 {
        io_reg_t        io_bit;
 
-       while ((io_bit = *bit_list++) != IO_REG_NULL) {
-           bp[io_bit>>3] &= ~(1 << (io_bit & 0x7));
-       }
+       if (bit_list == (io_reg_t *)(-1))
+               memset(bp, 0, IOPB_BYTES);
+       else
+               while ((io_bit = *bit_list++) != IO_REG_NULL) {
+                   bp[io_bit>>3] &= ~(1 << (io_bit & 0x7));
+               }
 }
 
 /*
@@ -145,9 +175,12 @@ io_bitmap_clear(
 {
        io_reg_t        io_bit;
 
-       while ((io_bit = *bit_list++) != IO_REG_NULL) {
-           bp[io_bit>>3] |= (1 << (io_bit & 0x7));
-       }
+       if (bit_list == (io_reg_t *)(-1))
+               memset(bp, ~0, IOPB_BYTES);
+       else
+               while ((io_bit = *bit_list++) != IO_REG_NULL) {
+                   bp[io_bit>>3] |= (1 << (io_bit & 0x7));
+               }
 }
 
 /*

2006-01-07  Samuel Thibault  <samuel.thibault@ens-lyon.org>

        * conf.c: New "io" device.
        (dev_name_list): Added "io" device.

diff -urp gnumach-mine-5-io_per_task/i386/i386at/conf.c 
gnumach-mine-6-io_device/i386/i386at/conf.c
--- gnumach-mine-5-io_per_task/i386/i386at/conf.c       2006-01-06 
23:43:24.000000000 +0100
+++ gnumach-mine-6-io_device/i386/i386at/conf.c 2006-01-06 23:43:44.000000000 
+0100
@@ -182,6 +182,9 @@
 extern vm_offset_t ioplmmap();
 #define        ioplname                "iopl"
 
+extern int     ioopen(), ioclose();
+#define ioname                 "io"
+
 extern int     kmsgopen(), kmsgclose(), kmsgread(), kmsggetstat();
 #define kmsgname               "kmsg"
 
@@ -367,6 +370,11 @@ struct dev_ops     dev_name_list[] =
          nodev,        nulldev,        nulldev,        0,
          nodev },
 
+       { ioname,       ioopen,         ioclose,        nodev,
+         nodev,        nodev,          nodev,          nodev,
+         nodev,        nulldev,        nulldev,        0,
+         nodev },
+
 #if 0
 #if    NHD > 0
        { pchdname,     pchdopen,       hdclose,        pchdread,

2006-01-02  Samuel Thibault  <samuel.thibault@ens-lyon.org>

        * generic-speaker.c: include <mach.h>, <mach/i386/mach_i386.h> and
        <device/device.h> for IO ports access.
        (kd_port): New variable.
        (generic_speaker_start): Add IO ports access request for gnumach1.
        * vga-support.c: include <mach.h>, <mach/i386/mach_i386.h> and
        <device/device.h> for IO ports access.
        (kd_port): New variable.
        (vga_init): Add IO ports access request for gnumach1.
        (vga_fini): Add IO ports access relinquish for gnumach1.

Index: console-client/generic-speaker.c
===================================================================
RCS file: /cvsroot/hurd/hurd/console-client/generic-speaker.c,v
retrieving revision 1.4
diff -u -u -r1.4 generic-speaker.c
--- console-client/generic-speaker.c    21 Mar 2004 19:57:00 -0000      1.4
+++ console-client/generic-speaker.c    2 Jan 2006 22:47:54 -0000
@@ -25,6 +25,10 @@
 
 #include <cthreads.h>
 
+#include <mach.h>
+#include <mach/i386/mach_i386.h>
+#include <device/device.h>
+
 #include "driver.h"
 #include "timer.h"
 
@@ -40,6 +44,9 @@
 static struct bell_ops generic_speaker_ops;
 
 
+/* Port for i/o access.  */
+static mach_port_t kd_port;
+
 /* The speaker port.  */
 #define SPEAKER                        0x61
 
@@ -477,6 +484,18 @@
     return errno;
   if (ioperm (PIT_COUNTER_2, PIT_CTRL - PIT_COUNTER_2 + 1, 1) < 0)
     return errno;
+#else
+  mach_port_t priv;
+  err = get_privileged_ports (NULL, &priv);
+  if (err)
+    return err;
+  err = device_open(priv, D_READ|D_WRITE, "kd", &kd_port);
+  mach_port_deallocate(mach_task_self(), priv);
+  if (err)
+    return err;
+  err = i386_io_port_add(mach_thread_self(), kd_port);
+  if (err)
+    return err;
 #endif
 
   beep_off ();
Index: console-client/vga-support.c
===================================================================
RCS file: /cvsroot/hurd/hurd/console-client/vga-support.c,v
retrieving revision 1.4
diff -u -u -r1.4 vga-support.c
--- console-client/vga-support.c        18 Nov 2002 07:35:47 -0000      1.4
+++ console-client/vga-support.c        2 Jan 2006 22:47:54 -0000
@@ -27,10 +27,17 @@
 #include <sys/types.h>
 #include <string.h>
 
+#include <mach.h>
+#include <mach/i386/mach_i386.h>
+#include <device/device.h>
+
 #include "vga-hw.h"
 #include "vga-support.h"
 
 
+/* Port for i/o access.  */
+static mach_port_t kd_port;
+
 /* The base of the video memory mapping.  */
 char *vga_videomem;
 
@@ -78,6 +85,7 @@
   error_t err;
   int fd;
 
+#ifdef OSKIT_MACH
   /* Acquire I/O port access.  */
   if (ioperm (VGA_MIN_REG, VGA_MAX_REG - VGA_MIN_REG + 1, 1) < 0)
     {
@@ -90,6 +98,19 @@
          return errno;
        }
     }
+#else
+  mach_port_t priv;
+  err = get_privileged_ports (NULL, &priv);
+  if (err)
+    return err;
+  err = device_open(priv, D_READ|D_WRITE, "kd", &kd_port);
+  mach_port_deallocate(mach_task_self(), priv);
+  if (err)
+    return err;
+  err = i386_io_port_add(mach_thread_self(), kd_port);
+  if (err)
+    return err;
+#endif
 
   fd = open ("/dev/mem", O_RDWR);
   if (fd >= 0)
@@ -229,7 +250,12 @@
   outb (VGA_CRT_CURSOR_LOW, VGA_CRT_ADDR_REG);
   outb (vga_state->crt_cursor_low, VGA_CRT_DATA_REG);
 
-  ioperm (VGA_MIN_REG, VGA_MAX_REG, 0);
+#ifdef OSKIT_MACH
+  ioperm (VGA_MIN_REG, VGA_MAX_REG - VGA_MIN_REG + 1, 0);
+#else
+  i386_io_port_remove(mach_thread_self(), kd_port);
+  mach_port_deallocate(mach_task_self(), kd_port);
+#endif
   munmap (vga_videomem, VGA_VIDEO_MEM_LENGTH);
 }
 




reply via email to

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