diff options
Diffstat (limited to 'arch/x86/include/asm/xen/page.h')
| -rw-r--r-- | arch/x86/include/asm/xen/page.h | 35 | 
1 files changed, 31 insertions, 4 deletions
| diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 123e669bf363..790ce08e41f2 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -9,7 +9,7 @@  #include <linux/mm.h>  #include <linux/device.h> -#include <linux/uaccess.h> +#include <asm/extable.h>  #include <asm/page.h>  #include <asm/pgtable.h> @@ -93,12 +93,39 @@ clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,   */  static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val)  { -	return __put_user(val, (unsigned long __user *)addr); +	int ret = 0; + +	asm volatile("1: mov %[val], %[ptr]\n" +		     "2:\n" +		     ".section .fixup, \"ax\"\n" +		     "3: sub $1, %[ret]\n" +		     "   jmp 2b\n" +		     ".previous\n" +		     _ASM_EXTABLE(1b, 3b) +		     : [ret] "+r" (ret), [ptr] "=m" (*addr) +		     : [val] "r" (val)); + +	return ret;  } -static inline int xen_safe_read_ulong(unsigned long *addr, unsigned long *val) +static inline int xen_safe_read_ulong(const unsigned long *addr, +				      unsigned long *val)  { -	return __get_user(*val, (unsigned long __user *)addr); +	int ret = 0; +	unsigned long rval = ~0ul; + +	asm volatile("1: mov %[ptr], %[rval]\n" +		     "2:\n" +		     ".section .fixup, \"ax\"\n" +		     "3: sub $1, %[ret]\n" +		     "   jmp 2b\n" +		     ".previous\n" +		     _ASM_EXTABLE(1b, 3b) +		     : [ret] "+r" (ret), [rval] "+r" (rval) +		     : [ptr] "m" (*addr)); +	*val = rval; + +	return ret;  }  #ifdef CONFIG_XEN_PV |