summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/fdt/psci.c51
1 files changed, 13 insertions, 38 deletions
diff --git a/sys/dev/fdt/psci.c b/sys/dev/fdt/psci.c
index ccee49cd10a..f0e37c50880 100644
--- a/sys/dev/fdt/psci.c
+++ b/sys/dev/fdt/psci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: psci.c,v 1.7 2018/05/03 09:45:57 kettenis Exp $ */
+/* $OpenBSD: psci.c,v 1.8 2018/05/23 09:12:34 kettenis Exp $ */
/*
* Copyright (c) 2016 Jonathan Gray <jsg@openbsd.org>
@@ -54,7 +54,6 @@ struct psci_softc {
uint32_t sc_system_reset;
uint32_t sc_cpu_on;
- uint32_t sc_version;
uint32_t sc_smccc_version;
};
@@ -98,6 +97,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)
@@ -127,10 +127,10 @@ psci_attach(struct device *parent, struct device *self, void *aux)
psci_sc = sc;
- sc->sc_version = psci_version();
- printf(": PSCI %d.%d", sc->sc_version >> 16, sc->sc_version & 0xffff);
+ version = psci_version();
+ printf(": PSCI %d.%d", version >> 16, version & 0xffff);
- if (sc->sc_version >= 0x10000) {
+ if (version >= 0x10000) {
if (psci_features(SMCCC_VERSION) == PSCI_SUCCESS) {
sc->sc_smccc_version = smccc_version();
printf(", SMCCC %d.%d", sc->sc_smccc_version >> 16,
@@ -165,11 +165,9 @@ psci_powerdown(void)
}
/*
- * Firmware-based workaround for CVE-2017-5715. We pick the
- * appropriate mechanism based on the PSCI and SMCCC versions. We
- * determine whether the workaround is actually needed the first time
- * we are invoked such that we only make the firmware call if we
- * really need to.
+ * Firmware-based workaround for CVE-2017-5715. We determine whether
+ * the workaround is actually implemented and needed the first time we
+ * are invoked such that we only make the firmware call when appropriate.
*/
void
@@ -178,14 +176,6 @@ psci_flush_bp_none(void)
}
void
-psci_flush_bp_psci_version(void)
-{
- struct psci_softc *sc = psci_sc;
-
- (*sc->sc_callfn)(PSCI_VERSION, 0, 0, 0);
-}
-
-void
psci_flush_bp_smccc_arch_workaround_1(void)
{
struct psci_softc *sc = psci_sc;
@@ -199,32 +189,17 @@ psci_flush_bp(void)
struct psci_softc *sc = psci_sc;
struct cpu_info *ci = curcpu();
- /* No PSCI or an old version of PSCI; nothing we can do. */
- if (sc == NULL || sc->sc_version < 0x10000) {
- ci->ci_flush_bp = psci_flush_bp_none;
- return;
- }
-
- /*
- * PSCI 1.0 or later with SMCCC 1.0; invoke PSCI_VERSION and
- * hope for the best.
- */
- if (sc->sc_smccc_version < 0x10001) {
- ci->ci_flush_bp = psci_flush_bp_psci_version;
- ci->ci_flush_bp();
- return;
- }
-
/*
- * SMCCC 1.1 or later; we can actually detect if the
- * workaround is implemented and needed.
+ * SMCCC 1.1 allows us to detect if the workaround is
+ * implemented and needed.
*/
- if (smccc_arch_features(SMCCC_ARCH_WORKAROUND_1) == 0) {
+ if (sc && sc->sc_smccc_version >= 0x10001 &&
+ smccc_arch_features(SMCCC_ARCH_WORKAROUND_1) == 0) {
/* Workaround implemented and needed. */
ci->ci_flush_bp = psci_flush_bp_smccc_arch_workaround_1;
ci->ci_flush_bp();
} else {
- /* No workaround needed. */
+ /* Workaround isn't implemented or isn't needed. */
ci->ci_flush_bp = psci_flush_bp_none;
}
}