Skip to content

Commit

Permalink
x86/kdump: Remove the backup region handling
Browse files Browse the repository at this point in the history
When the crashkernel kernel command line option is specified, the low
1M memory will always be reserved now. Therefore, it's not necessary to
create a backup region anymore and also no need to copy the contents of
the first 640k to it.

Remove all the code related to handling that backup region.

 [ bp: Massage commit message. ]

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: bhe@redhat.com
Cc: Dave Young <dyoung@redhat.com>
Cc: d.hatayama@fujitsu.com
Cc: dhowells@redhat.com
Cc: ebiederm@xmission.com
Cc: horms@verge.net.au
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jürgen Gross <jgross@suse.com>
Cc: kexec@lists.infradead.org
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: vgoyal@redhat.com
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20191108090027.11082-3-lijiang@redhat.com
  • Loading branch information
lian-bo authored and suryasaimadhu committed Nov 14, 2019
1 parent 6f599d8 commit 7c321eb
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 162 deletions.
10 changes: 0 additions & 10 deletions arch/x86/include/asm/kexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@ struct kimage;
# define KEXEC_ARCH KEXEC_ARCH_X86_64
#endif

/* Memory to backup during crash kdump */
#define KEXEC_BACKUP_SRC_START (0UL)
#define KEXEC_BACKUP_SRC_END (640 * 1024UL - 1) /* 640K */

/*
* This function is responsible for capturing register states if coming
* via panic otherwise just fix up the ss and sp if coming via kernel
Expand Down Expand Up @@ -154,12 +150,6 @@ struct kimage_arch {
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
/* Details of backup region */
unsigned long backup_src_start;
unsigned long backup_src_sz;

/* Physical address of backup segment */
unsigned long backup_load_addr;

/* Core ELF header buffer */
void *elf_headers;
Expand Down
10 changes: 0 additions & 10 deletions arch/x86/include/asm/purgatory.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@
#include <linux/purgatory.h>

extern void purgatory(void);
/*
* These forward declarations serve two purposes:
*
* 1) Make sparse happy when checking arch/purgatory
* 2) Document that these are required to be global so the symbol
* lookup in kexec works
*/
extern unsigned long purgatory_backup_dest;
extern unsigned long purgatory_backup_src;
extern unsigned long purgatory_backup_sz;
#endif /* __ASSEMBLY__ */

#endif /* _ASM_PURGATORY_H */
87 changes: 11 additions & 76 deletions arch/x86/kernel/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@ void native_machine_crash_shutdown(struct pt_regs *regs)

#ifdef CONFIG_KEXEC_FILE

static unsigned long crash_zero_bytes;

