arch/sparc/kernel/unaligned_32.c

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/unaligned_32.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/unaligned_32.c
Extension
.c
Size
7200 bytes
Lines
283
Domain
Architecture Layer
Bucket
arch/sparc
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

if(address < PAGE_SIZE) {
                	printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler");
        	} else
                	printk(KERN_ALERT "Unable to handle kernel paging request in mna handler");
	        printk(KERN_ALERT " at virtual address %08lx\n",address);
		printk(KERN_ALERT "current->{mm,active_mm}->context = %08lx\n",
			(current->mm ? current->mm->context :
			current->active_mm->context));
		printk(KERN_ALERT "current->{mm,active_mm}->pgd = %08lx\n",
			(current->mm ? (unsigned long) current->mm->pgd :
			(unsigned long) current->active_mm->pgd));
	        die_if_kernel("Oops", regs);
		/* Not reached */
	}
	regs->pc = entry->fixup;
	regs->npc = regs->pc + 4;
}

asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
{
	enum direction dir = decode_direction(insn);
	int size = decode_access_size(insn);

	if(!ok_for_kernel(insn) || dir == both) {
		printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
		       regs->pc);
		unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store.");
	} else {
		unsigned long addr = compute_effective_address(regs, insn);
		int err;

		perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
		switch (dir) {
		case load:
			err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
							 regs),
					  size, (unsigned long *) addr,
					  decode_signedness(insn));
			break;

		case store:
			err = do_int_store(((insn>>25)&0x1f), size,
					   (unsigned long *) addr, regs);
			break;
		default:
			panic("Impossible kernel unaligned trap.");
			/* Not reached... */
		}
		if (err)
			kernel_mna_trap_fault(regs, insn);
		else
			advance(regs);
	}
}

asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
{
	send_sig_fault(SIGBUS, BUS_ADRALN,
		       (void __user *)safe_compute_effective_address(regs, insn),
		       current);
}

Annotation

Implementation Notes