mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
RISC-V Patches for the 5.9 Merge Window, Part 1
We have a lot of new kernel features for this merge window: * ARCH_SUPPORTS_ATOMIC_RMW, to allow OSQ locks to be enabled. * The ability to enable NO_HZ_FULL * Support for enabling kcov, kmemleak, stack protector, and VM debugging. * JUMP_LABEL support. There are also a handful of cleanups. next points out a trivial Kconfig merge conflict. I don't see any way to have done this better: the symbols are sorted, it just happens that HAVE_COPY_THREAD_TLS was in the middle of two new symbols. In case it helps any, here's a pretty current conflict resolution: diff --cc arch/riscv/Kconfig index bc37241a6875,6c4bce7cad8a..7b5905529146 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@@ -57,9 -54,6 +59,8 @@@ config RISC select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_ASM_MODVERSIONS + select HAVE_CONTEXT_TRACKING - select HAVE_COPY_THREAD_TLS + select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_CONTIGUOUS if MMU select HAVE_EBPF_JIT if MMU select HAVE_FUTEX_CMPXCHG if FUTEX -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAl8sa2YTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYieFTD/0RlhicBrn5UGpaUwtgwuMENYOrb3pn 5SsPzhCni3/8HvMzr/gOGHWM2YOQZkY5FReIqy1IdbPSe/exjv6DyKMdZr+OI+3+ 232TAwAtILGlKB+zBMJWA3eLah0pbDvs7RpuhiPfWSzzWUrAMHcGSq0TzM2pYe1r KPOLj6bSKpnZO+Dto80V8w4ZeWmtAArVDiujIy8zlvgpM1Z66C2SazloQH7HkPS7 D2hvLZZU00etyAZI/aJJsemCBRg9nsVoqGTBSXWpUPATBRMZFfHovbh7AUJlqY5E HPHBSf3KDeOjoF8EXkvT/6z5Q6+LUpRyK+KKwWCs/337i1652P31nczDps9J6Eq0 IC3J/YWcy4eZ7pMEps0vQmr9aX+FusOCJUmJqJW77Uzi0fHHTXa+O3olwiz/JqYz c3yIihVAvtw9eCSoqlL7YoL9HNyfrXKCtZ4l/DLjwGG5WJw7C7mGMbBMClcD4ytU /Z91ON/UgWFW5805dBaajp72SStp1FP54HsAH5E12XYZSiepnu70G3BUNJHvDJT5 QOKkrhOswwit5DW30Celh6kmtidAWiavy6R0AbbpcqI+bItkEZWD1BSStTc0WdhV JgOp0ieCzu5Jyw03KC1nZA8VgM3zrAmU0moSDqirddzNYuuBTqt39doZOEs1MS2W TiR1JSnGNaKl4Q== =asH5 -----END PGP SIGNATURE----- Merge tag 'riscv-for-linus-5.9-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux Pull RISC-V updates from Palmer Dabbelt: "We have a lot of new kernel features for this merge window: - ARCH_SUPPORTS_ATOMIC_RMW, to allow OSQ locks to be enabled - The ability to enable NO_HZ_FULL - Support for enabling kcov, kmemleak, stack protector, and VM debugging - JUMP_LABEL support There are also a handful of cleanups" * tag 'riscv-for-linus-5.9-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (24 commits) riscv: disable stack-protector for vDSO RISC-V: Fix build warning for smpboot.c riscv: fix build warning of mm/pageattr riscv: Fix build warning for mm/init RISC-V: Setup exception vector early riscv: Select ARCH_HAS_DEBUG_VM_PGTABLE riscv: Use generic pgprot_* macros from <linux/pgtable.h> mm: pgtable: Make generic pgprot_* macros available for no-MMU riscv: Cleanup unnecessary define in asm-offset.c riscv: Add jump-label implementation riscv: Support R_RISCV_ADD64 and R_RISCV_SUB64 relocs Replace HTTP links with HTTPS ones: RISC-V riscv: Add STACKPROTECTOR supported riscv: Fix typo in asm/hwcap.h uapi header riscv: Add kmemleak support riscv: Allow building with kcov coverage riscv: Enable context tracking riscv: Support irq_work via self IPIs riscv: Enable LOCKDEP_SUPPORT & fixup TRACE_IRQFLAGS_SUPPORT riscv: Fixup lockdep_assert_held with wrong param cpu_running ...
This commit is contained in:
commit
dbf8381731
32 changed files with 356 additions and 71 deletions
|
@ -23,7 +23,7 @@
|
||||||
| openrisc: | TODO |
|
| openrisc: | TODO |
|
||||||
| parisc: | ok |
|
| parisc: | ok |
|
||||||
| powerpc: | ok |
|
| powerpc: | ok |
|
||||||
| riscv: | TODO |
|
| riscv: | ok |
|
||||||
| s390: | ok |
|
| s390: | ok |
|
||||||
| sh: | TODO |
|
| sh: | TODO |
|
||||||
| sparc: | ok |
|
| sparc: | ok |
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
| openrisc: | TODO |
|
| openrisc: | TODO |
|
||||||
| parisc: | TODO |
|
| parisc: | TODO |
|
||||||
| powerpc: | ok |
|
| powerpc: | ok |
|
||||||
| riscv: | TODO |
|
| riscv: | ok |
|
||||||
| s390: | ok |
|
| s390: | ok |
|
||||||
| sh: | TODO |
|
| sh: | TODO |
|
||||||
| sparc: | TODO |
|
| sparc: | TODO |
|
||||||
|
|
|
@ -13,11 +13,14 @@ config 32BIT
|
||||||
config RISCV
|
config RISCV
|
||||||
def_bool y
|
def_bool y
|
||||||
select ARCH_CLOCKSOURCE_INIT
|
select ARCH_CLOCKSOURCE_INIT
|
||||||
|
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||||
select ARCH_HAS_BINFMT_FLAT
|
select ARCH_HAS_BINFMT_FLAT
|
||||||
|
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||||
select ARCH_HAS_DEBUG_VIRTUAL if MMU
|
select ARCH_HAS_DEBUG_VIRTUAL if MMU
|
||||||
select ARCH_HAS_DEBUG_WX
|
select ARCH_HAS_DEBUG_WX
|
||||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||||
select ARCH_HAS_GIGANTIC_PAGE
|
select ARCH_HAS_GIGANTIC_PAGE
|
||||||
|
select ARCH_HAS_KCOV
|
||||||
select ARCH_HAS_MMIOWB
|
select ARCH_HAS_MMIOWB
|
||||||
select ARCH_HAS_PTE_SPECIAL
|
select ARCH_HAS_PTE_SPECIAL
|
||||||
select ARCH_HAS_SET_DIRECT_MAP
|
select ARCH_HAS_SET_DIRECT_MAP
|
||||||
|
@ -47,6 +50,8 @@ config RISCV
|
||||||
select GENERIC_TIME_VSYSCALL if MMU && 64BIT
|
select GENERIC_TIME_VSYSCALL if MMU && 64BIT
|
||||||
select HANDLE_DOMAIN_IRQ
|
select HANDLE_DOMAIN_IRQ
|
||||||
select HAVE_ARCH_AUDITSYSCALL
|
select HAVE_ARCH_AUDITSYSCALL
|
||||||
|
select HAVE_ARCH_JUMP_LABEL
|
||||||
|
select HAVE_ARCH_JUMP_LABEL_RELATIVE
|
||||||
select HAVE_ARCH_KASAN if MMU && 64BIT
|
select HAVE_ARCH_KASAN if MMU && 64BIT
|
||||||
select HAVE_ARCH_KGDB
|
select HAVE_ARCH_KGDB
|
||||||
select HAVE_ARCH_KGDB_QXFER_PKT
|
select HAVE_ARCH_KGDB_QXFER_PKT
|
||||||
|
@ -54,14 +59,18 @@ config RISCV
|
||||||
select HAVE_ARCH_SECCOMP_FILTER
|
select HAVE_ARCH_SECCOMP_FILTER
|
||||||
select HAVE_ARCH_TRACEHOOK
|
select HAVE_ARCH_TRACEHOOK
|
||||||
select HAVE_ASM_MODVERSIONS
|
select HAVE_ASM_MODVERSIONS
|
||||||
|
select HAVE_CONTEXT_TRACKING
|
||||||
|
select HAVE_DEBUG_KMEMLEAK
|
||||||
select HAVE_DMA_CONTIGUOUS if MMU
|
select HAVE_DMA_CONTIGUOUS if MMU
|
||||||
select HAVE_EBPF_JIT if MMU
|
select HAVE_EBPF_JIT if MMU
|
||||||
select HAVE_FUTEX_CMPXCHG if FUTEX
|
select HAVE_FUTEX_CMPXCHG if FUTEX
|
||||||
|
select HAVE_GCC_PLUGINS
|
||||||
select HAVE_GENERIC_VDSO if MMU && 64BIT
|
select HAVE_GENERIC_VDSO if MMU && 64BIT
|
||||||
select HAVE_PCI
|
select HAVE_PCI
|
||||||
select HAVE_PERF_EVENTS
|
select HAVE_PERF_EVENTS
|
||||||
select HAVE_PERF_REGS
|
select HAVE_PERF_REGS
|
||||||
select HAVE_PERF_USER_STACK_DUMP
|
select HAVE_PERF_USER_STACK_DUMP
|
||||||
|
select HAVE_STACKPROTECTOR
|
||||||
select HAVE_SYSCALL_TRACEPOINTS
|
select HAVE_SYSCALL_TRACEPOINTS
|
||||||
select IRQ_DOMAIN
|
select IRQ_DOMAIN
|
||||||
select MODULES_USE_ELF_RELA if MODULES
|
select MODULES_USE_ELF_RELA if MODULES
|
||||||
|
@ -179,6 +188,9 @@ config PGTABLE_LEVELS
|
||||||
default 3 if 64BIT
|
default 3 if 64BIT
|
||||||
default 2
|
default 2
|
||||||
|
|
||||||
|
config LOCKDEP_SUPPORT
|
||||||
|
def_bool y
|
||||||
|
|
||||||
source "arch/riscv/Kconfig.socs"
|
source "arch/riscv/Kconfig.socs"
|
||||||
|
|
||||||
menu "Platform type"
|
menu "Platform type"
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
# Based on the ia64 and arm64 boot/Makefile.
|
# Based on the ia64 and arm64 boot/Makefile.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
KCOV_INSTRUMENT := n
|
||||||
|
|
||||||
OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
|
OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
|
||||||
|
|
||||||
targets := Image loader
|
targets := Image loader
|
||||||
|
|
|
@ -17,6 +17,7 @@ CONFIG_BPF_SYSCALL=y
|
||||||
CONFIG_SOC_SIFIVE=y
|
CONFIG_SOC_SIFIVE=y
|
||||||
CONFIG_SOC_VIRT=y
|
CONFIG_SOC_VIRT=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
|
CONFIG_JUMP_LABEL=y
|
||||||
CONFIG_MODULES=y
|
CONFIG_MODULES=y
|
||||||
CONFIG_MODULE_UNLOAD=y
|
CONFIG_MODULE_UNLOAD=y
|
||||||
CONFIG_NET=y
|
CONFIG_NET=y
|
||||||
|
|
|
@ -33,6 +33,7 @@ CONFIG_SMP=y
|
||||||
CONFIG_NR_CPUS=2
|
CONFIG_NR_CPUS=2
|
||||||
CONFIG_CMDLINE="earlycon console=ttySIF0"
|
CONFIG_CMDLINE="earlycon console=ttySIF0"
|
||||||
CONFIG_CMDLINE_FORCE=y
|
CONFIG_CMDLINE_FORCE=y
|
||||||
|
CONFIG_JUMP_LABEL=y
|
||||||
# CONFIG_BLOCK is not set
|
# CONFIG_BLOCK is not set
|
||||||
CONFIG_BINFMT_FLAT=y
|
CONFIG_BINFMT_FLAT=y
|
||||||
# CONFIG_COREDUMP is not set
|
# CONFIG_COREDUMP is not set
|
||||||
|
|
|
@ -30,6 +30,7 @@ CONFIG_MAXPHYSMEM_2GB=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
|
CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
|
||||||
CONFIG_CMDLINE_FORCE=y
|
CONFIG_CMDLINE_FORCE=y
|
||||||
|
CONFIG_JUMP_LABEL=y
|
||||||
# CONFIG_BLK_DEV_BSG is not set
|
# CONFIG_BLK_DEV_BSG is not set
|
||||||
CONFIG_PARTITION_ADVANCED=y
|
CONFIG_PARTITION_ADVANCED=y
|
||||||
# CONFIG_MSDOS_PARTITION is not set
|
# CONFIG_MSDOS_PARTITION is not set
|
||||||
|
|
|
@ -17,6 +17,7 @@ CONFIG_BPF_SYSCALL=y
|
||||||
CONFIG_SOC_VIRT=y
|
CONFIG_SOC_VIRT=y
|
||||||
CONFIG_ARCH_RV32I=y
|
CONFIG_ARCH_RV32I=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
|
CONFIG_JUMP_LABEL=y
|
||||||
CONFIG_MODULES=y
|
CONFIG_MODULES=y
|
||||||
CONFIG_MODULE_UNLOAD=y
|
CONFIG_MODULE_UNLOAD=y
|
||||||
CONFIG_NET=y
|
CONFIG_NET=y
|
||||||
|
|
10
arch/riscv/include/asm/irq_work.h
Normal file
10
arch/riscv/include/asm/irq_work.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef _ASM_RISCV_IRQ_WORK_H
|
||||||
|
#define _ASM_RISCV_IRQ_WORK_H
|
||||||
|
|
||||||
|
static inline bool arch_irq_work_has_interrupt(void)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
extern void arch_irq_work_raise(void);
|
||||||
|
#endif /* _ASM_RISCV_IRQ_WORK_H */
|
60
arch/riscv/include/asm/jump_label.h
Normal file
60
arch/riscv/include/asm/jump_label.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Emil Renner Berthing
|
||||||
|
*
|
||||||
|
* Based on arch/arm64/include/asm/jump_label.h
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_JUMP_LABEL_H
|
||||||
|
#define __ASM_JUMP_LABEL_H
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <asm/asm.h>
|
||||||
|
|
||||||
|
#define JUMP_LABEL_NOP_SIZE 4
|
||||||
|
|
||||||
|
static __always_inline bool arch_static_branch(struct static_key *key,
|
||||||
|
bool branch)
|
||||||
|
{
|
||||||
|
asm_volatile_goto(
|
||||||
|
" .option push \n\t"
|
||||||
|
" .option norelax \n\t"
|
||||||
|
" .option norvc \n\t"
|
||||||
|
"1: nop \n\t"
|
||||||
|
" .option pop \n\t"
|
||||||
|
" .pushsection __jump_table, \"aw\" \n\t"
|
||||||
|
" .align " RISCV_LGPTR " \n\t"
|
||||||
|
" .long 1b - ., %l[label] - . \n\t"
|
||||||
|
" " RISCV_PTR " %0 - . \n\t"
|
||||||
|
" .popsection \n\t"
|
||||||
|
: : "i"(&((char *)key)[branch]) : : label);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
label:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline bool arch_static_branch_jump(struct static_key *key,
|
||||||
|
bool branch)
|
||||||
|
{
|
||||||
|
asm_volatile_goto(
|
||||||
|
" .option push \n\t"
|
||||||
|
" .option norelax \n\t"
|
||||||
|
" .option norvc \n\t"
|
||||||
|
"1: jal zero, %l[label] \n\t"
|
||||||
|
" .option pop \n\t"
|
||||||
|
" .pushsection __jump_table, \"aw\" \n\t"
|
||||||
|
" .align " RISCV_LGPTR " \n\t"
|
||||||
|
" .long 1b - ., %l[label] - . \n\t"
|
||||||
|
" " RISCV_PTR " %0 - . \n\t"
|
||||||
|
" .popsection \n\t"
|
||||||
|
: : "i"(&((char *)key)[branch]) : : label);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
label:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
#endif /* __ASM_JUMP_LABEL_H */
|
|
@ -14,12 +14,6 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <asm/mmiowb.h>
|
#include <asm/mmiowb.h>
|
||||||
|
|
||||||
#ifndef CONFIG_MMU
|
|
||||||
#define pgprot_noncached(x) (x)
|
|
||||||
#define pgprot_writecombine(x) (x)
|
|
||||||
#define pgprot_device(x) (x)
|
|
||||||
#endif /* CONFIG_MMU */
|
|
||||||
|
|
||||||
/* Generic IO read/write. These perform native-endian accesses. */
|
/* Generic IO read/write. These perform native-endian accesses. */
|
||||||
#define __raw_writeb __raw_writeb
|
#define __raw_writeb __raw_writeb
|
||||||
static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
|
static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
|
||||||
|
|
|
@ -40,6 +40,9 @@ void arch_send_call_function_single_ipi(int cpu);
|
||||||
int riscv_hartid_to_cpuid(int hartid);
|
int riscv_hartid_to_cpuid(int hartid);
|
||||||
void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out);
|
void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out);
|
||||||
|
|
||||||
|
/* Secondary hart entry */
|
||||||
|
asmlinkage void smp_callin(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtains the hart ID of the currently executing task. This relies on
|
* Obtains the hart ID of the currently executing task. This relies on
|
||||||
* THREAD_INFO_IN_TASK, but we define that unconditionally.
|
* THREAD_INFO_IN_TASK, but we define that unconditionally.
|
||||||
|
|
33
arch/riscv/include/asm/stackprotector.h
Normal file
33
arch/riscv/include/asm/stackprotector.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
|
||||||
|
#ifndef _ASM_RISCV_STACKPROTECTOR_H
|
||||||
|
#define _ASM_RISCV_STACKPROTECTOR_H
|
||||||
|
|
||||||
|
#include <linux/random.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <asm/timex.h>
|
||||||
|
|
||||||
|
extern unsigned long __stack_chk_guard;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the stackprotector canary value.
|
||||||
|
*
|
||||||
|
* NOTE: this must only be called from functions that never return,
|
||||||
|
* and it must always be inlined.
|
||||||
|
*/
|
||||||
|
static __always_inline void boot_init_stack_canary(void)
|
||||||
|
{
|
||||||
|
unsigned long canary;
|
||||||
|
unsigned long tsc;
|
||||||
|
|
||||||
|
/* Try to get a semi random initial value. */
|
||||||
|
get_random_bytes(&canary, sizeof(canary));
|
||||||
|
tsc = get_cycles();
|
||||||
|
canary += tsc + (tsc << BITS_PER_LONG/2);
|
||||||
|
canary ^= LINUX_VERSION_CODE;
|
||||||
|
canary &= CANARY_MASK;
|
||||||
|
|
||||||
|
current->stack_canary = canary;
|
||||||
|
__stack_chk_guard = current->stack_canary;
|
||||||
|
}
|
||||||
|
#endif /* _ASM_RISCV_STACKPROTECTOR_H */
|
|
@ -11,7 +11,7 @@
|
||||||
/*
|
/*
|
||||||
* Linux saves the floating-point registers according to the ISA Linux is
|
* Linux saves the floating-point registers according to the ISA Linux is
|
||||||
* executing on, as opposed to the ISA the user program is compiled for. This
|
* executing on, as opposed to the ISA the user program is compiled for. This
|
||||||
* is necessary for a handful of esoteric use cases: for example, userpsace
|
* is necessary for a handful of esoteric use cases: for example, userspace
|
||||||
* threading libraries must be able to examine the actual machine state in
|
* threading libraries must be able to examine the actual machine state in
|
||||||
* order to fully reconstruct the state of a thread.
|
* order to fully reconstruct the state of a thread.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
|
|
|
@ -53,4 +53,6 @@ endif
|
||||||
obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o
|
obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o
|
||||||
obj-$(CONFIG_KGDB) += kgdb.o
|
obj-$(CONFIG_KGDB) += kgdb.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -27,9 +27,6 @@ void asm_offsets(void)
|
||||||
OFFSET(TASK_THREAD_S9, task_struct, thread.s[9]);
|
OFFSET(TASK_THREAD_S9, task_struct, thread.s[9]);
|
||||||
OFFSET(TASK_THREAD_S10, task_struct, thread.s[10]);
|
OFFSET(TASK_THREAD_S10, task_struct, thread.s[10]);
|
||||||
OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]);
|
OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]);
|
||||||
OFFSET(TASK_THREAD_SP, task_struct, thread.sp);
|
|
||||||
OFFSET(TASK_STACK, task_struct, stack);
|
|
||||||
OFFSET(TASK_TI, task_struct, thread_info);
|
|
||||||
OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags);
|
OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags);
|
||||||
OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count);
|
OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count);
|
||||||
OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp);
|
OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp);
|
||||||
|
|
|
@ -97,19 +97,36 @@ _save_context:
|
||||||
la gp, __global_pointer$
|
la gp, __global_pointer$
|
||||||
.option pop
|
.option pop
|
||||||
|
|
||||||
la ra, ret_from_exception
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
|
call trace_hardirqs_off
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_CONTEXT_TRACKING
|
||||||
|
/* If previous state is in user mode, call context_tracking_user_exit. */
|
||||||
|
li a0, SR_PP
|
||||||
|
and a0, s1, a0
|
||||||
|
bnez a0, skip_context_tracking
|
||||||
|
call context_tracking_user_exit
|
||||||
|
skip_context_tracking:
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MSB of cause differentiates between
|
* MSB of cause differentiates between
|
||||||
* interrupts and exceptions
|
* interrupts and exceptions
|
||||||
*/
|
*/
|
||||||
bge s4, zero, 1f
|
bge s4, zero, 1f
|
||||||
|
|
||||||
|
la ra, ret_from_exception
|
||||||
|
|
||||||
/* Handle interrupts */
|
/* Handle interrupts */
|
||||||
move a0, sp /* pt_regs */
|
move a0, sp /* pt_regs */
|
||||||
la a1, handle_arch_irq
|
la a1, handle_arch_irq
|
||||||
REG_L a1, (a1)
|
REG_L a1, (a1)
|
||||||
jr a1
|
jr a1
|
||||||
1:
|
1:
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
|
call trace_hardirqs_on
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Exceptions run with interrupts enabled or disabled depending on the
|
* Exceptions run with interrupts enabled or disabled depending on the
|
||||||
* state of SR_PIE in m/sstatus.
|
* state of SR_PIE in m/sstatus.
|
||||||
|
@ -119,6 +136,7 @@ _save_context:
|
||||||
csrs CSR_STATUS, SR_IE
|
csrs CSR_STATUS, SR_IE
|
||||||
|
|
||||||
1:
|
1:
|
||||||
|
la ra, ret_from_exception
|
||||||
/* Handle syscalls */
|
/* Handle syscalls */
|
||||||
li t0, EXC_SYSCALL
|
li t0, EXC_SYSCALL
|
||||||
beq s4, t0, handle_syscall
|
beq s4, t0, handle_syscall
|
||||||
|
@ -137,6 +155,17 @@ _save_context:
|
||||||
tail do_trap_unknown
|
tail do_trap_unknown
|
||||||
|
|
||||||
handle_syscall:
|
handle_syscall:
|
||||||
|
#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING)
|
||||||
|
/* Recover a0 - a7 for system calls */
|
||||||
|
REG_L a0, PT_A0(sp)
|
||||||
|
REG_L a1, PT_A1(sp)
|
||||||
|
REG_L a2, PT_A2(sp)
|
||||||
|
REG_L a3, PT_A3(sp)
|
||||||
|
REG_L a4, PT_A4(sp)
|
||||||
|
REG_L a5, PT_A5(sp)
|
||||||
|
REG_L a6, PT_A6(sp)
|
||||||
|
REG_L a7, PT_A7(sp)
|
||||||
|
#endif
|
||||||
/* save the initial A0 value (needed in signal handlers) */
|
/* save the initial A0 value (needed in signal handlers) */
|
||||||
REG_S a0, PT_ORIG_A0(sp)
|
REG_S a0, PT_ORIG_A0(sp)
|
||||||
/*
|
/*
|
||||||
|
@ -190,6 +219,9 @@ ret_from_syscall_rejected:
|
||||||
ret_from_exception:
|
ret_from_exception:
|
||||||
REG_L s0, PT_STATUS(sp)
|
REG_L s0, PT_STATUS(sp)
|
||||||
csrc CSR_STATUS, SR_IE
|
csrc CSR_STATUS, SR_IE
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
|
call trace_hardirqs_off
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_RISCV_M_MODE
|
#ifdef CONFIG_RISCV_M_MODE
|
||||||
/* the MPP value is too large to be used as an immediate arg for addi */
|
/* the MPP value is too large to be used as an immediate arg for addi */
|
||||||
li t0, SR_MPP
|
li t0, SR_MPP
|
||||||
|
@ -205,6 +237,10 @@ resume_userspace:
|
||||||
andi s1, s0, _TIF_WORK_MASK
|
andi s1, s0, _TIF_WORK_MASK
|
||||||
bnez s1, work_pending
|
bnez s1, work_pending
|
||||||
|
|
||||||
|
#ifdef CONFIG_CONTEXT_TRACKING
|
||||||
|
call context_tracking_user_enter
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Save unwound kernel stack pointer in thread_info */
|
/* Save unwound kernel stack pointer in thread_info */
|
||||||
addi s0, sp, PT_SIZE_ON_STACK
|
addi s0, sp, PT_SIZE_ON_STACK
|
||||||
REG_S s0, TASK_TI_KERNEL_SP(tp)
|
REG_S s0, TASK_TI_KERNEL_SP(tp)
|
||||||
|
@ -216,6 +252,16 @@ resume_userspace:
|
||||||
csrw CSR_SCRATCH, tp
|
csrw CSR_SCRATCH, tp
|
||||||
|
|
||||||
restore_all:
|
restore_all:
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
|
REG_L s1, PT_STATUS(sp)
|
||||||
|
andi t0, s1, SR_PIE
|
||||||
|
beqz t0, 1f
|
||||||
|
call trace_hardirqs_on
|
||||||
|
j 2f
|
||||||
|
1:
|
||||||
|
call trace_hardirqs_off
|
||||||
|
2:
|
||||||
|
#endif
|
||||||
REG_L a0, PT_STATUS(sp)
|
REG_L a0, PT_STATUS(sp)
|
||||||
/*
|
/*
|
||||||
* The current load reservation is effectively part of the processor's
|
* The current load reservation is effectively part of the processor's
|
||||||
|
@ -389,12 +435,8 @@ ENTRY(__switch_to)
|
||||||
lw a4, TASK_TI_CPU(a1)
|
lw a4, TASK_TI_CPU(a1)
|
||||||
sw a3, TASK_TI_CPU(a1)
|
sw a3, TASK_TI_CPU(a1)
|
||||||
sw a4, TASK_TI_CPU(a0)
|
sw a4, TASK_TI_CPU(a0)
|
||||||
#if TASK_TI != 0
|
/* The offset of thread_info in task_struct is zero. */
|
||||||
#error "TASK_TI != 0: tp will contain a 'struct thread_info', not a 'struct task_struct' so get_current() won't work."
|
|
||||||
addi tp, a1, TASK_TI
|
|
||||||
#else
|
|
||||||
move tp, a1
|
move tp, a1
|
||||||
#endif
|
|
||||||
ret
|
ret
|
||||||
ENDPROC(__switch_to)
|
ENDPROC(__switch_to)
|
||||||
|
|
||||||
|
|
|
@ -77,10 +77,16 @@ relocate:
|
||||||
csrw CSR_SATP, a0
|
csrw CSR_SATP, a0
|
||||||
.align 2
|
.align 2
|
||||||
1:
|
1:
|
||||||
/* Set trap vector to spin forever to help debug */
|
/* Set trap vector to exception handler */
|
||||||
la a0, .Lsecondary_park
|
la a0, handle_exception
|
||||||
csrw CSR_TVEC, a0
|
csrw CSR_TVEC, a0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set sup0 scratch register to 0, indicating to exception vector that
|
||||||
|
* we are presently executing in kernel.
|
||||||
|
*/
|
||||||
|
csrw CSR_SCRATCH, zero
|
||||||
|
|
||||||
/* Reload the global pointer */
|
/* Reload the global pointer */
|
||||||
.option push
|
.option push
|
||||||
.option norelax
|
.option norelax
|
||||||
|
|
53
arch/riscv/kernel/jump_label.c
Normal file
53
arch/riscv/kernel/jump_label.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Emil Renner Berthing
|
||||||
|
*
|
||||||
|
* Based on arch/arm64/kernel/jump_label.c
|
||||||
|
*/
|
||||||
|
#include <linux/jump_label.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/memory.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <asm/bug.h>
|
||||||
|
#include <asm/patch.h>
|
||||||
|
|
||||||
|
#define RISCV_INSN_NOP 0x00000013U
|
||||||
|
#define RISCV_INSN_JAL 0x0000006fU
|
||||||
|
|
||||||
|
void arch_jump_label_transform(struct jump_entry *entry,
|
||||||
|
enum jump_label_type type)
|
||||||
|
{
|
||||||
|
void *addr = (void *)jump_entry_code(entry);
|
||||||
|
u32 insn;
|
||||||
|
|
||||||
|
if (type == JUMP_LABEL_JMP) {
|
||||||
|
long offset = jump_entry_target(entry) - jump_entry_code(entry);
|
||||||
|
|
||||||
|
if (WARN_ON(offset & 1 || offset < -524288 || offset >= 524288))
|
||||||
|
return;
|
||||||
|
|
||||||
|
insn = RISCV_INSN_JAL |
|
||||||
|
(((u32)offset & GENMASK(19, 12)) << (12 - 12)) |
|
||||||
|
(((u32)offset & GENMASK(11, 11)) << (20 - 11)) |
|
||||||
|
(((u32)offset & GENMASK(10, 1)) << (21 - 1)) |
|
||||||
|
(((u32)offset & GENMASK(20, 20)) << (31 - 20));
|
||||||
|
} else {
|
||||||
|
insn = RISCV_INSN_NOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&text_mutex);
|
||||||
|
patch_text_nosync(addr, &insn, sizeof(insn));
|
||||||
|
mutex_unlock(&text_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_jump_label_transform_static(struct jump_entry *entry,
|
||||||
|
enum jump_label_type type)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We use the same instructions in the arch_static_branch and
|
||||||
|
* arch_static_branch_jump inline functions, so there's no
|
||||||
|
* need to patch them up here.
|
||||||
|
* The core will call arch_jump_label_transform when those
|
||||||
|
* instructions need to be replaced.
|
||||||
|
*/
|
||||||
|
}
|
|
@ -263,6 +263,13 @@ static int apply_r_riscv_add32_rela(struct module *me, u32 *location,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int apply_r_riscv_add64_rela(struct module *me, u32 *location,
|
||||||
|
Elf_Addr v)
|
||||||
|
{
|
||||||
|
*(u64 *)location += (u64)v;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_sub32_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_sub32_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
|
@ -270,6 +277,13 @@ static int apply_r_riscv_sub32_rela(struct module *me, u32 *location,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int apply_r_riscv_sub64_rela(struct module *me, u32 *location,
|
||||||
|
Elf_Addr v)
|
||||||
|
{
|
||||||
|
*(u64 *)location -= (u64)v;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
|
static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
|
||||||
Elf_Addr v) = {
|
Elf_Addr v) = {
|
||||||
[R_RISCV_32] = apply_r_riscv_32_rela,
|
[R_RISCV_32] = apply_r_riscv_32_rela,
|
||||||
|
@ -290,7 +304,9 @@ static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
|
||||||
[R_RISCV_RELAX] = apply_r_riscv_relax_rela,
|
[R_RISCV_RELAX] = apply_r_riscv_relax_rela,
|
||||||
[R_RISCV_ALIGN] = apply_r_riscv_align_rela,
|
[R_RISCV_ALIGN] = apply_r_riscv_align_rela,
|
||||||
[R_RISCV_ADD32] = apply_r_riscv_add32_rela,
|
[R_RISCV_ADD32] = apply_r_riscv_add32_rela,
|
||||||
|
[R_RISCV_ADD64] = apply_r_riscv_add64_rela,
|
||||||
[R_RISCV_SUB32] = apply_r_riscv_sub32_rela,
|
[R_RISCV_SUB32] = apply_r_riscv_sub32_rela,
|
||||||
|
[R_RISCV_SUB64] = apply_r_riscv_sub64_rela,
|
||||||
};
|
};
|
||||||
|
|
||||||
int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
|
int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
|
||||||
|
|
|
@ -24,6 +24,12 @@
|
||||||
|
|
||||||
register unsigned long gp_in_global __asm__("gp");
|
register unsigned long gp_in_global __asm__("gp");
|
||||||
|
|
||||||
|
#ifdef CONFIG_STACKPROTECTOR
|
||||||
|
#include <linux/stackprotector.h>
|
||||||
|
unsigned long __stack_chk_guard __read_mostly;
|
||||||
|
EXPORT_SYMBOL(__stack_chk_guard);
|
||||||
|
#endif
|
||||||
|
|
||||||
extern asmlinkage void ret_from_fork(void);
|
extern asmlinkage void ret_from_fork(void);
|
||||||
extern asmlinkage void ret_from_kernel_thread(void);
|
extern asmlinkage void ret_from_kernel_thread(void);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/irq_work.h>
|
||||||
|
|
||||||
#include <asm/clint.h>
|
#include <asm/clint.h>
|
||||||
#include <asm/sbi.h>
|
#include <asm/sbi.h>
|
||||||
|
@ -26,6 +27,7 @@ enum ipi_message_type {
|
||||||
IPI_RESCHEDULE,
|
IPI_RESCHEDULE,
|
||||||
IPI_CALL_FUNC,
|
IPI_CALL_FUNC,
|
||||||
IPI_CPU_STOP,
|
IPI_CPU_STOP,
|
||||||
|
IPI_IRQ_WORK,
|
||||||
IPI_MAX
|
IPI_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,6 +125,13 @@ static inline void clear_ipi(void)
|
||||||
clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
|
clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IRQ_WORK
|
||||||
|
void arch_irq_work_raise(void)
|
||||||
|
{
|
||||||
|
send_ipi_single(smp_processor_id(), IPI_IRQ_WORK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void handle_IPI(struct pt_regs *regs)
|
void handle_IPI(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||||
|
@ -158,6 +167,11 @@ void handle_IPI(struct pt_regs *regs)
|
||||||
ipi_stop();
|
ipi_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ops & (1 << IPI_IRQ_WORK)) {
|
||||||
|
stats[IPI_IRQ_WORK]++;
|
||||||
|
irq_work_run();
|
||||||
|
}
|
||||||
|
|
||||||
BUG_ON((ops >> IPI_MAX) != 0);
|
BUG_ON((ops >> IPI_MAX) != 0);
|
||||||
|
|
||||||
/* Order data access and bit testing. */
|
/* Order data access and bit testing. */
|
||||||
|
@ -173,6 +187,7 @@ static const char * const ipi_names[] = {
|
||||||
[IPI_RESCHEDULE] = "Rescheduling interrupts",
|
[IPI_RESCHEDULE] = "Rescheduling interrupts",
|
||||||
[IPI_CALL_FUNC] = "Function call interrupts",
|
[IPI_CALL_FUNC] = "Function call interrupts",
|
||||||
[IPI_CPU_STOP] = "CPU stop interrupts",
|
[IPI_CPU_STOP] = "CPU stop interrupts",
|
||||||
|
[IPI_IRQ_WORK] = "IRQ work interrupts",
|
||||||
};
|
};
|
||||||
|
|
||||||
void show_ipi_stats(struct seq_file *p, int prec)
|
void show_ipi_stats(struct seq_file *p, int prec)
|
||||||
|
|
|
@ -106,7 +106,7 @@ void __init setup_smp(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int start_secondary_cpu(int cpu, struct task_struct *tidle)
|
static int start_secondary_cpu(int cpu, struct task_struct *tidle)
|
||||||
{
|
{
|
||||||
if (cpu_ops[cpu]->cpu_start)
|
if (cpu_ops[cpu]->cpu_start)
|
||||||
return cpu_ops[cpu]->cpu_start(cpu, tidle);
|
return cpu_ops[cpu]->cpu_start(cpu, tidle);
|
||||||
|
@ -121,7 +121,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
|
||||||
|
|
||||||
ret = start_secondary_cpu(cpu, tidle);
|
ret = start_secondary_cpu(cpu, tidle);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
lockdep_assert_held(&cpu_running);
|
|
||||||
wait_for_completion_timeout(&cpu_running,
|
wait_for_completion_timeout(&cpu_running,
|
||||||
msecs_to_jiffies(1000));
|
msecs_to_jiffies(1000));
|
||||||
|
|
||||||
|
@ -146,6 +145,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
|
||||||
asmlinkage __visible void smp_callin(void)
|
asmlinkage __visible void smp_callin(void)
|
||||||
{
|
{
|
||||||
struct mm_struct *mm = &init_mm;
|
struct mm_struct *mm = &init_mm;
|
||||||
|
unsigned int curr_cpuid = smp_processor_id();
|
||||||
|
|
||||||
if (!IS_ENABLED(CONFIG_RISCV_SBI))
|
if (!IS_ENABLED(CONFIG_RISCV_SBI))
|
||||||
clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
|
clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
|
||||||
|
@ -154,10 +154,10 @@ asmlinkage __visible void smp_callin(void)
|
||||||
mmgrab(mm);
|
mmgrab(mm);
|
||||||
current->active_mm = mm;
|
current->active_mm = mm;
|
||||||
|
|
||||||
trap_init();
|
notify_cpu_starting(curr_cpuid);
|
||||||
notify_cpu_starting(smp_processor_id());
|
update_siblings_masks(curr_cpuid);
|
||||||
update_siblings_masks(smp_processor_id());
|
set_cpu_online(curr_cpuid, 1);
|
||||||
set_cpu_online(smp_processor_id(), 1);
|
|
||||||
/*
|
/*
|
||||||
* Remote TLB flushes are ignored while the CPU is offline, so emit
|
* Remote TLB flushes are ignored while the CPU is offline, so emit
|
||||||
* a local TLB flush right now just in case.
|
* a local TLB flush right now just in case.
|
||||||
|
|
|
@ -174,13 +174,7 @@ int is_valid_bugaddr(unsigned long pc)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_GENERIC_BUG */
|
#endif /* CONFIG_GENERIC_BUG */
|
||||||
|
|
||||||
|
/* stvec & scratch is already set from head.S */
|
||||||
void trap_init(void)
|
void trap_init(void)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Set sup0 scratch register to 0, indicating to exception vector
|
|
||||||
* that we are presently executing in the kernel
|
|
||||||
*/
|
|
||||||
csr_write(CSR_SCRATCH, 0);
|
|
||||||
/* Set the exception vector address */
|
|
||||||
csr_write(CSR_TVEC, &handle_exception);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ vdso-syms += flush_icache
|
||||||
# Files to link into the vdso
|
# Files to link into the vdso
|
||||||
obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
|
obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
|
||||||
|
|
||||||
|
ccflags-y := -fno-stack-protector
|
||||||
|
|
||||||
ifneq ($(c-gettimeofday-y),)
|
ifneq ($(c-gettimeofday-y),)
|
||||||
CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
|
CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
|
||||||
endif
|
endif
|
||||||
|
@ -32,6 +34,7 @@ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
|
||||||
|
|
||||||
# Disable gcov profiling for VDSO code
|
# Disable gcov profiling for VDSO code
|
||||||
GCOV_PROFILE := n
|
GCOV_PROFILE := n
|
||||||
|
KCOV_INSTRUMENT := n
|
||||||
|
|
||||||
# Force dependency
|
# Force dependency
|
||||||
$(obj)/vdso.o: $(obj)/vdso.so
|
$(obj)/vdso.o: $(obj)/vdso.so
|
||||||
|
|
|
@ -22,6 +22,7 @@ SECTIONS
|
||||||
/* Beginning of code and text segment */
|
/* Beginning of code and text segment */
|
||||||
. = LOAD_OFFSET;
|
. = LOAD_OFFSET;
|
||||||
_start = .;
|
_start = .;
|
||||||
|
_stext = .;
|
||||||
HEAD_TEXT_SECTION
|
HEAD_TEXT_SECTION
|
||||||
. = ALIGN(PAGE_SIZE);
|
. = ALIGN(PAGE_SIZE);
|
||||||
|
|
||||||
|
@ -54,7 +55,6 @@ SECTIONS
|
||||||
. = ALIGN(SECTION_ALIGN);
|
. = ALIGN(SECTION_ALIGN);
|
||||||
.text : {
|
.text : {
|
||||||
_text = .;
|
_text = .;
|
||||||
_stext = .;
|
|
||||||
TEXT_TEXT
|
TEXT_TEXT
|
||||||
SCHED_TEXT
|
SCHED_TEXT
|
||||||
CPUIDLE_TEXT
|
CPUIDLE_TEXT
|
||||||
|
|
|
@ -5,6 +5,8 @@ ifdef CONFIG_FTRACE
|
||||||
CFLAGS_REMOVE_init.o = -pg
|
CFLAGS_REMOVE_init.o = -pg
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
KCOV_INSTRUMENT_init.o := n
|
||||||
|
|
||||||
obj-y += init.o
|
obj-y += init.o
|
||||||
obj-y += extable.o
|
obj-y += extable.o
|
||||||
obj-$(CONFIG_MMU) += fault.o pageattr.o
|
obj-$(CONFIG_MMU) += fault.o pageattr.o
|
||||||
|
|
|
@ -541,6 +541,32 @@ void mark_rodata_ro(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void __init resource_init(void)
|
||||||
|
{
|
||||||
|
struct memblock_region *region;
|
||||||
|
|
||||||
|
for_each_memblock(memory, region) {
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
|
res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
|
||||||
|
if (!res)
|
||||||
|
panic("%s: Failed to allocate %zu bytes\n", __func__,
|
||||||
|
sizeof(struct resource));
|
||||||
|
|
||||||
|
if (memblock_is_nomap(region)) {
|
||||||
|
res->name = "reserved";
|
||||||
|
res->flags = IORESOURCE_MEM;
|
||||||
|
} else {
|
||||||
|
res->name = "System RAM";
|
||||||
|
res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
|
||||||
|
}
|
||||||
|
res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
|
||||||
|
res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
|
||||||
|
|
||||||
|
request_resource(&iomem_resource, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void __init paging_init(void)
|
void __init paging_init(void)
|
||||||
{
|
{
|
||||||
setup_vm_final();
|
setup_vm_final();
|
||||||
|
@ -548,6 +574,7 @@ void __init paging_init(void)
|
||||||
sparse_init();
|
sparse_init();
|
||||||
setup_zero_page();
|
setup_zero_page();
|
||||||
zone_sizes_init();
|
zone_sizes_init();
|
||||||
|
resource_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <linux/pgtable.h>
|
#include <linux/pgtable.h>
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
||||||
|
#include <asm/set_memory.h>
|
||||||
|
|
||||||
struct pageattr_masks {
|
struct pageattr_masks {
|
||||||
pgprot_t set_mask;
|
pgprot_t set_mask;
|
||||||
|
@ -94,7 +95,7 @@ static int pageattr_pte_hole(unsigned long addr, unsigned long next,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const static struct mm_walk_ops pageattr_ops = {
|
static const struct mm_walk_ops pageattr_ops = {
|
||||||
.pgd_entry = pageattr_pgd_entry,
|
.pgd_entry = pageattr_pgd_entry,
|
||||||
.p4d_entry = pageattr_p4d_entry,
|
.p4d_entry = pageattr_p4d_entry,
|
||||||
.pud_entry = pageattr_pud_entry,
|
.pud_entry = pageattr_pud_entry,
|
||||||
|
|
|
@ -647,40 +647,6 @@ static inline int arch_unmap_one(struct mm_struct *mm,
|
||||||
#define flush_tlb_fix_spurious_fault(vma, address) flush_tlb_page(vma, address)
|
#define flush_tlb_fix_spurious_fault(vma, address) flush_tlb_page(vma, address)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef pgprot_nx
|
|
||||||
#define pgprot_nx(prot) (prot)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef pgprot_noncached
|
|
||||||
#define pgprot_noncached(prot) (prot)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef pgprot_writecombine
|
|
||||||
#define pgprot_writecombine pgprot_noncached
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef pgprot_writethrough
|
|
||||||
#define pgprot_writethrough pgprot_noncached
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef pgprot_device
|
|
||||||
#define pgprot_device pgprot_noncached
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef pgprot_modify
|
|
||||||
#define pgprot_modify pgprot_modify
|
|
||||||
static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
|
|
||||||
{
|
|
||||||
if (pgprot_val(oldprot) == pgprot_val(pgprot_noncached(oldprot)))
|
|
||||||
newprot = pgprot_noncached(newprot);
|
|
||||||
if (pgprot_val(oldprot) == pgprot_val(pgprot_writecombine(oldprot)))
|
|
||||||
newprot = pgprot_writecombine(newprot);
|
|
||||||
if (pgprot_val(oldprot) == pgprot_val(pgprot_device(oldprot)))
|
|
||||||
newprot = pgprot_device(newprot);
|
|
||||||
return newprot;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When walking page tables, get the address of the next boundary,
|
* When walking page tables, get the address of the next boundary,
|
||||||
* or the end address of the range if that comes earlier. Although no
|
* or the end address of the range if that comes earlier. Although no
|
||||||
|
@ -840,6 +806,43 @@ static inline void ptep_modify_prot_commit(struct vm_area_struct *vma,
|
||||||
* No-op macros that just return the current protection value. Defined here
|
* No-op macros that just return the current protection value. Defined here
|
||||||
* because these macros can be used used even if CONFIG_MMU is not defined.
|
* because these macros can be used used even if CONFIG_MMU is not defined.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef pgprot_nx
|
||||||
|
#define pgprot_nx(prot) (prot)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef pgprot_noncached
|
||||||
|
#define pgprot_noncached(prot) (prot)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef pgprot_writecombine
|
||||||
|
#define pgprot_writecombine pgprot_noncached
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef pgprot_writethrough
|
||||||
|
#define pgprot_writethrough pgprot_noncached
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef pgprot_device
|
||||||
|
#define pgprot_device pgprot_noncached
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
|
#ifndef pgprot_modify
|
||||||
|
#define pgprot_modify pgprot_modify
|
||||||
|
static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
|
||||||
|
{
|
||||||
|
if (pgprot_val(oldprot) == pgprot_val(pgprot_noncached(oldprot)))
|
||||||
|
newprot = pgprot_noncached(newprot);
|
||||||
|
if (pgprot_val(oldprot) == pgprot_val(pgprot_writecombine(oldprot)))
|
||||||
|
newprot = pgprot_writecombine(newprot);
|
||||||
|
if (pgprot_val(oldprot) == pgprot_val(pgprot_device(oldprot)))
|
||||||
|
newprot = pgprot_device(newprot);
|
||||||
|
return newprot;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_MMU */
|
||||||
|
|
||||||
#ifndef pgprot_encrypted
|
#ifndef pgprot_encrypted
|
||||||
#define pgprot_encrypted(prot) (prot)
|
#define pgprot_encrypted(prot) (prot)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
|
|
Loading…
Add table
Reference in a new issue