Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b29c164 authored by Vivek Goyal's avatar Vivek Goyal Committed by Andi Kleen
Browse files

[PATCH] x86-64: do not use virt_to_page on kernel data address



o virt_to_page() call should be used on kernel linear addresses and not
  on kernel text and data addresses. Swsusp code uses it on kernel data
  (statically allocated swsusp_header).

o Allocate swsusp_header dynamically so that virt_to_page() can be used
  safely.

o I am changing this because in next few patches, __pa() on x86_64 will
  no longer support kernel text and data addresses and hibernation breaks.

Signed-off-by: default avatarVivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 49c3df6a
Loading
Loading
Loading
Loading
+27 −15
Original line number Diff line number Diff line
@@ -33,12 +33,14 @@ extern char resume_file[];

#define SWSUSP_SIG	"S1SUSPEND"

static struct swsusp_header {
struct swsusp_header {
	char reserved[PAGE_SIZE - 20 - sizeof(sector_t)];
	sector_t image;
	char	orig_sig[10];
	char	sig[10];
} __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
} __attribute__((packed));

static struct swsusp_header *swsusp_header;

/*
 * General things
@@ -141,14 +143,14 @@ static int mark_swapfiles(sector_t start)
{
	int error;

	bio_read_page(swsusp_resume_block, &swsusp_header, NULL);
	if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
	    !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
		memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
		memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
		swsusp_header.image = start;
	bio_read_page(swsusp_resume_block, swsusp_header, NULL);
	if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) ||
	    !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) {
		memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10);
		memcpy(swsusp_header->sig,SWSUSP_SIG, 10);
		swsusp_header->image = start;
		error = bio_write_page(swsusp_resume_block,
					&swsusp_header, NULL);
					swsusp_header, NULL);
	} else {
		printk(KERN_ERR "swsusp: Swap header not found!\n");
		error = -ENODEV;
@@ -564,7 +566,7 @@ int swsusp_read(void)
	if (error < PAGE_SIZE)
		return error < 0 ? error : -EFAULT;
	header = (struct swsusp_info *)data_of(snapshot);
	error = get_swap_reader(&handle, swsusp_header.image);
	error = get_swap_reader(&handle, swsusp_header->image);
	if (!error)
		error = swap_read_page(&handle, header, NULL);
	if (!error)
@@ -591,17 +593,17 @@ int swsusp_check(void)
	resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
	if (!IS_ERR(resume_bdev)) {
		set_blocksize(resume_bdev, PAGE_SIZE);
		memset(&swsusp_header, 0, sizeof(swsusp_header));
		memset(swsusp_header, 0, sizeof(PAGE_SIZE));
		error = bio_read_page(swsusp_resume_block,
					&swsusp_header, NULL);
					swsusp_header, NULL);
		if (error)
			return error;

		if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
			memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
		if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) {
			memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10);
			/* Reset swap signature now */
			error = bio_write_page(swsusp_resume_block,
						&swsusp_header, NULL);
						swsusp_header, NULL);
		} else {
			return -EINVAL;
		}
@@ -632,3 +634,13 @@ void swsusp_close(void)

	blkdev_put(resume_bdev);
}

static int swsusp_header_init(void)
{
	swsusp_header = (struct swsusp_header*) __get_free_page(GFP_KERNEL);
	if (!swsusp_header)
		panic("Could not allocate memory for swsusp_header\n");
	return 0;
}

core_initcall(swsusp_header_init);