Thread (20 messages) flat view 20 messages, 3 authors, 2011-06-09
STALE5581d

[PATCH 4/6] ARM: reset: add reset functionality for jumping to a physical address

From: Frank Hofmann <hidden>
Date: 2011-06-07 11:37:23


On Tue, 7 Jun 2011, Frank Hofmann wrote:

On Mon, 6 Jun 2011, Will Deacon wrote:
quoted
Tools such as kexec and CPU hotplug require a way to reset the processor
and branch to some code in physical space. This requires various bits of
jiggery pokery with the caches and MMU which, when it goes wrong, tends
to lock up the system.

This patch implements a new function, arm_machine_reset, for
consolidating this code in one place where it can be used by multiple
subsystems.
[ ... ]
quoted
+void arm_machine_reset(unsigned long reset_code_phys)
+{
+	unsigned long cpu_reset_end = PAGE_ALIGN((unsigned long)cpu_reset);
+	/* This is stricter than necessary but better to be safe than sorry. 
*/
+	BUG_ON(virt_to_phys((void *)cpu_reset_end) >= TASK_SIZE);
+
+	/* Disable interrupts first */
+	local_irq_disable();
+	local_fiq_disable();
+
+	/*
+	 * Clean and invalidate L2.
+	 * This is racy, so we must be the last guy left.
+	 */
+	WARN_ON(num_online_cpus() > 1);
+	/* Flush while we still have locking available to us. */
+	outer_flush_all();
+	outer_disable();
+	/* Data destroyed here will only be speculative. */
+	outer_inv_all();
+
+	prepare_for_reboot(0);
+
+	/* Switch to the identity mapping. */
+	((typeof(cpu_reset) *)virt_to_phys((void *)cpu_reset))(reset_code_phys);
void (*reset_func)(unsigned long) = virt_to_phys(cpu_reset)
Sorry, pressed wrong key ... posted too early.

I meant to say this line is magic, why not decouple the declaration bit 
from the invocation so that at least the function call looks "normal" ?


Regarding the use of local_irq/fiq_disable - is it safe to call these 
multiple times, i.e. is it safe to invoke the reset function from a 
context where IRQ/FIQ are already off ?


Another question regarding the MMU tables.

prepare_for_reboot / setup_mm_for_reboot assume that current->mm is 
available _and_ lowmem / user area there can be blotted over.

Wrt. to hibernation, that's a stretch unless some way is found to fully 
"fake a context". With that I mean to create a threadinfo and pagedir 
that's guaranteed to sit outside the target kernel heap.

Currently, the hibernation code switches to swapper_pg_dir and puts the 
1:1 mappings in there; I'm starting to think that is safe if for no other 
reason than swapper_pg_dir having _nothing_ in the user area ?

Is it convention, design or accident that swapper_pg_dir doesn't map 
anything in the low range ?

FrankH.
quoted
+}
+
/*
 * Function pointers to optional machine specific functions
 */
-- 
1.7.0.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help