-/* $OpenBSD: cpu.c,v 1.92 2023/05/30 08:30:00 jsg Exp $ */
+/* $OpenBSD: cpu.c,v 1.93 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
{
uint64_t id_aa64mmfr1, sctlr;
uint64_t id_aa64pfr0;
+ uint64_t id_aa64isar1;
uint64_t tcr;
WRITE_SPECIALREG(ttbr0_el1, pmap_kernel()->pm_pt0pa);
if (ID_AA64PFR0_DIT(id_aa64pfr0) >= ID_AA64PFR0_DIT_IMPL)
__asm volatile (".arch armv8.4-a; msr dit, #1");
+ /* Enable PAuth. */
+ id_aa64isar1 = READ_SPECIALREG(id_aa64isar1_el1);
+ if (ID_AA64ISAR1_API(id_aa64isar1) >= ID_AA64ISAR1_API_BASE ||
+ ID_AA64ISAR1_APA(id_aa64isar1) >= ID_AA64ISAR1_APA_BASE) {
+ sctlr = READ_SPECIALREG(sctlr_el1);
+ sctlr |= SCTLR_EnIA | SCTLR_EnDA;
+ sctlr |= SCTLR_EnIB | SCTLR_EnDB;
+ WRITE_SPECIALREG(sctlr_el1, sctlr);
+ }
+
/* Initialize debug registers. */
WRITE_SPECIALREG(mdscr_el1, DBG_MDSCR_TDCC);
WRITE_SPECIALREG(oslar_el1, 0);
-/* $OpenBSD: machdep.c,v 1.81 2023/04/24 10:22:48 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.82 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
* Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
cpu_switchto_asm(old, new);
}
-extern uint64_t cpu_id_aa64isar0;
-extern uint64_t cpu_id_aa64isar1;
-extern uint64_t cpu_id_aa64pfr0;
-extern uint64_t cpu_id_aa64pfr1;
-
/*
* machine dependent system variables.
*/
setregs(struct proc *p, struct exec_package *pack, u_long stack,
struct ps_strings *arginfo)
{
+ struct pmap *pm = p->p_vmspace->vm_map.pmap;
struct pcb *pcb = &p->p_addr->u_pcb;
struct trapframe *tf = pcb->pcb_tf;
if (pack->ep_flags & EXEC_NOBTCFI)
- p->p_vmspace->vm_map.pmap->pm_guarded = 0;
+ pm->pm_guarded = 0;
else
- p->p_vmspace->vm_map.pmap->pm_guarded = ATTR_GP;
+ pm->pm_guarded = ATTR_GP;
+
+ arc4random_buf(&pm->pm_apiakey, sizeof(pm->pm_apiakey));
+ arc4random_buf(&pm->pm_apdakey, sizeof(pm->pm_apdakey));
+ arc4random_buf(&pm->pm_apibkey, sizeof(pm->pm_apibkey));
+ arc4random_buf(&pm->pm_apdbkey, sizeof(pm->pm_apdbkey));
+ arc4random_buf(&pm->pm_apgakey, sizeof(pm->pm_apgakey));
+ pmap_setpauthkeys(pm);
/* If we were using the FPU, forget about it. */
memset(&pcb->pcb_fpstate, 0, sizeof(pcb->pcb_fpstate));
-/* $OpenBSD: pmap.c,v 1.96 2023/04/16 11:14:26 kettenis Exp $ */
+/* $OpenBSD: pmap.c,v 1.97 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com>
*
pted, vp3->l3[VP_IDX3(va)], VP_IDX3(va)*8);
}
+void
+pmap_setpauthkeys(struct pmap *pm)
+{
+ if (ID_AA64ISAR1_API(cpu_id_aa64isar1) >= ID_AA64ISAR1_API_BASE ||
+ ID_AA64ISAR1_APA(cpu_id_aa64isar1) >= ID_AA64ISAR1_APA_BASE) {
+ __asm volatile (".arch armv8.3-a; msr apiakeylo_el1, %0"
+ :: "r"(pm->pm_apiakey[0]));
+ __asm volatile (".arch armv8.3-a; msr apiakeyhi_el1, %0"
+ :: "r"(pm->pm_apiakey[1]));
+ __asm volatile (".arch armv8.3-a; msr apdakeylo_el1, %0"
+ :: "r"(pm->pm_apdakey[0]));
+ __asm volatile (".arch armv8.3-a; msr apdakeyhi_el1, %0"
+ :: "r"(pm->pm_apdakey[1]));
+ __asm volatile (".arch armv8.3-a; msr apibkeylo_el1, %0"
+ :: "r"(pm->pm_apibkey[0]));
+ __asm volatile (".arch armv8.3-a; msr apibkeyhi_el1, %0"
+ :: "r"(pm->pm_apibkey[1]));
+ __asm volatile (".arch armv8.3-a; msr apdbkeylo_el1, %0"
+ :: "r"(pm->pm_apdbkey[0]));
+ __asm volatile (".arch armv8.3-a; msr apdbkeyhi_el1, %0"
+ :: "r"(pm->pm_apdbkey[1]));
+ }
+
+ if (ID_AA64ISAR1_GPI(cpu_id_aa64isar1) >= ID_AA64ISAR1_GPI_IMPL ||
+ ID_AA64ISAR1_GPA(cpu_id_aa64isar1) >= ID_AA64ISAR1_GPA_IMPL) {
+ __asm volatile (".arch armv8.3-a; msr apgakeylo_el1, %0"
+ :: "r"(pm->pm_apgakey[0]));
+ __asm volatile (".arch armv8.3-a; msr apgakeyhi_el1, %0"
+ :: "r"(pm->pm_apgakey[1]));
+ }
+}
+
void
pmap_setttb(struct proc *p)
{
(pm->pm_asid & ~PMAP_ASID_MASK) != pmap_asid_gen)
pmap_allocate_asid(pm);
+ if (pm != pmap_kernel())
+ pmap_setpauthkeys(pm);
+
WRITE_SPECIALREG(ttbr0_el1, pmap_kernel()->pm_pt0pa);
__asm volatile("isb");
cpu_setttb(pm->pm_asid, pm->pm_pt0pa);
-/* $OpenBSD: process_machdep.c,v 1.7 2023/04/16 10:14:59 kettenis Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.8 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
*
}
#endif /* PTRACE */
+
+register_t
+process_get_pacmask(struct proc *p)
+{
+ return (-1ULL << USER_SPACE_BITS);
+}
-/* $OpenBSD: trap.c,v 1.45 2023/05/15 15:02:06 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.46 2023/06/10 19:30:48 kettenis Exp $ */
/*-
* Copyright (c) 2014 Andrew Turner
* All rights reserved.
panic("FP exception in the kernel");
case EXCP_BRANCH_TGT:
panic("Branch target exception in the kernel");
+ case EXCP_FPAC:
+ panic("Faulting PAC trap in kernel");
case EXCP_INSN_ABORT:
kdata_abort(frame, esr, far, 1);
break;
sv.sival_ptr = (void *)frame->tf_elr;
trapsignal(p, SIGILL, esr, ILL_ILLOPC, sv);
break;
+ case EXCP_FPAC:
+ curcpu()->ci_flush_bp();
+ sv.sival_ptr = (void *)frame->tf_elr;
+ trapsignal(p, SIGILL, esr, ILL_ILLOPC, sv);
+ break;
case EXCP_SVC:
svc_handler(frame);
break;
-/* $OpenBSD: vm_machdep.c,v 1.11 2023/04/11 00:45:07 jsg Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.12 2023/06/10 19:30:48 kettenis Exp $ */
/* $NetBSD: vm_machdep.c,v 1.1 2003/04/26 18:39:33 fvdl Exp $ */
/*-
cpu_fork(struct proc *p1, struct proc *p2, void *stack, void *tcb,
void (*func)(void *), void *arg)
{
+ struct pmap *pm = p2->p_vmspace->vm_map.pmap;
+ struct pmap *pm1 = p1->p_vmspace->vm_map.pmap;
struct pcb *pcb = &p2->p_addr->u_pcb;
struct pcb *pcb1 = &p1->p_addr->u_pcb;
struct trapframe *tf;
struct switchframe *sf;
+ memcpy(pm->pm_apiakey, pm1->pm_apiakey, sizeof(pm->pm_apiakey));
+ memcpy(pm->pm_apdakey, pm1->pm_apdakey, sizeof(pm->pm_apdakey));
+ memcpy(pm->pm_apibkey, pm1->pm_apibkey, sizeof(pm->pm_apibkey));
+ memcpy(pm->pm_apdbkey, pm1->pm_apdbkey, sizeof(pm->pm_apdbkey));
+ memcpy(pm->pm_apgakey, pm1->pm_apgakey, sizeof(pm->pm_apgakey));
+
/* Save FPU state to PCB if necessary. */
if (pcb1->pcb_flags & PCB_FPU)
fpu_save(p1);
-/* $OpenBSD: armreg.h,v 1.28 2023/04/16 10:14:59 kettenis Exp $ */
+/* $OpenBSD: armreg.h,v 1.29 2023/06/10 19:30:48 kettenis Exp $ */
/*-
* Copyright (c) 2013, 2014 Andrew Turner
* Copyright (c) 2015 The FreeBSD Foundation
#define EXCP_ILL_STATE 0x0e /* Illegal execution state */
#define EXCP_SVC 0x15 /* SVC trap */
#define EXCP_MSR 0x18 /* MSR/MRS trap */
+#define EXCP_FPAC 0x1c /* Faulting PAC trap */
#define EXCP_INSN_ABORT_L 0x20 /* Instruction abort, from lower EL */
#define EXCP_INSN_ABORT 0x21 /* Instruction abort, from same EL */
#define EXCP_PC_ALIGN 0x22 /* PC alignment fault */
#define SCTLR_SED 0x0000000000000100
#define SCTLR_UMA 0x0000000000000200
#define SCTLR_I 0x0000000000001000
+#define SCTLR_EnDB 0x0000000000002000
#define SCTLR_DZE 0x0000000000004000
#define SCTLR_UCT 0x0000000000008000
#define SCTLR_nTWI 0x0000000000010000
#define SCTLR_EOE 0x0000000001000000
#define SCTLR_EE 0x0000000002000000
#define SCTLR_UCI 0x0000000004000000
+#define SCTLR_EnDA 0x0000000008000000
+#define SCTLR_EnIB 0x0000000040000000
+#define SCTLR_EnIA 0x0000000080000000
/* SPSR_EL1 */
/*
-/* $OpenBSD: cpu.h,v 1.35 2023/02/19 17:16:13 kettenis Exp $ */
+/* $OpenBSD: cpu.h,v 1.36 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
*
* Kernel-only definitions
*/
+extern uint64_t cpu_id_aa64isar0;
+extern uint64_t cpu_id_aa64isar1;
+extern uint64_t cpu_id_aa64pfr0;
+extern uint64_t cpu_id_aa64pfr1;
+
#include <machine/intr.h>
#include <machine/frame.h>
#include <machine/armreg.h>
-/* $OpenBSD: pmap.h,v 1.23 2023/04/16 11:14:26 kettenis Exp $ */
+/* $OpenBSD: pmap.h,v 1.24 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 2008,2009,2014 Dale Rahn <drahn@dalerahn.com>
*
int pm_privileged;
int pm_refs; /* ref count */
struct pmap_statistics pm_stats; /* pmap statistics */
+ uint64_t pm_apiakey[2];
+ uint64_t pm_apdakey[2];
+ uint64_t pm_apibkey[2];
+ uint64_t pm_apdbkey[2];
+ uint64_t pm_apgakey[2];
};
#define PMAP_PA_MASK ~((paddr_t)PAGE_MASK) /* to remove the flags */
void pmap_page_ro(pmap_t pm, vaddr_t va, vm_prot_t prot);
void pmap_page_rw(pmap_t pm, vaddr_t va);
+void pmap_setpauthkeys(struct pmap *);
+
paddr_t pmap_steal_avail(size_t size, int align, void **kva);
void pmap_avail_fixup(void);
void pmap_physload_avail(void);
-/* $OpenBSD: ptrace.h,v 1.1 2016/12/17 23:38:33 patrick Exp $ */
+/* $OpenBSD: ptrace.h,v 1.2 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
*
#define PT_SETREGS (PT_FIRSTMACH + 2)
#define PT_GETFPREGS (PT_FIRSTMACH + 3)
#define PT_SETFPREGS (PT_FIRSTMACH + 4)
+#define PT_PACMASK (PT_FIRSTMACH + 5)
+
+#ifdef _KERNEL
+register_t process_get_pacmask(struct proc *p);
+#endif
-/* $OpenBSD: exec_elf.c,v 1.181 2023/04/19 15:37:36 kettenis Exp $ */
+/* $OpenBSD: exec_elf.c,v 1.182 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 1996 Per Fogelstrom
#ifdef PT_GETFPREGS
struct fpreg freg;
#endif
+#ifdef PT_PACMASK
+ register_t pacmask[2];
+#endif
size = 0;
size += notesize;
#endif
+#ifdef PT_PACMASK
+ notesize = sizeof(nhdr) + elfround(namesize) +
+ elfround(sizeof(pacmask));
+ if (iocookie) {
+ pacmask[0] = pacmask[1] = process_get_pacmask(p);
+
+ nhdr.namesz = namesize;
+ nhdr.descsz = sizeof(pacmask);
+ nhdr.type = NT_OPENBSD_PACMASK;
+
+ error = coredump_writenote_elf(p, iocookie, &nhdr,
+ name, &pacmask);
+ if (error)
+ return (error);
+ }
+ size += notesize;
+#endif
+
*sizep = size;
/* XXX Add hook for machdep per-LWP notes. */
return (0);
-/* $OpenBSD: sys_process.c,v 1.93 2023/01/24 00:12:03 deraadt Exp $ */
+/* $OpenBSD: sys_process.c,v 1.94 2023/06/10 19:30:48 kettenis Exp $ */
/* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */
/*-
struct ptrace_event u_pe;
struct ptrace_state u_ps;
register_t u_wcookie;
+ register_t u_pacmask[2];
} u;
int size = 0;
enum { NONE, IN, IN_ALLOC, OUT, OUT_ALLOC, IN_OUT } mode;
size = sizeof u.u_wcookie;
data = size; /* suppress the data == size check */
break;
+#endif
+#ifdef PT_PACMASK
+ case PT_PACMASK:
+ mode = OUT;
+ size = sizeof u.u_pacmask;
+ break;
#endif
default:
return EINVAL;
case PT_WCOOKIE:
*(register_t *)addr = process_get_wcookie(t);
return 0;
+#endif
+#ifdef PT_PACMASK
+ case PT_PACMASK:
+ ((register_t *)addr)[0] = process_get_pacmask(t);
+ ((register_t *)addr)[1] = process_get_pacmask(t);
+ return 0;
#endif
default:
KASSERTMSG(0, "%s: unhandled request %d", __func__, req);
-/* $OpenBSD: exec_elf.h,v 1.100 2023/04/19 15:37:36 kettenis Exp $ */
+/* $OpenBSD: exec_elf.h,v 1.101 2023/06/10 19:30:48 kettenis Exp $ */
/*
* Copyright (c) 1995, 1996 Erik Theisen. All rights reserved.
*
#define NT_OPENBSD_FPREGS 21
#define NT_OPENBSD_XFPREGS 22
#define NT_OPENBSD_WCOOKIE 23
+#define NT_OPENBSD_PACMASK 24
struct elfcore_procinfo {
/* Version 1 fields start here. */