diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-08-31 15:28:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-08-31 15:28:21 -0700 |
commit | 81b0b29bf70bb8b459cf1f0b4a6a4898be457850 (patch) | |
tree | 516212c19126f7f29acf3affb77fd35e1db7f9f1 | |
parent | efa916af13206eb15916e102c45c99a13ea78f33 (diff) | |
parent | 7fd1d00bf8181db4b90c3c9dc25696229d185b5b (diff) |
Merge branch 'stable/for-linus-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft
Pull ibft updates from Konrad Rzeszutek Wilk:
"A fix for iBFT parsing code badly interfacing when KASLR is enabled"
* 'stable/for-linus-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft:
iscsi_ibft: fix warning in reserve_ibft_region()
iscsi_ibft: fix crash due to KASLR physical memory remapping
-rw-r--r-- | arch/x86/kernel/setup.c | 10 | ||||
-rw-r--r-- | drivers/firmware/iscsi_ibft.c | 10 | ||||
-rw-r--r-- | drivers/firmware/iscsi_ibft_find.c | 48 | ||||
-rw-r--r-- | include/linux/iscsi_ibft.h | 18 |
4 files changed, 32 insertions, 54 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index bff3a784aec5..63b20536c8d2 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -572,16 +572,6 @@ void __init reserve_standard_io_resources(void) } -static __init void reserve_ibft_region(void) -{ - unsigned long addr, size = 0; - - addr = find_ibft_region(&size); - - if (size) - memblock_reserve(addr, size); -} - static bool __init snb_gfx_workaround_needed(void) { #ifdef CONFIG_PCI diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 7127a04bca19..612a59e213df 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c @@ -84,8 +84,10 @@ MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information"); MODULE_LICENSE("GPL"); MODULE_VERSION(IBFT_ISCSI_VERSION); +static struct acpi_table_ibft *ibft_addr; + #ifndef CONFIG_ISCSI_IBFT_FIND -struct acpi_table_ibft *ibft_addr; +phys_addr_t ibft_phys_addr; #endif struct ibft_hdr { @@ -858,11 +860,13 @@ static int __init ibft_init(void) int rc = 0; /* - As on UEFI systems the setup_arch()/find_ibft_region() + As on UEFI systems the setup_arch()/reserve_ibft_region() is called before ACPI tables are parsed and it only does legacy finding. */ - if (!ibft_addr) + if (ibft_phys_addr) + ibft_addr = isa_bus_to_virt(ibft_phys_addr); + else acpi_find_ibft_region(); if (ibft_addr) { diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c index 64bb94523281..94b49ccd23ac 100644 --- a/drivers/firmware/iscsi_ibft_find.c +++ b/drivers/firmware/iscsi_ibft_find.c @@ -31,8 +31,8 @@ /* * Physical location of iSCSI Boot Format Table. */ -struct acpi_table_ibft *ibft_addr; -EXPORT_SYMBOL_GPL(ibft_addr); +phys_addr_t ibft_phys_addr; +EXPORT_SYMBOL_GPL(ibft_phys_addr); static const struct { char *sign; @@ -47,13 +47,24 @@ static const struct { #define VGA_MEM 0xA0000 /* VGA buffer */ #define VGA_SIZE 0x20000 /* 128kB */ -static int __init find_ibft_in_mem(void) +/* + * Routine used to find and reserve the iSCSI Boot Format Table + */ +void __init reserve_ibft_region(void) { unsigned long pos; unsigned int len = 0; void *virt; int i; + ibft_phys_addr = 0; + + /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will + * only use ACPI for this + */ + if (efi_enabled(EFI_BOOT)) + return; + for (pos = IBFT_START; pos < IBFT_END; pos += 16) { /* The table can't be inside the VGA BIOS reserved space, * so skip that area */ @@ -70,35 +81,12 @@ static int __init find_ibft_in_mem(void) /* if the length of the table extends past 1M, * the table cannot be valid. */ if (pos + len <= (IBFT_END-1)) { - ibft_addr = (struct acpi_table_ibft *)virt; - pr_info("iBFT found at 0x%lx.\n", pos); - goto done; + ibft_phys_addr = pos; + memblock_reserve(ibft_phys_addr, PAGE_ALIGN(len)); + pr_info("iBFT found at %pa.\n", &ibft_phys_addr); + return; } } } } -done: - return len; -} -/* - * Routine used to find the iSCSI Boot Format Table. The logical - * kernel address is set in the ibft_addr global variable. - */ -unsigned long __init find_ibft_region(unsigned long *sizep) -{ - ibft_addr = NULL; - - /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will - * only use ACPI for this */ - - if (!efi_enabled(EFI_BOOT)) - find_ibft_in_mem(); - - if (ibft_addr) { - *sizep = PAGE_ALIGN(ibft_addr->header.length); - return (u64)virt_to_phys(ibft_addr); - } - - *sizep = 0; - return 0; } diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h index b7b45ca82bea..790e7fcfc1a6 100644 --- a/include/linux/iscsi_ibft.h +++ b/include/linux/iscsi_ibft.h @@ -13,26 +13,22 @@ #ifndef ISCSI_IBFT_H #define ISCSI_IBFT_H -#include <linux/acpi.h> +#include <linux/types.h> /* - * Logical location of iSCSI Boot Format Table. - * If the value is NULL there is no iBFT on the machine. + * Physical location of iSCSI Boot Format Table. + * If the value is 0 there is no iBFT on the machine. */ -extern struct acpi_table_ibft *ibft_addr; +extern phys_addr_t ibft_phys_addr; /* * Routine used to find and reserve the iSCSI Boot Format Table. The - * mapped address is set in the ibft_addr variable. + * physical address is set in the ibft_phys_addr variable. */ #ifdef CONFIG_ISCSI_IBFT_FIND -unsigned long find_ibft_region(unsigned long *sizep); +void reserve_ibft_region(void); #else -static inline unsigned long find_ibft_region(unsigned long *sizep) -{ - *sizep = 0; - return 0; -} +static inline void reserve_ibft_region(void) {} #endif #endif /* ISCSI_IBFT_H */ |