aboutsummaryrefslogtreecommitdiff
path: root/arch/arm64/include/asm/daifflags.h
diff options
context:
space:
mode:
authorGravatar Mark Rutland <mark.rutland@arm.com> 2019-10-25 17:42:12 +0100
committerGravatar Catalin Marinas <catalin.marinas@arm.com> 2019-10-28 11:22:43 +0000
commit51077e03b8cef2a24d6582b8c54b718fced6878c (patch)
tree7644c7010684bf47a1e93362e73ffcd6cc00827b /arch/arm64/include/asm/daifflags.h
parentarm64: Add prototypes for functions called by entry.S (diff)
downloadlinux-51077e03b8cef2a24d6582b8c54b718fced6878c.tar.gz
linux-51077e03b8cef2a24d6582b8c54b718fced6878c.tar.bz2
linux-51077e03b8cef2a24d6582b8c54b718fced6878c.zip
arm64: add local_daif_inherit()
Some synchronous exceptions can be taken from a number of contexts, e.g. where IRQs may or may not be masked. In the entry assembly for these exceptions, we use the inherit_daif assembly macro to ensure that we only mask those exceptions which were masked when the exception was taken. So that we can do the same from C code, this patch adds a new local_daif_inherit() function, following the existing local_daif_*() naming scheme. Signed-off-by: Mark Rutland <mark.rutland@arm.com> [moved away from local_daif_restore()] Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/include/asm/daifflags.h')
-rw-r--r--arch/arm64/include/asm/daifflags.h16
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
index 063c964af705..9207cd5aa39e 100644
--- a/arch/arm64/include/asm/daifflags.h
+++ b/arch/arm64/include/asm/daifflags.h
@@ -9,6 +9,7 @@
#include <asm/arch_gicv3.h>
#include <asm/cpufeature.h>
+#include <asm/ptrace.h>
#define DAIF_PROCCTX 0
#define DAIF_PROCCTX_NOIRQ PSR_I_BIT
@@ -109,4 +110,19 @@ static inline void local_daif_restore(unsigned long flags)
trace_hardirqs_off();
}
+/*
+ * Called by synchronous exception handlers to restore the DAIF bits that were
+ * modified by taking an exception.
+ */
+static inline void local_daif_inherit(struct pt_regs *regs)
+{
+ unsigned long flags = regs->pstate & DAIF_MASK;
+
+ /*
+ * We can't use local_daif_restore(regs->pstate) here as
+ * system_has_prio_mask_debugging() won't restore the I bit if it can
+ * use the pmr instead.
+ */
+ write_sysreg(flags, daif);
+}
#endif