diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 7f312d8..1eb686b 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -697,6 +697,33 @@ config HZ default 1200 if HZ_1200 default 1024 +config ALPHA_UAC_SYSCTL + bool "Configure UAC policy via sysctl" + depends on SYSCTL + default y + ---help--- + Configuring the UAC (unaligned access control) policy on a Linux + system usually involves setting a compile time define. If you say + Y here, you will be able to modify the UAC policy at runtime using + the /proc interface. + + The UAC policy defines the action Linux should take when an + unaligned memory access occurs. The action can include printing a + warning message (NOPRINT), sending a signal to the offending + program to help developers debug their applications (SIGBUS), or + disabling the transparent fixing (NOFIX). + + The sysctls will be initialized to the compile-time defined UAC + policy. You can change these manually, or with the sysctl(8) + userspace utility. + + To disable the warning messages at runtime, you would use + + echo 1 > /proc/sys/kernel/uac/noprint + + This is pretty harmless. Say Y if you're not sure. + + source "drivers/pci/Kconfig" source "drivers/eisa/Kconfig" diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 74aceea..cb35d80 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -103,6 +103,49 @@ static char * ireg_name[] = {"v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"}; #endif +#ifdef CONFIG_ALPHA_UAC_SYSCTL + +#include + +static int enabled_noprint = 0; +static int enabled_sigbus = 0; +static int enabled_nofix = 0; + +struct ctl_table uac_table[] = { + { + .procname = "noprint", + .data = &enabled_noprint, + .maxlen = sizeof (int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .procname = "sigbus", + .data = &enabled_sigbus, + .maxlen = sizeof (int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .procname = "nofix", + .data = &enabled_nofix, + .maxlen = sizeof (int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { } +}; + +static int __init init_uac_sysctl(void) +{ + /* Initialize sysctls with the #defined UAC policy */ + enabled_noprint = (test_thread_flag (TS_UAC_NOPRINT)) ? 1 : 0; + enabled_sigbus = (test_thread_flag (TS_UAC_SIGBUS)) ? 1 : 0; + enabled_nofix = (test_thread_flag (TS_UAC_NOFIX)) ? 1 : 0; + return 0; +} +#endif + static void dik_show_code(unsigned int *pc) { @@ -785,7 +828,12 @@ do_entUnaUser(void __user * va, unsigned long opcode, /* Check the UAC bits to decide what the user wants us to do with the unaliged access. */ +#ifndef CONFIG_ALPHA_UAC_SYSCTL if (!(current_thread_info()->status & TS_UAC_NOPRINT)) { +#else /* CONFIG_ALPHA_UAC_SYSCTL */ + if (!(current_thread_info()->status & TS_UAC_NOPRINT) && + !(enabled_noprint)) { +#endif /* CONFIG_ALPHA_UAC_SYSCTL */ if (__ratelimit(&ratelimit)) { printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n", current->comm, task_pid_nr(current), @@ -1090,3 +1138,6 @@ trap_init(void) wrent(entSys, 5); wrent(entDbg, 6); } +#ifdef CONFIG_ALPHA_UAC_SYSCTL + __initcall(init_uac_sysctl); +#endif diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 87b2fc3..55021a8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -152,6 +152,11 @@ static unsigned long hung_task_timeout_max = (LONG_MAX/HZ); #ifdef CONFIG_INOTIFY_USER #include #endif + +#ifdef CONFIG_ALPHA_UAC_SYSCTL +extern struct ctl_table uac_table[]; +#endif + #ifdef CONFIG_SPARC #endif @@ -1844,6 +1849,13 @@ static struct ctl_table debug_table[] = { .extra2 = &one, }, #endif +#ifdef CONFIG_ALPHA_UAC_SYSCTL + { + .procname = "uac", + .mode = 0555, + .child = uac_table, + }, +#endif /* CONFIG_ALPHA_UAC_SYSCTL */ { } };