From: Vivek Goyal <vgoyal@redhat.com>
To: linux-kernel@vger.kernel.org, kexec@lists.infradead.org
Cc: ebiederm@xmission.com, hpa@zytor.com, mjg59@srcf.ucam.org,
greg@kroah.com, bp@alien8.de, jkosina@suse.cz, dyoung@redhat.com,
chaowang@redhat.com, bhe@redhat.com, akpm@linux-foundation.org,
Vivek Goyal <vgoyal@redhat.com>
Subject: [PATCH 13/13] kexec: Support kexec/kdump on EFI systems
Date: Tue, 3 Jun 2014 09:07:02 -0400 [thread overview]
Message-ID: <1401800822-27425-14-git-send-email-vgoyal@redhat.com> (raw)
In-Reply-To: <1401800822-27425-1-git-send-email-vgoyal@redhat.com>
This patch does two thigns. It passes EFI run time mappings to second
kernel in bootparams efi_info. Second kernel parse this info and create
new mappings in second kernel. That means mappings in first and second
kernel will be same. This paves the way to enable EFI in kexec kernel.
This patch also prepares and passes EFI setup data through bootparams.
This contains bunch of information about various tables and their
addresses.
These information gathering and passing has been written along the lines
of what current kexec-tools is doing to make kexec work with UEFI.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
arch/x86/include/asm/kexec.h | 4 +-
arch/x86/kernel/kexec-bzimage.c | 40 ++++++++++++----
arch/x86/kernel/machine_kexec.c | 93 ++++++++++++++++++++++++++++++++++++--
drivers/firmware/efi/runtime-map.c | 21 +++++++++
include/linux/efi.h | 19 ++++++++
5 files changed, 163 insertions(+), 14 deletions(-)
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 4cbe5f7..d8461cf 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -214,7 +214,9 @@ extern int kexec_setup_cmdline(struct kimage *image,
unsigned long cmdline_offset, char *cmdline,
unsigned long cmdline_len);
extern int kexec_setup_boot_parameters(struct kimage *image,
- struct boot_params *params);
+ struct boot_params *params, unsigned long params_load_addr,
+ unsigned int efi_map_offset, unsigned int efi_map_sz,
+ unsigned int efi_setup_data_offset);
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/kernel/kexec-bzimage.c b/arch/x86/kernel/kexec-bzimage.c
index 8e762d3..55716e1 100644
--- a/arch/x86/kernel/kexec-bzimage.c
+++ b/arch/x86/kernel/kexec-bzimage.c
@@ -15,10 +15,12 @@
#include <linux/kexec.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/efi.h>
#include <asm/bootparam.h>
#include <asm/setup.h>
#include <asm/crash.h>
+#include <asm/efi.h>
#define MAX_ELFCOREHDR_STR_LEN 30 /* elfcorehdr=0x<64bit-value> */
@@ -106,7 +108,7 @@ void *bzImage64_load(struct kimage *image, char *kernel,
struct setup_header *header;
int setup_sects, kern16_size, ret = 0;
- unsigned long setup_header_size, params_cmdline_sz;
+ unsigned long setup_header_size, params_cmdline_sz, params_misc_sz;
struct boot_params *params;
unsigned long bootparam_load_addr, kernel_load_addr, initrd_load_addr;
unsigned long purgatory_load_addr;
@@ -116,6 +118,7 @@ void *bzImage64_load(struct kimage *image, char *kernel,
struct kexec_entry64_regs regs64;
void *stack;
unsigned int setup_hdr_offset = offsetof(struct boot_params, hdr);
+ unsigned int efi_map_offset, efi_map_sz, efi_setup_data_offset;
header = (struct setup_header *)(kernel + setup_hdr_offset);
setup_sects = header->setup_sects;
@@ -168,28 +171,47 @@ void *bzImage64_load(struct kimage *image, char *kernel,
pr_debug("Loaded purgatory at 0x%lx\n", purgatory_load_addr);
- /* Load Bootparams and cmdline */
+
+ /*
+ * Load Bootparams and cmdline and space for efi stuff.
+ *
+ * Allocate memory together for multiple data structures so
+ * that they all can go in single area/segment and we don't
+ * have to create separate segment for each. Keeps things
+ * little bit simple
+ */
+ efi_map_sz = get_efi_runtime_map_size();
+ efi_map_sz = ALIGN(efi_map_sz, 16);
+
params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
MAX_ELFCOREHDR_STR_LEN;
- params = kzalloc(params_cmdline_sz, GFP_KERNEL);
+ params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
+ params_misc_sz = params_cmdline_sz + efi_map_sz +
+ sizeof(struct setup_data) +
+ sizeof(struct efi_setup_data);
+
+ params = kzalloc(params_misc_sz, GFP_KERNEL);
if (!params) {
ret = -ENOMEM;
goto out_free_loader_data;
}
+ efi_map_offset = params_cmdline_sz;
+ efi_setup_data_offset = efi_map_offset + efi_map_sz;
+
/* Copy setup header onto bootparams. Documentation/x86/boot.txt */
setup_header_size = 0x0202 + kernel[0x0201] - setup_hdr_offset;
/* Is there a limit on setup header size? */
memcpy(¶ms->hdr, (kernel + setup_hdr_offset), setup_header_size);
- ret = kexec_add_buffer(image, (char *)params, params_cmdline_sz,
- params_cmdline_sz, 16, MIN_BOOTPARAM_ADDR,
+ ret = kexec_add_buffer(image, (char *)params, params_misc_sz,
+ params_misc_sz, 16, MIN_BOOTPARAM_ADDR,
ULONG_MAX, 1, &bootparam_load_addr);
if (ret)
goto out_free_params;
- pr_debug("Loaded boot_param and command line at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
- bootparam_load_addr, params_cmdline_sz, params_cmdline_sz);
+ pr_debug("Loaded boot_param, command line and misc at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ bootparam_load_addr, params_misc_sz, params_misc_sz);
/* Load kernel */
kernel_buf = kernel + kern16_size;
@@ -254,7 +276,9 @@ void *bzImage64_load(struct kimage *image, char *kernel,
if (ret)
goto out_free_params;
- ret = kexec_setup_boot_parameters(image, params);
+ ret = kexec_setup_boot_parameters(image, params, bootparam_load_addr,
+ efi_map_offset, efi_map_sz,
+ efi_setup_data_offset);
if (ret)
goto out_free_params;
diff --git a/arch/x86/kernel/machine_kexec.c b/arch/x86/kernel/machine_kexec.c
index 6a3821b..f31a4b5 100644
--- a/arch/x86/kernel/machine_kexec.c
+++ b/arch/x86/kernel/machine_kexec.c
@@ -12,9 +12,11 @@
#include <linux/kernel.h>
#include <linux/kexec.h>
#include <linux/string.h>
+#include <linux/efi.h>
#include <asm/bootparam.h>
#include <asm/setup.h>
#include <asm/crash.h>
+#include <asm/efi.h>
/*
* Common code for x86 and x86_64 used for kexec.
@@ -67,11 +69,10 @@ int kexec_setup_cmdline(struct kimage *image, struct boot_params *params,
return 0;
}
-static int setup_memory_map_entries(struct boot_params *params)
+static int setup_e820_entries(struct boot_params *params)
{
unsigned int nr_e820_entries;
- /* TODO: What about EFI */
nr_e820_entries = e820_saved.nr_map;
if (nr_e820_entries > E820MAX)
nr_e820_entries = E820MAX;
@@ -83,8 +84,85 @@ static int setup_memory_map_entries(struct boot_params *params)
return 0;
}
-int kexec_setup_boot_parameters(struct kimage *image,
- struct boot_params *params)
+#ifdef CONFIG_EFI
+static int setup_efi_info_memmap(struct boot_params *params,
+ unsigned long params_load_addr,
+ unsigned int efi_map_offset,
+ unsigned int efi_map_sz)
+{
+ void *efi_map = (void *)params + efi_map_offset;
+ unsigned long efi_map_phys_addr = params_load_addr + efi_map_offset;
+ struct efi_info *ei = ¶ms->efi_info;
+
+ if (!efi_map_sz)
+ return 0;
+
+ efi_runtime_map_copy(efi_map, efi_map_sz);
+
+ ei->efi_memmap = efi_map_phys_addr & 0xffffffff;
+ ei->efi_memmap_hi = efi_map_phys_addr >> 32;
+ ei->efi_memmap_size = efi_map_sz;
+
+ return 0;
+}
+
+static int
+prepare_add_efi_setup_data(struct boot_params *params,
+ unsigned long params_load_addr,
+ unsigned int efi_setup_data_offset)
+{
+ unsigned long setup_data_phys;
+ struct setup_data *sd = (void *)params + efi_setup_data_offset;
+ struct efi_setup_data *esd = (void *)sd + sizeof(struct setup_data);
+
+ esd->fw_vendor = efi.fw_vendor;
+ esd->runtime = efi.runtime;
+ esd->tables = efi.config_table;
+ esd->smbios = efi.smbios;
+
+ sd->type = SETUP_EFI;
+ sd->len = sizeof(struct efi_setup_data);
+
+ /* Add setup data */
+ setup_data_phys = params_load_addr + efi_setup_data_offset;
+ sd->next = params->hdr.setup_data;
+ params->hdr.setup_data = setup_data_phys;
+
+ return 0;
+}
+
+static int setup_efi_state(struct boot_params *params,
+ unsigned long params_load_addr,
+ unsigned int efi_map_offset, unsigned int efi_map_sz,
+ unsigned int efi_setup_data_offset)
+{
+ struct efi_info *current_ei = &boot_params.efi_info;
+ struct efi_info *ei = ¶ms->efi_info;
+
+ if (!current_ei->efi_memmap_size)
+ return 0;
+
+ ei->efi_loader_signature = current_ei->efi_loader_signature;
+ ei->efi_systab = current_ei->efi_systab;
+ ei->efi_systab_hi = current_ei->efi_systab_hi;
+
+ ei->efi_memdesc_version = current_ei->efi_memdesc_version;
+ ei->efi_memdesc_size = get_efi_runtime_map_desc_size();
+
+ setup_efi_info_memmap(params, params_load_addr, efi_map_offset,
+ efi_map_sz);
+ prepare_add_efi_setup_data(params, params_load_addr,
+ efi_setup_data_offset);
+ return 0;
+}
+#endif /* CONFIG_EFI */
+
+int
+kexec_setup_boot_parameters(struct kimage *image, struct boot_params *params,
+ unsigned long params_load_addr,
+ unsigned int efi_map_offset,
+ unsigned int efi_map_sz,
+ unsigned int efi_setup_data_offset)
{
unsigned int nr_e820_entries;
unsigned long long mem_k, start, end;
@@ -114,7 +192,7 @@ int kexec_setup_boot_parameters(struct kimage *image,
if (image->type == KEXEC_TYPE_CRASH)
crash_setup_memmap_entries(image, params);
else
- setup_memory_map_entries(params);
+ setup_e820_entries(params);
nr_e820_entries = params->e820_entries;
@@ -135,6 +213,11 @@ int kexec_setup_boot_parameters(struct kimage *image,
}
}
+#ifdef CONFIG_EFI
+ /* Setup EFI state */
+ setup_efi_state(params, params_load_addr, efi_map_offset, efi_map_sz,
+ efi_setup_data_offset);
+#endif
/* Setup EDD info */
memcpy(params->eddbuf, boot_params.eddbuf,
EDDMAXNR * sizeof(struct edd_info));
diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c
index 97cdd16..40f2213 100644
--- a/drivers/firmware/efi/runtime-map.c
+++ b/drivers/firmware/efi/runtime-map.c
@@ -138,6 +138,27 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
return entry;
}
+int get_efi_runtime_map_size(void)
+{
+ return nr_efi_runtime_map * efi_memdesc_size;
+}
+
+int get_efi_runtime_map_desc_size(void)
+{
+ return efi_memdesc_size;
+}
+
+int efi_runtime_map_copy(void *buf, size_t bufsz)
+{
+ size_t sz = get_efi_runtime_map_size();
+
+ if (sz > bufsz)
+ sz = bufsz;
+
+ memcpy(buf, efi_runtime_map, sz);
+ return 0;
+}
+
void efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size)
{
efi_runtime_map = map;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 6c100ff..c2e5c4a 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1131,6 +1131,9 @@ int efivars_sysfs_init(void);
#ifdef CONFIG_EFI_RUNTIME_MAP
int efi_runtime_map_init(struct kobject *);
void efi_runtime_map_setup(void *, int, u32);
+int get_efi_runtime_map_size(void);
+int get_efi_runtime_map_desc_size(void);
+int efi_runtime_map_copy(void *buf, size_t bufsz);
#else
static inline int efi_runtime_map_init(struct kobject *kobj)
{
@@ -1139,6 +1142,22 @@ static inline int efi_runtime_map_init(struct kobject *kobj)
static inline void
efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size) {}
+
+static inline int get_efi_runtime_map_size(void)
+{
+ return 0;
+}
+
+static inline int get_efi_runtime_map_desc_size(void)
+{
+ return 0;
+}
+
+static inline int efi_runtime_map_copy(void *buf, size_t bufsz)
+{
+ return 0;
+}
+
#endif
#endif /* _LINUX_EFI_H */
--
1.9.0
next prev parent reply other threads:[~2014-06-03 13:08 UTC|newest]
Thread overview: 104+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-03 13:06 [RFC PATCH 00/13][V3] kexec: A new system call to allow in kernel loading Vivek Goyal
2014-06-03 13:06 ` [PATCH 01/13] bin2c: Move bin2c in scripts/basic Vivek Goyal
2014-06-03 16:01 ` Borislav Petkov
2014-06-03 17:13 ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 02/13] kernel: Build bin2c based on config option CONFIG_BUILD_BIN2C Vivek Goyal
2014-06-04 9:13 ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 03/13] kexec: Move segment verification code in a separate function Vivek Goyal
2014-06-04 9:32 ` Borislav Petkov
2014-06-04 18:47 ` Vivek Goyal
2014-06-04 20:30 ` Borislav Petkov
2014-06-05 14:05 ` Vivek Goyal
2014-06-05 14:07 ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 04/13] resource: Provide new functions to walk through resources Vivek Goyal
2014-06-04 10:24 ` Borislav Petkov
2014-06-05 13:58 ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 05/13] kexec: Make kexec_segment user buffer pointer a union Vivek Goyal
2014-06-04 10:34 ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 06/13] kexec: New syscall kexec_file_load() declaration Vivek Goyal
2014-06-04 15:18 ` Borislav Petkov
2014-06-05 9:56 ` WANG Chao
2014-06-05 15:16 ` Vivek Goyal
2014-06-05 15:22 ` Vivek Goyal
2014-06-06 6:34 ` WANG Chao
2014-06-03 13:06 ` [PATCH 07/13] kexec: Implementation of new syscall kexec_file_load Vivek Goyal
2014-06-05 11:15 ` Borislav Petkov
2014-06-05 20:17 ` Vivek Goyal
2014-06-06 2:11 ` Borislav Petkov
2014-06-06 18:02 ` Vivek Goyal
2014-06-11 14:13 ` Borislav Petkov
2014-06-11 17:04 ` Vivek Goyal
2014-06-06 6:56 ` WANG Chao
2014-06-06 18:19 ` Vivek Goyal
2014-06-09 2:11 ` Dave Young
2014-06-09 5:35 ` WANG Chao
2014-06-09 15:41 ` Vivek Goyal
2014-06-13 7:50 ` Borislav Petkov
2014-06-13 8:00 ` WANG Chao
2014-06-13 8:10 ` Borislav Petkov
2014-06-13 8:24 ` WANG Chao
2014-06-13 8:30 ` Borislav Petkov
2014-06-13 12:49 ` Vivek Goyal
2014-06-13 12:46 ` Vivek Goyal
2014-06-13 15:36 ` Borislav Petkov
2014-06-16 17:38 ` Vivek Goyal
2014-06-16 20:05 ` Borislav Petkov
2014-06-16 20:53 ` Vivek Goyal
2014-06-16 21:09 ` Borislav Petkov
2014-06-16 21:25 ` H. Peter Anvin
2014-06-16 21:43 ` Vivek Goyal
2014-06-16 22:10 ` Borislav Petkov
2014-06-16 22:49 ` H. Peter Anvin
2014-06-09 15:30 ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 08/13] purgatory/sha256: Provide implementation of sha256 in purgaotory context Vivek Goyal
2014-06-03 13:06 ` [PATCH 09/13] purgatory: Core purgatory functionality Vivek Goyal
2014-06-05 20:05 ` Borislav Petkov
2014-06-06 19:51 ` Vivek Goyal
2014-06-13 10:17 ` Borislav Petkov
2014-06-16 17:25 ` Vivek Goyal
2014-06-16 20:10 ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 10/13] kexec: Load and Relocate purgatory at kernel load time Vivek Goyal
2014-06-10 16:31 ` Borislav Petkov
2014-06-11 19:24 ` Vivek Goyal
2014-06-13 16:14 ` Borislav Petkov
2014-06-03 13:07 ` [PATCH 11/13] kexec-bzImage: Support for loading bzImage using 64bit entry Vivek Goyal
2014-06-15 16:35 ` Borislav Petkov
2014-06-15 16:56 ` H. Peter Anvin
2014-06-16 20:06 ` Vivek Goyal
2014-06-16 20:57 ` Borislav Petkov
2014-06-16 21:15 ` Vivek Goyal
2014-06-16 21:27 ` Borislav Petkov
2014-06-16 21:45 ` Vivek Goyal
2014-06-24 17:31 ` Vivek Goyal
2014-06-24 18:23 ` Borislav Petkov
2014-06-03 13:07 ` [PATCH 12/13] kexec: Support for Kexec on panic using new system call Vivek Goyal
2014-06-17 21:43 ` Borislav Petkov
2014-06-18 14:20 ` Vivek Goyal
2014-06-03 13:07 ` Vivek Goyal [this message]
2014-06-18 15:43 ` [PATCH 13/13] kexec: Support kexec/kdump on EFI systems Borislav Petkov
2014-06-18 16:06 ` Borislav Petkov
2014-06-18 17:39 ` Vivek Goyal
2014-06-03 13:12 ` [RFC PATCH 00/13][V3] kexec: A new system call to allow in kernel loading Vivek Goyal
2014-06-04 9:22 ` WANG Chao
2014-06-04 17:50 ` Vivek Goyal
2014-06-04 19:39 ` Michael Kerrisk
2014-06-05 14:04 ` Vivek Goyal
2014-06-06 5:45 ` Michael Kerrisk (man-pages)
2014-06-06 18:04 ` Vivek Goyal
2014-06-05 8:31 ` Dave Young
2014-06-05 15:01 ` Vivek Goyal
2014-06-06 7:37 ` Dave Young
2014-06-06 20:04 ` Vivek Goyal
2014-06-09 1:57 ` Dave Young
2014-06-06 20:37 ` H. Peter Anvin
2014-06-06 20:58 ` Matt Fleming
2014-06-06 21:00 ` H. Peter Anvin
2014-06-06 21:02 ` Matt Fleming
2014-06-12 5:42 ` Dave Young
2014-06-12 12:36 ` Vivek Goyal
2014-06-17 14:24 ` Vivek Goyal
2014-06-18 1:45 ` Dave Young
2014-06-18 1:52 ` Dave Young
2014-06-18 12:40 ` Vivek Goyal
2014-06-16 21:13 ` Borislav Petkov
2014-06-17 13:24 ` Vivek Goyal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1401800822-27425-14-git-send-email-vgoyal@redhat.com \
--to=vgoyal@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=bhe@redhat.com \
--cc=bp@alien8.de \
--cc=chaowang@redhat.com \
--cc=dyoung@redhat.com \
--cc=ebiederm@xmission.com \
--cc=greg@kroah.com \
--cc=hpa@zytor.com \
--cc=jkosina@suse.cz \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mjg59@srcf.ucam.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).