? paging.diff
? kernel/page-fault.c
Index: Makefile.in
===================================================================
RCS file: /cvsroot-freemware/plex86/Makefile.in,v
retrieving revision 1.5
diff -u -r1.5 Makefile.in
--- Makefile.in	2000/04/08 22:19:46	1.5
+++ Makefile.in	2000/04/14 07:02:28
@@ -46,6 +46,8 @@
 	$(MAKE) -C docs dist-clean
 	/bin/rm -f config.status config.cache config.log
 	/bin/rm -f Makefile config.h
+	/bin/rm -f `find . -name .#\*`
+	/bin/rm -f `find . -name \*~`
 
 Makefile:	Makefile.in config.status
 		CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) config.status
Index: kernel/Makefile.in
===================================================================
RCS file: /cvsroot-freemware/plex86/kernel/Makefile.in,v
retrieving revision 1.4
diff -u -r1.4 Makefile.in
--- kernel/Makefile.in	2000/03/26 17:30:27	1.4
+++ kernel/Makefile.in	2000/04/14 07:02:28
@@ -50,7 +50,7 @@
 
 
 $(KERNEL_TARGET): $(HOST_O) monitor.o nexus.o fault.o emulation.o \
-		prescan.o fetchdecode.o
+		prescan.o fetchdecode.o page-fault.o
 	$(LD) $(KLDFLAGS) $^ -o $@
 
 clean:
Index: kernel/emulation.c
===================================================================
RCS file: /cvsroot-freemware/plex86/kernel/emulation.c,v
retrieving revision 1.4
diff -u -r1.4 emulation.c
--- kernel/emulation.c	2000/04/11 19:04:05	1.4
+++ kernel/emulation.c	2000/04/14 07:02:28
@@ -25,37 +25,43 @@
 /*
  * Prototypes for instructions faulting in ring 3
  */
-int emulate_hlt(vm_t *, guest_context_t *context);
-int emulate_cli(vm_t *, guest_context_t *context);
-int emulate_sti(vm_t *, guest_context_t *context);
-int emulate_clts(vm_t *);
-int emulate_rdmsr(vm_t *);
-int emulate_wrmsr(vm_t *);
-int emulate_invd(vm_t *);
-int emulate_wbinvd(vm_t *);
-int emulate_invlpg(vm_t *);
-int emulate_lgdt(vm_t *, guest_context_t *context, Bit32u addr);
-int emulate_lidt(vm_t *, Bit32u addr);
-int emulate_lldt(vm_t *, Bit16u selector);
-int emulate_ltr(vm_t *, Bit16u selector);
-int emulate_lmsw(vm_t *);
-int emulate_mov_from_cr(vm_t *);
-int emulate_mov_to_cr(vm_t *);
-int emulate_mov_from_dr(vm_t *);
-int emulate_mov_to_dr(vm_t *);
-int emulate_in(vm_t *, guest_context_t *context, int op_size, int port);
-int emulate_out(vm_t *, guest_context_t *context, int op_size, int port);
-int emulate_ins(vm_t *, guest_context_t *context, int op_size, int address_size, int rep);
-int emulate_outs(vm_t *, guest_context_t *context, int op_size, int address_size, int rep);
-int emulate_load_ds(vm_t *, guest_context_t *context, Bit16u selector);
-int emulate_load_es(vm_t *, guest_context_t *context, Bit16u selector);
-int emulate_load_fs(vm_t *, guest_context_t *context, Bit16u selector);
-int emulate_load_gs(vm_t *, guest_context_t *context, Bit16u selector);
-int emulate_load_ss(vm_t *, guest_context_t *context, Bit16u selector);
-int emulate_int(vm_t *, guest_context_t *context, int vector, Bit32u eip);
-int emulate_iret(vm_t *, guest_context_t *context);
-int emulate_ljmp(vm_t *, guest_context_t *context);
+int   emulate_hlt (vm_t *, guest_context_t * context);
+int   emulate_cli (vm_t *, guest_context_t * context);
+int   emulate_sti (vm_t *, guest_context_t * context);
+int   emulate_clts (vm_t *);
+int   emulate_rdmsr (vm_t *);
+int   emulate_wrmsr (vm_t *);
+int   emulate_invd (vm_t *);
+int   emulate_wbinvd (vm_t *);
+int   emulate_invlpg (vm_t *);
+int   emulate_lgdt (vm_t *, guest_context_t * context, Bit32u addr);
+int   emulate_lidt (vm_t *, Bit32u addr);
+int   emulate_lldt (vm_t *, Bit16u selector);
+int   emulate_ltr (vm_t *, Bit16u selector);
+int   emulate_lmsw (vm_t *);
+int   emulate_mov_from_cr (vm_t *, guest_context_t *);
+int   emulate_mov_to_cr (vm_t *, guest_context_t *);
+int   emulate_mov_from_dr (vm_t *);
+int   emulate_mov_to_dr (vm_t *);
+int   emulate_in (vm_t *, guest_context_t * context, int op_size, int port);
+int   emulate_out (vm_t *, guest_context_t * context, int op_size, int port);
+int   emulate_ins (vm_t *, guest_context_t * context, int op_size, int address_size, int rep);
+int   emulate_outs (vm_t *, guest_context_t * context, int op_size, int address_size, int rep);
+int   emulate_load_ds (vm_t *, guest_context_t * context, Bit16u selector);
+int   emulate_load_es (vm_t *, guest_context_t * context, Bit16u selector);
+int   emulate_load_fs (vm_t *, guest_context_t * context, Bit16u selector);
+int   emulate_load_gs (vm_t *, guest_context_t * context, Bit16u selector);
+int   emulate_load_ss (vm_t *, guest_context_t * context, Bit16u selector);
+int   emulate_int (vm_t *, guest_context_t * context, int vector, Bit32u eip);
+int   emulate_iret (vm_t *, guest_context_t * context);
+int   emulate_ljmp (vm_t *, guest_context_t * context);
 
+/*
+ * Prototypes for helper routines
+ */
+int   emulate_set_pdbr (vm_t *, guest_context_t *, Bit32u);
+int   unmap_page_from_guest (vm_t *, Bit32u);
+
 
 /*
  * Various utility routines to access guest memory
@@ -63,143 +69,166 @@
  * FIXME -- all of these don't take segmentation or paging into account!
  */
 
-static inline Bit8u read_guest_byte(vm_t *vm, Bit32u *addr)
+static inline Bit8u 
+read_guest_byte (vm_t * vm, Bit32u * addr)
 {
-    Bit8u *ptr = (Bit8u *)(*addr - vm->common.addr->nexus->mon_base);
+    Bit8u *ptr = (Bit8u *) (*addr - vm->common.addr->nexus->mon_base);
+
     *addr += 1;
     return *ptr;
 }
-static inline Bit16u read_guest_word(vm_t *vm, Bit32u *addr)
+static inline Bit16u 
+read_guest_word (vm_t * vm, Bit32u * addr)
 {
-    Bit16u *ptr = (Bit16u *)(*addr - vm->common.addr->nexus->mon_base);
+    Bit16u *ptr = (Bit16u *) (*addr - vm->common.addr->nexus->mon_base);
+
     *addr += 2;
     return *ptr;
 }
-static inline Bit32u read_guest_dword(vm_t *vm, Bit32u *addr)
+static inline Bit32u 
+read_guest_dword (vm_t * vm, Bit32u * addr)
 {
-    Bit32u *ptr = (Bit32u *)(*addr - vm->common.addr->nexus->mon_base);
+    Bit32u *ptr = (Bit32u *) (*addr - vm->common.addr->nexus->mon_base);
+
     *addr += 4;
     return *ptr;
 }
 
-static inline void write_guest_byte(vm_t *vm, Bit32u *addr, Bit8u val)
+static inline void 
+write_guest_byte (vm_t * vm, Bit32u * addr, Bit8u val)
 {
-    Bit8u *ptr = (Bit8u *)(*addr - vm->common.addr->nexus->mon_base);
+    Bit8u *ptr = (Bit8u *) (*addr - vm->common.addr->nexus->mon_base);
+
     *addr += 1;
     *ptr = val;
 }
-static inline void write_guest_word(vm_t *vm, Bit32u *addr, Bit16u val)
+static inline void 
+write_guest_word (vm_t * vm, Bit32u * addr, Bit16u val)
 {
-    Bit16u *ptr = (Bit16u *)(*addr - vm->common.addr->nexus->mon_base);
+    Bit16u *ptr = (Bit16u *) (*addr - vm->common.addr->nexus->mon_base);
+
     *addr += 2;
     *ptr = val;
 }
-static inline void write_guest_dword(vm_t *vm, Bit32u *addr, Bit32u val)
+static inline void 
+write_guest_dword (vm_t * vm, Bit32u * addr, Bit32u val)
 {
-    Bit32u *ptr = (Bit32u *)(*addr - vm->common.addr->nexus->mon_base);
+    Bit32u *ptr = (Bit32u *) (*addr - vm->common.addr->nexus->mon_base);
+
     *addr += 4;
     *ptr = val;
 }
 
 static Bit32u
-guest_stack_pop(vm_t *vm, Bit32u *esp, int operand_size)
+guest_stack_pop (vm_t * vm, Bit32u * esp, int operand_size)
 {
     switch (operand_size)
     {
-    case 16: return read_guest_word(vm, esp);
-    case 32: return read_guest_dword(vm, esp);
+    case 16:
+	return read_guest_word (vm, esp);
+    case 32:
+	return read_guest_dword (vm, esp);
     }
     return 0;
 }
 
 static void
-guest_stack_push(vm_t *vm, Bit32u *esp, int operand_size, Bit32u val)
+guest_stack_push (vm_t * vm, Bit32u * esp, int operand_size, Bit32u val)
 {
     switch (operand_size)
     {
-    case 16: *esp -= 2; *(Bit16u *)(*esp - vm->common.addr->nexus->mon_base) = val; break;
-    case 32: *esp -= 4; *(Bit32u *)(*esp - vm->common.addr->nexus->mon_base) = val; break;
+    case 16:
+	*esp -= 2;
+	*(Bit16u *) (*esp - vm->common.addr->nexus->mon_base) = val;
+	break;
+    case 32:
+	*esp -= 4;
+	*(Bit32u *) (*esp - vm->common.addr->nexus->mon_base) = val;
+	break;
     }
 }
 
 static inline void
-clear_descriptor(vm_t *vm, descriptor_t *descr)
+clear_descriptor (vm_t * vm, descriptor_t * descr)
 {
-    ((Bit32u *)descr)[0] = 0;
-    ((Bit32u *)descr)[1] = 0;
+    ((Bit32u *) descr)[0] = 0;
+    ((Bit32u *) descr)[1] = 0;
 }
 
 static inline void
