Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ia64/pv_ops: move down __kernel_syscall_via_epc.

Move down __kernel_syscall_via_epc to the end of the page.
We want to paravirtualize only __kernel_syscall_via_epc because
it includes privileged instructions. Its paravirtualization increases
its symbols size.

On the other hand, each paravirtualized gate must have e symbols of
same value and size to native's because the page is mapped to GATE_ADDR
and GATE_ADDR + PERCPU_PAGE_SIZE and vmlinux is linked to those symbols.
Later to have the same symbol size, we pads NOPs at the end of
__kernel_syscall_via_epc. Move it after other functions to keep
symbols of other functions have same values and sizes.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Tony Luck <tony.luck@intel.com>

authored by

Isaku Yamahata and committed by
Tony Luck
53129c5c b937dd76

+81 -81
+81 -81
arch/ia64/kernel/gate.S
··· 48 48 } 49 49 END(__kernel_syscall_via_break) 50 50 51 - /* 52 - * On entry: 53 - * r11 = saved ar.pfs 54 - * r15 = system call # 55 - * b0 = saved return address 56 - * b6 = return address 57 - * On exit: 58 - * r11 = saved ar.pfs 59 - * r15 = system call # 60 - * b0 = saved return address 61 - * all other "scratch" registers: undefined 62 - * all "preserved" registers: same as on entry 63 - */ 64 - 65 - GLOBAL_ENTRY(__kernel_syscall_via_epc) 66 - .prologue 67 - .altrp b6 68 - .body 69 - { 70 - /* 71 - * Note: the kernel cannot assume that the first two instructions in this 72 - * bundle get executed. The remaining code must be safe even if 73 - * they do not get executed. 74 - */ 75 - adds r17=-1024,r15 // A 76 - mov r10=0 // A default to successful syscall execution 77 - epc // B causes split-issue 78 - } 79 - ;; 80 - rsm psr.be | psr.i // M2 (5 cyc to srlz.d) 81 - LOAD_FSYSCALL_TABLE(r14) // X 82 - ;; 83 - mov r16=IA64_KR(CURRENT) // M2 (12 cyc) 84 - shladd r18=r17,3,r14 // A 85 - mov r19=NR_syscalls-1 // A 86 - ;; 87 - lfetch [r18] // M0|1 88 - mov r29=psr // M2 (12 cyc) 89 - // If r17 is a NaT, p6 will be zero 90 - cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? 91 - ;; 92 - mov r21=ar.fpsr // M2 (12 cyc) 93 - tnat.nz p10,p9=r15 // I0 94 - mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) 95 - ;; 96 - srlz.d // M0 (forces split-issue) ensure PSR.BE==0 97 - (p6) ld8 r18=[r18] // M0|1 98 - nop.i 0 99 - ;; 100 - nop.m 0 101 - (p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) 102 - nop.i 0 103 - ;; 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) 109 - /* 110 - * brl.cond doesn't work as intended because the linker would convert this branch 111 - * into a branch to a PLT. Perhaps there will be a way to avoid this with some 112 - * future version of the linker. In the meantime, we just use an indirect branch 113 - * instead. 114 - */ 115 - #ifdef CONFIG_ITANIUM 116 - (p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry 117 - ;; 118 - (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down 119 - ;; 120 - (p6) mov b7=r14 121 - (p6) br.sptk.many b7 122 - #else 123 - BRL_COND_FSYS_BUBBLE_DOWN(p6) 124 - #endif 125 - ssm psr.i 126 - mov r10=-1 127 - (p10) mov r8=EINVAL 128 - (p9) mov r8=ENOSYS 129 - FSYS_RETURN 130 - END(__kernel_syscall_via_epc) 131 - 132 51 # define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET) 133 52 # define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET) 134 53 # define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET) ··· 293 374 // invala not necessary as that will happen when returning to user-mode 294 375 br.cond.sptk back_from_restore_rbs 295 376 END(__kernel_sigtramp) 377 + 378 + /* 379 + * On entry: 380 + * r11 = saved ar.pfs 381 + * r15 = system call # 382 + * b0 = saved return address 383 + * b6 = return address 384 + * On exit: 385 + * r11 = saved ar.pfs 386 + * r15 = system call # 387 + * b0 = saved return address 388 + * all other "scratch" registers: undefined 389 + * all "preserved" registers: same as on entry 390 + */ 391 + 392 + GLOBAL_ENTRY(__kernel_syscall_via_epc) 393 + .prologue 394 + .altrp b6 395 + .body 396 + { 397 + /* 398 + * Note: the kernel cannot assume that the first two instructions in this 399 + * bundle get executed. The remaining code must be safe even if 400 + * they do not get executed. 401 + */ 402 + adds r17=-1024,r15 // A 403 + mov r10=0 // A default to successful syscall execution 404 + epc // B causes split-issue 405 + } 406 + ;; 407 + rsm psr.be | psr.i // M2 (5 cyc to srlz.d) 408 + LOAD_FSYSCALL_TABLE(r14) // X 409 + ;; 410 + mov r16=IA64_KR(CURRENT) // M2 (12 cyc) 411 + shladd r18=r17,3,r14 // A 412 + mov r19=NR_syscalls-1 // A 413 + ;; 414 + lfetch [r18] // M0|1 415 + mov r29=psr // M2 (12 cyc) 416 + // If r17 is a NaT, p6 will be zero 417 + cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? 418 + ;; 419 + mov r21=ar.fpsr // M2 (12 cyc) 420 + tnat.nz p10,p9=r15 // I0 421 + mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) 422 + ;; 423 + srlz.d // M0 (forces split-issue) ensure PSR.BE==0 424 + (p6) ld8 r18=[r18] // M0|1 425 + nop.i 0 426 + ;; 427 + nop.m 0 428 + (p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) 429 + nop.i 0 430 + ;; 431 + (p8) ssm psr.i 432 + (p6) mov b7=r18 // I0 433 + (p8) br.dptk.many b7 // B 434 + 435 + mov r27=ar.rsc // M2 (12 cyc) 436 + /* 437 + * brl.cond doesn't work as intended because the linker would convert this branch 438 + * into a branch to a PLT. Perhaps there will be a way to avoid this with some 439 + * future version of the linker. In the meantime, we just use an indirect branch 440 + * instead. 441 + */ 442 + #ifdef CONFIG_ITANIUM 443 + (p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry 444 + ;; 445 + (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down 446 + ;; 447 + (p6) mov b7=r14 448 + (p6) br.sptk.many b7 449 + #else 450 + BRL_COND_FSYS_BUBBLE_DOWN(p6) 451 + #endif 452 + ssm psr.i 453 + mov r10=-1 454 + (p10) mov r8=EINVAL 455 + (p9) mov r8=ENOSYS 456 + FSYS_RETURN 457 + END(__kernel_syscall_via_epc)