summaryrefslogtreecommitdiff
path: root/arch/nios2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/nios2')
-rw-r--r--arch/nios2/Kbuild6
-rw-r--r--arch/nios2/Kconfig37
-rw-r--r--arch/nios2/Kconfig.debug3
-rw-r--r--arch/nios2/Makefile13
-rw-r--r--arch/nios2/boot/.gitignore1
-rw-r--r--arch/nios2/boot/Makefile5
-rw-r--r--arch/nios2/boot/dts/10m50_devboard.dts8
-rw-r--r--arch/nios2/boot/dts/3c120_devboard.dts2
-rw-r--r--arch/nios2/boot/dts/Makefile2
-rwxr-xr-x[-rw-r--r--]arch/nios2/boot/install.sh22
-rw-r--r--arch/nios2/configs/10m50_defconfig5
-rw-r--r--arch/nios2/configs/3c120_defconfig5
-rw-r--r--arch/nios2/include/asm/Kbuild38
-rw-r--r--arch/nios2/include/asm/cacheflush.h13
-rw-r--r--arch/nios2/include/asm/cachetype.h10
-rw-r--r--arch/nios2/include/asm/checksum.h7
-rw-r--r--arch/nios2/include/asm/entry.h3
-rw-r--r--arch/nios2/include/asm/irq.h1
-rw-r--r--arch/nios2/include/asm/irqflags.h4
-rw-r--r--arch/nios2/include/asm/mmu_context.h21
-rw-r--r--arch/nios2/include/asm/page.h14
-rw-r--r--arch/nios2/include/asm/pgalloc.h21
-rw-r--r--arch/nios2/include/asm/pgtable-bits.h3
-rw-r--r--arch/nios2/include/asm/pgtable.h123
-rw-r--r--arch/nios2/include/asm/processor.h10
-rw-r--r--arch/nios2/include/asm/ptrace.h2
-rw-r--r--arch/nios2/include/asm/registers.h2
-rw-r--r--arch/nios2/include/asm/syscall.h11
-rw-r--r--arch/nios2/include/asm/thread_info.h14
-rw-r--r--arch/nios2/include/asm/timex.h3
-rw-r--r--arch/nios2/include/asm/traps.h2
-rw-r--r--arch/nios2/include/asm/uaccess.h106
-rw-r--r--arch/nios2/include/asm/vmalloc.h4
-rw-r--r--arch/nios2/kernel/.gitignore1
-rw-r--r--arch/nios2/kernel/Makefile2
-rw-r--r--arch/nios2/kernel/cpuinfo.c2
-rw-r--r--arch/nios2/kernel/entry.S34
-rw-r--r--arch/nios2/kernel/irq.c5
-rw-r--r--arch/nios2/kernel/module.c1
-rw-r--r--arch/nios2/kernel/nios2_ksyms.c2
-rw-r--r--arch/nios2/kernel/process.c39
-rw-r--r--arch/nios2/kernel/ptrace.c62
-rw-r--r--arch/nios2/kernel/setup.c43
-rw-r--r--arch/nios2/kernel/signal.c33
-rw-r--r--arch/nios2/kernel/sys_nios2.c11
-rw-r--r--arch/nios2/kernel/syscall_table.c1
-rw-r--r--arch/nios2/kernel/traps.c26
-rw-r--r--arch/nios2/kernel/vmlinux.lds.S2
-rw-r--r--arch/nios2/mm/cacheflush.c85
-rw-r--r--arch/nios2/mm/dma-mapping.c12
-rw-r--r--arch/nios2/mm/fault.c84
-rw-r--r--arch/nios2/mm/init.c39
-rw-r--r--arch/nios2/mm/ioremap.c14
-rw-r--r--arch/nios2/mm/pgtable.c3
-rw-r--r--arch/nios2/mm/tlb.c1
-rw-r--r--arch/nios2/platform/Kconfig.platform1
-rw-r--r--arch/nios2/platform/platform.c8
57 files changed, 459 insertions, 573 deletions
diff --git a/arch/nios2/Kbuild b/arch/nios2/Kbuild
new file mode 100644
index 000000000000..fc2952edd2de
--- /dev/null
+++ b/arch/nios2/Kbuild
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-y += kernel/ mm/ platform/ boot/dts/
+
+# for cleaning
+subdir- += boot
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 44b5da37e8bd..9c0e6eaeb005 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -2,21 +2,23 @@
config NIOS2
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_CPU_CACHE_ALIASING
+ select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
- select ARCH_HAS_UNCACHED_SEGMENT
+ select ARCH_HAS_DMA_SET_UNCACHED
select ARCH_NO_SWAP
+ select COMMON_CLK
select TIMER_OF
select GENERIC_ATOMIC64
- select GENERIC_CLOCKEVENTS
select GENERIC_CPU_DEVICES
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_KGDB
+ select HAVE_PAGE_SIZE_4KB
select IRQ_DOMAIN
+ select LOCK_MM_AND_FIND_VMA
select MODULES_USE_ELF_RELA
select OF
select OF_EARLY_FLATTREE
@@ -41,27 +43,22 @@ config NO_IOPORT_MAP
config FPU
def_bool n
-config TRACE_IRQFLAGS_SUPPORT
- def_bool n
-
menu "Kernel features"
source "kernel/Kconfig.hz"
-config FORCE_MAX_ZONEORDER
- int "Maximum zone order"
- range 9 20
- default "11"
+config ARCH_FORCE_MAX_ORDER
+ int "Order of maximal physically contiguous allocations"
+ default "10"
help
- The kernel memory allocator divides physically contiguous memory
- blocks into "zones", where each zone is a power of two number of
- pages. This option selects the largest power of two that the kernel
- keeps in the memory allocator. If you need to allocate very large
- blocks of physically contiguous memory, then you may need to
- increase this value.
-
- This config option is actually maximum order plus one. For example,
- a value of 11 means that the largest free memory block is 2^10 pages.
+ The kernel page allocator limits the size of maximal physically
+ contiguous allocations. The limit is called MAX_PAGE_ORDER and it
+ defines the maximal power of two of number of pages that can be
+ allocated as a single contiguous block. This option allows
+ overriding the default setting when ability to allocate very
+ large blocks of physically contiguous memory is required.
+
+ Don't change if unsure.
endmenu
diff --git a/arch/nios2/Kconfig.debug b/arch/nios2/Kconfig.debug
index a8bc06e96ef5..ca1beb87f987 100644
--- a/arch/nios2/Kconfig.debug
+++ b/arch/nios2/Kconfig.debug
@@ -3,9 +3,10 @@
config EARLY_PRINTK
bool "Activate early kernel debugging"
default y
+ depends on TTY
select SERIAL_CORE_CONSOLE
help
- Enable early printk on console
+ Enable early printk on console.
This is useful for kernel debugging when your machine crashes very
early before the console code is initialized.
You should normally say N here, unless you want to debug such a crash.
diff --git a/arch/nios2/Makefile b/arch/nios2/Makefile
index 52c03e60b114..f1ff4ce0f1a2 100644
--- a/arch/nios2/Makefile
+++ b/arch/nios2/Makefile
@@ -8,8 +8,7 @@
# Written by Fredrik Markstrom
#
# This file is included by the global makefile so that you can add your own
-# architecture-specific flags and dependencies. Remember to do have actions
-# for "archclean" cleaning up for this architecture.
+# architecture-specific flags and dependencies.
#
# Nios2 port by Wind River Systems Inc trough:
# fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
@@ -38,10 +37,7 @@ KBUILD_CFLAGS += -DUTS_SYSNAME=\"$(UTS_SYSNAME)\"
KBUILD_CFLAGS += -fno-builtin
KBUILD_CFLAGS += -G 0
-head-y := arch/nios2/kernel/head.o
libs-y += arch/nios2/lib/ $(LIBGCC)
-core-y += arch/nios2/kernel/ arch/nios2/mm/
-core-y += arch/nios2/platform/
INSTALL_PATH ?= /tftpboot
nios2-boot := arch/$(ARCH)/boot
@@ -49,18 +45,13 @@ BOOT_TARGETS = vmImage zImage
PHONY += $(BOOT_TARGETS) install
KBUILD_IMAGE := $(nios2-boot)/vmImage
-core-y += $(nios2-boot)/dts/
-
all: vmImage
-archclean:
- $(Q)$(MAKE) $(clean)=$(nios2-boot)
-
$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(nios2-boot) $(nios2-boot)/$@
install:
- $(Q)$(MAKE) $(build)=$(nios2-boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+ $(call cmd,install)
define archhelp
echo '* vmImage - Kernel-only image for U-Boot ($(KBUILD_IMAGE))'
diff --git a/arch/nios2/boot/.gitignore b/arch/nios2/boot/.gitignore
index 64386a8dedd8..ef37cac5bcc0 100644
--- a/arch/nios2/boot/.gitignore
+++ b/arch/nios2/boot/.gitignore
@@ -1 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
vmImage
diff --git a/arch/nios2/boot/Makefile b/arch/nios2/boot/Makefile
index 37dfc7e584bc..29c11a06b750 100644
--- a/arch/nios2/boot/Makefile
+++ b/arch/nios2/boot/Makefile
@@ -20,7 +20,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
-$(obj)/vmImage: $(obj)/vmlinux.gz
+$(obj)/vmImage: $(obj)/vmlinux.gz FORCE
$(call if_changed,uimage)
@$(kecho) 'Kernel: $@ is ready'
@@ -30,6 +30,3 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(obj)/compressed/vmlinux: $(obj)/vmlinux.gz FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
-
-install:
- sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
diff --git a/arch/nios2/boot/dts/10m50_devboard.dts b/arch/nios2/boot/dts/10m50_devboard.dts
index 5e4ab032c1e8..0e7e5b0dd685 100644
--- a/arch/nios2/boot/dts/10m50_devboard.dts
+++ b/arch/nios2/boot/dts/10m50_devboard.dts
@@ -97,7 +97,7 @@
rx-fifo-depth = <8192>;
tx-fifo-depth = <8192>;
address-bits = <48>;
- max-frame-size = <1518>;
+ max-frame-size = <1500>;
local-mac-address = [00 00 00 00 00 00];
altr,has-supplementary-unicast;
altr,enable-sup-addr = <1>;
@@ -179,8 +179,7 @@
led_pio: gpio@180014d0 {
compatible = "altr,pio-1.0";
reg = <0x180014d0 0x00000010>;
- altr,gpio-bank-width = <4>;
- resetvalue = <15>;
+ altr,ngpio = <4>;
#gpio-cells = <2>;
gpio-controller;
};
@@ -190,11 +189,10 @@
reg = <0x180014c0 0x00000010>;
interrupt-parent = <&cpu>;
interrupts = <6>;
- altr,gpio-bank-width = <3>;
+ altr,ngpio = <3>;
altr,interrupt-type = <2>;
edge_type = <1>;
level_trigger = <0>;
- resetvalue = <0>;
#gpio-cells = <2>;
gpio-controller;
};
diff --git a/arch/nios2/boot/dts/3c120_devboard.dts b/arch/nios2/boot/dts/3c120_devboard.dts
index d10fb81686c7..3ee316906379 100644
--- a/arch/nios2/boot/dts/3c120_devboard.dts
+++ b/arch/nios2/boot/dts/3c120_devboard.dts
@@ -106,7 +106,7 @@
interrupt-names = "rx_irq", "tx_irq";
rx-fifo-depth = <8192>;
tx-fifo-depth = <8192>;
- max-frame-size = <1518>;
+ max-frame-size = <1500>;
local-mac-address = [ 00 00 00 00 00 00 ];
phy-mode = "rgmii-id";
phy-handle = <&phy0>;
diff --git a/arch/nios2/boot/dts/Makefile b/arch/nios2/boot/dts/Makefile
index a91a0b09be63..e9e31bb40df8 100644
--- a/arch/nios2/boot/dts/Makefile
+++ b/arch/nios2/boot/dts/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-obj-y := $(patsubst "%.dts",%.dtb.o,$(CONFIG_NIOS2_DTB_SOURCE))
+obj-y := $(patsubst %.dts,%.dtb.o,$(CONFIG_NIOS2_DTB_SOURCE))
dtstree := $(srctree)/$(src)
dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
diff --git a/arch/nios2/boot/install.sh b/arch/nios2/boot/install.sh
index 3cb3f468bc51..34a2feec42c8 100644..100755
--- a/arch/nios2/boot/install.sh
+++ b/arch/nios2/boot/install.sh
@@ -15,28 +15,6 @@
# $2 - kernel image file
# $3 - kernel map file
# $4 - default install path (blank if root directory)
-#
-
-verify () {
- if [ ! -f "$1" ]; then
- echo "" 1>&2
- echo " *** Missing file: $1" 1>&2
- echo ' *** You need to run "make" before "make install".' 1>&2
- echo "" 1>&2
- exit 1
- fi
-}
-
-# Make sure the files actually exist
-verify "$2"
-verify "$3"
-
-# User may have a custom install script
-
-if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
-if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
-
-# Default install - same as make zlilo
if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old
diff --git a/arch/nios2/configs/10m50_defconfig b/arch/nios2/configs/10m50_defconfig
index a7967b4cfb6e..048f74e0dc6d 100644
--- a/arch/nios2/configs/10m50_defconfig
+++ b/arch/nios2/configs/10m50_defconfig
@@ -9,8 +9,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_EVENTFD is not set
# CONFIG_SHMEM is not set
# CONFIG_AIO is not set
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
+CONFIG_EXPERT=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_NIOS2_MEM_BASE=0x8000000
@@ -74,4 +73,4 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_ROOT_NFS=y
CONFIG_SUNRPC_DEBUG=y
-CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
diff --git a/arch/nios2/configs/3c120_defconfig b/arch/nios2/configs/3c120_defconfig
index 423a0c40a162..48fe353f8d2d 100644
--- a/arch/nios2/configs/3c120_defconfig
+++ b/arch/nios2/configs/3c120_defconfig
@@ -9,8 +9,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_EVENTFD is not set
# CONFIG_SHMEM is not set
# CONFIG_AIO is not set
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
+CONFIG_EXPERT=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_NIOS2_MEM_BASE=0x10000000
@@ -71,4 +70,4 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_ROOT_NFS=y
CONFIG_SUNRPC_DEBUG=y
-CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
index 68093999bd26..7fe7437555fb 100644
--- a/arch/nios2/include/asm/Kbuild
+++ b/arch/nios2/include/asm/Kbuild
@@ -1,45 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
-generic-y += atomic.h
-generic-y += barrier.h
-generic-y += bitops.h
-generic-y += bug.h
-generic-y += bugs.h
generic-y += cmpxchg.h
-generic-y += compat.h
-generic-y += current.h
-generic-y += device.h
-generic-y += div64.h
-generic-y += dma.h
-generic-y += dma-mapping.h
-generic-y += emergency-restart.h
-generic-y += exec.h
generic-y += extable.h
-generic-y += fb.h
-generic-y += ftrace.h
-generic-y += futex.h
-generic-y += hardirq.h
-generic-y += hw_irq.h
-generic-y += irq_regs.h
-generic-y += irq_work.h
-generic-y += kdebug.h
-generic-y += kmap_types.h
-generic-y += kprobes.h
generic-y += kvm_para.h
-generic-y += local.h
generic-y += mcs_spinlock.h
-generic-y += mm-arch-hooks.h
-generic-y += mmiowb.h
-generic-y += module.h
-generic-y += pci.h
-generic-y += percpu.h
-generic-y += preempt.h
-generic-y += sections.h
-generic-y += serial.h
generic-y += spinlock.h
-generic-y += topology.h
-generic-y += trace_clock.h
-generic-y += unaligned.h
generic-y += user.h
-generic-y += vga.h
-generic-y += word-at-a-time.h
-generic-y += xor.h
diff --git a/arch/nios2/include/asm/cacheflush.h b/arch/nios2/include/asm/cacheflush.h
index 18eb9f69f806..81484a776b33 100644
--- a/arch/nios2/include/asm/cacheflush.h
+++ b/arch/nios2/include/asm/cacheflush.h
@@ -28,12 +28,17 @@ extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
extern void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
unsigned long pfn);
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
-extern void flush_dcache_page(struct page *page);
+void flush_dcache_page(struct page *page);
+void flush_dcache_folio(struct folio *folio);
+#define flush_dcache_folio flush_dcache_folio
extern void flush_icache_range(unsigned long start, unsigned long end);
-extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+void flush_icache_pages(struct vm_area_struct *vma, struct page *page,
+ unsigned int nr);
+#define flush_icache_pages flush_icache_pages
#define flush_cache_vmap(start, end) flush_dcache_range(start, end)
+#define flush_cache_vmap_early(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) flush_dcache_range(start, end)
extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
@@ -48,5 +53,9 @@ extern void invalidate_dcache_range(unsigned long start, unsigned long end);
#define flush_dcache_mmap_lock(mapping) xa_lock_irq(&mapping->i_pages)
#define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&mapping->i_pages)
+#define flush_dcache_mmap_lock_irqsave(mapping, flags) \
+ xa_lock_irqsave(&mapping->i_pages, flags)
+#define flush_dcache_mmap_unlock_irqrestore(mapping, flags) \
+ xa_unlock_irqrestore(&mapping->i_pages, flags)
#endif /* _ASM_NIOS2_CACHEFLUSH_H */
diff --git a/arch/nios2/include/asm/cachetype.h b/arch/nios2/include/asm/cachetype.h
new file mode 100644
index 000000000000..eb9c416b8a1c
--- /dev/null
+++ b/arch/nios2/include/asm/cachetype.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_NIOS2_CACHETYPE_H
+#define __ASM_NIOS2_CACHETYPE_H
+
+#include <asm/page.h>
+#include <asm/cache.h>
+
+#define cpu_dcache_is_aliasing() (NIOS2_DCACHE_SIZE > PAGE_SIZE)
+
+#endif
diff --git a/arch/nios2/include/asm/checksum.h b/arch/nios2/include/asm/checksum.h
index 703c5ee63421..69004e07a1ba 100644
--- a/arch/nios2/include/asm/checksum.h
+++ b/arch/nios2/include/asm/checksum.h
@@ -12,13 +12,6 @@
/* Take these from lib/checksum.c */
extern __wsum csum_partial(const void *buff, int len, __wsum sum);
-extern __wsum csum_partial_copy(const void *src, void *dst, int len,
- __wsum sum);
-extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
- int len, __wsum sum, int *csum_err);
-#define csum_partial_copy_nocheck(src, dst, len, sum) \
- csum_partial_copy((src), (dst), (len), (sum))
-
extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
extern __sum16 ip_compute_csum(const void *buff, int len);
diff --git a/arch/nios2/include/asm/entry.h b/arch/nios2/include/asm/entry.h
index cf37f55efbc2..bafb7b2ca59f 100644
--- a/arch/nios2/include/asm/entry.h
+++ b/arch/nios2/include/asm/entry.h
@@ -50,7 +50,8 @@
stw r13, PT_R13(sp)
stw r14, PT_R14(sp)
stw r15, PT_R15(sp)
- stw r2, PT_ORIG_R2(sp)
+ movi r24, -1
+ stw r24, PT_ORIG_R2(sp)
stw r7, PT_ORIG_R7(sp)
stw ra, PT_RA(sp)
diff --git a/arch/nios2/include/asm/irq.h b/arch/nios2/include/asm/irq.h
index 13ce37272279..c52c94884e93 100644
--- a/arch/nios2/include/asm/irq.h
+++ b/arch/nios2/include/asm/irq.h
@@ -10,6 +10,5 @@
#define NIOS2_CPU_NR_IRQS 32
#include <asm-generic/irq.h>
-#include <linux/irqdomain.h>
#endif
diff --git a/arch/nios2/include/asm/irqflags.h b/arch/nios2/include/asm/irqflags.h
index b3ec3e510706..25acf27862f9 100644
--- a/arch/nios2/include/asm/irqflags.h
+++ b/arch/nios2/include/asm/irqflags.h
@@ -9,7 +9,7 @@
static inline unsigned long arch_local_save_flags(void)
{
- return RDCTL(CTL_STATUS);
+ return RDCTL(CTL_FSTATUS);
}
/*
@@ -18,7 +18,7 @@ static inline unsigned long arch_local_save_flags(void)
*/
static inline void arch_local_irq_restore(unsigned long flags)
{
- WRCTL(CTL_STATUS, flags);
+ WRCTL(CTL_FSTATUS, flags);
}
static inline void arch_local_irq_disable(void)
diff --git a/arch/nios2/include/asm/mmu_context.h b/arch/nios2/include/asm/mmu_context.h
index 78ab3dacf579..4f99ed09b5a7 100644
--- a/arch/nios2/include/asm/mmu_context.h
+++ b/arch/nios2/include/asm/mmu_context.h
@@ -26,16 +26,13 @@ extern unsigned long get_pid_from_context(mm_context_t *ctx);
*/
extern pgd_t *pgd_current;
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
/*
* Initialize the context related info for a new mm_struct instance.
*
* Set all new contexts to 0, that way the generation will never match
* the currently running generation when this context is switched in.
*/
+#define init_new_context init_new_context
static inline int init_new_context(struct task_struct *tsk,
struct mm_struct *mm)
{
@@ -43,26 +40,16 @@ static inline int init_new_context(struct task_struct *tsk,
return 0;
}
-/*
- * Destroy context related info for an mm_struct that is about
- * to be put to rest.
- */
-static inline void destroy_context(struct mm_struct *mm)
-{
-}
-
void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk);
-static inline void deactivate_mm(struct task_struct *tsk,
- struct mm_struct *mm)
-{
-}
-
/*
* After we have set current->mm to a new value, this activates
* the context for the new mm so we see the new mappings.
*/
+#define activate_mm activate_mm
void activate_mm(struct mm_struct *prev, struct mm_struct *next);
+#include <asm-generic/mmu_context.h>
+
#endif /* _ASM_NIOS2_MMU_CONTEXT_H */
diff --git a/arch/nios2/include/asm/page.h b/arch/nios2/include/asm/page.h
index 79fcac61f6ef..0722f88e63cc 100644
--- a/arch/nios2/include/asm/page.h
+++ b/arch/nios2/include/asm/page.h
@@ -21,7 +21,7 @@
/*
* PAGE_SHIFT determines the page size
*/
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
@@ -86,20 +86,10 @@ extern struct page *mem_map;
# define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
-static inline bool pfn_valid(unsigned long pfn)
-{
- /* avoid <linux/mm.h> include hell */
- extern unsigned long max_mapnr;
- unsigned long pfn_offset = ARCH_PFN_OFFSET;
-
- return pfn >= pfn_offset && pfn < max_mapnr;
-}
-
# define virt_to_page(vaddr) pfn_to_page(PFN_DOWN(virt_to_phys(vaddr)))
# define virt_addr_valid(vaddr) pfn_valid(PFN_DOWN(virt_to_phys(vaddr)))
-# define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+# define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC
#include <asm-generic/memory_model.h>
diff --git a/arch/nios2/include/asm/pgalloc.h b/arch/nios2/include/asm/pgalloc.h
index 0b146d773c85..ce6bb8e74271 100644
--- a/arch/nios2/include/asm/pgalloc.h
+++ b/arch/nios2/include/asm/pgalloc.h
@@ -12,7 +12,7 @@
#include <linux/mm.h>
-#include <asm-generic/pgalloc.h> /* for pte_{alloc,free}_one */
+#include <asm-generic/pgalloc.h>
static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
pte_t *pte)
@@ -25,24 +25,13 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
{
set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
}
-#define pmd_pgtable(pmd) pmd_page(pmd)
-
-/*
- * Initialize a new pmd table with invalid pointers.
- */
-extern void pmd_init(unsigned long page, unsigned long pagetable);
extern pgd_t *pgd_alloc(struct mm_struct *mm);
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
- free_pages((unsigned long)pgd, PGD_ORDER);
-}
-
-#define __pte_free_tlb(tlb, pte, addr) \
- do { \
- pgtable_pte_page_dtor(pte); \
- tlb_remove_page((tlb), (pte)); \
+#define __pte_free_tlb(tlb, pte, addr) \
+ do { \
+ pagetable_pte_dtor(page_ptdesc(pte)); \
+ tlb_remove_page_ptdesc((tlb), (page_ptdesc(pte))); \
} while (0)
#endif /* _ASM_NIOS2_PGALLOC_H */
diff --git a/arch/nios2/include/asm/pgtable-bits.h b/arch/nios2/include/asm/pgtable-bits.h
index bfddff383e89..724f9b08b1d1 100644
--- a/arch/nios2/include/asm/pgtable-bits.h
+++ b/arch/nios2/include/asm/pgtable-bits.h
@@ -31,4 +31,7 @@
#define _PAGE_ACCESSED (1<<26) /* page referenced */
#define _PAGE_DIRTY (1<<27) /* dirty page */
+/* We borrow bit 31 to store the exclusive marker in swap PTEs. */
+#define _PAGE_SWP_EXCLUSIVE (1<<31)
+
#endif /* _ASM_NIOS2_PGTABLE_BITS_H */
diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h
index 99985d8b7166..d052dfcbe8d3 100644
--- a/arch/nios2/include/asm/pgtable.h
+++ b/arch/nios2/include/asm/pgtable.h
@@ -22,11 +22,8 @@
#include <asm/tlbflush.h>
#include <asm/pgtable-bits.h>
-#define __ARCH_USE_5LEVEL_HACK
#include <asm-generic/pgtable-nopmd.h>
-#define FIRST_USER_ADDRESS 0UL
-
#define VMALLOC_START CONFIG_NIOS2_KERNEL_MMU_REGION_BASE
#define VMALLOC_END (CONFIG_NIOS2_KERNEL_REGION_BASE - 1)
@@ -43,24 +40,8 @@ struct mm_struct;
*/
/* Remove W bit on private pages for COW support */
-#define __P000 MKP(0, 0, 0)
-#define __P001 MKP(0, 0, 1)
-#define __P010 MKP(0, 0, 0) /* COW */
-#define __P011 MKP(0, 0, 1) /* COW */
-#define __P100 MKP(1, 0, 0)
-#define __P101 MKP(1, 0, 1)
-#define __P110 MKP(1, 0, 0) /* COW */
-#define __P111 MKP(1, 0, 1) /* COW */
/* Shared pages can have exact HW mapping */
-#define __S000 MKP(0, 0, 0)
-#define __S001 MKP(0, 0, 1)
-#define __S010 MKP(0, 1, 0)
-#define __S011 MKP(0, 1, 1)
-#define __S100 MKP(1, 0, 0)
-#define __S101 MKP(1, 0, 1)
-#define __S110 MKP(1, 1, 0)
-#define __S111 MKP(1, 1, 1)
/* Used all over the kernel */
#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_CACHED | _PAGE_READ | \
@@ -71,11 +52,8 @@ struct mm_struct;
#define PAGE_COPY MKP(0, 0, 1)
-#define PGD_ORDER 0
-#define PTE_ORDER 0
-
-#define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
-#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
+#define PTRS_PER_PGD (PAGE_SIZE / sizeof(pgd_t))
+#define PTRS_PER_PTE (PAGE_SIZE / sizeof(pte_t))
#define USER_PTRS_PER_PGD \
(CONFIG_NIOS2_KERNEL_MMU_REGION_BASE / PGDIR_SIZE)
@@ -100,20 +78,15 @@ extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
*/
static inline void set_pmd(pmd_t *pmdptr, pmd_t pmdval)
{
- pmdptr->pud.pgd.pgd = pmdval.pud.pgd.pgd;
+ *pmdptr = pmdval;
}
-/* to find an entry in a page-table-directory */
-#define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
-#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
-
static inline int pte_write(pte_t pte) \
{ return pte_val(pte) & _PAGE_WRITE; }
static inline int pte_dirty(pte_t pte) \
{ return pte_val(pte) & _PAGE_DIRTY; }
static inline int pte_young(pte_t pte) \
{ return pte_val(pte) & _PAGE_ACCESSED; }
-static inline int pte_special(pte_t pte) { return 0; }
#define pgprot_noncached pgprot_noncached
@@ -156,7 +129,7 @@ static inline pte_t pte_mkold(pte_t pte)
return pte;
}
-static inline pte_t pte_mkwrite(pte_t pte)
+static inline pte_t pte_mkwrite_novma(pte_t pte)
{
pte_val(pte) |= _PAGE_WRITE;
return pte;
@@ -168,8 +141,6 @@ static inline pte_t pte_mkdirty(pte_t pte)
return pte;
}
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
-
static inline pte_t pte_mkyoung(pte_t pte)
{
pte_val(pte) |= _PAGE_ACCESSED;
@@ -207,14 +178,23 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
*ptep = pteval;
}
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pteval)
-{
- unsigned long paddr = (unsigned long)page_to_virt(pte_page(pteval));
+#define PFN_PTE_SHIFT 0
- flush_dcache_range(paddr, paddr + PAGE_SIZE);
- set_pte(ptep, pteval);
+static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, unsigned int nr)
+{
+ unsigned long paddr = (unsigned long)page_to_virt(pte_page(pte));
+
+ flush_dcache_range(paddr, paddr + nr * PAGE_SIZE);
+ for (;;) {
+ set_pte(ptep, pte);
+ if (--nr == 0)
+ break;
+ ptep++;
+ pte_val(pte) += 1;
+ }
}
+#define set_ptes set_ptes
static inline int pmd_none(pmd_t pmd)
{
@@ -231,7 +211,7 @@ static inline void pte_clear(struct mm_struct *mm,
pte_val(null) = (addr >> PAGE_SHIFT) & 0xf;
- set_pte_at(mm, addr, ptep, null);
+ set_pte(ptep, null);
}
/*
@@ -240,27 +220,18 @@ static inline void pte_clear(struct mm_struct *mm,
*/
#define mk_pte(page, prot) (pfn_pte(page_to_pfn(page), prot))
-#define pte_unmap(pte) do { } while (0)
-
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
#define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd))
+#define pmd_pfn(pmd) (pmd_phys(pmd) >> PAGE_SHIFT)
#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
-#define pmd_page_vaddr(pmd) pmd_val(pmd)
-
-#define pte_offset_map(dir, addr) \
- ((pte_t *) page_address(pmd_page(*dir)) + \
- (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
-
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
-/* Get the address to the PTE for a vaddr in specific directory */
-#define pte_offset_kernel(dir, addr) \
- ((pte_t *) pmd_page_vaddr(*(dir)) + \
- (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+static inline unsigned long pmd_page_vaddr(pmd_t pmd)
+{
+ return pmd_val(pmd);
+}
#define pte_ERROR(e) \
pr_err("%s:%d: bad pte %08lx.\n", \
@@ -270,31 +241,51 @@ static inline void pte_clear(struct mm_struct *mm,
__FILE__, __LINE__, pgd_val(e))
/*
- * Encode and decode a swap entry (must be !pte_none(pte) && !pte_present(pte):
+ * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that
+ * are !pte_none() && !pte_present().
*
- * 31 30 29 28 27 26 25 24 23 22 21 20 19 18 ... 1 0
- * 0 0 0 0 type. 0 0 0 0 0 0 offset.........
+ * Format of swap PTEs:
*
- * This gives us up to 2**2 = 4 swap files and 2**20 * 4K = 4G per swap file.
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * E < type -> 0 0 0 0 0 0 <-------------- offset --------------->
*
- * Note that the offset field is always non-zero, thus !pte_none(pte) is always
- * true.
+ * E is the exclusive marker that is not stored in swap entries.
+ *
+ * Note that the offset field is always non-zero if the swap type is 0, thus
+ * !pte_none() is always true.
*/
-#define __swp_type(swp) (((swp).val >> 26) & 0x3)
+#define __swp_type(swp) (((swp).val >> 26) & 0x1f)
#define __swp_offset(swp) ((swp).val & 0xfffff)
-#define __swp_entry(type, off) ((swp_entry_t) { (((type) & 0x3) << 26) \
+#define __swp_entry(type, off) ((swp_entry_t) { (((type) & 0x1f) << 26) \
| ((off) & 0xfffff) })
#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
-#define kern_addr_valid(addr) (1)
+static inline int pte_swp_exclusive(pte_t pte)
+{
+ return pte_val(pte) & _PAGE_SWP_EXCLUSIVE;
+}
-#include <asm-generic/pgtable.h>
+static inline pte_t pte_swp_mkexclusive(pte_t pte)
+{
+ pte_val(pte) |= _PAGE_SWP_EXCLUSIVE;
+ return pte;
+}
+
+static inline pte_t pte_swp_clear_exclusive(pte_t pte)
+{
+ pte_val(pte) &= ~_PAGE_SWP_EXCLUSIVE;
+ return pte;
+}
extern void __init paging_init(void);
extern void __init mmu_init(void);
-extern void update_mmu_cache(struct vm_area_struct *vma,
- unsigned long address, pte_t *pte);
+void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep, unsigned int nr);
+
+#define update_mmu_cache(vma, addr, ptep) \
+ update_mmu_cache_range(NULL, vma, addr, ptep, 1)
#endif /* _ASM_NIOS2_PGTABLE_H */
diff --git a/arch/nios2/include/asm/processor.h b/arch/nios2/include/asm/processor.h
index 94bcb86f679f..eb44130364a9 100644
--- a/arch/nios2/include/asm/processor.h
+++ b/arch/nios2/include/asm/processor.h
@@ -50,9 +50,6 @@ struct thread_struct {
unsigned long kpsr;
};
-#define INIT_MMAP \
- { &init_mm, (0), (0), __pgprot(0x0), VM_READ | VM_WRITE | VM_EXEC }
-
# define INIT_THREAD { \
.kregs = NULL, \
.ksp = 0, \
@@ -64,12 +61,7 @@ extern void start_thread(struct pt_regs *regs, unsigned long pc,
struct task_struct;
-/* Free all resources held by a thread. */
-static inline void release_thread(struct task_struct *dead_task)
-{
-}
-
-extern unsigned long get_wchan(struct task_struct *p);
+extern unsigned long __get_wchan(struct task_struct *p);
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
diff --git a/arch/nios2/include/asm/ptrace.h b/arch/nios2/include/asm/ptrace.h
index 642462144872..9da34c3022a2 100644
--- a/arch/nios2/include/asm/ptrace.h
+++ b/arch/nios2/include/asm/ptrace.h
@@ -74,6 +74,8 @@ extern void show_regs(struct pt_regs *);
((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE)\
- 1)
+#define force_successful_syscall_return() (current_pt_regs()->orig_r2 = -1)
+
int do_syscall_trace_enter(void);
void do_syscall_trace_exit(void);
#endif /* __ASSEMBLY__ */
diff --git a/arch/nios2/include/asm/registers.h b/arch/nios2/include/asm/registers.h
index 183c720e454d..95b67dd16f81 100644
--- a/arch/nios2/include/asm/registers.h
+++ b/arch/nios2/include/asm/registers.h
@@ -11,7 +11,7 @@
#endif
/* control register numbers */
-#define CTL_STATUS 0
+#define CTL_FSTATUS 0
#define CTL_ESTATUS 1
#define CTL_BSTATUS 2
#define CTL_IENABLE 3
diff --git a/arch/nios2/include/asm/syscall.h b/arch/nios2/include/asm/syscall.h
index 526449edd768..fff52205fb65 100644
--- a/arch/nios2/include/asm/syscall.h
+++ b/arch/nios2/include/asm/syscall.h
@@ -58,17 +58,6 @@ static inline void syscall_get_arguments(struct task_struct *task,
*args = regs->r9;
}
-static inline void syscall_set_arguments(struct task_struct *task,
- struct pt_regs *regs, const unsigned long *args)
-{
- regs->r4 = *args++;
- regs->r5 = *args++;
- regs->r6 = *args++;
- regs->r7 = *args++;
- regs->r8 = *args++;
- regs->r9 = *args;
-}
-
static inline int syscall_get_arch(struct task_struct *task)
{
return AUDIT_ARCH_NIOS2;
diff --git a/arch/nios2/include/asm/thread_info.h b/arch/nios2/include/asm/thread_info.h
index 7349a4fa635b..5abac9893b32 100644
--- a/arch/nios2/include/asm/thread_info.h
+++ b/arch/nios2/include/asm/thread_info.h
@@ -26,10 +26,6 @@
#ifndef __ASSEMBLY__
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
/*
* low level task data that entry.S needs immediate access to
* - this struct should fit entirely inside of one cache line
@@ -42,10 +38,6 @@ struct thread_info {
unsigned long flags; /* low level flags */
__u32 cpu; /* current CPU */
int preempt_count; /* 0 => preemptable,<0 => BUG */
- mm_segment_t addr_limit; /* thread address space:
- 0-0x7FFFFFFF for user-thead
- 0-0xFFFFFFFF for kernel-thread
- */
struct pt_regs *regs;
};
@@ -60,7 +52,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
- .addr_limit = KERNEL_DS, \
}
/* how to get the thread information struct from C */
@@ -86,6 +77,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_MEMDIE 4 /* is terminating due to OOM killer */
#define TIF_SECCOMP 5 /* secure computing */
#define TIF_SYSCALL_AUDIT 6 /* syscall auditing active */
+#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling
@@ -97,15 +89,13 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
+#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK 0x0000FFFE
-/* work to do on any return to u-space */
-# define _TIF_ALLWORK_MASK 0x0000FFFF
-
#endif /* __KERNEL__ */
#endif /* _ASM_NIOS2_THREAD_INFO_H */
diff --git a/arch/nios2/include/asm/timex.h b/arch/nios2/include/asm/timex.h
index a769f871b28d..40a1adc9bd03 100644
--- a/arch/nios2/include/asm/timex.h
+++ b/arch/nios2/include/asm/timex.h
@@ -8,5 +8,8 @@
typedef unsigned long cycles_t;
extern cycles_t get_cycles(void);
+#define get_cycles get_cycles
+
+#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback())
#endif
diff --git a/arch/nios2/include/asm/traps.h b/arch/nios2/include/asm/traps.h
index 82a48473280d..afd77bef01c6 100644
--- a/arch/nios2/include/asm/traps.h
+++ b/arch/nios2/include/asm/traps.h
@@ -14,6 +14,8 @@
#ifndef __ASSEMBLY__
void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr);
+void do_page_fault(struct pt_regs *regs, unsigned long cause,
+ unsigned long address);
#endif
#endif /* _ASM_NIOS2_TRAPS_H */
diff --git a/arch/nios2/include/asm/uaccess.h b/arch/nios2/include/asm/uaccess.h
index e83f831a76f9..b8299082adbe 100644
--- a/arch/nios2/include/asm/uaccess.h
+++ b/arch/nios2/include/asm/uaccess.h
@@ -18,31 +18,10 @@
#include <asm/page.h>
#include <asm/extable.h>
-
-/*
- * Segment stuff
- */
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define USER_DS MAKE_MM_SEG(0x80000000UL)
-#define KERNEL_DS MAKE_MM_SEG(0)
-
-
-#define get_fs() (current_thread_info()->addr_limit)
-#define set_fs(seg) (current_thread_info()->addr_limit = (seg))
-
-#define segment_eq(a, b) ((a).seg == (b).seg)
-
-#define __access_ok(addr, len) \
- (((signed long)(((long)get_fs().seg) & \
- ((long)(addr) | (((long)(addr)) + (len)) | (len)))) == 0)
-
-#define access_ok(addr, len) \
- likely(__access_ok((unsigned long)(addr), (unsigned long)(len)))
+#include <asm-generic/access_ok.h>
# define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n"
-#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE)
-
/*
* Zero Userspace
*/
@@ -83,12 +62,12 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n);
extern long strncpy_from_user(char *__to, const char __user *__from,
long __len);
-extern __must_check long strlen_user(const char __user *str);
extern __must_check long strnlen_user(const char __user *s, long n);
/* Optimized macros */
#define __get_user_asm(val, insn, addr, err) \
{ \
+ unsigned long __gu_val; \
__asm__ __volatile__( \
" movi %0, %3\n" \
"1: " insn " %1, 0(%2)\n" \
@@ -97,14 +76,20 @@ extern __must_check long strnlen_user(const char __user *s, long n);
" .section __ex_table,\"a\"\n" \
" .word 1b, 2b\n" \
" .previous" \
- : "=&r" (err), "=r" (val) \
+ : "=&r" (err), "=r" (__gu_val) \
: "r" (addr), "i" (-EFAULT)); \
+ val = (__force __typeof__(*(addr)))__gu_val; \
}
-#define __get_user_unknown(val, size, ptr, err) do { \
+extern void __get_user_unknown(void);
+
+#define __get_user_8(val, ptr, err) do { \
+ u64 __val = 0; \
err = 0; \
- if (__copy_from_user(&(val), ptr, size)) { \
+ if (raw_copy_from_user(&(__val), ptr, sizeof(val))) { \
err = -EFAULT; \
+ } else { \
+ val = (typeof(val))(typeof((val) - (val)))__val; \
} \
} while (0)
@@ -120,8 +105,11 @@ do { \
case 4: \
__get_user_asm(val, "ldw", ptr, err); \
break; \
+ case 8: \
+ __get_user_8(val, ptr, err); \
+ break; \
default: \
- __get_user_unknown(val, size, ptr, err); \
+ __get_user_unknown(); \
break; \
} \
} while (0)
@@ -130,9 +118,7 @@ do { \
({ \
long __gu_err = -EFAULT; \
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
- unsigned long __gu_val = 0; \
- __get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\
- (x) = (__force __typeof__(x))__gu_val; \
+ __get_user_common(x, sizeof(*(ptr)), __gu_ptr, __gu_err); \
__gu_err; \
})
@@ -140,11 +126,9 @@ do { \
({ \
long __gu_err = -EFAULT; \
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
- unsigned long __gu_val = 0; \
if (access_ok( __gu_ptr, sizeof(*__gu_ptr))) \
- __get_user_common(__gu_val, sizeof(*__gu_ptr), \
+ __get_user_common(x, sizeof(*__gu_ptr), \
__gu_ptr, __gu_err); \
- (x) = (__force __typeof__(x))__gu_val; \
__gu_err; \
})
@@ -162,34 +146,44 @@ do { \
: "r" (val), "r" (ptr), "i" (-EFAULT)); \
}
-#define put_user(x, ptr) \
+#define __put_user_common(__pu_val, __pu_ptr) \
({ \
long __pu_err = -EFAULT; \
- __typeof__(*(ptr)) __user *__pu_ptr = (ptr); \
- __typeof__(*(ptr)) __pu_val = (__typeof(*ptr))(x); \
- if (access_ok(__pu_ptr, sizeof(*__pu_ptr))) { \
- switch (sizeof(*__pu_ptr)) { \
- case 1: \
- __put_user_asm(__pu_val, "stb", __pu_ptr, __pu_err); \
- break; \
- case 2: \
- __put_user_asm(__pu_val, "sth", __pu_ptr, __pu_err); \
- break; \
- case 4: \
- __put_user_asm(__pu_val, "stw", __pu_ptr, __pu_err); \
- break; \
- default: \
- /* XXX: This looks wrong... */ \
- __pu_err = 0; \
- if (copy_to_user(__pu_ptr, &(__pu_val), \
- sizeof(*__pu_ptr))) \
- __pu_err = -EFAULT; \
- break; \
- } \
+ switch (sizeof(*__pu_ptr)) { \
+ case 1: \
+ __put_user_asm(__pu_val, "stb", __pu_ptr, __pu_err); \
+ break; \
+ case 2: \
+ __put_user_asm(__pu_val, "sth", __pu_ptr, __pu_err); \
+ break; \
+ case 4: \
+ __put_user_asm(__pu_val, "stw", __pu_ptr, __pu_err); \
+ break; \
+ default: \
+ /* XXX: This looks wrong... */ \
+ __pu_err = 0; \
+ if (__copy_to_user(__pu_ptr, &(__pu_val), \
+ sizeof(*__pu_ptr))) \
+ __pu_err = -EFAULT; \
+ break; \
} \
__pu_err; \
})
-#define __put_user(x, ptr) put_user(x, ptr)
+#define __put_user(x, ptr) \
+({ \
+ __auto_type __pu_ptr = (ptr); \
+ typeof(*__pu_ptr) __pu_val = (typeof(*__pu_ptr))(x); \
+ __put_user_common(__pu_val, __pu_ptr); \
+})
+
+#define put_user(x, ptr) \
+({ \
+ __auto_type __pu_ptr = (ptr); \
+ typeof(*__pu_ptr) __pu_val = (typeof(*__pu_ptr))(x); \
+ access_ok(__pu_ptr, sizeof(*__pu_ptr)) ? \
+ __put_user_common(__pu_val, __pu_ptr) : \
+ -EFAULT; \
+})
#endif /* _ASM_NIOS2_UACCESS_H */
diff --git a/arch/nios2/include/asm/vmalloc.h b/arch/nios2/include/asm/vmalloc.h
new file mode 100644
index 000000000000..ec7a9260090b
--- /dev/null
+++ b/arch/nios2/include/asm/vmalloc.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_NIOS2_VMALLOC_H
+#define _ASM_NIOS2_VMALLOC_H
+
+#endif /* _ASM_NIOS2_VMALLOC_H */
diff --git a/arch/nios2/kernel/.gitignore b/arch/nios2/kernel/.gitignore
index c5f676c3c224..bbb90f92d051 100644
--- a/arch/nios2/kernel/.gitignore
+++ b/arch/nios2/kernel/.gitignore
@@ -1 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
vmlinux.lds
diff --git a/arch/nios2/kernel/Makefile b/arch/nios2/kernel/Makefile
index 0b645e1e3158..78a913181fa1 100644
--- a/arch/nios2/kernel/Makefile
+++ b/arch/nios2/kernel/Makefile
@@ -3,9 +3,9 @@
# Makefile for the nios2 linux kernel.
#
-extra-y += head.o
extra-y += vmlinux.lds
+obj-y += head.o
obj-y += cpuinfo.o
obj-y += entry.o
obj-y += insnemu.o
diff --git a/arch/nios2/kernel/cpuinfo.c b/arch/nios2/kernel/cpuinfo.c
index 203870c4b86d..338849c430a5 100644
--- a/arch/nios2/kernel/cpuinfo.c
+++ b/arch/nios2/kernel/cpuinfo.c
@@ -47,7 +47,7 @@ void __init setup_cpuinfo(void)
str = of_get_property(cpu, "altr,implementation", &len);
if (str)
- strlcpy(cpuinfo.cpu_impl, str, sizeof(cpuinfo.cpu_impl));
+ strscpy(cpuinfo.cpu_impl, str, sizeof(cpuinfo.cpu_impl));
else
strcpy(cpuinfo.cpu_impl, "<unknown>");
diff --git a/arch/nios2/kernel/entry.S b/arch/nios2/kernel/entry.S
index 1e515ccd698e..99f0a65e6234 100644
--- a/arch/nios2/kernel/entry.S
+++ b/arch/nios2/kernel/entry.S
@@ -185,6 +185,7 @@ ENTRY(handle_system_call)
ldw r5, PT_R5(sp)
local_restart:
+ stw r2, PT_ORIG_R2(sp)
/* Check that the requested system call is within limits */
movui r1, __NR_syscalls
bgeu r2, r1, ret_invsyscall
@@ -192,7 +193,6 @@ local_restart:
movhi r11, %hiadj(sys_call_table)
add r1, r1, r11
ldw r1, %lo(sys_call_table)(r1)
- beq r1, r0, ret_invsyscall
/* Check if we are being traced */
GET_THREAD_INFO r11
@@ -213,6 +213,9 @@ local_restart:
translate_rc_and_ret:
movi r1, 0
bge r2, zero, 3f
+ ldw r1, PT_ORIG_R2(sp)
+ addi r1, r1, 1
+ beq r1, zero, 3f
sub r2, zero, r2
movi r1, 1
3:
@@ -255,9 +258,9 @@ traced_system_call:
ldw r6, PT_R6(sp)
ldw r7, PT_R7(sp)
- /* Fetch the syscall function, we don't need to check the boundaries
- * since this is already done.
- */
+ /* Fetch the syscall function. */
+ movui r1, __NR_syscalls
+ bgeu r2, r1, traced_invsyscall
slli r1, r2, 2
movhi r11,%hiadj(sys_call_table)
add r1, r1, r11
@@ -276,6 +279,9 @@ traced_system_call:
translate_rc_and_ret2:
movi r1, 0
bge r2, zero, 4f
+ ldw r1, PT_ORIG_R2(sp)
+ addi r1, r1, 1
+ beq r1, zero, 4f
sub r2, zero, r2
movi r1, 1
4:
@@ -287,6 +293,11 @@ end_translate_rc_and_ret2:
RESTORE_SWITCH_STACK
br ret_from_exception
+ /* If the syscall number was invalid return ENOSYS */
+traced_invsyscall:
+ movi r2, -ENOSYS
+ br translate_rc_and_ret2
+
Luser_return:
GET_THREAD_INFO r11 /* get thread_info pointer */
ldw r10, TI_FLAGS(r11) /* get thread_info->flags */
@@ -336,9 +347,6 @@ external_interrupt:
/* skip if no interrupt is pending */
beq r12, r0, ret_from_interrupt
- movi r24, -1
- stw r24, PT_ORIG_R2(sp)
-
/*
* Process an external hardware interrupt.
*/
@@ -365,7 +373,7 @@ ENTRY(ret_from_interrupt)
ldw r1, PT_ESTATUS(sp) /* check if returning to kernel */
TSTBNZ r1, r1, ESTATUS_EU, Luser_return
-#ifdef CONFIG_PREEMPT
+#ifdef CONFIG_PREEMPTION
GET_THREAD_INFO r1
ldw r4, TI_PREEMPT_COUNT(r1)
bne r4, r0, restore_all
@@ -389,12 +397,10 @@ ENTRY(ret_from_interrupt)
*/
ENTRY(sys_clone)
SAVE_SWITCH_STACK
- addi sp, sp, -4
- stw r7, 0(sp) /* Pass 5th arg thru stack */
- mov r7, r6 /* 4th arg is 3rd of clone() */
- mov r6, zero /* 3rd arg always 0 */
- call do_fork
- addi sp, sp, 4
+ subi sp, sp, 4 /* make space for tls pointer */
+ stw r8, 0(sp) /* pass tls pointer (r8) via stack (5th argument) */
+ call nios2_clone
+ addi sp, sp, 4
RESTORE_SWITCH_STACK
ret
diff --git a/arch/nios2/kernel/irq.c b/arch/nios2/kernel/irq.c
index 5f3555ce4865..6b7890e5f7af 100644
--- a/arch/nios2/kernel/irq.c
+++ b/arch/nios2/kernel/irq.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/of.h>
static u32 ienable;
@@ -18,11 +19,9 @@ static u32 ienable;
asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
{
struct pt_regs *oldregs = set_irq_regs(regs);
- int irq;
irq_enter();
- irq = irq_find_mapping(NULL, hwirq);
- generic_handle_irq(irq);
+ generic_handle_domain_irq(NULL, hwirq);
irq_exit();
set_irq_regs(oldregs);
diff --git a/arch/nios2/kernel/module.c b/arch/nios2/kernel/module.c
index e2e3f13f98d5..76e0a42d6e36 100644
--- a/arch/nios2/kernel/module.c
+++ b/arch/nios2/kernel/module.c
@@ -19,7 +19,6 @@
#include <linux/string.h>
#include <linux/kernel.h>
-#include <asm/pgtable.h>
#include <asm/cacheflush.h>
/*
diff --git a/arch/nios2/kernel/nios2_ksyms.c b/arch/nios2/kernel/nios2_ksyms.c
index 4e704046a150..54f7b23df1bf 100644
--- a/arch/nios2/kernel/nios2_ksyms.c
+++ b/arch/nios2/kernel/nios2_ksyms.c
@@ -8,9 +8,9 @@
#include <linux/export.h>
#include <linux/string.h>
+#include <linux/pgtable.h>
#include <asm/cacheflush.h>
-#include <asm/pgtable.h>
/* string functions */
diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c
index 509e7855e8dc..f84021303f6a 100644
--- a/arch/nios2/kernel/process.c
+++ b/arch/nios2/kernel/process.c
@@ -33,7 +33,6 @@ EXPORT_SYMBOL(pm_power_off);
void arch_cpu_idle(void)
{
- local_irq_enable();
}
/*
@@ -100,21 +99,23 @@ void flush_thread(void)
{
}
-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)
{
+ unsigned long clone_flags = args->flags;
+ unsigned long usp = args->stack;
+ unsigned long tls = args->tls;
struct pt_regs *childregs = task_pt_regs(p);
struct pt_regs *regs;
struct switch_stack *stack;
struct switch_stack *childstack =
((struct switch_stack *)childregs) - 1;
- if (unlikely(p->flags & PF_KTHREAD)) {
+ if (unlikely(args->fn)) {
memset(childstack, 0,
sizeof(struct switch_stack) + sizeof(struct pt_regs));
- childstack->r16 = usp; /* fn */
- childstack->r17 = arg;
+ childstack->r16 = (unsigned long) args->fn;
+ childstack->r17 = (unsigned long) args->fn_arg;
childstack->ra = (unsigned long) ret_from_kernel_thread;
childregs->estatus = STATUS_PIE;
childregs->sp = (unsigned long) childstack;
@@ -140,7 +141,7 @@ int copy_thread(unsigned long clone_flags,
/* Initialize tls register. */
if (clone_flags & CLONE_SETTLS)
- childstack->r23 = regs->r8;
+ childstack->r23 = tls;
return 0;
}
@@ -217,15 +218,12 @@ void dump(struct pt_regs *fp)
pr_emerg("\n\n");
}
-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)p;
fp = ((struct switch_stack *)p->thread.ksp)->fp; /* ;dgt2 */
do {
@@ -252,10 +250,19 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
regs->sp = sp;
}
-#include <linux/elfcore.h>
-
-/* Fill in the FPU structure for a core dump. */
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+asmlinkage int nios2_clone(unsigned long clone_flags, unsigned long newsp,
+ int __user *parent_tidptr, int __user *child_tidptr,
+ unsigned long tls)
{
- return 0; /* Nios2 has no FPU and thus no FPU registers */
+ struct kernel_clone_args args = {
+ .flags = (lower_32_bits(clone_flags) & ~CSIGNAL),
+ .pidfd = parent_tidptr,
+ .child_tid = child_tidptr,
+ .parent_tid = parent_tidptr,
+ .exit_signal = (lower_32_bits(clone_flags) & CSIGNAL),
+ .stack = newsp,
+ .tls = tls,
+ };
+
+ return kernel_clone(&args);
}
diff --git a/arch/nios2/kernel/ptrace.c b/arch/nios2/kernel/ptrace.c
index de97bcb7dd44..9221c15972e6 100644
--- a/arch/nios2/kernel/ptrace.c
+++ b/arch/nios2/kernel/ptrace.c
@@ -15,51 +15,29 @@
#include <linux/regset.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
-#include <linux/tracehook.h>
#include <linux/uaccess.h>
#include <linux/user.h>
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)
{
const struct pt_regs *regs = task_pt_regs(target);
const struct switch_stack *sw = (struct switch_stack *)regs - 1;
- int ret = 0;
-
-#define REG_O_ZERO_RANGE(START, END) \
- if (!ret) \
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, \
- START * 4, (END * 4) + 4);
-
-#define REG_O_ONE(PTR, LOC) \
- if (!ret) \
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, PTR, \
- LOC * 4, (LOC * 4) + 4);
-#define REG_O_RANGE(PTR, START, END) \
- if (!ret) \
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, PTR, \
- START * 4, (END * 4) + 4);
-
- REG_O_ZERO_RANGE(PTR_R0, PTR_R0);
- REG_O_RANGE(&regs->r1, PTR_R1, PTR_R7);
- REG_O_RANGE(&regs->r8, PTR_R8, PTR_R15);
- REG_O_RANGE(sw, PTR_R16, PTR_R23);
- REG_O_ZERO_RANGE(PTR_R24, PTR_R25); /* et and bt */
- REG_O_ONE(&regs->gp, PTR_GP);
- REG_O_ONE(&regs->sp, PTR_SP);
- REG_O_ONE(&regs->fp, PTR_FP);
- REG_O_ONE(&regs->ea, PTR_EA);
- REG_O_ZERO_RANGE(PTR_BA, PTR_BA);
- REG_O_ONE(&regs->ra, PTR_RA);
- REG_O_ONE(&regs->ea, PTR_PC); /* use ea for PC */
- if (!ret)
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- PTR_STATUS * 4, -1);
-
- return ret;
+ membuf_zero(&to, 4); // R0
+ membuf_write(&to, &regs->r1, 7 * 4); // R1..R7
+ membuf_write(&to, &regs->r8, 8 * 4); // R8..R15
+ membuf_write(&to, sw, 8 * 4); // R16..R23
+ membuf_zero(&to, 2 * 4); /* et and bt */
+ membuf_store(&to, regs->gp);
+ membuf_store(&to, regs->sp);
+ membuf_store(&to, regs->fp);
+ membuf_store(&to, regs->ea);
+ membuf_zero(&to, 4); // PTR_BA
+ membuf_store(&to, regs->ra);
+ membuf_store(&to, regs->ea); /* use ea for PC */
+ return membuf_zero(&to, (NUM_PTRACE_REG - PTR_PC) * 4);
}
/*
@@ -76,7 +54,7 @@ static int genregs_set(struct task_struct *target,
#define REG_IGNORE_RANGE(START, END) \
if (!ret) \
- ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, \
+ user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, \
START * 4, (END * 4) + 4);
#define REG_IN_ONE(PTR, LOC) \
@@ -102,8 +80,8 @@ static int genregs_set(struct task_struct *target,
REG_IN_ONE(&regs->ra, PTR_RA);
REG_IN_ONE(&regs->ea, PTR_PC); /* use ea for PC */
if (!ret)
- ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
- PTR_STATUS * 4, -1);
+ user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ PTR_STATUS * 4, -1);
return ret;
}
@@ -121,7 +99,7 @@ static const struct user_regset nios2_regsets[] = {
.n = NUM_PTRACE_REG,
.size = sizeof(unsigned long),
.align = sizeof(unsigned long),
- .get = genregs_get,
+ .regset_get = genregs_get,
.set = genregs_set,
}
};
@@ -155,7 +133,7 @@ asmlinkage int do_syscall_trace_enter(void)
int ret = 0;
if (test_thread_flag(TIF_SYSCALL_TRACE))
- ret = tracehook_report_syscall_entry(task_pt_regs(current));
+ ret = ptrace_report_syscall_entry(task_pt_regs(current));
return ret;
}
@@ -163,5 +141,5 @@ asmlinkage int do_syscall_trace_enter(void)
asmlinkage void do_syscall_trace_exit(void)
{
if (test_thread_flag(TIF_SYSCALL_TRACE))
- tracehook_report_syscall_exit(task_pt_regs(current), 0);
+ ptrace_report_syscall_exit(task_pt_regs(current), 0);
}
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
index 4cf35b09c0ec..da122a5fa43b 100644
--- a/arch/nios2/kernel/setup.c
+++ b/arch/nios2/kernel/setup.c
@@ -19,7 +19,6 @@
#include <linux/memblock.h>
#include <linux/initrd.h>
#include <linux/of_fdt.h>
-#include <linux/screen_info.h>
#include <asm/mmu_context.h>
#include <asm/sections.h>
@@ -32,16 +31,10 @@ EXPORT_SYMBOL(memory_start);
unsigned long memory_end;
EXPORT_SYMBOL(memory_end);
-unsigned long memory_size;
-
static struct pt_regs fake_regs = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0};
-#ifdef CONFIG_VT
-struct screen_info screen_info;
-#endif
-
/* Copy a short hook instruction sequence to the exception address */
static inline void copy_exception_handler(unsigned int addr)
{
@@ -123,7 +116,7 @@ asmlinkage void __init nios2_boot_init(unsigned r4, unsigned r5, unsigned r6,
dtb_passed = r6;
if (r7)
- strlcpy(cmdline_passed, (char *)r7, COMMAND_LINE_SIZE);
+ strscpy(cmdline_passed, (char *)r7, COMMAND_LINE_SIZE);
}
#endif
@@ -131,41 +124,41 @@ asmlinkage void __init nios2_boot_init(unsigned r4, unsigned r5, unsigned r6,
#ifndef CONFIG_CMDLINE_FORCE
if (cmdline_passed[0])
- strlcpy(boot_command_line, cmdline_passed, COMMAND_LINE_SIZE);
+ strscpy(boot_command_line, cmdline_passed, COMMAND_LINE_SIZE);
#ifdef CONFIG_NIOS2_CMDLINE_IGNORE_DTB
else
- strlcpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+ strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
#endif
#endif
parse_early_param();
}
-void __init setup_arch(char **cmdline_p)
+static void __init find_limits(unsigned long *min, unsigned long *max_low,
+ unsigned long *max_high)
{
- int dram_start;
+ *max_low = PFN_DOWN(memblock_get_current_limit());
+ *min = PFN_UP(memblock_start_of_DRAM());
+ *max_high = PFN_DOWN(memblock_end_of_DRAM());
+}
+void __init setup_arch(char **cmdline_p)
+{
console_verbose();
- dram_start = memblock_start_of_DRAM();
- memory_size = memblock_phys_mem_size();
- memory_start = PAGE_ALIGN((unsigned long)__pa(_end));
- memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size;
+ memory_start = memblock_start_of_DRAM();
+ memory_end = memblock_end_of_DRAM();
- init_mm.start_code = (unsigned long) _stext;
- init_mm.end_code = (unsigned long) _etext;
- init_mm.end_data = (unsigned long) _edata;
- init_mm.brk = (unsigned long) _end;
+ setup_initial_init_mm(_stext, _etext, _edata, _end);
init_task.thread.kregs = &fake_regs;
/* Keep a copy of command line */
*cmdline_p = boot_command_line;
- min_low_pfn = PFN_UP(memory_start);
- max_low_pfn = PFN_DOWN(memory_end);
+ find_limits(&min_low_pfn, &max_low_pfn, &max_pfn);
max_mapnr = max_low_pfn;
- memblock_reserve(dram_start, memory_start - dram_start);
+ memblock_reserve(__pa_symbol(_stext), _end - _stext);
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) {
memblock_reserve(virt_to_phys((void *)initrd_start),
@@ -196,8 +189,4 @@ void __init setup_arch(char **cmdline_p)
* get kmalloc into gear
*/
paging_init();
-
-#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
- conswitchp = &dummy_con;
-#endif
}
diff --git a/arch/nios2/kernel/signal.c b/arch/nios2/kernel/signal.c
index a42dd09c6578..a5b93a30c6eb 100644
--- a/arch/nios2/kernel/signal.c
+++ b/arch/nios2/kernel/signal.c
@@ -15,7 +15,7 @@
#include <linux/uaccess.h>
#include <linux/unistd.h>
#include <linux/personality.h>
-#include <linux/tracehook.h>
+#include <linux/resume_user_mode.h>
#include <asm/ucontext.h>
#include <asm/cacheflush.h>
@@ -36,10 +36,10 @@ struct rt_sigframe {
static inline int rt_restore_ucontext(struct pt_regs *regs,
struct switch_stack *sw,
- struct ucontext *uc, int *pr2)
+ struct ucontext __user *uc, int *pr2)
{
int temp;
- unsigned long *gregs = uc->uc_mcontext.gregs;
+ unsigned long __user *gregs = uc->uc_mcontext.gregs;
int err;
/* Always make any pending restarted system calls return -EINTR */
@@ -102,10 +102,11 @@ asmlinkage int do_rt_sigreturn(struct switch_stack *sw)
{
struct pt_regs *regs = (struct pt_regs *)(sw + 1);
/* Verify, can we follow the stack back */
- struct rt_sigframe *frame = (struct rt_sigframe *) regs->sp;
+ struct rt_sigframe __user *frame;
sigset_t set;
int rval;
+ frame = (struct rt_sigframe __user *) regs->sp;
if (!access_ok(frame, sizeof(*frame)))
goto badframe;
@@ -124,10 +125,10 @@ badframe:
return 0;
}
-static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
+static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
{
struct switch_stack *sw = (struct switch_stack *)regs - 1;
- unsigned long *gregs = uc->uc_mcontext.gregs;
+ unsigned long __user *gregs = uc->uc_mcontext.gregs;
int err = 0;
err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
@@ -162,8 +163,9 @@ static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
return err;
}
-static inline void *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
- size_t frame_size)
+static inline void __user *get_sigframe(struct ksignal *ksig,
+ struct pt_regs *regs,
+ size_t frame_size)
{
unsigned long usp;
@@ -174,13 +176,13 @@ static inline void *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
usp = sigsp(usp, ksig);
/* Verify, is it 32 or 64 bit aligned */
- return (void *)((usp - frame_size) & -8UL);
+ return (void __user *)((usp - frame_size) & -8UL);
}
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
- struct rt_sigframe *frame;
+ struct rt_sigframe __user *frame;
int err = 0;
frame = get_sigframe(ksig, regs, sizeof(*frame));
@@ -240,7 +242,7 @@ static int do_signal(struct pt_regs *regs)
/*
* If we were from a system call, check for system call restarting...
*/
- if (regs->orig_r2 >= 0) {
+ if (regs->orig_r2 >= 0 && regs->r1) {
continue_addr = regs->ea;
restart_addr = continue_addr - 4;
retval = regs->r2;
@@ -252,6 +254,7 @@ static int do_signal(struct pt_regs *regs)
switch (retval) {
case ERESTART_RESTARTBLOCK:
restart = -2;
+ fallthrough;
case ERESTARTNOHAND:
case ERESTARTSYS:
case ERESTARTNOINTR:
@@ -261,6 +264,7 @@ static int do_signal(struct pt_regs *regs)
regs->ea = restart_addr;
break;
}
+ regs->orig_r2 = -1;
}
if (get_signal(&ksig)) {
@@ -305,7 +309,8 @@ asmlinkage int do_notify_resume(struct pt_regs *regs)
if (!user_mode(regs))
return 0;
- if (test_thread_flag(TIF_SIGPENDING)) {
+ if (test_thread_flag(TIF_SIGPENDING) ||
+ test_thread_flag(TIF_NOTIFY_SIGNAL)) {
int restart = do_signal(regs);
if (unlikely(restart)) {
@@ -316,8 +321,8 @@ asmlinkage int do_notify_resume(struct pt_regs *regs)
*/
return restart;
}
- } else if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME))
- tracehook_notify_resume(regs);
+ } else if (test_thread_flag(TIF_NOTIFY_RESUME))
+ resume_user_mode_work(regs);
return 0;
}
diff --git a/arch/nios2/kernel/sys_nios2.c b/arch/nios2/kernel/sys_nios2.c
index cd390ec4f88b..b1ca85699952 100644
--- a/arch/nios2/kernel/sys_nios2.c
+++ b/arch/nios2/kernel/sys_nios2.c
@@ -22,6 +22,7 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len,
unsigned int op)
{
struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
if (len == 0)
return 0;
@@ -34,16 +35,22 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len,
if (addr + len < addr)
return -EFAULT;
+ if (mmap_read_lock_killable(mm))
+ return -EINTR;
+
/*
* Verify that the specified address region actually belongs
* to this process.
*/
- vma = find_vma(current->mm, addr);
- if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
+ vma = find_vma(mm, addr);
+ if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) {
+ mmap_read_unlock(mm);
return -EFAULT;
+ }
flush_cache_range(vma, addr, addr + len);
+ mmap_read_unlock(mm);
return 0;
}
diff --git a/arch/nios2/kernel/syscall_table.c b/arch/nios2/kernel/syscall_table.c
index 6176d63023c1..c2875a6dd5a4 100644
--- a/arch/nios2/kernel/syscall_table.c
+++ b/arch/nios2/kernel/syscall_table.c
@@ -13,5 +13,6 @@
#define __SYSCALL(nr, call) [nr] = (call),
void *sys_call_table[__NR_syscalls] = {
+ [0 ... __NR_syscalls-1] = sys_ni_syscall,
#include <asm/unistd.h>
};
diff --git a/arch/nios2/kernel/traps.c b/arch/nios2/kernel/traps.c
index 486db793923c..85ac49d64cf7 100644
--- a/arch/nios2/kernel/traps.c
+++ b/arch/nios2/kernel/traps.c
@@ -37,10 +37,10 @@ void die(const char *str, struct pt_regs *regs, long err)
show_regs(regs);
spin_unlock_irq(&die_lock);
/*
- * do_exit() should take care of panic'ing from an interrupt
+ * make_task_dead() should take care of panic'ing from an interrupt
* context so we don't handle it here
*/
- do_exit(err);
+ make_task_dead(err);
}
void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
@@ -52,12 +52,13 @@ void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
}
/*
- * The show_stack is an external API which we do not use ourselves.
+ * The show_stack() is external API which we do not use ourselves.
*/
int kstack_depth_to_print = 48;
-void show_stack(struct task_struct *task, unsigned long *stack)
+void show_stack(struct task_struct *task, unsigned long *stack,
+ const char *loglvl)
{
unsigned long *endstack, addr;
int i;
@@ -72,16 +73,16 @@ void show_stack(struct task_struct *task, unsigned long *stack)
addr = (unsigned long) stack;
endstack = (unsigned long *) PAGE_ALIGN(addr);
- pr_emerg("Stack from %08lx:", (unsigned long)stack);
+ printk("%sStack from %08lx:", loglvl, (unsigned long)stack);
for (i = 0; i < kstack_depth_to_print; i++) {
if (stack + 1 > endstack)
break;
if (i % 8 == 0)
- pr_emerg("\n ");
- pr_emerg(" %08lx", *stack++);
+ printk("%s\n ", loglvl);
+ printk("%s %08lx", loglvl, *stack++);
}
- pr_emerg("\nCall Trace:");
+ printk("%s\nCall Trace:", loglvl);
i = 0;
while (stack + 1 <= endstack) {
addr = *stack++;
@@ -97,16 +98,11 @@ void show_stack(struct task_struct *task, unsigned long *stack)
(addr <= (unsigned long) _etext))) {
if (i % 4 == 0)
pr_emerg("\n ");
- pr_emerg(" [<%08lx>]", addr);
+ printk("%s [<%08lx>]", loglvl, addr);
i++;
}
}
- pr_emerg("\n");
-}
-
-void __init trap_init(void)
-{
- /* Nothing to do here */
+ printk("%s\n", loglvl);
}
/* Breakpoint handler */
diff --git a/arch/nios2/kernel/vmlinux.lds.S b/arch/nios2/kernel/vmlinux.lds.S
index c55a7cfa1075..37b958055064 100644
--- a/arch/nios2/kernel/vmlinux.lds.S
+++ b/arch/nios2/kernel/vmlinux.lds.S
@@ -24,7 +24,6 @@ SECTIONS
.text : {
TEXT_TEXT
SCHED_TEXT
- CPUIDLE_TEXT
LOCK_TEXT
IRQENTRY_TEXT
SOFTIRQENTRY_TEXT
@@ -58,6 +57,7 @@ SECTIONS
STABS_DEBUG
DWARF_DEBUG
+ ELF_DETAILS
DISCARDS
}
diff --git a/arch/nios2/mm/cacheflush.c b/arch/nios2/mm/cacheflush.c
index 65de1bd6a760..0ee9c5f02e08 100644
--- a/arch/nios2/mm/cacheflush.c
+++ b/arch/nios2/mm/cacheflush.c
@@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/fs.h>
+#include <linux/pagemap.h>
#include <asm/cacheflush.h>
#include <asm/cpuinfo.h>
@@ -70,28 +71,29 @@ static void __flush_icache(unsigned long start, unsigned long end)
__asm__ __volatile(" flushp\n");
}
-static void flush_aliases(struct address_space *mapping, struct page *page)
+static void flush_aliases(struct address_space *mapping, struct folio *folio)
{
struct mm_struct *mm = current->active_mm;
- struct vm_area_struct *mpnt;
+ struct vm_area_struct *vma;
+ unsigned long flags;
pgoff_t pgoff;
+ unsigned long nr = folio_nr_pages(folio);
- pgoff = page->index;
+ pgoff = folio->index;
- flush_dcache_mmap_lock(mapping);
- vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
- unsigned long offset;
+ flush_dcache_mmap_lock_irqsave(mapping, flags);
+ vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff + nr - 1) {
+ unsigned long start;
- if (mpnt->vm_mm != mm)
+ if (vma->vm_mm != mm)
continue;
- if (!(mpnt->vm_flags & VM_MAYSHARE))
+ if (!(vma->vm_flags & VM_MAYSHARE))
continue;
- offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
- flush_cache_page(mpnt, mpnt->vm_start + offset,
- page_to_pfn(page));
+ start = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
+ flush_cache_range(vma, start, start + nr * PAGE_SIZE);
}
- flush_dcache_mmap_unlock(mapping);
+ flush_dcache_mmap_unlock_irqrestore(mapping, flags);
}
void flush_cache_all(void)
@@ -137,10 +139,11 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
__flush_icache(start, end);
}
-void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+void flush_icache_pages(struct vm_area_struct *vma, struct page *page,
+ unsigned int nr)
{
unsigned long start = (unsigned long) page_address(page);
- unsigned long end = start + PAGE_SIZE;
+ unsigned long end = start + nr * PAGE_SIZE;
__flush_dcache(start, end);
__flush_icache(start, end);
@@ -157,19 +160,19 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
__flush_icache(start, end);
}
-void __flush_dcache_page(struct address_space *mapping, struct page *page)
+static void __flush_dcache_folio(struct folio *folio)
{
/*
* Writeback any data associated with the kernel mapping of this
* page. This ensures that data in the physical page is mutually
* coherent with the kernels mapping.
*/
- unsigned long start = (unsigned long)page_address(page);
+ unsigned long start = (unsigned long)folio_address(folio);
- __flush_dcache(start, start + PAGE_SIZE);
+ __flush_dcache(start, start + folio_size(folio));
}
-void flush_dcache_page(struct page *page)
+void flush_dcache_folio(struct folio *folio)
{
struct address_space *mapping;
@@ -177,32 +180,38 @@ void flush_dcache_page(struct page *page)
* The zero page is never written to, so never has any dirty
* cache lines, and therefore never needs to be flushed.
*/
- if (page == ZERO_PAGE(0))
+ if (is_zero_pfn(folio_pfn(folio)))
return;
- mapping = page_mapping_file(page);
+ mapping = folio_flush_mapping(folio);
/* Flush this page if there are aliases. */
if (mapping && !mapping_mapped(mapping)) {
- clear_bit(PG_dcache_clean, &page->flags);
+ clear_bit(PG_dcache_clean, &folio->flags);
} else {
- __flush_dcache_page(mapping, page);
+ __flush_dcache_folio(folio);
if (mapping) {
- unsigned long start = (unsigned long)page_address(page);
- flush_aliases(mapping, page);
- flush_icache_range(start, start + PAGE_SIZE);
+ unsigned long start = (unsigned long)folio_address(folio);
+ flush_aliases(mapping, folio);
+ flush_icache_range(start, start + folio_size(folio));
}
- set_bit(PG_dcache_clean, &page->flags);
+ set_bit(PG_dcache_clean, &folio->flags);
}
}
+EXPORT_SYMBOL(flush_dcache_folio);
+
+void flush_dcache_page(struct page *page)
+{
+ flush_dcache_folio(page_folio(page));
+}
EXPORT_SYMBOL(flush_dcache_page);
-void update_mmu_cache(struct vm_area_struct *vma,
- unsigned long address, pte_t *ptep)
+void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep, unsigned int nr)
{
pte_t pte = *ptep;
unsigned long pfn = pte_pfn(pte);
- struct page *page;
+ struct folio *folio;
struct address_space *mapping;
reload_tlb_page(vma, address, pte);
@@ -214,19 +223,19 @@ void update_mmu_cache(struct vm_area_struct *vma,
* The zero page is never written to, so never has any dirty
* cache lines, and therefore never needs to be flushed.
*/
- page = pfn_to_page(pfn);
- if (page == ZERO_PAGE(0))
+ if (is_zero_pfn(pfn))
return;
- mapping = page_mapping_file(page);
- if (!test_and_set_bit(PG_dcache_clean, &page->flags))
- __flush_dcache_page(mapping, page);
+ folio = page_folio(pfn_to_page(pfn));
+ if (!test_and_set_bit(PG_dcache_clean, &folio->flags))
+ __flush_dcache_folio(folio);
- if(mapping)
- {
- flush_aliases(mapping, page);
+ mapping = folio_flush_mapping(folio);
+ if (mapping) {
+ flush_aliases(mapping, folio);
if (vma->vm_flags & VM_EXEC)
- flush_icache_page(vma, page);
+ flush_icache_pages(vma, &folio->page,
+ folio_nr_pages(folio));
}
}
diff --git a/arch/nios2/mm/dma-mapping.c b/arch/nios2/mm/dma-mapping.c
index 0ed711e37902..fd887d5f3f9a 100644
--- a/arch/nios2/mm/dma-mapping.c
+++ b/arch/nios2/mm/dma-mapping.c
@@ -67,7 +67,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
flush_dcache_range(start, start + size);
}
-void *uncached_kernel_address(void *ptr)
+void *arch_dma_set_uncached(void *ptr, size_t size)
{
unsigned long addr = (unsigned long)ptr;
@@ -75,13 +75,3 @@ void *uncached_kernel_address(void *ptr)
return (void *)ptr;
}
-
-void *cached_kernel_address(void *ptr)
-{
- unsigned long addr = (unsigned long)ptr;
-
- addr &= ~CONFIG_NIOS2_IO_REGION_BASE;
- addr |= CONFIG_NIOS2_KERNEL_REGION_BASE;
-
- return (void *)ptr;
-}
diff --git a/arch/nios2/mm/fault.c b/arch/nios2/mm/fault.c
index 6a2e716b959f..e3fa9c15181d 100644
--- a/arch/nios2/mm/fault.c
+++ b/arch/nios2/mm/fault.c
@@ -24,6 +24,7 @@
#include <linux/mm.h>
#include <linux/extable.h>
#include <linux/uaccess.h>
+#include <linux/perf_event.h>
#include <asm/mmu_context.h>
#include <asm/traps.h>
@@ -47,7 +48,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
struct mm_struct *mm = tsk->mm;
int code = SEGV_MAPERR;
vm_fault_t fault;
- unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
+ unsigned int flags = FAULT_FLAG_DEFAULT;
cause >>= 2;
@@ -83,27 +84,16 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
if (user_mode(regs))
flags |= FAULT_FLAG_USER;
- if (!down_read_trylock(&mm->mmap_sem)) {
- if (!user_mode(regs) && !search_exception_tables(regs->ea))
- goto bad_area_nosemaphore;
-retry:
- down_read(&mm->mmap_sem);
- }
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
- vma = find_vma(mm, address);
+retry:
+ vma = lock_mm_and_find_vma(mm, address, regs);
if (!vma)
- goto bad_area;
- if (vma->vm_start <= address)
- goto good_area;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- goto bad_area;
- if (expand_stack(vma, address))
- goto bad_area;
+ goto bad_area_nosemaphore;
/*
* Ok, we have a good vm_area for this memory access, so
* we can handle it..
*/
-good_area:
code = SEGV_ACCERR;
switch (cause) {
@@ -131,9 +121,16 @@ 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 & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ if (fault_signal_pending(fault, regs)) {
+ if (!user_mode(regs))
+ goto no_context;
+ return;
+ }
+
+ /* The fault is fully completed (including releasing mmap lock) */
+ if (fault & VM_FAULT_COMPLETED)
return;
if (unlikely(fault & VM_FAULT_ERROR)) {
@@ -146,33 +143,19 @@ good_area:
BUG();
}
- /*
- * Major/minor page fault accounting is only done on the
- * initial attempt. If we go through a retry, it is extremely
- * likely that the page will be found in page cache at that point.
- */
- if (flags & FAULT_FLAG_ALLOW_RETRY) {
- if (fault & VM_FAULT_MAJOR)
- current->maj_flt++;
- else
- current->min_flt++;
- if (fault & VM_FAULT_RETRY) {
- /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
- * of starvation. */
- flags &= ~FAULT_FLAG_ALLOW_RETRY;
- flags |= FAULT_FLAG_TRIED;
-
- /*
- * No need to up_read(&mm->mmap_sem) as we would
- * have already released it in __lock_page_or_retry
- * in mm/filemap.c.
- */
-
- goto retry;
- }
+ if (fault & VM_FAULT_RETRY) {
+ flags |= FAULT_FLAG_TRIED;
+
+ /*
+ * No need to mmap_read_unlock(mm) as we would
+ * have already released it in __lock_page_or_retry
+ * in mm/filemap.c.
+ */
+
+ goto retry;
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return;
/*
@@ -180,7 +163,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */
@@ -218,14 +201,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
if (!user_mode(regs))
goto no_context;
pagefault_out_of_memory();
return;
do_sigbus:
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
/* Kernel mode? Handle exceptions or die */
if (!user_mode(regs))
@@ -245,6 +228,7 @@ vmalloc_fault:
*/
int offset = pgd_index(address);
pgd_t *pgd, *pgd_k;
+ p4d_t *p4d, *p4d_k;
pud_t *pud, *pud_k;
pmd_t *pmd, *pmd_k;
pte_t *pte_k;
@@ -256,8 +240,12 @@ vmalloc_fault:
goto no_context;
set_pgd(pgd, *pgd_k);
- pud = pud_offset(pgd, address);
- pud_k = pud_offset(pgd_k, address);
+ p4d = p4d_offset(pgd, address);
+ p4d_k = p4d_offset(pgd_k, address);
+ if (!p4d_present(*p4d_k))
+ goto no_context;
+ pud = pud_offset(p4d, address);
+ pud_k = pud_offset(p4d_k, address);
if (!pud_present(*pud_k))
goto no_context;
pmd = pmd_offset(pud, address);
diff --git a/arch/nios2/mm/init.c b/arch/nios2/mm/init.c
index 2c609c2516b2..7bc82ee889c9 100644
--- a/arch/nios2/mm/init.c
+++ b/arch/nios2/mm/init.c
@@ -29,7 +29,6 @@
#include <asm/setup.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <asm/sections.h>
#include <asm/tlb.h>
#include <asm/mmu_context.h>
@@ -46,17 +45,15 @@ pgd_t *pgd_current;
*/
void __init paging_init(void)
{
- unsigned long zones_size[MAX_NR_ZONES];
-
- memset(zones_size, 0, sizeof(zones_size));
+ unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 };
pagetable_init();
pgd_current = swapper_pg_dir;
- zones_size[ZONE_NORMAL] = max_mapnr;
+ max_zone_pfn[ZONE_NORMAL] = max_mapnr;
/* pass the memory from the bootmem allocator to the main allocator */
- free_area_init(zones_size);
+ free_area_init(max_zone_pfn);
flush_dcache_range((unsigned long)empty_zero_page,
(unsigned long)empty_zero_page + PAGE_SIZE);
@@ -74,7 +71,6 @@ void __init mem_init(void)
/* this will put all memory onto the freelists */
memblock_free_all();
- mem_init_print_info(NULL);
}
void __init mmu_init(void)
@@ -82,9 +78,8 @@ void __init mmu_init(void)
flush_tlb_all();
}
-#define __page_aligned(order) __aligned(PAGE_SIZE << (order))
-pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER);
-pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE);
+pte_t invalid_pte_table[PTRS_PER_PTE] __aligned(PAGE_SIZE);
static struct page *kuser_page[1];
static int alloc_kuser_page(void)
@@ -112,14 +107,14 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
struct mm_struct *mm = current->mm;
int ret;
- down_write(&mm->mmap_sem);
+ mmap_write_lock(mm);
/* Map kuser helpers to user space address */
ret = install_special_mapping(mm, KUSER_BASE, KUSER_SIZE,
VM_READ | VM_EXEC | VM_MAYREAD |
VM_MAYEXEC, kuser_page);
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
return ret;
}
@@ -128,3 +123,23 @@ const char *arch_vma_name(struct vm_area_struct *vma)
{
return (vma->vm_start == KUSER_BASE) ? "[kuser]" : NULL;
}
+
+static const pgprot_t protection_map[16] = {
+ [VM_NONE] = MKP(0, 0, 0),
+ [VM_READ] = MKP(0, 0, 1),
+ [VM_WRITE] = MKP(0, 0, 0),
+ [VM_WRITE | VM_READ] = MKP(0, 0, 1),
+ [VM_EXEC] = MKP(1, 0, 0),
+ [VM_EXEC | VM_READ] = MKP(1, 0, 1),
+ [VM_EXEC | VM_WRITE] = MKP(1, 0, 0),
+ [VM_EXEC | VM_WRITE | VM_READ] = MKP(1, 0, 1),
+ [VM_SHARED] = MKP(0, 0, 0),
+ [VM_SHARED | VM_READ] = MKP(0, 0, 1),
+ [VM_SHARED | VM_WRITE] = MKP(0, 1, 0),
+ [VM_SHARED | VM_WRITE | VM_READ] = MKP(0, 1, 1),
+ [VM_SHARED | VM_EXEC] = MKP(1, 0, 0),
+ [VM_SHARED | VM_EXEC | VM_READ] = MKP(1, 0, 1),
+ [VM_SHARED | VM_EXEC | VM_WRITE] = MKP(1, 1, 0),
+ [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = MKP(1, 1, 1)
+};
+DECLARE_VM_GET_PAGE_PROT
diff --git a/arch/nios2/mm/ioremap.c b/arch/nios2/mm/ioremap.c
index b56af759dcdf..fe821efb9a99 100644
--- a/arch/nios2/mm/ioremap.c
+++ b/arch/nios2/mm/ioremap.c
@@ -86,11 +86,15 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
if (address >= end)
BUG();
do {
+ p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
error = -ENOMEM;
- pud = pud_alloc(&init_mm, dir, address);
+ p4d = p4d_alloc(&init_mm, dir, address);
+ if (!p4d)
+ break;
+ pud = pud_alloc(&init_mm, p4d, address);
if (!pud)
break;
pmd = pmd_alloc(&init_mm, pud, address);
@@ -138,6 +142,14 @@ void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
return NULL;
}
+ /*
+ * Map uncached objects in the low part of address space to
+ * CONFIG_NIOS2_IO_REGION_BASE
+ */
+ if (IS_MAPPABLE_UNCACHEABLE(phys_addr) &&
+ IS_MAPPABLE_UNCACHEABLE(last_addr))
+ return (void __iomem *)(CONFIG_NIOS2_IO_REGION_BASE + phys_addr);
+
/* Mappings have to be page-aligned */
offset = phys_addr & ~PAGE_MASK;
phys_addr &= PAGE_MASK;
diff --git a/arch/nios2/mm/pgtable.c b/arch/nios2/mm/pgtable.c
index 61e24a25f71a..7c76e8a7447a 100644
--- a/arch/nios2/mm/pgtable.c
+++ b/arch/nios2/mm/pgtable.c
@@ -10,7 +10,6 @@
#include <linux/mm.h>
#include <linux/sched.h>
-#include <asm/pgtable.h>
#include <asm/cpuinfo.h>
/* pteaddr:
@@ -55,7 +54,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
{
pgd_t *ret, *init;
- ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
+ ret = (pgd_t *) __get_free_page(GFP_KERNEL);
if (ret) {
init = pgd_offset(&init_mm, 0UL);
pgd_init(ret);
diff --git a/arch/nios2/mm/tlb.c b/arch/nios2/mm/tlb.c
index 7fea59e53f94..f90ac35f05f3 100644
--- a/arch/nios2/mm/tlb.c
+++ b/arch/nios2/mm/tlb.c
@@ -16,7 +16,6 @@
#include <asm/tlb.h>
#include <asm/mmu_context.h>
-#include <asm/pgtable.h>
#include <asm/cpuinfo.h>
#define TLB_INDEX_MASK \
diff --git a/arch/nios2/platform/Kconfig.platform b/arch/nios2/platform/Kconfig.platform
index 9e32fb7f3d4c..e849daff6fd1 100644
--- a/arch/nios2/platform/Kconfig.platform
+++ b/arch/nios2/platform/Kconfig.platform
@@ -37,6 +37,7 @@ config NIOS2_DTB_PHYS_ADDR
config NIOS2_DTB_SOURCE_BOOL
bool "Compile and link device tree into kernel image"
+ depends on !COMPILE_TEST
help
This allows you to specify a dts (device tree source) file
which will be compiled and linked into the kernel image.
diff --git a/arch/nios2/platform/platform.c b/arch/nios2/platform/platform.c
index 2a35154ca153..9737a87121fa 100644
--- a/arch/nios2/platform/platform.c
+++ b/arch/nios2/platform/platform.c
@@ -15,6 +15,12 @@
#include <linux/slab.h>
#include <linux/sys_soc.h>
#include <linux/io.h>
+#include <linux/clk-provider.h>
+
+static const struct of_device_id clk_match[] __initconst = {
+ { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+ {}
+};
static int __init nios2_soc_device_init(void)
{
@@ -38,6 +44,8 @@ static int __init nios2_soc_device_init(void)
}
}
+ of_clk_init(clk_match);
+
return 0;
}