-clear_gate(vm_t *vm, gate_t *gate)
+clear_gate (vm_t * vm, gate_t * gate)
 {
-    ((Bit32u *)gate)[0] = 0;
-    ((Bit32u *)gate)[1] = 0;
+    ((Bit32u *) gate)[0] = 0;
+    ((Bit32u *) gate)[1] = 0;
 }
 
-static void 
-read_guest_descriptor(vm_t *vm, descriptor_t *descr, Bit16u selector)
+static void
+read_guest_descriptor (vm_t * vm, descriptor_t * descr, Bit16u selector)
 {
-    if ( selector & 4 )
+    if (selector & 4)
     {
-        /* LDT selector -- not supported for now */
+	/* LDT selector -- not supported for now */
 
-        clear_descriptor(vm, descr);
+	clear_descriptor (vm, descr);
     }
     else
     {
-        /* GDT selector */
+	/* GDT selector */
+
+	Bit32u addr = selector & ~3;
 
-        Bit32u addr = selector & ~3;
-        if (addr+7 > vm->common.addr->nexus->guest_gdt_info.limit) 
-        {
-            clear_descriptor(vm, descr);
-        }
-        else
-        {
-            addr += vm->common.addr->nexus->guest_gdt_info.base;
-            ((Bit32u *)descr)[0] = read_guest_dword(vm, &addr);
-            ((Bit32u *)descr)[1] = read_guest_dword(vm, &addr);
-        }
+	if (addr + 7 > vm->common.addr->nexus->guest_gdt_info.limit)
+	{
+	    clear_descriptor (vm, descr);
+	}
+	else
+	{
+	    addr += vm->common.addr->nexus->guest_gdt_info.base;
+	    ((Bit32u *) descr)[0] = read_guest_dword (vm, &addr);
+	    ((Bit32u *) descr)[1] = read_guest_dword (vm, &addr);
+	}
     }
 }
 
-static void 
-write_guest_descriptor(vm_t *vm, descriptor_t *descr, Bit16u selector)
+static void
+write_guest_descriptor (vm_t * vm, descriptor_t * descr, Bit16u selector)
 {
-    if ( selector & 4 )
+    if (selector & 4)
     {
-        /* LDT selector -- not supported for now */
+	/* LDT selector -- not supported for now */
     }
     else
     {
-        /* GDT selector */
+	/* GDT selector */
 
-        Bit32u addr = selector & ~3;
-        if (addr+7 > vm->common.addr->nexus->guest_gdt_info.limit) 
-            ;
-        else
-        {
-            addr += vm->common.addr->nexus->guest_gdt_info.base;
-            write_guest_dword(vm, &addr, ((Bit32u *)descr)[0]);
-            write_guest_dword(vm, &addr, ((Bit32u *)descr)[1]);
-        }
+	Bit32u addr = selector & ~3;
+
+	if (addr + 7 > vm->common.addr->nexus->guest_gdt_info.limit)
+	    ;
+	else
+	{
+	    addr += vm->common.addr->nexus->guest_gdt_info.base;
+	    write_guest_dword (vm, &addr, ((Bit32u *) descr)[0]);
+	    write_guest_dword (vm, &addr, ((Bit32u *) descr)[1]);
+	}
     }
 }
 
-static void 
-read_guest_gate(vm_t *vm, gate_t *gate, int vector)
+static void
+read_guest_gate (vm_t * vm, gate_t * gate, int vector)
 {
-    Bit32u addr = 8*vector;
-    if (   vector < 0 || vector >= 256 
-        || addr+7 > vm->common.addr->nexus->guest_idt_info.limit) 
+    Bit32u addr = 8 * vector;
+
+    if (vector < 0 || vector >= 256
+	|| addr + 7 > vm->common.addr->nexus->guest_idt_info.limit)
     {
-        clear_gate(vm, gate);
+	clear_gate (vm, gate);
     }
     else
     {
-        addr += vm->common.addr->nexus->guest_idt_info.base;
-        ((Bit32u *)gate)[0] = read_guest_dword(vm, &addr);
-        ((Bit32u *)gate)[1] = read_guest_dword(vm, &addr);
+	addr += vm->common.addr->nexus->guest_idt_info.base;
+	((Bit32u *) gate)[0] = read_guest_dword (vm, &addr);
+	((Bit32u *) gate)[1] = read_guest_dword (vm, &addr);
     }
 }
 
@@ -209,24 +238,24 @@
  */
 
 void
-codeseg_activate(vm_t *vm, Bit16u selector, int active)
+codeseg_activate (vm_t * vm, Bit16u selector, int active)
 {
-    if ( selector & 4 )
+    if (selector & 4)
     {
-        /* LDT selector -- not supported for now */
+	/* LDT selector -- not supported for now */
     }
     else
     {
-        descriptor_t *monitor_gdt;
-        descriptor_t *descr;
+	descriptor_t *monitor_gdt;
+	descriptor_t *descr;
 
-        monitor_gdt = vm->common.addr->gdt;
-        descr = monitor_gdt + (selector >> 3);
+	monitor_gdt = vm->common.addr->gdt;
+	descr = monitor_gdt + (selector >> 3);
 
-        if ( active )
-            descr->type |= 0x08;
-        else
-            descr->type &= ~0x08;
+	if (active)
+	    descr->type |= 0x08;
+	else
+	    descr->type &= ~0x08;
     }
 }
 
@@ -235,7 +264,7 @@
  * Raise a hardware or software interrupt
  */
 int
-raise_interrupt(vm_t *vm, guest_context_t *context, int vector, int soft)
+raise_interrupt (vm_t * vm, guest_context_t * context, int vector, int soft)
 {
     Bit32u new_eip, new_esp;
     Bit16u new_cs, new_ss;
@@ -244,88 +273,102 @@
     descriptor_t code_descr;
     descriptor_t stack_descr;
 
-    int cpl = vm->common.addr->nexus->guest_cpl;
+    int   cpl = vm->common.addr->nexus->guest_cpl;
 
     /* Retrieve interrupt gate */
-    read_guest_gate(vm, &gate, vector);
-    if (!gate.p) return 0;
-    if (gate.type != D_INT && gate.type != D_TRAP) return 0;
-    if (soft && gate.dpl < cpl) return 0;
-    if (!gate.selector) return 0;
+    read_guest_gate (vm, &gate, vector);
+    if (!gate.p)
+	return 0;
+    if (gate.type != D_INT && gate.type != D_TRAP)
+	return 0;
+    if (soft && gate.dpl < cpl)
+	return 0;
+    if (!gate.selector)
+	return 0;
 
-    new_cs     = gate.selector;
-    new_eip    = (gate.offset_high << 16) | gate.offset_low;
+    new_cs = gate.selector;
+    new_eip = (gate.offset_high << 16) | gate.offset_low;
 
     /* Build a flags image for the stack */
-    context->eflags = FLG_USER(context->eflags,vm->common.addr->nexus->guest_eflags);
+    context->eflags = FLG_USER (context->eflags, vm->common.addr->nexus->guest_eflags);
 
     /* Update the guest flags */
     if (gate.type == D_INT)
     {
-        vm->common.addr->nexus->guest_eflags &= ~FLG_IF;
+	vm->common.addr->nexus->guest_eflags &= ~FLG_IF;
     }
 
     /* Retrieve code segment descriptor */
-    read_guest_descriptor(vm, &code_descr, new_cs);
-    if (!code_descr.p) return 0;
-    if ((code_descr.type & 0x18) != D_CODE) return 0;
-    if (code_descr.dpl > cpl) return 0;
-    if (new_eip > Limit(code_descr)) return 0;
+    read_guest_descriptor (vm, &code_descr, new_cs);
+    if (!code_descr.p)
+	return 0;
+    if ((code_descr.type & 0x18) != D_CODE)
+	return 0;
+    if (code_descr.dpl > cpl)
+	return 0;
+    if (new_eip > Limit (code_descr))
+	return 0;
 
     if (!(code_descr.type & D_CONFORM) && code_descr.dpl < cpl)
     {
-        /* Inter-privilege-level interrupt */
-        descriptor_t *tss = &vm->common.addr->nexus->guest_tss_descr;
-        Bit32u tss_limit = (tss->limit_high << 16) | tss->limit_low;
-        Bit32u tss_base  = (tss->base_high << 24) | (tss->base_med << 16) | tss->base_low;
-
-        Bit32u stack_addr = code_descr.dpl * 8 + 4;
-        if (stack_addr+7 > tss_limit) return 0;
-        stack_addr += tss_base;
-        new_esp = read_guest_dword(vm, &stack_addr);
-        new_ss  = read_guest_dword(vm, &stack_addr);
-
-        read_guest_descriptor(vm, &stack_descr, new_ss);
-        if (!stack_descr.p) return 0;
-        if ((stack_descr.type & 0x18) != D_DATA) return 0;
-        if (!(stack_descr.type & D_WRITE)) return 0;
-        if (stack_descr.dpl != code_descr.dpl) return 0;
-
-        /* FIXME: stack limits check */
-
-        /* Push old stack info */
-        guest_stack_push(vm, &new_esp, 32, (context->ss & ~3) | cpl);
-        guest_stack_push(vm, &new_esp, 32, context->esp);
+	/* Inter-privilege-level interrupt */
+	descriptor_t *tss = &vm->common.addr->nexus->guest_tss_descr;
+	Bit32u tss_limit = (tss->limit_high << 16) | tss->limit_low;
+	Bit32u tss_base = (tss->base_high << 24) | (tss->base_med << 16) | tss->base_low;
+
+	Bit32u stack_addr = code_descr.dpl * 8 + 4;
+
+	if (stack_addr + 7 > tss_limit)
+	    return 0;
+	stack_addr += tss_base;
+	new_esp = read_guest_dword (vm, &stack_addr);
+	new_ss = read_guest_dword (vm, &stack_addr);
+
+	read_guest_descriptor (vm, &stack_descr, new_ss);
+	if (!stack_descr.p)
+	    return 0;
+	if ((stack_descr.type & 0x18) != D_DATA)
+	    return 0;
+	if (!(stack_descr.type & D_WRITE))
+	    return 0;
+	if (stack_descr.dpl != code_descr.dpl)
+	    return 0;
+
+	/* FIXME: stack limits check */
+
+	/* Push old stack info */
+	guest_stack_push (vm, &new_esp, 32, (context->ss & ~3) | cpl);
+	guest_stack_push (vm, &new_esp, 32, context->esp);
 
-        vm->common.addr->nexus->guest_cpl = code_descr.dpl;
+	vm->common.addr->nexus->guest_cpl = code_descr.dpl;
     }
     else
     {
-        /* Intra-privilege-level interrupt */
+	/* Intra-privilege-level interrupt */
 
-        new_ss  = context->ss;
-        new_esp = context->esp;
+	new_ss = context->ss;
+	new_esp = context->esp;
 
-        /* FIXME: stack limits check */
+	/* FIXME: stack limits check */
     }
 
     /* Push return info */
-    guest_stack_push(vm, &new_esp, 32, context->eflags);
-    guest_stack_push(vm, &new_esp, 32, (context->cs & ~3) | cpl);
-    guest_stack_push(vm, &new_esp, 32, context->eip);
-
-    codeseg_activate( vm, context->cs, 0 );
-    codeseg_activate( vm, new_cs, 1 );
-
-    context->cs     = new_cs | 3;
-    context->eip    = new_eip;
-    context->ss     = new_ss | 3;
-    context->esp    = new_esp;
+    guest_stack_push (vm, &new_esp, 32, context->eflags);
+    guest_stack_push (vm, &new_esp, 32, (context->cs & ~3) | cpl);
+    guest_stack_push (vm, &new_esp, 32, context->eip);
 
+    codeseg_activate (vm, context->cs, 0);
+    codeseg_activate (vm, new_cs, 1);
+
+    context->cs = new_cs | 3;
+    context->eip = new_eip;
+    context->ss = new_ss | 3;
+    context->esp = new_esp;
+
     /* FIXME: other flags are also affected */
-    context->eflags = FLG_BUILD(context->eflags,
-                                vm->common.addr->nexus->guest_eflags,
-                                vm->common.addr->nexus->mon_eflags);
+    context->eflags = FLG_BUILD (context->eflags,
+				 vm->common.addr->nexus->guest_eflags,
+				 vm->common.addr->nexus->mon_eflags);
 
     return 1;
 }
