Index: kernel/arch/ia64/include/asm.h
===================================================================
--- kernel/arch/ia64/include/asm.h	(revision 26aafe8d909ecb61306a77910aeb374da3814391)
+++ kernel/arch/ia64/include/asm.h	(revision e06e27166f1b30422fc5f34049108ea34cdd2cfb)
@@ -122,31 +122,13 @@
 }
 
-/** Return base address of current stack
- *
- * Return the base address of the current stack.
- * The stack is assumed to be STACK_SIZE long.
- * The stack must start on page boundary.
- *
+/** Return base address of current memory stack.
+ *
+ * The memory stack is assumed to be STACK_SIZE / 2 long. Note that there is
+ * also the RSE stack, which takes up the upper half of STACK_SIZE.
+ * The memory stack must start on page boundary.
  */
 NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uint64_t value;
-	
-	/*
-	 * I'm not sure why but this code inlines badly
-	 * in scheduler, resulting in THE shifting about
-	 * 16B and causing kernel panic.
-	 *
-	 * asm volatile (
-	 *     "and %[value] = %[mask], r12"
-	 *     : [value] "=r" (v)
-	 *     : [mask] "r" (~(STACK_SIZE - 1))
-	 * );
-	 * return v;
-	 *
-	 * The following code has the same semantics but
-	 * inlines correctly.
-	 *
-	 */
 	
 	asm volatile (
@@ -155,5 +137,5 @@
 	);
 	
-	return (value & (~(STACK_SIZE - 1)));
+	return (value & (~(STACK_SIZE / 2 - 1)));
 }
 
Index: kernel/arch/ia64/include/context.h
===================================================================
--- kernel/arch/ia64/include/context.h	(revision 26aafe8d909ecb61306a77910aeb374da3814391)
+++ kernel/arch/ia64/include/context.h	(revision e06e27166f1b30422fc5f34049108ea34cdd2cfb)
@@ -49,11 +49,11 @@
 #define SP_DELTA	(0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
-/* RSE stack starts at the bottom of memory stack. */
+/* RSE stack starts at the bottom of memory stack, hence the division by 2. */
 #define context_set(c, _pc, stack, size)								\
 	do {												\
 		(c)->pc = (uintptr_t) _pc;								\
-		(c)->bsp = ((uintptr_t) stack) + ALIGN_UP((size), REGISTER_STACK_ALIGNMENT);		\
+		(c)->bsp = ((uintptr_t) stack) + ALIGN_UP((size / 2), REGISTER_STACK_ALIGNMENT);	\
 		(c)->ar_pfs &= PFM_MASK; 								\
-		(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - SP_DELTA;		\
+		(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size / 2), STACK_ALIGNMENT) - SP_DELTA;	\
 	} while (0);
 
Index: kernel/arch/ia64/src/ia64.c
===================================================================
--- kernel/arch/ia64/src/ia64.c	(revision 26aafe8d909ecb61306a77910aeb374da3814391)
+++ kernel/arch/ia64/src/ia64.c	(revision e06e27166f1b30422fc5f34049108ea34cdd2cfb)
@@ -249,8 +249,14 @@
 	rsc.mode = 3;			/* eager mode */
 
+	/*
+	 * Switch to userspace.
+	 *
+	 * When calculating stack addresses, mind the stack split between the
+	 * memory stack and the RSE stack. Each occuppies STACK_SIZE / 2 bytes.
+	 */
 	switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
-	    ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE -
+	    ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE / 2 -
 	    ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
-	    ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE,
+	    ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE / 2,
 	    (uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value);
 
Index: kernel/arch/ia64/src/proc/scheduler.c
===================================================================
--- kernel/arch/ia64/src/proc/scheduler.c	(revision 26aafe8d909ecb61306a77910aeb374da3814391)
+++ kernel/arch/ia64/src/proc/scheduler.c	(revision e06e27166f1b30422fc5f34049108ea34cdd2cfb)
@@ -79,4 +79,7 @@
 	 * Record address of kernel stack to bank 0 r23.
 	 * These values will be found there after switch from userspace.
+	 *
+	 * Mind the 1:1 split of the entire STACK_SIZE long region between the
+	 * memory stack and the RSE stack.
 	 */
 	asm volatile (
@@ -86,6 +89,6 @@
 		"bsw.1\n"
 		:
-		: "r" (&THREAD->kstack[STACK_SIZE]),
-		  "r" (&THREAD->kstack[STACK_SIZE - SP_DELTA])
+		: "r" (&THREAD->kstack[STACK_SIZE / 2]),
+		  "r" (&THREAD->kstack[STACK_SIZE / 2 - SP_DELTA])
 		);
 }
