mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
LoongArch changes for v7.1
1, Adjust build infrastructure for 32BIT/64BIT;
2, Add HIGHMEM (PKMAP and FIX_KMAP) support;
3, Show and handle CPU vulnerabilites correctly;
4, Batch the icache maintenance for jump_label;
5, Add more atomic instructions support for BPF JIT;
6, Add more features (e.g. fsession) support for BPF trampoline;
7, Some bug fixes and other small changes.
-----BEGIN PGP SIGNATURE-----
iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAmnpwWgWHGNoZW5odWFj
YWlAa2VybmVsLm9yZwAKCRAChivD8uImeiAXD/0RSRhj2y8LYGhVSPStMgN4uwMl
1ylbkRg0biTvV0g8sD1R3MQ58/tKBZY5wTeLjwT50rl+JgOqVdrN6OMAxjwOKzJ6
7C0rgpxBG5/YHI93paFVIYszsiWhRQaB5qfZCUOr230ZDJzvnfF1aH6JLybeHoMp
HvERNURQsRbZo9yc69YxhrmHETEbum37u9hsrY5mJSEs5Fh+QxvTSYjE36z3Dtal
YFqopTCaBgAhVw6BldVAcyvGvVK+d6iQEA035jObNLKKReNkwsQixxgnJhDSkbbG
Z3md+hWp+YQQElGIP5q6+rj1rJZGrs/XL3HAnTQfXN+8bXIUO9AOf2/l5f9fZx7o
2Vtt8n2/vVdzsVnKiHXGtsZ5uXrw4/kLiMZSCrUMZCtEOxJV9mmrVskPeie0iq0/
nDG9uCgRldL8Xpg7d5NM9coECui3J+ztNkv06tL/JLm02bJPuqNwt3FeA1T/aH1c
l2Hpw3Xuzl7lYuAYoa5CMm4X6yD/RA6w44pW1NKnb6j6llIOk6V6NwcwggWUnqht
oB5VIqPKMOYjZ+fLurI2o9VWqWokJxDdzyrHhXyaG0JRK9Vak06C8UI5BQuosu88
9WBoxK77PyNa60m56C32OZ5tu4UoPT8PgZWXDQDwn82SWzuYKWRruS2ng5A/JF7r
H2Ez4iBjs2/P7vTQHA==
=FiFl
-----END PGP SIGNATURE-----
Merge tag 'loongarch-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch updates from Huacai Chen:
- Adjust build infrastructure for 32BIT/64BIT
- Add HIGHMEM (PKMAP and FIX_KMAP) support
- Show and handle CPU vulnerabilites correctly
- Batch the icache maintenance for jump_label
- Add more atomic instructions support for BPF JIT
- Add more features (e.g. fsession) support for BPF trampoline
- Some bug fixes and other small changes
* tag 'loongarch-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson: (21 commits)
selftests/bpf: Enable CAN_USE_LOAD_ACQ_STORE_REL for LoongArch
LoongArch: BPF: Add fsession support for trampolines
LoongArch: BPF: Introduce emit_store_stack_imm64() helper
LoongArch: BPF: Support up to 12 function arguments for trampoline
LoongArch: BPF: Support small struct arguments for trampoline
LoongArch: BPF: Open code and remove invoke_bpf_mod_ret()
LoongArch: BPF: Support load-acquire and store-release instructions
LoongArch: BPF: Support 8 and 16 bit read-modify-write instructions
LoongArch: BPF: Add the default case in emit_atomic() and rename it
LoongArch: Define instruction formats for AM{SWAP/ADD}.{B/H} and DBAR
LoongArch: Batch the icache maintenance for jump_label
LoongArch: Add flush_icache_all()/local_flush_icache_all()
LoongArch: Add spectre boundry for syscall dispatch table
LoongArch: Show CPU vulnerabilites correctly
LoongArch: Make arch_irq_work_has_interrupt() true only if IPI HW exist
LoongArch: Use get_random_canary() for stack canary init
LoongArch: Improve the logging of disabling KASLR
LoongArch: Align FPU register state to 32 bytes
LoongArch: Handle CONFIG_32BIT in syscall_get_arch()
LoongArch: Add HIGHMEM (PKMAP and FIX_KMAP) support
...
This commit is contained in:
commit
ff57d59200
|
|
@ -20,11 +20,11 @@ config LOONGARCH
|
|||
select ARCH_HAS_FAST_MULTIPLIER
|
||||
select ARCH_HAS_FORTIFY_SOURCE
|
||||
select ARCH_HAS_KCOV
|
||||
select ARCH_HAS_KERNEL_FPU_SUPPORT if CPU_HAS_FPU
|
||||
select ARCH_HAS_KERNEL_FPU_SUPPORT if 64BIT && CPU_HAS_FPU
|
||||
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
|
||||
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
|
||||
select ARCH_HAS_PREEMPT_LAZY
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
select ARCH_HAS_PTE_SPECIAL if 64BIT
|
||||
select ARCH_HAS_SET_MEMORY
|
||||
select ARCH_HAS_SET_DIRECT_MAP
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
|
|
@ -59,16 +59,15 @@ config LOONGARCH
|
|||
select ARCH_KEEP_MEMBLOCK
|
||||
select ARCH_MIGHT_HAVE_PC_PARPORT
|
||||
select ARCH_MIGHT_HAVE_PC_SERIO
|
||||
select ARCH_SPARSEMEM_ENABLE
|
||||
select ARCH_STACKWALK
|
||||
select ARCH_SUPPORTS_ACPI
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||
select ARCH_SUPPORTS_HUGETLBFS
|
||||
select ARCH_SUPPORTS_HUGETLBFS if 64BIT
|
||||
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
|
||||
select ARCH_SUPPORTS_LTO_CLANG
|
||||
select ARCH_SUPPORTS_LTO_CLANG_THIN
|
||||
select ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS
|
||||
select ARCH_SUPPORTS_NUMA_BALANCING
|
||||
select ARCH_SUPPORTS_NUMA_BALANCING if NUMA
|
||||
select ARCH_SUPPORTS_PER_VMA_LOCK
|
||||
select ARCH_SUPPORTS_RT
|
||||
select ARCH_SUPPORTS_SCHED_SMT if SMP
|
||||
|
|
@ -78,10 +77,10 @@ config LOONGARCH
|
|||
select ARCH_USE_MEMTEST
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_USE_QUEUED_SPINLOCKS
|
||||
select ARCH_WANT_DEFAULT_BPF_JIT
|
||||
select ARCH_WANT_DEFAULT_BPF_JIT if HAVE_EBPF_JIT
|
||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
|
||||
select ARCH_WANT_LD_ORPHAN_WARN
|
||||
select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
|
||||
select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP if 64BIT
|
||||
select ARCH_WANTS_NO_INSTR
|
||||
select ARCH_WANTS_THP_SWAP if HAVE_ARCH_TRANSPARENT_HUGEPAGE
|
||||
select BUILDTIME_TABLE_SORT
|
||||
|
|
@ -89,13 +88,14 @@ config LOONGARCH
|
|||
select CPU_PM
|
||||
select EDAC_SUPPORT
|
||||
select EFI
|
||||
select GENERIC_ATOMIC64 if 32BIT
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_CMOS_UPDATE
|
||||
select GENERIC_CPU_AUTOPROBE
|
||||
select GENERIC_CPU_DEVICES
|
||||
select GENERIC_CPU_VULNERABILITIES
|
||||
select GENERIC_ENTRY
|
||||
select GENERIC_GETTIMEOFDAY
|
||||
select GENERIC_GETTIMEOFDAY if 64BIT
|
||||
select GENERIC_IOREMAP if !ARCH_IOREMAP
|
||||
select GENERIC_IRQ_MATRIX_ALLOCATOR
|
||||
select GENERIC_IRQ_MULTI_HANDLER
|
||||
|
|
@ -110,16 +110,16 @@ config LOONGARCH
|
|||
select GENERIC_PCI_IOMAP
|
||||
select GENERIC_SCHED_CLOCK
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select GENERIC_TIME_VSYSCALL
|
||||
select GENERIC_TIME_VSYSCALL if GENERIC_GETTIMEOFDAY
|
||||
select GPIOLIB
|
||||
select HAS_IOPORT
|
||||
select HAVE_ALIGNED_STRUCT_PAGE
|
||||
select HAVE_ALIGNED_STRUCT_PAGE if 64BIT
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_BITREVERSE
|
||||
select HAVE_ARCH_BITREVERSE if 64BIT
|
||||
select HAVE_ARCH_JUMP_LABEL
|
||||
select HAVE_ARCH_JUMP_LABEL_RELATIVE
|
||||
select HAVE_ARCH_KASAN
|
||||
select HAVE_ARCH_KFENCE
|
||||
select HAVE_ARCH_KASAN if 64BIT
|
||||
select HAVE_ARCH_KFENCE if 64BIT
|
||||
select HAVE_ARCH_KGDB if PERF_EVENTS
|
||||
select HAVE_ARCH_KSTACK_ERASE
|
||||
select HAVE_ARCH_MMAP_RND_BITS if MMU
|
||||
|
|
@ -127,8 +127,8 @@ config LOONGARCH
|
|||
select HAVE_ARCH_SECCOMP
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
|
||||
select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT
|
||||
select HAVE_ARCH_USERFAULTFD_MINOR if 64BIT && USERFAULTFD
|
||||
select HAVE_ASM_MODVERSIONS
|
||||
select HAVE_CMPXCHG_DOUBLE
|
||||
select HAVE_CMPXCHG_LOCAL
|
||||
|
|
@ -142,7 +142,7 @@ config LOONGARCH
|
|||
select HAVE_FTRACE_REGS_HAVING_PT_REGS
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_REGS
|
||||
select HAVE_EBPF_JIT
|
||||
select HAVE_EBPF_JIT if 64BIT
|
||||
select HAVE_EFFICIENT_UNALIGNED_ACCESS if !ARCH_STRICT_ALIGN
|
||||
select HAVE_EXIT_THREAD
|
||||
select HAVE_GENERIC_TIF_BITS
|
||||
|
|
@ -165,9 +165,9 @@ config LOONGARCH
|
|||
select HAVE_LIVEPATCH
|
||||
select HAVE_MOD_ARCH_SPECIFIC
|
||||
select HAVE_NMI
|
||||
select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB
|
||||
select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB && 64BIT
|
||||
select HAVE_PCI
|
||||
select HAVE_PERF_EVENTS
|
||||
select HAVE_PERF_EVENTS if 64BIT
|
||||
select HAVE_PERF_REGS
|
||||
select HAVE_PERF_USER_STACK_DUMP
|
||||
select HAVE_POSIX_CPU_TIMERS_TASK_WORK
|
||||
|
|
@ -209,18 +209,50 @@ config LOONGARCH
|
|||
select SYSCTL_ARCH_UNALIGN_ALLOW
|
||||
select SYSCTL_ARCH_UNALIGN_NO_WARN
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select SWIOTLB
|
||||
select SWIOTLB if 64BIT
|
||||
select TRACE_IRQFLAGS_SUPPORT
|
||||
select USE_PERCPU_NUMA_NODE_ID
|
||||
select USER_STACKTRACE_SUPPORT
|
||||
select VDSO_GETRANDOM
|
||||
select ZONE_DMA32
|
||||
select ZONE_DMA32 if 64BIT
|
||||
|
||||
menu "Kernel type and options"
|
||||
|
||||
choice
|
||||
prompt "Kernel type"
|
||||
|
||||
config 32BIT
|
||||
bool
|
||||
bool "32-bit kernel"
|
||||
help
|
||||
Select this option if you want to build a 32-bit kernel.
|
||||
|
||||
config 64BIT
|
||||
def_bool y
|
||||
bool "64-bit kernel"
|
||||
help
|
||||
Select this option if you want to build a 64-bit kernel.
|
||||
|
||||
endchoice
|
||||
|
||||
if 32BIT
|
||||
|
||||
choice
|
||||
prompt "32-bit kernel sub-type"
|
||||
|
||||
config 32BIT_REDUCED
|
||||
bool "32-bit kernel for LA32R"
|
||||
help
|
||||
Select this option if you want to build a 32-bit kernel for
|
||||
LoongArch32 Reduced (LA32R).
|
||||
|
||||
config 32BIT_STANDARD
|
||||
bool "32-bit kernel for LA32S"
|
||||
help
|
||||
Select this option if you want to build a 32-bit kernel for
|
||||
LoongArch32 Standard (LA32S).
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
||||
config GENERIC_BUG
|
||||
def_bool y
|
||||
|
|
@ -313,10 +345,13 @@ config RUSTC_HAS_ANNOTATE_TABLEJUMP
|
|||
depends on RUST
|
||||
def_bool $(rustc-option,-Cllvm-args=--loongarch-annotate-tablejump)
|
||||
|
||||
menu "Kernel type and options"
|
||||
|
||||
source "kernel/Kconfig.hz"
|
||||
|
||||
config HIGHMEM
|
||||
bool "High Memory Support"
|
||||
depends on 32BIT
|
||||
select KMAP_LOCAL
|
||||
|
||||
choice
|
||||
prompt "Page Table Layout"
|
||||
default 16KB_2LEVEL if 32BIT
|
||||
|
|
@ -326,8 +361,17 @@ choice
|
|||
of page size and page table levels. The size of virtual memory
|
||||
address space are determined by the page table layout.
|
||||
|
||||
config 4KB_2LEVEL
|
||||
bool "4KB with 2 levels"
|
||||
select HAVE_PAGE_SIZE_4KB
|
||||
select PGTABLE_2LEVEL
|
||||
help
|
||||
This option selects 4KB page size with 2 level page tables, which
|
||||
support a maximum of 32 bits of application virtual memory.
|
||||
|
||||
config 4KB_3LEVEL
|
||||
bool "4KB with 3 levels"
|
||||
depends on 64BIT
|
||||
select HAVE_PAGE_SIZE_4KB
|
||||
select PGTABLE_3LEVEL
|
||||
help
|
||||
|
|
@ -336,6 +380,7 @@ config 4KB_3LEVEL
|
|||
|
||||
config 4KB_4LEVEL
|
||||
bool "4KB with 4 levels"
|
||||
depends on 64BIT
|
||||
select HAVE_PAGE_SIZE_4KB
|
||||
select PGTABLE_4LEVEL
|
||||
help
|
||||
|
|
@ -352,6 +397,7 @@ config 16KB_2LEVEL
|
|||
|
||||
config 16KB_3LEVEL
|
||||
bool "16KB with 3 levels"
|
||||
depends on 64BIT
|
||||
select HAVE_PAGE_SIZE_16KB
|
||||
select PGTABLE_3LEVEL
|
||||
help
|
||||
|
|
@ -368,6 +414,7 @@ config 64KB_2LEVEL
|
|||
|
||||
config 64KB_3LEVEL
|
||||
bool "64KB with 3 levels"
|
||||
depends on 64BIT
|
||||
select HAVE_PAGE_SIZE_64KB
|
||||
select PGTABLE_3LEVEL
|
||||
help
|
||||
|
|
@ -465,6 +512,7 @@ config EFI_STUB
|
|||
|
||||
config SMP
|
||||
bool "Multi-Processing support"
|
||||
depends on 64BIT
|
||||
help
|
||||
This enables support for systems with more than one CPU. If you have
|
||||
a system with only one CPU, say N. If you have a system with more
|
||||
|
|
@ -503,6 +551,7 @@ config NR_CPUS
|
|||
config NUMA
|
||||
bool "NUMA Support"
|
||||
select SMP
|
||||
depends on 64BIT
|
||||
help
|
||||
Say Y to compile the kernel with NUMA (Non-Uniform Memory Access)
|
||||
support. This option improves performance on systems with more
|
||||
|
|
@ -585,7 +634,7 @@ config CPU_HAS_FPU
|
|||
|
||||
config CPU_HAS_LSX
|
||||
bool "Support for the Loongson SIMD Extension"
|
||||
depends on AS_HAS_LSX_EXTENSION
|
||||
depends on AS_HAS_LSX_EXTENSION && 64BIT
|
||||
help
|
||||
Loongson SIMD Extension (LSX) introduces 128 bit wide vector registers
|
||||
and a set of SIMD instructions to operate on them. When this option
|
||||
|
|
@ -600,7 +649,7 @@ config CPU_HAS_LSX
|
|||
config CPU_HAS_LASX
|
||||
bool "Support for the Loongson Advanced SIMD Extension"
|
||||
depends on CPU_HAS_LSX
|
||||
depends on AS_HAS_LASX_EXTENSION
|
||||
depends on AS_HAS_LASX_EXTENSION && 64BIT
|
||||
help
|
||||
Loongson Advanced SIMD Extension (LASX) introduces 256 bit wide vector
|
||||
registers and a set of SIMD instructions to operate on them. When this
|
||||
|
|
@ -614,7 +663,7 @@ config CPU_HAS_LASX
|
|||
|
||||
config CPU_HAS_LBT
|
||||
bool "Support for the Loongson Binary Translation Extension"
|
||||
depends on AS_HAS_LBT_EXTENSION
|
||||
depends on AS_HAS_LBT_EXTENSION && 64BIT
|
||||
help
|
||||
Loongson Binary Translation (LBT) introduces 4 scratch registers (SCR0
|
||||
to SCR3), x86/ARM eflags (eflags) and x87 fpu stack pointer (ftop).
|
||||
|
|
@ -642,13 +691,13 @@ config ARCH_SELECTS_KEXEC_FILE
|
|||
select HAVE_IMA_KEXEC if IMA
|
||||
|
||||
config ARCH_SUPPORTS_CRASH_DUMP
|
||||
def_bool y
|
||||
def_bool 64BIT
|
||||
|
||||
config ARCH_DEFAULT_CRASH_DUMP
|
||||
def_bool y
|
||||
def_bool 64BIT
|
||||
|
||||
config ARCH_SELECTS_CRASH_DUMP
|
||||
def_bool y
|
||||
def_bool 64BIT
|
||||
depends on CRASH_DUMP
|
||||
select RELOCATABLE
|
||||
|
||||
|
|
@ -657,6 +706,7 @@ config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
|
|||
|
||||
config RELOCATABLE
|
||||
bool "Relocatable kernel"
|
||||
depends on 64BIT
|
||||
select ARCH_HAS_RELR
|
||||
help
|
||||
This builds the kernel as a Position Independent Executable (PIE),
|
||||
|
|
@ -693,7 +743,7 @@ source "kernel/livepatch/Kconfig"
|
|||
|
||||
config PARAVIRT
|
||||
bool "Enable paravirtualization code"
|
||||
depends on AS_HAS_LVZ_EXTENSION
|
||||
depends on AS_HAS_LVZ_EXTENSION && 64BIT
|
||||
select HAVE_PV_STEAL_CLOCK_GEN
|
||||
help
|
||||
This changes the kernel so it can modify itself when it is run
|
||||
|
|
@ -722,7 +772,7 @@ config ARCH_FLATMEM_ENABLE
|
|||
depends on !NUMA
|
||||
|
||||
config ARCH_SPARSEMEM_ENABLE
|
||||
def_bool y
|
||||
def_bool 64BIT
|
||||
select SPARSEMEM_VMEMMAP_ENABLE
|
||||
help
|
||||
Say Y to support efficient handling of sparse physical memory,
|
||||
|
|
@ -739,10 +789,12 @@ config MMU
|
|||
default y
|
||||
|
||||
config ARCH_MMAP_RND_BITS_MIN
|
||||
default 12
|
||||
default 10 if 32BIT
|
||||
default 12 if 64BIT
|
||||
|
||||
config ARCH_MMAP_RND_BITS_MAX
|
||||
default 18
|
||||
default 15 if 32BIT
|
||||
default 20 if 64BIT
|
||||
|
||||
config ARCH_SUPPORTS_UPROBES
|
||||
def_bool y
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ endif
|
|||
#
|
||||
# Select the object file format to substitute into the linker script.
|
||||
#
|
||||
32bit-tool-archpref = loongarch32
|
||||
64bit-tool-archpref = loongarch64
|
||||
32bit-bfd = elf32-loongarch
|
||||
64bit-bfd = elf64-loongarch
|
||||
|
|
@ -51,7 +52,10 @@ KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
|
|||
CC_FLAGS_FTRACE := -fpatchable-function-entry=2
|
||||
endif
|
||||
|
||||
ifdef CONFIG_64BIT
|
||||
ifdef CONFIG_32BIT
|
||||
tool-archpref = $(32bit-tool-archpref)
|
||||
UTS_MACHINE := loongarch32
|
||||
else
|
||||
tool-archpref = $(64bit-tool-archpref)
|
||||
UTS_MACHINE := loongarch64
|
||||
endif
|
||||
|
|
@ -62,9 +66,19 @@ ifneq ($(SUBARCH),$(ARCH))
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_32BIT
|
||||
ifdef CONFIG_32BIT_STANDARD
|
||||
ld-emul = $(32bit-emul)
|
||||
cflags-y += -march=la32v1.0 -mabi=ilp32s -mcmodel=normal
|
||||
else # CONFIG_32BIT_REDUCED
|
||||
ld-emul = $(32bit-emul)
|
||||
cflags-y += -march=la32rv1.0 -mabi=ilp32s -mcmodel=normal
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_64BIT
|
||||
ld-emul = $(64bit-emul)
|
||||
cflags-y += -mabi=lp64s -mcmodel=normal
|
||||
cflags-y += -march=loongarch64 -mabi=lp64s -mcmodel=normal
|
||||
endif
|
||||
|
||||
cflags-y += -pipe $(CC_FLAGS_NO_FPU)
|
||||
|
|
@ -140,7 +154,12 @@ ifndef CONFIG_KASAN
|
|||
cflags-y += -fno-builtin-memcpy -fno-builtin-memmove -fno-builtin-memset
|
||||
endif
|
||||
|
||||
ifdef CONFIG_32BIT
|
||||
load-y = 0xa0200000
|
||||
else
|
||||
load-y = 0x9000000000200000
|
||||
endif
|
||||
|
||||
bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y)
|
||||
|
||||
drivers-$(CONFIG_PCI) += arch/loongarch/pci/
|
||||
|
|
|
|||
|
|
@ -20,7 +20,13 @@ $(obj)/vmlinux.efi: vmlinux FORCE
|
|||
$(call if_changed,objcopy)
|
||||
|
||||
EFI_ZBOOT_PAYLOAD := vmlinux.efi
|
||||
|
||||
ifdef CONFIG_32BIT
|
||||
EFI_ZBOOT_BFD_TARGET := elf32-loongarch
|
||||
EFI_ZBOOT_MACH_TYPE := LOONGARCH32
|
||||
else
|
||||
EFI_ZBOOT_BFD_TARGET := elf64-loongarch
|
||||
EFI_ZBOOT_MACH_TYPE := LOONGARCH64
|
||||
endif
|
||||
|
||||
include $(srctree)/drivers/firmware/efi/libstub/Makefile.zboot
|
||||
|
|
|
|||
|
|
@ -32,8 +32,22 @@ static inline unsigned int cpu_last_level_cache_line_size(void)
|
|||
}
|
||||
|
||||
asmlinkage void __flush_cache_all(void);
|
||||
void local_flush_icache_range(unsigned long start, unsigned long end);
|
||||
|
||||
/*
|
||||
* LoongArch maintains ICache/DCache coherency by hardware,
|
||||
* we just need "ibar" to avoid instruction hazard here.
|
||||
*/
|
||||
static inline void local_flush_icache_all(void)
|
||||
{
|
||||
asm volatile ("ibar\t0\n"::);
|
||||
}
|
||||
|
||||
static inline void local_flush_icache_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
asm volatile ("ibar\t0\n"::);
|
||||
}
|
||||
|
||||
#define flush_icache_all local_flush_icache_all
|
||||
#define flush_icache_range local_flush_icache_range
|
||||
#define flush_icache_user_range local_flush_icache_range
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
#define cpu_has_cpucfg cpu_opt(LOONGARCH_CPU_CPUCFG)
|
||||
#define cpu_has_lam cpu_opt(LOONGARCH_CPU_LAM)
|
||||
#define cpu_has_lam_bh cpu_opt(LOONGARCH_CPU_LAM_BH)
|
||||
#define cpu_has_scq cpu_opt(LOONGARCH_CPU_SCQ)
|
||||
#define cpu_has_ual cpu_opt(LOONGARCH_CPU_UAL)
|
||||
#define cpu_has_fpu cpu_opt(LOONGARCH_CPU_FPU)
|
||||
|
|
|
|||
|
|
@ -95,40 +95,42 @@ static inline char *id_to_core_name(unsigned int id)
|
|||
*/
|
||||
#define CPU_FEATURE_CPUCFG 0 /* CPU has CPUCFG */
|
||||
#define CPU_FEATURE_LAM 1 /* CPU has Atomic instructions */
|
||||
#define CPU_FEATURE_SCQ 2 /* CPU has SC.Q instruction */
|
||||
#define CPU_FEATURE_UAL 3 /* CPU supports unaligned access */
|
||||
#define CPU_FEATURE_FPU 4 /* CPU has FPU */
|
||||
#define CPU_FEATURE_LSX 5 /* CPU has LSX (128-bit SIMD) */
|
||||
#define CPU_FEATURE_LASX 6 /* CPU has LASX (256-bit SIMD) */
|
||||
#define CPU_FEATURE_CRC32 7 /* CPU has CRC32 instructions */
|
||||
#define CPU_FEATURE_COMPLEX 8 /* CPU has Complex instructions */
|
||||
#define CPU_FEATURE_CRYPTO 9 /* CPU has Crypto instructions */
|
||||
#define CPU_FEATURE_LVZ 10 /* CPU has Virtualization extension */
|
||||
#define CPU_FEATURE_LBT_X86 11 /* CPU has X86 Binary Translation */
|
||||
#define CPU_FEATURE_LBT_ARM 12 /* CPU has ARM Binary Translation */
|
||||
#define CPU_FEATURE_LBT_MIPS 13 /* CPU has MIPS Binary Translation */
|
||||
#define CPU_FEATURE_TLB 14 /* CPU has TLB */
|
||||
#define CPU_FEATURE_CSR 15 /* CPU has CSR */
|
||||
#define CPU_FEATURE_IOCSR 16 /* CPU has IOCSR */
|
||||
#define CPU_FEATURE_WATCH 17 /* CPU has watchpoint registers */
|
||||
#define CPU_FEATURE_VINT 18 /* CPU has vectored interrupts */
|
||||
#define CPU_FEATURE_CSRIPI 19 /* CPU has CSR-IPI */
|
||||
#define CPU_FEATURE_EXTIOI 20 /* CPU has EXT-IOI */
|
||||
#define CPU_FEATURE_PREFETCH 21 /* CPU has prefetch instructions */
|
||||
#define CPU_FEATURE_PMP 22 /* CPU has perfermance counter */
|
||||
#define CPU_FEATURE_SCALEFREQ 23 /* CPU supports cpufreq scaling */
|
||||
#define CPU_FEATURE_FLATMODE 24 /* CPU has flat mode */
|
||||
#define CPU_FEATURE_EIODECODE 25 /* CPU has EXTIOI interrupt pin decode mode */
|
||||
#define CPU_FEATURE_GUESTID 26 /* CPU has GuestID feature */
|
||||
#define CPU_FEATURE_HYPERVISOR 27 /* CPU has hypervisor (running in VM) */
|
||||
#define CPU_FEATURE_PTW 28 /* CPU has hardware page table walker */
|
||||
#define CPU_FEATURE_LSPW 29 /* CPU has LSPW (lddir/ldpte instructions) */
|
||||
#define CPU_FEATURE_MSGINT 30 /* CPU has MSG interrupt */
|
||||
#define CPU_FEATURE_AVECINT 31 /* CPU has AVEC interrupt */
|
||||
#define CPU_FEATURE_REDIRECTINT 32 /* CPU has interrupt remapping */
|
||||
#define CPU_FEATURE_LAM_BH 2 /* CPU has AM{SWAP/ADD}[_DB].{B/H} instructions */
|
||||
#define CPU_FEATURE_SCQ 3 /* CPU has SC.Q instruction */
|
||||
#define CPU_FEATURE_UAL 4 /* CPU supports unaligned access */
|
||||
#define CPU_FEATURE_FPU 5 /* CPU has FPU */
|
||||
#define CPU_FEATURE_LSX 6 /* CPU has LSX (128-bit SIMD) */
|
||||
#define CPU_FEATURE_LASX 7 /* CPU has LASX (256-bit SIMD) */
|
||||
#define CPU_FEATURE_CRC32 8 /* CPU has CRC32 instructions */
|
||||
#define CPU_FEATURE_COMPLEX 9 /* CPU has Complex instructions */
|
||||
#define CPU_FEATURE_CRYPTO 10 /* CPU has Crypto instructions */
|
||||
#define CPU_FEATURE_LVZ 11 /* CPU has Virtualization extension */
|
||||
#define CPU_FEATURE_LBT_X86 12 /* CPU has X86 Binary Translation */
|
||||
#define CPU_FEATURE_LBT_ARM 13 /* CPU has ARM Binary Translation */
|
||||
#define CPU_FEATURE_LBT_MIPS 14 /* CPU has MIPS Binary Translation */
|
||||
#define CPU_FEATURE_TLB 15 /* CPU has TLB */
|
||||
#define CPU_FEATURE_CSR 16 /* CPU has CSR */
|
||||
#define CPU_FEATURE_IOCSR 17 /* CPU has IOCSR */
|
||||
#define CPU_FEATURE_WATCH 18 /* CPU has watchpoint registers */
|
||||
#define CPU_FEATURE_VINT 19 /* CPU has vectored interrupts */
|
||||
#define CPU_FEATURE_CSRIPI 20 /* CPU has CSR-IPI */
|
||||
#define CPU_FEATURE_EXTIOI 21 /* CPU has EXT-IOI */
|
||||
#define CPU_FEATURE_PREFETCH 22 /* CPU has prefetch instructions */
|
||||
#define CPU_FEATURE_PMP 23 /* CPU has perfermance counter */
|
||||
#define CPU_FEATURE_SCALEFREQ 24 /* CPU supports cpufreq scaling */
|
||||
#define CPU_FEATURE_FLATMODE 25 /* CPU has flat mode */
|
||||
#define CPU_FEATURE_EIODECODE 26 /* CPU has EXTIOI interrupt pin decode mode */
|
||||
#define CPU_FEATURE_GUESTID 27 /* CPU has GuestID feature */
|
||||
#define CPU_FEATURE_HYPERVISOR 28 /* CPU has hypervisor (running in VM) */
|
||||
#define CPU_FEATURE_PTW 29 /* CPU has hardware page table walker */
|
||||
#define CPU_FEATURE_LSPW 30 /* CPU has LSPW (lddir/ldpte instructions) */
|
||||
#define CPU_FEATURE_MSGINT 31 /* CPU has MSG interrupt */
|
||||
#define CPU_FEATURE_AVECINT 32 /* CPU has AVEC interrupt */
|
||||
#define CPU_FEATURE_REDIRECTINT 33 /* CPU has interrupt remapping */
|
||||
|
||||
#define LOONGARCH_CPU_CPUCFG BIT_ULL(CPU_FEATURE_CPUCFG)
|
||||
#define LOONGARCH_CPU_LAM BIT_ULL(CPU_FEATURE_LAM)
|
||||
#define LOONGARCH_CPU_LAM_BH BIT_ULL(CPU_FEATURE_LAM_BH)
|
||||
#define LOONGARCH_CPU_SCQ BIT_ULL(CPU_FEATURE_SCQ)
|
||||
#define LOONGARCH_CPU_UAL BIT_ULL(CPU_FEATURE_UAL)
|
||||
#define LOONGARCH_CPU_FPU BIT_ULL(CPU_FEATURE_FPU)
|
||||
|
|
|
|||
|
|
@ -8,10 +8,19 @@
|
|||
#ifndef _ASM_FIXMAP_H
|
||||
#define _ASM_FIXMAP_H
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#include <linux/threads.h>
|
||||
#include <asm/kmap_size.h>
|
||||
#endif
|
||||
|
||||
#define NR_FIX_BTMAPS 64
|
||||
|
||||
enum fixed_addresses {
|
||||
FIX_HOLE,
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
FIX_KMAP_BEGIN,
|
||||
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
|
||||
#endif
|
||||
FIX_EARLYCON_MEM_BASE,
|
||||
__end_of_fixed_addresses
|
||||
};
|
||||
|
|
@ -25,4 +34,9 @@ extern void __set_fixmap(enum fixed_addresses idx,
|
|||
|
||||
#include <asm-generic/fixmap.h>
|
||||
|
||||
/*
|
||||
* Called from pagetable_init()
|
||||
*/
|
||||
extern void fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
43
arch/loongarch/include/asm/highmem.h
Normal file
43
arch/loongarch/include/asm/highmem.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* highmem.h: virtual kernel memory mappings for high memory
|
||||
*
|
||||
* Used in CONFIG_HIGHMEM systems for memory pages which
|
||||
* are not addressable by direct kernel virtual addresses.
|
||||
*
|
||||
* Copyright (C) 2025 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#ifndef _ASM_HIGHMEM_H
|
||||
#define _ASM_HIGHMEM_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/kmap_size.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
extern pte_t *pkmap_page_table;
|
||||
|
||||
#define ARCH_HAS_KMAP_FLUSH_TLB
|
||||
void kmap_flush_tlb(unsigned long addr);
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
/*
|
||||
* Right now we initialize only a single pte table. It can be extended
|
||||
* easily, subsequent pte tables have to be allocated in one physical
|
||||
* chunk of RAM.
|
||||
*/
|
||||
#define LAST_PKMAP 1024
|
||||
#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
|
||||
#define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT)
|
||||
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
|
||||
|
||||
#define flush_cache_kmaps() do {} while (0)
|
||||
|
||||
#define arch_kmap_local_post_map(vaddr, pteval) local_flush_tlb_one(vaddr)
|
||||
#define arch_kmap_local_post_unmap(vaddr) local_flush_tlb_one(vaddr)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ASM_HIGHMEM_H */
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
enum reg0i15_op {
|
||||
break_op = 0x54,
|
||||
dbar_op = 0x70e4,
|
||||
};
|
||||
|
||||
enum reg0i26_op {
|
||||
|
|
@ -194,6 +195,10 @@ enum reg3_op {
|
|||
fstxs_op = 0x7070,
|
||||
fstxd_op = 0x7078,
|
||||
scq_op = 0x70ae,
|
||||
amswapb_op = 0x70b8,
|
||||
amswaph_op = 0x70b9,
|
||||
amaddb_op = 0x70ba,
|
||||
amaddh_op = 0x70bb,
|
||||
amswapw_op = 0x70c0,
|
||||
amswapd_op = 0x70c1,
|
||||
amaddw_op = 0x70c2,
|
||||
|
|
@ -543,6 +548,7 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \
|
|||
}
|
||||
|
||||
DEF_EMIT_REG0I15_FORMAT(break, break_op)
|
||||
DEF_EMIT_REG0I15_FORMAT(dbar, dbar_op)
|
||||
|
||||
/* like emit_break(imm) but returns a constant expression */
|
||||
#define __emit_break(imm) ((u32)((imm) | (break_op << 15)))
|
||||
|
|
@ -763,6 +769,8 @@ DEF_EMIT_REG3_FORMAT(stxb, stxb_op)
|
|||
DEF_EMIT_REG3_FORMAT(stxh, stxh_op)
|
||||
DEF_EMIT_REG3_FORMAT(stxw, stxw_op)
|
||||
DEF_EMIT_REG3_FORMAT(stxd, stxd_op)
|
||||
DEF_EMIT_REG3_FORMAT(amaddb, amaddb_op)
|
||||
DEF_EMIT_REG3_FORMAT(amaddh, amaddh_op)
|
||||
DEF_EMIT_REG3_FORMAT(amaddw, amaddw_op)
|
||||
DEF_EMIT_REG3_FORMAT(amaddd, amaddd_op)
|
||||
DEF_EMIT_REG3_FORMAT(amandw, amandw_op)
|
||||
|
|
@ -771,6 +779,8 @@ DEF_EMIT_REG3_FORMAT(amorw, amorw_op)
|
|||
DEF_EMIT_REG3_FORMAT(amord, amord_op)
|
||||
DEF_EMIT_REG3_FORMAT(amxorw, amxorw_op)
|
||||
DEF_EMIT_REG3_FORMAT(amxord, amxord_op)
|
||||
DEF_EMIT_REG3_FORMAT(amswapb, amswapb_op)
|
||||
DEF_EMIT_REG3_FORMAT(amswaph, amswaph_op)
|
||||
DEF_EMIT_REG3_FORMAT(amswapw, amswapw_op)
|
||||
DEF_EMIT_REG3_FORMAT(amswapd, amswapd_op)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
static inline bool arch_irq_work_has_interrupt(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_SMP);
|
||||
return IS_ENABLED(CONFIG_SMP) && cpu_opt(LOONGARCH_CPU_CSRIPI);
|
||||
}
|
||||
|
||||
#endif /* _ASM_LOONGARCH_IRQ_WORK_H */
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#include <linux/stringify.h>
|
||||
#include <asm/asm.h>
|
||||
|
||||
#define HAVE_JUMP_LABEL_BATCH
|
||||
|
||||
#define JUMP_LABEL_NOP_SIZE 4
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
|
|
|
|||
|
|
@ -36,10 +36,6 @@ extern unsigned long shm_align_mask;
|
|||
|
||||
struct page;
|
||||
struct vm_area_struct;
|
||||
void copy_user_highpage(struct page *to, struct page *from,
|
||||
unsigned long vaddr, struct vm_area_struct *vma);
|
||||
|
||||
#define __HAVE_ARCH_COPY_USER_HIGHPAGE
|
||||
|
||||
typedef struct { unsigned long pte; } pte_t;
|
||||
#define pte_val(x) ((x).pte)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@
|
|||
#include <asm-generic/pgtable-nop4d.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#include <asm/highmem.h>
|
||||
#endif
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS == 2
|
||||
#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTRLOG))
|
||||
#elif CONFIG_PGTABLE_LEVELS == 3
|
||||
|
|
@ -77,7 +81,15 @@ struct vm_area_struct;
|
|||
#ifdef CONFIG_32BIT
|
||||
|
||||
#define VMALLOC_START (vm_map_base + PCI_IOSIZE + (2 * PAGE_SIZE))
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
#define VMALLOC_END (PKMAP_BASE - (2 * PAGE_SIZE))
|
||||
#else
|
||||
#define VMALLOC_END (FIXADDR_START - (2 * PAGE_SIZE))
|
||||
#endif
|
||||
|
||||
#define PKMAP_BASE (PKMAP_END - (PAGE_SIZE * LAST_PKMAP))
|
||||
#define PKMAP_END ((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -80,10 +80,10 @@ BUILD_FPR_ACCESS(32)
|
|||
BUILD_FPR_ACCESS(64)
|
||||
|
||||
struct loongarch_fpu {
|
||||
union fpureg fpr[NUM_FPU_REGS];
|
||||
uint64_t fcc; /* 8x8 */
|
||||
uint32_t fcsr;
|
||||
uint32_t ftop;
|
||||
union fpureg fpr[NUM_FPU_REGS];
|
||||
};
|
||||
|
||||
struct loongarch_lbt {
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@
|
|||
#ifndef _ASM_STACKPROTECTOR_H
|
||||
#define _ASM_STACKPROTECTOR_H
|
||||
|
||||
#include <linux/random.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
extern unsigned long __stack_chk_guard;
|
||||
|
||||
/*
|
||||
|
|
@ -25,11 +22,7 @@ extern unsigned long __stack_chk_guard;
|
|||
*/
|
||||
static __always_inline void boot_init_stack_canary(void)
|
||||
{
|
||||
unsigned long canary;
|
||||
|
||||
/* Try to get a semi random initial value. */
|
||||
get_random_bytes(&canary, sizeof(canary));
|
||||
canary ^= LINUX_VERSION_CODE;
|
||||
unsigned long canary = get_random_canary();
|
||||
|
||||
current->stack_canary = canary;
|
||||
__stack_chk_guard = current->stack_canary;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,11 @@ static inline void syscall_set_arguments(struct task_struct *task,
|
|||
|
||||
static inline int syscall_get_arch(struct task_struct *task)
|
||||
{
|
||||
#ifdef CONFIG_32BIT
|
||||
return AUDIT_ARCH_LOONGARCH32;
|
||||
#else
|
||||
return AUDIT_ARCH_LOONGARCH64;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
|
||||
|
|
|
|||
|
|
@ -19,5 +19,6 @@
|
|||
#define HWCAP_LOONGARCH_PTW (1 << 13)
|
||||
#define HWCAP_LOONGARCH_LSPW (1 << 14)
|
||||
#define HWCAP_LOONGARCH_SCQ (1 << 15)
|
||||
#define HWCAP_LOONGARCH_LAM_BH (1 << 16)
|
||||
|
||||
#endif /* _UAPI_ASM_HWCAP_H */
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/export.h>
|
||||
|
|
@ -177,6 +178,10 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
|
|||
c->options |= LOONGARCH_CPU_LAM;
|
||||
elf_hwcap |= HWCAP_LOONGARCH_LAM;
|
||||
}
|
||||
if (config & CPUCFG2_LAM_BH) {
|
||||
c->options |= LOONGARCH_CPU_LAM_BH;
|
||||
elf_hwcap |= HWCAP_LOONGARCH_LAM_BH;
|
||||
}
|
||||
if (config & CPUCFG2_SCQ) {
|
||||
c->options |= LOONGARCH_CPU_SCQ;
|
||||
elf_hwcap |= HWCAP_LOONGARCH_SCQ;
|
||||
|
|
@ -402,3 +407,9 @@ void cpu_probe(void)
|
|||
|
||||
cpu_report();
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spectre_v1(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "Mitigation: __user pointer sanitization\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@
|
|||
.endm
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
.macro sc_save_fcc thread tmp0 tmp1
|
||||
.macro sc_save_fcc base tmp0 tmp1
|
||||
movcf2gr \tmp0, $fcc0
|
||||
move \tmp1, \tmp0
|
||||
movcf2gr \tmp0, $fcc1
|
||||
|
|
@ -106,7 +106,7 @@
|
|||
bstrins.w \tmp1, \tmp0, 23, 16
|
||||
movcf2gr \tmp0, $fcc3
|
||||
bstrins.w \tmp1, \tmp0, 31, 24
|
||||
EX st.w \tmp1, \thread, THREAD_FCC
|
||||
EX st.w \tmp1, \base, 0
|
||||
movcf2gr \tmp0, $fcc4
|
||||
move \tmp1, \tmp0
|
||||
movcf2gr \tmp0, $fcc5
|
||||
|
|
@ -115,11 +115,11 @@
|
|||
bstrins.w \tmp1, \tmp0, 23, 16
|
||||
movcf2gr \tmp0, $fcc7
|
||||
bstrins.w \tmp1, \tmp0, 31, 24
|
||||
EX st.w \tmp1, \thread, (THREAD_FCC + 4)
|
||||
EX st.w \tmp1, \base, 4
|
||||
.endm
|
||||
|
||||
.macro sc_restore_fcc thread tmp0 tmp1
|
||||
EX ld.w \tmp0, \thread, THREAD_FCC
|
||||
.macro sc_restore_fcc base tmp0 tmp1
|
||||
EX ld.w \tmp0, \base, 0
|
||||
bstrpick.w \tmp1, \tmp0, 7, 0
|
||||
movgr2cf $fcc0, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 15, 8
|
||||
|
|
@ -128,7 +128,7 @@
|
|||
movgr2cf $fcc2, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 31, 24
|
||||
movgr2cf $fcc3, \tmp1
|
||||
EX ld.w \tmp0, \thread, (THREAD_FCC + 4)
|
||||
EX ld.w \tmp0, \base, 4
|
||||
bstrpick.w \tmp1, \tmp0, 7, 0
|
||||
movgr2cf $fcc4, \tmp1
|
||||
bstrpick.w \tmp1, \tmp0, 15, 8
|
||||
|
|
|
|||
|
|
@ -209,6 +209,9 @@ int larch_insn_write(void *addr, u32 insn)
|
|||
int ret;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if ((unsigned long)addr & 3)
|
||||
return -EINVAL;
|
||||
|
||||
raw_spin_lock_irqsave(&patch_lock, flags);
|
||||
ret = copy_to_kernel_nofault(addr, &insn, LOONGARCH_INSN_SIZE);
|
||||
raw_spin_unlock_irqrestore(&patch_lock, flags);
|
||||
|
|
@ -221,9 +224,6 @@ int larch_insn_patch_text(void *addr, u32 insn)
|
|||
int ret;
|
||||
u32 *tp = addr;
|
||||
|
||||
if ((unsigned long)tp & 3)
|
||||
return -EINVAL;
|
||||
|
||||
ret = larch_insn_write(tp, insn);
|
||||
if (!ret)
|
||||
flush_icache_range((unsigned long)tp,
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@
|
|||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/inst.h>
|
||||
|
||||
void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type)
|
||||
bool arch_jump_label_transform_queue(struct jump_entry *entry, enum jump_label_type type)
|
||||
{
|
||||
u32 insn;
|
||||
void *addr = (void *)jump_entry_code(entry);
|
||||
|
|
@ -18,5 +19,12 @@ void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type ty
|
|||
else
|
||||
insn = larch_insn_gen_nop();
|
||||
|
||||
larch_insn_patch_text(addr, insn);
|
||||
larch_insn_write(addr, insn);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void arch_jump_label_transform_apply(void)
|
||||
{
|
||||
flush_icache_all();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
|||
seq_puts(m, " cpucfg");
|
||||
if (cpu_has_lam)
|
||||
seq_puts(m, " lam");
|
||||
if (cpu_has_lam_bh)
|
||||
seq_puts(m, " lam_bh");
|
||||
if (cpu_has_scq)
|
||||
seq_puts(m, " scq");
|
||||
if (cpu_has_ual)
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
|
|||
return 0;
|
||||
}
|
||||
|
||||
dst->thread.fpu.fcsr = src->thread.fpu.fcsr;
|
||||
|
||||
if (!used_math())
|
||||
memcpy(dst, src, offsetof(struct task_struct, thread.fpu.fpr));
|
||||
else
|
||||
|
|
|
|||
|
|
@ -128,24 +128,28 @@ static inline __init unsigned long get_random_boot(void)
|
|||
|
||||
static int __init nokaslr(char *p)
|
||||
{
|
||||
pr_info("KASLR is disabled.\n");
|
||||
|
||||
return 0; /* Print a notice and silence the boot warning */
|
||||
return 0; /* Just silence the boot warning */
|
||||
}
|
||||
early_param("nokaslr", nokaslr);
|
||||
|
||||
#define KASLR_DISABLED_MESSAGE "KASLR is disabled by %s in %s cmdline.\n"
|
||||
|
||||
static inline __init bool kaslr_disabled(void)
|
||||
{
|
||||
char *str;
|
||||
const char *builtin_cmdline = CONFIG_CMDLINE;
|
||||
|
||||
str = strstr(builtin_cmdline, "nokaslr");
|
||||
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
|
||||
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' ')) {
|
||||
pr_info(KASLR_DISABLED_MESSAGE, "\'nokaslr\'", "built-in");
|
||||
return true;
|
||||
}
|
||||
|
||||
str = strstr(boot_command_line, "nokaslr");
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) {
|
||||
pr_info(KASLR_DISABLED_MESSAGE, "\'nokaslr\'", "bootloader");
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
str = strstr(builtin_cmdline, "nohibernate");
|
||||
|
|
@ -165,17 +169,23 @@ static inline __init bool kaslr_disabled(void)
|
|||
return false;
|
||||
|
||||
str = strstr(builtin_cmdline, "resume=");
|
||||
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
|
||||
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' ')) {
|
||||
pr_info(KASLR_DISABLED_MESSAGE, "\'resume=\'", "built-in");
|
||||
return true;
|
||||
}
|
||||
|
||||
str = strstr(boot_command_line, "resume=");
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) {
|
||||
pr_info(KASLR_DISABLED_MESSAGE, "\'resume=\'", "bootloader");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
str = strstr(boot_command_line, "kexec_file");
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) {
|
||||
pr_info(KASLR_DISABLED_MESSAGE, "\'kexec_file\'", "bootloader");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/entry-common.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/objtool.h>
|
||||
#include <linux/randomize_kstack.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
|
@ -74,7 +75,7 @@ void noinstr __no_stack_protector do_syscall(struct pt_regs *regs)
|
|||
add_random_kstack_offset();
|
||||
|
||||
if (nr < NR_syscalls) {
|
||||
syscall_fn = sys_call_table[nr];
|
||||
syscall_fn = sys_call_table[array_index_nospec(nr, NR_syscalls)];
|
||||
regs->regs[4] = syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6],
|
||||
regs->regs[7], regs->regs[8], regs->regs[9]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,12 @@
|
|||
|
||||
#define PAGE_SIZE _PAGE_SIZE
|
||||
#define RO_EXCEPTION_TABLE_ALIGN 4
|
||||
#define PHYSADDR_MASK 0xffffffffffff /* 48-bit */
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
#define PHYSADDR_MASK 0x1fffffff /* 29-bit */
|
||||
#else
|
||||
#define PHYSADDR_MASK 0xffffffffffff /* 48-bit */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Put .bss..swapper_pg_dir as the first thing in .bss. This will
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ if VIRTUALIZATION
|
|||
|
||||
config KVM
|
||||
tristate "Kernel-based Virtual Machine (KVM) support"
|
||||
depends on AS_HAS_LVZ_EXTENSION
|
||||
depends on AS_HAS_LVZ_EXTENSION && 64BIT
|
||||
select HAVE_KVM_DIRTY_RING_ACQ_REL
|
||||
select HAVE_KVM_IRQ_ROUTING
|
||||
select HAVE_KVM_IRQCHIP
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@
|
|||
# Makefile for LoongArch-specific library files.
|
||||
#
|
||||
|
||||
lib-y += delay.o memset.o memcpy.o memmove.o \
|
||||
clear_user.o copy_user.o csum.o dump_tlb.o unaligned.o
|
||||
lib-y += delay.o clear_user.o copy_user.o dump_tlb.o unaligned.o
|
||||
|
||||
lib-$(CONFIG_32BIT) += bswapsi.o bswapdi.o
|
||||
lib-$(CONFIG_64BIT) += memset.o memcpy.o memmove.o csum.o
|
||||
|
||||
obj-$(CONFIG_ARCH_SUPPORTS_INT128) += tishift.o
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ obj-y += init.o cache.o tlb.o tlbex.o extable.o \
|
|||
fault.o ioremap.o maccess.o mmap.o pgtable.o \
|
||||
page.o pageattr.o
|
||||
|
||||
obj-$(CONFIG_HIGHMEM) += highmem.o
|
||||
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
|
||||
obj-$(CONFIG_KASAN) += kasan_init.o
|
||||
|
||||
|
|
|
|||
|
|
@ -31,16 +31,6 @@ void cache_error_setup(void)
|
|||
set_merr_handler(0x0, &except_vec_cex, 0x80);
|
||||
}
|
||||
|
||||
/*
|
||||
* LoongArch maintains ICache/DCache coherency by hardware,
|
||||
* we just need "ibar" to avoid instruction hazard here.
|
||||
*/
|
||||
void local_flush_icache_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
asm volatile ("\tibar 0\n"::);
|
||||
}
|
||||
EXPORT_SYMBOL(local_flush_icache_range);
|
||||
|
||||
static void flush_cache_leaf(unsigned int leaf)
|
||||
{
|
||||
int i, j, nr_nodes;
|
||||
|
|
|
|||
12
arch/loongarch/mm/highmem.c
Normal file
12
arch/loongarch/mm/highmem.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
void kmap_flush_tlb(unsigned long addr)
|
||||
{
|
||||
flush_tlb_one(addr);
|
||||
}
|
||||
EXPORT_SYMBOL(kmap_flush_tlb);
|
||||
|
|
@ -36,20 +36,6 @@
|
|||
#include <asm/pgalloc.h>
|
||||
#include <asm/tlb.h>
|
||||
|
||||
void copy_user_highpage(struct page *to, struct page *from,
|
||||
unsigned long vaddr, struct vm_area_struct *vma)
|
||||
{
|
||||
void *vfrom, *vto;
|
||||
|
||||
vfrom = kmap_local_page(from);
|
||||
vto = kmap_local_page(to);
|
||||
copy_page(vto, vfrom);
|
||||
kunmap_local(vfrom);
|
||||
kunmap_local(vto);
|
||||
/* Make sure this page is cleared on other CPU's too before using it */
|
||||
smp_wmb();
|
||||
}
|
||||
|
||||
int __ref page_is_ram(unsigned long pfn)
|
||||
{
|
||||
unsigned long addr = PFN_PHYS(pfn);
|
||||
|
|
@ -63,6 +49,9 @@ void __init arch_zone_limits_init(unsigned long *max_zone_pfns)
|
|||
max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
|
||||
#endif
|
||||
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
max_zone_pfns[ZONE_HIGHMEM] = max_pfn;
|
||||
#endif
|
||||
}
|
||||
|
||||
void __ref free_initmem(void)
|
||||
|
|
@ -70,6 +59,50 @@ void __ref free_initmem(void)
|
|||
free_initmem_default(POISON_FREE_INITMEM);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
|
||||
void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
int i, j, k;
|
||||
int ptrs_per_pgd;
|
||||
unsigned long vaddr;
|
||||
|
||||
vaddr = start;
|
||||
i = pgd_index(vaddr);
|
||||
j = pud_index(vaddr);
|
||||
k = pmd_index(vaddr);
|
||||
pgd = pgd_base + i;
|
||||
ptrs_per_pgd = min((1 << (BITS_PER_LONG - PGDIR_SHIFT)), PTRS_PER_PGD);
|
||||
|
||||
for ( ; (i < ptrs_per_pgd) && (vaddr < end); pgd++, i++) {
|
||||
pud = (pud_t *)pgd;
|
||||
for ( ; (j < PTRS_PER_PUD) && (vaddr < end); pud++, j++) {
|
||||
pmd = (pmd_t *)pud;
|
||||
for (; (k < PTRS_PER_PMD) && (vaddr < end); pmd++, k++) {
|
||||
if (pmd_none(*pmd)) {
|
||||
pte = (pte_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
|
||||
if (!pte)
|
||||
panic("%s: Failed to allocate %lu bytes align=%lx\n",
|
||||
__func__, PAGE_SIZE, PAGE_SIZE);
|
||||
|
||||
kernel_pte_init(pte);
|
||||
set_pmd(pmd, __pmd((unsigned long)pte));
|
||||
BUG_ON(pte != pte_offset_kernel(pmd, 0));
|
||||
}
|
||||
vaddr += PMD_SIZE;
|
||||
}
|
||||
k = 0;
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
int arch_add_memory(int nid, u64 start, u64 size, struct mhp_params *params)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
|
@ -144,6 +145,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
|
|||
|
||||
void __init pagetable_init(void)
|
||||
{
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
unsigned long vaddr;
|
||||
pgd_t *pgd;
|
||||
p4d_t *p4d;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
#endif
|
||||
|
||||
/* Initialize the entire pgd. */
|
||||
pgd_init(swapper_pg_dir);
|
||||
pgd_init(invalid_pg_dir);
|
||||
|
|
@ -153,4 +163,21 @@ void __init pagetable_init(void)
|
|||
#ifndef __PAGETABLE_PMD_FOLDED
|
||||
pmd_init(invalid_pmd_table);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
/* Permanent kmaps */
|
||||
vaddr = PKMAP_BASE;
|
||||
fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE * LAST_PKMAP, swapper_pg_dir);
|
||||
|
||||
pgd = swapper_pg_dir + pgd_index(vaddr);
|
||||
p4d = p4d_offset(pgd, vaddr);
|
||||
pud = pud_offset(p4d, vaddr);
|
||||
pmd = pmd_offset(pud, vaddr);
|
||||
pte = pte_offset_kernel(pmd, vaddr);
|
||||
pkmap_page_table = pte;
|
||||
|
||||
/* Fixed mappings */
|
||||
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
|
||||
fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, swapper_pg_dir);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,7 +344,13 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int insn)
|
|||
#undef jmp_offset
|
||||
}
|
||||
|
||||
static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
||||
static void emit_store_stack_imm64(struct jit_ctx *ctx, int reg, int stack_off, u64 imm64)
|
||||
{
|
||||
move_imm(ctx, reg, imm64, false);
|
||||
emit_insn(ctx, std, reg, LOONGARCH_GPR_FP, stack_off);
|
||||
}
|
||||
|
||||
static int emit_atomic_rmw(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
||||
{
|
||||
const u8 t1 = LOONGARCH_GPR_T1;
|
||||
const u8 t2 = LOONGARCH_GPR_T2;
|
||||
|
|
@ -363,10 +369,28 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
switch (imm) {
|
||||
/* lock *(size *)(dst + off) <op>= src */
|
||||
case BPF_ADD:
|
||||
if (isdw)
|
||||
emit_insn(ctx, amaddd, t2, t1, src);
|
||||
else
|
||||
switch (BPF_SIZE(insn->code)) {
|
||||
case BPF_B:
|
||||
if (!cpu_has_lam_bh) {
|
||||
pr_err_once("bpf-jit: amadd.b instruction is not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
emit_insn(ctx, amaddb, t2, t1, src);
|
||||
break;
|
||||
case BPF_H:
|
||||
if (!cpu_has_lam_bh) {
|
||||
pr_err_once("bpf-jit: amadd.h instruction is not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
emit_insn(ctx, amaddh, t2, t1, src);
|
||||
break;
|
||||
case BPF_W:
|
||||
emit_insn(ctx, amaddw, t2, t1, src);
|
||||
break;
|
||||
case BPF_DW:
|
||||
emit_insn(ctx, amaddd, t2, t1, src);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BPF_AND:
|
||||
if (isdw)
|
||||
|
|
@ -388,11 +412,30 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
break;
|
||||
/* src = atomic_fetch_<op>(dst + off, src) */
|
||||
case BPF_ADD | BPF_FETCH:
|
||||
if (isdw) {
|
||||
emit_insn(ctx, amaddd, src, t1, t3);
|
||||
} else {
|
||||
switch (BPF_SIZE(insn->code)) {
|
||||
case BPF_B:
|
||||
if (!cpu_has_lam_bh) {
|
||||
pr_err_once("bpf-jit: amadd.b instruction is not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
emit_insn(ctx, amaddb, src, t1, t3);
|
||||
emit_zext_32(ctx, src, true);
|
||||
break;
|
||||
case BPF_H:
|
||||
if (!cpu_has_lam_bh) {
|
||||
pr_err_once("bpf-jit: amadd.h instruction is not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
emit_insn(ctx, amaddh, src, t1, t3);
|
||||
emit_zext_32(ctx, src, true);
|
||||
break;
|
||||
case BPF_W:
|
||||
emit_insn(ctx, amaddw, src, t1, t3);
|
||||
emit_zext_32(ctx, src, true);
|
||||
break;
|
||||
case BPF_DW:
|
||||
emit_insn(ctx, amaddd, src, t1, t3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BPF_AND | BPF_FETCH:
|
||||
|
|
@ -421,11 +464,30 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
break;
|
||||
/* src = atomic_xchg(dst + off, src); */
|
||||
case BPF_XCHG:
|
||||
if (isdw) {
|
||||
emit_insn(ctx, amswapd, src, t1, t3);
|
||||
} else {
|
||||
switch (BPF_SIZE(insn->code)) {
|
||||
case BPF_B:
|
||||
if (!cpu_has_lam_bh) {
|
||||
pr_err_once("bpf-jit: amswap.b instruction is not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
emit_insn(ctx, amswapb, src, t1, t3);
|
||||
emit_zext_32(ctx, src, true);
|
||||
break;
|
||||
case BPF_H:
|
||||
if (!cpu_has_lam_bh) {
|
||||
pr_err_once("bpf-jit: amswap.h instruction is not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
emit_insn(ctx, amswaph, src, t1, t3);
|
||||
emit_zext_32(ctx, src, true);
|
||||
break;
|
||||
case BPF_W:
|
||||
emit_insn(ctx, amswapw, src, t1, t3);
|
||||
emit_zext_32(ctx, src, true);
|
||||
break;
|
||||
case BPF_DW:
|
||||
emit_insn(ctx, amswapd, src, t1, t3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
/* r0 = atomic_cmpxchg(dst + off, r0, src); */
|
||||
|
|
@ -448,7 +510,105 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
emit_zext_32(ctx, r0, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err_once("bpf-jit: invalid atomic read-modify-write opcode %02x\n", imm);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int emit_atomic_ld_st(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
||||
{
|
||||
const u8 t1 = LOONGARCH_GPR_T1;
|
||||
const u8 src = regmap[insn->src_reg];
|
||||
const u8 dst = regmap[insn->dst_reg];
|
||||
const s16 off = insn->off;
|
||||
const s32 imm = insn->imm;
|
||||
|
||||
switch (imm) {
|
||||
/* dst_reg = load_acquire(src_reg + off16) */
|
||||
case BPF_LOAD_ACQ:
|
||||
switch (BPF_SIZE(insn->code)) {
|
||||
case BPF_B:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, ldbu, dst, src, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, false);
|
||||
emit_insn(ctx, ldxbu, dst, src, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_H:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, ldhu, dst, src, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, false);
|
||||
emit_insn(ctx, ldxhu, dst, src, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_W:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, ldwu, dst, src, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, false);
|
||||
emit_insn(ctx, ldxwu, dst, src, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_DW:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, ldd, dst, src, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, false);
|
||||
emit_insn(ctx, ldxd, dst, src, t1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
emit_insn(ctx, dbar, 0b10100);
|
||||
break;
|
||||
/* store_release(dst_reg + off16, src_reg) */
|
||||
case BPF_STORE_REL:
|
||||
emit_insn(ctx, dbar, 0b10010);
|
||||
switch (BPF_SIZE(insn->code)) {
|
||||
case BPF_B:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, stb, src, dst, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, false);
|
||||
emit_insn(ctx, stxb, src, dst, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_H:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, sth, src, dst, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, false);
|
||||
emit_insn(ctx, stxh, src, dst, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_W:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, stw, src, dst, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, false);
|
||||
emit_insn(ctx, stxw, src, dst, t1);
|
||||
}
|
||||
break;
|
||||
case BPF_DW:
|
||||
if (is_signed_imm12(off)) {
|
||||
emit_insn(ctx, std, src, dst, off);
|
||||
} else {
|
||||
move_imm(ctx, t1, off, false);
|
||||
emit_insn(ctx, stxd, src, dst, t1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err_once("bpf-jit: invalid atomic load/store opcode %02x\n", imm);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_signed_bpf_cond(u8 cond)
|
||||
|
|
@ -1254,9 +1414,17 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
|||
return ret;
|
||||
break;
|
||||
|
||||
/* Atomics */
|
||||
case BPF_STX | BPF_ATOMIC | BPF_B:
|
||||
case BPF_STX | BPF_ATOMIC | BPF_H:
|
||||
case BPF_STX | BPF_ATOMIC | BPF_W:
|
||||
case BPF_STX | BPF_ATOMIC | BPF_DW:
|
||||
emit_atomic(insn, ctx);
|
||||
if (!bpf_atomic_is_load_store(insn))
|
||||
ret = emit_atomic_rmw(insn, ctx);
|
||||
else
|
||||
ret = emit_atomic_ld_st(insn, ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
/* Speculation barrier */
|
||||
|
|
@ -1466,26 +1634,46 @@ int bpf_arch_text_invalidate(void *dst, size_t len)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void store_args(struct jit_ctx *ctx, int nargs, int args_off)
|
||||
static void store_args(struct jit_ctx *ctx, int nr_arg_slots, int args_off)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nargs; i++) {
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off);
|
||||
for (i = 0; i < nr_arg_slots; i++) {
|
||||
if (i < LOONGARCH_MAX_REG_ARGS)
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off);
|
||||
else {
|
||||
/* Skip slots for T0 and FP of traced function */
|
||||
emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP,
|
||||
16 + (i - LOONGARCH_MAX_REG_ARGS) * 8);
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -args_off);
|
||||
}
|
||||
args_off -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void restore_args(struct jit_ctx *ctx, int nargs, int args_off)
|
||||
static void restore_args(struct jit_ctx *ctx, int nr_reg_args, int args_off)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nargs; i++) {
|
||||
for (i = 0; i < nr_reg_args; i++) {
|
||||
emit_insn(ctx, ldd, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off);
|
||||
args_off -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void restore_stk_args(struct jit_ctx *ctx, int nr_stk_args, int args_off, int stk_args_off)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_stk_args; i++) {
|
||||
emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP,
|
||||
-(args_off - LOONGARCH_MAX_REG_ARGS * 8));
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -stk_args_off);
|
||||
args_off -= 8;
|
||||
stk_args_off -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
|
||||
int args_off, int retval_off, int run_ctx_off, bool save_ret)
|
||||
{
|
||||
|
|
@ -1494,12 +1682,11 @@ static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
|
|||
struct bpf_prog *p = l->link.prog;
|
||||
int cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie);
|
||||
|
||||
if (l->cookie) {
|
||||
move_imm(ctx, LOONGARCH_GPR_T1, l->cookie, false);
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -run_ctx_off + cookie_off);
|
||||
} else {
|
||||
if (l->cookie)
|
||||
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1,
|
||||
-run_ctx_off + cookie_off, l->cookie);
|
||||
else
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -run_ctx_off + cookie_off);
|
||||
}
|
||||
|
||||
/* arg1: prog */
|
||||
move_imm(ctx, LOONGARCH_GPR_A0, (const s64)p, false);
|
||||
|
|
@ -1550,18 +1737,27 @@ static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
|
||||
int args_off, int retval_off, int run_ctx_off, u32 **branches)
|
||||
static int invoke_bpf(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
|
||||
int args_off, int retval_off, int run_ctx_off,
|
||||
int func_meta_off, bool save_ret, u64 func_meta, int cookie_off)
|
||||
{
|
||||
int i;
|
||||
int i, cur_cookie = (cookie_off - args_off) / 8;
|
||||
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off);
|
||||
for (i = 0; i < tl->nr_links; i++) {
|
||||
invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off, run_ctx_off, true);
|
||||
emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -retval_off);
|
||||
branches[i] = (u32 *)ctx->image + ctx->idx;
|
||||
emit_insn(ctx, nop);
|
||||
int err;
|
||||
|
||||
if (bpf_prog_calls_session_cookie(tl->links[i])) {
|
||||
u64 meta = func_meta | ((u64)cur_cookie << BPF_TRAMP_COOKIE_INDEX_SHIFT);
|
||||
|
||||
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, meta);
|
||||
cur_cookie--;
|
||||
}
|
||||
err = invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off, run_ctx_off, save_ret);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *arch_alloc_bpf_trampoline(unsigned int size)
|
||||
|
|
@ -1615,8 +1811,10 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
void *func_addr, u32 flags)
|
||||
{
|
||||
int i, ret, save_ret;
|
||||
int stack_size, nargs;
|
||||
int retval_off, args_off, nargs_off, ip_off, run_ctx_off, sreg_off, tcc_ptr_off;
|
||||
int cookie_cnt, cookie_off;
|
||||
int stack_size, args_off, stk_args_off, nr_arg_slots = 0;
|
||||
int retval_off, func_meta_off, ip_off, run_ctx_off, sreg_off, tcc_ptr_off;
|
||||
unsigned long long func_meta;
|
||||
bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT;
|
||||
void *orig_call = func_addr;
|
||||
struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
|
||||
|
|
@ -1634,30 +1832,44 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
* FP - 16 [ FP of traced func ] frame pointer of traced
|
||||
* function
|
||||
*
|
||||
* FP - retval_off [ return value ] BPF_TRAMP_F_CALL_ORIG or
|
||||
* BPF_TRAMP_F_RET_FENTRY_RET
|
||||
* [ argN ]
|
||||
* [ ... ]
|
||||
* FP - args_off [ arg1 ]
|
||||
* FP - retval_off [ return value ] BPF_TRAMP_F_CALL_ORIG or
|
||||
* BPF_TRAMP_F_RET_FENTRY_RET
|
||||
* [ arg regN ]
|
||||
* [ ... ]
|
||||
* FP - args_off [ arg reg1 ]
|
||||
*
|
||||
* FP - nargs_off [ regs count ]
|
||||
* FP - func_meta_off [ regs count, etc ]
|
||||
*
|
||||
* FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG
|
||||
* FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG
|
||||
*
|
||||
* FP - run_ctx_off [ bpf_tramp_run_ctx ]
|
||||
* [ stack cookie N ]
|
||||
* [ ... ]
|
||||
* FP - cookie_off [ stack cookie 1 ]
|
||||
*
|
||||
* FP - sreg_off [ callee saved reg ]
|
||||
* FP - run_ctx_off [ bpf_tramp_run_ctx ]
|
||||
*
|
||||
* FP - tcc_ptr_off [ tail_call_cnt_ptr ]
|
||||
* FP - sreg_off [ callee saved reg ]
|
||||
*
|
||||
* FP - tcc_ptr_off [ tail_call_cnt_ptr ]
|
||||
*
|
||||
* [ stack_argN ]
|
||||
* [ ... ]
|
||||
* FP - stk_args_off [ stack_arg1 ] BPF_TRAMP_F_CALL_ORIG
|
||||
*/
|
||||
|
||||
if (m->nr_args > LOONGARCH_MAX_REG_ARGS)
|
||||
if (m->nr_args > MAX_BPF_FUNC_ARGS)
|
||||
return -ENOTSUPP;
|
||||
|
||||
/* FIXME: No support of struct argument */
|
||||
/* Extra registers for struct arguments */
|
||||
for (i = 0; i < m->nr_args; i++) {
|
||||
if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG)
|
||||
return -ENOTSUPP;
|
||||
/*
|
||||
* The struct argument size is at most 16 bytes,
|
||||
* enforced by the verifier. The struct argument
|
||||
* may be passed in a pair of registers if its
|
||||
* size is more than 8 bytes and no more than 16
|
||||
* bytes.
|
||||
*/
|
||||
nr_arg_slots += round_up(m->arg_size[i], 8) / 8;
|
||||
}
|
||||
|
||||
if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY))
|
||||
|
|
@ -1673,13 +1885,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
retval_off = stack_size;
|
||||
|
||||
/* Room of trampoline frame to store args */
|
||||
nargs = m->nr_args;
|
||||
stack_size += nargs * 8;
|
||||
stack_size += nr_arg_slots * 8;
|
||||
args_off = stack_size;
|
||||
|
||||
/* Room of trampoline frame to store args number */
|
||||
/* Room of function metadata, such as regs count */
|
||||
stack_size += 8;
|
||||
nargs_off = stack_size;
|
||||
func_meta_off = stack_size;
|
||||
|
||||
/* Room of trampoline frame to store ip address */
|
||||
if (flags & BPF_TRAMP_F_IP_ARG) {
|
||||
|
|
@ -1687,6 +1898,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
ip_off = stack_size;
|
||||
}
|
||||
|
||||
cookie_cnt = bpf_fsession_cookie_cnt(tlinks);
|
||||
|
||||
/* Room for session cookies */
|
||||
stack_size += cookie_cnt * 8;
|
||||
cookie_off = stack_size;
|
||||
|
||||
/* Room of trampoline frame to store struct bpf_tramp_run_ctx */
|
||||
stack_size += round_up(sizeof(struct bpf_tramp_run_ctx), 8);
|
||||
run_ctx_off = stack_size;
|
||||
|
|
@ -1700,8 +1917,14 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
tcc_ptr_off = stack_size;
|
||||
}
|
||||
|
||||
if ((flags & BPF_TRAMP_F_CALL_ORIG) && (nr_arg_slots - LOONGARCH_MAX_REG_ARGS > 0))
|
||||
stack_size += (nr_arg_slots - LOONGARCH_MAX_REG_ARGS) * 8;
|
||||
|
||||
stack_size = round_up(stack_size, 16);
|
||||
|
||||
/* Room for args on stack must be at the top of stack */
|
||||
stk_args_off = stack_size;
|
||||
|
||||
if (is_struct_ops) {
|
||||
/*
|
||||
* For the trampoline called directly, just handle
|
||||
|
|
@ -1737,17 +1960,24 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
emit_insn(ctx, std, LOONGARCH_GPR_S1, LOONGARCH_GPR_FP, -sreg_off);
|
||||
|
||||
/* store ip address of the traced function */
|
||||
if (flags & BPF_TRAMP_F_IP_ARG) {
|
||||
move_imm(ctx, LOONGARCH_GPR_T1, (const s64)func_addr, false);
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -ip_off);
|
||||
if (flags & BPF_TRAMP_F_IP_ARG)
|
||||
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -ip_off, (u64)func_addr);
|
||||
|
||||
/* store arg regs count */
|
||||
func_meta = nr_arg_slots;
|
||||
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
|
||||
|
||||
store_args(ctx, nr_arg_slots, args_off);
|
||||
|
||||
if (bpf_fsession_cnt(tlinks)) {
|
||||
/* clear all session cookies' value */
|
||||
for (i = 0; i < cookie_cnt; i++)
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -cookie_off + 8 * i);
|
||||
|
||||
/* clear return value to make sure fentry always get 0 */
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off);
|
||||
}
|
||||
|
||||
/* store nargs number */
|
||||
move_imm(ctx, LOONGARCH_GPR_T1, nargs, false);
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -nargs_off);
|
||||
|
||||
store_args(ctx, nargs, args_off);
|
||||
|
||||
/* To traced function */
|
||||
/* Ftrace jump skips 2 NOP instructions */
|
||||
if (is_kernel_text((unsigned long)orig_call) ||
|
||||
|
|
@ -1764,9 +1994,9 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < fentry->nr_links; i++) {
|
||||
ret = invoke_bpf_prog(ctx, fentry->links[i], args_off, retval_off,
|
||||
run_ctx_off, flags & BPF_TRAMP_F_RET_FENTRY_RET);
|
||||
if (fentry->nr_links) {
|
||||
ret = invoke_bpf(ctx, fentry, args_off, retval_off, run_ctx_off, func_meta_off,
|
||||
flags & BPF_TRAMP_F_RET_FENTRY_RET, func_meta, cookie_off);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1775,11 +2005,21 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
if (!branches)
|
||||
return -ENOMEM;
|
||||
|
||||
invoke_bpf_mod_ret(ctx, fmod_ret, args_off, retval_off, run_ctx_off, branches);
|
||||
emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off);
|
||||
for (i = 0; i < fmod_ret->nr_links; i++) {
|
||||
ret = invoke_bpf_prog(ctx, fmod_ret->links[i],
|
||||
args_off, retval_off, run_ctx_off, true);
|
||||
if (ret)
|
||||
goto out;
|
||||
emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -retval_off);
|
||||
branches[i] = (u32 *)ctx->image + ctx->idx;
|
||||
emit_insn(ctx, nop);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & BPF_TRAMP_F_CALL_ORIG) {
|
||||
restore_args(ctx, m->nr_args, args_off);
|
||||
restore_args(ctx, min_t(int, nr_arg_slots, LOONGARCH_MAX_REG_ARGS), args_off);
|
||||
restore_stk_args(ctx, nr_arg_slots - LOONGARCH_MAX_REG_ARGS, args_off, stk_args_off);
|
||||
|
||||
if (flags & BPF_TRAMP_F_TAIL_CALL_CTX)
|
||||
emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_FP, -tcc_ptr_off);
|
||||
|
|
@ -1800,8 +2040,14 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
*branches[i] = larch_insn_gen_bne(LOONGARCH_GPR_T1, LOONGARCH_GPR_ZERO, offset);
|
||||
}
|
||||
|
||||
for (i = 0; i < fexit->nr_links; i++) {
|
||||
ret = invoke_bpf_prog(ctx, fexit->links[i], args_off, retval_off, run_ctx_off, false);
|
||||
/* Set "is_return" flag for fsession */
|
||||
func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT);
|
||||
if (bpf_fsession_cnt(tlinks))
|
||||
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
|
||||
|
||||
if (fexit->nr_links) {
|
||||
ret = invoke_bpf(ctx, fexit, args_off, retval_off, run_ctx_off,
|
||||
func_meta_off, false, func_meta, cookie_off);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -1815,7 +2061,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
|
|||
}
|
||||
|
||||
if (flags & BPF_TRAMP_F_RESTORE_REGS)
|
||||
restore_args(ctx, m->nr_args, args_off);
|
||||
restore_args(ctx, min_t(int, nr_arg_slots, LOONGARCH_MAX_REG_ARGS), args_off);
|
||||
|
||||
if (save_ret) {
|
||||
emit_insn(ctx, ldd, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - 8));
|
||||
|
|
@ -2111,6 +2357,11 @@ bool bpf_jit_supports_arena(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool bpf_jit_supports_fsession(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
|
||||
bool bpf_jit_supports_subprog_tailcalls(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ zboot-obj-$(CONFIG_KERNEL_ZSTD) := zboot-decompress-zstd.o lib-xxhash.o
|
|||
CFLAGS_zboot-decompress-zstd.o += -I$(srctree)/lib/zstd
|
||||
|
||||
zboot-obj-$(CONFIG_RISCV) += lib-clz_ctz.o lib-ashldi3.o
|
||||
zboot-obj-$(CONFIG_LOONGARCH) += lib-clz_ctz.o lib-ashldi3.o
|
||||
lib-$(CONFIG_EFI_ZBOOT) += zboot.o $(zboot-obj-y)
|
||||
|
||||
lib-$(CONFIG_UNACCEPTED_MEMORY) += unaccepted_memory.o bitmap.o find.o
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ config VMD
|
|||
|
||||
config PCI_LOONGSON
|
||||
bool "LOONGSON PCIe controller"
|
||||
depends on MACH_LOONGSON64 || COMPILE_TEST
|
||||
depends on MACH_LOONGSON32 || MACH_LOONGSON64 || COMPILE_TEST
|
||||
depends on OF || ACPI
|
||||
depends on PCI_QUIRKS
|
||||
default MACH_LOONGSON64
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ config CRC32_ARCH
|
|||
depends on CRC32 && CRC_OPTIMIZATIONS
|
||||
default y if ARM && KERNEL_MODE_NEON
|
||||
default y if ARM64
|
||||
default y if LOONGARCH
|
||||
default y if LOONGARCH && 64BIT
|
||||
default y if MIPS && CPU_MIPSR6
|
||||
default y if PPC64 && ALTIVEC
|
||||
default y if RISCV && RISCV_ISA_ZBC
|
||||
|
|
|
|||
|
|
@ -263,8 +263,8 @@
|
|||
|
||||
#if __clang_major__ >= 18 && defined(ENABLE_ATOMICS_TESTS) && \
|
||||
(defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \
|
||||
(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) || \
|
||||
(defined(__TARGET_ARCH_powerpc))
|
||||
(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64) || \
|
||||
defined(__TARGET_ARCH_powerpc) || defined(__TARGET_ARCH_loongarch))
|
||||
#define CAN_USE_LOAD_ACQ_STORE_REL
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ __naked int bpf_end_to_be(void)
|
|||
|
||||
#if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \
|
||||
(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64) || \
|
||||
defined(__TARGET_ARCH_arm) || defined(__TARGET_ARCH_s390)) && \
|
||||
__clang_major__ >= 18
|
||||
defined(__TARGET_ARCH_arm) || defined(__TARGET_ARCH_s390) || \
|
||||
defined(__TARGET_ARCH_loongarch)) && __clang_major__ >= 18
|
||||
|
||||
SEC("?raw_tp")
|
||||
__success __log_level(2)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user