* Linus Torvalds <[EMAIL PROTECTED]> wrote: > > Along Linus' suggestion to work on larger chunks in kgdb, here are > > improved probe_kernel_read/write helpers that take a size argument. > > I don't think this is good. > > Make it > - a function, not a #define > - preferably uninlined (this does *not* look performance-critical) > - get rid of the get_fs/set_fs/set_fs dance
yeah. I've done that (see the patch below), and i've just tested that kgdb memory accesses work fine with that: (gdb) disassemble 0xc0153ed9 0xc0153eff Dump of assembler code from 0xc0153ed9 to 0xc0153eff: 0xc0153ed9: sfence 0xc0153edc: xchg %ax,%ax 0xc0153edf: pop %ebp 0xc0153ee0: movl $0x0,0xc0a48088 0xc0153eea: ret 0xc0153eeb: push %ebp 0xc0153eec: mov %esp,%ebp 0xc0153eee: push $0xc058f11d 0xc0153ef3: movl $0x0,0xc0a4bf4c 0xc0153efd: call 0xc0126ec5 End of assembler dump. i have to say, it's quite nice that via kgdb i can _see_ what the paravirt and alternatives stuff ends up patching into our binary image - see the 'sfence' instruction above. Unfortunately looking at the vmlinux is not as reliable as it used to be ;-) ( i've added a separate file for it under mm/maccess.c, because these functions will be needed on NOMMU kernel too, so i couldnt move them into their natural place, mm/memory.c. ) Ingo ----------------> Subject: uaccess: add probe_kernel_write() From: Ingo Molnar <[EMAIL PROTECTED]> add probe_kernel_read() and probe_kernel_write(). Uninlined and restricted to kernel range memory only, as suggested by Linus. Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]> --- include/linux/uaccess.h | 22 ++++++++++++++++++++++ mm/Makefile | 2 +- mm/maccess.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) Index: linux-kgdb.q/include/linux/uaccess.h =================================================================== --- linux-kgdb.q.orig/include/linux/uaccess.h +++ linux-kgdb.q/include/linux/uaccess.h @@ -84,4 +84,26 @@ static inline unsigned long __copy_from_ ret; \ }) +/* + * probe_kernel_read(): safely attempt to read from a location + * @dst: pointer to the buffer that shall take the data + * @src: address to read from + * @size: size of the data chunk + * + * Safely read from address @src to the buffer at @dst. If a kernel fault + * happens, handle that and return -EFAULT. + */ +extern long probe_kernel_read(void *dst, void *src, size_t size); + +/* + * probe_kernel_write(): safely attempt to write to a location + * @dst: address to write to + * @src: pointer to the data that shall be written + * @size: size of the data chunk + * + * Safely write to address @dst from the buffer at @src. If a kernel fault + * happens, handle that and return -EFAULT. + */ +extern long probe_kernel_write(void *dst, void *src, size_t size); + #endif /* __LINUX_UACCESS_H__ */ Index: linux-kgdb.q/mm/Makefile =================================================================== --- linux-kgdb.q.orig/mm/Makefile +++ linux-kgdb.q/mm/Makefile @@ -8,7 +8,7 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o vmalloc.o obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ - page_alloc.o page-writeback.o pdflush.o \ + maccess.o page_alloc.o page-writeback.o pdflush.o \ readahead.o swap.o truncate.o vmscan.o \ prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ page_isolation.o $(mmu-y) Index: linux-kgdb.q/mm/maccess.c =================================================================== --- /dev/null +++ linux-kgdb.q/mm/maccess.c @@ -0,0 +1,46 @@ +/* + * Access kernel memory without faulting. + */ +#include <linux/uaccess.h> +#include <linux/mm.h> + +/** + * probe_kernel_read(): safely attempt to read from a location + * @dst: pointer to the buffer that shall take the data + * @src: address to read from + * @size: size of the data chunk + * + * Safely read from address @src to the buffer at @dst. If a kernel fault + * happens, handle that and return -EFAULT. + */ +long probe_kernel_read(void *dst, void *src, size_t size) +{ + long ret; + + pagefault_disable(); + ret = __copy_from_user_inatomic(dst, + (__force const void __user *)src, size); + pagefault_enable(); + + return ret ? -EFAULT : 0; +} + +/** + * probe_kernel_write(): safely attempt to write to a location + * @dst: address to write to + * @src: pointer to the data that shall be written + * @size: size of the data chunk + * + * Safely write to address @dst from the buffer at @src. If a kernel fault + * happens, handle that and return -EFAULT. + */ +long probe_kernel_write(void *dst, void *src, size_t size) +{ + long ret; + + pagefault_disable(); + ret = __copy_to_user_inatomic((__force void __user *)dst, src, size); + pagefault_enable(); + + return ret ? -EFAULT : 0; +} -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/