[PATCH] x86/kexec: Prepare ACPI table mapping for kexec kernel

From: Baoquan He
Date: Tue Apr 23 2019 - 21:57:01 EST


If the kernel decompressing code accesses ACPI tabels in kexec-ed kernel,
they also need be 1:1 mapped.

---
arch/x86/kernel/machine_kexec_64.c | 54 ++++++++++++++++++++++++++++--
1 file changed, 51 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index d5da54893f97..e2948aea27d4 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -30,6 +30,48 @@
#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 init_acpi_pgtable(struct x86_mapping_info *info,
+ pgd_t *level4p)
+{
+ unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ struct init_pgtable_data data;
+
+ data.info = info;
+ data.level4p = level4p;
+ flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ return walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1,
+ &data, mem_region_callback);
+}
+#else
+static int init_acpi_pgtable(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,
@@ -114,6 +156,8 @@ static void *alloc_pgt_page(void *data)
return p;
}

+
+
#ifdef CONFIG_EFI
static int init_efi_systab_pgtable(struct x86_mapping_info *info,
pgd_t *level4p)
@@ -191,14 +235,18 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
return result;
}

- /*
- * Prepare EFI systab mapping for kexec kernel, systab is not
- * covered by pfn_mapped.
+ /**
+ * Prepare EFI systab and ACPI table mapping for kexec kernel,
+ * since they are not covered by pfn_mapped.
*/
result = init_efi_systab_pgtable(&info, level4p);
if (result)
return result;

+ result = init_acpi_pgtable(&info, level4p);
+ if (result)
+ return result;
+
return init_transition_pgtable(image, level4p);
}

--
2.17.2