This commit is contained in:
Ben Gras 2009-06-03 11:22:49 +00:00
parent f16eb59bbf
commit eb2959a560
37 changed files with 453 additions and 594 deletions

View File

@ -525,6 +525,7 @@
* 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 */

View File

@ -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));

View 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;
}

View 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 */

View File

@ -10,12 +10,10 @@
#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;
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;

View File

@ -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
@ -21,13 +20,14 @@
.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

View File

@ -23,22 +23,14 @@
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);
}

View File

@ -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

View File

@ -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;
}

View 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;

View 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;
}

View 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) { }

View File

@ -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 */

View File

@ -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();
}

View File

@ -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);
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;
}
@ -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) {

View File

@ -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

View File

@ -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 */

View File

@ -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);
}

View 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 */

View 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;
}

View 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;

View File

@ -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();
}

View 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; \
} }

View File

@ -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;
}

View File

@ -6,7 +6,6 @@ LIBRARIES=libsys
libsys_FILES=" \
asynsend.c \
kmalloc.c \
kprintf.c \
kputc.c \
tickdelay.c \

View 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 */
}

View 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;
}

View 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 { \

View 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;

View 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");
}
/*===========================================================================*

View 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;

View 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);
}

View 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;

View 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,16 +133,34 @@ 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];
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",
who, mem, mem+len, wrflag);
vmp->vm_endpoint, mem, mem+len, wrflag);
#endif
/* Page-align memory and length. */
o = mem % VM_PAGE_SIZE;
@ -173,13 +193,4 @@ PUBLIC void do_memory(void)
arch_map2vir(vmp, mem), arch_map2vir(vmp, mem+len),
vmp->vm_endpoint);
}
if(sys_vmctl(who, VMCTL_MEMREQ_REPLY, r) != OK)
vm_panic("do_memory: sys_vmctl failed", r);
printf("VM: handling memory request %d done OK\n",
who);
}
}

View 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) );

View 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

View 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. */