[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 10/15] xen: arm: handle traps from 64-bit guests
On Fri, 19 Jul 2013, Ian Campbell wrote: > While there observe that we weren't ever restoring the outer stack frame, even > for 32-bit guests when running a 64-bit hypervisor! The outer stack frame > "only" contains most of the SPSR registers for 32-bit... > > We can also remove the logic at "return_to_new_vcpu" which detects returns to > hypervisor mode -- seemingly trying to handle hypervisor threads which aren't > an thing which we have. The idle VCPUs do not take this path. This simplifies > the return_to_new_vcpu code, we also split it into 32- and 64-bit VCPU paths. > > There is no need to export return_to_hypervisor (now renamed return_from_trap > on arm64) and likewise stop doing so on 32-bit as well. > > Also tweak the case of some system registers for consistency. > > Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > --- > v3: actually restore the outer stack frame! Due to this change I have dropped > the previous Acks. It looks OK. However the code refactoring, the naming changes, and the new code to save the outer stack frame are difficult to follow together. Maybe separate out the latter? > xen/arch/arm/arm32/entry.S | 4 +- > xen/arch/arm/arm64/entry.S | 95 ++++++++++++++++++++++++++++++++----------- > xen/arch/arm/domain.c | 6 ++- > 3 files changed, 77 insertions(+), 28 deletions(-) > > diff --git a/xen/arch/arm/arm32/entry.S b/xen/arch/arm/arm32/entry.S > index 76814dd..cc0a99f 100644 > --- a/xen/arch/arm/arm32/entry.S > +++ b/xen/arch/arm/arm32/entry.S > @@ -87,7 +87,7 @@ DEFINE_TRAP_ENTRY_NOIRQ(fiq) > > return_from_trap: > mov sp, r11 > -ENTRY(return_to_new_vcpu) > +ENTRY(return_to_new_vcpu32) > ldr r11, [sp, #UREGS_cpsr] > and r11, #PSR_MODE_MASK > cmp r11, #PSR_MODE_HYP > @@ -108,7 +108,7 @@ ENTRY(return_to_guest) > RESTORE_ONE_BANKED(R8_fiq); RESTORE_ONE_BANKED(R9_fiq); > RESTORE_ONE_BANKED(R10_fiq) > RESTORE_ONE_BANKED(R11_fiq); RESTORE_ONE_BANKED(R12_fiq); > /* Fall thru */ > -ENTRY(return_to_hypervisor) > +return_to_hypervisor: > cpsid i > ldr lr, [sp, #UREGS_lr] > ldr r11, [sp, #UREGS_pc] > diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S > index b5af1e2..9cda8f1 100644 > --- a/xen/arch/arm/arm64/entry.S > +++ b/xen/arch/arm/arm64/entry.S > @@ -26,7 +26,7 @@ lr .req x30 // link register > .macro entry_guest, compat > > add x21, sp, #UREGS_SPSR_el1 > - mrs x23, SPSR_EL1 > + mrs x23, SPSR_el1 > str x23, [x21] > > .if \compat == 0 /* Aarch64 mode */ > @@ -40,24 +40,56 @@ lr .req x30 // link register > mrs x23, ELR_el1 > stp x22, x23, [x21] > > - .else /* Aarch32 mode */ > + .else /* Aarch32 mode */ > > add x21, sp, #UREGS_SPSR_fiq > - mrs x22, spsr_fiq > - mrs x23, spsr_irq > + mrs x22, SPSR_fiq > + mrs x23, SPSR_irq > stp w22, w23, [x21] > > add x21, sp, #UREGS_SPSR_und > - mrs x22, spsr_und > - mrs x23, spsr_abt > + mrs x22, SPSR_und > + mrs x23, SPSR_abt > stp w22, w23, [x21] > > .endif > > .endm > > + .macro exit_guest, compat > + > + add x21, sp, #UREGS_SPSR_el1 > + ldr x23, [x21] > + msr SPSR_el1, x23 > + > + .if \compat == 0 /* Aarch64 mode */ > + > + add x21, sp, #UREGS_SP_el0 > + ldr x22, [x21] > + msr SP_el0, x22 > + > + add x21, sp, #UREGS_SP_el1 > + ldp x22, x23, [x21] > + msr SP_el1, x22 > + msr ELR_el1, x23 > + > + .else /* Aarch32 mode */ > + > + add x21, sp, #UREGS_SPSR_fiq > + ldp w22, w23, [x21] > + msr SPSR_fiq, x22 > + msr SPSR_irq, x23 > + > + add x21, sp, #UREGS_SPSR_und > + ldp w22, w23, [x21] > + msr SPSR_und, x22 > + msr SPSR_abt, x23 > + > + .endif > + > + .endm > /* > - * Save state on entry to hypervisor > + * Save state on entry to hypervisor, restore on exit > */ > .macro entry, hyp, compat > sub sp, sp, #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */ > @@ -96,6 +128,20 @@ lr .req x30 // link register > > .endm > > + .macro exit, hyp, compat > + > + .if \hyp == 0 /* Guest mode */ > + > + bl leave_hypervisor_tail /* Disables interrupts on return */ > + > + exit_guest \compat > + > + .endif > + > + b return_from_trap > + > + .endm > + > /* > * Bad Abort numbers > *----------------- > @@ -133,21 +179,26 @@ hyp_sync: > msr daifclr, #2 > mov x0, sp > bl do_trap_hypervisor > - b return_to_hypervisor > + exit hyp=1 > > hyp_irq: > entry hyp=1 > mov x0, sp > bl do_trap_irq > - b return_to_hypervisor > + exit hyp=1 > > guest_sync: > entry hyp=0, compat=0 > - invalid BAD_SYNC /* No AArch64 guest support yet */ > + msr daifclr, #2 > + mov x0, sp > + bl do_trap_hypervisor > + exit hyp=0, compat=0 > > guest_irq: > entry hyp=0, compat=0 > - invalid BAD_IRQ /* No AArch64 guest support yet */ > + mov x0, sp > + bl do_trap_irq > + exit hyp=0, compat=0 > > guest_fiq_invalid: > entry hyp=0, compat=0 > @@ -162,13 +213,13 @@ guest_sync_compat: > msr daifclr, #2 > mov x0, sp > bl do_trap_hypervisor > - b return_to_guest > + exit hyp=0, compat=1 > > guest_irq_compat: > entry hyp=0, compat=1 > mov x0, sp > bl do_trap_irq > - b return_to_guest > + exit hyp=0, compat=1 > > guest_fiq_invalid_compat: > entry hyp=0, compat=1 > @@ -178,18 +229,12 @@ guest_error_invalid_compat: > entry hyp=0, compat=1 > invalid BAD_ERROR > > -ENTRY(return_to_new_vcpu) > - ldr x21, [sp, #UREGS_CPSR] > - and x21, x21, #PSR_MODE_MASK > - /* Returning to EL2? */ > - cmp x21, #PSR_MODE_EL2t > - ccmp x21, #PSR_MODE_EL2h, #0x4, ne > - b.eq return_to_hypervisor /* Yes */ > - /* Fall thru */ > -ENTRY(return_to_guest) > - bl leave_hypervisor_tail /* Disables interrupts on return */ > - /* Fall thru */ > -ENTRY(return_to_hypervisor) > +ENTRY(return_to_new_vcpu32) > + exit hyp=0, compat=1 > +ENTRY(return_to_new_vcpu64) > + exit hyp=0, compat=0 > + > +return_from_trap: > msr daifset, #2 /* Mask interrupts */ > > ldp x21, x22, [sp, #UREGS_PC] // load ELR, SPSR > diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c > index a409d11..cf82e21 100644 > --- a/xen/arch/arm/domain.c > +++ b/xen/arch/arm/domain.c > @@ -250,9 +250,13 @@ static void continue_new_vcpu(struct vcpu *prev) > > if ( is_idle_vcpu(current) ) > reset_stack_and_jump(idle_loop); > + else if is_pv32_domain(current->domain) > + /* check_wakeup_from_wait(); */ > + reset_stack_and_jump(return_to_new_vcpu32); > else > /* check_wakeup_from_wait(); */ > - reset_stack_and_jump(return_to_new_vcpu); > + reset_stack_and_jump(return_to_new_vcpu64); > + > } > > void context_switch(struct vcpu *prev, struct vcpu *next) > -- > 1.7.2.5 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |