diff options
author | Julien Thierry <julien.thierry@arm.com> | 2019-01-31 09:58:39 -0500 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2019-02-06 05:05:16 -0500 |
commit | 5870970b9a828d8693aa6d15742573289d7dbcd0 (patch) | |
tree | 5690841213b98793f73f6e8472605dd4e51efdb2 /include/linux/hardirq.h | |
parent | e26a433147065e9b1503df0b3e12296389cdfa94 (diff) |
arm64: Fix HCR.TGE status for NMI contexts
When using VHE, the host needs to clear HCR_EL2.TGE bit in order
to interact with guest TLBs, switching from EL2&0 translation regime
to EL1&0.
However, some non-maskable asynchronous event could happen while TGE is
cleared like SDEI. Because of this address translation operations
relying on EL2&0 translation regime could fail (tlb invalidation,
userspace access, ...).
Fix this by properly setting HCR_EL2.TGE when entering NMI context and
clear it if necessary when returning to the interrupted context.
Signed-off-by: Julien Thierry <julien.thierry@arm.com>
Suggested-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: linux-arch@vger.kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'include/linux/hardirq.h')
-rw-r--r-- | include/linux/hardirq.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 0fbbcdf0c178..da0af631ded5 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -60,8 +60,14 @@ extern void irq_enter(void); | |||
60 | */ | 60 | */ |
61 | extern void irq_exit(void); | 61 | extern void irq_exit(void); |
62 | 62 | ||
63 | #ifndef arch_nmi_enter | ||
64 | #define arch_nmi_enter() do { } while (0) | ||
65 | #define arch_nmi_exit() do { } while (0) | ||
66 | #endif | ||
67 | |||
63 | #define nmi_enter() \ | 68 | #define nmi_enter() \ |
64 | do { \ | 69 | do { \ |
70 | arch_nmi_enter(); \ | ||
65 | printk_nmi_enter(); \ | 71 | printk_nmi_enter(); \ |
66 | lockdep_off(); \ | 72 | lockdep_off(); \ |
67 | ftrace_nmi_enter(); \ | 73 | ftrace_nmi_enter(); \ |
@@ -80,6 +86,7 @@ extern void irq_exit(void); | |||
80 | ftrace_nmi_exit(); \ | 86 | ftrace_nmi_exit(); \ |
81 | lockdep_on(); \ | 87 | lockdep_on(); \ |
82 | printk_nmi_exit(); \ | 88 | printk_nmi_exit(); \ |
89 | arch_nmi_exit(); \ | ||
83 | } while (0) | 90 | } while (0) |
84 | 91 | ||
85 | #endif /* LINUX_HARDIRQ_H */ | 92 | #endif /* LINUX_HARDIRQ_H */ |