]> Zhao Yanbai Git Server - minix.git/commitdiff
state
authorBen Gras <ben@minix3.org>
Wed, 3 Jun 2009 11:22:49 +0000 (11:22 +0000)
committerBen Gras <ben@minix3.org>
Wed, 3 Jun 2009 11:22:49 +0000 (11:22 +0000)
37 files changed:
include/minix/com.h
include/minix/syslib.h
kernel/arch/i386/arch_do_vmctl.c
kernel/arch/i386/do_sdevio.c
kernel/arch/i386/exception.c
kernel/arch/i386/klib386.s
kernel/arch/i386/memory.c
kernel/arch/i386/mpx386.s
kernel/arch/i386/protect.c
kernel/arch/i386/system.c
kernel/debug.c
kernel/debug.h
kernel/glo.h
kernel/main.c
kernel/proc.c
kernel/proc.h
kernel/proto.h
kernel/system.c
kernel/system/do_exec.c
kernel/system/do_fork.c
kernel/system/do_vmctl.c
kernel/utility.c
kernel/vm.h
lib/syslib/sys_fork.c
lib/sysutil/Makefile.in
servers/init/init.c
servers/pm/main.c
servers/vfs/fs.h
servers/vfs/main.c
servers/vm/alloc.c
servers/vm/exit.c
servers/vm/fork.c
servers/vm/i386/pagetable.c
servers/vm/pagefaults.c
servers/vm/proto.h
servers/vm/region.c
servers/vm/vm.h

index 0c838685af6650546957d5aaa96c022776d4637a..5e629aa991e2858192f7b0fb7eed30ed9c1c8cdc 100755 (executable)
                                 * and sys_fork
                                 */
 #define PR_FORK_FLAGS  m1_i3
+#define PR_FORK_MSGADDR m1_p1
 
 /* Field names for SYS_INT86 */
 #define INT86_REG86    m1_p1   /* pointer to registers */
index d4facdc2c5f82805f78f95bf2afa80d540bc7680..07b9975dfeb95994a43cbdb96d71f8a501d08699 100755 (executable)
@@ -35,7 +35,7 @@ _PROTOTYPE( int sys_enable_iop, (endpoint_t proc));
 _PROTOTYPE( int sys_exec, (endpoint_t proc, char *ptr,  
                                char *aout, vir_bytes initpc));
 _PROTOTYPE( int sys_fork, (endpoint_t parent, endpoint_t child, int *,
-       struct mem_map *ptr, u32_t vm));
+       struct mem_map *ptr, u32_t vm, vir_bytes *));
 _PROTOTYPE( int sys_newmap, (endpoint_t proc, struct mem_map *ptr));
 _PROTOTYPE( int sys_exit, (endpoint_t proc));
 _PROTOTYPE( int sys_trace, (int req, endpoint_t proc, long addr, long *data_p));
index 71a0469aa5b191e975ec77aa7af89c9194a650df..5e0e9b350186610efe093c3d981c0e2abe3551d8 100644 (file)
@@ -53,22 +53,19 @@ struct proc *p;
                 m_ptr->SVMCTL_PF_WHO = rp->p_endpoint;
                 m_ptr->SVMCTL_PF_I386_CR2 = rp->p_pagefault.pf_virtual;
                m_ptr->SVMCTL_PF_I386_ERR = rp->p_pagefault.pf_flags;
-               printf("kernel: returning pagefault for %s / %d\n",
-                       rp->p_name, rp->p_endpoint);
                return OK;
        }
        case VMCTL_I386_KERNELLIMIT:
        {
+               int r;
                /* VM wants kernel to increase its segment. */
-               kprintf("kernel: increase limit to 0x%x\n", 
-                       m_ptr->SVMCTL_VALUE);
-               return prot_set_kern_seg_limit(m_ptr->SVMCTL_VALUE);
+               r = prot_set_kern_seg_limit(m_ptr->SVMCTL_VALUE);
+               return r;
        }
        case VMCTL_I386_PAGEDIRS:
        {
                int pde;
                vm_pagedirs = (u32_t *) m_ptr->SVMCTL_VALUE;
-               kprintf("kernel: pagedirs now 0x%lx\n", vm_pagedirs);
                return OK;
        }
        case VMCTL_I386_FREEPDE:
@@ -83,6 +80,8 @@ struct proc *p;
        }
   }
 
+
+
   kprintf("arch_do_vmctl: strange param %d\n", m_ptr->SVMCTL_PARAM);
   return EINVAL;
 }
index 1beefa499792a0f7471bc6ebe4fa11170fae7fd9..2363a2c570174e0a80a69c14181ea87af2fb4601 100644 (file)
@@ -33,10 +33,6 @@ register message *m_ptr;     /* pointer to request message */
   struct priv *privp;
   struct io_range *iorp;
 
-  kprintf("kernel: no sdevio\n");
-  return EIO;
-
-#if 0
   /* Allow safe copies and accesses to SELF */
   if ((m_ptr->DIO_REQUEST & _DIO_SAFEMASK) != _DIO_SAFE &&
        proc_nr_e != SELF)
@@ -85,6 +81,11 @@ register message *m_ptr;     /* pointer to request message */
         (vir_bytes) m_ptr->DIO_VEC_ADDR, count)) == 0)
          return(EFAULT);
   }
+     /* current process must be target for phys_* to be OK */
+     if(proc_addr(proc_nr) != ptproc) {
+       kprintf("do_sdevio: wrong process\n");
+       return EIO;
+     }
 
        switch (io_type)
        {
@@ -145,7 +146,6 @@ register message *m_ptr;    /* pointer to request message */
       return(EINVAL);
   }
   return(OK);
-#endif
 }
 
 #endif /* USE_SDEVIO */
index b28d7d03b85d181133f8405737c565434100a22b..29ab505e24be5fc283fb1702cd94bf503e97f08e 100755 (executable)
 #include <string.h>
 #include <minix/sysutil.h>
 #include "../../proc.h"
+#include "../../proto.h"
 
 extern int vm_copy_in_progress, catch_pagefaults;
 extern struct proc *vm_copy_from, *vm_copy_to;
-extern u32_t vm_copy_from_v, vm_copy_to_v;
-extern u32_t vm_copy_from_p, vm_copy_to_p, vm_copy_cr3;
-extern u32_t catchrange_lo, catchrange_hi;
 
 u32_t pagefault_cr2, pagefault_count = 0;
 vir_bytes *old_eip_ptr = NULL, *old_eax_ptr = NULL;
@@ -26,6 +24,7 @@ void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno)
        vir_bytes ph;
        u32_t pte;
        int procok = 0, pcok = 0, rangeok = 0;
+       int in_memcpy = 0, in_physcopy = 0;
 
        vmassert(old_eip_ptr);
        vmassert(old_eax_ptr);
@@ -35,33 +34,30 @@ void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno)
 
        vmassert(pagefault_count == 1);
 
