Diff markup
001 !! 001
002 !! 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 019
020 020
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <sos/klibc.h> 022 #include <sos/klibc.h>
023 #include <drivers/bochs.h> 023 #include <drivers/bochs.h>
024 #include <drivers/x86_videomem.h> 024 #include <drivers/x86_videomem.h>
025 #include <hwcore/segment.h> 025 #include <hwcore/segment.h>
026 #include <hwcore/gdt.h> <<
027 #include <sos/uaccess.h> <<
028 026
029 #include "cpu_context.h" 027 #include "cpu_context.h"
030 028
031 029
032 030
033 031
034 032
035 033
036 034
037 035
038 036
039 037
040 038
041 039
042 040
043 041
044 042
045 struct sos_cpu_state { !! 043 struct sos_cpu_kstate {
046 044
047 045
048 046
049 sos_ui16_t gs; 047 sos_ui16_t gs;
050 sos_ui16_t fs; 048 sos_ui16_t fs;
051 sos_ui16_t es; 049 sos_ui16_t es;
052 sos_ui16_t ds; 050 sos_ui16_t ds;
053 sos_ui16_t cpl0_ss; !! 051 sos_ui16_t ss;
054 <<
055 <<
056 sos_ui16_t alignment_padding; 052 sos_ui16_t alignment_padding;
057 sos_ui32_t eax; 053 sos_ui32_t eax;
058 sos_ui32_t ebx; 054 sos_ui32_t ebx;
059 sos_ui32_t ecx; 055 sos_ui32_t ecx;
060 sos_ui32_t edx; 056 sos_ui32_t edx;
061 sos_ui32_t esi; 057 sos_ui32_t esi;
062 sos_ui32_t edi; 058 sos_ui32_t edi;
063 sos_ui32_t ebp; 059 sos_ui32_t ebp;
064 060
065 061
066 sos_ui32_t error_code; 062 sos_ui32_t error_code;
067 sos_vaddr_t eip; 063 sos_vaddr_t eip;
068 sos_ui32_t cs; !! 064 sos_ui32_t cs;
069 <<
070 sos_ui32_t eflags; 065 sos_ui32_t eflags;
071 066
072 067
073 } __attribute__((packed)); 068 } __attribute__((packed));
074 069
075 070
076 <<
077 <<
078 <<
079 <<
080 <<
081 <<
082 <<
083 <<
084 <<
085 <<
086 <<
087 <<
088 <<
089 #define GET_CPU_CS_REGISTER_VALUE(pushed_ui32_ <<
090 ( (pushed_ui32_cs_value) & 0xffff ) <<
091 <<
092 <<
093 <<
094 <<
095 <<
096 struct sos_cpu_kstate <<
097 { <<
098 struct sos_cpu_state regs; <<
099 } __attribute__((packed)); <<
100 <<
101 <<
102 <<
103 <<
104 <<
105 <<
106 <<
107 <<
108 <<
109 <<
110 struct sos_cpu_ustate <<
111 { <<
112 struct sos_cpu_state regs; <<
113 struct <<
114 { <<
115 sos_ui32_t cpl3_esp; <<
116 sos_ui16_t cpl3_ss; <<
117 }; <<
118 } __attribute__((packed)); <<
119 <<
120 <<
121 <<
122 <<
123 <<
124 <<
125 <<
126 <<
127 <<
128 <<
129 <<
130 <<
131 struct x86_tss { <<
132 <<
133 <<
134 <<
135 <<
136 <<
137 <<
138 <<
139 <<
140 <<
141 <<
142 sos_ui16_t back_link; <<
143 <<
144 sos_ui16_t reserved1; <<
145 <<
146 <<
147 sos_vaddr_t esp0; <<
148 sos_ui16_t ss0; <<
149 <<
150 sos_ui16_t reserved2; <<
151 <<
152 <<
153 sos_vaddr_t esp1; <<
154 sos_ui16_t ss1; <<
155 <<
156 sos_ui16_t reserved3; <<
157 <<
158 <<
159 sos_vaddr_t esp2; <<
160 sos_ui16_t ss2; <<
161 <<
162 sos_ui16_t reserved4; <<
163 <<
164 <<
165 sos_vaddr_t cr3; <<
166 sos_vaddr_t eip; <<
167 sos_ui32_t eflags; <<
168 sos_ui32_t eax; <<
169 sos_ui32_t ecx; <<
170 sos_ui32_t edx; <<
171 sos_ui32_t ebx; <<
172 sos_ui32_t esp; <<
173 sos_ui32_t ebp; <<
174 sos_ui32_t esi; <<
175 sos_ui32_t edi; <<
176 <<
177 <<
178 sos_ui16_t es; <<
179 sos_ui16_t reserved5; <<
180 <<
181 <<
182 sos_ui16_t cs; <<
183 sos_ui16_t reserved6; <<
184 <<
185 <<
186 sos_ui16_t ss; <<
187 sos_ui16_t reserved7; <<
188 <<
189 <<
190 sos_ui16_t ds; <<
191 sos_ui16_t reserved8; <<
192 <<
193 <<
194 sos_ui16_t fs; <<
195 sos_ui16_t reserved9; <<
196 <<
197 <<
198 sos_ui16_t gs; <<
199 sos_ui16_t reserved10; <<
200 <<
201 <<
202 sos_ui16_t ldtr; <<
203 sos_ui16_t reserved11; <<
204 <<
205 <<
206 sos_ui16_t debug_trap_flag :1; <<
207 sos_ui16_t reserved12 :15; <<
208 sos_ui16_t iomap_base_addr; <<
209 <<
210 <<
211 } __attribute__((packed, aligned(128))); <<
212 <<
213 <<
214 static struct x86_tss kernel_tss; <<
215 <<
216 <<
217 sos_ret_t sos_cpu_context_subsystem_setup() <<
218 { <<
219 <<
220 memset(&kernel_tss, 0x0, sizeof(kernel_tss)) <<
221 <<
222 <<
223 <<
224 <<
225 <<
226 <<
227 <<
228 <<
229 <<
230 <<
231 <<
232 kernel_tss.ss0 = SOS_BUILD_SEGMENT_REG_VALUE <<
233 <<
234 <<
235 sos_gdt_register_kernel_tss((sos_vaddr_t) &k <<
236 <<
237 return SOS_OK; <<
238 } <<
239 <<
240 <<
241 <<
242 <<
243 <<
244 <<
245 <<
246 static void core_routine (sos_cpu_kstate_funct 071 static void core_routine (sos_cpu_kstate_function_arg1_t *start_func,
247 sos_ui32_t start_arg 072 sos_ui32_t start_arg,
248 sos_cpu_kstate_funct 073 sos_cpu_kstate_function_arg1_t *exit_func,
249 sos_ui32_t exit_arg) 074 sos_ui32_t exit_arg)
250 __attribute__((noreturn)); 075 __attribute__((noreturn));
251 076
252 static void core_routine (sos_cpu_kstate_funct 077 static void core_routine (sos_cpu_kstate_function_arg1_t *start_func,
253 sos_ui32_t start_arg 078 sos_ui32_t start_arg,
254 sos_cpu_kstate_funct 079 sos_cpu_kstate_function_arg1_t *exit_func,
255 sos_ui32_t exit_arg) 080 sos_ui32_t exit_arg)
256 { 081 {
257 start_func(start_arg); 082 start_func(start_arg);
258 exit_func(exit_arg); 083 exit_func(exit_arg);
259 084
260 SOS_ASSERT_FATAL(! "The exit function of the 085 SOS_ASSERT_FATAL(! "The exit function of the thread should NOT return !");
261 for(;;); 086 for(;;);
262 } 087 }
263 088
264 089
265 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_s !! 090 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_kstate **ctxt,
266 sos_cpu_kstate_f 091 sos_cpu_kstate_function_arg1_t *start_func,
267 sos_ui32_t star 092 sos_ui32_t start_arg,
268 sos_vaddr_t stac 093 sos_vaddr_t stack_bottom,
269 sos_size_t stac 094 sos_size_t stack_size,
270 sos_cpu_kstate_f 095 sos_cpu_kstate_function_arg1_t *exit_func,
271 sos_ui32_t exit 096 sos_ui32_t exit_arg)
272 { 097 {
273 <<
274 struct sos_cpu_kstate *kctxt; <<
275 <<
276 098
277 099
278 100
279 101
280 102
281 103
282 104
283 105
284 106
285 107
286 108
287 109
288 110
289 111
290 112
291 113
292 114
293 115
294 116
295 117
296 118
297 119
298 sos_vaddr_t tmp_vaddr = stack_bottom + stack 120 sos_vaddr_t tmp_vaddr = stack_bottom + stack_size;
299 sos_ui32_t *stack = (sos_ui32_t*)tmp_vaddr; 121 sos_ui32_t *stack = (sos_ui32_t*)tmp_vaddr;
300 122
301 123
302 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS !! 124 #ifdef SOS_CPU_KSTATE_DETECT_UNINIT_VARS
303 memset((void*)stack_bottom, SOS_CPU_STATE_ST !! 125 memset((void*)stack_bottom, SOS_CPU_KSTATE_STACK_POISON, stack_size);
304 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STAC !! 126 #elif defined(SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW)
305 sos_cpu_state_prepare_detect_kernel_stack_ov !! 127 sos_cpu_kstate_prepare_detect_stack_overflow(stack_bottom, stack_size);
306 #endif 128 #endif
307 129
308 130
309 131
310 *(--stack) = exit_arg; 132 *(--stack) = exit_arg;
311 *(--stack) = (sos_ui32_t)exit_func; 133 *(--stack) = (sos_ui32_t)exit_func;
312 *(--stack) = start_arg; 134 *(--stack) = start_arg;
313 *(--stack) = (sos_ui32_t)start_func; 135 *(--stack) = (sos_ui32_t)start_func;
314 *(--stack) = 0; 136 *(--stack) = 0;
315 137
316 138
317 139
318 140
319 141
320 142
321 143
322 144
323 145
324 tmp_vaddr = ((sos_vaddr_t)stack) - sizeof(s 146 tmp_vaddr = ((sos_vaddr_t)stack) - sizeof(struct sos_cpu_kstate);
325 kctxt = (struct sos_cpu_kstate*)tmp_vaddr; !! 147 *ctxt = (struct sos_cpu_kstate*)tmp_vaddr;
326 148
327 149
328 memset(kctxt, 0x0, sizeof(struct sos_cpu_kst !! 150 memset(*ctxt, 0x0, sizeof(struct sos_cpu_kstate));
329 151
330 152
331 153
332 kctxt->regs.eip = (sos_ui32_t)core_routine; !! 154 (*ctxt)->eip = (sos_ui32_t)core_routine;
333 <<
334 <<
335 kctxt->regs.cs <<
336 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
337 kctxt->regs.ds <<
338 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
339 kctxt->regs.es <<
340 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
341 kctxt->regs.cpl0_ss <<
342 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
343 <<
344 <<
345 <<
346 kctxt->regs.eflags = (1 << 9); <<
347 <<
348 <<
349 *ctxt = (struct sos_cpu_state*) kctxt; <<
350 <<
351 return SOS_OK; <<
352 } <<
353 <<
354 <<
355 <<
356 <<
357 <<
358 <<
359 <<
360 <<
361 static sos_ret_t cpu_ustate_init(struct sos_cp <<
362 const struct <<
363 sos_uaddr_t <<
364 sos_ui32_t <<
365 sos_ui32_t <<
366 sos_uaddr_t <<
367 sos_vaddr_t <<
368 sos_size_t <<
369 { <<
370 <<
371 struct sos_cpu_ustate *uctxt; <<
372 <<
373 <<
374 <<
375 <<
376 <<
377 <<
378 <<
379 sos_vaddr_t uctxt_vaddr = kernel_stack_botto <<
380 + kernel_stack_si <<
381 - sizeof(struct s <<
382 uctxt = (struct sos_cpu_ustate*)uctxt_vaddr; <<
383 <<
384 if (model_uctxt && !sos_cpu_context_is_in_us <<
385 return -SOS_EINVAL; <<
386 <<
387 <<
388 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS <<
389 memset((void*)kernel_stack_bottom, <<
390 SOS_CPU_STATE_STACK_POISON, <<
391 kernel_stack_size); <<
392 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STAC <<
393 sos_cpu_state_prepare_detect_kernel_stack_ov <<
394 <<
395 #endif <<
396 <<
397 <<
398 <<
399 <<
400 <<
401 <<
402 <<
403 <<
404 if (! model_uctxt) <<
405 { <<
406 memset(uctxt, 0x0, sizeof(struct sos_cpu <<
407 <<
408 <<
409 <<
410 uctxt->regs.eip = (sos_ui32_t)user_start <<
411 <<
412 <<
413 uctxt->cpl3_esp = user_initial_SP; <<
414 } <<
415 else <<
416 memcpy(uctxt, model_uctxt, sizeof(struct s <<
417 <<
418 <<
419 <<
420 uctxt->regs.eax = user_start_arg1; <<
421 <<
422 <<
423 if (! model_uctxt) <<
424 uctxt->regs.ebx = user_start_arg2; <<
425 155
426 156
427 uctxt->regs.cs !! 157 (*ctxt)->cs = SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KCODE);
428 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO !! 158 (*ctxt)->ds = SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA);
429 uctxt->regs.ds !! 159 (*ctxt)->es = SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA);
430 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO !! 160 (*ctxt)->ss = SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA);
431 uctxt->regs.es <<
432 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
433 uctxt->cpl3_ss <<
434 = SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, SO <<
435 <<
436 <<
437 <<
438 <<
439 <<
440 uctxt->regs.cpl0_ss <<
441 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SO <<
442 <<
443 161
444 162
445 163
446 uctxt->regs.eflags = (1 << 9); !! 164 (*ctxt)->eflags = (1 << 9);
447 <<
448 <<
449 *ctxt = (struct sos_cpu_state*) uctxt; <<
450 165
451 return SOS_OK; 166 return SOS_OK;
452 } 167 }
453 168
454 169
455 sos_ret_t sos_cpu_ustate_init(struct sos_cpu_s !! 170 #if defined(SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW)
456 sos_uaddr_t use <<
457 sos_ui32_t use <<
458 sos_ui32_t use <<
459 sos_uaddr_t use <<
460 sos_vaddr_t ker <<
461 sos_size_t ker <<
462 { <<
463 return cpu_ustate_init(ctxt, NULL, <<
464 user_start_PC, <<
465 user_start_arg1, user <<
466 user_initial_SP, <<
467 kernel_stack_bottom, <<
468 } <<
469 <<
470 <<
471 sos_ret_t sos_cpu_ustate_duplicate(struct sos_ <<
472 const struc <<
473 sos_ui32_t <<
474 sos_vaddr_t <<
475 sos_size_t <<
476 { <<
477 return cpu_ustate_init(ctxt, model_uctxt, <<
478 0, <<
479 user_retval, <<
480 0, <<
481 kernel_stack_bottom, <<
482 } <<
483 <<
484 <<
485 sos_ret_t <<
486 sos_cpu_context_is_in_user_mode(const struct s <<
487 { <<
488 <<
489 <<
490 switch (GET_CPU_CS_REGISTER_VALUE(ctxt->cs)) <<
491 { <<
492 case SOS_BUILD_SEGMENT_REG_VALUE(3, FALSE, <<
493 return TRUE; <<
494 break; <<
495 <<
496 case SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, <<
497 return FALSE; <<
498 break; <<
499 <<
500 default: <<
501 SOS_FATAL_ERROR("Invalid saved context C <<
502 (unsigned) GET_CPU_CS_RE <<
503 SOS_BUILD_SEGMENT_REG_VA <<
504 SOS_BUILD_SEGMENT_REG_VA <<
505 break; <<
506 } <<
507 <<
508 <<
509 return -SOS_EFATAL; <<
510 } <<
511 <<
512 <<
513 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_ <<
514 void 171 void
515 sos_cpu_state_prepare_detect_kernel_stack_over !! 172 sos_cpu_kstate_prepare_detect_stack_overflow(const struct sos_cpu_kstate *ctxt,
516 !! 173 sos_vaddr_t stack_bottom,
517 !! 174 sos_size_t stack_size)
518 { 175 {
519 sos_size_t poison_size = SOS_CPU_STATE_DETEC !! 176 sos_size_t poison_size = SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW;
520 if (poison_size > stack_size) 177 if (poison_size > stack_size)
521 poison_size = stack_size; 178 poison_size = stack_size;
522 179
523 memset((void*)stack_bottom, SOS_CPU_STATE_ST !! 180 memset((void*)stack_bottom, SOS_CPU_KSTATE_STACK_POISON, poison_size);
524 } 181 }
525 182
526 183
527 void 184 void
528 sos_cpu_state_detect_kernel_stack_overflow(con !! 185 sos_cpu_kstate_detect_stack_overflow(const struct sos_cpu_kstate *ctxt,
529 sos !! 186 sos_vaddr_t stack_bottom,
530 sos !! 187 sos_size_t stack_size)
531 { 188 {
532 unsigned char *c; 189 unsigned char *c;
533 int i; 190 int i;
534 191
535 <<
536 <<
537 <<
538 <<
539 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stac 192 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stack_bottom);
540 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeo 193 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeof(struct sos_cpu_kstate)
541 <= stack_bottom + stack_siz 194 <= stack_bottom + stack_size);
542 <<
543 <<
544 for (c = (unsigned char*) stack_bottom, i = 195 for (c = (unsigned char*) stack_bottom, i = 0 ;
545 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_ !! 196 (i < SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW) && (i < stack_size) ;
546 c++, i++) 197 c++, i++)
547 { 198 {
548 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POI !! 199 SOS_ASSERT_FATAL(SOS_CPU_KSTATE_STACK_POISON == *c);
549 } 200 }
550 } 201 }
551 #endif 202 #endif
552 203
553 204
554 !! 205 sos_vaddr_t sos_cpu_kstate_get_PC(const struct sos_cpu_kstate *ctxt)
555 <<
556 <<
557 <<
558 <<
559 sos_vaddr_t sos_cpu_context_get_PC(const struc <<
560 { 206 {
561 SOS_ASSERT_FATAL(NULL != ctxt); 207 SOS_ASSERT_FATAL(NULL != ctxt);
562 <<
563 <<
564 <<
565 return ctxt->eip; 208 return ctxt->eip;
566 } 209 }
567 210
568 211
569 sos_vaddr_t sos_cpu_context_get_SP(const struc !! 212 sos_vaddr_t sos_cpu_kstate_get_SP(const struct sos_cpu_kstate *ctxt)
570 { 213 {
571 SOS_ASSERT_FATAL(NULL != ctxt); 214 SOS_ASSERT_FATAL(NULL != ctxt);
572 <<
573 <<
574 <<
575 <<
576 if (TRUE == sos_cpu_context_is_in_user_mode( <<
577 { <<
578 struct sos_cpu_ustate * uctxt = (struct <<
579 return uctxt->cpl3_esp; <<
580 } <<
581 <<
582 <<
583 <<
584 <<
585 return (sos_vaddr_t)ctxt; 215 return (sos_vaddr_t)ctxt;
586 } 216 }
587 217
588 218
589 sos_ret_t !! 219 void sos_cpu_kstate_dump(const struct sos_cpu_kstate *ctxt)
590 sos_cpu_context_set_EX_return_address(struct s <<
591 sos_vadd <<
592 { <<
593 ctxt->eip = ret_vaddr; <<
594 return SOS_OK; <<
595 } <<
596 <<
597 <<
598 void sos_cpu_context_dump(const struct sos_cpu <<
599 { 220 {
600 char buf[128]; 221 char buf[128];
601 <<
602 snprintf(buf, sizeof(buf), 222 snprintf(buf, sizeof(buf),
603 "CPU: eip=%x esp0=%x eflags=%x cs=% !! 223 "CPU: eip=%x esp=%x eflags=%x cs=%x ds=%x ss=%x err=%x",
604 (unsigned)ctxt->eip, (unsigned)ctxt 224 (unsigned)ctxt->eip, (unsigned)ctxt, (unsigned)ctxt->eflags,
605 (unsigned)GET_CPU_CS_REGISTER_VALUE !! 225 (unsigned)ctxt->cs, (unsigned)ctxt->ds, (unsigned)ctxt->ss,
606 (unsigned)ctxt->cpl0_ss, <<
607 (unsigned)ctxt->error_code); 226 (unsigned)ctxt->error_code);
608 if (TRUE == sos_cpu_context_is_in_user_mode( <<
609 { <<
610 struct sos_cpu_ustate * uctxt = (struct <<
611 snprintf(buf, sizeof(buf), <<
612 "%s esp3=%x ss3=%x", <<
613 buf, (unsigned)uctxt->cpl3_esp, <<
614 } <<
615 else <<
616 snprintf(buf, sizeof(buf), "%s [KERNEL MOD <<
617 <<
618 sos_bochs_putstring(buf); sos_bochs_putstrin 227 sos_bochs_putstring(buf); sos_bochs_putstring("\n");
619 sos_x86_videomem_putstring(23, 0, 228 sos_x86_videomem_putstring(23, 0,
620 SOS_X86_VIDEO_FG_ !! 229 SOS_X86_VIDEO_FG_BLACK | SOS_X86_VIDEO_BG_LTGRAY,
621 buf); !! 230 buf);
622 } 231 }
623 232
624 233
625 !! 234 sos_ui32_t sos_cpu_kstate_get_EX_info(const struct sos_cpu_kstate *ctxt)
626 <<
627 <<
628 <<
629 <<
630 sos_ui32_t sos_cpu_context_get_EX_info(const s <<
631 { 235 {
632 SOS_ASSERT_FATAL(NULL != ctxt); 236 SOS_ASSERT_FATAL(NULL != ctxt);
633 return ctxt->error_code; 237 return ctxt->error_code;
634 } 238 }
635 239
636 240
637 sos_vaddr_t 241 sos_vaddr_t
638 sos_cpu_context_get_EX_faulting_vaddr(const st !! 242 sos_cpu_kstate_get_EX_faulting_vaddr(const struct sos_cpu_kstate *ctxt)
639 { 243 {
640 sos_ui32_t cr2; 244 sos_ui32_t cr2;
641 245
642 !! 246
643 !! 247
644 <<
645 <<
646 <<
647 <<
648 <<
649 <<
650 <<
651 <<
652 <<
653 <<
654 <<
655 asm volatile ("movl %%cr2, %0" 248 asm volatile ("movl %%cr2, %0"
656 :"=r"(cr2) 249 :"=r"(cr2)
657 : ); 250 : );
658 251
659 return cr2; 252 return cr2;
660 } 253 }
661 254
662 255
663 !! 256 sos_ui32_t sos_backtrace(const struct sos_cpu_kstate *cpu_kstate,
664 <<
665 <<
666 <<
667 <<
668 <<
669 <<
670 <<
671 <<
672 <<
673 <<
674 <<
675 <<
676 <<
677 <<
678 inline <<
679 sos_ret_t sos_syscall_get3args(const struct so <<
680 unsign <<
681 unsign <<
682 unsign <<
683 { <<
684 *arg1 = user_ctxt->ebx; <<
685 *arg2 = user_ctxt->ecx; <<
686 *arg3 = user_ctxt->edx; <<
687 return SOS_OK; <<
688 } <<
689 <<
690 <<
691 sos_ret_t sos_syscall_get1arg(const struct sos <<
692 unsigne <<
693 { <<
694 unsigned int unused; <<
695 return sos_syscall_get3args(user_ctxt, arg1, <<
696 } <<
697 <<
698 <<
699 sos_ret_t sos_syscall_get2args(const struct so <<
700 unsign <<
701 unsign <<
702 { <<
703 unsigned int unused; <<
704 return sos_syscall_get3args(user_ctxt, arg1, <<
705 } <<
706 <<
707 <<
708 <<
709 <<
710 <<
711 <<
712 <<
713 sos_ret_t sos_syscall_get4args(const struct so <<
714 unsign <<
715 unsign <<
716 unsign <<
717 unsign <<
718 { <<
719 sos_uaddr_t uaddr_other_args; <<
720 unsigned int other_args[2]; <<
721 sos_ret_t retval; <<
722 <<
723 <<
724 <<
725 retval = sos_syscall_get3args(user_ctxt, arg <<
726 (unsigned int <<
727 if (SOS_OK != retval) <<
728 return retval; <<
729 <<
730 <<
731 <<
732 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
733 (sos_uaddr_t)u <<
734 sizeof(other_a <<
735 if (sizeof(other_args) != retval) <<
736 return -SOS_EFAULT; <<
737 <<
738 *arg3 = other_args[0]; <<
739 *arg4 = other_args[1]; <<
740 return SOS_OK; <<
741 } <<
742 <<
743 <<
744 sos_ret_t sos_syscall_get5args(const struct so <<
745 unsign <<
746 unsign <<
747 unsign <<
748 unsign <<
749 unsign <<
750 { <<
751 sos_uaddr_t uaddr_other_args; <<
752 unsigned int other_args[3]; <<
753 sos_ret_t retval; <<
754 <<
755 <<
756 <<
757 retval = sos_syscall_get3args(user_ctxt, arg <<
758 (unsigned int <<
759 if (SOS_OK != retval) <<
760 return retval; <<
761 <<
762 <<
763 <<
764 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
765 (sos_uaddr_t)u <<
766 sizeof(other_a <<
767 if (sizeof(other_args) != retval) <<
768 return -SOS_EFAULT; <<
769 <<
770 *arg3 = other_args[0]; <<
771 *arg4 = other_args[1]; <<
772 *arg5 = other_args[2]; <<
773 return SOS_OK; <<
774 } <<
775 <<
776 <<
777 sos_ret_t sos_syscall_get6args(const struct so <<
778 unsign <<
779 unsign <<
780 unsign <<
781 unsign <<
782 unsign <<
783 unsign <<
784 { <<
785 sos_uaddr_t uaddr_other_args; <<
786 unsigned int other_args[4]; <<
787 sos_ret_t retval; <<
788 <<
789 <<
790 <<
791 retval = sos_syscall_get3args(user_ctxt, arg <<
792 (unsigned int <<
793 if (SOS_OK != retval) <<
794 return retval; <<
795 <<
796 <<
797 <<
798 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
799 (sos_uaddr_t)u <<
800 sizeof(other_a <<
801 if (sizeof(other_args) != retval) <<
802 return -SOS_EFAULT; <<
803 <<
804 *arg3 = other_args[0]; <<
805 *arg4 = other_args[1]; <<
806 *arg5 = other_args[2]; <<
807 *arg6 = other_args[3]; <<
808 return SOS_OK; <<
809 } <<
810 <<
811 <<
812 sos_ret_t sos_syscall_get7args(const struct so <<
813 unsign <<
814 unsign <<
815 unsign <<
816 unsign <<
817 unsign <<
818 unsign <<
819 unsign <<
820 { <<
821 sos_uaddr_t uaddr_other_args; <<
822 unsigned int other_args[5]; <<
823 sos_ret_t retval; <<
824 <<
825 <<
826 <<
827 retval = sos_syscall_get3args(user_ctxt, arg <<
828 (unsigned int <<
829 if (SOS_OK != retval) <<
830 return retval; <<
831 <<
832 <<
833 <<
834 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
835 (sos_uaddr_t)u <<
836 sizeof(other_a <<
837 if (sizeof(other_args) != retval) <<
838 return -SOS_EFAULT; <<
839 <<
840 *arg3 = other_args[0]; <<
841 *arg4 = other_args[1]; <<
842 *arg5 = other_args[2]; <<
843 *arg6 = other_args[3]; <<
844 *arg7 = other_args[4]; <<
845 return SOS_OK; <<
846 } <<
847 <<
848 <<
849 sos_ret_t sos_syscall_get8args(const struct so <<
850 unsign <<
851 unsign <<
852 unsign <<
853 unsign <<
854 unsign <<
855 unsign <<
856 unsign <<
857 unsign <<
858 { <<
859 sos_uaddr_t uaddr_other_args; <<
860 unsigned int other_args[6]; <<
861 sos_ret_t retval; <<
862 <<
863 <<
864 <<
865 retval = sos_syscall_get3args(user_ctxt, arg <<
866 (unsigned int <<
867 if (SOS_OK != retval) <<
868 return retval; <<
869 <<
870 <<
871 <<
872 retval = sos_memcpy_from_user((sos_vaddr_t)o <<
873 (sos_uaddr_t)u <<
874 sizeof(other_a <<
875 if (sizeof(other_args) != retval) <<
876 return -SOS_EFAULT; <<
877 <<
878 *arg3 = other_args[0]; <<
879 *arg4 = other_args[1]; <<
880 *arg5 = other_args[2]; <<
881 *arg6 = other_args[3]; <<
882 *arg7 = other_args[4]; <<
883 *arg8 = other_args[5]; <<
884 return SOS_OK; <<
885 } <<
886 <<
887 <<
888 <<
889 <<
890 <<
891 <<
892 <<
893 sos_ui32_t sos_backtrace(const struct sos_cpu_ <<
894 sos_ui32_t max_depth, 257 sos_ui32_t max_depth,
895 sos_vaddr_t stack_bot 258 sos_vaddr_t stack_bottom,
896 sos_size_t stack_size 259 sos_size_t stack_size,
897 sos_backtrace_callbac 260 sos_backtrace_callback_t * backtracer,
898 void *custom_arg) 261 void *custom_arg)
899 { 262 {
900 int depth; 263 int depth;
901 sos_vaddr_t callee_PC, caller_frame; 264 sos_vaddr_t callee_PC, caller_frame;
902 265
903 <<
904 if ((NULL != cpu_state) <<
905 && <<
906 (TRUE == sos_cpu_context_is_in_user_mode <<
907 { <<
908 return 0; <<
909 } <<
910 <<
911 266
912 267
913 268
914 269
915 270
916 271
917 272
918 273
919 274
920 275
921 276
922 277
923 278
924 279
925 280
926 281
927 282
928 283
929 284
930 285
931 286
932 287
933 288
934 289
935 290
936 291
937 292
938 293
939 294
940 if (cpu_state) !! 295 if (cpu_kstate)
941 { 296 {
942 callee_PC = cpu_state->eip; !! 297 callee_PC = cpu_kstate->eip;
943 caller_frame = cpu_state->ebp; !! 298 caller_frame = cpu_kstate->ebp;
944 } 299 }
945 else 300 else
946 { 301 {
947 302
948 callee_PC = (sos_vaddr_t)__builtin_re 303 callee_PC = (sos_vaddr_t)__builtin_return_address(0);
949 caller_frame = (sos_vaddr_t)__builtin_fr 304 caller_frame = (sos_vaddr_t)__builtin_frame_address(1);
950 } 305 }
951 306
952 for(depth=0 ; depth < max_depth ; depth ++) 307 for(depth=0 ; depth < max_depth ; depth ++)
953 { 308 {
954 309
955 backtracer(callee_PC, caller_frame + 8, 310 backtracer(callee_PC, caller_frame + 8, depth, custom_arg);
956 311
957 312
958 if ( (caller_frame < stack_bottom) 313 if ( (caller_frame < stack_bottom)
959 || (caller_frame + 4 >= stack_botto 314 || (caller_frame + 4 >= stack_bottom + stack_size) )
960 return depth; 315 return depth;
961 316
962 317
963 callee_PC = *((sos_vaddr_t*) (caller_ 318 callee_PC = *((sos_vaddr_t*) (caller_frame + 4));
964 caller_frame = *((sos_vaddr_t*) caller_f 319 caller_frame = *((sos_vaddr_t*) caller_frame);
965 } 320 }
966 321
967 return depth; 322 return depth;
968 } <<
969 <<
970 <<
971 <<
972 <<
973 <<
974 <<
975 <<
976 <<
977 <<
978 <<
979 <<
980 void <<
981 sos_cpu_context_update_kernel_tss(struct sos_c <<
982 { <<
983 <<
984 if (sos_cpu_context_is_in_user_mode(next_ctx <<
985 { <<
986 <<
987 <<
988 <<
989 <<
990 <<
991 <<
992 <<
993 <<
994 <<
995 <<
996 <<
997 kernel_tss.esp0 = ((sos_vaddr_t)next_ctx <<
998 + sizeof(struct sos_cp <<
999 <<
1000 <<
1001 <<
1002 } <<
1003 else <<
1004 { <<
1005 <<
1006 <<
1007 } <<
1008 } 323 }