Merge with upstream 2026-04-22

c59ce5a137 add clippy_mingw64_with_whpx presubmit
1be776ffef Roll recipe dependencies (trivial).
f0b151c545 Roll recipe dependencies (trivial).
65b9f328eb Roll recipe dependencies (trivial).
b49e336de5 Roll recipe dependencies (trivial).

https: //chromium.googlesource.com/crosvm/crosvm/+log/f105a548ca472f1d061879a7ddaa5e725b4e7b95..c59ce5a137126ee434dc0a298ed3b431ff7a93d0
Change-Id: Id3fbe189dab8969a48e9da321f4109c3d4448b18
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/7788343
Commit-Queue: David Stevens <stevensd@chromium.org>
Bot-Commit: crosvm LUCI CI <crosvm-luci-ci-builder@crosvm-infra.iam.gserviceaccount.com>
diff --git a/devices/tests/irqchip/whpx.rs b/devices/tests/irqchip/whpx.rs
index a48bfe0..451bc5b 100644
--- a/devices/tests/irqchip/whpx.rs
+++ b/devices/tests/irqchip/whpx.rs
@@ -13,7 +13,6 @@
 use devices::IrqEdgeEvent;
 use devices::IrqEventSource;
 use devices::IrqLevelEvent;
-use devices::PlatformDeviceId;
 use devices::WhpxSplitIrqChip;
 use devices::IOAPIC_BASE_ADDRESS;
 use hypervisor::whpx::Whpx;
@@ -32,6 +31,7 @@
 use resources::SystemAllocator;
 use resources::SystemAllocatorConfig;
 use vm_control::DeviceId;
+use vm_control::PlatformDeviceId;
 use vm_memory::GuestAddress;
 use vm_memory::GuestMemory;
 
diff --git a/hypervisor/src/whpx.rs b/hypervisor/src/whpx.rs
index 85d9fa6..ad9fb33 100644
--- a/hypervisor/src/whpx.rs
+++ b/hypervisor/src/whpx.rs
@@ -4,6 +4,8 @@
 
 //! Implementation for WHPX hypervisor aka Windows Hyper-V platform.
 
+#![allow(clippy::undocumented_unsafe_blocks)] // FIXME
+
 use core::ffi::c_void;
 use std::arch::x86_64::__cpuid_count;
 use std::sync::LazyLock;
diff --git a/hypervisor/src/whpx/types.rs b/hypervisor/src/whpx/types.rs
index 97becb1..458c211 100644
--- a/hypervisor/src/whpx/types.rs
+++ b/hypervisor/src/whpx/types.rs
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#![allow(clippy::undocumented_unsafe_blocks)] // FIXME
+
 use std::collections::HashMap;
 use std::sync::LazyLock;
 
diff --git a/hypervisor/src/whpx/vcpu.rs b/hypervisor/src/whpx/vcpu.rs
index 687594f..5b331ec 100644
--- a/hypervisor/src/whpx/vcpu.rs
+++ b/hypervisor/src/whpx/vcpu.rs
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#![allow(clippy::undocumented_unsafe_blocks)] // FIXME
+
 use core::ffi::c_void;
 use std::arch::x86_64::CpuidResult;
 use std::collections::BTreeMap;
@@ -364,7 +366,7 @@
                 WHV_REGISTER_NAME_WHvX64RegisterRdx,
             ];
 
-            let values = vec![
+            let values = [
                 WHV_REGISTER_VALUE { Reg64: rip },
                 // RDMSR instruction puts lower 32 bits in EAX and upper 32 bits in EDX
                 WHV_REGISTER_VALUE {
@@ -382,7 +384,7 @@
                     self.index,
                     &REG_NAMES as *const WHV_REGISTER_NAME,
                     REG_NAMES.len() as u32,
-                    values.as_ptr() as *const WHV_REGISTER_VALUE,
+                    values.as_ptr(),
                 )
             })
         } else {
@@ -413,7 +415,7 @@
 
         const REG_NAMES: [WHV_REGISTER_NAME; 1] = [WHV_REGISTER_NAME_WHvX64RegisterRip];
 
-        let values = vec![WHV_REGISTER_VALUE { Reg64: rip }];
+        let values = [WHV_REGISTER_VALUE { Reg64: rip }];
 
         // safe because we have enough space for all the registers
         check_whpx!(unsafe {
@@ -422,7 +424,7 @@
                 self.index,
                 &REG_NAMES as *const WHV_REGISTER_NAME,
                 REG_NAMES.len() as u32,
-                values.as_ptr() as *const WHV_REGISTER_VALUE,
+                values.as_ptr(),
             )
         })
     }