-       if(catch_pagefaults &&
-               (rangeok = (pagefault_cr2 >= catchrange_lo &&
-                  pagefault_cr2 < catchrange_hi))) {
+       if(catch_pagefaults) {
                vir_bytes test_eip;
                test_eip = k_reenter ? old_eip : pr->p_reg.pc;
-               if((pcok = ((test_eip > (vir_bytes) _memcpy_k) &&
-                  (test_eip < (vir_bytes) _memcpy_k_fault)))) {
-                       kprintf("handling pagefault during copy\n");
+               in_memcpy = (test_eip > (vir_bytes) _memcpy_k) &&
+                  (test_eip < (vir_bytes) _memcpy_k_fault);
+               in_physcopy = (test_eip > (vir_bytes) phys_copy) &&
+                  (test_eip < (vir_bytes) phys_copy_fault);
+               if((pcok = in_memcpy || in_physcopy)) {
                        pagefault_count = 0;
 
-                       *old_eip_ptr = _memcpy_k_fault;
+                       if(in_memcpy) {
+                               vmassert(!in_physcopy);
+                               *old_eip_ptr = _memcpy_k_fault;
+                       }
+                       if(in_physcopy) {
+                               vmassert(!in_memcpy);
+                               *old_eip_ptr = phys_copy_fault;
+                       }
                        *old_eax_ptr = pagefault_cr2;
 
                        return;
                }
        }
 
-       kprintf("kernel stacktrace in pagefault: "); 
-       util_stacktrace();
-
-       if(catch_pagefaults) {
-               kprintf("procok: %d pcok: %d rangeok: %d\n",
-                       procok, pcok, rangeok);
-               printf("k_reenter: %d addr: 0x%lx range: 0x%lx-0x%lx pc: 0x%lx\n",
-                       k_reenter, pagefault_cr2, catchrange_lo, catchrange_hi, pr->p_reg.pc);
-       }
-
        /* System processes that don't have their own page table can't
         * have page faults. VM does have its own page table but also
         * can't have page faults (because VM has to handle them).
@@ -94,16 +90,11 @@ void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno)
        pr->p_pagefault.pf_flags = trap_errno;
        pr->p_nextpagefault = pagefaults;
        pagefaults = pr;
-       soft_notify(VM_PROC_NR);
+               
+       lock_notify(SYSTEM, VM_PROC_NR);
 
        pagefault_count = 0;
 
-#if 0
-       kprintf("pagefault for process %d ('%s'), pc = 0x%x\n",
-                       pr->p_endpoint, pr->p_name, pr->p_reg.pc);
-       proc_stacktrace(pr);
-#endif
-
        return;
 }
 
@@ -148,13 +139,6 @@ struct proc *t;
   register struct ex_s *ep;
   struct proc *saved_proc;
 
-#if DEBUG_SCHED_CHECK
-  for (t = BEG_PROC_ADDR; t < END_PROC_ADDR; ++t) {
-       if(t->p_magic != PMAGIC)
-               kprintf("entry %d broken\n", t->p_nr);
-  }
-#endif
-
   /* Save proc_ptr, because it may be changed by debug statements. */
   saved_proc = proc_ptr;       
 
index fda2f3f393637cd337d0b63cdc3613de61d8f3ce..18a602846988da35af6f0ae6d86595bfb6dc8220 100755 (executable)
@@ -8,7 +8,6 @@
 #include <ibm/interrupt.h>
 #include <archconst.h>
 #include "../../const.h"
-#include "vm.h"
 #include "sconst.h"
 
 ! This file contains a number of assembly code utility routines needed by the
 .define        __exit          ! dummy for library routines
 .define        ___exit         ! dummy for library routines
 .define        ___main         ! dummy for GCC
-!.define       _phys_insw      ! transfer data from (disk controller) port to memory
-!.define       _phys_insb      ! likewise byte by byte
-!.define       _phys_outsw     ! transfer data from memory to (disk controller) port
-!.define       _phys_outsb     ! likewise byte by byte
+.define        _phys_insw      ! transfer data from (disk controller) port to memory
+.define        _phys_insb      ! likewise byte by byte
+.define        _phys_outsw     ! transfer data from memory to (disk controller) port
+.define        _phys_outsb     ! likewise byte by byte
 .define        _intr_unmask    ! enable an irq at the 8259 controller
 .define        _intr_mask      ! disable an irq
 .define        _phys_copy      ! copy data from anywhere to anywhere in memory
+.define        _phys_copy_fault! phys_copy pagefault
 .define        _phys_memset    ! write pattern anywhere in memory
 .define        _mem_rdw        ! copy one word from [segment:offset]
 .define        _reset          ! reset the system
@@ -35,9 +35,7 @@
 .define        _level0         ! call a function at level 0
 .define        _read_cpu_flags ! read the cpu flags
 .define        _read_cr0       ! read cr0
-.define        _write_cr3      ! write cr3
 .define        _getcr3val
-.define _last_cr3
 .define        _write_cr0      ! write a value in cr0
 .define        _read_cr4
 .define        _thecr3
@@ -46,6 +44,7 @@
 .define _i386_invlpg_level0
 .define __memcpy_k
 .define __memcpy_k_fault
+.define        _catch_pagefaults
 
 ! The routines only guarantee to preserve the registers the C compiler
 ! expects to be preserved (ebx, esi, edi, ebp, esp, segment registers, and
@@ -183,52 +182,52 @@ ___main:
 !*===========================================================================*
 ! PUBLIC void phys_insw(Port_t port, phys_bytes buf, size_t count);
 ! Input an array from an I/O port.  Absolute address version of insw().
-!
-!_phys_insw:
-!      push    ebp
-!      mov     ebp, esp
-!      cld
-!      push    edi
-!      push    es
-!
-!      mov     ecx, FLAT_DS_SELECTOR
-!      mov     es, cx
-!      mov     edx, 8(ebp)             ! port to read from
-!      mov     edi, 12(ebp)            ! destination addr
-!      mov     ecx, 16(ebp)            ! byte count
-!      shr     ecx, 1                  ! word count
-!rep o16       ins                             ! input many words
-!      pop     es
-!      pop     edi
-!      pop     ebp
-!      ret
-!
+
+_phys_insw:
+       push    ebp
+       mov     ebp, esp
+       cld
+       push    edi
+       push    es
+
+       mov     ecx, FLAT_DS_SELECTOR
+       mov     es, cx
+       mov     edx, 8(ebp)             ! port to read from
+       mov     edi, 12(ebp)            ! destination addr
+       mov     ecx, 16(ebp)            ! byte count
+       shr     ecx, 1                  ! word count
+rep o16        ins                             ! input many words
+       pop     es
+       pop     edi
+       pop     ebp
+       ret
+
 
 !*===========================================================================*
 !*                             phys_insb                                    *
 !*===========================================================================*
 ! PUBLIC void phys_insb(Port_t port, phys_bytes buf, size_t count);
 ! Input an array from an I/O port.  Absolute address version of insb().
-!
-!_phys_insb:
-!      push    ebp
-!      mov     ebp, esp
-!      cld
-!      push    edi
-!      push    es
-!
-!      mov     ecx, FLAT_DS_SELECTOR
-!      mov     es, cx
-!      mov     edx, 8(ebp)             ! port to read from
-!      mov     edi, 12(ebp)            ! destination addr
-!      mov     ecx, 16(ebp)            ! byte count
-!!     shr     ecx, 1                  ! word count
-!   rep        insb                            ! input many bytes
-!      pop     es
-!      pop     edi
-!      pop     ebp
-!      ret
-!
+
+_phys_insb:
+       push    ebp
+       mov     ebp, esp
+       cld
+       push    edi
+       push    es
+
+       mov     ecx, FLAT_DS_SELECTOR
+       mov     es, cx
+       mov     edx, 8(ebp)             ! port to read from
+       mov     edi, 12(ebp)            ! destination addr
+       mov     ecx, 16(ebp)            ! byte count
+!      shr     ecx, 1                  ! word count
+   rep insb                            ! input many bytes
+       pop     es
+       pop     edi
+       pop     ebp
+       ret
+
 
 !*===========================================================================*
 !*                             phys_outsw                                   *
@@ -236,51 +235,51 @@ ___main:
 ! PUBLIC void phys_outsw(Port_t port, phys_bytes buf, size_t count);
 ! Output an array to an I/O port.  Absolute address version of outsw().
 
-!      .align  16
-!_phys_outsw:
-!      push    ebp
-!      mov     ebp, esp
-!      cld
-!      push    esi
-!      push    ds
-!
-!      mov     ecx, FLAT_DS_SELECTOR
-!      mov     ds, cx
-!      mov     edx, 8(ebp)             ! port to write to
-!      mov     esi, 12(ebp)            ! source addr
-!      mov     ecx, 16(ebp)            ! byte count
-!      shr     ecx, 1                  ! word count
-!rep o16       outs                            ! output many words
-!      pop     ds
-!      pop     esi
-!      pop     ebp
-!      ret
-!
+       .align  16
+_phys_outsw:
+       push    ebp
+       mov     ebp, esp
+       cld
+       push    esi
+       push    ds
+
+       mov     ecx, FLAT_DS_SELECTOR
+       mov     ds, cx
+       mov     edx, 8(ebp)             ! port to write to
+       mov     esi, 12(ebp)            ! source addr
+       mov     ecx, 16(ebp)            ! byte count
+       shr     ecx, 1                  ! word count
+rep o16        outs                            ! output many words
+       pop     ds
+       pop     esi
+       pop     ebp
+       ret
+
 
 !*===========================================================================*
 !*                             phys_outsb                                   *
 !*===========================================================================*
 ! PUBLIC void phys_outsb(Port_t port, phys_bytes buf, size_t count);
 ! Output an array to an I/O port.  Absolute address version of outsb().
-!
-!      .align  16
-!_phys_outsb:
-!      push    ebp
-!      mov     ebp, esp
-!      cld
-!      push    esi
-!      push    ds
-!
-!      mov     ecx, FLAT_DS_SELECTOR
-!      mov     ds, cx
-!      mov     edx, 8(ebp)             ! port to write to
-!      mov     esi, 12(ebp)            ! source addr
-!      mov     ecx, 16(ebp)            ! byte count
-!   rep        outsb                           ! output many bytes
-!      pop     ds
-!      pop     esi
-!      pop     ebp
-!      ret
+
+       .align  16
+_phys_outsb:
+       push    ebp
+       mov     ebp, esp
+       cld
+       push    esi
+       push    ds
+
+       mov     ecx, FLAT_DS_SELECTOR
+       mov     ds, cx
+       mov     edx, 8(ebp)             ! port to write to
+       mov     esi, 12(ebp)            ! source addr
+       mov     ecx, 16(ebp)            ! byte count
+   rep outsb                           ! output many bytes
+       pop     ds
+       pop     esi
+       pop     ebp
+       ret
 
 
 !*==========================================================================*
@@ -363,7 +362,7 @@ dis_already:
 !*===========================================================================*
 !*                             phys_copy                                    *
 !*===========================================================================*
-! PUBLIC void phys_copy(phys_bytes source, phys_bytes destination,
+! PUBLIC phys_bytes phys_copy(phys_bytes source, phys_bytes destination,
 !                      phys_bytes bytecount);
 ! Copy a block of physical memory.
 
@@ -384,6 +383,8 @@ _phys_copy:
        mov     edi, PC_ARGS+4(esp)
        mov     eax, PC_ARGS+4+4(esp)
 
+       mov     (_catch_pagefaults), 1
+
        cmp     eax, 10                 ! avoid align overhead for small counts
        jb      pc_small
        mov     ecx, esi                ! align source, hope target is too
@@ -405,6 +406,9 @@ pc_small:
        pop     es
        pop     edi
        pop     esi
+       mov     eax, 0                  ! 0 means: no fault
+_phys_copy_fault:                      ! kernel can send us here
+       mov     (_catch_pagefaults), 0
        ret
 
 !*===========================================================================*
@@ -576,17 +580,6 @@ _write_cr4:
        pop     ebp
        ret
 
-!*===========================================================================*
-!*                             write_cr3                               *
-!*===========================================================================*
-! PUBLIC void write_cr3(unsigned long value);
-_write_cr3:
-       push    ebp
-       mov     ebp, esp
-       mov     eax, 8(ebp)
-       mov     cr3, eax
-       pop     ebp
-       ret
 
 !*===========================================================================*
 !*                             getcr3val                               *
@@ -602,9 +595,8 @@ _getcr3val:
 !*===========================================================================*
 ! PUBLIC void i386_invlpg(void);
 _i386_invlpg_level0:
-       push    ebp
-       invlpg  (_i386_invlpg_addr)
-       pop     ebp
+       mov eax, (_i386_invlpg_addr)
+       invlpg  (eax)
        ret
 
 
index ea725e3a7faca0367924122b5af82a6b27df57de..44896b90f6cea0f404cac4a363b569eacfb58ad3 100644 (file)
 
 PRIVATE int psok = 0;
 
+extern u32_t createpde, linlincopies, physzero;
+
 #define PROCPDEPTR(pr, pi) ((u32_t *) ((u8_t *) vm_pagedirs +\
                                I386_PAGE_SIZE * pr->p_nr +     \
                                I386_VM_PT_ENT_SIZE * pi))
 
 /* Signal to exception handler that pagefaults can happen. */
 int catch_pagefaults = 0;
-u32_t catchrange_lo = 0;
-u32_t catchrange_hi = 0;
-
-#if 0
-/* VM functions and data. */
-PUBLIC u32_t kernel_cr3;
-#endif
-
-extern u32_t cswitch;
-u32_t last_cr3 = 0;
 
 u8_t *vm_pagedirs = NULL;
 
@@ -70,11 +62,6 @@ PUBLIC void vm_init(struct proc *newptproc)
                ptproc->p_seg.p_cr3);
        vmassert(newcr3);
 
-       kprintf("vm_init thinks cr3 0x%lx is loaded, proc %d, cr3 0x%lx, actual cr3 0x%lx\n",
-               last_cr3, ptproc->p_endpoint, ptproc->p_seg.p_cr3, read_cr3());
-
-       kprintf("vm_init: writing cr3 0x%lx\n", newcr3);
-
        /* Set this cr3 now (not active until paging enabled). */
        vm_set_cr3(newcr3);
 
@@ -93,15 +80,6 @@ PUBLIC void vm_init(struct proc *newptproc)
        kprintf("vm_init done\n");
 }
 
-#if 0
-PRIVATE void phys_put32(addr, value)
-phys_bytes addr;
-u32_t value;
-{
-       phys_copy(vir2phys((vir_bytes)&value), addr, sizeof(value));
-}
-#endif
-
 PRIVATE u32_t phys_get32(addr)
 phys_bytes addr;
 {
@@ -179,9 +157,6 @@ PRIVATE void vm_enable_paging(void)
        cr0= read_cr0();
        cr4= read_cr4();
 
-       kprintf("vm_enable_paging: cr0: %s cr4: %s; want to disable\n",
-               cr0_str(cr0), cr4_str(cr4));
-
        /* First clear PG and PGE flag, as PGE must be enabled after PG. */
        write_cr0(cr0 & ~I386_CR0_PG);
        write_cr4(cr4 & ~(I386_CR4_PGE | I386_CR4_PSE));
@@ -189,9 +164,6 @@ PRIVATE void vm_enable_paging(void)
        cr0= read_cr0();
        cr4= read_cr4();
 
-       kprintf("vm_enable_paging: cr0: %s cr4: %s after disabling\n",
-               cr0_str(cr0), cr4_str(cr4));
-
        /* Our first page table contains 4MB entries. */
        if(psok)
                cr4 |= I386_CR4_PSE;
@@ -199,21 +171,15 @@ PRIVATE void vm_enable_paging(void)
        write_cr4(cr4);
 
        /* First enable paging, then enable global page flag. */
-       kprintf("vm_enable_paging: write PG\n");
        cr0 |= I386_CR0_PG;
        write_cr0(cr0 );
-       kprintf("vm_enable_paging: writing WP\n");
        cr0 |= I386_CR0_WP;
        write_cr0(cr0);
-       kprintf("vm_enable_paging: write WP done\n");
 
        /* May we enable these features? */
        if(pgeok)
                cr4 |= I386_CR4_PGE;
 
-       kprintf("vm_enable_paging: write cr4 0x%lx\n", cr4);
-       write_cr4(cr4);
-       kprintf("vm_enable_paging: write cr4 0x%lx done\n", cr4);
        write_cr4(cr4);
 }
 
@@ -510,9 +476,8 @@ PUBLIC int vm_suspend(struct proc *caller, struct proc *target)
        /* Connect caller on vmrequest wait queue. */   
        caller->p_vmrequest.nextrequestor = vmrequest;
        vmrequest = caller;     
-       if(!caller->p_vmrequest.nextrequestor) {
-               soft_notify(VM_PROC_NR);                
-       }                                               
+       if(!caller->p_vmrequest.nextrequestor)
+               lock_notify(SYSTEM, VM_PROC_NR);                
 }
 
 /*===========================================================================*
@@ -670,11 +635,7 @@ void invlpg_range(u32_t lin, u32_t bytes)
        limit = lin + bytes - 1;
        o = lin % I386_PAGE_SIZE;
        lin -= o;
-       limit += o;
-       limit &= I386_VM_PT_ENT_MASK;
-       FIXME("invlpg_range reloads cr3");
-       cr3 = read_cr3();
-       vm_set_cr3(cr3);
+       limit = (limit + o) & I386_VM_ADDR_MASK;
        for(i386_invlpg_addr = lin; i386_invlpg_addr <= limit;
            i386_invlpg_addr += I386_PAGE_SIZE)
                level0(i386_invlpg_level0);
@@ -700,10 +661,12 @@ u32_t read_cr3(void)
  * It needs FREEPDE (available and addressable PDE within kernel
  * address space), SEG (hardware segment), VIRT (in-datasegment
  * address if known).
- *
- * TODO: don't re-make a pde that's already there.
  */
 #define CREATEPDE(PROC, PTR, LINADDR, OFFSET, FREEPDE, VIRT, SEG, REMAIN, BYTES) { \
+       FIXME("CREATEPDE: check if invlpg is necessary");       \
+       if(PROC == ptproc) {                                    \
+               FIXME("CREATEPDE: use in-memory process");      \
+       }                                                       \
        if((PROC) && iskernelp(PROC) && SEG == D) {             \
                PTR = VIRT;                                     \
                OFFSET = 0;                                     \
@@ -713,16 +676,13 @@ u32_t read_cr3(void)
                vmassert(psok);                                 \
                pde_index = I386_VM_PDE(LINADDR);               \
                vmassert(!iskernelp(PROC));                     \
+               createpde++;                                    \
                if(PROC) {                                      \
                        u32_t *pdeptr; \
                        vmassert(!iskernelp(PROC));             \
                        vmassert(HASPT(PROC));                  \
                        pdeptr = PROCPDEPTR(PROC, pde_index);           \
                        pdeval = *pdeptr;       \
-                       if(!(pdeval & I386_VM_PRESENT)) {               \
-                               kprintf("kernel: pde %d 0x%lx for proc %d\n", \
-                                       pde_index, pdeval, PROC->p_endpoint); \
-                       }                                               \
                } else {                                                \
                        pdeval = (LINADDR & I386_VM_ADDR_MASK_4MB) |    \
                                I386_VM_BIGPAGE | I386_VM_PRESENT |     \
@@ -737,6 +697,20 @@ u32_t read_cr3(void)
        }                                                               \
 }
 
+
+/*===========================================================================*
+ *                             arch_switch_copymsg                          *
+ *===========================================================================*/
+phys_bytes arch_switch_copymsg(struct proc *rp, message *m, phys_bytes lin)
+{
+       phys_bytes r;
+       if(rp->p_seg.p_cr3) {
+               vm_set_cr3(rp->p_seg.p_cr3);
+               ptproc = rp;
+       }
+       r = phys_copy(vir2phys(m), lin, sizeof(message));
+}
+
 /*===========================================================================*
  *                             lin_lin_copy                                 *
  *===========================================================================*/
@@ -748,9 +722,11 @@ int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, u8_t *vsrc,
 {
        u32_t addr;
        int procslot;
-       u32_t catchrange_dst;
+       u32_t catchrange_dst, catchrange_lo, catchrange_hi;
        NOREC_ENTER(linlincopy);
 
+       linlincopies++;
+
        if(srcproc && dstproc && iskernelp(srcproc) && iskernelp(dstproc)) {
                memcpy(vdst, vsrc, bytes);
                NOREC_RETURN(linlincopy, OK);
@@ -795,14 +771,10 @@ int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, u8_t *vsrc,
                catch_pagefaults = 0;
 
                if(addr) {
-                       kprintf("kernel: lin_lin copy: returning EFAULT, addr 0x%lx\n",
-                               addr);
                        if(addr >= catchrange_lo && addr < catchrange_dst) {
-                               kprintf("src\n");
                                NOREC_RETURN(linlincopy, EFAULT_SRC);
                        }
                        if(addr >= catchrange_dst && addr < catchrange_hi) {
-                               kprintf("dst\n");
                                NOREC_RETURN(linlincopy, EFAULT_DST);
                        }
                        minix_panic("lin_lin_copy fault out of range", NO_NUM);
@@ -831,6 +803,8 @@ int vm_phys_memset(phys_bytes ph, u8_t c, phys_bytes bytes)
 {
        char *v;
 
+       physzero++;
+
        if(!vm_running) {
                u32_t p;
                p = c | (c << 8) | (c << 16) | (c << 24);
@@ -857,6 +831,7 @@ int vm_phys_memset(phys_bytes ph, u8_t c, phys_bytes bytes)
                ph += chunk;
        }
 
+
        return OK;
 }
 
@@ -966,8 +941,7 @@ int vmcheck;                        /* if nonzero, can return VMSUSPEND */
 
                caller = proc_addr(who_p);
 
-               printf("virtual_copy: suspending caller %d / %s\n",
-                       caller->p_endpoint, caller->p_name);
+               vmassert(procs[_SRC_] && procs[_DST_]);
 
                if(r == EFAULT_SRC) {
                        caller->p_vmrequest.start = phys_addr[_SRC_];
@@ -981,6 +955,12 @@ int vmcheck;                       /* if nonzero, can return VMSUSPEND */
                        minix_panic("r strange", r);
                }
 
+#if 0
+               printf("virtual_copy: suspending caller %d / %s, target %d / %s\n",
+                       caller->p_endpoint, caller->p_name,
+                       target->p_endpoint, target->p_name);
+#endif
+
                caller->p_vmrequest.length = bytes;
                caller->p_vmrequest.who = target->p_endpoint;
 
@@ -1068,5 +1048,4 @@ void i386_freepde(int pde)
        if(nfreepdes >= WANT_FREEPDES)
                return;
        freepdes[nfreepdes++] = pde;
-       printf("kernel: free pde: %d\n", pde);
 }
index 61b849c8d08cacffc8396db50316508dac199985..241df7330acf60cc18d0583cecc0af1e13652825 100755 (executable)
@@ -60,7 +60,6 @@ begbss:
 #include <ibm/interrupt.h>
 #include <archconst.h>
 #include "../../const.h"
-#include "vm.h"
 #include "sconst.h"
 
 /* Selected 386 tss offsets. */
@@ -78,6 +77,9 @@ begbss:
 .define _pagefault_count
 .define _old_eip_ptr
 .define _old_eax_ptr
+.define _cr3_test
+.define _cr3_reload
+.define        _write_cr3      ! write cr3
 
 .define errexception
 .define exception1
@@ -411,13 +413,15 @@ _restart:
        mov     (_next_ptr), 0
 0:     mov     esp, (_proc_ptr)        ! will assume P_STACKBASE == 0
        lldt    P_LDT_SEL(esp)          ! enable process' segment descriptors 
+       inc     (_cr3_test)
        cmp     P_CR3(esp), 0           ! process does not have its own PT
        jz      noload  
        mov     eax, P_CR3(esp)
-       mov     ebx, cr3
-       cmp     eax, ebx
+       cmp     eax, (loadedcr3)
        jz      noload
+       inc     (_cr3_reload)
        mov     cr3, eax
+       mov     (loadedcr3), eax
        mov     eax, (_proc_ptr)
        mov     (_ptproc), eax
 noload:
@@ -553,6 +557,20 @@ exception1:                                ! Common for all exceptions.
        add     esp, 5*4
        ret
 
+
+!*===========================================================================*
+!*                             write_cr3                               *
+!*===========================================================================*
+! PUBLIC void write_cr3(unsigned long value);
+_write_cr3:
+       push    ebp
+       mov     ebp, esp
+       mov     eax, 8(ebp)
+       mov     cr3, eax
+       mov     (loadedcr3), eax
+       pop     ebp
+       ret
+
 !*===========================================================================*
 !*                             level0_call                                  *
 !*===========================================================================*
@@ -576,4 +594,5 @@ k_stktop:                   ! top of kernel stack
        .comm   old_eip, 4
        .comm   old_cs, 4
        .comm   old_eflags, 4
+       .comm   loadedcr3, 4
 
index 8e2408ee7854f59af17a9e05dbafbeeca69c7ba9..0d13d89e3830ed19a9657efb74ac5e51b727810a 100755 (executable)
@@ -340,40 +340,25 @@ PUBLIC int prot_set_kern_seg_limit(vir_bytes limit)
        int orig_click;
        int incr_clicks;
 
-       kprintf("prot_set_kern_seg_limit: limit 0x%lx\n", limit);
-
        if(limit <= kinfo.data_base) {
                kprintf("prot_set_kern_seg_limit: limit bogus\n");
                return EINVAL;
        }
 
-       kprintf("size: 0x%lx -> ", kinfo.data_size);
-
        /* Do actual increase. */
        orig_click = kinfo.data_size / CLICK_SIZE;
        kinfo.data_size = limit - kinfo.data_base;
        incr_clicks = kinfo.data_size / CLICK_SIZE - orig_click;
 
-       kprintf("0x%lx\n", kinfo.data_size);
-
-       kprintf("prot_set_kern_seg_limit: prot_init\n");
-
        prot_init();
 
-       kprintf("prot_set_kern_seg_limit: prot_init done\n");
-
        /* Increase kernel processes too. */
        for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; ++rp) {
                if (RTS_ISSET(rp, SLOT_FREE) || !iskernelp(rp))
                        continue;
-               kprintf("prot_set_kern_seg_limit: increase %d 0x%x ->\n",
-                       rp->p_endpoint, rp->p_memmap[S].mem_len);
                rp->p_memmap[S].mem_len += incr_clicks;
                alloc_segments(rp);
-               kprintf("prot_set_kern_seg_limit: increase %d done -> 0x%x\n",
-                       rp->p_endpoint, rp->p_memmap[S].mem_len);
        }
-       kprintf("prot_set_kern_seg_limit: done\n");
 
        return OK;
 }
index ca3fae3947e2511b291d1a99ad68e5a2d38e7f1f..a04cdd6fbebf61a72e2aaf14db508c579d1c95cb 100644 (file)
@@ -166,11 +166,12 @@ PRIVATE void printslot(struct proc *pp)
 
        level++;
 
-       kprintf("%*s %d: %s %d prio %d/%d time %d/%d cr3 0x%lx rts %s ",
+       kprintf("%*s %d: %s %d prio %d/%d time %d/%d cr3 0x%lx rts %s misc %s ",
                level, "",
                proc_nr(pp), pp->p_name, pp->p_endpoint, 
                pp->p_priority, pp->p_max_priority, pp->p_user_time,
-               pp->p_sys_time, pp->p_seg.p_cr3, rtsflagstr(pp->p_rts_flags));
+               pp->p_sys_time, pp->p_seg.p_cr3,
+               rtsflagstr(pp->p_rts_flags), miscflagstr(pp->p_misc_flags));
 
        if(pp->p_rts_flags & SENDING) {
                dep = pp->p_sendto_e;
index 13a001dd701b28ccd8242d632cc4bd63bcd4cb49..9e4c78d46e4b29069c2f269837425cbf99906baa 100644 (file)
@@ -25,6 +25,8 @@ check_runqueues_f(char *file, int line)
        minix_panic("check_runqueues called with interrupts enabled", NO_NUM);
   }
 
+  FIXME("check_runqueues being done");
+
 #define MYPANIC(msg) {         \
        kprintf("check_runqueues:%s:%d: %s\n", file, line, msg); \
        minix_panic("check_runqueues failed", NO_NUM);  \
@@ -128,3 +130,17 @@ rtsflagstr(int flags)
        return str;
 }
 
+PUBLIC char *
+miscflagstr(int flags)
+{
+       static char str[100];
+       str[0] = '\0';
+
+       FLAG(MF_REPLY_PEND);
+       FLAG(MF_ASYNMSG);
+       FLAG(MF_FULLVM);
+       FLAG(MF_DELIVERMSG);
+
+       return str;
+}
+
index df6790cb9b3b224b5ee1688c7165a780b24ed496..67adacb2609a56527dbada4781fe5968f64f5ec9 100644 (file)
@@ -25,8 +25,8 @@
 #define DEBUG_TIME_LOCKS               1
 
 /* Runtime sanity checking. */
-#define DEBUG_VMASSERT                 1
-#define DEBUG_SCHED_CHECK              1
+#define DEBUG_VMASSERT                 0
+#define DEBUG_SCHED_CHECK              0
 
 #define NOREC_ENTER(varname) \
        static int varname = 0; \
@@ -48,9 +48,9 @@
        return v;       \
        } while(0)
 
-
 #if DEBUG_VMASSERT
 #define vmassert(t) { \
+       FIXME("vmassert on"); \
        if(!(t)) { minix_panic("vm: assert " #t " failed\n", __LINE__); } }
 #else
 #define vmassert(t) { }
index b7c1a19eb84346aa2f38bbad97a719f5fc316448..db67062195971b6e5d73859b6cf38ab940501ef6 100755 (executable)
@@ -36,7 +36,6 @@ EXTERN struct proc *bill_ptr; /* process to bill for clock ticks */
 EXTERN struct proc *vmrestart;  /* first process on vmrestart queue */
 EXTERN struct proc *vmrequest;  /* first process on vmrequest queue */
 EXTERN struct proc *pagefaults; /* first process on pagefault queue */
-EXTERN struct proc *softnotify;        /* first process on softnotify queue */
 EXTERN char k_reenter;         /* kernel reentry count (entry count less 1) */
 EXTERN unsigned lost_ticks;    /* clock ticks counted outside clock task */
 
index 18b510d4814e5f817fc8007d9574275cb8374fb9..8ff9e1f70723c6a1e078da68bd77e2a258496adc 100755 (executable)
@@ -195,6 +195,9 @@ PUBLIC void main()
 #endif
 #if DEBUG_VMASSERT
   FIXME("DEBUG_VMASSERT enabled");
+#endif
+#if DEBUG_PROC_CHECK
+  FIXME("PROC check enabled");
 #endif
   restart();
 }
index 2fee24eaccfa618c6649636275cf53a02acfcde8..8009b5be649facced88806b4e6d4cc9112ce9389 100755 (executable)
@@ -67,8 +67,7 @@ FORWARD _PROTOTYPE( int try_one, (struct proc *src_ptr, struct proc *dst_ptr));
 FORWARD _PROTOTYPE( void sched, (struct proc *rp, int *queue, int *front));
 FORWARD _PROTOTYPE( void pick_proc, (void));
 
-#define BuildMess(m_ptr, src, dst_ptr) \
-       (m_ptr)->m_source = proc_addr(src)->p_endpoint;         \
+#define BuildNotifyMessage(m_ptr, src, dst_ptr) \
        (m_ptr)->m_type = NOTIFY_FROM(src);                             \
        (m_ptr)->NOTIFY_TIMESTAMP = get_uptime();                       \
        switch (src) {                                                  \
@@ -82,43 +81,41 @@ FORWARD _PROTOTYPE( void pick_proc, (void));
                break;                                                  \
        }
 
-#define RETRYCOPY(sp, dp, sm, dm)      {\
-               if(r != EFAULT_DST) {                   \
-                       kprintf("error %d\n", r);       \
-                 minix_panic("CopyMess: copy error", __LINE__); \
-                } \
-               minix_panic("parameters unknown", NO_NUM);      \
-               (dp)->p_vmrequest.saved.msgcopy.dst = (dp);     \
-               (dp)->p_vmrequest.saved.msgcopy.dst_v = (vir_bytes) dm; \
-               (dp)->p_vmrequest.saved.msgcopy.msgbuf.m_source = e; \
-               (dp)->p_vmrequest.type = VMSTYPE_MSGCOPY; \
-               if(data_copy((sp)->p_endpoint,  \
-                       (vir_bytes) (sm), SYSTEM,       \
-                       (vir_bytes) &(dp)->p_vmrequest.saved.msgcopy.msgbuf, \
-                       sizeof(message)) != OK) {               \
-                               minix_panic("CopyMess: data_copy failed", __LINE__);\
-                       }                               \
+#define Deliver(rp)    do {    \
+               vmassert(rp->p_misc_flags & MF_DELIVERMSG);     \
+               vmassert(rp->p_delivermsg_lin); \
+               if(arch_switch_copymsg(rp, &rp->p_delivermsg,   \
+                       rp->p_delivermsg_lin)) {        \
+                       minix_panic("MF_DELIVERMSG copy failed", NO_NUM); \
+               }       \
+               rp->p_delivermsg.m_source = NONE;       \
+               rp->p_delivermsg_lin = 0;       \
+               rp->p_misc_flags &= ~MF_DELIVERMSG;     \
+       } while(0)
+
+/*===========================================================================*
+ *                             QueueMess                                    * 
+ *===========================================================================*/
+PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst)
+{
+       /* Queue a message from the src process (in memory) to the dst
+        * process (using dst process table entry). Do actual copy here;
+        * it's an error if the copy fails.
+        */
+       vmassert(!(dst->p_misc_flags & MF_DELIVERMSG)); 
+       vmassert(dst->p_delivermsg_lin);
+       if(phys_copy(msg_lin, vir2phys(&dst->p_delivermsg),
+               sizeof(message))) {
+               return EFAULT;
+       }
+       dst->p_delivermsg.m_source = ep;
+       dst->p_misc_flags |= MF_DELIVERMSG;
+       if(iskernelp(dst) || ptproc == dst) {
+               Deliver(dst);
        }
 
-#define CopyMess(s,sp,sm,dp,dm) do {                   \
-       endpoint_t e = proc_addr(s)->p_endpoint;        \
-       struct vir_addr src, dst;                       \
-       int r;                                          \
-       src.proc_nr_e = (sp)->p_endpoint;               \
-       dst.proc_nr_e = (dp)->p_endpoint;               \
-       src.segment = dst.segment = D;                  \
-       src.offset = (vir_bytes) (sm);                  \
-       dst.offset = (vir_bytes) (dm);                  \
-       if((r=virtual_copy(&src, &dst, sizeof(message))) != OK) { \
-               RETRYCOPY(sp, dp, sm, dm)                               \
-       } else {                                                \
-               src.proc_nr_e = SYSTEM;                         \
-               src.offset = (vir_bytes) &e;                    \
-               if((r=virtual_copy(&src, &dst, sizeof(e))) != OK) {     \
-                       RETRYCOPY(sp, dp, sm, dm)                               \
-               }                                       \
-       }       \
-} while(0)
+       return OK;
+}
 
 /*===========================================================================*
  *                             sys_call                                     * 
@@ -139,6 +136,15 @@ long bit_map;                      /* notification event set or flags */
   int result;                                  /* the system call's result */
   int src_dst_p;                               /* Process slot number */
   size_t msg_size;
+  phys_bytes linaddr = 0;
+
+#if DEBUG_SCHED_CHECK
+  if(caller_ptr->p_misc_flags & MF_DELIVERMSG) {
+       kprintf("sys_call: MF_DELIVERMSG on for %s / %d\n",
+               caller_ptr->p_name, caller_ptr->p_endpoint);
+       minix_panic("MF_DELIVERMSG on", NO_NUM);
+  }
+#endif
 
   if (caller_ptr->p_endpoint == ipc_stats_target)
        ipc_stats.total= add64u(ipc_stats.total, 1);
@@ -157,7 +163,7 @@ long bit_map;                       /* notification event set or flags */
   }
 #endif
 
-#if 1
+#if DEBUG_SCHED_CHECK
   if (RTS_ISSET(caller_ptr, SLOT_FREE))
   {
        kprintf("called by the dead?!?\n");
@@ -239,7 +245,7 @@ long bit_map;                       /* notification event set or flags */
 #if DEBUG_ENABLE_IPC_WARNINGS
                        kprintf(
                        "sys_call: ipc mask denied trap %d from %d to %d\n",
-                               call_nr, proc_nr(caller_ptr), src_dst_p);
+                               call_nr, caller_ptr->p_endpoint, src_dst_e);
 #endif
                        if (caller_ptr->p_endpoint == ipc_stats_target)
                                ipc_stats.dst_not_allowed++;
@@ -301,61 +307,6 @@ long bit_map;                      /* notification event set or flags */
        msg_size = sizeof(*m_ptr);
   }
 
