diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2012-01-23 09:41:27 +0000 |
---|---|---|
committer | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2012-01-23 09:41:27 +0000 |
commit | 7b8c36701d267971f189b435362bce8ff2266e79 (patch) | |
tree | 69e6db7b19474fada930ed0a9be2acd31c808d3f /xen/arch/x86/usercopy.c | |
parent | 02a59232513240899da538380010accf3d24f687 (diff) | |
download | xen-7b8c36701d267971f189b435362bce8ff2266e79.tar.gz xen-7b8c36701d267971f189b435362bce8ff2266e79.tar.bz2 xen-7b8c36701d267971f189b435362bce8ff2266e79.zip |
Introduce clear_user and clear_guest
Introduce clear_user for x86 and ia64, shamelessly taken from Linux.
The x86 version is the 32 bit clear_user implementation. Introduce
clear_guest for x86 and ia64. The x86 implementation is based on
clear_user and a new clear_user_hvm function. The ia64 implementation
is actually in xencomm and it is based on xencomm_copy_to_guest.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Jan Beulich <JBeulich@suse.com>
Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/usercopy.c')
-rw-r--r-- | xen/arch/x86/usercopy.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/xen/arch/x86/usercopy.c b/xen/arch/x86/usercopy.c index d88e635bb0..47dadaeaee 100644 --- a/xen/arch/x86/usercopy.c +++ b/xen/arch/x86/usercopy.c @@ -110,6 +110,42 @@ copy_to_user(void __user *to, const void *from, unsigned n) return n; } +#define __do_clear_user(addr,size) \ +do { \ + long __d0; \ + __asm__ __volatile__( \ + "0: rep; stosl\n" \ + " movl %2,%0\n" \ + "1: rep; stosb\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: lea 0(%2,%0,4),%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(0b,3b) \ + _ASM_EXTABLE(1b,2b) \ + : "=&c"(size), "=&D" (__d0) \ + : "r"(size & 3), "0"(size / 4), "1"((long)addr), "a"(0)); \ +} while (0) + +/** + * clear_user: - Zero a block of memory in user space. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ +unsigned long +clear_user(void __user *to, unsigned n) +{ + if ( access_ok(to, n) ) + __do_clear_user(to, n); + return n; +} + /** * copy_from_user: - Copy a block of data from user space. * @to: Destination address, in kernel space. |