diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 01:05:20 +0000 |
commit | 546db14ee74118296f425f3b91634fb767d67290 (patch) | |
tree | 22b613a3da8d4bf663eec5e155af01b87fdf9094 /kernel/ptrace.c | |
parent | 1e25e41c4f5474e14452094492dbc169b800e4c8 (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.c | 48 |
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; |