[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Patch for i/o permission control in GNU Mach (was: I/O permission contro
From: |
Thomas Schwinge |
Subject: |
Patch for i/o permission control in GNU Mach (was: I/O permission control in OSKit-Mach) |
Date: |
Wed, 25 Apr 2007 18:45:44 +0200 |
User-agent: |
Mutt/1.5.11 |
Hello!
On Wed, Apr 25, 2007 at 03:07:34PM +0200, I wrote:
> Now that it finally works, I can now polish and test my patch a bit. :-)
Here we go.
There are a few places marked with ``TODO''. Please comment on them.
If someone wants to see my testing equipment, I'll happily provide it.
I worked on integrating Marcus's work into the GNU Mach branch and did
not really check that all the low level details are correct -- I would
assume that checking those has been done at the time Marcus's patch was
installed into the OSKit-Mach branch.
With this patch, glibc's `ioperm' call will ``automagically'' begin to
work, as soon as it's been recompiled with the modified GNU Mach header
and definition files in place.
#v+
2007-04-25 Thomas Schwinge <tschwinge@gnu.org>
* i386/i386/io_port.h: Remove file.
* i386/i386at/kd.c: TODO.
* i386/Makefrag.am (libkernel_a_SOURCES): Add `i386/i386/io_perm.c',
`i386/i386/io_perm.h', `i386/i386/machine_task.c', `i386/i386/task.h'
and remove `i386/i386/io_port.h', `i386/i386/iopb.c',
`i386/i386/iopb.h'.
* include/stddef.h: New file.
* i386/i386/io_perm.c: Include <string.h>, <device/device_emul.h> and
don't include <oskit/ds_oskit.h>.
(io_perm_device_emulation_ops): New variable.
(dev_open_alloc, setup_no_senders): Remove declarations.
(convert_io_perm_to_port, convert_port_to_io_perm, io_perm_deallocate):
Rewrite.
(no_senders): New function.
(i386_io_perm_create, i386_io_perm_modify): Rewrite partially, to adapt
to the GNU Mach environment.
* i386/i386/io_perm.h: Include <device/dev_hdr.h> and
<ipc/ipc_types.h>.
(io_perm, io_perm_t): New structure and accompanying type definition.
(IO_PERM_NULL): Define.
* i386/i386/locore.S (ktss): Move variable to...
* i386/i386/ktss.c: ... here, make it a ``struct task_tss''.
(ktss_init): Initialize the `task_tss' structure and the i/o permission
bit map.
* i386/i386/ktss.h: Adapt to that.
* i386/i386/machine_task.c (machine_task_module_init): Adapt the `zinit'
call to the GNU Mach environment.
* i386/i386/mp_desc.c: Include <machine/ktss.h>.
* i386/i386/tss.h: Include <machine/io_perm.h>.
(task_tss): New structure, equivalent to the OSKit-Mach one.
* i386/include/mach/i386/mach_i386.defs: Don't include
<device/device_types.defs>.
(device_list_t): Remove type.
* i386/include/mach/i386/mach_i386_types.h (device_list_t): Remove type
definition.
2007-04-25 Marcus Brinkmann <marcus@gnu.org>
* i386/i386/iopb.h, i386/i386/iopb.c: Obsolete files removed.
* i386/i386/pcb.c (switch_context): Update the I/O permission
bitmap from stack_handoff() here (not only in stack_handoff()).
* i386/i386/machine_task.c (machine_task_module_init): Set
ZONE_COLLECTABLE and ZONE_EXHAUSTIBLE flags for the iopb zone.
Requested by Roland McGrath <roland@frob.com>.
* i386/i386/io_perm.h: New file.
* i386/i386/io_perm.c: New file.
* i386/i386/machine_task.c: New file.
* i386/i386/mp_desc.h: (struct mp_desc_table): Change type of ktss to
struct task_tss.
(mp_ktss): Likewise for array of pointers to the struct.
* i386/i386/mp_desc.c: Include `machine/tss.h' and `machine/io_perm.h'.
(mp_ktss): Change type to array of struct task_tss.
(mp_desc_init): Cast pointer to x86_tss into pointer to task_tss,
and use size of struct task_tss instead size of struct x86_tss.
Initialize the task_tss structure.
* i386/i386/pcb.c: Include `stddef.h' and `machine/tss.h'.
(iopb_create, iopb_destroy): Prototypes removed.
(curr_ktss): Cast pointer to base_tss to pointer to struct
task_tss.
(switch_ktss): Always use kernel TSS.
(update_ktss_iopb): New function.
(stack_handoff): Call update_ktss_iopb.
(pcb_module_init): Do not call iopb_init.
(pcb_terminate): Do not call iopb_destroy.
(thread_setstatus): Remove local variable tss.
(thread_getstatus): Rewrite i386_ISA_PORT_MAP_STATE case handler.
* i386/i386/task.h: New file.
* i386/i386/thread.h: Do not include `i386/iopb.h'.
(struct i386_machine_state): Remove member io_tss.
* i386/include/mach/i386/mach_i386.defs [KERNEL_SERVER]: Include
`machine/io_perm.h'. Define intran, outtran and destructor.
(io_port_t): New type.
(io_perm_t): Likewise.
(i386_io_port_add): Interface removed.
(i386_io_port_remove): Likewise.
(i386_io_port_list): Likewise.
(i386_io_perm_create): New interface.
(i386_io_perm_modify): Likewise.
* i386/include/mach/i386/mach_i386_types.h [MACH_KERNEL]: Include
`i386/io_perm.h'.
[!MACH_KERNEL]: Define types io_port_t and io_perm_t.
* kern/task.c (task_init): Call machine_task_module_init.
(task_create): Call machine_task_init.
(task_deallocate): Call machine_task_terminate.
(task_collect_scan): Call machine_task_collect.
* task.h: Include `machine/task.h'.
(struct task): Add member machine.
Index: i386/Makefrag.am
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/Attic/Makefrag.am,v
retrieving revision 1.1.2.9
diff -u -p -r1.1.2.9 Makefrag.am
--- i386/Makefrag.am 1 Apr 2007 22:10:39 -0000 1.1.2.9
+++ i386/Makefrag.am 25 Apr 2007 16:36:32 -0000
@@ -85,9 +85,8 @@ libkernel_a_SOURCES += \
i386/i386/idt.c \
i386/i386/idt_inittab.S \
i386/i386/io_map.c \
- i386/i386/io_port.h \
- i386/i386/iopb.c \
- i386/i386/iopb.h \
+ i386/i386/io_perm.c \
+ i386/i386/io_perm.h \
i386/i386/ipl.h \
i386/i386/ktss.c \
i386/i386/ktss.h \
@@ -101,6 +100,7 @@ libkernel_a_SOURCES += \
i386/i386/loose_ends.c \
i386/i386/mach_param.h \
i386/i386/machine_routines.h \
+ i386/i386/machine_task.c \
i386/i386/machspl.h \
i386/i386/mp_desc.c \
i386/i386/mp_desc.h \
@@ -120,6 +120,7 @@ libkernel_a_SOURCES += \
i386/i386/setjmp.h \
i386/i386/spl.S \
i386/i386/spl.h \
+ i386/i386/task.h \
i386/i386/thread.h \
i386/i386/time_stamp.h \
i386/i386/timer.h \
Index: i386/i386/io_perm.c
===================================================================
RCS file: i386/i386/io_perm.c
diff -N i386/i386/io_perm.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ i386/i386/io_perm.c 25 Apr 2007 16:36:32 -0000
@@ -0,0 +1,313 @@
+/* Manipulate I/O permission bitmap objects.
+
+ Copyright (C) 2002, 2007 Free Software Foundation, Inc.
+
+ Written by Marcus Brinkmann. Glued into GNU Mach by Thomas Schwinge.
+
+ This file is part of GNU Mach.
+
+ GNU Mach is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <string.h>
+
+#include <mach/boolean.h>
+#include <mach/kern_return.h>
+
+#include <ipc/ipc_port.h>
+
+#include <kern/zalloc.h>
+#include <kern/lock.h>
+#include <kern/queue.h>
+#include <kern/thread.h>
+
+#include <device/dev_hdr.h>
+#include <device/device_emul.h>
+#include <device/device_port.h>
+
+#include "io_perm.h"
+#include "gdt.h"
+
+/* Our device emulation ops. See below, at the bottom of this file. */
+static struct device_emulation_ops io_perm_device_emulation_ops;
+
+
+/* The outtran which allows MIG to convert an io_perm_t object to a port
+ representing it. */
+ipc_port_t
+convert_io_perm_to_port (io_perm_t io_perm)
+{
+ if (io_perm == IO_PERM_NULL)
+ return IP_NULL;
+
+ ipc_port_t port;
+
+ port = ipc_port_make_send (io_perm->port);
+
+ return port;
+}
+
+
+/* The intran which allows MIG to convert a port representing an
+ io_perm_t object to the object itself. */
+io_perm_t
+convert_port_to_io_perm (ipc_port_t port)
+{
+ device_t device;
+
+ device = dev_port_lookup (port);
+
+ if (device == DEVICE_NULL)
+ return IO_PERM_NULL;
+
+ io_perm_t io_perm;
+
+ io_perm = device->emul_data;
+
+ return io_perm;
+}
+
+#if REMOVE_ME
+/* TODO. Fix this comment. */
+/* The destructor which is called when the last send right to a port
+ representing an io_perm_t object vanishes. */
+void
+io_perm_deallocate (io_perm_t io_perm)
+{
+ /* TODO. Is there anything to deallocate in here? I don't think so, as we
+ don't allocate anything in `convert_port_to_io_perm'. */
+}
+#endif
+
+/* Our ``no senders'' handling routine. Deallocate the object. */
+static
+void
+no_senders (mach_no_senders_notification_t *notification)
+{
+ io_perm_t io_perm;
+
+ io_perm = convert_port_to_io_perm
+ ((ipc_port_t) notification->not_header.msgh_remote_port);
+
+ assert (io_perm != IO_PERM_NULL);
+
+ ip_lock (io_perm->port); /* TODO. Actually needed? */
+ ipc_kobject_set (io_perm->port, IKO_NULL, IKOT_NONE);
+ ipc_port_dealloc_kernel (io_perm->port);
+
+ kfree ((vm_offset_t) io_perm, sizeof *io_perm);
+}
+
+
+/* Initialize bitmap by setting all bits to OFF == 1. */
+static inline void
+io_bitmap_init (unsigned char *iopb)
+{
+ memset (iopb, ~0, IOPB_BYTES);
+}
+
+
+/* Set selected bits in bitmap to ON == 0. */
+static inline void
+io_bitmap_set (unsigned char *iopb, io_port_t from, io_port_t to)
+{
+ do
+ iopb[from >> 3] &= ~(1 << (from & 0x7));
+ while (from++ != to);
+}
+
+
+/* Set selected bits in bitmap to OFF == 1. */
+static inline void
+io_bitmap_clear (unsigned char *iopb, io_port_t from, io_port_t to)
+{
+ do
+ iopb[from >> 3] |= (1 << (from & 0x7));
+ while (from++ != to);
+}
+
+
+/* Request a new port IO_PERM that represents the capability to access
+ the I/O ports [FROM; TO] directly. MASTER_PORT is the master device port.
+
+ The function returns KERN_INVALID_ARGUMENT if TARGET_TASK is not a task,
+ or FROM is greater than TO.
+
+ The function is exported. */
+kern_return_t
+i386_io_perm_create (ipc_port_t master_port, io_port_t from, io_port_t to,
+ io_perm_t *new)
+{
+ /* TODO. Check for limits [0;IOPB_MAX)? */
+ if (master_port != master_device_port || from > to)
+ return KERN_INVALID_ARGUMENT;
+
+ io_perm_t io_perm;
+
+ io_perm = (io_perm_t) kalloc (sizeof *io_perm);
+ if (io_perm == NULL)
+ return KERN_RESOURCE_SHORTAGE;
+
+ io_perm->from = from;
+ io_perm->to = to;
+
+ io_perm->port = ipc_port_alloc_kernel ();
+ if (io_perm->port == IP_NULL)
+ {
+ kfree ((vm_offset_t) io_perm, sizeof *io_perm);
+ return KERN_RESOURCE_SHORTAGE;
+ }
+
+ /* Set up the dummy device. */
+ ipc_kobject_set(io_perm->port,
+ (ipc_kobject_t) &io_perm->device, IKOT_DEVICE);
+ io_perm->device.emul_data = io_perm;
+ io_perm->device.emul_ops = &io_perm_device_emulation_ops;
+
+ ipc_port_t notify;
+
+ notify = ipc_port_make_sonce(io_perm->port);
+ ip_lock(device->port);
+ ipc_port_nsrequest(io_perm->port, 1, notify, ¬ify);
+ assert(notify == IP_NULL);
+
+ *new = io_perm;
+
+ return KERN_SUCCESS;
+}
+
+
+/* From pcb.c. */
+extern void update_ktss_iopb (unsigned char *new_iopb, int last);
+
+
+/* Modify the I/O permissions for TARGET_TASK. If ENABLE is TRUE, the
+ permission to acces the I/O ports specified by IO_PERM is granted,
+ otherwise it is withdrawn.
+
+ The function returns KERN_INVALID_ARGUMENT if TARGET_TASK is not a valid
+ task or IO_PERM not a valid I/O permission port.
+
+ The function is exported. */
+kern_return_t
+i386_io_perm_modify (task_t target_task, io_perm_t io_perm, boolean_t enable)
+{
+ io_port_t from, to;
+ unsigned char *iopb;
+ io_port_t iopb_size;
+
+ if (target_task == TASK_NULL || io_perm == IO_PERM_NULL)
+ return KERN_INVALID_ARGUMENT;
+
+ from = io_perm->from;
+ to = io_perm->to;
+
+ simple_lock (&target_task->machine.iopb_lock);
+ iopb = target_task->machine.iopb;
+ iopb_size = target_task->machine.iopb_size;
+
+ if (!enable && !iopb_size)
+ {
+ simple_unlock (&target_task->machine.iopb_lock);
+ return KERN_SUCCESS;
+ }
+
+ if (!iopb)
+ {
+ simple_unlock (&target_task->machine.iopb_lock);
+ /* TODO. Does this have to be deallocated again? (Thinking about
+ `no_senders'.) Probably not, because glibc's `ioperm' call would be
+ rather difficult to implement then.*/
+ iopb = (unsigned char *) zalloc (machine_task_iopb_zone);
+ simple_lock (&target_task->machine.iopb_lock);
+ if (target_task->machine.iopb)
+ {
+ if (iopb)
+ zfree (machine_task_iopb_zone, (vm_offset_t) iopb);
+ iopb = target_task->machine.iopb;
+ iopb_size = target_task->machine.iopb_size;
+ }
+ else if (iopb)
+ {
+ target_task->machine.iopb = iopb;
+ io_bitmap_init (iopb);
+ }
+ else
+ /* TODO. Need some unlocking here? */
+ return KERN_RESOURCE_SHORTAGE;
+ }
+
+ if (enable)
+ {
+ io_bitmap_set (iopb, from, to);
+ if ((to >> 3) + 1 > iopb_size)
+ target_task->machine.iopb_size = (to >> 3) + 1;
+ }
+ else
+ {
+ if ((from >> 3) + 1 > iopb_size)
+ {
+ simple_unlock (&target_task->machine.iopb_lock);
+ return KERN_SUCCESS;
+ }
+
+ io_bitmap_clear (iopb, from, to);
+ while (iopb_size > 0 && iopb[iopb_size - 1] == 0xff)
+ iopb_size--;
+ target_task->machine.iopb_size = iopb_size;
+ }
+
+#if NCPUS>1
+#warning SMP support missing (notify all CPUs running threads in that of the
I/O bitmap change).
+#endif
+ if (target_task == current_task())
+ update_ktss_iopb (iopb, target_task->machine.iopb_size);
+
+ simple_unlock (&target_task->machine.iopb_lock);
+ return KERN_SUCCESS;
+}
+
+/* We are some sort of Mach device... */
+static struct device_emulation_ops io_perm_device_emulation_ops =
+{
+ /* ... in order to be easily able to receive a ``no senders'' notification
+ which we then use to deallocate ourselves. */
+ .no_senders = no_senders
+};
Index: i386/i386/io_perm.h
===================================================================
RCS file: i386/i386/io_perm.h
diff -N i386/i386/io_perm.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ i386/i386/io_perm.h 25 Apr 2007 16:36:32 -0000
@@ -0,0 +1,66 @@
+/* Data types for I/O permission bitmap objects.
+
+ Copyright (C) 2002, 2007 Free Software Foundation, Inc.
+
+ Written by Marcus Brinkmann. Glued into GNU Mach by Thomas Schwinge.
+
+ This file is part of GNU Mach.
+
+ GNU Mach is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef _I386_IO_PERM_H_
+#define _I386_IO_PERM_H_
+
+#include <device/dev_hdr.h>
+#include <ipc/ipc_types.h>
+
+
+/* The highest possible I/O port. ISA bus allows ports 0..3ff, but
+ accelerator cards are funky. */
+#define IOPB_MAX 0xFFFF
+
+/* The number of bytes needed to hold all permission bits. */
+#define IOPB_BYTES (((IOPB_MAX + 1) + 7) / 8)
+
+/* An offset that points outside of the permission bitmap, used to
+ disable all permission. */
+#define IOPB_INVAL 0x2FFF
+
+
+/* The type of an I/O port address. */
+typedef unsigned short io_port_t;
+
+
+struct io_perm
+{
+ /* We use a ``struct device'' for easy management. */
+ struct device device;
+
+ ipc_port_t port;
+
+ io_port_t from, to;
+};
+
+typedef struct io_perm *io_perm_t;
+
+#define IO_PERM_NULL ((io_perm_t) 0)
+
+extern io_perm_t convert_port_to_io_perm (ipc_port_t);
+extern ipc_port_t convert_io_perm_to_port (io_perm_t);
+#if REMOVE_ME
+extern void io_perm_deallocate (io_perm_t);
+#endif
+
+#endif
Index: i386/i386/ktss.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/Attic/ktss.c,v
retrieving revision 1.1.1.1.4.1
diff -u -p -r1.1.1.1.4.1 ktss.c
--- i386/i386/ktss.c 13 Nov 2006 21:30:36 -0000 1.1.1.1.4.1
+++ i386/i386/ktss.c 25 Apr 2007 16:36:32 -0000
@@ -36,6 +36,9 @@
#include "gdt.h"
#include "ktss.h"
+/* A kernel TSS with a complete I/O bitmap. */
+struct task_tss ktss;
+
void
ktss_init()
{
@@ -44,16 +47,15 @@ ktss_init()
/* Initialize the master TSS descriptor. */
fill_gdt_descriptor(KERNEL_TSS,
- kvtolin(&ktss), sizeof(ktss)+65536/8+1-1,
+ kvtolin(&ktss), sizeof(struct task_tss) - 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);
-
+ ktss.tss.ss0 = KERNEL_DS;
+ ktss.tss.esp0 = (unsigned)(exception_stack+1024);
+ ktss.tss.io_bit_map_offset = IOPB_INVAL;
/* Set the last byte in the I/O bitmap to all 1's. */
- ((unsigned char*)&ktss)[sizeof(ktss)+65536/8] = 0xff;
+ ktss.barrier = 0xff;
/* Load the TSS. */
ltr(KERNEL_TSS);
Index: i386/i386/ktss.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/Attic/ktss.h,v
retrieving revision 1.2
diff -u -p -r1.2 ktss.h
--- i386/i386/ktss.h 5 Apr 2001 06:39:20 -0000 1.2
+++ i386/i386/ktss.h 25 Apr 2007 16:36:32 -0000
@@ -25,6 +25,6 @@
#include "tss.h"
-extern struct i386_tss ktss;
+extern struct task_tss ktss;
#endif /* _I386_KTSS_ */
Index: i386/i386/locore.S
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/locore.S,v
retrieving revision 1.6.2.7
diff -u -p -r1.6.2.7 locore.S
--- i386/i386/locore.S 20 Dec 2006 21:13:45 -0000 1.6.2.7
+++ i386/i386/locore.S 25 Apr 2007 16:36:33 -0000
@@ -1441,12 +1441,3 @@ Entry(cpu_shutdown)
xor %ecx,%ecx /* generate a divide by zero */
div %ecx,%eax /* reboot now */
ret /* this will "never" be executed */
-
-
-/*
- * Allocate enough space for a kernel TSS with a complete I/O bitmap,
- * for making v86-mode BIOS calls. XXX
- */
- .data
- .globl EXT(ktss)
- .comm EXT(ktss),0x68+65536/8+1
Index: i386/i386/machine_task.c
===================================================================
RCS file: i386/i386/machine_task.c
diff -N i386/i386/machine_task.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ i386/i386/machine_task.c 25 Apr 2007 16:36:33 -0000
@@ -0,0 +1,79 @@
+/* Machine specific data for a task on i386.
+
+ Copyright (C) 2002, 2007 Free Software Foundation, Inc.
+
+ Written by Marcus Brinkmann. Glued into GNU Mach by Thomas Schwinge.
+
+ This file is part of GNU Mach.
+
+ GNU Mach is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <kern/lock.h>
+#include <mach/mach_types.h>
+#include <kern/zalloc.h>
+#include <kern/mach_param.h>
+#include <machine/task.h>
+
+#include <machine/io_perm.h>
+
+
+/* The zone which holds our IO permission bitmaps. */
+zone_t machine_task_iopb_zone;
+
+
+/* Initialize the machine task module. The function is called once at
+ start up by task_init in kern/task.c. */
+void
+machine_task_module_init (void)
+{
+ machine_task_iopb_zone = zinit (IOPB_BYTES, 0,
+ TASK_MAX * IOPB_BYTES,
+ IOPB_BYTES,
+ ZONE_COLLECTABLE | ZONE_EXHAUSTIBLE,
+ "i386 machine task iopb");
+}
+
+
+/* Initialize the machine specific part of task TASK. */
+void
+machine_task_init (task_t task)
+{
+ task->machine.iopb_size = 0;
+ task->machine.iopb = 0;
+ simple_lock_init (&task->machine.iopb_lock);
+}
+
+
+/* Destroy the machine specific part of task TASK and release all
+ associated resources. */
+void
+machine_task_terminate (task_t task)
+{
+ if (task->machine.iopb)
+ zfree (machine_task_iopb_zone, (vm_offset_t) task->machine.iopb);
+}
+
+
+/* Try to release as much memory from the machine specific data in
+ task TASK. */
+void
+machine_task_collect (task_t task)
+{
+ if (task->machine.iopb_size == 0 && task->machine.iopb)
+ {
+ zfree (machine_task_iopb_zone, (vm_offset_t) task->machine.iopb);
+ task->machine.iopb = 0;
+ }
+}
Index: i386/i386/mp_desc.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/mp_desc.c,v
retrieving revision 1.1.1.1.4.4
diff -u -p -r1.1.1.1.4.4 mp_desc.c
--- i386/i386/mp_desc.c 10 Nov 2006 01:22:57 -0000 1.1.1.1.4.4
+++ i386/i386/mp_desc.c 25 Apr 2007 16:36:33 -0000
@@ -35,6 +35,9 @@
#include <i386/mp_desc.h>
#include <i386/lock.h>
+#include <machine/ktss.h>
+#include <machine/tss.h>
+#include <machine/io_perm.h>
/*
* The i386 needs an interrupt stack to keep the PCB stack from being
@@ -82,7 +85,7 @@ struct mp_desc_table *mp_desc_table[NCPU
/*
* Pointer to TSS for access in load_context.
*/
-struct i386_tss *mp_ktss[NCPUS] = { 0 };
+struct task_tss *mp_ktss[NCPUS] = { 0 };
/*
* Pointer to GDT to reset the KTSS busy bit.
@@ -95,7 +98,6 @@ struct real_descriptor *mp_gdt[NCPUS] =
extern struct real_gate idt[IDTSZ];
extern struct real_descriptor gdt[GDTSZ];
extern struct real_descriptor ldt[LDTSZ];
-extern struct i386_tss ktss;
/*
* Allocate and initialize the per-processor descriptor tables.
@@ -112,7 +114,7 @@ mp_desc_init(mycpu)
* Master CPU uses the tables built at boot time.
* Just set the TSS and GDT pointers.
*/
- mp_ktss[mycpu] = &ktss;
+ mp_ktss[mycpu] = (struct task_tss *) &ktss;
mp_gdt[mycpu] = gdt;
return 0;
}
@@ -140,7 +142,7 @@ mp_desc_init(mycpu)
ldt,
sizeof(ldt));
memset(&mpt->ktss, 0,
- sizeof(struct i386_tss));
+ sizeof(struct task_tss));
/*
* Fix up the entries in the GDT to point to
@@ -152,11 +154,12 @@ mp_desc_init(mycpu)
ACC_P|ACC_PL_K|ACC_LDT, 0);
fill_descriptor(&mpt->gdt[sel_idx(KERNEL_TSS)],
(unsigned)&mpt->ktss,
- sizeof(struct i386_tss) - 1,
+ sizeof(struct task_tss) - 1,
ACC_P|ACC_PL_K|ACC_TSS, 0);
- mpt->ktss.ss0 = KERNEL_DS;
- mpt->ktss.io_bit_map_offset = 0x0FFF; /* no IO bitmap */
+ mpt->ktss.tss.ss0 = KERNEL_DS;
+ mpt->ktss.tss.io_bit_map_offset = IOPB_INVAL;
+ mpt->ktss.barrier = 0xFF;
return mpt;
}
Index: i386/i386/mp_desc.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/mp_desc.h,v
retrieving revision 1.2.2.1
diff -u -p -r1.2.2.1 mp_desc.h
--- i386/i386/mp_desc.h 15 Oct 2006 14:59:03 -0000 1.2.2.1
+++ i386/i386/mp_desc.h 25 Apr 2007 16:36:33 -0000
@@ -52,7 +52,7 @@ struct mp_desc_table {
struct real_gate idt[IDTSZ]; /* IDT */
struct real_descriptor gdt[GDTSZ]; /* GDT */
struct real_descriptor ldt[LDTSZ]; /* LDT */
- struct i386_tss ktss;
+ struct task_tss ktss;
};
/*
@@ -63,7 +63,7 @@ extern struct mp_desc_table *mp_desc_tab
/*
* The kernel TSS gets its own pointer.
*/
-extern struct i386_tss *mp_ktss[NCPUS];
+extern struct task_tss *mp_ktss[NCPUS];
/*
* So does the GDT.
Index: i386/i386/pcb.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/pcb.c,v
retrieving revision 1.2.4.9
diff -u -p -r1.2.4.9 pcb.c
--- i386/i386/pcb.c 4 Jan 2007 23:51:02 -0000 1.2.4.9
+++ i386/i386/pcb.c 25 Apr 2007 16:36:33 -0000
@@ -24,6 +24,7 @@
* the rights to redistribute these changes.
*/
+#include <stddef.h>
#include <string.h>
#include <mach/std_types.h>
@@ -43,7 +44,6 @@
#include <i386/thread.h>
#include <i386/proc_reg.h>
#include <i386/seg.h>
-#include <i386/tss.h>
#include <i386/user_ldt.h>
#include <i386/fpu.h>
#include "eflags.h"
@@ -52,6 +52,8 @@
#include "ktss.h"
#include "pcb.h"
+#include <machine/tss.h>
+
#if NCPUS > 1
#include <i386/mp_desc.h>
#endif
@@ -59,8 +61,6 @@
extern thread_t Switch_context();
extern void Thread_continue();
-extern iopb_tss_t iopb_create();
-extern void iopb_destroy();
extern void user_ldt_free();
zone_t pcb_zone;
@@ -126,7 +126,7 @@ vm_offset_t stack_detach(thread)
#define curr_ktss(mycpu) (mp_ktss[mycpu])
#else
#define curr_gdt(mycpu) ((void)(mycpu), gdt)
-#define curr_ktss(mycpu) ((void)(mycpu), &ktss)
+#define curr_ktss(mycpu) ((void)(mycpu), (struct task_tss
*)&ktss)
#endif
#define gdt_desc_p(mycpu,sel) \
@@ -137,7 +137,6 @@ void switch_ktss(pcb)
{
int mycpu = cpu_number();
{
- register iopb_tss_t tss = pcb->ims.io_tss;
vm_offset_t pcb_stack_top;
/*
@@ -153,25 +152,7 @@ void switch_ktss(pcb)
? (int) (&pcb->iss + 1)
: (int) (&pcb->iss.v86_segs);
- if (tss == 0) {
- /*
- * No per-thread IO permissions.
- * Use standard kernel TSS.
- */
- if (!(gdt_desc_p(mycpu,KERNEL_TSS)->access & ACC_TSS_BUSY))
- set_tr(KERNEL_TSS);
- curr_ktss(mycpu)->esp0 = pcb_stack_top;
- }
- else {
- /*
- * Set the IO permissions. Use this thread`s TSS.
- */
- *gdt_desc_p(mycpu,USER_TSS)
- = *(struct real_descriptor *)tss->iopb_desc;
- tss->tss.esp0 = pcb_stack_top;
- set_tr(USER_TSS);
- gdt_desc_p(mycpu,KERNEL_TSS)->access &= ~ ACC_TSS_BUSY;
- }
+ curr_ktss(mycpu)->tss.esp0 = pcb_stack_top;
}
{
@@ -207,6 +188,24 @@ void switch_ktss(pcb)
}
+/* If NEW_IOPB is not null, the SIZE denotes the number of bytes in
+ the new bitmap. Expects iopb_lock to be held. */
+void
+update_ktss_iopb (unsigned char *new_iopb, io_port_t size)
+{
+ struct task_tss *tss = curr_ktss (cpu_number ());
+
+ if (new_iopb && size > 0)
+ {
+ tss->tss.io_bit_map_offset
+ = offsetof (struct task_tss, barrier) - size;
+ memcpy (((char *) tss) + tss->tss.io_bit_map_offset,
+ new_iopb, size);
+ }
+ else
+ tss->tss.io_bit_map_offset = IOPB_INVAL;
+}
+
/*
* stack_handoff:
*
@@ -236,6 +235,19 @@ void stack_handoff(old, new)
old, mycpu);
PMAP_ACTIVATE_USER(vm_map_pmap(new_task->map),
new, mycpu);
+
+ simple_lock (&new_task->machine.iopb_lock);
+#if NCPUS>1
+#warning SMP support missing (avoid races with io_perm_modify).
+#else
+ /* This optimization only works on a single processor
+ machine, where old_task's iopb can not change while
+ we are switching. */
+ if (old_task->machine.iopb || new_task->machine.iopb)
+#endif
+ update_ktss_iopb (new_task->machine.iopb,
+ new_task->machine.iopb_size);
+ simple_unlock (&new_task->machine.iopb_lock);
}
}
@@ -298,6 +310,19 @@ thread_t switch_context(old, continuatio
old, mycpu);
PMAP_ACTIVATE_USER(vm_map_pmap(new_task->map),
new, mycpu);
+
+ simple_lock (&new_task->machine.iopb_lock);
+#if NCPUS>1
+#warning SMP support missing (avoid races with io_perm_modify).
+#else
+ /* This optimization only works on a single processor
+ machine, where old_task's iopb can not change while
+ we are switching. */
+ if (old_task->machine.iopb || new_task->machine.iopb)
+#endif
+ update_ktss_iopb (new_task->machine.iopb,
+ new_task->machine.iopb_size);
+ simple_unlock (&new_task->machine.iopb_lock);
}
}
@@ -317,7 +342,6 @@ void pcb_module_init()
0, "i386 pcb state");
fpu_module_init();
- iopb_init();
}
void pcb_init(thread)
@@ -361,8 +385,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)
@@ -516,7 +538,6 @@ 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;
if (count < i386_ISA_PORT_MAP_STATE_COUNT)
return(KERN_INVALID_ARGUMENT);
@@ -673,32 +694,20 @@ 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;
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;
-
- if (tss == 0) {
- int i;
- /*
- * The thread has no ktss, so no IO permissions.
- */
-
- for (i = 0; i < sizeof state->pm; i++)
- state->pm[i] = 0xff;
- } else {
- /*
- * The thread has its own ktss.
- */
-
- memcpy(state->pm,
- tss->bitmap,
- sizeof state->pm);
- }
+ simple_lock (&thread->task->machine.iopb_lock);
+ if (thread->task->machine.iopb == 0)
+ memset (state->pm, 0xff, sizeof state->pm);
+ else
+ memcpy((char *) state->pm,
+ (char *) thread->task->machine.iopb,
+ sizeof state->pm);
+ simple_unlock (&thread->task->machine.iopb_lock);
*count = i386_ISA_PORT_MAP_STATE_COUNT;
break;
Index: i386/i386/task.h
===================================================================
RCS file: i386/i386/task.h
diff -N i386/i386/task.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ i386/i386/task.h 25 Apr 2007 16:36:33 -0000
@@ -0,0 +1,61 @@
+/* Data types for machine specific parts of tasks on i386.
+
+ Copyright (C) 2002, 2007 Free Software Foundation, Inc.
+
+ Written by Marcus Brinkmann. Glued into GNU Mach by Thomas Schwinge.
+
+ This file is part of GNU Mach.
+
+ GNU Mach is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef _I386_TASK_H_
+#define _I386_TASK_H_
+
+#include <kern/kern_types.h>
+#include <kern/zalloc.h>
+
+/* The machine specific data of a task. */
+struct machine_task
+{
+ /* A lock protecting iopb_size and iopb. */
+ decl_simple_lock_data (, iopb_lock);
+
+ /* The highest I/O port number enabled. */
+ int iopb_size;
+
+ /* The I/O permission bitmap. */
+ unsigned char *iopb;
+};
+typedef struct machine_task machine_task_t;
+
+
+extern zone_t machine_task_iopb_zone;
+
+/* Initialize the machine task module. The function is called once at
+ start up by task_init in kern/task.c. */
+void machine_task_module_init (void);
+
+/* Initialize the machine specific part of task TASK. */
+void machine_task_init (task_t);
+
+/* Destroy the machine specific part of task TASK and release all
+ associated resources. */
+void machine_task_terminate (task_t);
+
+/* Try to release as much memory from the machine specific data in
+ task TASK. */
+void machine_task_collect (task_t);
+
+#endif /* _I386_TASK_H_ */
Index: i386/i386/thread.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/thread.h,v
retrieving revision 1.3.2.1
diff -u -p -r1.3.2.1 thread.h
--- i386/i386/thread.h 5 Nov 2006 20:39:24 -0000 1.3.2.1
+++ i386/i386/thread.h 25 Apr 2007 16:36:33 -0000
@@ -39,7 +39,6 @@
#include <kern/lock.h>
-#include <i386/iopb.h>
#include <i386/tss.h>
#include "gdt.h"
@@ -158,7 +157,6 @@ struct i386_interrupt_state {
*/
struct i386_machine_state {
- iopb_tss_t io_tss;
struct user_ldt * ldt;
struct i386_fpsave_state *ifps;
struct v86_assist_state v86s;
Index: i386/i386/tss.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/tss.h,v
retrieving revision 1.1
diff -u -p -r1.1 tss.h
--- i386/i386/tss.h 25 Feb 1997 21:27:12 -0000 1.1
+++ i386/i386/tss.h 25 Apr 2007 16:36:33 -0000
@@ -29,6 +29,8 @@
#include <mach/inline.h>
+#include <machine/io_perm.h>
+
/*
* i386 Task State Segment
*/
@@ -66,6 +68,17 @@ struct i386_tss {
bit map */
};
+
+/* The structure extends the above TSS structure by an I/O permission bitmap
+ and the barrier. */
+struct task_tss
+ {
+ struct i386_tss tss;
+ unsigned char iopb[IOPB_BYTES];
+ unsigned char barrier;
+};
+
+
/* Load the current task register. */
MACH_INLINE void
ltr(unsigned short segment)
Index: i386/i386at/kd.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386at/Attic/kd.c,v
retrieving revision 1.5.2.12
diff -u -p -r1.5.2.12 kd.c
--- i386/i386at/kd.c 5 Feb 2007 21:09:36 -0000 1.5.2.12
+++ i386/i386at/kd.c 25 Apr 2007 16:36:34 -0000
@@ -84,7 +84,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
#include <device/tty.h>
#include <device/io_req.h>
#include <device/buf.h> /* for struct uio (!) */
+#if REMOVE_ME
#include <i386/io_port.h>
+#endif
#include <vm/vm_kern.h>
#include <i386/vm_param.h>
#include <i386/machspl.h>
@@ -333,6 +335,7 @@ unsigned char key_map[NUMKEYS][WIDTH_KMA
short kd_index_reg = EGA_IDX_REG;
short kd_io_reg = EGA_IO_REG;
+#if REMOVE_ME
/*
* IO port sets for different controllers.
*/
@@ -360,6 +363,7 @@ kd_io_map_close()
io_port_destroy(kd_io_device);
kd_io_device = 0;
}
+#endif /* REMOVE_ME */
/*
* Globals used only for bitmap-based controllers. See kdsoft.h for
@@ -509,10 +513,12 @@ kdopen(dev, flag, ior)
tp->t_flags = ODDP|EVENP|ECHO|CRMOD|XTABS;
kdinit();
+#if REMOVE_ME
/* XXX kd_io_map_open allocates memory */
simple_unlock(&tp->t_lock);
kd_io_map_open(ior->io_device);
simple_lock(&tp->t_lock);
+#endif
}
tp->t_state |= TS_CARR_ON;
simple_unlock(&tp->t_lock);
@@ -549,7 +555,9 @@ int flag;
splx(s);
}
+#if REMOVE_ME
kd_io_map_close();
+#endif
return;
Index: i386/include/mach/i386/mach_i386.defs
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/include/mach/i386/mach_i386.defs,v
retrieving revision 1.2.2.2
diff -u -p -r1.2.2.2 mach_i386.defs
--- i386/include/mach/i386/mach_i386.defs 25 Apr 2007 13:59:03 -0000
1.2.2.2
+++ i386/include/mach/i386/mach_i386.defs 25 Apr 2007 16:36:34 -0000
@@ -35,26 +35,31 @@ subsystem
#include <mach/std_types.defs>
#include <mach/mach_types.defs>
-#include <device/device_types.defs>
-
-type device_list_t = ^array[] of device_t;
type descriptor_t = struct[2] of int;
type descriptor_list_t = array[*] of descriptor_t;
import <mach/machine/mach_i386_types.h>;
-routine i386_io_port_add(
- target_thread : thread_t;
- device : device_t);
-
-routine i386_io_port_remove(
- target_thread : thread_t;
- device : device_t);
-
-routine i386_io_port_list(
- target_thread : thread_t;
- out device_list : device_list_t);
+#if KERNEL_SERVER
+simport <machine/io_perm.h>;
+#endif
+
+type io_port_t = MACH_MSG_TYPE_INTEGER_16;
+type io_perm_t = mach_port_t
+ ctype: mach_port_t
+#if KERNEL_SERVER
+ intran: io_perm_t convert_port_to_io_perm(mach_port_t)
+ outtran: mach_port_t convert_io_perm_to_port(io_perm_t)
+#if REMOVE_ME
+ destructor: io_perm_deallocate(io_perm_t)
+#endif
+#endif /* KERNEL_SERVER */
+ ;
+
+skip; /* i386_io_port_add */
+skip; /* i386_io_port_remove */
+skip; /* i386_io_port_list */
routine i386_set_ldt(
target_thread : thread_t;
@@ -67,8 +72,27 @@ routine i386_get_ldt(
selector_count : int;
out desc_list : descriptor_list_t);
-skip; /* i386_io_perm_create */
-skip; /* i386_io_perm_modify */
+/* Request a new port IO_PERM that represents the capability to access
+ the I/O ports [FROM; TO] directly. MASTER_PORT is the master device port.
+
+ The function returns KERN_INVALID_ARGUMENT if TARGET_TASK is not a task,
+ or FROM is greater than TO. */
+routine i386_io_perm_create(
+ master_port : mach_port_t;
+ from : io_port_t;
+ to : io_port_t;
+ out io_perm : io_perm_t);
+
+/* Modify the I/O permissions for TARGET_TASK. If ENABLE is TRUE, the
+ permission to access the I/O ports specified by IO_PERM is granted,
+ otherwise it is withdrawn.
+
+ The function returns KERN_INVALID_ARGUMENT if TARGET_TASK is not a valid
+ task or IO_PERM not a valid I/O permission port. */
+routine i386_io_perm_modify(
+ target_task : task_t;
+ io_perm : io_perm_t;
+ enable : boolean_t);
/* Modify one of a few available thread-specific segment descriptor slots.
The SELECTOR must be a value from a previous call (on any thread),
Index: i386/include/mach/i386/mach_i386_types.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/include/mach/i386/mach_i386_types.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 mach_i386_types.h
--- i386/include/mach/i386/mach_i386_types.h 25 Feb 1997 21:27:00 -0000
1.1.1.1
+++ i386/include/mach/i386/mach_i386_types.h 25 Apr 2007 16:36:34 -0000
@@ -31,11 +31,6 @@
#define _MACH_MACH_I386_TYPES_H_
/*
- * Array of devices.
- */
-typedef device_t *device_list_t;
-
-/*
* i386 segment descriptor.
*/
struct descriptor {
@@ -46,4 +41,15 @@ struct descriptor {
typedef struct descriptor descriptor_t;
typedef struct descriptor *descriptor_list_t;
+/*
+ * i386 I/O port
+ */
+
+#ifdef MACH_KERNEL
+#include <i386/io_perm.h>
+#else
+typedef unsigned short io_port_t;
+typedef mach_port_t io_perm_t;
+#endif
+
#endif /* _MACH_MACH_I386_TYPES_H_ */
Index: include/stddef.h
===================================================================
RCS file: include/stddef.h
diff -N include/stddef.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ include/stddef.h 25 Apr 2007 16:36:35 -0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Mach.
+ *
+ * GNU Mach is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _STDDEF_H_
+#define _STDDEF_H_
+
+/* From GCC's `/lib/gcc/X/X/include/stddef.h'. */
+
+/* Offset of member MEMBER in a struct of type TYPE. */
+#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+
+#endif /* _STDDEF_H_ */
Index: kern/task.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/kern/task.c,v
retrieving revision 1.3.4.7
diff -u -p -r1.3.4.7 task.c
--- kern/task.c 4 Jan 2007 23:51:02 -0000 1.3.4.7
+++ kern/task.c 25 Apr 2007 16:36:35 -0000
@@ -67,6 +67,7 @@ void task_init(void)
0, "tasks");
eml_init();
+ machine_task_module_init ();
/*
* Create the kernel task as the first task.
@@ -145,6 +146,7 @@ kern_return_t task_create(
eml_task_reference(new_task, parent_task);
ipc_task_init(new_task, parent_task);
+ machine_task_init (new_task);
new_task->total_user_time.seconds = 0;
new_task->total_user_time.microseconds = 0;
@@ -220,6 +222,8 @@ void task_deallocate(
if (c != 0)
return;
+ machine_task_terminate (task);
+
eml_task_deallocate(task);
pset = task->processor_set;
@@ -1092,6 +1096,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)
Index: kern/task.h
===================================================================
RCS file: /cvsroot/hurd/gnumach/kern/task.h,v
retrieving revision 1.3.2.3
diff -u -p -r1.3.2.3 task.h
--- kern/task.h 15 Oct 2006 14:59:04 -0000 1.3.2.3
+++ kern/task.h 25 Apr 2007 16:36:35 -0000
@@ -46,6 +46,7 @@
#include <kern/processor.h>
#include <kern/syscall_emulation.h>
#include <vm/vm_map.h>
+#include <machine/task.h>
struct task {
/* Synchronization/destruction information */
@@ -98,6 +99,9 @@ struct task {
vm_offset_t fast_tas_base[TASK_FAST_TAS_NRAS];
vm_offset_t fast_tas_end[TASK_FAST_TAS_NRAS];
#endif /* FAST_TAS */
+
+ /* Hardware specific data. */
+ machine_task_t machine;
};
#define task_lock(task) simple_lock(&(task)->lock)
#v-
Regards,
Thomas
signature.asc
Description: Digital signature