This source file includes following definitions.
- disable_hlt
- enable_hlt
- sys_idle
- kb_wait
- hard_reset_now
- show_regs
- exit_thread
- flush_thread
- copy_thread
- dump_fpu
- dump_thread
- sys_fork
- sys_clone
- sys_execve
1
2
3
4
5
6
7
8
9
10
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/mm.h>
15 #include <linux/stddef.h>
16 #include <linux/unistd.h>
17 #include <linux/ptrace.h>
18 #include <linux/malloc.h>
19 #include <linux/ldt.h>
20 #include <linux/user.h>
21 #include <linux/a.out.h>
22
23 #include <asm/segment.h>
24 #include <asm/pgtable.h>
25 #include <asm/system.h>
26 #include <asm/io.h>
27
28 asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
29
30 static int hlt_counter=0;
31
32 void disable_hlt(void)
33 {
34 hlt_counter++;
35 }
36
37 void enable_hlt(void)
38 {
39 hlt_counter--;
40 }
41
42
43
44
45 asmlinkage int sys_idle(void)
46 {
47 if (current->pid != 0)
48 return -EPERM;
49
50
51 current->counter = -100;
52 for (;;) {
53 if (hlt_works_ok && !hlt_counter && !need_resched)
54 __asm__("hlt");
55 schedule();
56 }
57 }
58
59
60
61
62
63
64 static long no_idt[2] = {0, 0};
65
66 static inline void kb_wait(void)
67 {
68 int i;
69
70 for (i=0; i<0x10000; i++)
71 if ((inb_p(0x64) & 0x02) == 0)
72 break;
73 }
74
75 void hard_reset_now(void)
76 {
77 int i, j;
78
79 sti();
80
81 pg0[0] = 7;
82 *((unsigned short *)0x472) = 0x1234;
83 for (;;) {
84 for (i=0; i<100; i++) {
85 kb_wait();
86 for(j = 0; j < 100000 ; j++)
87 ;
88 outb(0xfe,0x64);
89 }
90 __asm__ __volatile__("\tlidt %0": "=m" (no_idt));
91 }
92 }
93
94 void show_regs(struct pt_regs * regs)
95 {
96 printk("\n");
97 printk("EIP: %04x:%08lx",0xffff & regs->cs,regs->eip);
98 if (regs->cs & 3)
99 printk(" ESP: %04x:%08lx",0xffff & regs->ss,regs->esp);
100 printk(" EFLAGS: %08lx\n",regs->eflags);
101 printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
102 regs->eax,regs->ebx,regs->ecx,regs->edx);
103 printk("ESI: %08lx EDI: %08lx EBP: %08lx",
104 regs->esi, regs->edi, regs->ebp);
105 printk(" DS: %04x ES: %04x FS: %04x GS: %04x\n",
106 0xffff & regs->ds,0xffff & regs->es,
107 0xffff & regs->fs,0xffff & regs->gs);
108 }
109
110
111
112
113 void exit_thread(void)
114 {
115
116 if (last_task_used_math == current)
117 last_task_used_math = NULL;
118
119 __asm__ __volatile__("mov %w0,%%fs ; mov %w0,%%gs ; lldt %w0"
120 :
121 : "r" (0));
122 current->tss.ldt = 0;
123 if (current->ldt) {
124 void * ldt = current->ldt;
125 current->ldt = NULL;
126 vfree(ldt);
127 }
128 }
129
130 void flush_thread(void)
131 {
132 int i;
133
134 if (current->ldt) {
135 free_page((unsigned long) current->ldt);
136 current->ldt = NULL;
137 for (i=1 ; i<NR_TASKS ; i++) {
138 if (task[i] == current) {
139 set_ldt_desc(gdt+(i<<1)+
140 FIRST_LDT_ENTRY,&default_ldt, 1);
141 load_ldt(i);
142 }
143 }
144 }
145
146 for (i=0 ; i<8 ; i++)
147 current->debugreg[i] = 0;
148 }
149
150 void copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
151 struct task_struct * p, struct pt_regs * regs)
152 {
153 int i;
154 struct pt_regs * childregs;
155
156 p->tss.es = KERNEL_DS;
157 p->tss.cs = KERNEL_CS;
158 p->tss.ss = KERNEL_DS;
159 p->tss.ds = KERNEL_DS;
160 p->tss.fs = USER_DS;
161 p->tss.gs = KERNEL_DS;
162 p->tss.ss0 = KERNEL_DS;
163 p->tss.esp0 = p->kernel_stack_page + PAGE_SIZE;
164 p->tss.tr = _TSS(nr);
165 childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1;
166 p->tss.esp = (unsigned long) childregs;
167 p->tss.eip = (unsigned long) ret_from_sys_call;
168 *childregs = *regs;
169 childregs->eax = 0;
170 childregs->esp = esp;
171 p->tss.back_link = 0;
172 p->tss.eflags = regs->eflags & 0xffffcfff;
173 p->tss.ldt = _LDT(nr);
174 if (p->ldt) {
175 p->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
176 if (p->ldt != NULL)
177 memcpy(p->ldt, current->ldt, LDT_ENTRIES*LDT_ENTRY_SIZE);
178 }
179 set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
180 if (p->ldt)
181 set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,p->ldt, 512);
182 else
183 set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&default_ldt, 1);
184 p->tss.bitmap = offsetof(struct thread_struct,io_bitmap);
185 for (i = 0; i < IO_BITMAP_SIZE+1 ; i++)
186 p->tss.io_bitmap[i] = ~0;
187 if (last_task_used_math == current)
188 __asm__("clts ; fnsave %0 ; frstor %0":"=m" (p->tss.i387));
189 }
190
191
192
193
194 int dump_fpu (struct user_i387_struct* fpu)
195 {
196 int fpvalid;
197
198
199
200 if (hard_math) {
201 if ((fpvalid = current->used_math) != 0) {
202 if (last_task_used_math == current)
203 __asm__("clts ; fnsave %0": :"m" (*fpu));
204 else
205 memcpy(fpu,¤t->tss.i387.hard,sizeof(*fpu));
206 }
207 } else {
208
209
210 fpvalid = 0;
211 }
212
213 return fpvalid;
214 }
215
216
217
218
219 void dump_thread(struct pt_regs * regs, struct user * dump)
220 {
221 int i;
222
223
224 dump->magic = CMAGIC;
225 dump->start_code = 0;
226 dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
227 dump->u_tsize = ((unsigned long) current->mm->end_code) >> 12;
228 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> 12;
229 dump->u_dsize -= dump->u_tsize;
230 dump->u_ssize = 0;
231 for (i = 0; i < 8; i++)
232 dump->u_debugreg[i] = current->debugreg[i];
233
234 if (dump->start_stack < TASK_SIZE) {
235 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> 12;
236 }
237
238 dump->regs = *regs;
239
240 dump->u_fpvalid = dump_fpu (&dump->i387);
241 }
242
243 asmlinkage int sys_fork(struct pt_regs regs)
244 {
245 return do_fork(SIGCHLD, regs.esp, ®s);
246 }
247
248 asmlinkage int sys_clone(struct pt_regs regs)
249 {
250 unsigned long clone_flags;
251 unsigned long newsp;
252
253 clone_flags = regs.ebx;
254 newsp = regs.ecx;
255 if (!newsp)
256 newsp = regs.esp;
257 return do_fork(clone_flags, newsp, ®s);
258 }
259
260
261
262
263 asmlinkage int sys_execve(struct pt_regs regs)
264 {
265 int error;
266 char * filename;
267
268 error = getname((char *) regs.ebx, &filename);
269 if (error)
270 return error;
271 error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, ®s);
272 putname(filename);
273 return error;
274 }