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 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 froml = from >> 5;
52 lindex = from & 0x1f;
53 tnum = lindex + num;
54 numl = (tnum + 0x1f) >> 5;
55 rindex = tnum & 0x1f;
56
57 if (!suser())
58 return -EPERM;
59 if (froml * 32 + tnum > sizeof(current->tss.io_bitmap) * 8 - 8)
60 return -EINVAL;
61
62 #ifdef IODEBUG
63 printk("io: from=%d num=%d %s\n", from, num, (turn_on ? "on" : "off"));
64 #endif
65
66 if (numl) {
67 iop = (unsigned long *)current->tss.io_bitmap + froml;
68 if (lindex != 0) {
69 mask = (~0 << lindex);
70 if (--numl == 0 && rindex)
71 mask &= ~(~0 << rindex);
72 if (turn_on)
73 *iop++ &= ~mask;
74 else
75 *iop++ |= mask;
76 }
77 if (numl) {
78 if (rindex)
79 --numl;
80 mask = (turn_on ? 0 : ~0);
81 while (numl--)
82 *iop++ = mask;
83 if (numl && rindex) {
84 mask = ~(~0 << rindex);
85 if (turn_on)
86 *iop++ &= ~mask;
87 else
88 *iop++ |= mask;
89 }
90 }
91 }
92 return 0;
93 }
94
95 unsigned int *stack;
96
97
98
99
100
101
102
103
104
105
106
107 int sys_iopl(long ebx,long ecx,long edx,
108 long esi, long edi, long ebp, long eax, long ds,
109 long es, long fs, long gs, long orig_eax,
110 long eip,long cs,long eflags,long esp,long ss)
111 {
112 unsigned int level = ebx;
113
114 if (level > 3)
115 return -EINVAL;
116 if (!suser())
117 return -EPERM;
118 *(&eflags) = (eflags & 0xffffcfff) | (level << 12);
119 return 0;
120 }