static inline void simulate_swa()

in kernel/traps.c [378:423]


static inline void simulate_swa(struct pt_regs *regs, unsigned long address,
				unsigned int insn)
{
	unsigned long __user *vaddr;
	unsigned long orig_pc;
	unsigned int ra, rb;
	long imm;

	const struct exception_table_entry *entry;

	orig_pc = regs->pc;
	adjust_pc(regs, address);

	ra = (insn >> 16) & 0x1f;
	rb = (insn >> 11) & 0x1f;
	imm = (short)(((insn & 0x2200000) >> 10) | (insn & 0x7ff));
	vaddr = (unsigned long __user *)(regs->gpr[ra] + imm);

	if (!lwa_flag || vaddr != lwa_addr) {
		regs->sr &= ~SPR_SR_F;
		return;
	}

	if ((unsigned long)vaddr & 0x3) {
		do_unaligned_access(regs, address);
		return;
	}

	if (put_user(regs->gpr[rb], vaddr)) {
		if (user_mode(regs)) {
			force_sig(SIGSEGV);
			return;
		}

		if ((entry = search_exception_tables(orig_pc))) {
			regs->pc = entry->fixup;
			return;
		}

		/* kernel access in kernel space, store it directly */
		*((unsigned long *)vaddr) = regs->gpr[rb];
	}

	lwa_flag = 0;
	regs->sr |= SPR_SR_F;
}