Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions arch/arm64/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,17 +165,21 @@
NEW_AUX_ENT(AT_IGNORE, 0); \
} while (0)

#define ARCH_HAS_SETUP_ADDITIONAL_PAGES

Check failure on line 168 in arch/arm64/include/asm/elf.h

View workflow job for this annotation

GitHub Actions / checkpatch review

ERROR: #define of 'ARCH_HAS_SETUP_ADDITIONAL_PAGES' is wrong - use Kconfig variables or standard guards instead
struct linux_binprm;
extern int aarch64_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);

#ifdef CONFIG_CHERI_PURECAP_UABI
extern int purecap_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);
#define arch_setup_additional_pages purecap_setup_additional_pages
#define ARCH_DLINFO SETUP_DLINFO(current->mm->context.vdso)
#else /* !CONFIG_CHERI_PURECAP_UABI */
#define arch_setup_additional_pages aarch64_setup_additional_pages
#define ARCH_DLINFO SETUP_DLINFO((elf_addr_t)current->mm->context.vdso)
#endif /* CONFIG_CHERI_PURECAP_UABI */

#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
struct linux_binprm;
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);

/* 1GB of VA */
#ifdef CONFIG_COMPAT32
#define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \
Expand Down Expand Up @@ -210,6 +214,8 @@

#define COMPAT_ARCH_DLINFO SETUP_DLINFO(current->mm->context.vdso)

#define compat_arch_setup_additional_pages aarch64_setup_additional_pages

#else /* !CONFIG_COMPAT64 */

/* AArch32 registers. */
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/include/asm/vdso.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

extern char vdso_start[], vdso_end[];
extern char vdso32_start[], vdso32_end[];
extern char vdso_purecap_start[], vdso_purecap_end[];

#endif /* !__ASSEMBLER__ */

Expand Down
26 changes: 26 additions & 0 deletions arch/arm64/include/asm/vdso/gettimeofday.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,32 @@ const struct vdso_data *__arch_get_vdso_data(void)
return vd;
}

static __always_inline
const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
{
const struct vdso_time_data *ret;

asm(".hidden vdso_u_time_data\n\t"
"adrp %0, vdso_u_time_data\n\t"
"add %0, %0, #:lo12:vdso_u_time_data"
: "=C"(ret));
return ret;
}

static __always_inline
const struct vdso_rng_data *__arch_get_vdso_u_rng_data(void)
{
const struct vdso_rng_data *ret;

asm(".hidden vdso_u_rng_data\n\t"
"adrp %0, vdso_u_rng_data\n\t"
"add %0, %0, #:lo12:vdso_u_rng_data"
: "=C"(ret));
return ret;
}

#define __arch_get_vdso_u_time_data __arch_get_vdso_u_time_data
#define __arch_get_vdso_u_rng_data __arch_get_vdso_u_rng_data
#else /* !__CHERI_PURE_CAPABILITY__ */
#if IS_ENABLED(CONFIG_CC_IS_GCC) && IS_ENABLED(CONFIG_PAGE_SIZE_64KB)
static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
Expand Down
2 changes: 2 additions & 0 deletions arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ obj-$(CONFIG_ARM64_MTE) += mte.o
obj-$(CONFIG_ARM64_MORELLO) += morello.o
obj-y += vdso-wrap.o
obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o
obj-$(CONFIG_CHERI_PURECAP_UABI) += vdso-purecap-wrap.o

# Force dependency (vdso*-wrap.S includes vdso.so through incbin)
$(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so
$(obj)/vdso32-wrap.o: $(obj)/vdso32/vdso.so
$(obj)/vdso-purecap-wrap.o: $(obj)/vdso-purecap/vdso.so

obj-y += probes/
obj-y += head.o
Expand Down
5 changes: 5 additions & 0 deletions arch/arm64/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
#endif
#include <asm/traps.h>
#include <asm/vdso.h>
#if defined(CONFIG_CHERI_PURECAP_UABI) && !defined(SIGNAL_COMPAT64)
#include <generated/vdso-purecap-offsets.h>
#else
#include <generated/vdso-offsets.h>
#endif

#define GCS_SIGNAL_CAP(addr) (((unsigned long)addr) & GCS_CAP_ADDR_MASK)

Expand Down
22 changes: 22 additions & 0 deletions arch/arm64/kernel/vdso-purecap-wrap.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2023 ARM Limited
*/

#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/const.h>
#include <asm/assembler.h>
#include <asm/page.h>

.globl vdso_purecap_start, vdso_purecap_end
.section .rodata
.balign PAGE_SIZE
vdso_purecap_start:
.incbin "arch/arm64/kernel/vdso-purecap/vdso.so"
.balign PAGE_SIZE
vdso_purecap_end:

.previous

emit_aarch64_feature_1_and
45 changes: 44 additions & 1 deletion arch/arm64/kernel/vdso.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
enum vdso_abi {
VDSO_ABI_AA64,
VDSO_ABI_AA32,
VDSO_ABI_PURECAP,
};

struct vdso_abi_info {
Expand All @@ -56,6 +57,13 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = {
.vdso_code_end = vdso32_end,
},
#endif /* CONFIG_COMPAT_VDSO */
#ifdef CONFIG_CHERI_PURECAP_UABI
[VDSO_ABI_PURECAP] = {
.name = "vdso_purecap",
.vdso_code_start = vdso_purecap_start,
.vdso_code_end = vdso_purecap_end,
},
#endif /* CONFIG_CHERI_PURECAP_UABI */
};

static user_uintptr_t make_vdso_ptr(struct vm_area_struct *vdso_text_vma)
Expand Down Expand Up @@ -340,6 +348,41 @@ int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
}
#endif /* CONFIG_COMPAT32 */

#ifdef CONFIG_CHERI_PURECAP_UABI
enum purecap_map {
PURECAP_MAP_VDSO,
};

static struct vm_special_mapping purecap_vdso_maps[] __ro_after_init = {
[PURECAP_MAP_VDSO] = {
.name = "[vdso]",
.mremap = vdso_mremap,
},
};

static int __init purecap_vdso_init(void)
{
vdso_info[VDSO_ABI_PURECAP].cm = &purecap_vdso_maps[PURECAP_MAP_VDSO];

return __vdso_init(VDSO_ABI_PURECAP);
}
arch_initcall(purecap_vdso_init);

int purecap_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
struct mm_struct *mm = current->mm;
int ret;

if (mmap_write_lock_killable(mm))
return -EINTR;

ret = __setup_additional_pages(VDSO_ABI_PURECAP, mm, bprm, uses_interp);
mmap_write_unlock(mm);

return ret;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this was basically a copy/paste of the AA64 handlers below. Let's update it accordingly, now that vvar is gone this can be a lot simpler.

enum aarch64_map below should also be removed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aarch64_map is removed now. Do you think it could be simplified more than this?

#endif /* CONFIG_CHERI_PURECAP_UABI */

static struct vm_special_mapping aarch64_vdso_map __ro_after_init = {
.name = "[vdso]",
.mremap = vdso_mremap,
Expand All @@ -353,7 +396,7 @@ static int __init vdso_init(void)
}
arch_initcall(vdso_init);

int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
int aarch64_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
struct mm_struct *mm = current->mm;
int ret;
Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/arm64/morello/bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ int verify_auxval(struct morello_auxv *auxv)
case AT_PLATFORM:
case AT_RANDOM:
case AT_PHDR:
case AT_SYSINFO_EHDR:
case AT_CHERI_EXEC_RX_CAP:
case AT_CHERI_STACK_CAP:
case AT_CHERI_SEAL_CAP:
Expand Down
Loading