diff options
| author | Guillem Jover <guillem@debian.org> | 2006-01-08 18:12:25 +0000 |
|---|---|---|
| committer | Guillem Jover <guillem@debian.org> | 2006-01-08 18:12:25 +0000 |
| commit | 45faef2722453c583ee8e281a1d903c5324e163c (patch) | |
| tree | c6c002d93816317eeb53d3b54f778c89933b1d9c | |
| parent | de320583f24be016934cb90875bc4edb6742e012 (diff) | |
* Fix io port access. (Closes: #46709)
- debian/patches/40_user-tss.patch: New file.
- debian/patches/41_io_unlock_ioremove.patch: Likewise.
- debian/patches/42_disable_ioperm.disabled: Likewise.
- debian/patches/43_debvice_port_fix.patch: Likewise.
- debian/patches/44_more_ports.patch: Likewise.
- debian/patches/45_io_per_task.patch: Likewise.
- debian/patches/46_io_device.patch: Likewise.
Thanks to Samuel Thibault <samuel.thibault@ens-lyon.org>.
| -rw-r--r-- | debian/changelog | 11 | ||||
| -rw-r--r-- | debian/patches/40_user-tss.patch | 43 | ||||
| -rw-r--r-- | debian/patches/41_io_unlock_ioremove.patch | 26 | ||||
| -rw-r--r-- | debian/patches/42_disable_ioperm.disabled | 53 | ||||
| -rw-r--r-- | debian/patches/43_debvice_port_fix.patch | 57 | ||||
| -rw-r--r-- | debian/patches/44_more_ports.patch | 50 | ||||
| -rw-r--r-- | debian/patches/45_io_per_task.patch | 591 | ||||
| -rw-r--r-- | debian/patches/46_io_device.patch | 117 |
8 files changed, 947 insertions, 1 deletions
diff --git a/debian/changelog b/debian/changelog index a02af3a..0c8f37a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,17 @@ -gnumach (1:20050801-3) unstable; urgency=low +gnumach (1:20050801-3) UNRELEASED; urgency=low * Added ChangeLog entries. - debian/patches/13_ide_dma.patch: Modify - debian/patches/14_alloc_params.patch: Likewise. + * Fix io port access. (Closes: #46709) + - debian/patches/40_user-tss.patch: New file. + - debian/patches/41_io_unlock_ioremove.patch: Likewise. + - debian/patches/42_disable_ioperm.disabled: Likewise. + - debian/patches/43_debvice_port_fix.patch: Likewise. + - debian/patches/44_more_ports.patch: Likewise. + - debian/patches/45_io_per_task.patch: Likewise. + - debian/patches/46_io_device.patch: Likewise. + Thanks to Samuel Thibault <samuel.thibault@ens-lyon.org>. -- Guillem Jover <guillem@debian.org> Sat, 7 Jan 2006 01:06:40 +0200 diff --git a/debian/patches/40_user-tss.patch b/debian/patches/40_user-tss.patch new file mode 100644 index 0000000..b55f361 --- /dev/null +++ b/debian/patches/40_user-tss.patch @@ -0,0 +1,43 @@ +#DPATCHLEVEL=0 + +2005-12-26 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * i386/i386/iopb.c: Include "vm_param.h" for kvtolin(). + (io_tss_init): Fix address and limit of user TSS. + + +--- i386/i386/iopb.c 2005-05-01 18:04:47.000000000 +0200 ++++ i386/i386/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); + } + diff --git a/debian/patches/41_io_unlock_ioremove.patch b/debian/patches/41_io_unlock_ioremove.patch new file mode 100644 index 0000000..e71ed41 --- /dev/null +++ b/debian/patches/41_io_unlock_ioremove.patch @@ -0,0 +1,26 @@ +#DPATCHLEVEL=0 + +2005-12-28 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * i386/i386/iopb.c (i386_io_port_remove): Fix unlocking when io mapping + is not found. + + +Index: i386/i386/iopb.c +=================================================================== +RCS file: /cvsroot/hurd/gnumach/i386/i386/Attic/iopb.c,v +retrieving revision 1.1.1.1 +diff -u -r1.1.1.1 iopb.c +--- i386/i386/iopb.c 25 Feb 1997 21:27:09 -0000 1.1.1.1 ++++ i386/i386/iopb.c 28 Dec 2005 16:18:40 -0000 +@@ -468,6 +468,10 @@ + /* + * No mapping. + */ ++ ++ simple_unlock(&pcb->lock); ++ simple_unlock(&iopb_lock); ++ + return KERN_INVALID_ARGUMENT; + } + diff --git a/debian/patches/42_disable_ioperm.disabled b/debian/patches/42_disable_ioperm.disabled new file mode 100644 index 0000000..2a292ec --- /dev/null +++ b/debian/patches/42_disable_ioperm.disabled @@ -0,0 +1,53 @@ +#DPATCHLEVEL=0 + +2001-10-07 Marcus Brinkmann <marcus@gnu.org> + + * i386/i386/iopb.c (iopb_create, i386_io_port_add): Disable io + permissions by default. + +2004-11-16 Guillem Jover <guillem@hadrons.org> + + * i386/i386/ktss.c (ktss_init): Disable io permissions by default. + + +--- i386/i386/iopb.c Tue Feb 25 22:27:09 1997 ++++ i386/i386/iopb.c Sun Oct 7 05:00:09 2001 +@@ -270,7 +270,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; + } + +@@ -357,7 +360,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; + } +--- i386/i386/ktss.c 25 Feb 1997 21:27:10 -0000 1.1.1.1 ++++ i386/i386/ktss.c 16 Nov 2004 06:55:28 -0000 +@@ -44,7 +44,7 @@ + + /* 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. */ +@@ -52,9 +52,6 @@ + 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; +- + /* Load the TSS. */ + ltr(KERNEL_TSS); + } diff --git a/debian/patches/43_debvice_port_fix.patch b/debian/patches/43_debvice_port_fix.patch new file mode 100644 index 0000000..49460a9 --- /dev/null +++ b/debian/patches/43_debvice_port_fix.patch @@ -0,0 +1,57 @@ +#DPATCHLEVEL=1 + +2006-01-02 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * i386/i386/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; diff --git a/debian/patches/44_more_ports.patch b/debian/patches/44_more_ports.patch new file mode 100644 index 0000000..39fa0ea --- /dev/null +++ b/debian/patches/44_more_ports.patch @@ -0,0 +1,50 @@ +#DPATCHLEVEL=1 + +2006-01-02 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * i386/i386at/iopl.c (iopl_port_list): Add timer controler port. + * i386/i386at/kd.c (vga_port_list): Renamed to ... + (kd_port_list): ... this. Add timer and speaker ports. + + +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() diff --git a/debian/patches/45_io_per_task.patch b/debian/patches/45_io_per_task.patch new file mode 100644 index 0000000..b9290b9 --- /dev/null +++ b/debian/patches/45_io_per_task.patch @@ -0,0 +1,591 @@ +#DPATCHLEVEL=1 + +2006-01-02 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * i386/i386/iopb.c: IO ports permissions are now task-based. + (i386_io_port_add): Fix TSS access and locking accordingly. + (i386_io_port_remove): Likewise. + (i386_io_port_list): Likewise. + (iopb_check_mapping): Likewise. + * i386/i386/pcb.c (switch_ktss): Now takes next thread as parameter + for TSS switch to be task-based. Fix all callers. + (switch_context): Likewise. + (pcb_module_init): Move iopb initialization to ... + (machine_task_module_init): ... here. New function. + (pcb_terminate): Move iopb termination to ... + (machine_task_terminate): ... here. New function. + (machine_task_init): New function. + (machine_task_collect): Likewise. + (thread_setstatus): TSS is now task-based, fix TSS and locking + accordingly. + (thread_getstatus): Likewise. + * i386/i386/thread.h (i386_machine_state): Move io_tss member to ... + (machine_task): ... here. New structure. + + * i386/i386at/iopl.c (iopl_emulate): TSS is now task-based, fix TSS + and locking accordingly. + + * kern/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. + * kern/task.h: Include <machine/thread.h> for machine_task_t. + (task): Add new machine member. + + +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); + } + + /* + +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 + + +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) diff --git a/debian/patches/46_io_device.patch b/debian/patches/46_io_device.patch new file mode 100644 index 0000000..731d30f --- /dev/null +++ b/debian/patches/46_io_device.patch @@ -0,0 +1,117 @@ +2006-01-07 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * i386/i386/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, |