@@ -710,7 +712,7 @@
             }
             // exit caused by host cancellation thorugh WHvCancelRunVirtualProcessor,
             WHV_RUN_VP_EXIT_REASON_WHvRunVpExitReasonCanceled => Ok(VcpuExit::Canceled),
-            r => panic!("unknown exit reason: {}", r),
+            r => panic!("unknown exit reason: {r}"),
         }
     }
 }
@@ -1199,7 +1201,7 @@
             WHV_REGISTER_NAME_WHvX64RegisterRdx,
         ];
 
-        let values = vec![
+        let values = [
             WHV_REGISTER_VALUE { Reg64: rip },
             WHV_REGISTER_VALUE {
                 Reg64: entry.cpuid.eax as u64,
@@ -1222,7 +1224,7 @@
                 self.index,
                 &REG_NAMES as *const WHV_REGISTER_NAME,
                 REG_NAMES.len() as u32,
-                values.as_ptr() as *const WHV_REGISTER_VALUE,
+                values.as_ptr(),
             )
         })
     }
diff --git a/hypervisor/src/whpx/vm.rs b/hypervisor/src/whpx/vm.rs
index 3673dca..bdbc883 100644
--- a/hypervisor/src/whpx/vm.rs
+++ b/hypervisor/src/whpx/vm.rs
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#![allow(clippy::undocumented_unsafe_blocks)] // FIXME
+#![allow(clippy::manual_div_ceil)] // FIXME
+
 use core::ffi::c_void;
 use std::cmp::Reverse;
 use std::collections::BTreeMap;
@@ -633,7 +636,7 @@
                     self.vm_partition.partition,
                     guest_addr.offset(),
                     mem.size() as u64,
-                    bitmap.as_mut_ptr() as *mut u64,
+                    bitmap.as_mut_ptr(),
                     (bitmap.len() * 8) as u32,
                 )
             })?;
diff --git a/hypervisor/src/whpx/whpx_sys/bindings.rs b/hypervisor/src/whpx/whpx_sys/bindings.rs
index 7fbb684..9319615 100644
--- a/hypervisor/src/whpx/whpx_sys/bindings.rs
+++ b/hypervisor/src/whpx/whpx_sys/bindings.rs
@@ -1,4 +1,5 @@
-#![allow(unaligned_references, deref_nullptr)]
+#![allow(deref_nullptr)]
+#![allow(clippy::undocumented_unsafe_blocks)]
 /* automatically generated by rust-bindgen 0.59.2 */
 
 #[repr(C)]
diff --git a/hypervisor/src/whpx/whpx_sys/hyperv_tlfs.rs b/hypervisor/src/whpx/whpx_sys/hyperv_tlfs.rs
index a376b0c..83a5785 100644
--- a/hypervisor/src/whpx/whpx_sys/hyperv_tlfs.rs
+++ b/hypervisor/src/whpx/whpx_sys/hyperv_tlfs.rs
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/// Constants from Hyper-V Top Level Functional Specification.
-/// This comes from the document published here:
-/// <https://github.com/MicrosoftDocs/Virtualization-Documentation/raw/live/tlfs/Hypervisor%20Top%20Level%20Functional%20Specification%20v6.0b.pdf>
+//! Constants from Hyper-V Top Level Functional Specification.
+//! This comes from the document published here:
+//! <https://github.com/MicrosoftDocs/Virtualization-Documentation/raw/live/tlfs/Hypervisor%20Top%20Level%20Functional%20Specification%20v6.0b.pdf>
 
 /// CPUID Leaf Range Register.
 pub const HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS: u32 = 0x40000000;
@@ -16,7 +16,7 @@
 /// Feature for Frequency MSR availability.
 pub const HV_FEATURE_FREQUENCY_MSRS_AVAILABLE: u32 = 1 << 8;
 
