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; _______________________________________________ Bug-hurd mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-hurd