Skip to content

Commit

Permalink
Merge tag 'arc-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/vgupta/arc

Pull ARC updates from Vineet Gupta:

 - Wire up clone3 syscall

 - ARCv2 FPU state save/restore across context switch

 - AXS10x platform and misc fixes

* tag 'arc-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  ARCv2: fpu: preserve userspace fpu state
  ARC: fpu: declutter code, move bits out into fpu.h
  ARC: wireup clone3 syscall
  ARC: [plat-axs10x]: Add missing multicast filter number to GMAC node
  ARC: update feature support for jump-labels
  • Loading branch information
torvalds committed Jan 31, 2020
2 parents a108454 + f45ba2b commit b7e573b
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 41 deletions.
2 changes: 1 addition & 1 deletion Documentation/features/core/jump-labels/arch-support.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
| arch |status|
-----------------------
| alpha: | TODO |
| arc: | TODO |
| arc: | ok |
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
Expand Down
16 changes: 6 additions & 10 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ config ARC
select GENERIC_SMP_IDLE_THREAD
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
select HAVE_COPY_THREAD_TLS
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DEBUG_KMEMLEAK
select HAVE_FUTEX_CMPXCHG if FUTEX
Expand Down Expand Up @@ -350,24 +351,19 @@ config NODES_SHIFT
Accessing memory beyond 1GB (with or w/o PAE) requires 2 memory
zones.

if ISA_ARCOMPACT

config ARC_COMPACT_IRQ_LEVELS
depends on ISA_ARCOMPACT
bool "Setup Timer IRQ as high Priority"
# if SMP, LV2 enabled ONLY if ARC implementation has LV2 re-entrancy
depends on !SMP

config ARC_FPU_SAVE_RESTORE
bool "Enable FPU state persistence across context switch"
help
Double Precision Floating Point unit had dedicated regs which
need to be saved/restored across context-switch.
Note that ARC FPU is overly simplistic, unlike say x86, which has
hardware pieces to allow software to conditionally save/restore,
based on actual usage of FPU by a task. Thus our implemn does
this for all tasks in system.

endif #ISA_ARCOMPACT
ARCompact FPU has internal registers to assist with Double precision
Floating Point operations. There are control and stauts registers
for floating point exceptions and rounding modes. These are
preserved across task context switch when enabled.

config ARC_CANT_LLSC
def_bool n
Expand Down
1 change: 1 addition & 0 deletions arch/arc/boot/dts/axs10x_mb.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
interrupt-names = "macirq";
phy-mode = "rgmii";
snps,pbl = < 32 >;
snps,multicast-filter-bins = <256>;
clocks = <&apbclk>;
clock-names = "stmmaceth";
max-speed = <100>;
Expand Down
2 changes: 2 additions & 0 deletions arch/arc/include/asm/arcregs.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#define ARC_REG_CLUSTER_BCR 0xcf
#define ARC_REG_AUX_ICCM 0x208 /* ICCM Base Addr (ARCv2) */
#define ARC_REG_LPB_CTRL 0x488 /* ARCv2 Loop Buffer control */
#define ARC_REG_FPU_CTRL 0x300
#define ARC_REG_FPU_STATUS 0x301

/* Common for ARCompact and ARCv2 status register */
#define ARC_REG_STATUS32 0x0A
Expand Down
55 changes: 55 additions & 0 deletions arch/arc/include/asm/fpu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
*
*/

#ifndef _ASM_ARC_FPU_H
#define _ASM_ARC_FPU_H

#ifdef CONFIG_ARC_FPU_SAVE_RESTORE

#include <asm/ptrace.h>

#ifdef CONFIG_ISA_ARCOMPACT

/* These DPFP regs need to be saved/restored across ctx-sw */
struct arc_fpu {
struct {
unsigned int l, h;
} aux_dpfp[2];
};

#define fpu_init_task(regs)

#else

/*
* ARCv2 FPU Control aux register
* - bits to enable Traps on Exceptions
* - Rounding mode
*
* ARCv2 FPU Status aux register
* - FPU exceptions flags (Inv, Div-by-Zero, overflow, underflow, inexact)
* - Flag Write Enable to clear flags explicitly (vs. by fpu instructions
* only
*/

struct arc_fpu {
unsigned int ctrl, status;
};

extern void fpu_init_task(struct pt_regs *regs);

#endif /* !CONFIG_ISA_ARCOMPACT */

extern void fpu_save_restore(struct task_struct *p, struct task_struct *n);

#else /* !CONFIG_ARC_FPU_SAVE_RESTORE */

#define fpu_save_restore(p, n)
#define fpu_init_task(regs)

#endif /* CONFIG_ARC_FPU_SAVE_RESTORE */

#endif /* _ASM_ARC_FPU_H */
10 changes: 1 addition & 9 deletions arch/arc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,7 @@
#ifndef __ASSEMBLY__

#include <asm/ptrace.h>

#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
/* These DPFP regs need to be saved/restored across ctx-sw */
struct arc_fpu {
struct {
unsigned int l, h;
} aux_dpfp[2];
};
#endif
#include <asm/fpu.h>

