Update of /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel In directory usw-pr-cvs1:/tmp/cvs-serv13561/m68k/kernel Modified Files: bios32.c head.S ints.c process.c ptrace.c semaphore.c setup.c sys_m68k.c traps.c Log Message: synch 2.4.15 commit 37 Index: bios32.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/bios32.c,v retrieving revision 1.1.1.2 retrieving revision 1.2 diff -u -r1.1.1.2 -r1.2 --- bios32.c 25 Feb 2001 23:15:19 -0000 1.1.1.2 +++ bios32.c 10 Apr 2002 14:34:35 -0000 1.2 @@ -444,7 +444,7 @@ * dev - device. * i - resource. * - * Result: 0 if successfull. + * Result: 0 if successful. */ int __init pcibios_assign_resource(struct pci_dev *dev, int i) Index: head.S =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/head.S,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- head.S 14 Jan 2001 19:39:56 -0000 1.1.1.1 +++ head.S 10 Apr 2002 14:34:35 -0000 1.2 @@ -840,7 +840,7 @@ #ifdef CONFIG_MVME16x is_not_mvme16x(L(gvtdone)) - /* Need to get the BRD_ID info to diferentiate between 162, 167, + /* Need to get the BRD_ID info to differentiate between 162, 167, * etc. This is available as a BI_VME_BRDINFO tag with later * versions of VMELILO and TFTPLILO, otherwise we call the Bug. */ @@ -1178,8 +1178,45 @@ #ifdef CONFIG_SUN3X is_not_sun3x(L(notsun3x)) + /* oh, the pain.. We're gonna want the prom code after + * starting the MMU, so we copy the mappings, translating + * from 8k -> 4k pages as we go. + */ + + /* copy maps from 0xfee00000 to 0xff000000 */ + movel #0xfee00000, %d0 + moveq #ROOT_INDEX_SHIFT, %d1 + lsrl %d1,%d0 + mmu_get_root_table_entry %d0 + + movel #0xfee00000, %d0 + moveq #PTR_INDEX_SHIFT, %d1 + lsrl %d1,%d0 + andl #PTR_TABLE_SIZE-1, %d0 + mmu_get_ptr_table_entry %a0,%d0 + + movel #0xfee00000, %d0 + moveq #PAGE_INDEX_SHIFT, %d1 + lsrl %d1,%d0 + andl #PAGE_TABLE_SIZE-1, %d0 + mmu_get_page_table_entry %a0,%d0 + + /* this is where the prom page table lives */ + movel 0xfefe00d4, %a1 + movel %a1@, %a1 + + movel #((0x200000 >> 13)-1), %d1 + +1: + movel %a1@+, %d3 + movel %d3,%a0@+ + addl #0x1000,%d3 + movel %d3,%a0@+ + + dbra %d1,1b + /* setup tt1 for I/O */ - mmu_map_tt #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S + mmu_map_tt #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S jbra L(mmu_init_done) L(notsun3x): @@ -1363,7 +1400,7 @@ is_not_sun3x(1f) /* enable copro */ - oriw #0x4000,0x61000000 + oriw #0x4000,0x61000000 1: #endif @@ -3061,6 +3098,16 @@ 2: #endif +#ifdef CONFIG_SUN3X + is_not_sun3x(2f) + movel %d0,-(%sp) + movel 0xFEFE0018,%a1 + jbsr (%a1) + addq #4,%sp + jbra L(serial_putc_done) +2: +#endif + #ifdef CONFIG_Q40 is_not_q40(2f) tst.l %pc@(L(q40_do_debug)) /* only debug if requested */ Index: ints.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/ints.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- ints.c 14 Jan 2001 19:39:57 -0000 1.1.1.1 +++ ints.c 10 Apr 2002 14:34:35 -0000 1.2 @@ -184,7 +184,7 @@ /* * Do we need these probe functions on the m68k? * - * ... may be usefull with ISA devices + * ... may be useful with ISA devices */ unsigned long probe_irq_on (void) { Index: process.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/process.c,v retrieving revision 1.1.1.2 retrieving revision 1.2 diff -u -r1.1.1.2 -r1.2 --- process.c 25 Feb 2001 23:15:19 -0000 1.1.1.2 +++ process.c 10 Apr 2002 14:34:35 -0000 1.2 @@ -38,7 +38,6 @@ * alignment requirements and potentially different initial * setup. */ -static struct vm_area_struct init_mmap = INIT_MMAP; static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; @@ -110,8 +109,8 @@ void show_regs(struct pt_regs * regs) { printk("\n"); - printk("Format %02x Vector: %04x PC: %08lx Status: %04x\n", - regs->format, regs->vector, regs->pc, regs->sr); + printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n", + regs->format, regs->vector, regs->pc, regs->sr, print_tainted()); printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n", regs->orig_d0, regs->d0, regs->a2, regs->a1); printk("A0: %08lx D5: %08lx D4: %08lx\n", Index: ptrace.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/ptrace.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- ptrace.c 14 Jan 2001 19:40:00 -0000 1.1.1.1 +++ ptrace.c 10 Apr 2002 14:34:35 -0000 1.2 @@ -87,6 +87,19 @@ return 0; } +/* + * Called by kernel/ptrace.c when detaching.. + * + * Make sure the single step bit is not set. + */ +void ptrace_disable(struct task_struct *child) +{ + unsigned long tmp; + /* make sure the single step bit is not set. */ + tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); + put_reg(child, PT_SR, tmp); +} + asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -107,50 +120,29 @@ ret = -ESRCH; read_lock(&tasklist_lock); child = find_task_by_pid(pid); - read_unlock(&tasklist_lock); /* FIXME!!! */ + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); if (!child) goto out; + ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; - if (request == PTRACE_ATTACH) { - if (child == current) - goto out; - if ((!child->dumpable || - (current->uid != child->euid) || - (current->uid != child->suid) || - (current->uid != child->uid) || - (current->gid != child->egid) || - (current->gid != child->sgid) || - (!cap_issubset(child->cap_permitted, current->cap_permitted)) || - (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) - goto out; - /* the same process cannot be attached many times */ - if (child->ptrace & PT_PTRACED) - goto out; - child->ptrace |= PT_PTRACED; + goto out_tsk; - write_lock_irqsave(&tasklist_lock, flags); - if (child->p_pptr != current) { - REMOVE_LINKS(child); - child->p_pptr = current; - SET_LINKS(child); - } - write_unlock_irqrestore(&tasklist_lock, flags); - - send_sig(SIGSTOP, child, 1); - ret = 0; - goto out; + if (request == PTRACE_ATTACH) { + ret = ptrace_attach(child); + goto out_tsk; } ret = -ESRCH; if (!(child->ptrace & PT_PTRACED)) - goto out; + goto out_tsk; if (child->state != TASK_STOPPED) { if (request != PTRACE_KILL) - goto out; + goto out_tsk; } if (child->p_pptr != current) - goto out; + goto out_tsk; switch (request) { /* when I and D space are separate, these will need to be fixed. */ @@ -162,9 +154,9 @@ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); ret = -EIO; if (copied != sizeof(tmp)) - goto out; + break; ret = put_user(tmp,(unsigned long *) data); - goto out; + break; } /* read the word at location addr in the USER area. */ @@ -172,8 +164,9 @@ unsigned long tmp; ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) - goto out; + if ((addr & 3) || addr < 0 || + addr > sizeof(struct user) - 3) + break; tmp = 0; /* Default return condition */ addr = addr >> 2; /* temporary hack. */ @@ -193,9 +186,9 @@ ((tmp & 0x0000ffff) << 16); #endif } else - goto out; + break; ret = put_user(tmp,(unsigned long *) data); - goto out; + break; } /* when I and D space are separate, this will have to be fixed. */ @@ -203,14 +196,15 @@ case PTRACE_POKEDATA: ret = 0; if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) - goto out; + break; ret = -EIO; - goto out; + break; case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) - goto out; + if ((addr & 3) || addr < 0 || + addr > sizeof(struct user) - 3) + break; addr = addr >> 2; /* temporary hack. */ @@ -221,9 +215,9 @@ } if (addr < 19) { if (put_reg(child, addr, data)) - goto out; + break; ret = 0; - goto out; + break; } if (addr >= 21 && addr < 48) { @@ -240,7 +234,7 @@ child->thread.fp[addr - 21] = data; ret = 0; } - goto out; + break; case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ @@ -248,7 +242,7 @@ ret = -EIO; if ((unsigned long) data > _NSIG) - goto out; + break; if (request == PTRACE_SYSCALL) child->ptrace |= PT_TRACESYS; else @@ -259,7 +253,7 @@ put_reg(child, PT_SR, tmp); wake_up_process(child); ret = 0; - goto out; + break; } /* @@ -272,13 +266,13 @@ ret = 0; if (child->state == TASK_ZOMBIE) /* already dead */ - goto out; + break; child->exit_code = SIGKILL; /* make sure the single step bit is not set. */ tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); put_reg(child, PT_SR, tmp); wake_up_process(child); - goto out; + break; } case PTRACE_SINGLESTEP: { /* set the trap flag. */ @@ -286,7 +280,7 @@ ret = -EIO; if ((unsigned long) data > _NSIG) - goto out; + break; child->ptrace &= ~PT_TRACESYS; tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); put_reg(child, PT_SR, tmp); @@ -295,29 +289,12 @@ /* give it a chance to run. */ wake_up_process(child); ret = 0; - goto out; + break; } - case PTRACE_DETACH: { /* detach a process that was attached. */ - long tmp; - - ret = -EIO; - if ((unsigned long) data > _NSIG) - goto out; - child->ptrace &= ~(PT_PTRACED|PT_TRACESYS); - child->exit_code = data; - write_lock_irqsave(&tasklist_lock, flags); - REMOVE_LINKS(child); - child->p_pptr = child->p_opptr; - SET_LINKS(child); - write_unlock_irqrestore(&tasklist_lock, flags); - /* make sure the single step bit is not set. */ - tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); - put_reg(child, PT_SR, tmp); - wake_up_process(child); - ret = 0; - goto out; - } + case PTRACE_DETACH: /* detach a process that was attached. */ + ret = ptrace_detach(child, data); + break; case PTRACE_GETREGS: { /* Get all gp regs from the child. */ int i; @@ -328,12 +305,12 @@ tmp >>= 16; if (put_user(tmp, (unsigned long *) data)) { ret = -EFAULT; - goto out; + break; } data += sizeof(long); } ret = 0; - goto out; + break; } case PTRACE_SETREGS: { /* Set all gp regs in the child. */ @@ -342,7 +319,7 @@ for (i = 0; i < 19; i++) { if (get_user(tmp, (unsigned long *) data)) { ret = -EFAULT; - goto out; + break; } if (i == PT_SR) { tmp &= SR_MASK; @@ -353,7 +330,7 @@ data += sizeof(long); } ret = 0; - goto out; + break; } case PTRACE_GETFPREGS: { /* Get the child FPU state. */ @@ -361,7 +338,7 @@ if (copy_to_user((void *)data, &child->thread.fp, sizeof(struct user_m68kfp_struct))) ret = -EFAULT; - goto out; + break; } case PTRACE_SETFPREGS: { /* Set the child FPU state. */ @@ -369,13 +346,15 @@ if (copy_from_user(&child->thread.fp, (void *)data, sizeof(struct user_m68kfp_struct))) ret = -EFAULT; - goto out; + break; } default: ret = -EIO; - goto out; + break; } +out_tsk: + free_task_struct(child); out: unlock_kernel(); return ret; @@ -383,10 +362,9 @@ asmlinkage void syscall_trace(void) { - lock_kernel(); if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) != (PT_PTRACED|PT_TRACESYS)) - goto out; + return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); @@ -400,6 +378,4 @@ send_sig(current->exit_code, current, 1); current->exit_code = 0; } -out: - unlock_kernel(); } Index: semaphore.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/semaphore.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- semaphore.c 14 Jan 2001 19:40:15 -0000 1.1.1.1 +++ semaphore.c 10 Apr 2002 14:34:35 -0000 1.2 @@ -130,111 +130,3 @@ { return waking_non_zero_trylock(sem); } - - -/* Wait for the lock to become unbiased. Readers - * are non-exclusive. =) - */ -void down_read_failed(struct rw_semaphore *sem) -{ - DECLARE_WAITQUEUE(wait, current); - - __up_read(sem); /* this takes care of granting the lock */ - - add_wait_queue(&sem->wait, &wait); - - while (atomic_read(&sem->count) < 0) { - set_task_state(current, TASK_UNINTERRUPTIBLE); - if (atomic_read(&sem->count) >= 0) - break; - schedule(); - } - - remove_wait_queue(&sem->wait, &wait); - current->state = TASK_RUNNING; -} - -void down_read_failed_biased(struct rw_semaphore *sem) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&sem->wait, &wait); /* put ourselves at the head of the list */ - - for (;;) { - if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0)) - break; - set_task_state(current, TASK_UNINTERRUPTIBLE); - if (!sem->read_bias_granted) - schedule(); - } - - remove_wait_queue(&sem->wait, &wait); - current->state = TASK_RUNNING; -} - - -/* Wait for the lock to become unbiased. Since we're - * a writer, we'll make ourselves exclusive. - */ -void down_write_failed(struct rw_semaphore *sem) -{ - DECLARE_WAITQUEUE(wait, current); - - __up_write(sem); /* this takes care of granting the lock */ - - add_wait_queue_exclusive(&sem->wait, &wait); - - while (atomic_read(&sem->count) < 0) { - set_task_state(current, TASK_UNINTERRUPTIBLE); - if (atomic_read(&sem->count) >= 0) - break; /* we must attempt to acquire or bias the lock */ - schedule(); - } - - remove_wait_queue(&sem->wait, &wait); - current->state = TASK_RUNNING; -} - -void down_write_failed_biased(struct rw_semaphore *sem) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue_exclusive(&sem->write_bias_wait, &wait); /* put ourselves at the end of the list */ - - for (;;) { - if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0)) - break; - set_task_state(current, TASK_UNINTERRUPTIBLE); - if (!sem->write_bias_granted) - schedule(); - } - - remove_wait_queue(&sem->write_bias_wait, &wait); - current->state = TASK_RUNNING; - - /* if the lock is currently unbiased, awaken the sleepers - * FIXME: this wakes up the readers early in a bit of a - * stampede -> bad! - */ - if (atomic_read(&sem->count) >= 0) - wake_up(&sem->wait); -} - - -/* Called when someone has done an up that transitioned from - * negative to non-negative, meaning that the lock has been - * granted to whomever owned the bias. - */ -void rwsem_wake_readers(struct rw_semaphore *sem) -{ - if (xchg(&sem->read_bias_granted, 1)) - BUG(); - wake_up(&sem->wait); -} - -void rwsem_wake_writer(struct rw_semaphore *sem) -{ - if (xchg(&sem->write_bias_granted, 1)) - BUG(); - wake_up(&sem->write_bias_wait); -} Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/setup.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- setup.c 14 Jan 2001 19:40:02 -0000 1.1.1.1 +++ setup.c 10 Apr 2002 14:34:35 -0000 1.2 @@ -34,15 +34,15 @@ #ifdef CONFIG_ATARI #include <asm/atarihw.h> #endif +#ifdef CONFIG_SUN3X +#include <asm/dvma.h> +extern void sun_serial_setup(void); +#endif #ifdef CONFIG_BLK_DEV_INITRD #include <linux/blk.h> #endif -#ifndef CONFIG_AMIGA -#define dbprintf printk -#endif - unsigned long m68k_machtype; unsigned long m68k_cputype; unsigned long m68k_fputype; @@ -110,6 +110,11 @@ char *mach_sysrq_xlate = NULL; #endif +#if defined(CONFIG_ISA) +int isa_type; +int isa_sex; +#endif + extern int amiga_parse_bootinfo(const struct bi_record *); extern int atari_parse_bootinfo(const struct bi_record *); extern int mac_parse_bootinfo(const struct bi_record *); @@ -141,7 +146,7 @@ { while (record->tag != BI_LAST) { int unknown = 0; - const u_long *data = record->data; + const unsigned long *data = record->data; switch (record->tag) { case BI_MACHTYPE: case BI_CPUTYPE: @@ -190,7 +195,7 @@ if (unknown) printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", record->tag); - record = (struct bi_record *)((u_long)record+record->size); + record = (struct bi_record *)((unsigned long)record+record->size); } m68k_realnum_memory = m68k_num_memory; @@ -369,14 +374,44 @@ if (MACH_IS_ATARI) atari_stram_reserve_pages(availmem); #endif +#ifdef CONFIG_SUN3X + if (MACH_IS_SUN3X) { + dvma_init(); +#ifdef CONFIG_SUN3X_ZS + sun_serial_setup(); +#endif + } +#endif + #endif /* !CONFIG_SUN3 */ + paging_init(); + +/* set ISA defs early as possible */ +#if defined(CONFIG_ISA) +#if defined(CONFIG_Q40) + if (MACH_IS_Q40) { + isa_type = Q40_ISA; + isa_sex = 0; + } +#elif defined(CONFIG_GG2) + if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)){ + isa_type = GG2_ISA; + isa_sex = 0; + } +#elif defined(CONFIG_AMIGA_PCMCIA) + if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)){ + isa_type = AG_ISA; + isa_sex = 1; + } +#endif +#endif } int get_cpuinfo(char * buffer) { const char *cpu, *mmu, *fpu; - u_long clockfreq, clockfactor; + unsigned long clockfreq, clockfactor; #define LOOP_CYCLES_68020 (8) #define LOOP_CYCLES_68030 (8) @@ -451,7 +486,7 @@ { int len = 0; char model[80]; - u_long mem; + unsigned long mem; int i; if (mach_get_model) Index: sys_m68k.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/sys_m68k.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- sys_m68k.c 14 Jan 2001 19:40:08 -0000 1.1.1.1 +++ sys_m68k.c 10 Apr 2002 14:34:35 -0000 1.2 @@ -59,9 +59,9 @@ goto out; } - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); @@ -146,9 +146,9 @@ } a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff); - up(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); if (file) fput(file); out: @@ -267,7 +267,8 @@ return -ENOSYS; } -/* Convert virtual address VADDR to physical address PADDR */ + +/* Convert virtual (user) address VADDR to physical address PADDR */ #define virt_to_phys_040(vaddr) \ ({ \ unsigned long _mmusr, _paddr; \ @@ -447,6 +448,12 @@ { unsigned long paddr, i; + /* + * 68060 manual says: + * cpush %dc : flush DC, remains valid (with our %cacr setup) + * cpush %ic : invalidate IC + * cpush %bc : flush DC + invalidate IC + */ switch (scope) { case FLUSH_SCOPE_ALL: @@ -455,20 +462,17 @@ case FLUSH_CACHE_DATA: __asm__ __volatile__ (".chip 68060\n\t" "cpusha %dc\n\t" - "cinva %dc\n\t" ".chip 68k"); break; case FLUSH_CACHE_INSN: __asm__ __volatile__ (".chip 68060\n\t" "cpusha %ic\n\t" - "cinva %ic\n\t" ".chip 68k"); break; default: case FLUSH_CACHE_BOTH: __asm__ __volatile__ (".chip 68060\n\t" "cpusha %bc\n\t" - "cinva %bc\n\t" ".chip 68k"); break; } @@ -506,14 +510,12 @@ case FLUSH_CACHE_DATA: __asm__ __volatile__ (".chip 68060\n\t" "cpushl %%dc,(%0)\n\t" - "cinvl %%dc,(%0)\n\t" ".chip 68k" : : "a" (paddr)); break; case FLUSH_CACHE_INSN: __asm__ __volatile__ (".chip 68060\n\t" "cpushl %%ic,(%0)\n\t" - "cinvl %%ic,(%0)\n\t" ".chip 68k" : : "a" (paddr)); break; @@ -521,7 +523,6 @@ case FLUSH_CACHE_BOTH: __asm__ __volatile__ (".chip 68060\n\t" "cpushl %%bc,(%0)\n\t" - "cinvl %%bc,(%0)\n\t" ".chip 68k" : : "a" (paddr)); break; @@ -568,14 +569,12 @@ case FLUSH_CACHE_DATA: __asm__ __volatile__ (".chip 68060\n\t" "cpushp %%dc,(%0)\n\t" - "cinvp %%dc,(%0)\n\t" ".chip 68k" : : "a" (paddr)); break; case FLUSH_CACHE_INSN: __asm__ __volatile__ (".chip 68060\n\t" "cpushp %%ic,(%0)\n\t" - "cinvp %%ic,(%0)\n\t" ".chip 68k" : : "a" (paddr)); break; @@ -583,7 +582,6 @@ case FLUSH_CACHE_BOTH: __asm__ __volatile__ (".chip 68060\n\t" "cpushp %%bc,(%0)\n\t" - "cinvp %%bc,(%0)\n\t" ".chip 68k" : : "a" (paddr)); break; @@ -607,13 +605,14 @@ goto out; if (scope == FLUSH_SCOPE_ALL) { - /* Only the superuser may flush the whole cache. */ + /* Only the superuser may explicitly flush the whole cache. */ ret = -EPERM; if (!capable(CAP_SYS_ADMIN)) goto out; } else { - /* Verify that the specified address region actually belongs to - * this process. + /* + * Verify that the specified address region actually belongs + * to this process. */ vma = find_vma (current->mm, addr); ret = -EINVAL; @@ -652,10 +651,21 @@ } ret = 0; goto out; - } else if (CPU_IS_040) { + } else { + /* + * 040 or 060: don't blindly trust 'scope', someone could + * try to flush a few megs of memory. + */ + + if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE) + scope=FLUSH_SCOPE_PAGE; + if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL) + scope=FLUSH_SCOPE_ALL; + if (CPU_IS_040) { ret = cache_flush_040 (addr, scope, cache, len); - } else if (CPU_IS_060) { + } else if (CPU_IS_060) { ret = cache_flush_060 (addr, scope, cache, len); + } } out: unlock_kernel(); Index: traps.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/traps.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- traps.c 14 Jan 2001 19:40:12 -0000 1.1.1.1 +++ traps.c 10 Apr 2002 14:34:35 -0000 1.2 @@ -72,6 +72,12 @@ */ void __init base_trap_init(void) { + if(MACH_IS_SUN3X) { + extern e_vector *sun3x_prom_vbr; + + __asm__ volatile ("movec %%vbr, %0" : "=r" ((void*)sun3x_prom_vbr)); + } + /* setup the exception vector table */ __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); @@ -245,9 +251,12 @@ #endif /* CONFIG_M68060 */ #if defined (CONFIG_M68040) -static inline unsigned long probe040(int iswrite, unsigned long addr) +static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs) { unsigned long mmusr; + mm_segment_t old_fs = get_fs(); + + set_fs(MAKE_MM_SEG(wbs)); asm volatile (".chip 68040"); @@ -260,6 +269,8 @@ asm volatile (".chip 68k"); + set_fs(old_fs); + return mmusr; } @@ -267,7 +278,9 @@ unsigned long wbd) { int res = 0; + mm_segment_t old_fs = get_fs(); + /* set_fs can not be moved, otherwise put_user() may oops */ set_fs(MAKE_MM_SEG(wbs)); switch (wbs & WBSIZ_040) { @@ -282,6 +295,10 @@ break; } + /* set_fs can not be moved, otherwise put_user() may oops */ + set_fs(old_fs); + + #ifdef DEBUG printk("do_040writeback1, res=%d\n",res); #endif @@ -293,10 +310,12 @@ * to that exception is discarded, set a few bits in the old frame * to simulate what it should look like */ -static inline void fix_xframe040(struct frame *fp, unsigned short wbs) +static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs) { - fp->un.fmt7.faddr = current->thread.faddr; + fp->un.fmt7.faddr = wba; fp->un.fmt7.ssw = wbs & 0xff; + if (wba != current->thread.faddr) + fp->un.fmt7.ssw |= MA_040; } static inline void do_040writebacks(struct frame *fp) @@ -312,7 +331,7 @@ res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d); if (res) - fix_xframe040(fp, fp->un.fmt7.wb2s); + fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s); else fp->un.fmt7.wb2s = 0; } @@ -322,7 +341,14 @@ res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d); if (res) - fix_xframe040(fp, fp->un.fmt7.wb3s); + { + fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s); + + fp->un.fmt7.wb2s = fp->un.fmt7.wb3s; + fp->un.fmt7.wb3s &= (~WBV_040); + fp->un.fmt7.wb2a = fp->un.fmt7.wb3a; + fp->un.fmt7.wb2d = fp->un.fmt7.wb3d; + } else fp->un.fmt7.wb3s = 0; } @@ -339,19 +365,15 @@ */ asmlinkage void berr_040cleanup(struct frame *fp) { - mm_segment_t old_fs = get_fs(); - fp->un.fmt7.wb2s &= ~4; fp->un.fmt7.wb3s &= ~4; do_040writebacks(fp); - set_fs(old_fs); } static inline void access_error040(struct frame *fp) { unsigned short ssw = fp->un.fmt7.ssw; - mm_segment_t old_fs = get_fs(); unsigned long mmusr; #ifdef DEBUG @@ -374,9 +396,8 @@ if (ssw & MA_040) addr = (addr + 7) & -8; - set_fs(MAKE_MM_SEG(ssw)); /* MMU error, get the MMUSR info for this access */ - mmusr = probe040(!(ssw & RW_040), addr); + mmusr = probe040(!(ssw & RW_040), addr, ssw); #ifdef DEBUG printk("mmusr = %lx\n", mmusr); #endif @@ -386,8 +407,12 @@ __flush_tlb040_one(addr); errorcode = 0; } - if (!(ssw & RW_040)) + + /* despite what documentation seems to say, RMW + * accesses have always both the LK and RW bits set */ + if (!(ssw & RW_040) || (ssw & LK_040)) errorcode |= 2; + if (do_page_fault(&fp->ptregs, addr, errorcode)) { #ifdef DEBUG printk("do_page_fault() !=0 \n"); @@ -415,7 +440,6 @@ } do_040writebacks(fp); - set_fs(old_fs); } #endif /* CONFIG_M68040 */ |