aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/sparc/crypto/sha256_glue.c14
-rw-r--r--arch/sparc/include/asm/atomic_32.h2
-rw-r--r--arch/sparc/include/asm/atomic_64.h1
-rw-r--r--arch/sparc/include/asm/ide.h1
-rw-r--r--arch/sparc/include/asm/percpu_64.h2
-rw-r--r--arch/sparc/include/asm/sparsemem.h1
-rw-r--r--arch/sparc/include/asm/syscalls.h7
-rw-r--r--arch/sparc/include/asm/timer_64.h1
-rw-r--r--arch/sparc/include/asm/tlb_64.h1
-rw-r--r--arch/sparc/include/asm/trap_block.h2
-rw-r--r--arch/sparc/include/asm/uaccess_32.h2
-rw-r--r--arch/sparc/include/asm/uaccess_64.h2
-rw-r--r--arch/sparc/include/asm/vvar.h3
-rw-r--r--arch/sparc/kernel/Makefile1
-rw-r--r--arch/sparc/kernel/entry.S29
-rw-r--r--arch/sparc/kernel/kernel.h11
-rw-r--r--arch/sparc/kernel/leon_smp.c1
-rw-r--r--arch/sparc/kernel/process.c110
-rw-r--r--arch/sparc/kernel/process_32.c83
-rw-r--r--arch/sparc/kernel/process_64.c106
-rw-r--r--arch/sparc/kernel/ptrace_32.c269
-rw-r--r--arch/sparc/kernel/ptrace_64.c591
-rw-r--r--arch/sparc/kernel/setup_32.c2
-rw-r--r--arch/sparc/kernel/setup_64.c2
-rw-r--r--arch/sparc/kernel/signal_32.c1
-rw-r--r--arch/sparc/kernel/smp_32.c1
-rw-r--r--arch/sparc/kernel/smp_64.c1
-rw-r--r--arch/sparc/kernel/sun4m_irq.c1
-rw-r--r--arch/sparc/kernel/sys32.S12
-rw-r--r--arch/sparc/kernel/syscalls.S23
-rw-r--r--arch/sparc/kernel/syscalls/syscall.tbl5
-rw-r--r--arch/sparc/kernel/vdso.c1
-rw-r--r--arch/sparc/mm/fault_32.c13
-rw-r--r--arch/sparc/mm/fault_64.c11
-rw-r--r--arch/sparc/mm/highmem.c1
-rw-r--r--arch/sparc/mm/init_64.c1
-rw-r--r--arch/sparc/mm/io-unit.c1
-rw-r--r--arch/sparc/mm/iommu.c1
-rw-r--r--arch/sparc/mm/tlb.c1
-rw-r--r--arch/sparc/vdso/Makefile4
41 files changed, 610 insertions, 714 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 5bf2dc163540..efeff2c896a5 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -15,6 +15,7 @@ config SPARC
default y
select ARCH_MIGHT_HAVE_PC_PARPORT if SPARC64 && PCI
select ARCH_MIGHT_HAVE_PC_SERIO
+ select DMA_OPS
select OF
select OF_PROMTREE
select HAVE_ASM_MODVERSIONS
@@ -80,7 +81,6 @@ config SPARC64
select RTC_DRV_STARFIRE
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
- select IRQ_PREFLOW_FASTEOI
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select HAVE_C_RECORDMCOUNT
select HAVE_ARCH_AUDITSYSCALL
diff --git a/arch/sparc/crypto/sha256_glue.c b/arch/sparc/crypto/sha256_glue.c
index 286bc8ecf15b..ca2547df9652 100644
--- a/arch/sparc/crypto/sha256_glue.c
+++ b/arch/sparc/crypto/sha256_glue.c
@@ -156,7 +156,7 @@ static int sha256_sparc64_import(struct shash_desc *desc, const void *in)
return 0;
}
-static struct shash_alg sha256 = {
+static struct shash_alg sha256_alg = {
.digestsize = SHA256_DIGEST_SIZE,
.init = sha256_sparc64_init,
.update = sha256_sparc64_update,
@@ -174,7 +174,7 @@ static struct shash_alg sha256 = {
}
};
-static struct shash_alg sha224 = {
+static struct shash_alg sha224_alg = {
.digestsize = SHA224_DIGEST_SIZE,
.init = sha224_sparc64_init,
.update = sha256_sparc64_update,
@@ -206,13 +206,13 @@ static bool __init sparc64_has_sha256_opcode(void)
static int __init sha256_sparc64_mod_init(void)
{
if (sparc64_has_sha256_opcode()) {
- int ret = crypto_register_shash(&sha224);
+ int ret = crypto_register_shash(&sha224_alg);
if (ret < 0)
return ret;
- ret = crypto_register_shash(&sha256);
+ ret = crypto_register_shash(&sha256_alg);
if (ret < 0) {
- crypto_unregister_shash(&sha224);
+ crypto_unregister_shash(&sha224_alg);
return ret;
}
@@ -225,8 +225,8 @@ static int __init sha256_sparc64_mod_init(void)
static void __exit sha256_sparc64_mod_fini(void)
{
- crypto_unregister_shash(&sha224);
- crypto_unregister_shash(&sha256);
+ crypto_unregister_shash(&sha224_alg);
+ crypto_unregister_shash(&sha256_alg);
}
module_init(sha256_sparc64_mod_init);
diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h
index 94c930f0bc62..efad5532f169 100644
--- a/arch/sparc/include/asm/atomic_32.h
+++ b/arch/sparc/include/asm/atomic_32.h
@@ -18,8 +18,6 @@
#include <asm/barrier.h>
#include <asm-generic/atomic64.h>
-#define ATOMIC_INIT(i) { (i) }
-
int atomic_add_return(int, atomic_t *);
int atomic_fetch_add(int, atomic_t *);
int atomic_fetch_and(int, atomic_t *);
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index b60448397d4f..6b235d3d1d9d 100644
--- a/arch/sparc/include/asm/atomic_64.h
+++ b/arch/sparc/include/asm/atomic_64.h
@@ -12,7 +12,6 @@
#include <asm/cmpxchg.h>
#include <asm/barrier.h>
-#define ATOMIC_INIT(i) { (i) }
#define ATOMIC64_INIT(i) { (i) }
#define atomic_read(v) READ_ONCE((v)->counter)
diff --git a/arch/sparc/include/asm/ide.h b/arch/sparc/include/asm/ide.h
index 499aa2e6e276..904cc6cbc155 100644
--- a/arch/sparc/include/asm/ide.h
+++ b/arch/sparc/include/asm/ide.h
@@ -13,7 +13,6 @@
#include <asm/io.h>
#ifdef CONFIG_SPARC64
-#include <asm/pgalloc.h>
#include <asm/spitfire.h>
#include <asm/cacheflush.h>
#include <asm/page.h>
diff --git a/arch/sparc/include/asm/percpu_64.h b/arch/sparc/include/asm/percpu_64.h
index 32ef6f05cc56..a8786a4b90b6 100644
--- a/arch/sparc/include/asm/percpu_64.h
+++ b/arch/sparc/include/asm/percpu_64.h
@@ -4,7 +4,9 @@
#include <linux/compiler.h>
+#ifndef BUILD_VDSO
register unsigned long __local_per_cpu_offset asm("g5");
+#endif
#ifdef CONFIG_SMP
diff --git a/arch/sparc/include/asm/sparsemem.h b/arch/sparc/include/asm/sparsemem.h
index 1dd1b61432db..aa9a676bc341 100644
--- a/arch/sparc/include/asm/sparsemem.h
+++ b/arch/sparc/include/asm/sparsemem.h
@@ -7,7 +7,6 @@
#include <asm/page.h>
#define SECTION_SIZE_BITS 30
-#define MAX_PHYSADDR_BITS MAX_PHYS_ADDRESS_BITS
#define MAX_PHYSMEM_BITS MAX_PHYS_ADDRESS_BITS
#endif /* !(__KERNEL__) */
diff --git a/arch/sparc/include/asm/syscalls.h b/arch/sparc/include/asm/syscalls.h
index 1d819f5e21da..35575fbfb9dc 100644
--- a/arch/sparc/include/asm/syscalls.h
+++ b/arch/sparc/include/asm/syscalls.h
@@ -4,9 +4,8 @@
struct pt_regs;
-asmlinkage long sparc_do_fork(unsigned long clone_flags,
- unsigned long stack_start,
- struct pt_regs *regs,
- unsigned long stack_size);
+asmlinkage long sparc_fork(struct pt_regs *regs);
+asmlinkage long sparc_vfork(struct pt_regs *regs);
+asmlinkage long sparc_clone(struct pt_regs *regs);
#endif /* _SPARC64_SYSCALLS_H */
diff --git a/arch/sparc/include/asm/timer_64.h b/arch/sparc/include/asm/timer_64.h
index c7e4fb601a57..dcfad4613e18 100644
--- a/arch/sparc/include/asm/timer_64.h
+++ b/arch/sparc/include/asm/timer_64.h
@@ -7,6 +7,7 @@
#ifndef _SPARC64_TIMER_H
#define _SPARC64_TIMER_H
+#include <uapi/asm/asi.h>
#include <linux/types.h>
#include <linux/init.h>
diff --git a/arch/sparc/include/asm/tlb_64.h b/arch/sparc/include/asm/tlb_64.h
index 6820d357581c..e841cae544c2 100644
--- a/arch/sparc/include/asm/tlb_64.h
+++ b/arch/sparc/include/asm/tlb_64.h
@@ -4,7 +4,6 @@
#include <linux/swap.h>
#include <linux/pagemap.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
diff --git a/arch/sparc/include/asm/trap_block.h b/arch/sparc/include/asm/trap_block.h
index 0f6d0c4f6683..ace0d48e837e 100644
--- a/arch/sparc/include/asm/trap_block.h
+++ b/arch/sparc/include/asm/trap_block.h
@@ -2,6 +2,8 @@
#ifndef _SPARC_TRAP_BLOCK_H
#define _SPARC_TRAP_BLOCK_H
+#include <linux/threads.h>
+
#include <asm/hypervisor.h>
#include <asm/asi.h>
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index d6d8413eca83..0a2d3ebc4bb8 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -28,7 +28,7 @@
#define get_fs() (current->thread.current_ds)
#define set_fs(val) ((current->thread.current_ds) = (val))
-#define segment_eq(a, b) ((a).seg == (b).seg)
+#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
/* We have there a nice not-mapped page at PAGE_OFFSET - PAGE_SIZE, so that this test
* can be fairly lightweight.
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index bf9d330073b2..698cf69f74e9 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -32,7 +32,7 @@
#define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)})
-#define segment_eq(a, b) ((a).seg == (b).seg)
+#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
#define set_fs(val) \
do { \
diff --git a/arch/sparc/include/asm/vvar.h b/arch/sparc/include/asm/vvar.h
index 0289503d1cb0..6eaf5cfcaae1 100644
--- a/arch/sparc/include/asm/vvar.h
+++ b/arch/sparc/include/asm/vvar.h
@@ -6,7 +6,8 @@
#define _ASM_SPARC_VVAR_DATA_H
#include <asm/clocksource.h>
-#include <linux/seqlock.h>
+#include <asm/processor.h>
+#include <asm/barrier.h>
#include <linux/time.h>
#include <linux/types.h>
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 97c0e19263d1..d3a0e072ebe8 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -33,6 +33,7 @@ obj-y += irq_$(BITS).o
obj-$(CONFIG_SPARC32) += sun4m_irq.o sun4d_irq.o
obj-y += process_$(BITS).o
+obj-y += process.o
obj-y += signal_$(BITS).o
obj-y += sigutil_$(BITS).o
obj-$(CONFIG_SPARC32) += ioport.o
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index f636acf3312f..d58940280f8d 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -869,14 +869,11 @@ flush_patch_two:
ld [%curptr + TI_TASK], %o4
rd %psr, %g4
WRITE_PAUSE
- mov SIGCHLD, %o0 ! arg0: clone flags
rd %wim, %g5
WRITE_PAUSE
- mov %fp, %o1 ! arg1: usp
std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
- add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr
- mov 0, %o3
- call sparc_do_fork
+ add %sp, STACKFRAME_SZ, %o0
+ call sparc_fork
mov %l5, %o7
/* Whee, kernel threads! */
@@ -888,19 +885,11 @@ flush_patch_three:
ld [%curptr + TI_TASK], %o4
rd %psr, %g4
WRITE_PAUSE
-
- /* arg0,1: flags,usp -- loaded already */
- cmp %o1, 0x0 ! Is new_usp NULL?
rd %wim, %g5
WRITE_PAUSE
- be,a 1f
- mov %fp, %o1 ! yes, use callers usp
- andn %o1, 7, %o1 ! no, align to 8 bytes
-1:
std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
- add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr
- mov 0, %o3
- call sparc_do_fork
+ add %sp, STACKFRAME_SZ, %o0
+ call sparc_clone
mov %l5, %o7
/* Whee, real vfork! */
@@ -914,13 +903,9 @@ flush_patch_four:
rd %wim, %g5
WRITE_PAUSE
std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
- sethi %hi(0x4000 | 0x0100 | SIGCHLD), %o0
- mov %fp, %o1
- or %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0
- sethi %hi(sparc_do_fork), %l1
- mov 0, %o3
- jmpl %l1 + %lo(sparc_do_fork), %g0
- add %sp, STACKFRAME_SZ, %o2
+ sethi %hi(sparc_vfork), %l1
+ jmpl %l1 + %lo(sparc_vfork), %g0
+ add %sp, STACKFRAME_SZ, %o0
.align 4
linux_sparc_ni_syscall:
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index f6f498ba3198..9cd09a3ef35f 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -14,6 +14,11 @@ extern const char *sparc_pmu_type;
extern unsigned int fsr_storage;
extern int ncpus_probed;
+/* process{_32,_64}.c */
+asmlinkage long sparc_clone(struct pt_regs *regs);
+asmlinkage long sparc_fork(struct pt_regs *regs);
+asmlinkage long sparc_vfork(struct pt_regs *regs);
+
#ifdef CONFIG_SPARC64
/* setup_64.c */
struct seq_file;
@@ -153,12 +158,6 @@ void floppy_hardint(void);
extern unsigned long sun4m_cpu_startup;
extern unsigned long sun4d_cpu_startup;
-/* process_32.c */
-asmlinkage int sparc_do_fork(unsigned long clone_flags,
- unsigned long stack_start,
- struct pt_regs *regs,
- unsigned long stack_size);
-
/* signal_32.c */
asmlinkage void do_sigreturn(struct pt_regs *regs);
asmlinkage void do_rt_sigreturn(struct pt_regs *regs);
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 41829c024f92..1eed26d423fb 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -38,7 +38,6 @@
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/page.h>
-#include <asm/pgalloc.h>
#include <asm/oplib.h>
#include <asm/cpudata.h>
#include <asm/asi.h>
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
new file mode 100644
index 000000000000..5234b5ccc0b9
--- /dev/null
+++ b/arch/sparc/kernel/process.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * This file handles the architecture independent parts of process handling..
+ */
+
+#include <linux/compat.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/sched/task.h>
+#include <linux/sched/task_stack.h>
+#include <linux/signal.h>
+
+#include "kernel.h"
+
+asmlinkage long sparc_fork(struct pt_regs *regs)
+{
+ unsigned long orig_i1 = regs->u_regs[UREG_I1];
+ long ret;
+ struct kernel_clone_args args = {
+ .exit_signal = SIGCHLD,
+ /* Reuse the parent's stack for the child. */
+ .stack = regs->u_regs[UREG_FP],
+ };
+
+ ret = _do_fork(&args);
+
+ /* If we get an error and potentially restart the system
+ * call, we're screwed because copy_thread() clobbered
+ * the parent's %o1. So detect that case and restore it
+ * here.
+ */
+ if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
+ regs->u_regs[UREG_I1] = orig_i1;
+
+ return ret;
+}
+
+asmlinkage long sparc_vfork(struct pt_regs *regs)
+{
+ unsigned long orig_i1 = regs->u_regs[UREG_I1];
+ long ret;
+
+ struct kernel_clone_args args = {
+ .flags = CLONE_VFORK | CLONE_VM,
+ .exit_signal = SIGCHLD,
+ /* Reuse the parent's stack for the child. */
+ .stack = regs->u_regs[UREG_FP],
+ };
+
+ ret = _do_fork(&args);
+
+ /* If we get an error and potentially restart the system
+ * call, we're screwed because copy_thread() clobbered
+ * the parent's %o1. So detect that case and restore it
+ * here.
+ */
+ if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
+ regs->u_regs[UREG_I1] = orig_i1;
+
+ return ret;
+}
+
+asmlinkage long sparc_clone(struct pt_regs *regs)
+{
+ unsigned long orig_i1 = regs->u_regs[UREG_I1];
+ unsigned int flags = lower_32_bits(regs->u_regs[UREG_I0]);
+ long ret;
+
+ struct kernel_clone_args args = {
+ .flags = (flags & ~CSIGNAL),
+ .exit_signal = (flags & CSIGNAL),
+ .tls = regs->u_regs[UREG_I3],
+ };
+
+#ifdef CONFIG_COMPAT
+ if (test_thread_flag(TIF_32BIT)) {
+ args.pidfd = compat_ptr(regs->u_regs[UREG_I2]);
+ args.child_tid = compat_ptr(regs->u_regs[UREG_I4]);
+ args.parent_tid = compat_ptr(regs->u_regs[UREG_I2]);
+ } else
+#endif
+ {
+ args.pidfd = (int __user *)regs->u_regs[UREG_I2];
+ args.child_tid = (int __user *)regs->u_regs[UREG_I4];
+ args.parent_tid = (int __user *)regs->u_regs[UREG_I2];
+ }
+
+ /* Did userspace give setup a separate stack for the child or are we
+ * reusing the parent's?
+ */
+ if (regs->u_regs[UREG_I1])
+ args.stack = regs->u_regs[UREG_I1];
+ else
+ args.stack = regs->u_regs[UREG_FP];
+
+ ret = _do_fork(&args);
+
+ /* If we get an error and potentially restart the system
+ * call, we're screwed because copy_thread() clobbered
+ * the parent's %o1. So detect that case and restore it
+ * here.
+ */
+ if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
+ regs->u_regs[UREG_I1] = orig_i1;
+
+ return ret;
+}
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 13cb5638fab8..adfcaeab3ddc 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -34,7 +34,6 @@
#include <asm/oplib.h>
#include <linux/uaccess.h>
#include <asm/page.h>
-#include <asm/pgalloc.h>
#include <asm/delay.h>
#include <asm/processor.h>
#include <asm/psr.h>
@@ -257,33 +256,6 @@ clone_stackframe(struct sparc_stackf __user *dst,
return sp;
}
-asmlinkage int sparc_do_fork(unsigned long clone_flags,
- unsigned long stack_start,
- struct pt_regs *regs,
- unsigned long stack_size)
-{
- unsigned long parent_tid_ptr, child_tid_ptr;
- unsigned long orig_i1 = regs->u_regs[UREG_I1];
- long ret;
-
- parent_tid_ptr = regs->u_regs[UREG_I2];
- child_tid_ptr = regs->u_regs[UREG_I4];
-
- ret = do_fork(clone_flags, stack_start, stack_size,
- (int __user *) parent_tid_ptr,
- (int __user *) child_tid_ptr);
-
- /* If we get an error and potentially restart the system
- * call, we're screwed because copy_thread() clobbered
- * the parent's %o1. So detect that case and restore it
- * here.
- */
- if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
- regs->u_regs[UREG_I1] = orig_i1;
-
- return ret;
-}
-
/* Copy a Sparc thread. The fork() return value conventions
* under SunOS are nothing short of bletcherous:
* Parent --> %o0 == childs pid, %o1 == 0
@@ -300,8 +272,8 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
extern void ret_from_fork(void);
extern void ret_from_kernel_thread(void);
-int copy_thread(unsigned long clone_flags, unsigned long sp,
- unsigned long arg, struct task_struct *p)
+int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
+ struct task_struct *p, unsigned long tls)
{
struct thread_info *ti = task_thread_info(p);
struct pt_regs *childregs, *regs = current_pt_regs();
@@ -403,60 +375,11 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
regs->u_regs[UREG_I1] = 0;
if (clone_flags & CLONE_SETTLS)
- childregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3];
+ childregs->u_regs[UREG_G7] = tls;
return 0;
}
-/*
- * fill in the fpu structure for a core dump.
- */
-int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
-{
- if (used_math()) {
- memset(fpregs, 0, sizeof(*fpregs));
- fpregs->pr_q_entrysize = 8;
- return 1;
- }
-#ifdef CONFIG_SMP
- if (test_thread_flag(TIF_USEDFPU)) {
- put_psr(get_psr() | PSR_EF);
- fpsave(&current->thread.float_regs[0], &current->thread.fsr,
- &current->thread.fpqueue[0], &current->thread.fpqdepth);
- if (regs != NULL) {
- regs->psr &= ~(PSR_EF);
- clear_thread_flag(TIF_USEDFPU);
- }
- }
-#else
- if (current == last_task_used_math) {
- put_psr(get_psr() | PSR_EF);
- fpsave(&current->thread.float_regs[0], &current->thread.fsr,
- &current->thread.fpqueue[0], &current->thread.fpqdepth);
- if (regs != NULL) {
- regs->psr &= ~(PSR_EF);
- last_task_used_math = NULL;
- }
- }
-#endif
- memcpy(&fpregs->pr_fr.pr_regs[0],
- &current->thread.float_regs[0],
- (sizeof(unsigned long) * 32));
- fpregs->pr_fsr = current->thread.fsr;
- fpregs->pr_qcnt = current->thread.fpqdepth;
- fpregs->pr_q_entrysize = 8;
- fpregs->pr_en = 1;
- if(fpregs->pr_qcnt != 0) {
- memcpy(&fpregs->pr_q[0],
- &current->thread.fpqueue[0],
- sizeof(struct fpq) * fpregs->pr_qcnt);
- }
- /* Zero out the rest. */
- memset(&fpregs->pr_q[fpregs->pr_qcnt], 0,
- sizeof(struct fpq) * (32 - fpregs->pr_qcnt));
- return 1;
-}
-
unsigned long get_wchan(struct task_struct *task)
{
unsigned long pc, fp, bias = 0;
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 54945eacd3b5..a75093b993f9 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -572,47 +572,13 @@ barf:
force_sig(SIGSEGV);
}
-asmlinkage long sparc_do_fork(unsigned long clone_flags,
- unsigned long stack_start,
- struct pt_regs *regs,
- unsigned long stack_size)
-{
- int __user *parent_tid_ptr, *child_tid_ptr;
- unsigned long orig_i1 = regs->u_regs[UREG_I1];
- long ret;
-
-#ifdef CONFIG_COMPAT
- if (test_thread_flag(TIF_32BIT)) {
- parent_tid_ptr = compat_ptr(regs->u_regs[UREG_I2]);
- child_tid_ptr = compat_ptr(regs->u_regs[UREG_I4]);
- } else
-#endif
- {
- parent_tid_ptr = (int __user *) regs->u_regs[UREG_I2];
- child_tid_ptr = (int __user *) regs->u_regs[UREG_I4];
- }
-
- ret = do_fork(clone_flags, stack_start, stack_size,
- parent_tid_ptr, child_tid_ptr);
-
- /* If we get an error and potentially restart the system
- * call, we're screwed because copy_thread() clobbered
- * the parent's %o1. So detect that case and restore it
- * here.
- */
- if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
- regs->u_regs[UREG_I1] = orig_i1;
-
- return ret;
-}
-
/* Copy a Sparc thread. The fork() return value conventions
* under SunOS are nothing short of bletcherous:
* Parent --> %o0 == childs pid, %o1 == 0
* Child --> %o0 == parents pid, %o1 == 1
*/
-int copy_thread(unsigned long clone_flags, unsigned long sp,
- unsigned long arg, struct task_struct *p)
+int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
+ struct task_struct *p, unsigned long tls)
{
struct thread_info *t = task_thread_info(p);
struct pt_regs *regs = current_pt_regs();
@@ -670,7 +636,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
regs->u_regs[UREG_I1] = 0;
if (clone_flags & CLONE_SETTLS)
- t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3];
+ t->kregs->u_regs[UREG_G7] = tls;
return 0;
}
@@ -700,72 +666,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
return 0;
}
-typedef struct {
- union {
- unsigned int pr_regs[32];
- unsigned long pr_dregs[16];
- } pr_fr;
- unsigned int __unused;
- unsigned int pr_fsr;
- unsigned char pr_qcnt;
- unsigned char pr_q_entrysize;
- unsigned char pr_en;
- unsigned int pr_q[64];
-} elf_fpregset_t32;
-
-/*
- * fill in the fpu structure for a core dump.
- */
-int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
-{
- unsigned long *kfpregs = current_thread_info()->fpregs;
- unsigned long fprs = current_thread_info()->fpsaved[0];
-
- if (test_thread_flag(TIF_32BIT)) {
- elf_fpregset_t32 *fpregs32 = (elf_fpregset_t32 *)fpregs;
-
- if (fprs & FPRS_DL)
- memcpy(&fpregs32->pr_fr.pr_regs[0], kfpregs,
- sizeof(unsigned int) * 32);
- else
- memset(&fpregs32->pr_fr.pr_regs[0], 0,
- sizeof(unsigned int) * 32);
- fpregs32->pr_qcnt = 0;
- fpregs32->pr_q_entrysize = 8;
- memset(&fpregs32->pr_q[0], 0,
- (sizeof(unsigned int) * 64));
- if (fprs & FPRS_FEF) {
- fpregs32->pr_fsr = (unsigned int) current_thread_info()->xfsr[0];
- fpregs32->pr_en = 1;
- } else {
- fpregs32->pr_fsr = 0;
- fpregs32->pr_en = 0;
- }
- } else {
- if(fprs & FPRS_DL)
- memcpy(&fpregs->pr_regs[0], kfpregs,
- sizeof(unsigned int) * 32);
- else
- memset(&fpregs->pr_regs[0], 0,
- sizeof(unsigned int) * 32);
- if(fprs & FPRS_DU)
- memcpy(&fpregs->pr_regs[16], kfpregs+16,
- sizeof(unsigned int) * 32);
- else
- memset(&fpregs->pr_regs[16], 0,
- sizeof(unsigned int) * 32);
- if(fprs & FPRS_FEF) {
- fpregs->pr_fsr = current_thread_info()->xfsr[0];
- fpregs->pr_gsr = current_thread_info()->gsr[0];
- } else {
- fpregs->pr_fsr = fpregs->pr_gsr = 0;
- }
- fpregs->pr_fprs = fprs;
- }
- return 1;
-}
-EXPORT_SYMBOL(dump_fpu);
-
unsigned long get_wchan(struct task_struct *task)
{
unsigned long pc, fp, bias = 0;
diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c
index 47eb315d411c..5318174a0268 100644
--- a/arch/sparc/kernel/ptrace_32.c
+++ b/arch/sparc/kernel/ptrace_32.c
@@ -83,41 +83,25 @@ static int regwindow32_set(struct task_struct *target,
static int genregs32_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
const struct pt_regs *regs = target->thread.kregs;
u32 uregs[16];
- int ret;
if (target == current)
flush_user_windows();
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- regs->u_regs,
- 0, 16 * sizeof(u32));
- if (ret || !count)
- return ret;
-
- if (pos < 32 * sizeof(u32)) {
- if (regwindow32_get(target, regs, uregs))
- return -EFAULT;
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- uregs,
- 16 * sizeof(u32), 32 * sizeof(u32));
- if (ret || !count)
- return ret;
- }
-
- uregs[0] = regs->psr;
- uregs[1] = regs->pc;
- uregs[2] = regs->npc;
- uregs[3] = regs->y;
- uregs[4] = 0; /* WIM */
- uregs[5] = 0; /* TBR */
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- uregs,
- 32 * sizeof(u32), 38 * sizeof(u32));
+ membuf_write(&to, regs->u_regs, 16 * sizeof(u32));
+ if (!to.left)
+ return 0;
+ if (regwindow32_get(target, regs, uregs))
+ return -EFAULT;
+ membuf_write(&to, uregs, 16 * sizeof(u32));
+ membuf_store(&to, regs->psr);
+ membuf_store(&to, regs->pc);
+ membuf_store(&to, regs->npc);
+ membuf_store(&to, regs->y);
+ return membuf_zero(&to, 2 * sizeof(u32));
}
static int genregs32_set(struct task_struct *target,
@@ -139,19 +123,18 @@ static int genregs32_set(struct task_struct *target,
if (ret || !count)
return ret;
- if (pos < 32 * sizeof(u32)) {
- if (regwindow32_get(target, regs, uregs))
- return -EFAULT;
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- uregs,
- 16 * sizeof(u32), 32 * sizeof(u32));
- if (ret)
- return ret;
- if (regwindow32_set(target, regs, uregs))
- return -EFAULT;
- if (!count)
- return 0;
- }
+ if (regwindow32_get(target, regs, uregs))
+ return -EFAULT;
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ uregs,
+ 16 * sizeof(u32), 32 * sizeof(u32));
+ if (ret)
+ return ret;
+ if (regwindow32_set(target, regs, uregs))
+ return -EFAULT;
+ if (!count)
+ return 0;
+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
&psr,
32 * sizeof(u32), 33 * sizeof(u32));
@@ -182,46 +165,18 @@ static int genregs32_set(struct task_struct *target,
static int fpregs32_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
- const unsigned long *fpregs = target->thread.float_regs;
- int ret = 0;
-
#if 0
if (target == current)
save_and_clear_fpu();
#endif
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- fpregs,
- 0, 32 * sizeof(u32));
-
- if (!ret)
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- 32 * sizeof(u32),
- 33 * sizeof(u32));
- if (!ret)
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fsr,
- 33 * sizeof(u32),
- 34 * sizeof(u32));
-
- if (!ret) {
- unsigned long val;
-
- val = (1 << 8) | (8 << 16);
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &val,
- 34 * sizeof(u32),
- 35 * sizeof(u32));
- }
-
- if (!ret)
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- 35 * sizeof(u32), -1);
-
- return ret;
+ membuf_write(&to, target->thread.float_regs, 32 * sizeof(u32));
+ membuf_zero(&to, sizeof(u32));
+ membuf_write(&to, &target->thread.fsr, sizeof(u32));
+ membuf_store(&to, (u32)((1 << 8) | (8 << 16)));
+ return membuf_zero(&to, 64 * sizeof(u32));
}
static int fpregs32_set(struct task_struct *target,
@@ -243,13 +198,11 @@ static int fpregs32_set(struct task_struct *target,
user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
32 * sizeof(u32),
33 * sizeof(u32));
- if (!ret && count > 0) {
+ if (!ret)
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
&target->thread.fsr,
33 * sizeof(u32),
34 * sizeof(u32));
- }
-
if (!ret)
ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
34 * sizeof(u32), -1);
@@ -268,7 +221,7 @@ static const struct user_regset sparc32_regsets[] = {
.core_note_type = NT_PRSTATUS,
.n = 38,
.size = sizeof(u32), .align = sizeof(u32),
- .get = genregs32_get, .set = genregs32_set
+ .regset_get = genregs32_get, .set = genregs32_set
},
/* Format is:
* F0 --> F31
@@ -284,10 +237,104 @@ static const struct user_regset sparc32_regsets[] = {
.core_note_type = NT_PRFPREG,
.n = 99,
.size = sizeof(u32), .align = sizeof(u32),
- .get = fpregs32_get, .set = fpregs32_set
+ .regset_get = fpregs32_get, .set = fpregs32_set
+ },
+};
+
+static int getregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ struct membuf to)
+{
+ const struct pt_regs *regs = target->thread.kregs;
+
+ if (target == current)
+ flush_user_windows();
+
+ membuf_store(&to, regs->psr);
+ membuf_store(&to, regs->pc);
+ membuf_store(&to, regs->npc);
+ membuf_store(&to, regs->y);
+ return membuf_write(&to, regs->u_regs + 1, 15 * sizeof(u32));
+}
+
+static int setregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct pt_regs *regs = target->thread.kregs;
+ u32 v[4];
+ int ret;
+
+ if (target == current)
+ flush_user_windows();
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ v,
+ 0, 4 * sizeof(u32));
+ if (ret)
+ return ret;
+ regs->psr = (regs->psr & ~(PSR_ICC | PSR_SYSCALL)) |
+ (v[0] & (PSR_ICC | PSR_SYSCALL));
+ regs->pc = v[1];
+ regs->npc = v[2];
+ regs->y = v[3];
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ regs->u_regs + 1,
+ 4 * sizeof(u32) , 19 * sizeof(u32));
+}
+
+static int getfpregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ struct membuf to)
+{
+#if 0
+ if (target == current)
+ save_and_clear_fpu();
+#endif
+ membuf_write(&to, &target->thread.float_regs, 32 * sizeof(u32));
+ membuf_write(&to, &target->thread.fsr, sizeof(u32));
+ return membuf_zero(&to, 35 * sizeof(u32));
+}
+
+static int setfpregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ unsigned long *fpregs = target->thread.float_regs;
+ int ret;
+
+#if 0
+ if (target == current)
+ save_and_clear_fpu();
+#endif
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ fpregs,
+ 0, 32 * sizeof(u32));
+ if (ret)
+ return ret;
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fsr,
+ 32 * sizeof(u32),
+ 33 * sizeof(u32));
+}
+
+static const struct user_regset ptrace32_regsets[] = {
+ [REGSET_GENERAL] = {
+ .n = 19, .size = sizeof(u32),
+ .regset_get = getregs_get, .set = setregs_set,
+ },
+ [REGSET_FP] = {
+ .n = 68, .size = sizeof(u32),
+ .regset_get = getfpregs_get, .set = setfpregs_set,
},
};
+static const struct user_regset_view ptrace32_view = {
+ .regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets)
+};
+
static const struct user_regset_view user_sparc32_view = {
.name = "sparc", .e_machine = EM_SPARC,
.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
@@ -315,74 +362,44 @@ long arch_ptrace(struct task_struct *child, long request,
{
unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4];
void __user *addr2p;
- const struct user_regset_view *view;
struct pt_regs __user *pregs;
struct fps __user *fps;
int ret;
- view = task_user_regset_view(current);
addr2p = (void __user *) addr2;
pregs = (struct pt_regs __user *) addr;
fps = (struct fps __user *) addr;
switch(request) {
case PTRACE_GETREGS: {
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
- 32 * sizeof(u32),
- 4 * sizeof(u32),
- &pregs->psr);
- if (!ret)
- copy_regset_to_user(child, view, REGSET_GENERAL,
- 1 * sizeof(u32),
- 15 * sizeof(u32),
- &pregs->u_regs[0]);
+ ret = copy_regset_to_user(child, &ptrace32_view,
+ REGSET_GENERAL, 0,
+ 19 * sizeof(u32),
+ pregs);
break;
}
case PTRACE_SETREGS: {
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
- 32 * sizeof(u32),
- 4 * sizeof(u32),
- &pregs->psr);
- if (!ret)
- copy_regset_from_user(child, view, REGSET_GENERAL,
- 1 * sizeof(u32),
- 15 * sizeof(u32),
- &pregs->u_regs[0]);
+ ret = copy_regset_from_user(child, &ptrace32_view,
+ REGSET_GENERAL, 0,
+ 19 * sizeof(u32),
+ pregs);
break;
}
case PTRACE_GETFPREGS: {
- ret = copy_regset_to_user(child, view, REGSET_FP,
- 0 * sizeof(u32),
- 32 * sizeof(u32),
- &fps->regs[0]);
- if (!ret)
- ret = copy_regset_to_user(child, view, REGSET_FP,
- 33 * sizeof(u32),
- 1 * sizeof(u32),
- &fps->fsr);
-
- if (!ret) {
- if (__put_user(0, &fps->fpqd) ||
- __put_user(0, &fps->flags) ||
- __put_user(0, &fps->extra) ||
- clear_user(fps->fpq, sizeof(fps->fpq)))
- ret = -EFAULT;
- }
+ ret = copy_regset_to_user(child, &ptrace32_view,
+ REGSET_FP, 0,
+ 68 * sizeof(u32),
+ fps);
break;
}
case PTRACE_SETFPREGS: {
- ret = copy_regset_from_user(child, view, REGSET_FP,
- 0 * sizeof(u32),
- 32 * sizeof(u32),
- &fps->regs[0]);
- if (!ret)
- ret = copy_regset_from_user(child, view, REGSET_FP,
- 33 * sizeof(u32),
- 1 * sizeof(u32),
- &fps->fsr);
+ ret = copy_regset_from_user(child, &ptrace32_view,
+ REGSET_FP, 0,
+ 33 * sizeof(u32),
+ fps);
break;
}
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index 7122efb4b1cc..2b92155db8a5 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -246,52 +246,23 @@ enum sparc_regset {
static int genregs64_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
const struct pt_regs *regs = task_pt_regs(target);
- int ret;
+ struct reg_window window;
if (target == current)
flushw_user();
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- regs->u_regs,
- 0, 16 * sizeof(u64));
- if (!ret && count && pos < (32 * sizeof(u64))) {
- struct reg_window window;
-
- if (regwindow64_get(target, regs, &window))
- return -EFAULT;
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &window,
- 16 * sizeof(u64),
- 32 * sizeof(u64));
- }
-
- if (!ret) {
- /* TSTATE, TPC, TNPC */
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &regs->tstate,
- 32 * sizeof(u64),
- 35 * sizeof(u64));
- }
-
- if (!ret) {
- unsigned long y = regs->y;
-
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &y,
- 35 * sizeof(u64),
- 36 * sizeof(u64));
- }
-
- if (!ret) {
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- 36 * sizeof(u64), -1);
-
- }
- return ret;
+ membuf_write(&to, regs->u_regs, 16 * sizeof(u64));
+ if (!to.left)
+ return 0;
+ if (regwindow64_get(target, regs, &window))
+ return -EFAULT;
+ membuf_write(&to, &window, 16 * sizeof(u64));
+ /* TSTATE, TPC, TNPC */
+ membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
+ return membuf_store(&to, (u64)regs->y);
}
static int genregs64_set(struct task_struct *target,
@@ -370,69 +341,32 @@ static int genregs64_set(struct task_struct *target,
static int fpregs64_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
- const unsigned long *fpregs = task_thread_info(target)->fpregs;
- unsigned long fprs, fsr, gsr;
- int ret;
+ struct thread_info *t = task_thread_info(target);
+ unsigned long fprs;
if (target == current)
save_and_clear_fpu();
- fprs = task_thread_info(target)->fpsaved[0];
+ fprs = t->fpsaved[0];
if (fprs & FPRS_DL)
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- fpregs,
- 0, 16 * sizeof(u64));
+ membuf_write(&to, t->fpregs, 16 * sizeof(u64));
else
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- 0,
- 16 * sizeof(u64));
-
- if (!ret) {
- if (fprs & FPRS_DU)
- ret = user_regset_copyout(&pos, &count,
- &kbuf, &ubuf,
- fpregs + 16,
- 16 * sizeof(u64),
- 32 * sizeof(u64));
- else
- ret = user_regset_copyout_zero(&pos, &count,
- &kbuf, &ubuf,
- 16 * sizeof(u64),
- 32 * sizeof(u64));
- }
+ membuf_zero(&to, 16 * sizeof(u64));
+ if (fprs & FPRS_DU)
+ membuf_write(&to, t->fpregs + 16, 16 * sizeof(u64));
+ else
+ membuf_zero(&to, 16 * sizeof(u64));
if (fprs & FPRS_FEF) {
- fsr = task_thread_info(target)->xfsr[0];
- gsr = task_thread_info(target)->gsr[0];
+ membuf_store(&to, t->xfsr[0]);
+ membuf_store(&to, t->gsr[0]);
} else {
- fsr = gsr = 0;
+ membuf_zero(&to, 2 * sizeof(u64));
}
-
- if (!ret)
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &fsr,
- 32 * sizeof(u64),
- 33 * sizeof(u64));
- if (!ret)
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &gsr,
- 33 * sizeof(u64),
- 34 * sizeof(u64));
- if (!ret)
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &fprs,
- 34 * sizeof(u64),
- 35 * sizeof(u64));
-
- if (!ret)
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- 35 * sizeof(u64), -1);
-
- return ret;
+ return membuf_store(&to, fprs);
}
static int fpregs64_set(struct task_struct *target,
@@ -490,7 +424,7 @@ static const struct user_regset sparc64_regsets[] = {
.core_note_type = NT_PRSTATUS,
.n = 36,
.size = sizeof(u64), .align = sizeof(u64),
- .get = genregs64_get, .set = genregs64_set
+ .regset_get = genregs64_get, .set = genregs64_set
},
/* Format is:
* F0 --> F63
@@ -502,10 +436,96 @@ static const struct user_regset sparc64_regsets[] = {
.core_note_type = NT_PRFPREG,
.n = 35,
.size = sizeof(u64), .align = sizeof(u64),
- .get = fpregs64_get, .set = fpregs64_set
+ .regset_get = fpregs64_get, .set = fpregs64_set
+ },
+};
+
+static int getregs64_get(struct task_struct *target,
+ const struct user_regset *regset,
+ struct membuf to)
+{
+ const struct pt_regs *regs = task_pt_regs(target);
+
+ if (target == current)
+ flushw_user();
+
+ membuf_write(&to, regs->u_regs + 1, 15 * sizeof(u64));
+ membuf_store(&to, (u64)0);
+ membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
+ return membuf_store(&to, (u64)regs->y);
+}
+
+static int setregs64_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct pt_regs *regs = task_pt_regs(target);
+ unsigned long y = regs->y;
+ unsigned long tstate;
+ int ret;
+
+ if (target == current)
+ flushw_user();
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ regs->u_regs + 1,
+ 0 * sizeof(u64),
+ 15 * sizeof(u64));
+ if (ret)
+ return ret;
+ ret =user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ 15 * sizeof(u64), 16 * sizeof(u64));
+ if (ret)
+ return ret;
+ /* TSTATE */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &tstate,
+ 16 * sizeof(u64),
+ 17 * sizeof(u64));
+ if (ret)
+ return ret;
+ /* Only the condition codes and the "in syscall"
+ * state can be modified in the %tstate register.
+ */
+ tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+ regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+ regs->tstate |= tstate;
+
+ /* TPC, TNPC */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &regs->tpc,
+ 17 * sizeof(u64),
+ 19 * sizeof(u64));
+ if (ret)
+ return ret;
+ /* Y */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &y,
+ 19 * sizeof(u64),
+ 20 * sizeof(u64));
+ if (!ret)
+ regs->y = y;
+ return ret;
+}
+
+static const struct user_regset ptrace64_regsets[] = {
+ /* Format is:
+ * G1 --> G7
+ * O0 --> O7
+ * 0
+ * TSTATE, TPC, TNPC, Y
+ */
+ [REGSET_GENERAL] = {
+ .n = 20, .size = sizeof(u64),
+ .regset_get = getregs64_get, .set = setregs64_set,
},
};
+static const struct user_regset_view ptrace64_view = {
+ .regsets = ptrace64_regsets, .n = ARRAY_SIZE(ptrace64_regsets)
+};
+
static const struct user_regset_view user_sparc64_view = {
.name = "sparc64", .e_machine = EM_SPARCV9,
.regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets)
@@ -514,108 +534,28 @@ static const struct user_regset_view user_sparc64_view = {
#ifdef CONFIG_COMPAT
static int genregs32_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
const struct pt_regs *regs = task_pt_regs(target);
- compat_ulong_t __user *reg_window;
- compat_ulong_t *k = kbuf;
- compat_ulong_t __user *u = ubuf;
- compat_ulong_t reg;
+ u32 uregs[16];
+ int i;
if (target == current)
flushw_user();
- pos /= sizeof(reg);
- count /= sizeof(reg);
-
- if (kbuf) {
- for (; count > 0 && pos < 16; count--)
- *k++ = regs->u_regs[pos++];
-
- reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
- reg_window -= 16;
- if (target == current) {
- for (; count > 0 && pos < 32; count--) {
- if (get_user(*k++, &reg_window[pos++]))
- return -EFAULT;
- }
- } else {
- for (; count > 0 && pos < 32; count--) {
- if (access_process_vm(target,
- (unsigned long)
- &reg_window[pos],
- k, sizeof(*k),
- FOLL_FORCE)
- != sizeof(*k))
- return -EFAULT;
- k++;
- pos++;
- }
- }
- } else {
- for (; count > 0 && pos < 16; count--) {
- if (put_user((compat_ulong_t) regs->u_regs[pos++], u++))
- return -EFAULT;
- }
-
- reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
- reg_window -= 16;
- if (target == current) {
- for (; count > 0 && pos < 32; count--) {
- if (get_user(reg, &reg_window[pos++]) ||
- put_user(reg, u++))
- return -EFAULT;
- }
- } else {
- for (; count > 0 && pos < 32; count--) {
- if (access_process_vm(target,
- (unsigned long)
- &reg_window[pos++],
- &reg, sizeof(reg),
- FOLL_FORCE)
- != sizeof(reg))
- return -EFAULT;
- if (put_user(reg, u++))
- return -EFAULT;
- }
- }
- }
- while (count > 0) {
- switch (pos) {
- case 32: /* PSR */
- reg = tstate_to_psr(regs->tstate);
- break;
- case 33: /* PC */
- reg = regs->tpc;
- break;
- case 34: /* NPC */
- reg = regs->tnpc;
- break;
- case 35: /* Y */
- reg = regs->y;
- break;
- case 36: /* WIM */
- case 37: /* TBR */
- reg = 0;
- break;
- default:
- goto finish;
- }
-
- if (kbuf)
- *k++ = reg;
- else if (put_user(reg, u++))
- return -EFAULT;
- pos++;
- count--;
- }
-finish:
- pos *= sizeof(reg);
- count *= sizeof(reg);
-
- return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- 38 * sizeof(reg), -1);
+ for (i = 0; i < 16; i++)
+ membuf_store(&to, (u32)regs->u_regs[i]);
+ if (!to.left)
+ return 0;
+ if (get_from_target(target, regs->u_regs[UREG_I6],
+ uregs, sizeof(uregs)))
+ return -EFAULT;
+ membuf_write(&to, uregs, 16 * sizeof(u32));
+ membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
+ membuf_store(&to, (u32)(regs->tpc));
+ membuf_store(&to, (u32)(regs->tnpc));
+ membuf_store(&to, (u32)(regs->y));
+ return membuf_zero(&to, 2 * sizeof(u32));
}
static int genregs32_set(struct task_struct *target,
@@ -737,56 +677,24 @@ finish:
static int fpregs32_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
- const unsigned long *fpregs = task_thread_info(target)->fpregs;
- compat_ulong_t enabled;
- unsigned long fprs;
- compat_ulong_t fsr;
- int ret = 0;
+ struct thread_info *t = task_thread_info(target);
+ bool enabled;
if (target == current)
save_and_clear_fpu();
- fprs = task_thread_info(target)->fpsaved[0];
- if (fprs & FPRS_FEF) {
- fsr = task_thread_info(target)->xfsr[0];
- enabled = 1;
- } else {
- fsr = 0;
- enabled = 0;
- }
-
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- fpregs,
- 0, 32 * sizeof(u32));
-
- if (!ret)
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- 32 * sizeof(u32),
- 33 * sizeof(u32));
- if (!ret)
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &fsr,
- 33 * sizeof(u32),
- 34 * sizeof(u32));
-
- if (!ret) {
- compat_ulong_t val;
-
- val = (enabled << 8) | (8 << 16);
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &val,
- 34 * sizeof(u32),
- 35 * sizeof(u32));
- }
+ enabled = t->fpsaved[0] & FPRS_FEF;
- if (!ret)
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- 35 * sizeof(u32), -1);
-
- return ret;
+ membuf_write(&to, t->fpregs, 32 * sizeof(u32));
+ membuf_zero(&to, sizeof(u32));
+ if (enabled)
+ membuf_store(&to, (u32)t->xfsr[0]);
+ else
+ membuf_zero(&to, sizeof(u32));
+ membuf_store(&to, (u32)((enabled << 8) | (8 << 16)));
+ return membuf_zero(&to, 64 * sizeof(u32));
}
static int fpregs32_set(struct task_struct *target,
@@ -847,7 +755,7 @@ static const struct user_regset sparc32_regsets[] = {
.core_note_type = NT_PRSTATUS,
.n = 38,
.size = sizeof(u32), .align = sizeof(u32),
- .get = genregs32_get, .set = genregs32_set
+ .regset_get = genregs32_get, .set = genregs32_set
},
/* Format is:
* F0 --> F31
@@ -863,10 +771,133 @@ static const struct user_regset sparc32_regsets[] = {
.core_note_type = NT_PRFPREG,
.n = 99,
.size = sizeof(u32), .align = sizeof(u32),
- .get = fpregs32_get, .set = fpregs32_set
+ .regset_get = fpregs32_get, .set = fpregs32_set
},
};
+static int getregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ struct membuf to)
+{
+ const struct pt_regs *regs = task_pt_regs(target);
+ int i;
+
+ if (target == current)
+ flushw_user();
+
+ membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
+ membuf_store(&to, (u32)(regs->tpc));
+ membuf_store(&to, (u32)(regs->tnpc));
+ membuf_store(&to, (u32)(regs->y));
+ for (i = 1; i < 16; i++)
+ membuf_store(&to, (u32)regs->u_regs[i]);
+ return to.left;
+}
+
+static int setregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct pt_regs *regs = task_pt_regs(target);
+ unsigned long tstate;
+ u32 uregs[19];
+ int i, ret;
+
+ if (target == current)
+ flushw_user();
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ uregs,
+ 0, 19 * sizeof(u32));
+ if (ret)
+ return ret;
+
+ tstate = regs->tstate;
+ tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+ tstate |= psr_to_tstate_icc(uregs[0]);
+ if (uregs[0] & PSR_SYSCALL)
+ tstate |= TSTATE_SYSCALL;
+ regs->tstate = tstate;
+ regs->tpc = uregs[1];
+ regs->tnpc = uregs[2];
+ regs->y = uregs[3];
+
+ for (i = 1; i < 15; i++)
+ regs->u_regs[i] = uregs[3 + i];
+ return 0;
+}
+
+static int getfpregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ struct membuf to)
+{
+ struct thread_info *t = task_thread_info(target);
+
+ if (target == current)
+ save_and_clear_fpu();
+
+ membuf_write(&to, t->fpregs, 32 * sizeof(u32));
+ if (t->fpsaved[0] & FPRS_FEF)
+ membuf_store(&to, (u32)t->xfsr[0]);
+ else
+ membuf_zero(&to, sizeof(u32));
+ return membuf_zero(&to, 35 * sizeof(u32));
+}
+
+static int setfpregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ unsigned long *fpregs = task_thread_info(target)->fpregs;
+ unsigned long fprs;
+ int ret;
+
+ if (target == current)
+ save_and_clear_fpu();
+
+ fprs = task_thread_info(target)->fpsaved[0];
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ fpregs,
+ 0, 32 * sizeof(u32));
+ if (!ret) {
+ compat_ulong_t fsr;
+ unsigned long val;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &fsr,
+ 32 * sizeof(u32),
+ 33 * sizeof(u32));
+ if (!ret) {
+ val = task_thread_info(target)->xfsr[0];
+ val &= 0xffffffff00000000UL;
+ val |= fsr;
+ task_thread_info(target)->xfsr[0] = val;
+ }
+ }
+
+ fprs |= (FPRS_FEF | FPRS_DL);
+ task_thread_info(target)->fpsaved[0] = fprs;
+ return ret;
+}
+
+static const struct user_regset ptrace32_regsets[] = {
+ [REGSET_GENERAL] = {
+ .n = 19, .size = sizeof(u32),
+ .regset_get = getregs_get, .set = setregs_set,
+ },
+ [REGSET_FP] = {
+ .n = 68, .size = sizeof(u32),
+ .regset_get = getfpregs_get, .set = setfpregs_set,
+ },
+};
+
+static const struct user_regset_view ptrace32_view = {
+ .regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets)
+};
+
static const struct user_regset_view user_sparc32_view = {
.name = "sparc", .e_machine = EM_SPARC,
.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
@@ -898,7 +929,6 @@ struct compat_fps {
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata)
{
- const struct user_regset_view *view = task_user_regset_view(current);
compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
struct pt_regs32 __user *pregs;
struct compat_fps __user *fps;
@@ -916,58 +946,31 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
break;
case PTRACE_GETREGS:
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
- 32 * sizeof(u32),
- 4 * sizeof(u32),
- &pregs->psr);
- if (!ret)
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
- 1 * sizeof(u32),
- 15 * sizeof(u32),
- &pregs->u_regs[0]);
+ ret = copy_regset_to_user(child, &ptrace32_view,
+ REGSET_GENERAL, 0,
+ 19 * sizeof(u32),
+ pregs);
break;
case PTRACE_SETREGS:
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
- 32 * sizeof(u32),
- 4 * sizeof(u32),
- &pregs->psr);
- if (!ret)
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
- 1 * sizeof(u32),
- 15 * sizeof(u32),
- &pregs->u_regs[0]);
+ ret = copy_regset_from_user(child, &ptrace32_view,
+ REGSET_GENERAL, 0,
+ 19 * sizeof(u32),
+ pregs);
break;
case PTRACE_GETFPREGS:
- ret = copy_regset_to_user(child, view, REGSET_FP,
- 0 * sizeof(u32),
- 32 * sizeof(u32),
- &fps->regs[0]);
- if (!ret)
- ret = copy_regset_to_user(child, view, REGSET_FP,
- 33 * sizeof(u32),
- 1 * sizeof(u32),
- &fps->fsr);
- if (!ret) {
- if (__put_user(0, &fps->flags) ||
- __put_user(0, &fps->extra) ||
- __put_user(0, &fps->fpqd) ||
- clear_user(&fps->fpq[0], 32 * sizeof(unsigned int)))
- ret = -EFAULT;
- }
+ ret = copy_regset_to_user(child, &ptrace32_view,
+ REGSET_FP, 0,
+ 68 * sizeof(u32),
+ fps);
break;
case PTRACE_SETFPREGS:
- ret = copy_regset_from_user(child, view, REGSET_FP,
- 0 * sizeof(u32),
- 32 * sizeof(u32),
- &fps->regs[0]);
- if (!ret)
- ret = copy_regset_from_user(child, view, REGSET_FP,
- 33 * sizeof(u32),
- 1 * sizeof(u32),
- &fps->fsr);
+ ret = copy_regset_from_user(child, &ptrace32_view,
+ REGSET_FP, 0,
+ 33 * sizeof(u32),
+ fps);
break;
case PTRACE_READTEXT:
@@ -1026,31 +1029,17 @@ long arch_ptrace(struct task_struct *child, long request,
break;
case PTRACE_GETREGS64:
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
- 1 * sizeof(u64),
- 15 * sizeof(u64),
- &pregs->u_regs[0]);
- if (!ret) {
- /* XXX doesn't handle 'y' register correctly XXX */
- ret = copy_regset_to_user(child, view, REGSET_GENERAL,
- 32 * sizeof(u64),
- 4 * sizeof(u64),
- &pregs->tstate);
- }
+ ret = copy_regset_to_user(child, &ptrace64_view,
+ REGSET_GENERAL, 0,
+ 19 * sizeof(u64),
+ pregs);
break;
case PTRACE_SETREGS64:
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
- 1 * sizeof(u64),
- 15 * sizeof(u64),
- &pregs->u_regs[0]);
- if (!ret) {
- /* XXX doesn't handle 'y' register correctly XXX */
- ret = copy_regset_from_user(child, view, REGSET_GENERAL,
- 32 * sizeof(u64),
- 4 * sizeof(u64),
- &pregs->tstate);
- }
+ ret = copy_regset_from_user(child, &ptrace64_view,
+ REGSET_GENERAL, 0,
+ 19 * sizeof(u64),
+ pregs);
break;
case PTRACE_GETFPREGS64:
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index 6d07b85b9e24..eea43a1aef1b 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -353,8 +353,6 @@ void __init setup_arch(char **cmdline_p)
ROOT_DEV = old_decode_dev(root_dev);
#ifdef CONFIG_BLK_DEV_RAM
rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);
#endif
prom_setsync(prom_sync_me);
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index f765fda871eb..d87244197d5c 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -659,8 +659,6 @@ void __init setup_arch(char **cmdline_p)
ROOT_DEV = old_decode_dev(root_dev);
#ifdef CONFIG_BLK_DEV_RAM
rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);
#endif
task_thread_info(&init_task)->kregs = &fake_swapper_regs;
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 3b005b6c3e0f..f1f8c8ebe641 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -23,7 +23,6 @@
#include <linux/uaccess.h>
#include <asm/ptrace.h>
-#include <asm/pgalloc.h>
#include <asm/cacheflush.h> /* flush_sig_insns */
#include <asm/switch_to.h>
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 76ce290c67cf..50c127ab46d5 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -29,7 +29,6 @@
#include <asm/irq.h>
#include <asm/page.h>
-#include <asm/pgalloc.h>
#include <asm/oplib.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 0085e28bf019..e286e2badc8a 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -47,6 +47,7 @@
#include <linux/uaccess.h>
#include <asm/starfire.h>
#include <asm/tlb.h>
+#include <asm/pgalloc.h>
#include <asm/sections.h>
#include <asm/prom.h>
#include <asm/mdesc.h>
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index 91b61f012d19..1079638986b5 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -16,7 +16,6 @@
#include <asm/timer.h>
#include <asm/traps.h>
-#include <asm/pgalloc.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index 489ffab918a8..a45f0f31fe51 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -157,22 +157,22 @@ do_sys_shutdown: /* sys_shutdown(int, int) */
nop
nop
nop
-do_sys_setsockopt: /* compat_sys_setsockopt(int, int, int, char *, int) */
+do_sys_setsockopt: /* sys_setsockopt(int, int, int, char *, int) */
47: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(compat_sys_setsockopt), %g1
+ sethi %hi(sys_setsockopt), %g1
48: ldswa [%o1 + 0x8] %asi, %o2
49: lduwa [%o1 + 0xc] %asi, %o3
50: ldswa [%o1 + 0x10] %asi, %o4
- jmpl %g1 + %lo(compat_sys_setsockopt), %g0
+ jmpl %g1 + %lo(sys_setsockopt), %g0
51: ldswa [%o1 + 0x4] %asi, %o1
nop
-do_sys_getsockopt: /* compat_sys_getsockopt(int, int, int, u32, u32) */
+do_sys_getsockopt: /* sys_getsockopt(int, int, int, u32, u32) */
52: ldswa [%o1 + 0x0] %asi, %o0
- sethi %hi(compat_sys_getsockopt), %g1
+ sethi %hi(sys_getsockopt), %g1
53: ldswa [%o1 + 0x8] %asi, %o2
54: lduwa [%o1 + 0xc] %asi, %o3
55: lduwa [%o1 + 0x10] %asi, %o4
- jmpl %g1 + %lo(compat_sys_getsockopt), %g0
+ jmpl %g1 + %lo(sys_getsockopt), %g0
56: ldswa [%o1 + 0x4] %asi, %o1
nop
do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index db42b4fb3708..0e8ab0602c36 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -86,19 +86,22 @@ sys32_rt_sigreturn:
* during system calls...
*/
.align 32
-sys_vfork: /* Under Linux, vfork and fork are just special cases of clone. */
- sethi %hi(0x4000 | 0x0100 | SIGCHLD), %o0
- or %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0
- ba,pt %xcc, sys_clone
+sys_vfork:
+ flushw
+ ba,pt %xcc, sparc_vfork
+ add %sp, PTREGS_OFF, %o0
+
+ .align 32
sys_fork:
- clr %o1
- mov SIGCHLD, %o0
+ flushw
+ ba,pt %xcc, sparc_fork
+ add %sp, PTREGS_OFF, %o0
+
+ .align 32
sys_clone:
flushw
- movrz %o1, %fp, %o1
- mov 0, %o3
- ba,pt %xcc, sparc_do_fork
- add %sp, PTREGS_OFF, %o2
+ ba,pt %xcc, sparc_clone
+ add %sp, PTREGS_OFF, %o0
.globl ret_from_fork
ret_from_fork:
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 8004a276cb74..46024e80ee86 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -147,7 +147,7 @@
115 32 getgroups32 sys_getgroups
116 common gettimeofday sys_gettimeofday compat_sys_gettimeofday
117 common getrusage sys_getrusage compat_sys_getrusage
-118 common getsockopt sys_getsockopt compat_sys_getsockopt
+118 common getsockopt sys_getsockopt sys_getsockopt
119 common getcwd sys_getcwd
120 common readv sys_readv compat_sys_readv
121 common writev sys_writev compat_sys_writev
@@ -425,7 +425,7 @@
352 common userfaultfd sys_userfaultfd
353 common bind sys_bind
354 common listen sys_listen
-355 common setsockopt sys_setsockopt compat_sys_setsockopt
+355 common setsockopt sys_setsockopt sys_setsockopt
356 common mlock2 sys_mlock2
357 common copy_file_range sys_copy_file_range
358 common preadv2 sys_preadv2 compat_sys_preadv2
@@ -481,6 +481,7 @@
433 common fspick sys_fspick
434 common pidfd_open sys_pidfd_open
# 435 reserved for clone3
+436 common close_range sys_close_range
437 common openat2 sys_openat2
438 common pidfd_getfd sys_pidfd_getfd
439 common faccessat2 sys_faccessat2
diff --git a/arch/sparc/kernel/vdso.c b/arch/sparc/kernel/vdso.c
index 58880662b271..0e27437eb97b 100644
--- a/arch/sparc/kernel/vdso.c
+++ b/arch/sparc/kernel/vdso.c
@@ -7,7 +7,6 @@
* a different vsyscall implementation for Linux/IA32 and for the name.
*/
-#include <linux/seqlock.h>
#include <linux/time.h>
#include <linux/timekeeper_internal.h>
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index cfef656eda0f..8071bfd72349 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -234,7 +234,7 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- fault = handle_mm_fault(vma, address, flags);
+ fault = handle_mm_fault(vma, address, flags, regs);
if (fault_signal_pending(fault, regs))
return;
@@ -250,15 +250,6 @@ good_area:
}
if (flags & FAULT_FLAG_ALLOW_RETRY) {
- if (fault & VM_FAULT_MAJOR) {
- current->maj_flt++;
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
- 1, regs, address);
- } else {
- current->min_flt++;
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
- 1, regs, address);
- }
if (fault & VM_FAULT_RETRY) {
flags |= FAULT_FLAG_TRIED;
@@ -410,7 +401,7 @@ good_area:
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- switch (handle_mm_fault(vma, address, flags)) {
+ switch (handle_mm_fault(vma, address, flags, NULL)) {
case VM_FAULT_SIGBUS:
case VM_FAULT_OOM:
goto do_sigbus;
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index a3806614e4dc..0a6bcc85fba7 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -422,7 +422,7 @@ good_area:
goto bad_area;
}
- fault = handle_mm_fault(vma, address, flags);
+ fault = handle_mm_fault(vma, address, flags, regs);
if (fault_signal_pending(fault, regs))
goto exit_exception;
@@ -438,15 +438,6 @@ good_area:
}
if (flags & FAULT_FLAG_ALLOW_RETRY) {
- if (fault & VM_FAULT_MAJOR) {
- current->maj_flt++;
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
- 1, regs, address);
- } else {
- current->min_flt++;
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
- 1, regs, address);
- }
if (fault & VM_FAULT_RETRY) {
flags |= FAULT_FLAG_TRIED;
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index d1fc9a7b7d78..8f2a2afb048a 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -29,7 +29,6 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
-#include <asm/pgalloc.h>
#include <asm/vaddrs.h>
static pte_t *kmap_pte;
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 02e6e5e0f106..fad6d3129904 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1610,7 +1610,6 @@ static unsigned long __init bootmem_init(unsigned long phys_base)
/* XXX cpu notifier XXX */
- sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
return end_pfn;
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index bfcc04bfce54..430a47a1b6ae 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -15,7 +15,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
-#include <asm/pgalloc.h>
#include <asm/io.h>
#include <asm/io-unit.h>
#include <asm/mxcc.h>
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 35b002eb312e..3a388b1c5d4b 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -16,7 +16,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
-#include <asm/pgalloc.h>
#include <asm/io.h>
#include <asm/mxcc.h>
#include <asm/mbus.h>
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index a32a16c18617..20ee14739333 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -10,7 +10,6 @@
#include <linux/swap.h>
#include <linux/preempt.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile
index 708cb6304c2d..f44355e46f31 100644
--- a/arch/sparc/vdso/Makefile
+++ b/arch/sparc/vdso/Makefile
@@ -54,7 +54,7 @@ $(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(obj)/vdso2c FORCE
# optimize sibling calls.
#
CFL := $(PROFILING) -mcmodel=medlow -fPIC -O2 -fasynchronous-unwind-tables -m64 \
- $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \
+ $(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \
-fno-omit-frame-pointer -foptimize-sibling-calls \
-DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
@@ -93,7 +93,7 @@ KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 := $(filter-out $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS_32))
KBUILD_CFLAGS_32 += -m32 -msoft-float -fpic
-KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
+KBUILD_CFLAGS_32 += -fno-stack-protector
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING