lkml.org 
[lkml]   [2005]   [Apr]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] s390: kexec fixes for -mm
Hi Andrew,

could you please add the patch below to your mm tree? It fixes some issues
with the current kexec implementation on s390. This one needs to be applied
after kexec-s390-support.patch.

Thanks,
Heiko

From: Heiko Carstens <heiko.carstens@de.ibm.com>

This patch is mostly based on comments which I received from
Milton Miller <miltonm@bga.com>. Changes are:

- Fix passing of first argument to relocate_kernel assembly.
- Fix Kconfig description.
- Remove wrong comment and comments that describe obvious things.
- Allow only KEXEC_TYPE_DEFAULT as image type -> dump not supported.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>

diffstat:
arch/s390/Kconfig | 14 --------
arch/s390/kernel/machine_kexec.c | 61 ++++++++---------------------------
arch/s390/kernel/relocate_kernel.S | 14 +++-----
arch/s390/kernel/relocate_kernel64.S | 14 +++-----
4 files changed, 27 insertions(+), 76 deletions(-)
diff -urN a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig 2005-04-27 13:18:09.000000000 +0200
+++ b/arch/s390/Kconfig 2005-04-27 13:19:11.000000000 +0200
@@ -461,19 +461,7 @@
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
- but it is indepedent of the system firmware. And like a reboot
- you can start any kernel with it, not just Linux.
-
- The name comes from the similiarity to the exec system call.
-
- It is an ongoing process to be certain the hardware in a machine
- is properly shutdown, so do not be surprised if this code does not
- initially work for you. It may help to enable device hotplugging
- support. As of this writing the exact hardware interface is
- strongly in flux, so no good recommendation can be made.
-
- In the GAMECUBE implementation, kexec allows you to load and
- run DOL files, including kernel and homebrew DOLs.
+ but is independent of hardware/microcode support.

endmenu

diff -urN a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
--- a/arch/s390/kernel/machine_kexec.c 2005-04-27 13:18:09.000000000 +0200
+++ b/arch/s390/kernel/machine_kexec.c 2005-04-27 13:19:11.000000000 +0200
@@ -22,29 +22,22 @@
#include <asm/pgalloc.h>
#include <asm/system.h>

-int machine_kexec_prepare(struct kimage *);
-void machine_kexec_cleanup(struct kimage *);
-void machine_shutdown(void);
-void machine_kexec(struct kimage *);
static void kexec_halt_all_cpus(void *);

-typedef void (*relocate_kernel_t) (unsigned long indirection_page,
- unsigned long reboot_code_buffer,
- unsigned long start_address);
+typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);

const extern unsigned char relocate_kernel[];
const extern unsigned long long relocate_kernel_len;

-/*
- * Do whatever setup is needed on image and the reboot code buffer to
- * allow us to aviood allocations later.
- */
-
int
-machine_kexec_prepare(struct kimage * image)
+machine_kexec_prepare(struct kimage *image)
{
unsigned long reboot_code_buffer;

+ /* We don't support anything but the default image type for now. */
+ if (image->type != KEXEC_TYPE_DEFAULT)
+ return -EINVAL;
+
/* Get the destination where the assembler code should be copied to.*/
reboot_code_buffer = page_to_pfn(image->control_code_page)<<PAGE_SHIFT;

@@ -54,45 +47,20 @@
return 0;
}

-
-/*
- * We don't have to do anything here, because we didn't have to prepare
- * (i.e. allocate or the like) anything in 'machine_kexec_prepare'.
- */
void
machine_kexec_cleanup(struct kimage *image)
{
}

-/*
- * Just print a message in the kernel log.
- */
void
machine_shutdown(void)
{
printk(KERN_INFO "kexec: machine_shutdown called\n");
}

-/*
- * The addresses for the reboot_code_buffer, the indirection page and the
- * data_mover can already be assigned here.
- * Also, we can here clear all subchannels.
- * In any case we have to disable the lowcore protection, because we will
- * write a new PSW to address 0.
- * Then we call the function 'kexec_halt_all_cpus'.
- */
-
-static unsigned long indirection_page;
-static unsigned long reboot_code_buffer;
-static relocate_kernel_t data_mover;
-
NORET_TYPE void
machine_kexec(struct kimage *image)
{
- reboot_code_buffer = page_to_pfn(image->control_code_page)<<PAGE_SHIFT;
- indirection_page = image->head & PAGE_MASK;
- data_mover = (relocate_kernel_t) reboot_code_buffer;
-
clear_all_subchannels();

/* Disable lowcore protection */
@@ -102,20 +70,15 @@
for(;;);
}

