Correct definition of UREGS_kernel_sizeof and use it.
Correct adjustment of stack on entry and exit.
Add 64-bit versions of the build time checks for stack pointer alignment
correctness when pushing the stack frames.
Lastly, correct the padding in the stack frames to properly align the inner and
outer frames and also avoid an unnecessary 64bit padding field.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
OFFSET(UREGS_SP_el1, struct cpu_user_regs, sp_el1);
OFFSET(UREGS_ELR_el1, struct cpu_user_regs, elr_el1);
- OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, cpsr);
+ OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, spsr_el1);
DEFINE(UREGS_user_sizeof, sizeof(struct cpu_user_regs));
BLANK();
mrs x22, SP_el0
str x22, [x21]
- add x21, sp, #UREGS_ELR_el1
+ add x21, sp, #UREGS_SP_el1
mrs x22, SP_el1
mrs x23, ELR_el1
stp x22, x23, [x21]
* Save state on entry to hypervisor
*/
.macro entry, hyp, compat
- sub sp, sp, #(UREGS_SPSR_el1 - UREGS_SP)
+ sub sp, sp, #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
push x28, x29
push x26, x27
push x24, x25
.if \hyp == 1 /* Hypervisor mode */
- add x21, sp, #(UREGS_X0 - UREGS_SP)
+ add x21, sp, #UREGS_kernel_sizeof
.else /* Guest mode */
pop x26, x27
pop x28, x29
- ldr lr, [sp], #(UREGS_SPSR_el1 - UREGS_SP)
+ ldr lr, [sp], #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
+
eret
/*
{
int rc = 0;
+ BUILD_BUG_ON( sizeof(struct cpu_info) > STACK_SIZE );
+
v->arch.stack = alloc_xenheap_pages(STACK_ORDER, MEMF_node(vcpu_to_node(v)));
if ( v->arch.stack == NULL )
return -ENOMEM;
* entry.S) and struct cpu_info (which lives at the bottom of a Xen
* stack) must be doubleword-aligned in size. */
static inline void check_stack_alignment_constraints(void) {
+#ifdef CONFIG_ARM_64
+ BUILD_BUG_ON((sizeof (struct cpu_user_regs)) & 0xf);
+ BUILD_BUG_ON((offsetof(struct cpu_user_regs, spsr_el1)) & 0xf);
+ BUILD_BUG_ON((offsetof(struct cpu_user_regs, lr)) & 0xf);
+ BUILD_BUG_ON((sizeof (struct cpu_info)) & 0xf);
+#else
BUILD_BUG_ON((sizeof (struct cpu_user_regs)) & 0x7);
BUILD_BUG_ON((offsetof(struct cpu_user_regs, sp_usr)) & 0x7);
BUILD_BUG_ON((sizeof (struct cpu_info)) & 0x7);
+#endif
}
static int debug_stack_lines = 20;
__DECL_REG(x27, r11_fiq);
__DECL_REG(x28, r12_fiq);
__DECL_REG(/* x29 */ fp, /* r13_fiq */ sp_fiq);
+
__DECL_REG(/* x30 */ lr, /* r14_fiq */ lr_fiq);
register_t sp; /* Valid for hypervisor frames */
__DECL_REG(pc, pc32); /* ELR_EL2 */
uint32_t cpsr; /* SPSR_EL2 */
- uint64_t pad0;
+ uint32_t pad0; /* Align end of kernel frame. */
/* Outer guest frame only from here on... */
uint32_t spsr_svc; /* AArch32 */
};
- uint32_t pad1; /* Align */
+ uint32_t pad1; /* Doubleword-align the user half of the frame */
/* AArch32 guests only */
uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt;
/* AArch64 guests only */
uint64_t sp_el0;
uint64_t sp_el1, elr_el1;
-
- uint64_t pad2; /* Doubleword-align the user half of the frame */
};
#undef __DECL_REG