Hello,

this patch activates PDBR switching to a real monitor/guest page directory.
(The patch applies against fwm-19990822b.)

Actually, I'm still cheating somewhat, as I'm mapping the complete code/data
pages of the kernel module at the same linear address inside the monitor/guest
machine, so that PDBR switching is simple ;-)  Nevertheles, now there are only
about 6 pages shared with the host, and no longer all of them, so you could
call that progress ...

What the patch does in detail:

- Use some linker/ELF magic to retrieve the linear address space occupied
  by the kernel module at runtime.

- Walk the host page tables to retrieve a list of all physical pages 
  underlying the kernel module's code and data sections.

- Allocate memory for the monitor page tables, and set them up as follows:
  * An identity mapping of the complete guest physical memory (at address 0)
  * A mapping of the kernel module's code/data pages at the same 
    linear address as in the host space.

- Remove the dynamic allocation of interrupt reflection stubs (sorry Ramon :-/).
  These stubs are called in the guest VM, so using kmalloc() -- which 
  returns some arbitrary address inside host physical memory -- to
  allocate them is not a real good idea ;-)   I've moved them to memory
  inside the module's data pages.

- Add the actual PDBR reloading.


Note that I'm still running the do_nothing task inside the guest context;
the next step would be to set up a user-mode guest task inside the user
mode app (by writing into the mapped guest physical memory) and run this.

Before I'm implementing this, I'd like you all to test this patch;
I've tested it only on Linux 2.0.36 ...  Also, testing with various
versions of gcc and/or ld to find out whether the linker script works
would be great (note that GNU ld is now required ...).

(Please do sync your disks before testing; I've managed to trigger
triple faults more than once while implementing this :-/)

Bye,
Ulrich



diff -urN fmw-19990822b/kernel/Makefile.in fmw-uw/kernel/Makefile.in
--- fmw-19990822b/kernel/Makefile.in    Sun Aug 22 21:50:15 1999
+++ fmw-uw/kernel/Makefile.in   Tue Aug 24 00:30:10 1999
@@ -27,7 +27,7 @@
 
 # extra kernel CFLAGS and LDFLAGS for each host OS
 KCFLAGS_LINUX  = -D__KERNEL__ -I/usr/src/linux/include -DCPU=586 -DMODULE
-KLDFLAGS_LINUX = -r
+KLDFLAGS_LINUX = -r -Thost-linux.ld
 
 KCFLAGS_BEOS   =
 KLDFLAGS_BEOS  = -nostdlib /boot/develop/lib/x86/_KERNEL_
diff -urN fmw-19990822b/kernel/host-linux.c fmw-uw/kernel/host-linux.c
--- fmw-19990822b/kernel/host-linux.c   Sun Aug 22 22:59:36 1999
+++ fmw-uw/kernel/host-linux.c  Tue Aug 24 03:28:35 1999
@@ -60,8 +60,8 @@
 // Freemware linux host functions
 static void unalloc_vm_pages(void);
 static int alloc_vm_pages(unsigned nmegs);
+static void retrieve_monitor_pages(void);
 static void init_ints(void);
-static void release_ints(void);
 
 
 
@@ -70,8 +70,8 @@
 /************************************************************************/
 
 vm_pages_t vm_pages;
+monitor_pages_t monitor_pages;
 static unsigned redir_cnt[256];
-static char *redir_handl[256];
 static struct file_operations fmw_fops;
 static int mon_ok = 0;
 
@@ -142,8 +142,8 @@
 
     // clear uninitialised structures
     memset(redir_cnt, 0, sizeof(redir_cnt));
-    memset(redir_handl, 0, sizeof(redir_handl));
     memset(&vm_pages, 0, sizeof(vm_pages));
+    memset(&monitor_pages, 0, sizeof(monitor_pages));
 
     // fill in the file operation entries we support
     fmw_fops.mmap    = fmw_mmap;
@@ -160,9 +160,12 @@
 
     // register the /proc entry
     proc_register_dynamic(&proc_root, &fmw_proc_entry);
-    EXPORT_NO_SYMBOLS;
+
+    // retrieve the monitor physical pages
+    retrieve_monitor_pages();
 
     // success
+    EXPORT_NO_SYMBOLS;
     return(0);
 }
 
@@ -369,7 +372,6 @@
           break;
 
       case FMWTEARDOWN: // tear down VM environment
