[prev in list] [next in list] [prev in thread] [next in thread] 

List:       osdl-fastboot
Subject:    [Fastboot] [PATCH 2.6.9-rc2-mm1] kexec: ppc: remove init_mm usage
From:       Albert Herranz <albert_herranz () yahoo ! es>
Date:       2004-09-21 18:11:37
Message-ID: 20040921181137.20200.qmail () web52308 ! mail ! yahoo ! com
[Download RAW message or body]

Hi,

Signed-off-by: Albert Herranz

Available here, against 2.6.9-rc2-mm1 (but may apply
to  other kernel versions with current kexec3
patches):

http://www.gc-linux.org/down/isobel/kexec/2.6.9-rc2-mm1/broken-out/kexec3-ppc-remove-init_mm-usage-take-ii.patch


This patch is a replacement for
kexec3-ppc-remove-init_mm-usage.patch, which was found
to have at least a design flaw.

The patch (optionally) removes &init_mm usage in the
kexec GameCube/ppc32 port, and uses architecture
specific code to avoid identity mapping the reboot
code buffer.

Defining WANT_IDENTITY_MAP reverts back to old
behaviour, and uses the old &init_mm-based identity
mapping code.

Any comments are welcome!

Cheers,
Albert



		
______________________________________________
Renovamos el Correo Yahoo!: ˇ100 MB GRATIS!
Nuevos servicios, más seguridad
http://correo.yahoo.es


["kexec3-ppc-remove-init_mm-usage-take-ii.patch" (text/plain)]

--- a/arch/ppc/kernel/machine_kexec.c	2004-09-19 01:41:00.000000000 +0200
+++ b/arch/ppc/kernel/machine_kexec.c	2004-09-21 19:57:57.000000000 +0200
@@ -18,12 +18,21 @@
 #include <asm/hw_irq.h>
 #include <asm/cacheflush.h>
 
+/*
+ * By default, we WON'T identity map the reboot code buffer.
+ * The PowerPC allows disabling the MMU and jumping to a known 
+ * physical address, atomically.
+ */
+/* #define WANT_IDENTITY_MAP 1 */
+
 typedef void (*relocate_new_kernel_t)(
 	unsigned long indirection_page, unsigned long reboot_code_buffer,
 	unsigned long start_address);
 
 const extern unsigned char relocate_new_kernel[];
 const extern unsigned int relocate_new_kernel_size;
+
+#ifdef WANT_IDENTITY_MAP
 extern void use_mm(struct mm_struct *mm);
 
 static int identity_map_pages(struct page *pages, int order)
@@ -72,6 +81,7 @@ static int identity_map_pages(struct pag
 
 	return error;
 }
+#endif
 
 /*
  * Do what every setup is needed on image and the
@@ -80,18 +90,24 @@ static int identity_map_pages(struct pag
  */
 int machine_kexec_prepare(struct kimage *image)
 {
+#ifdef WANT_IDENTITY_MAP
 	unsigned int order;
 	order = get_order(KEXEC_CONTROL_CODE_SIZE);
 	return identity_map_pages(image->control_code_page, order);
+#else
+	return 0;
+#endif
 }
 
 void machine_kexec_cleanup(struct kimage *image)
 {
+#ifdef WANT_IDENTITY_MAP
 	unsigned int order;
 	order = get_order(KEXEC_CONTROL_CODE_SIZE);
 	do_munmap(&init_mm,
 		page_to_pfn(image->control_code_page) << PAGE_SHIFT,
 		1 << (order + PAGE_SHIFT));
+#endif
 }
 
 void machine_shutdown(void)
@@ -105,19 +121,31 @@ void machine_shutdown(void)
 void machine_kexec(struct kimage *image)
 {
 	unsigned long indirection_page;
-	unsigned long reboot_code_buffer;
+	unsigned long reboot_code_buffer, reboot_code_buffer_phys;
 	relocate_new_kernel_t rnk;
 
+#ifdef WANT_IDENTITY_MAP
 	/* switch to an mm where the reboot_code_buffer is identity mapped */
 	use_mm(&init_mm);
+#endif
 
 	/* Interrupts aren't acceptable while we reboot */
 	local_irq_disable();
 
-	reboot_code_buffer = page_to_pfn(image->control_code_page) <<PAGE_SHIFT;
 	indirection_page = image->head & PAGE_MASK;
 
-	/* copy it out */
+#ifdef WANT_IDENTITY_MAP
+	/* same effective and real address here */
+	reboot_code_buffer = page_to_phys(image->control_code_page);
+	reboot_code_buffer_phys = reboot_code_buffer;
+#else
+	/* we need both effective and real address here */
+	reboot_code_buffer = 
+		(unsigned long)page_address(image->control_code_page);
+	reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer);
+
+#endif
+	/* copy our kernel relocation code to the control code page */
 	memcpy((void *)reboot_code_buffer,
 		relocate_new_kernel, relocate_new_kernel_size);
 
@@ -127,6 +155,6 @@ void machine_kexec(struct kimage *image)
 
 	/* now call it */
 	rnk = (relocate_new_kernel_t) reboot_code_buffer;
-	(*rnk)(indirection_page, reboot_code_buffer, image->start);
+	(*rnk)(indirection_page, reboot_code_buffer_phys, image->start);
 }
 
--- a/arch/ppc/kernel/relocate_kernel.S	2004-09-19 01:41:00.000000000 +0200
+++ b/arch/ppc/kernel/relocate_kernel.S	2004-09-21 19:58:47.000000000 +0200
@@ -41,12 +41,20 @@ relocate_new_kernel:
 
 	li	r0, 0
 
-	/* Set Machine Status Register to a known status */
+	/*
+	 * Set Machine Status Register to a known status,
+	 * switch the MMU off and jump to 1: in a single step.
+	 */
+
 	mr	r8, r0
 	ori     r8, r8, MSR_RI|MSR_ME
-	mtmsr	r8
-	isync
+	mtspr	SRR1, r8
+	addi	r8, r4, 1f - relocate_new_kernel
+	mtspr	SRR0, r8
+	sync
+	rfi
 
+1:	
 	/* from this point address translation is turned off */
 	/* and interrupts are disabled */
 


_______________________________________________
fastboot mailing list
fastboot@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/fastboot


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic