From 9b68bba374f9c87adcc04d5b35daa9a0aa5af806 Mon Sep 17 00:00:00 2001 From: Rob Gardner Date: Sun, 27 Mar 2016 16:39:13 -0600 Subject: [PATCH] sparc64: Add lightweight syscall mechanism for lwp_info This patch introduces a new "light weight" system call mechanism which has the ability to retrieve small bits of information and/or perform minor computations without the need for a full blown save/switch/restore context. Solaris provides _lwp_info(), which returns basically the same information as getrusage(RUSAGE_THREAD) but much faster. This is used extensively by the database code, and returns the utime and stime for the calling thread. (This patch also provides a fast getcpu function just as a demonstration of how additional calls might be added. Unlike x86, there is no unprivileged instruction to do this, and so it is a fairly expensive system call.) Orabug: 22952506 Signed-off-by: Rob Gardner --- arch/sparc/kernel/asm-offsets.c | 4 +++ arch/sparc/kernel/head_64.S | 1 + arch/sparc/kernel/lw_syscall.S | 60 +++++++++++++++++++++++++++++++++ arch/sparc/kernel/ttable_64.S | 2 +- 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 arch/sparc/kernel/lw_syscall.S diff --git a/arch/sparc/kernel/asm-offsets.c b/arch/sparc/kernel/asm-offsets.c index f76389a32342..58bfb5b0a162 100644 --- a/arch/sparc/kernel/asm-offsets.c +++ b/arch/sparc/kernel/asm-offsets.c @@ -51,6 +51,10 @@ int foo(void) DEFINE(AOFF_mm_context, offsetof(struct mm_struct, context)); BLANK(); DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); + BLANK(); + DEFINE(AOFF_task_utime, offsetof(struct task_struct, utime)); + DEFINE(AOFF_task_stime, offsetof(struct task_struct, stime)); + DEFINE(ASM_HZ, HZ); /* DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); */ return 0; diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index cfc590ee1bd7..664ba687deb5 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -926,6 +926,7 @@ swapper_4m_tsb: * you'll have an unbootable kernel. */ #include "ttable_64.S" +#include "lw_syscall.S" ! 0x0000000000428000 diff --git a/arch/sparc/kernel/lw_syscall.S b/arch/sparc/kernel/lw_syscall.S new file mode 100644 index 000000000000..bdf70acd0394 --- /dev/null +++ b/arch/sparc/kernel/lw_syscall.S @@ -0,0 +1,60 @@ +/* + * light weight syscall handler, invoked from trap table + */ + +/* +The "lightweight" syscall mechanism is very simple: + - parameters (if any) are passed as normal in the input + registers, with %i0 containing the index of the requested + function + - return values are also in the input registers: + %i0 = 0 for success otherwise -errno + %i1, %i2, %i3 are function return values + +Other things to note about the environment in which these +calls are executed, and resulting constraints: + 1. Primary context is the user's, not kernel. You probably + should not touch any user memory, but if you must, + then use ASI_AIUP and be aware that a fault may + kill the system. + 2. The stack pointer points to user memory. So don't + use the stack, and don't change the stack pointer + or frame pointer. + 3. All the windowed registers belong to the user, so + be very careful what you mess with. For example, + %i7 is the caller's return pointer. + 4. You can't make any (conventional) procedure calls, + since a save instruction could cause a spill trap. + 5. Interrupts are off until you get to 'done'. Be aware! + 6. Be sure you know what you're doing before using or + modifying this +*/ + +#include +#define LW_SYS_GETCPU 0 +#define LW_SYS_LWP_INFO 1 +#define LW_SYS_MAX 2 + +lw_syscall: + cmp %i0, LW_SYS_GETCPU + be,pn %xcc, lw_sys_getcpu + nop + cmp %i0, LW_SYS_LWP_INFO + be,pt %xcc, lw_sys_lwp_info + mov -EINVAL, %i0 + done + +lw_sys_getcpu: + __GET_CPUID(%i1) + mov %g0, %i0 + done + nop + +lw_sys_lwp_info: + TRAP_LOAD_THREAD_REG(%g6, %g1) + ldx [%g6 + TI_TASK], %g4 + ldx [%g4 + AOFF_task_utime], %i1 + ldx [%g4 + AOFF_task_stime], %i2 + mov ASM_HZ, %i3 + mov %g0, %i0 + done diff --git a/arch/sparc/kernel/ttable_64.S b/arch/sparc/kernel/ttable_64.S index c6dfdaa29e20..c735a5d36abd 100644 --- a/arch/sparc/kernel/ttable_64.S +++ b/arch/sparc/kernel/ttable_64.S @@ -147,7 +147,7 @@ tl0_resv11e: TRAP_UTRAP(UT_TRAP_INSTRUCTION_30,0x11e) TRAP_UTRAP(UT_TRAP_INSTRUC tl0_getcc: GETCC_TRAP tl0_setcc: SETCC_TRAP tl0_getpsr: TRAP(do_getpsr) -tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) BTRAP(0x127) +tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) TRAP_NOSAVE(lw_syscall) tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c) tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131) tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136) -- 2.50.1