]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'core-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Nov 2015 23:05:52 +0000 (15:05 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 3 Nov 2015 23:05:52 +0000 (15:05 -0800)
Pull EFI changes from Ingo Molnar:
 "The main changes in this cycle were:

   - further EFI code generalization to make it more workable for ARM64
   - various extensions, such as 64-bit framebuffer address support,
     UEFI v2.5 EFI_PROPERTIES_TABLE support
   - code modularization simplifications and cleanups
   - new debugging parameters
   - various fixes and smaller additions"

* 'core-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits)
  efi: Fix warning of int-to-pointer-cast on x86 32-bit builds
  efi: Use correct type for struct efi_memory_map::phys_map
  x86/efi: Fix kernel panic when CONFIG_DEBUG_VIRTUAL is enabled
  efi: Add "efi_fake_mem" boot option
  x86/efi: Rename print_efi_memmap() to efi_print_memmap()
  efi: Auto-load the efi-pstore module
  efi: Introduce EFI_NX_PE_DATA bit and set it from properties table
  efi: Add support for UEFIv2.5 Properties table
  efi: Add EFI_MEMORY_MORE_RELIABLE support to efi_md_typeattr_format()
  efifb: Add support for 64-bit frame buffer addresses
  efi/arm64: Clean up efi_get_fdt_params() interface
  arm64: Use core efi=debug instead of uefi_debug command line parameter
  efi/x86: Move efi=debug option parsing to core
  drivers/firmware: Make efi/esrt.c driver explicitly non-modular
  efi: Use the generic efi.memmap instead of 'memmap'
  acpi/apei: Use appropriate pgprot_t to map GHES memory
  arm64, acpi/apei: Implement arch_apei_get_mem_attributes()
  arm64/mm: Add PROT_DEVICE_nGnRnE and PROT_NORMAL_WT
  acpi, x86: Implement arch_apei_get_mem_attributes()
  efi, x86: Rearrange efi_mem_attributes()
  ...

26 files changed:
Documentation/arm/uefi.txt
Documentation/kernel-parameters.txt
arch/arm64/include/asm/acpi.h
arch/arm64/include/asm/memory.h
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/acpi.c
arch/arm64/kernel/efi.c
arch/arm64/mm/proc.S
arch/x86/boot/compressed/eboot.c
arch/x86/boot/header.S
arch/x86/include/asm/acpi.h
arch/x86/include/asm/efi.h
arch/x86/kernel/setup.c
arch/x86/mm/pageattr.c
arch/x86/platform/efi/efi-bgrt.c
arch/x86/platform/efi/efi.c
drivers/acpi/apei/ghes.c
drivers/firmware/efi/Kconfig
drivers/firmware/efi/Makefile
drivers/firmware/efi/efi-pstore.c
drivers/firmware/efi/efi.c
drivers/firmware/efi/esrt.c
drivers/firmware/efi/fake_mem.c [new file with mode: 0644]
drivers/video/fbdev/efifb.c
include/linux/efi.h
include/uapi/linux/screen_info.h

index d60030a1b909bc68dbe7e6d275064cafbe3fdf4e..7b3fdfe0f7ba37a7ff6a0e46cfec18e1fcfbe68e 100644 (file)
@@ -60,5 +60,3 @@ linux,uefi-mmap-desc-ver  | 32-bit | Version of the mmap descriptor format.
 --------------------------------------------------------------------------------
 linux,uefi-stub-kern-ver  | string | Copy of linux_banner from build.
 --------------------------------------------------------------------------------
-
-For verbose debug messages, specify 'uefi_debug' on the kernel command line.
index 22a4b687ea5b4b3cb9d576bfeffaed813256a795..50fc09b623f65f6a42ff43701e20fb42d993d649 100644 (file)
@@ -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: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.
 
index 208cec08a74fa09973473adca3c69dfbcdb6111c..5f8a38dee2744d6655bb6eceb3cabf6917c80ad4 100644 (file)
@@ -92,4 +92,9 @@ static inline const char *acpi_get_enable_method(int cpu)
 {
        return acpi_psci_present() ? "psci" : NULL;
 }
+
+#ifdef CONFIG_ACPI_APEI
+pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
+#endif
+
 #endif /*_ASM_ACPI_H*/
index 6b4c3ad75a2a99b0760a38436b7d159bfe3209c3..67027c611dbd51e66b72492943394ff317c3998a 100644 (file)
@@ -94,6 +94,7 @@
 #define MT_DEVICE_GRE          2
 #define MT_NORMAL_NC           3
 #define MT_NORMAL              4
+#define MT_NORMAL_WT           5
 
 /*
  * Memory types for Stage-2 translation
index 26b066690593cd6304e81fdd24465a25ace2f396..571ca0ed4f0565378131b25f317ef8b2f819c3b2 100644 (file)
@@ -60,8 +60,10 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
 #define PROT_DEFAULT           (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
 #define PROT_SECT_DEFAULT      (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
 
+#define PROT_DEVICE_nGnRnE     (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
 #define PROT_DEVICE_nGnRE      (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
 #define PROT_NORMAL_NC         (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_NC))
+#define PROT_NORMAL_WT         (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_WT))
 #define PROT_NORMAL            (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL))
 
 #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
index 19de7537e7d32f407f3f75d5f295ab5f3c7c4291..137d537ddceb8001f15d9daa18c95631b561a085 100644 (file)
 #include <asm/cpu_ops.h>
 #include <asm/smp_plat.h>
 
+#ifdef CONFIG_ACPI_APEI
+# include <linux/efi.h>
+# include <asm/pgtable.h>
+#endif
+
 int acpi_noirq = 1;            /* skip ACPI IRQ initialization */
 int acpi_disabled = 1;
 EXPORT_SYMBOL(acpi_disabled);
@@ -230,3 +235,27 @@ void __init acpi_gic_init(void)
 
        early_acpi_os_unmap_memory((char *)table, tbl_size);
 }
+
+#ifdef CONFIG_ACPI_APEI
+pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
+{
+       /*
+        * According to "Table 8 Map: EFI memory types to AArch64 memory
+        * types" of UEFI 2.5 section 2.3.6.1, each EFI memory type is
+        * mapped to a corresponding MAIR attribute encoding.
+        * The EFI memory attribute advises all possible capabilities
+        * of a memory region. We use the most efficient capability.
+        */
+
+       u64 attr;
+
+       attr = efi_mem_attributes(addr);
+       if (attr & EFI_MEMORY_WB)
+               return PAGE_KERNEL;
+       if (attr & EFI_MEMORY_WT)
+               return __pgprot(PROT_NORMAL_WT);
+       if (attr & EFI_MEMORY_WC)
+               return __pgprot(PROT_NORMAL_NC);
+       return __pgprot(PROT_DEVICE_nGnRnE);
+}
+#endif
index 13671a9cf0167057d583f1c2dddca54ee94658f8..61eb1d17586a859a1fcc1d0d0fd653028d736b11 100644 (file)
@@ -51,15 +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 @@ 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",
@@ -194,11 +185,11 @@ static __init void reserve_regions(void)
 
                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,14 +201,14 @@ 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;
 
        memblock_reserve(params.mmap & PAGE_MASK,
                         PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK)));
-       memmap.phys_map = (void *)params.mmap;
+       memmap.phys_map = params.mmap;
        memmap.map = early_memremap(params.mmap, params.mmap_size);
        memmap.map_end = memmap.map + params.mmap_size;
        memmap.desc_size = params.desc_size;
@@ -291,7 +282,7 @@ static int __init arm64_enable_runtime_services(void)
        pr_info("Remapping and enabling EFI services.\n");
 
        mapsize = memmap.map_end - memmap.map;
