mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'riscv-for-linus-6.6-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux
Pull RISC-V updates from Palmer Dabbelt: - Support for the new "riscv,isa-extensions" and "riscv,isa-base" device tree interfaces for probing extensions - Support for userspace access to the performance counters - Support for more instructions in kprobes - Crash kernels can be allocated above 4GiB - Support for KCFI - Support for ELFs in !MMU configurations - ARCH_KMALLOC_MINALIGN has been reduced to 8 - mmap() defaults to sv48-sized addresses, with longer addresses hidden behind a hint (similar to Arm and Intel) - Also various fixes and cleanups * tag 'riscv-for-linus-6.6-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (51 commits) lib/Kconfig.debug: Restrict DEBUG_INFO_SPLIT for RISC-V riscv: support PREEMPT_DYNAMIC with static keys riscv: Move create_tmp_mapping() to init sections riscv: Mark KASAN tmp* page tables variables as static riscv: mm: use bitmap_zero() API riscv: enable DEBUG_FORCE_FUNCTION_ALIGN_64B riscv: remove redundant mv instructions RISC-V: mm: Document mmap changes RISC-V: mm: Update pgtable comment documentation RISC-V: mm: Add tests for RISC-V mm RISC-V: mm: Restrict address space for sv39,sv48,sv57 riscv: enable DMA_BOUNCE_UNALIGNED_KMALLOC for !dma_coherent riscv: allow kmalloc() caches aligned to the smallest value riscv: support the elf-fdpic binfmt loader binfmt_elf_fdpic: support 64-bit systems riscv: Allow CONFIG_CFI_CLANG to be selected riscv/purgatory: Disable CFI riscv: Add CFI error handling riscv: Add ftrace_stub_graph riscv: Add types to indirectly called assembly functions ...
This commit is contained in:
@@ -873,7 +873,7 @@
|
||||
memory region [offset, offset + size] for that kernel
|
||||
image. If '@offset' is omitted, then a suitable offset
|
||||
is selected automatically.
|
||||
[KNL, X86-64, ARM64] Select a region under 4G first, and
|
||||
[KNL, X86-64, ARM64, RISCV] Select a region under 4G first, and
|
||||
fall back to reserve region above 4G when '@offset'
|
||||
hasn't been specified.
|
||||
See Documentation/admin-guide/kdump/kdump.rst for further details.
|
||||
@@ -886,14 +886,14 @@
|
||||
Documentation/admin-guide/kdump/kdump.rst for an example.
|
||||
|
||||
crashkernel=size[KMG],high
|
||||
[KNL, X86-64, ARM64] range could be above 4G. Allow kernel
|
||||
to allocate physical memory region from top, so could
|
||||
be above 4G if system have more than 4G ram installed.
|
||||
Otherwise memory region will be allocated below 4G, if
|
||||
available.
|
||||
[KNL, X86-64, ARM64, RISCV] range could be above 4G.
|
||||
Allow kernel to allocate physical memory region from top,
|
||||
so could be above 4G if system have more than 4G ram
|
||||
installed. Otherwise memory region will be allocated
|
||||
below 4G, if available.
|
||||
It will be ignored if crashkernel=X is specified.
|
||||
crashkernel=size[KMG],low
|
||||
[KNL, X86-64, ARM64] range under 4G. When crashkernel=X,high
|
||||
[KNL, X86-64, ARM64, RISCV] range under 4G. When crashkernel=X,high
|
||||
is passed, kernel could allocate physical memory region
|
||||
above 4G, that cause second kernel crash on system
|
||||
that require some amount of low memory, e.g. swiotlb
|
||||
@@ -904,6 +904,7 @@
|
||||
size is platform dependent.
|
||||
--> x86: max(swiotlb_size_or_default() + 8MiB, 256MiB)
|
||||
--> arm64: 128MiB
|
||||
--> riscv: 128MiB
|
||||
This one lets the user specify own low range under 4G
|
||||
for second kernel instead.
|
||||
0: to disable low allocation.
|
||||
@@ -5554,6 +5555,13 @@
|
||||
[KNL] Disable ring 3 MONITOR/MWAIT feature on supported
|
||||
CPUs.
|
||||
|
||||
riscv_isa_fallback [RISCV]
|
||||
When CONFIG_RISCV_ISA_FALLBACK is not enabled, permit
|
||||
falling back to detecting extension support by parsing
|
||||
"riscv,isa" property on devicetree systems when the
|
||||
replacement properties are not found. See the Kconfig
|
||||
entry for RISCV_ISA_FALLBACK.
|
||||
|
||||
ro [KNL] Mount root device read-only on boot
|
||||
|
||||
rodata= [KNL]
|
||||
|
||||
@@ -941,16 +941,35 @@ enabled, otherwise writing to this file will return ``-EBUSY``.
|
||||
The default value is 8.
|
||||
|
||||
|
||||
perf_user_access (arm64 only)
|
||||
=================================
|
||||
perf_user_access (arm64 and riscv only)
|
||||
=======================================
|
||||
|
||||
Controls user space access for reading perf event counters. When set to 1,
|
||||
user space can read performance monitor counter registers directly.
|
||||
Controls user space access for reading perf event counters.
|
||||
|
||||
arm64
|
||||
=====
|
||||
|
||||
The default value is 0 (access disabled).
|
||||
|
||||
When set to 1, user space can read performance monitor counter registers
|
||||
directly.
|
||||
|
||||
See Documentation/arch/arm64/perf.rst for more information.
|
||||
|
||||
riscv
|
||||
=====
|
||||
|
||||
When set to 0, user space access is disabled.
|
||||
|
||||
The default value is 1, user space can read performance monitor counter
|
||||
registers through perf, any direct access without perf intervention will trigger
|
||||
an illegal instruction.
|
||||
|
||||
When set to 2, which enables legacy mode (user space has direct access to cycle
|
||||
and insret CSRs only). Note that this legacy value is deprecated and will be
|
||||
removed once all user space applications are fixed.
|
||||
|
||||
Note that the time CSR is always directly accessible to all modes.
|
||||
|
||||
pid_max
|
||||
=======
|
||||
|
||||
@@ -133,3 +133,25 @@ RISC-V Linux Kernel SV57
|
||||
ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | modules, BPF
|
||||
ffffffff80000000 | -2 GB | ffffffffffffffff | 2 GB | kernel
|
||||
__________________|____________|__________________|_________|____________________________________________________________
|
||||
|
||||
|
||||
Userspace VAs
|
||||
--------------------
|
||||
To maintain compatibility with software that relies on the VA space with a
|
||||
maximum of 48 bits the kernel will, by default, return virtual addresses to
|
||||
userspace from a 48-bit range (sv48). This default behavior is achieved by
|
||||
passing 0 into the hint address parameter of mmap. On CPUs with an address space
|
||||
smaller than sv48, the CPU maximum supported address space will be the default.
|
||||
|
||||
Software can "opt-in" to receiving VAs from another VA space by providing
|
||||
a hint address to mmap. A hint address passed to mmap will cause the largest
|
||||
address space that fits entirely into the hint to be used, unless there is no
|
||||
space left in the address space. If there is no space available in the requested
|
||||
address space, an address in the next smallest available address space will be
|
||||
returned.
|
||||
|
||||
For example, in order to obtain 48-bit VA space, a hint address greater than
|
||||
:code:`1 << 47` must be provided. Note that this is 47 due to sv48 userspace
|
||||
ending at :code:`1 << 47` and the addresses beyond this are reserved for the
|
||||
kernel. Similarly, to obtain 57-bit VA space addresses, a hint address greater
|
||||
than or equal to :code:`1 << 56` must be provided.
|
||||
|
||||
@@ -35,6 +35,7 @@ config RISCV
|
||||
select ARCH_HAS_SET_MEMORY if MMU
|
||||
select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL
|
||||
select ARCH_HAS_STRICT_MODULE_RWX if MMU && !XIP_KERNEL
|
||||
select ARCH_HAS_SYSCALL_WRAPPER
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select ARCH_HAS_UBSAN_SANITIZE_ALL
|
||||
select ARCH_HAS_VDSO_DATA
|
||||
@@ -42,12 +43,14 @@ config RISCV
|
||||
select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
|
||||
select ARCH_STACKWALK
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||
select ARCH_SUPPORTS_CFI_CLANG
|
||||
select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
|
||||
select ARCH_SUPPORTS_HUGETLBFS if MMU
|
||||
select ARCH_SUPPORTS_PAGE_TABLE_CHECK if MMU
|
||||
select ARCH_SUPPORTS_PER_VMA_LOCK if MMU
|
||||
select ARCH_USE_MEMTEST
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_USES_CFI_TRAPS if CFI_CLANG
|
||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
select ARCH_WANT_GENERAL_HUGETLB if !RISCV_ISA_SVNAPOT
|
||||
@@ -62,6 +65,7 @@ config RISCV
|
||||
select COMMON_CLK
|
||||
select CPU_PM if CPU_IDLE || HIBERNATION
|
||||
select EDAC_SUPPORT
|
||||
select FRAME_POINTER if PERF_EVENTS || (FUNCTION_TRACER && !DYNAMIC_FTRACE)
|
||||
select GENERIC_ARCH_TOPOLOGY
|
||||
select GENERIC_ATOMIC64 if !64BIT
|
||||
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
|
||||
@@ -130,6 +134,7 @@ config RISCV
|
||||
select HAVE_PERF_REGS
|
||||
select HAVE_PERF_USER_STACK_DUMP
|
||||
select HAVE_POSIX_CPU_TIMERS_TASK_WORK
|
||||
select HAVE_PREEMPT_DYNAMIC_KEY if !XIP_KERNEL
|
||||
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||
select HAVE_RETHOOK if !XIP_KERNEL
|
||||
select HAVE_RSEQ
|
||||
@@ -267,6 +272,7 @@ config RISCV_DMA_NONCOHERENT
|
||||
select ARCH_HAS_SETUP_DMA_OPS
|
||||
select ARCH_HAS_SYNC_DMA_FOR_CPU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
|
||||
select DMA_BOUNCE_UNALIGNED_KMALLOC if SWIOTLB
|
||||
select DMA_DIRECT_REMAP
|
||||
|
||||
config AS_HAS_INSN
|
||||
@@ -836,6 +842,24 @@ config XIP_PHYS_ADDR
|
||||
be linked for and stored to. This address is dependent on your
|
||||
own flash usage.
|
||||
|
||||
config RISCV_ISA_FALLBACK
|
||||
bool "Permit falling back to parsing riscv,isa for extension support by default"
|
||||
default y
|
||||
help
|
||||
Parsing the "riscv,isa" devicetree property has been deprecated and
|
||||
replaced by a list of explicitly defined strings. For compatibility
|
||||
with existing platforms, the kernel will fall back to parsing the
|
||||
"riscv,isa" property if the replacements are not found.
|
||||
|
||||
Selecting N here will result in a kernel that does not use the
|
||||
fallback, unless the commandline "riscv_isa_fallback" parameter is
|
||||
present.
|
||||
|
||||
Please see the dt-binding, located at
|
||||
Documentation/devicetree/bindings/riscv/extensions.yaml for details
|
||||
on the replacement properties, "riscv,isa-base" and
|
||||
"riscv,isa-extensions".
|
||||
|
||||
endmenu # "Boot options"
|
||||
|
||||
config BUILTIN_DTB
|
||||
|
||||
@@ -87,9 +87,6 @@ endif
|
||||
ifeq ($(CONFIG_CMODEL_MEDANY),y)
|
||||
KBUILD_CFLAGS += -mcmodel=medany
|
||||
endif
|
||||
ifeq ($(CONFIG_PERF_EVENTS),y)
|
||||
KBUILD_CFLAGS += -fno-omit-frame-pointer
|
||||
endif
|
||||
|
||||
# Avoid generating .eh_frame sections.
|
||||
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
* vendor_id: The CPU vendor ID.
|
||||
* patch_id: The patch ID (erratum ID or cpufeature ID).
|
||||
* CONFIG_k: The Kconfig of this patch ID. When Kconfig is disabled, the old
|
||||
* content will alwyas be executed.
|
||||
* content will always be executed.
|
||||
*/
|
||||
#define ALTERNATIVE(old_content, new_content, vendor_id, patch_id, CONFIG_k) \
|
||||
_ALTERNATIVE_CFG(old_content, new_content, vendor_id, patch_id, CONFIG_k)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#ifdef CONFIG_RISCV_DMA_NONCOHERENT
|
||||
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
|
||||
#define ARCH_KMALLOC_MINALIGN (8)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -23,4 +24,17 @@
|
||||
#define ARCH_SLAB_MINALIGN 16
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_RISCV_DMA_NONCOHERENT
|
||||
extern int dma_cache_alignment;
|
||||
#define dma_get_cache_alignment dma_get_cache_alignment
|
||||
static inline int dma_get_cache_alignment(void)
|
||||
{
|
||||
return dma_cache_alignment;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_RISCV_CACHE_H */
|
||||
|
||||
@@ -58,8 +58,10 @@ void riscv_init_cbo_blocksizes(void);
|
||||
|
||||
#ifdef CONFIG_RISCV_DMA_NONCOHERENT
|
||||
void riscv_noncoherent_supported(void);
|
||||
void __init riscv_set_dma_cache_alignment(void);
|
||||
#else
|
||||
static inline void riscv_noncoherent_supported(void) {}
|
||||
static inline void riscv_set_dma_cache_alignment(void) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
22
arch/riscv/include/asm/cfi.h
Normal file
22
arch/riscv/include/asm/cfi.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_RISCV_CFI_H
|
||||
#define _ASM_RISCV_CFI_H
|
||||
|
||||
/*
|
||||
* Clang Control Flow Integrity (CFI) support.
|
||||
*
|
||||
* Copyright (C) 2023 Google LLC
|
||||
*/
|
||||
|
||||
#include <linux/cfi.h>
|
||||
|
||||
#ifdef CONFIG_CFI_CLANG
|
||||
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
|
||||
#else
|
||||
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
|
||||
{
|
||||
return BUG_TRAP_TYPE_NONE;
|
||||
}
|
||||
#endif /* CONFIG_CFI_CLANG */
|
||||
|
||||
#endif /* _ASM_RISCV_CFI_H */
|
||||
@@ -41,6 +41,7 @@ extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
|
||||
#define compat_elf_check_arch compat_elf_check_arch
|
||||
|
||||
#define CORE_DUMP_USE_REGSET
|
||||
#define ELF_FDPIC_CORE_EFLAGS 0
|
||||
#define ELF_EXEC_PAGESIZE (PAGE_SIZE)
|
||||
|
||||
/*
|
||||
@@ -49,7 +50,7 @@ extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
|
||||
* the loader. We need to make sure that it is out of the way of the program
|
||||
* that it will "exec", and that there is sufficient room for the brk.
|
||||
*/
|
||||
#define ELF_ET_DYN_BASE ((TASK_SIZE / 3) * 2)
|
||||
#define ELF_ET_DYN_BASE ((DEFAULT_MAP_WINDOW / 3) * 2)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#ifdef CONFIG_COMPAT
|
||||
@@ -69,6 +70,13 @@ extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
|
||||
#define ELF_HWCAP riscv_get_elf_hwcap()
|
||||
extern unsigned long elf_hwcap;
|
||||
|
||||
#define ELF_FDPIC_PLAT_INIT(_r, _exec_map_addr, _interp_map_addr, dynamic_addr) \
|
||||
do { \
|
||||
(_r)->a1 = _exec_map_addr; \
|
||||
(_r)->a2 = _interp_map_addr; \
|
||||
(_r)->a3 = dynamic_addr; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* This yields a string that ld.so will use to load implementation
|
||||
* specific libraries for optimization. This is more specific in
|
||||
@@ -78,7 +86,6 @@ extern unsigned long elf_hwcap;
|
||||
|
||||
#define COMPAT_ELF_PLATFORM (NULL)
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#define ARCH_DLINFO \
|
||||
do { \
|
||||
/* \
|
||||
@@ -115,6 +122,8 @@ do { \
|
||||
else \
|
||||
NEW_AUX_ENT(AT_IGNORE, 0); \
|
||||
} while (0)
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
|
||||
struct linux_binprm;
|
||||
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||
|
||||
@@ -14,12 +14,17 @@
|
||||
#include <uapi/asm/hwcap.h>
|
||||
|
||||
#define RISCV_ISA_EXT_a ('a' - 'a')
|
||||
#define RISCV_ISA_EXT_b ('b' - 'a')
|
||||
#define RISCV_ISA_EXT_c ('c' - 'a')
|
||||
#define RISCV_ISA_EXT_d ('d' - 'a')
|
||||
#define RISCV_ISA_EXT_f ('f' - 'a')
|
||||
#define RISCV_ISA_EXT_h ('h' - 'a')
|
||||
#define RISCV_ISA_EXT_i ('i' - 'a')
|
||||
#define RISCV_ISA_EXT_j ('j' - 'a')
|
||||
#define RISCV_ISA_EXT_k ('k' - 'a')
|
||||
#define RISCV_ISA_EXT_m ('m' - 'a')
|
||||
#define RISCV_ISA_EXT_p ('p' - 'a')
|
||||
#define RISCV_ISA_EXT_q ('q' - 'a')
|
||||
#define RISCV_ISA_EXT_s ('s' - 'a')
|
||||
#define RISCV_ISA_EXT_u ('u' - 'a')
|
||||
#define RISCV_ISA_EXT_v ('v' - 'a')
|
||||
@@ -55,7 +60,6 @@
|
||||
#define RISCV_ISA_EXT_ZIHPM 42
|
||||
|
||||
#define RISCV_ISA_EXT_MAX 64
|
||||
#define RISCV_ISA_EXT_NAME_LEN_MAX 32
|
||||
|
||||
#ifdef CONFIG_RISCV_M_MODE
|
||||
#define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SMAIA
|
||||
@@ -70,12 +74,15 @@
|
||||
unsigned long riscv_get_elf_hwcap(void);
|
||||
|
||||
struct riscv_isa_ext_data {
|
||||
/* Name of the extension displayed to userspace via /proc/cpuinfo */
|
||||
char uprop[RISCV_ISA_EXT_NAME_LEN_MAX];
|
||||
/* The logical ISA extension ID */
|
||||
unsigned int isa_ext_id;
|
||||
const unsigned int id;
|
||||
const char *name;
|
||||
const char *property;
|
||||
};
|
||||
|
||||
extern const struct riscv_isa_ext_data riscv_isa_ext[];
|
||||
extern const size_t riscv_isa_ext_count;
|
||||
extern bool riscv_isa_fallback;
|
||||
|
||||
unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
|
||||
|
||||
#define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext)
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#define RVG_RS1_OPOFF 15
|
||||
#define RVG_RS2_OPOFF 20
|
||||
#define RVG_RD_OPOFF 7
|
||||
#define RVG_RS1_MASK GENMASK(4, 0)
|
||||
#define RVG_RD_MASK GENMASK(4, 0)
|
||||
|
||||
/* The bit field of immediate value in RVC J instruction */
|
||||
@@ -130,6 +131,7 @@
|
||||
#define RVC_C2_RS1_OPOFF 7
|
||||
#define RVC_C2_RS2_OPOFF 2
|
||||
#define RVC_C2_RD_OPOFF 7
|
||||
#define RVC_C2_RS1_MASK GENMASK(4, 0)
|
||||
|
||||
/* parts of opcode for RVG*/
|
||||
#define RVG_OPCODE_FENCE 0x0f
|
||||
@@ -289,6 +291,10 @@ static __always_inline bool riscv_insn_is_c_jalr(u32 code)
|
||||
#define RV_X(X, s, mask) (((X) >> (s)) & (mask))
|
||||
#define RVC_X(X, s, mask) RV_X(X, s, mask)
|
||||
|
||||
#define RV_EXTRACT_RS1_REG(x) \
|
||||
({typeof(x) x_ = (x); \
|
||||
(RV_X(x_, RVG_RS1_OPOFF, RVG_RS1_MASK)); })
|
||||
|
||||
#define RV_EXTRACT_RD_REG(x) \
|
||||
({typeof(x) x_ = (x); \
|
||||
(RV_X(x_, RVG_RD_OPOFF, RVG_RD_MASK)); })
|
||||
@@ -316,6 +322,10 @@ static __always_inline bool riscv_insn_is_c_jalr(u32 code)
|
||||
(RV_X(x_, RV_B_IMM_11_OPOFF, RV_B_IMM_11_MASK) << RV_B_IMM_11_OFF) | \
|
||||
(RV_IMM_SIGN(x_) << RV_B_IMM_SIGN_OFF); })
|
||||
|
||||
#define RVC_EXTRACT_C2_RS1_REG(x) \
|
||||
({typeof(x) x_ = (x); \
|
||||
(RV_X(x_, RVC_C2_RS1_OPOFF, RVC_C2_RS1_MASK)); })
|
||||
|
||||
#define RVC_EXTRACT_JTYPE_IMM(x) \
|
||||
({typeof(x) x_ = (x); \
|
||||
(RVC_X(x_, RVC_J_IMM_3_1_OPOFF, RVC_J_IMM_3_1_MASK) << RVC_J_IMM_3_1_OFF) | \
|
||||
|
||||
@@ -20,6 +20,10 @@ typedef struct {
|
||||
/* A local icache flush is needed before user execution can resume. */
|
||||
cpumask_t icache_stale_mask;
|
||||
#endif
|
||||
#ifdef CONFIG_BINFMT_ELF_FDPIC
|
||||
unsigned long exec_fdpic_loadmap;
|
||||
unsigned long interp_fdpic_loadmap;
|
||||
#endif
|
||||
} mm_context_t;
|
||||
|
||||
void __init create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa,
|
||||
|
||||
@@ -62,11 +62,16 @@
|
||||
* struct pages to map half the virtual address space. Then
|
||||
* position vmemmap directly below the VMALLOC region.
|
||||
*/
|
||||
#define VA_BITS_SV32 32
|
||||
#ifdef CONFIG_64BIT
|
||||
#define VA_BITS_SV39 39
|
||||
#define VA_BITS_SV48 48
|
||||
#define VA_BITS_SV57 57
|
||||
|
||||
#define VA_BITS (pgtable_l5_enabled ? \
|
||||
57 : (pgtable_l4_enabled ? 48 : 39))
|
||||
VA_BITS_SV57 : (pgtable_l4_enabled ? VA_BITS_SV48 : VA_BITS_SV39))
|
||||
#else
|
||||
#define VA_BITS 32
|
||||
#define VA_BITS VA_BITS_SV32
|
||||
#endif
|
||||
|
||||
#define VMEMMAP_SHIFT \
|
||||
@@ -111,11 +116,27 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <linux/mm_types.h>
|
||||
#include <asm/compat.h>
|
||||
|
||||
#define __page_val_to_pfn(_val) (((_val) & _PAGE_PFN_MASK) >> _PAGE_PFN_SHIFT)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#include <asm/pgtable-64.h>
|
||||
|
||||
#define VA_USER_SV39 (UL(1) << (VA_BITS_SV39 - 1))
|
||||
#define VA_USER_SV48 (UL(1) << (VA_BITS_SV48 - 1))
|
||||
#define VA_USER_SV57 (UL(1) << (VA_BITS_SV57 - 1))
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define MMAP_VA_BITS_64 ((VA_BITS >= VA_BITS_SV48) ? VA_BITS_SV48 : VA_BITS)
|
||||
#define MMAP_MIN_VA_BITS_64 (VA_BITS_SV39)
|
||||
#define MMAP_VA_BITS (is_compat_task() ? VA_BITS_SV32 : MMAP_VA_BITS_64)
|
||||
#define MMAP_MIN_VA_BITS (is_compat_task() ? VA_BITS_SV32 : MMAP_MIN_VA_BITS_64)
|
||||
#else
|
||||
#define MMAP_VA_BITS ((VA_BITS >= VA_BITS_SV48) ? VA_BITS_SV48 : VA_BITS)
|
||||
#define MMAP_MIN_VA_BITS (VA_BITS_SV39)
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
#else
|
||||
#include <asm/pgtable-32.h>
|
||||
#endif /* CONFIG_64BIT */
|
||||
@@ -843,14 +864,16 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
|
||||
* Task size is 0x4000000000 for RV64 or 0x9fc00000 for RV32.
|
||||
* Note that PGDIR_SIZE must evenly divide TASK_SIZE.
|
||||
* Task size is:
|
||||
* - 0x9fc00000 (~2.5GB) for RV32.
|
||||
* - 0x4000000000 ( 256GB) for RV64 using SV39 mmu
|
||||
* - 0x800000000000 ( 128TB) for RV64 using SV48 mmu
|
||||
* - 0x9fc00000 (~2.5GB) for RV32.
|
||||
* - 0x4000000000 ( 256GB) for RV64 using SV39 mmu
|
||||
* - 0x800000000000 ( 128TB) for RV64 using SV48 mmu
|
||||
* - 0x100000000000000 ( 64PB) for RV64 using SV57 mmu
|
||||
*
|
||||
* Note that PGDIR_SIZE must evenly divide TASK_SIZE since "RISC-V
|
||||
* Instruction Set Manual Volume II: Privileged Architecture" states that
|
||||
* "load and store effective addresses, which are 64bits, must have bits
|
||||
* 63–48 all equal to bit 47, or else a page-fault exception will occur."
|
||||
* Similarly for SV57, bits 63–57 must be equal to bit 56.
|
||||
*/
|
||||
#ifdef CONFIG_64BIT
|
||||
#define TASK_SIZE_64 (PGDIR_SIZE * PTRS_PER_PGD / 2)
|
||||
|
||||
@@ -13,19 +13,59 @@
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1))
|
||||
#define STACK_TOP_MAX TASK_SIZE_64
|
||||
|
||||
#define arch_get_mmap_end(addr, len, flags) \
|
||||
({ \
|
||||
unsigned long mmap_end; \
|
||||
typeof(addr) _addr = (addr); \
|
||||
if ((_addr) == 0 || (IS_ENABLED(CONFIG_COMPAT) && is_compat_task())) \
|
||||
mmap_end = STACK_TOP_MAX; \
|
||||
else if ((_addr) >= VA_USER_SV57) \
|
||||
mmap_end = STACK_TOP_MAX; \
|
||||
else if ((((_addr) >= VA_USER_SV48)) && (VA_BITS >= VA_BITS_SV48)) \
|
||||
mmap_end = VA_USER_SV48; \
|
||||
else \
|
||||
mmap_end = VA_USER_SV39; \
|
||||
mmap_end; \
|
||||
})
|
||||
|
||||
#define arch_get_mmap_base(addr, base) \
|
||||
({ \
|
||||
unsigned long mmap_base; \
|
||||
typeof(addr) _addr = (addr); \
|
||||
typeof(base) _base = (base); \
|
||||
unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \
|
||||
if ((_addr) == 0 || (IS_ENABLED(CONFIG_COMPAT) && is_compat_task())) \
|
||||
mmap_base = (_base); \
|
||||
else if (((_addr) >= VA_USER_SV57) && (VA_BITS >= VA_BITS_SV57)) \
|
||||
mmap_base = VA_USER_SV57 - rnd_gap; \
|
||||
else if ((((_addr) >= VA_USER_SV48)) && (VA_BITS >= VA_BITS_SV48)) \
|
||||
mmap_base = VA_USER_SV48 - rnd_gap; \
|
||||
else \
|
||||
mmap_base = VA_USER_SV39 - rnd_gap; \
|
||||
mmap_base; \
|
||||
})
|
||||
|
||||
#else
|
||||
#define DEFAULT_MAP_WINDOW TASK_SIZE
|
||||
#define STACK_TOP_MAX TASK_SIZE
|
||||
#endif
|
||||
#define STACK_ALIGN 16
|
||||
|
||||
#define STACK_TOP DEFAULT_MAP_WINDOW
|
||||
|
||||
/*
|
||||
* This decides where the kernel will search for a free chunk of vm
|
||||
* space during mmap's.
|
||||
*/
|
||||
#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
|
||||
|
||||
#define STACK_TOP TASK_SIZE
|
||||
#ifdef CONFIG_64BIT
|
||||
#define STACK_TOP_MAX TASK_SIZE_64
|
||||
#define TASK_UNMAPPED_BASE PAGE_ALIGN((UL(1) << MMAP_MIN_VA_BITS) / 3)
|
||||
#else
|
||||
#define STACK_TOP_MAX TASK_SIZE
|
||||
#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
|
||||
#endif
|
||||
#define STACK_ALIGN 16
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ static inline int syscall_get_arch(struct task_struct *task)
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef long (*syscall_t)(ulong, ulong, ulong, ulong, ulong, ulong, ulong);
|
||||
typedef long (*syscall_t)(const struct pt_regs *);
|
||||
static inline void syscall_handler(struct pt_regs *regs, ulong syscall)
|
||||
{
|
||||
syscall_t fn;
|
||||
@@ -87,8 +87,7 @@ static inline void syscall_handler(struct pt_regs *regs, ulong syscall)
|
||||
#endif
|
||||
fn = sys_call_table[syscall];
|
||||
|
||||
regs->a0 = fn(regs->orig_a0, regs->a1, regs->a2,
|
||||
regs->a3, regs->a4, regs->a5, regs->a6);
|
||||
regs->a0 = fn(regs);
|
||||
}
|
||||
|
||||
static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
|
||||
|
||||
87
arch/riscv/include/asm/syscall_wrapper.h
Normal file
87
arch/riscv/include/asm/syscall_wrapper.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* syscall_wrapper.h - riscv specific wrappers to syscall definitions
|
||||
*
|
||||
* Based on arch/arm64/include/syscall_wrapper.h
|
||||
*/
|
||||
|
||||
#ifndef __ASM_SYSCALL_WRAPPER_H
|
||||
#define __ASM_SYSCALL_WRAPPER_H
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
asmlinkage long __riscv_sys_ni_syscall(const struct pt_regs *);
|
||||
|
||||
#define SC_RISCV_REGS_TO_ARGS(x, ...) \
|
||||
__MAP(x,__SC_ARGS \
|
||||
,,regs->orig_a0,,regs->a1,,regs->a2 \
|
||||
,,regs->a3,,regs->a4,,regs->a5,,regs->a6)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
#define COMPAT_SYSCALL_DEFINEx(x, name, ...) \
|
||||
asmlinkage long __riscv_compat_sys##name(const struct pt_regs *regs); \
|
||||
ALLOW_ERROR_INJECTION(__riscv_compat_sys##name, ERRNO); \
|
||||
static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
|
||||
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
|
||||
asmlinkage long __riscv_compat_sys##name(const struct pt_regs *regs) \
|
||||
{ \
|
||||
return __se_compat_sys##name(SC_RISCV_REGS_TO_ARGS(x,__VA_ARGS__)); \
|
||||
} \
|
||||
static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
|
||||
{ \
|
||||
return __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \
|
||||
} \
|
||||
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
|
||||
|
||||
#define COMPAT_SYSCALL_DEFINE0(sname) \
|
||||
asmlinkage long __riscv_compat_sys_##sname(const struct pt_regs *__unused); \
|
||||
ALLOW_ERROR_INJECTION(__riscv_compat_sys_##sname, ERRNO); \
|
||||
asmlinkage long __riscv_compat_sys_##sname(const struct pt_regs *__unused)
|
||||
|
||||
#define COND_SYSCALL_COMPAT(name) \
|
||||
asmlinkage long __weak __riscv_compat_sys_##name(const struct pt_regs *regs); \
|
||||
asmlinkage long __weak __riscv_compat_sys_##name(const struct pt_regs *regs) \
|
||||
{ \
|
||||
return sys_ni_syscall(); \
|
||||
}
|
||||
|
||||
#define COMPAT_SYS_NI(name) \
|
||||
SYSCALL_ALIAS(__riscv_compat_sys_##name, sys_ni_posix_timers);
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
#define __SYSCALL_DEFINEx(x, name, ...) \
|
||||
asmlinkage long __riscv_sys##name(const struct pt_regs *regs); \
|
||||
ALLOW_ERROR_INJECTION(__riscv_sys##name, ERRNO); \
|
||||
static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
|
||||
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
|
||||
asmlinkage long __riscv_sys##name(const struct pt_regs *regs) \
|
||||
{ \
|
||||
return __se_sys##name(SC_RISCV_REGS_TO_ARGS(x,__VA_ARGS__)); \
|
||||
} \
|
||||
static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
|
||||
{ \
|
||||
long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
|
||||
__MAP(x,__SC_TEST,__VA_ARGS__); \
|
||||
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
|
||||
return ret; \
|
||||
} \
|
||||
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
|
||||
|
||||
#define SYSCALL_DEFINE0(sname) \
|
||||
SYSCALL_METADATA(_##sname, 0); \
|
||||
asmlinkage long __riscv_sys_##sname(const struct pt_regs *__unused); \
|
||||
ALLOW_ERROR_INJECTION(__riscv_sys_##sname, ERRNO); \
|
||||
asmlinkage long __riscv_sys_##sname(const struct pt_regs *__unused)
|
||||
|
||||
#define COND_SYSCALL(name) \
|
||||
asmlinkage long __weak __riscv_sys_##name(const struct pt_regs *regs); \
|
||||
asmlinkage long __weak __riscv_sys_##name(const struct pt_regs *regs) \
|
||||
{ \
|
||||
return sys_ni_syscall(); \
|
||||
}
|
||||
|
||||
#define SYS_NI(name) SYSCALL_ALIAS(__riscv_sys_##name, sys_ni_posix_timers);
|
||||
|
||||
#endif /* __ASM_SYSCALL_WRAPPER_H */
|
||||
@@ -10,6 +10,11 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define PTRACE_GETFDPIC 33
|
||||
|
||||
#define PTRACE_GETFDPIC_EXEC 0
|
||||
#define PTRACE_GETFDPIC_INTERP 1
|
||||
|
||||
/*
|
||||
* User-mode register state for core dumps, ptrace, sigcontext
|
||||
*
|
||||
|
||||
@@ -25,7 +25,7 @@ struct __sc_riscv_v_state {
|
||||
* Signal context structure
|
||||
*
|
||||
* This contains the context saved before a signal handler is invoked;
|
||||
* it is restored by sys_sigreturn / sys_rt_sigreturn.
|
||||
* it is restored by sys_rt_sigreturn.
|
||||
*/
|
||||
struct sigcontext {
|
||||
struct user_regs_struct sc_regs;
|
||||
|
||||
@@ -91,6 +91,8 @@ obj-$(CONFIG_CRASH_CORE) += crash_core.o
|
||||
|
||||
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||
|
||||
obj-$(CONFIG_CFI_CLANG) += cfi.o
|
||||
|
||||
obj-$(CONFIG_EFI) += efi.o
|
||||
obj-$(CONFIG_COMPAT) += compat_syscall_table.o
|
||||
obj-$(CONFIG_COMPAT) += compat_signal.o
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user