You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(6) |
Sep
(2) |
Oct
(43) |
Nov
(4) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(78) |
Feb
(97) |
Mar
(29) |
Apr
(2) |
May
(22) |
Jun
(38) |
Jul
(11) |
Aug
(27) |
Sep
(40) |
Oct
(2) |
Nov
(17) |
Dec
(8) |
2002 |
Jan
|
Feb
(2) |
Mar
(1) |
Apr
(480) |
May
(456) |
Jun
(12) |
Jul
|
Aug
(1) |
Sep
|
Oct
(18) |
Nov
(3) |
Dec
(6) |
2003 |
Jan
|
Feb
(18) |
Mar
(1) |
Apr
|
May
(6) |
Jun
(147) |
Jul
(7) |
Aug
(3) |
Sep
(235) |
Oct
(10) |
Nov
(2) |
Dec
(1) |
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Andy P. <at...@us...> - 2001-09-01 12:21:19
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv26693 Modified Files: regdump.c Log Message: I find --- less useful than the numbers. Nasty hack to dump more information Index: regdump.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/regdump.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- regdump.c 2001/08/20 21:30:52 1.3 +++ regdump.c 2001/09/01 12:21:15 1.4 @@ -108,11 +108,18 @@ if (i%4 == 0) { printk(" %08lx ", (unsigned long)(p+i)); } + if ((p+i)<PAGE_OFFSET){ if (get_user(x, p+i)) { printk(" --------"); } else { printk(" %08x", x); } + } else { + x= *(p+i); + printk(" %08x", x); + } + + if (i%4 == 3) { printk("\n"); } |
From: Andy P. <at...@us...> - 2001-09-01 12:19:52
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv26247 Modified Files: pgalloc.c Log Message: fix the stupid pgtable->pgd_table cache size counter bug Index: pgalloc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgalloc.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- pgalloc.c 2001/08/31 11:50:57 1.6 +++ pgalloc.c 2001/09/01 12:19:47 1.7 @@ -36,7 +36,7 @@ if ((ret = pgd_quicklist) != NULL) { pgd_quicklist = (unsigned long *)(*ret); ret[0] = 0; - pgtable_cache_size--; + pgd_cache_size--; } return (pgd_t *)ret; } |
From: Andy P. <at...@us...> - 2001-08-31 14:10:47
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv2202 Modified Files: pagelet_pgprot.h pagelet_pte.h Log Message: page_chg_mask incorrectly defined, and pte_modify modified. Some things shifted about Index: pagelet_pgprot.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pagelet_pgprot.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- pagelet_pgprot.h 2001/02/15 01:17:23 1.1 +++ pagelet_pgprot.h 2001/08/31 11:53:29 1.2 @@ -56,10 +56,9 @@ #define _PAGE_TABLE (_PAGE_VALID | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_UW ) #define _KERNPG_TABLE (_PAGE_VALID | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_KW ) -/* UW has fewer bits set than UR */ -#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_UR ) +#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) -#define PAGE_PROT_MASK (0x1e000000) +/*#define PAGE_PROT_MASK (0x1e000000)*/ #define PAGE_NONE __pgprot(_PAGE_VALID | _PAGE_ACCESSED) #define PAGE_SHARED __pgprot(_PAGE_VALID | _PAGE_ACCESSED | _PAGE_UW ) Index: pagelet_pte.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pagelet_pte.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- pagelet_pte.h 2001/07/31 17:33:26 1.6 +++ pagelet_pte.h 2001/08/31 11:53:29 1.7 @@ -149,7 +149,7 @@ */ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - pte_val(pte) &= PAGELET_MASK; + pte_val(pte) &= _PAGE_CHG_MASK; pte_val(pte) |= pgprot_val(newprot); return pte; } @@ -242,6 +242,7 @@ return pte; } +/* used in arch/vax/mm/pgalloc.c */ static inline pte_t pte_mkinvalid(pte_t pte) { pte_val(pte) &= ~_PAGE_VALID; |
From: Andy P. <at...@us...> - 2001-08-31 14:04:51
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv1856 Modified Files: fault.c pgalloc.c Log Message: Fix double pte invalidate bug Index: fault.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/fault.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- fault.c 2001/08/21 20:09:34 1.10 +++ fault.c 2001/08/31 11:50:57 1.11 @@ -59,7 +59,7 @@ unsigned fixup; #ifdef VAX_MM_DEBUG - printk("mmfault: fault at %8x, pc %8x, psl %8x, reason %8x\n",info->addr, info->pc, info->psl, info->reason); + printk("mmfault: pid %d fault at %8x, pc %8x, psl %8x, reason %8x\n",current->pid,info->addr, info->pc, info->psl, info->reason); printk("mmfault:p0br %8lx, p0lr %8lx, p1br %8lx, p1lr %8lx\n",Xmfpr(PR_P0BR),Xmfpr(PR_P0LR),Xmfpr(PR_P1BR),Xmfpr(PR_P1LR)); #endif /* This check, and the mm != NULL checks later, will be removed @@ -105,6 +105,7 @@ } survive: { + int fault; fault = handle_mm_fault(mm, vma, address, reason & REASON_WRITE); if (!fault) @@ -112,6 +113,7 @@ if (fault < 0) goto out_of_memory; } + up(&mm->mmap_sem); return; @@ -120,6 +122,7 @@ * Fix it, but check if it's kernel or user first.. */ bad_area: + up(&mm->mmap_sem); if (user_mode(regs)) { @@ -127,16 +130,17 @@ "pid %d, virtual address %08lx, reason mask %08x, " "PC %08x, PSL %08x\n", current->pid, address, reason, info->pc, info->psl); - printk("do_page_fault: sending SIGSEGV\n"); + show_regs(regs); + show_cpu_regs(); + + printk("do_page_fault: sending SIGSEGV\n"); force_sig(SIGSEGV, current); - /* signals arent implemented yet */ - /* They are now atp aug 17 2001 */ -// machine_halt(); return; } no_context: + /* Are we prepared to handle this fault as an exception? */ if ((fixup = search_exception_table(regs->pc)) != 0) { regs->pc = fixup; @@ -147,6 +151,7 @@ * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ + printk(KERN_ALERT "Unable to handle kernel paging request at " "virtual address %08lx, reason mask %08x, " "PC %08x, PSL %08x\n", Index: pgalloc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgalloc.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- pgalloc.c 2001/08/23 09:27:01 1.5 +++ pgalloc.c 2001/08/31 11:50:57 1.6 @@ -225,7 +225,6 @@ s0pte = GET_SPTE_VIRT(ptep); addr = (unsigned long)(((pte_val(*s0pte)&PAGELET_PFN_MASK)<<PAGELET_SHIFT)|PAGE_OFFSET); -// printk("get_pageaddr: ptep %p, spte %8lx, *spte %8lx, addr %8lx\n",ptep,s0pte,pte_val(*s0pte),addr); return addr; } @@ -249,7 +248,7 @@ * This is like remap_pte_range in memory.c but VAX specific * * s0addr is the address in S0 space that we need to remap the page - * pointed to pte_page to. We also clear the page pointed at by pte_page + * pointed at by pte_page to. We also clear the page pointed at by pte_page */ void remap_and_clear_pte_page(pmd_t *s0addr, pte_t *pte_page) { @@ -301,7 +300,6 @@ s0pte = GET_SPTE_VIRT(s0addr); set_pte(s0pte, pte_mkinvalid(*s0pte)); -// print_pte(s0pte); /* FIXME: these flush_tlb_alls need replacing with flush_tlb_8 */ flush_tlb_all(); // __flush_tlb_one(s0addr); @@ -444,8 +442,6 @@ is_p1=pgdp->segment; -// printk(KERN_DEBUG "ptealloc:pgd %8p, pgd->segment %ld, pgd->br %8lx, pgd->lr %lx, pgd->slot %8lx\n",pgdp,pgdp->segment,pgdp->br,pgdp->lr,pgdp->slot); - /* make an adjusted address + calculate linear page table entry */ adjusted_address = (((pmd-pmd_basep))<<(PAGE_SHIFT+7))+ (address&~PMD_MASK); @@ -566,12 +562,11 @@ remap_pte_invalidate(pte); } -/* we don't allocate any space for pte, just clear the one passed to us */ +/* This is only ever called from do_pgt_cache, all the unmapping have been done + * before the page has been placed on the pgt cache */ void free_pte_slow(pte_t *pte) { - free_page((unsigned long) get_pageaddr_from_pte(pte)); - /* invalidate the S0 pte that maps this */ - remap_pte_invalidate(pte); + free_page(pte); } void pte_free_kernel(pte_t *pte) |
From: Andy P. <at...@us...> - 2001-08-27 23:39:31
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv3881 Modified Files: signal.c Log Message: Add trampoline code to make user signal handlers work. Index: signal.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/signal.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- signal.c 2001/08/17 20:20:41 1.4 +++ signal.c 2001/08/27 23:39:28 1.5 @@ -40,7 +40,7 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs); +int do_signal(sigset_t *oldset, struct pt_regs *regs); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) { @@ -96,7 +96,7 @@ while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(0, &saveset, regs)) + if (do_signal(&saveset, regs)) return -EINTR; } } @@ -128,7 +128,7 @@ while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(0, &saveset, regs)) + if (do_signal(&saveset, regs)) return -EINTR; } } @@ -178,12 +178,13 @@ */ struct sigframe { - char *pretcode; + int sig; struct sigcontext sc; unsigned long extramask[_NSIG_WORDS-1]; - unsigned char retcode[8]; /* trampoline code */ + unsigned char retcode[20]; /* trampoline code */ }; +/* FIXME: this dont work ... */ struct rt_sigframe { char *pretcode; struct siginfo *pinfo; @@ -241,7 +242,7 @@ if (((long)frame) & 3) goto badframe; - if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask) || (_NSIG_WORDS > 1 @@ -267,6 +268,8 @@ return 0; } + +/* FIXME: _rt_ stuff is completely unchecked + probably does not work */ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *frame = (struct rt_sigframe *)(regs->sp); @@ -342,7 +345,7 @@ } /* make sure the frame is dword-aligned */ - + sp &= ~3; return (void *)(sp - frame_size); @@ -360,14 +363,20 @@ sigset_t *set, struct pt_regs * regs) { struct sigframe *frame; - unsigned long return_ip; int err = 0; frame = get_sigframe(ka, regs, sizeof(*frame)); - + + +#ifdef DEBUG_SIG + printk("setup_frame: pid %d, sig %d, regs %p, frame %p, sigaction %p\n",current->pid,sig,regs,frame,ka); + show_regs(regs); +#endif if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; + /* write the signal onto the stack */ + err |= __put_user(sig, (unsigned int *)&frame->sig); err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); if (err) goto give_sigsegv; @@ -381,27 +390,127 @@ /* Set up to return from userspace. If provided, use a stub already in userspace. */ + + /* We do this differently to other ports. Each function has a two byte RSM. + * (due to the calling convention). Each sighandler will expect to be + * CALLS'd and will RET from that. So we cant just muck about with PC's on the + * stack like the i386. So we use the trampoline code on the stack a bit more. + * The easiest way to skip around all this is to calls the signal + * handler, and then either calls the restorer, or chmk to sys_sigreturn */ + + /* CALLS $1, */ + err |= __put_user(0xfb, (char *)(frame->retcode+0)); + err |= __put_user(0x01, (char *)(frame->retcode+1)); + /* (absolute address)*/ + err |= __put_user(0x9f, (char *)(frame->retcode+2)); + /* sighandler */ + err |= __put_user(((unsigned long) ka->sa.sa_handler), (unsigned long *)(frame->retcode + 3)); + if (ka->sa.sa_flags & SA_RESTORER) { - return_ip = (unsigned long)ka->sa.sa_restorer; + /* CALLS $0,*/ + err |= __put_user(0xfb, (char *)(frame->retcode+7)); + err |= __put_user(0x00, (char *)(frame->retcode+8)); + /* (absolute address)*/ + err |= __put_user(0x9f, (char *)(frame->retcode+9)); + /* restorer */ + err |= __put_user(((unsigned long) ka->sa.sa_restorer), (unsigned long *)(frame->retcode + 10)); + /* plus a halt */ + err |= __put_user(0x00, (char *)(frame->retcode+14)); } else { - /* trampoline - the desired return ip is the retcode itself */ - return_ip = (unsigned long)&frame->retcode; - /* This is chmk __NR_sigreturn; */ - /* TODO: check byteorder */ - err |= __put_user(0xbc8f, (short *)(frame->retcode+0)); - err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2)); + /* perform a syscall to sys_sigreturn. First set up the + * argument list to avoid confusing it */ + + /* pushl $0x0 */ + err |= __put_user(0xdd, (char *)(frame->retcode+7)); + err |= __put_user(0x00, (char *)(frame->retcode+8)); + /* movl sp, ap */ + err |= __put_user(0xd0, (char *)(frame->retcode+9)); + err |= __put_user(0x5e, (char *)(frame->retcode+10)); + err |= __put_user(0x5c, (char *)(frame->retcode+11)); + /* chmk __NR_sigreturn; */ + err |= __put_user(0xbc, (char *)(frame->retcode+12)); + err |= __put_user(0x8f, (char *)(frame->retcode+13)); + err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+14)); + /* plus a halt */ + err |= __put_user(0x00, (char *)(frame->retcode+16)); } - err |= __put_user(return_ip, &frame->pretcode); - if (err) goto give_sigsegv; +#ifdef DEBUG_SIG + printk("setup_frame: pid %d, frame->retcode %p, sa_handler %p\n",current->pid,frame->retcode,ka->sa.sa_handler); +#endif /* Set up registers for signal handler */ - - regs->pc = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ - regs->sp = frame; - + + regs->pc = (unsigned long) frame->retcode; /* what we enter NOW */ + regs->fp = regs->sp; + regs->sp = frame; + __mtpr(frame,PR_USP); /* and into to the register, ready for REI */ + +#ifdef DEBUG_SIG + printk("setup_frame: pid %d, regs->pc %8lx, regs->sp %8lx, regs->ap %8lx\n",current->pid,regs->pc,regs->sp,regs->ap); + { + unsigned char c[4]; + __get_user(c[0], (char *)&frame->sig); + __get_user(c[1], (char *)&frame->sig+1); + __get_user(c[2], (char *)&frame->sig+2); + __get_user(c[3], (char *)&frame->sig+3); + printk("setup_frame: %p %1x %p %1x %p %1x %p %1x\n", + &frame->sig, c[0], + &frame->sig+1, c[1], + &frame->sig+2, c[2], + &frame->sig+3, c[3]); + } + { + unsigned char c[4]; + __get_user(c[0], (char *)frame->retcode); + __get_user(c[1], (char *)frame->retcode+1); + __get_user(c[2], (char *)frame->retcode+2); + __get_user(c[3], (char *)frame->retcode+3); + printk("setup_frame: %p %1x %p %1x %p %1x %p %1x\n", + frame->retcode, c[0], + frame->retcode+1, c[1], + frame->retcode+2, c[2], + frame->retcode+3, c[3]); + } + { + unsigned char c[4]; + __get_user(c[0], (char *)frame->retcode+4); + __get_user(c[1], (char *)frame->retcode+5); + __get_user(c[2], (char *)frame->retcode+6); + __get_user(c[3], (char *)frame->retcode+7); + printk("setup_frame: %p %1x %p %1x %p %1x %p %1x\n", + frame->retcode+4, c[0], + frame->retcode+5, c[1], + frame->retcode+6, c[2], + frame->retcode+7, c[3]); + } + { + unsigned char c[4]; + __get_user(c[0], (char *)frame->retcode+8); + __get_user(c[1], (char *)frame->retcode+9); + __get_user(c[2], (char *)frame->retcode+10); + __get_user(c[3], (char *)frame->retcode+11); + printk("setup_frame: %p %1x %p %1x %p %1x %p %1x\n", + frame->retcode+8, c[0], + frame->retcode+9, c[1], + frame->retcode+10, c[2], + frame->retcode+11, c[3]); + } + { + unsigned char c[4]; + __get_user(c[0], (char *)frame->retcode+12); + __get_user(c[1], (char *)frame->retcode+13); + __get_user(c[2], (char *)frame->retcode+14); + __get_user(c[3], (char *)frame->retcode+15); + printk("setup_frame: %p %1x %p %1x %p %1x %p %1x\n", + frame->retcode+12, c[0], + frame->retcode+13, c[1], + frame->retcode+14, c[2], + frame->retcode+15, c[3]); + } +#endif return; give_sigsegv: @@ -410,6 +519,7 @@ force_sig(SIGSEGV, current); } +/* FIXME: this is bogus */ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs * regs) { @@ -504,7 +614,10 @@ } /* Set up the stack frame */ - if (ka->sa.sa_flags & SA_SIGINFO) +#ifdef DEBUG_SIG + printk("handle_signal: setup_frame(sig=%d,ka=%p,oldset=%d,regs=%p)\n",sig,ka,oldset,regs); +#endif + if (ka->sa.sa_flags & SA_SIGINFO) setup_rt_frame(sig, ka, info, oldset, regs); else setup_frame(sig, ka, oldset, regs); @@ -526,11 +639,11 @@ * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) +int do_signal(sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; struct k_sigaction *ka; - + int canrestart; /* * We want the common case to go fast, which * is why we may in certain cases get here from @@ -540,16 +653,24 @@ if (!user_mode(regs)) return 1; + /* FIXME: */ + canrestart=0; +#ifdef DEBUG_SIG + printk("do_signal: pid %d,canrestart %d, current->sigpending %d,current->blocked %d ", current->pid,canrestart,current->sigpending,current->blocked); +#endif if (!oldset) oldset = ¤t->blocked; + for (;;) { unsigned long signr; spin_lock_irq(¤t->sigmask_lock); signr = dequeue_signal(¤t->blocked, &info); spin_unlock_irq(¤t->sigmask_lock); - +#ifdef DEBUG_SIG + printk(" sig %d\n",signr); +#endif if (!signr) break; @@ -589,6 +710,9 @@ if (ka->sa.sa_handler == SIG_IGN) { if (signr != SIGCHLD) continue; +#ifdef DEBUG_SIG + printk("do_signal: waiting for sigchld\n"); +#endif /* Check for SIGCHLD: it's special. */ while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) /* nothing */; @@ -597,7 +721,9 @@ if (ka->sa.sa_handler == SIG_DFL) { int exit_code = signr; - +#ifdef DEBUG_SIG + printk("do_signal: invoking default handler for sig %d\n",signr); +#endif /* Init gets no signals it doesn't want. */ if (current->pid == 1) continue; @@ -631,11 +757,16 @@ sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; +#ifdef DEBUG_SIG + printk("handle_sig: do_exit exit_code=%d\n",exit_code); +#endif do_exit(exit_code); /* NOTREACHED */ } } - +#ifdef DEBUG_SIG + printk("do_signal: handle_signal(canrestart=%d,signr=%d,info=%p,ka->sa.sa_handler=%p)\n",canrestart,signr,info,ka->sa.sa_handler); +#endif /* Whee! Actually deliver the signal. */ handle_signal(canrestart, signr, ka, &info, oldset, regs); return 1; |
From: Andy P. <at...@us...> - 2001-08-23 09:29:18
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv28094 Modified Files: pgalloc.h Log Message: Move some functions from here to pgalloc.c Fixup the freeing of pages from the page cache to use correct addresses Index: pgalloc.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pgalloc.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- pgalloc.h 2001/08/20 21:34:48 1.10 +++ pgalloc.h 2001/08/23 09:29:15 1.11 @@ -105,11 +105,13 @@ extern void pmd_free_kernel(pmd_t *pmd); extern void pte_free(pte_t *pte); extern unsigned long get_pageaddr_from_pte(pte_t *ptep); +extern void free_pte_slow(pte_t *pte); extern pte_t *get_pte_slow(void); extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset); extern void remap_and_clear_pte_page(pmd_t *s0addr, pte_t *page); extern void remap_pte_invalidate(pmd_t *s0addr); +extern void pte_free_kernel(pte_t *pte); extern __inline__ pte_t *get_pte_fast(void) { @@ -130,16 +132,8 @@ pgtable_cache_size++; } -/* we don't allocate any space for pte, just clear the one passed to us */ -extern __inline__ void free_pte_slow(pte_t *pte) -{ - pte_clear(pte); - free_page((unsigned long)pte); -} - extern __inline__ void page_clear(pte_t *pte) {memset(pte, 0, PAGE_SIZE);} -#define pte_free_kernel(pte) free_pte_fast(pte) #define pgd_free(pgd) free_pgd_fast(pgd) /* atp jun 01, moved these to arch/vax/mm/pgalloc.c */ |
From: Andy P. <at...@us...> - 2001-08-23 09:27:05
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv27320 Modified Files: pgalloc.c Log Message: Include last remaining functions from pgalloc.h that need special treatment. Fixup freeing of pages from pte cache to free correct addresses. Index: pgalloc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgalloc.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- pgalloc.c 2001/08/21 20:09:34 1.4 +++ pgalloc.c 2001/08/23 09:27:01 1.5 @@ -566,6 +566,23 @@ remap_pte_invalidate(pte); } +/* we don't allocate any space for pte, just clear the one passed to us */ +void free_pte_slow(pte_t *pte) +{ + free_page((unsigned long) get_pageaddr_from_pte(pte)); + /* invalidate the S0 pte that maps this */ + remap_pte_invalidate(pte); +} + +void pte_free_kernel(pte_t *pte) +{ +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM: pte_free_kernel called on pte %8p\n",pte); +#endif + printk(KERN_DEBUG "VAXMM: pte_free_kernel called on pte %8p\n",pte); + free_pte_fast(pte); +} + /* Find an entry in the third-level page table.. */ #ifdef VAX_MM_PGALLOC_DEBUG pte_t * pte_offset(pmd_t * dir, unsigned long address) |
From: Andy P. <at...@us...> - 2001-08-23 09:25:16
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv27208 Modified Files: pgtable.c Log Message: fix do_pgt_cache. Index: pgtable.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgtable.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- pgtable.c 2001/07/31 17:28:26 1.6 +++ pgtable.c 2001/08/23 09:25:13 1.7 @@ -29,7 +29,7 @@ } } -/* Note the factor of 8 in the length registers */ +/* Note no factor of 8 in the length registers */ void set_page_dir_kernel(pgd_t * pgdir) { __mtpr( (pgdir[2]).br, PR_SBR); @@ -43,10 +43,10 @@ int freed = 0; if(pgtable_cache_size > high) { do { - if(pgd_quicklist) - free_pgd_slow(get_pgd_fast()), freed++; - if(pmd_quicklist) - free_pmd_slow(get_pmd_fast()), freed++; +// if(pgd_quicklist) +// free_pgd_slow(get_pgd_fast()), freed++; +// if(pmd_quicklist) +// free_pmd_slow(get_pmd_fast()), freed++; if(pte_quicklist) free_pte_slow(get_pte_fast()), freed++; } while(pgtable_cache_size > low); |
From: Andy P. <at...@us...> - 2001-08-21 20:12:45
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv23832/mm Modified Files: task.h Log Message: Change task.h to more sane defaults for WSMAX and so forth Index: task.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/task.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- task.h 2001/07/31 17:33:26 1.1 +++ task.h 2001/08/21 20:12:42 1.2 @@ -15,17 +15,22 @@ /* TASK_WSMAX is the max virtual address space in P0 */ /* TASK_WSMAX must not be larger than 768MB. In the unlikely event that * you really want to allocate that much to a process, change PGD_SPECIAL below */ -#define TASK_WSMAX (40*1024*1024) +/* TASK_TXTMAX is the maximum program size, including shared libs */ +#define TASK_TXTMAX (16*1024*1024) + +/* TASK_MMAPMAX is the max space in P0 for the mmap() function , + contiguous with TASK_TXTMAX - Its basically the amount of memory you + give a process to play with */ +#define TASK_MMAPMAX (32*1024*1024) + /* TASK_STKMAX is the max space for the stack in P1 */ /* Like WSMAX above, the upper limit for this is set by PGD_SPECIAL below. If this * is above 256MB change PGD_SPECIAL */ #define TASK_STKMAX (8*1024*1024) -/* TASK_MMAPMAX is the max space in P0 for the mmap() function , - contiguous with TASK_WSMAX */ -#define TASK_MMAPMAX (8*1024*1024) +#define TASK_WSMAX (TASK_TXTMAX+TASK_MMAPMAX) /* TASK_MAXUPRC is the maximum number of user processes on the system * Think of this like balsetcnt on VMS. @@ -38,11 +43,11 @@ * space during mmap's. */ -#define TASK_UNMAPPED_BASE TASK_WSMAX +#define TASK_UNMAPPED_BASE TASK_TXTMAX /* calculations based on the above for the SPT */ /* NPTE_TASK = the number of HWPTE's needed to map a process */ -#define N_HWPTE_TASK_P0 ((TASK_WSMAX+TASK_MMAPMAX)>>PAGELET_SHIFT) +#define N_HWPTE_TASK_P0 ((TASK_WSMAX)>>PAGELET_SHIFT) #define N_HWPTE_TASK_P1 ((TASK_STKMAX)>>PAGELET_SHIFT) /* There are 4 4096 byte pages in the pmd. = 4x1024 hwptes. */ #define N_HWPTE_TASK_PMD ((4*1024)) @@ -60,7 +65,8 @@ /* The offsets into page table area from the start of this slot, in bytes */ #define P0PTE_OFFSET (N_HWPTE_TASK_PMD<<2) -#define P1PTE_OFFSET ((N_HWPTE_TASK_P0+N_HWPTE_TASK_PMD)<<2) +/* this is the end of the slot, as p1 counts backwards */ +#define P1PTE_OFFSET ((N_HWPTE_TASK_P0+N_HWPTE_TASK_P1+N_HWPTE_TASK_PMD)<<2) #define P0PMD_OFFSET (0) #define P1PMD_OFFSET (PAGE_SIZE*2) |
From: Andy P. <at...@us...> - 2001-08-21 20:09:37
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv23019 Modified Files: fault.c pgalloc.c Log Message: Bit more debugging in fault.c, change pgalloc.c to handle slot sizes properly, and fix stupid p1 section page table bug. Index: fault.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/fault.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- fault.c 2001/08/20 21:29:07 1.9 +++ fault.c 2001/08/21 20:09:34 1.10 @@ -123,7 +123,12 @@ up(&mm->mmap_sem); if (user_mode(regs)) { + printk(KERN_ALERT "Unable to do USER paging request: " + "pid %d, virtual address %08lx, reason mask %08x, " + "PC %08x, PSL %08x\n", + current->pid, address, reason, info->pc, info->psl); printk("do_page_fault: sending SIGSEGV\n"); + force_sig(SIGSEGV, current); /* signals arent implemented yet */ /* They are now atp aug 17 2001 */ Index: pgalloc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgalloc.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- pgalloc.c 2001/08/20 21:29:07 1.3 +++ pgalloc.c 2001/08/21 20:09:34 1.4 @@ -2,12 +2,16 @@ * * pgalloc.c Routines from include/asm-vax/mm/pgalloc.h * Allocation of page table entries and so forth. + * + * This is the main part of the VAX specific memory layer. * * Copyright atp Jun 2001 - complete rewrite. - * atp aug 2001 - add in stuff for vmalloc to work (pmd_alloc_kernel) - * fix mistake in pte_alloc_kernel. - * GNU GPL -*/ + * atp aug 2001 - add in stuff for vmalloc to work (pmd_alloc_kernel) + * fix mistake in pte_alloc_kernel. + * atp 21 aug 01 - make TASK_WSMAX what was intended, add in segv stuff. + * + * License: GNU GPL + */ #include <linux/sched.h> #include <linux/mm.h> @@ -73,7 +77,7 @@ /* this comes in handy later */ ret[0].slot = taskslot; /* p1br points at what would be page mapping 0x40000000 (i.e. the _end_ of the slot)*/ - ret[1].br = taskslot+ (P1PTE_OFFSET) /*+ (N_HWPTE_TASK_P1<<2)*/ - 0x800000 ; + ret[1].br = taskslot+ (P1PTE_OFFSET) - 0x800000 ; /* This is the unmapped number of PTEs */ ret[1].lr = 0x40000; ret[1].slot = taskslot; @@ -289,7 +293,7 @@ /* sanity checks */ if (!s0addr) { - printk(KERN_ERR "VAXMM: null S0 address in remap_and_clear_pte_page!\n"); + vaxpanic(KERN_ERR "VAXMM: null S0 address in remap_and_clear_pte_page!\n"); return; } /* locate the S0 pte that describes the page pointed to by s0addr */ @@ -299,8 +303,7 @@ set_pte(s0pte, pte_mkinvalid(*s0pte)); // print_pte(s0pte); /* FIXME: these flush_tlb_alls need replacing with flush_tlb_8 */ - flush_tlb_all(); - + flush_tlb_all(); // __flush_tlb_one(s0addr); } @@ -451,10 +454,16 @@ /* enforce wsmax memory limits */ if (is_p1){ adjusted_address |= 0x40000000; - if (adjusted_address <= (PAGE_OFFSET-TASK_STKMAX)) goto give_segv; + if (adjusted_address <= (PAGE_OFFSET-TASK_STKMAX)) { + printk(KERN_NOTICE "VAXMM: process %p exceeded TASK_STKMAX (%dMB)\n",current,(TASK_STKMAX>>10)); + goto give_segv; + } pte_number = (adjusted_address - 0x40000000) >> PAGE_SHIFT; } else { - if (adjusted_address >= (TASK_WSMAX+TASK_MMAPMAX)) goto give_segv; + if (adjusted_address >= (TASK_WSMAX)) { + printk(KERN_NOTICE "VAXMM: process %p exceeded TASK_WSMAX (%dMB)\n",current,(TASK_WSMAX>>10)); + goto give_segv; + } pte_number = (adjusted_address>>PAGE_SHIFT); } @@ -531,7 +540,7 @@ return pte_offset(pmd, adjusted_address); give_segv: - printk(KERN_ERR "pte_alloc: sending SIGSEGV to process %p\n",current); + printk(KERN_NOTICE "VAXMM pte_alloc: sending SIGSEGV to process %p\n",current); force_sig(SIGSEGV,current); return NULL; |
From: Andy P. <at...@us...> - 2001-08-21 20:06:45
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv22254 Modified Files: setup.c Log Message: align memory regions to 4k boundaries before feeding to free_bootmem. kernel start and end are not guaranteed to be on 4k pages.. Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/setup.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- setup.c 2001/08/20 21:32:36 1.11 +++ setup.c 2001/08/21 20:06:42 1.12 @@ -68,7 +68,7 @@ * atp -- have a temporary one. * Shouldn't we use strcpy here? */ - memcpy(command_line, "root=/dev/nfs nfsroot=/tftpboot/vaxroot rw debug\0",63); + memcpy(command_line, "root=/dev/nfs nfsroot=/tftpboot/vaxroot rw debug\0",55); *cmdline_p = command_line; /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); @@ -92,22 +92,31 @@ at the start of physical memory. init_bootmem() also marks every page as reserved. We have to explicitly free available memory ourselves. (max_pfn comes from RPB.) */ - bootmap_size = init_bootmem(0, max_pfn); + +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PAGEALIGNUP(x) (((x) + PAGE_SIZE-1) & ~(PAGE_SIZE-1)) +#define PAGEALIGNDN(x) ((x) & ~(PAGE_SIZE-1)) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) + + bootmap_size = init_bootmem(0, max_pfn); printk("bootmap size = %8.8x\n", bootmap_size); + /* Available memory is now the region from the end of the bootmem bitmap to the start of the kernel and from the end of the SPT to the end of memory */ - region_start = bootmap_size; - region_len = KERNEL_START_PHYS - bootmap_size; + + region_start = PAGEALIGNUP(bootmap_size); + region_len = PAGEALIGNDN(KERNEL_START_PHYS) - region_start; printk("calling free_bootmem(start=%08lx, len=%08lx)\n", region_start, region_len); free_bootmem(region_start, region_len); + - region_start = __pa(SPT_BASE + SPT_SIZE); - region_len = (max_pfn << PAGE_SHIFT) - __pa(SPT_BASE + SPT_SIZE); + region_start = PAGEALIGNUP(__pa(SPT_BASE + SPT_SIZE)); + region_len = PAGEALIGNDN((max_pfn << PAGE_SHIFT)) - region_start; printk("calling free_bootmem(start=%08lx, len=%08lx)\n", region_start, region_len); |
From: Andy P. <at...@us...> - 2001-08-20 21:34:51
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv25267/mm Modified Files: pgalloc.h Log Message: pgalloc pmd_alloc_kernel and free now in pgalloc.c irq.h change call proto for register_excep_handler processor.h eliminate fixme and change pages allocated for task Index: pgalloc.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pgalloc.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- pgalloc.h 2001/07/31 17:33:26 1.9 +++ pgalloc.h 2001/08/20 21:34:48 1.10 @@ -19,6 +19,7 @@ * * atp Jun 2001 remove fixed size processes, use 3 level page table and pte slots. * atp Jun-Jul 2001 - complete rewrite. + * atp Aug 2001 - swapping and vmalloc need pmd_alloc_kernel * * each 'pgd' spans an address range of 0x40000000 bytes. * each page of 'ptes' spans an address range of 0x80000 bytes @@ -100,6 +101,8 @@ /* in arch/vax/mm/pgalloc.c */ extern pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address); extern void pmd_free(pmd_t *pmd); +extern pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address); +extern void pmd_free_kernel(pmd_t *pmd); extern void pte_free(pte_t *pte); extern unsigned long get_pageaddr_from_pte(pte_t *ptep); @@ -138,15 +141,6 @@ #define pte_free_kernel(pte) free_pte_fast(pte) #define pgd_free(pgd) free_pgd_fast(pgd) - - -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ -#define pmd_free_kernel pmd_free -#define pmd_alloc_kernel pmd_alloc - /* atp jun 01, moved these to arch/vax/mm/pgalloc.c */ /* Allocate a new page for a page table for the kernel */ |
From: Andy P. <at...@us...> - 2001-08-20 21:34:51
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax In directory usw-pr-cvs1:/tmp/cvs-serv25267 Modified Files: processor.h irq.h Log Message: pgalloc pmd_alloc_kernel and free now in pgalloc.c irq.h change call proto for register_excep_handler processor.h eliminate fixme and change pages allocated for task Index: processor.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/processor.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- processor.h 2001/07/31 17:33:26 1.9 +++ processor.h 2001/08/20 21:34:48 1.10 @@ -1,6 +1,14 @@ #ifndef _VAX_PROCESSOR_H #define _VAX_PROCESSOR_H +/* Copyright atp 1998-2001. + * kenn 1999-2001. + * + * processor.h for vax architecture. + * + * Aug 2001. atp fix size of task structure allocation + remove fixme comment + */ + #include <asm/pcb.h> /* process control block definition */ #include <asm/page.h> @@ -68,10 +76,6 @@ #define THREAD_SIZE (8192) - - - - /* * Do necessary setup to start up a newly executed thread. */ @@ -131,10 +135,9 @@ machines. See arch/i386/kernel/process.c for the implementation of this. */ -/* FIXME: change the page order from 4 to 1 once the pagelet stuff is done */ #define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL,4)) -#define free_task_struct(p) free_pages((unsigned long)(p),4) + ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) +#define free_task_struct(p) free_pages((unsigned long)(p),1) #define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) #define init_task (init_task_union.task) Index: irq.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/irq.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- irq.h 2001/07/31 17:33:26 1.3 +++ irq.h 2001/08/20 21:34:48 1.4 @@ -47,6 +47,7 @@ /* This function registers the handler for an exception. */ int register_excep_handler(unsigned int vec_num, + char *exception_name, void (*handler)(struct pt_regs *, void *), unsigned int excep_info_size, unsigned int use_interrupt_stack); |
From: Andy P. <at...@us...> - 2001-08-20 21:32:39
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv25010 Modified Files: setup.c Log Message: fix call to cpu_type_str - its a function. Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/setup.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- setup.c 2001/07/31 17:28:26 1.10 +++ setup.c 2001/08/20 21:32:36 1.11 @@ -45,7 +45,7 @@ "cpu sidex\t\t: %d\n" "page size\t\t: %ld\n" "BogoMIPS\t\t: %lu.%02lu\n", - (char *)mv->cpu_type_str, + (char *)mv->cpu_type_str(), /* mv->sidex */ 0x0, PAGE_SIZE, |
From: Andy P. <at...@us...> - 2001-08-20 21:30:55
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv24293 Modified Files: interrupt.c regdump.c Log Message: add vaxpanic convenience function and fix machine check handler and get_irq_list null deferences Index: interrupt.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- interrupt.c 2001/08/19 10:32:57 1.14 +++ interrupt.c 2001/08/20 21:30:52 1.15 @@ -99,55 +99,78 @@ flush_icache(); } -void trap_init(void) + +/* register the machine check handler. */ +void register_mcheck_handler(void) { extern void machine_check_handler(void); - void *mhandler; + struct irqvector *vector; + unsigned char *inside_vec; + + /* first register things properly so that the irq functions dont get upset */ + if (register_excep_handler(SCB_MCHECK, "Machine Check (machine_check_handler)", machine_check_handler, 2, 1)) { + printk("Panic: unable to register machine check handler\n"); + machine_halt(); + } + + /* Install the specific machine check handler in entry.S + * We override the value set up above, in register_excep_handler, as + * its easier than special casing all the exception info sizing. + */ + inside_vec = (unsigned char *) ((unsigned long)(SCB_VECTOR(SCB_MCHECK)) & ~0x3); + vector = (struct irqvector *)(inside_vec - + offsetof(struct irqvector, inst_jsb)); + vector->dest_addr = machine_check_handler; +} +void trap_init(void) +{ + /* Initialize the SCB with the stray interrupt/exception handlers. Some of these will be overridden later as device drivers hook up to their interrupts. */ setup_scb(); - /* Install the specific machine check handler in entry.S - * bits 0-1 must contain 1. machine check handler is longword aligned - */ - mhandler = (void *)(machine_check_handler) + 1; - scb.scb.mcheck = mhandler; /* And tell the hardware to use this SCB */ __mtpr(__pa(&scb), PR_SCBB); - - /* Register the access violation, page fault, corrected + + /* register the machine check handler. This is a special case due to + * the machine specific exception info which is not fixed sized */ + register_mcheck_handler(); + + /* Register the access violation, page fault, corrected read and other standard exception handlers */ - if (register_excep_handler(SCB_ACCVIO, page_fault_handler, 2, 0)) { + + + if (register_excep_handler(SCB_ACCVIO, "access violation (page_fault_handler)", page_fault_handler, 2, 0)) { printk("Panic: unable to register access violation handler\n"); machine_halt(); } - if (register_excep_handler(SCB_TRANS_INVAL, page_fault_handler, 2, 0)) { + if (register_excep_handler(SCB_TRANS_INVAL, "translation not valid (page_fault_handler)", page_fault_handler, 2, 0)) { printk("Panic: unable to register page fault handler\n"); machine_halt(); } - if (register_excep_handler(SCB_RESOP, reserved_operand_handler, 0, 0)) { + if (register_excep_handler(SCB_RESOP, "reserved operand (reserved_operand_handler)", reserved_operand_handler, 0, 0)) { printk("Panic: unable to register reserved operand handler\n"); machine_halt(); } - if (register_excep_handler(SCB_RESINSTR, reserved_instr_handler, 0, 0)) { + if (register_excep_handler(SCB_RESINSTR, "reserved instruction (reserved_instr_handler)", reserved_instr_handler, 0, 0)) { printk("Panic: unable to register reserved operand handler\n"); machine_halt(); } - if (register_excep_handler(SCB_CHMK, syscall_handler, 1, 0)) { + if (register_excep_handler(SCB_CHMK,"CHMK trap (syscall_handler)", syscall_handler, 1, 0)) { printk("Panic: unable to register syscall handler\n"); machine_halt(); } /* Perhaps this should be done in CPU-specific code? */ - if (register_excep_handler(SCB_MEMCORR, corrected_read_handler, 0, 0)) { + if (register_excep_handler(SCB_MEMCORR,"memory corrected read (corrected_read_handler)", corrected_read_handler, 0, 0)) { printk("Panic: unable to register corrected read handler\n"); machine_halt(); } @@ -595,6 +618,7 @@ } int register_excep_handler(unsigned int vec_num, + char *exception_name, void (*handler)(struct pt_regs *, void *), unsigned int excep_info_size, unsigned int use_interrupt_stack) @@ -619,8 +643,11 @@ vector->excep_info_size = excep_info_size; vector->excep_handler = handler; - + vector->action.name = exception_name; /* needed to stop get_irq_list dying */ + /* FIXME: this doesnt set dev_id or other members of the irqaction structure .. */ + retval = hook_scb_vector(vec_num, vector, use_interrupt_stack); + if (retval) #ifdef KMALLOC_WORKS @@ -638,10 +665,9 @@ struct irqvector *vector; unsigned char *inside_vec; - printk("get irq list: \n"); +// printk("get irq list: \n"); for (i=0; i<NR_IRQS; i++) { - printk("\t%d: scb free %d\n",i,scb_vec_free(i)); if (!scb_vec_free(i)) { inside_vec = SCB_VECTOR(i); @@ -653,8 +679,10 @@ vector = (struct irqvector *)(inside_vec - offsetof(struct irqvector, inst_jsb)); + if (vector->action.name == NULL) + len += sprintf(buf+len, "%4d: %8d no interrupt vector name\n", vector->vec_num, 0); + else len += sprintf(buf+len, "%4d: %8d %s\n", vector->vec_num, 0, vector->action.name); - printk("%4d: %8d %s, len %d\n", vector->vec_num, 0, vector->action.name, len); } } return len; Index: regdump.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/regdump.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- regdump.c 2001/01/29 00:57:00 1.2 +++ regdump.c 2001/08/20 21:30:52 1.3 @@ -229,3 +229,14 @@ show_regs(®s); } +/* little convenience function -- temporary debugging aid - atp */ +void vaxpanic(char *reason) +{ + if (reason) printk(KERN_CRIT "panic: %s\n",reason); + + printk(KERN_CRIT "\nStack dump\n"); + hex_dump((void *)__mfpr(PR_KSP), 256); + dump_cur_regs(1); /* us and parent */ + show_cpu_regs(); + machine_halt(); +} |
From: Andy P. <at...@us...> - 2001-08-20 21:29:11
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv23775 Modified Files: init.c fault.c pgalloc.c Log Message: fix vmalloc handling pte_alloc_kernel and kernel pmd Index: init.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/init.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- init.c 2001/07/31 17:28:26 1.15 +++ init.c 2001/08/20 21:29:07 1.16 @@ -36,6 +36,7 @@ context in task 0. */ pgd_t swapper_pg_dir[PTRS_PER_PGD]; +pmd_t swapper_pm_dir[2048]; /* two pages for the kernel pmd */ /* * In other architectures, paging_init sets up the kernel's page tables. @@ -50,7 +51,13 @@ /* sort out page table. */ pg0 = (pte_t *)SPT_BASE; - + + /* set up pmd */ + swapper_pg_dir[2].pmd = swapper_pm_dir; + swapper_pg_dir[2].pmd2 = &swapper_pm_dir[1024]; + /* FIXME: I _really_ dont like this flag. */ + pmd_val(swapper_pm_dir[PGD_SPECIAL]) = (unsigned long)swapper_pg_dir | 0x1; + /* FIXME: This is where the VMALLOC stuff from head.S should go */ printk("VAXMM: Initialising mm layer for %d tasks of size %dMB\n",TASK_MAXUPRC,(TASK_WSMAX>>20)); Index: fault.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/fault.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- fault.c 2001/08/17 20:20:41 1.8 +++ fault.c 2001/08/20 21:29:07 1.9 @@ -121,10 +121,6 @@ */ bad_area: up(&mm->mmap_sem); - printk("\nStack dump\n"); - hex_dump((void *)(regs->r1), 256); - show_regs(regs); - show_cpu_regs(); if (user_mode(regs)) { printk("do_page_fault: sending SIGSEGV\n"); Index: pgalloc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgalloc.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- pgalloc.c 2001/07/31 17:28:26 1.2 +++ pgalloc.c 2001/08/20 21:29:07 1.3 @@ -3,8 +3,9 @@ * pgalloc.c Routines from include/asm-vax/mm/pgalloc.h * Allocation of page table entries and so forth. * - * Copyright atp Jun 2001 - complete rewrite. - * + * Copyright atp Jun 2001 - complete rewrite. + * atp aug 2001 - add in stuff for vmalloc to work (pmd_alloc_kernel) + * fix mistake in pte_alloc_kernel. * GNU GPL */ @@ -15,6 +16,8 @@ #include <asm/pgalloc.h> #include <asm/mmu_context.h> +extern void vaxpanic(char *reason); + #undef VAX_MM_PGALLOC_DEBUG /* @@ -69,8 +72,8 @@ ret[0].lr = 0x0; /* this comes in handy later */ ret[0].slot = taskslot; - /* p1br points at what would be page mapping 0x40000000 */ - ret[1].br = taskslot+ (P1PTE_OFFSET) - 0x800000 ; + /* p1br points at what would be page mapping 0x40000000 (i.e. the _end_ of the slot)*/ + ret[1].br = taskslot+ (P1PTE_OFFSET) /*+ (N_HWPTE_TASK_P1<<2)*/ - 0x800000 ; /* This is the unmapped number of PTEs */ ret[1].lr = 0x40000; ret[1].slot = taskslot; @@ -122,7 +125,10 @@ unsigned long adjaddr; is_p1 = pgd->segment; - adjaddr = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + adjaddr = pmd_index(address); +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM: Calling pmd_alloc with (pgd=%8p,pmd=%8lx,address %8lx, adjaddr %8lx)\n",pgd,pgd->pmd,address,adjaddr); +#endif /* sanity check */ /* FIXME: is this pgd_none? */ @@ -190,6 +196,22 @@ return (pmd_t *) pgd->pmd+adjaddr; } +/* the kernel pmd is in mm/init.c */ +extern pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) +{ + /* we rely on init.c to set up the pmd pointers in the pgd for us. + * This leaves us just a pmd_offset sort of job */ +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM: pmd_alloc_kernel: pgd %8p, pgd->pmd %8lx, address %8lx\n",pgd,pgd->pmd,address); +#endif + return pmd_offset(pgd, address); +} + +extern void pmd_free_kernel(pmd_t *pmd) +{ + return; +} + /* This inverts the remapping done in remap_and_clear */ unsigned long get_pageaddr_from_pte(pte_t *ptep) { @@ -232,11 +254,11 @@ /* sanity checks */ if (!s0addr) { - printk(KERN_ERR "VAXMM: null S0 address in remap_and_clear_pte_page!\n"); + vaxpanic("VAXMM: null S0 address in remap_and_clear_pte_page!\n"); return; } if (!pte_page) { - printk(KERN_ERR "VAXMM: null pte_page in remap_and_clear_pte_page!\n"); + vaxpanic("VAXMM: null pte_page in remap_and_clear_pte_page!\n"); return; } @@ -332,18 +354,38 @@ * * - Indeed, however, the implementation is still not obvious to me. * atp July 2001. + * - let me qualify that. pte_alloc_kernel is called infrequently. + * Mostly by the VMALLOC stuff, which already has a VMALLOC_END check. + * so the only reason for calling this is if we are in the middle of + * some operation, outside of the vmalloc family, mapping system space. + * Hence the current implementation suffices, and I cant see a reason + * to implement an expandable s0 page table. */ pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) { - pgd_t *pgdptr = (pgd_t *)pmd; - - /* note the lr in the system pgd is in PAGELETS.... shift it down to - give page view */ -//printk("pte_allock: pmd, %p, address %8lx\n",pmd,address); - if ((address >> PAGE_SHIFT) < (pgdptr->lr>>3)) - return pte_offset(pmd, address); + pgd_t *pgdptr = (pgd_t *)&swapper_pg_dir[2]; + unsigned long int adjusted_address; + unsigned long int spt_entry; + pte_t *spte; + + adjusted_address = ((pmd - (pmd_t *)(pgdptr->pmd))<<(PAGE_SHIFT+7)) + (address&~PMD_MASK); +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM:pte_alloc_kernel: pmd, %p, address %8lx, adjaddr %8lx\n",pmd,address,adjusted_address); +#endif + + /* note the lr in the system pgd is in PAGELETS */ + if (((adjusted_address) >> PAGELET_SHIFT) < (pgdptr->lr)) { + /* fill in any bits missing. Perhaps we should do this when we set up the + * SPT in init.c just to be consistent */ + if (pmd_val(*pmd)==NULL) { + spt_entry = (pmd - (pmd_t *)(pgdptr->pmd))<< (PAGE_SHIFT+7) | PAGE_OFFSET; + spte = GET_SPTE_VIRT(spt_entry); + pmd_val(*pmd) = spte; + } + return pte_offset(pmd, adjusted_address); + } else return NULL; } @@ -390,11 +432,11 @@ /* FIXME: should test pgdp. this is pointless otherwise */ if ((!pgdp)||(pgd_none(*pgdp))) { printk(KERN_ERR "VAXMM: Bad PGD (%8p, from pmd %8p) in pte_alloc\n",pgdp,pmd_basep); - return NULL; + goto give_segv; } if (pgdp->pmd != (unsigned long)pmd_basep) { printk(KERN_ERR "VAXMM: Mismatched PGD (%8p, has pmd %8lx from pmd %8p) in pte_alloc\n",pgdp,pgdp->pmd,pmd_basep); - return NULL; + goto give_segv; } is_p1=pgdp->segment; @@ -404,14 +446,18 @@ /* make an adjusted address + calculate linear page table entry */ adjusted_address = (((pmd-pmd_basep))<<(PAGE_SHIFT+7))+ (address&~PMD_MASK); + + + /* enforce wsmax memory limits */ if (is_p1){ adjusted_address |= 0x40000000; + if (adjusted_address <= (PAGE_OFFSET-TASK_STKMAX)) goto give_segv; pte_number = (adjusted_address - 0x40000000) >> PAGE_SHIFT; } else { + if (adjusted_address >= (TASK_WSMAX+TASK_MMAPMAX)) goto give_segv; pte_number = (adjusted_address>>PAGE_SHIFT); } - /* FIXME: check against WSMAX */ /* check that the pte we want isnt already allocated */ if (is_p1) { @@ -451,7 +497,7 @@ for (ii=0; ii<npages; ii++) { if (!(pte_page=pte_alloc_one(pmdi))) { printk(KERN_ERR "VAXMM: Unable to expand process page table (pgd=%8p)\n",pgdp); - return NULL; + goto give_segv; } /* remap and clear this page */ @@ -483,6 +529,11 @@ /* we flush tlb anways as we have touched S0 page tables */ flush_tlb_all(); return pte_offset(pmd, adjusted_address); + +give_segv: + printk(KERN_ERR "pte_alloc: sending SIGSEGV to process %p\n",current); + force_sig(SIGSEGV,current); + return NULL; } /* pte_alloc */ @@ -507,11 +558,20 @@ } /* Find an entry in the third-level page table.. */ +#ifdef VAX_MM_PGALLOC_DEBUG +pte_t * pte_offset(pmd_t * dir, unsigned long address) +{ + unsigned long int offset; + offset = (pmd_val(*dir)+(((address>>PAGE_SHIFT)&(PTRS_PER_PTE-1))<<SIZEOF_PTE_LOG2)); + printk(KERN_DEBUG "VAXMM:pte_offset: pmd %8p, address %8lx, pte_offset %8lx\n",dir, address, offset); + return offset; +} +#else pte_t * pte_offset(pmd_t * dir, unsigned long address) { return (pmd_val(*dir)+(((address>>PAGE_SHIFT)&(PTRS_PER_PTE-1))<<SIZEOF_PTE_LOG2)); } - +#endif /* get_pte_kernel_slow. allocate a page of PTEs for the S0 pagetable. * See comments in include/asm/mm/pgalloc.h for get_pte_kernel. */ |
From: Andy P. <at...@us...> - 2001-08-19 10:34:46
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/boot In directory usw-pr-cvs1:/tmp/cvs-serv6214 Modified Files: Makefile Added Files: startup.c Removed Files: tmp_init.c Log Message: Clean up initial boot sequence. Remove vestiges of debugging init sequence --- NEW FILE --- /* First C code - started by head.S */ /* Copyright atp 1998-2001 under the GNU GPL */ #include <asm/rpb.h> #include <asm/mv.h> #include <linux/mm.h> /* stuff that is declared in head.S */ extern unsigned long int phys_start; /* physical address of kernel*/ extern unsigned long int virt_start; /* virtual address of kernel */ extern unsigned long int boot_ap; /* argument pointer */ extern unsigned long int boot_r11; /* rpb pointer */ extern unsigned long int boot_scb; /* scb pointer */ extern unsigned long int iomap_base; /* head.S copies the RPB into this structure */ struct rpb_struct boot_rpb; /* head.S gets the size of the RPB from here. We do it this way because we can't use sizeof() in assembly :-( */ unsigned int rpb_size = sizeof(struct rpb_struct); char *vax_linux_banner="Linux/VAX (lin...@mi...)\n"; extern void start_kernel(void); /* This is a transitionary function. When things are finally sorted * the only tasks this function will perform will relate to the interaction * with VMB and other stuff that needs to go on early before we start_kernel() * like patchable control store, memory bitmap creation on non-ROM based * VAXen. * At present its used for testing the early parts of the kernel startup. * The other main thing it does is load the rpb and scb global variables, * and switch on basic paging. The main paging setup is done later. * * ok ive changed my mind. We turn on MM in the asm before we hit C code * (keeps stacks simpler) just like the i386, with a default 8mb system * page table setup (with a 1:1 mapping of system space. * * Things that are temporary have a habit of becoming permanent. * I've renamed from tmp_start_kernel to vax_start_kernel, as convenient * bit of arch-specific C code before starting the main start_kernel * * atp aug 2001 - This is now permanent, and has been renamed to startup.c */ #define IOMAP_START (PAGE_OFFSET+((iomap_base-swapper_pg_dir[2].br)<<(PAGELET_SHIFT-2))) void vax_start_kernel(void) { /* set the number of 4k pages */ max_pfn = max_hwpfn/8; printk(vax_linux_banner); /* Protect us from interrupt stack overflows */ guard_int_stack(); /* If it is possible to register a console for your machine at this point in the boot sequence, do so in post_vm_init(). Otherwise, implement mv->console_init() which will be called later. */ mv->post_vm_init(); #ifdef __SMP__ static int boot_cpu = 1; /* "current" has been set up, we need to load it now */ if (!boot_cpu) initialize_secondary(); boot_cpu = 0; #endif /* * Interrupts are still disabled. Do necessary setups, then * enable them */ printk("RPB info: l_pfncnt: %08x, .l_vmb_version: %08x .l_badpgs: %08x\n", boot_rpb.l_pfncnt, boot_rpb.l_vmb_version, boot_rpb.l_badpgs); printk("Physical memory: %08x HW pagelets, %08lx pages (%dKB)\n", max_hwpfn, max_pfn, max_hwpfn/2); printk("CPU type: %s, SID: %08x\n", mv->cpu_type_str(), vax_cpu.sid); printk("VM: mapped physical from %x to %x, iomap from %x\n", PAGE_OFFSET, PAGE_OFFSET+(max_hwpfn*512), IOMAP_START); printk("VM: vmalloc from %x to %x\n", VMALLOC_START, VMALLOC_END); printk("VM: ptemap from %x to %x for %d processes\n",TASKPTE_START, TASKPTE_END,TASK_MAXUPRC); printk("calling start_kernel...\n"); start_kernel(); } Index: Makefile =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/boot/Makefile,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- Makefile 2001/03/04 23:44:42 1.4 +++ Makefile 2001/08/19 10:34:42 1.5 @@ -14,6 +14,6 @@ all: head.o libboot.a L_TARGET := libboot.a -obj-y := tmp_init.o lib.o hexdump.o mmstart.o cpu_sel.o +obj-y := startup.o lib.o hexdump.o mmstart.o cpu_sel.o include $(TOPDIR)/Rules.make --- tmp_init.c DELETED --- |
From: Andy P. <at...@us...> - 2001-08-19 10:33:00
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv6028 Modified Files: interrupt.c syscall.c Log Message: place do_signal call in correct place Index: interrupt.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- interrupt.c 2001/07/31 17:28:26 1.13 +++ interrupt.c 2001/08/19 10:32:57 1.14 @@ -358,7 +358,12 @@ schedule(); goto ret_from_sys_call; } - /* Check for signals here */ + + /* check for pending signals */ + if (current->sigpending != 0) { + /* FIXME: do we need to check the IPL here (i386 does a sti here) */ + do_signal(); + } done: } @@ -633,8 +638,10 @@ struct irqvector *vector; unsigned char *inside_vec; - for (i=0; i<NR_IRQS; i++) + printk("get irq list: \n"); + for (i=0; i<NR_IRQS; i++) { + printk("\t%d: scb free %d\n",i,scb_vec_free(i)); if (!scb_vec_free(i)) { inside_vec = SCB_VECTOR(i); @@ -647,6 +654,7 @@ vector = (struct irqvector *)(inside_vec - offsetof(struct irqvector, inst_jsb)); len += sprintf(buf+len, "%4d: %8d %s\n", vector->vec_num, 0, vector->action.name); + printk("%4d: %8d %s, len %d\n", vector->vec_num, 0, vector->action.name, len); } } return len; Index: syscall.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/syscall.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- syscall.c 2001/08/17 20:20:41 1.5 +++ syscall.c 2001/08/19 10:32:58 1.6 @@ -118,19 +118,6 @@ // printk("syscall %d returned %ld (0x%08lx)\n", chmk_arg, regs->r0, regs->r0); - /* now we check for softirqs ready to be run */ - /* This is the equivalent of ENTRY(ret_from_syscall) on other ports */ - if ( (softirq_active(smp_processor_id()) & softirq_mask(smp_processor_id())) !=0 ) do_softirq(); - - /* check for need_reschedule */ - if (current->need_resched !=0) schedule(); - - /* check for pending signals */ - if (current->sigpending != 0) { - /* FIXME: do we need to check the IPL here (i386 does a sti here) */ - do_signal(); - } - return; } |
From: Andy P. <at...@us...> - 2001-08-17 20:36:33
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv21901 Modified Files: process.c Log Message: Signals implementation. Index: process.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/process.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- process.c 2001/07/31 17:28:26 1.10 +++ process.c 2001/08/17 20:36:30 1.11 @@ -110,8 +110,8 @@ struct pt_regs *child_regs; void *stack_top; - printk("copy_thread: creating new thread: pid %d, task 0x%08lx, usp 0x%08lx\n", - p->pid, (unsigned long)p, usp); +/* printk("copy_thread: creating new thread: pid %d, task 0x%08lx, usp 0x%08lx\n", + p->pid, (unsigned long)p, usp); */ stack_top = ((union task_union *)p) + 1; @@ -180,8 +180,8 @@ /* In child. At this point SP points to the very top of our kernel stack, so we cannot pop anything off. That means that we can never return from here. */ - printk("kernel_thread: calling thread function at %08lx\n", - (unsigned long)fn); +/* printk("kernel_thread: calling thread function at %08lx\n", + (unsigned long)fn);*/ kernel_thread_exit(fn(arg)); } @@ -193,12 +193,12 @@ newsp = regs->sp; } - printk("sys_clone: calling do_fork(0x%08lx, 0x%08lx, 0x%p)\n", - clone_flags, newsp, regs); +/* printk("sys_clone: calling do_fork(0x%08lx, 0x%08lx, 0x%p)\n", + clone_flags, newsp, regs); */ retval = do_fork(clone_flags, newsp, regs, 0); - printk("sys_clone: do_fork() returned %d\n", retval); +/* printk("sys_clone: do_fork() returned %d\n", retval);*/ return retval; } @@ -250,7 +250,7 @@ void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp) { - printk("starting thread %8lX %8lX %8lX\n", new_pc, new_sp, regs->sp); +/* printk("starting thread %8lX %8lX %8lX\n", new_pc, new_sp, regs->sp);*/ set_fs(USER_DS); regs->pc = new_pc; regs->sp = new_sp; |
From: Andy P. <at...@us...> - 2001-08-17 20:35:18
|
Update of /cvsroot/linux-vax/kernel-2.4/fs/reiserfs In directory usw-pr-cvs1:/tmp/cvs-serv21666 Added Files: .cvsignore Log Message: missing cvs ignore file for new file system --- NEW FILE --- *.a.flags *.o.flags .depend *.lst |
From: Andy P. <at...@us...> - 2001-08-17 20:33:32
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax In directory usw-pr-cvs1:/tmp/cvs-serv21311 Modified Files: signal.h Log Message: Included missing signal - SIGSYS Index: signal.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/signal.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- signal.h 2001/01/17 16:18:52 1.1 +++ signal.h 2001/08/17 20:33:29 1.2 @@ -66,6 +66,7 @@ */ #define SIGPWR 30 #define SIGUNUSED 31 +#define SIGSYS 31 /* These should not be considered constants from userland. */ #define SIGRTMIN 32 |
From: Andy P. <at...@us...> - 2001-08-17 20:20:45
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv18613/kernel Modified Files: syscall.c signal.c Log Message: Signals implementation. First attempt. Index: syscall.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/syscall.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- syscall.c 2001/07/31 17:28:26 1.4 +++ syscall.c 2001/08/17 20:20:41 1.5 @@ -95,6 +95,7 @@ by the user. We'll sort this out later... - KPH 2000-10-16 */ + /* atp aug 2001, FIXME: ptrace/strace syscall stuff */ __asm__(" pushl %1 \n subl2 %2,sp \n @@ -115,8 +116,21 @@ "g"(-EFAULT) : "r0","r1","r2","r3","r4","r5" /* clobbers*/ ); -/* printk("syscall %d returned %ld (0x%08lx)\n", chmk_arg, regs->r0, regs->r0);*/ +// printk("syscall %d returned %ld (0x%08lx)\n", chmk_arg, regs->r0, regs->r0); + /* now we check for softirqs ready to be run */ + /* This is the equivalent of ENTRY(ret_from_syscall) on other ports */ + if ( (softirq_active(smp_processor_id()) & softirq_mask(smp_processor_id())) !=0 ) do_softirq(); + + /* check for need_reschedule */ + if (current->need_resched !=0) schedule(); + + /* check for pending signals */ + if (current->sigpending != 0) { + /* FIXME: do we need to check the IPL here (i386 does a sti here) */ + do_signal(); + } + return; } Index: signal.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/signal.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- signal.c 2001/07/31 17:28:26 1.3 +++ signal.c 2001/08/17 20:20:41 1.4 @@ -1,14 +1,20 @@ -/* - $Id$ - - This file contains the standard functions that the arch-independent - kernel expects for signal handling - - Copyright, 1998-2001 atp, kenn, airlied. - - atp Jul 2001, signal handling, based on S390/Intel version. - -*/ +/* + * linux/arch/vax/kernel/signal.c + * + * From arch/cris/kernel/signal.c + * + * Based on arch/i386/kernel/signal.c by + * Copyright (C) 1991, 1992 Linus Torvalds + * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * + * + * Ideas also taken from arch/arm. + * + * Copyright (C) 2000 Axis Communications AB + * + * Authors: Bjorn Wesen (bj...@ax...) + * VAX port at...@pe.... + * See syscall.c for details of the call stack layout etc... + */ #include <linux/sched.h> #include <linux/mm.h> @@ -21,12 +27,20 @@ #include <linux/ptrace.h> #include <linux/unistd.h> #include <linux/stddef.h> + +#include <asm/processor.h> #include <asm/ucontext.h> #include <asm/uaccess.h> +#define DEBUG_SIG 0 + +/* FIXME: Check this & fixup other regs, like r0 */ +#define RESTART_VAX_SYSCALL(regs) { (regs)->pc -= 4; } + + #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); +int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) { @@ -66,8 +80,8 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage int -sys_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask) +int +sys_sigsuspend(struct pt_regs *regs, old_sigset_t mask) { sigset_t saveset; @@ -77,18 +91,22 @@ siginitset(¤t->blocked, mask); recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - regs->r2 = -EINTR; + regs->r0 = -EINTR; while (1) { - set_current_state(TASK_INTERRUPTIBLE); + current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(regs, &saveset)) + if (do_signal(0, &saveset, regs)) return -EINTR; } } -asmlinkage int -sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize) +/* + * atp - it is a little confusing, looking at other ports, as to what the arguments to + * this function are. I'm assuming two args, plus our pushed pt_regs set up by syscall + */ +int +sys_rt_sigsuspend(struct pt_regs *regs,sigset_t *unewset, size_t sigsetsize) { sigset_t saveset, newset; @@ -105,17 +123,17 @@ current->blocked = newset; recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - regs->r2 = -EINTR; + regs->r0 = -EINTR; while (1) { - set_current_state(TASK_INTERRUPTIBLE); + current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(regs, &saveset)) + if (do_signal(0, &saveset, regs)) return -EINTR; } } -asmlinkage int +int sys_sigaction(int sig, const struct old_sigaction *act, struct old_sigaction *oact) { @@ -146,10 +164,12 @@ return ret; } -asmlinkage int -sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs) + +int +sys_sigaltstack(const stack_t *uss, stack_t *uoss) { - return do_sigaltstack(uss, uoss, regs->sp); /* is ->sp the right one FIXME: check */ + struct pt_regs *regs = (struct pt_regs *) &uss; + return do_sigaltstack(uss, uoss, regs->sp ); } @@ -158,12 +178,14 @@ */ struct sigframe { + char *pretcode; struct sigcontext sc; unsigned long extramask[_NSIG_WORDS-1]; unsigned char retcode[8]; /* trampoline code */ }; struct rt_sigframe { + char *pretcode; struct siginfo *pinfo; void *puc; struct siginfo info; @@ -171,16 +193,462 @@ unsigned char retcode[8]; /* trampoline code */ }; + +static int +restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +{ + unsigned int err = 0; + unsigned long old_usp; + + /* restore the regs from &sc->regs (same as sc, since regs is first) + * (sc is already checked for VERIFY_READ since the sigframe was + * checked in sys_sigreturn previously) + */ + + if (__copy_from_user(regs, sc, sizeof(struct pt_regs))) + goto badframe; + + /* FIXME: check user mode flag in restored regs PSW */ + + /* restore the old USP as it was before we stacked the sc etc. + * (we cannot just pop the sigcontext since we aligned the sp and + * stuff after pushing it) + */ + + /* FIXME: check process stack */ + + /* TODO: the other ports use regs->orig_XX to disable syscall checks + * after this completes, but we don't use that mechanism. maybe we can + * use it now ? + */ + + return err; + +badframe: + return 1; +} + +asmlinkage int sys_sigreturn(struct pt_regs *regs) +{ + struct sigframe *frame = (struct sigframe *)(regs->sp); + sigset_t set; + + /* + * Since we stacked the signal on a dword boundary, + * then frame should be dword aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (((long)frame) & 3) + goto badframe; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__get_user(set.sig[0], &frame->sc.oldmask) + || (_NSIG_WORDS > 1 + && __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + if (restore_sigcontext(regs, &frame->sc)) + goto badframe; + + /* TODO: SIGTRAP when single-stepping as in arm ? */ + + return regs->r0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) +{ + struct rt_sigframe *frame = (struct rt_sigframe *)(regs->sp); + sigset_t set; + stack_t st; + + /* + * Since we stacked the signal on a dword boundary, + * then frame should be dword aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (((long)frame) & 3) + goto badframe; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) + goto badframe; + + if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) + goto badframe; + /* It is more difficult to avoid calling this function than to + call it and ignore errors. */ + do_sigaltstack(&st, NULL, (regs->sp)); + + return regs->r0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +/* + * Set up a signal frame. + */ + +static int +setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask) +{ + int err = 0; + + /* copy the regs. they are first in sc so we can use sc directly */ + + err |= __copy_to_user(sc, regs, sizeof(struct pt_regs)); + + /* then some other stuff */ + + err |= __put_user(mask, &sc->oldmask); + + return err; +} + +/* figure out where we want to put the new signal frame - usually on the stack */ -int sys_sigreturn(void) +static inline void * +get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) { - return -ENOSYS; + unsigned long sp = regs->sp; + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { + if (! on_sig_stack(sp)) + sp = current->sas_ss_sp + current->sas_ss_size; + } + + /* make sure the frame is dword-aligned */ + + sp &= ~3; + + return (void *)(sp - frame_size); } + +/* grab and setup a signal frame. + * + * basically we stack a lot of state info, and arrange for the + * user-mode program to return to the kernel using either a + * trampoline which performs the syscall sigreturn, or a provided + * user-mode trampoline. + */ -int sys_rt_sigreturn(void) +static void setup_frame(int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs * regs) { - return -ENOSYS; + struct sigframe *frame; + unsigned long return_ip; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto give_sigsegv; + + err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); + if (err) + goto give_sigsegv; + + if (_NSIG_WORDS > 1) { + err |= __copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + } + if (err) + goto give_sigsegv; + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa.sa_flags & SA_RESTORER) { + return_ip = (unsigned long)ka->sa.sa_restorer; + } else { + /* trampoline - the desired return ip is the retcode itself */ + return_ip = (unsigned long)&frame->retcode; + /* This is chmk __NR_sigreturn; */ + /* TODO: check byteorder */ + err |= __put_user(0xbc8f, (short *)(frame->retcode+0)); + err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2)); + } + + err |= __put_user(return_ip, &frame->pretcode); + + if (err) + goto give_sigsegv; + + /* Set up registers for signal handler */ + + regs->pc = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ + regs->sp = frame; + + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); } +static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs * regs) +{ + struct rt_sigframe *frame; + unsigned long return_ip; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto give_sigsegv; + + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + if (err) + goto give_sigsegv; + + /* Clear all the bits of the ucontext we don't use. */ + err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); + + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); + + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + + if (err) + goto give_sigsegv; + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa.sa_flags & SA_RESTORER) { + return_ip = (unsigned long)ka->sa.sa_restorer; + } else { + /* trampoline - the desired return ip is the retcode itself */ + return_ip = (unsigned long)&frame->retcode; + /* TODO: check byteorder */ + err |= __put_user(0xbc8f, (short *)(frame->retcode+0)); + err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2)); + } + + err |= __put_user(return_ip, &frame->pretcode); + if (err) + goto give_sigsegv; + + /* TODO what is the current->exec_domain stuff and invmap ? */ + + /* Set up registers for signal handler */ + + regs->pc = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ + regs->sp = frame; /* what we enter LATER */ + + return; +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +/* + * OK, we're invoking a handler + */ +static inline void +handle_signal(int canrestart, unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) +{ + /* Are we from a system call? */ + if (canrestart) { + /* If so, check system call restarting.. */ + switch (regs->r0) { + case -ERESTARTNOHAND: + /* ERESTARTNOHAND means that the syscall should only be + restarted if there was no handler for the signal, and since + we only get here if there is a handler, we dont restart */ + regs->r0 = -EINTR; + break; + + case -ERESTARTSYS: + /* ERESTARTSYS means to restart the syscall if there is no + handler or the handler was registered with SA_RESTART */ + if (!(ka->sa.sa_flags & SA_RESTART)) { + regs->r0 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + /* ERESTARTNOINTR means that the syscall should be called again + after the signal handler returns. */ + RESTART_VAX_SYSCALL(regs); + } + } + + /* Set up the stack frame */ + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(sig, ka, info, oldset, regs); + else + setup_frame(sig, ka, oldset, regs); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sigmask_lock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + } +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + */ +int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) +{ + siginfo_t info; + struct k_sigaction *ka; + + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (!user_mode(regs)) + return 1; + + if (!oldset) + oldset = ¤t->blocked; + + for (;;) { + unsigned long signr; + + spin_lock_irq(¤t->sigmask_lock); + signr = dequeue_signal(¤t->blocked, &info); + spin_unlock_irq(¤t->sigmask_lock); + + if (!signr) + break; + + if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { + /* Let the debugger run. */ + current->exit_code = signr; + current->state = TASK_STOPPED; + notify_parent(current, SIGCHLD); + schedule(); + + /* We're back. Did the debugger cancel the sig? */ + if (!(signr = current->exit_code)) + continue; + current->exit_code = 0; + + /* The debugger continued. Ignore SIGSTOP. */ + if (signr == SIGSTOP) + continue; + + /* Update the siginfo structure. Is this good? */ + if (signr != info.si_signo) { + info.si_signo = signr; + info.si_errno = 0; + info.si_code = SI_USER; + info.si_pid = current->p_pptr->pid; + info.si_uid = current->p_pptr->uid; + } + + /* If the (new) signal is now blocked, requeue it. */ + if (sigismember(¤t->blocked, signr)) { + send_sig_info(signr, &info, current); + continue; + } + } + + ka = ¤t->sig->action[signr-1]; + if (ka->sa.sa_handler == SIG_IGN) { + if (signr != SIGCHLD) + continue; + /* Check for SIGCHLD: it's special. */ + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + /* nothing */; + continue; + } + + if (ka->sa.sa_handler == SIG_DFL) { + int exit_code = signr; + + /* Init gets no signals it doesn't want. */ + if (current->pid == 1) + continue; + + switch (signr) { + case SIGCONT: case SIGCHLD: case SIGWINCH: + continue; + + case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (is_orphaned_pgrp(current->pgrp)) + continue; + /* FALLTHRU */ + + case SIGSTOP: + current->state = TASK_STOPPED; + current->exit_code = signr; + if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) + notify_parent(current, SIGCHLD); + schedule(); + continue; + + case SIGQUIT: case SIGILL: case SIGTRAP: + case SIGABRT: case SIGFPE: case SIGSEGV: + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: + if (do_coredump(signr, regs)) + exit_code |= 0x80; + /* FALLTHRU */ + + default: + lock_kernel(); + sigaddset(¤t->pending.signal, signr); + recalc_sigpending(current); + current->flags |= PF_SIGNALED; + do_exit(exit_code); + /* NOTREACHED */ + } + } + + /* Whee! Actually deliver the signal. */ + handle_signal(canrestart, signr, ka, &info, oldset, regs); + return 1; + } + + /* Did we come from a system call? */ + if (canrestart) { + /* Restart the system call - no handlers present */ + if (regs->r0 == -ERESTARTNOHAND || + regs->r0 == -ERESTARTSYS || + regs->r0 == -ERESTARTNOINTR) { + RESTART_VAX_SYSCALL(regs); + } + } + return 0; +} |
From: Andy P. <at...@us...> - 2001-08-17 20:20:44
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv18613/mm Modified Files: fault.c Log Message: Signals implementation. First attempt. Index: fault.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/fault.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- fault.c 2001/07/31 17:28:26 1.7 +++ fault.c 2001/08/17 20:20:41 1.8 @@ -130,7 +130,8 @@ printk("do_page_fault: sending SIGSEGV\n"); force_sig(SIGSEGV, current); /* signals arent implemented yet */ - machine_halt(); + /* They are now atp aug 17 2001 */ +// machine_halt(); return; } |
From: Dave A. <ai...@us...> - 2001-08-15 22:55:17
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv12396 Modified Files: entry.S Log Message: DA: oops .. wrong calll.. I'm, redoing the whole lot of entry.S now.. missing some stuff .. other stuff to 16/32 bit stuff Index: entry.S =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/entry.S,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- entry.S 2001/08/15 22:23:32 1.6 +++ entry.S 2001/08/15 22:55:13 1.7 @@ -304,7 +304,7 @@ .long sys_geteuid .long sys_getegid /* 50 */ .long sys_acct - .long sys_umount /* recycled never used phys() */ + .long sys_oldumount /* recycled never used phys() */ .long sys_ni_syscall /* old lock syscall holder */ .long sys_ioctl .long sys_fcntl /* 55 */ |
From: Dave A. <ai...@us...> - 2001-08-15 22:24:29
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/net In directory usw-pr-cvs1:/tmp/cvs-serv5261/drivers/net Modified Files: vaxlance.c Log Message: DA: add some missing CRs Index: vaxlance.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/net/vaxlance.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- vaxlance.c 2001/08/14 21:25:43 1.14 +++ vaxlance.c 2001/08/15 22:24:27 1.15 @@ -1077,11 +1077,11 @@ #else dev->irq=0x94; - printk("Using LANCE interrupt vector %d", dev->irq); + printk("Using LANCE interrupt vector %d\n", dev->irq); #endif /* tmp atp*/ dev->irq=0x94; - printk("Using LANCE interrupt vector %d", dev->irq); + printk("Using LANCE interrupt vector %d\n", dev->irq); dev->open = &lance_open; dev->stop = &lance_close; |