s390/kexec_file: Load new kernel to absolute 0
The leading 64 kB of a kernel image doesn't contain any data needed to boot the new kernel when it was loaded via kexec_file. Thus kexec_file currently strips them off before loading the image. Keep the leading 64 kB in order to be able to pass a ipl_report to the next kernel. Signed-off-by: Philipp Rudo <prudo@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
8e49642613
commit
653beba24d
@ -43,6 +43,9 @@
|
|||||||
/* The native architecture */
|
/* The native architecture */
|
||||||
#define KEXEC_ARCH KEXEC_ARCH_S390
|
#define KEXEC_ARCH KEXEC_ARCH_S390
|
||||||
|
|
||||||
|
/* Allow kexec_file to load a segment to 0 */
|
||||||
|
#define KEXEC_BUF_MEM_UNKNOWN -1
|
||||||
|
|
||||||
/* Provide a dummy definition to avoid build failures. */
|
/* Provide a dummy definition to avoid build failures. */
|
||||||
static inline void crash_setup_regs(struct pt_regs *newregs,
|
static inline void crash_setup_regs(struct pt_regs *newregs,
|
||||||
struct pt_regs *oldregs) { }
|
struct pt_regs *oldregs) { }
|
||||||
@ -52,6 +55,9 @@ struct s390_load_data {
|
|||||||
/* Pointer to the kernel buffer. Used to register cmdline etc.. */
|
/* Pointer to the kernel buffer. Used to register cmdline etc.. */
|
||||||
void *kernel_buf;
|
void *kernel_buf;
|
||||||
|
|
||||||
|
/* Load address of the kernel_buf. */
|
||||||
|
unsigned long kernel_mem;
|
||||||
|
|
||||||
/* Parmarea in the kernel buffer. */
|
/* Parmarea in the kernel buffer. */
|
||||||
struct parmarea *parm;
|
struct parmarea *parm;
|
||||||
|
|
||||||
|
@ -39,28 +39,20 @@ static int kexec_file_add_kernel_elf(struct kimage *image,
|
|||||||
buf.bufsz = phdr->p_filesz;
|
buf.bufsz = phdr->p_filesz;
|
||||||
|
|
||||||
buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
|
buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
|
||||||
|
if (image->type == KEXEC_TYPE_CRASH)
|
||||||
|
buf.mem += crashk_res.start;
|
||||||
buf.memsz = phdr->p_memsz;
|
buf.memsz = phdr->p_memsz;
|
||||||
|
data->memsz = ALIGN(data->memsz, phdr->p_align) + buf.memsz;
|
||||||
|
|
||||||
if (entry - phdr->p_paddr < phdr->p_memsz) {
|
if (entry - phdr->p_paddr < phdr->p_memsz) {
|
||||||
data->kernel_buf = buf.buffer;
|
data->kernel_buf = buf.buffer;
|
||||||
|
data->kernel_mem = buf.mem;
|
||||||
data->parm = buf.buffer + PARMAREA;
|
data->parm = buf.buffer + PARMAREA;
|
||||||
data->memsz += STARTUP_NORMAL_OFFSET;
|
|
||||||
|
|
||||||
buf.buffer += STARTUP_NORMAL_OFFSET;
|
|
||||||
buf.bufsz -= STARTUP_NORMAL_OFFSET;
|
|
||||||
|
|
||||||
buf.mem += STARTUP_NORMAL_OFFSET;
|
|
||||||
buf.memsz -= STARTUP_NORMAL_OFFSET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image->type == KEXEC_TYPE_CRASH)
|
|
||||||
buf.mem += crashk_res.start;
|
|
||||||
|
|
||||||
ret = kexec_add_buffer(&buf);
|
ret = kexec_add_buffer(&buf);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
data->memsz = ALIGN(data->memsz, phdr->p_align) + buf.memsz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data->memsz ? 0 : -EINVAL;
|
return data->memsz ? 0 : -EINVAL;
|
||||||
|
@ -19,17 +19,18 @@ static int kexec_file_add_kernel_image(struct kimage *image,
|
|||||||
|
|
||||||
buf.image = image;
|
buf.image = image;
|
||||||
|
|
||||||
buf.buffer = image->kernel_buf + STARTUP_NORMAL_OFFSET;
|
buf.buffer = image->kernel_buf;
|
||||||
buf.bufsz = image->kernel_buf_len - STARTUP_NORMAL_OFFSET;
|
buf.bufsz = image->kernel_buf_len;
|
||||||
|
|
||||||
buf.mem = STARTUP_NORMAL_OFFSET;
|
buf.mem = 0;
|
||||||
if (image->type == KEXEC_TYPE_CRASH)
|
if (image->type == KEXEC_TYPE_CRASH)
|
||||||
buf.mem += crashk_res.start;
|
buf.mem += crashk_res.start;
|
||||||
buf.memsz = buf.bufsz;
|
buf.memsz = buf.bufsz;
|
||||||
|
|
||||||
data->kernel_buf = image->kernel_buf;
|
data->kernel_buf = image->kernel_buf;
|
||||||
|
data->kernel_mem = buf.mem;
|
||||||
data->parm = image->kernel_buf + PARMAREA;
|
data->parm = image->kernel_buf + PARMAREA;
|
||||||
data->memsz += buf.memsz + STARTUP_NORMAL_OFFSET;
|
data->memsz += buf.memsz;
|
||||||
|
|
||||||
return kexec_add_buffer(&buf);
|
return kexec_add_buffer(&buf);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int kexec_file_update_purgatory(struct kimage *image)
|
static int kexec_file_update_purgatory(struct kimage *image,
|
||||||
|
struct s390_load_data *data)
|
||||||
{
|
{
|
||||||
u64 entry, type;
|
u64 entry, type;
|
||||||
int ret;
|
int ret;
|
||||||
@ -76,7 +77,7 @@ static int kexec_file_add_purgatory(struct kimage *image,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = kexec_file_update_purgatory(image);
|
ret = kexec_file_update_purgatory(image, data);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +137,13 @@ void *kexec_file_add_components(struct kimage *image,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
|
if (data.kernel_mem == 0) {
|
||||||
|
unsigned long restart_psw = 0x0008000080000000UL;
|
||||||
|
restart_psw += image->start;
|
||||||
|
memcpy(data.kernel_buf, &restart_psw, sizeof(restart_psw));
|
||||||
|
image->start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,10 +58,13 @@ ENTRY(relocate_kernel)
|
|||||||
j .base
|
j .base
|
||||||
.done:
|
.done:
|
||||||
sgr %r0,%r0 # clear register r0
|
sgr %r0,%r0 # clear register r0
|
||||||
|
cghi %r3,0
|
||||||
|
je .diag
|
||||||
la %r4,load_psw-.base(%r13) # load psw-address into the register
|
la %r4,load_psw-.base(%r13) # load psw-address into the register
|
||||||
o %r3,4(%r4) # or load address into psw
|
o %r3,4(%r4) # or load address into psw
|
||||||
st %r3,4(%r4)
|
st %r3,4(%r4)
|
||||||
mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0
|
mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0
|
||||||
|
.diag:
|
||||||
diag %r0,%r0,0x308
|
diag %r0,%r0,0x308
|
||||||
|
|
||||||
.align 8
|
.align 8
|
||||||
|
Loading…
Reference in New Issue
Block a user