static int get_nr_ram_ranges_callback(struct resource *res, void *arg)
{
unsigned int *nr_ranges = arg;
Expand Down Expand Up @@ -232,6 +230,11 @@ static int elf_header_exclude_ranges(struct crash_mem *cmem)
{
int ret = 0;

/* Exclude the low 1M because it is always reserved */
ret = crash_exclude_mem_range(cmem, 0, 1<<20);
if (ret)
return ret;

/* Exclude crashkernel region */
ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
if (ret)
Expand Down Expand Up @@ -261,9 +264,7 @@ static int prepare_elf_headers(struct kimage *image, void **addr,
unsigned long *sz)
{
struct crash_mem *cmem;
Elf64_Ehdr *ehdr;
Elf64_Phdr *phdr;
int ret, i;
int ret;

cmem = fill_up_crash_elf_data();
if (!cmem)
Expand All @@ -282,22 +283,7 @@ static int prepare_elf_headers(struct kimage *image, void **addr,
/* By default prepare 64bit headers */
ret = crash_prepare_elf64_headers(cmem,
IS_ENABLED(CONFIG_X86_64), addr, sz);
if (ret)
goto out;

/*
* If a range matches backup region, adjust offset to backup
* segment.
*/
ehdr = (Elf64_Ehdr *)*addr;
phdr = (Elf64_Phdr *)(ehdr + 1);
for (i = 0; i < ehdr->e_phnum; phdr++, i++)
if (phdr->p_type == PT_LOAD &&
phdr->p_paddr == image->arch.backup_src_start &&
phdr->p_memsz == image->arch.backup_src_sz) {
phdr->p_offset = image->arch.backup_load_addr;
break;
}
out:
vfree(cmem);
return ret;
Expand Down Expand Up @@ -336,19 +322,11 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem,
unsigned long long mend)
{
unsigned long start, end;
int ret = 0;

cmem->ranges[0].start = mstart;
cmem->ranges[0].end = mend;
cmem->nr_ranges = 1;

/* Exclude Backup region */
start = image->arch.backup_load_addr;
end = start + image->arch.backup_src_sz - 1;
ret = crash_exclude_mem_range(cmem, start, end);
if (ret)
return ret;

/* Exclude elf header region */
start = image->arch.elf_load_addr;
end = start + image->arch.elf_headers_sz - 1;
Expand All @@ -371,11 +349,11 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
memset(&cmd, 0, sizeof(struct crash_memmap_data));
cmd.params = params;

/* Add first 640K segment */
ei.addr = image->arch.backup_src_start;
ei.size = image->arch.backup_src_sz;
ei.type = E820_TYPE_RAM;
add_e820_entry(params, &ei);
/* Add the low 1M */
cmd.type = E820_TYPE_RAM;
flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
walk_iomem_res_desc(IORES_DESC_NONE, flags, 0, (1<<20)-1, &cmd,
memmap_entry_callback);

/* Add ACPI tables */
cmd.type = E820_TYPE_ACPI;
Expand Down Expand Up @@ -424,55 +402,12 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
return ret;
}

static int determine_backup_region(struct resource *res, void *arg)
{
struct kimage *image = arg;

image->arch.backup_src_start = res->start;
image->arch.backup_src_sz = resource_size(res);

/* Expecting only one range for backup region */
return 1;
}

int crash_load_segments(struct kimage *image)
{
int ret;
struct kexec_buf kbuf = { .image = image, .buf_min = 0,
.buf_max = ULONG_MAX, .top_down = false };

/*
* Determine and load a segment for backup area. First 640K RAM
* region is backup source
*/

ret = walk_system_ram_res(KEXEC_BACKUP_SRC_START, KEXEC_BACKUP_SRC_END,
image, determine_backup_region);

/* Zero or postive return values are ok */
if (ret < 0)
return ret;

/* Add backup segment. */
if (image->arch.backup_src_sz) {
kbuf.buffer = &crash_zero_bytes;
kbuf.bufsz = sizeof(crash_zero_bytes);
kbuf.memsz = image->arch.backup_src_sz;
kbuf.buf_align = PAGE_SIZE;
/*
* Ideally there is no source for backup segment. This is
* copied in purgatory after crash. Just add a zero filled
* segment for now to make sure checksum logic works fine.
*/
ret = kexec_add_buffer(&kbuf);
if (ret)
return ret;
image->arch.backup_load_addr = kbuf.mem;
pr_debug("Loaded backup region at 0x%lx backup_start=0x%lx memsz=0x%lx\n",
image->arch.backup_load_addr,
image->arch.backup_src_start, kbuf.memsz);
}

/* Prepare elf headers and add a segment */
ret = prepare_elf_headers(image, &kbuf.buffer, &kbuf.bufsz);
if (ret)
Expand Down
47 changes: 0 additions & 47 deletions arch/x86/kernel/machine_kexec_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,48 +298,6 @@ static void load_segments(void)
);
}

#ifdef CONFIG_KEXEC_FILE
/* Update purgatory as needed after various image segments have been prepared */
static int arch_update_purgatory(struct kimage *image)
{
int ret = 0;

if (!image->file_mode)
return 0;

/* Setup copying of backup region */
if (image->type == KEXEC_TYPE_CRASH) {
ret = kexec_purgatory_get_set_symbol(image,
"purgatory_backup_dest",
&image->arch.backup_load_addr,
sizeof(image->arch.backup_load_addr), 0);
if (ret)
return ret;

ret = kexec_purgatory_get_set_symbol(image,
"purgatory_backup_src",
&image->arch.backup_src_start,
sizeof(image->arch.backup_src_start), 0);
if (ret)
return ret;

ret = kexec_purgatory_get_set_symbol(image,
"purgatory_backup_sz",
&image->arch.backup_src_sz,
sizeof(image->arch.backup_src_sz), 0);
if (ret)
return ret;
}

return ret;
}
#else /* !CONFIG_KEXEC_FILE */
static inline int arch_update_purgatory(struct kimage *image)
{
return 0;
}
#endif /* CONFIG_KEXEC_FILE */

int machine_kexec_prepare(struct kimage *image)
{
unsigned long start_pgtable;
Expand All @@ -353,11 +311,6 @@ int machine_kexec_prepare(struct kimage *image)
if (result)
return result;

/* update purgatory as needed */
result = arch_update_purgatory(image);
if (result)
return result;

return 0;
}

Expand Down
19 changes: 0 additions & 19 deletions arch/x86/purgatory/purgatory.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,10 @@

#include "../boot/string.h"

unsigned long purgatory_backup_dest __section(.kexec-purgatory);
unsigned long purgatory_backup_src __section(.kexec-purgatory);
unsigned long purgatory_backup_sz __section(.kexec-purgatory);

u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE] __section(.kexec-purgatory);

struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX] __section(.kexec-purgatory);

/*
* On x86, second kernel requries first 640K of memory to boot. Copy
* first 640K to a backup region in reserved memory range so that second
* kernel can use first 640K.
*/
static int copy_backup_region(void)
{
if (purgatory_backup_dest) {
memcpy((void *)purgatory_backup_dest,
(void *)purgatory_backup_src, purgatory_backup_sz);
}
return 0;
}

static int verify_sha256_digest(void)
{
struct kexec_sha_region *ptr, *end;
Expand Down Expand Up @@ -66,7 +48,6 @@ void purgatory(void)
for (;;)
;
}
copy_backup_region();
}

/*
Expand Down

0 comments on commit 7c321eb

Please sign in to comment.