mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
LoongArch changes for v7.2
1, Add THREAD_INFO_IN_TASK implementation;
2, Add build salt to the vDSO;
3, Add some BPF JIT inline helpers;
4, Update DTS for I2C clocks and clock-frequency;
5, Some bug fixes and other small changes.
-----BEGIN PGP SIGNATURE-----
iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAmo+MBYWHGNoZW5odWFj
YWlAa2VybmVsLm9yZwAKCRAChivD8uImesGWD/9HygPT6/JFvFR2rijLaym9TNYi
+X8m0GTUJDrBGasDQ1rXSgUAkWKIQHEvx0Q947HYWhceiIrwbiZrgMStVapk40hd
/WsiuTHFaiVzjiiXf2bdTSr9uWHIon3P1EZ6zkmdRO4l2VsvAq2elMJXazIP7NUa
fTnTGAMPXvA/TinNXZqGq/Ny9c6gp63pVUgATcBpSUmYCNYGz6xx7OwSWyGV0ncq
Kfxm87nVq6wdyCgmrzfYSGze9vM0FxfFpzvZbX9vLOfGZBGaxzDcBjH9LRU09vyp
/9fNpacKT49yNOfLO3R3MHSPFSa5DCg8ph8CDfMnqPmP01SfZpC+zmlFWv23ojx5
4v47fyaRQu6ucKL2vxkIJfKO6l8bXgcuzVgZPGVt5q5yJ5O+7yhuamncrxUKk6Ol
KGpIEJM3iKbcHKr9GF0EUcgJkbA2J/pU/094snBU3HlkoHDVcp28XxlJmNtW+jY4
49dCTbX/5v+680uf/KTUyXJ4j3m9bxMOB6feE1uVaSJF1nx6f7WYHRg7A/1pXnWy
f2chgwR4eUeqZRpFlUhcLx4R+OOD2ORvvdM0qcNv4T7E8FD31JtFVD873R2iFEG8
AlKG4Ln3DUeJdhskXXmJRIDD5nZb9XZNYlnM4ghQLBas5dtSxsSPnzkSjJHirTjR
naFFT9xxRBQOBBTrjQ==
=EvQG
-----END PGP SIGNATURE-----
Merge tag 'loongarch-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch updates from Huacai Chen:
- Add THREAD_INFO_IN_TASK implementation
- Add build salt to the vDSO
- Add some BPF JIT inline helpers
- Update DTS for I2C clocks and clock-frequency
- Some bug fixes and other small changes
* tag 'loongarch-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
selftests/bpf: Test jited inline of bpf_get_smp_processor_id() for LoongArch
selftests/bpf: Test jited inline of bpf_get_current_task() for LoongArch
selftests/bpf: Add __arch_loongarch to limit test cases for LoongArch
selftests/bpf: Add get_preempt_count() support for LoongArch
LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K2000
LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K1000
LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K0500
LoongArch: BPF: Inline bpf_get_smp_processor_id() helper
LoongArch: BPF: Inline bpf_get_current_task/_btf() helpers
LoongArch: BPF: Fix off-by-one error in tail call
LoongArch: BPF: Fix outdated tail call comments
LoongArch: Add build salt to the vDSO
LoongArch: Fix nr passing in set_direct_map_valid_noflush()
LoongArch: Fix missing dirty page tracking in {pte,pmd}_wrprotect()
LoongArch: Move struct kimage forward declaration before use
LoongArch: Report dying CPU to RCU in stop_this_cpu()
LoongArch: Add PIO for early access before ACPI PCI root register
LoongArch: Add THREAD_INFO_IN_TASK implementation
This commit is contained in:
commit
51cb1aa125
|
|
@ -12,7 +12,7 @@
|
|||
| arm64: | ok |
|
||||
| csky: | TODO |
|
||||
| hexagon: | TODO |
|
||||
| loongarch: | TODO |
|
||||
| loongarch: | ok |
|
||||
| m68k: | TODO |
|
||||
| microblaze: | TODO |
|
||||
| mips: | TODO |
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ config LOONGARCH
|
|||
select SYSCTL_ARCH_UNALIGN_NO_WARN
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select SWIOTLB if 64BIT
|
||||
select THREAD_INFO_IN_TASK
|
||||
select TRACE_IRQFLAGS_SUPPORT
|
||||
select USE_PERCPU_NUMA_NODE_ID
|
||||
select USER_STACKTRACE_SUPPORT
|
||||
|
|
|
|||
|
|
@ -405,6 +405,8 @@ uart0: serial@1ff40800 {
|
|||
i2c0: i2c@1ff48000 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1ff48000 0x0 0x0800>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_APB_CLK>;
|
||||
interrupt-parent = <&eiointc>;
|
||||
interrupts = <14>;
|
||||
status = "disabled";
|
||||
|
|
@ -413,6 +415,8 @@ i2c0: i2c@1ff48000 {
|
|||
i2c@1ff48800 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1ff48800 0x0 0x0800>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_APB_CLK>;
|
||||
interrupt-parent = <&eiointc>;
|
||||
interrupts = <15>;
|
||||
status = "disabled";
|
||||
|
|
@ -421,6 +425,8 @@ i2c@1ff48800 {
|
|||
i2c@1ff49000 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1ff49000 0x0 0x0800>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_APB_CLK>;
|
||||
interrupt-parent = <&eiointc>;
|
||||
interrupts = <16>;
|
||||
status = "disabled";
|
||||
|
|
@ -429,6 +435,8 @@ i2c@1ff49000 {
|
|||
i2c@1ff49800 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1ff49800 0x0 0x0800>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_APB_CLK>;
|
||||
interrupt-parent = <&eiointc>;
|
||||
interrupts = <17>;
|
||||
status = "disabled";
|
||||
|
|
@ -437,6 +445,8 @@ i2c@1ff49800 {
|
|||
i2c@1ff4a000 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1ff4a000 0x0 0x0800>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_APB_CLK>;
|
||||
interrupt-parent = <&eiointc>;
|
||||
interrupts = <18>;
|
||||
status = "disabled";
|
||||
|
|
@ -445,6 +455,8 @@ i2c@1ff4a000 {
|
|||
i2c@1ff4a800 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1ff4a800 0x0 0x0800>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_APB_CLK>;
|
||||
interrupt-parent = <&eiointc>;
|
||||
interrupts = <19>;
|
||||
status = "disabled";
|
||||
|
|
|
|||
|
|
@ -311,6 +311,8 @@ uart0: serial@1fe20000 {
|
|||
i2c2: i2c@1fe21000 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1fe21000 0x0 0x8>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_APB_CLK>;
|
||||
interrupt-parent = <&liointc0>;
|
||||
interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
|
|
@ -319,6 +321,8 @@ i2c2: i2c@1fe21000 {
|
|||
i2c3: i2c@1fe21800 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1fe21800 0x0 0x8>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_APB_CLK>;
|
||||
interrupt-parent = <&liointc0>;
|
||||
interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
|
|
|
|||
|
|
@ -239,6 +239,8 @@ rtc0: rtc@100d0100 {
|
|||
i2c@1fe00120 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1fe00120 0x0 0x8>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_MISC_CLK>;
|
||||
interrupt-parent = <&liointc>;
|
||||
interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
|
|
@ -247,6 +249,8 @@ i2c@1fe00120 {
|
|||
i2c@1fe00130 {
|
||||
compatible = "loongson,ls2k-i2c";
|
||||
reg = <0x0 0x1fe00130 0x0 0x8>;
|
||||
clock-frequency = <100000>;
|
||||
clocks = <&clk LOONGSON2_MISC_CLK>;
|
||||
interrupt-parent = <&liointc>;
|
||||
interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ static inline bool acpi_has_cpu_in_madt(void)
|
|||
extern struct list_head acpi_wakeup_device_list;
|
||||
extern struct acpi_madt_core_pic acpi_core_pic[MAX_CORE_PIC];
|
||||
|
||||
extern void acpi_add_early_pio(void);
|
||||
extern void acpi_remove_early_pio(void);
|
||||
extern int __init parse_acpi_topology(void);
|
||||
|
||||
#endif /* !CONFIG_ACPI */
|
||||
|
|
|
|||
31
arch/loongarch/include/asm/current.h
Normal file
31
arch/loongarch/include/asm/current.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_LOONGARCH_CURRENT_H
|
||||
#define __ASM_LOONGARCH_CURRENT_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <asm/percpu.h>
|
||||
|
||||
struct task_struct;
|
||||
|
||||
DECLARE_PER_CPU(struct task_struct *, cpu_tasks);
|
||||
|
||||
register struct task_struct *current_thread_pointer __asm__("$tp");
|
||||
|
||||
static __always_inline struct task_struct *get_current(void)
|
||||
{
|
||||
return current_thread_pointer;
|
||||
}
|
||||
|
||||
#define current get_current()
|
||||
|
||||
static __always_inline void set_current(struct task_struct *task)
|
||||
{
|
||||
__this_cpu_write(cpu_tasks, task);
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* __ASM_LOONGARCH_CURRENT_H */
|
||||
|
|
@ -41,6 +41,8 @@ struct kimage_arch {
|
|||
unsigned long systable_ptr;
|
||||
};
|
||||
|
||||
struct kimage;
|
||||
|
||||
#ifdef CONFIG_KEXEC_FILE
|
||||
extern const struct kexec_file_ops kexec_efi_ops;
|
||||
extern const struct kexec_file_ops kexec_elf_ops;
|
||||
|
|
@ -59,7 +61,6 @@ typedef void (*do_kexec_t)(unsigned long efi_boot,
|
|||
unsigned long start_addr,
|
||||
unsigned long first_ind_entry);
|
||||
|
||||
struct kimage;
|
||||
extern const unsigned char relocate_new_kernel[];
|
||||
extern const size_t relocate_new_kernel_size;
|
||||
extern void kexec_reboot(void);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#ifndef __ASM_PERCPU_H
|
||||
#define __ASM_PERCPU_H
|
||||
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/loongarch.h>
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -429,6 +429,8 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
|
|||
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
{
|
||||
if (pte_val(pte) & _PAGE_DIRTY)
|
||||
pte_val(pte) |= _PAGE_MODIFIED;
|
||||
pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_DIRTY);
|
||||
return pte;
|
||||
}
|
||||
|
|
@ -535,6 +537,8 @@ static inline pmd_t pmd_mkwrite_novma(pmd_t pmd)
|
|||
|
||||
static inline pmd_t pmd_wrprotect(pmd_t pmd)
|
||||
{
|
||||
if (pmd_val(pmd) & _PAGE_DIRTY)
|
||||
pmd_val(pmd) |= _PAGE_MODIFIED;
|
||||
pmd_val(pmd) &= ~(_PAGE_WRITE | _PAGE_DIRTY);
|
||||
return pmd;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,8 +81,9 @@ extern int __cpu_logical_map[NR_CPUS];
|
|||
struct seq_file;
|
||||
|
||||
struct secondary_data {
|
||||
unsigned long task;
|
||||
unsigned long stack;
|
||||
unsigned long thread_info;
|
||||
unsigned long offset;
|
||||
};
|
||||
extern struct secondary_data cpuboot_data;
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@
|
|||
.cfi_rel_offset ra, PT_ERA
|
||||
.endif
|
||||
cfi_st tp, PT_R2, \docfi
|
||||
cfi_st u0, PT_R21, \docfi
|
||||
cfi_st fp, PT_R22, \docfi
|
||||
|
||||
/* Set thread_info if we're coming from user mode */
|
||||
|
|
@ -191,10 +192,13 @@
|
|||
andi t0, t0, 0x3 /* extract pplv bit */
|
||||
beqz t0, 9f
|
||||
|
||||
LONG_LI tp, ~_THREAD_MASK
|
||||
and tp, tp, sp
|
||||
cfi_st u0, PT_R21, \docfi
|
||||
csrrd u0, PERCPU_BASE_KS
|
||||
|
||||
la_abs t1, cpu_tasks
|
||||
#ifdef CONFIG_SMP
|
||||
LONG_ADD t1, t1, u0
|
||||
#endif
|
||||
LONG_L tp, t1, 0
|
||||
9:
|
||||
#ifdef CONFIG_KGDB
|
||||
li.w t0, CSR_CRMD_WE
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ struct task_struct;
|
|||
* __switch_to - switch execution of a task
|
||||
* @prev: The task previously executed.
|
||||
* @next: The task to begin executing.
|
||||
* @next_ti: task_thread_info(next).
|
||||
* @sched_ra: __schedule return address.
|
||||
* @sched_cfa: __schedule call frame address.
|
||||
*
|
||||
|
|
@ -23,8 +22,7 @@ struct task_struct;
|
|||
* the context of next. Returns prev.
|
||||
*/
|
||||
extern asmlinkage struct task_struct *__switch_to(struct task_struct *prev,
|
||||
struct task_struct *next, struct thread_info *next_ti,
|
||||
void *sched_ra, void *sched_cfa);
|
||||
struct task_struct *next, void *sched_ra, void *sched_cfa);
|
||||
|
||||
/*
|
||||
* For newly created kernel threads switch_to() will return to
|
||||
|
|
@ -37,7 +35,8 @@ do { \
|
|||
lose_fpu_inatomic(1, prev); \
|
||||
lose_lbt_inatomic(1, prev); \
|
||||
hw_breakpoint_thread_switch(next); \
|
||||
(last) = __switch_to(prev, next, task_thread_info(next), \
|
||||
set_current(next); \
|
||||
(last) = __switch_to(prev, next, \
|
||||
__builtin_return_address(0), __builtin_frame_address(0)); \
|
||||
} while (0)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
* must also be changed
|
||||
*/
|
||||
struct thread_info {
|
||||
struct task_struct *task; /* main task structure */
|
||||
unsigned long flags; /* low level flags */
|
||||
unsigned long tp_value; /* thread pointer */
|
||||
__u32 cpu; /* current CPU */
|
||||
|
|
@ -37,20 +36,11 @@ struct thread_info {
|
|||
*/
|
||||
#define INIT_THREAD_INFO(tsk) \
|
||||
{ \
|
||||
.task = &tsk, \
|
||||
.flags = _TIF_FIXADE, \
|
||||
.cpu = 0, \
|
||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||
}
|
||||
|
||||
/* How to get the thread information struct from C. */
|
||||
register struct thread_info *__current_thread_info __asm__("$tp");
|
||||
|
||||
static inline struct thread_info *current_thread_info(void)
|
||||
{
|
||||
return __current_thread_info;
|
||||
}
|
||||
|
||||
register unsigned long current_stack_pointer __asm__("$sp");
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/memblock.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/numa.h>
|
||||
#include <asm/loongson.h>
|
||||
|
|
@ -59,6 +60,33 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
|
|||
return ioremap_cache(phys, size);
|
||||
}
|
||||
|
||||
#define PIO_BASE (unsigned long)PCI_IOBASE
|
||||
#define PIO_SIZE ALIGN(ISA_IOSIZE, PAGE_SIZE)
|
||||
|
||||
static bool acpi_pio;
|
||||
|
||||
/* Add PIO for early access */
|
||||
void acpi_add_early_pio(void)
|
||||
{
|
||||
if (!acpi_disabled) {
|
||||
acpi_pio = true;
|
||||
vmap_page_range(PIO_BASE, PIO_BASE + PIO_SIZE,
|
||||
LOONGSON_LIO_BASE, pgprot_device(PAGE_KERNEL));
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove PIO for PCI register */
|
||||
void acpi_remove_early_pio(void)
|
||||
{
|
||||
if (!acpi_pio)
|
||||
return;
|
||||
|
||||
if (!acpi_disabled) {
|
||||
acpi_pio = false;
|
||||
vunmap_range(PIO_BASE, PIO_BASE + PIO_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int set_processor_mask(u32 id, u32 pass)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ static void __used output_task_defines(void)
|
|||
{
|
||||
COMMENT("LoongArch task_struct offsets.");
|
||||
OFFSET(TASK_STATE, task_struct, __state);
|
||||
OFFSET(TASK_THREAD_INFO, task_struct, stack);
|
||||
OFFSET(TASK_STACK, task_struct, stack);
|
||||
OFFSET(TASK_FLAGS, task_struct, flags);
|
||||
OFFSET(TASK_MM, task_struct, mm);
|
||||
OFFSET(TASK_PID, task_struct, pid);
|
||||
|
|
@ -84,7 +84,6 @@ static void __used output_task_defines(void)
|
|||
static void __used output_thread_info_defines(void)
|
||||
{
|
||||
COMMENT("LoongArch thread_info offsets.");
|
||||
OFFSET(TI_TASK, thread_info, task);
|
||||
OFFSET(TI_FLAGS, thread_info, flags);
|
||||
OFFSET(TI_TP_VALUE, thread_info, tp_value);
|
||||
OFFSET(TI_CPU, thread_info, cpu);
|
||||
|
|
@ -266,8 +265,9 @@ static void __used output_signal_defines(void)
|
|||
static void __used output_smpboot_defines(void)
|
||||
{
|
||||
COMMENT("Linux smp cpu boot offsets.");
|
||||
OFFSET(CPU_BOOT_TASK, secondary_data, task);
|
||||
OFFSET(CPU_BOOT_STACK, secondary_data, stack);
|
||||
OFFSET(CPU_BOOT_TINFO, secondary_data, thread_info);
|
||||
OFFSET(CPU_BOOT_OFFSET, secondary_data, offset);
|
||||
BLANK();
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -67,8 +67,11 @@ SYM_CODE_START(handle_syscall)
|
|||
#endif
|
||||
|
||||
move u0, t0
|
||||
LONG_LI tp, ~_THREAD_MASK
|
||||
and tp, tp, sp
|
||||
la_abs t1, cpu_tasks
|
||||
#ifdef CONFIG_SMP
|
||||
LONG_ADD t1, t1, u0
|
||||
#endif
|
||||
LONG_L tp, t1, 0
|
||||
|
||||
move a0, sp
|
||||
bl do_syscall
|
||||
|
|
|
|||
|
|
@ -74,10 +74,11 @@ SYM_CODE_START(kernel_entry) # kernel entry point
|
|||
/* GPR21 used for percpu base (runtime), initialized as 0 */
|
||||
move u0, zero
|
||||
|
||||
la.pcrel tp, init_thread_union
|
||||
/* Set the SP after an empty pt_regs. */
|
||||
PTR_LI sp, (_THREAD_SIZE - PT_SIZE)
|
||||
PTR_ADD sp, sp, tp
|
||||
la.pcrel tp, init_task
|
||||
la.pcrel t0, init_stack
|
||||
PTR_LI t1, _THREAD_SIZE
|
||||
PTR_ADD t0, t0, t1
|
||||
PTR_ADDI sp, t0, -PT_SIZE
|
||||
set_saved_sp sp, t0, t1
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
|
|
@ -86,8 +87,10 @@ SYM_CODE_START(kernel_entry) # kernel entry point
|
|||
|
||||
#ifdef CONFIG_RANDOMIZE_BASE
|
||||
/* Repoint the sp into the new kernel */
|
||||
PTR_LI sp, (_THREAD_SIZE - PT_SIZE)
|
||||
PTR_ADD sp, sp, tp
|
||||
LONG_LPTR t0, tp, TASK_STACK
|
||||
PTR_LI t1, _THREAD_SIZE
|
||||
PTR_ADD t0, t0, t1
|
||||
PTR_ADDI sp, t0, -PT_SIZE
|
||||
set_saved_sp sp, t0, t1
|
||||
|
||||
/* Jump to the new kernel: new_pc = current_pc + random_offset */
|
||||
|
|
@ -127,8 +130,9 @@ SYM_CODE_START(smpboot_entry)
|
|||
csrxchg t0, t1, LOONGARCH_CSR_IMPCTL1
|
||||
#endif
|
||||
la.pcrel t0, cpuboot_data
|
||||
ld.d tp, t0, CPU_BOOT_TASK
|
||||
ld.d sp, t0, CPU_BOOT_STACK
|
||||
ld.d tp, t0, CPU_BOOT_TINFO
|
||||
ld.d u0, t0, CPU_BOOT_OFFSET
|
||||
|
||||
bl start_secondary
|
||||
ASM_BUG()
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ unsigned long __stack_chk_guard __read_mostly;
|
|||
EXPORT_SYMBOL(__stack_chk_guard);
|
||||
#endif
|
||||
|
||||
DEFINE_PER_CPU(struct task_struct *, cpu_tasks);
|
||||
|
||||
/*
|
||||
* Idle related variables and functions
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ unsigned long __init relocate_kernel(void)
|
|||
reloc_offset += random_offset;
|
||||
|
||||
/* The current thread is now within the relocated kernel */
|
||||
__current_thread_info = RELOCATED_KASLR(__current_thread_info);
|
||||
current_thread_pointer = RELOCATED_KASLR(current_thread_pointer);
|
||||
|
||||
update_reloc_offset(&reloc_offset, random_offset);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -502,6 +502,8 @@ static __init int arch_reserve_pio_range(void)
|
|||
{
|
||||
struct device_node *np;
|
||||
|
||||
acpi_add_early_pio();
|
||||
|
||||
for_each_node_by_name(np, "isa") {
|
||||
struct of_range range;
|
||||
struct of_range_parser parser;
|
||||
|
|
@ -593,6 +595,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
{
|
||||
cpu_probe();
|
||||
unwind_init();
|
||||
set_current(current);
|
||||
|
||||
init_environ();
|
||||
efi_init();
|
||||
|
|
|
|||
|
|
@ -400,8 +400,9 @@ void loongson_boot_secondary(int cpu, struct task_struct *idle)
|
|||
pr_info("Booting CPU#%d...\n", cpu);
|
||||
|
||||
entry = __pa_symbol((unsigned long)&smpboot_entry);
|
||||
cpuboot_data.stack = (unsigned long)__KSTK_TOS(idle);
|
||||
cpuboot_data.thread_info = (unsigned long)task_thread_info(idle);
|
||||
cpuboot_data.task = (unsigned long)idle;
|
||||
cpuboot_data.stack = (unsigned long)task_pt_regs(idle);
|
||||
cpuboot_data.offset = per_cpu_offset(cpu);
|
||||
|
||||
csr_mail_send(entry, cpu_logical_map(cpu), 0);
|
||||
|
||||
|
|
@ -663,6 +664,7 @@ asmlinkage void start_secondary(void)
|
|||
set_my_cpu_offset(per_cpu_offset(cpu));
|
||||
|
||||
cpu_probe();
|
||||
set_current(current);
|
||||
constant_clockevent_init();
|
||||
loongson_init_secondary();
|
||||
|
||||
|
|
@ -705,6 +707,7 @@ static void stop_this_cpu(void *dummy)
|
|||
set_cpu_online(smp_processor_id(), false);
|
||||
calculate_cpu_foreign_map();
|
||||
local_irq_disable();
|
||||
rcutree_report_cpu_dead();
|
||||
while (true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/*
|
||||
* task_struct *__switch_to(task_struct *prev, task_struct *next,
|
||||
* struct thread_info *next_ti, void *sched_ra, void *sched_cfa)
|
||||
* void *sched_ra, void *sched_cfa)
|
||||
*/
|
||||
.align 5
|
||||
SYM_FUNC_START(__switch_to)
|
||||
|
|
@ -24,8 +24,8 @@ SYM_FUNC_START(__switch_to)
|
|||
LONG_SPTR t1, a0, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET)
|
||||
|
||||
cpu_save_nonscratch a0
|
||||
LONG_SPTR a3, a0, (THREAD_SCHED_RA - TASK_STRUCT_OFFSET)
|
||||
LONG_SPTR a4, a0, (THREAD_SCHED_CFA - TASK_STRUCT_OFFSET)
|
||||
LONG_SPTR a2, a0, (THREAD_SCHED_RA - TASK_STRUCT_OFFSET)
|
||||
LONG_SPTR a3, a0, (THREAD_SCHED_CFA - TASK_STRUCT_OFFSET)
|
||||
|
||||
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
|
||||
la t7, __stack_chk_guard
|
||||
|
|
@ -33,11 +33,12 @@ SYM_FUNC_START(__switch_to)
|
|||
LONG_SPTR t8, t7, 0
|
||||
#endif
|
||||
|
||||
move tp, a2
|
||||
move tp, a1
|
||||
cpu_restore_nonscratch a1
|
||||
|
||||
li.w t0, _THREAD_SIZE
|
||||
PTR_ADD t0, t0, tp
|
||||
LONG_LPTR t0, a1, (TASK_STACK - TASK_STRUCT_OFFSET)
|
||||
PTR_LI t1, _THREAD_SIZE
|
||||
PTR_ADD t0, t0, t1
|
||||
set_saved_sp t0, t1, t2
|
||||
|
||||
LONG_LPTR t1, a1, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET)
|
||||
|
|
@ -45,6 +46,7 @@ SYM_FUNC_START(__switch_to)
|
|||
|
||||
#ifdef CONFIG_32BIT
|
||||
PTR_ADDI a0, a0, -TASK_STRUCT_OFFSET
|
||||
PTR_ADDI tp, tp, -TASK_STRUCT_OFFSET
|
||||
#endif
|
||||
jr ra
|
||||
SYM_FUNC_END(__switch_to)
|
||||
|
|
|
|||
|
|
@ -107,6 +107,12 @@ static void show_stacktrace(struct task_struct *task,
|
|||
unsigned long stackdata;
|
||||
unsigned long *sp = (unsigned long *)regs->regs[3];
|
||||
|
||||
if (!task)
|
||||
task = current;
|
||||
|
||||
if (!try_get_task_stack(task))
|
||||
return;
|
||||
|
||||
printk("%sStack :", loglvl);
|
||||
i = 0;
|
||||
while ((unsigned long) sp & (PAGE_SIZE - 1)) {
|
||||
|
|
@ -129,6 +135,8 @@ static void show_stacktrace(struct task_struct *task,
|
|||
}
|
||||
pr_cont("\n");
|
||||
show_backtrace(task, regs, loglvl, user);
|
||||
|
||||
put_task_stack(task);
|
||||
}
|
||||
|
||||
void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
|
||||
|
|
|
|||
|
|
@ -234,5 +234,5 @@ int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid)
|
|||
clear = __pgprot(_PAGE_PRESENT | _PAGE_VALID);
|
||||
}
|
||||
|
||||
return __set_memory(addr, 1, set, clear);
|
||||
return __set_memory(addr, nr, set, clear);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,18 @@
|
|||
* Copyright (C) 2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#include <linux/memory.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include "bpf_jit.h"
|
||||
|
||||
#define LOONGARCH_MAX_REG_ARGS 8
|
||||
|
||||
#define LOONGARCH_SAVE_RA_NINSNS 1
|
||||
#define LOONGARCH_LONG_JUMP_NINSNS 5
|
||||
#define LOONGARCH_TCC_SLOT_NINSNS 1
|
||||
|
||||
#define LOONGARCH_PROLOGUE_SKIP_INSNS \
|
||||
(LOONGARCH_SAVE_RA_NINSNS + LOONGARCH_LONG_JUMP_NINSNS + LOONGARCH_TCC_SLOT_NINSNS)
|
||||
|
||||
#define LOONGARCH_LONG_JUMP_NBYTES (LOONGARCH_LONG_JUMP_NINSNS * 4)
|
||||
|
||||
#define LOONGARCH_FENTRY_NINSNS 2
|
||||
|
|
@ -143,8 +150,13 @@ static void build_prologue(struct jit_ctx *ctx)
|
|||
stack_adjust = round_up(stack_adjust, 16);
|
||||
stack_adjust += bpf_stack_adjust;
|
||||
|
||||
/*
|
||||
* Save the original return address to a temporary register to prevent
|
||||
* it from being overwritten, then reserve space for the long jump and
|
||||
* fentry trampoline slot for dynamically patching by ftrace at runtime.
|
||||
* These instructions are bypassed during a tail call invocation.
|
||||
*/
|
||||
move_reg(ctx, LOONGARCH_GPR_T0, LOONGARCH_GPR_RA);
|
||||
/* Reserve space for the move_imm + jirl instruction */
|
||||
for (i = 0; i < LOONGARCH_LONG_JUMP_NINSNS; i++)
|
||||
emit_insn(ctx, nop);
|
||||
|
||||
|
|
@ -253,10 +265,11 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call)
|
|||
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0);
|
||||
} else {
|
||||
/*
|
||||
* Call the next bpf prog and skip the first instruction
|
||||
* of TCC initialization.
|
||||
* Tail call to the next BPF program, passing offset in number
|
||||
* of instructions to jirl to bypass the initial setup slots.
|
||||
*/
|
||||
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 7);
|
||||
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO,
|
||||
LOONGARCH_GPR_T3, LOONGARCH_PROLOGUE_SKIP_INSNS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -312,12 +325,12 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int insn)
|
|||
*/
|
||||
emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_SP, tcc_ptr_off);
|
||||
emit_insn(ctx, ldd, t3, REG_TCC, 0);
|
||||
emit_insn(ctx, addid, t3, t3, 1);
|
||||
emit_insn(ctx, std, t3, REG_TCC, 0);
|
||||
emit_insn(ctx, addid, t2, LOONGARCH_GPR_ZERO, MAX_TAIL_CALL_CNT);
|
||||
if (emit_tailcall_jmp(ctx, BPF_JSGT, t3, t2, jmp_offset) < 0)
|
||||
if (emit_tailcall_jmp(ctx, BPF_JSGE, t3, t2, jmp_offset) < 0)
|
||||
goto toofar;
|
||||
|
||||
emit_insn(ctx, addid, t3, t3, 1);
|
||||
|
||||
/*
|
||||
* prog = array->ptrs[index];
|
||||
* if (!prog)
|
||||
|
|
@ -330,6 +343,8 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int insn)
|
|||
if (emit_tailcall_jmp(ctx, BPF_JEQ, t2, LOONGARCH_GPR_ZERO, jmp_offset) < 0)
|
||||
goto toofar;
|
||||
|
||||
emit_insn(ctx, std, t3, REG_TCC, 0);
|
||||
|
||||
/* goto *(prog->bpf_func + 4); */
|
||||
off = offsetof(struct bpf_prog, bpf_func);
|
||||
emit_insn(ctx, ldd, t3, t2, off);
|
||||
|
|
@ -1147,6 +1162,19 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
|
|||
|
||||
/* function call */
|
||||
case BPF_JMP | BPF_CALL:
|
||||
/* Implement helper call to bpf_get_current_task/_btf() inline */
|
||||
if (insn->src_reg == 0 && (insn->imm == BPF_FUNC_get_current_task ||
|
||||
insn->imm == BPF_FUNC_get_current_task_btf)) {
|
||||
move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_TP);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Implement helper call to bpf_get_smp_processor_id() inline */
|
||||
if (insn->src_reg == 0 && insn->imm == BPF_FUNC_get_smp_processor_id) {
|
||||
emit_insn(ctx, ldwu, regmap[BPF_REG_0], LOONGARCH_GPR_TP, TI_CPU);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
|
||||
&func_addr, &func_addr_fixed);
|
||||
if (ret < 0)
|
||||
|
|
@ -2367,3 +2395,15 @@ bool bpf_jit_supports_subprog_tailcalls(void)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bpf_jit_inlines_helper_call(s32 imm)
|
||||
{
|
||||
switch (imm) {
|
||||
case BPF_FUNC_get_current_task:
|
||||
case BPF_FUNC_get_current_task_btf:
|
||||
case BPF_FUNC_get_smp_processor_id:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ static int acpi_prepare_root_resources(struct acpi_pci_root_info *ci)
|
|||
struct resource_entry *entry, *tmp;
|
||||
struct acpi_device *device = ci->bridge;
|
||||
|
||||
acpi_remove_early_pio();
|
||||
|
||||
status = acpi_pci_probe_root_resources(ci);
|
||||
if (status > 0) {
|
||||
acpi_evaluate_integer(device->handle, "PCIH", NULL, &pci_h);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@
|
|||
|
||||
#include <asm/vdso/vdso.h>
|
||||
|
||||
#include <linux/build-salt.h>
|
||||
#include <linux/elfnote.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
ELFNOTE_START(Linux, 0, "a")
|
||||
.long LINUX_VERSION_CODE
|
||||
ELFNOTE_END
|
||||
|
||||
BUILD_SALT
|
||||
|
|
|
|||
|
|
@ -423,6 +423,8 @@ static inline int get_preempt_count(void)
|
|||
return bpf_get_current_task_btf()->thread_info.preempt_count;
|
||||
#elif defined(bpf_target_s390)
|
||||
return bpf_get_lowcore()->preempt_count;
|
||||
#elif defined(bpf_target_loongarch)
|
||||
return bpf_get_current_task_btf()->thread_info.preempt_count;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -433,6 +435,7 @@ static inline int get_preempt_count(void)
|
|||
* * arm64
|
||||
* * powerpc64
|
||||
* * s390x
|
||||
* * loongarch
|
||||
*/
|
||||
static inline int bpf_in_interrupt(void)
|
||||
{
|
||||
|
|
@ -454,6 +457,7 @@ static inline int bpf_in_interrupt(void)
|
|||
* * arm64
|
||||
* * powerpc64
|
||||
* * s390x
|
||||
* * loongarch
|
||||
*/
|
||||
static inline int bpf_in_nmi(void)
|
||||
{
|
||||
|
|
@ -466,6 +470,7 @@ static inline int bpf_in_nmi(void)
|
|||
* * arm64
|
||||
* * powerpc64
|
||||
* * s390x
|
||||
* * loongarch
|
||||
*/
|
||||
static inline int bpf_in_hardirq(void)
|
||||
{
|
||||
|
|
@ -478,6 +483,7 @@ static inline int bpf_in_hardirq(void)
|
|||
* * arm64
|
||||
* * powerpc64
|
||||
* * s390x
|
||||
* * loongarch
|
||||
*/
|
||||
static inline int bpf_in_serving_softirq(void)
|
||||
{
|
||||
|
|
@ -498,6 +504,7 @@ static inline int bpf_in_serving_softirq(void)
|
|||
* * arm64
|
||||
* * powerpc64
|
||||
* * s390x
|
||||
* * loongarch
|
||||
*/
|
||||
static inline int bpf_in_task(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@
|
|||
#define __arch_arm64 __arch("ARM64")
|
||||
#define __arch_riscv64 __arch("RISCV64")
|
||||
#define __arch_s390x __arch("s390x")
|
||||
#define __arch_loongarch __arch("LOONGARCH")
|
||||
#define __caps_unpriv(caps) __test_tag("test_caps_unpriv=" EXPAND_QUOTE(caps))
|
||||
#define __load_if_JITed() __test_tag("load_mode=jited")
|
||||
#define __load_if_no_JITed() __test_tag("load_mode=no_jited")
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ __arch_arm64
|
|||
__jited(" mrs x8, SP_EL0")
|
||||
__arch_riscv64
|
||||
__jited(" mv a5, tp")
|
||||
__arch_loongarch
|
||||
__jited(" move $a5, $tp")
|
||||
int inline_bpf_get_current_task(void)
|
||||
{
|
||||
bpf_get_current_task();
|
||||
|
|
@ -19,4 +21,15 @@ int inline_bpf_get_current_task(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SEC("fentry/bpf_fentry_test2")
|
||||
__success __retval(0)
|
||||
__arch_loongarch
|
||||
__jited(" ld.wu $a5, $tp, 16")
|
||||
int inline_bpf_get_smp_processor_id(void)
|
||||
{
|
||||
bpf_get_smp_processor_id();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
|
|
|||
|
|
@ -377,6 +377,7 @@ enum arch {
|
|||
ARCH_ARM64 = 0x4,
|
||||
ARCH_RISCV64 = 0x8,
|
||||
ARCH_S390X = 0x10,
|
||||
ARCH_LOONGARCH = 0x20,
|
||||
};
|
||||
|
||||
static int get_current_arch(void)
|
||||
|
|
@ -389,6 +390,8 @@ static int get_current_arch(void)
|
|||
return ARCH_RISCV64;
|
||||
#elif defined(__s390x__)
|
||||
return ARCH_S390X;
|
||||
#elif defined(__loongarch__)
|
||||
return ARCH_LOONGARCH;
|
||||
#endif
|
||||
return ARCH_UNKNOWN;
|
||||
}
|
||||
|
|
@ -580,6 +583,8 @@ static int parse_test_spec(struct test_loader *tester,
|
|||
arch = ARCH_RISCV64;
|
||||
} else if (strcmp(val, "s390x") == 0) {
|
||||
arch = ARCH_S390X;
|
||||
} else if (strcmp(val, "LOONGARCH") == 0) {
|
||||
arch = ARCH_LOONGARCH;
|
||||
} else {
|
||||
PRINT_FAIL("bad arch spec: '%s'\n", val);
|
||||
err = -EINVAL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user