-  /* If the call involves a message buffer, i.e., for SEND, SENDREC, 
-   * or RECEIVE, check the message pointer. This check allows a message to be 
-   * anywhere in data or stack or gap. It will have to be made more elaborate 
-   * for machines which don't have the gap mapped. 
-   *
-   * We use msg_size decided above.
-   */
-  if (call_nr == SEND || call_nr == SENDREC ||
-       call_nr == RECEIVE || call_nr == SENDA || call_nr == SENDNB) {
-       int r;
-       phys_bytes lin;
-
-       /* Map to linear address. */
-       if(msg_size > 0 && 
-               (lin = umap_local(caller_ptr, D, (vir_bytes) m_ptr, msg_size)) == 0) {
-               kprintf("umap_local failed for %s / %d on 0x%lx size %d\n",
-                       caller_ptr->p_name, caller_ptr->p_endpoint,
-                       m_ptr, msg_size);
-               return EFAULT;
-       }
-
-       /* Check if message pages in calling process are mapped.
-        * We don't have to check the recipient if this is a send,
-        * because this code will do that before its receive() starts.
-        *
-        * It is important the range is verified as _writable_, because
-        * the kernel will want to write to the SENDA buffer in the future,
-        * and those pages may not be shared between processes.
-        */
-
-       if(vm_running && msg_size > 0 &&
-        (r=vm_checkrange(caller_ptr, caller_ptr, lin, msg_size, 1, 0)) != OK) {
-               if(r != VMSUSPEND) {
-                       kprintf("SYSTEM:sys_call:vm_checkrange: err %d\n", r);
-                       return r;
-               }
-               
-               /* We can't go ahead with this call. Caller is suspended
-                * and we have to save the state in its process struct.
-                */
-               caller_ptr->p_vmrequest.saved.sys_call.call_nr = call_nr;
-               caller_ptr->p_vmrequest.saved.sys_call.m_ptr = m_ptr;
-               caller_ptr->p_vmrequest.saved.sys_call.src_dst_e = src_dst_e;
-               caller_ptr->p_vmrequest.saved.sys_call.bit_map = bit_map;
-               caller_ptr->p_vmrequest.type = VMSTYPE_SYS_CALL;
-
-               kprintf("SYSTEM: %s:%d: suspending call 0x%lx on ipc buffer 0x%lx length 0x%lx\n",
-                       caller_ptr->p_name, caller_ptr->p_endpoint, call_nr, m_ptr, msg_size);
-
-               /* vm_checkrange() will have suspended caller with VMREQUEST. */
-               return OK;
-       }
-
-  } 
-
   /* Check for a possible deadlock for blocking SEND(REC) and RECEIVE. */
   if (call_nr == SEND || call_nr == SENDREC || call_nr == RECEIVE) {
       if (group_size = deadlock(call_nr, caller_ptr, src_dst_p)) {
@@ -380,7 +331,7 @@ long bit_map;                       /* notification event set or flags */
   switch(call_nr) {
   case SENDREC:
        /* A flag is set so that notifications cannot interrupt SENDREC. */
-       caller_ptr->p_misc_flags |= REPLY_PENDING;
+       caller_ptr->p_misc_flags |= MF_REPLY_PEND;
        /* fall through */
   case SEND:                   
        result = mini_send(caller_ptr, src_dst_e, m_ptr, 0);
@@ -389,7 +340,7 @@ long bit_map;                       /* notification event set or flags */
        /* fall through for SENDREC */
   case RECEIVE:                        
        if (call_nr == RECEIVE)
-               caller_ptr->p_misc_flags &= ~REPLY_PENDING;
+               caller_ptr->p_misc_flags &= ~MF_REPLY_PEND;
        result = mini_receive(caller_ptr, src_dst_e, m_ptr, 0);
        break;
   case NOTIFY:
@@ -478,22 +429,6 @@ int src_dst;                                       /* src or dst process */
   return(0);                                   /* not a deadlock */
 }
 
-/*===========================================================================*
- *                             sys_call_restart                             * 
- *===========================================================================*/
-PUBLIC void sys_call_restart(caller)
-struct proc *caller;
-{
-       int r;
-       kprintf("restarting sys_call code 0x%lx, "
-               "m_ptr 0x%lx, srcdst %d, bitmap 0x%lx, but not really\n",
-               caller->p_vmrequest.saved.sys_call.call_nr,
-               caller->p_vmrequest.saved.sys_call.m_ptr,
-               caller->p_vmrequest.saved.sys_call.src_dst_e,
-               caller->p_vmrequest.saved.sys_call.bit_map);
-       caller->p_reg.retreg = r;
-}
-
 /*===========================================================================*
  *                             mini_send                                    * 
  *===========================================================================*/
@@ -510,7 +445,13 @@ int flags;
   register struct proc *dst_ptr;
   register struct proc **xpp;
   int dst_p;
+  phys_bytes linaddr;
+  int r;
 
+  if(!(linaddr = umap_local(caller_ptr, D, (vir_bytes) m_ptr,
+       sizeof(message)))) {
+       return EFAULT;
+  }
   dst_p = _ENDPOINT_P(dst_e);
   dst_ptr = proc_addr(dst_p);
 
@@ -526,8 +467,9 @@ int flags;
    */
   if (WILLRECEIVE(dst_ptr, caller_ptr->p_endpoint)) {
        /* Destination is indeed waiting for this message. */
-       CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, dst_ptr,
-                dst_ptr->p_messbuf);
+       vmassert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));     
+       if((r=QueueMess(caller_ptr->p_endpoint, linaddr, dst_ptr)) != OK)
+               return r;
        RTS_UNSET(dst_ptr, RECEIVING);
   } else {
        if(flags & NON_BLOCKING) {
@@ -537,7 +479,9 @@ int flags;
        }
 
        /* Destination is not waiting.  Block and dequeue caller. */
-       caller_ptr->p_messbuf = m_ptr;
+       if(phys_copy(linaddr, vir2phys(&caller_ptr->p_sendmsg), sizeof(message))) {
+               return EFAULT;
+       }
        RTS_SET(caller_ptr, SENDING);
        caller_ptr->p_sendto_e = dst_e;
 
@@ -570,6 +514,17 @@ int flags;
   sys_map_t *map;
   bitchunk_t *chunk;
   int i, r, src_id, src_proc_nr, src_p;
+  phys_bytes linaddr;
+
+  vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
+
+  if(!(linaddr = umap_local(caller_ptr, D, (vir_bytes) m_ptr,
+       sizeof(message)))) {
+       return EFAULT;
+  }
+
+  /* This is where we want our message. */
+  caller_ptr->p_delivermsg_lin = linaddr;
 
   if(src_e == ANY) src_p = ANY;
   else
@@ -591,7 +546,7 @@ int flags;
   if (!RTS_ISSET(caller_ptr, SENDING)) {
 
     /* Check if there are pending notifications, except for SENDREC. */
-    if (! (caller_ptr->p_misc_flags & REPLY_PENDING)) {
+    if (! (caller_ptr->p_misc_flags & MF_REPLY_PEND)) {
 
         map = &priv(caller_ptr)->s_notify_pending;
         for (chunk=&map->chunk[0]; chunk<&map->chunk[NR_SYS_CHUNKS]; chunk++) {
@@ -611,8 +566,11 @@ int flags;
             *chunk &= ~(1 << i);                       /* no longer pending */
 
             /* Found a suitable source, deliver the notification message. */
-           BuildMess(&m, src_proc_nr, caller_ptr);     /* assemble message */
-            CopyMess(src_proc_nr, proc_addr(HARDWARE), &m, caller_ptr, m_ptr);
+           BuildNotifyMessage(&m, src_proc_nr, caller_ptr);    /* assemble message */
+           vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));      
+           if((r=QueueMess(src_proc_nr, vir2phys(&m), caller_ptr)) != OK)  {
+               minix_panic("mini_receive: local QueueMess failed", NO_NUM);
+           }
             return(OK);                                        /* report success */
         }
     }
@@ -621,7 +579,7 @@ int flags;
     xpp = &caller_ptr->p_caller_q;
     while (*xpp != NIL_PROC) {
         if (src_e == ANY || src_p == proc_nr(*xpp)) {
-#if 1
+#if DEBUG_SCHED_CHECK
            if (RTS_ISSET(*xpp, SLOT_FREE) || RTS_ISSET(*xpp, NO_ENDPOINT))
            {
                kprintf("%d: receive from %d; found dead %d (%s)?\n",
@@ -634,7 +592,10 @@ int flags;
 #endif
 
            /* Found acceptable message. Copy it and update status. */
-           CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr);
+           FIXME("message copied twice here");
+           vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
+           QueueMess((*xpp)->p_endpoint,
+               vir2phys(&(*xpp)->p_sendmsg), caller_ptr);
            RTS_UNSET(*xpp, SENDING);
             *xpp = (*xpp)->p_q_link;           /* remove from queue */
             return(OK);                                /* report success */
@@ -653,7 +614,6 @@ int flags;
        }
        else
        {
-               caller_ptr->p_messbuf = m_ptr;
                r= try_async(caller_ptr);
        }
        if (r == OK)
@@ -666,7 +626,6 @@ int flags;
    */
   if ( ! (flags & NON_BLOCKING)) {
       caller_ptr->p_getfrom_e = src_e;         
-      caller_ptr->p_messbuf = m_ptr;
       RTS_SET(caller_ptr, RECEIVING);
       return(OK);
   } else {
@@ -686,19 +645,22 @@ int dst;                          /* which process to notify */
   register struct proc *dst_ptr = proc_addr(dst);
   int src_id;                          /* source id for late delivery */
   message m;                           /* the notification message */
+  int r;
 
   /* Check to see if target is blocked waiting for this message. A process 
    * can be both sending and receiving during a SENDREC system call.
    */
     if (WILLRECEIVE(dst_ptr, caller_ptr->p_endpoint) &&
-      ! (dst_ptr->p_misc_flags & REPLY_PENDING)) {
+      ! (dst_ptr->p_misc_flags & MF_REPLY_PEND)) {
       /* Destination is indeed waiting for a message. Assemble a notification 
        * message and deliver it. Copy from pseudo-source HARDWARE, since the
        * message is in the kernel's address space.
        */ 
-      BuildMess(&m, proc_nr(caller_ptr), dst_ptr);
-      CopyMess(proc_nr(caller_ptr), proc_addr(HARDWARE), &m, 
-          dst_ptr, dst_ptr->p_messbuf);
+      BuildNotifyMessage(&m, proc_nr(caller_ptr), dst_ptr);
+      vmassert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
+      if((r=QueueMess(caller_ptr->p_endpoint, vir2phys(&m), dst_ptr)) != OK) {
+       minix_panic("mini_notify: local QueueMess failed", NO_NUM);
+      }
       RTS_UNSET(dst_ptr, RECEIVING);
       return(OK);
   } 
@@ -743,13 +705,19 @@ struct proc *caller_ptr;
 asynmsg_t *table;
 size_t size;
 {
-       int i, dst_p, done, do_notify;
+       int i, dst_p, done, do_notify, r;
        unsigned flags;
        struct proc *dst_ptr;
        struct priv *privp;
        message *m_ptr;
        asynmsg_t tabent;
        vir_bytes table_v = (vir_bytes) table;
+       vir_bytes linaddr;
+
+       if(!(linaddr = umap_local(caller_ptr, D, (vir_bytes) table,
+               size * sizeof(*table)))) {
+               return EFAULT;
+       }
 
        privp= priv(caller_ptr);
        if (!(privp->s_flags & SYS_PROC))
@@ -827,11 +795,6 @@ size_t size;
                        continue;
                }
 
-#if 0
-               kprintf("mini_senda: entry[%d]: flags 0x%x dst %d/%d\n",
-                       i, tabent.flags, tabent.dst, dst_p);
-#endif
-
                dst_ptr = proc_addr(dst_p);
 
                /* NO_ENDPOINT should be removed */
@@ -860,12 +823,13 @@ size_t size;
                        m_ptr= &table[i].msg;   /* Note: pointer in the
                                                 * caller's address space.
                                                 */
-                       CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, dst_ptr,
-                               dst_ptr->p_messbuf);
+                       /* Copy message from sender. */
+                       tabent.result= QueueMess(caller_ptr->p_endpoint,
+                               linaddr + (vir_bytes) &table[i].msg -
+                                       (vir_bytes) table, dst_ptr);
+                       if(tabent.result == OK)
+                               RTS_UNSET(dst_ptr, RECEIVING);
 
-                       RTS_UNSET(dst_ptr, RECEIVING);
-
-                       tabent.result= OK;
                        A_INSERT(i, result);
                        tabent.flags= flags | AMF_DONE;
                        A_INSERT(i, flags);
@@ -888,13 +852,6 @@ size_t size;
        {
                privp->s_asyntab= (vir_bytes)table;
                privp->s_asynsize= size;
-#if 0
-               if(caller_ptr->p_endpoint > INIT_PROC_NR) {
-                       kprintf("kernel: %s (%d) asynsend table at 0x%lx, %d\n", 
-                               caller_ptr->p_name, caller_ptr->p_endpoint,
-                               table, size);
-               }
-#endif
        }
        return OK;
 }
@@ -909,7 +866,7 @@ struct proc *caller_ptr;
        int r;
        struct priv *privp;
        struct proc *src_ptr;
-
+       
        /* Try all privilege structures */
        for (privp = BEG_PRIV_ADDR; privp < END_PRIV_ADDR; ++privp) 
        {
@@ -917,11 +874,8 @@ struct proc *caller_ptr;
                        continue;
                if (privp->s_asynsize == 0)
                        continue;
-#if 0
-               kprintf("try_async: found asyntable for proc %d\n",
-                       privp->s_proc_nr);
-#endif
                src_ptr= proc_addr(privp->s_proc_nr);
+               vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
                r= try_one(src_ptr, caller_ptr);
                if (r == OK)
                        return r;
@@ -951,6 +905,7 @@ struct proc *dst_ptr;
        asynmsg_t tabent;
        vir_bytes table_v;
        struct proc *caller_ptr;
+       int r;
 
        privp= priv(src_ptr);
        size= privp->s_asynsize;
@@ -1009,10 +964,11 @@ struct proc *dst_ptr;
                m_ptr= &table_ptr[i].msg;       /* Note: pointer in the
                                                 * caller's address space.
                                                 */
-               CopyMess(src_ptr->p_nr, src_ptr, m_ptr, dst_ptr,
-                       dst_ptr->p_messbuf);
+               A_RETRIEVE(i, msg);
+               r = QueueMess(src_ptr->p_endpoint, vir2phys(&tabent.msg),
+                       dst_ptr);
 
-               tabent.result= OK;
+               tabent.result= r;
                A_INSERT(i, result);
                tabent.flags= flags | AMF_DONE;
                A_INSERT(i, flags);
@@ -1060,43 +1016,6 @@ int dst_e;                       /* (endpoint) who is to be notified */
   return(result);
 }
 
-/*===========================================================================*
- *                             soft_notify                                  *
- *===========================================================================*/
-PUBLIC int soft_notify(dst_e)
-int dst_e;                     /* (endpoint) who is to be notified */
-{
-       int dst, u = 0;
-       struct proc *dstp, *sys = proc_addr(SYSTEM);
-
-/* Delayed interface to notify() from SYSTEM that is safe/easy to call
- * from more places than notify().
- */
-       if(!intr_disabled()) { lock; u = 1; }
-
-       {
-               if(!isokendpt(dst_e, &dst))
-                       minix_panic("soft_notify to dead ep", dst_e);
-
-               dstp = proc_addr(dst);
-
-               if(!dstp->p_softnotified) {
-                       dstp->next_soft_notify = softnotify;
-                       softnotify = dstp;
-                       dstp->p_softnotified = 1;
-       
-                       if (RTS_ISSET(sys, RECEIVING)) {
-                               sys->p_messbuf->m_source = SYSTEM;
-                               RTS_UNSET(sys, RECEIVING);
-                       }
-               }
-       }
-
-       if(u) { unlock; }
-
-       return OK;
-}
-
 /*===========================================================================*
  *                             enqueue                                      * 
  *===========================================================================*/
@@ -1251,6 +1170,13 @@ PRIVATE void pick_proc()
    */
   for (q=0; q < NR_SCHED_QUEUES; q++) {        
       if ( (rp = rdy_head[q]) != NIL_PROC) {
+         if(rp->p_misc_flags & MF_DELIVERMSG) {
+               /* Want to schedule process, but have to copy a message
+                * first.
+                */
+               FIXME("MF_DELIVERMSG no callback");
+               Deliver(rp);
+         }
           next_ptr = rp;                       /* run process 'rp' next */
 #if 0
        if(!iskernelp(rp))
@@ -1296,9 +1222,6 @@ timer_t *tp;                                      /* watchdog timer pointer */
          unlock;
       }
   }
-#if DEBUG
-  kprintf("ticks_added: %d\n", ticks_added);
-#endif
 
   /* Now schedule a new watchdog timer to balance the queues again.  The 
    * period depends on the total amount of quantum ticks added.
@@ -1395,24 +1318,18 @@ int *p, fatalflag;
        *p = _ENDPOINT_P(e);
        if(!isokprocn(*p)) {
 #if DEBUG_ENABLE_IPC_WARNINGS
-#if 0
                kprintf("kernel:%s:%d: bad endpoint %d: proc %d out of range\n",
                file, line, e, *p);
-#endif
 #endif
        } else if(isemptyn(*p)) {
 #if DEBUG_ENABLE_IPC_WARNINGS
-#if 0
        kprintf("kernel:%s:%d: bad endpoint %d: proc %d empty\n", file, line, e, *p);
-#endif
 #endif
        } else if(proc_addr(*p)->p_endpoint != e) {
 #if DEBUG_ENABLE_IPC_WARNINGS
-#if 0
                kprintf("kernel:%s:%d: bad endpoint %d: proc %d has ept %d (generation %d vs. %d)\n", file, line,
                e, *p, proc_addr(*p)->p_endpoint,
                _ENDPOINT_G(e), _ENDPOINT_G(proc_addr(*p)->p_endpoint));
-#endif
 #endif
        } else ok = 1;
        if(!ok && fatalflag) {
index 52a4612a8e4c6b8320d8d95a26b8b609bd18b9ae..f8956eb833a2ad17856e7ab99d4dc660e0395e50 100755 (executable)
@@ -36,7 +36,6 @@ struct proc {
   struct proc *p_nextready;    /* pointer to next ready process */
   struct proc *p_caller_q;     /* head of list of procs wishing to send */
   struct proc *p_q_link;       /* link to next proc wishing to send */
-  message *p_messbuf;          /* pointer to passed message buffer */
   int p_getfrom_e;             /* from whom does process want to receive? */
   int p_sendto_e;              /* to whom does process want to send? */
 
@@ -46,6 +45,10 @@ struct proc {
 
   endpoint_t p_endpoint;       /* endpoint number, generation-aware */
 
+  message p_sendmsg;           /* Message from this process if SENDING */
+  message p_delivermsg;                /* Message for this process if MF_DELIVERMSG */
+  vir_bytes p_delivermsg_lin;  /* Linear addr this proc wants message at */
+
   /* If handler functions detect a process wants to do something with
    * memory that isn't present, VM has to fix it. Until it has asked
    * what needs to be done and fixed it, save necessary state here.
@@ -58,27 +61,10 @@ struct proc {
        struct proc     *nextrequestor; /* next in vmrequest chain */
 #define VMSTYPE_SYS_NONE       0
 #define VMSTYPE_SYS_MESSAGE    1
-#define VMSTYPE_SYS_CALL       2
-#define VMSTYPE_MSGCOPY                3
        int             type;           /* suspended operation */
        union {
                /* VMSTYPE_SYS_MESSAGE */
                message         reqmsg; /* suspended request message */
-
-               /* VMSTYPE_SYS_CALL */
-               struct {
-                       int call_nr;
-                       message *m_ptr;
-                       int src_dst_e;
-                       long bit_map;
-               } sys_call;
-
-               /* VMSTYPE_MSGCOPY */
-               struct {
-                       struct proc     *dst;
-                       vir_bytes       dst_v;
-                       message         msgbuf;
-               } msgcopy;
        } saved;
 
        /* Parameters of request to VM */
@@ -107,7 +93,6 @@ struct proc {
 #define PMAGIC 0xC0FFEE1
   int p_magic; /* check validity of proc pointers */
 #endif
-  int verbose;
 };
 
 /* Bits for the runtime flags. A process is runnable iff p_rts_flags == 0. */
@@ -169,10 +154,10 @@ struct proc {
        } while(0)
 
 /* Misc flags */
-#define REPLY_PENDING  0x01    /* reply to IPC_REQUEST is pending */
-#define MF_VM          0x08    /* process uses VM */
+#define MF_REPLY_PEND  0x01    /* reply to IPC_REQUEST is pending */
 #define MF_ASYNMSG     0x10    /* Asynchrous message pending */
 #define MF_FULLVM      0x20
+#define MF_DELIVERMSG  0x40    /* Copy message for him before running */
 
 /* Scheduling priorities for p_priority. Values must start at zero (highest
  * priority) and increment.  Priorities of the processes in the boot image 
index 130900ebba990edb0a839770b8a8addd44294d35..44bbbfefeaacf1e346c2897a0ee8522b422b26e6 100755 (executable)
@@ -33,7 +33,6 @@ _PROTOTYPE( int sys_call, (int call_nr, int src_dst,
                                        message *m_ptr, long bit_map)   );
 _PROTOTYPE( void sys_call_restart, (struct proc *caller)               );
 _PROTOTYPE( int lock_notify, (int src, int dst)                                );
-_PROTOTYPE( int soft_notify, (int dst)                         );
 _PROTOTYPE( int lock_send, (int dst, message *m_ptr)                   );
 _PROTOTYPE( void lock_enqueue, (struct proc *rp)                       );
 _PROTOTYPE( void lock_dequeue, (struct proc *rp)                       );
@@ -88,6 +87,7 @@ _PROTOTYPE( void cons_seth, (int pos, int n)                          );
 _PROTOTYPE( void check_runqueues_f, (char *file, int line) );
 #endif
 _PROTOTYPE( char *rtsflagstr, (int flags) );
+_PROTOTYPE( char *miscflagstr, (int flags) );
 
 /* system/do_safecopy.c */
 _PROTOTYPE( int verify_grant, (endpoint_t, endpoint_t, cp_grant_id_t, vir_bytes,
@@ -103,8 +103,9 @@ _PROTOTYPE( void stop_profile_clock, (void)                         );
 #endif
 
 /* functions defined in architecture-dependent files. */
-_PROTOTYPE( void phys_copy, (phys_bytes source, phys_bytes dest,
+_PROTOTYPE( phys_bytes phys_copy, (phys_bytes source, phys_bytes dest,
                 phys_bytes count)                                       );
+_PROTOTYPE( void phys_copy_fault, (void));
 #define virtual_copy(src, dst, bytes) virtual_copy_f(src, dst, bytes, 0)
 #define virtual_copy_vmcheck(src, dst, bytes) virtual_copy_f(src, dst, bytes, 1)
 _PROTOTYPE( int virtual_copy_f, (struct vir_addr *src, struct vir_addr *dst, 
@@ -162,5 +163,7 @@ _PROTOTYPE( int vm_checkrange, (struct proc *caller, struct proc *target,
 _PROTOTYPE( void proc_stacktrace, (struct proc *proc)           );
 _PROTOTYPE( int vm_lookup, (struct proc *proc, vir_bytes virtual, vir_bytes *result, u32_t *ptent));
 _PROTOTYPE( int vm_suspend, (struct proc *caller, struct proc *target));
+_PROTOTYPE( phys_bytes arch_switch_copymsg, (struct proc *rp, message *m,
+       phys_bytes lin));
 
 #endif /* PROTO_H */
index 148459ecc64cb55c395a7ce589c1f312e8022a5b..8e27606de71bb85299424acd25713468f266b56f 100755 (executable)
@@ -56,9 +56,10 @@ char *callnames[NR_SYS_CALLS];
     call_vec[(call_nr-KERNEL_CALL)] = (handler)  
 
 FORWARD _PROTOTYPE( void initialize, (void));
-FORWARD _PROTOTYPE( void softnotify_check, (void));
 FORWARD _PROTOTYPE( struct proc *vmrestart_check, (message *));
 
+u32_t cr3_test, cr3_reload, createpde, linlincopies, physzero;
+
 /*===========================================================================*
  *                             sys_task                                     *
  *===========================================================================*/
@@ -75,27 +76,35 @@ PUBLIC void sys_task()
   /* Initialize the system task. */
   initialize();
 
+
   while (TRUE) {
       struct proc *restarting;
 
       restarting = vmrestart_check(&m);
-      softnotify_check();
-       if(softnotify)
-               minix_panic("softnotify non-NULL before receive (1)", NO_NUM);
 
       if(!restarting) {
         int r;
        /* Get work. Block and wait until a request message arrives. */
-       if(softnotify)
-               minix_panic("softnotify non-NULL before receive (2)", NO_NUM);
        if((r=receive(ANY, &m)) != OK)
                minix_panic("receive() failed", r);
-       if(m.m_source == SYSTEM)
-               continue;
-       if(softnotify)
-               minix_panic("softnotify non-NULL after receive", NO_NUM);
       }
 
+#if 1
+      {
+       static int prevu;
+       int u;
+       u = get_uptime();
+       if(u/system_hz != prevu/system_hz) {
+               printf("cr3 tests: %5lu reloads: %5lu createpde: %5lu linlincopies: %5lu physzero: %5lu\n",
+                       cr3_test, cr3_reload, createpde, linlincopies, physzero);
+               cr3_test = 1;
+               cr3_reload = 0;
+               createpde = linlincopies = physzero = 0;
+       }
+       prevu = u;
+      }
+#endif
+
       sys_call_code = (unsigned) m.m_type;
       call_nr = sys_call_code - KERNEL_CALL;   
       who_e = m.m_source;
@@ -310,7 +319,7 @@ PUBLIC void send_sig(int proc_nr, int sig_nr)
 
   rp = proc_addr(proc_nr);
   sigaddset(&priv(rp)->s_sig_pending, sig_nr);
-  soft_notify(rp->p_endpoint); 
+  lock_notify(SYSTEM, rp->p_endpoint); 
 }
 
 /*===========================================================================*
@@ -429,7 +438,6 @@ register struct proc *rc;           /* slot of process to clean up */
 
 #if 0
   if(rc->p_endpoint == PM_PROC_NR || rc->p_endpoint == VFS_PROC_NR)
-#endif
   {
        /* This test is great for debugging system processes dying,
         * but as this happens normally on reboot, not good permanent code.
@@ -438,10 +446,9 @@ register struct proc *rc;          /* slot of process to clean up */
        proc_stacktrace(rc);
        kprintf("kernel trace: ");
        util_stacktrace();
-#if 0
        minix_panic("clear_proc: system process died", rc->p_endpoint);
-#endif
   }
+#endif
 
   /* Make sure that the exiting process is no longer scheduled. */
   RTS_LOCK_SET(rc, NO_ENDPOINT);
@@ -508,13 +515,6 @@ register struct proc *rc;          /* slot of process to clean up */
 #endif
       } 
   }
-
-  /* No pending soft notifies. */
-  for(np = softnotify; np; np = np->next_soft_notify) {
-    if(np == rc) {
-       minix_panic("dying proc was on next_soft_notify", np->p_endpoint);
-    }
-  }
 }
 
 /*===========================================================================*
@@ -548,28 +548,6 @@ int access;                     /* does grantee want to CPF_READ or _WRITE? */
         return umap_virtual(proc_addr(proc_nr), D, v_offset, bytes);
 } 
 
-/*===========================================================================*
- *                              softnotify_check                            *
- *===========================================================================*/
-PRIVATE void softnotify_check(void)
-{  
-       struct proc *np, *nextnp;
-
-       if(!softnotify) 
-               return;
-
-       for(np = softnotify; np; np = nextnp) {
-               if(!np->p_softnotified)
-                       minix_panic("softnotify but no p_softnotified", NO_NUM);
-               lock_notify(SYSTEM, np->p_endpoint);
-               nextnp = np->next_soft_notify;
-               np->next_soft_notify = NULL;
-               np->p_softnotified = 0;
-       }
-
-       softnotify = NULL;
-}
-
 /*===========================================================================*
  *                              vmrestart_check                            *
  *===========================================================================*/
@@ -618,29 +596,6 @@ PRIVATE struct proc *vmrestart_check(message *m)
                                }
                        }
                        return restarting;
-               case VMSTYPE_SYS_CALL:
-                       kprintf("SYSTEM: restart sys_call\n");
-                       /* Restarting a kernel trap. */
-                       sys_call_restart(restarting);
-
-                       /* Handled; restart system loop. */
-                       return NULL;
-               case VMSTYPE_MSGCOPY:
-                       /* Do delayed message copy. */
-                       printf("copying message into %d..\n", 
-                               restarting->p_vmrequest.saved.msgcopy.dst->p_endpoint);
-                       if((r=data_copy(SYSTEM,
-                               (vir_bytes) &restarting->p_vmrequest.saved.msgcopy.msgbuf,
-                               restarting->p_vmrequest.saved.msgcopy.dst->p_endpoint,
-                               (vir_bytes) restarting->p_vmrequest.saved.msgcopy.dst_v,
-                               sizeof(message))) != OK) {
-                               minix_panic("SYSTEM: delayed msgcopy failed", r);
-                       }
-                       printf("OK!\n");
-                       RTS_LOCK_UNSET(restarting, VMREQUEST);
-
-                       /* Handled; restart system loop. */
-                       return NULL;
                default:
                        minix_panic("strange restart type", type);
        }
index 4161bb0882017dd3c30ef065a88ee5f9b090410f..0bffb7f648078aa074da87c29db76a71c17966e3 100644 (file)
@@ -31,6 +31,15 @@ register message *m_ptr;     /* pointer to request message */
 
   rp = proc_addr(proc);
 
+  if(rp->p_misc_flags & MF_DELIVERMSG) {
+       printf("%s / %d has MF_DELIVERMSG on during exec - clearing.\n",
+               rp->p_name, rp->p_endpoint);
+#if 1
+       rp->p_misc_flags &= ~MF_DELIVERMSG;
+       rp->p_delivermsg_lin = 0;
+#endif
+  }
+
   /* Save command name for debugging, ps(1) output, etc. */
   if(data_copy(who_e, (vir_bytes) m_ptr->PR_NAME_PTR,
        SYSTEM, (vir_bytes) rp->p_name, (phys_bytes) P_NAME_LEN - 1) != OK)
@@ -42,8 +51,6 @@ register message *m_ptr;      /* pointer to request message */
   /* No reply to EXEC call */
   RTS_LOCK_UNSET(rp, RECEIVING);
 
-  printf("kernel: exec %d now %s\n", rp->p_endpoint, rp->p_name);
-
   return(OK);
 }
 #endif /* USE_EXEC */
index e6e1ef5e5b5a41b65bdfe50d86f2d7c4c789b06d..3df76da50e19956f3aaa6f81dda863d7db504314 100644 (file)
@@ -31,10 +31,25 @@ register message *m_ptr;    /* pointer to request message */
 
   if(!isokendpt(m_ptr->PR_ENDPT, &p_proc))
        return EINVAL;
+
   rpp = proc_addr(p_proc);
   rpc = proc_addr(m_ptr->PR_SLOT);
   if (isemptyp(rpp) || ! isemptyp(rpc)) return(EINVAL);
 
+  vmassert(!(rpp->p_misc_flags & MF_DELIVERMSG));
+
+  /* needs to be receiving so we know where the message buffer is */
+  if(!RTS_ISSET(rpp, RECEIVING)) {
+       printf("kernel: fork not done synchronously?\n");
+       return EINVAL;
+  }
+
+  /* memory becomes readonly */
+  if (priv(rpp)->s_asynsize > 0) {
+       printf("kernel: process with waiting asynsend table can't fork\n");
+       return EINVAL;
+  }
+
   map_ptr= (struct mem_map *) m_ptr->PR_MEM_PTR;
 
   /* Copy parent 'proc' struct to child. And reinitialize some fields. */
@@ -75,6 +90,7 @@ register message *m_ptr;      /* pointer to request message */
 
   /* Calculate endpoint identifier, so caller knows what it is. */
   m_ptr->PR_ENDPT = rpc->p_endpoint;
+  m_ptr->PR_FORK_MSGADDR = (char *) rpp->p_delivermsg_lin;
 
   /* Install new map */
   r = newmap(rpc, map_ptr);
@@ -88,9 +104,6 @@ register message *m_ptr;     /* pointer to request message */
   RTS_LOCK_UNSET(rpc, (SIGNALED | SIG_PENDING | P_STOP));
   sigemptyset(&rpc->p_pending);
 
-  printf("kernel: %d / %s forked into %d\n",
-       rpp->p_endpoint, rpp->p_name, rpc->p_endpoint);
-
   return r;
 }
 
index fa2a30dfc35b8a07fba98d05bc810aeb0a979875..f766ba853174844fa6a26fe80ec6cde9ac9cb184 100644 (file)
@@ -43,11 +43,13 @@ register message *m_ptr;    /* pointer to request message */
                if(!RTS_ISSET(rp, VMREQUEST))
                        minix_panic("do_vmctl: no VMREQUEST set", NO_NUM);
 
+#if 0
                printf("kernel: vm request sent by: %s / %d about %d; 0x%lx-0x%lx, wr %d\n",
                        rp->p_name, rp->p_endpoint, rp->p_vmrequest.who,
                        rp->p_vmrequest.start,
                        rp->p_vmrequest.start + rp->p_vmrequest.length,
                        rp->p_vmrequest.writeflag);
+#endif
 
                /* Reply with request fields. */
                m_ptr->SVMCTL_MRG_ADDR = (char *) rp->p_vmrequest.start;
@@ -77,7 +79,6 @@ register message *m_ptr;      /* pointer to request message */
                                rp->p_vmrequest.vmresult);
 
                /* Put on restart chain. */
-               printf("kernel: vm reply received for %d\n", rp->p_endpoint);
                rp->p_vmrequest.nextrestart = vmrestart;
                vmrestart = rp;
 
@@ -94,7 +95,7 @@ kprintf("SYSTEM: request %d:0x%lx-0x%lx, wrflag %d, failed\n",
        rp->p_vmrequest.writeflag); 
        
                                minix_panic("SYSTEM: fail but VM said OK", NO_NUM);
-                       }
+                       } 
                }
 #endif
                return OK;
index 03bc8cfcea36b83f8f998f09622e2735a8e448d9..a061f6f4f5a82ad546882d37e2f73c6f241db214 100755 (executable)
@@ -46,6 +46,7 @@ if (!minix_panicing++) {
        kprintf("\n");
   }
 
+  kprintf("proc_ptr %s / %d\n", proc_ptr->p_name, proc_ptr->p_endpoint);
   kprintf("kernel stacktrace: ");
   util_stacktrace();
 }
index e94645eedf53d2d5fd6592cdacafab7b0e71cc80..8a618d6bf2d392f95114778427e0c4a818f28fb2 100644 (file)
@@ -3,6 +3,7 @@
 #define _VM_H 1
 
 #define CHECKRANGE_OR_SUSPEND(pr, start, length, wr)  { int mr; \
+       FIXME("CHECKRANGE_OR_SUSPEND exists");  \
        if(vm_running && (mr=vm_checkrange(proc_addr(who_p), pr, start, length, wr, 0)) != OK) { \
                return mr;                                       \
        } }
index 8aef1b8caa5af25d81fdeaf0eccca4fb0ad25b80..1aa4c90347f9dd5349dc1afedf8f4b617b5335f3 100755 (executable)
@@ -1,11 +1,12 @@
 #include "syslib.h"
 
