Re: [PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
On Wed, 30 Sep, at 11:01:56PM, Taku Izumi wrote: > This patch introduces new boot option named "efi_fake_mem". > By specifying this parameter, you can add arbitrary attribute > to specific memory range. > This is useful for debugging of Address Range Mirroring feature. > > For example, if "efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1" > is specified, the original (firmware provided) EFI memmap will be > updated so that the specified memory regions have > EFI_MEMORY_MORE_RELIABLE attribute (0x1): > > >efi: mem36: [Conventional Memory| | | | | | |WB|WT|WC|UC] > range=[0x0001-0x0020a000) (129536MB) > > >efi: mem36: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] > range=[0x0001-0x00018000) (2048MB) >efi: mem37: [Conventional Memory| | | | | | |WB|WT|WC|UC] > range=[0x00018000-0x0010a000) (61952MB) >efi: mem38: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] > range=[0x0010a000-0x00112000) (2048MB) >efi: mem39: [Conventional Memory| | | | | | |WB|WT|WC|UC] > range=[0x00112000-0x0020a000) (63488MB) > > And you will find that the following message is output: > >efi: Memory: 4096M/131455M mirrored memory > > Signed-off-by: Taku Izumi > --- > Documentation/kernel-parameters.txt | 15 +++ > arch/x86/kernel/setup.c | 4 +- > drivers/firmware/efi/Kconfig| 22 > drivers/firmware/efi/Makefile | 1 + > drivers/firmware/efi/fake_mem.c | 238 > > include/linux/efi.h | 6 + > 6 files changed, 285 insertions(+), 1 deletion(-) > create mode 100644 drivers/firmware/efi/fake_mem.c Looks good to me! I've queued this up with one minor change... > +config EFI_MAX_FAKE_MEM > + int "maximum allowable number of ranges in efi_fake_mem boot option" > + depends on EFI && X86 && EFI_FAKE_MEMMAP We can simplify this depends line since EFI_FAKE_MEMMAP itself is dependent on EFI and X86, and we should use that level of indirection to our advantage to save updating this line if/when arm64 support is added. -- Matt Fleming, Intel Open Source Technology Center -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
On Wed, 30 Sep, at 11:01:56PM, Taku Izumi wrote: > This patch introduces new boot option named "efi_fake_mem". > By specifying this parameter, you can add arbitrary attribute > to specific memory range. > This is useful for debugging of Address Range Mirroring feature. > > For example, if "efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1" > is specified, the original (firmware provided) EFI memmap will be > updated so that the specified memory regions have > EFI_MEMORY_MORE_RELIABLE attribute (0x1): > > >efi: mem36: [Conventional Memory| | | | | | |WB|WT|WC|UC] > range=[0x0001-0x0020a000) (129536MB) > > >efi: mem36: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] > range=[0x0001-0x00018000) (2048MB) >efi: mem37: [Conventional Memory| | | | | | |WB|WT|WC|UC] > range=[0x00018000-0x0010a000) (61952MB) >efi: mem38: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] > range=[0x0010a000-0x00112000) (2048MB) >efi: mem39: [Conventional Memory| | | | | | |WB|WT|WC|UC] > range=[0x00112000-0x0020a000) (63488MB) > > And you will find that the following message is output: > >efi: Memory: 4096M/131455M mirrored memory > > Signed-off-by: Taku Izumi> --- > Documentation/kernel-parameters.txt | 15 +++ > arch/x86/kernel/setup.c | 4 +- > drivers/firmware/efi/Kconfig| 22 > drivers/firmware/efi/Makefile | 1 + > drivers/firmware/efi/fake_mem.c | 238 > > include/linux/efi.h | 6 + > 6 files changed, 285 insertions(+), 1 deletion(-) > create mode 100644 drivers/firmware/efi/fake_mem.c Looks good to me! I've queued this up with one minor change... > +config EFI_MAX_FAKE_MEM > + int "maximum allowable number of ranges in efi_fake_mem boot option" > + depends on EFI && X86 && EFI_FAKE_MEMMAP We can simplify this depends line since EFI_FAKE_MEMMAP itself is dependent on EFI and X86, and we should use that level of indirection to our advantage to save updating this line if/when arm64 support is added. -- Matt Fleming, Intel Open Source Technology Center -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
This patch introduces new boot option named "efi_fake_mem". By specifying this parameter, you can add arbitrary attribute to specific memory range. This is useful for debugging of Address Range Mirroring feature. For example, if "efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1" is specified, the original (firmware provided) EFI memmap will be updated so that the specified memory regions have EFI_MEMORY_MORE_RELIABLE attribute (0x1): efi: mem36: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x0001-0x0020a000) (129536MB) efi: mem36: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] range=[0x0001-0x00018000) (2048MB) efi: mem37: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x00018000-0x0010a000) (61952MB) efi: mem38: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] range=[0x0010a000-0x00112000) (2048MB) efi: mem39: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x00112000-0x0020a000) (63488MB) And you will find that the following message is output: efi: Memory: 4096M/131455M mirrored memory Signed-off-by: Taku Izumi --- Documentation/kernel-parameters.txt | 15 +++ arch/x86/kernel/setup.c | 4 +- drivers/firmware/efi/Kconfig| 22 drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/fake_mem.c | 238 include/linux/efi.h | 6 + 6 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/efi/fake_mem.c diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 22a4b68..50fc09b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1094,6 +1094,21 @@ bytes respectively. Such letter suffixes can also be entirely omitted. you are really sure that your UEFI does sane gc and fulfills the spec otherwise your board may brick. + efi_fake_mem= nn[KMG]@ss[KMG]:aa[,nn[KMG]@ss[KMG]:aa,..] [EFI; X86] + Add arbitrary attribute to specific memory range by + updating original EFI memory map. + Region of memory which aa attribute is added to is + from ss to ss+nn. + If efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1 + is specified, EFI_MEMORY_MORE_RELIABLE(0x1) + attribute is added to range 0x1-0x18000 and + 0x10a000-0x112000. + + Using this parameter you can do debugging of EFI memmap + related feature. For example, you can do debugging of + Address Range Mirroring feature even if your box + doesn't support it. + eisa_irq_edge= [PARISC,HW] See header of drivers/parisc/eisa.c. diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index fdb7f2a..30b4c44 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1079,8 +1079,10 @@ void __init setup_arch(char **cmdline_p) memblock_set_current_limit(ISA_END_ADDRESS); memblock_x86_fill(); - if (efi_enabled(EFI_BOOT)) + if (efi_enabled(EFI_BOOT)) { + efi_fake_memmap(); efi_find_mirror(); + } /* * The EFI specification says that boot service code won't be called diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 84533e0..ac47cc4d 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -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 && X86 && 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 diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 6fd3da9..c24f005 100644 --- a/drivers/firmware/efi/Makefile +++
RE: [PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
I've missed git-format-patch after rebasing. I'll resend right one.. > -Original Message- > From: kbuild test robot [mailto:l...@intel.com] > Sent: Wednesday, September 30, 2015 10:37 AM > To: Izumi, Taku/泉 拓 > Cc: kbuild-...@01.org; linux-kernel@vger.kernel.org; > linux-...@vger.kernel.org; x...@kernel.org; matt.flem...@intel.com; > t...@linutronix.de; mi...@redhat.com; h...@zytor.com; tony.l...@intel.com; > qinxi...@huawei.com; Kamezawa, Hiroyuki/亀 > 澤 寛之; ard.biesheu...@linaro.org; Izumi, Taku/泉 拓 > Subject: Re: [PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option > > Hi Taku, > > [auto build test results on v4.3-rc3 -- if it's inappropriate base, please > ignore] > > config: i386-allmodconfig (attached as .config) > reproduce: > git checkout afcc94d3f91a00ce97d735a563a8e5d595f45a03 > # save the attached .config to linux build tree > make ARCH=i386 > > All error/warnings (new ones prefixed by >>): > > >> drivers/firmware/efi/fake_mem.c:36:25: error: 'CONFIG_EFI_MAX_FAKEMEM' > >> undeclared here (not in a function) > #define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKEMEM > ^ > >> drivers/firmware/efi/fake_mem.c:42:34: note: in expansion of macro > >> 'EFI_MAX_FAKEMEM' > static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; > ^ >drivers/firmware/efi/fake_mem.c: In function 'efi_fake_memmap': > >> drivers/firmware/efi/fake_mem.c:186:20: warning: cast to pointer from > >> integer of different size [-Wint-to-pointer-cast] > memmap.phys_map = (void *)new_memmap_phy; >^ >drivers/firmware/efi/fake_mem.c: At top level: > >> drivers/firmware/efi/fake_mem.c:42:24: warning: 'fake_mems' defined but > >> not used [-Wunused-variable] > static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; >^ > > vim +/CONFIG_EFI_MAX_FAKEMEM +36 drivers/firmware/efi/fake_mem.c > > 30#include > 31#include > 32#include > 33#include > 34#include > 35 > > 36#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKEMEM > 37 > 38struct fake_mem { > 39struct range range; > 40u64 attribute; > 41}; > > 42static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; > 43static int nr_fake_mem; > 44 > 45static int __init cmp_fake_mem(const void *x1, const void *x2) > 46{ > 47const struct fake_mem *m1 = x1; > 48const struct fake_mem *m2 = x2; > 49 > 50if (m1->range.start < m2->range.start) > 51return -1; > 52if (m1->range.start > m2->range.start) > 53return 1; > 54return 0; > 55} > 56 > 57void __init efi_fake_memmap(void) > 58{ > 59u64 start, end, m_start, m_end, m_attr; > 60int new_nr_map = memmap.nr_map; > 61efi_memory_desc_t *md; > 62u64 new_memmap_phy; > 63void *new_memmap; > 64void *old, *new; > 65int i; > 66 > 67if (!nr_fake_mem || !efi_enabled(EFI_MEMMAP)) > 68return; > 69 > 70/* count up the number of EFI memory descriptor */ > 71for (old = memmap.map; old < memmap.map_end; old += > memmap.desc_size) { > 72md = old; > 73start = md->phys_addr; > 74end = start + (md->num_pages << EFI_PAGE_SHIFT) > - 1; > 75 > 76for (i = 0; i < nr_fake_mem; i++) { > 77/* modifying range */ > 78m_start = fake_mems[i].range.start; > 79m_end = fake_mems[i].range.end; > 80 > 81if (m_start <= start) { > 82/* split into 2 parts */ > 83if (start < m_end && m_end < > end) > 84new_nr_map++; > 85} > 86if (start < m_start && m_start < end) { > 87/
Re: [PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
Hi Taku, [auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore] config: i386-allmodconfig (attached as .config) reproduce: git checkout afcc94d3f91a00ce97d735a563a8e5d595f45a03 # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): >> drivers/firmware/efi/fake_mem.c:36:25: error: 'CONFIG_EFI_MAX_FAKEMEM' >> undeclared here (not in a function) #define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKEMEM ^ >> drivers/firmware/efi/fake_mem.c:42:34: note: in expansion of macro >> 'EFI_MAX_FAKEMEM' static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; ^ drivers/firmware/efi/fake_mem.c: In function 'efi_fake_memmap': >> drivers/firmware/efi/fake_mem.c:186:20: warning: cast to pointer from >> integer of different size [-Wint-to-pointer-cast] memmap.phys_map = (void *)new_memmap_phy; ^ drivers/firmware/efi/fake_mem.c: At top level: >> drivers/firmware/efi/fake_mem.c:42:24: warning: 'fake_mems' defined but not >> used [-Wunused-variable] static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; ^ vim +/CONFIG_EFI_MAX_FAKEMEM +36 drivers/firmware/efi/fake_mem.c 30 #include 31 #include 32 #include 33 #include 34 #include 35 > 36 #define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKEMEM 37 38 struct fake_mem { 39 struct range range; 40 u64 attribute; 41 }; > 42 static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; 43 static int nr_fake_mem; 44 45 static int __init cmp_fake_mem(const void *x1, const void *x2) 46 { 47 const struct fake_mem *m1 = x1; 48 const struct fake_mem *m2 = x2; 49 50 if (m1->range.start < m2->range.start) 51 return -1; 52 if (m1->range.start > m2->range.start) 53 return 1; 54 return 0; 55 } 56 57 void __init efi_fake_memmap(void) 58 { 59 u64 start, end, m_start, m_end, m_attr; 60 int new_nr_map = memmap.nr_map; 61 efi_memory_desc_t *md; 62 u64 new_memmap_phy; 63 void *new_memmap; 64 void *old, *new; 65 int i; 66 67 if (!nr_fake_mem || !efi_enabled(EFI_MEMMAP)) 68 return; 69 70 /* count up the number of EFI memory descriptor */ 71 for (old = memmap.map; old < memmap.map_end; old += memmap.desc_size) { 72 md = old; 73 start = md->phys_addr; 74 end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; 75 76 for (i = 0; i < nr_fake_mem; i++) { 77 /* modifying range */ 78 m_start = fake_mems[i].range.start; 79 m_end = fake_mems[i].range.end; 80 81 if (m_start <= start) { 82 /* split into 2 parts */ 83 if (start < m_end && m_end < end) 84 new_nr_map++; 85 } 86 if (start < m_start && m_start < end) { 87 /* split into 3 parts */ 88 if (m_end < end) 89 new_nr_map += 2; 90 /* split into 2 parts */ 91 if (end <= m_end) 92 new_nr_map++; 93 } 94 } 95 } 96 97 /* allocate memory for new EFI memmap */ 98 new_memmap_phy = memblock_alloc(memmap.desc_size * new_nr_map, 99 PAGE_SIZE); 100 if (!new_memmap_phy) 101 return; 102 103 /* create new EFI memmap */ 104 new_memmap = early_memremap(new_memmap_phy, 105 memmap.desc_size * new_nr_map); 106 if (!new_memmap) { 107 memblock_free(new_memmap_phy, memmap.desc_size * new_nr_map); 108 return; 109 } 110 111 for (old = memmap.map, new = new_memmap; 112 old < memmap.map_end; 113 old += memmap.desc_size, new += memmap.desc_size) { 114 115 /* copy original EFI memory descriptor */ 116 memcpy(new, old, memmap.desc_size); 117 md = new; 118 start = md->phys_addr; 119 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) -
[PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
This patch introduces new boot option named "efi_fake_mem". By specifying this parameter, you can add arbitrary attribute to specific memory range. This is useful for debugging of Address Range Mirroring feature. For example, if "efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1" is specified, the original (firmware provided) EFI memmap will be updated so that the specified memory regions have EFI_MEMORY_MORE_RELIABLE attribute (0x1): efi: mem36: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x0001-0x0020a000) (129536MB) efi: mem36: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] range=[0x0001-0x00018000) (2048MB) efi: mem37: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x00018000-0x0010a000) (61952MB) efi: mem38: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] range=[0x0010a000-0x00112000) (2048MB) efi: mem39: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x00112000-0x0020a000) (63488MB) And you will find that the following message is output: efi: Memory: 4096M/131455M mirrored memory Signed-off-by: Taku Izumi --- Documentation/kernel-parameters.txt | 15 +++ arch/x86/kernel/setup.c | 4 +- drivers/firmware/efi/Kconfig| 22 drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/fake_mem.c | 238 include/linux/efi.h | 6 + 6 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/efi/fake_mem.c diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 22a4b68..50fc09b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1094,6 +1094,21 @@ bytes respectively. Such letter suffixes can also be entirely omitted. you are really sure that your UEFI does sane gc and fulfills the spec otherwise your board may brick. + efi_fake_mem= nn[KMG]@ss[KMG]:aa[,nn[KMG]@ss[KMG]:aa,..] [EFI; X86] + Add arbitrary attribute to specific memory range by + updating original EFI memory map. + Region of memory which aa attribute is added to is + from ss to ss+nn. + If efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1 + is specified, EFI_MEMORY_MORE_RELIABLE(0x1) + attribute is added to range 0x1-0x18000 and + 0x10a000-0x112000. + + Using this parameter you can do debugging of EFI memmap + related feature. For example, you can do debugging of + Address Range Mirroring feature even if your box + doesn't support it. + eisa_irq_edge= [PARISC,HW] See header of drivers/parisc/eisa.c. diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index fdb7f2a..30b4c44 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1079,8 +1079,10 @@ void __init setup_arch(char **cmdline_p) memblock_set_current_limit(ISA_END_ADDRESS); memblock_x86_fill(); - if (efi_enabled(EFI_BOOT)) + if (efi_enabled(EFI_BOOT)) { + efi_fake_memmap(); efi_find_mirror(); + } /* * The EFI specification says that boot service code won't be called diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 84533e0..ac47cc4d 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -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 && X86 && 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 diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 6fd3da9..c24f005 100644 --- a/drivers/firmware/efi/Makefile +++
[PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
This patch introduces new boot option named "efi_fake_mem". By specifying this parameter, you can add arbitrary attribute to specific memory range. This is useful for debugging of Address Range Mirroring feature. For example, if "efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1" is specified, the original (firmware provided) EFI memmap will be updated so that the specified memory regions have EFI_MEMORY_MORE_RELIABLE attribute (0x1): efi: mem36: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x0001-0x0020a000) (129536MB) efi: mem36: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] range=[0x0001-0x00018000) (2048MB) efi: mem37: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x00018000-0x0010a000) (61952MB) efi: mem38: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] range=[0x0010a000-0x00112000) (2048MB) efi: mem39: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x00112000-0x0020a000) (63488MB) And you will find that the following message is output: efi: Memory: 4096M/131455M mirrored memory Signed-off-by: Taku Izumi--- Documentation/kernel-parameters.txt | 15 +++ arch/x86/kernel/setup.c | 4 +- drivers/firmware/efi/Kconfig| 22 drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/fake_mem.c | 238 include/linux/efi.h | 6 + 6 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/efi/fake_mem.c diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 22a4b68..50fc09b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1094,6 +1094,21 @@ bytes respectively. Such letter suffixes can also be entirely omitted. you are really sure that your UEFI does sane gc and fulfills the spec otherwise your board may brick. + efi_fake_mem= nn[KMG]@ss[KMG]:aa[,nn[KMG]@ss[KMG]:aa,..] [EFI; X86] + Add arbitrary attribute to specific memory range by + updating original EFI memory map. + Region of memory which aa attribute is added to is + from ss to ss+nn. + If efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1 + is specified, EFI_MEMORY_MORE_RELIABLE(0x1) + attribute is added to range 0x1-0x18000 and + 0x10a000-0x112000. + + Using this parameter you can do debugging of EFI memmap + related feature. For example, you can do debugging of + Address Range Mirroring feature even if your box + doesn't support it. + eisa_irq_edge= [PARISC,HW] See header of drivers/parisc/eisa.c. diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index fdb7f2a..30b4c44 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1079,8 +1079,10 @@ void __init setup_arch(char **cmdline_p) memblock_set_current_limit(ISA_END_ADDRESS); memblock_x86_fill(); - if (efi_enabled(EFI_BOOT)) + if (efi_enabled(EFI_BOOT)) { + efi_fake_memmap(); efi_find_mirror(); + } /* * The EFI specification says that boot service code won't be called diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 84533e0..ac47cc4d 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -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 && X86 && 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 diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 6fd3da9..c24f005 100644 --- a/drivers/firmware/efi/Makefile +++
[PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
This patch introduces new boot option named "efi_fake_mem". By specifying this parameter, you can add arbitrary attribute to specific memory range. This is useful for debugging of Address Range Mirroring feature. For example, if "efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1" is specified, the original (firmware provided) EFI memmap will be updated so that the specified memory regions have EFI_MEMORY_MORE_RELIABLE attribute (0x1): efi: mem36: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x0001-0x0020a000) (129536MB) efi: mem36: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] range=[0x0001-0x00018000) (2048MB) efi: mem37: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x00018000-0x0010a000) (61952MB) efi: mem38: [Conventional Memory| |MR| | | | |WB|WT|WC|UC] range=[0x0010a000-0x00112000) (2048MB) efi: mem39: [Conventional Memory| | | | | | |WB|WT|WC|UC] range=[0x00112000-0x0020a000) (63488MB) And you will find that the following message is output: efi: Memory: 4096M/131455M mirrored memory Signed-off-by: Taku Izumi--- Documentation/kernel-parameters.txt | 15 +++ arch/x86/kernel/setup.c | 4 +- drivers/firmware/efi/Kconfig| 22 drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/fake_mem.c | 238 include/linux/efi.h | 6 + 6 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/efi/fake_mem.c diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 22a4b68..50fc09b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1094,6 +1094,21 @@ bytes respectively. Such letter suffixes can also be entirely omitted. you are really sure that your UEFI does sane gc and fulfills the spec otherwise your board may brick. + efi_fake_mem= nn[KMG]@ss[KMG]:aa[,nn[KMG]@ss[KMG]:aa,..] [EFI; X86] + Add arbitrary attribute to specific memory range by + updating original EFI memory map. + Region of memory which aa attribute is added to is + from ss to ss+nn. + If efi_fake_mem=2G@4G:0x1,2G@0x10a000:0x1 + is specified, EFI_MEMORY_MORE_RELIABLE(0x1) + attribute is added to range 0x1-0x18000 and + 0x10a000-0x112000. + + Using this parameter you can do debugging of EFI memmap + related feature. For example, you can do debugging of + Address Range Mirroring feature even if your box + doesn't support it. + eisa_irq_edge= [PARISC,HW] See header of drivers/parisc/eisa.c. diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index fdb7f2a..30b4c44 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1079,8 +1079,10 @@ void __init setup_arch(char **cmdline_p) memblock_set_current_limit(ISA_END_ADDRESS); memblock_x86_fill(); - if (efi_enabled(EFI_BOOT)) + if (efi_enabled(EFI_BOOT)) { + efi_fake_memmap(); efi_find_mirror(); + } /* * The EFI specification says that boot service code won't be called diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 84533e0..ac47cc4d 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -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 && X86 && 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 diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 6fd3da9..c24f005 100644 --- a/drivers/firmware/efi/Makefile +++
Re: [PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
Hi Taku, [auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore] config: i386-allmodconfig (attached as .config) reproduce: git checkout afcc94d3f91a00ce97d735a563a8e5d595f45a03 # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): >> drivers/firmware/efi/fake_mem.c:36:25: error: 'CONFIG_EFI_MAX_FAKEMEM' >> undeclared here (not in a function) #define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKEMEM ^ >> drivers/firmware/efi/fake_mem.c:42:34: note: in expansion of macro >> 'EFI_MAX_FAKEMEM' static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; ^ drivers/firmware/efi/fake_mem.c: In function 'efi_fake_memmap': >> drivers/firmware/efi/fake_mem.c:186:20: warning: cast to pointer from >> integer of different size [-Wint-to-pointer-cast] memmap.phys_map = (void *)new_memmap_phy; ^ drivers/firmware/efi/fake_mem.c: At top level: >> drivers/firmware/efi/fake_mem.c:42:24: warning: 'fake_mems' defined but not >> used [-Wunused-variable] static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; ^ vim +/CONFIG_EFI_MAX_FAKEMEM +36 drivers/firmware/efi/fake_mem.c 30 #include 31 #include 32 #include 33 #include 34 #include 35 > 36 #define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKEMEM 37 38 struct fake_mem { 39 struct range range; 40 u64 attribute; 41 }; > 42 static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; 43 static int nr_fake_mem; 44 45 static int __init cmp_fake_mem(const void *x1, const void *x2) 46 { 47 const struct fake_mem *m1 = x1; 48 const struct fake_mem *m2 = x2; 49 50 if (m1->range.start < m2->range.start) 51 return -1; 52 if (m1->range.start > m2->range.start) 53 return 1; 54 return 0; 55 } 56 57 void __init efi_fake_memmap(void) 58 { 59 u64 start, end, m_start, m_end, m_attr; 60 int new_nr_map = memmap.nr_map; 61 efi_memory_desc_t *md; 62 u64 new_memmap_phy; 63 void *new_memmap; 64 void *old, *new; 65 int i; 66 67 if (!nr_fake_mem || !efi_enabled(EFI_MEMMAP)) 68 return; 69 70 /* count up the number of EFI memory descriptor */ 71 for (old = memmap.map; old < memmap.map_end; old += memmap.desc_size) { 72 md = old; 73 start = md->phys_addr; 74 end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; 75 76 for (i = 0; i < nr_fake_mem; i++) { 77 /* modifying range */ 78 m_start = fake_mems[i].range.start; 79 m_end = fake_mems[i].range.end; 80 81 if (m_start <= start) { 82 /* split into 2 parts */ 83 if (start < m_end && m_end < end) 84 new_nr_map++; 85 } 86 if (start < m_start && m_start < end) { 87 /* split into 3 parts */ 88 if (m_end < end) 89 new_nr_map += 2; 90 /* split into 2 parts */ 91 if (end <= m_end) 92 new_nr_map++; 93 } 94 } 95 } 96 97 /* allocate memory for new EFI memmap */ 98 new_memmap_phy = memblock_alloc(memmap.desc_size * new_nr_map, 99 PAGE_SIZE); 100 if (!new_memmap_phy) 101 return; 102 103 /* create new EFI memmap */ 104 new_memmap = early_memremap(new_memmap_phy, 105 memmap.desc_size * new_nr_map); 106 if (!new_memmap) { 107 memblock_free(new_memmap_phy, memmap.desc_size * new_nr_map); 108 return; 109 } 110 111 for (old = memmap.map, new = new_memmap; 112 old < memmap.map_end; 113 old += memmap.desc_size, new += memmap.desc_size) { 114 115 /* copy original EFI memory descriptor */ 116 memcpy(new, old, memmap.desc_size); 117 md = new; 118 start = md->phys_addr; 119 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) -
RE: [PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option
I've missed git-format-patch after rebasing. I'll resend right one.. > -Original Message- > From: kbuild test robot [mailto:l...@intel.com] > Sent: Wednesday, September 30, 2015 10:37 AM > To: Izumi, Taku/泉 拓 > Cc: kbuild-...@01.org; linux-kernel@vger.kernel.org; > linux-...@vger.kernel.org; x...@kernel.org; matt.flem...@intel.com; > t...@linutronix.de; mi...@redhat.com; h...@zytor.com; tony.l...@intel.com; > qinxi...@huawei.com; Kamezawa, Hiroyuki/亀 > 澤 寛之; ard.biesheu...@linaro.org; Izumi, Taku/泉 拓 > Subject: Re: [PATCH 2/2] x86, efi: Add "efi_fake_mem" boot option > > Hi Taku, > > [auto build test results on v4.3-rc3 -- if it's inappropriate base, please > ignore] > > config: i386-allmodconfig (attached as .config) > reproduce: > git checkout afcc94d3f91a00ce97d735a563a8e5d595f45a03 > # save the attached .config to linux build tree > make ARCH=i386 > > All error/warnings (new ones prefixed by >>): > > >> drivers/firmware/efi/fake_mem.c:36:25: error: 'CONFIG_EFI_MAX_FAKEMEM' > >> undeclared here (not in a function) > #define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKEMEM > ^ > >> drivers/firmware/efi/fake_mem.c:42:34: note: in expansion of macro > >> 'EFI_MAX_FAKEMEM' > static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; > ^ >drivers/firmware/efi/fake_mem.c: In function 'efi_fake_memmap': > >> drivers/firmware/efi/fake_mem.c:186:20: warning: cast to pointer from > >> integer of different size [-Wint-to-pointer-cast] > memmap.phys_map = (void *)new_memmap_phy; >^ >drivers/firmware/efi/fake_mem.c: At top level: > >> drivers/firmware/efi/fake_mem.c:42:24: warning: 'fake_mems' defined but > >> not used [-Wunused-variable] > static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; >^ > > vim +/CONFIG_EFI_MAX_FAKEMEM +36 drivers/firmware/efi/fake_mem.c > > 30#include > 31#include > 32#include > 33#include > 34#include > 35 > > 36#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKEMEM > 37 > 38struct fake_mem { > 39struct range range; > 40u64 attribute; > 41}; > > 42static struct fake_mem fake_mems[EFI_MAX_FAKEMEM]; > 43static int nr_fake_mem; > 44 > 45static int __init cmp_fake_mem(const void *x1, const void *x2) > 46{ > 47const struct fake_mem *m1 = x1; > 48const struct fake_mem *m2 = x2; > 49 > 50if (m1->range.start < m2->range.start) > 51return -1; > 52if (m1->range.start > m2->range.start) > 53return 1; > 54return 0; > 55} > 56 > 57void __init efi_fake_memmap(void) > 58{ > 59u64 start, end, m_start, m_end, m_attr; > 60int new_nr_map = memmap.nr_map; > 61efi_memory_desc_t *md; > 62u64 new_memmap_phy; > 63void *new_memmap; > 64void *old, *new; > 65int i; > 66 > 67if (!nr_fake_mem || !efi_enabled(EFI_MEMMAP)) > 68return; > 69 > 70/* count up the number of EFI memory descriptor */ > 71for (old = memmap.map; old < memmap.map_end; old += > memmap.desc_size) { > 72md = old; > 73start = md->phys_addr; > 74end = start + (md->num_pages << EFI_PAGE_SHIFT) > - 1; > 75 > 76for (i = 0; i < nr_fake_mem; i++) { > 77/* modifying range */ > 78m_start = fake_mems[i].range.start; > 79m_end = fake_mems[i].range.end; > 80 > 81if (m_start <= start) { > 82/* split into 2 parts */ > 83if (start < m_end && m_end < > end) > 84new_nr_map++; > 85} > 86if (start < m_start && m_start < end) { > 87/