further messing with page fault handling

This commit is contained in:
Ben Gras 2009-05-29 18:47:31 +00:00
parent 85881e9995
commit f16eb59bbf
7 changed files with 56 additions and 50 deletions

View File

@ -18,32 +18,48 @@ 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;
void pagefault(struct proc *pr, int trap_errno)
void pagefault(vir_bytes old_eip, struct proc *pr, int trap_errno)
{
int s;
vir_bytes ph;
u32_t pte;
int procok = 0, pcok = 0, rangeok = 0;
vmassert(old_eip_ptr);
vmassert(old_eax_ptr);
vmassert(*old_eip_ptr == old_eip);
vmassert(old_eip_ptr != &old_eip);
vmassert(pagefault_count == 1);
if((iskernelp(pr) || k_reenter) && catch_pagefaults
&& (pr->p_reg.pc > (vir_bytes) _memcpy_k &&
pr->p_reg.pc < (vir_bytes) _memcpy_k_fault) &&
pagefault_cr2 >= catchrange_lo &&
pagefault_cr2 < catchrange_hi) {
kprintf("handling pagefault during copy\n");
pr->p_reg.pc = (vir_bytes) _memcpy_k_fault;
pr->p_reg.retreg = pagefault_cr2;
pagefault_count = 0;
return;
if(catch_pagefaults &&
(rangeok = (pagefault_cr2 >= catchrange_lo &&
pagefault_cr2 < catchrange_hi))) {
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");
pagefault_count = 0;
*old_eip_ptr = _memcpy_k_fault;
*old_eax_ptr = pagefault_cr2;
return;
}
}
proc_stacktrace(pr);
kprintf("kernel stacktrace in pagefault: ");
util_stacktrace();
if(catch_pagefaults) {
printf("k_reenter: %d addr: 0x%lx range: 0x%lx-0x%lx\n",
k_reenter, pagefault_cr2, catchrange_lo, catchrange_hi);
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
@ -150,7 +166,7 @@ struct proc *t;
}
if(vec_nr == PAGE_FAULT_VECTOR) {
pagefault(saved_proc, trap_errno);
pagefault(old_eip, saved_proc, trap_errno);
return;
}
@ -214,7 +230,7 @@ PUBLIC void proc_stacktrace(struct proc *proc)
while(v_bp) {
#define PRCOPY(pr, pv, v, n) \
(iskernelp(pr) ? (memcpy(v, pv, n), OK) : \
(iskernelp(pr) ? (memcpy((char *) v, (char *) pv, n), OK) : \
data_copy(pr->p_endpoint, pv, SYSTEM, (vir_bytes) (v), n))
if(PRCOPY(proc, v_bp, &v_hbp, sizeof(v_hbp)) != OK) {

View File

@ -723,7 +723,6 @@ u32_t read_cr3(void)
kprintf("kernel: pde %d 0x%lx for proc %d\n", \
pde_index, pdeval, PROC->p_endpoint); \
} \
if(copyverbose) { kprintf("installing pde val 0x%lx from pde index %d of proc %d into my pde\n", pdeval, pde_index, PROC->p_endpoint); } \
} else { \
pdeval = (LINADDR & I386_VM_ADDR_MASK_4MB) | \
I386_VM_BIGPAGE | I386_VM_PRESENT | \
@ -745,7 +744,7 @@ int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, u8_t *vsrc,
int srcseg,
struct proc *dstproc, vir_bytes dstlinaddr, u8_t *vdst,
int dstseg,
vir_bytes bytes, int copyverbose)
vir_bytes bytes)
{
u32_t addr;
int procslot;
@ -780,8 +779,6 @@ int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, u8_t *vsrc,
vir_bytes srcoffset, dstoffset;
vir_bytes chunk = bytes;
FIXME("copyverbose");
/* Set up 4MB ranges. */
CREATEPDE(srcproc, srcptr, srclinaddr, srcoffset,
freepdes[FREEPDE_SRC], vsrc, srcseg, chunk, bytes);
@ -850,7 +847,6 @@ int vm_phys_memset(phys_bytes ph, u8_t c, phys_bytes bytes)
vir_bytes chunk = bytes;
u8_t *ptr;
u32_t offset;
int copyverbose = 0;
CREATEPDE(((struct proc *) NULL), ptr, ph,
offset, freepdes[FREEPDE_MEMSET], 0, 0, chunk, bytes);
/* We can memset as many bytes as we have remaining,
@ -957,20 +953,11 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
if(vm_running) {
int r;
struct proc *target, *caller;
int verbose = 0;
if(procs[_SRC_] && procs[_DST_] &&
procs[_SRC_]->p_endpoint == PM_PROC_NR &&
(procs[_DST_]->p_endpoint == INIT_PROC_NR ||
procs[_DST_]->p_endpoint == 35549) &&
bytes == sizeof(message)) {
verbose = 1;
}
if((r=lin_lin_copy(procs[_SRC_], phys_addr[_SRC_],
(u8_t *) src_addr->offset, src_addr->segment,
procs[_DST_], phys_addr[_DST_], (u8_t *) dst_addr->offset,
dst_addr->segment, bytes, verbose)) != OK) {
dst_addr->segment, bytes)) != OK) {
if(r != EFAULT_SRC && r != EFAULT_DST)
minix_panic("lin_lin_copy failed", r);
if(!vmcheck) {
@ -1002,17 +989,6 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
NOREC_RETURN(virtualcopy, VMSUSPEND);
}
if(verbose) {
static int count = 0;
message *m;
kprintf("lin_lin_copy: PM to %d: %d bytes copy OK\n",
procs[_DST_]->p_endpoint, bytes);
if(count++ < 10) {
vm_print(procs[_SRC_]->p_seg.p_cr3);
vm_print(procs[_DST_]->p_seg.p_cr3);
}
}
NOREC_RETURN(virtualcopy, OK);
}

View File

@ -76,6 +76,8 @@ begbss:
.define save
.define _pagefault_cr2
.define _pagefault_count
.define _old_eip_ptr
.define _old_eax_ptr
.define errexception
.define exception1
@ -524,10 +526,16 @@ errexception:
sseg pop (ex_number)
sseg pop (trap_errno)
exception1: ! Common for all exceptions.
sseg mov (_old_eax_ptr), esp ! where will eax be saved?
sseg sub (_old_eax_ptr), PCREG-AXREG ! here
push eax ! eax is scratch register
mov eax, 0+4(esp) ! old eip
sseg mov (old_eip), eax
mov eax, esp
add eax, 4
sseg mov (_old_eip_ptr), eax
movzx eax, 4+4(esp) ! old cs
sseg mov (old_cs), eax
mov eax, 8+4(esp) ! old eflags

View File

@ -76,6 +76,7 @@ _PROTOTYPE( void phys_outsw, (U16_t port, phys_bytes buf, size_t count) );
_PROTOTYPE( void i386_invlpg_level0, (void) );
_PROTOTYPE( int _memcpy_k, (void *dst, void *src, size_t n) );
_PROTOTYPE( int _memcpy_k_fault, (void) );
_PROTOTYPE( u32_t read_cr3, (void) );
/* protect.c */
_PROTOTYPE( void prot_init, (void) );

View File

@ -87,17 +87,17 @@ FORWARD _PROTOTYPE( void pick_proc, (void));
kprintf("error %d\n", r); \
minix_panic("CopyMess: copy error", __LINE__); \
} \
vm_suspend(dp, dp); \
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__);\
} \
(dp)->p_vmrequest.saved.msgcopy.msgbuf.m_source = e; \
(dp)->p_vmrequest.type = VMSTYPE_MSGCOPY; \
}
#define CopyMess(s,sp,sm,dp,dm) do { \

View File

@ -43,8 +43,11 @@ register message *m_ptr; /* pointer to request message */
if(!RTS_ISSET(rp, VMREQUEST))
minix_panic("do_vmctl: no VMREQUEST set", NO_NUM);
printf("kernel: vm request sent by: %s / %d about %d\n",
rp->p_name, rp->p_endpoint, rp->p_vmrequest.who);
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);
/* Reply with request fields. */
m_ptr->SVMCTL_MRG_ADDR = (char *) rp->p_vmrequest.start;

View File

@ -30,11 +30,13 @@
*===========================================================================*/
PUBLIC vir_bytes arch_map2vir(struct vmproc *vmp, vir_bytes addr)
{
vir_bytes bottom = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
vir_bytes textstart = CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_phys);
vir_bytes datastart = CLICK2ABS(vmp->vm_arch.vm_seg[D].mem_phys);
vm_assert(bottom <= addr);
/* Could be a text address. */
vm_assert(datastart <= addr || textstart <= addr);
return addr - bottom;
return addr - datastart;
}
/*===========================================================================*