-PUBLIC int sys_fork(parent, child, child_endpoint, map_ptr, flags)
+PUBLIC int sys_fork(parent, child, child_endpoint, map_ptr, flags, msgaddr)
 endpoint_t parent;             /* process doing the fork */
 endpoint_t child;              /* which proc has been created by the fork */
 int *child_endpoint;
 struct mem_map *map_ptr;
 u32_t flags;
+vir_bytes *msgaddr;
 {
 /* A process has forked.  Tell the kernel. */
 
@@ -18,5 +19,6 @@ u32_t flags;
   m.PR_FORK_FLAGS = flags;
   r = _taskcall(SYSTASK, SYS_FORK, &m);
   *child_endpoint = m.PR_ENDPT;
+  *msgaddr = m.PR_FORK_MSGADDR;
   return r;
 }
index a44addf98309e19eae967e6a003d4fe78c65b7e0..cd9f53252da03f66cab68b3633fb556fccae2b71 100644 (file)
@@ -6,7 +6,6 @@ LIBRARIES=libsys
 
 libsys_FILES=" \
        asynsend.c \
-       kmalloc.c \
        kprintf.c \
        kputc.c \
        tickdelay.c \
index 5e5cb583289587b0bdbbc09f3ae5e70f69a6e4c0..5fd15fd3e40398fa472f3f7b4b9d65c141d62cec 100644 (file)
@@ -99,7 +99,6 @@ int main(void)
 
   /* Execute the /etc/rc file. */
   if ((pid = fork()) != 0) {
-       printf("init: parent (%d)\n", getpid());
        /* Parent just waits. */
        while (wait(NULL) != pid) {
                if (gotabrt) reboot(RBT_HALT);
@@ -112,7 +111,6 @@ int main(void)
        static char *rc_command[] = { "sh", "/etc/rc", NULL, NULL, NULL };
        char **rcp = rc_command + 2;
 
-       printf("init: child (%d)\n", getpid());
        /* Get the boot options from the boot environment. */
        sysgetenv.key = "bootopts";
        sysgetenv.keylen = 8+1;
@@ -121,9 +119,7 @@ int main(void)
        if (svrctl(MMGETPARAM, &sysgetenv) == 0) *rcp++ = bootopts;
        *rcp = "start";
 
-       printf("init: %d: exec /etc/rc..\n", getpid());
        execute(rc_command);
-       printf("init: %d: exec /etc/rc fail..\n", getpid());
        report(2, "sh /etc/rc");
        _exit(1);       /* impossible, we hope */
   }
index b57e876264aef60280fdf72bd028cf4d1bf23109..6ed92614ee2d11b3c8ba5100f418c96d2d9da342 100644 (file)
@@ -452,13 +452,9 @@ PRIVATE void send_work()
                        rmp->mp_fs_call= PM_IDLE;
 
                        /* Wakeup the newly created process */
-                       printf("PM: replying fork OK to child %d\n",
-                               rmp->mp_endpoint);
                        setreply(rmp-mproc, OK);
 
                        /* Wakeup the parent */
-                       printf("PM: replying fork %d to parent %d\n",
-                               rmp->mp_pid, parent_mp->mp_endpoint);
                        setreply(parent_mp-mproc, rmp->mp_pid);
                        break;
                }
index 40a22b4722c9a5d48c24aef325c264e6475f0e2f..9bd2058ace4751c704422d47e4aefeceaa74f97b 100644 (file)
@@ -5,7 +5,7 @@
 #define _MINIX             1   /* tell headers to include MINIX stuff */
 #define _SYSTEM            1   /* tell headers that this is the kernel */
 
-#define DO_SANITYCHECKS           1
+#define DO_SANITYCHECKS           0
 
 #if DO_SANITYCHECKS
 #define SANITYCHECK do {                       \
index 0d9161792a463c6ced5da78c846374e40035d411..e1e5ed21744c6472b28aed036b7c582a2a820394 100644 (file)
@@ -292,7 +292,9 @@ PRIVATE void get_work()
     if(who_p >= 0 && fproc[who_p].fp_endpoint != who_e) {
        printf("FS: receive endpoint inconsistent (%d, %d, %d).\n",
                who_e, fproc[who_p].fp_endpoint, who_e);
+#if 0
        panic(__FILE__, "FS: inconsistent endpoint ", NO_NUM);
+#endif
        continue;
     }
     call_nr = m_in.m_type;
index 7ab0fd48861aac04f34270db30633d69efd47db9..96331e09968f14ecc3a39ecce42d6304b9bb3d8f 100644 (file)
@@ -23,6 +23,7 @@
 #include <minix/const.h>
 #include <minix/sysutil.h>
 #include <minix/syslib.h>
