summaryrefslogtreecommitdiff
path: root/arch/hexagon/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/hexagon/kernel')
-rw-r--r--arch/hexagon/kernel/.gitignore1
-rw-r--r--arch/hexagon/kernel/Makefile4
-rw-r--r--arch/hexagon/kernel/Makefile.syscalls3
-rw-r--r--arch/hexagon/kernel/asm-offsets.c17
-rw-r--r--arch/hexagon/kernel/dma.c211
-rw-r--r--arch/hexagon/kernel/head.S16
-rw-r--r--arch/hexagon/kernel/hexagon_ksyms.c33
-rw-r--r--arch/hexagon/kernel/irq_cpu.c15
-rw-r--r--arch/hexagon/kernel/kgdb.c56
-rw-r--r--arch/hexagon/kernel/module.c17
-rw-r--r--arch/hexagon/kernel/process.c80
-rw-r--r--arch/hexagon/kernel/ptrace.c97
-rw-r--r--arch/hexagon/kernel/reset.c21
-rw-r--r--arch/hexagon/kernel/setup.c31
-rw-r--r--arch/hexagon/kernel/signal.c89
-rw-r--r--arch/hexagon/kernel/smp.c67
-rw-r--r--arch/hexagon/kernel/stacktrace.c20
-rw-r--r--arch/hexagon/kernel/syscalltab.c30
-rw-r--r--arch/hexagon/kernel/time.c80
-rw-r--r--arch/hexagon/kernel/trampoline.S15
-rw-r--r--arch/hexagon/kernel/traps.c94
-rw-r--r--arch/hexagon/kernel/vdso.c35
-rw-r--r--arch/hexagon/kernel/vm_entry.S23
-rw-r--r--arch/hexagon/kernel/vm_events.c23
-rw-r--r--arch/hexagon/kernel/vm_init_segtable.S15
-rw-r--r--arch/hexagon/kernel/vm_ops.S17
-rw-r--r--arch/hexagon/kernel/vm_switch.S15
-rw-r--r--arch/hexagon/kernel/vm_vectors.S15
-rw-r--r--arch/hexagon/kernel/vmlinux.lds.S35
29 files changed, 286 insertions, 889 deletions
diff --git a/arch/hexagon/kernel/.gitignore b/arch/hexagon/kernel/.gitignore
new file mode 100644
index 000000000000..c5f676c3c224
--- /dev/null
+++ b/arch/hexagon/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/hexagon/kernel/Makefile b/arch/hexagon/kernel/Makefile
index 29fc933a7722..8e0fb4a62315 100644
--- a/arch/hexagon/kernel/Makefile
+++ b/arch/hexagon/kernel/Makefile
@@ -1,5 +1,7 @@
-extra-y := head.o vmlinux.lds
+# SPDX-License-Identifier: GPL-2.0
+always-$(KBUILD_BUILTIN) := vmlinux.lds
+obj-y += head.o
obj-$(CONFIG_SMP) += smp.o
obj-y += setup.o irq_cpu.o traps.o syscalltab.o signal.o time.o
diff --git a/arch/hexagon/kernel/Makefile.syscalls b/arch/hexagon/kernel/Makefile.syscalls
new file mode 100644
index 000000000000..d2b7c5d44d95
--- /dev/null
+++ b/arch/hexagon/kernel/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += hexagon time32 stat64 rlimit renameat
diff --git a/arch/hexagon/kernel/asm-offsets.c b/arch/hexagon/kernel/asm-offsets.c
index 308be68d4fb3..50eea9fa6f13 100644
--- a/arch/hexagon/kernel/asm-offsets.c
+++ b/arch/hexagon/kernel/asm-offsets.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 1996 David S. Miller
* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle
@@ -6,26 +7,12 @@
* Copyright (C) 2000 MIPS Technologies, Inc.
*
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
+#define COMPILE_OFFSETS
#include <linux/compat.h>
#include <linux/types.h>
#include <linux/sched.h>
-#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/kbuild.h>
#include <asm/ptrace.h>
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index b74f9bae31a3..882680e81a30 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -1,148 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* DMA implementation for Hexagon
*
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
-#include <linux/dma-mapping.h>
-#include <linux/bootmem.h>
-#include <linux/genalloc.h>
-#include <asm/dma-mapping.h>
-#include <linux/module.h>
+#include <linux/dma-map-ops.h>
+#include <linux/memblock.h>
#include <asm/page.h>
-struct dma_map_ops *dma_ops;
-EXPORT_SYMBOL(dma_ops);
-
-int bad_dma_address; /* globals are automatically initialized to zero */
-
-static inline void *dma_addr_to_virt(dma_addr_t dma_addr)
+void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
+ enum dma_data_direction dir)
{
- return phys_to_virt((unsigned long) dma_addr);
-}
-
-int dma_supported(struct device *dev, u64 mask)
-{
- if (mask == DMA_BIT_MASK(32))
- return 1;
- else
- return 0;
-}
-EXPORT_SYMBOL(dma_supported);
-
-int dma_set_mask(struct device *dev, u64 mask)
-{
- if (!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
-
- return 0;
-}
-EXPORT_SYMBOL(dma_set_mask);
-
-static struct gen_pool *coherent_pool;
-
-
-/* Allocates from a pool of uncached memory that was reserved at boot time */
+ void *addr = phys_to_virt(paddr);
-static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_addr, gfp_t flag,
- struct dma_attrs *attrs)
-{
- void *ret;
-
- /*
- * Our max_low_pfn should have been backed off by 16MB in
- * mm/init.c to create DMA coherent space. Use that as the VA
- * for the pool.
- */
-
- if (coherent_pool == NULL) {
- coherent_pool = gen_pool_create(PAGE_SHIFT, -1);
-
- if (coherent_pool == NULL)
- panic("Can't create %s() memory pool!", __func__);
- else
- gen_pool_add(coherent_pool,
- pfn_to_virt(max_low_pfn),
- hexagon_coherent_pool_size, -1);
- }
-
- ret = (void *) gen_pool_alloc(coherent_pool, size);
-
- if (ret) {
- memset(ret, 0, size);
- *dma_addr = (dma_addr_t) virt_to_phys(ret);
- } else
- *dma_addr = ~0;
-
- return ret;
-}
-
-static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_addr, struct dma_attrs *attrs)
-{
- gen_pool_free(coherent_pool, (unsigned long) vaddr, size);
-}
-
-static int check_addr(const char *name, struct device *hwdev,
- dma_addr_t bus, size_t size)
-{
- if (hwdev && hwdev->dma_mask && !dma_capable(hwdev, bus, size)) {
- if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
- printk(KERN_ERR
- "%s: overflow %Lx+%zu of device mask %Lx\n",
- name, (long long)bus, size,
- (long long)*hwdev->dma_mask);
- return 0;
- }
- return 1;
-}
-
-static int hexagon_map_sg(struct device *hwdev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir,
- struct dma_attrs *attrs)
-{
- struct scatterlist *s;
- int i;
-
- WARN_ON(nents == 0 || sg[0].length == 0);
-
- for_each_sg(sg, s, nents, i) {
- s->dma_address = sg_phys(s);
- if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
- return 0;
-
- s->dma_length = s->length;
-
- flush_dcache_range(dma_addr_to_virt(s->dma_address),
- dma_addr_to_virt(s->dma_address + s->length));
- }
-
- return nents;
-}
-
-/*
- * address is virtual
- */
-static inline void dma_sync(void *addr, size_t size,
- enum dma_data_direction dir)
-{
switch (dir) {
case DMA_TO_DEVICE:
hexagon_clean_dcache_range((unsigned long) addr,
@@ -161,69 +32,13 @@ static inline void dma_sync(void *addr, size_t size,
}
}
-/**
- * hexagon_map_page() - maps an address for device DMA
- * @dev: pointer to DMA device
- * @page: pointer to page struct of DMA memory
- * @offset: offset within page
- * @size: size of memory to map
- * @dir: transfer direction
- * @attrs: pointer to DMA attrs (not used)
- *
- * Called to map a memory address to a DMA address prior
- * to accesses to/from device.
- *
- * We don't particularly have many hoops to jump through
- * so far. Straight translation between phys and virtual.
- *
- * DMA is not cache coherent so sync is necessary; this
- * seems to be a convenient place to do it.
- *
+/*
+ * Our max_low_pfn should have been backed off by 16MB in mm/init.c to create
+ * DMA coherent space. Use that for the pool.
*/
-static dma_addr_t hexagon_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir,
- struct dma_attrs *attrs)
-{
- dma_addr_t bus = page_to_phys(page) + offset;
- WARN_ON(size == 0);
-
- if (!check_addr("map_single", dev, bus, size))
- return bad_dma_address;
-
- dma_sync(dma_addr_to_virt(bus), size, dir);
-
- return bus;
-}
-
-static void hexagon_sync_single_for_cpu(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
+static int __init hexagon_dma_init(void)
{
- dma_sync(dma_addr_to_virt(dma_handle), size, dir);
-}
-
-static void hexagon_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
-{
- dma_sync(dma_addr_to_virt(dma_handle), size, dir);
-}
-
-struct dma_map_ops hexagon_dma_ops = {
- .alloc = hexagon_dma_alloc_coherent,
- .free = hexagon_free_coherent,
- .map_sg = hexagon_map_sg,
- .map_page = hexagon_map_page,
- .sync_single_for_cpu = hexagon_sync_single_for_cpu,
- .sync_single_for_device = hexagon_sync_single_for_device,
- .is_phys = 1,
-};
-
-void __init hexagon_dma_init(void)
-{
- if (dma_ops)
- return;
-
- dma_ops = &hexagon_dma_ops;
+ return dma_init_global_coherent(PFN_PHYS(max_low_pfn),
+ hexagon_coherent_pool_size);
}
+core_initcall(hexagon_dma_init);
diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S
index b9b63d085db2..0b016308cc79 100644
--- a/arch/hexagon/kernel/head.S
+++ b/arch/hexagon/kernel/head.S
@@ -1,22 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Early kernel startup code for Hexagon
*
* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/linkage.h>
diff --git a/arch/hexagon/kernel/hexagon_ksyms.c b/arch/hexagon/kernel/hexagon_ksyms.c
index 32b1379d6877..36a80e31d187 100644
--- a/arch/hexagon/kernel/hexagon_ksyms.c
+++ b/arch/hexagon/kernel/hexagon_ksyms.c
@@ -1,40 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Export of symbols defined in assembly files and/or libgcc.
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
+#include <linux/dma-mapping.h>
#include <asm/hexagon_vm.h>
-#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/uaccess.h>
-EXPORT_SYMBOL(__copy_from_user_hexagon);
-EXPORT_SYMBOL(__copy_to_user_hexagon);
+/* Additional functions */
+EXPORT_SYMBOL(__clear_user_hexagon);
+EXPORT_SYMBOL(raw_copy_from_user);
+EXPORT_SYMBOL(raw_copy_to_user);
EXPORT_SYMBOL(__vmgetie);
EXPORT_SYMBOL(__vmsetie);
+EXPORT_SYMBOL(__vmyield);
+EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
+/* Additional variables */
+EXPORT_SYMBOL(__phys_offset);
+EXPORT_SYMBOL(_dflt_cache_att);
+
#define DECLARE_EXPORT(name) \
extern void name(void); EXPORT_SYMBOL(name)
/* Symbols found in libgcc that assorted kernel modules need */
DECLARE_EXPORT(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes);
+/* Additional functions */
DECLARE_EXPORT(__hexagon_divsi3);
DECLARE_EXPORT(__hexagon_modsi3);
DECLARE_EXPORT(__hexagon_udivsi3);
DECLARE_EXPORT(__hexagon_umodsi3);
+DECLARE_EXPORT(csum_tcpudp_magic);
diff --git a/arch/hexagon/kernel/irq_cpu.c b/arch/hexagon/kernel/irq_cpu.c
index 85883e1fdc12..9c92f2fc7e05 100644
--- a/arch/hexagon/kernel/irq_cpu.c
+++ b/arch/hexagon/kernel/irq_cpu.c
@@ -1,21 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* First-level interrupt controller model for Hexagon.
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/interrupt.h>
diff --git a/arch/hexagon/kernel/kgdb.c b/arch/hexagon/kernel/kgdb.c
index 82d5c2593323..903609fbbbdc 100644
--- a/arch/hexagon/kernel/kgdb.c
+++ b/arch/hexagon/kernel/kgdb.c
@@ -1,23 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* arch/hexagon/kernel/kgdb.c - Hexagon KGDB Support
*
* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/sched/task_stack.h>
#include <linux/kdebug.h>
#include <linux/kgdb.h>
@@ -80,7 +70,7 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{ "syscall_nr", GDB_SIZEOF_REG, offsetof(struct pt_regs, syscall_nr)},
};
-struct kgdb_arch arch_kgdb_ops = {
+const struct kgdb_arch arch_kgdb_ops = {
/* trap0(#0xDB) 0x0cdb0054 */
.gdb_bpt_instr = {0x54, 0x00, 0xdb, 0x0c},
};
@@ -112,38 +102,6 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
instruction_pointer(regs) = pc;
}
-#ifdef CONFIG_SMP
-
-/**
- * kgdb_roundup_cpus - Get other CPUs into a holding pattern
- * @flags: Current IRQ state
- *
- * On SMP systems, we need to get the attention of the other CPUs
- * and get them be in a known state. This should do what is needed
- * to get the other CPUs to call kgdb_wait(). Note that on some arches,
- * the NMI approach is not used for rounding up all the CPUs. For example,
- * in case of MIPS, smp_call_function() is used to roundup CPUs. In
- * this case, we have to make sure that interrupts are enabled before
- * calling smp_call_function(). The argument to this function is
- * the flags that will be used when restoring the interrupts. There is
- * local_irq_save() call before kgdb_roundup_cpus().
- *
- * On non-SMP systems, this is not called.
- */
-
-static void hexagon_kgdb_nmi_hook(void *ignored)
-{
- kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
-}
-
-void kgdb_roundup_cpus(unsigned long flags)
-{
- local_irq_enable();
- smp_call_function(hexagon_kgdb_nmi_hook, NULL, 0);
- local_irq_disable();
-}
-#endif
-
/* Not yet working */
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
@@ -234,9 +192,9 @@ static struct notifier_block kgdb_notifier = {
};
/**
- * kgdb_arch_init - Perform any architecture specific initalization.
+ * kgdb_arch_init - Perform any architecture specific initialization.
*
- * This function will handle the initalization of any architecture
+ * This function will handle the initialization of any architecture
* specific callbacks.
*/
int kgdb_arch_init(void)
diff --git a/arch/hexagon/kernel/module.c b/arch/hexagon/kernel/module.c
index 477d07a5646c..cb3bf19b0640 100644
--- a/arch/hexagon/kernel/module.c
+++ b/arch/hexagon/kernel/module.c
@@ -1,21 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Kernel module loader for Hexagon
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <asm/module.h>
@@ -133,7 +120,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
}
case R_HEXAGON_HI16:
value = (value>>16) & 0xffff;
- /* fallthrough */
+ fallthrough;
case R_HEXAGON_LO16:
*location &= ~0x00c03fff;
*location |= value & 0x3fff;
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index 0a0dd5c05b46..15b4992bfa29 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -1,30 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Process creation support for Hexagon
*
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
+#include <linux/cpu.h>
#include <linux/sched.h>
+#include <linux/sched/debug.h>
+#include <linux/sched/task.h>
+#include <linux/sched/task_stack.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/tick.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
-#include <linux/tracehook.h>
+#include <linux/resume_user_mode.h>
/*
* Program thread launch. Often defined as a macro in processor.h,
@@ -37,8 +28,6 @@
*/
void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
{
- /* Set to run with user-mode data segmentation */
- set_fs(USER_DS);
/* We want to zero all data-containing registers. Is this overkill? */
memset(regs, 0, sizeof(*regs));
/* We might want to also zero all Processor registers here */
@@ -56,23 +45,16 @@ void arch_cpu_idle(void)
{
__vmwait();
/* interrupts wake us up, but irqs are still disabled */
- local_irq_enable();
-}
-
-/*
- * Return saved PC of a blocked thread
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
- return 0;
}
/*
* Copy architecture-specific thread state
*/
-int copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long arg, struct task_struct *p)
+int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
+ u64 clone_flags = args->flags;
+ unsigned long usp = args->stack;
+ unsigned long tls = args->tls;
struct thread_info *ti = task_thread_info(p);
struct hexagon_switch_stack *ss;
struct pt_regs *childregs;
@@ -93,11 +75,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
sizeof(*ss));
ss->lr = (unsigned long)ret_from_fork;
p->thread.switch_sp = ss;
- if (unlikely(p->flags & PF_KTHREAD)) {
+ if (unlikely(args->fn)) {
memset(childregs, 0, sizeof(struct pt_regs));
/* r24 <- fn, r25 <- arg */
- ss->r24 = usp;
- ss->r25 = arg;
+ ss->r24 = (unsigned long)args->fn;
+ ss->r25 = (unsigned long)args->fn_arg;
pt_set_kmode(childregs);
return 0;
}
@@ -120,32 +102,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
* ugp is used to provide TLS support.
*/
if (clone_flags & CLONE_SETTLS)
- childregs->ugp = childregs->r04;
+ childregs->ugp = tls;
/*
* Parent sees new pid -- not necessary, not even possible at
* this point in the fork process
- * Might also want to set things like ti->addr_limit
*/
return 0;
}
/*
- * Release any architecture-specific resources locked by thread
- */
-void release_thread(struct task_struct *dead_task)
-{
-}
-
-/*
- * Free any architecture-specific thread data structures, etc.
- */
-void exit_thread(void)
-{
-}
-
-/*
* Some archs flush debug and FPU info here
*/
void flush_thread(void)
@@ -157,13 +124,11 @@ void flush_thread(void)
* is an identification of the point at which the scheduler
* was invoked by a blocked thread.
*/
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;
- if (!p || p == current || p->state == TASK_RUNNING)
- return 0;
stack_page = (unsigned long)task_stack_page(p);
fp = ((struct hexagon_switch_stack *)p->thread.switch_sp)->fp;
@@ -181,15 +146,6 @@ unsigned long get_wchan(struct task_struct *p)
}
/*
- * Required placeholder.
- */
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
-{
- return 0;
-}
-
-
-/*
* Called on the exit path of event entry; see vm_entry.S
*
* Interrupts will already be disabled.
@@ -197,6 +153,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
* Returns 0 if there's no need to re-check for more work.
*/
+int do_work_pending(struct pt_regs *regs, u32 thread_info_flags);
int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
{
if (!(thread_info_flags & _TIF_WORK_MASK)) {
@@ -210,14 +167,13 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
return 1;
}
- if (thread_info_flags & _TIF_SIGPENDING) {
+ if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
do_signal(regs);
return 1;
}
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(regs);
+ resume_user_mode_work(regs);
return 1;
}
diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c
index de829eb7f185..2093eee143e1 100644
--- a/arch/hexagon/kernel/ptrace.c
+++ b/arch/hexagon/kernel/ptrace.c
@@ -1,27 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Ptrace support for Hexagon
*
* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
-#include <generated/compile.h>
-
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/sched/task_stack.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/errno.h>
@@ -49,58 +35,38 @@ void user_disable_single_step(struct task_struct *child)
static int genregs_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
- int ret;
- unsigned int dummy;
struct pt_regs *regs = task_pt_regs(target);
-
- if (!regs)
- return -EIO;
-
/* The general idea here is that the copyout must happen in
* exactly the same order in which the userspace expects these
* regs. Now, the sequence in userspace does not match the
* sequence in the kernel, so everything past the 32 gprs
* happens one at a time.
*/
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &regs->r00, 0, 32*sizeof(unsigned long));
-
-#define ONEXT(KPT_REG, USR_REG) \
- if (!ret) \
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, \
- KPT_REG, offsetof(struct user_regs_struct, USR_REG), \
- offsetof(struct user_regs_struct, USR_REG) + \
- sizeof(unsigned long));
-
+ membuf_write(&to, &regs->r00, 32*sizeof(unsigned long));
/* Must be exactly same sequence as struct user_regs_struct */
- ONEXT(&regs->sa0, sa0);
- ONEXT(&regs->lc0, lc0);
- ONEXT(&regs->sa1, sa1);
- ONEXT(&regs->lc1, lc1);
- ONEXT(&regs->m0, m0);
- ONEXT(&regs->m1, m1);
- ONEXT(&regs->usr, usr);
- ONEXT(&regs->preds, p3_0);
- ONEXT(&regs->gp, gp);
- ONEXT(&regs->ugp, ugp);
- ONEXT(&pt_elr(regs), pc);
- dummy = pt_cause(regs);
- ONEXT(&dummy, cause);
- ONEXT(&pt_badva(regs), badva);
+ membuf_store(&to, regs->sa0);
+ membuf_store(&to, regs->lc0);
+ membuf_store(&to, regs->sa1);
+ membuf_store(&to, regs->lc1);
+ membuf_store(&to, regs->m0);
+ membuf_store(&to, regs->m1);
+ membuf_store(&to, regs->usr);
+ membuf_store(&to, regs->preds);
+ membuf_store(&to, regs->gp);
+ membuf_store(&to, regs->ugp);
+ membuf_store(&to, pt_elr(regs)); // pc
+ membuf_store(&to, (unsigned long)pt_cause(regs)); // cause
+ membuf_store(&to, pt_badva(regs)); // badva
#if CONFIG_HEXAGON_ARCH_VERSION >=4
- ONEXT(&regs->cs0, cs0);
- ONEXT(&regs->cs1, cs1);
+ membuf_store(&to, regs->cs0);
+ membuf_store(&to, regs->cs1);
+ return membuf_zero(&to, sizeof(unsigned long));
+#else
+ return membuf_zero(&to, 3 * sizeof(unsigned long));
#endif
-
- /* Pad the rest with zeros, if needed */
- if (!ret)
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- offsetof(struct user_regs_struct, pad1), -1);
- return ret;
}
static int genregs_set(struct task_struct *target,
@@ -108,7 +74,7 @@ static int genregs_set(struct task_struct *target,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
- int ret;
+ int ret, ignore_offset;
unsigned long bucket;
struct pt_regs *regs = task_pt_regs(target);
@@ -145,14 +111,16 @@ static int genregs_set(struct task_struct *target,
#if CONFIG_HEXAGON_ARCH_VERSION >=4
INEXT(&regs->cs0, cs0);
INEXT(&regs->cs1, cs1);
+ ignore_offset = offsetof(struct user_regs_struct, pad1);
+#else
+ ignore_offset = offsetof(struct user_regs_struct, cs0);
#endif
/* Ignore the rest, if needed */
if (!ret)
- ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
- offsetof(struct user_regs_struct, pad1), -1);
-
- if (ret)
+ user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ ignore_offset, -1);
+ else
return ret;
/*
@@ -169,20 +137,21 @@ enum hexagon_regset {
static const struct user_regset hexagon_regsets[] = {
[REGSET_GENERAL] = {
- .core_note_type = NT_PRSTATUS,
+ USER_REGSET_NOTE_TYPE(PRSTATUS),
.n = ELF_NGREG,
.size = sizeof(unsigned long),
.align = sizeof(unsigned long),
- .get = genregs_get,
+ .regset_get = genregs_get,
.set = genregs_set,
},
};
static const struct user_regset_view hexagon_user_view = {
- .name = UTS_MACHINE,
+ .name = "hexagon",
.e_machine = ELF_ARCH,
.ei_osabi = ELF_OSABI,
.regsets = hexagon_regsets,
+ .e_flags = ELF_CORE_EFLAGS,
.n = ARRAY_SIZE(hexagon_regsets)
};
diff --git a/arch/hexagon/kernel/reset.c b/arch/hexagon/kernel/reset.c
index 6aeabc962b3b..efd70a8d2526 100644
--- a/arch/hexagon/kernel/reset.c
+++ b/arch/hexagon/kernel/reset.c
@@ -1,21 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
+#include <linux/reboot.h>
#include <linux/smp.h>
#include <asm/hexagon_vm.h>
@@ -33,6 +21,5 @@ void machine_restart(char *cmd)
{
}
-void pm_power_off(void)
-{
-}
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c
index bfe13311d70d..621674e86232 100644
--- a/arch/hexagon/kernel/setup.c
+++ b/arch/hexagon/kernel/setup.c
@@ -1,25 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Arch related setup for Hexagon
*
* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/delay.h>
+#include <linux/memblock.h>
#include <linux/mmzone.h>
#include <linux/mm.h>
#include <linux/seq_file.h>
@@ -32,16 +20,13 @@
#include <asm/hexagon_vm.h>
#include <asm/vm_mmu.h>
#include <asm/time.h>
-#ifdef CONFIG_OF
-#include <asm/prom.h>
-#endif
char cmd_line[COMMAND_LINE_SIZE];
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
int on_simulator;
-void __cpuinit calibrate_delay(void)
+void calibrate_delay(void)
{
loops_per_jiffy = thread_freq_mhz * 1000000 / HZ;
}
@@ -68,7 +53,7 @@ void __init setup_arch(char **cmdline_p)
*/
__vmsetvec(_K_VM_event_vector);
- printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET);
+ printk(KERN_INFO "PHYS_OFFSET=0x%08lx\n", PHYS_OFFSET);
/*
* Simulator has a few differences from the hardware.
@@ -81,9 +66,9 @@ void __init setup_arch(char **cmdline_p)
on_simulator = 0;
if (p[0] != '\0')
- strlcpy(boot_command_line, p, COMMAND_LINE_SIZE);
+ strscpy(boot_command_line, p, COMMAND_LINE_SIZE);
else
- strlcpy(boot_command_line, default_command_line,
+ strscpy(boot_command_line, default_command_line,
COMMAND_LINE_SIZE);
/*
@@ -91,7 +76,7 @@ void __init setup_arch(char **cmdline_p)
* are both picked up by the init code. If no reason to
* make them different, pass the same pointer back.
*/
- strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+ strscpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = cmd_line;
parse_early_param();
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index d7c73874b515..d301f4621553 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -1,30 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Signal support for Hexagon processor
*
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/linkage.h>
#include <linux/syscalls.h>
-#include <linux/tracehook.h>
+#include <linux/sched/task_stack.h>
+
#include <asm/registers.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/ucontext.h>
#include <asm/cacheflush.h>
#include <asm/signal.h>
@@ -36,18 +24,10 @@ struct rt_sigframe {
struct ucontext uc;
};
-static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
size_t frame_size)
{
- unsigned long sp = regs->r29;
-
- /* check if we would overflow the alt stack */
- if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
- return (void __user __force *)-1UL;
-
- /* Switch to signal stack if appropriate */
- if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
- sp = current->sas_ss_sp + current->sas_ss_size;
+ unsigned long sp = sigsp(regs->r29, ksig);
return (void __user *)((sp - frame_size) & ~(sizeof(long long) - 1));
}
@@ -112,20 +92,20 @@ static int restore_sigcontext(struct pt_regs *regs,
/*
* Setup signal stack frame with siginfo structure
*/
-static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
int err = 0;
struct rt_sigframe __user *frame;
struct hexagon_vdso *vdso = current->mm->context.vdso;
- frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+ frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));
- if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe)))
- goto sigsegv;
+ if (!access_ok(frame, sizeof(struct rt_sigframe)))
+ return -EFAULT;
- if (copy_siginfo_to_user(&frame->info, info))
- goto sigsegv;
+ if (copy_siginfo_to_user(&frame->info, &ksig->info))
+ return -EFAULT;
/* The on-stack signal trampoline is no longer executed;
* however, the libgcc signal frame unwinding code checks for
@@ -137,29 +117,26 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs));
if (err)
- goto sigsegv;
+ return -EFAULT;
/* Load r0/r1 pair with signumber/siginfo pointer... */
regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32)
- | (unsigned long long)signr;
+ | (unsigned long long)ksig->sig;
regs->r02 = (unsigned long) &frame->uc;
regs->r31 = (unsigned long) vdso->rt_signal_trampoline;
pt_psp(regs) = (unsigned long) frame;
- pt_set_elr(regs, (unsigned long)ka->sa.sa_handler);
+ pt_set_elr(regs, (unsigned long)ksig->ka.sa.sa_handler);
return 0;
-
-sigsegv:
- force_sigsegv(signr, current);
- return -EFAULT;
}
/*
* Setup invocation of signal handler
*/
-static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
+ int ret;
+
/*
* If we're handling a signal that aborted a system call,
* set up the error return value before adding the signal
@@ -173,11 +150,11 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
regs->r00 = -EINTR;
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->r00 = -EINTR;
break;
}
- /* Fall through */
+ fallthrough;
case -ERESTARTNOINTR:
regs->r06 = regs->syscall_nr;
pt_set_elr(regs, pt_elr(regs) - 4);
@@ -193,11 +170,9 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
* only set up the rt_frame flavor.
*/
/* If there was an error on setup, no signal was delivered. */
- if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
- return;
+ ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
@@ -205,17 +180,13 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
*/
void do_signal(struct pt_regs *regs)
{
- struct k_sigaction sigact;
- siginfo_t info;
- int signo;
+ struct ksignal ksig;
if (!user_mode(regs))
return;
- signo = get_signal_to_deliver(&info, &sigact, regs, NULL);
-
- if (signo > 0) {
- handle_signal(signo, &info, &sigact, regs);
+ if (get_signal(&ksig)) {
+ handle_signal(&ksig, regs);
return;
}
@@ -249,17 +220,17 @@ no_restart:
* Architecture-specific wrappers for signal-related system calls
*/
-asmlinkage int sys_rt_sigreturn(void)
+SYSCALL_DEFINE0(rt_sigreturn)
{
struct pt_regs *regs = current_pt_regs();
struct rt_sigframe __user *frame;
sigset_t blocked;
/* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.fn = do_no_restart_syscall;
frame = (struct rt_sigframe __user *)pt_psp(regs);
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ if (!access_ok(frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&blocked, &frame->uc.uc_sigmask, sizeof(blocked)))
goto badframe;
@@ -280,6 +251,6 @@ asmlinkage int sys_rt_sigreturn(void)
return regs->r00;
badframe:
- force_sig(SIGSEGV, current);
+ force_sig(SIGSEGV);
return 0;
}
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c
index 0e364ca43198..65e1fdf9fdb2 100644
--- a/arch/hexagon/kernel/smp.c
+++ b/arch/hexagon/kernel/smp.c
@@ -1,21 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* SMP support for Hexagon
*
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/err.h>
@@ -25,10 +12,11 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/percpu.h>
-#include <linux/sched.h>
+#include <linux/sched/mm.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <linux/cpu.h>
+#include <linux/mm_types.h>
#include <asm/time.h> /* timer_interrupt */
#include <asm/hexagon_vm.h>
@@ -64,10 +52,6 @@ static inline void __handle_ipi(unsigned long *ops, struct ipi_data *ipi,
generic_smp_call_function_interrupt();
break;
- case IPI_CALL_FUNC_SINGLE:
- generic_smp_call_function_single_interrupt();
- break;
-
case IPI_CPU_STOP:
/*
* call vmstop()
@@ -95,7 +79,7 @@ void smp_vm_unmask_irq(void *info)
* Specifically, first arg is irq, second is the irq_desc.
*/
-irqreturn_t handle_ipi(int irq, void *desc)
+static irqreturn_t handle_ipi(int irq, void *desc)
{
int cpu = smp_processor_id();
struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
@@ -130,26 +114,16 @@ void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg)
local_irq_restore(flags);
}
-static struct irqaction ipi_intdesc = {
- .handler = handle_ipi,
- .flags = IRQF_TRIGGER_RISING,
- .name = "ipi_handler"
-};
-
-void __init smp_prepare_boot_cpu(void)
-{
-}
-
/*
* interrupts should already be disabled from the VM
* SP should already be correct; need to set THREADINFO_REG
* to point to current thread info
*/
-void __cpuinit start_secondary(void)
+static void start_secondary(void)
{
- unsigned int cpu;
unsigned long thread_ptr;
+ unsigned int cpu, irq;
/* Calculate thread_info pointer from stack pointer */
__asm__ __volatile__(
@@ -166,12 +140,15 @@ void __cpuinit start_secondary(void)
);
/* Set the memory struct */
- atomic_inc(&init_mm.mm_count);
+ mmgrab(&init_mm);
current->active_mm = &init_mm;
cpu = smp_processor_id();
- setup_irq(BASE_IPI_IRQ + cpu, &ipi_intdesc);
+ irq = BASE_IPI_IRQ + cpu;
+ if (request_irq(irq, handle_ipi, IRQF_TRIGGER_RISING, "ipi_handler",
+ NULL))
+ pr_err("Failed to request irq %u (ipi_handler)\n", irq);
/* Register the clock_event dummy */
setup_percpu_clockdev();
@@ -184,7 +161,7 @@ void __cpuinit start_secondary(void)
local_irq_enable();
- cpu_startup_entry(CPUHP_ONLINE);
+ cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
@@ -194,7 +171,7 @@ void __cpuinit start_secondary(void)
* maintains control until "cpu_online(cpu)" is set.
*/
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
{
struct thread_info *thread = (struct thread_info *)idle->stack;
void *stack_start;
@@ -217,7 +194,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
void __init smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
+ int i, irq = BASE_IPI_IRQ;
/*
* should eventually have some sort of machine
@@ -229,11 +206,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
set_cpu_present(i, true);
/* Also need to register the interrupts for IPI */
- if (max_cpus > 1)
- setup_irq(BASE_IPI_IRQ, &ipi_intdesc);
+ if (max_cpus > 1) {
+ if (request_irq(irq, handle_ipi, IRQF_TRIGGER_RISING,
+ "ipi_handler", NULL))
+ pr_err("Failed to request irq %d (ipi_handler)\n", irq);
+ }
}
-void smp_send_reschedule(int cpu)
+void arch_smp_send_reschedule(int cpu)
{
send_ipi(cpumask_of(cpu), IPI_RESCHEDULE);
}
@@ -248,7 +228,7 @@ void smp_send_stop(void)
void arch_send_call_function_single_ipi(int cpu)
{
- send_ipi(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+ send_ipi(cpumask_of(cpu), IPI_CALL_FUNC);
}
void arch_send_call_function_ipi_mask(const struct cpumask *mask)
@@ -256,11 +236,6 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
send_ipi(mask, IPI_CALL_FUNC);
}
-int setup_profiling_timer(unsigned int multiplier)
-{
- return -EINVAL;
-}
-
void smp_start_cpus(void)
{
int i;
diff --git a/arch/hexagon/kernel/stacktrace.c b/arch/hexagon/kernel/stacktrace.c
index f94918b449a8..5ed02f699479 100644
--- a/arch/hexagon/kernel/stacktrace.c
+++ b/arch/hexagon/kernel/stacktrace.c
@@ -1,30 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Stacktrace support for Hexagon
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/sched.h>
+#include <linux/sched/task_stack.h>
#include <linux/stacktrace.h>
#include <linux/thread_info.h>
#include <linux/module.h>
-register unsigned long current_frame_pointer asm("r30");
-
struct stackframe {
unsigned long fp;
unsigned long rets;
@@ -42,7 +28,7 @@ void save_stack_trace(struct stack_trace *trace)
low = (unsigned long)task_stack_page(current);
high = low + THREAD_SIZE;
- fp = current_frame_pointer;
+ fp = (unsigned long)__builtin_frame_address(0);
while (fp >= low && fp <= (high - sizeof(*frame))) {
frame = (struct stackframe *)fp;
diff --git a/arch/hexagon/kernel/syscalltab.c b/arch/hexagon/kernel/syscalltab.c
index 7024b1ddc08a..b53e2eead4ac 100644
--- a/arch/hexagon/kernel/syscalltab.c
+++ b/arch/hexagon/kernel/syscalltab.c
@@ -1,21 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* System call table for Hexagon
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/syscalls.h>
@@ -24,9 +11,20 @@
#include <asm/syscall.h>
-#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),
+#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
+
+#define sys_mmap2 sys_mmap_pgoff
+
+SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice,
+ SC_ARG64(offset), SC_ARG64(len))
+{
+ return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, len), advice);
+}
+#define sys_fadvise64_64 sys_hexagon_fadvise64_64
+
+#define sys_sync_file_range sys_sync_file_range2
void *sys_call_table[__NR_syscalls] = {
-#include <asm/unistd.h>
+#include <asm/syscall_table_32.h>
};
diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c
index 9903fad997f3..6f851e1cd4ee 100644
--- a/arch/hexagon/kernel/time.c
+++ b/arch/hexagon/kernel/time.c
@@ -1,21 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Time related functions for Hexagon architecture
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/init.h>
@@ -30,8 +17,11 @@
#include <linux/of_irq.h>
#include <linux/module.h>
-#include <asm/timer-regs.h>
+#include <asm/delay.h>
#include <asm/hexagon_vm.h>
+#include <asm/time.h>
+
+#define TIMER_ENABLE BIT(0)
/*
* For the clocksource we need:
@@ -46,6 +36,13 @@ cycles_t pcycle_freq_mhz;
cycles_t thread_freq_mhz;
cycles_t sleep_clk_freq;
+/*
+ * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until
+ * release 1.1, and then it's "adjustable" and probably not defaulted.
+ */
+#define RTOS_TIMER_INT 3
+#define RTOS_TIMER_REGS_ADDR 0xAB000000UL
+
static struct resource rtos_timer_resources[] = {
{
.start = RTOS_TIMER_REGS_ADDR,
@@ -72,9 +69,9 @@ struct adsp_hw_timer_struct {
/* Look for "TCX0" for related constants. */
static __iomem struct adsp_hw_timer_struct *rtos_timer;
-static cycle_t timer_get_cycles(struct clocksource *cs)
+static u64 timer_get_cycles(struct clocksource *cs)
{
- return (cycle_t) __vmgettime();
+ return (u64) __vmgettime();
}
static struct clocksource hexagon_clocksource = {
@@ -93,24 +90,10 @@ static int set_next_event(unsigned long delta, struct clock_event_device *evt)
iowrite32(0, &rtos_timer->clear);
iowrite32(delta, &rtos_timer->match);
- iowrite32(1 << TIMER_ENABLE, &rtos_timer->enable);
+ iowrite32(TIMER_ENABLE, &rtos_timer->enable);
return 0;
}
-/*
- * Sets the mode (periodic, shutdown, oneshot, etc) of a timer.
- */
-static void set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- switch (mode) {
- case CLOCK_EVT_MODE_SHUTDOWN:
- /* XXX implement me */
- default:
- break;
- }
-}
-
#ifdef CONFIG_SMP
/* Broadcast mechanism */
static void broadcast(const struct cpumask *mask)
@@ -119,13 +102,13 @@ static void broadcast(const struct cpumask *mask)
}
#endif
+/* XXX Implement set_state_shutdown() */
static struct clock_event_device hexagon_clockevent_dev = {
.name = "clockevent",
.features = CLOCK_EVT_FEAT_ONESHOT,
.rating = 400,
.irq = RTOS_TIMER_INT,
.set_next_event = set_next_event,
- .set_mode = set_mode,
#ifdef CONFIG_SMP
.broadcast = broadcast,
#endif
@@ -146,7 +129,6 @@ void setup_percpu_clockdev(void)
dummy_clock_dev->features = CLOCK_EVT_FEAT_DUMMY;
dummy_clock_dev->cpumask = cpumask_of(cpu);
- dummy_clock_dev->mode = CLOCK_EVT_MODE_UNUSED;
clockevents_register_device(dummy_clock_dev);
}
@@ -171,13 +153,6 @@ static irqreturn_t timer_interrupt(int irq, void *devid)
return IRQ_HANDLED;
}
-/* This should also be pulled from devtree */
-static struct irqaction rtos_timer_intdesc = {
- .handler = timer_interrupt,
- .flags = IRQF_TIMER | IRQF_TRIGGER_RISING,
- .name = "rtos_timer"
-};
-
/*
* time_init_deferred - called by start_kernel to set up timer/clock source
*
@@ -187,18 +162,15 @@ static struct irqaction rtos_timer_intdesc = {
* This runs just before the delay loop is calibrated, and
* is used for delay calibration.
*/
-void __init time_init_deferred(void)
+static void __init time_init_deferred(void)
{
struct resource *resource = NULL;
struct clock_event_device *ce_dev = &hexagon_clockevent_dev;
- struct device_node *dn;
- struct resource r;
- int err;
+ unsigned long flag = IRQF_TIMER | IRQF_TRIGGER_RISING;
ce_dev->cpumask = cpu_all_mask;
- if (!resource)
- resource = rtos_timer_device.resource;
+ resource = rtos_timer_device.resource;
/* ioremap here means this has to run later, after paging init */
rtos_timer = ioremap(resource->start, resource_size(resource));
@@ -217,14 +189,17 @@ void __init time_init_deferred(void)
clockevents_calc_mult_shift(ce_dev, sleep_clk_freq, 4);
ce_dev->max_delta_ns = clockevent_delta2ns(0x7fffffff, ce_dev);
+ ce_dev->max_delta_ticks = 0x7fffffff;
ce_dev->min_delta_ns = clockevent_delta2ns(0xf, ce_dev);
+ ce_dev->min_delta_ticks = 0xf;
#ifdef CONFIG_SMP
setup_percpu_clockdev();
#endif
clockevents_register_device(ce_dev);
- setup_irq(ce_dev->irq, &rtos_timer_intdesc);
+ if (request_irq(ce_dev->irq, timer_interrupt, flag, "rtos_timer", NULL))
+ pr_err("Failed to register rtos_timer interrupt\n");
}
void __init time_init(void)
@@ -232,6 +207,15 @@ void __init time_init(void)
late_time_init = time_init_deferred;
}
+void __delay(unsigned long cycles)
+{
+ unsigned long long start = __vmgettime();
+
+ while ((__vmgettime() - start) < cycles)
+ cpu_relax();
+}
+EXPORT_SYMBOL(__delay);
+
/*
* This could become parametric or perhaps even computed at run-time,
* but for now we take the observed simulator jitter.
diff --git a/arch/hexagon/kernel/trampoline.S b/arch/hexagon/kernel/trampoline.S
index 18110a9056b0..58f631870f7e 100644
--- a/arch/hexagon/kernel/trampoline.S
+++ b/arch/hexagon/kernel/trampoline.S
@@ -1,19 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
/*
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index 7858663352b9..e732aa01c2ff 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -1,31 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Kernel traps/events for Hexagon processor
*
- * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
-#include <linux/sched.h>
+#include <linux/sched/signal.h>
+#include <linux/sched/debug.h>
+#include <linux/sched/task_stack.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/kdebug.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
-#include <linux/tracehook.h>
+#include <linux/ptrace.h>
#include <asm/traps.h>
#include <asm/vm_fault.h>
#include <asm/syscall.h>
@@ -39,10 +28,6 @@
#define TRAP_SYSCALL 1
#define TRAP_DEBUG 0xdb
-void __init trap_init(void)
-{
-}
-
#ifdef CONFIG_GENERIC_BUG
/* Maybe should resemble arch/sh/kernel/traps.c ?? */
int is_valid_bugaddr(unsigned long addr)
@@ -90,7 +75,7 @@ static const char *ex_name(int ex)
}
static void do_show_stack(struct task_struct *task, unsigned long *fp,
- unsigned long ip)
+ unsigned long ip, const char *loglvl)
{
int kstack_depth_to_print = 24;
unsigned long offset, size;
@@ -104,9 +89,8 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
if (task == NULL)
task = current;
- printk(KERN_INFO "CPU#%d, %s/%d, Call Trace:\n",
- raw_smp_processor_id(), task->comm,
- task_pid_nr(task));
+ printk("%sCPU#%d, %s/%d, Call Trace:\n", loglvl, raw_smp_processor_id(),
+ task->comm, task_pid_nr(task));
if (fp == NULL) {
if (task == current) {
@@ -119,7 +103,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
}
if ((((unsigned long) fp) & 0x3) || ((unsigned long) fp < 0x1000)) {
- printk(KERN_INFO "-- Corrupt frame pointer %p\n", fp);
+ printk("%s-- Corrupt frame pointer %p\n", loglvl, fp);
return;
}
@@ -136,8 +120,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr);
- printk(KERN_INFO "[%p] 0x%lx: %s + 0x%lx", fp, ip, name,
- offset);
+ printk("%s[%p] 0x%lx: %s + 0x%lx", loglvl, fp, ip, name, offset);
if (((unsigned long) fp < low) || (high < (unsigned long) fp))
printk(KERN_CONT " (FP out of bounds!)");
if (modname)
@@ -147,18 +130,17 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
newfp = (unsigned long *) *fp;
if (((unsigned long) newfp) & 0x3) {
- printk(KERN_INFO "-- Corrupt frame pointer %p\n",
- newfp);
+ printk("%s-- Corrupt frame pointer %p\n", loglvl, newfp);
break;
}
/* Attempt to continue past exception. */
- if (0 == newfp) {
+ if (!newfp) {
struct pt_regs *regs = (struct pt_regs *) (((void *)fp)
+ 8);
if (regs->syscall_nr != -1) {
- printk(KERN_INFO "-- trap0 -- syscall_nr: %ld",
+ printk("%s-- trap0 -- syscall_nr: %ld", loglvl,
regs->syscall_nr);
printk(KERN_CONT " psp: %lx elr: %lx\n",
pt_psp(regs), pt_elr(regs));
@@ -166,7 +148,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
} else {
/* really want to see more ... */
kstack_depth_to_print += 6;
- printk(KERN_INFO "-- %s (0x%lx) badva: %lx\n",
+ printk("%s-- %s (0x%lx) badva: %lx\n", loglvl,
ex_name(pt_cause(regs)), pt_cause(regs),
pt_badva(regs));
}
@@ -189,10 +171,10 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
}
}
-void show_stack(struct task_struct *task, unsigned long *fp)
+void show_stack(struct task_struct *task, unsigned long *fp, const char *loglvl)
{
/* Saved link reg is one word above FP */
- do_show_stack(task, fp, 0);
+ do_show_stack(task, fp, 0, loglvl);
}
int die(const char *str, struct pt_regs *regs, long err)
@@ -213,12 +195,14 @@ int die(const char *str, struct pt_regs *regs, long err)
printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter);
if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) ==
- NOTIFY_STOP)
+ NOTIFY_STOP) {
+ spin_unlock_irq(&die.lock);
return 1;
+ }
print_modules();
show_regs(regs);
- do_show_stack(current, &regs->r30, pt_elr(regs));
+ do_show_stack(current, &regs->r30, pt_elr(regs), KERN_EMERG);
bust_spinlocks(0);
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
@@ -232,7 +216,7 @@ int die(const char *str, struct pt_regs *regs, long err)
panic("Fatal exception");
oops_exit();
- do_exit(err);
+ make_task_dead(err);
return 0;
}
@@ -250,7 +234,7 @@ int die_if_kernel(char *str, struct pt_regs *regs, long err)
static void misaligned_instruction(struct pt_regs *regs)
{
die_if_kernel("Misaligned Instruction", regs, 0);
- force_sig(SIGBUS, current);
+ force_sig(SIGBUS);
}
/*
@@ -261,19 +245,19 @@ static void misaligned_instruction(struct pt_regs *regs)
static void misaligned_data_load(struct pt_regs *regs)
{
die_if_kernel("Misaligned Data Load", regs, 0);
- force_sig(SIGBUS, current);
+ force_sig(SIGBUS);
}
static void misaligned_data_store(struct pt_regs *regs)
{
die_if_kernel("Misaligned Data Store", regs, 0);
- force_sig(SIGBUS, current);
+ force_sig(SIGBUS);
}
static void illegal_instruction(struct pt_regs *regs)
{
die_if_kernel("Illegal Instruction", regs, 0);
- force_sig(SIGILL, current);
+ force_sig(SIGILL);
}
/*
@@ -283,7 +267,7 @@ static void illegal_instruction(struct pt_regs *regs)
static void precise_bus_error(struct pt_regs *regs)
{
die_if_kernel("Precise Bus Error", regs, 0);
- force_sig(SIGBUS, current);
+ force_sig(SIGBUS);
}
/*
@@ -299,6 +283,7 @@ static void cache_error(struct pt_regs *regs)
/*
* General exception handler
*/
+void do_genex(struct pt_regs *regs);
void do_genex(struct pt_regs *regs)
{
/*
@@ -349,13 +334,7 @@ void do_genex(struct pt_regs *regs)
}
}
-/* Indirect system call dispatch */
-long sys_syscall(void)
-{
- printk(KERN_ERR "sys_syscall invoked!\n");
- return -ENOSYS;
-}
-
+void do_trap0(struct pt_regs *regs);
void do_trap0(struct pt_regs *regs)
{
syscall_fn syscall;
@@ -366,7 +345,7 @@ void do_trap0(struct pt_regs *regs)
/* allow strace to catch syscall args */
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) &&
- tracehook_report_syscall_entry(regs)))
+ ptrace_report_syscall_entry(regs)))
return; /* return -ENOSYS somewhere? */
/* Interrupts should be re-enabled for syscall processing */
@@ -404,16 +383,12 @@ void do_trap0(struct pt_regs *regs)
/* allow strace to get the syscall return state */
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE)))
- tracehook_report_syscall_exit(regs, 0);
+ ptrace_report_syscall_exit(regs, 0);
break;
case TRAP_DEBUG:
/* Trap0 0xdb is debug breakpoint */
if (user_mode(regs)) {
- struct siginfo info;
-
- info.si_signo = SIGTRAP;
- info.si_errno = 0;
/*
* Some architecures add some per-thread state
* to distinguish between breakpoint traps and
@@ -421,9 +396,8 @@ void do_trap0(struct pt_regs *regs)
* set the si_code value appropriately, or we
* may want to use a different trap0 flavor.
*/
- info.si_code = TRAP_BRKPT;
- info.si_addr = (void __user *) pt_elr(regs);
- send_sig_info(SIGTRAP, &info, current);
+ force_sig_fault(SIGTRAP, TRAP_BRKPT,
+ (void __user *) pt_elr(regs));
} else {
#ifdef CONFIG_KGDB
kgdb_handle_exception(pt_cause(regs), SIGTRAP,
@@ -438,6 +412,7 @@ void do_trap0(struct pt_regs *regs)
/*
* Machine check exception handler
*/
+void do_machcheck(struct pt_regs *regs);
void do_machcheck(struct pt_regs *regs)
{
/* Halt and catch fire */
@@ -448,6 +423,7 @@ void do_machcheck(struct pt_regs *regs)
* Treat this like the old 0xdb trap.
*/
+void do_debug_exception(struct pt_regs *regs);
void do_debug_exception(struct pt_regs *regs)
{
regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK;
diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c
index 0bf5a87e4d0a..8119084dc519 100644
--- a/arch/hexagon/kernel/vdso.c
+++ b/arch/hexagon/kernel/vdso.c
@@ -1,21 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* vDSO implementation for Hexagon
*
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/err.h>
@@ -23,6 +10,7 @@
#include <linux/vmalloc.h>
#include <linux/binfmts.h>
+#include <asm/elf.h>
#include <asm/vdso.h>
static struct page *vdso_page;
@@ -63,9 +51,14 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
int ret;
unsigned long vdso_base;
+ struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
+ static struct vm_special_mapping vdso_mapping = {
+ .name = "[vdso]",
+ };
- down_write(&mm->mmap_sem);
+ if (mmap_write_lock_killable(mm))
+ return -EINTR;
/* Try to get it loaded right near ld.so/glibc. */
vdso_base = STACK_TOP;
@@ -77,18 +70,20 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
}
/* MAYWRITE to allow gdb to COW and set breakpoints. */
- ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
+ vdso_mapping.pages = &vdso_page;
+ vma = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
VM_READ|VM_EXEC|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
- &vdso_page);
+ &vdso_mapping);
- if (ret)
+ ret = PTR_ERR(vma);
+ if (IS_ERR(vma))
goto up_fail;
mm->context.vdso = (void *)vdso_base;
-
+ ret = 0;
up_fail:
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
return ret;
}
diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S
index 67c6ccc14770..554371d92bed 100644
--- a/arch/hexagon/kernel/vm_entry.S
+++ b/arch/hexagon/kernel/vm_entry.S
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Event entry/exit for Hexagon
*
* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <asm/asm-offsets.h> /* assembly-safer versions of C defines */
@@ -278,12 +265,12 @@ event_dispatch:
* should be in the designated register (usually R19)
*
* If we were in kernel mode, we don't need to check scheduler
- * or signals if CONFIG_PREEMPT is not set. If set, then it has
+ * or signals if CONFIG_PREEMPTION is not set. If set, then it has
* to jump to a need_resched kind of block.
- * BTW, CONFIG_PREEMPT is not supported yet.
+ * BTW, CONFIG_PREEMPTION is not supported yet.
*/
-#ifdef CONFIG_PREEMPT
+#ifdef CONFIG_PREEMPTION
R0 = #VM_INT_DISABLE
trap1(#HVM_TRAP1_VMSETIE)
#endif
@@ -382,7 +369,7 @@ ret_from_fork:
R26.L = #LO(do_work_pending);
R0 = #VM_INT_DISABLE;
}
- if P0 jump check_work_pending
+ if (P0) jump check_work_pending
{
R0 = R25;
callr R24
diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c
index 741aaa917cda..2b881a89b206 100644
--- a/arch/hexagon/kernel/vm_events.c
+++ b/arch/hexagon/kernel/vm_events.c
@@ -1,24 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Mostly IRQ support for Hexagon
*
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/kernel.h>
+#include <linux/sched/debug.h>
#include <asm/registers.h>
#include <linux/irq.h>
#include <linux/hardirq.h>
@@ -85,13 +73,6 @@ void show_regs(struct pt_regs *regs)
pt_psp(regs), pt_badva(regs), ints_enabled(regs));
}
-void dummy_handler(struct pt_regs *regs)
-{
- unsigned int elr = pt_elr(regs);
- printk(KERN_ERR "Unimplemented handler; ELR=0x%08x\n", elr);
-}
-
-
void arch_do_IRQ(struct pt_regs *regs)
{
int irq = pt_cause(regs);
diff --git a/arch/hexagon/kernel/vm_init_segtable.S b/arch/hexagon/kernel/vm_init_segtable.S
index 80967f2192b3..2638a0906361 100644
--- a/arch/hexagon/kernel/vm_init_segtable.S
+++ b/arch/hexagon/kernel/vm_init_segtable.S
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Initial page table for Linux kernel under Hexagon VM,
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
/*
diff --git a/arch/hexagon/kernel/vm_ops.S b/arch/hexagon/kernel/vm_ops.S
index 9fb77b3f6cf2..f61c04d485f6 100644
--- a/arch/hexagon/kernel/vm_ops.S
+++ b/arch/hexagon/kernel/vm_ops.S
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Hexagon VM instruction support
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <linux/linkage.h>
@@ -26,7 +13,7 @@
* could be, and perhaps some day will be, handled as in-line
* macros, but for tracing/debugging it's handy to have
* a single point of invocation for each of them.
- * Conveniently, they take paramters and return values
+ * Conveniently, they take parameters and return values
* consistent with the ABI calling convention.
*/
diff --git a/arch/hexagon/kernel/vm_switch.S b/arch/hexagon/kernel/vm_switch.S
index 62c6df91b3bb..5ec2d43fee1f 100644
--- a/arch/hexagon/kernel/vm_switch.S
+++ b/arch/hexagon/kernel/vm_switch.S
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Context switch support for Hexagon
*
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <asm/asm-offsets.h>
diff --git a/arch/hexagon/kernel/vm_vectors.S b/arch/hexagon/kernel/vm_vectors.S
index 791a7422dde4..fba33745ce57 100644
--- a/arch/hexagon/kernel/vm_vectors.S
+++ b/arch/hexagon/kernel/vm_vectors.S
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Event jump tables
*
* Copyright (c) 2010-2012,2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
*/
#include <asm/hexagon_vm.h>
diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S
index 44d8c47bae2f..1150b77fa281 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -1,27 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Linker script for Hexagon kernel
*
- * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
*/
#include <asm-generic/vmlinux.lds.h>
#include <asm/asm-offsets.h> /* Most of the kernel defines are here */
#include <asm/mem-layout.h> /* except for page_offset */
#include <asm/cache.h> /* and now we're pulling cache line size */
+#include <asm/thread_info.h> /* and we need THREAD_SIZE too */
+
OUTPUT_ARCH(hexagon)
ENTRY(stext)
@@ -49,6 +38,8 @@ SECTIONS
.text : AT(ADDR(.text)) {
_text = .;
TEXT_TEXT
+ IRQENTRY_TEXT
+ SOFTIRQENTRY_TEXT
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
@@ -59,24 +50,20 @@ SECTIONS
INIT_DATA_SECTION(PAGE_SIZE)
_sdata = .;
- RW_DATA_SECTION(32,PAGE_SIZE,PAGE_SIZE)
- RO_DATA_SECTION(PAGE_SIZE)
+ RW_DATA(32,PAGE_SIZE,_THREAD_SIZE)
+ RO_DATA(PAGE_SIZE)
_edata = .;
EXCEPTION_TABLE(16)
- NOTES
BSS_SECTION(_PAGE_SIZE, _PAGE_SIZE, _PAGE_SIZE)
_end = .;
- /DISCARD/ : {
- EXIT_TEXT
- EXIT_DATA
- EXIT_CALL
- }
-
STABS_DEBUG
DWARF_DEBUG
+ ELF_DETAILS
+ .hexagon.attributes 0 : { *(.hexagon.attributes) }
+ DISCARDS
}