-          release_ints();
           unalloc_vm_pages();
           mon_ok = 0;
           return(0);
@@ -459,6 +461,61 @@
 /************************************************************************/
 
 void
+retrieve_monitor_pages(void)
+{
+    /* These symbols are defined by the host-linux.ld linker script */
+    extern int freemware_start, freemware_end;
+
+    int start_addr = (int)&freemware_start, end_addr = (int)&freemware_end;
+    int start_page = start_addr >> 12, end_page = ((end_addr-1) >> 12) + 1;
+    int n_pages = end_page - start_page;
+    int i;
+    u32 host_cr3;
+    pageEntry_t *host_pgd;
+
+    printk(KERN_WARNING "freemware: start: %08x end: %08x: init: %08x pages: %d\n",
+           start_addr, end_addr, (long)init_module, n_pages);
+
+    if (n_pages > FMW_MAX_MONITOR_PAGES)
+    {
+        printk(KERN_WARNING "freemware: FMW_MAX_MONITOR_PAGES is too small!\n");
+        return;
+    }
+
+    if ((end_addr & (~1 << 22)) != (start_addr & (~1 << 22)))
+    {
+        printk(KERN_WARNING "freemware: module VM spanning more than one page 
+table!\n");
+        return;
+    }
+
+    monitor_pages.start_addr = start_addr;
+    monitor_pages.end_addr   = end_addr;
+    monitor_pages.n_pages    = n_pages;
+
+    /*  
+     * Grrr.  There doesn't seem to be an exported mechanism to retrieve
+     * the physical pages underlying a vmalloc()'ed area.  We do it the
+     * hard way ... 
+     */
+
+    asm volatile("movl %%cr3, %0" : "=r" (host_cr3));
+    host_pgd = (pageEntry_t *)(phys_to_virt(host_cr3 & ~0xfff));
+
+    for (i = 0; i < n_pages; i++)
+    {
+        u32 virt_addr = (start_page+i) * PAGE_SIZE + KERNEL_OFFSET;
+        pageEntry_t *pde = host_pgd + (virt_addr >> 22);
+        pageEntry_t *pte = (pageEntry_t *)phys_to_virt(pde->base << 12)
+                         + ((virt_addr >> 12) & 0x3ff);
+        
+        monitor_pages.page[i] = pte->base;
+
+        //printk(KERN_WARNING "freemware: vm %08lx..%08lx -> page %08lx\n",
+        //       virt_addr, virt_addr + PAGE_SIZE-1, pte->base);
+    }
+}
+
+void
 unalloc_vm_pages(void)
 {
     unsigned p;
@@ -479,10 +536,14 @@
             free_page(vm_pages.monitor_page_tbl[p]);
     }
 
+    if (vm_pages.monitor_extra_page_tbl)
+        free_page(vm_pages.monitor_extra_page_tbl);
+
     // clear out allocated pages lists
     memset(&vm_pages.guest, 0, sizeof(vm_pages.guest));
     vm_pages.monitor_page_dir = 0;
     memset(&vm_pages.monitor_page_tbl, 0, sizeof(vm_pages.monitor_page_tbl));
+    vm_pages.monitor_extra_page_tbl = 0;
 }
 
 
@@ -495,6 +556,7 @@
     memset(&vm_pages.guest, 0, sizeof(vm_pages.guest));
     vm_pages.monitor_page_dir = 0;
     memset(&vm_pages.monitor_page_tbl, 0, sizeof(vm_pages.monitor_page_tbl));
+    vm_pages.monitor_extra_page_tbl = 0;
 
     for (p=0; p<vm_pages.guest_n_pages; p++) {
         vm_pages.guest[p] = get_free_page(GFP_KERNEL);
@@ -508,6 +570,26 @@
        //  virt_to_phys((void *) vm_pages.guest[p]));
     }
 
+    vm_pages.monitor_page_dir = get_free_page(GFP_KERNEL);
+    if (!vm_pages.monitor_page_dir) {
+        unalloc_vm_pages();
+        return -ENOMEM;
+    }
+
+    for 
+(p=0;p<sizeof(vm_pages.monitor_page_tbl)/sizeof(vm_pages.monitor_page_tbl[0]);p++) {
+        vm_pages.monitor_page_tbl[p] = get_free_page(GFP_KERNEL);
+        if (!vm_pages.monitor_page_tbl[p]) {
+            unalloc_vm_pages();
+            return -ENOMEM;
+        }
+    }
+
+    vm_pages.monitor_extra_page_tbl = get_free_page(GFP_KERNEL);
+    if (!vm_pages.monitor_extra_page_tbl) {
+        unalloc_vm_pages();
+        return -ENOMEM;
+    }
+
     return(0);
 }
 
@@ -521,21 +603,15 @@
 init_ints(void)
 {
     int i;
-#if CONFIG_SMP
-    char *handl;
-#endif
 
     /* Setup IRQ redirections:  IRQ 0..7 */
-    for(i = MASTER_PIC_BASE_VECTOR; i < MASTER_PIC_BASE_VECTOR+8; i++) {
-        redir_handl[i] = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        init_reflect(i, redir_handl[i]);
-    }
+    for(i = MASTER_PIC_BASE_VECTOR; i < MASTER_PIC_BASE_VECTOR+8; i++) 
+        init_reflect(i);
 
     /* Setup IRQ redirections:  IRQ 8..15 */
-    for(i = SLAVE_PIC_BASE_VECTOR; i < SLAVE_PIC_BASE_VECTOR+8; i++) {
-        redir_handl[i] = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        init_reflect(i, redir_handl[i]);
-    }
+    for(i = SLAVE_PIC_BASE_VECTOR; i < SLAVE_PIC_BASE_VECTOR+8; i++) 
+        init_reflect(i);
+   
 
     /* Setup SMP IPI redirections */
 #if CONFIG_SMP
@@ -551,29 +627,12 @@
         #define SPURIOUS_APIC_VECTOR   0xff
         #define IRQ0_TRAP_VECTOR       0x51
 
-        handl = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        redir_handl[RESCHEDULE_VECTOR] = handl;
-        init_reflect(RESCHEDULE_VECTOR, handl);
-
-        handl = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        redir_handl[INVALIDATE_TLB_VECTOR] = handl;
-        init_reflect(INVALIDATE_TLB_VECTOR, handl);
-
-        handl = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        redir_handl[STOP_CPU_VECTOR] = handl;
-        init_reflect(STOP_CPU_VECTOR, handl);
-
-        handl = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        redir_handl[LOCAL_TIMER_VECTOR] = handl;
-        init_reflect(LOCAL_TIMER_VECTOR, handl);
-
-        handl = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        redir_handl[MTRR_CHANGE_VECTOR] = handl;
-        init_reflect(MTRR_CHANGE_VECTOR, handl);
-
-        handl = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        redir_handl[SPURIOUS_APIC_VECTOR] = handl;
-        init_reflect(SPURIOUS_APIC_VECTOR, handl);
+        init_reflect(RESCHEDULE_VECTOR);
+        init_reflect(INVALIDATE_TLB_VECTOR);
+        init_reflect(STOP_CPU_VECTOR);
+        init_reflect(LOCAL_TIMER_VECTOR);
+        init_reflect(MTRR_CHANGE_VECTOR);
+        init_reflect(SPURIOUS_APIC_VECTOR);
 
         /*
          *  Now we need to allocate the dynamically allocated
@@ -582,38 +641,16 @@
          *  and linux/arch/i386/io_apic.c, function assign_irq_vector()).
          */
 
-        for(i = 0; i < NR_IRQS; i++) {
-            if(irq_vector[i] > 0) {
-                handl = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-                redir_handl[irq_vector[i]] = handl;
-                init_reflect(irq_vector[i], handl);
-            }
-        }
+        for(i = 0; i < NR_IRQS; i++) 
+            if(irq_vector[i] > 0) 
+                init_reflect(irq_vector[i]);
     }
     #else
         #define IRQ16_BASE_VECTOR      0x30
 
-        handl = kmalloc(sizeof(reflect_stub_t), GFP_KERNEL);
-        redir_handl[IRQ16_BASE_VECTOR] = handl;
-        init_reflect(IRQ16_BASE_VECTOR, handl);
+        init_reflect(IRQ16_BASE_VECTOR);
     #endif
 #endif
-}
-
-void
-release_ints(void)
-{
-    int i;
-
-    // Free all stubs
-    for(i=0; i<256; i++) {
-        if(redir_handl[i]) {
-            kfree(redir_handl[i]);
-        }
-    }
-
-    // Cleanup redirect handler array
-    memset(redir_handl, 0, sizeof(redir_handl));
 }
 
 /* The end */
diff -urN fmw-19990822b/kernel/host-linux.ld fmw-uw/kernel/host-linux.ld
--- fmw-19990822b/kernel/host-linux.ld  Thu Jan  1 01:00:00 1970
+++ fmw-uw/kernel/host-linux.ld Mon Aug 23 23:51:16 1999
@@ -0,0 +1,36 @@
+/*
+ * Hack alert!
+ *
+ * We use this linker script for the sole purpose of defining 
+ * the 'freemware_start' and 'freemware_end' symbols.
+ *
+ * I'd really prefer to use the standard linker script and just
+ * add the two symbol definitions at the end, but I just didn't
+ * manage to get the addresses correct that way ... :-/
+ *
+ * Thus, this script copies those parts of the standard script
+ * that we need (we don't need dynamic linking, constructors,
+ * and all the other stuff ...).
+ *
+ * Note: The 'FORCE_COMMON_ALLOCATION' command is essential; 
+ *       otherwise, the 'freemware_end' symbol would point *before*
+ *       the uninitialized global variables!
+ */
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+FORCE_COMMON_ALLOCATION
+SECTIONS
+{
+  .text    : { freemware_start = .;
+               *(.text)    } =0x9090
+  .rodata  : { *(.rodata)  }
+  .data    : { *(.data)    }
+  .bss     : { *(.bss)     
+               *(COMMON)   
+               freemware_end = .; }
+  .stab    : { *(.stab)    }
+  .stabstr : { *(.stabstr) }
+  .comment : { *(.comment) }
+}
+
diff -urN fmw-19990822b/kernel/include/fmw.h fmw-uw/kernel/include/fmw.h
--- fmw-19990822b/kernel/include/fmw.h  Sat Aug 21 20:54:40 1999
+++ fmw-uw/kernel/include/fmw.h Tue Aug 24 03:20:59 1999
@@ -29,7 +29,7 @@
 
 
 void init_monitor(void);
-void init_reflect(int vec, void *handler);
+void init_reflect(int vec);
 void __host2monitor(void);
 
 #define ASM_USED(x) ((void) (x))
diff -urN fmw-19990822b/kernel/include/monitor.h fmw-uw/kernel/include/monitor.h
--- fmw-19990822b/kernel/include/monitor.h      Sat Aug 21 20:39:28 1999
+++ fmw-uw/kernel/include/monitor.h     Tue Aug 24 01:15:22 1999
@@ -53,12 +53,36 @@
     // for the monitor's page table
     u32 monitor_page_tbl[(FMW_MAX_PHY_MEGS+3)>>2];
 
+    // one extra page table for the monitor code/data pages
+    u32 monitor_extra_page_tbl;
+
     // requested size of the guest[] array in megs and pages
     unsigned guest_n_megs;
     unsigned guest_n_pages;
 } vm_pages_t;
 
 extern vm_pages_t vm_pages;
