File: segment.h

package info (click to toggle)
kernel-source-2.0.38 2.0.38-3
  • links: PTS
  • area: main
  • in suites: potato
  • size: 34,660 kB
  • ctags: 102,964
  • sloc: ansic: 632,204; asm: 26,444; makefile: 4,286; sh: 1,276; perl: 761; tcl: 408; cpp: 277; lisp: 211; awk: 134
file content (134 lines) | stat: -rw-r--r-- 2,726 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* $Id: segment.h,v 1.10 1996/03/08 01:19:38 miguel Exp $ */
#ifndef _ASM_SEGMENT_H
#define _ASM_SEGMENT_H

#ifdef __KERNEL__
#include <asm/vac-ops.h>
#endif

#ifndef __ASSEMBLY__

/*
 * Uh, these should become the main single-value transfer routines..
 * They automatically use the right size if we just have the right
 * pointer type..
 */
#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))

/*
 * This is a silly but good way to make sure that
 * the __put_user function is indeed always optimized,
 * and that we use the correct sizes..
 */
extern int bad_user_access_length(void);

/* I should make this use unaligned transfers etc.. */
static inline void __put_user(unsigned long x, void * y, int size)
{
	switch (size) {
		case 1:
			*(char *) y = x;
			break;
		case 2:
			*(short *) y = x;
			break;
		case 4:
			*(int *) y = x;
			break;
		default:
			bad_user_access_length();
	}
}

/* I should make this use unaligned transfers etc.. */
static inline unsigned long __get_user(const void * y, int size)
{
	switch (size) {
		case 1:
			return *(unsigned char *) y;
		case 2:
			return *(unsigned short *) y;
		case 4:
			return *(unsigned int *) y;
		default:
			return bad_user_access_length();
	}
}

/*
 * Deprecated routines
 */

static inline unsigned char get_user_byte(const char * addr)
{
	return *addr;
}

#define get_fs_byte(addr) get_user_byte((char *)(addr))

static inline unsigned short get_user_word(const short *addr)
{
	return *addr;
}

#define get_fs_word(addr) get_user_word((short *)(addr))

static inline unsigned long get_user_long(const int *addr)
{
	return *addr;
}

#define get_fs_long(addr) get_user_long((int *)(addr))

static inline void put_user_byte(char val,char *addr)
{
	*addr = val;
}

#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))

static inline void put_user_word(short val,short * addr)
{
	*addr = val;
}

#define put_fs_word(x,addr) put_user_word((x),(short *)(addr))

static inline void put_user_long(unsigned long val,int * addr)
{
	*addr = val;
}

#define put_fs_long(x,addr) put_user_long((x),(int *)(addr))

#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n))

#define memcpy_tofs(to, from, n) memcpy((to),(from),(n))

/* Sparc is not segmented, however we need to be able to fool verify_area()
 * when doing system calls from kernel mode legitimately.
 */
#define KERNEL_DS   0
#define USER_DS     1

extern int active_ds;

static inline int get_fs(void)
{
	return active_ds;
}

static inline int get_ds(void)
{
	return KERNEL_DS;
}

static inline void set_fs(int val)
{
	active_ds = val;
}

#endif  /* __ASSEMBLY__ */

#endif /* _ASM_SEGMENT_H */