aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2016-01-11 12:03:54 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2016-02-08 10:48:32 -0500
commit4138323eac0b485316e54ad9ce241bac24ddd175 (patch)
tree1a9cd8c95fe1ad0c5e54abf34f1b2c264401bbc8
parent2841029393fad551b49b6de34d44bfa9ef256441 (diff)
ARM: use virt_to_idmap() for soft_restart()
Code run via soft_restart() is run with the MMU disabled, so we need to pass the identity map physical address rather than the address obtained from virt_to_phys(). Therefore, replace virt_to_phys() with virt_to_idmap() for all callers of soft_restart(). Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/hibernate.c4
-rw-r--r--arch/arm/kernel/machine_kexec.c16
2 files changed, 8 insertions, 12 deletions
diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c
index a71501ff6f18..b09561a6d06a 100644
--- a/arch/arm/kernel/hibernate.c
+++ b/arch/arm/kernel/hibernate.c
@@ -62,7 +62,7 @@ static int notrace arch_save_image(unsigned long unused)
62 62
63 ret = swsusp_save(); 63 ret = swsusp_save();
64 if (ret == 0) 64 if (ret == 0)
65 _soft_restart(virt_to_phys(cpu_resume), false); 65 _soft_restart(virt_to_idmap(cpu_resume), false);
66 return ret; 66 return ret;
67} 67}
68 68
@@ -87,7 +87,7 @@ static void notrace arch_restore_image(void *unused)
87 for (pbe = restore_pblist; pbe; pbe = pbe->next) 87 for (pbe = restore_pblist; pbe; pbe = pbe->next)
88 copy_page(pbe->orig_address, pbe->address); 88 copy_page(pbe->orig_address, pbe->address);
89 89
90 _soft_restart(virt_to_phys(cpu_resume), false); 90 _soft_restart(virt_to_idmap(cpu_resume), false);
91} 91}
92 92
93static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata; 93static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata;
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 8bf3b7c09888..59fd0e24c56b 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -143,10 +143,8 @@ void (*kexec_reinit)(void);
143 143
144void machine_kexec(struct kimage *image) 144void machine_kexec(struct kimage *image)
145{ 145{
146 unsigned long page_list; 146 unsigned long page_list, reboot_entry_phys;
147 unsigned long reboot_code_buffer_phys; 147 void (*reboot_entry)(void);
148 unsigned long reboot_entry = (unsigned long)relocate_new_kernel;
149 unsigned long reboot_entry_phys;
150 void *reboot_code_buffer; 148 void *reboot_code_buffer;
151 149
152 /* 150 /*
@@ -159,9 +157,6 @@ void machine_kexec(struct kimage *image)
159 157
160 page_list = image->head & PAGE_MASK; 158 page_list = image->head & PAGE_MASK;
161 159
162 /* we need both effective and real address here */
163 reboot_code_buffer_phys =
164 page_to_pfn(image->control_code_page) << PAGE_SHIFT;
165 reboot_code_buffer = page_address(image->control_code_page); 160 reboot_code_buffer = page_address(image->control_code_page);
166 161
167 /* Prepare parameters for reboot_code_buffer*/ 162 /* Prepare parameters for reboot_code_buffer*/
@@ -174,10 +169,11 @@ void machine_kexec(struct kimage *image)
174 169
175 /* copy our kernel relocation code to the control code page */ 170 /* copy our kernel relocation code to the control code page */
176 reboot_entry = fncpy(reboot_code_buffer, 171 reboot_entry = fncpy(reboot_code_buffer,
177 reboot_entry, 172 &relocate_new_kernel,
178 relocate_new_kernel_size); 173 relocate_new_kernel_size);
179 reboot_entry_phys = (unsigned long)reboot_entry + 174
180 (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); 175 /* get the identity mapping physical address for the reboot code */
176 reboot_entry_phys = virt_to_idmap(reboot_entry);
181 177
182 pr_info("Bye!\n"); 178 pr_info("Bye!\n");
183 179