This source file includes following definitions.
- ios
- dump_io_bitmap
- sys_ioperm
- sys_iopl
1
2
3
4
5
6
7
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/types.h>
12
13 #define _IODEBUG
14
15 #ifdef IODEBUG
16 static char * ios(unsigned long l)
17 {
18 static char str[33] = { '\0' };
19 int i;
20 unsigned long mask;
21
22 for (i = 0, mask = 0x80000000; i < 32; ++i, mask >>= 1)
23 str[i] = (l & mask) ? '1' : '0';
24 return str;
25 }
26
27 static void dump_io_bitmap(void)
28 {
29 int i, j;
30 int numl = sizeof(current->tss.io_bitmap) >> 2;
31
32 for (i = j = 0; j < numl; ++i)
33 {
34 printk("%4d [%3x]: ", 64*i, 64*i);
35 printk("%s ", ios(current->tss.io_bitmap[j++]));
36 if (j < numl)
37 printk("%s", ios(current->tss.io_bitmap[j++]));
38 printk("\n");
39 }
40 }
41 #endif
42
43
44
45
46 extern "C" int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
47 {
48 unsigned long froml, lindex, tnum, numl, rindex, mask;
49 unsigned long *iop;
50
51 if (from + num <= from)
52 return -EINVAL;
53 if (from + num > IO_BITMAP_SIZE*32)
54 return -EINVAL;
55 if (!suser())
56 return -EPERM;
57 froml = from >> 5;
58 lindex = from & 0x1f;
59 tnum = lindex + num;
60 numl = (tnum + 0x1f) >> 5;
61 rindex = tnum & 0x1f;
62
63 #ifdef IODEBUG
64 printk("io: from=%d num=%d %s\n", from, num, (turn_on ? "on" : "off"));
65 #endif
66
67 if (numl) {
68 iop = (unsigned long *)current->tss.io_bitmap + froml;
69 if (lindex != 0) {
70 mask = (~0 << lindex);
71 if (--numl == 0 && rindex)
72 mask &= ~(~0 << rindex);
73 if (turn_on)
74 *iop++ &= ~mask;
75 else
76 *iop++ |= mask;
77 }
78 if (numl) {
79 if (rindex)
80 --numl;
81 mask = (turn_on ? 0 : ~0);
82 while (numl--)
83 *iop++ = mask;
84 if (numl && rindex) {
85 mask = ~(~0 << rindex);
86 if (turn_on)
87 *iop++ &= ~mask;
88 else
89 *iop++ |= mask;
90 }
91 }
92 }
93 return 0;
94 }
95
96 unsigned int *stack;
97
98
99
100
101
102
103
104
105
106
107
108 extern "C" int sys_iopl(long ebx,long ecx,long edx,
109 long esi, long edi, long ebp, long eax, long ds,
110 long es, long fs, long gs, long orig_eax,
111 long eip,long cs,long eflags,long esp,long ss)
112 {
113 unsigned int level = ebx;
114
115 if (level > 3)
116 return -EINVAL;
117 if (!suser())
118 return -EPERM;
119 *(&eflags) = (eflags & 0xffffcfff) | (level << 12);
120 return 0;
121 }