-/// Group A features.
+// Group A features.
 
 /// Privilege bit for partition reference TSC register.
 pub const HV_MSR_REFERENCE_TSC_AVAILABLE: u32 = 1 << 9;
diff --git a/hypervisor/tests/hypervisor_virtualization.rs b/hypervisor/tests/hypervisor_virtualization.rs
index a91a97e..e906212 100644
--- a/hypervisor/tests/hypervisor_virtualization.rs
+++ b/hypervisor/tests/hypervisor_virtualization.rs
@@ -3483,7 +3483,7 @@
             false
         }
         VcpuExit::MsrAccess => false, // MsrAccess handled by hypervisor impl
-        r => panic!("unexpected exit reason: {:?}", r),
+        r => panic!("unexpected exit reason: {r:?}"),
     };
 
     run_tests!(setup, regs_matcher, exit_matcher);
diff --git a/hypervisor/tests/mmio_fetch_memory.rs b/hypervisor/tests/mmio_fetch_memory.rs
index 4da3e7e..1f7b9dd 100644
--- a/hypervisor/tests/mmio_fetch_memory.rs
+++ b/hypervisor/tests/mmio_fetch_memory.rs
@@ -59,7 +59,7 @@
     vcpu.set_sregs(&vcpu_sregs).expect("set sregs failed");
 
     let vcpu_regs = Regs {
-        rip: load_addr.offset() as u64,
+        rip: load_addr.offset(),
         rflags: 2,
         rax: 0x33,
         rbx: 0x3000,
@@ -127,7 +127,7 @@
             }
             // Continue on external interrupt or signal
             VcpuExit::Intr => continue,
-            r => panic!("unexpected exit reason: {:?}", r),
+            r => panic!("unexpected exit reason: {r:?}"),
         }
     }
 
