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
}
if(vec_nr == PAGE_FAULT_VECTOR) {
- pagefault(saved_proc, trap_errno);
+ pagefault(old_eip, saved_proc, trap_errno);
return;
}
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) {
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 | \
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;
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);
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,
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) {
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);
}
.define save
.define _pagefault_cr2
.define _pagefault_count
+.define _old_eip_ptr
+.define _old_eax_ptr
.define errexception
.define exception1
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
_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) );
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 { \
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;
*===========================================================================*/
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;
}
/*===========================================================================*