Commit b7e573bb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'arc-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/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
parents a1084542 f45ba2bd
......@@ -7,7 +7,7 @@
| arch |status|
-----------------------
| alpha: | TODO |
| arc: | TODO |
| arc: | ok |
| arm: | ok |
| arm64: | ok |
| c6x: | TODO |
......
......@@ -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
......@@ -350,9 +351,8 @@ 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
......@@ -360,14 +360,10 @@ config ARC_COMPACT_IRQ_LEVELS
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
......
......@@ -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>;
......
......@@ -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
......
/* 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 */
......@@ -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 {
......
......@@ -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);
......@@ -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)
......
......@@ -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);
......
......@@ -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
......
......@@ -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
......
......@@ -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.
......
......@@ -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.
......@@ -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
......@@ -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;
......@@ -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() */
......@@ -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 =
......@@ -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;
......@@ -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;
......
......@@ -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),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment