mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
Userspace specifies CLONE_VM to share address space and spawn new thread. 'clone' allows userspace to specify a new stack for a new thread. However there is no way to specify a new shadow stack base address without changing the API. This patch allocates a new shadow stack whenever CLONE_VM is given. In case of CLONE_VFORK, the parent is suspended until the child finishes; thus the child can use the parent's shadow stack. In case of !CLONE_VM, COW kicks in because entire address space is copied from parent to child. 'clone3' is extensible and can provide mechanisms for specifying the shadow stack as an input parameter. This is not settled yet and is being extensively discussed on the mailing list. Once that's settled, this code should be adapted. Reviewed-by: Zong Li <zong.li@sifive.com> Signed-off-by: Deepak Gupta <debug@rivosinc.com> Tested-by: Andreas Korb <andreas.korb@aisec.fraunhofer.de> # QEMU, custom CVA6 Tested-by: Valentin Haudiquet <valentin.haudiquet@canonical.com> Link: https://patch.msgid.link/20251112-v5_user_cfi_series-v23-11-b55691eacf4f@rivosinc.com [pjw@kernel.org: cleaned up patch description] Signed-off-by: Paul Walmsley <pjw@kernel.org>
61 lines
1.3 KiB
C
61 lines
1.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (C) 2012 Regents of the University of California
|
|
* Copyright (C) 2017 SiFive
|
|
*/
|
|
|
|
#ifndef _ASM_RISCV_MMU_CONTEXT_H
|
|
#define _ASM_RISCV_MMU_CONTEXT_H
|
|
|
|
#include <linux/mm_types.h>
|
|
#include <asm-generic/mm_hooks.h>
|
|
|
|
#include <linux/mm.h>
|
|
#include <linux/sched.h>
|
|
|
|
void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|
struct task_struct *task);
|
|
|
|
#define activate_mm activate_mm
|
|
static inline void activate_mm(struct mm_struct *prev,
|
|
struct mm_struct *next)
|
|
{
|
|
#ifdef CONFIG_RISCV_ISA_SUPM
|
|
next->context.pmlen = 0;
|
|
#endif
|
|
switch_mm(prev, next, NULL);
|
|
}
|
|
|
|
#define init_new_context init_new_context
|
|
static inline int init_new_context(struct task_struct *tsk,
|
|
struct mm_struct *mm)
|
|
{
|
|
#ifdef CONFIG_MMU
|
|
atomic_long_set(&mm->context.id, 0);
|
|
#endif
|
|
if (IS_ENABLED(CONFIG_RISCV_ISA_SUPM))
|
|
clear_bit(MM_CONTEXT_LOCK_PMLEN, &mm->context.flags);
|
|
return 0;
|
|
}
|
|
|
|
DECLARE_STATIC_KEY_FALSE(use_asid_allocator);
|
|
|
|
#ifdef CONFIG_RISCV_ISA_SUPM
|
|
#define mm_untag_mask mm_untag_mask
|
|
static inline unsigned long mm_untag_mask(struct mm_struct *mm)
|
|
{
|
|
return -1UL >> mm->context.pmlen;
|
|
}
|
|
#endif
|
|
|
|
#define deactivate_mm deactivate_mm
|
|
static inline void deactivate_mm(struct task_struct *tsk,
|
|
struct mm_struct *mm)
|
|
{
|
|
shstk_release(tsk);
|
|
}
|
|
|
|
#include <asm-generic/mmu_context.h>
|
|
|
|
#endif /* _ASM_RISCV_MMU_CONTEXT_H */
|