hello,everybody! i have a question in mips kernel, can anybody help me ??
in scall_o32.s, syscall procedure is as follows:
NESTED(handle_sys, PT_SIZE, sp)
.set noat
SAVE_SOME
STI
.set at

lw t1, PT_EPC(sp) # skip syscall on return

sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
addiu t1, 4 # skip to next instruction
beqz t0, illegal_syscall
sw t1, PT_EPC(sp)

/* XXX Put both in one cacheline, should save a bit. */
sll t0, v0, 2
lw t2, sys_call_table(t0) # syscall routine
lbu t3, sys_narg_table(v0) # number of arguments
beqz t2, illegal_syscall;

subu t0, t3, 5 # 5 or more arguments?
sw a3, PT_R26(sp) # save a3 for syscall restarting
bgez t0, stackargs

stack_done:
sw a3, PT_R26(sp) # save for syscall restart
lw t0, TASK_PTRACE($2 # syscall tracing enabled?
andi t0, PT_TRACESYS
bnez t0, trace_a_syscall

jalr t2 # Do The Real Thing (TM)

li t0, -EMAXERRNO - 1 # error?
sltu t0, t0, v0
sw t0, PT_R7(sp) # set error flag
beqz t0, 1f

negu v0 # error
sw v0, PT_R0(sp) # set flag for syscall restarting
1: sw v0, PT_R2(sp) # result

EXPORT(o32_ret_from_sys_call)
mfc0 t0, CP0_STATUS # need_resched and signals atomic test
ori t0, t0, 1
xori t0, t0, 1
mtc0 t0, CP0_STATUS

lw t2, TASK_NEED_RESCHED($2
bnez t2, o32_reschedule
lw v0, TASK_SIGPENDING($2
bnez v0, signal_return
restore_all:
RESTORE_SOME
RESTORE_SP_AND_RET

it use SAVE_SOME to save some registers,not save s* registers. but in sys_sigreturn function, last jump to the ret_from_sys_call in entry.s:
asmlinkage void
sys_sigreturn(struct pt_regs regs)
{
struct sigframe *frame;
sigset_t blocked;

frame = (struct sigframe *) regs.regs[29];
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
goto badframe;

sigdelsetmask(&blocked, ~_BLOCKABLE);
spin_lock_irq(&current->sigmask_lock);
current->blocked = blocked;
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);

if (restore_sigcontext(&regs, &frame->sf_sc))
goto badframe;

/*
* Don't let your children do this ...
*/
if (current->ptrace & PT_TRACESYS)
syscall_trace();
__asm__ __volatile__(
"move\t$29, %0\n\t"
"j\tret_from_sys_call"
:/* no outputs */
:"r" (&regs));
/* Unreached */

badframe:
force_sig(SIGSEGV, current);
}

ret_from_sys_call in entry.s use RESTORE_ALL_AND_RET to restore all registers, so SAVE_SOME and RESTORE_ALL_AND_RET are not match, is this a kernel bug?? can anyone help me, thanks!