-/*
- * Make sure that all except one CPU are stopped. The first CPU
- * that enters this function is going to halt all the others and then, if it is
- * the only one left, the 'data_mover' function will be called.
- */
static void
kexec_halt_all_cpus(void *kernel_image)
{
static atomic_t cpuid = ATOMIC_INIT(-1);
int cpu;
+ struct kimage *image;
+ relocate_kernel_t data_mover;

- struct kimage *image = (struct kimage *) kernel_image;
-
- if(atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
+ if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
signal_processor(smp_processor_id(), sigp_stop);

/* Wait for all other cpus to enter stopped state */
@@ -126,6 +89,10 @@
cpu_relax();
}

+ image = (struct kimage *) kernel_image;
+ data_mover = (relocate_kernel_t)
+ (page_to_pfn(image->control_code_page) << PAGE_SHIFT);
+
/* Call the moving routine */
- (*data_mover) (indirection_page, reboot_code_buffer, image->start);
+ (*data_mover) (&image->head, image->start);
}
diff -urN a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S
--- a/arch/s390/kernel/relocate_kernel64.S 2005-04-27 13:18:09.000000000 +0200
+++ b/arch/s390/kernel/relocate_kernel64.S 2005-04-27 13:20:02.000000000 +0200
@@ -9,9 +9,8 @@

/*
* moves the new kernel to its destination...
- * %r2 = indirection page
- * %r3 = reboot_code_buffer
- * %r4 = start address - where to jump to after the job is done...
+ * %r2 = pointer to first kimage_entry_t
+ * %r3 = start address - where to jump to after the job is done...
*
* %r5 will be used as temp. storage
* %r6 holds the destination address
@@ -59,11 +58,10 @@
j .top
.done:
sgr %r0,%r0 #clear register r0
- la %r3,load_psw-.base(%r13) #load psw-address into the register
- mvc 0(4,%r0),0(%r3) #copy the first part of it
- l %r1,4(0,%r3) #copy the second part of load_psw in %r1
- or %r1,%r4 #OR it with the given psw --> %r1 = (%r1 | %r4)
- st %r1,4(0,%r0) #store it at addr 0+4B, i.e. second part of psw
+ la %r4,load_psw-.base(%r13) #load psw-address into the register
+ o %r3,4(%r4) #or load address into psw
+ st %r3,4(%r4)
+ mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0
sam31 #31 bit mode
sr %r1,%r1 #erase register r1
sr %r2,%r2 #erase register r2
diff -urN a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S
--- a/arch/s390/kernel/relocate_kernel.S 2005-04-27 13:18:09.000000000 +0200
+++ b/arch/s390/kernel/relocate_kernel.S 2005-04-27 13:19:37.000000000 +0200
@@ -9,9 +9,8 @@

/*
* moves the new kernel to its destination...
- * %r2 = indirection page
- * %r3 = reboot_code_buffer
- * %r4 = start address - where to jump to after the job is done...
+ * %r2 = pointer to first kimage_entry_t
+ * %r3 = start address - where to jump to after the job is done...
*
* %r5 will be used as temp. storage
* %r6 holds the destination address
@@ -60,11 +59,10 @@
j .top
.done:
sr %r0,%r0 #clear register r0
- la %r3,load_psw-.base(%r13) #load psw-address into the register
- mvc 0(4,%r0),0(%r3) #copy the first part of psw
- l %r1,4(0,%r3) #get the second part of psw in %r1
- or %r1,%r4 #OR the load address with the 2nd part of psw
- st %r1,4(0,%r0) #store it at add 0+4B
+ la %r4,load_psw-.base(%r13) #load psw-address into the register
+ o %r3,4(%r4) #or load address into psw
+ st %r3,4(%r4)
+ mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0
sr %r1,%r1 #clear %r1
sr %r2,%r2 #clear %r2
sigp %r1,%r2,0x12 #set cpuid to zero
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-04-29 08:11    [from the cache]
©2003-2011 Jasper Spaans. Advertise on this site