aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/snsc_event.c
diff options
context:
space:
mode:
authorGreg Howard <ghoward@sgi.com>2005-08-15 16:00:00 -0400
committerTony Luck <tony.luck@intel.com>2005-08-15 17:17:49 -0400
commit1a402aaca51b7d56e62348f50a426c531b6bc29e (patch)
treef11678902e54db1205bad348e2a6cdb2017ccfbe /drivers/char/snsc_event.c
parent2ba84684e8cf6f980e4e95a2300f53a505eb794e (diff)
[IA64-SGI] fix unaligned memory access in snsc_event.c
It's been pointed out that environmental events from the system controllers on Altix machines cause the kernel to complain about unaligned memory accesses. This turns out to be because "be32_to_cpup()" didn't do everything I thought/hoped it did. I've added calls to pull the offending integers out of the buffers using get_unaligned() before feeding them to be32_to_cpup(). Signed-off-by: Greg Howard <ghoward@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'drivers/char/snsc_event.c')
-rw-r--r--drivers/char/snsc_event.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index d692af57213a..baaa365285fa 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -19,6 +19,7 @@
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/byteorder/generic.h> 20#include <linux/byteorder/generic.h>
21#include <asm/sn/sn_sal.h> 21#include <asm/sn/sn_sal.h>
22#include <asm/unaligned.h>
22#include "snsc.h" 23#include "snsc.h"
23 24
24static struct subch_data_s *event_sd; 25static struct subch_data_s *event_sd;
@@ -62,13 +63,16 @@ static int
62scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc) 63scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc)
63{ 64{
64 char *desc_end; 65 char *desc_end;
66 __be32 from_buf;
65 67
66 /* record event source address */ 68 /* record event source address */
67 *src = be32_to_cpup((__be32 *)event); 69 from_buf = get_unaligned((__be32 *)event);
70 *src = be32_to_cpup(&from_buf);
68 event += 4; /* move on to event code */ 71 event += 4; /* move on to event code */
69 72
70 /* record the system controller's event code */ 73 /* record the system controller's event code */
71 *code = be32_to_cpup((__be32 *)event); 74 from_buf = get_unaligned((__be32 *)event);
75 *code = be32_to_cpup(&from_buf);
72 event += 4; /* move on to event arguments */ 76 event += 4; /* move on to event arguments */
73 77
74 /* how many arguments are in the packet? */ 78 /* how many arguments are in the packet? */
@@ -82,7 +86,8 @@ scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc)
82 /* not an integer argument, so give up */ 86 /* not an integer argument, so give up */
83 return -1; 87 return -1;
84 } 88 }
85 *esp_code = be32_to_cpup((__be32 *)event); 89 from_buf = get_unaligned((__be32 *)event);
90 *esp_code = be32_to_cpup(&from_buf);
86 event += 4; 91 event += 4;
87 92
88 /* parse out the event description */ 93 /* parse out the event description */