Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d307c4a8e826c44f9633bd3f7e60d0491e7d885a
Commit:     d307c4a8e826c44f9633bd3f7e60d0491e7d885a
Parent:     50a1efe14fd56a273cdbe53bf1c7fc12099d2e1a
Author:     Rafael J. Wysocki <[EMAIL PROTECTED]>
AuthorDate: Thu Oct 18 03:04:52 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Thu Oct 18 14:37:19 2007 -0700

    Hibernation: Arbitrary boot kernel support - generic code
    
    Add the bits needed for supporting arbitrary boot kernels to the common
    hibernation code.
    
    To support arbitrary boot kernels, make it possible to replace the 'struct
    new_utsname' and the kernel version in the hibernation image header by some
    architecture specific data that will be used to verify if the image is valid
    and to restore the image.
    
    Signed-off-by: Rafael J. Wysocki <[EMAIL PROTECTED]>
    Acked-by: Pavel Machek <[EMAIL PROTECTED]>
    Cc: Andi Kleen <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 kernel/power/power.h    |   20 ++++++++++++++++-
 kernel/power/snapshot.c |   53 +++++++++++++++++++++++++++++++----------------
 2 files changed, 54 insertions(+), 19 deletions(-)

diff --git a/kernel/power/power.h b/kernel/power/power.h
index 95fbf2d..a0204df 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -11,14 +11,32 @@ struct swsusp_info {
        unsigned long           size;
 } __attribute__((aligned(PAGE_SIZE)));
 
+#ifdef CONFIG_HIBERNATION
+#ifdef CONFIG_ARCH_HIBERNATION_HEADER
+/* Maximum size of architecture specific data in a hibernation header */
+#define MAX_ARCH_HEADER_SIZE   (sizeof(struct new_utsname) + 4)
 
+extern int arch_hibernation_header_save(void *addr, unsigned int max_size);
+extern int arch_hibernation_header_restore(void *addr);
+
+static inline int init_header_complete(struct swsusp_info *info)
+{
+       return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE);
+}
+
+static inline char *check_image_kernel(struct swsusp_info *info)
+{
+       return arch_hibernation_header_restore(info) ?
+                       "architecture specific data" : NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
 
-#ifdef CONFIG_HIBERNATION
 /*
  * Keep some memory free so that I/O operations can succeed without paging
  * [Might this be more than 4 MB?]
  */
 #define PAGES_FOR_IO   ((4096 * 1024) >> PAGE_SHIFT)
+
 /*
  * Keep 1 MB of memory free so that device drivers can allocate some pages in
  * their .suspend() routines without breaking the suspend to disk.
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index a686590..ccc95ac 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1239,17 +1239,39 @@ asmlinkage int swsusp_save(void)
        return 0;
 }
 
-static void init_header(struct swsusp_info *info)
+#ifndef CONFIG_ARCH_HIBERNATION_HEADER
+static int init_header_complete(struct swsusp_info *info)
 {
-       memset(info, 0, sizeof(struct swsusp_info));
+       memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
        info->version_code = LINUX_VERSION_CODE;
+       return 0;
+}
+
+static char *check_image_kernel(struct swsusp_info *info)
+{
+       if (info->version_code != LINUX_VERSION_CODE)
+               return "kernel version";
+       if (strcmp(info->uts.sysname,init_utsname()->sysname))
+               return "system type";
+       if (strcmp(info->uts.release,init_utsname()->release))
+               return "kernel release";
+       if (strcmp(info->uts.version,init_utsname()->version))
+               return "version";
+       if (strcmp(info->uts.machine,init_utsname()->machine))
+               return "machine";
+       return NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
+
+static int init_header(struct swsusp_info *info)
+{
+       memset(info, 0, sizeof(struct swsusp_info));
        info->num_physpages = num_physpages;
-       memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
-       info->cpus = num_online_cpus();
        info->image_pages = nr_copy_pages;
        info->pages = nr_copy_pages + nr_meta_pages + 1;
        info->size = info->pages;
        info->size <<= PAGE_SHIFT;
+       return init_header_complete(info);
 }
 
 /**
@@ -1303,7 +1325,11 @@ int snapshot_read_next(struct snapshot_handle *handle, 
size_t count)
                        return -ENOMEM;
        }
        if (!handle->offset) {
-               init_header((struct swsusp_info *)buffer);
+               int error;
+
+               error = init_header((struct swsusp_info *)buffer);
+               if (error)
+                       return error;
                handle->buffer = buffer;
                memory_bm_position_reset(&orig_bm);
                memory_bm_position_reset(&copy_bm);
@@ -1394,22 +1420,13 @@ duplicate_memory_bitmap(struct memory_bitmap *dst, 
struct memory_bitmap *src)
        }
 }
 
-static inline int check_header(struct swsusp_info *info)
+static int check_header(struct swsusp_info *info)
 {
-       char *reason = NULL;
+       char *reason;
 
-       if (info->version_code != LINUX_VERSION_CODE)
-               reason = "kernel version";
-       if (info->num_physpages != num_physpages)
+       reason = check_image_kernel(info);
+       if (!reason && info->num_physpages != num_physpages)
                reason = "memory size";
-       if (strcmp(info->uts.sysname,init_utsname()->sysname))
-               reason = "system type";
-       if (strcmp(info->uts.release,init_utsname()->release))
-               reason = "kernel release";
-       if (strcmp(info->uts.version,init_utsname()->version))
-               reason = "version";
-       if (strcmp(info->uts.machine,init_utsname()->machine))
-               reason = "machine";
        if (reason) {
                printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
                return -EPERM;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to