On Thu, 15 Dec 2022 at 13:38, Evgeniy Baskov <baskov@xxxxxxxxx> wrote: > > Implicit mappings hide possible memory errors, e.g. allocations for > ACPI tables were not included in boot page table size. > > Replace all implicit mappings from page fault handler with > explicit mappings. > I agree with the motivation but this patch seems to break the boot under SeaBIOS/QEMU, and I imagine other legacy BIOS boot scenarios as well. Naively, I would assume that there is simply a legacy BIOS region that we fail to map here, but I am fairly clueless when it comes to non-EFI x86 boot so take this with a grain of salt. > Tested-by: Mario Limonciello <mario.limonciello@xxxxxxx> > Tested-by: Peter Jones <pjones@xxxxxxxxxx> > Signed-off-by: Evgeniy Baskov <baskov@xxxxxxxxx> > --- > arch/x86/boot/compressed/acpi.c | 25 ++++++++++++++++++++++++- > arch/x86/boot/compressed/efi.c | 19 ++++++++++++++++++- > arch/x86/boot/compressed/kaslr.c | 4 ++++ > 3 files changed, 46 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c > index 9caf89063e77..c775e01fc7db 100644 > --- a/arch/x86/boot/compressed/acpi.c > +++ b/arch/x86/boot/compressed/acpi.c > @@ -93,6 +93,8 @@ static u8 *scan_mem_for_rsdp(u8 *start, u32 length) > > end = start + length; > > + kernel_add_identity_map((unsigned long)start, (unsigned long)end, 0); > + > /* Search from given start address for the requested length */ > for (address = start; address < end; address += ACPI_RSDP_SCAN_STEP) { > /* > @@ -128,6 +130,9 @@ static acpi_physical_address bios_get_rsdp_addr(void) > unsigned long address; > u8 *rsdp; > > + kernel_add_identity_map((unsigned long)ACPI_EBDA_PTR_LOCATION, > + (unsigned long)ACPI_EBDA_PTR_LOCATION + 2, 0); > + > /* Get the location of the Extended BIOS Data Area (EBDA) */ > address = *(u16 *)ACPI_EBDA_PTR_LOCATION; > address <<= 4; > @@ -215,6 +220,9 @@ static unsigned long get_acpi_srat_table(void) > if (!rsdp) > return 0; > > + kernel_add_identity_map((unsigned long)rsdp, > + (unsigned long)(rsdp + 1), 0); > + > /* Get ACPI root table from RSDP.*/ > if (!(cmdline_find_option("acpi", arg, sizeof(arg)) == 4 && > !strncmp(arg, "rsdt", 4)) && > @@ -231,10 +239,17 @@ static unsigned long get_acpi_srat_table(void) > return 0; > > header = (struct acpi_table_header *)root_table; > + > + kernel_add_identity_map((unsigned long)header, > + (unsigned long)(header + 1), 0); > + > len = header->length; > if (len < sizeof(struct acpi_table_header) + size) > return 0; > > + kernel_add_identity_map((unsigned long)header, > + (unsigned long)header + len, 0); > + > num_entries = (len - sizeof(struct acpi_table_header)) / size; > entry = (u8 *)(root_table + sizeof(struct acpi_table_header)); > > @@ -247,8 +262,16 @@ static unsigned long get_acpi_srat_table(void) > if (acpi_table) { > header = (struct acpi_table_header *)acpi_table; > > - if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT)) > + kernel_add_identity_map(acpi_table, > + acpi_table + sizeof(*header), > + 0); > + > + if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT)) { > + kernel_add_identity_map(acpi_table, > + acpi_table + header->length, > + 0); > return acpi_table; > + } > } > entry += size; > } > diff --git a/arch/x86/boot/compressed/efi.c b/arch/x86/boot/compressed/efi.c > index 6edd034b0b30..ce70103fbbc0 100644 > --- a/arch/x86/boot/compressed/efi.c > +++ b/arch/x86/boot/compressed/efi.c > @@ -57,10 +57,14 @@ enum efi_type efi_get_type(struct boot_params *bp) > */ > unsigned long efi_get_system_table(struct boot_params *bp) > { > - unsigned long sys_tbl_pa; > + static unsigned long sys_tbl_pa __section(".data"); > struct efi_info *ei; > + unsigned long sys_tbl_size; > enum efi_type et; > > + if (sys_tbl_pa) > + return sys_tbl_pa; > + > /* Get systab from boot params. */ > ei = &bp->efi_info; > #ifdef CONFIG_X86_64 > @@ -73,6 +77,13 @@ unsigned long efi_get_system_table(struct boot_params *bp) > return 0; > } > > + if (efi_get_type(bp) == EFI_TYPE_64) > + sys_tbl_size = sizeof(efi_system_table_64_t); > + else > + sys_tbl_size = sizeof(efi_system_table_32_t); > + > + kernel_add_identity_map(sys_tbl_pa, sys_tbl_pa + sys_tbl_size, 0); > + > return sys_tbl_pa; > } > > @@ -92,6 +103,10 @@ static struct efi_setup_data *get_kexec_setup_data(struct boot_params *bp, > > pa_data = bp->hdr.setup_data; > while (pa_data) { > + unsigned long pa_data_end = pa_data + sizeof(struct setup_data) > + + sizeof(struct efi_setup_data); > + kernel_add_identity_map(pa_data, pa_data_end, 0); > + > data = (struct setup_data *)pa_data; > if (data->type == SETUP_EFI) { > esd = (struct efi_setup_data *)(pa_data + sizeof(struct setup_data)); > @@ -160,6 +175,8 @@ int efi_get_conf_table(struct boot_params *bp, unsigned long *cfg_tbl_pa, > return -EINVAL; > } > > + kernel_add_identity_map(*cfg_tbl_pa, *cfg_tbl_pa + *cfg_tbl_len, 0); > + > return 0; > } > > diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c > index 454757fbdfe5..c0ee116c4fa2 100644 > --- a/arch/x86/boot/compressed/kaslr.c > +++ b/arch/x86/boot/compressed/kaslr.c > @@ -688,6 +688,8 @@ process_efi_entries(unsigned long minimum, unsigned long image_size) > u32 nr_desc; > int i; > > + kernel_add_identity_map((unsigned long)e, (unsigned long)(e + 1), 0); > + > signature = (char *)&e->efi_loader_signature; > if (strncmp(signature, EFI32_LOADER_SIGNATURE, 4) && > strncmp(signature, EFI64_LOADER_SIGNATURE, 4)) > @@ -704,6 +706,8 @@ process_efi_entries(unsigned long minimum, unsigned long image_size) > pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); > #endif > > + kernel_add_identity_map(pmap, pmap + e->efi_memmap_size, 0); > + > nr_desc = e->efi_memmap_size / e->efi_memdesc_size; > for (i = 0; i < nr_desc; i++) { > md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i); > -- > 2.37.4 >