Index: arch/ia32/include/asm.h
===================================================================
--- arch/ia32/include/asm.h	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/ia32/include/asm.h	(revision 39cea6a27db77024039730f632eb27a57fda09ab)
@@ -257,5 +257,5 @@
  * @param gdtr_reg Address of memory from where to load GDTR.
  */
-static inline void gdtr_load(struct ptr_16_32 *gdtr_reg)
+static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
 {
 	__asm__ volatile ("lgdt %0\n" : : "m" (*gdtr_reg));
@@ -266,5 +266,5 @@
  * @param gdtr_reg Address of memory to where to load GDTR.
  */
-static inline void gdtr_store(struct ptr_16_32 *gdtr_reg)
+static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
 {
 	__asm__ volatile ("sgdt %0\n" : : "m" (*gdtr_reg));
@@ -275,5 +275,5 @@
  * @param idtr_reg Address of memory from where to load IDTR.
  */
-static inline void idtr_load(struct ptr_16_32 *idtr_reg)
+static inline void idtr_load(ptr_16_32_t *idtr_reg)
 {
 	__asm__ volatile ("lidt %0\n" : : "m" (*idtr_reg));
Index: arch/ia32/include/pm.h
===================================================================
--- arch/ia32/include/pm.h	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/ia32/include/pm.h	(revision 39cea6a27db77024039730f632eb27a57fda09ab)
@@ -56,5 +56,5 @@
 #define DPL_USER	(PL_USER<<5)
 
-#define IO_MAP_BASE	(104)
+#define TSS_BASIC_SIZE	104
 
 #ifndef __ASM__
@@ -68,4 +68,5 @@
 	__u32 base;
 } __attribute__ ((packed));
+typedef struct ptr_16_32 ptr_16_32_t;
 
 struct descriptor {
@@ -81,4 +82,5 @@
 	unsigned base_24_31: 8;
 } __attribute__ ((packed));
+typedef struct descriptor  descriptor_t;
 
 struct idescriptor {
@@ -89,5 +91,5 @@
 	unsigned offset_16_31: 16;
 } __attribute__ ((packed));
-
+typedef struct idescriptor idescriptor_t;
 
 struct tss {
@@ -132,21 +134,22 @@
 	__u8 iomap[0x10000+1];	/* 64K + 1 terminating byte */
 } __attribute__ ((packed));
+typedef struct tss tss_t;
 
-extern struct ptr_16_32 gdtr;
-extern struct ptr_16_32 bootstrap_gdtr;
-extern struct ptr_16_32 protected_ap_gdtr;
+extern ptr_16_32_t gdtr;
+extern ptr_16_32_t bootstrap_gdtr;
+extern ptr_16_32_t protected_ap_gdtr;
 extern struct tss *tss_p;
 
-extern struct descriptor gdt[];
+extern descriptor_t gdt[];
 
 extern void pm_init(void);
 
-extern void gdt_setbase(struct descriptor *d, __address base);
-extern void gdt_setlimit(struct descriptor *d, __u32 limit);
+extern void gdt_setbase(descriptor_t *d, __address base);
+extern void gdt_setlimit(descriptor_t *d, __u32 limit);
 
 extern void idt_init(void);
-extern void idt_setoffset(struct idescriptor *d, __address offset);
+extern void idt_setoffset(idescriptor_t *d, __address offset);
 
-extern void tss_initialize(struct tss *t);
+extern void tss_initialize(tss_t *t);
 extern void set_tls_desc(__address tls);
 
Index: arch/ia32/src/cpu/cpu.c
===================================================================
--- arch/ia32/src/cpu/cpu.c	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/ia32/src/cpu/cpu.c	(revision 39cea6a27db77024039730f632eb27a57fda09ab)
@@ -88,36 +88,36 @@
 }
 
-
-
-
 void cpu_arch_init(void)
 {
-	__u32 help=0;
+	cpuid_feature_info fi;
+	cpuid_extended_feature_info efi;
+	cpu_info_t info;
+	__u32 help = 0;
 	
 	CPU->arch.tss = tss_p;
-	CPU->fpu_owner=NULL;
+	CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((__u8 *) CPU->arch.tss);
 
-	cpuid_feature_info fi;
-	cpuid_extended_feature_info efi;
+	CPU->fpu_owner = NULL;
 
-	cpu_info_t info;
 	cpuid(1, &info);
 
-	fi.word=info.cpuid_edx;
-	efi.word=info.cpuid_ecx;
+	fi.word = info.cpuid_edx;
+	efi.word = info.cpuid_ecx;
 	
-	if(fi.bits.fxsr) 	fpu_fxsr();
-	else fpu_fsr();	
+	if (fi.bits.fxsr)
+		fpu_fxsr();
+	else
+		fpu_fsr();	
 	
-	if(fi.bits.sse)	asm volatile (
-		"mov %%cr4,%0;\n"
-		"or %1,%0;\n"
-		"mov %0,%%cr4;\n"
-		:"+r"(help)
-		:"i"(CR4_OSFXSR_MASK|(1<<10)) 
-	);
-	
+	if (fi.bits.sse) {
+		asm volatile (
+			"mov %%cr4,%0\n"
+			"or %1,%0\n"
+			"mov %0,%%cr4\n"
+			: "+r" (help)
+			: "i" (CR4_OSFXSR_MASK|(1<<10)) 
+		);
+	}
 }
-
 
 void cpu_identify(void)
Index: arch/ia32/src/pm.c
===================================================================
--- arch/ia32/src/pm.c	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/ia32/src/pm.c	(revision 39cea6a27db77024039730f632eb27a57fda09ab)
@@ -53,5 +53,5 @@
  * structure in it's base.
  */
-struct descriptor gdt[GDT_ITEMS] = {
+descriptor_t gdt[GDT_ITEMS] = {
 	/* NULL descriptor */
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@@ -69,15 +69,15 @@
 };
 
-static struct idescriptor idt[IDT_ITEMS];
-
-static struct tss tss;
-
-struct tss *tss_p = NULL;
+static idescriptor_t idt[IDT_ITEMS];
+
+static tss_t tss;
+
+tss_t *tss_p = NULL;
 
 /* gdtr is changed by kmp before next CPU is initialized */
-struct ptr_16_32 bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((__address) gdt) };
-struct ptr_16_32 gdtr = { .limit = sizeof(gdt), .base = (__address) gdt };
-
-void gdt_setbase(struct descriptor *d, __address base)
+ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((__address) gdt) };
+ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (__address) gdt };
+
+void gdt_setbase(descriptor_t *d, __address base)
 {
 	d->base_0_15 = base & 0xffff;
@@ -86,5 +86,5 @@
 }
 
-void gdt_setlimit(struct descriptor *d, __u32 limit)
+void gdt_setlimit(descriptor_t *d, __u32 limit)
 {
 	d->limit_0_15 = limit & 0xffff;
@@ -92,5 +92,5 @@
 }
 
-void idt_setoffset(struct idescriptor *d, __address offset)
+void idt_setoffset(idescriptor_t *d, __address offset)
 {
 	/*
@@ -101,5 +101,5 @@
 }
 
-void tss_initialize(struct tss *t)
+void tss_initialize(tss_t *t)
 {
 	memsetb((__address) t, sizeof(struct tss), 0);
@@ -111,5 +111,5 @@
 void idt_init(void)
 {
-	struct idescriptor *d;
+	idescriptor_t *d;
 	int i;
 
@@ -142,14 +142,11 @@
 static void clean_IOPL_NT_flags(void)
 {
-	asm
-	(
-		"pushfl;"
-		"pop %%eax;"
-		"and $0xffff8fff,%%eax;"
-		"push %%eax;"
-		"popfl;"
-		:
-		:
-		:"%eax"
+	__asm__ volatile (
+		"pushfl\n"
+		"pop %%eax\n"
+		"and $0xffff8fff, %%eax\n"
+		"push %%eax\n"
+		"popfl\n"
+		: : : "eax"
 	);
 }
@@ -158,12 +155,9 @@
 static void clean_AM_flag(void)
 {
-	asm
-	(
-		"mov %%cr0,%%eax;"
-		"and $0xFFFBFFFF,%%eax;"
-		"mov %%eax,%%cr0;"
-		:
-		:
-		:"%eax"
+	__asm__ volatile (
+		"mov %%cr0, %%eax\n"
+		"and $0xfffbffff, %%eax\n"
+		"mov %%eax, %%cr0\n"
+		: : : "eax"
 	);
 }
@@ -171,6 +165,6 @@
 void pm_init(void)
 {
-	struct descriptor *gdt_p = (struct descriptor *) gdtr.base;
-	struct ptr_16_32 idtr;
+	descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
+	ptr_16_32_t idtr;
 
 	/*
@@ -196,5 +190,5 @@
 	}
 	else {
-		tss_p = (struct tss *) malloc(sizeof(struct tss),FRAME_ATOMIC);
+		tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
 		if (!tss_p)
 			panic("could not allocate TSS\n");
@@ -208,5 +202,5 @@
 	
 	gdt_setbase(&gdt_p[TSS_DES], (__address) tss_p);
-	gdt_setlimit(&gdt_p[TSS_DES], sizeof(struct tss) - 1);
+	gdt_setlimit(&gdt_p[TSS_DES], sizeof(tss_t) - 1);
 
 	/*
@@ -222,6 +216,6 @@
 void set_tls_desc(__address tls)
 {
-	struct ptr_16_32 cpugdtr;
-	struct descriptor *gdt_p = (struct descriptor *) cpugdtr.base;
+	ptr_16_32_t cpugdtr;
+	descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
 
 	gdtr_store(&cpugdtr);
Index: arch/ia32/src/proc/scheduler.c
===================================================================
--- arch/ia32/src/proc/scheduler.c	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/ia32/src/proc/scheduler.c	(revision 39cea6a27db77024039730f632eb27a57fda09ab)
@@ -29,4 +29,5 @@
 #include <proc/scheduler.h>
 #include <cpu.h>
+#include <proc/task.h>
 #include <proc/thread.h>
 #include <arch.h>
@@ -34,7 +35,21 @@
 #include <arch/debugger.h>
 #include <arch/pm.h>
+#include <arch/asm.h>
 
+/** Perform ia32 specific tasks needed before the new task is run. */
+void before_task_runs_arch(void)
+{
+}
+
+/** Perform ia32 specific tasks needed before the new thread is scheduled.
+ *
+ * THREAD is locked and interrupts are disabled.
+ */
 void before_thread_runs_arch(void)
 {
+	size_t iomap_size;
+	ptr_16_32_t cpugdtr;
+	descriptor_t *gdt_p;
+
 	CPU->arch.tss->esp0 = (__address) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA];
 	CPU->arch.tss->ss0 = selector(KDATA_DES);
@@ -42,4 +57,28 @@
 	/* Set up TLS in GS register */
 	set_tls_desc(THREAD->arch.tls);
+
+	/*
+	 * Switch the I/O Permission Bitmap, if necessary.
+	 *
+	 * First, copy the I/O Permission Bitmap.
+	 * This needs to be changed so that the
+	 * copying is avoided if the same task
+	 * was already running and the iomap did
+	 * not change.
+	 */
+	spinlock_lock(&TASK->lock);
+	iomap_size = TASK->arch.iomap_size;
+	if (iomap_size) {
+		ASSERT(TASK->arch.iomap);
+		memcpy(CPU->arch.tss->iomap, TASK->arch.iomap, iomap_size);
+		CPU->arch.tss->iomap[iomap_size] = 0xff;	/* terminating byte */
+	}
+	spinlock_unlock(&TASK->lock);	
+
+	/* Second, adjust TSS segment limit. */
+	gdtr_store(&cpugdtr);
+	gdt_p = (descriptor_t *) cpugdtr.base;
+	gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + iomap_size - 1);
+	gdtr_load(&cpugdtr);
 
 #ifdef CONFIG_DEBUG_AS_WATCHPOINT