diff --git a/infra/README.recipes.md b/infra/README.recipes.md
index 35d9b65..dc330af 100644
--- a/infra/README.recipes.md
+++ b/infra/README.recipes.md
@@ -208,11 +208,11 @@
 
 &mdash; **def [RunSteps](/infra/recipes/uprev_refvm_image.py#36)(api: RecipeApi, properties: UprevRefvmImageProperties):**
 
-[depot_tools/recipe_modules/bot_update]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/e16ce5a52dbf64646a1de370f562672bbeb9d9f4/recipes/README.recipes.md#recipe_modules-bot_update
-[depot_tools/recipe_modules/depot_tools]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/e16ce5a52dbf64646a1de370f562672bbeb9d9f4/recipes/README.recipes.md#recipe_modules-depot_tools
-[depot_tools/recipe_modules/gclient]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/e16ce5a52dbf64646a1de370f562672bbeb9d9f4/recipes/README.recipes.md#recipe_modules-gclient
-[depot_tools/recipe_modules/git]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/e16ce5a52dbf64646a1de370f562672bbeb9d9f4/recipes/README.recipes.md#recipe_modules-git
-[depot_tools/recipe_modules/gsutil]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/e16ce5a52dbf64646a1de370f562672bbeb9d9f4/recipes/README.recipes.md#recipe_modules-gsutil
+[depot_tools/recipe_modules/bot_update]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/fd3c638f52200fd1a2b6d6211712d822021908ec/recipes/README.recipes.md#recipe_modules-bot_update
+[depot_tools/recipe_modules/depot_tools]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/fd3c638f52200fd1a2b6d6211712d822021908ec/recipes/README.recipes.md#recipe_modules-depot_tools
+[depot_tools/recipe_modules/gclient]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/fd3c638f52200fd1a2b6d6211712d822021908ec/recipes/README.recipes.md#recipe_modules-gclient
+[depot_tools/recipe_modules/git]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/fd3c638f52200fd1a2b6d6211712d822021908ec/recipes/README.recipes.md#recipe_modules-git
+[depot_tools/recipe_modules/gsutil]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/fd3c638f52200fd1a2b6d6211712d822021908ec/recipes/README.recipes.md#recipe_modules-gsutil
 [recipe_engine/recipe_modules/buildbucket]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/36229065a1e627aa00341564303ac1336c51d925/README.recipes.md#recipe_modules-buildbucket
 [recipe_engine/recipe_modules/cipd]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/36229065a1e627aa00341564303ac1336c51d925/README.recipes.md#recipe_modules-cipd
 [recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/36229065a1e627aa00341564303ac1336c51d925/README.recipes.md#recipe_modules-context
diff --git a/infra/config/recipes.cfg b/infra/config/recipes.cfg
index 80df6fa..c9f8414 100644
--- a/infra/config/recipes.cfg
+++ b/infra/config/recipes.cfg
@@ -18,7 +18,7 @@
   "deps": {
     "depot_tools": {
       "branch": "refs/heads/main",
-      "revision": "e16ce5a52dbf64646a1de370f562672bbeb9d9f4",
+      "revision": "fd3c638f52200fd1a2b6d6211712d822021908ec",
       "url": "https://chromium.googlesource.com/chromium/tools/depot_tools.git"
     },
     "recipe_engine": {
diff --git a/src/sys/windows.rs b/src/sys/windows.rs
index 0a9b661..aaefb4f 100644
--- a/src/sys/windows.rs
+++ b/src/sys/windows.rs
@@ -2442,7 +2442,9 @@
             )?;
 
             let mut irq_chip = match irq_chip {
-                IrqChipKind::Kernel => unimplemented!("Kernel irqchip mode not supported by WHPX"),
+                IrqChipKind::Kernel {} => {
+                    unimplemented!("Kernel irqchip mode not supported by WHPX")
+                }
                 IrqChipKind::Split => {
                     if !apic_emulation_supported {
                         panic!(
diff --git a/tools/clippy b/tools/clippy
index a654959..8e1d364 100755
--- a/tools/clippy
+++ b/tools/clippy
@@ -21,6 +21,7 @@
     json: bool = False,
     locked: bool = False,
     platform: Optional[str] = None,
+    features: Optional[str] = None,
 ):
     try:
         triple: Triple = Triple.from_shorthand(platform) if platform else Triple.host_default()
@@ -53,7 +54,7 @@
 
     print("Clippy crosvm workspace")
     clippy(
-        f"--features={triple.feature_flag}",
+        f"--features={triple.feature_flag}" + (f",{features}" if features is not None else ""),
         *args,
     ).with_envs(triple.get_cargo_env()).fg()
 
diff --git a/tools/presubmit b/tools/presubmit
index ee63330..00a7e47 100755
--- a/tools/presubmit
+++ b/tools/presubmit
@@ -161,13 +161,14 @@
     return check
 
 
-def check_clippy(platform: Union[Platform, ClippyOnlyPlatform]):
+def check_clippy(platform: Union[Platform, ClippyOnlyPlatform], features: Optional[str] = None):
     def check(context: CheckContext):
         if not platform_is_supported(platform):
             return None
         return cmd(
             "./tools/clippy --platform",
             platform,
+            f"--features={features}" if features is not None else None,
             "--fix" if context.fix else None,
         ).with_color_flag()
 
@@ -300,6 +301,13 @@
         for platform in (*PLATFORMS, *CLIPPY_ONLY_PLATFORMS)
     ),
     Check(
+        check_clippy("mingw64", features="whpx"),
+        custom_name=f"clippy_mingw64_with_whpx",
+        files=["**.rs"],
+        can_fix=True,
+        priority=True,
+    ),
+    Check(
         custom_check("check-copyright-header"),
         files=["**.rs", "**.py", "**.c", "**.h", "**.policy", "**.sh"],
         exclude=[
@@ -376,13 +384,15 @@
             "health_checks",
             *(f"linux_{platform}" for platform in PLATFORMS),
             *(f"clippy_{platform}" for platform in CLIPPY_ONLY_PLATFORMS),
+            "clippy_mingw64_with_whpx",
         ],
     ),
     # Convenience groups for local usage:
     Group(
         name="clippy",
         doc="Runs clippy for all platforms",
-        checks=[f"clippy_{platform}" for platform in PLATFORMS + CLIPPY_ONLY_PLATFORMS],
+        checks=[f"clippy_{platform}" for platform in PLATFORMS + CLIPPY_ONLY_PLATFORMS]
+        + ["clippy_mingw64_with_whpx"],
     ),
     Group(
         name="unit_tests",