]> Zhao Yanbai Git Server - minix.git/commitdiff
fix from trunk for assert(ptproc == newptproc) without vm_stop on shutdown.
authorBen Gras <ben@minix3.org>
Mon, 7 Jun 2010 22:24:21 +0000 (22:24 +0000)
committerBen Gras <ben@minix3.org>
Mon, 7 Jun 2010 22:24:21 +0000 (22:24 +0000)
kernel/arch/i386/klib.S
kernel/arch/i386/memory.c
kernel/arch/i386/proto.h
kernel/proto.h

index 98d7171b275591855573da6bf230a02cf03e6290..4d99dd782595ef288076a7c2ed7c37398da3a03f 100644 (file)
@@ -38,6 +38,7 @@
 .globl _getcr3val
 .globl _write_cr0      /* write a value in cr0 */
 .globl _read_cr3
+.globl _write_cr3
 .globl _read_cr4
 .globl _write_cr4
 
@@ -788,6 +789,22 @@ _write_cr4:
 0:
        pop     %ebp
        ret
+
+/*===========================================================================*/
+/*                           write_cr3                                      */
+/*===========================================================================*/
+/* PUBLIC void write_cr3(unsigned long value); */
+_write_cr3:
+       push    %ebp
+       mov     %esp, %ebp
+       mov     8(%ebp), %eax
+
+       /* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
+       mov     %eax, %cr3
+
+       pop     %ebp
+       ret
+
 /*===========================================================================*/
 /*                             getcr3val                                    */
 /*===========================================================================*/
index e3bc551beee5750fadcd3809d6664d4ab739e4ab..ca93a298d5b8c8bd582152b26b40112e3d17cded 100644 (file)
@@ -45,11 +45,25 @@ PUBLIC void vm_init(struct proc *newptproc)
 {
        if(vm_running)
                panic("vm_init: vm_running");
+
+       /* switch_address_space() checks what is in cr3, and doesn't do
+        * anything if it's the same as the cr3 of its argument, newptproc.
+        * If MINIX was previously booted, this could very well be the case.
+        *
+        * The first time switch_address_space() is called, we want to
+        * force it to do something (load cr3 and set newptproc), so we
+        * zero cr3, and force paging off to make that a safe thing to do.
+        *
+        * After that, vm_enable_paging() enables paging with the page table
+        * of newptproc loaded.
+        */
+
+       vm_stop();
+       write_cr3(0);
        switch_address_space(newptproc);
        assert(ptproc == newptproc);
        vm_enable_paging();
        vm_running = 1;
-
 }
 
 /* This function sets up a mapping from within the kernel's address
@@ -254,6 +268,11 @@ PRIVATE char *cr4_str(u32_t e)
        return str;
 }
 
+PUBLIC void vm_stop(void)
+{
+       write_cr0(read_cr0() & ~I386_CR0_PG);
+}
+
 PRIVATE void vm_enable_paging(void)
 {
        u32_t cr0, cr4;
index 3acb7c42c91fa50b4c06b02aa40729539cede17b..cdc40ab8264be389e7a1beb8eef5832013a42381 100644 (file)
@@ -74,6 +74,7 @@ _PROTOTYPE( reg_t read_cr2, (void)                                    );
 _PROTOTYPE( void write_cr0, (unsigned long value)                       );
 _PROTOTYPE( unsigned long read_cr4, (void)                              );
 _PROTOTYPE( void write_cr4, (unsigned long value)                       );
+_PROTOTYPE( void write_cr3, (unsigned long value)                       );
 _PROTOTYPE( unsigned long read_cpu_flags, (void)                        );
 _PROTOTYPE( void phys_insb, (u16_t port, phys_bytes buf, size_t count)  );
 _PROTOTYPE( void phys_insw, (u16_t port, phys_bytes buf, size_t count)  );
index 32ea89448cd997584b047888314bb5468b50efaf..265d3a055570740215849439354b0ef9361ff3a4 100644 (file)
@@ -142,6 +142,7 @@ _PROTOTYPE( int data_copy_vmcheck, (struct proc *,
        endpoint_t to, vir_bytes to_addr, size_t bytes));
 _PROTOTYPE( void alloc_segments, (struct proc *rp)                      );
 _PROTOTYPE( void vm_init, (struct proc *first)                         );
+_PROTOTYPE( void vm_stop, (void)                                       );
 _PROTOTYPE( phys_bytes umap_local, (register struct proc *rp, int seg,
        vir_bytes vir_addr, vir_bytes bytes));
 _PROTOTYPE( phys_bytes umap_remote, (const struct proc* rp, int seg,