Subject: emulation-specific page fault handling
To: None <tech-kern@netbsd.org>
From: Emmanuel Dreyfus <manu@netbsd.org>
List: tech-kern
Date: 09/07/2002 07:59:58
Hi all

I need a change to UVM in order to accurately emulate IRIX share groups:
In IRIX, share groups share their whole VM, except one page which
remains private to each process. We cannot just use the same vm_space to
emulate this.

Each process has its own vm_map, and we need to keep the share group
processes vm_space in sync on each modification that affect a share
group member vm_space. This looks weird, but we do not have another
option yet (and this is the way IRIX does it, according to man pages).

To do this, we provide a custom implementation of system calls that
modify the vm_space, such as mmap, munmap, mlock... When called by a
share group member, they walk the share group member list and make the
modification on all share group members.

We have a remaining problem, because the vm_space can be modified by
memory fault traps, in particular when we have a COW. Chuck Silvers
suggested to introduce a e_fault in struct emul that points to uvm_fault
for natives processes and to irix_vm_fault for IRIX processes. 

        int             (*e_fault)(struct vm_map *, vaddr_t, vm_fault_t,
                                   vm_prot_t);


In sys/arch/mips/mips/trap.c, we would replace occurences of uvm_fault
by (*p->p_emul->e_fault). 

Other ports trap handlers would remain unaffected for now, but e_fault
would be in the MI part of struct emul, just in case we need a similar
mecanism for another emulation later.

Another problem is that I need a pointer to struct proc in irix_vm_fault
in order to walk the share group list (it is in p_emuldata). I suggest
to introduct struct proc * as an argument to uvm_fault. 

Opinions about this?

Last problem: declaring e_fault in struct proc uses vm_fault_t, which
forces me to include <uvm/uvm_extern.h> in <sys/proc.h>. Unfortunately,
<uvm/extern.h> needs to include <sys/proc.h> in order to get ltsleep
definition, which is after the include <uvm/uvm_extern.h> in
<sys/proc.h>. I end up with duplicated declaration of ltsleep in
<sys/proc.h> before inlcuding <uvm/uvm_extern.h>, is it the way it
should be done?

-- 
Emmanuel Dreyfus.  
Hiroshima 45. Tchernobyl 86. Windows 95. 
manu@netbsd.org