summaryrefslogtreecommitdiffstats
path: root/kernel/ptrace.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
commit546db14ee74118296f425f3b91634fb767d67290 (patch)
tree22b613a3da8d4bf663eec5e155af01b87fdf9094 /kernel/ptrace.c
parent1e25e41c4f5474e14452094492dbc169b800e4c8 (diff)
Merge with Linux 2.3.23. The new bootmem stuff has broken various
platforms. At this time I've only verified that IP22 support compiles and IP27 actually works.
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r--kernel/ptrace.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 35fa9768d..4945a0223 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -10,7 +10,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/mm.h>
-#include <linux/bigmem.h>
+#include <linux/highmem.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -23,7 +23,9 @@ static int access_one_page(struct task_struct * tsk, struct vm_area_struct * vma
pgd_t * pgdir;
pmd_t * pgmiddle;
pte_t * pgtable;
- unsigned long page;
+ unsigned long mapnr;
+ unsigned long maddr;
+ struct page *page;
repeat:
pgdir = pgd_offset(vma->vm_mm, addr);
@@ -39,27 +41,25 @@ repeat:
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable))
goto fault_in_page;
- page = pte_page(*pgtable);
+ mapnr = pte_pagenr(*pgtable);
if (write && (!pte_write(*pgtable) || !pte_dirty(*pgtable)))
goto fault_in_page;
- if (MAP_NR(page) >= max_mapnr)
+ if (mapnr >= max_mapnr)
return 0;
+ page = mem_map + mapnr;
flush_cache_page(vma, addr);
- {
- void *src = (void *) (page + (addr & ~PAGE_MASK));
- void *dst = buf;
- if (write) {
- dst = src;
- src = buf;
- }
- src = (void *) kmap((unsigned long) src, KM_READ);
- dst = (void *) kmap((unsigned long) dst, KM_WRITE);
- memcpy(dst, src, len);
- kunmap((unsigned long) src, KM_READ);
- kunmap((unsigned long) dst, KM_WRITE);
+ if (write) {
+ maddr = kmap(page, KM_WRITE);
+ memcpy((char *)maddr + (addr & ~PAGE_MASK), buf, len);
+ flush_page_to_ram(page);
+ kunmap(maddr, KM_WRITE);
+ } else {
+ maddr = kmap(page, KM_READ);
+ memcpy(buf, (char *)maddr + (addr & ~PAGE_MASK), len);
+ flush_page_to_ram(page);
+ kunmap(maddr, KM_READ);
}
- flush_page_to_ram(page);
return len;
fault_in_page:
@@ -69,23 +69,25 @@ fault_in_page:
return 0;
bad_pgd:
- printk("ptrace: bad pgd in '%s' at %08lx (%08lx)\n", tsk->comm, addr, pgd_val(*pgdir));
+ pgd_ERROR(*pgdir);
return 0;
bad_pmd:
- printk("ptrace: bad pmd in '%s' at %08lx (%08lx)\n", tsk->comm, addr, pmd_val(*pgmiddle));
+ pmd_ERROR(*pgmiddle);
return 0;
}
int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
{
int copied;
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- if (!vma)
- return 0;
+ struct vm_area_struct * vma;
down(&tsk->mm->mmap_sem);
+ vma = find_extend_vma(tsk, addr);
+ if (!vma) {
+ up(&tsk->mm->mmap_sem);
+ return 0;
+ }
copied = 0;
for (;;) {
unsigned long offset = addr & ~PAGE_MASK;