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

📄 ia32_signal.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	fcr = (fcr & (~0xff1000001f3fUL)) | num64;	/* setting bits 0..31 with sw and tag and 32..37 from mxcsr */	__get_user(lo, (unsigned int __user *)&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 __user *)&save->tag);	num64 = mxcsr & 0x3f;	num64 = (num64 << 16) | (hi & 0xffff);	num64 = (num64 << 16) | (lo & 0xffff);	fsr = (fsr & (~0x3fffffffffUL)) | num64;	/* setting bits 0..47 with cssel and ipoff */	__get_user(lo, (unsigned int __user *)&save->ipoff);	__get_user(hi, (unsigned int __user *)&save->cssel);	num64 = hi & 0xffff;	num64 = (num64 << 32) | lo;	fir = (fir & (~0xffffffffffffUL)) | num64;	/* setting bits 0..47 with datasel and dataoff */	__get_user(lo, (unsigned int __user *)&save->dataoff);	__get_user(hi, (unsigned int __user *)&save->datasel);	num64 = hi & 0xffff;	num64 = (num64 << 32) | lo;	fdr = (fdr & (~0xffffffffffffUL)) | num64;	ia64_setreg(_IA64_REG_AR_FSR, fsr);	ia64_setreg(_IA64_REG_AR_FCR, fcr);	ia64_setreg(_IA64_REG_AR_FIR, fir);	ia64_setreg(_IA64_REG_AR_FDR, 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));	ia64_ldfe(12, fpregp);	copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	ia64_ldfe(13, fpregp);	copy_from_user(fpregp, &save->_st[(6+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	ia64_ldfe(14, fpregp);	copy_from_user(fpregp, &save->_st[(7+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));	ia64_ldfe(15, fpregp);	copy_from_user(num128, &save->_xmm[0], sizeof(struct _xmmreg_ia32));	ia64_ldf8(16, &num128[0]);	ia64_ldf8(17, &num128[1]);	copy_from_user(num128, &save->_xmm[1], sizeof(struct _xmmreg_ia32));	ia64_ldf8(18, &num128[0]);	ia64_ldf8(19, &num128[1]);	copy_from_user(num128, &save->_xmm[2], sizeof(struct _xmmreg_ia32));	ia64_ldf8(20, &num128[0]);	ia64_ldf8(21, &num128[1]);	copy_from_user(num128, &save->_xmm[3], sizeof(struct _xmmreg_ia32));	ia64_ldf8(22, &num128[0]);	ia64_ldf8(23, &num128[1]);	copy_from_user(num128, &save->_xmm[4], sizeof(struct _xmmreg_ia32));	ia64_ldf8(24, &num128[0]);	ia64_ldf8(25, &num128[1]);	copy_from_user(num128, &save->_xmm[5], sizeof(struct _xmmreg_ia32));	ia64_ldf8(26, &num128[0]);	ia64_ldf8(27, &num128[1]);	copy_from_user(num128, &save->_xmm[6], sizeof(struct _xmmreg_ia32));	ia64_ldf8(28, &num128[0]);	ia64_ldf8(29, &num128[1]);	copy_from_user(num128, &save->_xmm[7], sizeof(struct _xmmreg_ia32));	ia64_ldf8(30, &num128[0]);	ia64_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);}long__ia32_rt_sigsuspend (compat_sigset_t *sset, 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));	memcpy(&set.sig, &sset->sig, sigsetsize);	sigdelsetmask(&set, ~_BLOCKABLE);	spin_lock_irq(&current->sighand->siglock);	{		oldset = current->blocked;		current->blocked = set;		recalc_sigpending();	}	spin_unlock_irq(&current->sighand->siglock);	/*	 * 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_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr){	compat_sigset_t set;	if (sigsetsize > sizeof(compat_sigset_t))		return -EINVAL;	if (copy_from_user(&set.sig, &uset->sig, sigsetsize))		return -EFAULT;	return __ia32_rt_sigsuspend(&set, sigsetsize, scr);}asmlinkage longia32_sigsuspend (unsigned int mask, struct sigscratch *scr){	return __ia32_rt_sigsuspend((compat_sigset_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;	sigemptyset(&new_sa.sa.sa_mask);	ret = do_sigaction(sig, &new_sa, &old_sa);	return ret ? ret : IA32_SA_HANDLER(&old_sa);}asmlinkage longsys32_rt_sigaction (int sig, struct sigaction32 __user *act,		    struct sigaction32 __user *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(compat_sigset_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(compat_sigset_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(compat_sigset_t));	}	return ret;}asmlinkage longsys32_rt_sigprocmask (int how, compat_sigset_t __user *set, compat_sigset_t __user *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 ? (sigset_t __user *) &s : NULL,				 oset ? (sigset_t __user *) &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_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo){	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, (siginfo_t __user *) &info);	set_fs(old_fs);	return ret;}asmlinkage longsys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact){	struct k_sigaction new_ka, old_ka;	unsigned int handler, restorer;	int ret;	if (act) {		compat_old_sigset_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 __user *sc, struct _fpstate_ia32 __user *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 __user *)&sc->fs);	err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int __user *)&sc->gs);	err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int __user *)&sc->es);	err |= __put_user(regs->r16 & 0xffff, (unsigned int __user *)&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 __user *)&sc->cs);	/*	 *  `eflags' is in an ar register for this context	 */	flag = ia64_getreg(_IA64_REG_AR_EFLAG);	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 __user *)&sc->ss);	if ( save_ia32_fpstate_live(fpstate) < 0 )		err = -EFAULT;	else		err |= __put_user((u32)(u64)fpstate, &sc->fpstate);#if 0	tmp = save_i387(fpstate);	if (tmp < 0)		err = 1;	else		err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);	/* non-iBCS2 extensions.. */#endif	err |= __put_user(mask, &sc->oldmask);#if 0	err |= __put_user(current->tss.cr2, &sc->cr2);#endif	return err;

⌨️ 快捷键说明

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