/* * Called by sys_execve() * Despite its name, this function sets up the user stack */ void arch_setup_kernel_stack(register struct task_struct *t) { put_ustack(t, -2, USER_FLAGS); /* Flags */ put_ustack(t, -4, (int) t->t_xregs.cs); /* user CS */ put_ustack(t, -6, 0); /* addr 0 */ put_ustack(t, -8, 0); /* user BP */ t->t_regs.sp -= 8; }
void arch_setup_sighandler_stack(register struct task_struct *t, __sighandler_t addr,unsigned signr) { debug5("Stack %x was %x %x %x %x\n", addr, get_ustack(t,0), get_ustack(t,2), get_ustack(t,4), get_ustack(t,6)); put_ustack(t, -4, (int)get_ustack(t,0)); put_ustack(t, -2, (int)addr); put_ustack(t, 0, (int)get_ustack(t,4)); put_ustack(t, 4, (int)get_ustack(t,2)); put_ustack(t, 2, (int)get_ustack(t,6)); put_ustack(t, 6, (int)signr); t->t_regs.sp -= 4; debug6("Stack is %x %x %x %x %x %x\n", get_ustack(t,0), get_ustack(t,2), get_ustack(t,4), get_ustack(t,6), get_ustack(t,8), get_ustack(t,10)); }
static int swap_in(seg_t base, int chint) { register struct malloc_hole *o; struct malloc_hole *so; int ct, blocks; register struct task_struct *t; so = find_hole(&swapmap, base); /* Find memory for this segment */ o = best_fit_hole(&memmap, so->extent << 6); if (o == NULL) return -1; /* Now read the segment in */ split_hole(&memmap, o, so->extent << 6); o->flags = HOLE_USED; o->refcount = so->refcount; blocks = so->extent; for (ct = 0; ct < blocks; ct++) { swap_buf.b_blocknr = so->page_base + ct; swap_buf.b_dev = swap_dev; swap_buf.b_lock = 0; swap_buf.b_dirty = 0; swap_buf.b_uptodate = 0; swap_buf.b_seg = o->page_base; swap_buf.b_data = ct << 10; ll_rw_blk(READ, &swap_buf); wait_on_buffer(&swap_buf); } /* * Update the memory management tables */ for_each_task(t) { int c = t->mm.flags; if (t->mm.cseg == base && c & CS_SWAP) { debug2("MALLOC: swapping in code of pid %d seg %x\n", t->pid, t->mm.cseg); t->mm.cseg = o->page_base; t->mm.flags &= ~CS_SWAP; } if (t->mm.dseg == base && c & DS_SWAP) { debug2("MALLOC: swapping in data of pid %d seg %x\n", t->pid, t->mm.dseg); t->mm.dseg = o->page_base; t->mm.flags &= ~DS_SWAP; } if (c && !t->mm.flags) { t->t_regs.cs = t->mm.cseg; t->t_regs.ds = t->mm.dseg; t->t_regs.ss = t->mm.dseg; put_ustack(t, 2, t->t_regs.cs); } } /* Our equivalent of the Linux swap cache. Try and avoid writing CS * back. Need to kill segments on last exit for this to work, and * keep a table - TODO */ #if 0 if (chint==0) #endif { so->refcount = 0; so->flags = HOLE_FREE; sweep_holes(&swapmap); } return 0; }