diff --git a/arch/sw_64/Kconfig b/arch/sw_64/Kconfig index ca5f37673985115b661adf2259b2e5807d0d4891..bcad24f568d03bd622e6a7ee0f021cbe4a39053e 100644 --- a/arch/sw_64/Kconfig +++ b/arch/sw_64/Kconfig @@ -94,6 +94,7 @@ config SW64 select HAVE_C_RECORDMCOUNT select HAVE_DEBUG_BUGVERBOSE select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_ARGS select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_EBPF_JIT @@ -147,6 +148,7 @@ config SW64 select SW64_TIMER select SWIOTLB select THREAD_INFO_IN_TASK + select CRYPTO_CRC32_SW64 if !SUBARCH_C3B config LOCKDEP_SUPPORT def_bool y diff --git a/arch/sw_64/Makefile b/arch/sw_64/Makefile index 41b90403ee3c68941ea1a0ccbe70f7580a53eff0..c2d3e332f9225dc168197feea1c5f8d8ffa50057 100644 --- a/arch/sw_64/Makefile +++ b/arch/sw_64/Makefile @@ -42,6 +42,7 @@ head-y := arch/sw_64/kernel/head.o core-y += arch/sw_64/ drivers-$(CONFIG_PCI) += arch/sw_64/pci/ libs-y += arch/sw_64/lib/ +drivers-y += arch/sw_64/crypto/ # export what is needed by arch/sw_64/boot/Makefile LIBS_Y := $(patsubst %/, %/lib.a, $(libs-y)) diff --git a/arch/sw_64/crypto/Kconfig b/arch/sw_64/crypto/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..00d2e92be32445130449baac4ba77b9236da329f --- /dev/null +++ b/arch/sw_64/crypto/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 + +menu "Accelerated Cryptographic Algorithms for CPU (SW64)" + +config CRYPTO_CRC32_SW64 + tristate "CRC32c and CRC32" + depends on SW64 && !SUBARCH_C3B + select CRC32 + select CRYPTO_HASH + help + CRC32c and CRC32 CRC algorithms + + Architecture: SW64 with CRC32 instructions + +endmenu diff --git a/arch/sw_64/crypto/Makefile b/arch/sw_64/crypto/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ed00a8978d1a196a650c5853ef1660cc42c0501e --- /dev/null +++ b/arch/sw_64/crypto/Makefile @@ -0,0 +1 @@ +lib-$(CONFIG_CRYPTO_CRC32_SW64) += crc32.o crc32c.o diff --git a/arch/sw_64/crypto/crc32.S b/arch/sw_64/crypto/crc32.S new file mode 100644 index 0000000000000000000000000000000000000000..2daf961208bd72a7979375a22fc0885dbc1bc12b --- /dev/null +++ b/arch/sw_64/crypto/crc32.S @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#define CRC32OP_L(x, y, z) crc32l x, y, z +#define CRC32OP_W(x, y, z) crc32w x, y, z +#define CRC32OP_H(x, y, z) crc32h x, y, z +#define CRC32OP_B(x, y, z) crc32b x, y, z + + .text + .global crc32_le + .align 4 + .ent crc32_le +crc32_le: + .prologue 0 +#include "crc32_template.S" + .end crc32_le + +#undef CRC32OP_L +#undef CRC32OP_W +#undef CRC32OP_H +#undef CRC32OP_B diff --git a/arch/sw_64/crypto/crc32_template.S b/arch/sw_64/crypto/crc32_template.S new file mode 100644 index 0000000000000000000000000000000000000000..56e56ac42014be36ff64bf822c20c67ef3eca2e7 --- /dev/null +++ b/arch/sw_64/crypto/crc32_template.S @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * $16: crc + * $17: buf + * $18: len + */ + + beq $18, $return_crc + srl $18, 4, $19 + beq $19, $check_8B + + .align 4 +$loop_16B: + ldl_a $1, 8($17) + ldl_a $2, 8($17) + CRC32OP_L($16, $1, $16) + CRC32OP_L($16, $2, $16) + subl $19, 1, $19 + bne $19, $loop_16B + +$check_8B: + and $18, 8, $3 + beq $3, $check_4B + ldl_a $1, 8($17) + CRC32OP_L($16, $1, $16) +$check_4B: + and $18, 4, $3 + beq $3, $check_2B + ldw_a $1, 4($17) + CRC32OP_W($16, $1, $16) +$check_2B: + and $18, 2, $3 + beq $3, $check_1B + ldhu_a $1, 2($17) + CRC32OP_H($16, $1, $16) +$check_1B: + and $18, 1, $3 + beq $3, $return_crc + ldbu_a $1, 1($17) + CRC32OP_B($16, $1, $16) + +$return_crc: + mov $16, $0 + ret diff --git a/arch/sw_64/crypto/crc32c.S b/arch/sw_64/crypto/crc32c.S new file mode 100644 index 0000000000000000000000000000000000000000..1005bc113ebb9a6bbf2dc991f9de621171ffb591 --- /dev/null +++ b/arch/sw_64/crypto/crc32c.S @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#define CRC32OP_L(x, y, z) crc32cl x, y, z +#define CRC32OP_W(x, y, z) crc32cw x, y, z +#define CRC32OP_H(x, y, z) crc32ch x, y, z +#define CRC32OP_B(x, y, z) crc32cb x, y, z + + .text + .global __crc32c_le + .align 4 + .ent __crc32c_le +__crc32c_le: + .prologue 0 +#include "crc32_template.S" + .end __crc32c_le + +#undef CRC32OP_L +#undef CRC32OP_W +#undef CRC32OP_H +#undef CRC32OP_B diff --git a/arch/sw_64/include/asm/efi.h b/arch/sw_64/include/asm/efi.h index ef2eda461f947b4bd4a3b435e7c1998702efa9ad..f2a470127c473344977d68153bf2747588316470 100644 --- a/arch/sw_64/include/asm/efi.h +++ b/arch/sw_64/include/asm/efi.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ + #ifndef _ASM_SW64_EFI_H #define _ASM_SW64_EFI_H -#include #include #ifdef CONFIG_EFI @@ -28,14 +28,4 @@ extern unsigned long sunway_bios_version; /* arch specific definitions used by the stub code */ -/* - * AArch64 requires the DTB to be 8-byte aligned in the first 512MiB from - * start of kernel and may not cross a 2MiB boundary. We set alignment to - * 2MiB so we know it won't cross a 2MiB boundary. - */ -#define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ -#define MAX_FDT_OFFSET SZ_512M - -#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) - #endif /* _ASM_SW64_EFI_H */ diff --git a/arch/sw_64/include/asm/ftrace.h b/arch/sw_64/include/asm/ftrace.h index 33122cd7f91b762f894e53e4a55e97e8de0c2563..eb1b05186705215dd2660e8937c928d18df7b807 100644 --- a/arch/sw_64/include/asm/ftrace.h +++ b/arch/sw_64/include/asm/ftrace.h @@ -46,6 +46,70 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) return addr; } +#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS +struct ftrace_ops; + +struct ftrace_regs { + struct pt_regs regs; +}; + +static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) +{ + return &fregs->regs; +} + +static __always_inline unsigned long +ftrace_regs_get_instruction_pointer(const struct ftrace_regs *fregs) +{ + return fregs->regs.regs[28]; +} + + static __always_inline void +ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs, unsigned long ip) +{ + fregs->regs.regs[27] = ip; + fregs->regs.regs[28] = ip; +} + +static __always_inline unsigned long +ftrace_regs_get_stack_pointer(const struct ftrace_regs *fregs) +{ + return fregs->regs.regs[30]; +} + +static __always_inline unsigned long +ftrace_regs_get_argument(struct ftrace_regs *fregs, unsigned int n) +{ + if (n < 6) + return fregs->regs.regs[16+n]; + return 0; +} + +static __always_inline unsigned long +ftrace_regs_get_return_value(const struct ftrace_regs *fregs) +{ + return fregs->regs.regs[0]; +} + +static __always_inline void +ftrace_regs_set_return_value(struct ftrace_regs *fregs, unsigned long ret) +{ + fregs->regs.regs[0] = ret; +} + +static __always_inline void +ftrace_override_function_with_return(struct ftrace_regs *fregs) +{ + fregs->regs.regs[27] = fregs->regs.regs[26]; + fregs->regs.regs[28] = fregs->regs.regs[26]; +} + +int ftrace_regs_query_register_offset(const char *name); + +#define ftrace_graph_func ftrace_graph_func +void ftrace_graph_func(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *op, struct ftrace_regs *fregs); + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS static inline void __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr) @@ -57,6 +121,8 @@ __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr) __arch_ftrace_set_direct_caller(&(fregs)->regs, addr) #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ +#endif + #endif /* ifndef __ASSEMBLY__ */ #ifndef __ASSEMBLY__ diff --git a/arch/sw_64/include/asm/kvm_host.h b/arch/sw_64/include/asm/kvm_host.h index cf0009f2d3656aa3874ebc0c9489ffa4ad7b5f64..35c8bf9fd515004f7a48aaa2e0f9622d6a190356 100644 --- a/arch/sw_64/include/asm/kvm_host.h +++ b/arch/sw_64/include/asm/kvm_host.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,10 @@ #define KVM_HALT_POLL_NS_DEFAULT 0 #define KVM_IRQCHIP_NUM_PINS 256 + +#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ + KVM_DIRTY_LOG_INITIALLY_SET) + /* KVM Hugepage definitions for sw64 */ #define KVM_NR_PAGE_SIZES 3 #define KVM_HPAGE_GFN_SHIFT(x) (((x) - 1) * 9) diff --git a/arch/sw_64/include/asm/vcpu.h b/arch/sw_64/include/asm/vcpu.h index b069031add3935fe2a42a1cbe4808b2419bd5408..38066427afdb9bd9c054057b63e3cf9ded2b6cbb 100644 --- a/arch/sw_64/include/asm/vcpu.h +++ b/arch/sw_64/include/asm/vcpu.h @@ -110,10 +110,10 @@ struct vcpucb { unsigned long csr_earg2; unsigned long csr_scratch; unsigned long atc; - unsigned long reserved1[10]; - /* Pending virtual interrupts */ - DECLARE_BITMAP(irqs_pending, CORE4VM_IRQS); - unsigned long reserved2[31]; + unsigned long reserved1[10]; /* USE IN HMCODE */ + DECLARE_BITMAP(irqs_pending, CORE4VM_IRQS); /* Pending virtual interrupts */ + unsigned long irqs_addr; + unsigned long reserved2[30]; }; #endif diff --git a/arch/sw_64/kernel/dup_print.c b/arch/sw_64/kernel/dup_print.c index fa604abef38c77bb97d96d5cd7f4c13a735cdee4..2d77ccae30d2749aaa90430f1b8dea1f8fa8c4b2 100644 --- a/arch/sw_64/kernel/dup_print.c +++ b/arch/sw_64/kernel/dup_print.c @@ -54,7 +54,7 @@ void sw64_rrk_store(const char *text, u16 text_len, u64 ts_nsec, int level, max_offset_allowed = PRINTK_SIZE - text_len - header_len - (newline_first ? 1 : 0); if (unlikely(sw64_printk_offset >= max_offset_allowed)) { sw64_printk_offset = 0; - memset(sw64_printk_buf, 0, PRINTK_SIZE); + memset((void *)KERNEL_PRINTK_BUFF_BASE, 0, PRINTK_SIZE); wrap = true; } sw64_printk_buf = (char *)(KERNEL_PRINTK_BUFF_BASE + sw64_printk_offset); diff --git a/arch/sw_64/kernel/entry-ftrace.S b/arch/sw_64/kernel/entry-ftrace.S index 9274ca8d976924b33da78ae2cd7c0d8002bea043..ec3677d404776fdcde1d8acd639cf868bda06d00 100644 --- a/arch/sw_64/kernel/entry-ftrace.S +++ b/arch/sw_64/kernel/entry-ftrace.S @@ -75,7 +75,7 @@ #endif .endm - .macro SAVE_PT_REGS + .macro SAVE_PT_REGS allregs=0 /* save $26 & fp of the function before caller */ subl $sp, 0x10, $sp stl $26, 0($sp) @@ -88,15 +88,11 @@ stl $15, 0x8($sp) ldi $15, 0($sp) - /* save pt_regs */ ldi $sp, -PT_REGS_SIZE($sp) stl $0, PT_REGS_R0($sp) +#ifdef CONFIG_FUNCTION_GRAPH_TRACER stl $9, PT_REGS_R9($sp) - stl $10, PT_REGS_R10($sp) - stl $11, PT_REGS_R11($sp) - stl $12, PT_REGS_R12($sp) - stl $13, PT_REGS_R13($sp) - stl $14, PT_REGS_R14($sp) +#endif stl $15, PT_REGS_R15($sp) stl $16, PT_REGS_R16($sp) stl $17, PT_REGS_R17($sp) @@ -112,6 +108,15 @@ stl $27, PT_REGS_R27($sp) stl $28, PT_REGS_R28($sp) stl $29, PT_REGS_GP($sp) + subl $28, MCOUNT_INSN_SIZE, $0 + stl $0, PT_REGS_PC($sp) + .if \allregs + stl $10, PT_REGS_R10($sp) + stl $11, PT_REGS_R11($sp) + stl $12, PT_REGS_R12($sp) + stl $13, PT_REGS_R13($sp) + stl $14, PT_REGS_R14($sp) + .endif ldi $0, PT_REGS_SIZE($sp) stl $0, PT_REGS_R30($sp) @@ -120,15 +125,12 @@ stl $2, PT_REGS_R2($sp) .endm - .macro RESTORE_PT_REGS + .macro RESTORE_PT_REGS allregs=0 /* restore pt_regs */ ldl $0, PT_REGS_R0($sp) +#ifdef CONFIG_FUNCTION_GRAPH_TRACER ldl $9, PT_REGS_R9($sp) - ldl $10, PT_REGS_R10($sp) - ldl $11, PT_REGS_R11($sp) - ldl $12, PT_REGS_R12($sp) - ldl $13, PT_REGS_R13($sp) - ldl $14, PT_REGS_R14($sp) +#endif ldl $15, PT_REGS_R15($sp) ldl $16, PT_REGS_R16($sp) ldl $17, PT_REGS_R17($sp) @@ -144,11 +146,23 @@ ldl $27, PT_REGS_R27($sp) ldl $28, PT_REGS_R28($sp) ldl $29, PT_REGS_GP($sp) + .if \allregs + ldl $10, PT_REGS_R10($sp) + ldl $11, PT_REGS_R11($sp) + ldl $12, PT_REGS_R12($sp) + ldl $13, PT_REGS_R13($sp) + ldl $14, PT_REGS_R14($sp) + .endif ldi $sp, PT_REGS_SIZE($sp) /* only restore $fp */ ldl $15, 0x18($sp) addl $sp, 0x20, $sp + + bne $2, .Ldirect\@ + ret $31, ($28), 1 +.Ldirect\@: + ret $31, ($2), 1 /* direct call */ .endm .macro RESTORE_GRAPH_REG_ARGS @@ -173,6 +187,40 @@ addl $sp, 16, $sp .endm + .macro ftrace_common allregs=0 + br $27, 1f +1: ldgp $29, 0($27) + + subl $28, MCOUNT_INSN_SIZE, $16 + bis $26, $31, $17 + ldi $4, function_trace_op + ldl $18, 0($4) + mov $sp, $19 + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + bis $31, $16, $9 +#endif + ldi $4, current_tracer + ldl $27, 0($4) + +.if \allregs == 0 + .global ftrace_call +ftrace_call: + nop +.endif + +.if \allregs + .global ftrace_regs_call +ftrace_regs_call: + nop +.endif + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + RESTORE_GRAPH_REG_ARGS + call ftrace_graph_caller +#endif + ldl $2, PT_REGS_R2($sp) // load direct call addr + .endm #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* @@ -243,35 +291,9 @@ _mcount: .global ftrace_caller .ent ftrace_caller ftrace_caller: - mcount_enter - br $27, 1f -1: ldgp $29, 0($27) - - subl $28, MCOUNT_INSN_SIZE, $16 - bis $26, $31, $17 - ldl $18, function_trace_op - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - /* - * the graph tracer (specifically, prepare_ftrace_return) needs these - * arguments but for now the function tracer occupies the regs, so we - * save them in callee-saved regs to recover later. - */ - bis $31, $16, $9 -#endif - ldi $4, current_tracer - ldl $27, 0($4) - - .global ftrace_call -ftrace_call: /* tracer(pc, ra); */ - nop - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - RESTORE_GRAPH_ARGS - call ftrace_graph_caller -#endif - mcount_end - ret $31, ($28), 1 + SAVE_PT_REGS allregs=0 + ftrace_common allregs=0 + RESTORE_PT_REGS allregs=0 .end ftrace_caller #else /* !CONFIG_DYNAMIC_FTRACE */ @@ -316,37 +338,9 @@ skip_ftrace: .global ftrace_regs_caller .ent ftrace_regs_caller ftrace_regs_caller: - SAVE_PT_REGS - br $27, 1f -1: ldgp $29, 0($27) - - subl $28, MCOUNT_INSN_SIZE, $16 - stl $16, PT_REGS_PC($sp) - bis $26, $31, $17 - ldi $4, function_trace_op - ldl $18, 0($4) - mov $sp, $19 - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - bis $31, $16, $9 -#endif - ldi $4, current_tracer - ldl $27, 0($4) - - .global ftrace_regs_call -ftrace_regs_call: - nop - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - RESTORE_GRAPH_REG_ARGS - call ftrace_graph_caller -#endif - ldl $2, PT_REGS_R2($sp) // load direct call addr - RESTORE_PT_REGS - bne $2, .Ldirect - ret $31, ($28), 1 -.Ldirect: - ret $31, ($2), 1 + SAVE_PT_REGS allregs=1 + ftrace_common allregs=1 + RESTORE_PT_REGS allregs=1 .end ftrace_regs_caller #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ diff --git a/arch/sw_64/kernel/ftrace.c b/arch/sw_64/kernel/ftrace.c index 511760ac18c2ae5803e43d9fa7daa0e6ce074f7e..84ba10d93c9fa9de080cfe92bc4e598a93d45ee1 100644 --- a/arch/sw_64/kernel/ftrace.c +++ b/arch/sw_64/kernel/ftrace.c @@ -175,6 +175,17 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, * Turn on/off the call to ftrace_graph_caller() in ftrace_caller() * depending on @enable. */ +#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS +void ftrace_graph_func(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *op, struct ftrace_regs *fregs) +{ + struct pt_regs *regs = arch_ftrace_get_regs(fregs); + unsigned long *parent = (unsigned long *)®s->regs[26]; + unsigned long frame_pointer = regs->regs[15]; + + prepare_ftrace_return(parent, ip, frame_pointer); +} +#else static int ftrace_modify_graph_caller(bool enable) { unsigned long pc = (unsigned long)&ftrace_graph_call; @@ -194,5 +205,6 @@ int ftrace_disable_ftrace_graph_caller(void) { return ftrace_modify_graph_caller(false); } +#endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */ #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/arch/sw_64/kernel/machine_kexec.c b/arch/sw_64/kernel/machine_kexec.c index 5d54e7cf6823b3621db9f649177efda6f13f4461..9547f12a5299d245af9ce0bd8c5f9cd7b59f1184 100644 --- a/arch/sw_64/kernel/machine_kexec.c +++ b/arch/sw_64/kernel/machine_kexec.c @@ -155,8 +155,10 @@ static void machine_crash_nonpanic_core(void *unused) atomic_dec(&waiting_for_crash_ipi); while (READ_ONCE(smp_rcb->ready) != 0) mdelay(1); - if (cpu != 0) - reset_cpu(cpu); + if (cpu != 0) { + while (1) + cpu_relax(); + } else machine_kexec(kexec_crash_image); } @@ -209,8 +211,10 @@ void machine_crash_shutdown(struct pt_regs *regs) pr_info("Loading crashdump kernel...\n"); #ifdef CONFIG_SMP WRITE_ONCE(smp_rcb->ready, 0); - if (cpu != 0) - reset_cpu(cpu); + if (cpu != 0) { + while (1) + cpu_relax(); + } #endif } diff --git a/arch/sw_64/kernel/ptrace.c b/arch/sw_64/kernel/ptrace.c index 9c5539f58ded7cc5540f46c0cb1fba5aa4e35e15..5842fcc5044bab92b4cd7f410ef2e2f7f1b4246c 100644 --- a/arch/sw_64/kernel/ptrace.c +++ b/arch/sw_64/kernel/ptrace.c @@ -127,7 +127,9 @@ get_reg_addr(struct task_struct *task, unsigned long regno) unsigned long get_reg(struct task_struct *task, unsigned long regno) { - return *get_reg_addr(task, regno); + unsigned long addr = *get_reg_addr(task, regno); + + return (addr) ? addr : -EIO; } /* @@ -136,8 +138,9 @@ get_reg(struct task_struct *task, unsigned long regno) static int put_reg(struct task_struct *task, unsigned long regno, unsigned long data) { - *get_reg_addr(task, regno) = data; - return 0; + unsigned long addr = *get_reg_addr(task, regno); + + return (addr) ? 0 : -EIO; } static inline int diff --git a/arch/sw_64/kernel/smp.c b/arch/sw_64/kernel/smp.c index 93122a011f66bbacbc79d9c5b6bdde54465492fa..53aeb4c9792fe22bd9b50a35d73de1ce33a904f2 100644 --- a/arch/sw_64/kernel/smp.c +++ b/arch/sw_64/kernel/smp.c @@ -21,6 +21,8 @@ #include "proto.h" +static DECLARE_COMPLETION(cpu_running); + struct smp_rcb_struct *smp_rcb; EXPORT_SYMBOL(smp_rcb); @@ -135,15 +137,13 @@ void smp_callin(void) save_ktp(); upshift_freq(); cpuid = smp_processor_id(); - local_irq_disable(); + WARN_ON_ONCE(!irqs_disabled()); if (cpu_online(cpuid)) { pr_err("??, cpu 0x%x already present??\n", cpuid); BUG(); } - set_cpu_online(cpuid, true); - /* Set trap vectors. */ trap_init(); @@ -182,6 +182,10 @@ void smp_callin(void) store_cpu_topology(cpuid); numa_add_cpu(cpuid); + set_cpu_online(cpuid, true); + + complete(&cpu_running); + /* Must have completely accurate bogos. */ local_irq_enable(); @@ -205,7 +209,6 @@ static inline void set_secondary_ready(int cpuid) */ static int secondary_cpu_start(int cpuid, struct task_struct *idle) { - unsigned long timeout; /* * Precalculate the target ksp. */ @@ -222,17 +225,12 @@ static int secondary_cpu_start(int cpuid, struct task_struct *idle) #endif /* Wait 10 seconds for secondary cpu. */ - timeout = jiffies + 10*HZ; - while (time_before(jiffies, timeout)) { - if (cpu_online(cpuid)) - goto started; - udelay(10); - barrier(); + if (!wait_for_completion_timeout(&cpu_running, + msecs_to_jiffies(10000))) { + pr_err("SMP: Processor %d failed to start.\n", cpuid); + return -1; } - pr_err("SMP: Processor %d failed to start.\n", cpuid); - return -1; -started: return 0; } diff --git a/arch/sw_64/kvm/Kconfig b/arch/sw_64/kvm/Kconfig index 124cead28b53167932fd2e9ee3ac643a7f3b35c9..8fef5561516b64c905df04ef267362187b86bdb7 100644 --- a/arch/sw_64/kvm/Kconfig +++ b/arch/sw_64/kvm/Kconfig @@ -27,7 +27,6 @@ config KVM select HAVE_KVM_MSI select KVM_VFIO select MMU_NOTIFIER - select KVM_GENERIC_DIRTYLOG_READ_PROTECT select TUN select GENERIC_ALLOCATOR select KVM_GENERIC_DIRTYLOG_READ_PROTECT diff --git a/arch/sw_64/kvm/kvm_core3.c b/arch/sw_64/kvm/kvm_core3.c index 378831c211397a1dbe02f4a45e95156f8ea45b1a..910688f915ccc12a1c102c511588dd220d474c54 100644 --- a/arch/sw_64/kvm/kvm_core3.c +++ b/arch/sw_64/kvm/kvm_core3.c @@ -383,6 +383,7 @@ static int __init kvm_core3_init(void) if (likely(!ret)) return 0; + kvm_unregister_perf_callbacks(); vmem_exit(); out: bind_vcpu_exit(); @@ -392,6 +393,7 @@ static int __init kvm_core3_init(void) static void __exit kvm_core3_exit(void) { kvm_exit(); + kvm_unregister_perf_callbacks(); vmem_exit(); bind_vcpu_exit(); } diff --git a/arch/sw_64/kvm/kvm_core4.c b/arch/sw_64/kvm/kvm_core4.c index 98fdbfe88fedbb63cb716b0a57c3a758b7d9d181..a13e9fd57249eeb55a0ed95d2db8379cea469c07 100644 --- a/arch/sw_64/kvm/kvm_core4.c +++ b/arch/sw_64/kvm/kvm_core4.c @@ -97,6 +97,8 @@ long kvm_sw64_set_vcb(struct file *filp, unsigned long arg) set_timer(vcpu, 200000000); vcpu->arch.vcb.migration_mark = 0; } + + vcpu->arch.vcb.irqs_addr = (unsigned long)&vcpu->arch.vcb.irqs_pending; return 0; } @@ -224,15 +226,18 @@ static int __init kvm_core4_init(void) ret = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE); - if (ret) - return ret; + if (likely(!ret)) + return 0; + + kvm_unregister_perf_callbacks(); - return 0; + return ret; } static void __exit kvm_core4_exit(void) { kvm_exit(); + kvm_unregister_perf_callbacks(); } module_init(kvm_core4_init); diff --git a/arch/sw_64/kvm/mmu.c b/arch/sw_64/kvm/mmu.c index 24f6bc3545b484f7b44277e463625e39612c81b6..f853069de47bf3d0880e48c8c7195e2c2a5e1685 100644 --- a/arch/sw_64/kvm/mmu.c +++ b/arch/sw_64/kvm/mmu.c @@ -546,6 +546,14 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, if (change == KVM_MR_FLAGS_ONLY && (!(old->flags & KVM_MEM_LOG_DIRTY_PAGES) && new->flags & KVM_MEM_LOG_DIRTY_PAGES)) { kvm_mark_migration(kvm, 1); + + /* + * Initially-all-set does not require write protecting any page, + * because they're all assumed to be dirty. + */ + if (kvm_dirty_log_manual_protect_and_init_set(kvm)) + return; + kvm_mmu_wp_memory_region(kvm, new->id); } diff --git a/arch/sw_64/kvm/sw64.c b/arch/sw_64/kvm/sw64.c index 19c0449b59dcb538db913787673f171c6f1e2e82..73c547fb674ca119022190bf1ad593da9b701d3b 100644 --- a/arch/sw_64/kvm/sw64.c +++ b/arch/sw_64/kvm/sw64.c @@ -191,7 +191,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) return -EINVAL; feature_vint = (cpuid(GET_FEATURES, 0) & CPU_FEAT_VINT); - smp_rcb->feat_vint = 1; + smp_rcb->feat_vint = 2; return kvm_sw64_init_vm(kvm); } diff --git a/crypto/Kconfig b/crypto/Kconfig index fc0f75d8be01d2aa744f7d9b041829545e2fcd3b..c1815d86bd7b350995c972f273b6bb571a6fed0d 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1446,6 +1446,9 @@ endif if X86 source "arch/x86/crypto/Kconfig" endif +if SW64 +source "arch/sw_64/crypto/Kconfig" +endif endif source "drivers/crypto/Kconfig" diff --git a/drivers/cpufreq/sunway-cpufreq.c b/drivers/cpufreq/sunway-cpufreq.c index ba12dad3b28b5f745b11da615b91613707aa549f..a68ff16efa66d6a55208a6607fa0b2a18f1fe13a 100644 --- a/drivers/cpufreq/sunway-cpufreq.c +++ b/drivers/cpufreq/sunway-cpufreq.c @@ -19,6 +19,8 @@ #define CLK_LV1_SEL_MUXB (0x1UL << 3) #define OFFSET_CLU_LV1_SEL 0x3a80UL +#define OFFSET_CLU_LV2_SEL_H 0x3a00UL +#define OFFSET_CLU_LV2_SEL_L 0x3b00UL #define OFFSET_CLK_CTL 0x3b80UL /* @@ -31,16 +33,20 @@ .driver_data = (mv) \ } +enum sunway_cpu_pll { + SUNWAY_CPU_PLL0 = 0, + SUNWAY_CPU_PLL1 = 1, + SUNWAY_CPU_PLL2 = 2 +}; + #ifdef CONFIG_PLATFORM_JUNZHANG -#define CLK0_PROTECT (0x1UL << 0) -#define CLK2_PROTECT (0x1UL << 32) -#define CORE_CLK2_VALID (0x1UL << 33) -#define CORE_CLK2_RESET (0x1UL << 34) -#define CORE_CLK2_LOCK (0x1UL << 35) -#define CORE_PLL0_CFG_SHIFT 4 -#define CORE_PLL1_CFG_SHIFT 20 -#define CORE_PLL2_CFG_SHIFT 36 -#define CORE_PLL2_CFG_MASK 0x1f + +#define CLK_PROTECT(pll) (0x1UL << (16 * (pll))) +#define CLK_VALID(pll) (0x1UL << (1 + 16 * (pll))) +#define CLK_RESET(pll) (0x1UL << (2 + 16 * (pll))) +#define CLK_LOCK(pll) (0x1UL << (3 + 16 * (pll))) +#define PLL_CFG_SHIFT(pll) (4 + 16 * (pll)) +#define CORE_PLL_CFG_MASK 0x1f struct cpufreq_frequency_table freq_table[] = { {0, 0, CPUFREQ_ENTRY_INVALID}, /* 200Mhz is ignored */ @@ -77,19 +83,17 @@ struct cpufreq_frequency_table freq_table[] = { FV(2850, 0), {0, 0, CPUFREQ_TABLE_END}, }; + #endif #ifdef CONFIG_PLATFORM_XUELANG -#define CLK_PROTECT (0x1UL << 0) -#define CLK0_PROTECT CLK_PROTECT -#define CLK2_PROTECT CLK_PROTECT -#define CORE_CLK2_VALID (0x1UL << 15) -#define CORE_CLK2_RESET (0x1UL << 16) -#define CORE_CLK2_LOCK (0x1UL << 17) -#define CORE_PLL0_CFG_SHIFT 4 -#define CORE_PLL1_CFG_SHIFT 11 -#define CORE_PLL2_CFG_SHIFT 18 -#define CORE_PLL2_CFG_MASK 0xf + +#define CLK_PROTECT(pll) (0x1UL << 0) +#define CLK_VALID(pll) (0x1UL << (1 + 7 * (pll))) +#define CLK_RESET(pll) (0x1UL << (2 + 7 * (pll))) +#define CLK_LOCK(pll) (0x1UL << (3 + 7 * (pll))) +#define PLL_CFG_SHIFT(pll) (4 + 7 * (pll)) +#define CORE_PLL_CFG_MASK 0xf struct cpufreq_frequency_table freq_table[] = { {0, 0, CPUFREQ_ENTRY_INVALID}, /* 200Mhz is ignored */ @@ -128,6 +132,7 @@ static void __init fill_freq_table(struct cpufreq_frequency_table *ft) for (i = 3; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) freq_table[i].frequency = freq_off * 38 + ((i - 3) * freq_off); } + #endif static unsigned int sunway_get_rate(struct cpufreq_policy *policy) @@ -141,8 +146,8 @@ static unsigned int sunway_get_rate(struct cpufreq_policy *policy) spbu_base = misc_platform_get_spbu_base(node); /* PLL2 provides working frequency for core */ - val = readq(spbu_base + OFFSET_CLK_CTL) >> CORE_PLL2_CFG_SHIFT; - val &= CORE_PLL2_CFG_MASK; + val = readq(spbu_base + OFFSET_CLK_CTL) >> PLL_CFG_SHIFT(SUNWAY_CPU_PLL2); + val &= CORE_PLL_CFG_MASK; for (i = 0; ft[i].frequency != CPUFREQ_TABLE_END; i++) { if (val == i) { @@ -155,41 +160,57 @@ static unsigned int sunway_get_rate(struct cpufreq_policy *policy) return 0; } -static int sunway_set_rate(struct cpufreq_policy *policy, unsigned int index) +static int sunway_update_pll_cfg(struct cpufreq_policy *policy, + enum sunway_cpu_pll pll, unsigned long pll_cfg) { - int retry, node; + int retry = 0, node; void __iomem *spbu_base; node = per_cpu(hard_node_id, policy->cpu); spbu_base = misc_platform_get_spbu_base(node); - /* select PLL0/PLL1 */ - writeq(CLK_LV1_SEL_PROTECT, spbu_base + OFFSET_CLU_LV1_SEL); - /* reset PLL2 */ - writeq(CLK2_PROTECT | CORE_CLK2_RESET | CORE_CLK2_VALID, spbu_base + OFFSET_CLK_CTL); - /* configure PLL2_CFG */ - writeq(CLK2_PROTECT | CORE_CLK2_VALID | (unsigned long)index << CORE_PLL2_CFG_SHIFT, + /* PLL1 should keep stable */ + if (WARN_ON(pll == SUNWAY_CPU_PLL1)) + return -EINVAL; + + if (pll == SUNWAY_CPU_PLL0) { + /* LV1 MUXA select PLL2, LV1 MUXB select PLL2 */ + writeq(CLK_LV1_SEL_MUXA | CLK_LV1_SEL_MUXB | CLK_LV1_SEL_PROTECT, + spbu_base + OFFSET_CLU_LV1_SEL); + } else if (pll == SUNWAY_CPU_PLL2) { + /* LV1 MUXA keep PLL0 selected, LV1 MUXB select PLL1 */ + writeq(CLK_LV1_SEL_PROTECT, spbu_base + OFFSET_CLU_LV1_SEL); + } + + /* Reset PLL */ + writeq(CLK_PROTECT(pll) | CLK_RESET(pll) | CLK_VALID(pll), spbu_base + OFFSET_CLK_CTL); - udelay(1); - /* reset over */ - writeq(CORE_CLK2_VALID, spbu_base + OFFSET_CLK_CTL); - retry = 0; + /* Configure PLL */ + writeq(CLK_PROTECT(pll) | CLK_VALID(pll) | pll_cfg << PLL_CFG_SHIFT(pll), + spbu_base + OFFSET_CLK_CTL); + + udelay(2); + + /* Reset over */ + writeq(CLK_VALID(pll), spbu_base + OFFSET_CLK_CTL); + + /* Wait until PLL stable */ while (retry < MAX_RETRY) { - if (readq(spbu_base + OFFSET_CLK_CTL) & CORE_CLK2_LOCK) + if (readq(spbu_base + OFFSET_CLK_CTL) & CLK_LOCK(pll)) break; retry++; udelay(100); } - if (retry == MAX_RETRY) + if (pll_cfg && (retry == MAX_RETRY)) return -ETIME; - /* configure over */ + /* Configure over */ writeq(0, spbu_base + OFFSET_CLK_CTL); - /* select PLL2/PLL2 */ - writeq(CLK_LV1_SEL_MUXA | CLK_LV1_SEL_MUXB | CLK_LV1_SEL_PROTECT, - spbu_base + OFFSET_CLU_LV1_SEL); + + /* LV1 MUXA select PLL0, LV1 MUXB select PLL2 */ + writeq(CLK_LV1_SEL_MUXB | CLK_LV1_SEL_PROTECT, spbu_base + OFFSET_CLU_LV1_SEL); return 0; } @@ -210,23 +231,18 @@ static unsigned int sunway_cpufreq_get(unsigned int cpu) static int sunway_cpufreq_target(struct cpufreq_policy *policy, unsigned int index) { - int ret; unsigned int cpu = policy->cpu; if (!cpu_online(cpu)) return -ENODEV; - /* setting the cpu frequency */ - ret = sunway_set_rate(policy, index); - if (ret) - return ret; - - return 0; + return sunway_update_pll_cfg(policy, SUNWAY_CPU_PLL2, index); } static int sunway_cpufreq_init(struct cpufreq_policy *policy) { int cpu, node; + void __iomem *spbu_base; node = per_cpu(hard_node_id, policy->cpu); @@ -237,6 +253,16 @@ static int sunway_cpufreq_init(struct cpufreq_policy *policy) policy->freq_table = freq_table; + spbu_base = misc_platform_get_spbu_base(node); + + /* LV2 MUX select the clock output by LV1 MUXB as working freq */ + writeq(~0ULL, spbu_base + OFFSET_CLU_LV2_SEL_L); + if (is_junzhang_v1() || is_junzhang_v2()) + writeq(~0ULL, spbu_base + OFFSET_CLU_LV2_SEL_H); + + /* Set PLL0 to the lowest freq */ + sunway_update_pll_cfg(policy, SUNWAY_CPU_PLL0, 0); + return 0; } diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index c1bebadf22bcf6fd2243b85e8b42dc670816f393..2e8e0970c2826503a228c0276eb3db26f077fdf9 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig @@ -70,6 +70,11 @@ depends on RISCV source "drivers/cpuidle/Kconfig.riscv" endmenu +menu "SW64 CPU Idle Drivers" +depends on SW64 +source "drivers/cpuidle/Kconfig.sw64" +endmenu + config HALTPOLL_CPUIDLE tristate "Haltpoll cpuidle driver" depends on ARCH_CPUIDLE_HALTPOLL && ARCH_HAS_OPTIMIZED_POLL diff --git a/drivers/cpuidle/Kconfig.sw64 b/drivers/cpuidle/Kconfig.sw64 new file mode 100644 index 0000000000000000000000000000000000000000..0f23175ad36ab520c96af3a795633fb14684c661 --- /dev/null +++ b/drivers/cpuidle/Kconfig.sw64 @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# SW64 CPU Idle drivers +# +config SW64_CPUIDLE + bool "Generic SW64 CPU idle Driver" diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index f29dfd1525b01b895bf439716d07fef84d3429fe..200b6de3847ef0e7a384dcc0deeebec72ff02cad 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile @@ -39,3 +39,7 @@ obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o ############################################################################### # RISC-V drivers obj-$(CONFIG_RISCV_SBI_CPUIDLE) += cpuidle-riscv-sbi.o + +############################################################################### +# SW64 drivers +obj-$(CONFIG_SW64_CPUIDLE) += cpuidle-sw64.o diff --git a/drivers/cpuidle/cpuidle-sw64.c b/drivers/cpuidle/cpuidle-sw64.c new file mode 100644 index 0000000000000000000000000000000000000000..7af9d75185c1b76a13941a834c2ff514f165b1b9 --- /dev/null +++ b/drivers/cpuidle/cpuidle-sw64.c @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: GPL-2.0 +/* SW64 generic CPU idle driver */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_NODES 4 +#define CORE_ID_BITMASK 0x1F +#define MAX_NR_LOCKS_PER_NODE 64 + +extern void arch_cpu_idle(void); +static void __iomem *spbu_base[MAX_NODES]; +static int cpu_siblings[NR_CPUS]; +static bool cpu_deeper_states[NR_CPUS]; +static spinlock_t per_core_lock[MAX_NODES][MAX_NR_LOCKS_PER_NODE]; + +/* CLU_LV2_SEL offset for LV2 MUX */ +#define OFFSET_CLU_LV2_SELH 0x3a00UL +#define OFFSET_CLU_LV2_SELL 0x3b00UL +#define OFFSET_CLU_LV2(core) ((core) > 31 ? OFFSET_CLU_LV2_SELH : OFFSET_CLU_LV2_SELL) + +static bool can_switch_freq(int cpu_sibling) +{ + return cpu_sibling < 0 || + !cpu_online(cpu_sibling) || + cpu_deeper_states[cpu_sibling]; +} + +/* + * sw64_do_deeper_idle + * + * Handles frequency scaling by writing specific bits to + * CLU_LV2_SEL when CPU core wants a deeper idle state. + */ +static void sw64_do_deeper_idle(int cpu) +{ + int core_id, node_id, cpu_sibling; + unsigned long flags; + u64 freq_scaling; + + core_id = rcid_to_core_id(cpu_to_rcid(cpu)); + node_id = rcid_to_domain_id(cpu_to_rcid(cpu)); + cpu_sibling = cpu_siblings[cpu]; + + /* downshift frequency before idle if possible*/ + spin_lock_irqsave(&per_core_lock[node_id][core_id], flags); + cpu_deeper_states[cpu] = true; + if (can_switch_freq(cpu_sibling)) { + freq_scaling = 0x1UL << (2 * (core_id & CORE_ID_BITMASK)); + writeq(freq_scaling, spbu_base[node_id] + OFFSET_CLU_LV2(core_id)); + } + spin_unlock_irqrestore(&per_core_lock[node_id][core_id], flags); + + arch_cpu_idle(); + + /* upshift frequency after idle */ + spin_lock_irqsave(&per_core_lock[node_id][core_id], flags); + cpu_deeper_states[cpu] = false; + freq_scaling = 0x3UL << (2 * (core_id & CORE_ID_BITMASK)); + writeq(freq_scaling, spbu_base[node_id] + OFFSET_CLU_LV2(core_id)); + spin_unlock_irqrestore(&per_core_lock[node_id][core_id], flags); +} + +/* + * sw64_idle_enter - Programs CPU to enter the specified state + * + * dev: cpuidle device + * drv: cpuidle driver + * index: state index + * + * Called from the cpuidle framework to program the device to the + * specified target state selected by the governor. + */ +static int sw64_idle_enter(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + + int cpu = smp_processor_id(); + bool deeper_idle = IS_ENABLED(CONFIG_SW64_CPUFREQ); + + if (!is_in_host()) { + arch_cpu_idle(); + return index; + } + + if (cpu == 0) + deeper_idle = false; + + if (index > 0 && deeper_idle) + sw64_do_deeper_idle(cpu); + else + arch_cpu_idle(); + + return index; +} + +static struct cpuidle_driver sw64_idle_driver = { + .name = "sw64_idle", + .owner = THIS_MODULE, + /* + * State at index 0 is halt and considered standard on + * all SW64 platforms. State at index 1 represents an + * idle state where the CPU enters a halt state combined + * with frequency scaling, which means the CPU core run + * at a reduced frequnecy (e.g., 200MHz) to achieve power + * savings. + * + * To enable State 1, CONFIG_SW64_CPUFREQ must be enabled, + * otherwise the required frequency scaling support will + * be unavailable. + */ + .states[0] = { + .name = "idle0", + .desc = "sw64 idle 0", + .exit_latency = 1, + .target_residency = 1, + .enter = sw64_idle_enter, + }, + .states[1] = { + .name = "idle1", + .desc = "sw64 idle 1", + .exit_latency = 100, + .target_residency = 100, + .enter = sw64_idle_enter, + }, + .state_count = 2, + .cpumask = (struct cpumask *) cpu_possible_mask, +}; + +static int get_sibling_cpu(int cpu) +{ + const cpumask_t *mask = topology_sibling_cpumask(cpu); + int sibling; + + for_each_cpu(sibling, mask) { + if (sibling != cpu) + return sibling; + } + + return -1; +} + +static int __init sw64_cpuidle_init(void) +{ + int i, cpu; + int core_id, node_id; + + for_each_online_cpu(cpu) { + cpu_siblings[cpu] = get_sibling_cpu(cpu); + core_id = rcid_to_core_id(cpu_to_rcid(cpu)); + node_id = rcid_to_domain_id(cpu_to_rcid(cpu)); + spin_lock_init(&per_core_lock[node_id][core_id]); + } + + for (i = 0; i < MAX_NODES; ++i) + spbu_base[i] = misc_platform_get_spbu_base(i); + + return cpuidle_register(&sw64_idle_driver, cpu_possible_mask); +} + +static void __exit sw64_cpuidle_exit(void) +{ + cpuidle_unregister(&sw64_idle_driver); +} +device_initcall(sw64_cpuidle_init); diff --git a/drivers/platform/sw64/misc-platform.c b/drivers/platform/sw64/misc-platform.c index 4d47ebb90546384d0ad735a5e3205014e71bc746..af426429ef238a103fe1ae9f56069dd2a1bbb90a 100644 --- a/drivers/platform/sw64/misc-platform.c +++ b/drivers/platform/sw64/misc-platform.c @@ -163,6 +163,7 @@ void __iomem *misc_platform_get_intpu_base(unsigned long node) return intpu_base; } +EXPORT_SYMBOL(misc_platform_get_intpu_base); void __iomem *misc_platform_get_gpio_base(unsigned long node) { diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index de9f3fc6ec2bdf1c5983a64b01fd3ff954aa0feb..3fdf3cb3b743edae55320cd35bf8d12f20ad0135 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2258,7 +2258,7 @@ int vprintk_store(int facility, int level, } #ifdef CONFIG_SW64_RRK - sw64_rrk_store(&r.text_buf[r.info->text_len], text_len, + sw64_rrk_store(&r.text_buf[r.info->text_len - text_len], text_len, r.info->ts_nsec, -1, e.id, !!(flags & LOG_NEWLINE)); #endif diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h index 8d34cb534ca672ac46931372b027e8d78f9929ee..48d3464204a003773ba3e634179b504fd36a289d 100644 --- a/tools/lib/bpf/bpf_tracing.h +++ b/tools/lib/bpf/bpf_tracing.h @@ -450,30 +450,28 @@ struct pt_regs___arm64 { #elif defined(bpf_target_sw64) /* sw64 provides struct user_pt_regs instead of struct pt_regs to userspace */ -struct pt_regs; -#define PT_REGS_SW64 const volatile struct user_pt_regs -#define PT_REGS_PARM1(x) (((PT_REGS_SW64 *)(x))->regs[16]) -#define PT_REGS_PARM2(x) (((PT_REGS_SW64 *)(x))->regs[17]) -#define PT_REGS_PARM3(x) (((PT_REGS_SW64 *)(x))->regs[18]) -#define PT_REGS_PARM4(x) (((PT_REGS_SW64 *)(x))->regs[19]) -#define PT_REGS_PARM5(x) (((PT_REGS_SW64 *)(x))->regs[20]) -#define PT_REGS_RET(x) (((PT_REGS_SW64 *)(x))->regs[26]) -/* Works only with CONFIG_FRAME_POINTER */ -#define PT_REGS_FP(x) (((PT_REGS_SW64 *)(x))->regs[15]) -#define PT_REGS_RC(x) (((PT_REGS_SW64 *)(x))->regs[0]) -#define PT_REGS_SP(x) (((PT_REGS_SW64 *)(x))->regs[30]) -#define PT_REGS_IP(x) (((PT_REGS_SW64 *)(x))->pc) - -#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[16]) -#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[17]) -#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[18]) -#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[19]) -#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[20]) -#define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[26]) -#define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[15]) -#define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[0]) -#define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), regs[30]) -#define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_SW64 *)(x), pc) +#define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x)) +#define __PT_PARM1_REG regs[16] +#define __PT_PARM2_REG regs[17] +#define __PT_PARM3_REG regs[18] +#define __PT_PARM4_REG regs[19] +#define __PT_PARM5_REG regs[20] +#define __PT_PARM6_REG regs[21] + +/* sw64 does not select ARCH_HAS_SYSCALL_WRAPPER. */ +#define PT_REGS_SYSCALL_REGS(ctx) ctx +#define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG +#define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG +#define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG +#define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG +#define __PT_PARM5_SYSCALL_REG __PT_PARM5_REG +#define __PT_PARM6_SYSCALL_REG __PT_PARM6_REG + +#define __PT_RET_REG regs[26] +#define __PT_FP_REG regs[15] +#define __PT_RC_REG regs[0] +#define __PT_SP_REG regs[30] +#define __PT_IP_REG pc #endif diff --git a/tools/testing/selftests/net/io_uring_zerocopy_tx.c b/tools/testing/selftests/net/io_uring_zerocopy_tx.c index 154287740172617f0f6eb914429335b7e9a0cc89..dd7c23066ab70d8ed29cc2c749f02ade3c1d3d89 100644 --- a/tools/testing/selftests/net/io_uring_zerocopy_tx.c +++ b/tools/testing/selftests/net/io_uring_zerocopy_tx.c @@ -120,6 +120,16 @@ struct io_uring { # ifndef __NR_io_uring_register # define __NR_io_uring_register 537 # endif +#elif defined(__sw_64__) +# ifndef __NR_io_uring_setup +# define __NR_io_uring_setup 272 +# endif +# ifndef __NR_io_uring_enter +# define __NR_io_uring_enter 273 +# endif +# ifndef __NR_io_uring_register +# define __NR_io_uring_register 274 +# endif #else /* !__alpha__ */ # ifndef __NR_io_uring_setup # define __NR_io_uring_setup 425