patch-2.1.101 linux/arch/sparc64/kernel/ptrace.c
Next file: linux/arch/sparc64/kernel/smp.c
Previous file: linux/arch/sparc64/kernel/psycho.c
Back to the patch index
Back to the overall index
- Lines: 174
- Date:
Fri May 8 00:11:29 1998
- Orig file:
v2.1.100/linux/arch/sparc64/kernel/ptrace.c
- Orig date:
Thu May 7 22:51:47 1998
diff -u --recursive --new-file v2.1.100/linux/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
@@ -19,6 +19,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <asm/asi.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -72,6 +73,41 @@
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)
{
@@ -84,7 +120,7 @@
if (MAP_NR(page) >= max_mapnr)
return 0;
page += addr & ~PAGE_MASK;
- retval = *(unsigned long *) page;
+ retval = read_user_long(page);
flush_page_to_ram(page);
return retval;
}
@@ -103,14 +139,12 @@
unsigned long pgaddr;
pgaddr = page + (addr & ~PAGE_MASK);
- *(unsigned long *) (pgaddr) = data;
+ write_user_long(pgaddr, data);
__asm__ __volatile__("
membar #StoreStore
flush %0
" : : "r" (pgaddr & ~7) : "memory");
-
- flush_page_to_ram(page);
}
/* 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 */
@@ -131,7 +165,7 @@
if (MAP_NR(page) >= max_mapnr)
return 0;
page += addr & ~PAGE_MASK;
- retval = *(unsigned int *) page;
+ retval = read_user_int(page);
flush_page_to_ram(page);
return retval;
}
@@ -150,14 +184,12 @@
unsigned long pgaddr;
pgaddr = page + (addr & ~PAGE_MASK);
- *(unsigned int *) (pgaddr) = data;
+ write_user_int(pgaddr, data);
__asm__ __volatile__("
membar #StoreStore
flush %0
" : : "r" (pgaddr & ~7) : "memory");
-
- flush_page_to_ram(page);
}
/* 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 */
@@ -890,7 +922,7 @@
vma = find_extend_vma(child, src);
if (!vma) {
pt_error_return(regs, EIO);
- goto out;
+ goto flush_and_out;
}
pgtable = get_page (child, vma, src, 0);
if (src & ~PAGE_MASK) {
@@ -904,13 +936,13 @@
if (copy_to_user (dest, ((char *)page) + (src & ~PAGE_MASK), curlen)) {
flush_page_to_ram(page);
pt_error_return(regs, EFAULT);
- goto out;
+ goto flush_and_out;
}
flush_page_to_ram(page);
} else {
if (clear_user (dest, curlen)) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto flush_and_out;
}
}
src += curlen;
@@ -918,7 +950,7 @@
len -= curlen;
}
pt_succ_return(regs, 0);
- goto out;
+ goto flush_and_out;
}
case PTRACE_WRITETEXT:
@@ -934,7 +966,7 @@
vma = find_extend_vma(child, dest);
if (!vma) {
pt_error_return(regs, EIO);
- goto out;
+ goto flush_and_out;
}
pgtable = get_page (child, vma, dest, 1);
if (dest & ~PAGE_MASK) {
@@ -951,7 +983,7 @@
set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
flush_tlb_page(vma, dest);
pt_error_return(regs, EFAULT);
- goto out;
+ goto flush_and_out;
}
flush_page_to_ram(page);
set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
@@ -962,7 +994,7 @@
len -= curlen;
}
pt_succ_return(regs, 0);
- goto out;
+ goto flush_and_out;
}
case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
@@ -1040,6 +1072,12 @@
default:
pt_error_return(regs, EIO);
goto out;
+ }
+flush_and_out:
+ {
+ unsigned long va;
+ for(va = 0; va < (PAGE_SIZE << 1); va += 32)
+ spitfire_put_dcache_tag(va, 0x0);
}
out:
unlock_kernel();
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov