Merge branch 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 boot updates from Thomas Gleixner: "Assorted updates to kexec/kdump: - Proper kexec support for 4/5-level paging and jumping from a 5-level to a 4-level paging kernel. - Make the EFI support for kexec/kdump more robust - Enforce that the GDT is properly aligned instead of getting the alignment by chance" * 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/kdump/64: Restrict kdump kernel reservation to <64TB x86/kexec/64: Prevent kexec from 5-level paging to a 4-level only kernel x86/boot: Add xloadflags bits to check for 5-level paging support x86/boot: Make the GDT 8-byte aligned x86/kexec: Add the ACPI NVS region to the ident map x86/boot: Call get_rsdp_addr() after console_init() Revert "x86/boot: Disable RSDP parsing temporarily" x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernels x86/kexec: Add the EFI system tables and ACPI tables to the ident map
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/efi.h>
|
||||
|
||||
#include <asm/init.h>
|
||||
#include <asm/pgtable.h>
|
||||
@@ -27,6 +28,55 @@
|
||||
#include <asm/setup.h>
|
||||
#include <asm/set_memory.h>
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/*
|
||||
* Used while adding mapping for ACPI tables.
|
||||
* Can be reused when other iomem regions need be mapped
|
||||
*/
|
||||
struct init_pgtable_data {
|
||||
struct x86_mapping_info *info;
|
||||
pgd_t *level4p;
|
||||
};
|
||||
|
||||
static int mem_region_callback(struct resource *res, void *arg)
|
||||
{
|
||||
struct init_pgtable_data *data = arg;
|
||||
unsigned long mstart, mend;
|
||||
|
||||
mstart = res->start;
|
||||
mend = mstart + resource_size(res) - 1;
|
||||
|
||||
return kernel_ident_mapping_init(data->info, data->level4p, mstart, mend);
|
||||
}
|
||||
|
||||
static int
|
||||
map_acpi_tables(struct x86_mapping_info *info, pgd_t *level4p)
|
||||
{
|
||||
struct init_pgtable_data data;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
data.info = info;
|
||||
data.level4p = level4p;
|
||||
flags = IORESOURCE_MEM | IORESOURCE_BUSY;
|
||||
|
||||
ret = walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1,
|
||||
&data, mem_region_callback);
|
||||
if (ret && ret != -EINVAL)
|
||||
return ret;
|
||||
|
||||
/* ACPI tables could be located in ACPI Non-volatile Storage region */
|
||||
ret = walk_iomem_res_desc(IORES_DESC_ACPI_NV_STORAGE, flags, 0, -1,
|
||||
&data, mem_region_callback);
|
||||
if (ret && ret != -EINVAL)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int map_acpi_tables(struct x86_mapping_info *info, pgd_t *level4p) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KEXEC_FILE
|
||||
const struct kexec_file_ops * const kexec_file_loaders[] = {
|
||||
&kexec_bzImage64_ops,
|
||||
@@ -34,6 +84,31 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static int
|
||||
map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p)
|
||||
{
|
||||
#ifdef CONFIG_EFI
|
||||
unsigned long mstart, mend;
|
||||
|
||||
if (!efi_enabled(EFI_BOOT))
|
||||
return 0;
|
||||
|
||||
mstart = (boot_params.efi_info.efi_systab |
|
||||
((u64)boot_params.efi_info.efi_systab_hi<<32));
|
||||
|
||||
if (efi_enabled(EFI_64BIT))
|
||||
mend = mstart + sizeof(efi_system_table_64_t);
|
||||
else
|
||||
mend = mstart + sizeof(efi_system_table_32_t);
|
||||
|
||||
if (!mstart)
|
||||
return 0;
|
||||
|
||||
return kernel_ident_mapping_init(info, level4p, mstart, mend);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_transition_pgtable(struct kimage *image)
|
||||
{
|
||||
free_page((unsigned long)image->arch.p4d);
|
||||
@@ -157,6 +232,18 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare EFI systab and ACPI tables for kexec kernel since they are
|
||||
* not covered by pfn_mapped.
|
||||
*/
|
||||
result = map_efi_systab(&info, level4p);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = map_acpi_tables(&info, level4p);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return init_transition_pgtable(image, level4p);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user