diff --git a/Cargo.lock b/Cargo.lock
index 41288c55fe59a..0e5d6281d672d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2046,9 +2046,9 @@ dependencies = [
 
 [[package]]
 name = "libffi"
-version = "3.2.0"
+version = "4.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2"
+checksum = "4a9434b6fc77375fb624698d5f8c49d7e80b10d59eb1219afda27d1f824d4074"
 dependencies = [
  "libc",
  "libffi-sys",
@@ -2056,9 +2056,9 @@ dependencies = [
 
 [[package]]
 name = "libffi-sys"
-version = "2.3.0"
+version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c"
+checksum = "ead36a2496acfc8edd6cc32352110e9478ac5b9b5f5b9856ebd3d28019addb84"
 dependencies = [
  "cc",
 ]
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 0c6f4a3dd06e7..6f4bd3eab51a2 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -257,9 +257,9 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.14"
+version = "0.5.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471"
+checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
 dependencies = [
  "crossbeam-utils",
 ]
@@ -436,9 +436,9 @@ checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
 
 [[package]]
 name = "libffi"
-version = "3.2.0"
+version = "4.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2"
+checksum = "4a9434b6fc77375fb624698d5f8c49d7e80b10d59eb1219afda27d1f824d4074"
 dependencies = [
  "libc",
  "libffi-sys",
@@ -446,9 +446,9 @@ dependencies = [
 
 [[package]]
 name = "libffi-sys"
-version = "2.3.0"
+version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c"
+checksum = "ead36a2496acfc8edd6cc32352110e9478ac5b9b5f5b9856ebd3d28019addb84"
 dependencies = [
  "cc",
 ]
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index e9ee19b793266..bb24e700e7388 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -37,7 +37,7 @@ features = ['unprefixed_malloc_on_supported_platforms']
 
 [target.'cfg(unix)'.dependencies]
 libc = "0.2"
-libffi = "3.2.0"
+libffi = "4.0.0"
 libloading = "0.8"
 
 [target.'cfg(target_family = "windows")'.dependencies]
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index b690bd9cd2b97..755e02d02eca1 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -164,9 +164,9 @@ case $HOST_TARGET in
     # Partially supported targets (tier 2)
     BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
     UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
-    TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe concurrency sync
-    TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
-    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap random sync concurrency thread epoll eventfd
+    TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency fs libc-pipe
+    TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency fs libc-pipe
+    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd
     TEST_TARGET=wasm32-wasip2          run_tests_minimal $BASIC wasm
     TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
     TEST_TARGET=thumbv7em-none-eabihf  run_tests_minimal no_std
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index d2b8b51473061..d1107e5150906 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-7d7de5bf3c3cbf9c2c5bbc5cbfb9197a8a427d35
+1bc56185ee257ed829a0aea7abdc3b03c5fed887
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index 7d97e333cd9b0..8dcadbed130c0 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -65,7 +65,7 @@ fn win_get_full_path_name<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<Pa
     }
     // Otherwise we try to do something kind of close to what Windows does, but this is probably not
     // right in all cases.
-    let mut result: Vec<&[u8]> = vec![]; // will be a vecot of components, joined by `/`.
+    let mut result: Vec<&[u8]> = vec![]; // will be a vector of components, joined by `/`.
     let mut bytes = bytes; // the remaining bytes to process
     let mut stop = false;
     while !stop {
@@ -396,6 +396,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let last_error = this.get_last_error()?;
                 this.write_scalar(last_error, dest)?;
             }
+            "RtlNtStatusToDosError" => {
+                let [status] = this.check_shim(abi, sys_conv, link_name, args)?;
+                let status = this.read_scalar(status)?.to_u32()?;
+                let err = match status {
+                    // STATUS_MEDIA_WRITE_PROTECTED => ERROR_WRITE_PROTECT
+                    0xC00000A2 => 19,
+                    // STATUS_FILE_INVALID => ERROR_FILE_INVALID
+                    0xC0000098 => 1006,
+                    // STATUS_DISK_FULL => ERROR_DISK_FULL
+                    0xC000007F => 112,
+                    // STATUS_IO_DEVICE_ERROR => ERROR_IO_DEVICE
+                    0xC0000185 => 1117,
+                    // STATUS_ACCESS_DENIED => ERROR_ACCESS_DENIED
+                    0xC0000022 => 5,
+                    // Anything without an error code => ERROR_MR_MID_NOT_FOUND
+                    _ => 317,
+                };
+                this.write_scalar(Scalar::from_i32(err), dest)?;
+            }
 
             // Querying system information
             "GetSystemInfo" => {
diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
index 312df9eb115db..a015464dbde32 100644
--- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
+++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
@@ -10,7 +10,9 @@ use std::ptr;
 mod utils;
 
 use windows_sys::Win32::Foundation::{
-    CloseHandle, ERROR_ALREADY_EXISTS, GENERIC_READ, GENERIC_WRITE, GetLastError,
+    CloseHandle, ERROR_ACCESS_DENIED, ERROR_ALREADY_EXISTS, ERROR_IO_DEVICE, GENERIC_READ,
+    GENERIC_WRITE, GetLastError, RtlNtStatusToDosError, STATUS_ACCESS_DENIED,
+    STATUS_IO_DEVICE_ERROR,
 };
 use windows_sys::Win32::Storage::FileSystem::{
     BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, FILE_ATTRIBUTE_DIRECTORY,
@@ -26,6 +28,7 @@ fn main() {
         test_create_always_twice();
         test_open_always_twice();
         test_open_dir_reparse();
+        test_ntstatus_to_dos();
     }
 }
 
@@ -191,6 +194,12 @@ unsafe fn test_open_dir_reparse() {
     };
 }
 
+unsafe fn test_ntstatus_to_dos() {
+    // We won't test all combinations, just a couple common ones
+    assert_eq!(RtlNtStatusToDosError(STATUS_IO_DEVICE_ERROR), ERROR_IO_DEVICE);
+    assert_eq!(RtlNtStatusToDosError(STATUS_ACCESS_DENIED), ERROR_ACCESS_DENIED);
+}
+
 fn to_wide_cstr(path: &Path) -> Vec<u16> {
     let mut raw_path = path.as_os_str().encode_wide().collect::<Vec<_>>();
     raw_path.extend([0, 0]);
diff --git a/src/tools/miri/tests/pass/issues/issue-134713-swap_nonoverlapping_untyped.rs b/src/tools/miri/tests/pass/issues/issue-134713-swap_nonoverlapping_untyped.rs
index a1da60ce65c4d..27ea12398d88a 100644
--- a/src/tools/miri/tests/pass/issues/issue-134713-swap_nonoverlapping_untyped.rs
+++ b/src/tools/miri/tests/pass/issues/issue-134713-swap_nonoverlapping_untyped.rs
@@ -1,4 +1,4 @@
-use std::mem::{size_of, align_of};
+use std::mem::{align_of, size_of};
 
 // See <https://github.com/rust-lang/rust/issues/134713>