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
This commit is contained in:
commit
81b0b29bf7
@ -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)
|
static bool __init snb_gfx_workaround_needed(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
|
@ -84,8 +84,10 @@ MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information");
|
|||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(IBFT_ISCSI_VERSION);
|
MODULE_VERSION(IBFT_ISCSI_VERSION);
|
||||||
|
|
||||||
|
static struct acpi_table_ibft *ibft_addr;
|
||||||
|
|
||||||
#ifndef CONFIG_ISCSI_IBFT_FIND
|
#ifndef CONFIG_ISCSI_IBFT_FIND
|
||||||
struct acpi_table_ibft *ibft_addr;
|
phys_addr_t ibft_phys_addr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ibft_hdr {
|
struct ibft_hdr {
|
||||||
@ -858,11 +860,13 @@ static int __init ibft_init(void)
|
|||||||
int rc = 0;
|
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
|
is called before ACPI tables are parsed and it only does
|
||||||
legacy finding.
|
legacy finding.
|
||||||
*/
|
*/
|
||||||
if (!ibft_addr)
|
if (ibft_phys_addr)
|
||||||
|
ibft_addr = isa_bus_to_virt(ibft_phys_addr);
|
||||||
|
else
|
||||||
acpi_find_ibft_region();
|
acpi_find_ibft_region();
|
||||||
|
|
||||||
if (ibft_addr) {
|
if (ibft_addr) {
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
/*
|
/*
|
||||||
* Physical location of iSCSI Boot Format Table.
|
* Physical location of iSCSI Boot Format Table.
|
||||||
*/
|
*/
|
||||||
struct acpi_table_ibft *ibft_addr;
|
phys_addr_t ibft_phys_addr;
|
||||||
EXPORT_SYMBOL_GPL(ibft_addr);
|
EXPORT_SYMBOL_GPL(ibft_phys_addr);
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
char *sign;
|
char *sign;
|
||||||
@ -47,13 +47,24 @@ static const struct {
|
|||||||
#define VGA_MEM 0xA0000 /* VGA buffer */
|
#define VGA_MEM 0xA0000 /* VGA buffer */
|
||||||
#define VGA_SIZE 0x20000 /* 128kB */
|
#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 long pos;
|
||||||
unsigned int len = 0;
|
unsigned int len = 0;
|
||||||
void *virt;
|
void *virt;
|
||||||
int i;
|
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) {
|
for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
|
||||||
/* The table can't be inside the VGA BIOS reserved space,
|
/* The table can't be inside the VGA BIOS reserved space,
|
||||||
* so skip that area */
|
* 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,
|
/* if the length of the table extends past 1M,
|
||||||
* the table cannot be valid. */
|
* the table cannot be valid. */
|
||||||
if (pos + len <= (IBFT_END-1)) {
|
if (pos + len <= (IBFT_END-1)) {
|
||||||
ibft_addr = (struct acpi_table_ibft *)virt;
|
ibft_phys_addr = pos;
|
||||||
pr_info("iBFT found at 0x%lx.\n", pos);
|
memblock_reserve(ibft_phys_addr, PAGE_ALIGN(len));
|
||||||
goto done;
|
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;
|
|
||||||
}
|
}
|
||||||
|
@ -13,26 +13,22 @@
|
|||||||
#ifndef ISCSI_IBFT_H
|
#ifndef ISCSI_IBFT_H
|
||||||
#define ISCSI_IBFT_H
|
#define ISCSI_IBFT_H
|
||||||
|
|
||||||
#include <linux/acpi.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logical location of iSCSI Boot Format Table.
|
* Physical location of iSCSI Boot Format Table.
|
||||||
* If the value is NULL there is no iBFT on the machine.
|
* 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
|
* 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
|
#ifdef CONFIG_ISCSI_IBFT_FIND
|
||||||
unsigned long find_ibft_region(unsigned long *sizep);
|
void reserve_ibft_region(void);
|
||||||
#else
|
#else
|
||||||
static inline unsigned long find_ibft_region(unsigned long *sizep)
|
static inline void reserve_ibft_region(void) {}
|
||||||
{
|
|
||||||
*sizep = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ISCSI_IBFT_H */
|
#endif /* ISCSI_IBFT_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user