-       memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
+       memmap.map = (__force void *)ioremap_cache(memmap.phys_map,
                                                   mapsize);
        if (!memmap.map) {
                pr_err("Failed to remap EFI memory map\n");
index e4ee7bd8830aed60b9b0b493c4c4dc93863d419c..7783ff05f74cc262c643b1a96932a717e47445c5 100644 (file)
@@ -163,12 +163,14 @@ ENTRY(__cpu_setup)
         *   DEVICE_GRE         010     00001100
         *   NORMAL_NC          011     01000100
         *   NORMAL             100     11111111
+        *   NORMAL_WT          101     10111011
         */
        ldr     x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \
                     MAIR(0x04, MT_DEVICE_nGnRE) | \
                     MAIR(0x0c, MT_DEVICE_GRE) | \
                     MAIR(0x44, MT_NORMAL_NC) | \
-                    MAIR(0xff, MT_NORMAL)
+                    MAIR(0xff, MT_NORMAL) | \
+                    MAIR(0xbb, MT_NORMAL_WT)
        msr     mair_el1, x5
        /*
         * Prepare SCTLR
index db51c1f27446157001cedc87bdd38b551e2f1844..583d539a41977a2c7397b9fd38e0839d3c41dbb9 100644 (file)
@@ -624,7 +624,7 @@ setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line,
 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 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
        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;
@@ -667,7 +668,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
                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);
@@ -715,6 +716,13 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
        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 +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 +763,8 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
        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;
@@ -772,7 +781,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
                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);
@@ -820,6 +829,13 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
        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);
index 2d6b309c8e9a12ac67ddf9d9cb429cb1fe8a7eae..6236b9ec4b764cfd988fb47f08cc000a653fbed4 100644 (file)
@@ -154,7 +154,7 @@ extra_header_fields:
 #else
        .quad   0                               # ImageBase
 #endif
-       .long   CONFIG_PHYSICAL_ALIGN           # SectionAlignment
+       .long   0x20                            # SectionAlignment
        .long   0x20                            # FileAlignment
        .word   0                               # MajorOperatingSystemVersion
        .word   0                               # MinorOperatingSystemVersion
index 3a45668f6dc38312bc9f5761214f076a144d00d4..94c18ebfd68cafaec66c6fc0b8c31ccdf37641fb 100644 (file)
 #include <asm/mpspec.h>
 #include <asm/realmode.h>
 
+#ifdef CONFIG_ACPI_APEI
+# include <asm/pgtable_types.h>
+#endif
+
 #ifdef CONFIG_ACPI
 extern int acpi_lapic;
 extern int acpi_ioapic;
@@ -147,4 +151,23 @@ extern int x86_acpi_numa_init(void);
 
 #define acpi_unlazy_tlb(x)     leave_mm(x)
 
+#ifdef CONFIG_ACPI_APEI
+static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
+{
+       /*
+        * We currently have no way to look up the EFI memory map
+        * attributes for a region in a consistent way, because the
+        * memmap is discarded after efi_free_boot_services(). So if
+        * you call efi_mem_attributes() during boot and at runtime,
+        * you could theoretically see different attributes.
+        *
+        * Since we are yet to see any x86 platforms that require
+        * anything other than PAGE_KERNEL (some arm64 platforms
+        * require the equivalent of PAGE_KERNEL_NOCACHE), return that
+        * until we know differently.
+        */
+        return PAGE_KERNEL;
+}
+#endif
+
 #endif /* _ASM_X86_ACPI_H */
index ae68be92f75587ce2bfdc2d09f18711ef9cd9c8a..0010c78c4998cf0702299ea2f8a9229e09bb6438 100644 (file)
@@ -105,6 +105,7 @@ extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable);
 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);
index a3cccbfc5f777e3483cad7da4a5a587bdd56c09c..7a83b7874b4007d54a890d05b3d0b6c068b6a049 100644 (file)
@@ -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
index 2c44c07923012a58e9f430bf4754910984771556..050a092b8d9a2628c03227d06c4d8a8314d5433a 100644 (file)
@@ -647,9 +647,12 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
        for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc)
                set_pte(&pbase[i], pfn_pte(pfn, canon_pgprot(ref_prot)));
 
-       if (pfn_range_is_mapped(PFN_DOWN(__pa(address)),
-                               PFN_DOWN(__pa(address)) + 1))
-               split_page_count(level);
+       if (virt_addr_valid(address)) {
+               unsigned long pfn = PFN_DOWN(__pa(address));
+
+               if (pfn_range_is_mapped(pfn, pfn + 1))
+                       split_page_count(level);
+       }
 
        /*
         * Install the new, split up pagetable.
index d7f997f7c26d2502a1a188583d6817c3672417d1..ea48449b2e63d1428de814d654ba58087dee436a 100644 (file)
@@ -50,11 +50,16 @@ void __init efi_bgrt_init(void)
                       bgrt_tab->version);
                return;
        }
-       if (bgrt_tab->status != 1) {
-               pr_err("Ignoring BGRT: invalid status %u (expected 1)\n",
+       if (bgrt_tab->status & 0xfe) {
+               pr_err("Ignoring BGRT: reserved status bits are non-zero %u\n",
                       bgrt_tab->status);
                return;
        }
+       if (bgrt_tab->status != 1) {
+               pr_debug("Ignoring BGRT: invalid status %u (expected 1)\n",
+                        bgrt_tab->status);
+               return;
+       }
        if (bgrt_tab->image_type != 0) {
                pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n",
                       bgrt_tab->image_type);
index 6a28ded74211145a74bfe677f9619f2d2fb676ae..ad285404ea7f58ac74e998d5658a8c72a9be019d 100644 (file)
@@ -194,7 +194,7 @@ static void __init do_add_efi_memmap(void)
 int __init efi_memblock_x86_reserve_range(void)
 {
        struct efi_info *e = &boot_params.efi_info;
-       unsigned long pmap;
+       phys_addr_t pmap;
 
        if (efi_enabled(EFI_PARAVIRT))
                return 0;
@@ -209,7 +209,7 @@ int __init efi_memblock_x86_reserve_range(void)
 #else
        pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32));
 #endif
-       memmap.phys_map         = (void *)pmap;
+       memmap.phys_map         = pmap;
        memmap.nr_map           = e->efi_memmap_size /
                                  e->efi_memdesc_size;
        memmap.desc_size        = e->efi_memdesc_size;
@@ -222,7 +222,7 @@ int __init efi_memblock_x86_reserve_range(void)
        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 @@ void __init efi_init(void)
                return;
 
        if (efi_enabled(EFI_DBG))
-               print_efi_memmap();
+               efi_print_memmap();
 
        efi_esrt_init();
 }
@@ -1017,24 +1017,6 @@ u32 efi_mem_type(unsigned long phys_addr)
        return 0;
 }
 
-u64 efi_mem_attributes(unsigned long phys_addr)
-{
-       efi_memory_desc_t *md;
-       void *p;
-
-       if (!efi_enabled(EFI_MEMMAP))
-               return 0;
-
-       for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-               md = p;
-               if ((md->phys_addr <= phys_addr) &&
-                   (phys_addr < (md->phys_addr +
-                                 (md->num_pages << EFI_PAGE_SHIFT))))
-                       return md->attribute;
-       }
-       return 0;
-}
-
 static int __init arch_parse_efi_cmdline(char *str)
 {
        if (!str) {
@@ -1044,8 +1026,6 @@ static int __init arch_parse_efi_cmdline(char *str)
 
        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;
 }
index 23981ac1c6c21a895de24f18117aa9c381cee19c..3dd9c462d22afd650b989399ac9c973afc983257 100644 (file)
@@ -157,11 +157,15 @@ static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn)
 
 static void __iomem *ghes_ioremap_pfn_irq(u64 pfn)
 {
-       unsigned long vaddr;
+       unsigned long vaddr, paddr;
+       pgprot_t prot;
 
        vaddr = (unsigned long)GHES_IOREMAP_IRQ_PAGE(ghes_ioremap_area->addr);
-       ioremap_page_range(vaddr, vaddr + PAGE_SIZE,
-                          pfn << PAGE_SHIFT, PAGE_KERNEL);
+
+       paddr = pfn << PAGE_SHIFT;
+       prot = arch_apei_get_mem_attribute(paddr);
+
+       ioremap_page_range(vaddr, vaddr + PAGE_SIZE, paddr, prot);
 
        return (void __iomem *)vaddr;
 }
index 84533e02fbf8ba292cddf960fde5881e1898821c..e1670d533f9742e94b505ba0684d9373956c8bb0 100644 (file)
@@ -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
index 6fd3da938717c27c233af9c6b66b186f69fc93fa..c24f00569acb3b92c5e0a3a91cc04f257336f96f 100644 (file)
@@ -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
index e992abc5ef264e38fefb0b3361f91c357fd1d08e..c8d794c5847989e1d150b8da968e76a24c6e0d91 100644 (file)
@@ -400,3 +400,4 @@ module_exit(efivars_pstore_exit);
 
 MODULE_DESCRIPTION("EFI variable backend for pstore");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:efivars");
index d6144e3b97c54235ca45a0ad71872957a36ffe48..027ca212179f7f81276733d0bda6b97a636c6770 100644 (file)
 #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;
 
@@ -250,7 +254,7 @@ subsys_initcall(efisubsys_init);
 int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
 {
        struct efi_memory_map *map = efi.memmap;
-       void *p, *e;
+       phys_addr_t p, e;
 
        if (!efi_enabled(EFI_MEMMAP)) {
                pr_err_once("EFI_MEMMAP is not enabled.\n");
@@ -282,10 +286,10 @@ int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
                 * So just always get our own virtual map on the CPU.
                 *
                 */
