📄 uaccess.h
字号:
/* * include/asm-s390/uaccess.h * * S390 version * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Hartmut Penner (hp@de.ibm.com), * Martin Schwidefsky (schwidefsky@de.ibm.com) * * Derived from "include/asm-i386/uaccess.h" */#ifndef __S390_UACCESS_H#define __S390_UACCESS_H/* * User space memory access functions */#include <linux/sched.h>#define VERIFY_READ 0#define VERIFY_WRITE 1/* * The fs value determines whether argument validity checking should be * performed or not. If get_fs() == USER_DS, checking is performed, with * get_fs() == KERNEL_DS, checking is bypassed. * * For historical reasons, these macros are grossly misnamed. */#define MAKE_MM_SEG(s,a) ((mm_segment_t) { (s),(a) })#define KERNEL_DS MAKE_MM_SEG(0x7FFFFFFF,0)#define USER_DS MAKE_MM_SEG(PAGE_OFFSET,1)#define get_ds() (KERNEL_DS)#define get_fs() (current->thread.fs)#define set_fs(x) ({asm volatile("sar 4,%0"::"a" (x.acc4)); \ current->thread.fs = (x);})#define segment_eq(a,b) ((a).acc4 == (b).acc4)#define __access_ok(addr,size) ((((long) addr + size)&0x7FFFFFFFL) < current->addr_limit.seg)#define access_ok(type,addr,size) __access_ok(addr,size)extern inline int verify_area(int type, const void * addr, unsigned long size){ return access_ok(type,addr,size)?0:-EFAULT;}/* * The exception table consists of pairs of addresses: the first is the * address of an instruction that is allowed to fault, and the second is * the address at which the program should continue. No registers are * modified, so it is entirely up to the continuation code to figure out * what to do. * * All the routines below use bits of fixup code that are out of line * with the main instruction path. This means when everything is well, * we don't even have to jump over them. Further, they do not intrude * on our cache or tlb entries. */struct exception_table_entry{ unsigned long insn, fixup;};/* Returns 0 if exception not found and fixup otherwise. */extern unsigned long search_exception_table(unsigned long);/* * These are the main single-value transfer routines. They automatically * use the right size if we just have the right pointer type. */extern inline int __put_user_asm_8(__u64 x, void *ptr){ int err; __asm__ __volatile__ ( " sr %1,%1\n" " la 2,%2\n" " la 4,%0\n" " sacf 512\n" "0: mvc 0(8,4),0(2)\n" " sacf 0\n" "1:\n" ".section .fixup,\"ax\"\n" "2: sacf 0\n" " lhi %1,%h3\n" " bras 4,3f\n" " .long 1b\n" "3: l 4,0(4)\n" " br 4\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 0b,2b\n" ".previous" : "=m" (*((__u32*) ptr)), "=&d" (err) : "m" (x), "K" (-EFAULT) : "cc", "2", "4" ); return err;}extern inline int __put_user_asm_4(__u32 x, void *ptr){ int err; __asm__ __volatile__ ( " sr %1,%1\n" " la 4,%0\n" " sacf 512\n" "0: st %2,0(4)\n" " sacf 0\n" "1:\n" ".section .fixup,\"ax\"\n" "2: sacf 0\n" " lhi %1,%h3\n" " bras 4,3f\n" " .long 1b\n" "3: l 4,0(4)\n" " br 4\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 0b,2b\n" ".previous" : "=m" (*((__u32*) ptr)) , "=&d" (err) : "d" (x), "K" (-EFAULT) : "cc", "4" ); return err;}extern inline int __put_user_asm_2(__u16 x, void *ptr){ int err; __asm__ __volatile__ ( " sr %1,%1\n" " la 4,%0\n" " sacf 512\n" "0: sth %2,0(4)\n" " sacf 0\n" "1:\n" ".section .fixup,\"ax\"\n" "2: sacf 0\n" " lhi %1,%h3\n" " bras 4,3f\n" " .long 1b\n" "3: l 4,0(4)\n" " br 4\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 0b,2b\n" ".previous" : "=m" (*((__u16*) ptr)) , "=&d" (err) : "d" (x), "K" (-EFAULT) : "cc", "4" ); return err;}extern inline int __put_user_asm_1(__u8 x, void *ptr){ int err; __asm__ __volatile__ ( " sr %1,%1\n" " la 4,%0\n" " sacf 512\n" "0: stc %2,0(4)\n" " sacf 0\n" "1:\n" ".section .fixup,\"ax\"\n" "2: sacf 0\n" " lhi %1,%h3\n" " bras 4,3f\n" " .long 1b\n" "3: l 4,0(4)\n" " br 4\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 0b,2b\n" ".previous" : "=m" (*((__u8*) ptr)) , "=&d" (err) : "d" (x), "K" (-EFAULT) : "cc", "4" ); return err;}/* * (u8)(u32) ... autsch, but that the only way we can suppress the * warnings when compiling binfmt_elf.c */#define __put_user(x, ptr) \({ \ int __pu_err; \ switch (sizeof (*(ptr))) { \ case 1: \ __pu_err = __put_user_asm_1((__u8)(__u32)x,(ptr));\ break; \ case 2: \ __pu_err = __put_user_asm_2((__u16)(__u32)x,(ptr));\ break; \ case 4: \ __pu_err = __put_user_asm_4((__u32) x,(ptr));\ break; \ case 8: \ __pu_err = __put_user_asm_8((__u64) x,(ptr));\ break; \ default: \ __pu_err = __put_user_bad(); \ break; \ } \ __pu_err; \})#define put_user(x, ptr) \({ \ long __pu_err = -EFAULT; \ __typeof__(*(ptr)) *__pu_addr = (ptr); \ __typeof__(*(ptr)) __x = (x); \ if (__access_ok((long)__pu_addr,sizeof(*(ptr)))) { \ __pu_err = 0; \ __put_user((__x), (__pu_addr)); \ } \ __pu_err; \})extern int __put_user_bad(void);#define __get_user_asm_8(x, ptr, err) \({ \ __asm__ __volatile__ ( " sr %1,%1\n" \ " la 2,%0\n" \ " la 4,%2\n" \ " sacf 512\n" \ "0: mvc 0(8,2),0(4)\n" \ " sacf 0\n" \ "1:\n" \ ".section .fixup,\"ax\"\n" \ "2: sacf 0\n" \ " lhi %1,%h3\n" \ " bras 4,3f\n" \ " .long 1b\n" \ "3: l 4,0(4)\n" \ " br 4\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,2b\n" \ ".previous" \ : "=m" (x) , "=&d" (err) \ : "m" (*(const __u64*)(ptr)),"K" (-EFAULT) \ : "cc", "2", "4" ); \})#define __get_user_asm_4(x, ptr, err) \({ \ __asm__ __volatile__ ( " sr %1,%1\n" \ " la 4,%2\n" \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -