Index: arch/amd64/include/pm.h
===================================================================
--- arch/amd64/include/pm.h	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/amd64/include/pm.h	(revision 0ddeabc57b1d75f43de34a8874ed2d9af0416f7e)
@@ -67,5 +67,5 @@
 #define DPL_USER	(PL_USER<<5)
 
-#define IO_MAP_BASE	(104)
+#define TSS_BASIC_SIZE	104
 
 #ifndef __ASM__
@@ -83,4 +83,5 @@
 	unsigned base_24_31: 8;
 } __attribute__ ((packed));
+typedef struct descriptor descriptor_t;
 
 struct tss_descriptor {
@@ -89,5 +90,5 @@
 	unsigned base_16_23: 8;
 	unsigned type: 4;
-	unsigned  : 1;
+	unsigned : 1;
 	unsigned dpl : 2;
 	unsigned present : 1;
@@ -100,4 +101,5 @@
 	unsigned  : 32;
 } __attribute__ ((packed));
+typedef struct tss_descriptor tss_descriptor_t;
 
 struct idescriptor {
@@ -113,4 +115,5 @@
 	unsigned  : 32;
 } __attribute__ ((packed));
+typedef struct idescriptor idescriptor_t;
 
 struct ptr_16_64 {
@@ -118,4 +121,5 @@
 	__u64 base;
 } __attribute__ ((packed));
+typedef struct ptr_16_64 ptr_16_64_t;
 
 struct ptr_16_32 {
@@ -123,4 +127,5 @@
 	__u32 base;
 } __attribute__ ((packed));
+typedef struct ptr_16_32 ptr_16_32_t;
 
 struct tss {
@@ -142,23 +147,24 @@
 	__u8 iomap[0x10000 + 1];	/* 64K + 1 terminating byte */
 } __attribute__ ((packed));
+typedef struct tss tss_t;
 
-extern struct tss *tss_p;
+extern tss_t *tss_p;
 
-extern struct descriptor gdt[];
-extern struct idescriptor idt[];
+extern descriptor_t gdt[];
+extern idescriptor_t idt[];
 
-extern struct ptr_16_64 gdtr;
-extern struct ptr_16_32 bootstrap_gdtr;
-extern struct ptr_16_32 protected_ap_gdtr;
+extern ptr_16_64_t gdtr;
+extern ptr_16_32_t bootstrap_gdtr;
+extern ptr_16_32_t protected_ap_gdtr;
 
 extern void pm_init(void);
 
-extern void gdt_tss_setbase(struct descriptor *d, __address base);
-extern void gdt_tss_setlimit(struct descriptor *d, __u32 limit);
+extern void gdt_tss_setbase(descriptor_t *d, __address base);
+extern void gdt_tss_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);
 
 #endif /* __ASM__ */
Index: arch/amd64/src/cpu/cpu.c
===================================================================
--- arch/amd64/src/cpu/cpu.c	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/amd64/src/cpu/cpu.c	(revision 0ddeabc57b1d75f43de34a8874ed2d9af0416f7e)
@@ -119,7 +119,7 @@
 {
 	CPU->arch.tss = tss_p;
-	CPU->fpu_owner=NULL;
+	CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((__u8 *) CPU->arch.tss);
+	CPU->fpu_owner = NULL;
 }
-
 
 void cpu_identify(void)
Index: arch/amd64/src/pm.c
===================================================================
--- arch/amd64/src/pm.c	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/amd64/src/pm.c	(revision 0ddeabc57b1d75f43de34a8874ed2d9af0416f7e)
@@ -47,5 +47,5 @@
  */
 
