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