@@ -344,161 +387,246 @@
 #define FieldSIBBase(sib)   ( (sib)       & 0x7)
 
 static Bit32u
-decode_register(vm_t *vm, guest_context_t *context, int operand_size, int reg)
+decode_register (vm_t * vm, guest_context_t * context, int operand_size, int reg)
 {
-    switch ( operand_size )
+    switch (operand_size)
     {
     case 8:
-        switch ( reg )
-        {
-        case 0: return context->eax & 0xff;
-        case 1: return context->ecx & 0xff;
-        case 2: return context->edx & 0xff;
-        case 3: return context->ebx & 0xff;
-        case 4: return (context->eax >> 8) & 0xff;
-        case 5: return (context->ecx >> 8) & 0xff;
-        case 6: return (context->edx >> 8) & 0xff;
-        case 7: return (context->ebx >> 8) & 0xff;
-        }
-        break;
+	switch (reg)
+	{
+	case 0:
+	    return context->eax & 0xff;
+	case 1:
+	    return context->ecx & 0xff;
+	case 2:
+	    return context->edx & 0xff;
+	case 3:
+	    return context->ebx & 0xff;
+	case 4:
+	    return (context->eax >> 8) & 0xff;
+	case 5:
+	    return (context->ecx >> 8) & 0xff;
+	case 6:
+	    return (context->edx >> 8) & 0xff;
+	case 7:
+	    return (context->ebx >> 8) & 0xff;
+	}
+	break;
 
     case 16:
-        switch ( reg )
-        {
-        case 0: return context->eax & 0xffff;
-        case 1: return context->ecx & 0xffff;
-        case 2: return context->edx & 0xffff;
-        case 3: return context->ebx & 0xffff;
-        case 4: return context->esp & 0xffff;
-        case 5: return context->ebp & 0xffff;
-        case 6: return context->esi & 0xffff;
-        case 7: return context->edi & 0xffff;
-        }
-        break;
+	switch (reg)
+	{
+	case 0:
+	    return context->eax & 0xffff;
+	case 1:
+	    return context->ecx & 0xffff;
+	case 2:
+	    return context->edx & 0xffff;
+	case 3:
+	    return context->ebx & 0xffff;
+	case 4:
+	    return context->esp & 0xffff;
+	case 5:
+	    return context->ebp & 0xffff;
+	case 6:
+	    return context->esi & 0xffff;
+	case 7:
+	    return context->edi & 0xffff;
+	}
+	break;
 
     case 32:
-        switch ( reg )
-        {
-        case 0: return context->eax;
-        case 1: return context->ecx;
-        case 2: return context->edx;
-        case 3: return context->ebx;
-        case 4: return context->esp;
-        case 5: return context->ebp;
-        case 6: return context->esi;
-        case 7: return context->edi;
-        }
-        break;
+	switch (reg)
+	{
+	case 0:
+	    return context->eax;
+	case 1:
+	    return context->ecx;
+	case 2:
+	    return context->edx;
+	case 3:
+	    return context->ebx;
+	case 4:
+	    return context->esp;
+	case 5:
+	    return context->ebp;
+	case 6:
+	    return context->esi;
+	case 7:
+	    return context->edi;
+	}
+	break;
     }
     return 0;
 }
 
 static Bit32u
-decode_memory_operand(vm_t *vm, guest_context_t *context, int operand_size, Bit32u addr)
+decode_memory_operand (vm_t * vm, guest_context_t * context, int operand_size, Bit32u addr)
 {
-    switch ( operand_size )
+    switch (operand_size)
     {
-    case 8:   return read_guest_byte(vm, &addr);
-    case 16:  return read_guest_word(vm, &addr);
-    case 32:  return read_guest_dword(vm, &addr);
+    case 8:
+	return read_guest_byte (vm, &addr);
+    case 16:
+	return read_guest_word (vm, &addr);
+    case 32:
+	return read_guest_dword (vm, &addr);
     }
     return 0;
 }
 
 static Bit32u
-decode_effective_address(vm_t *vm, guest_context_t *context, int address_size, 
-                         Bit8u ModRegRM, Bit32u *addr)
+decode_effective_address (vm_t * vm, guest_context_t * context, int address_size,
+			  Bit8u ModRegRM, Bit32u * addr)
 {
-    Bit32u mod = FieldMod(ModRegRM);
-    if ( mod == 3 ) return 0;   /* not an effective address - can't happen */
+    Bit32u mod = FieldMod (ModRegRM);
 
-    if ( address_size == 16 )
-    { 
-        Bit32u base = 0, displ = 0;
-
-        /* Decode Base + Index */
-        switch ( FieldRM(ModRegRM) )
-        {
-        case 0: base = context->ebx + context->esi; break;
-        case 1: base = context->ebx + context->edi; break;
-        case 2: base = context->ebp + context->esi; break;
-        case 3: base = context->ebp + context->edi; break;
-        case 4: base = context->esi; break;
-        case 5: base = context->edi; break;
-        case 6: base = mod? context->ebp : read_guest_word(vm, addr); break;
-        case 7: base = context->ebx;
-        }
-
-        /* Get Displacement */
-        switch ( mod )
-        {
-        case 1:  displ = (signed char)read_guest_byte(vm, addr); break;
-        case 2:  displ = read_guest_word(vm, addr); break;
-        }
+    if (mod == 3)
+	return 0;		/* not an effective address - can't happen */
 
-        return (base + displ) & 0xffff;
+    if (address_size == 16)
+    {
+	Bit32u base = 0, displ = 0;
+
+	/* Decode Base + Index */
+	switch (FieldRM (ModRegRM))
+	{
+	case 0:
+	    base = context->ebx + context->esi;
+	    break;
+	case 1:
+	    base = context->ebx + context->edi;
+	    break;
+	case 2:
+	    base = context->ebp + context->esi;
+	    break;
+	case 3:
+	    base = context->ebp + context->edi;
+	    break;
+	case 4:
+	    base = context->esi;
+	    break;
+	case 5:
+	    base = context->edi;
+	    break;
+	case 6:
+	    base = mod ? context->ebp : read_guest_word (vm, addr);
+	    break;
+	case 7:
+	    base = context->ebx;
+	}
+
+	/* Get Displacement */
+	switch (mod)
+	{
+	case 1:
+	    displ = (signed char) read_guest_byte (vm, addr);
+	    break;
+	case 2:
+	    displ = read_guest_word (vm, addr);
+	    break;
+	}
+
+	return (base + displ) & 0xffff;
     }
     else
-    { 
-        Bit32u base, index = 0, displ = 0;
+    {
+	Bit32u base, index = 0, displ = 0;
+
+	/* Get SIB byte if present */
+	if ((base = FieldRM (ModRegRM)) == 4)
+	{
+	    Bit8u sib = read_guest_byte (vm, addr);
+
+	    base = FieldSIBBase (sib);
+
+	    switch (FieldSIBIndex (sib))
+	    {
+	    case 0:
+		index = context->eax;
+		break;
+	    case 1:
+		index = context->ecx;
+		break;
+	    case 2:
+		index = context->edx;
+		break;
+	    case 3:
+		index = context->ebx;
+		break;
+	    case 4:
+		index = 0;
+		break;
+	    case 5:
+		index = context->ebp;
+		break;
+	    case 6:
+		index = context->esi;
+		break;
+	    case 7:
+		index = context->edi;
+		break;
+	    }
+
+	    index <<= FieldSIBScale (sib);
+	}
+
+	/* Decode Base */
+	switch (base)
+	{
+	case 0:
+	    base = context->eax;
+	    break;
+	case 1:
+	    base = context->ecx;
+	    break;
+	case 2:
+	    base = context->edx;
+	    break;
+	case 3:
+	    base = context->ebx;
+	    break;
+	case 4:
+	    base = context->esp;
+	    break;
+	case 5:
+	    base = mod ? context->ebp : read_guest_dword (vm, addr);
+	    break;
+	case 6:
+	    base = context->esi;
+	    break;
+	case 7:
+	    base = context->edi;
+	    break;
+	}
 
-        /* Get SIB byte if present */
-        if ( (base = FieldRM(ModRegRM)) == 4 )
-        {
-            Bit8u sib = read_guest_byte(vm, addr);
-            base = FieldSIBBase(sib);
-
-            switch ( FieldSIBIndex(sib) )
-            {
-            case 0: index = context->eax; break;
-            case 1: index = context->ecx; break;
-            case 2: index = context->edx; break;
-            case 3: index = context->ebx; break;
-            case 4: index = 0;            break;
-            case 5: index = context->ebp; break;
-            case 6: index = context->esi; break;
-            case 7: index = context->edi; break;
-            }
-
-            index <<= FieldSIBScale(sib);
-        }
-
-        /* Decode Base */
-        switch ( base )
-        {
-        case 0: base = context->eax; break;
-        case 1: base = context->ecx; break;
-        case 2: base = context->edx; break;
-        case 3: base = context->ebx; break;
-        case 4: base = context->esp; break;
-        case 5: base = mod? context->ebp : read_guest_dword(vm, addr); break;
-        case 6: base = context->esi; break;
-        case 7: base = context->edi; break;
-        }
-
-        /* Get Displacement */
-        switch ( mod )
-        {
-        case 1:  displ = (signed char)read_guest_byte(vm, addr); break;
-        case 2:  displ = read_guest_dword(vm, addr); break;
-        }
+	/* Get Displacement */
+	switch (mod)
+	{
+	case 1:
+	    displ = (signed char) read_guest_byte (vm, addr);
+	    break;
+	case 2:
+	    displ = read_guest_dword (vm, addr);
+	    break;
+	}
 
-        return base + index + displ;
+	return base + index + displ;
     }
 }
 
 static Bit32u
-decode_rm_operand(vm_t *vm, guest_context_t *context, int operand_size, int address_size,
-                  Bit8u ModRegRM, Bit32u *addr)
+decode_rm_operand (vm_t * vm, guest_context_t * context, int operand_size, int address_size,
+		   Bit8u ModRegRM, Bit32u * addr)
 {
     Bit32u ptr, val;
 
-    if ( FieldMod(ModRegRM) == 3 )
-        val = decode_register(vm, context, operand_size, FieldRM(ModRegRM) );
+    if (FieldMod (ModRegRM) == 3)
+	val = decode_register (vm, context, operand_size, FieldRM (ModRegRM));
     else
     {
-        ptr = decode_effective_address(vm, context, address_size, ModRegRM, addr );
-        val = decode_memory_operand(vm,  context, operand_size, ptr );
+	ptr = decode_effective_address (vm, context, address_size, ModRegRM, addr);
+	val = decode_memory_operand (vm, context, operand_size, ptr);
     }
 
     return val;
@@ -506,7 +634,7 @@
 
 
 int
-emulate(vm_t *vm, guest_context_t *context)
+emulate (vm_t * vm, guest_context_t * context)
 /*
  *  emulation(): find out faulting instruction, jump to emulation function
  *
@@ -517,228 +645,247 @@
  *     0 if no success
  *     1 if success
  *     2 if success, but monitor needs to be remapped
- */ 
+ */
 {
-    int action = 0;
-    int use32 = 1;       /* FIXME: is CS 16-bit or 32-bit */
-    int address_size;
-    int operand_size;
-    int seg_override = 0;
-    int rep = 0;
+    int   action = 0;
+    int   use32 = 1;		/* FIXME: is CS 16-bit or 32-bit */
+    int   address_size;
+    int   operand_size;
+    int   seg_override = 0;
+    int   rep = 0;
     Bit8u c;
     Bit32u addr, val;
     Bit32u eip = context->eip;
     Bit32u esp = context->esp;
-  
-    address_size = use32? 32 : 16;
-    operand_size = use32? 32 : 16;
+
+    address_size = use32 ? 32 : 16;
+    operand_size = use32 ? 32 : 16;
 
     /*
      * Decode Intel instruction
      */
 
- prefix:
-    c = read_guest_byte(vm,&eip);
-    switch (c) 
-    {
-    case 0x26: /* ES prefix */
-        seg_override = context->es;
-        goto prefix;
-    case 0x2e: /* CS prefix */
-        seg_override = context->cs;
-        goto prefix;
-    case 0x36: /* SS prefix */
-        seg_override = context->ss;
-        goto prefix;
-    case 0x3e: /* DS prefix */
-        seg_override = context->ds;
-        goto prefix;
-    case 0x64: /* FS prefix */
-        seg_override = context->fs;
-        goto prefix;
-    case 0x65: /* GS prefix */
-        seg_override = context->gs;
-        goto prefix;
-    case 0x66: /* Operand size prefix */
-        operand_size = use32? 16 : 32;
-        goto prefix;
-    case 0x67: /* Address size prefix */
-        address_size = use32? 16 : 32;
-        goto prefix;
-    case 0xf3: /* rep prefix */
-        rep = 1;
-        goto prefix;
-
-    case 0x07: /* pop ES */
-        val = guest_stack_pop(vm, &esp, operand_size);
-        action = emulate_load_es(vm, context, val);
-        break;
-    case 0x17: /* pop SS */
-        val = guest_stack_pop(vm, &esp, operand_size);
-        action = emulate_load_ss(vm, context, val);
-        break;
-    case 0x1f: /* pop DS */
-        val = guest_stack_pop(vm, &esp, operand_size);
-        action = emulate_load_ds(vm, context, val);
-        break;
-
-    case 0x6c: /* insb == ins dx, m8 */
-      action = emulate_ins(vm, context, 8, address_size, rep);
-      break;
-
-    case 0x6d: /* insw || insd */
-      action = emulate_ins(vm, context, operand_size, address_size, rep);
-      break;
-
-    case 0x6e: /* outsb == outs dx, m8 */
-      action = emulate_outs(vm, context, 8, address_size, rep);
-      break;
-
-    case 0x6f: /* outsw || outsd */
-      action = emulate_outs(vm, context, operand_size, address_size, rep);
-      break;
-
-    case 0x8e: /* mov Sw, Ew */
-        c = read_guest_byte(vm, &eip);  /* RegModRM */
-        val = decode_rm_operand(vm, context, 16, address_size, c, &eip);
-        switch ( FieldReg(c) )
-        {
-        case 0: action = emulate_load_es(vm, context, val); break;
-        case 1: /* mov CS, ... ??? */; break;
-        case 2: action = emulate_load_ss(vm, context, val); break;
-        case 3: action = emulate_load_ds(vm, context, val); break;
-        case 4: action = emulate_load_fs(vm, context, val); break;
-        case 5: action = emulate_load_gs(vm, context, val); break;
-        }
-        break;
-
-    case 0xcc: /* int3 */
-        action = emulate_int(vm, context, 3, eip);
-        break;
-
-    case 0xcd: /* int Ib */
-        c = read_guest_byte(vm, &eip);
-        action = emulate_int(vm, context, c, eip);
-        break;
-
-    case 0xcf: /* iret */
-        action = emulate_iret(vm, context);
-        break;
-
-    case 0xe4: /* in imm8,al */
-        c = read_guest_byte(vm, &eip);
-        action = emulate_in(vm, context, 8, c);
-        break;
-
-    case 0xe5: /* in imm8,[e]ax */
-        c = read_guest_byte(vm, &eip);
-        action = emulate_in(vm, context, operand_size, c);
-        break;
-
-    case 0xe6: /* out imm8,al */
-        c = read_guest_byte(vm, &eip);
-        action = emulate_out(vm, context, 8, c);
-        break;
-
-    case 0xe7: /* out imm8,[e]ax */
-        c = read_guest_byte(vm, &eip);
-        action = emulate_out(vm, context, operand_size, c);
-        break;
-
-    case 0xea: /* ljmp */
-        action = emulate_ljmp(vm, context);
-        break;
-
-
-    case 0xec: /* in al,dx */
-        action = emulate_in(vm, context, 8, context->edx & 0xffff);
-        break;
-
-    case 0xed: /* in [e]ax,dx */
-        action = emulate_in(vm, context, operand_size, context->edx & 0xffff);
-        break;
-
-    case 0xee: /* out dx,al */
-        action = emulate_out(vm, context, 8, context->edx & 0xffff);
-        break;
-
-    case 0xef: /* out dx,[e]ax */
-        action = emulate_out(vm, context, operand_size, context->edx & 0xffff);
-        break;
-
-    case 0xf4: /* hlt */
-        action = emulate_hlt(vm, context);
-        break;
-
-    case 0xfa: /* cli */
-        action = emulate_cli(vm, context);
-        break;
-
-    case 0xfb: /* sti */
-        action = emulate_sti(vm, context);
-        break;
+  prefix:
+    c = read_guest_byte (vm, &eip);
+    switch (c)
+    {
+    case 0x26:			/* ES prefix */
+	seg_override = context->es;
+	goto prefix;
+    case 0x2e:			/* CS prefix */
+	seg_override = context->cs;
+	goto prefix;
+    case 0x36:			/* SS prefix */
+	seg_override = context->ss;
+	goto prefix;
+    case 0x3e:			/* DS prefix */
+	seg_override = context->ds;
+	goto prefix;
+    case 0x64:			/* FS prefix */
+	seg_override = context->fs;
+	goto prefix;
+    case 0x65:			/* GS prefix */
+	seg_override = context->gs;
+	goto prefix;
+    case 0x66:			/* Operand size prefix */
+	operand_size = use32 ? 16 : 32;
+	goto prefix;
+    case 0x67:			/* Address size prefix */
+	address_size = use32 ? 16 : 32;
+	goto prefix;
+    case 0xf3:			/* rep prefix */
+	rep = 1;
+	goto prefix;
+
+    case 0x07:			/* pop ES */
+	val = guest_stack_pop (vm, &esp, operand_size);
+	action = emulate_load_es (vm, context, val);
+	break;
+    case 0x17:			/* pop SS */
+	val = guest_stack_pop (vm, &esp, operand_size);
+	action = emulate_load_ss (vm, context, val);
+	break;
+    case 0x1f:			/* pop DS */
+	val = guest_stack_pop (vm, &esp, operand_size);
+	action = emulate_load_ds (vm, context, val);
+	break;
+
+    case 0x6c:			/* insb == ins dx, m8 */
+	action = emulate_ins (vm, context, 8, address_size, rep);
+	break;
+
+    case 0x6d:			/* insw || insd */
+	action = emulate_ins (vm, context, operand_size, address_size, rep);
+	break;
+
+    case 0x6e:			/* outsb == outs dx, m8 */
+	action = emulate_outs (vm, context, 8, address_size, rep);
+	break;
+
+    case 0x6f:			/* outsw || outsd */
+	action = emulate_outs (vm, context, operand_size, address_size, rep);
+	break;
+
+    case 0x8e:			/* mov Sw, Ew */
+	c = read_guest_byte (vm, &eip);		/* RegModRM */
+	val = decode_rm_operand (vm, context, 16, address_size, c, &eip);
+	switch (FieldReg (c))
+	{
+	case 0:
+	    action = emulate_load_es (vm, context, val);
+	    break;
+	case 1:		/* mov CS, ... ??? */ ;
+	    break;
+	case 2:
+	    action = emulate_load_ss (vm, context, val);
+	    break;
+	case 3:
+	    action = emulate_load_ds (vm, context, val);
+	    break;
+	case 4:
+	    action = emulate_load_fs (vm, context, val);
+	    break;
+	case 5:
+	    action = emulate_load_gs (vm, context, val);
+	    break;
+	}
+	break;
+
+    case 0xcc:			/* int3 */
+	action = emulate_int (vm, context, 3, eip);
+	break;
+
+    case 0xcd:			/* int Ib */
+	c = read_guest_byte (vm, &eip);
+	action = emulate_int (vm, context, c, eip);
+	break;
+
+    case 0xcf:			/* iret */
+	action = emulate_iret (vm, context);
+	break;
+
+    case 0xe4:			/* in imm8,al */
+	c = read_guest_byte (vm, &eip);
+	action = emulate_in (vm, context, 8, c);
+	break;
+
+    case 0xe5:			/* in imm8,[e]ax */
+	c = read_guest_byte (vm, &eip);
+	action = emulate_in (vm, context, operand_size, c);
+	break;
+
+    case 0xe6:			/* out imm8,al */
+	c = read_guest_byte (vm, &eip);
+	action = emulate_out (vm, context, 8, c);
+	break;
+
+    case 0xe7:			/* out imm8,[e]ax */
+	c = read_guest_byte (vm, &eip);
+	action = emulate_out (vm, context, operand_size, c);
+	break;
+
+    case 0xea:			/* ljmp */
+	action = emulate_ljmp (vm, context);
+	break;
+
+
+    case 0xec:			/* in al,dx */
+	action = emulate_in (vm, context, 8, context->edx & 0xffff);
+	break;
+
+    case 0xed:			/* in [e]ax,dx */
+	action = emulate_in (vm, context, operand_size, context->edx & 0xffff);
+	break;
+
+    case 0xee:			/* out dx,al */
+	action = emulate_out (vm, context, 8, context->edx & 0xffff);
+	break;
+
+    case 0xef:			/* out dx,[e]ax */
+	action = emulate_out (vm, context, operand_size, context->edx & 0xffff);
+	break;
+
+    case 0xf4:			/* hlt */
+	action = emulate_hlt (vm, context);
+	break;
+
+    case 0xfa:			/* cli */
+	action = emulate_cli (vm, context);
+	break;
+
+    case 0xfb:			/* sti */
+	action = emulate_sti (vm, context);
+	break;
 
     case 0x0f:
-        /* there are some instructions beginning with 0x0f
-         * we have a look on the second opcode byte
-         */
-        c = read_guest_byte(vm, &eip);
-        switch (c) 
-        {
-        case 0x00: /* Group 6 */
-            c = read_guest_byte(vm, &eip);
-            switch (FieldReg(c))
-            {
-            case 2:  /* lldt */
-                val = decode_rm_operand(vm, context, 16, address_size, c, &eip);
-                action = emulate_lldt(vm, val);
-                break;
-
-            case 3:  /* ltr */
-                val = decode_rm_operand(vm, context, 16, address_size, c, &eip);
-                action = emulate_ltr(vm, val);
-                break;
-            }
-            break;
-
-        case 0x01: /* Group 7 */
-            c = read_guest_byte(vm, &eip);
-            switch (FieldReg(c))
-            {
-            case 2:  /* lgdt */
-                addr = decode_effective_address(vm, context, address_size, c, &eip);
-                action = emulate_lgdt(vm, context, addr);
-                break;
-
-            case 3:  /* lidt */
-                addr = decode_effective_address(vm, context, address_size, c, &eip);
-                action = emulate_lidt(vm, addr);
-                break;
-            }
-            break;
-
-        case 0x06: /* clts */
-            action = emulate_clts(vm);
-            break;
-
-	case 0x08: /* invd */
-	  action = emulate_invd(vm);
-	  break;
-	    
-	case 0x09: /* wbinvd */
-	  action = emulate_wbinvd(vm);
-	  break;
-
-        case 0xa1: /* pop FS */
-            val = guest_stack_pop(vm, &esp, operand_size);
-            action = emulate_load_fs(vm, context, val);
-            break;
-        case 0xa9: /* pop GS */
-            val = guest_stack_pop(vm, &esp, operand_size);
-            action = emulate_load_gs(vm, context, val);
-            break;
-        }
-        break;
+	/* there are some instructions beginning with 0x0f
+	 * we have a look on the second opcode byte
+	 */
+	c = read_guest_byte (vm, &eip);
+	switch (c)
+	{
+	case 0x00:		/* Group 6 */
+	    c = read_guest_byte (vm, &eip);
+	    switch (FieldReg (c))
+	    {
+	    case 2:		/* lldt */
+		val = decode_rm_operand (vm, context, 16, address_size, c, &eip);
+		action = emulate_lldt (vm, val);
+		break;
+
+	    case 3:		/* ltr */
+		val = decode_rm_operand (vm, context, 16, address_size, c, &eip);
+		action = emulate_ltr (vm, val);
+		break;
+	    }
+	    break;
+
+	case 0x01:		/* Group 7 */
+	    c = read_guest_byte (vm, &eip);
+	    switch (FieldReg (c))
+	    {
+	    case 2:		/* lgdt */
+		addr = decode_effective_address (vm, context, address_size, c, &eip);
+		action = emulate_lgdt (vm, context, addr);
+		break;
+
+	    case 3:		/* lidt */
+		addr = decode_effective_address (vm, context, address_size, c, &eip);
+		action = emulate_lidt (vm, addr);
+		break;
+	    }
+	    break;
+
+	case 0x06:		/* clts */
+	    action = emulate_clts (vm);
+	    break;
+
+	case 0x08:		/* invd */
+	    action = emulate_invd (vm);
+	    break;
+
+	case 0x09:		/* wbinvd */
+	    action = emulate_wbinvd (vm);
+	    break;
+
+	case 0x20:		/* mov r32, CRx (CRx to register) */
+	    action = emulate_mov_from_cr (vm, context);
+	    break;
+
+	case 0x22:		/* mov CRx, r32 */
+	    action = emulate_mov_to_cr (vm, context);
+	    break;
+
+	case 0xa1:		/* pop FS */
+	    val = guest_stack_pop (vm, &esp, operand_size);
+	    action = emulate_load_fs (vm, context, val);
+	    break;
+	case 0xa9:		/* pop GS */
+	    val = guest_stack_pop (vm, &esp, operand_size);
+	    action = emulate_load_gs (vm, context, val);
+	    break;
+	}
+	break;
     }
 
 
@@ -746,62 +893,62 @@
     switch (action)
     {
     default:
-    case 0:   /* Failure */
-        return 0;
+    case 0:			/* Failure */
+	return 0;
 
-    case 1:   /* Retry instruction */
-        return 1;
+    case 1:			/* Retry instruction */
+	return 1;
 
-    case 2:   /* Skip instruction */
-        context->eip = eip;
-        context->esp = esp;
-        return 1;
+    case 2:			/* Skip instruction */
+	context->eip = eip;
+	context->esp = esp;
+	return 1;
 
-    case 3:   /* Remap monitor and skip instruction */
-        context->eip = eip;
-        context->esp = esp;
-        return 2;
+    case 3:			/* Remap monitor and skip instruction */
+	context->eip = eip;
+	context->esp = esp;
+	return 2;
 
-    case 4:   /* Try to emulate in user space */
-        context->eip = eip;
-        context->esp = esp;
-        return 3;
+    case 4:			/* Try to emulate in user space */
+	context->eip = eip;
+	context->esp = esp;
+	return 3;
     }
 }
 
 
 int
-emulate_cli(vm_t *vm, guest_context_t *context)
+emulate_cli (vm_t * vm, guest_context_t * context)
      /*
       * Emulate cli instruction
       */
 {
-    int cpl = vm->common.addr->nexus->guest_cpl;
+    int   cpl = vm->common.addr->nexus->guest_cpl;
 
-    if (cpl > FLG_GET_IOPL(vm->common.addr->nexus->guest_eflags))
+    if (cpl > FLG_GET_IOPL (vm->common.addr->nexus->guest_eflags))
     {
-        return 0;
+	return 0;
     }
 
     vm->common.addr->nexus->guest_eflags &= ~FLG_IF;
-    context->eflags = FLG_BUILD(context->eflags,
-                                vm->common.addr->nexus->guest_eflags,
-                                vm->common.addr->nexus->mon_eflags);
+    context->eflags = FLG_BUILD (context->eflags,
+				 vm->common.addr->nexus->guest_eflags,
+				 vm->common.addr->nexus->mon_eflags);
 
     return 2;
 }
 
 int
-emulate_sti(vm_t *vm, guest_context_t *context) 
+emulate_sti (vm_t * vm, guest_context_t * context)
      /* 
       * Emulate sti instruction
       */
 {
-    int cpl = vm->common.addr->nexus->guest_cpl;
+    int   cpl = vm->common.addr->nexus->guest_cpl;
 
-    if (cpl > FLG_GET_IOPL(vm->common.addr->nexus->guest_eflags))
+    if (cpl > FLG_GET_IOPL (vm->common.addr->nexus->guest_eflags))
     {
-        return 0;
+	return 0;
     }
 
     vm->common.addr->nexus->guest_eflags |= FLG_IF;
@@ -809,25 +956,25 @@
     /* if the VIP flag is set, we need to trap to the user */
     if (vm->common.addr->nexus->mon_eflags & FLG_VIP)
     {
-        context->event_info = EMU_INSTR_STI | (RET_BECAUSE_USEREMU << 8);
+	context->event_info = EMU_INSTR_STI | (RET_BECAUSE_USEREMU << 8);
 
-        vm->common.addr->nexus->mon_eflags &= ~FLG_VIP;
-        context->eflags = FLG_BUILD(context->eflags,
-                                    vm->common.addr->nexus->guest_eflags,
-                                    vm->common.addr->nexus->mon_eflags);
-        return 4;
+	vm->common.addr->nexus->mon_eflags &= ~FLG_VIP;
+	context->eflags = FLG_BUILD (context->eflags,
+				     vm->common.addr->nexus->guest_eflags,
+				     vm->common.addr->nexus->mon_eflags);
+	return 4;
     }
     else
     {
-        context->eflags = FLG_BUILD(context->eflags,
-                                    vm->common.addr->nexus->guest_eflags,
-                                    vm->common.addr->nexus->mon_eflags);
-        return 2;
+	context->eflags = FLG_BUILD (context->eflags,
+				     vm->common.addr->nexus->guest_eflags,
+				     vm->common.addr->nexus->mon_eflags);
+	return 2;
     }
 }
 
 int
-emulate_clts(vm_t *vm) 
+emulate_clts (vm_t * vm)
      /* 
       * Emulate clts instruction
       */
@@ -837,17 +984,18 @@
 }
 
 int
-emulate_lgdt(vm_t *vm, guest_context_t *context, Bit32u addr) 
+emulate_lgdt (vm_t * vm, guest_context_t * context, Bit32u addr)
      /* 
       * Emulate lgdt instruction
       */
 {
     descriptor_t *monitor_gdt;
-    Bit16u limit = read_guest_word(vm, &addr);
-    Bit32u base  = read_guest_dword(vm, &addr);
-    descriptor_t current_cs, current_ds, current_es, current_fs, current_gs, current_ss;
-    int nr_currents = 0;
-    int i, nr_descriptors;
+    Bit16u limit = read_guest_word (vm, &addr);
+    Bit32u base = read_guest_dword (vm, &addr);
+    descriptor_t current_cs, current_ds, current_es, current_fs, current_gs,
+          current_ss;
+    int   nr_currents = 0;
+    int   i, nr_descriptors;
 
     monitor_gdt = vm->common.addr->gdt;
 
@@ -862,53 +1010,57 @@
 
     /* "install" new gdt */
     vm->common.addr->nexus->guest_gdt_info.limit = limit;
-    vm->common.addr->nexus->guest_gdt_info.base  = base;
+    vm->common.addr->nexus->guest_gdt_info.base = base;
 
-    if ( limit >= MON_GDT_PAGES*PAGESIZE ) return 0;
-    nr_descriptors = (limit+1) / 8;
+    if (limit >= MON_GDT_PAGES * PAGESIZE)
+	return 0;
+    nr_descriptors = (limit + 1) / 8;
 
-    for ( i = 1; i < nr_descriptors; i++ )
+    for (i = 1; i < nr_descriptors; i++)
     {
-        descriptor_t descr;
-        read_guest_descriptor(vm, &descr, i << 3);
-        
-        if ( descr.type & 0x10 )
-        {
-            /* Code or data segment descriptor */
-
-            /* For now, we let everything go through unchanged, 
-               only the DPL is forced to 3 */
-            descr.dpl = D_DPL3;
-
-            /* Change code segments to data segments; this is to make all
-               inter-segment transfers, especially iret, fault. */
-            descr.type &= ~0x08;
-        }
-        else
-        {
-            /* System segment descriptor */
-       
-            switch ( descr.type )
-            {
-            case D_TSS: case D_TSS | 2:  /* available/busy TSS */
-                /* Force the DPL to zero to disallow task switches */
-                descr.dpl = D_DPL0;
-                break;
-
-            /* FIXME: Don't allow LDTs or gates for now ... */
-            case D_LDT:
-            case D_CALL:
-            case D_INT: case D_TRAP:
-            default:
-                clear_descriptor(vm, &descr);
-                break;
-            }
-        }
+	descriptor_t descr;
+
+	read_guest_descriptor (vm, &descr, i << 3);
+
+	if (descr.type & 0x10)
+	{
+	    /* Code or data segment descriptor */
+
+	    /* For now, we let everything go through unchanged, 
+	     * only the DPL is forced to 3 */
+	    descr.dpl = D_DPL3;
+
+	    /* Change code segments to data segments; this is to make all
+	     * inter-segment transfers, especially iret, fault. */
+	    descr.type &= ~0x08;
+	}
+	else
+	{
+	    /* System segment descriptor */
+
+	    switch (descr.type)
+	    {
+	    case D_TSS:
+	    case D_TSS | 2:	/* available/busy TSS */
+		/* Force the DPL to zero to disallow task switches */
+		descr.dpl = D_DPL0;
+		break;
+
+		/* FIXME: Don't allow LDTs or gates for now ... */
+	    case D_LDT:
+	    case D_CALL:
+	    case D_INT:
+	    case D_TRAP:
+	    default:
+		clear_descriptor (vm, &descr);
+		break;
+	    }
+	}
 
-        monitor_gdt[i] = descr;
+	monitor_gdt[i] = descr;
     }
-    for ( ; i < MON_GDT_PAGES*PAGESIZE / 8; i++ )
-        clear_descriptor(vm, monitor_gdt + i);
+    for (; i < MON_GDT_PAGES * PAGESIZE / 8; i++)
+	clear_descriptor (vm, monitor_gdt + i);
 
 
     /* in a real processor the old segments were used after lgdt due to selector caches
@@ -917,75 +1069,75 @@
      * therefore we look for unused gdt entries, fill them with old used selector and
      * use them (fill selectors with "new old" values)
      */
-    for (i = 1, nr_currents = 0 ; i < MON_GDT_PAGES*PAGESIZE / 8; i++ )
+    for (i = 1, nr_currents = 0; i < MON_GDT_PAGES * PAGESIZE / 8; i++)
     {
-        descriptor_t descr;
+	descriptor_t descr;
 
-        descr = monitor_gdt[i];
+	descr = monitor_gdt[i];
 
-	if (((Bit32u *)&descr)[0] == 0 && ((Bit32u *)&descr)[1] == 0)
+	if (((Bit32u *) & descr)[0] == 0 && ((Bit32u *) & descr)[1] == 0)
 	{
 	    /* this gdt entry is unused, we may fill it with old descriptors still needed */
 	    switch (nr_currents)
 	    {
 	    case 0:
-                nr_currents++;
-                if ( context->cs )
-                {
+		nr_currents++;
+		if (context->cs)
+		{
 		    monitor_gdt[i] = current_cs;
 		    context->cs = (i << 3) + 3;
 		    break;
-                }
+		}
 	    case 1:
-                nr_currents++;
-                if ( context->ss )
-                {
+		nr_currents++;
+		if (context->ss)
+		{
 		    monitor_gdt[i] = current_ss;
 		    context->ss = (i << 3) + 3;
 		    break;
-                }
+		}
 	    case 2:
-                nr_currents++;
-                if ( context->ds )
-                {
+		nr_currents++;
+		if (context->ds)
+		{
 		    monitor_gdt[i] = current_ds;
 		    context->ds = (i << 3) + 3;
 		    break;
-                }
+		}
 	    case 3:
-                nr_currents++;
-                if ( context->es )
-                {
+		nr_currents++;
+		if (context->es)
+		{
 		    monitor_gdt[i] = current_es;
 		    context->es = (i << 3) + 3;
 		    break;
-                }
+		}
 	    case 4:
-                nr_currents++;
-                if ( context->fs )
-                {
+		nr_currents++;
+		if (context->fs)
+		{
 		    monitor_gdt[i] = current_fs;
 		    context->fs = (i << 3) + 3;
 		    break;
-                }
+		}
 	    case 5:
-                nr_currents++;
-                if ( context->gs )
-                {
+		nr_currents++;
+		if (context->gs)
+		{
 		    monitor_gdt[i] = current_gs;
 		    context->gs = (i << 3) + 3;
 		    break;
-                }
+		}
 	    }
 	}
     }
 
 
     /* Mark current CS active */
-    codeseg_activate(vm, context->cs, 1);
+    codeseg_activate (vm, context->cs, 1);
 
     /* We have just clobbered the monitor selectors.  Zero them out in the
-       nexus data structure to reflect this.  See unmap_monitor() ... */
+     * nexus data structure to reflect this.  See unmap_monitor() ... */
     vm->common.addr->nexus->mon_jmp_info.selector = 0;
     vm->common.addr->nexus->mon_stack_info.selector = 0;
     vm->common.addr->nexus->mon_tss_sel = 0;
@@ -995,41 +1147,44 @@
 }
 
 int
-emulate_lidt(vm_t *vm, Bit32u addr) 
+emulate_lidt (vm_t * vm, Bit32u addr)
      /* 
       * Emulate lidt instruction
       */
 {
-    Bit16u limit = read_guest_word(vm, &addr);
-    Bit32u base  = read_guest_dword(vm, &addr);
+    Bit16u limit = read_guest_word (vm, &addr);
+    Bit32u base = read_guest_dword (vm, &addr);
 
     vm->common.addr->nexus->guest_idt_info.limit = limit;
-    vm->common.addr->nexus->guest_idt_info.base  = base;
+    vm->common.addr->nexus->guest_idt_info.base = base;
 
     return 2;
 }
 
 int
-emulate_lldt(vm_t *vm, Bit16u selector) 
+emulate_lldt (vm_t * vm, Bit16u selector)
      /* 
       * Emulate lldt instruction
       */
 {
     descriptor_t descr;
 
-    if (selector & 4) return 0;    /* No LDT allowed */
+    if (selector & 4)
+	return 0;		/* No LDT allowed */
 
     if (selector)
     {
-        read_guest_descriptor(vm, &descr, selector);
-        if (!descr.p) return 0;
-        if (descr.type != D_LDT) return 0;
+	read_guest_descriptor (vm, &descr, selector);
+	if (!descr.p)
+	    return 0;
+	if (descr.type != D_LDT)
+	    return 0;
     }
     else
     {
-        clear_descriptor(vm, &descr);
+	clear_descriptor (vm, &descr);
     }
-    
+
     vm->common.addr->nexus->guest_ldt_sel = selector;
     vm->common.addr->nexus->guest_ldt_descr = descr;
 
@@ -1037,22 +1192,25 @@
 }
 
 int
-emulate_ltr(vm_t *vm, Bit16u selector) 
+emulate_ltr (vm_t * vm, Bit16u selector)
      /* 
       * Emulate ltr instruction
       */
 {
     descriptor_t descr;
+
+    if (selector & 4)
+	return 0;		/* No LDT allowed */
 
-    if (selector & 4) return 0;    /* No LDT allowed */
+    read_guest_descriptor (vm, &descr, selector);
+    if (!descr.p)
+	return 0;
+    if (descr.type != D_TSS)
+	return 0;
 
-    read_guest_descriptor(vm, &descr, selector);
-    if (!descr.p) return 0;
-    if (descr.type != D_TSS) return 0;
-    
-    descr.type |= 2;  /* set busy flag */
+    descr.type |= 2;		/* set busy flag */
 
-    write_guest_descriptor(vm, &descr, selector);
+    write_guest_descriptor (vm, &descr, selector);
 
     vm->common.addr->nexus->guest_tss_sel = selector;
     vm->common.addr->nexus->guest_tss_descr = descr;
@@ -1061,13 +1219,13 @@
 }
 
 int
-emulate_load_ds(vm_t *vm, guest_context_t *context, Bit16u selector)
+emulate_load_ds (vm_t * vm, guest_context_t * context, Bit16u selector)
      /* 
       * Emulate instruction that loads DS register
       */
 {
     descriptor_t *monitor_gdt;
- 
+
     monitor_gdt = vm->common.addr->gdt;
 
     // force the segment to 3;
@@ -1083,7 +1241,7 @@
 }
 
 int
-emulate_load_es(vm_t *vm, guest_context_t *context, Bit16u selector)
+emulate_load_es (vm_t * vm, guest_context_t * context, Bit16u selector)
      /* 
       * Emulate instruction that loads ES register
       */
@@ -1096,7 +1254,7 @@
 }
 
 int
-emulate_load_fs(vm_t *vm, guest_context_t *context, Bit16u selector)
+emulate_load_fs (vm_t * vm, guest_context_t * context, Bit16u selector)
      /* 
       * Emulate instruction that loads FS register
       */
@@ -1109,7 +1267,7 @@
 }
 
 int
-emulate_load_gs(vm_t *vm, guest_context_t *context, Bit16u selector)
+emulate_load_gs (vm_t * vm, guest_context_t * context, Bit16u selector)
      /* 
       * Emulate instruction that loads GS register
       */
@@ -1122,21 +1280,27 @@
 }
 
 int
-emulate_load_ss(vm_t *vm, guest_context_t *context, Bit16u selector)
+emulate_load_ss (vm_t * vm, guest_context_t * context, Bit16u selector)
      /* 
       * Emulate instruction that loads SS register
       */
 {
     descriptor_t descr;
-
-    if (!selector) return 0;
-    if ((selector & 3) != vm->common.addr->nexus->guest_cpl) return 0;
 
-    read_guest_descriptor(vm, &descr, selector);
-    if (!descr.p) return 0;
-    if ((descr.type & 0x18) != D_DATA) return 0;
-    if (!(descr.type & D_WRITE)) return 0;
-    if (descr.dpl != vm->common.addr->nexus->guest_cpl) return 0;
+    if (!selector)
+	return 0;
+    if ((selector & 3) != vm->common.addr->nexus->guest_cpl)
+	return 0;
+
+    read_guest_descriptor (vm, &descr, selector);
+    if (!descr.p)
+	return 0;
+    if ((descr.type & 0x18) != D_DATA)
+	return 0;
+    if (!(descr.type & D_WRITE))
+	return 0;
+    if (descr.dpl != vm->common.addr->nexus->guest_cpl)
+	return 0;
 
     context->ss = selector | 3;
 
@@ -1144,33 +1308,33 @@
 }
 
 int