-struct descriptor gdt[GDT_ITEMS] = {
+descriptor_t gdt[GDT_ITEMS] = {
 	/* NULL descriptor */
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@@ -111,15 +111,15 @@
 };
 
-struct idescriptor idt[IDT_ITEMS];
-
-struct ptr_16_64 gdtr = {.limit = sizeof(gdt), .base= (__u64) gdt };
-struct ptr_16_64 idtr = {.limit = sizeof(idt), .base= (__u64) idt };
-
-static struct tss tss;
-struct tss *tss_p = NULL;
-
-void gdt_tss_setbase(struct descriptor *d, __address base)
-{
-	struct tss_descriptor *td = (struct tss_descriptor *) d;
+idescriptor_t idt[IDT_ITEMS];
+
+ptr_16_64_t gdtr = {.limit = sizeof(gdt), .base= (__u64) gdt };
+ptr_16_64_t idtr = {.limit = sizeof(idt), .base= (__u64) idt };
+
+static tss_t tss;
+tss_t *tss_p = NULL;
+
+void gdt_tss_setbase(descriptor_t *d, __address base)
+{
+	tss_descriptor_t *td = (tss_descriptor_t *) d;
 
 	td->base_0_15 = base & 0xffff;
@@ -129,7 +129,7 @@
 }
 
-void gdt_tss_setlimit(struct descriptor *d, __u32 limit)
-{
-	struct tss_descriptor *td = (struct tss_descriptor *) d;
+void gdt_tss_setlimit(descriptor_t *d, __u32 limit)
+{
+	struct tss_descriptor *td = (tss_descriptor_t *) d;
 
 	td->limit_0_15 = limit & 0xffff;
@@ -137,5 +137,5 @@
 }
 
-void idt_setoffset(struct idescriptor *d, __address offset)
+void idt_setoffset(idescriptor_t *d, __address offset)
 {
 	/*
@@ -147,7 +147,7 @@
 }
 
-void tss_initialize(struct tss *t)
-{
-	memsetb((__address) t, sizeof(struct tss), 0);
+void tss_initialize(tss_t *t)
+{
+	memsetb((__address) t, sizeof(tss_t), 0);
 }
 
@@ -157,5 +157,5 @@
 void idt_init(void)
 {
-	struct idescriptor *d;
+	idescriptor_t *d;
 	int i;
 
@@ -184,6 +184,6 @@
 void pm_init(void)
 {
-	struct descriptor *gdt_p = (struct descriptor *) gdtr.base;
-	struct tss_descriptor *tss_desc;
+	descriptor_t *gdt_p = (struct descriptor *) gdtr.base;
+	tss_descriptor_t *tss_desc;
 
 	/*
@@ -201,5 +201,5 @@
 	}
 	else {
-		tss_p = (struct tss *) malloc(sizeof(struct tss),FRAME_ATOMIC);
+		tss_p = (struct tss *) malloc(sizeof(tss_t), FRAME_ATOMIC);
 		if (!tss_p)
 			panic("could not allocate TSS\n");
@@ -208,5 +208,5 @@
 	tss_initialize(tss_p);
 
-	tss_desc = (struct tss_descriptor *) (&gdt_p[TSS_DES]);
+	tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]);
 	tss_desc->present = 1;
 	tss_desc->type = AR_TSS;
@@ -214,5 +214,5 @@
 	
 	gdt_tss_setbase(&gdt_p[TSS_DES], (__address) tss_p);
-	gdt_tss_setlimit(&gdt_p[TSS_DES], sizeof(struct tss) - 1);
+	gdt_tss_setlimit(&gdt_p[TSS_DES], sizeof(tss_t) - 1);
 
 	gdtr_load(&gdtr);
Index: arch/amd64/src/proc/scheduler.c
===================================================================
--- arch/amd64/src/proc/scheduler.c	(revision 897ad6092a3a8ef98f7407649e9b961cfe423882)
+++ arch/amd64/src/proc/scheduler.c	(revision 0ddeabc57b1d75f43de34a8874ed2d9af0416f7e)
@@ -29,4 +29,5 @@
 #include <proc/scheduler.h>
 #include <cpu.h>
+#include <proc/task.h>
 #include <proc/thread.h>
 #include <arch.h>
@@ -35,7 +36,18 @@
 #include <arch/debugger.h>
 #include <print.h>
+#include <arch/pm.h>
 
+/** Perform amd64 specific tasks needed before the new task is run. */
+void before_task_runs_arch(void)
+{
+}
+
+/** Perform amd64 specific tasks needed before the new thread is scheduled. */
 void before_thread_runs_arch(void)
 {
+	size_t iomap_size;
+	ptr_16_64_t cpugdtr;
+	descriptor_t *gdt_p;
+
 	CPU->arch.tss->rsp0 = (__address) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA];
 
@@ -43,10 +55,33 @@
 	 * hidden part of gs */
 	swapgs();
-	write_msr(AMD_MSR_GS,
-		  (__u64)&THREAD->kstack);
+	write_msr(AMD_MSR_GS, (__u64)&THREAD->kstack);
 	swapgs();
 
 	/* TLS support - set FS to thread local storage */
 	write_msr(AMD_MSR_FS, 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_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + iomap_size - 1);
+	gdtr_load(&cpugdtr);
 
 #ifdef CONFIG_DEBUG_AS_WATCHPOINT
