Skip to content

Commit

Permalink
x86: Disable kexec if system has unaccepted memory
Browse files Browse the repository at this point in the history
On kexec, the target kernel has to know what memory has been accepted.
Information in EFI map is out of date and cannot be used.

boot_params.unaccepted_memory can be used to pass the bitmap between two
kernels on kexec, but the use-case is not yet implemented.

Disable kexec on machines with unaccepted memory for now.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
  • Loading branch information
kiryl committed Aug 16, 2022
1 parent 51a63fe commit 820c5c3
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 0 deletions.
3 changes: 3 additions & 0 deletions arch/x86/include/asm/kexec.h
Expand Up @@ -189,6 +189,9 @@ extern void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages);
void arch_kexec_protect_crashkres(void);
#define arch_kexec_protect_crashkres arch_kexec_protect_crashkres

int arch_kexec_load(void);
#define arch_kexec_load arch_kexec_load

void arch_kexec_unprotect_crashkres(void);
#define arch_kexec_unprotect_crashkres arch_kexec_unprotect_crashkres

Expand Down
16 changes: 16 additions & 0 deletions arch/x86/mm/unaccepted_memory.c
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/kexec.h>
#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/pfn.h>
Expand Down Expand Up @@ -98,3 +99,18 @@ bool range_contains_unaccepted_memory(phys_addr_t start, phys_addr_t end)

return ret;
}

#ifdef CONFIG_KEXEC_CORE
int arch_kexec_load(void)
{
if (!boot_params.unaccepted_memory)
return 0;

/*
* TODO: Information on memory acceptance status has to be communicated
* between kernel.
*/
pr_warn_once("Disable kexec: not yet supported on systems with unaccepted memory\n");
return -EOPNOTSUPP;
}
#endif
7 changes: 7 additions & 0 deletions include/linux/kexec.h
Expand Up @@ -444,6 +444,13 @@ static inline void arch_kexec_protect_crashkres(void) { }
static inline void arch_kexec_unprotect_crashkres(void) { }
#endif

#ifndef arch_kexec_load
static inline int arch_kexec_load(void)
{
return 0;
}
#endif

#ifndef page_to_boot_pfn
static inline unsigned long page_to_boot_pfn(struct page *page)
{
Expand Down
4 changes: 4 additions & 0 deletions kernel/kexec.c
Expand Up @@ -195,6 +195,10 @@ static inline int kexec_load_check(unsigned long nr_segments,
{
int result;

result = arch_kexec_load();
if (result)
return result;

/* We only trust the superuser with rebooting the system. */
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
return -EPERM;
Expand Down
4 changes: 4 additions & 0 deletions kernel/kexec_file.c
Expand Up @@ -329,6 +329,10 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
int ret = 0, i;
struct kimage **dest_image, *image;

ret = arch_kexec_load();
if (ret)
return ret;

/* We only trust the superuser with rebooting the system. */
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
return -EPERM;
Expand Down

0 comments on commit 820c5c3

Please sign in to comment.