-emulate_int(vm_t *vm, guest_context_t *context, int vector, Bit32u eip)
+emulate_int (vm_t * vm, guest_context_t * context, int vector, Bit32u eip)
      /* 
       * Emulate INT instruction
       */
 {
     Bit32u old_eip;
 
-    if ( BMAP_GET(vm->common.addr->nexus->host_fwd_ints, vector) )
+    if (BMAP_GET (vm->common.addr->nexus->host_fwd_ints, vector))
     {
-        context->event_info = EMU_INSTR_INT | (RET_BECAUSE_USEREMU << 8) | (vector << 16);
-        return 4;
+	context->event_info = EMU_INSTR_INT | (RET_BECAUSE_USEREMU << 8) | (vector << 16);
+	return 4;
     }
 
     old_eip = context->eip;
     context->eip = eip;
 
-    if ( !raise_interrupt(vm, context, vector, 1) )
+    if (!raise_interrupt (vm, context, vector, 1))
     {
-        context->eip = old_eip;
-        return 0;
+	context->eip = old_eip;
+	return 0;
     }
 
     return 1;
 }
 
 int
-emulate_iret(vm_t *vm, guest_context_t *context)
+emulate_iret (vm_t * vm, guest_context_t * context)
      /* 
       * Emulate IRET instruction
       */
