diff --git a/cortex-m-rt/examples/override-exception.rs b/cortex-m-rt/examples/override-exception.rs
index 3190b77d..72fbbff8 100644
--- a/cortex-m-rt/examples/override-exception.rs
+++ b/cortex-m-rt/examples/override-exception.rs
@@ -22,7 +22,7 @@ unsafe fn DefaultHandler(_irqn: i16) {
 }
 
 #[exception]
-unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+unsafe fn HardFault(_ef: &mut ExceptionFrame) -> ! {
     asm::bkpt();
 
     loop {}
diff --git a/cortex-m-rt/examples/unsafe-hard-fault.rs b/cortex-m-rt/examples/unsafe-hard-fault.rs
index b1d48f34..0911f9bc 100644
--- a/cortex-m-rt/examples/unsafe-hard-fault.rs
+++ b/cortex-m-rt/examples/unsafe-hard-fault.rs
@@ -13,6 +13,6 @@ fn foo() -> ! {
 }
 
 #[exception]
-unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+unsafe fn HardFault(_ef: &mut ExceptionFrame) -> ! {
     loop {}
 }
diff --git a/cortex-m-rt/examples/unsafety.rs b/cortex-m-rt/examples/unsafety.rs
index cdb5acaf..7931be27 100644
--- a/cortex-m-rt/examples/unsafety.rs
+++ b/cortex-m-rt/examples/unsafety.rs
@@ -22,7 +22,7 @@ unsafe fn DefaultHandler(_irqn: i16) {
 }
 
 #[exception]
-unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+unsafe fn HardFault(_ef: &mut ExceptionFrame) -> ! {
     foo();
 
     loop {}
diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs
index 04774051..5669ddd9 100644
--- a/cortex-m-rt/macros/src/lib.rs
+++ b/cortex-m-rt/macros/src/lib.rs
@@ -325,7 +325,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
                         && match &f.sig.inputs[0] {
                             FnArg::Typed(arg) => match arg.ty.as_ref() {
                                 Type::Reference(r) => {
-                                    r.lifetime.is_none() && r.mutability.is_none()
+                                    r.lifetime.is_none() && r.mutability.is_some()
                                 }
                                 _ => false,
                             },
@@ -346,7 +346,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
                 return parse::Error::new(
                     fspan,
                     if args.trampoline {
-                        "`HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`"
+                        "`HardFault` handler must have signature `unsafe fn(&mut ExceptionFrame) -> !`"
                     } else {
                         "`HardFault` handler must have signature `unsafe fn() -> !`"
                     },
@@ -368,7 +368,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
                     #(#attrs)*
                     #[doc(hidden)]
                     #[export_name = "_HardFault"]
-                    unsafe extern "C" fn #tramp_ident(frame: &::cortex_m_rt::ExceptionFrame) {
+                    unsafe extern "C" fn #tramp_ident(frame: &mut ::cortex_m_rt::ExceptionFrame) {
                         #ident(frame)
                     }
 
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs
index 8b7985a1..fbae454e 100644
--- a/cortex-m-rt/src/lib.rs
+++ b/cortex-m-rt/src/lib.rs
@@ -730,7 +730,7 @@ pub use macros::entry;
 /// ## HardFault handler
 ///
 /// `#[exception(trampoline = true)] unsafe fn HardFault(..` sets the hard fault handler.
-/// If the trampoline parameter is set to true, the handler must have signature `unsafe fn(&ExceptionFrame) -> !`.
+/// If the trampoline parameter is set to true, the handler must have signature `unsafe fn(&mut ExceptionFrame) -> !`.
 /// If set to false, the handler must have signature `unsafe fn() -> !`.
 ///
 /// This handler is not allowed to return as that can cause undefined behavior.
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
index 11b53dc9..5549812c 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
@@ -13,6 +13,6 @@ fn foo() -> ! {
 
 #[exception]
 unsafe fn HardFault(_ef: &ExceptionFrame, undef: u32) -> ! {
-    //~^ ERROR `HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`
+    //~^ ERROR `HardFault` handler must have signature `unsafe fn(&mut ExceptionFrame) -> !`
     loop {}
 }
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-2.rs
index d20d832a..82d4c825 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-2.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-2.rs
@@ -13,6 +13,6 @@ fn foo() -> ! {
 
 #[exception(trampoline = true)]
 unsafe fn HardFault() -> ! {
-    //~^ ERROR `HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`
+    //~^ ERROR `HardFault` handler must have signature `unsafe fn(&mut ExceptionFrame) -> !`
     loop {}
 }
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-3.rs b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-3.rs
index 62c84392..ccd08867 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-3.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-3.rs
@@ -12,7 +12,7 @@ fn foo() -> ! {
 }
 
 #[exception(trampoline = false)]
-unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+unsafe fn HardFault(_ef: &mut ExceptionFrame) -> ! {
     //~^ ERROR `HardFault` handler must have signature `unsafe fn() -> !`
     loop {}
 }
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-twice-mixed-trampoline.rs b/cortex-m-rt/tests/compile-fail/hard-fault-twice-mixed-trampoline.rs
index 36101702..3d7a7830 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-twice-mixed-trampoline.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-twice-mixed-trampoline.rs
@@ -20,7 +20,7 @@ pub mod reachable {
     use cortex_m_rt::{exception, ExceptionFrame};
 
     #[exception] //~ ERROR symbol `_HardFault` is already defined
-    unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+    unsafe fn HardFault(_ef: &mut ExceptionFrame) -> ! {
         loop {}
     }
 }
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
index af80127c..1dd8b38b 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
@@ -12,7 +12,7 @@ fn foo() -> ! {
 }
 
 #[exception]
-unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+unsafe fn HardFault(_ef: &mut ExceptionFrame) -> ! {
     loop {}
 }
 
@@ -20,7 +20,7 @@ pub mod reachable {
     use cortex_m_rt::{exception, ExceptionFrame};
 
     #[exception] //~ ERROR symbol `_HardFault` is already defined
-    unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+    unsafe fn HardFault(_ef: &mut ExceptionFrame) -> ! {
         loop {}
     }
 }
diff --git a/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs b/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
index 23105f15..3615e996 100644
--- a/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
+++ b/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
@@ -34,7 +34,7 @@ unsafe fn DefaultHandler(_irq: i16) {
 }
 
 #[exception]
-unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
+unsafe fn HardFault(_frame: &mut cortex_m_rt::ExceptionFrame) -> ! {
     static mut X: u32 = init();  //~ ERROR requires unsafe
     loop {}
 }