From 88672784c8989279f379384ef76ac52682805eab Mon Sep 17 00:00:00 2001 From: kettenis Date: Wed, 17 Jan 2018 10:17:33 +0000 Subject: [PATCH] Implement support for the PSCI_VERSION call and export the function such that we can use it to defend against branch target injection attacks. ok patrick@, visa@ --- sys/dev/fdt/files.fdt | 4 ++-- sys/dev/fdt/psci.c | 26 +++++++++++++++++++++++--- sys/dev/fdt/pscivar.h | 8 ++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 sys/dev/fdt/pscivar.h diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt index f2aee8937b1..65286f96bd3 100644 --- a/sys/dev/fdt/files.fdt +++ b/sys/dev/fdt/files.fdt @@ -1,4 +1,4 @@ -# $OpenBSD: files.fdt,v 1.36 2018/01/06 13:04:47 kettenis Exp $ +# $OpenBSD: files.fdt,v 1.37 2018/01/17 10:17:33 kettenis Exp $ # # Config file and device description for machine-independent FDT code. # Included by ports that need it. @@ -69,7 +69,7 @@ file dev/fdt/plrtc.c plrtc # ARM Power State Coordination Interface device psci attach psci at fdt -file dev/fdt/psci.c psci +file dev/fdt/psci.c psci needs-flag attach virtio at fdt with virtio_mmio file dev/fdt/virtio_mmio.c virtio_mmio diff --git a/sys/dev/fdt/psci.c b/sys/dev/fdt/psci.c index e5761a8aa33..69d20dddea9 100644 --- a/sys/dev/fdt/psci.c +++ b/sys/dev/fdt/psci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psci.c,v 1.3 2017/12/29 14:45:15 kettenis Exp $ */ +/* $OpenBSD: psci.c,v 1.4 2018/01/17 10:17:33 kettenis Exp $ */ /* * Copyright (c) 2016 Jonathan Gray @@ -26,10 +26,13 @@ #include #include +#include + extern void (*cpuresetfn)(void); extern void (*powerdownfn)(void); extern int (*cpu_on_fn)(register_t, register_t); +#define PSCI_VERSION 0x84000000 #define SYSTEM_OFF 0x84000008 #define SYSTEM_RESET 0x84000009 #ifdef __LP64__ @@ -42,6 +45,7 @@ struct psci_softc { struct device sc_dev; register_t (*sc_callfn)(register_t, register_t, register_t, register_t); + int sc_psci_version; int sc_system_off; int sc_system_reset; int sc_cpu_on; @@ -82,6 +86,7 @@ psci_attach(struct device *parent, struct device *self, void *aux) struct psci_softc *sc = (struct psci_softc *)self; struct fdt_attach_args *faa = aux; char method[128]; + uint32_t version; if (OF_getprop(faa->fa_node, "method", method, sizeof(method))) { if (strcmp(method, "hvc") == 0) @@ -97,6 +102,7 @@ psci_attach(struct device *parent, struct device *self, void *aux) */ if (OF_is_compatible(faa->fa_node, "arm,psci-0.2") || OF_is_compatible(faa->fa_node, "arm,psci-1.0")) { + sc->sc_psci_version = PSCI_VERSION; sc->sc_system_off = SYSTEM_OFF; sc->sc_system_reset = SYSTEM_RESET; sc->sc_cpu_on = CPU_ON; @@ -108,9 +114,11 @@ psci_attach(struct device *parent, struct device *self, void *aux) sc->sc_cpu_on = OF_getpropint(faa->fa_node, "cpu_on", 0); } - printf("\n"); - psci_sc = sc; + + version = psci_version(); + printf(": PSCI %d.%d\n", version >> 16, version & 0xffff); + if (sc->sc_system_off != 0) powerdownfn = psci_powerdown; if (sc->sc_system_reset != 0) @@ -119,6 +127,18 @@ psci_attach(struct device *parent, struct device *self, void *aux) cpu_on_fn = psci_cpu_on; } +uint32_t +psci_version(void) +{ + struct psci_softc *sc = psci_sc; + + if (sc && sc->sc_callfn && sc->sc_psci_version != 0) + return (*sc->sc_callfn)(sc->sc_psci_version, 0, 0, 0); + + /* No version support; return 0.0. */ + return 0; +} + void psci_reset(void) { diff --git a/sys/dev/fdt/pscivar.h b/sys/dev/fdt/pscivar.h new file mode 100644 index 00000000000..77551db3d2a --- /dev/null +++ b/sys/dev/fdt/pscivar.h @@ -0,0 +1,8 @@ +/* Public Domain */ + +#ifndef _SYS_DEV_FDT_PSCIVAR_H_ +#define _SYS_DEV_FDT_PSCIVAR_H_ + +uint32_t psci_version(void); + +#endif /* _SYS_DEV_FDT_PSCIVAR_H_ */ -- 2.20.1