+#include <minix/debug.h>
 
 #include <sys/mman.h>
 
@@ -423,6 +424,8 @@ struct memory *chunks;              /* list of free memory chunks */
   }
 
   CHECKHOLES;
+
+  FIXME("below 16MB allocation not done");
 }
 
 /*===========================================================================*
index 99151c08729b09e12ec5d8dc3fa962da904d32be..c311e17e0c3d413535d76a53bd5c7cc7a3899d19 100644 (file)
@@ -55,8 +55,6 @@ PUBLIC int do_exit(message *msg)
 
 SANITYCHECK(SCL_FUNCTIONS);
 
-       printf("VM: %d exiting\n", msg->VME_ENDPOINT);
-
        if(vm_isokendpt(msg->VME_ENDPOINT, &proc) != OK) {
                printf("VM: bogus endpoint VM_EXIT %d\n", msg->VME_ENDPOINT);
                return EINVAL;
index caef81c36620a1aa987afccc197b4ed6e3a6b716..a0af18811ecf1d2e252c17d526476cbce15a55ef 100644 (file)
@@ -33,6 +33,7 @@ PUBLIC int do_fork(message *msg)
   int r, proc, s, childproc, fullvm;
   struct vmproc *vmp, *vmc;
   pt_t origpt;
+  vir_bytes msgaddr;
 
   SANITYCHECK(SCL_FUNCTIONS);
 
@@ -139,11 +140,15 @@ PUBLIC int do_fork(message *msg)
   /* Tell kernel about the (now successful) FORK. */
   if((r=sys_fork(vmp->vm_endpoint, childproc,
        &vmc->vm_endpoint, vmc->vm_arch.vm_seg,
-       fullvm ? PFF_VMINHIBIT : 0)) != OK) {
+       fullvm ? PFF_VMINHIBIT : 0, &msgaddr)) != OK) {
         vm_panic("do_fork can't sys_fork", r);
   }
 
   if(fullvm) {
+       if(handle_memory(vmc, msgaddr, sizeof(message), 1) != OK)
+               vm_panic("can't make message writable (child)", NO_NUM);
+       if(handle_memory(vmp, msgaddr, sizeof(message), 1) != OK)
+               vm_panic("can't make message writable (parent)", NO_NUM);
        if((r=pt_bind(&vmc->vm_pt, vmc)) != OK)
                vm_panic("fork can't pt_bind", r);
   }
index cc0e6b9debecffb06a9bd88e0f909450b6618022..947ff51414f16c458d44a75a516a1fce494f4986 100644 (file)
@@ -647,8 +647,6 @@ PUBLIC void pt_init(void)
                1, VMP_PAGETABLE)))
                 vm_panic("no virt addr for vm mappings", NO_NUM);
 
-       printf("VM: pt made\n");
-
        memset(page_directories, 0, I386_PAGE_SIZE);
        
         /* Increase our hardware data segment to create virtual address
@@ -684,8 +682,6 @@ PUBLIC void pt_init(void)
         }
         varmap = (unsigned char *) arch_map2vir(vmp, varmap_loc);
 
-       printf("VM: setting pagedir_pde\n");
-
        /* Find a PDE below processes available for mapping in the
         * page directories (readonly).
         */
@@ -705,8 +701,6 @@ PUBLIC void pt_init(void)
 
        kernlimit = free_pde*I386_BIG_PAGE_SIZE;
 
-       printf("VM: set limit to 0x%x\n", kernlimit);
-
        /* Increase kernel segment to address this memory. */
        if((r=sys_vmctl(SELF, VMCTL_I386_KERNELLIMIT, kernlimit)) != OK) {
                 vm_panic("VMCTL_I386_KERNELLIMIT failed", r);
@@ -714,8 +708,6 @@ PUBLIC void pt_init(void)
 
        kpagedir = arch_map2vir(&vmproc[VMP_SYSTEM],
                pagedir_pde*I386_BIG_PAGE_SIZE);
-       printf("VM: pagedir linear 0x%x, in kernel 0x%x\n",
-               pagedir_pde*I386_BIG_PAGE_SIZE, kpagedir);
 
        /* Tell kernel how to get at the page directories. */
        if((r=sys_vmctl(SELF, VMCTL_I386_PAGEDIRS, kpagedir)) != OK) {
@@ -723,20 +715,15 @@ PUBLIC void pt_init(void)
        }
        
         /* Give our process the new, copied, private page table. */
-       printf("VM: pt_bind for VM\n");
        pt_mapkernel(newpt);    /* didn't know about vm_dir pages earlier */
         pt_bind(newpt, vmp);
        
-       printf("VM: enable paging\n");
-
        /* Now actually enable paging. */
        if((r=sys_vmctl(SELF, VMCTL_ENABLE_PAGING,
                vmp->vm_arch.vm_seg)) != OK) {
                 vm_panic("VMCTL_ENABLE_PAGING failed", r);
        }
 
-       printf("VM: enable paging done\n");
-
         /* Back to reality - this is where the stack actually is. */
         vmp->vm_arch.vm_seg[S].mem_len -= extra_clicks;
        
@@ -747,8 +734,6 @@ PUBLIC void pt_init(void)
                         vm_panic("pt_init: pt_writemap failed", NO_NUM);
         }
 
-       printf("VM: pt_init done\n");
-
         /* All OK. */
         return;
 }
@@ -843,8 +828,6 @@ PUBLIC int pt_mapkernel(pt_t *pt)
        if(pagedir_pde >= 0) {
                /* Kernel also wants to know about all page directories. */
                pt->pt_dir[pagedir_pde] = pagedir_pde_val;
-       } else {
-               printf("VM: pagedir pde not set\n");
        }
 
        return OK;
index fcf84c558c276c1b38befdfbb2e24ccb18e410f5..60987118bf235806bd8eea647d7392445b3bce38 100644 (file)
@@ -106,8 +106,10 @@ PUBLIC void do_pagefaults(void)
                }
 
 
+#if 0
                printf("VM: handling pagefault OK: %d addr 0x%lx %s\n", 
                        ep, arch_map2vir(vmp, addr), pf_errstr(err));
+#endif
 
                /* Pagefault is handled, so now reactivate the process. */
                if((s=sys_vmctl(ep, VMCTL_CLEAR_PAGEFAULT, r)) != OK)
@@ -131,55 +133,64 @@ PUBLIC void do_memory(void)
 
        while((r=sys_vmctl_get_memreq(&who, &mem, &len, &wrflag)) == OK) {
                int p, r = OK;
-               struct vir_region *region;
                struct vmproc *vmp;
-               vir_bytes o;
 
                if(vm_isokendpt(who, &p) != OK)
                        vm_panic("do_memory: endpoint wrong", who);
                vmp = &vmproc[p];
 
-               printf("VM: handling memory request: %d, 0x%lx-0x%lx, wr %d\n",
-                       who, mem, mem+len, wrflag);
-
-               /* Page-align memory and length. */
-               o = mem % VM_PAGE_SIZE;
-               mem -= o;
-               len += o;
-               o = len % VM_PAGE_SIZE;
-               if(o > 0) len += VM_PAGE_SIZE - o;
-
-               if(!(region = map_lookup(vmp, mem))) {
-                       printf("VM: do_memory: memory doesn't exist\n");
-                       r = EFAULT;
-               } else if(mem + len > region->vaddr + region->length) {
-                       vm_assert(region->vaddr <= mem);
-                       vm_panic("do_memory: not contained", NO_NUM);
-               } else if(!(region->flags & VR_WRITABLE) && wrflag) {
-                       printf("VM: do_memory: write to unwritable map\n");
-                       r = EFAULT;
-               } else {
-                       vir_bytes offset;
-                       vm_assert(region->vaddr <= mem);
-                       vm_assert(!(region->flags & VR_NOPF));
-                       vm_assert(!(region->vaddr % VM_PAGE_SIZE));
-                       offset = mem - region->vaddr;
-
-                       r = map_handle_memory(vmp, region, offset, len, wrflag);
-               }
-
-               if(r != OK) {
-                       printf("VM: memory range 0x%lx-0x%lx not available in %d\n",
-                               arch_map2vir(vmp, mem), arch_map2vir(vmp, mem+len),
-                               vmp->vm_endpoint);
-               }
-
+               r = handle_memory(vmp, mem, len, wrflag);
 
                if(sys_vmctl(who, VMCTL_MEMREQ_REPLY, r) != OK)
                        vm_panic("do_memory: sys_vmctl failed", r);
 
+#if 0
                printf("VM: handling memory request %d done OK\n",
                        who);
+#endif
        }
 }
 
+int handle_memory(struct vmproc *vmp, vir_bytes mem, vir_bytes len, int wrflag)
+{
+       struct vir_region *region;
+       vir_bytes o;
+       int r;
+
+#if 0
+       printf("VM: handling memory request: %d, 0x%lx-0x%lx, wr %d\n",
+               vmp->vm_endpoint, mem, mem+len, wrflag);
+#endif
+
+       /* Page-align memory and length. */
+       o = mem % VM_PAGE_SIZE;
+       mem -= o;
+       len += o;
+       o = len % VM_PAGE_SIZE;
+       if(o > 0) len += VM_PAGE_SIZE - o;
+
+       if(!(region = map_lookup(vmp, mem))) {
+               printf("VM: do_memory: memory doesn't exist\n");
+               r = EFAULT;
+       } else if(mem + len > region->vaddr + region->length) {
+               vm_assert(region->vaddr <= mem);
+               vm_panic("do_memory: not contained", NO_NUM);
+       } else if(!(region->flags & VR_WRITABLE) && wrflag) {
+               printf("VM: do_memory: write to unwritable map\n");
+               r = EFAULT;
+       } else {
+               vir_bytes offset;
+               vm_assert(region->vaddr <= mem);
+               vm_assert(!(region->flags & VR_NOPF));
+               vm_assert(!(region->vaddr % VM_PAGE_SIZE));
+               offset = mem - region->vaddr;
+
+               r = map_handle_memory(vmp, region, offset, len, wrflag);
+       }
+
+       if(r != OK) {
+               printf("VM: memory range 0x%lx-0x%lx not available in %d\n",
+                       arch_map2vir(vmp, mem), arch_map2vir(vmp, mem+len),
+                       vmp->vm_endpoint);
+       }
+}
index f4e860834fca781bfe6c8d4e10437f0923b111e7..91a0ac1a43b06e76e628c3998ec6a560d153d7be 100644 (file)
@@ -81,6 +81,8 @@ _PROTOTYPE(int do_unmap_phys, (message *msg)                            );
 _PROTOTYPE( void do_pagefaults, (void)                         );
 _PROTOTYPE( void do_memory, (void)                             );
 _PROTOTYPE( char *pf_errstr, (u32_t err));
+_PROTOTYPE( int handle_memory, (struct vmproc *vmp, vir_bytes mem,
+       vir_bytes len, int wrflag));
 
 /* $(ARCH)/pagetable.c */
 _PROTOTYPE( void pt_init, (void)                                       );
index ac25ced45d36f4cce16a669250e186126966fedb..cad35238891b1a9477fb78e6ec6d94e9c6d9ca91 100644 (file)
@@ -718,8 +718,9 @@ int write;
 
                if(ph->ph->refcount == 1)
                        r = map_ph_writept(vmp, region, ph->ph, NULL, NULL);
-               else
+               else {
                        r = map_copy_ph_block(vmp, region, ph);
+               }
        } else {
                /* Pagefault in non-existing block. Map in new block. */
 #if 0
index fb3b14c8e575da860c14e2a4c96bafbea02d380c..8ac80f4ceceea96308bc8b109d25401c0da2aa16 100644 (file)
@@ -13,8 +13,8 @@
 #define ABS2CLICK(a) ((a) >> CLICK_SHIFT)
 
 /* Compile in asserts and custom sanity checks at all? */
-#define SANITYCHECKS   1
-#define VMSTATS                1
+#define SANITYCHECKS   0
+#define VMSTATS                0
 
 /* If so, this level: */
 #define SCL_NONE       0       /* No sanity checks - vm_assert()s only. */