Commit 81b0b29b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents efa916af 7fd1d00b
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -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
+7 −3
Original line number Diff line number Diff line
@@ -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) {
+18 −30
Original line number Diff line number Diff line
@@ -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;
}
+7 −11
Original line number Diff line number Diff line
@@ -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 */