diff options
-rw-r--r-- | arch/ia64/kernel/entry.S | 110 | ||||
-rw-r--r-- | arch/ia64/kernel/fsys.S | 147 | ||||
-rw-r--r-- | arch/ia64/kernel/gate.S | 62 | ||||
-rw-r--r-- | arch/ia64/kernel/ia64_ksyms.c | 3 | ||||
-rw-r--r-- | arch/ia64/kernel/ivt.S | 179 |
5 files changed, 279 insertions, 222 deletions
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index d3f093820bc7..9353adc18956 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -470,18 +470,6 @@ ENTRY(load_switch_stack) | |||
470 | br.cond.sptk.many b7 | 470 | br.cond.sptk.many b7 |
471 | END(load_switch_stack) | 471 | END(load_switch_stack) |
472 | 472 | ||
473 | GLOBAL_ENTRY(__ia64_syscall) | ||
474 | .regstk 6,0,0,0 | ||
475 | mov r15=in5 // put syscall number in place | ||
476 | break __BREAK_SYSCALL | ||
477 | movl r2=errno | ||
478 | cmp.eq p6,p7=-1,r10 | ||
479 | ;; | ||
480 | (p6) st4 [r2]=r8 | ||
481 | (p6) mov r8=-1 | ||
482 | br.ret.sptk.many rp | ||
483 | END(__ia64_syscall) | ||
484 | |||
485 | GLOBAL_ENTRY(execve) | 473 | GLOBAL_ENTRY(execve) |
486 | mov r15=__NR_execve // put syscall number in place | 474 | mov r15=__NR_execve // put syscall number in place |
487 | break __BREAK_SYSCALL | 475 | break __BREAK_SYSCALL |
@@ -637,7 +625,7 @@ END(ia64_ret_from_syscall) | |||
637 | * r8-r11: restored (syscall return value(s)) | 625 | * r8-r11: restored (syscall return value(s)) |
638 | * r12: restored (user-level stack pointer) | 626 | * r12: restored (user-level stack pointer) |
639 | * r13: restored (user-level thread pointer) | 627 | * r13: restored (user-level thread pointer) |
640 | * r14: cleared | 628 | * r14: set to __kernel_syscall_via_epc |
641 | * r15: restored (syscall #) | 629 | * r15: restored (syscall #) |
642 | * r16-r17: cleared | 630 | * r16-r17: cleared |
643 | * r18: user-level b6 | 631 | * r18: user-level b6 |
@@ -658,7 +646,7 @@ END(ia64_ret_from_syscall) | |||
658 | * pr: restored (user-level pr) | 646 | * pr: restored (user-level pr) |
659 | * b0: restored (user-level rp) | 647 | * b0: restored (user-level rp) |
660 | * b6: restored | 648 | * b6: restored |
661 | * b7: cleared | 649 | * b7: set to __kernel_syscall_via_epc |
662 | * ar.unat: restored (user-level ar.unat) | 650 | * ar.unat: restored (user-level ar.unat) |
663 | * ar.pfs: restored (user-level ar.pfs) | 651 | * ar.pfs: restored (user-level ar.pfs) |
664 | * ar.rsc: restored (user-level ar.rsc) | 652 | * ar.rsc: restored (user-level ar.rsc) |
@@ -704,72 +692,79 @@ ENTRY(ia64_leave_syscall) | |||
704 | ;; | 692 | ;; |
705 | (p6) ld4 r31=[r18] // load current_thread_info()->flags | 693 | (p6) ld4 r31=[r18] // load current_thread_info()->flags |
706 | ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" | 694 | ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" |
707 | mov b7=r0 // clear b7 | 695 | nop.i 0 |
708 | ;; | 696 | ;; |
709 | ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) | 697 | mov r16=ar.bsp // M2 get existing backing store pointer |
710 | ld8 r18=[r2],PT(R9)-PT(B6) // load b6 | 698 | ld8 r18=[r2],PT(R9)-PT(B6) // load b6 |
711 | (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? | 699 | (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? |
712 | ;; | 700 | ;; |
713 | mov r16=ar.bsp // M2 get existing backing store pointer | 701 | ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) |
714 | (p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? | 702 | (p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? |
715 | (p6) br.cond.spnt .work_pending_syscall | 703 | (p6) br.cond.spnt .work_pending_syscall |
716 | ;; | 704 | ;; |
717 | // start restoring the state saved on the kernel stack (struct pt_regs): | 705 | // start restoring the state saved on the kernel stack (struct pt_regs): |
718 | ld8 r9=[r2],PT(CR_IPSR)-PT(R9) | 706 | ld8 r9=[r2],PT(CR_IPSR)-PT(R9) |
719 | ld8 r11=[r3],PT(CR_IIP)-PT(R11) | 707 | ld8 r11=[r3],PT(CR_IIP)-PT(R11) |
720 | mov f6=f0 // clear f6 | 708 | (pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! |
721 | ;; | 709 | ;; |
722 | invala // M0|1 invalidate ALAT | 710 | invala // M0|1 invalidate ALAT |
723 | rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection | 711 | rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection |
724 | mov f9=f0 // clear f9 | 712 | cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs |
725 | 713 | ||
726 | ld8 r29=[r2],16 // load cr.ipsr | 714 | ld8 r29=[r2],16 // M0|1 load cr.ipsr |
727 | ld8 r28=[r3],16 // load cr.iip | 715 | ld8 r28=[r3],16 // M0|1 load cr.iip |
728 | mov f8=f0 // clear f8 | 716 | mov r22=r0 // A clear r22 |
729 | ;; | 717 | ;; |
730 | ld8 r30=[r2],16 // M0|1 load cr.ifs | 718 | ld8 r30=[r2],16 // M0|1 load cr.ifs |
731 | ld8 r25=[r3],16 // M0|1 load ar.unat | 719 | ld8 r25=[r3],16 // M0|1 load ar.unat |
732 | cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs | 720 | (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 |
733 | ;; | 721 | ;; |
734 | ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs | 722 | ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs |
735 | (pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled | 723 | (pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled |
736 | mov f10=f0 // clear f10 | 724 | nop 0 |
737 | ;; | 725 | ;; |
738 | ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 | 726 | ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0 |
739 | ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc | 727 | ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc |
740 | mov f11=f0 // clear f11 | 728 | mov f6=f0 // F clear f6 |
741 | ;; | 729 | ;; |
742 | ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) | 730 | ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage) |
743 | ld8 r31=[r3],PT(R1)-PT(PR) // load predicates | 731 | ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates |
744 | (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 | 732 | mov f7=f0 // F clear f7 |
745 | ;; | 733 | ;; |
746 | ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr | 734 | ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr |
747 | ld8.fill r1=[r3],16 // load r1 | 735 | ld8.fill r1=[r3],16 // M0|1 load r1 |
748 | (pUStk) mov r17=1 | 736 | (pUStk) mov r17=1 // A |
749 | ;; | 737 | ;; |
750 | srlz.d // M0 ensure interruption collection is off | 738 | (pUStk) st1 [r14]=r17 // M2|3 |
751 | ld8.fill r13=[r3],16 | 739 | ld8.fill r13=[r3],16 // M0|1 |
752 | mov f7=f0 // clear f7 | 740 | mov f8=f0 // F clear f8 |
753 | ;; | 741 | ;; |
754 | ld8.fill r12=[r2] // restore r12 (sp) | 742 | ld8.fill r12=[r2] // M0|1 restore r12 (sp) |
755 | mov.m ar.ssd=r0 // M2 clear ar.ssd | 743 | ld8.fill r15=[r3] // M0|1 restore r15 |
756 | mov r22=r0 // clear r22 | 744 | mov b6=r18 // I0 restore b6 |
757 | 745 | ||
758 | ld8.fill r15=[r3] // restore r15 | 746 | addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A |
759 | (pUStk) st1 [r14]=r17 | 747 | mov f9=f0 // F clear f9 |
760 | addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 | 748 | (pKStk) br.cond.dpnt.many skip_rbs_switch // B |
749 | |||
750 | srlz.d // M0 ensure interruption collection is off (for cover) | ||
751 | shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition | ||
752 | cover // B add current frame into dirty partition & set cr.ifs | ||
761 | ;; | 753 | ;; |
762 | (pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 | 754 | (pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 |
763 | mov.m ar.csd=r0 // M2 clear ar.csd | 755 | mov r19=ar.bsp // M2 get new backing store pointer |
764 | mov b6=r18 // I0 restore b6 | 756 | mov f10=f0 // F clear f10 |
757 | |||
758 | nop.m 0 | ||
759 | movl r14=__kernel_syscall_via_epc // X | ||
765 | ;; | 760 | ;; |
766 | mov r14=r0 // clear r14 | 761 | mov.m ar.csd=r0 // M2 clear ar.csd |
767 | shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition | 762 | mov.m ar.ccv=r0 // M2 clear ar.ccv |
768 | (pKStk) br.cond.dpnt.many skip_rbs_switch | 763 | mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) |
769 | 764 | ||
770 | mov.m ar.ccv=r0 // clear ar.ccv | 765 | mov.m ar.ssd=r0 // M2 clear ar.ssd |
771 | (pNonSys) br.cond.dpnt.many dont_preserve_current_frame | 766 | mov f11=f0 // F clear f11 |
772 | br.cond.sptk.many rbs_switch | 767 | br.cond.sptk.many rbs_switch // B |
773 | END(ia64_leave_syscall) | 768 | END(ia64_leave_syscall) |
774 | 769 | ||
775 | #ifdef CONFIG_IA32_SUPPORT | 770 | #ifdef CONFIG_IA32_SUPPORT |
@@ -885,7 +880,7 @@ GLOBAL_ENTRY(ia64_leave_kernel) | |||
885 | ldf.fill f7=[r2],PT(F11)-PT(F7) | 880 | ldf.fill f7=[r2],PT(F11)-PT(F7) |
886 | ldf.fill f8=[r3],32 | 881 | ldf.fill f8=[r3],32 |
887 | ;; | 882 | ;; |
888 | srlz.i // ensure interruption collection is off | 883 | srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned) |
889 | mov ar.ccv=r15 | 884 | mov ar.ccv=r15 |
890 | ;; | 885 | ;; |
891 | ldf.fill f11=[r2] | 886 | ldf.fill f11=[r2] |
@@ -945,11 +940,10 @@ GLOBAL_ENTRY(ia64_leave_kernel) | |||
945 | * NOTE: alloc, loadrs, and cover can't be predicated. | 940 | * NOTE: alloc, loadrs, and cover can't be predicated. |
946 | */ | 941 | */ |
947 | (pNonSys) br.cond.dpnt dont_preserve_current_frame | 942 | (pNonSys) br.cond.dpnt dont_preserve_current_frame |
948 | |||
949 | rbs_switch: | ||
950 | cover // add current frame into dirty partition and set cr.ifs | 943 | cover // add current frame into dirty partition and set cr.ifs |
951 | ;; | 944 | ;; |
952 | mov r19=ar.bsp // get new backing store pointer | 945 | mov r19=ar.bsp // get new backing store pointer |
946 | rbs_switch: | ||
953 | sub r16=r16,r18 // krbs = old bsp - size of dirty partition | 947 | sub r16=r16,r18 // krbs = old bsp - size of dirty partition |
954 | cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs | 948 | cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs |
955 | ;; | 949 | ;; |
@@ -1024,14 +1018,14 @@ rse_clear_invalid: | |||
1024 | mov loc5=0 | 1018 | mov loc5=0 |
1025 | mov loc6=0 | 1019 | mov loc6=0 |
1026 | mov loc7=0 | 1020 | mov loc7=0 |
1027 | (pRecurse) br.call.sptk.few b0=rse_clear_invalid | 1021 | (pRecurse) br.call.dptk.few b0=rse_clear_invalid |
1028 | ;; | 1022 | ;; |
1029 | mov loc8=0 | 1023 | mov loc8=0 |
1030 | mov loc9=0 | 1024 | mov loc9=0 |
1031 | cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret | 1025 | cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret |
1032 | mov loc10=0 | 1026 | mov loc10=0 |
1033 | mov loc11=0 | 1027 | mov loc11=0 |
1034 | (pReturn) br.ret.sptk.many b0 | 1028 | (pReturn) br.ret.dptk.many b0 |
1035 | #endif /* !CONFIG_ITANIUM */ | 1029 | #endif /* !CONFIG_ITANIUM */ |
1036 | # undef pRecurse | 1030 | # undef pRecurse |
1037 | # undef pReturn | 1031 | # undef pReturn |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 0d8650f7fce7..f566ff43a389 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
@@ -531,91 +531,114 @@ GLOBAL_ENTRY(fsys_bubble_down) | |||
531 | .altrp b6 | 531 | .altrp b6 |
532 | .body | 532 | .body |
533 | /* | 533 | /* |
534 | * We get here for syscalls that don't have a lightweight handler. For those, we | 534 | * We get here for syscalls that don't have a lightweight |
535 | * need to bubble down into the kernel and that requires setting up a minimal | 535 | * handler. For those, we need to bubble down into the kernel |
536 | * pt_regs structure, and initializing the CPU state more or less as if an | 536 | * and that requires setting up a minimal pt_regs structure, |
537 | * interruption had occurred. To make syscall-restarts work, we setup pt_regs | 537 | * and initializing the CPU state more or less as if an |
538 | * such that cr_iip points to the second instruction in syscall_via_break. | 538 | * interruption had occurred. To make syscall-restarts work, |
539 | * Decrementing the IP hence will restart the syscall via break and not | 539 | * we setup pt_regs such that cr_iip points to the second |
540 | * decrementing IP will return us to the caller, as usual. Note that we preserve | 540 | * instruction in syscall_via_break. Decrementing the IP |
541 | * the value of psr.pp rather than initializing it from dcr.pp. This makes it | 541 | * hence will restart the syscall via break and not |
542 | * possible to distinguish fsyscall execution from other privileged execution. | 542 | * decrementing IP will return us to the caller, as usual. |
543 | * Note that we preserve the value of psr.pp rather than | ||
544 | * initializing it from dcr.pp. This makes it possible to | ||
545 | * distinguish fsyscall execution from other privileged | ||
546 | * execution. | ||
543 | * | 547 | * |
544 | * On entry: | 548 | * On entry: |
545 | * - normal fsyscall handler register usage, except that we also have: | 549 | * - normal fsyscall handler register usage, except |
550 | * that we also have: | ||
546 | * - r18: address of syscall entry point | 551 | * - r18: address of syscall entry point |
547 | * - r21: ar.fpsr | 552 | * - r21: ar.fpsr |
548 | * - r26: ar.pfs | 553 | * - r26: ar.pfs |
549 | * - r27: ar.rsc | 554 | * - r27: ar.rsc |
550 | * - r29: psr | 555 | * - r29: psr |
556 | * | ||
557 | * We used to clear some PSR bits here but that requires slow | ||
558 | * serialization. Fortuntely, that isn't really necessary. | ||
559 | * The rationale is as follows: we used to clear bits | ||
560 | * ~PSR_PRESERVED_BITS in PSR.L. Since | ||
561 | * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we | ||
562 | * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}. | ||
563 | * However, | ||
564 | * | ||
565 | * PSR.BE : already is turned off in __kernel_syscall_via_epc() | ||
566 | * PSR.AC : don't care (kernel normally turns PSR.AC on) | ||
567 | * PSR.I : already turned off by the time fsys_bubble_down gets | ||
568 | * invoked | ||
569 | * PSR.DFL: always 0 (kernel never turns it on) | ||
570 | * PSR.DFH: don't care --- kernel never touches f32-f127 on its own | ||
571 | * initiative | ||
572 | * PSR.DI : always 0 (kernel never turns it on) | ||
573 | * PSR.SI : always 0 (kernel never turns it on) | ||
574 | * PSR.DB : don't care --- kernel never enables kernel-level | ||
575 | * breakpoints | ||
576 | * PSR.TB : must be 0 already; if it wasn't zero on entry to | ||
577 | * __kernel_syscall_via_epc, the branch to fsys_bubble_down | ||
578 | * will trigger a taken branch; the taken-trap-handler then | ||
579 | * converts the syscall into a break-based system-call. | ||
551 | */ | 580 | */ |
552 | # define PSR_PRESERVED_BITS (IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \ | ||
553 | | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \ | ||
554 | | IA64_PSR_IC) | ||
555 | /* | 581 | /* |
556 | * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have | 582 | * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. |
557 | * to synthesize. | 583 | * The rest we have to synthesize. |
558 | */ | 584 | */ |
559 | # define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \ | 585 | # define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) \ |
586 | | (0x1 << IA64_PSR_RI_BIT) \ | ||
560 | | IA64_PSR_BN | IA64_PSR_I) | 587 | | IA64_PSR_BN | IA64_PSR_I) |
561 | 588 | ||
562 | invala | 589 | invala // M0|1 |
563 | movl r8=PSR_ONE_BITS | 590 | movl r14=ia64_ret_from_syscall // X |
564 | 591 | ||
565 | mov r25=ar.unat // save ar.unat (5 cyc) | 592 | nop.m 0 |
566 | movl r9=PSR_PRESERVED_BITS | 593 | movl r28=__kernel_syscall_via_break // X create cr.iip |
567 | |||
568 | mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 | ||
569 | movl r28=__kernel_syscall_via_break | ||
570 | ;; | 594 | ;; |
571 | mov r23=ar.bspstore // save ar.bspstore (12 cyc) | 595 | |
572 | mov r31=pr // save pr (2 cyc) | 596 | mov r2=r16 // A get task addr to addl-addressable register |
573 | mov r20=r1 // save caller's gp in r20 | 597 | adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A |
598 | mov r31=pr // I0 save pr (2 cyc) | ||
574 | ;; | 599 | ;; |
575 | mov r2=r16 // copy current task addr to addl-addressable register | 600 | st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag |
576 | and r9=r9,r29 | 601 | addl r22=IA64_RBS_OFFSET,r2 // A compute base of RBS |
577 | mov r19=b6 // save b6 (2 cyc) | 602 | add r3=TI_FLAGS+IA64_TASK_SIZE,r2 // A |
578 | ;; | 603 | ;; |
579 | mov psr.l=r9 // slam the door (17 cyc to srlz.i) | 604 | ld4 r3=[r3] // M0|1 r3 = current_thread_info()->flags |
580 | or r29=r8,r29 // construct cr.ipsr value to save | 605 | lfetch.fault.excl.nt1 [r22] // M0|1 prefetch register backing-store |
581 | addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS | 606 | nop.i 0 |
582 | ;; | 607 | ;; |
583 | // GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks | 608 | mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 |
584 | // we may be reading ar.itc after writing to psr.l. Avoid that message with | 609 | nop.m 0 |
585 | // this directive: | 610 | nop.i 0 |
586 | dv_serialize_data | ||
587 | mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) | ||
588 | lfetch.fault.excl.nt1 [r22] | ||
589 | adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2 | ||
590 | |||
591 | // ensure previous insn group is issued before we stall for srlz.i: | ||
592 | ;; | 611 | ;; |
593 | srlz.i // ensure new psr.l has been established | 612 | mov r23=ar.bspstore // M2 (12 cyc) save ar.bspstore |
594 | ///////////////////////////////////////////////////////////////////////////// | 613 | mov.m r24=ar.rnat // M2 (5 cyc) read ar.rnat (dual-issues!) |
595 | ////////// from this point on, execution is not interruptible anymore | 614 | nop.i 0 |
596 | ///////////////////////////////////////////////////////////////////////////// | ||
597 | addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack | ||
598 | cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 | ||
599 | ;; | 615 | ;; |
600 | st1 [r16]=r0 // clear current->thread.on_ustack flag | 616 | mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS |
601 | mov ar.bspstore=r22 // switch to kernel RBS | 617 | movl r8=PSR_ONE_BITS // X |
602 | mov b6=r18 // copy syscall entry-point to b6 (7 cyc) | ||
603 | add r3=TI_FLAGS+IA64_TASK_SIZE,r2 | ||
604 | ;; | 618 | ;; |
605 | ld4 r3=[r3] // r2 = current_thread_info()->flags | 619 | mov r25=ar.unat // M2 (5 cyc) save ar.unat |
606 | mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc) | 620 | mov r19=b6 // I0 save b6 (2 cyc) |
607 | mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 | 621 | mov r20=r1 // A save caller's gp in r20 |
608 | br.call.sptk.many b7=ia64_syscall_setup | ||
609 | ;; | 622 | ;; |
610 | ssm psr.i | 623 | or r29=r8,r29 // A construct cr.ipsr value to save |
611 | movl r2=ia64_ret_from_syscall | 624 | mov b6=r18 // I0 copy syscall entry-point to b6 (7 cyc) |
625 | addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack | ||
626 | |||
627 | mov r18=ar.bsp // M2 save (kernel) ar.bsp (12 cyc) | ||
628 | cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1 | ||
629 | br.call.sptk.many b7=ia64_syscall_setup // B | ||
612 | ;; | 630 | ;; |
613 | mov rp=r2 // set the real return addr | 631 | mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 |
614 | tbit.z p8,p0=r3,TIF_SYSCALL_TRACE | 632 | mov rp=r14 // I0 set the real return addr |
633 | and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A | ||
615 | ;; | 634 | ;; |
616 | (p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 | 635 | ssm psr.i // M2 we're on kernel stacks now, reenable irqs |
617 | (p8) br.call.sptk.many b6=b6 // ignore this return addr | 636 | cmp.eq p8,p0=r3,r0 // A |
618 | br.cond.sptk ia64_trace_syscall | 637 | (p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT |
638 | |||
639 | nop.m 0 | ||
640 | (p8) br.call.sptk.many b6=b6 // B (ignore return address) | ||
641 | br.cond.spnt ia64_trace_syscall // B | ||
619 | END(fsys_bubble_down) | 642 | END(fsys_bubble_down) |
620 | 643 | ||
621 | .rodata | 644 | .rodata |
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index facf75acdc85..86948ce63e43 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S | |||
@@ -72,38 +72,40 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) | |||
72 | * bundle get executed. The remaining code must be safe even if | 72 | * bundle get executed. The remaining code must be safe even if |
73 | * they do not get executed. | 73 | * they do not get executed. |
74 | */ | 74 | */ |
75 | adds r17=-1024,r15 | 75 | adds r17=-1024,r15 // A |
76 | mov r10=0 // default to successful syscall execution | 76 | mov r10=0 // A default to successful syscall execution |
77 | epc | 77 | epc // B causes split-issue |
78 | } | 78 | } |
79 | ;; | 79 | ;; |
80 | rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be" | 80 | rsm psr.be | psr.i // M2 (5 cyc to srlz.d) |
81 | LOAD_FSYSCALL_TABLE(r14) | 81 | LOAD_FSYSCALL_TABLE(r14) // X |
82 | |||
83 | mov r16=IA64_KR(CURRENT) // 12 cycle read latency | ||
84 | tnat.nz p10,p9=r15 | ||
85 | mov r19=NR_syscalls-1 | ||
86 | ;; | 82 | ;; |
87 | shladd r18=r17,3,r14 | 83 | mov r16=IA64_KR(CURRENT) // M2 (12 cyc) |
88 | 84 | shladd r18=r17,3,r14 // A | |
89 | srlz.d | 85 | mov r19=NR_syscalls-1 // A |
90 | cmp.ne p8,p0=r0,r0 // p8 <- FALSE | 86 | ;; |
91 | /* Note: if r17 is a NaT, p6 will be set to zero. */ | 87 | lfetch [r18] // M0|1 |
92 | cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? | 88 | mov r29=psr // M2 (12 cyc) |
93 | ;; | 89 | // If r17 is a NaT, p6 will be zero |
94 | (p6) ld8 r18=[r18] | 90 | cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? |
95 | mov r21=ar.fpsr | 91 | ;; |
96 | add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry | 92 | mov r21=ar.fpsr // M2 (12 cyc) |
97 | ;; | 93 | tnat.nz p10,p9=r15 // I0 |
98 | (p6) mov b7=r18 | 94 | mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) |
99 | (p6) tbit.z p8,p0=r18,0 | 95 | ;; |
100 | (p8) br.dptk.many b7 | 96 | srlz.d // M0 (forces split-issue) ensure PSR.BE==0 |
101 | 97 | (p6) ld8 r18=[r18] // M0|1 | |
102 | (p6) rsm psr.i | 98 | nop.i 0 |
103 | mov r27=ar.rsc | 99 | ;; |
104 | mov r26=ar.pfs | 100 | nop.m 0 |
101 | (p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) | ||
102 | nop.i 0 | ||
105 | ;; | 103 | ;; |
106 | mov r29=psr // read psr (12 cyc load latency) | 104 | (p8) ssm psr.i |
105 | (p6) mov b7=r18 // I0 | ||
106 | (p8) br.dptk.many b7 // B | ||
107 | |||
108 | mov r27=ar.rsc // M2 (12 cyc) | ||
107 | /* | 109 | /* |
108 | * brl.cond doesn't work as intended because the linker would convert this branch | 110 | * brl.cond doesn't work as intended because the linker would convert this branch |
109 | * into a branch to a PLT. Perhaps there will be a way to avoid this with some | 111 | * into a branch to a PLT. Perhaps there will be a way to avoid this with some |
@@ -111,6 +113,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) | |||
111 | * instead. | 113 | * instead. |
112 | */ | 114 | */ |
113 | #ifdef CONFIG_ITANIUM | 115 | #ifdef CONFIG_ITANIUM |
116 | (p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry | ||
117 | ;; | ||
114 | (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down | 118 | (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down |
115 | ;; | 119 | ;; |
116 | (p6) mov b7=r14 | 120 | (p6) mov b7=r14 |
@@ -118,7 +122,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) | |||
118 | #else | 122 | #else |
119 | BRL_COND_FSYS_BUBBLE_DOWN(p6) | 123 | BRL_COND_FSYS_BUBBLE_DOWN(p6) |
120 | #endif | 124 | #endif |
121 | 125 | ssm psr.i | |
122 | mov r10=-1 | 126 | mov r10=-1 |
123 | (p10) mov r8=EINVAL | 127 | (p10) mov r8=EINVAL |
124 | (p9) mov r8=ENOSYS | 128 | (p9) mov r8=ENOSYS |
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 7bbf019c9867..01572814abe4 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c | |||
@@ -58,9 +58,6 @@ EXPORT_SYMBOL(__strlen_user); | |||
58 | EXPORT_SYMBOL(__strncpy_from_user); | 58 | EXPORT_SYMBOL(__strncpy_from_user); |
59 | EXPORT_SYMBOL(__strnlen_user); | 59 | EXPORT_SYMBOL(__strnlen_user); |
60 | 60 | ||
61 | #include <asm/unistd.h> | ||
62 | EXPORT_SYMBOL(__ia64_syscall); | ||
63 | |||
64 | /* from arch/ia64/lib */ | 61 | /* from arch/ia64/lib */ |
65 | extern void __divsi3(void); | 62 | extern void __divsi3(void); |
66 | extern void __udivsi3(void); | 63 | extern void __udivsi3(void); |
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index d9c05d53435b..386087edabf2 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/ia64/kernel/ivt.S | 2 | * arch/ia64/kernel/ivt.S |
3 | * | 3 | * |
4 | * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co | 4 | * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co |
5 | * Stephane Eranian <eranian@hpl.hp.com> | 5 | * Stephane Eranian <eranian@hpl.hp.com> |
6 | * David Mosberger <davidm@hpl.hp.com> | 6 | * David Mosberger <davidm@hpl.hp.com> |
7 | * Copyright (C) 2000, 2002-2003 Intel Co | 7 | * Copyright (C) 2000, 2002-2003 Intel Co |
@@ -687,82 +687,118 @@ ENTRY(break_fault) | |||
687 | * to prevent leaking bits from kernel to user level. | 687 | * to prevent leaking bits from kernel to user level. |
688 | */ | 688 | */ |
689 | DBG_FAULT(11) | 689 | DBG_FAULT(11) |
690 | mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat. | 690 | mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) |
691 | mov r17=cr.iim | 691 | mov r29=cr.ipsr // M2 (12 cyc) |
692 | mov r18=__IA64_BREAK_SYSCALL | 692 | mov r31=pr // I0 (2 cyc) |
693 | mov r21=ar.fpsr | 693 | |
694 | mov r29=cr.ipsr | 694 | mov r17=cr.iim // M2 (2 cyc) |
695 | mov r19=b6 | 695 | mov.m r27=ar.rsc // M2 (12 cyc) |
696 | mov r25=ar.unat | 696 | mov r18=__IA64_BREAK_SYSCALL // A |
697 | mov r27=ar.rsc | 697 | |
698 | mov r26=ar.pfs | 698 | mov.m ar.rsc=0 // M2 |
699 | mov r28=cr.iip | 699 | mov.m r21=ar.fpsr // M2 (12 cyc) |
700 | mov r31=pr // prepare to save predicates | 700 | mov r19=b6 // I0 (2 cyc) |
701 | mov r20=r1 | 701 | ;; |
702 | ;; | 702 | mov.m r23=ar.bspstore // M2 (12 cyc) |
703 | mov.m r24=ar.rnat // M2 (5 cyc) | ||
704 | mov.i r26=ar.pfs // I0 (2 cyc) | ||
705 | |||
706 | invala // M0|1 | ||
707 | nop.m 0 // M | ||
708 | mov r20=r1 // A save r1 | ||
709 | |||
710 | nop.m 0 | ||
711 | movl r30=sys_call_table // X | ||
712 | |||
713 | mov r28=cr.iip // M2 (2 cyc) | ||
714 | cmp.eq p0,p7=r18,r17 // I0 is this a system call? | ||
715 | (p7) br.cond.spnt non_syscall // B no -> | ||
716 | // | ||
717 | // From this point on, we are definitely on the syscall-path | ||
718 | // and we can use (non-banked) scratch registers. | ||
719 | // | ||
720 | /////////////////////////////////////////////////////////////////////// | ||
721 | mov r1=r16 // A move task-pointer to "addl"-addressable reg | ||
722 | mov r2=r16 // A setup r2 for ia64_syscall_setup | ||
723 | add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags | ||
724 | |||
703 | adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 | 725 | adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 |
704 | cmp.eq p0,p7=r18,r17 // is this a system call? (p7 <- false, if so) | 726 | adds r15=-1024,r15 // A subtract 1024 from syscall number |
705 | (p7) br.cond.spnt non_syscall | 727 | mov r3=NR_syscalls - 1 |
706 | ;; | 728 | ;; |
707 | ld1 r17=[r16] // load current->thread.on_ustack flag | 729 | ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag |
708 | st1 [r16]=r0 // clear current->thread.on_ustack flag | 730 | ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags |
709 | add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // set r1 for MINSTATE_START_SAVE_MIN_VIRT | 731 | extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr |
732 | |||
733 | shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) | ||
734 | addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS | ||
735 | cmp.leu p6,p7=r15,r3 // A syscall number in range? | ||
710 | ;; | 736 | ;; |
711 | invala | ||
712 | 737 | ||
713 | /* adjust return address so we skip over the break instruction: */ | 738 | lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS |
739 | (p6) ld8 r30=[r30] // M0|1 load address of syscall entry point | ||
740 | tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? | ||
714 | 741 | ||
715 | extr.u r8=r29,41,2 // extract ei field from cr.ipsr | 742 | mov.m ar.bspstore=r22 // M2 switch to kernel RBS |
716 | ;; | 743 | cmp.eq p8,p9=2,r8 // A isr.ei==2? |
717 | cmp.eq p6,p7=2,r8 // isr.ei==2? | ||
718 | mov r2=r1 // setup r2 for ia64_syscall_setup | ||
719 | ;; | ||
720 | (p6) mov r8=0 // clear ei to 0 | ||
721 | (p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped | ||
722 | (p7) adds r8=1,r8 // increment ei to next slot | ||
723 | ;; | ||
724 | cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already? | ||
725 | dep r29=r8,r29,41,2 // insert new ei into cr.ipsr | ||
726 | ;; | 744 | ;; |
727 | 745 | ||
728 | // switch from user to kernel RBS: | 746 | (p8) mov r8=0 // A clear ei to 0 |
729 | MINSTATE_START_SAVE_MIN_VIRT | 747 | (p7) movl r30=sys_ni_syscall // X |
730 | br.call.sptk.many b7=ia64_syscall_setup | ||
731 | ;; | ||
732 | MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1 | ||
733 | ssm psr.ic | PSR_DEFAULT_BITS | ||
734 | ;; | ||
735 | srlz.i // guarantee that interruption collection is on | ||
736 | mov r3=NR_syscalls - 1 | ||
737 | ;; | ||
738 | (p15) ssm psr.i // restore psr.i | ||
739 | // p10==true means out registers are more than 8 or r15's Nat is true | ||
740 | (p10) br.cond.spnt.many ia64_ret_from_syscall | ||
741 | ;; | ||
742 | movl r16=sys_call_table | ||
743 | 748 | ||
744 | adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 | 749 | (p8) adds r28=16,r28 // A switch cr.iip to next bundle |
745 | movl r2=ia64_ret_from_syscall | 750 | (p9) adds r8=1,r8 // A increment ei to next slot |
746 | ;; | 751 | nop.i 0 |
747 | shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) | ||
748 | cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ? | ||
749 | mov rp=r2 // set the real return addr | ||
750 | ;; | 752 | ;; |
751 | (p6) ld8 r20=[r20] // load address of syscall entry point | ||
752 | (p7) movl r20=sys_ni_syscall | ||
753 | 753 | ||
754 | add r2=TI_FLAGS+IA64_TASK_SIZE,r13 | 754 | mov.m r25=ar.unat // M2 (5 cyc) |
755 | ;; | 755 | dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr |
756 | ld4 r2=[r2] // r2 = current_thread_info()->flags | 756 | adds r15=1024,r15 // A restore original syscall number |
757 | ;; | 757 | // |
758 | and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit | 758 | // If any of the above loads miss in L1D, we'll stall here until |
759 | // the data arrives. | ||
760 | // | ||
761 | /////////////////////////////////////////////////////////////////////// | ||
762 | st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag | ||
763 | mov b6=r30 // I0 setup syscall handler branch reg early | ||
764 | cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? | ||
765 | |||
766 | and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit | ||
767 | mov r18=ar.bsp // M2 (12 cyc) | ||
768 | (pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS | ||
769 | ;; | ||
770 | .back_from_break_fixup: | ||
771 | (pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack | ||
772 | cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? | ||
773 | br.call.sptk.many b7=ia64_syscall_setup // B | ||
774 | 1: | ||
775 | mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 | ||
776 | nop 0 | ||
777 | bsw.1 // B (6 cyc) regs are saved, switch to bank 1 | ||
759 | ;; | 778 | ;; |
760 | cmp.eq p8,p0=r2,r0 | 779 | |
761 | mov b6=r20 | 780 | ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection |
781 | movl r3=ia64_ret_from_syscall // X | ||
762 | ;; | 782 | ;; |
763 | (p8) br.call.sptk.many b6=b6 // ignore this return addr | 783 | |
764 | br.cond.sptk ia64_trace_syscall | 784 | srlz.i // M0 ensure interruption collection is on |
785 | mov rp=r3 // I0 set the real return addr | ||
786 | (p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT | ||
787 | |||
788 | (p15) ssm psr.i // M2 restore psr.i | ||
789 | (p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) | ||
790 | br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic | ||
765 | // NOT REACHED | 791 | // NOT REACHED |
792 | /////////////////////////////////////////////////////////////////////// | ||
793 | // On entry, we optimistically assumed that we're coming from user-space. | ||
794 | // For the rare cases where a system-call is done from within the kernel, | ||
795 | // we fix things up at this point: | ||
796 | .break_fixup: | ||
797 | add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure | ||
798 | mov ar.rnat=r24 // M2 restore kernel's AR.RNAT | ||
799 | ;; | ||
800 | mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE | ||
801 | br.cond.sptk .back_from_break_fixup | ||
766 | END(break_fault) | 802 | END(break_fault) |
767 | 803 | ||
768 | .org ia64_ivt+0x3000 | 804 | .org ia64_ivt+0x3000 |
@@ -837,8 +873,6 @@ END(interrupt) | |||
837 | * - r31: saved pr | 873 | * - r31: saved pr |
838 | * - b0: original contents (to be saved) | 874 | * - b0: original contents (to be saved) |
839 | * On exit: | 875 | * On exit: |
840 | * - executing on bank 1 registers | ||
841 | * - psr.ic enabled, interrupts restored | ||
842 | * - p10: TRUE if syscall is invoked with more than 8 out | 876 | * - p10: TRUE if syscall is invoked with more than 8 out |
843 | * registers or r15's Nat is true | 877 | * registers or r15's Nat is true |
844 | * - r1: kernel's gp | 878 | * - r1: kernel's gp |
@@ -846,8 +880,11 @@ END(interrupt) | |||
846 | * - r8: -EINVAL if p10 is true | 880 | * - r8: -EINVAL if p10 is true |
847 | * - r12: points to kernel stack | 881 | * - r12: points to kernel stack |
848 | * - r13: points to current task | 882 | * - r13: points to current task |
883 | * - r14: preserved (same as on entry) | ||
884 | * - p13: preserved | ||
849 | * - p15: TRUE if interrupts need to be re-enabled | 885 | * - p15: TRUE if interrupts need to be re-enabled |
850 | * - ar.fpsr: set to kernel settings | 886 | * - ar.fpsr: set to kernel settings |
887 | * - b6: preserved (same as on entry) | ||
851 | */ | 888 | */ |
852 | GLOBAL_ENTRY(ia64_syscall_setup) | 889 | GLOBAL_ENTRY(ia64_syscall_setup) |
853 | #if PT(B6) != 0 | 890 | #if PT(B6) != 0 |
@@ -915,10 +952,10 @@ GLOBAL_ENTRY(ia64_syscall_setup) | |||
915 | (p13) mov in5=-1 | 952 | (p13) mov in5=-1 |
916 | ;; | 953 | ;; |
917 | st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr | 954 | st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr |
918 | tnat.nz p14,p0=in6 | 955 | tnat.nz p13,p0=in6 |
919 | cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 | 956 | cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 |
920 | ;; | 957 | ;; |
921 | stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) | 958 | mov r8=1 |
922 | (p9) tnat.nz p10,p0=r15 | 959 | (p9) tnat.nz p10,p0=r15 |
923 | adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) | 960 | adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) |
924 | 961 | ||
@@ -929,9 +966,9 @@ GLOBAL_ENTRY(ia64_syscall_setup) | |||
929 | mov r13=r2 // establish `current' | 966 | mov r13=r2 // establish `current' |
930 | movl r1=__gp // establish kernel global pointer | 967 | movl r1=__gp // establish kernel global pointer |
931 | ;; | 968 | ;; |
932 | (p14) mov in6=-1 | 969 | st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) |
970 | (p13) mov in6=-1 | ||
933 | (p8) mov in7=-1 | 971 | (p8) mov in7=-1 |
934 | nop.i 0 | ||
935 | 972 | ||
936 | cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 | 973 | cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 |
937 | movl r17=FPSR_DEFAULT | 974 | movl r17=FPSR_DEFAULT |
@@ -1002,6 +1039,8 @@ END(dispatch_illegal_op_fault) | |||
1002 | FAULT(17) | 1039 | FAULT(17) |
1003 | 1040 | ||
1004 | ENTRY(non_syscall) | 1041 | ENTRY(non_syscall) |
1042 | mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER | ||
1043 | ;; | ||
1005 | SAVE_MIN_WITH_COVER | 1044 | SAVE_MIN_WITH_COVER |
1006 | 1045 | ||
1007 | // There is no particular reason for this code to be here, other than that | 1046 | // There is no particular reason for this code to be here, other than that |