Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi...
authorIngo Molnar <mingo@kernel.org>
Wed, 14 Oct 2015 14:05:40 +0000 (16:05 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 14 Oct 2015 14:51:34 +0000 (16:51 +0200)
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:

  8a53554e12e9 ("x86/efi: Fix multiple GOP device support")
  ae2ee627dc87 ("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 <mingo@kernel.org>
1  2 
Documentation/kernel-parameters.txt
arch/arm64/kernel/efi.c
arch/x86/boot/compressed/eboot.c
arch/x86/include/asm/efi.h
arch/x86/kernel/setup.c
arch/x86/platform/efi/efi.c
drivers/firmware/efi/Kconfig

@@@ -910,8 -910,6 +910,8 @@@ bytes respectively. Such letter suffixe
                        Disable PIN 1 of APIC timer
                        Can be useful to work around chipset bugs.
  
 +      dis_ucode_ldr   [X86] Disable the microcode loader.
 +
        dma_debug=off   If the kernel is compiled with DMA_API_DEBUG support,
                        this option disables the debugging code at boot.
  
                        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:0x10000,2G@0x10a0000000:0x10000
+                       is specified, EFI_MEMORY_MORE_RELIABLE(0x10000)
+                       attribute is added to range 0x100000000-0x180000000 and
+                       0x10a0000000-0x1120000000.
+                       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.
  
                             <bus_id>,<clkrate>
  
        i8042.debug     [HW] Toggle i8042 debug mode
 +      i8042.unmask_kbd_data
 +                      [HW] Enable printing of interrupt data from the KBD port
 +                           (disabled by default, and as a pre-condition
 +                           requires that i8042.debug=1 be enabled)
        i8042.direct    [HW] Put keyboard port into non-translated mode
        i8042.dumbkbd   [HW] Pretend that controller can only read data from
                             keyboard and cannot control its state
                        The default parameter value of '0' causes the kernel
                        not to attempt recovery of lost locks.
  
 +      nfs4.layoutstats_timer =
 +                      [NFSv4.2] Change the rate at which the kernel sends
 +                      layoutstats to the pNFS metadata server.
 +
 +                      Setting this to value to 0 causes the kernel to use
 +                      whatever value is the default set by the layout
 +                      driver. A non-zero value sets the minimum interval
 +                      in seconds between layoutstats transmissions.
 +
        nfsd.nfs4_disable_idmapping=
                        [NFSv4] When set to the default of '1', the NFSv4
                        server will return only numeric uids and gids to
                        in a given burst of a callback-flood test.
  
        rcutorture.fqs_duration= [KNL]
 -                      Set duration of force_quiescent_state bursts.
 +                      Set duration of force_quiescent_state bursts
 +                      in microseconds.
  
        rcutorture.fqs_holdoff= [KNL]
 -                      Set holdoff time within force_quiescent_state bursts.
 +                      Set holdoff time within force_quiescent_state bursts
 +                      in microseconds.
  
        rcutorture.fqs_stutter= [KNL]
 -                      Set wait time between force_quiescent_state bursts.
 +                      Set wait time between force_quiescent_state bursts
 +                      in seconds.
 +
 +      rcutorture.gp_cond= [KNL]
 +                      Use conditional/asynchronous update-side
 +                      primitives, if available.
  
        rcutorture.gp_exp= [KNL]
 -                      Use expedited update-side primitives.
 +                      Use expedited update-side primitives, if available.
  
        rcutorture.gp_normal= [KNL]
 -                      Use normal (non-expedited) update-side primitives.
 -                      If both gp_exp and gp_normal are set, do both.
 -                      If neither gp_exp nor gp_normal are set, still
 -                      do both.
 +                      Use normal (non-expedited) asynchronous
 +                      update-side primitives, if available.
 +
 +      rcutorture.gp_sync= [KNL]
 +                      Use normal (non-expedited) synchronous
 +                      update-side primitives, if available.  If all
 +                      of rcutorture.gp_cond=, rcutorture.gp_exp=,
 +                      rcutorture.gp_normal=, and rcutorture.gp_sync=
 +                      are zero, rcutorture acts as if is interpreted
 +                      they are all non-zero.
  
        rcutorture.n_barrier_cbs= [KNL]
                        Set callbacks/threads for rcu_barrier() testing.
                        Set time (s) between CPU-hotplug operations, or
                        zero to disable CPU-hotplug testing.
  
 -      rcutorture.torture_runnable= [BOOT]
 -                      Start rcutorture running at boot time.
 -
        rcutorture.shuffle_interval= [KNL]
                        Set task-shuffle interval (s).  Shuffling tasks
                        allows some CPUs to go into dyntick-idle mode
                        Test RCU's dyntick-idle handling.  See also the
                        rcutorture.shuffle_interval parameter.
  
 +      rcutorture.torture_runnable= [BOOT]
 +                      Start rcutorture running at boot time.
 +
        rcutorture.torture_type= [KNL]
                        Specify the RCU implementation to test.
  
                        plus one apbt timer for broadcast timer.
                        x86_intel_mid_timer=apbt_only | lapic_and_apbt
  
 +      xen_512gb_limit         [KNL,X86-64,XEN]
 +                      Restricts the kernel running paravirtualized under Xen
 +                      to use only up to 512 GB of RAM. The reason to do so is
 +                      crash analysis tools and Xen tools for doing domain
 +                      save/restore/migration must be enabled to handle larger
 +                      domains.
 +
        xen_emul_unplug=                [HW,X86,XEN]
                        Unplug Xen emulated devices
                        Format: [unplug0,][unplug1]
diff --combined arch/arm64/kernel/efi.c
@@@ -51,15 -51,6 +51,6 @@@ static struct mm_struct efi_mm = 
        INIT_MM_CONTEXT(efi_mm)
  };
  
- static int uefi_debug __initdata;
- static int __init uefi_debug_setup(char *str)
- {
-       uefi_debug = 1;
-       return 0;
- }
- early_param("uefi_debug", uefi_debug_setup);
  static int __init is_normal_ram(efi_memory_desc_t *md)
  {
        if (md->attribute & EFI_MEMORY_WB)
@@@ -171,14 -162,14 +162,14 @@@ static __init void reserve_regions(void
        efi_memory_desc_t *md;
        u64 paddr, npages, size;
  
-       if (uefi_debug)
+       if (efi_enabled(EFI_DBG))
                pr_info("Processing EFI memory map:\n");
  
        for_each_efi_memory_desc(&memmap, md) {
                paddr = md->phys_addr;
                npages = md->num_pages;
  
-               if (uefi_debug) {
+               if (efi_enabled(EFI_DBG)) {
                        char buf[64];
  
                        pr_info("  0x%012llx-0x%012llx %s",
  
                if (is_reserve_region(md)) {
                        memblock_reserve(paddr, size);
-                       if (uefi_debug)
+                       if (efi_enabled(EFI_DBG))
                                pr_cont("*");
                }
  
-               if (uefi_debug)
+               if (efi_enabled(EFI_DBG))
                        pr_cont("\n");
        }
  
@@@ -210,7 -201,7 +201,7 @@@ void __init efi_init(void
        struct efi_fdt_params params;
  
        /* Grab UEFI information placed in FDT by stub */
-       if (!efi_get_fdt_params(&params, uefi_debug))
+       if (!efi_get_fdt_params(&params))
                return;
  
        efi_system_table = params.system_table;
@@@ -258,8 -249,7 +249,8 @@@ static bool __init efi_virtmap_init(voi
                 */
                if (!is_normal_ram(md))
                        prot = __pgprot(PROT_DEVICE_nGnRE);
 -              else if (md->type == EFI_RUNTIME_SERVICES_CODE)
 +              else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
 +                       !PAGE_ALIGNED(md->phys_addr))
                        prot = PAGE_KERNEL_EXEC;
                else
                        prot = PAGE_KERNEL;
@@@ -624,7 -624,7 +624,7 @@@ setup_pixel_info(struct screen_info *si
  static efi_status_t
  __gop_query32(struct efi_graphics_output_protocol_32 *gop32,
              struct efi_graphics_output_mode_info **info,
-             unsigned long *size, u32 *fb_base)
+             unsigned long *size, u64 *fb_base)
  {
        struct efi_graphics_output_protocol_mode_32 *mode;
        efi_status_t status;
@@@ -650,7 -650,8 +650,8 @@@ setup_gop32(struct screen_info *si, efi
        unsigned long nr_gops;
        u16 width, height;
        u32 pixels_per_scan_line;
-       u32 fb_base;
+       u32 ext_lfb_base;
+       u64 fb_base;
        struct efi_pixel_bitmask pixel_info;
        int pixel_format;
        efi_status_t status;
                bool conout_found = false;
                void *dummy = NULL;
                u32 h = handles[i];
-               u32 current_fb_base;
++              u64 current_fb_base;
  
                status = efi_call_early(handle_protocol, h,
                                        proto, (void **)&gop32);
                if (status == EFI_SUCCESS)
                        conout_found = true;
  
 -              status = __gop_query32(gop32, &info, &size, &fb_base);
 +              status = __gop_query32(gop32, &info, &size, &current_fb_base);
                if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
                        /*
                         * Systems that use the UEFI Console Splitter may
                        pixel_format = info->pixel_format;
                        pixel_info = info->pixel_information;
                        pixels_per_scan_line = info->pixels_per_scan_line;
 +                      fb_base = current_fb_base;
  
                        /*
                         * Once we've found a GOP supporting ConOut,
        si->lfb_width = width;
        si->lfb_height = height;
        si->lfb_base = fb_base;
+       ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
+       if (ext_lfb_base) {
+               si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
+               si->ext_lfb_base = ext_lfb_base;
+       }
        si->pages = 1;
  
        setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
@@@ -729,7 -735,7 +737,7 @@@ out
  static efi_status_t
  __gop_query64(struct efi_graphics_output_protocol_64 *gop64,
              struct efi_graphics_output_mode_info **info,
-             unsigned long *size, u32 *fb_base)
+             unsigned long *size, u64 *fb_base)
  {
        struct efi_graphics_output_protocol_mode_64 *mode;
        efi_status_t status;
@@@ -755,7 -761,8 +763,8 @@@ setup_gop64(struct screen_info *si, efi
        unsigned long nr_gops;
        u16 width, height;
        u32 pixels_per_scan_line;
-       u32 fb_base;
+       u32 ext_lfb_base;
+       u64 fb_base;
        struct efi_pixel_bitmask pixel_info;
        int pixel_format;
        efi_status_t status;
                bool conout_found = false;
                void *dummy = NULL;
                u64 h = handles[i];
-               u32 current_fb_base;
++              u64 current_fb_base;
  
                status = efi_call_early(handle_protocol, h,
                                        proto, (void **)&gop64);
                if (status == EFI_SUCCESS)
                        conout_found = true;
  
 -              status = __gop_query64(gop64, &info, &size, &fb_base);
 +              status = __gop_query64(gop64, &info, &size, &current_fb_base);
                if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
                        /*
                         * Systems that use the UEFI Console Splitter may
                        pixel_format = info->pixel_format;
                        pixel_info = info->pixel_information;
                        pixels_per_scan_line = info->pixels_per_scan_line;
 +                      fb_base = current_fb_base;
  
                        /*
                         * Once we've found a GOP supporting ConOut,
        si->lfb_width = width;
        si->lfb_height = height;
        si->lfb_base = fb_base;
+       ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
+       if (ext_lfb_base) {
+               si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
+               si->ext_lfb_base = ext_lfb_base;
+       }
        si->pages = 1;
  
        setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
@@@ -1045,6 -1057,7 +1061,6 @@@ void setup_graphics(struct boot_params 
  struct boot_params *make_boot_params(struct efi_config *c)
  {
        struct boot_params *boot_params;
 -      struct sys_desc_table *sdt;
        struct apm_bios_info *bi;
        struct setup_header *hdr;
        struct efi_info *efi;
        hdr = &boot_params->hdr;
        efi = &boot_params->efi_info;
        bi = &boot_params->apm_bios_info;
 -      sdt = &boot_params->sys_desc_table;
  
        /* Copy the second sector to boot_params */
        memcpy(&hdr->jump, image->image_base + 512, 512);
        /* Clear APM BIOS info */
        memset(bi, 0, sizeof(*bi));
  
 -      memset(sdt, 0, sizeof(*sdt));
 -
        status = efi_parse_options(cmdline_ptr);
        if (status != EFI_SUCCESS)
                goto fail2;
@@@ -86,18 -86,6 +86,18 @@@ extern u64 asmlinkage efi_call(void *fp
  extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
                                        u32 type, u64 attribute);
  
 +#ifdef CONFIG_KASAN
 +/*
 + * CONFIG_KASAN may redefine memset to __memset.  __memset function is present
 + * only in kernel binary.  Since the EFI stub linked into a separate binary it
 + * doesn't have __memset().  So we should use standard memset from
 + * arch/x86/boot/compressed/string.c.  The same applies to memcpy and memmove.
 + */
 +#undef memcpy
 +#undef memset
 +#undef memmove
 +#endif
 +
  #endif /* CONFIG_X86_32 */
  
  extern struct efi_scratch efi_scratch;
@@@ -105,6 -93,7 +105,7 @@@ extern void __init efi_set_executable(e
  extern int __init efi_memblock_x86_reserve_range(void);
  extern pgd_t * __init efi_call_phys_prolog(void);
  extern void __init efi_call_phys_epilog(pgd_t *save_pgd);
+ extern void __init efi_print_memmap(void);
  extern void __init efi_unmap_memmap(void);
  extern void __init efi_memory_uc(u64 addr, unsigned long size);
  extern void __init efi_map_region(efi_memory_desc_t *md);
diff --combined arch/x86/kernel/setup.c
@@@ -317,12 -317,15 +317,12 @@@ static u64 __init get_ramdisk_size(void
        return ramdisk_size;
  }
  
 -#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT)
  static void __init relocate_initrd(void)
  {
        /* Assume only end is not page aligned */
        u64 ramdisk_image = get_ramdisk_image();
        u64 ramdisk_size  = get_ramdisk_size();
        u64 area_size     = PAGE_ALIGN(ramdisk_size);
 -      unsigned long slop, clen, mapaddr;
 -      char *p, *q;
  
        /* We need to move the initrd down into directly mapped mem */
        relocated_ramdisk = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
        printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
               relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
  
 -      q = (char *)initrd_start;
 -
 -      /* Copy the initrd */
 -      while (ramdisk_size) {
 -              slop = ramdisk_image & ~PAGE_MASK;
 -              clen = ramdisk_size;
 -              if (clen > MAX_MAP_CHUNK-slop)
 -                      clen = MAX_MAP_CHUNK-slop;
 -              mapaddr = ramdisk_image & PAGE_MASK;
 -              p = early_memremap(mapaddr, clen+slop);
 -              memcpy(q, p+slop, clen);
 -              early_memunmap(p, clen+slop);
 -              q += clen;
 -              ramdisk_image += clen;
 -              ramdisk_size  -= clen;
 -      }
 +      copy_from_early_mem((void *)initrd_start, ramdisk_image, ramdisk_size);
  
 -      ramdisk_image = get_ramdisk_image();
 -      ramdisk_size  = get_ramdisk_size();
        printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
                " [mem %#010llx-%#010llx]\n",
                ramdisk_image, ramdisk_image + ramdisk_size - 1,
@@@ -478,7 -498,7 +478,7 @@@ static void __init memblock_x86_reserve
   * --------- Crashkernel reservation ------------------------------
   */
  
 -#ifdef CONFIG_KEXEC
 +#ifdef CONFIG_KEXEC_CORE
  
  /*
   * Keep the crash kernel below this limit.  On 32 bits earlier kernels
@@@ -896,6 -916,11 +896,6 @@@ void __init setup_arch(char **cmdline_p
  #ifdef CONFIG_X86_32
        apm_info.bios = boot_params.apm_bios_info;
        ist_info = boot_params.ist_info;
 -      if (boot_params.sys_desc_table.length != 0) {
 -              machine_id = boot_params.sys_desc_table.table[0];
 -              machine_submodel_id = boot_params.sys_desc_table.table[1];
 -              BIOS_revision = boot_params.sys_desc_table.table[2];
 -      }
  #endif
        saved_video_mode = boot_params.hdr.vid_mode;
        bootloader_type = boot_params.hdr.type_of_loader;
        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
@@@ -222,7 -222,7 +222,7 @@@ int __init efi_memblock_x86_reserve_ran
        return 0;
  }
  
static void __init print_efi_memmap(void)
void __init efi_print_memmap(void)
  {
  #ifdef EFI_DEBUG
        efi_memory_desc_t *md;
@@@ -524,7 -524,7 +524,7 @@@ void __init efi_init(void
                return;
  
        if (efi_enabled(EFI_DBG))
-               print_efi_memmap();
+               efi_print_memmap();
  
        efi_esrt_init();
  }
@@@ -650,7 -650,7 +650,7 @@@ static void __init get_systab_virt_addr
  
  static void __init save_runtime_map(void)
  {
 -#ifdef CONFIG_KEXEC
 +#ifdef CONFIG_KEXEC_CORE
        efi_memory_desc_t *md;
        void *tmp, *p, *q = NULL;
        int count = 0;
@@@ -704,70 -704,6 +704,70 @@@ out
        return ret;
  }
  
 +/*
 + * Iterate the EFI memory map in reverse order because the regions
 + * will be mapped top-down. The end result is the same as if we had
 + * mapped things forward, but doesn't require us to change the
 + * existing implementation of efi_map_region().
 + */
 +static inline void *efi_map_next_entry_reverse(void *entry)
 +{
 +      /* Initial call */
 +      if (!entry)
 +              return memmap.map_end - memmap.desc_size;
 +
 +      entry -= memmap.desc_size;
 +      if (entry < memmap.map)
 +              return NULL;
 +
 +      return entry;
 +}
 +
 +/*
 + * efi_map_next_entry - Return the next EFI memory map descriptor
 + * @entry: Previous EFI memory map descriptor
 + *
 + * This is a helper function to iterate over the EFI memory map, which
 + * we do in different orders depending on the current configuration.
 + *
 + * To begin traversing the memory map @entry must be %NULL.
 + *
 + * Returns %NULL when we reach the end of the memory map.
 + */
 +static void *efi_map_next_entry(void *entry)
 +{
 +      if (!efi_enabled(EFI_OLD_MEMMAP) && efi_enabled(EFI_64BIT)) {
 +              /*
 +               * Starting in UEFI v2.5 the EFI_PROPERTIES_TABLE
 +               * config table feature requires us to map all entries
 +               * in the same order as they appear in the EFI memory
 +               * map. That is to say, entry N must have a lower
 +               * virtual address than entry N+1. This is because the
 +               * firmware toolchain leaves relative references in
 +               * the code/data sections, which are split and become
 +               * separate EFI memory regions. Mapping things
 +               * out-of-order leads to the firmware accessing
 +               * unmapped addresses.
 +               *
 +               * Since we need to map things this way whether or not
 +               * the kernel actually makes use of
 +               * EFI_PROPERTIES_TABLE, let's just switch to this
 +               * scheme by default for 64-bit.
 +               */
 +              return efi_map_next_entry_reverse(entry);
 +      }
 +
 +      /* Initial call */
 +      if (!entry)
 +              return memmap.map;
 +
 +      entry += memmap.desc_size;
 +      if (entry >= memmap.map_end)
 +              return NULL;
 +
 +      return entry;
 +}
 +
  /*
   * Map the efi memory ranges of the runtime services and update new_mmap with
   * virtual addresses.
@@@ -778,8 -714,7 +778,8 @@@ static void * __init efi_map_regions(in
        unsigned long left = 0;
        efi_memory_desc_t *md;
  
 -      for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 +      p = NULL;
 +      while ((p = efi_map_next_entry(p))) {
                md = p;
                if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
  #ifdef CONFIG_X86_64
  
  static void __init kexec_enter_virtual_mode(void)
  {
 -#ifdef CONFIG_KEXEC
 +#ifdef CONFIG_KEXEC_CORE
        efi_memory_desc_t *md;
        void *p;
  
@@@ -1026,8 -961,6 +1026,6 @@@ static int __init arch_parse_efi_cmdlin
  
        if (parse_option_str(str, "old_map"))
                set_bit(EFI_OLD_MEMMAP, &efi.flags);
-       if (parse_option_str(str, "debug"))
-               set_bit(EFI_DBG, &efi.flags);
  
        return 0;
  }
@@@ -43,7 -43,7 +43,7 @@@ config EFI_VARS_PSTORE_DEFAULT_DISABL
  
  config EFI_RUNTIME_MAP
        bool "Export efi runtime maps to sysfs"
 -      depends on X86 && EFI && KEXEC
 +      depends on X86 && EFI && KEXEC_CORE
        default y
        help
          Export efi runtime memory maps to /sys/firmware/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