Re: [RFC PATCH v2 04/10] lib: vdso: get pointer to vdso data from the arch

From: christophe leroy
Date: Tue Dec 24 2019 - 06:53:46 EST




Le 24/12/2019 Ã 03:27, Andy Lutomirski a ÃcritÂ:
On Mon, Dec 23, 2019 at 6:31 AM Christophe Leroy
<christophe.leroy@xxxxxx> wrote:

On powerpc, __arch_get_vdso_data() clobbers the link register,
requiring the caller to set a stack frame in order to save it.

As the parent function already has to set a stack frame and save
the link register to call the C vdso function, retriving the
vdso data pointer there is lighter.

I'm confused. Can't you inline __arch_get_vdso_data()? Or is the
issue that you can't retrieve the program counter on power without
clobbering the link register?

Yes it can be inlined (I did it in V1 https://patchwork.ozlabs.org/patch/1180571/), but you can't do it without clobbering the link register, because the only way to get the program counter is to do to as if you were calling another function but you call to the address which just follows where you are, so that it sets LR which the simulated return address which corresponds to the address following the branch.

static __always_inline
const struct vdso_data *__arch_get_vdso_data(void)
{
void *ptr;

asm volatile(
" bcl 20, 31, .+4;\n"
" mflr %0;\n"
" addi %0, %0, __kernel_datapage_offset - (.-4);\n"
: "=b"(ptr) : : "lr");

return ptr + *(unsigned long *)ptr;
}


I would imagine that this patch generates worse code on any
architecture with PC-relative addressing modes (which includes at
least x86_64, and I would guess includes most modern architectures).

Why ? Powerpc is also using PC-relative addressing for all calls but indirect calls.

As the other arch C VDSO callers are in C and written in such a way that callee is inlined into callers, and as __arch_get_vdso_data() is inlined, it should make no difference, shouldn't it ?

Christophe