-               md = early_memremap((phys_addr_t)p, sizeof (*md));
+               md = early_memremap(p, sizeof (*md));
                if (!md) {
-                       pr_err_once("early_memremap(%p, %zu) failed.\n",
-                                   p, sizeof (*md));
+                       pr_err_once("early_memremap(%pa, %zu) failed.\n",
+                                   &p, sizeof (*md));
                        return -ENOMEM;
                }
 
@@ -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;
 
@@ -588,16 +609,19 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
 
        attr = md->attribute;
        if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
-                    EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP |
-                    EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME))
+                    EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
+                    EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
+                    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|%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"  : "",
+                        attr & EFI_MEMORY_RO      ? "RO"  : "",
                         attr & EFI_MEMORY_UCE     ? "UCE" : "",
                         attr & EFI_MEMORY_WB      ? "WB"  : "",
                         attr & EFI_MEMORY_WT      ? "WT"  : "",
@@ -605,3 +629,36 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
                         attr & EFI_MEMORY_UC      ? "UC"  : "");
        return buf;
 }
+
+/*
+ * efi_mem_attributes - lookup memmap attributes for physical address
+ * @phys_addr: the physical address to lookup
+ *
+ * Search in the EFI memory map for the region covering
+ * @phys_addr. Returns the EFI memory attributes if the region
+ * was found in the memory map, 0 otherwise.
+ *
+ * Despite being marked __weak, most architectures should *not*
+ * override this function. It is __weak solely for the benefit
+ * of ia64 which has a funky EFI memory map that doesn't work
+ * the same way as other architectures.
+ */
+u64 __weak efi_mem_attributes(unsigned long phys_addr)
+{
+       struct efi_memory_map *map;
+       efi_memory_desc_t *md;
+       void *p;
+
+       if (!efi_enabled(EFI_MEMMAP))
+               return 0;
+
+       map = efi.memmap;
+       for (p = map->map; p < map->map_end; p += map->desc_size) {
+               md = p;
+               if ((md->phys_addr <= phys_addr) &&
+                   (phys_addr < (md->phys_addr +
+                   (md->num_pages << EFI_PAGE_SHIFT))))
+                       return md->attribute;
+       }
+       return 0;
+}
index a5b95d61ae71efe1252978406ceb4b6bb922eb46..22c5285f77050f27d2d96a22b5ade945bae54316 100644 (file)
@@ -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 <pjones@redhat.com>");
 MODULE_DESCRIPTION("EFI System Resource Table support");
 MODULE_LICENSE("GPL");
+*/
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
new file mode 100644 (file)
index 0000000..ed3a854
--- /dev/null
@@ -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;
+       phys_addr_t 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 = 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);
index 4bfff349b1fbb56f0b99e206f21fc2986ad4db0d..95d293b7445a83473bc2131cf657f5de14ef52b3 100644 (file)
@@ -114,6 +114,20 @@ static int efifb_setup(char *options)
        return 0;
 }
 
+static inline bool fb_base_is_valid(void)
+{
+       if (screen_info.lfb_base)
+               return true;
+
+       if (!(screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE))
+               return false;
+
+       if (screen_info.ext_lfb_base)
+               return true;
+
+       return false;
+}
+
 static int efifb_probe(struct platform_device *dev)
 {
        struct fb_info *info;
@@ -141,7 +155,7 @@ static int efifb_probe(struct platform_device *dev)
                screen_info.lfb_depth = 32;
        if (!screen_info.pages)
                screen_info.pages = 1;
-       if (!screen_info.lfb_base) {
+       if (!fb_base_is_valid()) {
                printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
                return -ENODEV;
        }
@@ -160,6 +174,14 @@ static int efifb_probe(struct platform_device *dev)
        }
 
        efifb_fix.smem_start = screen_info.lfb_base;
+
+       if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
+               u64 ext_lfb_base;
+
+               ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
+               efifb_fix.smem_start |= ext_lfb_base;
+       }
+
        efifb_defined.bits_per_pixel = screen_info.lfb_depth;
        efifb_defined.xres = screen_info.lfb_width;
        efifb_defined.yres = screen_info.lfb_height;
