|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCHv5 30/46] plat/kvm: Add exception table for Arm64
> -----Original Message-----
> From: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> Sent: 2018年9月11日 22:10
> To: Wei Chen (Arm Technology China) <Wei.Chen@xxxxxxx>; minios-
> devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Kaly Xin (Arm Technology China) <Kaly.Xin@xxxxxxx>; nd <nd@xxxxxxx>
> Subject: Re: [Minios-devel] [UNIKRAFT PATCHv5 30/46] plat/kvm: Add exception
> table for Arm64
>
> On 10.08.2018 09:08, Wei Chen wrote:
> > From: Wei Chen <Wei.Chen@xxxxxxx>
> >
> > On Arm64, we need SYNC exception handler to handle some exceptions
> > like access NULL pointer, and we need IRQ exception handler to handle
> > IRQs like timer IRQ. Both these types of exceptions would be handled
> > in EL1. Except these two types of exceptions, other exceptions would
> > treated as invalid exceptions.
> >
> > But we have't enabled the GIC, so the IRQ exception also be treated
> > as invalid exception in current stage.
> >
> > Signed-off-by: Wei Chen <Wei.Chen@xxxxxxx>
> > ---
> > include/uk/arch/arm/arm64/lcpu.h | 14 +++
> > plat/kvm/Makefile.uk | 1 +
> > plat/kvm/arm/entry64.S | 4 +
> > plat/kvm/arm/exceptions.S | 187 +++++++++++++++++++++++++++++++
> > 4 files changed, 206 insertions(+)
> > create mode 100644 plat/kvm/arm/exceptions.S
> >
> > diff --git a/include/uk/arch/arm/arm64/lcpu.h
> b/include/uk/arch/arm/arm64/lcpu.h
> > index 1acdd2b..f765e6d 100644
> > --- a/include/uk/arch/arm/arm64/lcpu.h
> > +++ b/include/uk/arch/arm/arm64/lcpu.h
> > @@ -30,6 +30,18 @@
> > #error Do not include this header directly
> > #endif
> >
> > +#ifdef __ASSEMBLY__
> > +/*
> > + * Stack size to save general purpose registers and essential system
> > + * registers. 8 * (30 + lr + elr_el1 + spsr_el1 + esr_el1) = 272.
> > + * From exceptions come from EL0, we have to save sp_el0. So the
> > + * TRAP_STACK_SIZE should be 272 + 8 = 280
> > + *
> > + * TODO: We'd better to calculate this size automatically later.
> > + */
> > +#define TRAP_STACK_SIZE 280
>
> Maybe it is better to double underscore TRAP_STACK_SIZE:
> __TRAP_STACK_SIZE. We did this for almost all definitions in /include in
> order to avoid name clashes with other libraries.
>
Thanks, now I understand why Unikraft always uses __ for macros ; )
> > +#else
> > +/* Change this structure must update TRAP_STACK_SIZE at the same time */
> > struct __regs {
> > /* Generic Purpose registers, from x0 ~ x29 */
> > unsigned long x[30];
> > @@ -87,3 +99,5 @@ struct __regs {
> > #ifndef wmb
> > #define wmb() dsb(st) /* Full system memory barrier store */
> > #endif
> > +
> > +#endif /* __ASSEMBLY__ */
> > diff --git a/plat/kvm/Makefile.uk b/plat/kvm/Makefile.uk
> > index 53e6b90..a43cdbe 100644
> > --- a/plat/kvm/Makefile.uk
> > +++ b/plat/kvm/Makefile.uk
> > @@ -57,6 +57,7 @@ LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(UK_PLAT_COMMON_BASE)/arm/cache64.S|co
> > LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(UK_PLAT_COMMON_BASE)/arm/time.c|common
> > LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(UK_PLAT_COMMON_BASE)/arm/traps.c|common
> > LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/entry64.S
> > +LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) +=
> $(LIBKVMPLAT_BASE)/arm/exceptions.S
> > LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/setup.c
> > LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/lcpu.c
> > LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBKVMPLAT_BASE)/arm/intctrl.c
> > diff --git a/plat/kvm/arm/entry64.S b/plat/kvm/arm/entry64.S
> > index 50362c2..d054e5c 100644
> > --- a/plat/kvm/arm/entry64.S
> > +++ b/plat/kvm/arm/entry64.S
> > @@ -68,6 +68,10 @@ ENTRY(_libkvmplat_entry)
> >
> > mov sp, x27
> >
> > + /* Setup excetpion vector table address before enable MMU */
> > + ldr x29, =vector_table
> > + msr VBAR_EL1, x29
> > +
> > /* Load dtb address to x0 as a parameter */
> > ldr x0, =_dtb
> > b _libkvmplat_start
> > diff --git a/plat/kvm/arm/exceptions.S b/plat/kvm/arm/exceptions.S
> > new file mode 100644
> > index 0000000..7992aa8
> > --- /dev/null
> > +++ b/plat/kvm/arm/exceptions.S
> > @@ -0,0 +1,187 @@
> > +/* SPDX-License-Identifier: ISC */
> > +/*-
> > + *
> > + * Copyright (c) 2014 Andrew Turner, All rights reserved.
> > + * Copyright (c) 2018 Arm Ltd., All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or without
> > + * modification, are permitted provided that the following conditions
> > + * are met:
> > + * 1. Redistributions of source code must retain the above copyright
> > + * notice, this list of conditions and the following disclaimer.
> > + * 2. Redistributions in binary form must reproduce the above copyright
> > + * notice, this list of conditions and the following disclaimer in the
> > + * documentation and/or other materials provided with the distribution.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> CONSEQUENTIAL
> > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> STRICT
> > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
> WAY
> > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> > + * SUCH DAMAGE.
> > + *
> > + */
> > +#include <uk/arch/lcpu.h>
> > +#include <asm.h>
> > +
> > +.macro ENTER_TRAP, el
> > + sub sp, sp, #TRAP_STACK_SIZE
> > +
> > + /* Save general purpose registers */
> > + stp x0, x1, [sp, #16 * 0]
> > + stp x2, x3, [sp, #16 * 1]
> > + stp x4, x5, [sp, #16 * 2]
> > + stp x6, x7, [sp, #16 * 3]
> > + stp x8, x9, [sp, #16 * 4]
> > + stp x10, x11, [sp, #16 * 5]
> > + stp x12, x13, [sp, #16 * 6]
> > + stp x14, x15, [sp, #16 * 7]
> > + stp x16, x17, [sp, #16 * 8]
> > + stp x18, x19, [sp, #16 * 9]
> > + stp x20, x21, [sp, #16 * 10]
> > + stp x22, x23, [sp, #16 * 11]
> > + stp x24, x25, [sp, #16 * 12]
> > + stp x26, x27, [sp, #16 * 13]
> > + stp x28, x29, [sp, #16 * 14]
> > +
> > + /* Save LR and exception PC */
> > + mrs x21, elr_el1
> > + stp x30, x21, [sp, #16 * 15]
> > +
> > + /* Save pstate and exception status register */
> > + mrs x22, spsr_el1
> > + mrs x23, esr_el1
> > + stp x22, x23, [sp, #16 * 16]
> > +
> > + /* Save stack pointer for lower level exception */
> > +.if \el == 0
> > + mrs x18, sp_el0
> > +.else
> > + add x18, sp, #TRAP_STACK_SIZE
> > +.endif
> > + str x18, [sp, #16 * 17]
> > +.endm
> > +
> > +.macro LEAVE_TRAP, el
> > + /* Mask IRQ to make sure restore would not be interrupted by IRQ */
> > + msr daifset, #2
> > +
> > + /* Restore stack pointer for lower level exception */
> > + ldr x18, [sp, #16 * 17]
> > +.if \el == 0
> > + msr sp_el0, x18
> > +.endif
> > +
> > + /* Restore pstate and exception status register */
> > + ldp x22, x23, [sp, #16 * 16]
> > + msr spsr_el1, x22
> > + msr esr_el1, x23
> > +
> > + /* Restore LR and exception PC */
> > + ldp x30, x21, [sp, #16 * 15]
> > + msr elr_el1, x21
> > +
> > + /* Restore general purpose registers */
> > + ldp x28, x29, [sp, #16 * 14]
> > + ldp x26, x27, [sp, #16 * 13]
> > + ldp x24, x25, [sp, #16 * 12]
> > + ldp x22, x23, [sp, #16 * 11]
> > + ldp x20, x21, [sp, #16 * 10]
> > + ldp x18, x19, [sp, #16 * 9]
> > + ldp x16, x17, [sp, #16 * 8]
> > + ldp x14, x15, [sp, #16 * 7]
> > + ldp x12, x13, [sp, #16 * 6]
> > + ldp x10, x11, [sp, #16 * 5]
> > + ldp x8, x9, [sp, #16 * 4]
> > + ldp x6, x7, [sp, #16 * 3]
> > + ldp x4, x5, [sp, #16 * 2]
> > + ldp x2, x3, [sp, #16 * 1]
> > + ldp x0, x1, [sp, #16 * 0]
> > +
> > + eret
> > +.endm
> > +
> > +/*
> > + * Most aarch64 SoC is using 64-byte cache line. Align the
> > + * exception handlers to 64-byte will benefit the cache hit
> > + * rate of handlers.
> > + */
> > +.align 6
> > +el1_sync:
> > + ENTER_TRAP 1
> > + mov x0, sp
> > + mrs x1, far_el1
> > + bl trap_el1_sync
> > + LEAVE_TRAP 1
> > +
> > +/* Bad Abort numbers */
> > +#define BAD_SYNC 0
> > +#define BAD_IRQ 1
> > +#define BAD_FIQ 2
> > +#define BAD_ERROR 3
> > +
> > +#define el_invalid(name, reason, el) \
> > +.align 6; \
> > +name##_invalid: \
> > + ENTER_TRAP el; \
> > + mov x0, sp; \
> > + mov x1, el; \
> > + mov x2, #(reason); \
> > + mrs x3, far_el1; \
> > + b invalid_trap_handler; \
> > +ENDPROC(name##_invalid); \
> > +
> > +el_invalid(el1_sync, BAD_SYNC, 1);
> > +el_invalid(el0_sync, BAD_SYNC, 0);
> > +el_invalid(el1_irq, BAD_IRQ, 1);
> > +el_invalid(el0_irq, BAD_IRQ, 0);
> > +el_invalid(el1_fiq, BAD_FIQ, 1);
> > +el_invalid(el0_fiq, BAD_FIQ, 0);
> > +el_invalid(el1_error, BAD_ERROR, 1);
> > +el_invalid(el0_error, BAD_ERROR, 0);
> > +
> > +/*
> > + * Macro for Exception vectors.
> > + */
> > +.macro vector_entry label
> > +.align 7
> > + b \label
> > +.endm
> > +
> > +/*
> > + * Exception vectors.
> > + *
> > + * AArch64 unikernel runs in EL1 mode using the SP_EL1 stack. The vectors
> > + * don't have a fixed address, only alignment (2^11) requirements.
> > + */
> > +.align 11
> > +ENTRY(vector_table)
> > + /* Current Exception level with SP_EL0 */
> > + vector_entry el1_sync_invalid /* Synchronous EL1t */
> > + vector_entry el1_irq_invalid /* IRQ EL1t */
> > + vector_entry el1_fiq_invalid /* FIQ EL1t */
> > + vector_entry el1_error_invalid /* Error EL1t */
> > +
> > + /* Current Exception level with SP_EL1 */
> > + vector_entry el1_sync /* Synchronous EL1h */
> > + vector_entry el1_irq_invalid /* IRQ EL1h */
> > + vector_entry el1_fiq_invalid /* FIQ EL1h */
> > + vector_entry el1_error_invalid /* Error EL1h */
> > +
> > + /* Lower Exception level using AArch64 */
> > + vector_entry el0_sync_invalid /* Synchronous 64-bit EL0 */
> > + vector_entry el0_irq_invalid /* IRQ 64-bit EL0 */
> > + vector_entry el0_fiq_invalid /* FIQ 64-bit EL0 */
> > + vector_entry el0_error_invalid /* Error 64-bit EL0 */
> > +
> > + /* Lower Exception level using AArch32 */
> > + vector_entry el0_sync_invalid /* Synchronous 32-bit EL0 */
> > + vector_entry el0_irq_invalid /* IRQ 32-bit EL0 */
> > + vector_entry el0_fiq_invalid /* FIQ 32-bit EL0 */
> > + vector_entry el0_error_invalid /* Error 32-bit EL0 */
> > +END(vector_table)
> >
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |