keep some processes mapped in always; direct message copying

where possible (no buffering); no more explicit vm checkranges
in kernel; new allocator for vm using avl tree without needing
remapping
This commit is contained in:
Ben Gras
2009-06-08 04:02:22 +00:00
parent e2a7535c55
commit ac86f5bb49
35 changed files with 1770 additions and 755 deletions

View File

@@ -73,11 +73,6 @@ struct proc *p;
i386_freepde(m_ptr->SVMCTL_VALUE);
return OK;
}
case VMCTL_I386_INVLPG:
{
invlpg_range(m_ptr->SVMCTL_VALUE, 1);
return OK;
}
}

View File

@@ -15,9 +15,6 @@
extern int vm_copy_in_progress, catch_pagefaults;
extern struct proc *vm_copy_from, *vm_copy_to;
extern u32_t npagefaults;
PUBLIC u32_t pagefault_count = 0;
void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno,
u32_t *old_eipptr, u32_t *old_eaxptr, u32_t pagefaultcr2)
@@ -35,8 +32,6 @@ void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno,
vmassert(*old_eipptr == old_eip);
vmassert(old_eipptr != &old_eip);
vmassert(pagefault_count == 1);
#if 0
printf("kernel: pagefault in pr %d, addr 0x%lx, his cr3 0x%lx, actual cr3 0x%lx\n",
pr->p_endpoint, pagefaultcr2, pr->p_seg.p_cr3, read_cr3());
@@ -48,8 +43,22 @@ void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno,
#endif
vmassert(pr->p_seg.p_cr3 == read_cr3());
} else {
u32_t cr3;
lock;
cr3 = read_cr3();
vmassert(ptproc);
vmassert(ptproc->p_seg.p_cr3 == read_cr3());
if(ptproc->p_seg.p_cr3 != cr3) {
util_stacktrace();
printf("cr3 wrong in pagefault; value 0x%lx, ptproc %s / %d, his cr3 0x%lx, pr %s / %d\n",
cr3,
ptproc->p_name, ptproc->p_endpoint,
ptproc->p_seg.p_cr3,
pr->p_name, pr->p_endpoint);
ser_dump_proc();
vm_print(cr3);
vm_print(ptproc->p_seg.p_cr3);
}
unlock;
}
test_eip = k_reenter ? old_eip : pr->p_reg.pc;
@@ -65,13 +74,9 @@ void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno,
*old_eipptr = phys_copy_fault;
*old_eaxptr = pagefaultcr2;
pagefault_count = 0;
return;
}
npagefaults++;
/* 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).
@@ -107,8 +112,6 @@ void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno,
lock_notify(HARDWARE, VM_PROC_NR);
pagefault_count = 0;
return;
}

View File

@@ -68,5 +68,7 @@ struct pagefault
u32_t pf_flags; /* Pagefault flags on stack. */
};
#define INMEMORY(p) (!p->p_seg.p_cr3 || ptproc == p)
#endif /* #ifndef _I386_TYPES_H */

View File

@@ -40,10 +40,6 @@
.define _read_cr4
.define _thecr3
.define _write_cr4
.define _i386_invlpg_addr
.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
@@ -587,57 +583,3 @@ _getcr3val:
mov (_thecr3), eax
ret
!*===========================================================================*
!* i386_invlpg *
!*===========================================================================*
! PUBLIC void i386_invlpg(void);
_i386_invlpg_level0:
mov eax, (_i386_invlpg_addr)
invlpg (eax)
ret
!*===========================================================================*
!* _memcpy_k *
!*===========================================================================*
! _memcpy_k() Original Author: Kees J. Bot
! 2 Jan 1994
! void *_memcpy_k(void *s1, const void *s2, size_t n)
! Copy a chunk of memory that the kernel can use to trap pagefaults.
.define __memcpy_k
.define __memcpy_k_fault
.align 16
__memcpy_k:
push ebp
mov ebp, esp
push esi
push edi
mov edi, 8(ebp) ! String s1
mov esi, 12(ebp) ! String s2
mov ecx, 16(ebp) ! Length
cld ! Clear direction bit: upwards
cmp ecx, 16
jb upbyte ! Don't bother being smart with short arrays
mov eax, esi
or eax, edi
testb al, 1
jnz upbyte ! Bit 0 set, use byte copy
testb al, 2
jnz upword ! Bit 1 set, use word copy
uplword:shrd eax, ecx, 2 ! Save low 2 bits of ecx in eax
shr ecx, 2
rep
movs ! Copy longwords.
shld ecx, eax, 2 ! Restore excess count
upword: shr ecx, 1
rep
o16 movs ! Copy words
adc ecx, ecx ! One more byte?
upbyte: rep
movsb ! Copy bytes
done: mov eax, 0
__memcpy_k_fault: ! Kernel can send us here with pf cr2 in eax
pop edi
pop esi
pop ebp
ret

View File

@@ -22,20 +22,12 @@ PRIVATE int psok = 0;
int verifyrange = 0;
extern u32_t newpde, overwritepde, linlincopies,
physzero, invlpgs, straightpdes;
#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;
u8_t *vm_pagedirs = NULL;
u32_t i386_invlpg_addr = 0;
#define WANT_FREEPDES 100
#define NOPDE -1
#define PDEMASK(n) (1L << (n))
@@ -62,6 +54,145 @@ PUBLIC void vm_init(struct proc *newptproc)
}
/* This macro sets up a mapping from within the kernel's address
* space to any other area of memory, either straight physical
* memory (PROC == NULL) or a process view of memory, in 4MB chunks.
* It recognizes PROC having kernel address space as a special case.
*
* It sets PTR to the pointer within kernel address space at the start
* of the 4MB chunk, and OFFSET to the offset within that chunk
* that corresponds to LINADDR.
*
* It needs FREEPDE (available and addressable PDE within kernel
* address space), SEG (hardware segment), VIRT (in-datasegment
* address if known).
*/
#define CREATEPDE(PROC, PTR, LINADDR, REMAIN, BYTES, PDE) { \
int proc_pde_index; \
proc_pde_index = I386_VM_PDE(LINADDR); \
PDE = NOPDE; \
if((PROC) && (((PROC) == ptproc) || !HASPT(PROC))) { \
PTR = LINADDR; \
} else { \
int fp; \
int mustinvl; \
u32_t pdeval, *pdevalptr, mask; \
phys_bytes offset; \
vmassert(psok); \
if(PROC) { \
u32_t *pdeptr; \
vmassert(!iskernelp(PROC)); \
vmassert(HASPT(PROC)); \
pdeptr = PROCPDEPTR(PROC, proc_pde_index); \
pdeval = *pdeptr; \
} else { \
vmassert(!iskernelp(PROC)); \
pdeval = (LINADDR & I386_VM_ADDR_MASK_4MB) | \
I386_VM_BIGPAGE | I386_VM_PRESENT | \
I386_VM_WRITE | I386_VM_USER; \
} \
for(fp = 0; fp < nfreepdes; fp++) { \
int k = freepdes[fp]; \
if(inusepde == k) \
continue; \
PDE = k; \
mask = PDEMASK(k); \
vmassert(mask); \
if(dirtypde & mask) \
continue; \
break; \
} \
vmassert(PDE != NOPDE); \
vmassert(mask); \
if(dirtypde & mask) { \
mustinvl = 1; \
} else { \
mustinvl = 0; \
} \
inusepde = PDE; \
*PROCPDEPTR(ptproc, PDE) = pdeval; \
offset = LINADDR & I386_VM_OFFSET_MASK_4MB; \
PTR = I386_BIG_PAGE_SIZE*PDE + offset; \
REMAIN = MIN(REMAIN, I386_BIG_PAGE_SIZE - offset); \
if(mustinvl) { \
level0(reload_cr3); \
} \
} \
}
#define DONEPDE(PDE) { \
if(PDE != NOPDE) { \
dirtypde |= PDEMASK(PDE); \
*PROCPDEPTR(ptproc, PDE) = 0; \
} \
}
/*===========================================================================*
* lin_lin_copy *
*===========================================================================*/
int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr,
struct proc *dstproc, vir_bytes dstlinaddr, vir_bytes bytes)
{
u32_t addr;
int procslot;
NOREC_ENTER(linlincopy);
FIXME("lin_lin_copy requires big pages");
vmassert(vm_running);
vmassert(!catch_pagefaults);
vmassert(nfreepdes >= 3);
vmassert(ptproc);
vmassert(proc_ptr);
vmassert(read_cr3() == ptproc->p_seg.p_cr3);
procslot = ptproc->p_nr;
vmassert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES);
while(bytes > 0) {
phys_bytes srcptr, dstptr;
vir_bytes chunk = bytes;
int srcpde, dstpde;
/* Set up 4MB ranges. */
inusepde = NOPDE;
CREATEPDE(srcproc, srcptr, srclinaddr, chunk, bytes, srcpde);
CREATEPDE(dstproc, dstptr, dstlinaddr, chunk, bytes, dstpde);
/* Copy pages. */
PHYS_COPY_CATCH(srcptr, dstptr, chunk, addr);
DONEPDE(srcpde);
DONEPDE(dstpde);
if(addr) {
if(addr >= srcptr && addr < (srcptr + chunk)) {
NOREC_RETURN(linlincopy, EFAULT_SRC);
}
if(addr >= dstptr && addr < (dstptr + chunk)) {
NOREC_RETURN(linlincopy, EFAULT_DST);
}
minix_panic("lin_lin_copy fault out of range", NO_NUM);
/* Not reached. */
NOREC_RETURN(linlincopy, EFAULT);
}
/* Update counter and addresses for next iteration, if any. */
bytes -= chunk;
srclinaddr += chunk;
dstlinaddr += chunk;
}
NOREC_RETURN(linlincopy, OK);
}
PRIVATE u32_t phys_get32(addr)
phys_bytes addr;
{
@@ -448,8 +579,6 @@ PUBLIC int vm_contiguous(struct proc *targetproc, u32_t vir_buf, size_t bytes)
return 1;
}
extern u32_t vmreqs;
/*===========================================================================*
* vm_suspend *
*===========================================================================*/
@@ -472,8 +601,6 @@ PUBLIC int vm_suspend(struct proc *caller, struct proc *target,
util_stacktrace_strcat(caller->p_vmrequest.stacktrace);
#endif
vmreqs++;
caller->p_vmrequest.writeflag = 1;
caller->p_vmrequest.start = linaddr;
caller->p_vmrequest.length = len;
@@ -499,18 +626,21 @@ int delivermsg(struct proc *rp)
vmassert(rp->p_delivermsg.m_source != NONE);
vmassert(rp->p_delivermsg_lin);
vmassert(rp->p_delivermsg_lin ==
#if DEBUG_VMASSERT
if(rp->p_delivermsg_lin !=
umap_local(rp, D, rp->p_delivermsg_vir, sizeof(message))) {
printf("vir: 0x%lx lin was: 0x%lx umap now: 0x%lx\n",
rp->p_delivermsg_vir, rp->p_delivermsg_lin,
umap_local(rp, D, rp->p_delivermsg_vir, sizeof(message)));
minix_panic("that's wrong", NO_NUM);
}
#endif
vm_set_cr3(rp);
vmassert(intr_disabled());
vmassert(!catch_pagefaults);
catch_pagefaults = 1;
addr = phys_copy(vir2phys(&rp->p_delivermsg),
rp->p_delivermsg_lin, sizeof(message));
vmassert(catch_pagefaults);
catch_pagefaults = 0;
PHYS_COPY_CATCH(vir2phys(&rp->p_delivermsg),
rp->p_delivermsg_lin, sizeof(message), addr);
if(addr) {
printf("phys_copy failed - addr 0x%lx\n", addr);
@@ -600,32 +730,6 @@ void vm_print(u32_t *root)
return;
}
/*===========================================================================*
* invlpg_range *
*===========================================================================*/
void invlpg_range(u32_t lin, u32_t bytes)
{
/* Remove a range of translated addresses from the TLB.
* Addresses are in linear, i.e., post-segment, pre-pagetable
* form. Parameters are byte values, any offset and any multiple.
*/
u32_t cr3;
u32_t o, limit, addr;
limit = lin + bytes - 1;
o = lin % I386_PAGE_SIZE;
lin -= o;
limit = (limit + o) & I386_VM_ADDR_MASK;
#if 1
for(i386_invlpg_addr = lin; i386_invlpg_addr <= limit;
i386_invlpg_addr += I386_PAGE_SIZE) {
invlpgs++;
level0(i386_invlpg_level0);
}
#else
level0(reload_cr3);
#endif
}
u32_t thecr3;
u32_t read_cr3(void)
@@ -634,153 +738,6 @@ u32_t read_cr3(void)
return thecr3;
}
/* This macro sets up a mapping from within the kernel's address
* space to any other area of memory, either straight physical
* memory (PROC == NULL) or a process view of memory, in 4MB chunks.
* It recognizes PROC having kernel address space as a special case.
*
* It sets PTR to the pointer within kernel address space at the start
* of the 4MB chunk, and OFFSET to the offset within that chunk
* that corresponds to LINADDR.
*
* It needs FREEPDE (available and addressable PDE within kernel
* address space), SEG (hardware segment), VIRT (in-datasegment
* address if known).
*/
#define CREATEPDE(PROC, PTR, LINADDR, REMAIN, BYTES, PDE) { \
int proc_pde_index; \
FIXME("CREATEPDE: check if invlpg is necessary"); \
proc_pde_index = I386_VM_PDE(LINADDR); \
PDE = NOPDE; \
if((PROC) && (((PROC) == ptproc) || iskernelp(PROC))) { \
PTR = LINADDR; \
straightpdes++; \
} else { \
int fp; \
int mustinvl; \
u32_t pdeval, *pdevalptr, mask; \
phys_bytes offset; \
vmassert(psok); \
if(PROC) { \
u32_t *pdeptr; \
vmassert(!iskernelp(PROC)); \
vmassert(HASPT(PROC)); \
pdeptr = PROCPDEPTR(PROC, proc_pde_index); \
pdeval = *pdeptr; \
} else { \
vmassert(!iskernelp(PROC)); \
pdeval = (LINADDR & I386_VM_ADDR_MASK_4MB) | \
I386_VM_BIGPAGE | I386_VM_PRESENT | \
I386_VM_WRITE | I386_VM_USER; \
} \
for(fp = 0; fp < nfreepdes; fp++) { \
int k = freepdes[fp]; \
if(inusepde == k) \
continue; \
PDE = k; \
mask = PDEMASK(k); \
vmassert(mask); \
if(dirtypde & mask) \
continue; \
break; \
} \
vmassert(PDE != NOPDE); \
vmassert(mask); \
if(dirtypde & mask) { \
mustinvl = 1; \
overwritepde++; \
} else { \
mustinvl = 0; \
newpde++; \
} \
inusepde = PDE; \
*PROCPDEPTR(ptproc, PDE) = pdeval; \
offset = LINADDR & I386_VM_OFFSET_MASK_4MB; \
PTR = I386_BIG_PAGE_SIZE*PDE + offset; \
REMAIN = MIN(REMAIN, I386_BIG_PAGE_SIZE - offset); \
if(mustinvl) { \
invlpg_range(PTR, REMAIN); \
} \
} \
}
#define DONEPDE(PDE) { \
if(PDE != NOPDE) { \
dirtypde |= PDEMASK(PDE); \
*PROCPDEPTR(ptproc, PDE) = 0; \
} \
}
/*===========================================================================*
* lin_lin_copy *
*===========================================================================*/
int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr,
struct proc *dstproc, vir_bytes dstlinaddr, vir_bytes bytes)
{
u32_t addr;
int procslot;
NOREC_ENTER(linlincopy);
linlincopies++;
FIXME("lin_lin_copy requires big pages");
vmassert(vm_running);
vmassert(!catch_pagefaults);
vmassert(nfreepdes >= 3);
vmassert(ptproc);
vmassert(proc_ptr);
vmassert(read_cr3() == ptproc->p_seg.p_cr3);
procslot = ptproc->p_nr;
vmassert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES);
while(bytes > 0) {
phys_bytes srcptr, dstptr;
vir_bytes chunk = bytes;
int srcpde, dstpde;
/* Set up 4MB ranges. */
inusepde = NOPDE;
CREATEPDE(srcproc, srcptr, srclinaddr, chunk, bytes, srcpde);
CREATEPDE(dstproc, dstptr, dstlinaddr, chunk, bytes, dstpde);
/* Copy pages. */
vmassert(intr_disabled());
vmassert(!catch_pagefaults);
catch_pagefaults = 1;
addr=phys_copy(srcptr, dstptr, chunk);
vmassert(intr_disabled());
vmassert(catch_pagefaults);
catch_pagefaults = 0;
DONEPDE(srcpde);
DONEPDE(dstpde);
if(addr) {
if(addr >= srcptr && addr < (srcptr + chunk)) {
NOREC_RETURN(linlincopy, EFAULT_SRC);
}
if(addr >= dstptr && addr < (dstptr + chunk)) {
NOREC_RETURN(linlincopy, EFAULT_DST);
}
minix_panic("lin_lin_copy fault out of range", NO_NUM);
/* Not reached. */
NOREC_RETURN(linlincopy, EFAULT);
}
/* Update counter and addresses for next iteration, if any. */
bytes -= chunk;
srclinaddr += chunk;
dstlinaddr += chunk;
}
NOREC_RETURN(linlincopy, OK);
}
/*===========================================================================*
* lin_memset *
@@ -791,8 +748,6 @@ int vm_phys_memset(phys_bytes ph, u8_t c, phys_bytes bytes)
u32_t p;
p = c | (c << 8) | (c << 16) | (c << 24);
physzero++;
if(!vm_running) {
phys_memset(ph, p, bytes);
return OK;

View File

@@ -73,9 +73,6 @@ begbss:
.define _restart
.define save
.define _pagefault_count
.define _cr3_test
.define _cr3_reload
.define _reload_cr3
.define _write_cr3 ! write cr3
@@ -409,13 +406,11 @@ _restart:
call _schedcheck ! ask C function who we're running
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 0f
mov eax, P_CR3(esp)
cmp eax, (loadedcr3)
jz 0f
inc (_cr3_reload)
mov cr3, eax
mov (loadedcr3), eax
mov eax, (_proc_ptr)
@@ -498,7 +493,6 @@ _page_fault:
push eax
mov eax, cr2
sseg mov (pagefaultcr2), eax
sseg inc (_pagefault_count)
pop eax
jmp errexception
@@ -566,10 +560,8 @@ _write_cr3:
push ebp
mov ebp, esp
mov eax, 8(ebp)
inc (_cr3_test)
cmp eax, (loadedcr3)
jz 0f
inc (_cr3_reload)
mov cr3, eax
mov (loadedcr3), eax
mov (_dirtypde), 0
@@ -584,7 +576,6 @@ _write_cr3:
_reload_cr3:
push ebp
mov ebp, esp
inc (_cr3_reload)
mov (_dirtypde), 0
mov eax, cr3
mov cr3, eax

View File

@@ -25,9 +25,9 @@
#define DEBUG_TIME_LOCKS 1
/* Runtime sanity checking. */
#define DEBUG_VMASSERT 0
#define DEBUG_SCHED_CHECK 0
#define DEBUG_STACK_CHECK 0
#define DEBUG_VMASSERT 1
#define DEBUG_SCHED_CHECK 1
#define DEBUG_STACK_CHECK 1
#define DEBUG_TRACE 1
#if DEBUG_TRACE

View File

@@ -65,6 +65,7 @@ EXTERN int verboseflags;
/* VM */
EXTERN int vm_running;
EXTERN int catch_pagefaults;
EXTERN struct proc *ptproc;
/* Timing */

View File

@@ -88,6 +88,7 @@ FORWARD _PROTOTYPE( void pick_proc, (void));
PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst)
{
int k;
phys_bytes addr;
NOREC_ENTER(queuemess);
/* Queue a message from the src process (in memory) to the dst
* process (using dst process table entry). Do actual copy to
@@ -96,15 +97,35 @@ PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst)
vmassert(!(dst->p_misc_flags & MF_DELIVERMSG));
vmassert(dst->p_delivermsg_lin);
vmassert(isokendpt(ep, &k));
FIXME("copy messages directly if in memory");
FIXME("possibly also msgcopy specific function");
if(phys_copy(msg_lin, vir2phys(&dst->p_delivermsg),
sizeof(message))) {
if(INMEMORY(dst)) {
PHYS_COPY_CATCH(msg_lin, dst->p_delivermsg_lin,
sizeof(message), addr);
if(!addr) {
PHYS_COPY_CATCH(vir2phys(&ep), dst->p_delivermsg_lin,
sizeof(ep), addr);
if(!addr) {
NOREC_RETURN(queuemess, OK);
}
}
}
PHYS_COPY_CATCH(msg_lin, vir2phys(&dst->p_delivermsg), sizeof(message), addr);
if(addr) {
NOREC_RETURN(queuemess, EFAULT);
}
dst->p_delivermsg.m_source = ep;
dst->p_misc_flags |= MF_DELIVERMSG;
#if 0
if(INMEMORY(dst)) {
delivermsg(dst);
}
#endif
NOREC_RETURN(queuemess, OK);
}
@@ -456,6 +477,7 @@ int flags;
register struct proc **xpp;
int dst_p;
phys_bytes linaddr;
vir_bytes addr;
int r;
if(!(linaddr = umap_local(caller_ptr, D, (vir_bytes) m_ptr,
@@ -485,9 +507,10 @@ int flags;
}
/* Destination is not waiting. Block and dequeue caller. */
if(phys_copy(linaddr, vir2phys(&caller_ptr->p_sendmsg), sizeof(message))) {
return EFAULT;
}
PHYS_COPY_CATCH(linaddr, vir2phys(&caller_ptr->p_sendmsg),
sizeof(message), addr);
if(addr) { return EFAULT; }
RTS_SET(caller_ptr, SENDING);
caller_ptr->p_sendto_e = dst_e;
@@ -531,7 +554,7 @@ int flags;
/* This is where we want our message. */
caller_ptr->p_delivermsg_lin = linaddr;
caller_ptr->p_delivermsg_vir = m_ptr;
caller_ptr->p_delivermsg_vir = (vir_bytes) m_ptr;
if(src_e == ANY) src_p = ANY;
else
@@ -1063,7 +1086,6 @@ register struct proc *rp; /* this process is now runnable */
* process yet or current process isn't ready any more, or
* it's PREEMPTIBLE.
*/
FIXME("PREEMPTIBLE test?");
vmassert(proc_ptr);
#if 0
if(!proc_ptr || proc_ptr->p_rts_flags)

View File

@@ -10,6 +10,7 @@
* struct proc, be sure to change sconst.h to match.
*/
#include <minix/com.h>
#include <minix/portio.h>
#include "const.h"
#include "priv.h"

View File

@@ -38,6 +38,7 @@
#include <sys/sigcontext.h>
#include <minix/endpoint.h>
#include <minix/safecopies.h>
#include <minix/portio.h>
#include <minix/u64.h>
#include <sys/vm_i386.h>
@@ -58,9 +59,6 @@ char *callnames[NR_SYS_CALLS];
FORWARD _PROTOTYPE( void initialize, (void));
FORWARD _PROTOTYPE( struct proc *vmrestart_check, (message *));
u32_t cr3_test, cr3_reload, newpde, overwritepde,
linlincopies, physzero, invlpgs, npagefaults, vmreqs, straightpdes;
/*===========================================================================*
* sys_task *
*===========================================================================*/
@@ -90,46 +88,6 @@ PUBLIC void sys_task()
minix_panic("receive() failed", r);
}
#if 1
{
struct proc *stp;
static int prevu;
int u, dt;
u = get_uptime();
dt = u - prevu;
if(dt >= 5*system_hz) {
#define PERSEC(n) ((n)*system_hz/dt)
printf("%6d cr3 tests: %5lu cr3: %5lu straightpdes: %5lu newpde: %5lu overwritepde %5lu linlincopies: %5lu physzero: %5lu invlpgs: %5lu pagefaults: %5lu vmreq: %5lu\n",
u/system_hz,
PERSEC(cr3_test), PERSEC(cr3_reload),
PERSEC(straightpdes), PERSEC(newpde),
PERSEC(overwritepde),
PERSEC(linlincopies), PERSEC(physzero),
PERSEC(invlpgs), PERSEC(npagefaults),
PERSEC(vmreqs));
cr3_reload = 0;
cr3_test = 0;
newpde = overwritepde = linlincopies =
physzero = invlpgs = straightpdes = 0;
npagefaults = 0;
vmreqs = 0;
prevu = u;
#if DEBUG_TRACE
for (stp = BEG_PROC_ADDR; stp < END_PROC_ADDR; stp++) {
int ps = PERSEC(stp->p_schedules);
if(isemptyp(stp))
continue;
if(ps > 10) {
printf("%s %d ", stp->p_name, ps);
stp->p_schedules = 0;
}
}
printf("\n");
#endif
}
}
#endif
sys_call_code = (unsigned) m.m_type;
call_nr = sys_call_code - KERNEL_CALL;
who_e = m.m_source;

