Merge branch 'stable/for-linus-5.15' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Aug 2021 22:28:21 +0000 (15:28 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Aug 2021 22:28:21 +0000 (15:28 -0700)
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

arch/x86/kernel/setup.c
drivers/firmware/iscsi_ibft.c
drivers/firmware/iscsi_ibft_find.c
include/linux/iscsi_ibft.h

index bff3a78..63b2053 100644 (file)
@@ -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
index 7127a04..612a59e 100644 (file)
@@ -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) {
index 64bb945..94b49cc 100644 (file)
@@ -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;
 }
index b7b45ca..790e7fc 100644 (file)
 #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 */