mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
* Make the EFI System Resource Table (ESRT) driver explicitly
non-modular by ripping out the module_* code since Kconfig doesn't
allow it to be built as a module anyway - Paul Gortmaker
* Make the x86 efi=debug kernel parameter, which enables EFI debug
code and output, generic and usable by arm64 - Leif Lindholm
* Add support to the x86 EFI boot stub for 64-bit Graphics Output
Protocol frame buffer addresses - Matt Fleming
* Detect when the UEFI v2.5 EFI_PROPERTIES_TABLE feature is enabled
in the firmware and set an efi.flags bit so the kernel knows when
it can apply more strict runtime mapping attributes - Ard Biesheuvel
* Auto-load the efi-pstore module on EFI systems, just like we
currently do for the efivars module - Ben Hutchings
* Add "efi_fake_mem" kernel parameter which allows the system's EFI
memory map to be updated with additional attributes for specific
memory ranges. This is useful for testing the kernel code that handles
the EFI_MEMORY_MORE_RELIABLE memmap bit even if your firmware
doesn't include support - Taku Izumi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJWG7OwAAoJEC84WcCNIz1VEEEP/0SsdrwJ66B4MfP5YNjqHYWm
+OTHR6Ovv2i10kc+NjOV/GN8sWPndnkLfIfJ4EqJ9BoQ9PDEYZilV2aleSQ4DrPm
H7uGwBXQkfd76tZKX9pMToK76mkhg6M7M2LR3Suv3OGfOEzuozAOt3Ez37lpksTN
2ByhHr/oGbhu99jC2ki5+k0ySH8PMqDBRxqrPbBzTD+FfB7bM11vAJbSNbSMQ21R
ZwX0acZBLqb9J2Vf7tDsW+fCfz0TFo8JHW8jdLRFm/y2dpquzxswkkBpODgA8+VM
0F5UbiUdkaIRug75I6N/OJ8+yLwdzuxm7ul+tbS3JrXGLAlK3850+dP2Pr5zQ2Ce
zaYGRUy+tD5xMXqOKgzpu+Ia8XnDRLhOlHabiRd5fG6ZC9nR8E9uK52g79voSN07
pADAJnVB03CGV/HdduDOI4C4UykUKubuArbQVkqWJcecV1Jic/tYI0gjeACmU1VF
v8FzXpBUe3U3A0jauOz8PBz8M+k5qky/GbIrnEvXreBtKdt999LN9fykTN7rBOpo
dk/6vTR1Jyv3aYc9EXHmRluktI6KmfWCqmRBOIgQveX1VhdRM+1w2LKC0+8co3dF
v/DBh19KDyfPI8eOvxKykhn164UeAt03EXqDa46wFGr2nVOm/JiShL/d+QuyYU4G
8xb/rET4JrhCG4gFMUZ7
=1Oee
-----END PGP SIGNATURE-----
Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi into core/efi
Pull v4.4 EFI updates from Matt Fleming:
- Make the EFI System Resource Table (ESRT) driver explicitly
non-modular by ripping out the module_* code since Kconfig doesn't
allow it to be built as a module anyway. (Paul Gortmaker)
- Make the x86 efi=debug kernel parameter, which enables EFI debug
code and output, generic and usable by arm64. (Leif Lindholm)
- Add support to the x86 EFI boot stub for 64-bit Graphics Output
Protocol frame buffer addresses. (Matt Fleming)
- Detect when the UEFI v2.5 EFI_PROPERTIES_TABLE feature is enabled
in the firmware and set an efi.flags bit so the kernel knows when
it can apply more strict runtime mapping attributes - Ard Biesheuvel
- Auto-load the efi-pstore module on EFI systems, just like we
currently do for the efivars module. (Ben Hutchings)
- Add "efi_fake_mem" kernel parameter which allows the system's EFI
memory map to be updated with additional attributes for specific
memory ranges. This is useful for testing the kernel code that handles
the EFI_MEMORY_MORE_RELIABLE memmap bit even if your firmware
doesn't include support. (Taku Izumi)
Note: there is a semantic conflict between the following two commits:
8a53554e12 ("x86/efi: Fix multiple GOP device support")
ae2ee627dc ("efifb: Add support for 64-bit frame buffer addresses")
I fixed up the interaction in the merge commit, changing the type of
current_fb_base from u32 to u64.
Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
commit
790a2ee242
16 changed files with 402 additions and 67 deletions
|
|
@ -52,6 +52,28 @@ config EFI_RUNTIME_MAP
|
|||
|
||||
See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
|
||||
|
||||
config EFI_FAKE_MEMMAP
|
||||
bool "Enable EFI fake memory map"
|
||||
depends on EFI && X86
|
||||
default n
|
||||
help
|
||||
Saying Y here will enable "efi_fake_mem" boot option.
|
||||
By specifying this parameter, you can add arbitrary attribute
|
||||
to specific memory range by updating original (firmware provided)
|
||||
EFI memmap.
|
||||
This is useful for debugging of EFI memmap related feature.
|
||||
e.g. Address Range Mirroring feature.
|
||||
|
||||
config EFI_MAX_FAKE_MEM
|
||||
int "maximum allowable number of ranges in efi_fake_mem boot option"
|
||||
depends on EFI_FAKE_MEMMAP
|
||||
range 1 128
|
||||
default 8
|
||||
help
|
||||
Maximum allowable number of ranges in efi_fake_mem boot option.
|
||||
Ranges can be set up to this value using comma-separated list.
|
||||
The default value is 8.
|
||||
|
||||
config EFI_PARAMS_FROM_FDT
|
||||
bool
|
||||
help
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@ obj-$(CONFIG_UEFI_CPER) += cper.o
|
|||
obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o
|
||||
obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o
|
||||
obj-$(CONFIG_EFI_STUB) += libstub/
|
||||
obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o
|
||||
|
|
|
|||
|
|
@ -400,3 +400,4 @@ module_exit(efivars_pstore_exit);
|
|||
|
||||
MODULE_DESCRIPTION("EFI variable backend for pstore");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:efivars");
|
||||
|
|
|
|||
|
|
@ -26,20 +26,21 @@
|
|||
#include <linux/platform_device.h>
|
||||
|
||||
struct efi __read_mostly efi = {
|
||||
.mps = EFI_INVALID_TABLE_ADDR,
|
||||
.acpi = EFI_INVALID_TABLE_ADDR,
|
||||
.acpi20 = EFI_INVALID_TABLE_ADDR,
|
||||
.smbios = EFI_INVALID_TABLE_ADDR,
|
||||
.smbios3 = EFI_INVALID_TABLE_ADDR,
|
||||
.sal_systab = EFI_INVALID_TABLE_ADDR,
|
||||
.boot_info = EFI_INVALID_TABLE_ADDR,
|
||||
.hcdp = EFI_INVALID_TABLE_ADDR,
|
||||
.uga = EFI_INVALID_TABLE_ADDR,
|
||||
.uv_systab = EFI_INVALID_TABLE_ADDR,
|
||||
.fw_vendor = EFI_INVALID_TABLE_ADDR,
|
||||
.runtime = EFI_INVALID_TABLE_ADDR,
|
||||
.config_table = EFI_INVALID_TABLE_ADDR,
|
||||
.esrt = EFI_INVALID_TABLE_ADDR,
|
||||
.mps = EFI_INVALID_TABLE_ADDR,
|
||||
.acpi = EFI_INVALID_TABLE_ADDR,
|
||||
.acpi20 = EFI_INVALID_TABLE_ADDR,
|
||||
.smbios = EFI_INVALID_TABLE_ADDR,
|
||||
.smbios3 = EFI_INVALID_TABLE_ADDR,
|
||||
.sal_systab = EFI_INVALID_TABLE_ADDR,
|
||||
.boot_info = EFI_INVALID_TABLE_ADDR,
|
||||
.hcdp = EFI_INVALID_TABLE_ADDR,
|
||||
.uga = EFI_INVALID_TABLE_ADDR,
|
||||
.uv_systab = EFI_INVALID_TABLE_ADDR,
|
||||
.fw_vendor = EFI_INVALID_TABLE_ADDR,
|
||||
.runtime = EFI_INVALID_TABLE_ADDR,
|
||||
.config_table = EFI_INVALID_TABLE_ADDR,
|
||||
.esrt = EFI_INVALID_TABLE_ADDR,
|
||||
.properties_table = EFI_INVALID_TABLE_ADDR,
|
||||
};
|
||||
EXPORT_SYMBOL(efi);
|
||||
|
||||
|
|
@ -63,6 +64,9 @@ static int __init parse_efi_cmdline(char *str)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (parse_option_str(str, "debug"))
|
||||
set_bit(EFI_DBG, &efi.flags);
|
||||
|
||||
if (parse_option_str(str, "noruntime"))
|
||||
disable_runtime = true;
|
||||
|
||||
|
|
@ -362,6 +366,7 @@ static __initdata efi_config_table_type_t common_tables[] = {
|
|||
{SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
|
||||
{UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
|
||||
{EFI_SYSTEM_RESOURCE_TABLE_GUID, "ESRT", &efi.esrt},
|
||||
{EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table},
|
||||
{NULL_GUID, NULL, NULL},
|
||||
};
|
||||
|
||||
|
|
@ -421,6 +426,24 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
|
|||
}
|
||||
pr_cont("\n");
|
||||
set_bit(EFI_CONFIG_TABLES, &efi.flags);
|
||||
|
||||
/* Parse the EFI Properties table if it exists */
|
||||
if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
|
||||
efi_properties_table_t *tbl;
|
||||
|
||||
tbl = early_memremap(efi.properties_table, sizeof(*tbl));
|
||||
if (tbl == NULL) {
|
||||
pr_err("Could not map Properties table!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (tbl->memory_protection_attribute &
|
||||
EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA)
|
||||
set_bit(EFI_NX_PE_DATA, &efi.flags);
|
||||
|
||||
early_memunmap(tbl, sizeof(*tbl));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -489,7 +512,6 @@ static __initdata struct {
|
|||
};
|
||||
|
||||
struct param_info {
|
||||
int verbose;
|
||||
int found;
|
||||
void *params;
|
||||
};
|
||||
|
|
@ -520,21 +542,20 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
|
|||
else
|
||||
*(u64 *)dest = val;
|
||||
|
||||
if (info->verbose)
|
||||
if (efi_enabled(EFI_DBG))
|
||||
pr_info(" %s: 0x%0*llx\n", dt_params[i].name,
|
||||
dt_params[i].size * 2, val);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
|
||||
int __init efi_get_fdt_params(struct efi_fdt_params *params)
|
||||
{
|
||||
struct param_info info;
|
||||
int ret;
|
||||
|
||||
pr_info("Getting EFI parameters from FDT:\n");
|
||||
|
||||
info.verbose = verbose;
|
||||
info.found = 0;
|
||||
info.params = params;
|
||||
|
||||
|
|
@ -590,12 +611,13 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
|
|||
if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
|
||||
EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
|
||||
EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
|
||||
EFI_MEMORY_RUNTIME))
|
||||
EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
|
||||
snprintf(pos, size, "|attr=0x%016llx]",
|
||||
(unsigned long long)attr);
|
||||
else
|
||||
snprintf(pos, size, "|%3s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
|
||||
snprintf(pos, size, "|%3s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
|
||||
attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
|
||||
attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
|
||||
attr & EFI_MEMORY_XP ? "XP" : "",
|
||||
attr & EFI_MEMORY_RP ? "RP" : "",
|
||||
attr & EFI_MEMORY_WP ? "WP" : "",
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include <linux/kobject.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
|
|
@ -450,22 +449,10 @@ err:
|
|||
esrt = NULL;
|
||||
return error;
|
||||
}
|
||||
device_initcall(esrt_sysfs_init);
|
||||
|
||||
static void __exit esrt_sysfs_exit(void)
|
||||
{
|
||||
pr_debug("esrt-sysfs: unloading.\n");
|
||||
cleanup_entry_list();
|
||||
kset_unregister(esrt_kset);
|
||||
sysfs_remove_group(esrt_kobj, &esrt_attr_group);
|
||||
kfree(esrt);
|
||||
esrt = NULL;
|
||||
kobject_del(esrt_kobj);
|
||||
kobject_put(esrt_kobj);
|
||||
}
|
||||
|
||||
module_init(esrt_sysfs_init);
|
||||
module_exit(esrt_sysfs_exit);
|
||||
|
||||
/*
|
||||
MODULE_AUTHOR("Peter Jones <[email protected]>");
|
||||
MODULE_DESCRIPTION("EFI System Resource Table support");
|
||||
MODULE_LICENSE("GPL");
|
||||
*/
|
||||
|
|
|
|||
238
drivers/firmware/efi/fake_mem.c
Normal file
238
drivers/firmware/efi/fake_mem.c
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* fake_mem.c
|
||||
*
|
||||
* Copyright (C) 2015 FUJITSU LIMITED
|
||||
* Author: Taku Izumi <izumi.taku@jp.fujitsu.com>
|
||||
*
|
||||
* This code introduces new boot option named "efi_fake_mem"
|
||||
* By specifying this parameter, you can add arbitrary attribute to
|
||||
* specific memory range by updating original (firmware provided) EFI
|
||||
* memmap.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in
|
||||
* the file called "COPYING".
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/efi.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sort.h>
|
||||
#include <asm/efi.h>
|
||||
|
||||
#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKE_MEM
|
||||
|
||||
struct fake_mem {
|
||||
struct range range;
|
||||
u64 attribute;
|
||||
};
|
||||
static struct fake_mem fake_mems[EFI_MAX_FAKEMEM];
|
||||
static int nr_fake_mem;
|
||||
|
||||
static int __init cmp_fake_mem(const void *x1, const void *x2)
|
||||
{
|
||||
const struct fake_mem *m1 = x1;
|
||||
const struct fake_mem *m2 = x2;
|
||||
|
||||
if (m1->range.start < m2->range.start)
|
||||
return -1;
|
||||
if (m1->range.start > m2->range.start)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init efi_fake_memmap(void)
|
||||
{
|
||||
u64 start, end, m_start, m_end, m_attr;
|
||||
int new_nr_map = memmap.nr_map;
|
||||
efi_memory_desc_t *md;
|
||||
u64 new_memmap_phy;
|
||||
void *new_memmap;
|
||||
void *old, *new;
|
||||
int i;
|
||||
|
||||
if (!nr_fake_mem || !efi_enabled(EFI_MEMMAP))
|
||||
return;
|
||||
|
||||
/* count up the number of EFI memory descriptor */
|
||||
for (old = memmap.map; old < memmap.map_end; old += memmap.desc_size) {
|
||||
md = old;
|
||||
start = md->phys_addr;
|
||||
end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1;
|
||||
|
||||
for (i = 0; i < nr_fake_mem; i++) {
|
||||
/* modifying range */
|
||||
m_start = fake_mems[i].range.start;
|
||||
m_end = fake_mems[i].range.end;
|
||||
|
||||
if (m_start <= start) {
|
||||
/* split into 2 parts */
|
||||
if (start < m_end && m_end < end)
|
||||
new_nr_map++;
|
||||
}
|
||||
if (start < m_start && m_start < end) {
|
||||
/* split into 3 parts */
|
||||
if (m_end < end)
|
||||
new_nr_map += 2;
|
||||
/* split into 2 parts */
|
||||
if (end <= m_end)
|
||||
new_nr_map++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate memory for new EFI memmap */
|
||||
new_memmap_phy = memblock_alloc(memmap.desc_size * new_nr_map,
|
||||
PAGE_SIZE);
|
||||
if (!new_memmap_phy)
|
||||
return;
|
||||
|
||||
/* create new EFI memmap */
|
||||
new_memmap = early_memremap(new_memmap_phy,
|
||||
memmap.desc_size * new_nr_map);
|
||||
if (!new_memmap) {
|
||||
memblock_free(new_memmap_phy, memmap.desc_size * new_nr_map);
|
||||
return;
|
||||
}
|
||||
|
||||
for (old = memmap.map, new = new_memmap;
|
||||
old < memmap.map_end;
|
||||
old += memmap.desc_size, new += memmap.desc_size) {
|
||||
|
||||
/* copy original EFI memory descriptor */
|
||||
memcpy(new, old, memmap.desc_size);
|
||||
md = new;
|
||||
start = md->phys_addr;
|
||||
end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
|
||||
|
||||
for (i = 0; i < nr_fake_mem; i++) {
|
||||
/* modifying range */
|
||||
m_start = fake_mems[i].range.start;
|
||||
m_end = fake_mems[i].range.end;
|
||||
m_attr = fake_mems[i].attribute;
|
||||
|
||||
if (m_start <= start && end <= m_end)
|
||||
md->attribute |= m_attr;
|
||||
|
||||
if (m_start <= start &&
|
||||
(start < m_end && m_end < end)) {
|
||||
/* first part */
|
||||
md->attribute |= m_attr;
|
||||
md->num_pages = (m_end - md->phys_addr + 1) >>
|
||||
EFI_PAGE_SHIFT;
|
||||
/* latter part */
|
||||
new += memmap.desc_size;
|
||||
memcpy(new, old, memmap.desc_size);
|
||||
md = new;
|
||||
md->phys_addr = m_end + 1;
|
||||
md->num_pages = (end - md->phys_addr + 1) >>
|
||||
EFI_PAGE_SHIFT;
|
||||
}
|
||||
|
||||
if ((start < m_start && m_start < end) && m_end < end) {
|
||||
/* first part */
|
||||
md->num_pages = (m_start - md->phys_addr) >>
|
||||
EFI_PAGE_SHIFT;
|
||||
/* middle part */
|
||||
new += memmap.desc_size;
|
||||
memcpy(new, old, memmap.desc_size);
|
||||
md = new;
|
||||
md->attribute |= m_attr;
|
||||
md->phys_addr = m_start;
|
||||
md->num_pages = (m_end - m_start + 1) >>
|
||||
EFI_PAGE_SHIFT;
|
||||
/* last part */
|
||||
new += memmap.desc_size;
|
||||
memcpy(new, old, memmap.desc_size);
|
||||
md = new;
|
||||
md->phys_addr = m_end + 1;
|
||||
md->num_pages = (end - m_end) >>
|
||||
EFI_PAGE_SHIFT;
|
||||
}
|
||||
|
||||
if ((start < m_start && m_start < end) &&
|
||||
(end <= m_end)) {
|
||||
/* first part */
|
||||
md->num_pages = (m_start - md->phys_addr) >>
|
||||
EFI_PAGE_SHIFT;
|
||||
/* latter part */
|
||||
new += memmap.desc_size;
|
||||
memcpy(new, old, memmap.desc_size);
|
||||
md = new;
|
||||
md->phys_addr = m_start;
|
||||
md->num_pages = (end - md->phys_addr + 1) >>
|
||||
EFI_PAGE_SHIFT;
|
||||
md->attribute |= m_attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* swap into new EFI memmap */
|
||||
efi_unmap_memmap();
|
||||
memmap.map = new_memmap;
|
||||
memmap.phys_map = (void *)new_memmap_phy;
|
||||
memmap.nr_map = new_nr_map;
|
||||
memmap.map_end = memmap.map + memmap.nr_map * memmap.desc_size;
|
||||
set_bit(EFI_MEMMAP, &efi.flags);
|
||||
|
||||
/* print new EFI memmap */
|
||||
efi_print_memmap();
|
||||
}
|
||||
|
||||
static int __init setup_fake_mem(char *p)
|
||||
{
|
||||
u64 start = 0, mem_size = 0, attribute = 0;
|
||||
int i;
|
||||
|
||||
if (!p)
|
||||
return -EINVAL;
|
||||
|
||||
while (*p != '\0') {
|
||||
mem_size = memparse(p, &p);
|
||||
if (*p == '@')
|
||||
start = memparse(p+1, &p);
|
||||
else
|
||||
break;
|
||||
|
||||
if (*p == ':')
|
||||
attribute = simple_strtoull(p+1, &p, 0);
|
||||
else
|
||||
break;
|
||||
|
||||
if (nr_fake_mem >= EFI_MAX_FAKEMEM)
|
||||
break;
|
||||
|
||||
fake_mems[nr_fake_mem].range.start = start;
|
||||
fake_mems[nr_fake_mem].range.end = start + mem_size - 1;
|
||||
fake_mems[nr_fake_mem].attribute = attribute;
|
||||
nr_fake_mem++;
|
||||
|
||||
if (*p == ',')
|
||||
p++;
|
||||
}
|
||||
|
||||
sort(fake_mems, nr_fake_mem, sizeof(struct fake_mem),
|
||||
cmp_fake_mem, NULL);
|
||||
|
||||
for (i = 0; i < nr_fake_mem; i++)
|
||||
pr_info("efi_fake_mem: add attr=0x%016llx to [mem 0x%016llx-0x%016llx]",
|
||||
fake_mems[i].attribute, fake_mems[i].range.start,
|
||||
fake_mems[i].range.end);
|
||||
|
||||
return *p == '\0' ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
early_param("efi_fake_mem", setup_fake_mem);
|
||||
Loading…
Reference in a new issue