+
+/*
+ * This structure describes the pages containing the code/data
+ * of the monitor itself (inside the kernel module)
+ */
+
+#define FMW_MAX_MONITOR_PAGES 32
+
+typedef struct {
+    // virtual address space occupied by the module
+    u32 start_addr;
+    u32 end_addr;
+
+    // number of pages
+    unsigned n_pages;
+    
+    // the pages themselves
+    u32 page[FMW_MAX_MONITOR_PAGES];
+} monitor_pages_t;
+
+extern monitor_pages_t monitor_pages;
 
 
 /*
diff -urN fmw-19990822b/kernel/monitor.c fmw-uw/kernel/monitor.c
--- fmw-19990822b/kernel/monitor.c      Sat Aug 21 20:57:39 1999
+++ fmw-uw/kernel/monitor.c     Tue Aug 24 03:29:39 1999
@@ -76,6 +76,7 @@
 static far_jmp_info_t mon_stack_info;    // Far pointer to monitor stack
 static u16            mon_tss_sel;       // Monitor TSS selector
 static descriptor_t  *mon_tss_desc_ptr;  // Pointer to monitor TSS desc in GDT
+static u32            mon_cr3;           // The monitor CR3
 
 
 /*
@@ -88,7 +89,7 @@
 static far_jmp_info_t host_stack_info;   // Far pointer to host stack
 static u16            host_tss_selector; // Host TSS selector
 static descriptor_t  *host_tss_desc_ptr; // Pointer to host TSS descriptor
-
+static u32            host_cr3;          // The host CR3
 
 /*
  *  Stacks
@@ -115,15 +116,13 @@
  *     none
  */
 {
-#if 0
     // These variables are used to set up the monitor pagetables
     pageEntry_t *pageDirectory, *pageTable;
     unsigned pdi, pti, page_index;
-#endif
     unsigned int i;
     unsigned int seg;
     u32 off;
-    u32 host_cr3;
+    u32 virt_addr;
 
     // Zero out data structures for good measure
     memset(&monitor_info, 0, sizeof(monitor_info));
@@ -169,16 +168,16 @@
     mon_tss_desc_ptr  = (descriptor_t *) &mon_gdt[5];
     mon_tss_sel       = Selector(5, 0, RPL0);
 
-
     /*
-     *  The paging system.  This is not used yet.  For now, we
-     *  just use the page mappings of the host OS.  But to
-     *  get ready for the next step ...
+     *  Create linear mapping of all guest physical memory
      */
-#if 0
+
     // page_index cycles thru all of vm_pages.guest[]
     page_index = 0;
 
+    // Set monitor CR3 value
+    mon_cr3 = L2P(vm_pages.monitor_page_dir);
+
     // clear Page Directory
     pageDirectory = (pageEntry_t *) vm_pages.monitor_page_dir;
     memset(pageDirectory, 0, 4096);
@@ -223,10 +222,62 @@
         }
     }
 
-    /*
-     *  also need to allocate pages for PD and PTs in host.c
+    /* 
+     *  Map the monitor's code/data pages
+     *
+     *  Note that for now, we map the monitor's code/data pages into the 
+     *  guest address space at the same linear addresses as they have in
+     *  the host space.  This simplifies PDBR reloading ;-)
+     *
+     *  Furthermore, we assume that the address space occupied by the
+     *  monitor fits into a single page table (4 MB range) ...
      */
-#endif
+
+    // Get monitor virtual address
+    virt_addr = (monitor_pages.start_addr & ~0xfff) + KERNEL_OFFSET;
+    pdi = virt_addr >> 22;
+    pti = (virt_addr >> 12) & 0x3ff;
+
+    // Use vm_pages.monitor_extra_page_table to hold this page table ...
+    pageDirectory[pdi].base = L2P(vm_pages.monitor_extra_page_tbl) >> 12;
+
+    // Fill in the PDE flags
+    pageDirectory[pdi].avail = 0;
+    pageDirectory[pdi].G = 0;      // not global
+    pageDirectory[pdi].PS = 0;     // 4K pages
+    pageDirectory[pdi].D = 0;      // (unused in pde)
+    pageDirectory[pdi].A = 0;      // not accessed
+    pageDirectory[pdi].PCD = 0;    // normal caching
+    pageDirectory[pdi].PWT = 0;    // normal write-back
+    pageDirectory[pdi].US = 0;     // user *cannot* access
+    pageDirectory[pdi].RW = 1;     // read or write
+    pageDirectory[pdi].P = 1;      // present in memory
+
+    // clear Page Table
+    pageTable = (pageEntry_t *) vm_pages.monitor_extra_page_tbl;
+    memset(pageTable, 0, 4096);
+
+    // setup the Page Table
+    for (i = 0; i < monitor_pages.n_pages; i++, pti++)
+    {
+        if (pti > 1024)
+            break;  /* This cannot happen! */
+
+        // Get the address of the page frame
+        pageTable[pti].base = monitor_pages.page[i];
+
+        // Fill in the PTE flags
+        pageTable[pti].avail = 0;
+        pageTable[pti].G = 0;      // not global
+        pageTable[pti].PS = 0;     // (unused in pte)
+        pageTable[pti].D = 0;      // clean
+        pageTable[pti].A = 0;      // not accessed
+        pageTable[pti].PCD = 0;    // normal caching
+        pageTable[pti].PWT = 0;    // normal write-back
+        pageTable[pti].US = 0;     // user *cannot* access
+        pageTable[pti].RW = 1;     // read or write
+        pageTable[pti].P = 1;      // present in memory
+    }
 
 
     /*
@@ -330,21 +381,21 @@
 }
 
 void
-init_reflect(int vec, void *handler)
+init_reflect(int vec)
 /*
  *  init_reflect():  Initialise an interrupt that needs to reflected
  *                   to the host OS
  *
  *  INPUTS:
  *     vec:      vector of interrupt to reflect
- *     handler:  address of memory allocated for interrupt handler stub
  *
  *  OUTPUTS:
  *     none
  */
 {
+    static reflect_stub_t int_stub[256];
+    reflect_stub_t *stub = int_stub + vec;
     unsigned int seg;
-    reflect_stub_t *stub = handler;
 
     /* Setup stub */
     stub->pushl  = 0x68;
@@ -356,7 +407,7 @@
     seg = Selector(1, 0, RPL0); // same CPL0 CS for all handlers
 
     /* Set the interrupt gate */
-    SET_INT_GATE(mon_idt[vec], seg, (u32) handler, D_PRESENT, D_DPL0, D_D32);
+    SET_INT_GATE(mon_idt[vec], seg, (u32) stub, D_PRESENT, D_DPL0, D_D32);
 }
 
 
@@ -399,11 +450,14 @@
     "    movl  %eax, host_jmp_info     \n"  // to when switching back
     "    movw  %cs,  host_jmp_info+4   \n"  // to host context
     "                                  \n"
+    "    movl  mon_cr3, %eax           \n"  // Switch to monitor PDBR
+    "    movl  %eax, %cr3              \n"
     "    lgdt  (mon_gdt_info)          \n"  // Switch to monitor GDT
     "    lidt  (mon_idt_info)          \n"  // ... and IDT
     "    movl  mon_tss_desc_ptr, %eax  \n"  // Switch to monitor TSS
     "    andl  $0xfffffdff, 4(%eax)    \n"  // Clear busy bit first
     "    ltr   mon_tss_sel             \n"
+    "    lss   mon_stack_info, %esp    \n"  // Switch to monitor stack
     "    ljmp  (mon_jmp_info)          \n"  // Jump to monitor code
 
     /*
@@ -412,7 +466,6 @@
      */
 
     "restore_to_host:                  \n"
-    "    lss   host_stack_info, %esp   \n"  // Return to host stack
     "    popl %gs                      \n"  // Restore segments
     "    popl %fs                      \n"
     "    popl %ds                      \n"
@@ -469,11 +522,14 @@
     "    movl  %eax, mon_jmp_info      \n"  // to when switching back
     "    movw  %cs,  mon_jmp_info+4    \n"  // to monitor context
     "                                  \n"
+    "    movl  host_cr3, %eax          \n"  // Switch to host PDBR
+    "    movl  %eax, %cr3              \n"
     "    lgdt  (host_gdt_info)         \n"  // Switch to host context
     "    lidt  (host_idt_info)         \n"  // GDT and IDT
     "    movl  host_tss_desc_ptr, %eax \n"  // Switch to host TSS
     "    andl  $0xfffffdff, 4(%eax)    \n"  // but first clea busy bit
     "    ltr   host_tss_selector       \n"
+    "    lss   host_stack_info, %esp   \n"  // Return to host stack
     "    ljmp  (host_jmp_info)         \n"  // Jump back to host code
 
     /*
@@ -482,7 +538,6 @@
      */
 
     "restore_to_monitor:               \n"
-    "    lss  mon_stack_info, %esp     \n"  // Switch to monitor stack
     "    popl %gs                      \n"  // Switch to monitor
     "    popl %fs                      \n"  // segments
     "    popl %ds                      \n"
diff -urN fmw-19990822b/kernel/virtcode.c fmw-uw/kernel/virtcode.c
--- fmw-19990822b/kernel/virtcode.c     Sat Aug 21 20:58:02 1999
+++ fmw-uw/kernel/virtcode.c    Tue Aug 24 03:24:22 1999
@@ -32,7 +32,6 @@
 asm (
     ".text; .globl __do_nothing     \n"
     "__do_nothing:                  \n"
-    "    lss  mon_stack_info, %esp  \n"  /* Switch to our own stack     */
     "    movw %ss, %ax              \n"  /* Setup the segment registers */
     "    movw %ax, %ds              \n"
     "    movw %ax, %es              \n"
-- 
  Ulrich Weigand,
  IMMD 1, Universitaet Erlangen-Nuernberg,
  Martensstr. 3, D-91058 Erlangen, Phone: +49 9131 85-7688

Reply via email to