1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <config.h> 8#include <machine/assembler.h> 9 10/* From <arch/mode/machine/registerset.h> */ 11#define Error 9 12#define NextIP 10 13#define CS 11 14#define FLAGS 12 15#define ESP 13 16#define n_contextRegisters 17 17 18# On kernel entry, ESP points to the end of the thread's registers array. 19# Hardware pushes onto the stack SS, ESP, EFLAGS, CS, NextIP and Error, 20# leaving the stack pointer pointing to TLS_BASE. The kernel pushes the rest. 21 22#define INT_HANDLER_COMMON(number, error_code) \ 23.global int_##number; \ 24.type int_##number, %function; \ 25int_##number: \ 26 error_code; \ 27 pushl 4(%esp); /* FaultIP := NextIP */ \ 28 pushl %ebp; \ 29 pushl %edi; \ 30 pushl %esi; \ 31 pushl %edx; \ 32 pushl %ecx; \ 33 pushl %ebx; \ 34 pushl %eax; \ 35 pushl $0; \ 36 movl $0x##number, %ecx; \ 37 jmp handle_interrupt; \ 38 .size int_##number, .-int_##number; 39 40#define INT_HANDLER_WITH_ERR_CODE(number) INT_HANDLER_COMMON(number,) 41#define INT_HANDLER_WITHOUT_ERR_CODE(number) INT_HANDLER_COMMON(number,pushl $0x0) 42 43#ifdef ENABLE_SMP_SUPPORT 44#define SET_KERNEL_STACK_FROM(x) \ 45 movl (x)(%esp), %esp 46#else 47#define SET_KERNEL_STACK_FROM(x) \ 48 leal kernel_stack_alloc + (1 << CONFIG_KERNEL_STACK_BITS) - 4, %esp 49#endif 50 51#define SET_KERNEL_STACK SET_KERNEL_STACK_FROM(4 * n_contextRegisters) 52 53# switch to the user data segments as the rest of our entry/exit code assumes that's 54# what they will be 55 56#define SET_SELECTOR(selector, value, tmp) \ 57 movl %selector, %tmp; \ 58 cmpl $value, %tmp; \ 59 je 1f; \ 60 movl $value, %tmp; \ 61 movl %tmp, %selector; \ 62 1: 63 64/* user-level selectors from </arch/mode/object/structures.h> */ 65#define GDT_DS_0 2 66#define GDT_DS_3 4 67#define GDT_FS 6 68#define GDT_GS 7 69 70/* user-level selectors from </arch/object/structures.h> */ 71#define SEL_CS_3 ((GDT_CS_3 << 3) | 3) 72#define SEL_DS_3 ((GDT_DS_3 << 3) | 3) 73#define SEL_FS ((GDT_FS << 3) | 3) 74#define SEL_GS ((GDT_GS << 3) | 3) 75 76#define RESET_SELECTORS(tmp) \ 77 SET_SELECTOR(ds, SEL_DS_3, tmp) \ 78 SET_SELECTOR(es, SEL_DS_3, tmp) \ 79 SET_SELECTOR(fs, SEL_FS, tmp) \ 80 SET_SELECTOR(gs, SEL_GS, tmp) 81 82.section .text 83 84INT_HANDLER_WITHOUT_ERR_CODE(00) 85INT_HANDLER_WITHOUT_ERR_CODE(01) 86INT_HANDLER_WITHOUT_ERR_CODE(02) 87INT_HANDLER_WITHOUT_ERR_CODE(03) 88INT_HANDLER_WITHOUT_ERR_CODE(04) 89INT_HANDLER_WITHOUT_ERR_CODE(05) 90INT_HANDLER_WITHOUT_ERR_CODE(06) 91INT_HANDLER_WITHOUT_ERR_CODE(07) 92INT_HANDLER_WITH_ERR_CODE(08) 93INT_HANDLER_WITHOUT_ERR_CODE(09) 94INT_HANDLER_WITH_ERR_CODE(0a) 95INT_HANDLER_WITH_ERR_CODE(0b) 96INT_HANDLER_WITH_ERR_CODE(0c) 97INT_HANDLER_WITH_ERR_CODE(0d) 98INT_HANDLER_WITH_ERR_CODE(0e) 99INT_HANDLER_WITHOUT_ERR_CODE(0f) 100 101INT_HANDLER_WITHOUT_ERR_CODE(10) 102INT_HANDLER_WITH_ERR_CODE(11) 103INT_HANDLER_WITHOUT_ERR_CODE(12) 104INT_HANDLER_WITHOUT_ERR_CODE(13) 105INT_HANDLER_WITHOUT_ERR_CODE(14) 106INT_HANDLER_WITHOUT_ERR_CODE(15) 107INT_HANDLER_WITHOUT_ERR_CODE(16) 108INT_HANDLER_WITHOUT_ERR_CODE(17) 109INT_HANDLER_WITHOUT_ERR_CODE(18) 110INT_HANDLER_WITHOUT_ERR_CODE(19) 111INT_HANDLER_WITHOUT_ERR_CODE(1a) 112INT_HANDLER_WITHOUT_ERR_CODE(1b) 113INT_HANDLER_WITHOUT_ERR_CODE(1c) 114INT_HANDLER_WITHOUT_ERR_CODE(1d) 115INT_HANDLER_WITHOUT_ERR_CODE(1e) 116INT_HANDLER_WITHOUT_ERR_CODE(1f) 117 118INT_HANDLER_WITHOUT_ERR_CODE(20) 119INT_HANDLER_WITHOUT_ERR_CODE(21) 120INT_HANDLER_WITHOUT_ERR_CODE(22) 121INT_HANDLER_WITHOUT_ERR_CODE(23) 122INT_HANDLER_WITHOUT_ERR_CODE(24) 123INT_HANDLER_WITHOUT_ERR_CODE(25) 124INT_HANDLER_WITHOUT_ERR_CODE(26) 125INT_HANDLER_WITHOUT_ERR_CODE(27) 126INT_HANDLER_WITHOUT_ERR_CODE(28) 127INT_HANDLER_WITHOUT_ERR_CODE(29) 128INT_HANDLER_WITHOUT_ERR_CODE(2a) 129INT_HANDLER_WITHOUT_ERR_CODE(2b) 130INT_HANDLER_WITHOUT_ERR_CODE(2c) 131INT_HANDLER_WITHOUT_ERR_CODE(2d) 132INT_HANDLER_WITHOUT_ERR_CODE(2e) 133INT_HANDLER_WITHOUT_ERR_CODE(2f) 134 135INT_HANDLER_WITHOUT_ERR_CODE(30) 136INT_HANDLER_WITHOUT_ERR_CODE(31) 137INT_HANDLER_WITHOUT_ERR_CODE(32) 138INT_HANDLER_WITHOUT_ERR_CODE(33) 139INT_HANDLER_WITHOUT_ERR_CODE(34) 140INT_HANDLER_WITHOUT_ERR_CODE(35) 141INT_HANDLER_WITHOUT_ERR_CODE(36) 142INT_HANDLER_WITHOUT_ERR_CODE(37) 143INT_HANDLER_WITHOUT_ERR_CODE(38) 144INT_HANDLER_WITHOUT_ERR_CODE(39) 145INT_HANDLER_WITHOUT_ERR_CODE(3a) 146INT_HANDLER_WITHOUT_ERR_CODE(3b) 147INT_HANDLER_WITHOUT_ERR_CODE(3c) 148INT_HANDLER_WITHOUT_ERR_CODE(3d) 149INT_HANDLER_WITHOUT_ERR_CODE(3e) 150INT_HANDLER_WITHOUT_ERR_CODE(3f) 151 152INT_HANDLER_WITHOUT_ERR_CODE(40) 153INT_HANDLER_WITHOUT_ERR_CODE(41) 154INT_HANDLER_WITHOUT_ERR_CODE(42) 155INT_HANDLER_WITHOUT_ERR_CODE(43) 156INT_HANDLER_WITHOUT_ERR_CODE(44) 157INT_HANDLER_WITHOUT_ERR_CODE(45) 158INT_HANDLER_WITHOUT_ERR_CODE(46) 159INT_HANDLER_WITHOUT_ERR_CODE(47) 160INT_HANDLER_WITHOUT_ERR_CODE(48) 161INT_HANDLER_WITHOUT_ERR_CODE(49) 162INT_HANDLER_WITHOUT_ERR_CODE(4a) 163INT_HANDLER_WITHOUT_ERR_CODE(4b) 164INT_HANDLER_WITHOUT_ERR_CODE(4c) 165INT_HANDLER_WITHOUT_ERR_CODE(4d) 166INT_HANDLER_WITHOUT_ERR_CODE(4e) 167INT_HANDLER_WITHOUT_ERR_CODE(4f) 168 169INT_HANDLER_WITHOUT_ERR_CODE(50) 170INT_HANDLER_WITHOUT_ERR_CODE(51) 171INT_HANDLER_WITHOUT_ERR_CODE(52) 172INT_HANDLER_WITHOUT_ERR_CODE(53) 173INT_HANDLER_WITHOUT_ERR_CODE(54) 174INT_HANDLER_WITHOUT_ERR_CODE(55) 175INT_HANDLER_WITHOUT_ERR_CODE(56) 176INT_HANDLER_WITHOUT_ERR_CODE(57) 177INT_HANDLER_WITHOUT_ERR_CODE(58) 178INT_HANDLER_WITHOUT_ERR_CODE(59) 179INT_HANDLER_WITHOUT_ERR_CODE(5a) 180INT_HANDLER_WITHOUT_ERR_CODE(5b) 181INT_HANDLER_WITHOUT_ERR_CODE(5c) 182INT_HANDLER_WITHOUT_ERR_CODE(5d) 183INT_HANDLER_WITHOUT_ERR_CODE(5e) 184INT_HANDLER_WITHOUT_ERR_CODE(5f) 185 186INT_HANDLER_WITHOUT_ERR_CODE(60) 187INT_HANDLER_WITHOUT_ERR_CODE(61) 188INT_HANDLER_WITHOUT_ERR_CODE(62) 189INT_HANDLER_WITHOUT_ERR_CODE(63) 190INT_HANDLER_WITHOUT_ERR_CODE(64) 191INT_HANDLER_WITHOUT_ERR_CODE(65) 192INT_HANDLER_WITHOUT_ERR_CODE(66) 193INT_HANDLER_WITHOUT_ERR_CODE(67) 194INT_HANDLER_WITHOUT_ERR_CODE(68) 195INT_HANDLER_WITHOUT_ERR_CODE(69) 196INT_HANDLER_WITHOUT_ERR_CODE(6a) 197INT_HANDLER_WITHOUT_ERR_CODE(6b) 198INT_HANDLER_WITHOUT_ERR_CODE(6c) 199INT_HANDLER_WITHOUT_ERR_CODE(6d) 200INT_HANDLER_WITHOUT_ERR_CODE(6e) 201INT_HANDLER_WITHOUT_ERR_CODE(6f) 202 203INT_HANDLER_WITHOUT_ERR_CODE(70) 204INT_HANDLER_WITHOUT_ERR_CODE(71) 205INT_HANDLER_WITHOUT_ERR_CODE(72) 206INT_HANDLER_WITHOUT_ERR_CODE(73) 207INT_HANDLER_WITHOUT_ERR_CODE(74) 208INT_HANDLER_WITHOUT_ERR_CODE(75) 209INT_HANDLER_WITHOUT_ERR_CODE(76) 210INT_HANDLER_WITHOUT_ERR_CODE(77) 211INT_HANDLER_WITHOUT_ERR_CODE(78) 212INT_HANDLER_WITHOUT_ERR_CODE(79) 213INT_HANDLER_WITHOUT_ERR_CODE(7a) 214INT_HANDLER_WITHOUT_ERR_CODE(7b) 215INT_HANDLER_WITHOUT_ERR_CODE(7c) 216INT_HANDLER_WITHOUT_ERR_CODE(7d) 217INT_HANDLER_WITHOUT_ERR_CODE(7e) 218INT_HANDLER_WITHOUT_ERR_CODE(7f) 219 220INT_HANDLER_WITHOUT_ERR_CODE(80) 221INT_HANDLER_WITHOUT_ERR_CODE(81) 222INT_HANDLER_WITHOUT_ERR_CODE(82) 223INT_HANDLER_WITHOUT_ERR_CODE(83) 224INT_HANDLER_WITHOUT_ERR_CODE(84) 225INT_HANDLER_WITHOUT_ERR_CODE(85) 226INT_HANDLER_WITHOUT_ERR_CODE(86) 227INT_HANDLER_WITHOUT_ERR_CODE(87) 228INT_HANDLER_WITHOUT_ERR_CODE(88) 229INT_HANDLER_WITHOUT_ERR_CODE(89) 230INT_HANDLER_WITHOUT_ERR_CODE(8a) 231INT_HANDLER_WITHOUT_ERR_CODE(8b) 232INT_HANDLER_WITHOUT_ERR_CODE(8c) 233INT_HANDLER_WITHOUT_ERR_CODE(8d) 234INT_HANDLER_WITHOUT_ERR_CODE(8e) 235INT_HANDLER_WITHOUT_ERR_CODE(8f) 236 237INT_HANDLER_WITHOUT_ERR_CODE(90) 238INT_HANDLER_WITHOUT_ERR_CODE(91) 239INT_HANDLER_WITHOUT_ERR_CODE(92) 240INT_HANDLER_WITHOUT_ERR_CODE(93) 241INT_HANDLER_WITHOUT_ERR_CODE(94) 242INT_HANDLER_WITHOUT_ERR_CODE(95) 243INT_HANDLER_WITHOUT_ERR_CODE(96) 244INT_HANDLER_WITHOUT_ERR_CODE(97) 245INT_HANDLER_WITHOUT_ERR_CODE(98) 246INT_HANDLER_WITHOUT_ERR_CODE(99) 247INT_HANDLER_WITHOUT_ERR_CODE(9a) 248INT_HANDLER_WITHOUT_ERR_CODE(9b) 249INT_HANDLER_WITHOUT_ERR_CODE(9c) 250INT_HANDLER_WITHOUT_ERR_CODE(9d) 251INT_HANDLER_WITHOUT_ERR_CODE(9e) 252INT_HANDLER_WITHOUT_ERR_CODE(9f) 253 254INT_HANDLER_WITHOUT_ERR_CODE(a0) 255INT_HANDLER_WITHOUT_ERR_CODE(a1) 256INT_HANDLER_WITHOUT_ERR_CODE(a2) 257INT_HANDLER_WITHOUT_ERR_CODE(a3) 258INT_HANDLER_WITHOUT_ERR_CODE(a4) 259INT_HANDLER_WITHOUT_ERR_CODE(a5) 260INT_HANDLER_WITHOUT_ERR_CODE(a6) 261INT_HANDLER_WITHOUT_ERR_CODE(a7) 262INT_HANDLER_WITHOUT_ERR_CODE(a8) 263INT_HANDLER_WITHOUT_ERR_CODE(a9) 264INT_HANDLER_WITHOUT_ERR_CODE(aa) 265INT_HANDLER_WITHOUT_ERR_CODE(ab) 266INT_HANDLER_WITHOUT_ERR_CODE(ac) 267INT_HANDLER_WITHOUT_ERR_CODE(ad) 268INT_HANDLER_WITHOUT_ERR_CODE(ae) 269INT_HANDLER_WITHOUT_ERR_CODE(af) 270 271INT_HANDLER_WITHOUT_ERR_CODE(b0) 272INT_HANDLER_WITHOUT_ERR_CODE(b1) 273INT_HANDLER_WITHOUT_ERR_CODE(b2) 274INT_HANDLER_WITHOUT_ERR_CODE(b3) 275INT_HANDLER_WITHOUT_ERR_CODE(b4) 276INT_HANDLER_WITHOUT_ERR_CODE(b5) 277INT_HANDLER_WITHOUT_ERR_CODE(b6) 278INT_HANDLER_WITHOUT_ERR_CODE(b7) 279INT_HANDLER_WITHOUT_ERR_CODE(b8) 280INT_HANDLER_WITHOUT_ERR_CODE(b9) 281INT_HANDLER_WITHOUT_ERR_CODE(ba) 282INT_HANDLER_WITHOUT_ERR_CODE(bb) 283INT_HANDLER_WITHOUT_ERR_CODE(bc) 284INT_HANDLER_WITHOUT_ERR_CODE(bd) 285INT_HANDLER_WITHOUT_ERR_CODE(be) 286INT_HANDLER_WITHOUT_ERR_CODE(bf) 287 288INT_HANDLER_WITHOUT_ERR_CODE(c0) 289INT_HANDLER_WITHOUT_ERR_CODE(c1) 290INT_HANDLER_WITHOUT_ERR_CODE(c2) 291INT_HANDLER_WITHOUT_ERR_CODE(c3) 292INT_HANDLER_WITHOUT_ERR_CODE(c4) 293INT_HANDLER_WITHOUT_ERR_CODE(c5) 294INT_HANDLER_WITHOUT_ERR_CODE(c6) 295INT_HANDLER_WITHOUT_ERR_CODE(c7) 296INT_HANDLER_WITHOUT_ERR_CODE(c8) 297INT_HANDLER_WITHOUT_ERR_CODE(c9) 298INT_HANDLER_WITHOUT_ERR_CODE(ca) 299INT_HANDLER_WITHOUT_ERR_CODE(cb) 300INT_HANDLER_WITHOUT_ERR_CODE(cc) 301INT_HANDLER_WITHOUT_ERR_CODE(cd) 302INT_HANDLER_WITHOUT_ERR_CODE(ce) 303INT_HANDLER_WITHOUT_ERR_CODE(cf) 304 305INT_HANDLER_WITHOUT_ERR_CODE(d0) 306INT_HANDLER_WITHOUT_ERR_CODE(d1) 307INT_HANDLER_WITHOUT_ERR_CODE(d2) 308INT_HANDLER_WITHOUT_ERR_CODE(d3) 309INT_HANDLER_WITHOUT_ERR_CODE(d4) 310INT_HANDLER_WITHOUT_ERR_CODE(d5) 311INT_HANDLER_WITHOUT_ERR_CODE(d6) 312INT_HANDLER_WITHOUT_ERR_CODE(d7) 313INT_HANDLER_WITHOUT_ERR_CODE(d8) 314INT_HANDLER_WITHOUT_ERR_CODE(d9) 315INT_HANDLER_WITHOUT_ERR_CODE(da) 316INT_HANDLER_WITHOUT_ERR_CODE(db) 317INT_HANDLER_WITHOUT_ERR_CODE(dc) 318INT_HANDLER_WITHOUT_ERR_CODE(dd) 319INT_HANDLER_WITHOUT_ERR_CODE(de) 320INT_HANDLER_WITHOUT_ERR_CODE(df) 321 322INT_HANDLER_WITHOUT_ERR_CODE(e0) 323INT_HANDLER_WITHOUT_ERR_CODE(e1) 324INT_HANDLER_WITHOUT_ERR_CODE(e2) 325INT_HANDLER_WITHOUT_ERR_CODE(e3) 326INT_HANDLER_WITHOUT_ERR_CODE(e4) 327INT_HANDLER_WITHOUT_ERR_CODE(e5) 328INT_HANDLER_WITHOUT_ERR_CODE(e6) 329INT_HANDLER_WITHOUT_ERR_CODE(e7) 330INT_HANDLER_WITHOUT_ERR_CODE(e8) 331INT_HANDLER_WITHOUT_ERR_CODE(e9) 332INT_HANDLER_WITHOUT_ERR_CODE(ea) 333INT_HANDLER_WITHOUT_ERR_CODE(eb) 334INT_HANDLER_WITHOUT_ERR_CODE(ec) 335INT_HANDLER_WITHOUT_ERR_CODE(ed) 336INT_HANDLER_WITHOUT_ERR_CODE(ee) 337INT_HANDLER_WITHOUT_ERR_CODE(ef) 338 339INT_HANDLER_WITHOUT_ERR_CODE(f0) 340INT_HANDLER_WITHOUT_ERR_CODE(f1) 341INT_HANDLER_WITHOUT_ERR_CODE(f2) 342INT_HANDLER_WITHOUT_ERR_CODE(f3) 343INT_HANDLER_WITHOUT_ERR_CODE(f4) 344INT_HANDLER_WITHOUT_ERR_CODE(f5) 345INT_HANDLER_WITHOUT_ERR_CODE(f6) 346INT_HANDLER_WITHOUT_ERR_CODE(f7) 347INT_HANDLER_WITHOUT_ERR_CODE(f8) 348INT_HANDLER_WITHOUT_ERR_CODE(f9) 349INT_HANDLER_WITHOUT_ERR_CODE(fa) 350INT_HANDLER_WITHOUT_ERR_CODE(fb) 351INT_HANDLER_WITHOUT_ERR_CODE(fc) 352INT_HANDLER_WITHOUT_ERR_CODE(fd) 353INT_HANDLER_WITHOUT_ERR_CODE(fe) 354INT_HANDLER_WITHOUT_ERR_CODE(ff) 355 356handle_interrupt: 357 # Reset segment selectors 358 RESET_SELECTORS(edx) 359 360 # determine if we have a kernel exception 361 testl $3, (4 * CS)(%esp) # extract CPL (current privilege level) 362 jz kernel_interrupt 363 364user_interrupt: 365 # switch to kernel stack 366 SET_KERNEL_STACK 367 368 # Place the arguments on the stack 369 pushl %eax 370 pushl %ecx 371 372 # gtfo to C land, we will not return 373 call c_handle_interrupt 374 375kernel_interrupt: 376 cmpl $0x20, %ecx # if interrupt vector is below 0x20, we have an exception 377 jl kernel_exception 378 # Check the current ESP. If this is within the bounds of __idle_thread_start and 379 # __idle_thread_end then this is the idle thread. Interrupts from the idle thread 380 # are handled like normal interrupts. 381 cmpl $__idle_thread_start, %esp 382 jb not_idle_thread 383 cmpl $__idle_thread_end, %esp 384 jae not_idle_thread 385 jmp user_interrupt 386not_idle_thread: 387 # We got an interrupt from the kernel. Call into C to save 388 # the IRQ number, then return back to where we were 389 pushl %ecx 390 call c_nested_interrupt 391 addl $4, %esp 392 # Disable the interrupt flag so that we do not take any additional interrupts 393 andl $~0x200, (4 * FLAGS)(%esp) 394 # Return 395kernel_int_return: 396 addl $4, %esp 397 popl %eax 398 popl %ebx 399 popl %ecx 400 popl %edx 401 popl %esi 402 popl %edi 403 popl %ebp 404 /* Skip FaultIP and error-code. */ 405 addl $8, %esp 406 iretl 407 408# Handle a kernel exception 409 410BEGIN_FUNC(kernel_exception) 411#ifdef CONFIG_HARDWARE_DEBUG_API 412 /* Before giving up and panicking, we need to test for the extra case that 413 * this might be a kernel exception that is the result of EFLAGS.TF being 414 * set when SYSENTER was called. 415 * 416 * Since EFLAGS.TF is not disabled by SYSENTER, single-stepping continues 417 * into the kernel, and so causes a debug-exception in kernel code, since 418 * the CPU is trying to single-step the kernel code. 419 * 420 * So we test for EFLAGS.TF, and if it's set, we unset it, and let the 421 * exception continue. The debug exception handler will notice that it was 422 * kernel exception, and handle it appropriately -- that really just means 423 * setting EFLAGS.TF before SYSEXIT so that single-stepping resumes in the 424 * userspace thread. 425 */ 426 movl (4 * FLAGS)(%esp), %eax 427 movl $(1<<8), %ebx 428 testl %ebx, %eax 429 je .not_eflags_tf 430 431 /* Else it was EFLAGS.TF that caused the kernel exception on SYSENTER. 432 * So, unset the EFLAGS.TF on the stack and this causes the syscall that we 433 * will return to, to be able to execute properly. 434 * 435 * It will then be the debug exception handler's responsibility to re-set 436 * EFLAGS.TF for the userspace thread before it returns. 437 * 438 * So at this point we want to just unset EFLAGS.TF and IRET immediately. 439 */ 440 andl $~(1<<8), %eax 441 movl %eax, (4 * FLAGS)(%esp) 442 443 /* Begin popping registers to IRET now. We don't need to consider any 444 * unexpected side effects because we are just immediately returning after 445 * entering. 446 */ 447 addl $4, %esp 448 popl %eax 449 popl %ebx 450 popl %ecx 451 popl %edx 452 popl %esi 453 popl %edi 454 popl %ebp 455 /* Skip FaultIP and error-code. */ 456 addl $8, %esp 457 iretl 458 459.not_eflags_tf: 460#endif /* CONFIG_HARDWARE_DEBUG_API */ 461 462 # prepare debug info 463 movl (4 * Error)(%esp), %eax # EAX contains Error Code 464 movl (4 * NextIP)(%esp), %ebx # EBX contains EIP of the exception generating instruction 465 movl (4 * FLAGS)(%esp), %edx # EDX contains EFLAGS 466 leal (4 * ESP)(%esp), %edi # EDI contains ESP when exception happened 467 468 # call handleKernelException(vector, errcode, EIP, ESP, EFLAGS, CR0, CR2, CR3, CR4) 469 movl %cr4, %esi 470 pushl %esi 471 movl %cr3, %esi 472 pushl %esi 473 movl %cr2, %esi 474 pushl %esi 475 movl %cr0, %esi 476 pushl %esi 477 pushl %edx 478 pushl %edi 479 pushl %ebx 480 pushl %eax 481 pushl %ecx 482 call handleKernelException 483 addl $36, %esp 484 # Set EIP in the saved register context to the new IP returned from handleKernelException 485 movl %eax, (4 * NextIP)(%esp) 486 jmp kernel_int_return 487END_FUNC(kernel_exception) 488 489# Handle vmexit 490# ESP points to the end of an array that just holds the general purpose registers 491#ifdef CONFIG_VTX 492BEGIN_FUNC(handle_vmexit) 493 pushl %ebp 494 pushl %edi 495 pushl %esi 496 pushl %edx 497 pushl %ecx 498 pushl %ebx 499 pushl %eax 500 501 # Reset segment selectors 502 RESET_SELECTORS(ecx) 503 504 # switch to kernel stack 505 SET_KERNEL_STACK_FROM(7 * 4) 506 # Handle the vmexit, we will not return 507 call c_handle_vmexit 508END_FUNC(handle_vmexit) 509#endif 510 511# Handle Syscall (coming via sysenter) 512# Assume following register contents when called: 513# EAX : syscall number 514# ECX : user ESP 515# EDX : user EIP (pointing to the sysenter instruction) 516# ESP : points to tss.esp0 which points to the end of the thread's registers array 517 518BEGIN_FUNC(handle_syscall) 519#ifndef CONFIG_HARDWARE_DEBUG_API 520 movl (%esp), %esp # ESP := tss.esp0 521#endif 522 523 subl $4, %esp # skip SS 524 pushl %ecx # save ESP (passed in ECX) 525 pushfl # save EFLAGS 526 orl $0x200, (%esp) # set interrupt bit in saved EFLAGS 527 subl $4, %esp # skip CS 528 pushl %edx # NextIP := EDX 529 pushl $-1 # save Error (-1 means we entered via syscall) 530 pushl %edx # save FaultIP (passed in EDX) 531 pushl %ebp # save EBP (reply register) 532 pushl %edi # save EDI (message register) 533 pushl %esi # save ESI (msgInfo register) 534 pushl %edx # save EDX (contains FaultIP) 535 pushl %ecx # save ECX (contains ESP) 536 pushl %ebx # save EBX (cap/badge register) 537 pushl %eax # save EAX (syscall number) 538 pushl $0 539 540 # Reset segment selectors 541 RESET_SELECTORS(ecx) 542 543 # switch to kernel stack 544 SET_KERNEL_STACK 545 546 # Push all the arguments for c_handle_syscall 547#ifdef CONFIG_KERNEL_MCS 548 pushl %ebp # reply 549#endif 550 pushl %eax # syscall number 551 pushl %esi # msgInfo 552 pushl %ebx # cptr 553 554 # gtfo to C land, we will not return 555 call c_handle_syscall 556 557END_FUNC(handle_syscall) 558