⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ia32_signal.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* setting bits 0..31 with sw and tag and 32..37 from mxcsr */	__get_user(lo, (unsigned int *)&save->sw);	/* set bits 15,7 (fsw.b, fsw.es) to reflect the current error status */	if ( !(lo & 0x7f) )		lo &= (~0x8080);	__get_user(hi, (unsigned int *)&save->tag);	num64 = mxcsr & 0x3f;	num64 = (num64 << 16) | (hi & 0xffff);	num64 = (num64 << 16) | (lo & 0xffff);	fsr = (fsr & (~0x3fffffffff)) | num64;	/* setting bits 0..47 with cssel and ipoff */	__get_user(lo, (unsigned int *)&save->ipoff);	__get_user(hi, (unsigned int *)&save->cssel);	num64 = hi & 0xffff;	num64 = (num64 << 32) | lo;	fir = (fir & (~0xffffffffffff)) | num64;	/* setting bits 0..47 with datasel and dataoff */	__get_user(lo, (unsigned int *)&save->dataoff);	__get_user(hi, (unsigned int *)&save->datasel);	num64 = hi & 0xffff;	num64 = (num64 << 32) | lo;	fdr = (fdr & (~0xffffffffffff)) | num64;	asm volatile ( "mov ar.fsr=%0;" :: "r"(fsr));	asm volatile ( "mov ar.fcr=%0;" :: "r"(fcr));	asm volatile ( "mov ar.fir=%0;" :: "r"(fir));	asm volatile ( "mov ar.fdr=%0;" :: "r"(fdr));	/*	 * restore f8..f11 onto pt_regs	 * restore f12..f15 onto live registers	 */	/*	 *  Find the location where f8 has to go in fp reg stack.  This depends on	 *  TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps	 *  to.	 */	fp_tos = (fsr>>11)&0x7;	fr8_st_map = (8-fp_tos)&0x7;	fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);	ptp = ia64_task_regs(tsk);	copy_from_user(fpregp, &save->_st[(0+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	ia32f2ia64f(&ptp->f8, fpregp);	copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	ia32f2ia64f(&ptp->f9, fpregp);	copy_from_user(fpregp, &save->_st[(2+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	ia32f2ia64f(&ptp->f10, fpregp);	copy_from_user(fpregp, &save->_st[(3+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	ia32f2ia64f(&ptp->f11, fpregp);	copy_from_user(fpregp, &save->_st[(4+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	__ldfe(12, fpregp);	copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	__ldfe(13, fpregp);	copy_from_user(fpregp, &save->_st[(6+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	__ldfe(14, fpregp);	copy_from_user(fpregp, &save->_st[(7+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	__ldfe(15, fpregp);	copy_from_user(num128, &save->_xmm[0], sizeof(struct _xmmreg_ia32));	__ldf8(16, &num128[0]);	__ldf8(17, &num128[1]);	copy_from_user(num128, &save->_xmm[1], sizeof(struct _xmmreg_ia32));	__ldf8(18, &num128[0]);	__ldf8(19, &num128[1]);	copy_from_user(num128, &save->_xmm[2], sizeof(struct _xmmreg_ia32));	__ldf8(20, &num128[0]);	__ldf8(21, &num128[1]);	copy_from_user(num128, &save->_xmm[3], sizeof(struct _xmmreg_ia32));	__ldf8(22, &num128[0]);	__ldf8(23, &num128[1]);	copy_from_user(num128, &save->_xmm[4], sizeof(struct _xmmreg_ia32));	__ldf8(24, &num128[0]);	__ldf8(25, &num128[1]);	copy_from_user(num128, &save->_xmm[5], sizeof(struct _xmmreg_ia32));	__ldf8(26, &num128[0]);	__ldf8(27, &num128[1]);	copy_from_user(num128, &save->_xmm[6], sizeof(struct _xmmreg_ia32));	__ldf8(28, &num128[0]);	__ldf8(29, &num128[1]);	copy_from_user(num128, &save->_xmm[7], sizeof(struct _xmmreg_ia32));	__ldf8(30, &num128[0]);	__ldf8(31, &num128[1]);	return 0;}static inline voidsigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int restorer){	if (handler + 1 <= 2)		/* SIG_DFL, SIG_IGN, or SIG_ERR: must sign-extend to 64-bits */		sa->sa.sa_handler = (__sighandler_t) A((int) handler);	else		sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler);}asmlinkage longia32_rt_sigsuspend (sigset32_t *uset, unsigned int sigsetsize, struct sigscratch *scr){	extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);	sigset_t oldset, set;	scr->scratch_unat = 0;	/* avoid leaking kernel bits to user level */	memset(&set, 0, sizeof(&set));	if (sigsetsize > sizeof(sigset_t))		return -EINVAL;	if (copy_from_user(&set.sig, &uset->sig, sigsetsize))		return -EFAULT;	sigdelsetmask(&set, ~_BLOCKABLE);	spin_lock_irq(&current->sigmask_lock);	{		oldset = current->blocked;		current->blocked = set;		recalc_sigpending(current);	}	spin_unlock_irq(&current->sigmask_lock);	/*	 * The return below usually returns to the signal handler.  We need to pre-set the	 * correct error code here to ensure that the right values get saved in sigcontext	 * by ia64_do_signal.	 */	scr->pt.r8 = -EINTR;	while (1) {		current->state = TASK_INTERRUPTIBLE;		schedule();		if (ia64_do_signal(&oldset, scr, 1))			return -EINTR;	}}asmlinkage longia32_sigsuspend (unsigned int mask, struct sigscratch *scr){	return ia32_rt_sigsuspend((sigset32_t *)&mask, sizeof(mask), scr);}asmlinkage longsys32_signal (int sig, unsigned int handler){	struct k_sigaction new_sa, old_sa;	int ret;	sigact_set_handler(&new_sa, handler, 0);	new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;	ret = do_sigaction(sig, &new_sa, &old_sa);	return ret ? ret : IA32_SA_HANDLER(&old_sa);}asmlinkage longsys32_rt_sigaction (int sig, struct sigaction32 *act,		    struct sigaction32 *oact, unsigned int sigsetsize){	struct k_sigaction new_ka, old_ka;	unsigned int handler, restorer;	int ret;	/* XXX: Don't preclude handling different sized sigset_t's.  */	if (sigsetsize != sizeof(sigset32_t))		return -EINVAL;	if (act) {		ret = get_user(handler, &act->sa_handler);		ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);		ret |= get_user(restorer, &act->sa_restorer);		ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(sigset32_t));		if (ret)			return -EFAULT;		sigact_set_handler(&new_ka, handler, restorer);	}	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);	if (!ret && oact) {		ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);		ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);		ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);		ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(sigset32_t));	}	return ret;}extern asmlinkage long sys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset,					   size_t sigsetsize);asmlinkage longsys32_rt_sigprocmask (int how, sigset32_t *set, sigset32_t *oset, unsigned int sigsetsize){	mm_segment_t old_fs = get_fs();	sigset_t s;	long ret;	if (sigsetsize > sizeof(s))		return -EINVAL;	if (set) {		memset(&s, 0, sizeof(s));		if (copy_from_user(&s.sig, set, sigsetsize))			return -EFAULT;	}	set_fs(KERNEL_DS);	ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sizeof(s));	set_fs(old_fs);	if (ret)		return ret;	if (oset) {		if (copy_to_user(oset, &s.sig, sigsetsize))			return -EFAULT;	}	return 0;}asmlinkage longsys32_sigprocmask (int how, unsigned int *set, unsigned int *oset){	return sys32_rt_sigprocmask(how, (sigset32_t *) set, (sigset32_t *) oset, sizeof(*set));}asmlinkage longsys32_rt_sigtimedwait (sigset32_t *uthese, siginfo_t32 *uinfo, struct timespec32 *uts,		       unsigned int sigsetsize){	extern asmlinkage long sys_rt_sigtimedwait (const sigset_t *, siginfo_t *,						    const struct timespec *, size_t);	extern int copy_siginfo_to_user32 (siginfo_t32 *, siginfo_t *);	mm_segment_t old_fs = get_fs();	struct timespec t;	siginfo_t info;	sigset_t s;	int ret;	if (copy_from_user(&s.sig, uthese, sizeof(sigset32_t)))		return -EFAULT;	if (uts) {		ret = get_user(t.tv_sec, &uts->tv_sec);		ret |= get_user(t.tv_nsec, &uts->tv_nsec);		if (ret)			return -EFAULT;	}	set_fs(KERNEL_DS);	ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL, sigsetsize);	set_fs(old_fs);	if (ret >= 0 && uinfo) {		if (copy_siginfo_to_user32(uinfo, &info))			return -EFAULT;	}	return ret;}asmlinkage longsys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 *uinfo){	extern asmlinkage long sys_rt_sigqueueinfo (int, int, siginfo_t *);	extern int copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from);	mm_segment_t old_fs = get_fs();	siginfo_t info;	int ret;	if (copy_siginfo_from_user32(&info, uinfo))		return -EFAULT;	set_fs(KERNEL_DS);	ret = sys_rt_sigqueueinfo(pid, sig, &info);	set_fs(old_fs);	return ret;}asmlinkage longsys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact){	struct k_sigaction new_ka, old_ka;	unsigned int handler, restorer;	int ret;	if (act) {		old_sigset32_t mask;		ret = get_user(handler, &act->sa_handler);		ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);		ret |= get_user(restorer, &act->sa_restorer);		ret |= get_user(mask, &act->sa_mask);		if (ret)			return ret;		sigact_set_handler(&new_ka, handler, restorer);		siginitset(&new_ka.sa.sa_mask, mask);	}	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);	if (!ret && oact) {		ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);		ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);		ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);		ret |= put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);	}	return ret;}static intsetup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,		       struct pt_regs *regs, unsigned long mask){	int  err = 0;	unsigned long flag;	if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc)))		return -EFAULT;	err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int *)&sc->fs);	err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int *)&sc->gs);	err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int *)&sc->es);	err |= __put_user(regs->r16 & 0xffff, (unsigned int *)&sc->ds);	err |= __put_user(regs->r15, &sc->edi);	err |= __put_user(regs->r14, &sc->esi);	err |= __put_user(regs->r13, &sc->ebp);	err |= __put_user(regs->r12, &sc->esp);	err |= __put_user(regs->r11, &sc->ebx);	err |= __put_user(regs->r10, &sc->edx);	err |= __put_user(regs->r9, &sc->ecx);	err |= __put_user(regs->r8, &sc->eax);#if 0	err |= __put_user(current->tss.trap_no, &sc->trapno);	err |= __put_user(current->tss.error_code, &sc->err);#endif	err |= __put_user(regs->cr_iip, &sc->eip);	err |= __put_user(regs->r17 & 0xffff, (unsigned int *)&sc->cs);	/*	 *  `eflags' is in an ar register for this context	 */	asm volatile ("mov %0=ar.eflag ;;" : "=r"(flag));	err |= __put_user((unsigned int)flag, &sc->eflags);	err |= __put_user(regs->r12, &sc->esp_at_signal);	err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int *)&sc->ss);	if ( save_ia32_fpstate_live(fpstate) < 0 )		err = -EFAULT;	else		err |= __put_user((u32)(u64)fpstate, &sc->fpstate);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -