Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a3575fd authored by Huang, Ying's avatar Huang, Ying Committed by Ingo Molnar
Browse files

x86: EFI_PAGE_SHIFT fix



Make x86 EFI code works when EFI_PAGE_SHIFT != PAGE_SHIFT. The
memrage_efi_to_native() provided in this patch can be used on other
EFI platform such as IA64 too.

This patch has been tested on Intel x86_64 platform with EFI 64/32
firmware.

Signed-off-by: default avatarHuang Ying <ying.huang@intel.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent f8dfd5ed
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -383,6 +383,7 @@ static void __init runtime_code_page_mkexec(void)
{
	efi_memory_desc_t *md;
	void *p;
	u64 addr, npages;

	/* Make EFI runtime service code area executable */
	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
@@ -391,7 +392,10 @@ static void __init runtime_code_page_mkexec(void)
		if (md->type != EFI_RUNTIME_SERVICES_CODE)
			continue;

		set_memory_x(md->virt_addr, md->num_pages);
		addr = md->virt_addr;
		npages = md->num_pages;
		memrange_efi_to_native(&addr, &npages);
		set_memory_x(addr, npages);
	}
}

@@ -408,7 +412,7 @@ void __init efi_enter_virtual_mode(void)
	efi_memory_desc_t *md;
	efi_status_t status;
	unsigned long size;
	u64 end, systab;
	u64 end, systab, addr, npages;
	void *p, *va;

	efi.systab = NULL;
@@ -420,7 +424,7 @@ void __init efi_enter_virtual_mode(void)
		size = md->num_pages << EFI_PAGE_SHIFT;
		end = md->phys_addr + size;

		if ((end >> PAGE_SHIFT) <= max_pfn_mapped)
		if (PFN_UP(end) <= max_pfn_mapped)
			va = __va(md->phys_addr);
		else
			va = efi_ioremap(md->phys_addr, size);
@@ -433,8 +437,12 @@ void __init efi_enter_virtual_mode(void)
			continue;
		}

		if (!(md->attribute & EFI_MEMORY_WB))
			set_memory_uc(md->virt_addr, md->num_pages);
		if (!(md->attribute & EFI_MEMORY_WB)) {
			addr = md->virt_addr;
			npages = md->num_pages;
			memrange_efi_to_native(&addr, &npages);
			set_memory_uc(addr, npages);
		}

		systab = (u64) (unsigned long) efi_phys.systab;
		if (md->phys_addr <= systab && systab < end) {
+6 −6
Original line number Diff line number Diff line
@@ -105,14 +105,14 @@ void __init efi_reserve_bootmem(void)

void __iomem * __init efi_ioremap(unsigned long phys_addr, unsigned long size)
{
	static unsigned pages_mapped;
	static unsigned pages_mapped __initdata;
	unsigned i, pages;
	unsigned long offset;

	/* phys_addr and size must be page aligned */
	if ((phys_addr & ~PAGE_MASK) || (size & ~PAGE_MASK))
		return NULL;
	pages = PFN_UP(phys_addr + size) - PFN_DOWN(phys_addr);
	offset = phys_addr & ~PAGE_MASK;
	phys_addr &= PAGE_MASK;

	pages = size >> PAGE_SHIFT;
	if (pages_mapped + pages > MAX_EFI_IO_PAGES)
		return NULL;

@@ -124,5 +124,5 @@ void __iomem * __init efi_ioremap(unsigned long phys_addr, unsigned long size)
	}

	return (void __iomem *)__fix_to_virt(FIX_EFI_IO_MAP_FIRST_PAGE - \
					     (pages_mapped - pages));
					     (pages_mapped - pages)) + offset;
}
+7 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/proc_fs.h>
#include <linux/rtc.h>
#include <linux/ioport.h>
#include <linux/pfn.h>

#include <asm/page.h>
#include <asm/system.h>
@@ -394,4 +395,10 @@ struct efi_generic_dev_path {
	u16 length;
} __attribute ((packed));

static inline void memrange_efi_to_native(u64 *addr, u64 *npages)
{
	*npages = PFN_UP(*addr + (*npages<<EFI_PAGE_SHIFT)) - PFN_DOWN(*addr);
	*addr &= PAGE_MASK;
}

#endif /* _LINUX_EFI_H */