All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heiko Stuebner <heiko@sntech.de>
To: Conor Dooley <conor@kernel.org>
Cc: linux-riscv@lists.infradead.org, palmer@dabbelt.com,
	christoph.muellner@vrull.eu, prabhakar.csengg@gmail.com,
	philipp.tomsich@vrull.eu, ajones@ventanamicro.com,
	emil.renner.berthing@canonical.com, jszhang@kernel.org
Subject: Re: [PATCH v4 12/12] RISC-V: fix auipc-jalr addresses in patched alternatives
Date: Wed, 07 Dec 2022 23:37:30 +0100	[thread overview]
Message-ID: <4261102.ElGaqSPkdT@phil> (raw)
In-Reply-To: <Y5D8CHkJZGmQKxdh@spud>

Am Mittwoch, 7. Dezember 2022, 21:48:08 CET schrieb Conor Dooley:
> On Wed, Dec 07, 2022 at 07:08:21PM +0100, Heiko Stuebner wrote:
> > From: Heiko Stuebner <heiko.stuebner@vrull.eu>
> > 
> > Alternatives live in a different section, so addresses used by call
> > functions will point to wrong locations after the patch got applied.
> > 
> > Similar to arm64, adjust the location to consider that offset.
> > 
> > Signed-off-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
> > ---
> >  arch/riscv/include/asm/alternative.h |  3 ++
> >  arch/riscv/kernel/alternative.c      | 56 ++++++++++++++++++++++++++++
> >  arch/riscv/kernel/cpufeature.c       |  5 ++-
> >  3 files changed, 63 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h
> > index 6511dd73e812..1bd4027d34ca 100644
> > --- a/arch/riscv/include/asm/alternative.h
> > +++ b/arch/riscv/include/asm/alternative.h
> > @@ -27,6 +27,9 @@ void __init apply_boot_alternatives(void);
> >  void __init apply_early_boot_alternatives(void);
> >  void apply_module_alternatives(void *start, size_t length);
> >  
> > +void riscv_alternative_fix_offsets(void *alt_ptr, unsigned int len,
> > +				   int patch_offset);
> > +
> >  struct alt_entry {
> >  	void *old_ptr;		 /* address of original instruciton or data  */
> >  	void *alt_ptr;		 /* address of replacement instruction or data */
> > diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
> > index a7d26a00beea..c29e198ed9df 100644
> > --- a/arch/riscv/kernel/alternative.c
> > +++ b/arch/riscv/kernel/alternative.c
> > @@ -15,6 +15,8 @@
> >  #include <asm/vendorid_list.h>
> >  #include <asm/sbi.h>
> >  #include <asm/csr.h>
> > +#include <asm/insn.h>
> > +#include <asm/patch.h>
> >  
> >  struct cpu_manufacturer_info_t {
> >  	unsigned long vendor_id;
> > @@ -53,6 +55,60 @@ static void __init_or_module riscv_fill_cpu_mfr_info(struct cpu_manufacturer_inf
> >  	}
> >  }
> >  
> > +static u32 riscv_instruction_at(void *p)
> > +{
> > +	u16 *parcel = p;
> > +
> > +	return (unsigned int)parcel[0] | (unsigned int)parcel[1] << 16;
> 
> I feel bad for not mentioning this before - can we replace this magic 16
> with something self documenting?
> 
> > +}
> > +
> > +static void riscv_alternative_fix_auipc_jalr(void *ptr, u32 insn1, u32 insn2, int patch_offset)
> > +{
> > +	/* pick the original auipc + jalr */
> > +	u32 call[2] = { insn1, insn2 };
> > +	s32 imm;
> > +
> > +	/* get and adjust new target address */
> > +	imm = riscv_insn_extract_utype_itype_imm(insn1, insn2);
> > +	imm -= patch_offset;
> > +
> > +	/* update instructions */
> > +	riscv_insn_insert_utype_itype_imm(call, imm);
> > +
> > +	/* patch the call place again */
> > +	patch_text_nosync(ptr, call, sizeof(u32) * 2);
> > +}
> 
> Obv. I have not left R-b tags on stuff without trying to understand
> what's going on, but from a lay-observer point of view, I think these
> function names & flow does a good job of explaining some of the black
> magic in this neck of the woods.
> 
> > +
> > +void riscv_alternative_fix_offsets(void *alt_ptr, unsigned int len,
> > +				      int patch_offset)
> > +{
> > +	int num_instr = len / sizeof(u32);
> 
> instr...
> 
> > +	int i;
> > +
> > +	/*
> > +	 * stop one instruction before the end, as we're checking
> > +	 * for auipc + jalr
> > +	 */
> > +	for (i = 0; i < num_instr; i++) {
> > +		u32 inst = riscv_instruction_at(alt_ptr + i * sizeof(u32));
> 
> ...inst...
> 
> > +
> > +		/* may be the start of an auipc + jalr pair */
> > +		if (riscv_insn_is_auipc(inst) && i < num_instr - 1) {
> 
> ...insn.
> 
> Is there a reason for that?

I guess more of a generational issue - with the code spanning
too much time :-)

So poll question, what would be preferred?
I think I remember seeing all of them somewhere, so I'm unsure what
to standardize on.

> 
> Also, I've gotten myself slightly confused about the loop. You "stop one
> instruction before the end" but the main loop goes from 0 -> num_instr.
> The inner loop then checks for i < num_instr - 1. What am I missing that
> prevents the outer loop from stopping at num_instr - 1 instead?

The idea with this is to allow a
	if(riscv_insn_is_jal(inst))
		riscv_alternative_fix_jal(...)

etc, and everything else is a single instruction so needs one more
loop iteration, only for auipc+jalr do we want to stop one earlier.

So to get this alternatives_fix_offsets() main entry point I
made the loop do the one iteration more again.


> > +			u32 inst2 = riscv_instruction_at(alt_ptr + (i + 1) * sizeof(u32));
> > +
> > +			if (!riscv_insn_is_jalr(inst2))
> > +				continue;
> > +
> > +			/* call will use ra register */
> 
> Super minor, but "call will use ra register" is a little unclear. As
> written, it makes perfect sense when you've been staring at this code,
> but not so much if you're passing through.. How about:
> /* if this instruction pair is a call, it will use the ra register */

sure :-)

> 
> > +			if (RV_EXTRACT_RD_REG(inst) != 1)
> > +				continue;
> >
> 
> All minor stuff though, so you can re-add my R-b either way:
> Reviewed-by: Conor Dooley <conor.dooley@microchip.com>

thanks :-)

Heiko



_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  parent reply	other threads:[~2022-12-07 22:37 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-07 18:08 [PATCH v4 00/12] Allow calls in alternatives Heiko Stuebner
2022-12-07 18:08 ` [PATCH v4 01/12] RISC-V: fix funct4 definition for c.jalr in parse_asm.h Heiko Stuebner
2022-12-10 12:34   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 02/12] RISC-V: add prefix to all constants/macros " Heiko Stuebner
2022-12-10 12:45   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 03/12] RISC-V: detach funct-values from their offset Heiko Stuebner
2022-12-10 22:16   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 04/12] RISC-V: add ebreak instructions to definitions Heiko Stuebner
2022-12-10 23:08   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 05/12] RISC-V: add auipc elements to parse_asm header Heiko Stuebner
2022-12-10 23:28   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 06/12] RISC-V: Move riscv_insn_is_* macros into a common header Heiko Stuebner
2022-12-11 17:32   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 07/12] RISC-V: rename parse_asm.h to insn.h Heiko Stuebner
2022-12-11 17:33   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 08/12] RISC-V: kprobes: use central defined funct3 constants Heiko Stuebner
2022-12-11 17:34   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 09/12] RISC-V: add U-type imm parsing to insn.h header Heiko Stuebner
2022-12-11 17:36   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 10/12] RISC-V: add rd reg " Heiko Stuebner
2022-12-11 17:41   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 11/12] RISC-V: add helpers for handling immediates in U-type and I-type pairs Heiko Stuebner
2022-12-07 20:07   ` Conor Dooley
2022-12-07 22:43     ` Heiko Stuebner
2022-12-08 14:38   ` Andrew Jones
2022-12-22 13:46     ` Heiko Stübner
2022-12-11 20:45   ` Lad, Prabhakar
2022-12-07 18:08 ` [PATCH v4 12/12] RISC-V: fix auipc-jalr addresses in patched alternatives Heiko Stuebner
2022-12-07 20:48   ` Conor Dooley
2022-12-07 22:00     ` Jessica Clarke
2022-12-07 22:04       ` Conor Dooley
2022-12-07 22:37     ` Heiko Stuebner [this message]
2022-12-08  5:03       ` Conor.Dooley
2022-12-08 14:47   ` Andrew Jones
2022-12-11 20:49   ` Lad, Prabhakar

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=4261102.ElGaqSPkdT@phil \
    --to=heiko@sntech.de \
    --cc=ajones@ventanamicro.com \
    --cc=christoph.muellner@vrull.eu \
    --cc=conor@kernel.org \
    --cc=emil.renner.berthing@canonical.com \
    --cc=jszhang@kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=philipp.tomsich@vrull.eu \
    --cc=prabhakar.csengg@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.