Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 44157
b: refs/heads/master
c: c449c38
h: refs/heads/master
i:
  44155: 205bbf5
v: v3
  • Loading branch information
David S. Miller committed Dec 10, 2006
1 parent b533ce7 commit f6de212
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6e7726e16fb5e8f1169dbfcb75e321ac871af827
refs/heads/master: c449c38b5df1fad556ea210deb6cff3b27323e49
44 changes: 31 additions & 13 deletions trunk/arch/sparc64/kernel/unaligned.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ static inline int ok_for_kernel(unsigned int insn)
return !floating_point_load_or_store_p(insn);
}

static void kernel_mna_trap_fault(void)
static void kernel_mna_trap_fault(int fixup_tstate_asi)
{
struct pt_regs *regs = current_thread_info()->kern_una_regs;
unsigned int insn = current_thread_info()->kern_una_insn;
Expand Down Expand Up @@ -274,18 +274,15 @@ static void kernel_mna_trap_fault(void)
regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;

regs->tstate &= ~TSTATE_ASI;
regs->tstate |= (ASI_AIUS << 24UL);
if (fixup_tstate_asi) {
regs->tstate &= ~TSTATE_ASI;
regs->tstate |= (ASI_AIUS << 24UL);
}
}

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

current_thread_info()->kern_una_regs = regs;
current_thread_info()->kern_una_insn = insn;

if (jiffies - last_time > 5 * HZ)
count = 0;
Expand All @@ -295,17 +292,39 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
printk("Kernel unaligned access at TPC[%lx] ", regs->tpc);
print_symbol("%s\n", regs->tpc);
}
}

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

current_thread_info()->kern_una_regs = regs;
current_thread_info()->kern_una_insn = insn;

orig_asi = asi = decode_asi(insn, regs);

/* If this is a {get,put}_user() on an unaligned userspace pointer,
* just signal a fault and do not log the event.
*/
if (asi == ASI_AIUS) {
kernel_mna_trap_fault(0);
return;
}

log_unaligned(regs);

if (!ok_for_kernel(insn) || dir == both) {
printk("Unsupported unaligned load/store trap for kernel "
"at <%016lx>.\n", regs->tpc);
unaligned_panic("Kernel does fpu/atomic "
"unaligned load/store.", regs);

kernel_mna_trap_fault();
kernel_mna_trap_fault(0);
} else {
unsigned long addr, *reg_addr;
int orig_asi, asi, err;
int err;

addr = compute_effective_address(regs, insn,
((insn >> 25) & 0x1f));
Expand All @@ -315,7 +334,6 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
regs->tpc, dirstrings[dir], addr, size,
regs->u_regs[UREG_RETPC]);
#endif
orig_asi = asi = decode_asi(insn, regs);
switch (asi) {
case ASI_NL:
case ASI_AIUPL:
Expand Down Expand Up @@ -365,7 +383,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
/* Not reached... */
}
if (unlikely(err))
kernel_mna_trap_fault();
kernel_mna_trap_fault(1);
else
advance(regs);
}
Expand Down

0 comments on commit f6de212

Please sign in to comment.