arch/mips/kernel/unaligned.c

Source file repositories/reference/linux-study-clean/arch/mips/kernel/unaligned.c

File Facts

System
Linux kernel
Corpus path
arch/mips/kernel/unaligned.c
Extension
.c
Size
35251 bytes
Lines
1615
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (insn.mxu_lx_format.op) {
		case mxu_lxw_op:
			if (user && !access_ok(addr, 4))
				goto sigbus;
			LoadW(addr, value, res);
			if (res)
				goto fault;
			compute_return_epc(regs);
			regs->regs[insn.mxu_lx_format.rd] = value;
			break;
		case mxu_lxh_op:
			if (user && !access_ok(addr, 2))
				goto sigbus;
			LoadHW(addr, value, res);
			if (res)
				goto fault;
			compute_return_epc(regs);
			regs->regs[insn.dsp_format.rd] = value;
			break;
		case mxu_lxhu_op:
			if (user && !access_ok(addr, 2))
				goto sigbus;
			LoadHWU(addr, value, res);
			if (res)
				goto fault;
			compute_return_epc(regs);
			regs->regs[insn.dsp_format.rd] = value;
			break;
		case mxu_lxb_op:
		case mxu_lxbu_op:
			goto sigbus;
		default:
			goto sigill;
		}
		break;
#endif
	case spec3_op:
		if (insn.dsp_format.func == lx_op) {
			switch (insn.dsp_format.op) {
			case lwx_op:
				if (user && !access_ok(addr, 4))
					goto sigbus;
				LoadW(addr, value, res);
				if (res)
					goto fault;
				compute_return_epc(regs);
				regs->regs[insn.dsp_format.rd] = value;
				break;
			case lhx_op:
				if (user && !access_ok(addr, 2))
					goto sigbus;
				LoadHW(addr, value, res);
				if (res)
					goto fault;
				compute_return_epc(regs);
				regs->regs[insn.dsp_format.rd] = value;
				break;
			default:
				goto sigill;
			}
		}
#ifdef CONFIG_EVA
		else {
			/*
			 * we can land here only from kernel accessing user
			 * memory, so we need to "switch" the address limit to
			 * user space, so that address check can work properly.
			 */
			switch (insn.spec3_format.func) {
			case lhe_op:
				if (!access_ok(addr, 2))
					goto sigbus;
				LoadHWE(addr, value, res);
				if (res)
					goto fault;
				compute_return_epc(regs);
				regs->regs[insn.spec3_format.rt] = value;
				break;
			case lwe_op:
				if (!access_ok(addr, 4))
					goto sigbus;
				LoadWE(addr, value, res);
				if (res)
					goto fault;
				compute_return_epc(regs);
				regs->regs[insn.spec3_format.rt] = value;
				break;
			case lhue_op:
				if (!access_ok(addr, 2))
					goto sigbus;

Annotation

Implementation Notes