From: Sahil <sahilcdq0@gmail.com>
To: Stafford Horne <shorne@gmail.com>
Cc: jonas@southpole.se, stefan.kristiansson@saunalahti.fi,
naveen@kernel.org, davem@davemloft.net, mhiramat@kernel.org,
pjw@kernel.org, wangruikang@iscas.ac.cn, namcao@linutronix.de,
kees@kernel.org, linux-openrisc@vger.kernel.org,
linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 1/4] openrisc: Add utilities and clean up simulation of instructions
Date: Fri, 13 Nov 2026 22:41:56 +0530 [thread overview]
Message-ID: <52c3ae66-4165-4fc3-a440-fcb76931382a@gmail.com> (raw)
In-Reply-To: <au7I8FNoMcsoh54X@antec>
Hi Stafford,
On 11/7/26 12:15 PM, Stafford Horne wrote:
> Hi Sahil,
>
> Thanks for your patches, sorry its taken me time to get around to them, my year
> since summer has been quite hectic.
No worries. I completely understand :)
> I will do the review in chunks so give me some time.
Thank you for the review.
> On Tue, Oct 27, 2026 at 01:42:37AM +0530, Sahil Siddiq wrote:
>> Introduce new instruction-related utilities and macros for OpenRISC.
>> This is in preparation for patches that add tracing support such as
>> KProbes and Kretprobes.
>>
>> Currently, PC is first updated and then saved in the link register
>> (r9) when simulating l.jal and l.jalr. This can result in a corrupted
>> page table (bad page map in process). Fix this by saving PC in r9
>> before updating it.
>>
>> Move branch simulation to its own function, simulate_branch(), so it
>> can be reused. It's already being used by do_illegal_instruction().
>> It'll also be used by KProbes in the following commit.
>>
>> Introduce simulate_pc() to simulate l.adrp. KProbes will require this
>> instruction to be simulated as well. simulate_branch() and simulate_pc()
>> need to be handled differently since branch instructions change the
>> value of PC while l.adrp depends on PC but doesn't change its value.
>>
>> Use a static key to check if delay slots are disabled. Delay slots are
>> a part of the CPU's configuration and won't change at runtime. Since
>> they are often enabled in an OpenRISC CPU, using a static key will
>> reduce the overhead of checking this flag in the default case while
>> processing KProbes inserted at branch instructions and simulating them.
>>
>> Link: https://raw.githubusercontent.com/openrisc/doc/master/openrisc-arch-1.4-rev0.pdf
>> Signed-off-by: Sahil Siddiq <sahilcdq0@gmail.com>
>> ---
>> Changes v2 -> v3:
>> - arch/openrisc/kernel/insn.c:
>> - (simulate_pc):
>> Handle case when rd=0
>> Add function to KProbe blacklist
>> - (simulate_branch): Likewise
>> - arch/openrisc/kernel/setup.c:
>> - (setup_arch): Set static key before calling paging_init()
>> - arch/openrisc/kernel/traps.c:
>> - (do_trap): Move handling of Kprobes in commit #2
>>
>> Changes v1 -> v2:
>> - arch/openrisc/include/asm/cpuinfo.h: Introduce "delay_slot" static key
>> - arch/openrisc/include/asm/insn-def.h:
>> - Use macros instead of union
>> - Use better names for macros
>> - Use genmask() for masks
>> - arch/openrisc/kernel/insn.c:
>> - Use macros instead of magic values
>> - (simulate_pc): Update PC
>> - (simulate_branch): Handle rb=r9 in l.jalr simulation
>> - arch/openrisc/kernel/setup.c: Use "delay slot" static key
>> - arch/openrisc/kernel/traps.c: Use macros instead of magic values
>>
>> arch/openrisc/include/asm/cpuinfo.h | 3 +
>> arch/openrisc/include/asm/insn-def.h | 58 ++++++++++++++++--
>> arch/openrisc/include/asm/spr_defs.h | 1 +
>> arch/openrisc/kernel/Makefile | 2 +-
>> arch/openrisc/kernel/insn.c | 88 ++++++++++++++++++++++++++++
>> arch/openrisc/kernel/setup.c | 4 ++
>> arch/openrisc/kernel/traps.c | 53 +++--------------
>> 7 files changed, 159 insertions(+), 50 deletions(-)
>> create mode 100644 arch/openrisc/kernel/insn.c
>>
>> [...]
>> diff --git a/arch/openrisc/kernel/insn.c b/arch/openrisc/kernel/insn.c
>> new file mode 100644
>> index 000000000000..619d8080d822
>> --- /dev/null
>> +++ b/arch/openrisc/kernel/insn.c
>> @@ -0,0 +1,88 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * OpenRISC instruction utils
>> + *
>> + * Linux architectural port borrowing liberally from similar works of
>> + * others. All original copyrights apply as per the original source
>> + * declaration.
>> + *
>> + * OpenRISC implementation:
>> + * Copyright (C) 2026 Sahil Siddiq <sahilcdq0@gmail.com>
>> + */
>> +
>> +#include <linux/kprobes.h>
>> +#include <linux/ptrace.h>
>> +#include <asm/insn-def.h>
>> +#include <asm/cpuinfo.h>
>> +
>> +DEFINE_STATIC_KEY_TRUE(delay_slot);
>> +
>> +void simulate_pc(struct pt_regs *regs, unsigned long pc_insn)
>
> Since this simulates l.adrp, maybe the name makes more sense to be called
> simulate_adrp?
Sure, I'll rename it.
>> +{
>> + int page_offset;
>> + unsigned int rd, op;
>> +
>> + page_offset = sign_extend32(
>> + (pc_insn & OPENRISC_ADRP_IMM_MASK) << OPENRISC_ADRP_IMM_SHIFT, 31);
>> + rd = (pc_insn & OPENRISC_ADRP_REG_MASK) >> OPENRISC_ADRP_REG_SHIFT;
>> + op = get_6_bit_opcode(pc_insn);
>> +
>> + switch (op) {
>> + case OPENRISC_OPCODE_ADRP:
>> + if (rd != 0)
>> + regs->gpr[rd] = page_offset + (regs->pc & OPENRISC_ADRP_OFFSET_MASK);
>> + regs->pc += OPENRISC_INSN_SIZE;
>> + return;
>> + default:
>> + break;
>> + }
>> +}
>> +NOKPROBE_SYMBOL(simulate_pc)
>> +
>> +void simulate_branch(struct pt_regs *regs, unsigned long jmp_insn)
>> +{
>> + int displacement;
>> + unsigned int rb, op, link_offset, temp;
>> +
>> + displacement = sign_extend32(
>> + ((jmp_insn) & OPENRISC_JUMP_IMM_MASK) << OPENRISC_JUMP_IMM_SHIFT, 27);
>> + rb = (jmp_insn & OPENRISC_JUMP_REG_MASK) >> OPENRISC_JUMP_REG_SHIFT;
>> + op = get_6_bit_opcode(jmp_insn);
>> + link_offset = OPENRISC_INSN_SIZE;
>> +
>> + if (static_branch_likely(&delay_slot))
>> + link_offset <<= 1;
>
> Why do shift left here instead of += OPENRISC_INSN_SIZE? Since logically we are
> adding one more insn for the delay slot, not doubling.
Since link_offset is initialized to OPENRISC_INSN_SIZE, shifting it to the left by 1 would
update link_offset to 2 * OPENRISC_INSN_SIZE. This is a little more obscure than explicitly
setting it to 2 * OPENRISC_INSN_SIZE. Initially, I thought the left shift operator might be
less expensive than multiplying.
I was going through mor1kx's design and noticed there's also a pipelined implementation for
the multiplier [1]. But it looks like the implementation for shifting is simpler and can be done
in one cycle. Please let me know if my understanding is incorrect here.
> However, It may be more efficient to avoid using the alu and write as:
>
> if (static_branch_likely(&delay_slot))
> link_offset = 2 * OPENRISC_INSN_SIZE;
> else
> link_offset = OPENRISC_INSN_SIZE;
>
> what do you think?
I am not sure if I have understood the alu part. WIll it be more efficient because 2 * OPENRISC_INSN_SIZE
will be optimized by the compiler to simply be a single number? So no alu operation will be required,
just one store operation?
>
>> + switch (op) {
>> + case OPENRISC_OPCODE_J: /* l.j */
>
> I think these comments (/* l.j */) are no longer needed sinc you have
> the named macros.
Got it, I'll remove the comments.
>> + regs->pc += displacement;
>> + return;
>> + case OPENRISC_OPCODE_JAL: /* l.jal */
>> + regs->gpr[9] = regs->pc + link_offset;
>> + regs->pc += displacement;
>> + return;
>> + case OPENRISC_OPCODE_BNF: /* l.bnf */
>> + if (regs->sr & SPR_SR_F)
>> + regs->pc += link_offset;
>> + else
>> + regs->pc += displacement;
>> + return;
>> + case OPENRISC_OPCODE_BF: /* l.bf */
>> + if (regs->sr & SPR_SR_F)
>> + regs->pc += displacement;
>> + else
>> + regs->pc += link_offset;
>> + return;
>> + case OPENRISC_OPCODE_JR: /* l.jr */
>> + regs->pc = rb == 0 ? 0 : regs->gpr[rb];
>> + return;
>> + case OPENRISC_OPCODE_JALR: /* l.jalr */
>> + temp = regs->pc + link_offset;
>> + regs->pc = rb == 0 ? 0 : regs->gpr[rb];
>> + regs->gpr[9] = temp;
>> + return;
>> + default:
>> + break;
>> + }
>> +}
>> +NOKPROBE_SYMBOL(simulate_branch)
>> diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
>> index 000a9cc10e6f..9c231b320d45 100644
>> --- a/arch/openrisc/kernel/setup.c
>> +++ b/arch/openrisc/kernel/setup.c
>> @@ -252,6 +252,10 @@ void __init setup_arch(char **cmdline_p)
>> /* perform jump_table sorting before paging_init locks down read only memory */
>> jump_label_init();
>>
>> + /* determine if the processor supports delay slots */
>> + if (mfspr(SPR_CPUCFGR) & SPR_CPUCFGR_ND)
>> + static_branch_disable(&delay_slot);
>> +
>> /* paging_init() sets up the MMU and marks all pages as reserved */
>> paging_init();
>>
>> diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
>> index c195be9cc9fc..a59abbca3555 100644
>> --- a/arch/openrisc/kernel/traps.c
>> +++ b/arch/openrisc/kernel/traps.c
>> @@ -32,6 +32,7 @@
>>
>> #include <asm/bug.h>
>> #include <asm/fpu.h>
>> +#include <asm/insn-def.h>
>> #include <asm/io.h>
>> #include <asm/processor.h>
>> #include <asm/unwinder.h>
>> @@ -252,12 +253,12 @@ static inline int in_delay_slot(struct pt_regs *regs)
>> insn = *((unsigned int *)regs->pc);
>> op = insn >> 26;
>> switch (op) {
>> - case 0x00: /* l.j */
>> - case 0x01: /* l.jal */
>> - case 0x03: /* l.bnf */
>> - case 0x04: /* l.bf */
>> - case 0x11: /* l.jr */
>> - case 0x12: /* l.jalr */
>> + case OPENRISC_OPCODE_J: /* l.j */
>> + case OPENRISC_OPCODE_JAL: /* l.jal */
>> + case OPENRISC_OPCODE_BNF: /* l.bnf */
>> + case OPENRISC_OPCODE_BF: /* l.bf */
>> + case OPENRISC_OPCODE_JR: /* l.jr */
>> + case OPENRISC_OPCODE_JALR: /* l.jalr */
>
> Nice cleanup, again I think comments can be removed now.
Sure, I'll remove these comments as well.
>> return 1;
>> default:
>> return 0;
>> @@ -269,47 +270,9 @@ static inline int in_delay_slot(struct pt_regs *regs)
>>
>> static inline void adjust_pc(struct pt_regs *regs, unsigned long address)
>> {
>> - int displacement;
>> - unsigned int rb, op, jmp;
>> -
>> if (unlikely(in_delay_slot(regs))) {
>> /* In delay slot, instruction at pc is a branch, simulate it */
>> - jmp = *((unsigned int *)regs->pc);
>> -
>> - displacement = sign_extend32(((jmp) & 0x3ffffff) << 2, 27);
>> - rb = (jmp & 0x0000ffff) >> 11;
>> - op = jmp >> 26;
>> -
>> - switch (op) {
>> - case 0x00: /* l.j */
>> - regs->pc += displacement;
>> - return;
>> - case 0x01: /* l.jal */
>> - regs->pc += displacement;
>> - regs->gpr[9] = regs->pc + 8;
>> - return;
>> - case 0x03: /* l.bnf */
>> - if (regs->sr & SPR_SR_F)
>> - regs->pc += 8;
>> - else
>> - regs->pc += displacement;
>> - return;
>> - case 0x04: /* l.bf */
>> - if (regs->sr & SPR_SR_F)
>> - regs->pc += displacement;
>> - else
>> - regs->pc += 8;
>> - return;
>> - case 0x11: /* l.jr */
>> - regs->pc = regs->gpr[rb];
>> - return;
>> - case 0x12: /* l.jalr */
>> - regs->pc = regs->gpr[rb];
>> - regs->gpr[9] = regs->pc + 8;
>> - return;
>> - default:
>> - break;
>> - }
>> + simulate_branch(regs, *((unsigned int *)regs->pc));
>> } else {
>> regs->pc += 4;
>> }
>> --
>> 2.55.0
>>
Thanks,
Sahil
[1] https://github.com/openrisc/mor1kx/blob/master/rtl/verilog/mor1kx_execute_alu.v#L224-L377
next prev parent reply other threads:[~2026-11-13 17:12 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260930202744.50489-1-sahilcdq0@gmail.com>
2026-10-26 20:12 ` [PATCH v3 0/4] openrisc: Add support for KProbes and Kretprobes Sahil Siddiq
2026-11-13 9:04 ` Masami Hiramatsu (Google)
2026-11-13 17:22 ` Sahil
2026-10-26 20:12 ` [PATCH v3 1/4] openrisc: Add utilities and clean up simulation of instructions Sahil Siddiq
2026-11-07 6:45 ` Stafford Horne
2026-11-13 17:11 ` Sahil [this message]
2026-10-26 20:12 ` [PATCH v3 2/4] openrisc: Add KProbes Sahil Siddiq
2026-10-26 20:26 ` Sahil
2026-11-08 7:46 ` Stafford Horne
2026-11-13 17:13 ` Sahil
2026-10-26 20:12 ` [PATCH v3 3/4] openrisc: Add unit tests for KProbes on branch instructions Sahil Siddiq
2026-11-08 8:03 ` Stafford Horne
2026-11-13 17:15 ` Sahil
2026-10-26 20:12 ` [PATCH v3 4/4] openrisc: Add Kretprobes Sahil Siddiq
2026-11-08 7:58 ` Stafford Horne
2026-11-13 17:16 ` Sahil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52c3ae66-4165-4fc3-a440-fcb76931382a@gmail.com \
--to=sahilcdq0@gmail.com \
--cc=davem@davemloft.net \
--cc=jonas@southpole.se \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-openrisc@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=namcao@linutronix.de \
--cc=naveen@kernel.org \
--cc=pjw@kernel.org \
--cc=shorne@gmail.com \
--cc=stefan.kristiansson@saunalahti.fi \
--cc=wangruikang@iscas.ac.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®