[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;
- TSS switching,
Marcus Brinkmann <=
- Re: TSS switching, Roland McGrath, 2001/10/07
- Re: TSS switching, Marcus Brinkmann, 2001/10/08
- Re: TSS switching, Roland McGrath, 2001/10/08
- Re: TSS switching, Marcus Brinkmann, 2001/10/10
- Re: TSS switching, Roland McGrath, 2001/10/10
- Re: TSS switching, Marcus Brinkmann, 2001/10/10
- Re: TSS switching, Roland McGrath, 2001/10/10
- Re: TSS switching, Marcus Brinkmann, 2001/10/12
- Re: TSS switching, Roland McGrath, 2001/10/12
- Re: TSS switching, Marcus Brinkmann, 2001/10/15