@@ -1183,90 +1347,108 @@
     descriptor_t code_descr;
     descriptor_t stack_descr;
 
-    int cpl = vm->common.addr->nexus->guest_cpl;
+    int   cpl = vm->common.addr->nexus->guest_cpl;
 
     /* FIXME: stack limits check */
 
-    new_eip    = guest_stack_pop(vm, &esp, 32);
-    new_cs     = guest_stack_pop(vm, &esp, 32);
-    new_eflags = guest_stack_pop(vm, &esp, 32);
-
-    if ((new_cs & 3) < cpl) return 0;
-    if (!new_cs) return 0;
-    read_guest_descriptor(vm, &code_descr, new_cs);
-    if (!code_descr.p) return 0;
-    if ((code_descr.type & 0x18) != D_CODE) return 0;
-    if (   (code_descr.type & D_CONFORM)
-         ? (code_descr.dpl < cpl)
-         : (code_descr.dpl != (new_cs & 3)) )  return 0;
-    if (new_eip > Limit(code_descr)) return 0;
+    new_eip = guest_stack_pop (vm, &esp, 32);
+    new_cs = guest_stack_pop (vm, &esp, 32);
+    new_eflags = guest_stack_pop (vm, &esp, 32);
+
+    if ((new_cs & 3) < cpl)
+	return 0;
+    if (!new_cs)
+	return 0;
+    read_guest_descriptor (vm, &code_descr, new_cs);
+    if (!code_descr.p)
+	return 0;
+    if ((code_descr.type & 0x18) != D_CODE)
+	return 0;
+    if ((code_descr.type & D_CONFORM)
+	? (code_descr.dpl < cpl)
+	: (code_descr.dpl != (new_cs & 3)))
+	return 0;
+    if (new_eip > Limit (code_descr))
+	return 0;
 
-    if (cpl > FLG_GET_IOPL(vm->common.addr->nexus->guest_eflags))
+    if (cpl > FLG_GET_IOPL (vm->common.addr->nexus->guest_eflags))
     {
-        new_eflags &= ~FLG_IF;
-        new_eflags |= context->eflags & FLG_IF;
+	new_eflags &= ~FLG_IF;
+	new_eflags |= context->eflags & FLG_IF;
     }
 
     if (cpl > 0)
     {
-        new_eflags &= ~FLG_IOPL;
-        new_eflags |= context->eflags & FLG_IOPL;
+	new_eflags &= ~FLG_IOPL;
+	new_eflags |= context->eflags & FLG_IOPL;
     }
 
     vm->common.addr->nexus->guest_eflags = new_eflags & (FLG_EMUL_MASK | FLG_ASYN_MASK);
 
     if ((new_cs & 3) > cpl)
     {
-        /* Inter-privilege-level return */
+	/* Inter-privilege-level return */
 
-        new_esp = guest_stack_pop(vm, &esp, 32);
-        new_ss  = guest_stack_pop(vm, &esp, 32);
+	new_esp = guest_stack_pop (vm, &esp, 32);
+	new_ss = guest_stack_pop (vm, &esp, 32);
 
-        if ((new_ss & 3) != (new_cs & 3)) return 0;
-        if (!new_ss) return 0;
-        read_guest_descriptor(vm, &stack_descr, new_ss);
-        if (!stack_descr.p) return 0;
-        if ((stack_descr.type & 0x18) != D_DATA) return 0;
-        if (!(stack_descr.type & D_WRITE)) return 0;
-        if (stack_descr.dpl != (new_cs & 3)) return 0;
+	if ((new_ss & 3) != (new_cs & 3))
+	    return 0;
+	if (!new_ss)
+	    return 0;
+	read_guest_descriptor (vm, &stack_descr, new_ss);
+	if (!stack_descr.p)
+	    return 0;
+	if ((stack_descr.type & 0x18) != D_DATA)
+	    return 0;
+	if (!(stack_descr.type & D_WRITE))
+	    return 0;
+	if (stack_descr.dpl != (new_cs & 3))
+	    return 0;
 
-        /* FIXME: clear out invalid DS/ES/FS/GS selectors */
+	/* FIXME: clear out invalid DS/ES/FS/GS selectors */
 
-        vm->common.addr->nexus->guest_cpl = new_cs & 3;
+	vm->common.addr->nexus->guest_cpl = new_cs & 3;
     }
     else
     {
-        /* Intra-privilege-level return */
+	/* Intra-privilege-level return */
 
-        new_esp = esp;
-        new_ss  = context->ss;
+	new_esp = esp;
+	new_ss = context->ss;
     }
 
-    codeseg_activate(vm,  context->cs, 0 );
-    codeseg_activate(vm,  new_cs, 1 );
+    codeseg_activate (vm, context->cs, 0);
+    codeseg_activate (vm, new_cs, 1);
 
-    context->cs     = new_cs | 3;
-    context->eip    = new_eip;
-    context->ss     = new_ss | 3;
-    context->esp    = new_esp;
-    context->eflags = FLG_BUILD(context->eflags,
-                                vm->common.addr->nexus->guest_eflags,
-                                vm->common.addr->nexus->mon_eflags);
+    context->cs = new_cs | 3;
+    context->eip = new_eip;
+    context->ss = new_ss | 3;
+    context->esp = new_esp;
+    context->eflags = FLG_BUILD (context->eflags,
+				 vm->common.addr->nexus->guest_eflags,
+				 vm->common.addr->nexus->mon_eflags);
 
     return 1;
 }
 
 int
-emulate_out(vm_t *vm, guest_context_t *context, int operand_size, int port)
+emulate_out (vm_t * vm, guest_context_t * context, int operand_size, int port)
      /*
       * Emulate out instruction
       */
 {
-    switch ( operand_size )
+    switch (operand_size)
     {
-    case 8:  context->event_info = EMU_INSTR_OUT_8;  break;
-    case 16: context->event_info = EMU_INSTR_OUT_16; break;
-    case 32: context->event_info = EMU_INSTR_OUT_32; break;
+    case 8:
+	context->event_info = EMU_INSTR_OUT_8;
+	break;
+    case 16:
+	context->event_info = EMU_INSTR_OUT_16;
+	break;
+    case 32:
+	context->event_info = EMU_INSTR_OUT_32;
+	break;
     }
 
     context->event_info |= (RET_BECAUSE_USEREMU << 8) | (port << 16);
@@ -1274,16 +1456,22 @@
 }
 
 int
-emulate_in(vm_t *vm, guest_context_t *context, int operand_size, int port)
+emulate_in (vm_t * vm, guest_context_t * context, int operand_size, int port)
      /*
       * Emulate in instruction
       */
 {
-    switch ( operand_size )
+    switch (operand_size)
     {
-    case 8:  context->event_info = EMU_INSTR_IN_8;  break;
-    case 16: context->event_info = EMU_INSTR_IN_16; break;
-    case 32: context->event_info = EMU_INSTR_IN_32; break;
+    case 8:
+	context->event_info = EMU_INSTR_IN_8;
+	break;
+    case 16:
+	context->event_info = EMU_INSTR_IN_16;
+	break;
+    case 32:
+	context->event_info = EMU_INSTR_IN_32;
+	break;
     }
 
     context->event_info |= (RET_BECAUSE_USEREMU << 8) | (port << 16);
@@ -1291,28 +1479,40 @@
 }
 
 int
