Skip to contentSkip to conversation

align signal-frame even when not using alternate signal-stack

PATCH In review David Mosberger-Tang 3 participants 3 messages Nov 3, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 align signal-frame even when not using alternate signal-stack

[IA64] align signal-frame even when not using alternate signal-stack

At the moment, attempting to invoke a signal-handler on the normal stack is guaranteed to fail if the stack-pointer happens not to be 16-byte aligned. This is because the signal-trampoline will attempt to store fp-regs with stf.spill instructions, which will trap for misaligned addresses. This isn't terribly useful behavior. It's better to just always align the signal frame to the next lower 16-byte boundary. (Lightly) tested patch attached below.

arch/ia64/kernel/signal.c +5 -6
@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction
 	     struct sigscratch *scr)
 {
 	extern char __kernel_sigtramp[];
-	unsigned long tramp_addr, new_rbs = 0;
+	unsigned long tramp_addr, new_rbs = 0, new_sp;
 	struct sigframe __user *frame;
 	long err;
 
-	frame = (void __user *) scr->pt.r12;
+	new_sp = scr->pt.r12;
 	tramp_addr = (unsigned long) __kernel_sigtramp;
-	if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) = 0) {
-		frame = (void __user *) ((current->sas_ss_sp + current->sas_ss_size)
-					 & ~(STACK_ALIGN - 1));
+	if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) = 0) {
+		new_sp = current->sas_ss_sp + current->sas_ss_size;
 		/*
 		 * We need to check for the register stack being on the signal stack
 		 * separately, because it's switched separately (memory stack is switched
@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction
 		if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
 			new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
 	}
-	frame = (void __user *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1));
+	frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		return force_sigsegv_info(sig, frame);
#1 lore raw
Quoted 3 lines · On Wed, 2 Nov 2005 22:40:19 -0800 (PST), [email protected] (David…

At the moment, attempting to invoke a signal-handler on the normal stack is guaranteed to fail if the stack-pointer happens not to be 16-byte aligned.

Itanium Software Conventions and Runtime Architecture Guide, section 7.1 says that the stack pointer must always be aligned on a 16 byte boundary. What software is not using 16 byte alignment for the stack?

#2 lore raw
In reply to David Mosberger-Tang
Quoted 9 lines · Keith Owens
Quoted 3 lines · On Wed, 2 Nov 2005 22:40:19 -0800 (PST), [email protected] (David…

At the moment, attempting to invoke a signal-handler on the normal stack is guaranteed to fail if the stack-pointer happens not to be 16-byte aligned.

Itanium Software Conventions and Runtime Architecture Guide, section 7.1 says that the stack pointer must always be aligned on a 16 byte boundary. What software is not using 16 byte alignment for the stack?

Buggy software...

This really is more a "ease debugging" kind of thing. Clearly you're in a heap of trouble once your stack-pointer is misaligned, but with the old behavior, that was aggravated by triggering an infinite series of nested signals, which makes it quite hard to just stop the process (plus it may eat lots of memory if the stack limit is large).

On top of that, I don't think it makes a lot of sense to force 16-byte alignment for delivery on alternate signal-stacks and not do so for the normal stack. I don't have access to the very earliest ia64-linux patches anymore (prior to 2000, when things went public), but I'm pretty sure this was a historical accident.

Thanks,

--david
--
Mosberger Consulting LLC, voice/fax: 510-744-9372,
http://www.mosberger-consulting.com/
35706 Runckel Lane, Fremont, CA 94536