diff --git a/rust/kernel/drm/kms/plane.rs b/rust/kernel/drm/kms/plane.rs
index b05f7385412af88da8879e86d923393075007b07..fb0265e2ddb6faceb6e91f3d2720f72b0d882703 100644
--- a/rust/kernel/drm/kms/plane.rs
+++ b/rust/kernel/drm/kms/plane.rs
@@ -2,36 +2,54 @@
 
 //! KMS atomic plane abstractions for rust.
 
+use alloc::boxed::Box;
 use crate::{
-    container_of,
     bindings,
+    container_of,
+    drm::device::Device,
+    error::to_result,
     init::Zeroable,
     prelude::*,
 };
 use core::{
+    cell::UnsafeCell,
     marker::PhantomPinned,
-    mem
+    mem,
+    ptr::{NonNull, addr_of_mut, null_mut},
 };
 use macros::pin_data;
+use super::KmsDriver;
 
 /// The main data structure for a drm_plane. This holds the actual drm_plane struct, along with
 /// whatever the driver's private data type (T) is.
 #[repr(C)]
 #[pin_data] // TODO: verify this is how we want to pin things?
 pub struct Plane<T: DriverPlane> {
-    plane: bindings::drm_plane,
+    plane: UnsafeCell<bindings::drm_plane>,
     #[pin]
     inner: T,
     #[pin]
     _p: PhantomPinned,
 }
 
+unsafe impl Zeroable for bindings::drm_plane {}
+
 /// The main trait for implementing the drm_plane API. This contains the various trait methods that
 /// need to be implemented by a driver. The private driver data for the plane is contained in
 /// whatever struct the driver defines which implements this trait.
 pub trait DriverPlane: Sized {
+    /// The return type of the new() function. Should be `impl PinInit<Self, Error>`.
+    /// TODO: Remove this when return_position_impl_trait_in_trait is stable.
+    type Initializer: PinInit<Self, Error>;
+
+    /// The parent driver implementation
+    type Driver: KmsDriver;
+
     /// The type for this driver's drm_plane_state implementation
     type State: DriverPlaneState;
+
+    /// Create a new plane for this driver
+    fn new() -> Self::Initializer;
 }
 
 impl<T: DriverPlane> Plane<T> {
@@ -45,8 +63,8 @@ impl<T: DriverPlane> Plane<T> {
         destroy: None,
         reset: Some(bindings::drm_atomic_helper_plane_reset),
         set_property: None,
-        atomic_duplicate_state: Some(atomic_duplicate_state_callback::<T>),
-        atomic_destroy_state: None, // TODO: required (some sort of clone?)
+        atomic_duplicate_state: Some(atomic_duplicate_state_callback::<T::State>),
+        atomic_destroy_state: Some(atomic_destroy_state_callback::<T::State>),
         atomic_set_property: None, // TODO someday
         atomic_get_property: None, // TODO someday
         late_register: None, // TODO someday
@@ -54,16 +72,47 @@ impl<T: DriverPlane> Plane<T> {
         atomic_print_state: None, // TODO: Display someday???
         format_mod_supported: None // TODO someday
     };
+
+    fn new(
+        dev: &Device<T::Driver>,
+        possible_crtcs: u32,
+        formats: &'static [u32],
+        format_modifiers: &'static [u64],
+        type_: bindings::drm_plane_type,
+        name: &CStr,
+    ) -> Result<Pin<Box<Self>>> {
+        // TODO: Figure out some way of making sure that format_modifiers has the correct
+        // terminating sentinel (DRM_FORMAT_MOD_INVALID)
+
+        let plane: Pin<Box<Self>> = Box::pin_init(try_pin_init!(Self {
+            // SAFETY: This struct is expected to be zero-initialized
+            plane: UnsafeCell::new(bindings::drm_plane { ..Default::default() }),
+            inner <- T::new(),
+            _p: PhantomPinned
+        }))?;
+
+        to_result(unsafe {
+            bindings::drm_universal_plane_init(
+                dev.drm.get(),
+                plane.plane.get(),
+                possible_crtcs,
+                &Self::FUNCS,
+                formats.as_ptr(),
+                formats.len() as _,
+                format_modifiers.as_ptr(),
+                type_,
+                name.as_char_ptr()
+            )
+        })?;
+
+        Ok(plane)
+    }
 }
 
-#[pin_data]
-#[derive(Clone)]
+#[repr(C)]
 pub struct PlaneState<T: DriverPlaneState> {
     state: bindings::drm_plane_state,
-    #[pin]
     inner: T,
-    #[pin]
-    _p: PhantomPinned,
 }
 
 /// Traits which must be implemented by KMS drivers for DRM planes.
@@ -72,17 +121,76 @@ pub trait DriverPlaneState: Clone + Sized {
     type Plane: DriverPlane;
 }
 
-unsafe extern "C" fn atomic_duplicate_state_callback<T: DriverPlane>(
+impl<T: DriverPlaneState> PlaneState<T> {
+    /// Consume this struct without dropping it, and return a pointer to it's base `drm_plane_state`
+    /// which can be handed off to DRM.
+    fn into_raw(self: Box<Self>) -> *mut bindings::drm_plane_state {
+        let this = Box::into_raw(self);
+
+        unsafe { addr_of_mut!((*this).state) }
+    }
+
+    /// Consume a raw pointer and recover the original `Box<PlaneState<T>>`
+    ///
+    /// SAFETY: Callers must ensure that ptr contains a non-null pointer
+    unsafe fn from_raw(ptr: *mut bindings::drm_plane_state) -> Box<Self> {
+        unsafe { Box::from_raw(container_of!(ptr, Self, state) as *mut _) }
+    }
+
+    /// Obtain a mutable reference back to the PlaneState<T>
+    ///
+    /// SAFETY: Callers must ensure that ptr contains a non-null pointer
+    unsafe fn as_mut<'a>(ptr: *mut bindings::drm_plane_state) -> &'a mut Self {
+        unsafe { &mut *(container_of!(ptr, Self, state) as *mut _) }
+    }
+
+    /// Obtain a mutable pointer to the base plane state, for use in FFI calls
+    fn as_ptr(&mut self) -> *mut bindings::drm_plane_state {
+        addr_of_mut!(self.state)
+    }
+}
+
+unsafe impl Zeroable for bindings::drm_plane_state { }
+
+unsafe extern "C" fn atomic_duplicate_state_callback<T: DriverPlaneState>(
     plane: *mut bindings::drm_plane
 ) -> *mut bindings::drm_plane_state
 {
+    // SAFETY: `plane` has to be non-null, since it holds the vtable for this function - which is
+    // the only possible entrypoint the caller could have used
     let state = unsafe { (*plane).state };
-    // SAFETY: `plane` is guaranteed by FFI call signatures to be PlaneState<S>
-    // TODO: Do we need container_of!? I think we might actually be able to just cast this if the
-    // layout is identical
-    let state = container_of!(state, PlaneState<T::State>, state);
+    if state.is_null() {
+        return null_mut();
+    }
+
+    // SAFETY: We just verified that `state` is non-null, and we're guaranteed by our bindings that
+    // `state` is of type `PlaneState<T>`.
+    let state = unsafe { PlaneState::<T>::as_mut(state) };
+
+    let mut new: Result<Box<PlaneState<T>>> = Box::try_init(try_init!(PlaneState::<T> {
+        state: bindings::drm_plane_state { ..Default::default() },
+        inner: state.inner.clone()
+    }));
+
+    if let Ok(mut new) = new {
+        // SAFETY: Just a lil' FFI call, nothing special here
+        unsafe { bindings::__drm_atomic_helper_plane_duplicate_state(plane, new.as_ptr()) };
+
+        new.into_raw()
+    } else {
+        null_mut()
+    }
+}
 
-    let new = unsafe { (&*state).clone() };
+unsafe extern "C" fn atomic_destroy_state_callback<T: DriverPlaneState>(
+    _plane: *mut bindings::drm_plane,
+    plane_state: *mut bindings::drm_plane_state
+) {
+    // SAFETY: This callback wouldn't be called unless there a plane state to destroy
+    unsafe { bindings::__drm_atomic_helper_plane_destroy_state(plane_state) };
 
-    todo!()
+    // SAFETY: We're guaranteed by type invariants that plane_state is of type PlaneState<T>, and
+    // since this is the destructor callback for DRM - we're guaranteed to hold the only remaining
+    // reference to this state
+    unsafe { PlaneState::<T>::from_raw(plane_state) };
 }