Loading arch/s390/include/asm/system.h +2 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,8 @@ extern void pfault_fini(void); extern void cmma_init(void); extern int memcpy_real(void *, void *, size_t); extern void copy_to_absolute_zero(void *dest, void *src, size_t count); extern int copy_to_user_real(void __user *dest, void *src, size_t count); extern int copy_from_user_real(void *dest, void __user *src, size_t count); #define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ Loading arch/s390/mm/maccess.c +56 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/gfp.h> #include <asm/system.h> /* Loading Loading @@ -60,6 +61,9 @@ long probe_kernel_write(void *dst, const void *src, size_t size) return copied < 0 ? -EFAULT : 0; } /* * Copy memory in real mode (kernel to kernel) */ int memcpy_real(void *dest, void *src, size_t count) { register unsigned long _dest asm("2") = (unsigned long) dest; Loading Loading @@ -101,3 +105,55 @@ void copy_to_absolute_zero(void *dest, void *src, size_t count) __ctl_load(cr0, 0, 0); preempt_enable(); } /* * Copy memory from kernel (real) to user (virtual) */ int copy_to_user_real(void __user *dest, void *src, size_t count) { int offs = 0, size, rc; char *buf; buf = (char *) __get_free_page(GFP_KERNEL); if (!buf) return -ENOMEM; rc = -EFAULT; while (offs < count) { size = min(PAGE_SIZE, count - offs); if (memcpy_real(buf, src + offs, size)) goto out; if (copy_to_user(dest + offs, buf, size)) goto out; offs += size; } rc = 0; out: free_page((unsigned long) buf); return rc; } /* * Copy memory from user (virtual) to kernel (real) */ int copy_from_user_real(void *dest, void __user *src, size_t count) { int offs = 0, size, rc; char *buf; buf = (char *) __get_free_page(GFP_KERNEL); if (!buf) return -ENOMEM; rc = -EFAULT; while (offs < count) { size = min(PAGE_SIZE, count - offs); if (copy_from_user(buf, src + offs, size)) goto out; if (memcpy_real(dest + offs, buf, size)) goto out; offs += size; } rc = 0; out: free_page((unsigned long) buf); return rc; } drivers/s390/char/zcore.c +2 −18 Original line number Diff line number Diff line Loading @@ -142,22 +142,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) return memcpy_hsa(dest, src, count, TO_KERNEL); } static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) { static char buf[4096]; int offs = 0, size; while (offs < count) { size = min(sizeof(buf), count - offs); if (memcpy_real(buf, (void *) src + offs, size)) return -EFAULT; if (copy_to_user(dest + offs, buf, size)) return -EFAULT; offs += size; } return 0; } static int __init init_cpu_info(enum arch_id arch) { struct save_area *sa; Loading Loading @@ -346,8 +330,8 @@ static ssize_t zcore_read(struct file *file, char __user *buf, size_t count, /* Copy from real mem */ size = count - mem_offs - hdr_count; rc = memcpy_real_user(buf + hdr_count + mem_offs, mem_start + mem_offs, size); rc = copy_to_user_real(buf + hdr_count + mem_offs, (void *) mem_start + mem_offs, size); if (rc) goto fail; Loading Loading
arch/s390/include/asm/system.h +2 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,8 @@ extern void pfault_fini(void); extern void cmma_init(void); extern int memcpy_real(void *, void *, size_t); extern void copy_to_absolute_zero(void *dest, void *src, size_t count); extern int copy_to_user_real(void __user *dest, void *src, size_t count); extern int copy_from_user_real(void *dest, void __user *src, size_t count); #define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ Loading
arch/s390/mm/maccess.c +56 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/gfp.h> #include <asm/system.h> /* Loading Loading @@ -60,6 +61,9 @@ long probe_kernel_write(void *dst, const void *src, size_t size) return copied < 0 ? -EFAULT : 0; } /* * Copy memory in real mode (kernel to kernel) */ int memcpy_real(void *dest, void *src, size_t count) { register unsigned long _dest asm("2") = (unsigned long) dest; Loading Loading @@ -101,3 +105,55 @@ void copy_to_absolute_zero(void *dest, void *src, size_t count) __ctl_load(cr0, 0, 0); preempt_enable(); } /* * Copy memory from kernel (real) to user (virtual) */ int copy_to_user_real(void __user *dest, void *src, size_t count) { int offs = 0, size, rc; char *buf; buf = (char *) __get_free_page(GFP_KERNEL); if (!buf) return -ENOMEM; rc = -EFAULT; while (offs < count) { size = min(PAGE_SIZE, count - offs); if (memcpy_real(buf, src + offs, size)) goto out; if (copy_to_user(dest + offs, buf, size)) goto out; offs += size; } rc = 0; out: free_page((unsigned long) buf); return rc; } /* * Copy memory from user (virtual) to kernel (real) */ int copy_from_user_real(void *dest, void __user *src, size_t count) { int offs = 0, size, rc; char *buf; buf = (char *) __get_free_page(GFP_KERNEL); if (!buf) return -ENOMEM; rc = -EFAULT; while (offs < count) { size = min(PAGE_SIZE, count - offs); if (copy_from_user(buf, src + offs, size)) goto out; if (memcpy_real(dest + offs, buf, size)) goto out; offs += size; } rc = 0; out: free_page((unsigned long) buf); return rc; }
drivers/s390/char/zcore.c +2 −18 Original line number Diff line number Diff line Loading @@ -142,22 +142,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) return memcpy_hsa(dest, src, count, TO_KERNEL); } static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) { static char buf[4096]; int offs = 0, size; while (offs < count) { size = min(sizeof(buf), count - offs); if (memcpy_real(buf, (void *) src + offs, size)) return -EFAULT; if (copy_to_user(dest + offs, buf, size)) return -EFAULT; offs += size; } return 0; } static int __init init_cpu_info(enum arch_id arch) { struct save_area *sa; Loading Loading @@ -346,8 +330,8 @@ static ssize_t zcore_read(struct file *file, char __user *buf, size_t count, /* Copy from real mem */ size = count - mem_offs - hdr_count; rc = memcpy_real_user(buf + hdr_count + mem_offs, mem_start + mem_offs, size); rc = copy_to_user_real(buf + hdr_count + mem_offs, (void *) mem_start + mem_offs, size); if (rc) goto fail; Loading