index 85ef051ac6fb43a64c38779c6bf754d2e492abcf..569b5a866bb1e6308bbc4c0a28a2da92d106d6b5 100644 (file)
@@ -99,6 +99,7 @@ typedef       struct {
 #define EFI_MEMORY_XP          ((u64)0x0000000000004000ULL)    /* execute-protect */
 #define EFI_MEMORY_MORE_RELIABLE \
                                ((u64)0x0000000000010000ULL)    /* higher reliability */
+#define EFI_MEMORY_RO          ((u64)0x0000000000020000ULL)    /* read-only */
 #define EFI_MEMORY_RUNTIME     ((u64)0x8000000000000000ULL)    /* range requires runtime mapping */
 #define EFI_MEMORY_DESCRIPTOR_VERSION  1
 
@@ -595,6 +596,9 @@ void efi_native_runtime_setup(void);
 #define DEVICE_TREE_GUID \
     EFI_GUID(  0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 )
 
+#define EFI_PROPERTIES_TABLE_GUID \
+    EFI_GUID(  0x880aaca3, 0x4adc, 0x4a04, 0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5 )
+
 typedef struct {
        efi_guid_t guid;
        u64 table;
@@ -676,7 +680,7 @@ typedef struct {
 } efi_system_table_t;
 
 struct efi_memory_map {
-       void *phys_map;
+       phys_addr_t phys_map;
        void *map;
        void *map_end;
        int nr_map;
@@ -808,6 +812,15 @@ typedef struct _efi_file_io_interface {
 #define EFI_FILE_MODE_WRITE    0x0000000000000002
 #define EFI_FILE_MODE_CREATE   0x8000000000000000
 
+typedef struct {
+       u32 version;
+       u32 length;
+       u64 memory_protection_attribute;
+} efi_properties_table_t;
+
+#define EFI_PROPERTIES_TABLE_VERSION   0x00010000
+#define EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA        0x1
+
 #define EFI_INVALID_TABLE_ADDR         (~0UL)
 
 /*
@@ -830,6 +843,7 @@ extern struct efi {
        unsigned long runtime;          /* runtime table */
        unsigned long config_table;     /* config tables */
        unsigned long esrt;             /* ESRT table */
+       unsigned long properties_table; /* properties table */
        efi_get_time_t *get_time;
        efi_set_time_t *set_time;
        efi_get_wakeup_time_t *get_wakeup_time;
@@ -901,13 +915,19 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource,
                struct resource *data_resource, struct resource *bss_resource);
 extern void efi_get_time(struct timespec *now);
 extern void efi_reserve_boot_services(void);
-extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
+extern int efi_get_fdt_params(struct efi_fdt_params *params);
 extern struct efi_memory_map memmap;
 extern struct kobject *efi_kobj;
 
 extern int efi_reboot_quirk_mode;
 extern bool efi_poweroff_required(void);
 
+#ifdef CONFIG_EFI_FAKE_MEMMAP
+extern void __init efi_fake_memmap(void);
+#else
+static inline void efi_fake_memmap(void) { }
+#endif
+
 /* Iterate through an efi_memory_map */
 #define for_each_efi_memory_desc(m, md)                                           \
        for ((md) = (m)->map;                                              \
@@ -959,6 +979,7 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_PARAVIRT           6       /* Access is via a paravirt interface */
 #define EFI_ARCH_1             7       /* First arch-specific bit */
 #define EFI_DBG                        8       /* Print additional debug info at runtime */
+#define EFI_NX_PE_DATA         9       /* Can runtime data regions be mapped non-executable? */
 
 #ifdef CONFIG_EFI
 /*
index 7530e7447620ef8e4a1fee697c016e84da52cf0f..8b8d39dfb67f1992bc8e9fa95af34c8c4f05eb3a 100644 (file)
@@ -43,7 +43,8 @@ struct screen_info {
        __u16 pages;            /* 0x32 */
        __u16 vesa_attributes;  /* 0x34 */
        __u32 capabilities;     /* 0x36 */
-       __u8  _reserved[6];     /* 0x3a */
+       __u32 ext_lfb_base;     /* 0x3a */
+       __u8  _reserved[2];     /* 0x3e */
 } __attribute__((packed));
 
 #define VIDEO_TYPE_MDA         0x10    /* Monochrome Text Display      */
@@ -69,6 +70,6 @@ struct screen_info {
 #define VIDEO_FLAGS_NOCURSOR   (1 << 0) /* The video mode has no cursor set */
 
 #define VIDEO_CAPABILITY_SKIP_QUIRKS   (1 << 0)
-
+#define VIDEO_CAPABILITY_64BIT_BASE    (1 << 1)        /* Frame buffer base is 64-bit */
 
 #endif /* _UAPI_SCREEN_INFO_H */