cregit-Linux how code gets into the kernel

Release 4.18 arch/arm64/kernel/ssbd.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2018 ARM Ltd, All Rights Reserved.
 */

#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/thread_info.h>

#include <asm/cpufeature.h>

/*
 * prctl interface for SSBD
 * FIXME: Drop the below ifdefery once merged in 4.18.
 */
#ifdef PR_SPEC_STORE_BYPASS

static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl) { int state = arm64_get_ssbd_state(); /* Unsupported */ if (state == ARM64_SSBD_UNKNOWN) return -EINVAL; /* Treat the unaffected/mitigated state separately */ if (state == ARM64_SSBD_MITIGATED) { switch (ctrl) { case PR_SPEC_ENABLE: return -EPERM; case PR_SPEC_DISABLE: case PR_SPEC_FORCE_DISABLE: return 0; } } /* * Things are a bit backward here: the arm64 internal API * *enables the mitigation* when the userspace API *disables * speculation*. So much fun. */ switch (ctrl) { case PR_SPEC_ENABLE: /* If speculation is force disabled, enable is not allowed */ if (state == ARM64_SSBD_FORCE_ENABLE || task_spec_ssb_force_disable(task)) return -EPERM; task_clear_spec_ssb_disable(task); clear_tsk_thread_flag(task, TIF_SSBD); break; case PR_SPEC_DISABLE: if (state == ARM64_SSBD_FORCE_DISABLE) return -EPERM; task_set_spec_ssb_disable(task); set_tsk_thread_flag(task, TIF_SSBD); break; case PR_SPEC_FORCE_DISABLE: if (state == ARM64_SSBD_FORCE_DISABLE) return -EPERM; task_set_spec_ssb_disable(task); task_set_spec_ssb_force_disable(task); set_tsk_thread_flag(task, TIF_SSBD); break; default: return -ERANGE; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Marc Zyngier167100.00%1100.00%
Total167100.00%1100.00%


int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, unsigned long ctrl) { switch (which) { case PR_SPEC_STORE_BYPASS: return ssbd_prctl_set(task, ctrl); default: return -ENODEV; } }

Contributors

PersonTokensPropCommitsCommitProp
Marc Zyngier40100.00%1100.00%
Total40100.00%1100.00%


static int ssbd_prctl_get(struct task_struct *task) { switch (arm64_get_ssbd_state()) { case ARM64_SSBD_UNKNOWN: return -EINVAL; case ARM64_SSBD_FORCE_ENABLE: return PR_SPEC_DISABLE; case ARM64_SSBD_KERNEL: if (task_spec_ssb_force_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; if (task_spec_ssb_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_DISABLE; return PR_SPEC_PRCTL | PR_SPEC_ENABLE; case ARM64_SSBD_FORCE_DISABLE: return PR_SPEC_ENABLE; default: return PR_SPEC_NOT_AFFECTED; } }

Contributors

PersonTokensPropCommitsCommitProp
Marc Zyngier73100.00%1100.00%
Total73100.00%1100.00%


int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) { switch (which) { case PR_SPEC_STORE_BYPASS: return ssbd_prctl_get(task); default: return -ENODEV; } }

Contributors

PersonTokensPropCommitsCommitProp
Marc Zyngier34100.00%1100.00%
Total34100.00%1100.00%

#endif /* PR_SPEC_STORE_BYPASS */

Overall Contributors

PersonTokensPropCommitsCommitProp
Marc Zyngier335100.00%1100.00%
Total335100.00%1100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.