diff --git a/rust/kernel/drm/kms/plane.rs b/rust/kernel/drm/kms/plane.rs
index d3d8b9f6d5c8d4f08a9e541580cee8a1a422b880..9eea0f4fe0c42690503fd556a890d3c6bf316811 100644
--- a/rust/kernel/drm/kms/plane.rs
+++ b/rust/kernel/drm/kms/plane.rs
@@ -22,6 +22,7 @@ use core::{
     ptr::{self, null, null_mut, NonNull},
     marker::*,
     ops::*,
+    iter,
 };
 use macros::pin_data;
 use super::{
@@ -150,6 +151,10 @@ pub struct DriverPlaneOps {
 /// An enumerator describing a type of [`Plane`].
 ///
 /// This is mainly just relevant for DRM legacy drivers.
+///
+/// # Invariants
+///
+/// This type is identical to `drm_plane_type`.
 pub enum PlaneType {
     /// Overlay planes represent all non-primary, non-cursor planes. Some drivers refer to these
     /// types of planes as "sprites" internally.
@@ -210,11 +215,11 @@ impl<T: DriverPlane> Plane<T> {
     /// [`Plane`] objects.
     ///
     /// [`KmsDriver::create_objects`]: kernel::drm::kms::KmsDriver::create_objects
-    pub fn new<'a, 'b: 'a, const FMT_COUNT: usize, const MOD_COUNT: usize>(
+    pub fn new<'a, 'b: 'a>(
         dev: &'a UnregisteredKmsDevice<'a, T::Driver>,
         possible_crtcs: u32,
-        formats: &'static FormatList<FMT_COUNT>,
-        format_modifiers: Option<&'static ModifierList<MOD_COUNT>>,
+        formats: &[u32],
+        format_modifiers: Option<&[u64]>,
         type_: PlaneType,
         name: Option<&CStr>,
         args: T::Args,
@@ -231,7 +236,31 @@ impl<T: DriverPlane> Plane<T> {
             GFP_KERNEL
         )?;
 
-        // SAFETY: FFI call with no special requirements
+        // TODO: Move this over to using collect() someday
+        // Create a modifiers array with the sentinel for passing to DRM
+        let format_modifiers_raw;
+        if let Some(modifiers) = format_modifiers {
+            let mut raw = KVec::with_capacity(modifiers.len() + 1, GFP_KERNEL)?;
+            for modifier in modifiers {
+                raw.push(*modifier, GFP_KERNEL)?;
+            }
+            raw.push(bindings::DRM_FORMAT_MOD_INVALID, GFP_KERNEL)?;
+
+            format_modifiers_raw = Some(raw);
+        } else {
+            format_modifiers_raw = None;
+        }
+
+        // SAFETY:
+        // - We just allocated `this`, and we won't move it since it's pinned
+        // - We just allocated the `format_modifiers_raw` vec and added the sentinel DRM expects
+        //   above
+        // - `drm_universal_plane_init` will memcpy() the following parameters into its own storage,
+        //   so it's safe for them to become inaccessible after this call returns:
+        //   - `formats`
+        //   - `format_modifiers_raw`
+        //   - `name`
+        // - `type_` is equivalent to `drm_plane_type` via its type invariants.
         to_result(unsafe {
             bindings::drm_universal_plane_init(
                 dev.as_raw(),
@@ -239,8 +268,8 @@ impl<T: DriverPlane> Plane<T> {
                 possible_crtcs,
                 &T::OPS.funcs,
                 formats.as_ptr(),
-                formats.raw_len() as _,
-                format_modifiers.map_or(null(), |f| f.as_ptr()),
+                formats.len() as _,
+                format_modifiers_raw.map_or(null(), |f| f.as_ptr()),
                 type_ as _,
                 name.map_or(null(), |n| n.as_char_ptr())
             )