Re: [PATCH v3 11/14] RISC-V: fix auipc-jalr addresses in patched alternatives

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Dec 07, 2022 at 10:35:50AM +0100, Heiko Stübner wrote:
> Am Dienstag, 6. Dezember 2022, 23:10:01 CET schrieb Heiko Stübner:
> > Am Donnerstag, 1. Dezember 2022, 20:33:53 CET schrieb Andrew Jones:
> > > On Wed, Nov 30, 2022 at 11:56:11PM +0100, Heiko Stuebner wrote:
> > > > From: Heiko Stuebner <heiko.stuebner@xxxxxxxx>
...
> > > > +#define to_auipc_imm(value)						\
> > > > +	((value & JALR_SIGN_MASK) ?					\
> > > > +	((value & RV_U_IMM_31_12_MASK) + AUIPC_PAD) :	\
> > > > +	(value & RV_U_IMM_31_12_MASK))
> > > 
> > > I know RV_U_IMM_31_12_OPOFF is 0, but it looks odd not shifting
> > > RV_U_IMM_31_12_MASK when we do shift RV_I_IMM_11_0_MASK.
> > > 
> > > So, it looks like to_auipc_imm() is doing
> > > 
> > >    offset[31:12] + ((value & BIT(11)) ? (1 << 12) : 0)
> > > 
> > > but the spec says the auipc part of the 'call' pseudoinstruction should be
> > 
> > can you point me to that part of the spec?
> > 
> > For educational purposes, because in the main riscv-spec I only found
> > the main auipc + jalr descriptions, but nothing about the actual
> > "call" pseudoinstruction.
> > 
> > [and I'm probably just looking at the wrong document]
> > 
> > 
> > >    offset[31:12] + offset[11]
> > >  
> > > which I think would be written as
> > > 
> > >  ((((value) & RV_U_IMM_31_12_MASK) << RV_U_IMM_31_12_OPOFF) + ((value) & BIT(11)))
> > > 
> > > or what am I missing?
> 
> So far I've found the riscv-asm-manual [0], which only states for call
> 	auipc x1, offset[31:12]
> 	jalr x1, x1, offset[11:0]
> 
> and the psABI spec [1], neither mention your "offset[31:12] + offset[11]" ?
> 
> But [1] does contain that tiny sentence
> "The successive instruction has a signed 12-bit immediate so the value
>  of the preceding high 20-bit relocation may have 1 added to it."
> 
> 
> I.e. the lower 12 bits become themself a signed number [-2048:2047]
> 
> Take an example:
> - address is 1862116 ( 0b 111000110 100111100100 )
> - address[31:12] becomes 1859584 (as 0b 111000110 000000000000)
> - while address[11:0] is 2532 as part of the bigger number
> - as lone 12bit signed IMM it becomes -1564
> - so you need to add this 4096 to the auipc IMM to compensate
> 
> 
> Heiko
> 
> 
> [0] https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md
> [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/releases/tag/v1.0

Yeah, I got this figured out yesterday and sent another mail confirming
the way you had it was right. Did you receive that mail?

Where I see 

 call offset     auipc x1, offset[31 : 12] + offset[11]
                 jalr x1, offset[11:0](x1)

is in chapter 25 of the unprivileged ISA.

> 
> > 
> > that whole thing came from the ftrace parts, also doing call fixup voodoo
> > And I can't really say that I understand every nook and cranny of it.
> > 
> > But for practical purposes, the addresses generated now work,
> > and also seem to work for the ftrace counterpart (see include/asm/ftrace.h)
> > 
> > [another place that will profit from more generalization :-) ]
> > 
> > 
> > > > +
> > > > +void riscv_alternative_fix_auipc_jalr(void *alt_ptr, unsigned int len,
> > > > +				      int patch_offset)
> > > > +{
> > > > +	int num_instr = len / sizeof(u32);
> > > > +	unsigned int call[2];
> > > > +	int i;
> > > > +	int imm;
> > > > +	u32 rd1;
> > > > +
> > > > +	/*
> > > > +	 * stop one instruction before the end, as we're checking
> > > > +	 * for auipc + jalr
> > > > +	 */
> > > > +	for (i = 0; i < num_instr - 1; i++) {
> > > 
> > > If we change riscv_instruction_at() to just take a pointer then we can do
> > > the math in the for() and actually just use pointer arithmetic.
> > > 
> > >         uint32_t *p = alt_ptr;
> > >         for (i = 0; i < num_instr - 1; i++, p++) {
> > 
> > Wasn't not using uint32 pointers the whole point of going with the accessor?

Oh, right. So maybe stick to the offsetting, but still do the math in the
caller.

Thanks,
drew



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux