aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/kexec.c
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-04-24 09:48:08 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-04-24 09:48:08 +0100
commit6265f09192803de7b8024e13b676dfeb74ef996a (patch)
tree709cd7ba062d4d54bdc6e3ad68c58a3f3d8ab263 /xen/common/kexec.c
parent348762501c938967c1ad7e566633d40b1ea8e8bd (diff)
downloadxen-6265f09192803de7b8024e13b676dfeb74ef996a.tar.gz
xen-6265f09192803de7b8024e13b676dfeb74ef996a.tar.bz2
xen-6265f09192803de7b8024e13b676dfeb74ef996a.zip
kexec: Avoid unaligned writes when producing crash info.
The alignment of info is 32bits in line with the elf specification. This means that on 64 bit architectures accessing it directly may result unaligned access and a panic. I have been experiencing this on IA64. It seems that a simple approach of having an crash_xen_info_t on the stack and simply memcopying it into info at the end alleviates the problem. Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'xen/common/kexec.c')
-rw-r--r--xen/common/kexec.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 80314a6673..c0fe6d2396 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -81,20 +81,25 @@ void kexec_crash_save_cpu(void)
crash_xen_info_t *kexec_crash_save_info(void)
{
int cpu = smp_processor_id();
- crash_xen_info_t *info = (crash_xen_info_t *)ELFNOTE_DESC(xen_crash_note);
+ crash_xen_info_t info;
+ crash_xen_info_t *out = (crash_xen_info_t *)ELFNOTE_DESC(xen_crash_note);
BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus));
- info->xen_major_version = xen_major_version();
- info->xen_minor_version = xen_minor_version();
- info->xen_extra_version = __pa(xen_extra_version());
- info->xen_changeset = __pa(xen_changeset());
- info->xen_compiler = __pa(xen_compiler());
- info->xen_compile_date = __pa(xen_compile_date());
- info->xen_compile_time = __pa(xen_compile_time());
- info->tainted = tainted;
+ memset(&info, 0, sizeof(info));
+ info.xen_major_version = xen_major_version();
+ info.xen_minor_version = xen_minor_version();
+ info.xen_extra_version = __pa(xen_extra_version());
+ info.xen_changeset = __pa(xen_changeset());
+ info.xen_compiler = __pa(xen_compiler());
+ info.xen_compile_date = __pa(xen_compile_date());
+ info.xen_compile_time = __pa(xen_compile_time());
+ info.tainted = tainted;
- return info;
+ /* Copy from guaranteed-aligned local copy to possibly-unaligned dest. */
+ memcpy(out, &info, sizeof(info));
+
+ return out;
}
void kexec_crash(void)