From 2654ebb7f40b0dc546565a088b0f0acc63dc0378 Mon Sep 17 00:00:00 2001 From: He Sheng Date: Wed, 18 Jan 2023 15:01:00 +0800 Subject: [PATCH] sw64: activate CONFIG_THREAD_INFO_IN_TASK Sunway inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6ILGG -------------------------------- This patch activates CONFIG_THREAD_INFO_IN_TASK which moves the thread_info into task_struct. This has the following consequences: - thread_info is now located at the beginning of task_struct. - thread_info doesn't have anymore the `task` field. This patch: - Adds hmcall wrktp and rdktp to save/restore `current` task pointer. - Changes the current_thread_info() macro to point to `current`. - Selects CONFIG_THREAD_INFO_IN_TASK. - Modifies raw_smp_processor_id() to get ->cpu from `current` without including linux/sched.h to avoid circular inclusion and without including asm/asm-offsets.h to avoid symbol names duplication between ASM constants and C constants. - Modifies task_pt_regs() macro to avoid error which says that task_stack_page() is undefined. This error can not be fixed by including linux/sched.h which results in circular inclusion. Signed-off-by: He Sheng Reviewed-by: Cui Wei Signed-off-by: Gu Zitao --- arch/sw_64/Kconfig | 1 + arch/sw_64/include/asm/current.h | 15 ++++++++-- arch/sw_64/include/asm/hmcall.h | 7 +++++ arch/sw_64/include/asm/processor.h | 2 +- arch/sw_64/include/asm/ptrace.h | 6 ---- arch/sw_64/include/asm/smp.h | 20 +++++++++---- arch/sw_64/include/asm/thread_info.h | 8 +----- arch/sw_64/kernel/asm-offsets.c | 9 ++++-- arch/sw_64/kernel/early_init.c | 1 + arch/sw_64/kernel/entry.S | 17 ++--------- arch/sw_64/kernel/head.S | 14 ++++++---- arch/sw_64/kernel/hmcall.c | 18 ++++++++++++ arch/sw_64/kernel/smp.c | 5 ++-- arch/sw_64/kvm/entry.S | 42 +++++++++++++--------------- 14 files changed, 96 insertions(+), 69 deletions(-) diff --git a/arch/sw_64/Kconfig b/arch/sw_64/Kconfig index 53b2226f8516..3b9b13209e35 100644 --- a/arch/sw_64/Kconfig +++ b/arch/sw_64/Kconfig @@ -107,6 +107,7 @@ config SW64 select SET_FS select SPARSEMEM_EXTREME if SPARSEMEM select SWIOTLB + select THREAD_INFO_IN_TASK config LOCKDEP_SUPPORT def_bool y diff --git a/arch/sw_64/include/asm/current.h b/arch/sw_64/include/asm/current.h index 219b5ce9f4fc..862caabb9c70 100644 --- a/arch/sw_64/include/asm/current.h +++ b/arch/sw_64/include/asm/current.h @@ -2,9 +2,18 @@ #ifndef _ASM_SW64_CURRENT_H #define _ASM_SW64_CURRENT_H -#include +#ifndef __ASSEMBLY__ -#define get_current() (current_thread_info()->task) -#define current get_current() +struct task_struct; +static __always_inline struct task_struct *get_current(void) +{ + register struct task_struct *tp __asm__("$8"); + + return tp; +} + +#define current get_current() + +#endif /* __ASSEMBLY__ */ #endif /* _ASM_SW64_CURRENT_H */ diff --git a/arch/sw_64/include/asm/hmcall.h b/arch/sw_64/include/asm/hmcall.h index 22de7d9f41a3..8bd5f5357bc0 100644 --- a/arch/sw_64/include/asm/hmcall.h +++ b/arch/sw_64/include/asm/hmcall.h @@ -13,6 +13,8 @@ #define HMC_sleepen 0x05 #define HMC_rdksp 0x06 #define HMC_wrasid 0x08 +#define HMC_rdktp 0x09 +#define HMC_wrktp 0x0A #define HMC_rdptbr 0x0B #define HMC_wrptbr 0x0C #define HMC_wrksp 0x0E @@ -150,6 +152,11 @@ __CALL_HMC_VOID(wrfen); __CALL_HMC_VOID(sleepen); __CALL_HMC_VOID(mtinten); +__CALL_HMC_VOID(rdktp); +#define restore_ktp() rdktp() +__CALL_HMC_VOID(wrktp); +#define save_ktp() wrktp() + __CALL_HMC_R0(rdps, unsigned long); __CALL_HMC_R0(rdusp, unsigned long); diff --git a/arch/sw_64/include/asm/processor.h b/arch/sw_64/include/asm/processor.h index 886f28635dd4..75dd24deaa9d 100644 --- a/arch/sw_64/include/asm/processor.h +++ b/arch/sw_64/include/asm/processor.h @@ -12,7 +12,7 @@ #include #define task_pt_regs(task) \ - ((struct pt_regs *) (task_stack_page(task) + 2 * PAGE_SIZE) - 1) + ((struct pt_regs *) (task->stack + THREAD_SIZE) - 1) /* * Returns current instruction pointer ("program counter"). diff --git a/arch/sw_64/include/asm/ptrace.h b/arch/sw_64/include/asm/ptrace.h index 4db8b61fc093..48e6dc4443e2 100644 --- a/arch/sw_64/include/asm/ptrace.h +++ b/arch/sw_64/include/asm/ptrace.h @@ -4,7 +4,6 @@ #include #include -#include #include /* @@ -58,11 +57,6 @@ struct pt_regs { #define kernel_stack_pointer(regs) ((unsigned long)((regs) + 1)) #define instruction_pointer_set(regs, val) ((regs)->pc = val) - -#define current_pt_regs() \ - ((struct pt_regs *) ((char *)current_thread_info() + 2 * PAGE_SIZE) - 1) -#define signal_pt_regs current_pt_regs - #define force_successful_syscall_return() (current_pt_regs()->r0 = 0) #define MAX_REG_OFFSET (offsetof(struct pt_regs, r18)) diff --git a/arch/sw_64/include/asm/smp.h b/arch/sw_64/include/asm/smp.h index 0573361dc840..ca913090fd9a 100644 --- a/arch/sw_64/include/asm/smp.h +++ b/arch/sw_64/include/asm/smp.h @@ -2,14 +2,16 @@ #ifndef _ASM_SW64_SMP_H #define _ASM_SW64_SMP_H -#include -#include -#include -#include -#include #include +#include +#include +#include #include +#include +#include +#include + /* HACK: Cabrio WHAMI return value is bogus if more than 8 bits used.. :-( */ extern cpumask_t core_start; @@ -55,7 +57,13 @@ struct smp_rcb_struct { #define INIT_SMP_RCB ((struct smp_rcb_struct *) __va(0x820000UL)) #define hard_smp_processor_id() __hard_smp_processor_id() -#define raw_smp_processor_id() (current_thread_info()->cpu) + +#ifdef GENERATING_ASM_OFFSETS +#define raw_smp_processor_id() (0) +#else +#include +#define raw_smp_processor_id() (*((unsigned int *)((void *)current + TASK_CPU))) +#endif /* The map from sequential logical cpu number to hard cid. */ extern int __cpu_to_rcid[NR_CPUS]; diff --git a/arch/sw_64/include/asm/thread_info.h b/arch/sw_64/include/asm/thread_info.h index c9637d32e1be..a8341d64ad43 100644 --- a/arch/sw_64/include/asm/thread_info.h +++ b/arch/sw_64/include/asm/thread_info.h @@ -5,7 +5,6 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ -#include #include #include @@ -25,12 +24,11 @@ struct pcb_struct { struct thread_info { struct pcb_struct pcb; /* hmcode state */ - struct task_struct *task; /* main task structure */ unsigned int flags; /* low level flags */ unsigned int ieee_state; /* see fpu.h */ mm_segment_t addr_limit; /* thread address space */ - unsigned int cpu; /* current CPU */ + unsigned int cpu; /* current CPU */ int preempt_count; /* 0 => preemptible, <0 => BUG */ unsigned int status; /* thread-synchronous flags */ @@ -58,14 +56,10 @@ static __always_inline u64 rtid(void) */ #define INIT_THREAD_INFO(tsk) \ { \ - .task = &tsk, \ .addr_limit = KERNEL_DS, \ .preempt_count = INIT_PREEMPT_COUNT, \ } -/* How to get the thread information struct from C. */ -register struct thread_info *__current_thread_info __asm__("$8"); -#define current_thread_info() __current_thread_info #endif /* __ASSEMBLY__ */ diff --git a/arch/sw_64/kernel/asm-offsets.c b/arch/sw_64/kernel/asm-offsets.c index 12b3311c1bcb..58f488d3427c 100644 --- a/arch/sw_64/kernel/asm-offsets.c +++ b/arch/sw_64/kernel/asm-offsets.c @@ -5,6 +5,7 @@ * and format the required data. */ +#define GENERATING_ASM_OFFSETS /* asm/smp.h */ #include #include #include @@ -15,11 +16,11 @@ #include "traps.c" + void foo(void) { - DEFINE(TI_TASK, offsetof(struct thread_info, task)); + DEFINE(ASM_THREAD_SIZE, THREAD_SIZE); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); BLANK(); DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); @@ -27,6 +28,10 @@ void foo(void) DEFINE(TASK_REAL_PARENT, offsetof(struct task_struct, real_parent)); DEFINE(TASK_GROUP_LEADER, offsetof(struct task_struct, group_leader)); DEFINE(TASK_TGID, offsetof(struct task_struct, tgid)); + DEFINE(TASK_STACK, offsetof(struct task_struct, stack)); +#ifdef CONFIG_SMP + DEFINE(TASK_CPU, offsetof(struct task_struct, thread_info.cpu)); +#endif BLANK(); OFFSET(PSTATE_REGS, processor_state, regs); diff --git a/arch/sw_64/kernel/early_init.c b/arch/sw_64/kernel/early_init.c index 2f38719cc216..bcd458a9bdad 100644 --- a/arch/sw_64/kernel/early_init.c +++ b/arch/sw_64/kernel/early_init.c @@ -24,6 +24,7 @@ static void __init sw64_setup_platform_ops(void) asmlinkage __visible void __init sw64_start_kernel(void) { fixup_hmcall(); + save_ktp(); sw64_setup_chip_ops(); sw64_setup_platform_ops(); sw64_platform->ops_fixup(); diff --git a/arch/sw_64/kernel/entry.S b/arch/sw_64/kernel/entry.S index b360f0e2ddd6..750bd634dde3 100644 --- a/arch/sw_64/kernel/entry.S +++ b/arch/sw_64/kernel/entry.S @@ -48,6 +48,7 @@ stl $25, PT_REGS_R25($sp) stl $26, PT_REGS_R26($sp) stl $27, PT_REGS_R27($sp) + sys_call HMC_rdktp .endm .macro RESTORE_ALL @@ -89,9 +90,7 @@ .ent entInt entInt: SAVE_ALL - ldi $8, 0x3fff ldi $26, ret_from_sys_call - bic $sp, $8, $8 mov $sp, $19 call $31, do_entInt .end entInt @@ -101,9 +100,7 @@ entInt: .ent entArith entArith: SAVE_ALL - ldi $8, 0x3fff ldi $26, ret_from_sys_call - bic $sp, $8, $8 mov $sp, $18 call $31, do_entArith .end entArith @@ -113,9 +110,7 @@ entArith: .ent entMM entMM: SAVE_ALL - ldi $8, 0x3fff ldi $26, ret_from_sys_call - bic $sp, $8, $8 mov $sp, $19 call $31, do_page_fault .end entMM @@ -125,9 +120,7 @@ entMM: .ent entIF entIF: SAVE_ALL - ldi $8, 0x3fff ldi $26, ret_from_sys_call - bic $sp, $8, $8 mov $sp, $17 call $31, do_entIF .end entIF @@ -143,8 +136,6 @@ entIF: .ent entUna entUna: SAVE_ALL - ldi $8, 0x3fff - bic $sp, $8, $8 mov $sp, $19 ldl $0, PT_REGS_PS($sp) and $0, 8, $0 /* user mode ? */ @@ -176,8 +167,6 @@ entUna: entSys: SAVE_ALL - ldi $8, 0x3fff - bic $sp, $8, $8 ldi $4, NR_SYSCALLS($31) stl $16, PT_REGS_R16($sp) ldi $5, sys_call_table @@ -395,8 +384,8 @@ __switch_to: ldl $13, TASK_THREAD_S4($17) ldl $14, TASK_THREAD_S5($17) ldl $15, TASK_THREAD_S6($17) - ldi $8, 0x3fff - bic $sp, $8, $8 + mov $17, $8 + sys_call HMC_wrktp mov $16, $0 ret .end __switch_to diff --git a/arch/sw_64/kernel/head.S b/arch/sw_64/kernel/head.S index 7cce2a8859e5..d5975a971b86 100644 --- a/arch/sw_64/kernel/head.S +++ b/arch/sw_64/kernel/head.S @@ -22,9 +22,11 @@ __start: br $27, 1f 1: ldgp $29, 0($27) /* We need to get current_task_info loaded up... */ - ldi $8, init_thread_union + ldi $8, init_task + ldl $30, TASK_STACK($8) /* ... and find our stack ... */ - ldi $30, ASM_THREAD_SIZE($8) + ldi $30, ASM_THREAD_SIZE($30) + /* ... and then we can clear bss data. */ ldi $16, __bss_start ldi $18, __bss_stop @@ -68,11 +70,13 @@ __smp_callin: s4addl $0, $1, $1 ldw $0, 0($1) # Get logical cpu number - ldi $2, tidle_ksp + ldi $2, idle_task_pointer s8addl $0, $2, $2 - ldl $30, 0($2) # Get ksp of idle thread + ldl $8, 0($2) # Get ksp of idle thread + sys_call HMC_wrktp - ldi $8, -ASM_THREAD_SIZE($30) # Find "current" + ldl $30, TASK_STACK($8) + ldi $30, ASM_THREAD_SIZE($30) call $26, smp_callin sys_call HMC_halt diff --git a/arch/sw_64/kernel/hmcall.c b/arch/sw_64/kernel/hmcall.c index 3d60569a4f6f..e2be9f618e57 100644 --- a/arch/sw_64/kernel/hmcall.c +++ b/arch/sw_64/kernel/hmcall.c @@ -76,6 +76,22 @@ static inline void fixup_wrasid(void) entry[9] = 0x1ef00000; /* pri_ret/b p23 */ } +static inline void fixup_rdktp(void) +{ + unsigned int *entry = __va(HMCALL_ENTRY(rdktp)); + + entry[0] = 0x95161000; /* pri_ldl/p $8, VC__KTP(vcpucb) */ + entry[1] = 0x1ee00000; /* pri_ret $23 */ +} + +static inline void fixup_wrktp(void) +{ + unsigned int *entry = __va(HMCALL_ENTRY(wrktp)); + + entry[0] = 0xb5161000; /* pri_stl/p $8, VC__KTP(vcpucb) */ + entry[1] = 0x1ee00000; /* pri_ret $23 */ +} + void __init fixup_hmcall(void) { #if defined(CONFIG_SUBARCH_C3B) @@ -83,6 +99,8 @@ void __init fixup_hmcall(void) fixup_wrtp(); fixup_tbiasid(); fixup_wrasid(); + fixup_rdktp(); + fixup_wrktp(); #endif } diff --git a/arch/sw_64/kernel/smp.c b/arch/sw_64/kernel/smp.c index 1bf289b6a89e..ff2cd690a935 100644 --- a/arch/sw_64/kernel/smp.c +++ b/arch/sw_64/kernel/smp.c @@ -34,7 +34,7 @@ EXPORT_SYMBOL(__cpu_to_rcid); int __rcid_to_cpu[NR_CPUS]; /* Map physical to logical */ EXPORT_SYMBOL(__rcid_to_cpu); -void *tidle_ksp[NR_CPUS]; +void *idle_task_pointer[NR_CPUS]; /* State of each CPU */ DEFINE_PER_CPU(int, cpu_state) = { 0 }; @@ -130,7 +130,7 @@ static int secondary_cpu_start(int cpuid, struct task_struct *idle) /* * Precalculate the target ksp. */ - tidle_ksp[cpuid] = idle->stack + THREAD_SIZE; + idle_task_pointer[cpuid] = idle; DBGS("Starting secondary cpu %d: state 0x%lx\n", cpuid, idle->state); @@ -237,7 +237,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) memset(ipi_data, 0, sizeof(ipi_data)); init_cpu_topology(); - current_thread_info()->cpu = 0; store_cpu_topology(smp_processor_id()); numa_add_cpu(smp_processor_id()); diff --git a/arch/sw_64/kvm/entry.S b/arch/sw_64/kvm/entry.S index a331709320ca..a61ecc387d26 100644 --- a/arch/sw_64/kvm/entry.S +++ b/arch/sw_64/kvm/entry.S @@ -18,22 +18,22 @@ */ ENTRY(__sw64_vcpu_run) /* save host fpregs */ - ldl $1, TI_TASK($8) rfpcr $f0 - fstd $f0, TASK_THREAD_FPCR($1) - vstd $f2, TASK_THREAD_F2($1) - vstd $f3, TASK_THREAD_F3($1) - vstd $f4, TASK_THREAD_F4($1) - vstd $f5, TASK_THREAD_F5($1) - vstd $f6, TASK_THREAD_F6($1) - vstd $f7, TASK_THREAD_F7($1) - vstd $f8, TASK_THREAD_F8($1) - vstd $f9, TASK_THREAD_F9($1) + fstd $f0, TASK_THREAD_FPCR($8) + vstd $f2, TASK_THREAD_F2($8) + vstd $f3, TASK_THREAD_F3($8) + vstd $f4, TASK_THREAD_F4($8) + vstd $f5, TASK_THREAD_F5($8) + vstd $f6, TASK_THREAD_F6($8) + vstd $f7, TASK_THREAD_F7($8) + vstd $f8, TASK_THREAD_F8($8) + vstd $f9, TASK_THREAD_F9($8) ldi sp, -VCPU_RET_SIZE(sp) /* save host pt_regs to current kernel stack */ ldi sp, -PT_REGS_SIZE(sp) stl $9, PT_REGS_R9(sp) + stl $8, PT_REGS_R8(sp) stl $10, PT_REGS_R10(sp) stl $11, PT_REGS_R11(sp) stl $12, PT_REGS_R12(sp) @@ -198,6 +198,7 @@ $g_setfpec_over: stl $28, KVM_REGS_R28($17) /* restore host regs from host sp */ + ldl $8, PT_REGS_R8(sp) ldl $9, PT_REGS_R9(sp) ldl $10, PT_REGS_R10(sp) ldl $11, PT_REGS_R11(sp) @@ -208,11 +209,8 @@ $g_setfpec_over: ldl $26, PT_REGS_R26(sp) ldi sp, PT_REGS_SIZE(sp) - ldi $8, 0x3fff - bic sp, $8, $8 /* restore host fpregs */ - ldl $1, TI_TASK($8) - fldd $f0, TASK_THREAD_FPCR($1) + fldd $f0, TASK_THREAD_FPCR($8) wfpcr $f0 fimovd $f0, $2 and $2, 0x3, $2 @@ -232,14 +230,14 @@ $setfpec_1: $setfpec_2: setfpec2 $setfpec_over: - vldd $f2, TASK_THREAD_F2($1) - vldd $f3, TASK_THREAD_F3($1) - vldd $f4, TASK_THREAD_F4($1) - vldd $f5, TASK_THREAD_F5($1) - vldd $f6, TASK_THREAD_F6($1) - vldd $f7, TASK_THREAD_F7($1) - vldd $f8, TASK_THREAD_F8($1) - vldd $f9, TASK_THREAD_F9($1) + vldd $f2, TASK_THREAD_F2($8) + vldd $f3, TASK_THREAD_F3($8) + vldd $f4, TASK_THREAD_F4($8) + vldd $f5, TASK_THREAD_F5($8) + vldd $f6, TASK_THREAD_F6($8) + vldd $f7, TASK_THREAD_F7($8) + vldd $f8, TASK_THREAD_F8($8) + vldd $f9, TASK_THREAD_F9($8) /* if $0 > 0, handle hcall */ bgt $0, $ret_to -- GitLab