Skip to content

Commit

Permalink
sh: Always fixup unaligned userspace accesses on sh64.
Browse files Browse the repository at this point in the history
sh64 has traditionally had this configurable via a Kconfig option
(CONFIG_SH64_USER_MISALIGNED_FIXUP). In practice it has never really been
terribly useful to turn this off, so just get rid of the option entirely.

We leave the sysctl around so we don't end up breaking existing root
file systems, and to allow folks that really want this off to do so at
their own risk.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
  • Loading branch information
Paul Mundt committed May 8, 2009
1 parent 30d88cf commit c29418c
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 35 deletions.
5 changes: 0 additions & 5 deletions arch/sh/Kconfig.cpu
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ config SPECULATIVE_EXECUTION

If unsure, say N.

config SH64_USER_MISALIGNED_FIXUP
def_bool y
prompt "Fixup misaligned loads/stores occurring in user mode"
depends on SUPERH64

config SH64_ID2815_WORKAROUND
bool "Include workaround for SH5-101 cut2 silicon defect ID2815"
depends on CPU_SUBTYPE_SH5_101
Expand Down
35 changes: 5 additions & 30 deletions arch/sh/kernel/traps_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,6 @@ static int generate_and_check_address(struct pt_regs *regs,
return -1;
}

#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
/* Check accessible. For misaligned access in the kernel, assume the
address is always accessible (and if not, just fault when the
load/store gets done.) */
Expand All @@ -380,18 +379,13 @@ static int generate_and_check_address(struct pt_regs *regs,
}
/* Do access_ok check later - it depends on whether it's a load or a store. */
}
#endif

*address = addr;
return 0;
}

/* Default value as for sh */
#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
static int user_mode_unaligned_fixup_count = 10;
static int user_mode_unaligned_fixup_enable = 1;
#endif

static int kernel_mode_unaligned_fixup_count = 32;

static void misaligned_kernel_word_load(__u64 address, int do_sign_extend, __u64 *result)
Expand Down Expand Up @@ -440,7 +434,6 @@ static int misaligned_load(struct pt_regs *regs,
}

destreg = (opcode >> 4) & 0x3f;
#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
if (user_mode(regs)) {
__u64 buffer;

Expand Down Expand Up @@ -470,9 +463,7 @@ static int misaligned_load(struct pt_regs *regs,
width_shift, (unsigned long) regs->pc);
break;
}
} else
#endif
{
} else {
/* kernel mode - we can take short cuts since if we fault, it's a genuine bug */
__u64 lo, hi;

Expand Down Expand Up @@ -519,7 +510,6 @@ static int misaligned_store(struct pt_regs *regs,
}

srcreg = (opcode >> 4) & 0x3f;
#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
if (user_mode(regs)) {
__u64 buffer;

Expand All @@ -546,9 +536,7 @@ static int misaligned_store(struct pt_regs *regs,
if (__copy_user((void *)(int)address, &buffer, (1 << width_shift)) > 0) {
return -1; /* fault */
}
} else
#endif
{
} else {
/* kernel mode - we can take short cuts since if we fault, it's a genuine bug */
__u64 val = regs->regs[srcreg];

Expand Down Expand Up @@ -576,7 +564,6 @@ static int misaligned_store(struct pt_regs *regs,

}

#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
/* Never need to fix up misaligned FPU accesses within the kernel since that's a real
error. */
static int misaligned_fpu_load(struct pt_regs *regs,
Expand Down Expand Up @@ -727,20 +714,15 @@ static int misaligned_fpu_store(struct pt_regs *regs,
return -1;
}
}
#endif

static int misaligned_fixup(struct pt_regs *regs)
{
unsigned long opcode;
int error;
int major, minor;

#if !defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
/* Never fixup user mode misaligned accesses without this option enabled. */
return -1;
#else
if (!user_mode_unaligned_fixup_enable) return -1;
#endif
if (!user_mode_unaligned_fixup_enable)
return -1;

error = read_opcode(regs->pc, &opcode, user_mode(regs));
if (error < 0) {
Expand All @@ -749,15 +731,12 @@ static int misaligned_fixup(struct pt_regs *regs)
major = (opcode >> 26) & 0x3f;
minor = (opcode >> 16) & 0xf;

#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
if (user_mode(regs) && (user_mode_unaligned_fixup_count > 0)) {
--user_mode_unaligned_fixup_count;
/* Only do 'count' worth of these reports, to remove a potential DoS against syslog */
printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
} else
#endif
if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) {
} else if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) {
--kernel_mode_unaligned_fixup_count;
if (in_interrupt()) {
printk("Fixing up unaligned kernelspace access in interrupt pc=0x%08x ins=0x%08lx\n",
Expand Down Expand Up @@ -830,7 +809,6 @@ static int misaligned_fixup(struct pt_regs *regs)
}
break;

#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
case (0x94>>2): /* FLD.S */
error = misaligned_fpu_load(regs, opcode, 1, 2, 0);
break;
Expand Down Expand Up @@ -881,7 +859,6 @@ static int misaligned_fixup(struct pt_regs *regs)
break;
}
break;
#endif

default:
/* Fault */
Expand All @@ -907,7 +884,6 @@ static ctl_table unaligned_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec
},
#if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP)
{
.ctl_name = CTL_UNNUMBERED,
.procname = "user_reports",
Expand All @@ -923,7 +899,6 @@ static ctl_table unaligned_table[] = {
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec},
#endif
{}
};

Expand Down

0 comments on commit c29418c

Please sign in to comment.