|
|
1.1 root 1: /*
2: * linux/kernel/ioport.c
3: *
4: * This contains the io-permission bitmap code - written by obz, with changes
5: * by Linus.
6: */
7:
8: #include <linux/sched.h>
9: #include <linux/kernel.h>
1.1.1.2 ! root 10: #include <linux/errno.h>
! 11: #include <linux/types.h>
1.1 root 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: * this changes the io permissions bitmap in the current task.
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: }
1.1.1.2 ! root 94:
! 95: unsigned int *stack;
! 96:
! 97: /*
! 98: * sys_iopl has to be used when you want to access the IO ports
! 99: * beyond the 0x3ff range: to get the full 65536 ports bitmapped
! 100: * you'd need 8kB of bitmaps/process, which is a bit excessive.
! 101: *
! 102: * Here we just change the eflags value on the stack: we allow
! 103: * only the super-user to do it. This depends on the stack-layout
! 104: * on system-call entry - see also fork() and the signal handling
! 105: * code.
! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.