further messing with page fault handling
This commit is contained in:
parent
85881e9995
commit
f16eb59bbf
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) );
|
||||
|
@ -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 { \
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
Loading…
x
Reference in New Issue
Block a user