#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/kexec.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/highmem.h>
 #include <linux/syscalls.h>
  */
 struct kimage *kexec_image;
 struct kimage *kexec_crash_image;
-/*
- * A home grown binary mutex.
- * Nothing can wait so this mutex is safe to use
- * in interrupt context :)
- */
-static int kexec_lock;
+
+static DEFINE_MUTEX(kexec_mutex);
 
 asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
                                struct kexec_segment __user *segments,
                                unsigned long flags)
 {
        struct kimage **dest_image, *image;
-       int locked;
        int result;
 
        /* We only trust the superuser with rebooting the system. */
         *
         * KISS: always take the mutex.
         */
-       locked = xchg(&kexec_lock, 1);
-       if (locked)
+       if (!mutex_trylock(&kexec_mutex))
                return -EBUSY;
 
        dest_image = &kexec_image;
        image = xchg(dest_image, image);
 
 out:
-       locked = xchg(&kexec_lock, 0); /* Release the mutex */
-       BUG_ON(!locked);
+       mutex_unlock(&kexec_mutex);
        kimage_free(image);
 
        return result;
 
 void crash_kexec(struct pt_regs *regs)
 {
-       int locked;
-
-
-       /* Take the kexec_lock here to prevent sys_kexec_load
+       /* Take the kexec_mutex here to prevent sys_kexec_load
         * running on one cpu from replacing the crash kernel
         * we are using after a panic on a different cpu.
         *
         * of memory the xchg(&kexec_crash_image) would be
         * sufficient.  But since I reuse the memory...
         */
-       locked = xchg(&kexec_lock, 1);
-       if (!locked) {
+       if (mutex_trylock(&kexec_mutex)) {
                if (kexec_crash_image) {
                        struct pt_regs fixed_regs;
                        crash_setup_regs(&fixed_regs, regs);
                        machine_crash_shutdown(&fixed_regs);
                        machine_kexec(kexec_crash_image);
                }
-               locked = xchg(&kexec_lock, 0);
-               BUG_ON(!locked);
+               mutex_unlock(&kexec_mutex);
        }
 }
 
 {
        int error = 0;
 
-       if (xchg(&kexec_lock, 1))
+       if (!mutex_trylock(&kexec_mutex))
                return -EBUSY;
        if (!kexec_image) {
                error = -EINVAL;
 #endif
 
  Unlock:
-       if (!xchg(&kexec_lock, 0))
-               BUG();
-
+       mutex_unlock(&kexec_mutex);
        return error;
 }