-emulate_outs(vm_t *vm, guest_context_t *context, int operand_size, int address_size, int rep)
+emulate_outs (vm_t * vm, guest_context_t * context, int operand_size, int address_size, int rep)
      /*
       * Emulate outs instruction
       */
 {
     if (rep)
     {
-        switch (operand_size)
-        {
-        case 8:  context->event_info = EMU_INSTR_REP_OUTS_8;  break;
-        case 16: context->event_info = EMU_INSTR_REP_OUTS_16; break;
-        case 32: context->event_info = EMU_INSTR_REP_OUTS_32; break;
-        }
+	switch (operand_size)
+	{
+	case 8:
+	    context->event_info = EMU_INSTR_REP_OUTS_8;
+	    break;
+	case 16:
+	    context->event_info = EMU_INSTR_REP_OUTS_16;
+	    break;
+	case 32:
+	    context->event_info = EMU_INSTR_REP_OUTS_32;
+	    break;
+	}
     }
     else
     {
-        switch (operand_size)
-        {
-        case 8:  context->event_info = EMU_INSTR_OUTS_8;  break;
-        case 16: context->event_info = EMU_INSTR_OUTS_16; break;
-        case 32: context->event_info = EMU_INSTR_OUTS_32; break;
-        }
+	switch (operand_size)
+	{
+	case 8:
+	    context->event_info = EMU_INSTR_OUTS_8;
+	    break;
+	case 16:
+	    context->event_info = EMU_INSTR_OUTS_16;
+	    break;
+	case 32:
+	    context->event_info = EMU_INSTR_OUTS_32;
+	    break;
+	}
     }
     context->event_info |= (RET_BECAUSE_USEREMU << 8) | (address_size << 16);
     return 4;
@@ -1320,57 +1520,211 @@
 
 
 int
-emulate_ins(vm_t *vm, guest_context_t *context, int operand_size, int address_size, int rep)
+emulate_ins (vm_t * vm, guest_context_t * context, int operand_size, int address_size, int rep)
      /*
       * Emulate ins instruction
       */
 {
     if (rep)
     {
-        switch (operand_size)
-        {
-        case 8:  context->event_info = EMU_INSTR_REP_INS_8;  break;
-        case 16: context->event_info = EMU_INSTR_REP_INS_16; break;
-        case 32: context->event_info = EMU_INSTR_REP_INS_32; break;
-        }
+	switch (operand_size)
+	{
+	case 8:
+	    context->event_info = EMU_INSTR_REP_INS_8;
+	    break;
+	case 16:
+	    context->event_info = EMU_INSTR_REP_INS_16;
+	    break;
+	case 32:
+	    context->event_info = EMU_INSTR_REP_INS_32;
+	    break;
+	}
     }
     else
     {
-        switch (operand_size)
-        {
-        case 8:  context->event_info = EMU_INSTR_INS_8;  break;
-        case 16: context->event_info = EMU_INSTR_INS_16; break;
-        case 32: context->event_info = EMU_INSTR_INS_32; break;
-        }
+	switch (operand_size)
+	{
+	case 8:
+	    context->event_info = EMU_INSTR_INS_8;
+	    break;
+	case 16:
+	    context->event_info = EMU_INSTR_INS_16;
+	    break;
+	case 32:
+	    context->event_info = EMU_INSTR_INS_32;
+	    break;
+	}
     }
     context->event_info |= (RET_BECAUSE_USEREMU << 8) | (address_size << 16);
     return 4;
 }
 
 int
-emulate_invd(vm_t *vm) 
+emulate_invd (vm_t * vm)
 {
     /* nothing to do ;) */
     return 2;
 }
 
 int
-emulate_wbinvd(vm_t *vm) 
+emulate_wbinvd (vm_t * vm)
 {
     /* nothing to do ;) */
     return 2;
 }
 
 int
-emulate_hlt(vm_t *vm, guest_context_t *context) 
+emulate_hlt (vm_t * vm, guest_context_t * context)
 {
     context->event_info = EMU_INSTR_HLT | (RET_BECAUSE_USEREMU << 8);
     return 4;
 }
 
+int
+emulate_mov_from_cr (vm_t * vm, guest_context_t * context)
+     /* move from CRx into register */
+{
+    Bit8u data;
+    Bit32u eip;
+    Bit32u crx = 0;
+
+    eip = context->eip + 2;
+    data = read_guest_byte (vm, &eip);
+    switch (FieldReg (data))
+    {
+    case 0:			/* control register */
+	crx = vm->common.guest_cpu_state.cr0;
+	break;
+
+    case 1:
+	context->error = 1;
+	return 0;		/* reserved */
+    case 2:
+	context->error = 2;
+	return 0;		/* linear page fault address; unsupported for now */
+
+    case 3:			/* page table base register */
+	crx = vm->common.guest_cpu_state.cr3;
+	break;
+
+    case 4:			/* pentium control register */
+	crx = vm->common.guest_cpu_state.cr4;
+	break;
+
+    default:
+	context->error = data;
+	return 0;
+	break;
+    }
+
+    switch (FieldRM (data))
+    {
+    case 0:			/* eax */
+	context->eax = crx;
+	break;
+    case 1:			/* ecx */
+	context->ecx = crx;
+	break;
+    case 2:			/* edx */
+	context->edx = crx;
+	break;
+    case 3:			/* ebx */
+	context->ebx = crx;
+	break;
+    case 4:			/* esp */
+	context->esp = crx;
+	break;
+    case 5:			/* ebp */
+	context->ebp = crx;
+	break;
+    case 6:			/* esi */
+	context->esi = crx;
+	break;
+    case 7:			/* edi */
+	context->edi = crx;
+	break;
+    }
+    context->eip += 3;
+    return 1;
+}
 
 int
-emulate_ljmp(vm_t *vm, guest_context_t *context)
+emulate_mov_to_cr (vm_t * vm, guest_context_t * context)
+     /* move from register into virtual CRx
+      * FIXME: no emulation is done yet, add this ...*/
+{
+    Bit8u data;
+    Bit32u eip;
+    Bit32u crx = 0;
+
+    eip = context->eip + 2;
+    data = read_guest_byte (vm, &eip);
+    context->eip += 3;
+
+    // fetch data from register
+    switch (FieldRM (data))
+    {
+    case 0:			/* eax */
+	crx = context->eax;
+	break;
+    case 1:			/* ecx */
+	crx = context->ecx;
+	break;
+    case 2:			/* edx */
+	crx = context->edx;
+	break;
+    case 3:			/* ebx */
+	crx = context->ebx;
+	break;
+    case 4:			/* esp */
+	crx = context->esp;
+	break;
+    case 5:			/* ebp */
+	crx = context->ebp;
+	break;
+    case 6:			/* esi */
+	crx = context->esi;
+	break;
+    case 7:			/* edi */
+	crx = context->edi;
+	break;
+    }
+
+    // store data in virtual control registers
+    switch (FieldReg (data))
+    {
+    case 0:			/* control register */
+	vm->common.guest_cpu_state.cr0 = crx;
+	break;
+
+    case 1:
+	context->error = 1;
+	return 0;		/* reserved */
+    case 2:
+	context->error = 2;
+	return 0;		/* linear page fault address; unsupported for now */
+
+    case 3:			/* page table base register */
+	vm->common.guest_cpu_state.cr3 = crx;
+	return emulate_set_pdbr (vm, context, crx);
+	break;
+
+    case 4:			/* pentium control register */
+	vm->common.guest_cpu_state.cr4 = crx;
+	break;
+
+    default:
+	context->error = data;
+	return 0;
+	break;
+    }
+
+    return 1;
+}
+
+
+int
+emulate_ljmp (vm_t * vm, guest_context_t * context)
      /* ljmp may be an intersegment call
       * we have disabled intersegment calls, so we have to emulate them
       */
@@ -1380,17 +1734,73 @@
     Bit32u new_eip;
     Bit32u eip = context->eip + 1;
 
-    new_eip = read_guest_dword(vm, &eip);
-    new_cs = read_guest_word(vm, &eip);
+    new_eip = read_guest_dword (vm, &eip);
+    new_cs = read_guest_word (vm, &eip);
 
-    read_guest_descriptor(vm, &descr, new_cs);
+    read_guest_descriptor (vm, &descr, new_cs);
     if (!(descr.type & D_CODE))
-        return 0;
+	return 0;
 
-    codeseg_activate(vm,  context->cs, 0 );
+    codeseg_activate (vm, context->cs, 0);
     context->cs = new_cs | 3;
     context->eip = new_eip;
-    codeseg_activate(vm,  new_cs, 1 );
+    codeseg_activate (vm, new_cs, 1);
 
     return 1;
+}
+
+int
+emulate_set_pdbr (vm_t * vm, guest_context_t * context, Bit32u cr3)
+{
+    Bit32u dummy, addr;
+    int   i;
+    pageEntry_t *pte;
+
+    addr = cr3;
+    pte = (pageEntry_t *) & dummy;
+
+    /* cr3 points to a page directory
+     * read all entries of this page and unmap page tables
+     */
+    for (i = 0; i < 1024; i++)
+    {
+	dummy = read_guest_dword (vm, &addr);
+	if (pte->P == 1)
+	{
+	    unmap_page_from_guest (vm, vm->common.pages.guest[pte->base]);
+	}
+    }
+
+    /* unmap the page directory itself */
+    unmap_page_from_guest (vm, vm->common.pages.guest[cr3 >> 12]);
+    return 1;
+}
+
+
+int
+unmap_page_from_guest (vm_t * vm, Bit32u page)
+{
+    Bit32u pdi, pti;
+    pageEntry_t pte;
+
+
+    for (pdi = 0; pdi < (vm->common.pages.guest_n_megs >> 2); pdi++)
+    {
+	/* browse through all entries in page directory */
+
+	for (pti = 0; pti < 1024; pti++)
+	{
+	    /* look into all entries of the page table */
+	    pte = vm->common.addr->page_tbl[pdi].u.pte[pti];
+	    if (pte.base == page)
+	    {
+		vm->common.addr->page_tbl[pdi].u.pte[pti].P = 0;	// mark as not present in page table;
+
+		asm volatile ("invlpg %0"::"m" (page << 12));	// remove from TLB;
+
+		return 1;
+	    }
+	}
+    }
+    return 0;
 }
Index: kernel/fault.c
===================================================================
RCS file: /cvsroot-freemware/plex86/kernel/fault.c,v
retrieving revision 1.3
diff -u -r1.3 fault.c
--- kernel/fault.c	2000/03/26 16:52:47	1.3
+++ kernel/fault.c	2000/04/14 07:02:29
@@ -89,6 +89,10 @@
         action = emulate(vm, context );
         break;
 
+    case 14: /* Page Fault */
+        action = emulate_page_fault(vm, context);
+	break;
+
     default: 
         action = emulate_int(vm,  context,
                              context->event_info & 0xff, context->eip );
Index: kernel/include/monitor.h
===================================================================
RCS file: /cvsroot-freemware/plex86/kernel/include/monitor.h,v
retrieving revision 1.4
diff -u -r1.4 monitor.h
--- kernel/include/monitor.h	2000/03/26 18:17:48	1.4
+++ kernel/include/monitor.h	2000/04/14 07:02:29
@@ -172,6 +172,7 @@
   Bit32u cr1;
   Bit32u cr2;
   Bit32u cr3;
+  Bit32u cr4;
   } guest_cpu_state_t;
 

-----------------------------------------------------------------
kernel/page-fault.c:
 
/*
 *  plex86: run multiple x86 operating systems concurrently
 *  Copyright (C) 1999, 2000 The plex86 Team
 *
 *  emulation.c:  This file contains functions to emulate IA32 instructions
 *                
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include "plex86.h"
#include "monitor.h"

int
emulate_page_fault(vm_t *vm, guest_context_t *context)

{

  Bit32u cr2;

  asm volatile("movl %%cr2, %0" : "=r" (cr2)); // linear fault address;

  /* FIXME: do some checks:
   * comes the page fault from guest os kernel?
   * if so, is it a page table emulation page fault?
   * ...
   */

  if(vm->common.addr->nexus->guest_cpl > 0)
    {
      /* guest application causes page fault 
       * we should redirect page fault to guest kernel,
       * but this isn't implemented yet
       */
      context->event_info = EMU_INSTR_HLT | (RET_BECAUSE_USEREMU << 8);
      return 4;
    }

  context->event_info = EMU_INSTR_HLT | (RET_BECAUSE_USEREMU << 8);
  context->error = 0x3333;
  return 3;
}
