Re: [PATCH v5 4/5] powerpc/vdso: Wire up getrandom() vDSO implementation on VDSO32

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

 



On Thu, Sep 05, 2024 at 10:41:40PM +0200, Jason A. Donenfeld wrote:
> On Thu, Sep 05, 2024 at 06:13:29PM +0200, Jason A. Donenfeld wrote:
> > > +/*
> > > + * The macro sets two stack frames, one for the caller and one for the callee
> > > + * because there are no requirement for the caller to set a stack frame when
> > > + * calling VDSO so it may have omitted to set one, especially on PPC64
> > > + */
> > > +
> > > +.macro cvdso_call funct
> > > +  .cfi_startproc
> > > +	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
> > > +  .cfi_adjust_cfa_offset PPC_MIN_STKFRM
> > > +	mflr		r0
> > > +	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
> > > +  .cfi_adjust_cfa_offset PPC_MIN_STKFRM
> > > +	PPC_STL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
> > > +  .cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF
> > > +	get_datapage	r8
> > > +	addi		r8, r8, VDSO_RNG_DATA_OFFSET
> > > +	bl		CFUNC(DOTSYM(\funct))
> > > +	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
> > > +	cmpwi		r3, 0
> > > +	mtlr		r0
> > > +	addi		r1, r1, 2 * PPC_MIN_STKFRM
> > > +  .cfi_restore lr
> > > +  .cfi_def_cfa_offset 0
> > > +	crclr		so
> > > +	bgelr+
> > > +	crset		so
> > > +	neg		r3, r3
> > > +	blr
> > > +  .cfi_endproc
> > > +.endm
> > 
> > Can you figure out what's going on and send a fix, which I'll squash
> > into this commit?
> 
> This doesn't work, but I wonder if something like it is what we want. I
> need to head out for the day, but here's what I've got. It's all wrong
> but might be of interest.

Oh, I just got one small detail wrong before. The below actually works,
and uses the same strategy as on arm64.

Let me know if you'd like me to fix up this commit with the below patch,
or if you have another way you'd like to go about it.

diff --git a/arch/powerpc/include/asm/vdso/getrandom.h b/arch/powerpc/include/asm/vdso/getrandom.h
index 501d6bb14e8a..acb271709d30 100644
--- a/arch/powerpc/include/asm/vdso/getrandom.h
+++ b/arch/powerpc/include/asm/vdso/getrandom.h
@@ -47,7 +47,8 @@ static __always_inline struct vdso_rng_data *__arch_get_vdso_rng_data(void)
 }

 ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
-			     size_t opaque_len, const struct vdso_rng_data *vd);
+			     size_t opaque_len, const struct vdso_data *vd,
+			     const struct vdso_rng_data *vrd);

 #endif /* !__ASSEMBLY__ */

diff --git a/arch/powerpc/kernel/vdso/getrandom.S b/arch/powerpc/kernel/vdso/getrandom.S
index a957cd2b2b03..64cc1fad3ccc 100644
--- a/arch/powerpc/kernel/vdso/getrandom.S
+++ b/arch/powerpc/kernel/vdso/getrandom.S
@@ -32,7 +32,8 @@
   .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
 #endif
 	get_datapage	r8
-	addi		r8, r8, VDSO_RNG_DATA_OFFSET
+	addi		r9, r8, VDSO_RNG_DATA_OFFSET
+	addi		r8, r8, VDSO_DATA_OFFSET
 	bl		CFUNC(DOTSYM(\funct))
 	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
 #ifdef __powerpc64__
diff --git a/arch/powerpc/kernel/vdso/vgetrandom.c b/arch/powerpc/kernel/vdso/vgetrandom.c
index 5f855d45fb7b..408c76036868 100644
--- a/arch/powerpc/kernel/vdso/vgetrandom.c
+++ b/arch/powerpc/kernel/vdso/vgetrandom.c
@@ -8,7 +8,10 @@
 #include <linux/types.h>

 ssize_t __c_kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state,
-			     size_t opaque_len, const struct vdso_rng_data *vd)
+			     size_t opaque_len, const struct vdso_data *vd,
+			     const struct vdso_rng_data *vrd)
 {
-	return __cvdso_getrandom_data(vd, buffer, len, flags, opaque_state, opaque_len);
+	if (IS_ENABLED(CONFIG_TIME_NS) && vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
+		vrd = (void *)vrd + (1UL << CONFIG_PAGE_SHIFT);
+	return __cvdso_getrandom_data(vrd, buffer, len, flags, opaque_state, opaque_len);
 }





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

  Powered by Linux