mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-16 13:34:30 +00:00
scripts/gdb: add lx_current support for riscv
csr_sscratch CSR holds current task_struct address when hart is in user space. Trap handler on entry spills csr_sscratch into "tp" (x2) register and zeroes out csr_sscratch CSR. Trap handler on exit reloads "tp" with expected user mode value and place current task_struct address again in csr_sscratch CSR. This patch assumes "tp" is pointing to task_struct. If value in csr_sscratch is numerically greater than "tp" then it assumes csr_sscratch is correct address of current task_struct. This logic holds when - hart is in user space, "tp" will be less than csr_sscratch. - hart is in kernel space but not in trap handler, "tp" will be more than csr_sscratch (csr_sscratch being equal to 0). - hart is executing trap handler - "tp" is still pointing to user mode but csr_sscratch contains ptr to task_struct. Thus numerically higher. - "tp" is pointing to task_struct but csr_sscratch now contains either 0 or numerically smaller value (transiently holds user mode tp) Link: https://lkml.kernel.org/r/20231026233837.612405-1-debug@rivosinc.com Signed-off-by: Deepak Gupta <debug@rivosinc.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com> Acked-by: Palmer Dabbelt <palmer@rivosinc.com> Tested-by: Hsieh-Tseng Shen <woodrow.shen@sifive.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Glenn Washburn <development@efficientek.com> Cc: Jan Kiszka <jan.kiszka@siemens.com> Cc: Jeff Xie <xiehuan09@gmail.com> Cc: Kieran Bingham <kbingham@kernel.org> Cc: Palmer Dabbelt <palmer@rivosinc.com> Cc: Paul Walmsley <paul.walmsley@sifive.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
e3bc0c427f
commit
cd24f44050
@ -179,6 +179,21 @@ def get_current_task(cpu):
|
||||
else:
|
||||
raise gdb.GdbError("Sorry, obtaining the current task is not allowed "
|
||||
"while running in userspace(EL0)")
|
||||
elif utils.is_target_arch("riscv"):
|
||||
current_tp = gdb.parse_and_eval("$tp")
|
||||
scratch_reg = gdb.parse_and_eval("$sscratch")
|
||||
|
||||
# by default tp points to current task
|
||||
current_task = current_tp.cast(task_ptr_type)
|
||||
|
||||
# scratch register is set 0 in trap handler after entering kernel.
|
||||
# When hart is in user mode, scratch register is pointing to task_struct.
|
||||
# and tp is used by user mode. So when scratch register holds larger value
|
||||
# (negative address as ulong is larger value) than tp, then use scratch register.
|
||||
if (scratch_reg.cast(utils.get_ulong_type()) > current_tp.cast(utils.get_ulong_type())):
|
||||
current_task = scratch_reg.cast(task_ptr_type)
|
||||
|
||||
return current_task.dereference()
|
||||
else:
|
||||
raise gdb.GdbError("Sorry, obtaining the current task is not yet "
|
||||
"supported with this arch")
|
||||
|
Loading…
x
Reference in New Issue
Block a user