Date: Sun, 23 Aug 2020 20:32:13 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r364530 - in head/sys: amd64/amd64 x86/include Message-ID: <202008232032.07NKWDWZ028079@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sun Aug 23 20:32:13 2020 New Revision: 364530 URL: https://svnweb.freebsd.org/changeset/base/364530 Log: Add amd64 procctl(2) ops to manage forced LA48/LA57 VA after exec. Tested by: pho (LA48 hardware) Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D25273 Modified: head/sys/amd64/amd64/vm_machdep.c head/sys/x86/include/procctl.h Modified: head/sys/amd64/amd64/vm_machdep.c ============================================================================== --- head/sys/amd64/amd64/vm_machdep.c Sun Aug 23 20:25:10 2020 (r364529) +++ head/sys/amd64/amd64/vm_machdep.c Sun Aug 23 20:32:13 2020 (r364530) @@ -377,23 +377,69 @@ cpu_exec_vmspace_reuse(struct proc *p, vm_map_t map) } static void -cpu_procctl_kpti(struct proc *p, int com, int *val) +cpu_procctl_kpti_ctl(struct proc *p, int val) { - if (com == PROC_KPTI_CTL) { - if (pti && *val == PROC_KPTI_CTL_ENABLE_ON_EXEC) - p->p_md.md_flags |= P_MD_KPTI; - if (*val == PROC_KPTI_CTL_DISABLE_ON_EXEC) - p->p_md.md_flags &= ~P_MD_KPTI; - } else /* PROC_KPTI_STATUS */ { - *val = (p->p_md.md_flags & P_MD_KPTI) != 0 ? - PROC_KPTI_CTL_ENABLE_ON_EXEC: - PROC_KPTI_CTL_DISABLE_ON_EXEC; - if (vmspace_pmap(p->p_vmspace)->pm_ucr3 != PMAP_NO_CR3) - *val |= PROC_KPTI_STATUS_ACTIVE; + if (pti && val == PROC_KPTI_CTL_ENABLE_ON_EXEC) + p->p_md.md_flags |= P_MD_KPTI; + if (val == PROC_KPTI_CTL_DISABLE_ON_EXEC) + p->p_md.md_flags &= ~P_MD_KPTI; +} + +static void +cpu_procctl_kpti_status(struct proc *p, int *val) +{ + *val = (p->p_md.md_flags & P_MD_KPTI) != 0 ? + PROC_KPTI_CTL_ENABLE_ON_EXEC: + PROC_KPTI_CTL_DISABLE_ON_EXEC; + if (vmspace_pmap(p->p_vmspace)->pm_ucr3 != PMAP_NO_CR3) + *val |= PROC_KPTI_STATUS_ACTIVE; +} + +static int +cpu_procctl_la_ctl(struct proc *p, int val) +{ + int error; + + error = 0; + switch (val) { + case PROC_LA_CTL_LA48_ON_EXEC: + p->p_md.md_flags |= P_MD_LA48; + p->p_md.md_flags &= ~P_MD_LA57; + break; + case PROC_LA_CTL_LA57_ON_EXEC: + if (la57) { + p->p_md.md_flags &= ~P_MD_LA48; + p->p_md.md_flags |= P_MD_LA57; + } else { + error = ENOTSUP; + } + break; + case PROC_LA_CTL_DEFAULT_ON_EXEC: + p->p_md.md_flags &= ~(P_MD_LA48 | P_MD_LA57); + break; } + return (error); } +static void +cpu_procctl_la_status(struct proc *p, int *val) +{ + int res; + + if ((p->p_md.md_flags & P_MD_LA48) != 0) + res = PROC_LA_CTL_LA48_ON_EXEC; + else if ((p->p_md.md_flags & P_MD_LA57) != 0) + res = PROC_LA_CTL_LA57_ON_EXEC; + else + res = PROC_LA_CTL_DEFAULT_ON_EXEC; + if (p->p_sysent->sv_maxuser == VM_MAXUSER_ADDRESS_LA48) + res |= PROC_LA_STATUS_LA48; + else + res |= PROC_LA_STATUS_LA57; + *val = res; +} + int cpu_procctl(struct thread *td, int idtype, id_t id, int com, void *data) { @@ -403,6 +449,8 @@ cpu_procctl(struct thread *td, int idtype, id_t id, in switch (com) { case PROC_KPTI_CTL: case PROC_KPTI_STATUS: + case PROC_LA_CTL: + case PROC_LA_STATUS: if (idtype != P_PID) { error = EINVAL; break; @@ -412,22 +460,45 @@ cpu_procctl(struct thread *td, int idtype, id_t id, in error = priv_check(td, PRIV_IO); if (error != 0) break; + } + if (com == PROC_KPTI_CTL || com == PROC_LA_CTL) { error = copyin(data, &val, sizeof(val)); if (error != 0) break; - if (val != PROC_KPTI_CTL_ENABLE_ON_EXEC && - val != PROC_KPTI_CTL_DISABLE_ON_EXEC) { - error = EINVAL; - break; - } } + if (com == PROC_KPTI_CTL && + val != PROC_KPTI_CTL_ENABLE_ON_EXEC && + val != PROC_KPTI_CTL_DISABLE_ON_EXEC) { + error = EINVAL; + break; + } + if (com == PROC_LA_CTL && + val != PROC_LA_CTL_LA48_ON_EXEC && + val != PROC_LA_CTL_LA57_ON_EXEC && + val != PROC_LA_CTL_DEFAULT_ON_EXEC) { + error = EINVAL; + break; + } error = pget(id, PGET_CANSEE | PGET_NOTWEXIT | PGET_NOTID, &p); - if (error == 0) { - cpu_procctl_kpti(p, com, &val); - PROC_UNLOCK(p); - if (com == PROC_KPTI_STATUS) - error = copyout(&val, data, sizeof(val)); + if (error != 0) + break; + switch (com) { + case PROC_KPTI_CTL: + cpu_procctl_kpti_ctl(p, val); + break; + case PROC_KPTI_STATUS: + cpu_procctl_kpti_status(p, &val); + break; + case PROC_LA_CTL: + error = cpu_procctl_la_ctl(p, val); + break; + case PROC_LA_STATUS: + cpu_procctl_la_status(p, &val); + break; } + PROC_UNLOCK(p); + if (com == PROC_KPTI_STATUS || com == PROC_LA_STATUS) + error = copyout(&val, data, sizeof(val)); break; default: error = EINVAL; Modified: head/sys/x86/include/procctl.h ============================================================================== --- head/sys/x86/include/procctl.h Sun Aug 23 20:25:10 2020 (r364529) +++ head/sys/x86/include/procctl.h Sun Aug 23 20:32:13 2020 (r364530) @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * - * Copyright (c) 2019 The FreeBSD Foundation + * Copyright (c) 2019,2020 The FreeBSD Foundation * * Portions of this software were developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. @@ -35,9 +35,18 @@ #define PROC_KPTI_CTL (PROC_PROCCTL_MD_MIN + 0) #define PROC_KPTI_STATUS (PROC_PROCCTL_MD_MIN + 1) +#define PROC_LA_CTL (PROC_PROCCTL_MD_MIN + 2) +#define PROC_LA_STATUS (PROC_PROCCTL_MD_MIN + 3) #define PROC_KPTI_CTL_ENABLE_ON_EXEC 1 #define PROC_KPTI_CTL_DISABLE_ON_EXEC 2 #define PROC_KPTI_STATUS_ACTIVE 0x80000000 + +#define PROC_LA_CTL_LA48_ON_EXEC 1 +#define PROC_LA_CTL_LA57_ON_EXEC 2 +#define PROC_LA_CTL_DEFAULT_ON_EXEC 3 + +#define PROC_LA_STATUS_LA48 0x01000000 +#define PROC_LA_STATUS_LA57 0x02000000 #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202008232032.07NKWDWZ028079>