#ifdef CONFIG_ARC_PLAT_EZNPS
struct eznps_dp {
Expand Down
17 changes: 2 additions & 15 deletions arch/arc/include/asm/switch_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,7 @@
#ifndef __ASSEMBLY__

#include <linux/sched.h>

#ifdef CONFIG_ARC_FPU_SAVE_RESTORE

extern void fpu_save_restore(struct task_struct *p, struct task_struct *n);
#define ARC_FPU_PREV(p, n) fpu_save_restore(p, n)
#define ARC_FPU_NEXT(t)

#else

#define ARC_FPU_PREV(p, n)
#define ARC_FPU_NEXT(n)

#endif /* !CONFIG_ARC_FPU_SAVE_RESTORE */
#include <asm/fpu.h>

#ifdef CONFIG_ARC_PLAT_EZNPS
extern void dp_save_restore(struct task_struct *p, struct task_struct *n);
Expand All @@ -36,9 +24,8 @@ struct task_struct *__switch_to(struct task_struct *p, struct task_struct *n);
#define switch_to(prev, next, last) \
do { \
ARC_EZNPS_DP_PREV(prev, next); \
ARC_FPU_PREV(prev, next); \
fpu_save_restore(prev, next); \
last = __switch_to(prev, next);\
ARC_FPU_NEXT(next); \
mb(); \
} while (0)

Expand Down
1 change: 1 addition & 0 deletions arch/arc/include/asm/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/types.h>

int sys_clone_wrapper(int, int, int, int, int);
int sys_clone3_wrapper(void *, size_t);
int sys_cacheflush(uint32_t, uint32_t uint32_t);
int sys_arc_settls(void *);
int sys_arc_gettls(void);
Expand Down
1 change: 1 addition & 0 deletions arch/arc/include/uapi/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define __ARCH_WANT_SET_GET_RLIMIT
#define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_SYS_CLONE
#define __ARCH_WANT_SYS_CLONE3
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_TIME32_SYSCALLS
Expand Down
2 changes: 2 additions & 0 deletions arch/arc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o

obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o
ifdef CONFIG_ISA_ARCOMPACT
CFLAGS_fpu.o += -mdpfp
endif

ifdef CONFIG_ARC_DW2_UNWIND
CFLAGS_ctx_sw.o += -fno-omit-frame-pointer
Expand Down
12 changes: 12 additions & 0 deletions arch/arc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ ENTRY(sys_clone_wrapper)
b .Lret_from_system_call
END(sys_clone_wrapper)

ENTRY(sys_clone3_wrapper)
SAVE_CALLEE_SAVED_USER
bl @sys_clone3
DISCARD_CALLEE_SAVED_USER

GET_CURR_THR_INFO_FLAGS r10
btst r10, TIF_SYSCALL_TRACE
bnz tracesys_exit

b .Lret_from_system_call
END(sys_clone3_wrapper)

ENTRY(ret_from_fork)
; when the forked child comes here from the __switch_to function
; r0 has the last task pointer.
Expand Down
29 changes: 28 additions & 1 deletion arch/arc/kernel/fpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
*/

#include <linux/sched.h>
#include <asm/switch_to.h>
#include <asm/fpu.h>

#ifdef CONFIG_ISA_ARCOMPACT

/*
* To save/restore FPU regs, simplest scheme would use LR/SR insns.
Expand Down Expand Up @@ -50,3 +52,28 @@ void fpu_save_restore(struct task_struct *prev, struct task_struct *next)
: "r" (zero), "r" (*(readfrom + 3)), "r" (*(readfrom + 2))
);
}

#else

void fpu_init_task(struct pt_regs *regs)
{
/* default rounding mode */
write_aux_reg(ARC_REG_FPU_CTRL, 0x100);

/* set "Write enable" to allow explicit write to exception flags */
write_aux_reg(ARC_REG_FPU_STATUS, 0x80000000);
}

void fpu_save_restore(struct task_struct *prev, struct task_struct *next)
{
struct arc_fpu *save = &prev->thread.fpu;
struct arc_fpu *restore = &next->thread.fpu;

save->ctrl = read_aux_reg(ARC_REG_FPU_CTRL);
save->status = read_aux_reg(ARC_REG_FPU_STATUS);

write_aux_reg(ARC_REG_FPU_CTRL, restore->ctrl);
write_aux_reg(ARC_REG_FPU_STATUS, restore->status);
}

#endif
13 changes: 8 additions & 5 deletions arch/arc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <linux/elf.h>
#include <linux/tick.h>

#include <asm/fpu.h>

SYSCALL_DEFINE1(arc_settls, void *, user_tls_data_ptr)
{
task_thread_info(current)->thr_ptr = (unsigned int)user_tls_data_ptr;
Expand Down Expand Up @@ -171,9 +173,8 @@ asmlinkage void ret_from_fork(void);
* | user_r25 |
* ------------------ <===== END of PAGE
*/
int copy_thread(unsigned long clone_flags,
unsigned long usp, unsigned long kthread_arg,
struct task_struct *p)
int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
unsigned long kthread_arg, struct task_struct *p, unsigned long tls)
{
struct pt_regs *c_regs; /* child's pt_regs */
unsigned long *childksp; /* to unwind out of __switch_to() */
Expand Down Expand Up @@ -231,7 +232,7 @@ int copy_thread(unsigned long clone_flags,
* set task's userland tls data ptr from 4th arg
* clone C-lib call is difft from clone sys-call
*/
task_thread_info(p)->thr_ptr = regs->r3;
task_thread_info(p)->thr_ptr = tls;
} else {
/* Normal fork case: set parent's TLS ptr in child */
task_thread_info(p)->thr_ptr =
Expand Down Expand Up @@ -264,7 +265,7 @@ int copy_thread(unsigned long clone_flags,
/*
* Do necessary setup to start up a new user task
*/
void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp)
void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
{
regs->sp = usp;
regs->ret = pc;
Expand All @@ -280,6 +281,8 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp)
regs->eflags = 0;
#endif

fpu_init_task(regs);

/* bogus seed values for debugging */
regs->lp_start = 0x10;
regs->lp_end = 0x80;
Expand Down
1 change: 1 addition & 0 deletions arch/arc/kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <asm/syscalls.h>

#define sys_clone sys_clone_wrapper
#define sys_clone3 sys_clone3_wrapper

#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),
Expand Down

0 comments on commit b7e573b

Please sign in to comment.