From 58f45934780aff54a4ddfabd06094d8bd725b702 Mon Sep 17 00:00:00 2001 From: "TOIDA,Suguru" Date: Tue, 20 Aug 2019 12:15:45 +0900 Subject: [PATCH] fork: fpregs: return error code. Change-Id: I6ff150a39cd8952adad9b21d0c9f8514126ef957 --- arch/arm64/kernel/cpu.c | 38 ++++++++++++++++++++---------- arch/arm64/kernel/fpsimd.c | 10 ++++---- arch/arm64/kernel/include/fpsimd.h | 2 +- arch/x86_64/kernel/cpu.c | 30 ++++++++++++++++------- kernel/include/process.h | 6 ++--- 5 files changed, 56 insertions(+), 30 deletions(-) diff --git a/arch/arm64/kernel/cpu.c b/arch/arm64/kernel/cpu.c index d7490247..7de26fbd 100644 --- a/arch/arm64/kernel/cpu.c +++ b/arch/arm64/kernel/cpu.c @@ -1,4 +1,4 @@ -/* cpu.c COPYRIGHT FUJITSU LIMITED 2015-2018 */ +/* cpu.c COPYRIGHT FUJITSU LIMITED 2015-2019 */ #include #include #include @@ -1240,7 +1240,6 @@ err: } static int check_and_allocate_fp_regs(struct thread *thread); -void save_fp_regs(struct thread *thread); void arch_clone_thread(struct thread *othread, unsigned long pc, unsigned long sp, struct thread *nthread) @@ -1481,8 +1480,7 @@ check_and_allocate_fp_regs(struct thread *thread) if (!thread->fp_regs) { kprintf("error: allocating fp_regs pages\n"); - result = 1; - panic("panic: error allocating fp_regs pages"); + result = -ENOMEM; goto out; } @@ -1491,37 +1489,51 @@ check_and_allocate_fp_regs(struct thread *thread) #ifdef CONFIG_ARM64_SVE if (likely(elf_hwcap & HWCAP_SVE)) { - sve_alloc(thread); + result = sve_alloc(thread); } #endif /* CONFIG_ARM64_SVE */ out: + if (result) { + release_fp_regs(thread); + } return result; } /*@ @ requires \valid(thread); @*/ -void +int save_fp_regs(struct thread *thread) { + int ret = 0; if (thread == &cpu_local_var(idle)) { - return; + goto out; } if (likely(elf_hwcap & (HWCAP_FP | HWCAP_ASIMD))) { - if (check_and_allocate_fp_regs(thread) != 0) { - // alloc error. - return; + ret = check_and_allocate_fp_regs(thread); + if (ret) { + goto out; } thread_fpsimd_save(thread); } +out: + return ret; } -void copy_fp_regs(struct thread *from, struct thread *to) +int copy_fp_regs(struct thread *from, struct thread *to) { - if ((from->fp_regs != NULL) && (check_and_allocate_fp_regs(to) == 0)) { - memcpy(to->fp_regs, from->fp_regs, sizeof(fp_regs_struct)); + int ret = 0; + + if (from->fp_regs != NULL) { + ret = check_and_allocate_fp_regs(to); + if (!ret) { + memcpy(to->fp_regs, + from->fp_regs, + sizeof(fp_regs_struct)); + } } + return ret; } void clear_fp_regs(void) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 37358ef0..60bfa309 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -119,17 +119,19 @@ void sve_free(struct thread *thread) } } -void sve_alloc(struct thread *thread) +int sve_alloc(struct thread *thread) { if (thread->ctx.thread->sve_state) { - return; + return 0; } thread->ctx.thread->sve_state = kmalloc(sve_state_size(thread), IHK_MC_AP_NOWAIT); - BUG_ON(!thread->ctx.thread->sve_state); - + if (thread->ctx.thread->sve_state == NULL) { + return -ENOMEM; + } memset(thread->ctx.thread->sve_state, 0, sve_state_size(thread)); + return 0; } static int get_nr_threads(struct process *proc) diff --git a/arch/arm64/kernel/include/fpsimd.h b/arch/arm64/kernel/include/fpsimd.h index 1a099c23..ef988b16 100644 --- a/arch/arm64/kernel/include/fpsimd.h +++ b/arch/arm64/kernel/include/fpsimd.h @@ -42,7 +42,7 @@ extern void thread_sve_to_fpsimd(struct thread *thread, fp_regs_struct *fp_regs) extern size_t sve_state_size(struct thread const *thread); extern void sve_free(struct thread *thread); -extern void sve_alloc(struct thread *thread); +extern int sve_alloc(struct thread *thread); extern void sve_save_state(void *state, unsigned int *pfpsr); extern void sve_load_state(void const *state, unsigned int const *pfpsr, unsigned long vq_minus_1); extern unsigned int sve_get_vl(void); diff --git a/arch/x86_64/kernel/cpu.c b/arch/x86_64/kernel/cpu.c index 2ba5bd36..007f162d 100644 --- a/arch/x86_64/kernel/cpu.c +++ b/arch/x86_64/kernel/cpu.c @@ -1,4 +1,4 @@ -/* cpu.c COPYRIGHT FUJITSU LIMITED 2018 */ +/* cpu.c COPYRIGHT FUJITSU LIMITED 2018-2019 */ /** * \file cpu.c * License details are found in the file LICENSE. @@ -1709,7 +1709,7 @@ check_and_allocate_fp_regs(struct thread *thread) if (!thread->fp_regs) { kprintf("error: allocating fp_regs pages\n"); - result = 1; + result = -ENOMEM; goto out; } @@ -1722,12 +1722,14 @@ out: /*@ @ requires \valid(thread); @*/ -void +int save_fp_regs(struct thread *thread) { - if (check_and_allocate_fp_regs(thread) != 0) { - // alloc error - return; + int ret = 0; + + ret = check_and_allocate_fp_regs(thread); + if (ret) { + goto out; } if (xsave_available) { @@ -1742,13 +1744,23 @@ save_fp_regs(struct thread *thread) dkprintf("fp_regs for TID %d saved\n", thread->tid); } +out: + return ret; } -void copy_fp_regs(struct thread *from, struct thread *to) +int copy_fp_regs(struct thread *from, struct thread *to) { - if ((from->fp_regs != NULL) && (check_and_allocate_fp_regs(to) == 0)) { - memcpy(to->fp_regs, from->fp_regs, sizeof(fp_regs_struct)); + int ret = 0; + + if (from->fp_regs != NULL) { + ret = check_and_allocate_fp_regs(to); + if (!ret) { + memcpy(to->fp_regs, + from->fp_regs, + sizeof(fp_regs_struct)); + } } + return ret; } /*@ diff --git a/kernel/include/process.h b/kernel/include/process.h index 8a4a0f59..409e1d2d 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -9,7 +9,7 @@ /* * HISTORY */ -/* process.h COPYRIGHT FUJITSU LIMITED 2015-2018 */ +/* process.h COPYRIGHT FUJITSU LIMITED 2015-2019 */ #ifndef HEADER_PROCESS_H #define HEADER_PROCESS_H @@ -914,8 +914,8 @@ extern void check_sig_pending(void); void clear_single_step(struct thread *thread); void release_fp_regs(struct thread *proc); -void save_fp_regs(struct thread *proc); -void copy_fp_regs(struct thread *from, struct thread *to); +int save_fp_regs(struct thread *proc); +int copy_fp_regs(struct thread *from, struct thread *to); void restore_fp_regs(struct thread *proc); void clear_fp_regs(void);