[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);
}
- [bug #15295] Mach lets processes write to I/O ports, (continued)
- [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/02
- [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/02
- [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/02
- [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/02
- [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/02
- [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/02
- Re: [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/02
- [bug #15295] Mach lets processes write to I/O ports, anonymous, 2006/01/06
- [bug #15295] Mach lets processes write to I/O ports, anonymous, 2006/01/06
- [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/06
- Re: [bug #15295] Mach lets processes write to I/O ports,
Samuel Thibault <=
- [bug #15295] Mach lets processes write to I/O ports, anonymous, 2006/01/13
- [bug #15295] Mach lets processes write to I/O ports, anonymous, 2006/01/13
- [bug #15295] Mach lets processes write to I/O ports, anonymous, 2006/01/13
- [bug #15295] Mach lets processes write to I/O ports, anonymous, 2006/01/13
- [bug #15295] Mach lets processes write to I/O ports, anonymous, 2006/01/13
- [bug #15295] Mach lets processes write to I/O ports, anonymous, 2006/01/13
- [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/13
Re: [bug #15295] Mach lets processes write to I/O ports, Samuel Thibault, 2006/01/02