[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH v5 4/7] plat/arm: Support fp/simd save/restore during context switch
Floating point feature is useful for some applications. We should save/restore fp registers during context switch. Signed-off-by: Jia He <justin.he@xxxxxxx> --- plat/common/arm/fp_arm64.c | 79 +++++++++++++++++++++++++++++ plat/common/include/arm/arm64/cpu.h | 46 ++++++++++++++++- plat/kvm/Makefile.uk | 3 +- 3 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 plat/common/arm/fp_arm64.c diff --git a/plat/common/arm/fp_arm64.c b/plat/common/arm/fp_arm64.c new file mode 100644 index 0000000..87ee75d --- /dev/null +++ b/plat/common/arm/fp_arm64.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: ISC */ +/* + * Authors: Jia He <justin.he@xxxxxxx> + * + * Copyright (c) 2020 Arm Ltd. + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear + * in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <uk/plat/common/cpu.h> + +void fpsimd_save_state(uintptr_t ptr) +{ + __u32 fpcr, fpsr; + + __asm__ __volatile__( + "mrs %0, fpcr\n" + "mrs %1, fpsr\n" + "stp q0, q1, [%2, #16 * 0]\n" + "stp q2, q3, [%2, #16 * 2]\n" + "stp q4, q5, [%2, #16 * 4]\n" + "stp q6, q7, [%2, #16 * 6]\n" + "stp q8, q9, [%2, #16 * 8]\n" + "stp q10, q11, [%2, #16 * 10]\n" + "stp q12, q13, [%2, #16 * 12]\n" + "stp q14, q15, [%2, #16 * 14]\n" + "stp q16, q17, [%2, #16 * 16]\n" + "stp q18, q19, [%2, #16 * 18]\n" + "stp q20, q21, [%2, #16 * 20]\n" + "stp q22, q23, [%2, #16 * 22]\n" + "stp q24, q25, [%2, #16 * 24]\n" + "stp q26, q27, [%2, #16 * 26]\n" + "stp q28, q29, [%2, #16 * 28]\n" + "stp q30, q31, [%2, #16 * 30]\n" + : "=&r"(fpcr), "=&r"(fpsr) : "r"(ptr)); + + ((struct fpsimd_state *)ptr)->fpcr = fpcr; + ((struct fpsimd_state *)ptr)->fpsr = fpsr; +} + +void fpsimd_restore_state(uintptr_t ptr) +{ + __u32 fpcr, fpsr; + + fpcr = ((struct fpsimd_state *)ptr)->fpcr; + fpsr = ((struct fpsimd_state *)ptr)->fpsr; + + __asm__ __volatile__( + "ldp q0, q1, [%2, #16 * 0]\n" + "ldp q2, q3, [%2, #16 * 2]\n" + "ldp q4, q5, [%2, #16 * 4]\n" + "ldp q6, q7, [%2, #16 * 6]\n" + "ldp q8, q9, [%2, #16 * 8]\n" + "ldp q10, q11, [%2, #16 * 10]\n" + "ldp q12, q13, [%2, #16 * 12]\n" + "ldp q14, q15, [%2, #16 * 14]\n" + "ldp q16, q17, [%2, #16 * 16]\n" + "ldp q18, q19, [%2, #16 * 18]\n" + "ldp q20, q21, [%2, #16 * 20]\n" + "ldp q22, q23, [%2, #16 * 22]\n" + "ldp q24, q25, [%2, #16 * 24]\n" + "ldp q26, q27, [%2, #16 * 26]\n" + "ldp q28, q29, [%2, #16 * 28]\n" + "ldp q30, q31, [%2, #16 * 30]\n" + "msr fpcr, %0\n" + "msr fpsr, %1\n" + : : "r"(fpcr), "r"(fpsr), "r"(ptr)); +} diff --git a/plat/common/include/arm/arm64/cpu.h b/plat/common/include/arm/arm64/cpu.h index 122727a..93ad13b 100644 --- a/plat/common/include/arm/arm64/cpu.h +++ b/plat/common/include/arm/arm64/cpu.h @@ -116,6 +116,47 @@ void halt(void); void reset(void); void system_off(void); +#ifdef CONFIG_FPSIMD +struct fpsimd_state { + __u64 regs[32 * 2]; + __u32 fpsr; + __u32 fpcr; +}; + +extern void fpsimd_save_state(uintptr_t ptr); +extern void fpsimd_restore_state(uintptr_t ptr); + +static inline void save_extregs(struct sw_ctx *ctx) +{ + fpsimd_save_state(ctx->extregs); +} + +static inline void restore_extregs(struct sw_ctx *ctx) +{ + fpsimd_restore_state(ctx->extregs); +} + +static inline struct sw_ctx *arch_alloc_sw_ctx(struct uk_alloc *allocator) +{ + struct sw_ctx *ctx; + + ctx = (struct sw_ctx *)uk_malloc(allocator, + sizeof(struct sw_ctx) + sizeof(struct fpsimd_state)); + if (ctx) + ctx->extregs = (uintptr_t)((void *)ctx + sizeof(struct sw_ctx)); + + uk_pr_debug("Allocating %lu + %lu bytes for sw ctx at %p, extregs at %p\n", + sizeof(struct sw_ctx), sizeof(struct fpsimd_state), + ctx, (void *)ctx->extregs); + + return ctx; +} + +static inline void arch_init_extregs(struct sw_ctx *ctx __unused) +{ +} + +#else /* !CONFIG_FPSIMD */ static inline void save_extregs(struct sw_ctx *ctx __unused) { } @@ -128,9 +169,9 @@ static inline struct sw_ctx *arch_alloc_sw_ctx(struct uk_alloc *allocator) { struct sw_ctx *ctx; - ctx = uk_malloc(allocator, sizeof(struct sw_ctx)); + ctx = (struct sw_ctx *)uk_malloc(allocator, sizeof(struct sw_ctx)); uk_pr_debug("Allocating %lu bytes for sw ctx at %p\n", - sizeof(struct sw_ctx), ctx); + sizeof(struct sw_ctx), ctx); return ctx; } @@ -140,4 +181,5 @@ static inline void arch_init_extregs(struct sw_ctx *ctx) ctx->extregs = (uintptr_t)ctx + sizeof(struct sw_ctx); } +#endif /* CONFIG_FPSIMD */ #endif /* __PLAT_COMMON_ARM64_CPU_H__ */ diff --git a/plat/kvm/Makefile.uk b/plat/kvm/Makefile.uk index a6d6f5e..9354d64 100644 --- a/plat/kvm/Makefile.uk +++ b/plat/kvm/Makefile.uk @@ -82,7 +82,8 @@ 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/psci_arm64.S|common 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/generic_timer.c|common -LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/traps.c|common +LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/traps.c|isr +LIBKVMPLAT_SRCS-$(CONFIG_FPSIMD) += $(UK_PLAT_COMMON_BASE)/arm/fp_arm64.c|isr ifeq ($(CONFIG_HAVE_SCHED),y) LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/thread_start64.S|common LIBKVMPLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/thread.c|common -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |