default: 0
 
        acpi_sleep=     [HW,ACPI] Sleep options
-                       Format: { s3_bios, s3_mode, s3_beep, old_ordering }
+                       Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, old_ordering }
                        See Documentation/power/video.txt for s3_bios and s3_mode.
                        s3_beep is for debugging; it makes the PC's speaker beep
                        as soon as the kernel's real-mode entry point is called.
+                       s4_nohwsig prevents ACPI hardware signature from being
+                       used during resume from hibernation.
                        old_ordering causes the ACPI 1.0 ordering of the _PTS
                        control method, wrt putting devices into low power
                        states, to be enforced (the ACPI 2.0 ordering of _PTS is
 
                        acpi_realmode_flags |= 2;
                if (strncmp(str, "s3_beep", 7) == 0)
                        acpi_realmode_flags |= 4;
+#ifdef CONFIG_HIBERNATION
+               if (strncmp(str, "s4_nohwsig", 10) == 0)
+                       acpi_no_s4_hw_signature();
+#endif
                if (strncmp(str, "old_ordering", 12) == 0)
                        acpi_old_suspend_ordering();
                str = strchr(str, ',');
 
 #endif /* CONFIG_SUSPEND */
 
 #ifdef CONFIG_HIBERNATION
+static unsigned long s4_hardware_signature;
+static struct acpi_table_facs *facs;
+static bool nosigcheck;
+
+void __init acpi_no_s4_hw_signature(void)
+{
+       nosigcheck = true;
+}
+
 static int acpi_hibernation_begin(void)
 {
        acpi_target_sleep_state = ACPI_STATE_S4;
        acpi_enable();
        /* Reprogram control registers and execute _BFS */
        acpi_leave_sleep_state_prep(ACPI_STATE_S4);
+       /* Check the hardware signature */
+       if (facs && s4_hardware_signature != facs->hardware_signature) {
+               printk(KERN_EMERG "ACPI: Hardware changed while hibernated, "
+                       "cannot resume!\n");
+               panic("ACPI S4 hardware signature mismatch");
+       }
 }
 
 static void acpi_pm_enable_gpes(void)
                        &acpi_hibernation_ops_old : &acpi_hibernation_ops);
                sleep_states[ACPI_STATE_S4] = 1;
                printk(" S4");
+               if (!nosigcheck) {
+                       acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
+                               (struct acpi_table_header **)&facs);
+                       if (facs)
+                               s4_hardware_signature =
+                                       facs->hardware_signature;
+               }
        }
 #endif
        status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
 
                      const char *name);
 
 #ifdef CONFIG_PM_SLEEP
+void __init acpi_no_s4_hw_signature(void);
 void __init acpi_old_suspend_ordering(void);
 #endif /* CONFIG_PM_SLEEP */
 #else  /* CONFIG_ACPI */