diff options
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/binfmt_aout32.c | 5 | ||||
-rw-r--r-- | arch/sparc64/kernel/ioctl32.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/psycho.c | 14 | ||||
-rw-r--r-- | arch/sparc64/kernel/ptrace.c | 596 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 13 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 8 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sunos32.c | 3 |
8 files changed, 86 insertions, 561 deletions
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index 7d638c5da..bc77266f9 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -311,9 +311,10 @@ static inline int do_load_aout32_binary(struct linux_binprm * bprm, fd = open_dentry(bprm->dentry, O_RDONLY); if (fd < 0) return fd; - file = fcheck(fd); + file = fget(fd); if (!file->f_op || !file->f_op->mmap) { + fput(fd); sys_close(fd); do_brk(0, ex.a_text+ex.a_data); read_exec(bprm->dentry, fd_offset, @@ -327,6 +328,7 @@ static inline int do_load_aout32_binary(struct linux_binprm * bprm, fd_offset); if (error != N_TXTADDR(ex)) { + fput(file); sys_close(fd); send_sig(SIGKILL, current, 0); return error; @@ -336,6 +338,7 @@ static inline int do_load_aout32_binary(struct linux_binprm * bprm, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset + ex.a_text); + fput(file); sys_close(fd); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index 6759f74d4..833331202 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1696,9 +1696,9 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) int error = -EBADF; lock_kernel(); - filp = fcheck(fd); + filp = fget(fd); if(!filp) - goto out; + goto out2; if (!filp->f_op || !filp->f_op->ioctl) { error = sys_ioctl (fd, cmd, arg); @@ -2381,6 +2381,8 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) break; } out: + fput(filp); +out2: unlock_kernel(); return error; } diff --git a/arch/sparc64/kernel/psycho.c b/arch/sparc64/kernel/psycho.c index 7df9a5882..392ddab55 100644 --- a/arch/sparc64/kernel/psycho.c +++ b/arch/sparc64/kernel/psycho.c @@ -1,4 +1,4 @@ -/* $Id: psycho.c,v 1.85 1999/04/02 14:54:28 davem Exp $ +/* $Id: psycho.c,v 1.86 1999/07/01 10:39:43 davem Exp $ * psycho.c: Ultra/AX U2P PCI controller support. * * Copyright (C) 1997 David S. Miller (davem@caipfs.rutgers.edu) @@ -68,7 +68,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, #include <linux/smp_lock.h> #include <linux/pci.h> -#include <asm/io.h> #include <asm/oplib.h> #include <asm/pbm.h> #include <asm/apb.h> @@ -757,13 +756,15 @@ static void __init apb_init(struct linux_psycho *sabre) unsigned short stmp; unsigned int itmp; +#if 0 for(pdev = pci_devices; pdev; pdev = pdev->next) { if(pdev->vendor == PCI_VENDOR_ID_SUN && pdev->device == PCI_DEVICE_ID_SUN_SABRE) { - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 128); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); break; } } +#endif for (pdev = sabre->pci_bus->devices; pdev; pdev = pdev->sibling) { if (pdev->vendor == PCI_VENDOR_ID_SUN && pdev->device == PCI_DEVICE_ID_SUN_SIMBA) { @@ -795,13 +796,14 @@ static void __init apb_init(struct linux_psycho *sabre) pci_read_config_dword(pdev, APB_PCI_CONTROL_LOW, &itmp); itmp = APB_PCI_CTL_LOW_ERRINT_EN | 0x0f; pci_write_config_dword(pdev, APB_PCI_CONTROL_LOW, itmp); - +#if 0 /* Don't mess with the retry limit and PIO/DMA latency * timer settings. But do set primary and secondary * latency timers. */ - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 128); - pci_write_config_byte(pdev, PCI_SEC_LATENCY_TIMER, 128); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); + pci_write_config_byte(pdev, PCI_SEC_LATENCY_TIMER, 64); +#endif } } } diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 476d53558..61a6a6bfa 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -28,242 +28,6 @@ #define MAGIC_CONSTANT 0x80000000 -/* - * This routine gets a long from any process space by following the page - * tables. NOTE! You should check that the long isn't on a page boundary, - * and that it is in the task area before calling this: this routine does - * no checking. - */ -static pte_t *ptrace_get_page(struct task_struct * tsk, - struct vm_area_struct * vma, unsigned long addr, int write) -{ - pgd_t * pgdir; - pmd_t * pgmiddle; - pte_t * pgtable; - -repeat: - pgdir = pgd_offset(vma->vm_mm, addr); - - /* Seems non-intuitive but the page copy/clear routines always - * check current's value. - */ - current->mm->segments = (void *) (addr & PAGE_SIZE); - - if (pgd_none(*pgdir)) { - handle_mm_fault(tsk, vma, addr, write); - goto repeat; - } - if (pgd_bad(*pgdir)) { - printk("ptrace: bad page directory %016lx\n", pgd_val(*pgdir)); - pgd_clear(pgdir); - return 0; - } - pgmiddle = pmd_offset(pgdir, addr); - if (pmd_none(*pgmiddle)) { - handle_mm_fault(tsk, vma, addr, write); - goto repeat; - } - if (pmd_bad(*pgmiddle)) { - printk("ptrace: bad page middle %016lx\n", pmd_val(*pgmiddle)); - pmd_clear(pgmiddle); - return 0; - } - pgtable = pte_offset(pgmiddle, addr); - if (!pte_present(*pgtable)) { - handle_mm_fault(tsk, vma, addr, write); - goto repeat; - } - if (write && !pte_write(*pgtable)) { - handle_mm_fault(tsk, vma, addr, write); - goto repeat; - } - return pgtable; -} - -/* We must bypass the L1-cache to avoid alias issues. -DaveM */ -static __inline__ unsigned long read_user_long(unsigned long kvaddr) -{ - unsigned long ret; - - __asm__ __volatile__("ldxa [%1] %2, %0" - : "=r" (ret) - : "r" (__pa(kvaddr)), "i" (ASI_PHYS_USE_EC)); - return ret; -} - -static __inline__ unsigned int read_user_int(unsigned long kvaddr) -{ - unsigned int ret; - - __asm__ __volatile__("lduwa [%1] %2, %0" - : "=r" (ret) - : "r" (__pa(kvaddr)), "i" (ASI_PHYS_USE_EC)); - return ret; -} - -static __inline__ void write_user_long(unsigned long kvaddr, unsigned long val) -{ - __asm__ __volatile__("stxa %0, [%1] %2" - : /* no outputs */ - : "r" (val), "r" (__pa(kvaddr)), "i" (ASI_PHYS_USE_EC)); -} - -static __inline__ void write_user_int(unsigned long kvaddr, unsigned int val) -{ - __asm__ __volatile__("stwa %0, [%1] %2" - : /* no outputs */ - : "r" (val), "r" (__pa(kvaddr)), "i" (ASI_PHYS_USE_EC)); -} - -static inline unsigned long get_long(struct task_struct * tsk, - struct vm_area_struct * vma, unsigned long addr) -{ - pte_t * pgtable; - unsigned long page, retval; - - if (!(pgtable = ptrace_get_page (tsk, vma, addr, 0))) return 0; - page = pte_page(*pgtable); -/* this is a hack for non-kernel-mapped video buffers and similar */ - if (MAP_NR(page) >= max_mapnr) - return 0; - page += addr & ~PAGE_MASK; - retval = read_user_long(page); - flush_page_to_ram(page); - return retval; -} - -static inline void put_long(struct task_struct * tsk, struct vm_area_struct * vma, - unsigned long addr, unsigned long data) -{ - pte_t *pgtable; - unsigned long page; - - if (!(pgtable = ptrace_get_page (tsk, vma, addr, 1))) return; - page = pte_page(*pgtable); -/* this is a hack for non-kernel-mapped video buffers and similar */ - flush_cache_page(vma, addr); - if (MAP_NR(page) < max_mapnr) { - unsigned long pgaddr; - - pgaddr = page + (addr & ~PAGE_MASK); - write_user_long(pgaddr, data); - - __asm__ __volatile__(" - membar #StoreStore - flush %0 -" : : "r" (pgaddr & ~7) : "memory"); - } -/* we're bypassing pagetables, so we have to set the dirty bit ourselves */ -/* this should also re-instate whatever read-only mode there was before */ - set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - flush_tlb_page(vma, addr); -} - -static inline unsigned int get_int(struct task_struct * tsk, - struct vm_area_struct * vma, unsigned long addr) -{ - pte_t * pgtable; - unsigned long page; - unsigned int retval; - - if (!(pgtable = ptrace_get_page (tsk, vma, addr, 0))) return 0; - page = pte_page(*pgtable); -/* this is a hack for non-kernel-mapped video buffers and similar */ - if (MAP_NR(page) >= max_mapnr) - return 0; - page += addr & ~PAGE_MASK; - retval = read_user_int(page); - flush_page_to_ram(page); - return retval; -} - -static inline void put_int(struct task_struct * tsk, struct vm_area_struct * vma, - unsigned long addr, unsigned int data) -{ - pte_t *pgtable; - unsigned long page; - - if (!(pgtable = ptrace_get_page (tsk, vma, addr, 1))) return; - page = pte_page(*pgtable); -/* this is a hack for non-kernel-mapped video buffers and similar */ - flush_cache_page(vma, addr); - if (MAP_NR(page) < max_mapnr) { - unsigned long pgaddr; - - pgaddr = page + (addr & ~PAGE_MASK); - write_user_int(pgaddr, data); - - __asm__ __volatile__(" - membar #StoreStore - flush %0 -" : : "r" (pgaddr & ~7) : "memory"); - } -/* we're bypassing pagetables, so we have to set the dirty bit ourselves */ -/* this should also re-instate whatever read-only mode there was before */ - set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - flush_tlb_page(vma, addr); -} - -/* - * This routine checks the page boundaries, and that the offset is - * within the task area. It then calls get_long() to read a long. - */ -static int read_long(struct task_struct * tsk, unsigned long addr, - unsigned long * result) -{ - struct vm_area_struct * vma = find_extend_vma(tsk, addr); - - if (!vma) - return -EIO; - *result = get_long(tsk, vma, addr); - return 0; -} - -/* - * This routine checks the page boundaries, and that the offset is - * within the task area. It then calls get_int() to read a int. - */ -static int read_int(struct task_struct * tsk, unsigned long addr, - unsigned int * result) -{ - struct vm_area_struct * vma = find_extend_vma(tsk, addr); - - if (!vma) - return -EIO; - *result = get_int(tsk, vma, addr); - return 0; -} - -/* - * This routine checks the page boundaries, and that the offset is - * within the task area. It then calls put_long() to write a long. - */ -static int write_long(struct task_struct * tsk, unsigned long addr, - unsigned long data) -{ - struct vm_area_struct * vma = find_extend_vma(tsk, addr); - - if (!vma) - return -EIO; - put_long(tsk, vma, addr, data); - return 0; -} - -/* - * This routine checks the page boundaries, and that the offset is - * within the task area. It then calls put_int() to write a int. - */ -static int write_int(struct task_struct * tsk, unsigned long addr, - unsigned int data) -{ - struct vm_area_struct * vma = find_extend_vma(tsk, addr); - - if (!vma) - return -EIO; - put_int(tsk, vma, addr, data); - return 0; -} - /* Returning from ptrace is a bit tricky because the syscall return * low level code assumes any value returned which is negative and * is a valid errno will mean setting the condition codes to indicate @@ -310,175 +74,6 @@ pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr) pt_succ_return_linux (regs, val, addr); } -#if 0 -/* XXX: Implement this some day */ -/* Fuck me gently with a chainsaw... */ -static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset, - struct task_struct *tsk, long *addr) -{ - struct pt_regs *cregs = tsk->tss.kregs; - struct thread_struct *t = &tsk->tss; - int v; - - if(offset >= 1024) - offset -= 1024; /* whee... */ - if(offset & ((sizeof(unsigned int) - 1))) { - pt_error_return(regs, EIO); - return; - } - if(offset >= 16 && offset < 784) { - offset -= 16; offset >>= 2; - if (t->w_saved) - pt_os_succ_return(regs, *(((unsigned long *)(&t->reg_window[0]))+offset), addr); - return; - } - if(offset >= 784 && offset < 832) { - offset -= 784; offset >>= 2; - if (t->w_saved) - pt_os_succ_return(regs, *(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset), addr); - return; - } - switch(offset) { - case 0: - v = t->ksp; - break; -#if 0 - case 4: - v = t->kpc; - break; -#endif - case 8: - v = t->kpsr; - break; - case 12: - v = t->uwinmask; - break; - case 832: - v = t->w_saved; - break; - case 896: - v = cregs->u_regs[UREG_I0]; - break; - case 900: - v = cregs->u_regs[UREG_I1]; - break; - case 904: - v = cregs->u_regs[UREG_I2]; - break; - case 908: - v = cregs->u_regs[UREG_I3]; - break; - case 912: - v = cregs->u_regs[UREG_I4]; - break; - case 916: - v = cregs->u_regs[UREG_I5]; - break; - case 920: - v = cregs->u_regs[UREG_I6]; - break; - case 924: - if(tsk->tss.flags & MAGIC_CONSTANT) - v = cregs->u_regs[UREG_G1]; - else - v = 0; - break; - case 940: - v = cregs->u_regs[UREG_I0]; - break; - case 944: - v = cregs->u_regs[UREG_I1]; - break; - - case 948: - /* Isn't binary compatibility _fun_??? */ - if(cregs->psr & PSR_C) - v = cregs->u_regs[UREG_I0] << 24; - else - v = 0; - break; - - /* Rest of them are completely unsupported. */ - default: - printk("%s [%d]: Wants to read user offset %ld\n", - current->comm, current->pid, offset); - pt_error_return(regs, EIO); - return; - } - pt_os_succ_return_linux (regs, v, addr); - return; -} - -static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset, - struct task_struct *tsk) -{ - struct pt_regs *cregs = tsk->tss.kregs; - struct thread_struct *t = &tsk->tss; - unsigned int value = regs->u_regs[UREG_I3]; - - if(offset >= 1024) - offset -= 1024; /* whee... */ - if(offset & ((sizeof(unsigned long) - 1))) - goto failure; - if(offset >= 16 && offset < 784) { - offset -= 16; offset >>= 2; - if (t->w_saved) - *(((unsigned long *)(&t->reg_window[0]))+offset) = value; - goto success; - } - if(offset >= 784 && offset < 832) { - offset -= 784; offset >>= 2; - if (t->w_saved) - *(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset) = value; - goto success; - } - switch(offset) { - case 896: - cregs->u_regs[UREG_I0] = value; - break; - case 900: - cregs->u_regs[UREG_I1] = value; - break; - case 904: - cregs->u_regs[UREG_I2] = value; - break; - case 908: - cregs->u_regs[UREG_I3] = value; - break; - case 912: - cregs->u_regs[UREG_I4] = value; - break; - case 916: - cregs->u_regs[UREG_I5] = value; - break; - case 920: - cregs->u_regs[UREG_I6] = value; - break; - case 924: - cregs->u_regs[UREG_I7] = value; - break; - case 940: - cregs->u_regs[UREG_I0] = value; - break; - case 944: - cregs->u_regs[UREG_I1] = value; - break; - - /* Rest of them are completely unsupported or "no-touch". */ - default: - printk("%s [%d]: Wants to write user offset %ld\n", - current->comm, current->pid, offset); - goto failure; - } -success: - pt_succ_return(regs, 0); - return; -failure: - pt_error_return(regs, EIO); - return; -} -#endif - /* #define ALLOW_INIT_TRACING */ /* #define DEBUG_PTRACE */ @@ -642,76 +237,54 @@ asmlinkage void do_ptrace(struct pt_regs *regs) switch(request) { case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { - unsigned long tmp; - int res; + unsigned long tmp64; + unsigned int tmp32; + int res, copied; - /* Non-word alignment _not_ allowed on Sparc. */ + res = -EIO; if (current->tss.flags & SPARC_FLAG_32BIT) { - unsigned int x; - if(addr & (sizeof(unsigned int) - 1)) { - pt_error_return(regs, EINVAL); - goto out; - } - down(&child->mm->mmap_sem); - res = read_int(child, addr, &x); - up(&child->mm->mmap_sem); - tmp = x; + copied = access_process_vm(child, addr, + &tmp32, sizeof(tmp32), 0); + tmp64 = (unsigned long) tmp32; + if (copied == sizeof(tmp32)) + res = 0; } else { - if(addr & (sizeof(unsigned long) - 1)) { - pt_error_return(regs, EINVAL); - goto out; - } - down(&child->mm->mmap_sem); - res = read_long(child, addr, &tmp); - up(&child->mm->mmap_sem); + copied = access_process_vm(child, addr, + &tmp64, sizeof(tmp64), 0); + if (copied == sizeof(tmp64)) + res = 0; } - if (res < 0) { + if (res < 0) pt_error_return(regs, -res); - goto out; - } - pt_os_succ_return(regs, tmp, (long *) data); - goto out; + else + pt_os_succ_return(regs, tmp64, (long *) data); + goto flush_and_out; } - case PTRACE_PEEKUSR: -#if 0 - read_sunos_user(regs, addr, child, (long *) data); -#endif - goto out; - - case PTRACE_POKEUSR: -#if 0 - write_sunos_user(regs, addr, child); -#endif - goto out; - case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: { - int res; + unsigned long tmp64; + unsigned int tmp32; + int copied, res = -EIO; - /* Non-word alignment _not_ allowed on Sparc. */ if (current->tss.flags & SPARC_FLAG_32BIT) { - if(addr & (sizeof(unsigned int) - 1)) { - pt_error_return(regs, EINVAL); - goto out; - } - down(&child->mm->mmap_sem); - res = write_int(child, addr, data); - up(&child->mm->mmap_sem); + tmp32 = data; + copied = access_process_vm(child, addr, + &tmp32, sizeof(tmp32), 1); + if (copied == sizeof(tmp32)) + res = 0; } else { - if(addr & (sizeof(unsigned long) - 1)) { - pt_error_return(regs, EINVAL); - goto out; - } - down(&child->mm->mmap_sem); - res = write_long(child, addr, data); - up(&child->mm->mmap_sem); + tmp64 = data; + copied = access_process_vm(child, addr, + &tmp64, sizeof(tmp64), 1); + if (copied == sizeof(tmp64)) + res = 0; } if(res < 0) pt_error_return(regs, -res); else pt_succ_return(regs, res); - goto out; + goto flush_and_out; } case PTRACE_GETREGS: { @@ -926,98 +499,31 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_READTEXT: case PTRACE_READDATA: { - unsigned char *dest = (unsigned char *) addr2; - unsigned long src = addr; - int len = data, curlen; - struct vm_area_struct *vma; - pte_t *pgtable; - unsigned long page; - - while(len) { - down(&child->mm->mmap_sem); - vma = find_extend_vma(child, src); - if (!vma) { - up(&child->mm->mmap_sem); - pt_error_return(regs, EIO); - goto flush_and_out; - } - pgtable = ptrace_get_page (child, vma, src, 0); - up(&child->mm->mmap_sem); - if (src & ~PAGE_MASK) { - curlen = PAGE_SIZE - (src & ~PAGE_MASK); - if (curlen > len) curlen = len; - } else if (len > PAGE_SIZE) - curlen = PAGE_SIZE; - else - curlen = len; - if (pgtable && MAP_NR(page = pte_page(*pgtable)) < max_mapnr) { - if (copy_to_user (dest, ((char *)page) + (src & ~PAGE_MASK), curlen)) { - flush_page_to_ram(page); - pt_error_return(regs, EFAULT); - goto flush_and_out; - } - flush_page_to_ram(page); - } else { - if (clear_user (dest, curlen)) { - pt_error_return(regs, EFAULT); - goto flush_and_out; - } - } - src += curlen; - dest += curlen; - len -= curlen; + int res = ptrace_readdata(child, addr, + (void *)addr2, data); + if (res == data) { + pt_succ_return(regs, 0); + goto flush_and_out; } - pt_succ_return(regs, 0); + if (res >= 0) + res = -EIO; + pt_error_return(regs, -res); goto flush_and_out; } case PTRACE_WRITETEXT: case PTRACE_WRITEDATA: { - unsigned char *src = (unsigned char *) addr2; - unsigned long dest = addr; - int len = data, curlen; - struct vm_area_struct *vma; - pte_t *pgtable; - unsigned long page; - - while(len) { - down(&child->mm->mmap_sem); - vma = find_extend_vma(child, dest); - if (!vma) { - up(&child->mm->mmap_sem); - pt_error_return(regs, EIO); - goto flush_and_out; - } - pgtable = ptrace_get_page (child, vma, dest, 1); - up(&child->mm->mmap_sem); - if (dest & ~PAGE_MASK) { - curlen = PAGE_SIZE - (dest & ~PAGE_MASK); - if (curlen > len) curlen = len; - } else if (len > PAGE_SIZE) - curlen = PAGE_SIZE; - else - curlen = len; - if (pgtable && MAP_NR(page = pte_page(*pgtable)) < max_mapnr) { - flush_cache_page(vma, dest); - if (copy_from_user (((char *)page) + (dest & ~PAGE_MASK), src, curlen)) { - flush_page_to_ram(page); - set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - flush_tlb_page(vma, dest); - pt_error_return(regs, EFAULT); - goto flush_and_out; - } - flush_page_to_ram(page); - set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - flush_tlb_page(vma, dest); - } - src += curlen; - dest += curlen; - len -= curlen; + int res = ptrace_writedata(child, (void *) addr2, + addr, data); + if (res == data) { + pt_succ_return(regs, 0); + goto flush_and_out; } - pt_succ_return(regs, 0); + if (res >= 0) + res = -EIO; + pt_error_return(regs, -res); goto flush_and_out; } - case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */ addr = 1; @@ -1105,6 +611,14 @@ flush_and_out: unsigned long va; for(va = 0; va < (PAGE_SIZE << 1); va += 32) spitfire_put_dcache_tag(va, 0x0); + if (request == PTRACE_PEEKTEXT || + request == PTRACE_POKETEXT || + request == PTRACE_READTEXT || + request == PTRACE_WRITETEXT) { + for(va = 0; va < (PAGE_SIZE << 1); va += 32) + spitfire_put_icache_tag(va, 0x0); + __asm__ __volatile__("flush %g6"); + } } out: unlock_kernel(); diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index b0e92d50b..a0e8f7e69 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -615,7 +615,7 @@ do { hardirq_enter(cpu); \ unsigned int *inc, *inc2; update_one_process(current, 1, user, !user, cpu); - if(--current->counter < 0) { + if(--current->counter <= 0) { current->counter = 0; current->need_resched = 1; } diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 6d6043617..91277fc4a 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.58 1999/05/08 03:00:31 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.60 1999/07/03 22:11:12 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -45,7 +45,6 @@ #include <asm/ebus.h> #endif #include <asm/a.out.h> -#include <asm/svr4.h> struct poll { int fd; @@ -118,6 +117,12 @@ __attribute__((section("__ksymtab"))) = \ /* used by various drivers */ #ifdef __SMP__ +/* Out of line rw-locking implementation. */ +EXPORT_SYMBOL_PRIVATE(read_lock); +EXPORT_SYMBOL_PRIVATE(read_unlock); +EXPORT_SYMBOL_PRIVATE(write_lock); +EXPORT_SYMBOL_PRIVATE(write_unlock); + /* Kernel wide locking */ EXPORT_SYMBOL(kernel_flag); @@ -158,6 +163,10 @@ EXPORT_SYMBOL(local_irq_count); EXPORT_SYMBOL(local_bh_count); #endif +/* Atomic counter implementation. */ +EXPORT_SYMBOL_PRIVATE(atomic_add); +EXPORT_SYMBOL_PRIVATE(atomic_sub); + EXPORT_SYMBOL(ivector_table); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 77d2ddc6c..0e42e2c32 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -17,7 +17,6 @@ #include <linux/utime.h> #include <linux/resource.h> #include <linux/times.h> -#include <linux/utime.h> #include <linux/utsname.h> #include <linux/timex.h> #include <linux/smp.h> @@ -32,18 +31,15 @@ #include <linux/smb_mount.h> #include <linux/ncp_fs.h> #include <linux/quota.h> -#include <linux/file.h> #include <linux/module.h> #include <linux/sunrpc/svc.h> #include <linux/nfsd/nfsd.h> #include <linux/nfsd/cache.h> #include <linux/nfsd/xdr.h> #include <linux/nfsd/syscall.h> -#include <linux/module.h> #include <linux/poll.h> #include <linux/personality.h> #include <linux/stat.h> -#include <linux/timex.h> #include <asm/types.h> #include <asm/ipc.h> @@ -2328,8 +2324,8 @@ static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm) break; } /* Bump the usage count and install the file. */ - atomic_inc(&fp[i]->f_count); - current->files->fd[new_fd] = fp[i]; + get_file(fp[i]); + fd_install(new_fd, fp[i]); } if (i > 0) { diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 9ea1ffcc2..156d1d8ee 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -25,7 +25,6 @@ #include <linux/signal.h> #include <linux/uio.h> #include <linux/utsname.h> -#include <linux/fs.h> #include <linux/major.h> #include <linux/stat.h> #include <linux/malloc.h> @@ -712,7 +711,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) struct inode *inode; struct file *file; - file = current->files->fd [fd]; + file = fcheck(fd); if(!file) return 0; |