[RFC PATCH v3 07/11] arm64: compat: Add a 32-bit vDSO
Nathan Lynch
nathan_lynch at mentor.com
Wed Dec 7 10:51:01 PST 2016
Hi Kevin,
Kevin Brodsky <kevin.brodsky at arm.com> writes:
> diff --git a/arch/arm64/kernel/vdso32/vgettimeofday.c b/arch/arm64/kernel/vdso32/vgettimeofday.c
> new file mode 100644
> index 000000000000..53c3d1f82b26
> --- /dev/null
> +++ b/arch/arm64/kernel/vdso32/vgettimeofday.c
As I said at LPC last month, I'm not excited to have arch/arm's
vgettimeofday.c copied into arch/arm64 and tweaked; I'd rather see this
part of the implementation shared between arch/arm and arch/arm64
somehow, even if there's not an elegant way to do so.
The situation which must be avoided is one where the arch/arm64 compat
VDSO incompatibly diverges from the arch/arm VDSO. That becomes much
less likely if there's only one copy of the userspace-exposed code to
maintain.
[...]
> +/*
> + * We use the hidden visibility to prevent the compiler from generating a GOT
> + * relocation. Not only is going through a GOT useless (the entry couldn't and
> + * musn't be overridden by another library), it does not even work: the linker
> + * cannot generate an absolute address to the data page.
> + *
> + * With the hidden visibility, the compiler simply generates a PC-relative
> + * relocation (R_ARM_REL32), and this is what we need.
> + */
> +extern const struct vdso_data _vdso_data __attribute__((visibility("hidden")));
> +
> +static inline const struct vdso_data *get_vdso_data(void)
> +{
> + const struct vdso_data *ret;
> + /*
> + * This simply puts &_vdso_data into ret. The reason why we don't use
> + * `ret = &_vdso_data` is that the compiler tends to optimise this in a
> + * very suboptimal way: instead of keeping &_vdso_data in a register,
> + * it goes through a relocation almost every time _vdso_data must be
> + * accessed (even in subfunctions). This is both time and space
> + * consuming: each relocation uses a word in the code section, and it
> + * has to be loaded at runtime.
> + *
> + * This trick hides the assignment from the compiler. Since it cannot
> + * track where the pointer comes from, it will only use one relocation
> + * where get_vdso_data() is called, and then keep the result in a
> + * register.
> + */
> + asm("mov %0, %1" : "=r"(ret) : "r"(&_vdso_data));
> + return ret;
> +}
I think this is an instructive case: this code looks like an improvement
over how the arch/arm VDSO accesses the data page. Enhancements like
this (not to mention fixes) shouldn't require a patch-per-architecture;
things inevitably get out of sync and it's more of a maintenance burden
in the long term.
More information about the linux-arm-kernel
mailing list