View File

@@ -7,6 +7,7 @@
*/
#include "../system.h"
#include "../vm.h"
#include <signal.h>
#include <minix/endpoint.h>
@@ -94,6 +95,7 @@ register message *m_ptr; /* pointer to request message */
/* Install new map */
r = newmap(rpc, map_ptr);
FIXLINMSG(rpc);
/* Don't schedule process in VM mode until it has a new pagetable. */
if(m_ptr->PR_FORK_FLAGS & PFF_VMINHIBIT) {

View File

@@ -96,41 +96,6 @@ register message *m_ptr; /* pointer to request message */
printf("type %d\n", p->p_vmrequest.type);
#endif
#if DEBUG_VMASSERT
{
vmassert(target->p_rts_flags);
/* Sanity check. */
if(p->p_vmrequest.vmresult == OK) {
int r;
vmassert(!verifyrange);
verifyrange = 1;
r = CHECKRANGE(target,
p->p_vmrequest.start,
p->p_vmrequest.length,
p->p_vmrequest.writeflag);
vmassert(verifyrange);
verifyrange = 0;
if(r != OK) {
kprintf("SYSTEM: request by %d: on ep %d: 0x%lx-0x%lx, wrflag %d, stack %s, failed\n",
p->p_endpoint, target->p_endpoint,
p->p_vmrequest.start, p->p_vmrequest.start + p->p_vmrequest.length,
p->p_vmrequest.writeflag,
p->p_vmrequest.stacktrace);
printf("printing pt of %d (0x%lx)\n",
vm_print(target->p_endpoint),
target->p_seg.p_cr3
);
vm_print(target->p_seg.p_cr3);
minix_panic("SYSTEM: fail but VM said OK", NO_NUM);
}
}
}
#endif
vmassert(RTS_ISSET(target, VMREQTARGET));
RTS_LOCK_UNSET(target, VMREQTARGET);
@@ -163,10 +128,9 @@ kprintf("SYSTEM: request by %d: on ep %d: 0x%lx-0x%lx, wrflag %d, stack %s, fail
minix_panic("do_vmctl: paging enabling failed", NO_NUM);
vmassert(p->p_delivermsg_lin ==
umap_local(p, D, p->p_delivermsg_vir, sizeof(message)));
if(newmap(p, m_ptr->SVMCTL_VALUE) != OK)
if(newmap(p, (struct mem_map *) m_ptr->SVMCTL_VALUE) != OK)
minix_panic("do_vmctl: newmap failed", NO_NUM);
p->p_delivermsg_lin =
umap_local(p, D, p->p_delivermsg_vir, sizeof(message));
FIXLINMSG(p);
vmassert(p->p_delivermsg_lin);
return OK;
}

View File

@@ -118,13 +118,13 @@ PUBLIC struct boot_image image[] = {
{CLOCK,clock_task,TSK_F, 8, TASK_Q, TSK_S, TSK_T, 0, no_c,"clock" },
{SYSTEM, sys_task,TSK_F, 8, TASK_Q, TSK_S, TSK_T, 0, no_c,"system"},
{HARDWARE, 0,TSK_F, 8, TASK_Q, HRD_S, 0, 0, no_c,"kernel"},
{PM_PROC_NR, 0,SVM_F, 32, 4, 0, SRV_T, SRV_M, c(pm_c),"pm" },
{FS_PROC_NR, 0,SVM_F, 32, 5, 0, SRV_T, SRV_M, c(fs_c),"vfs" },
{PM_PROC_NR, 0,SRV_F, 32, 4, 0, SRV_T, SRV_M, c(pm_c),"pm" },
{FS_PROC_NR, 0,SRV_F, 32, 5, 0, SRV_T, SRV_M, c(fs_c),"vfs" },
{RS_PROC_NR, 0,SVM_F, 4, 4, 0, SRV_T, SYS_M, c(rs_c),"rs" },
{DS_PROC_NR, 0,SVM_F, 4, 4, 0, SRV_T, SYS_M, c(ds_c),"ds" },
{DS_PROC_NR, 0,SRV_F, 4, 4, 0, SRV_T, SYS_M, c(ds_c),"ds" },
{TTY_PROC_NR, 0,SVM_F, 4, 1, 0, SRV_T, SYS_M,c(tty_c),"tty" },
{MEM_PROC_NR, 0,SVM_F, 4, 3, 0, SRV_T, SYS_M,c(mem_c),"memory"},
{LOG_PROC_NR, 0,SVM_F, 4, 2, 0, SRV_T, SYS_M,c(drv_c),"log" },
{LOG_PROC_NR, 0,SRV_F, 4, 2, 0, SRV_T, SYS_M,c(drv_c),"log" },
{MFS_PROC_NR, 0,SVM_F, 32, 5, 0, SRV_T, SRV_M, c(fs_c),"mfs" },
{VM_PROC_NR, 0,SRV_F, 32, 2, 0, SRV_T, SRV_M, c(vm_c),"vm" },
{INIT_PROC_NR, 0,USR_F, 8, USER_Q, 0, USR_T, USR_M, c(usr_c),"init" },

View File

@@ -7,6 +7,15 @@
#define EFAULT_SRC -995
#define EFAULT_DST -994
#define FIXLINMSG(prp) { prp->p_delivermsg_lin = umap_local(prp, D, prp->p_delivermsg_vir, sizeof(message)); }
#define PHYS_COPY_CATCH(src, dst, size, a) { \
vmassert(intr_disabled()); \
catch_pagefaults++; \
a = phys_copy(src, dst, size); \
catch_pagefaults--; \
}
#endif