From patchwork Mon Nov 16 18:32:30 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 56674 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp1481952lbb; Mon, 16 Nov 2015 10:36:00 -0800 (PST) X-Received: by 10.68.57.137 with SMTP id i9mr56904471pbq.66.1447698960132; Mon, 16 Nov 2015 10:36:00 -0800 (PST) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id ia2si52133092pbb.85.2015.11.16.10.35.59 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Nov 2015 10:36:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) smtp.mailfrom=linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@linaro_org.20150623.gappssmtp.com Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZyObm-00007K-Hm; Mon, 16 Nov 2015 18:34:30 +0000 Received: from mail-wm0-x235.google.com ([2a00:1450:400c:c09::235]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZyOad-0007SU-A8 for linux-arm-kernel@lists.infradead.org; Mon, 16 Nov 2015 18:33:25 +0000 Received: by wmww144 with SMTP id w144so122751965wmw.1 for ; Mon, 16 Nov 2015 10:32:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2LvL6QI9y/e0yDvxOUx2SsiMk+fqDxuY73PuTWuIJs8=; b=ljhNstOeqUDM1ynxwmz5aBAU8K+gN7cIITgzPzLYt4SwouBsRDHS8mS6oRi21y5ylF 3c5VqLbxYZdQa8Qu6Kl2tEX0Z0Ax1dvMBLGW8Ui8XKmG30V524Wfp5uUGlLCT4WBf6+j vsmbfLcDmjljddE1nzOWhH6h05ANX9920JH2y20mTAfUAz4n8H4Wgcpz1jJPF0EuSX5L l3Mg8zncm+aFy3TIKCiNnz2iJ3CY9ONOW3NCs42HbisjqwmTSoKatZJmJwq4eCaQ0hSN 6en/hntIsf8a79/5UAxUR/p5l72wBZX0csQINSHBxYcdi+tDzp1+yVwu3clLn0lUgr3o vmoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=2LvL6QI9y/e0yDvxOUx2SsiMk+fqDxuY73PuTWuIJs8=; b=RveG3EUd43bnF5cApyMeFsb02u0bsSygs7lYg9v9a27o0lhiI0l9GSiro0XHFjjnkz 4jkR5dp9IRH2ggYrmdJg95lVW5NaguzPjwOJkYsbuGExjrDrA09C9ttVQ3lrKhR0VGc8 Mfp6MZOONiSbEQ5WOx96uUcdWhtrhE+cJfAl+PoZXYLWhj9PQFYficY21oFjEmZBYaGX vX/lVCow3lMeqeh7yD4JYXXC5CTCi08V5Xs2CncaeKam8a32gJ/HZgjYhjH2blBGly4b V6RHzAYCWlWB2dJLLzCXcAaKa2ksQdsyUBbcbJY2F8Hmr6JJF/y3uLMLnm6Mpyjef9Gd vzpA== X-Gm-Message-State: ALoCoQkRGqoDhBxslDZaIrVvAklRV7jiQdmz7RtXZR9Ie1Dgn/J6Km1tl9nOQ+SVYmB1vUayenBk X-Received: by 10.194.92.170 with SMTP id cn10mr42799689wjb.12.1447698777806; Mon, 16 Nov 2015 10:32:57 -0800 (PST) Received: from ards-macbook-pro.lan (2-237-3-18.ip236.fastwebnet.it. [2.237.3.18]) by smtp.gmail.com with ESMTPSA id he3sm35796779wjc.48.2015.11.16.10.32.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 16 Nov 2015 10:32:57 -0800 (PST) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, linux-efi@vger.kernel.org, matt.fleming@intel.com, linux@arm.linux.org.uk, will.deacon@arm.com, grant.likely@linaro.org, catalin.marinas@arm.com, mark.rutland@arm.com, leif.lindholm@linaro.org, roy.franz@linaro.org Subject: [PATCH v2 05/12] arm64/efi: refactor EFI init and runtime code for reuse by 32-bit ARM Date: Mon, 16 Nov 2015 19:32:30 +0100 Message-Id: <1447698757-8762-6-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1447698757-8762-1-git-send-email-ard.biesheuvel@linaro.org> References: <1447698757-8762-1-git-send-email-ard.biesheuvel@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151116_103319_901612_B270C448 X-CRM114-Status: GOOD ( 18.61 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [2a00:1450:400c:c09:0:0:0:235 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-mm@kvack.org, ryan.harkin@linaro.org, Ard Biesheuvel , akpm@linux-foundation.org, msalter@redhat.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org This refactors the EFI init and runtime code that will be shared between arm64 and ARM so that it can be built for both archs. Signed-off-by: Ard Biesheuvel --- arch/arm64/include/asm/efi.h | 16 ++++++ arch/arm64/kernel/efi.c | 27 +++++++++ drivers/firmware/efi/arm-init.c | 7 ++- drivers/firmware/efi/arm-runtime.c | 60 ++++++-------------- drivers/firmware/efi/efi.c | 2 + 5 files changed, 66 insertions(+), 46 deletions(-) -- 1.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index ef572206f1c3..1ae6f635dc2c 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -2,7 +2,9 @@ #define _ASM_EFI_H #include +#include #include +#include #ifdef CONFIG_EFI extern void efi_init(void); @@ -10,6 +12,8 @@ extern void efi_init(void); #define efi_init() #endif +int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); + #define efi_call_virt(f, ...) \ ({ \ efi_##f##_t *__f; \ @@ -63,6 +67,18 @@ extern void efi_init(void); * Services are enabled and the EFI_RUNTIME_SERVICES bit set. */ +static inline void efi_set_pgd(struct mm_struct *mm) +{ + if (mm == &init_mm) + cpu_set_reserved_ttbr0(); + else + cpu_switch_mm(mm->pgd, mm); + + flush_tlb_all(); + if (icache_is_aivivt()) + __flush_icache_all(); +} + void efi_virtmap_load(void); void efi_virtmap_unload(void); diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index bd3b2f5adf0c..1e62b5f036c1 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -17,6 +17,33 @@ #include +int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) +{ + u64 paddr, npages, size; + pteval_t prot_val; + + paddr = md->phys_addr; + npages = md->num_pages; + memrange_efi_to_native(&paddr, &npages); + size = npages << PAGE_SHIFT; + + /* + * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be + * executable, everything else can be mapped with the XN bits + * set. + */ + if ((md->attribute & EFI_MEMORY_WB) == 0) + prot_val = PROT_DEVICE_nGnRE; + else if (md->type == EFI_RUNTIME_SERVICES_CODE || + !PAGE_ALIGNED(md->phys_addr)) + prot_val = pgprot_val(PAGE_KERNEL_EXEC); + else + prot_val = pgprot_val(PAGE_KERNEL); + + create_pgd_mapping(mm, paddr, md->virt_addr, size, __pgprot(prot_val)); + return 0; +} + static int __init arm64_dmi_init(void) { /* diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 4653d789f10d..11de5cf210c4 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -57,7 +57,7 @@ static int __init uefi_init(void) { efi_char16_t *c16; void *config_tables; - u64 table_size; + size_t table_size; char vendor[100] = "unknown"; int i, retval; @@ -69,7 +69,8 @@ static int __init uefi_init(void) } set_bit(EFI_BOOT, &efi.flags); - set_bit(EFI_64BIT, &efi.flags); + if (IS_ENABLED(CONFIG_64BIT)) + set_bit(EFI_64BIT, &efi.flags); /* * Verify the EFI Table @@ -103,7 +104,7 @@ static int __init uefi_init(void) table_size); retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables, - sizeof(efi_config_table_64_t), NULL); + sizeof(efi_config_table_t), NULL); early_memunmap(config_tables, table_size); out: diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c index e62ee5df96ca..ad11ba6964f6 100644 --- a/drivers/firmware/efi/arm-runtime.c +++ b/drivers/firmware/efi/arm-runtime.c @@ -23,18 +23,15 @@ #include #include -#include -#include +#include #include +#include #include -static pgd_t efi_pgd[PTRS_PER_PGD] __page_aligned_bss; - extern u64 efi_system_table; static struct mm_struct efi_mm = { .mm_rb = RB_ROOT, - .pgd = efi_pgd, .mm_users = ATOMIC_INIT(2), .mm_count = ATOMIC_INIT(1), .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem), @@ -46,37 +43,26 @@ static bool __init efi_virtmap_init(void) { efi_memory_desc_t *md; + efi_mm.pgd = pgd_alloc(&efi_mm); + for_each_efi_memory_desc(&memmap, md) { - u64 paddr, npages, size; - pgprot_t prot; + phys_addr_t phys = (phys_addr_t)md->phys_addr; + int ret; if (!(md->attribute & EFI_MEMORY_RUNTIME)) continue; if (md->virt_addr == 0) return false; - paddr = md->phys_addr; - npages = md->num_pages; - memrange_efi_to_native(&paddr, &npages); - size = npages << PAGE_SHIFT; - - pr_info(" EFI remap 0x%016llx => %p\n", - md->phys_addr, (void *)md->virt_addr); - - /* - * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be - * executable, everything else can be mapped with the XN bits - * set. - */ - if ((md->attribute & EFI_MEMORY_WB) == 0) - prot = __pgprot(PROT_DEVICE_nGnRE); - else if (md->type == EFI_RUNTIME_SERVICES_CODE || - !PAGE_ALIGNED(md->phys_addr)) - prot = PAGE_KERNEL_EXEC; - else - prot = PAGE_KERNEL; - - create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size, prot); + ret = efi_create_mapping(&efi_mm, md); + if (!ret) { + pr_info(" EFI remap %pa => %p\n", + &phys, (void *)(unsigned long)md->virt_addr); + } else { + pr_warn(" EFI remap %pa: failed to create mapping (%d)\n", + &phys, ret); + return false; + } } return true; } @@ -86,7 +72,7 @@ static bool __init efi_virtmap_init(void) * non-early mapping of the UEFI system table and virtual mappings for all * EFI_MEMORY_RUNTIME regions. */ -static int __init arm64_enable_runtime_services(void) +static int __init arm_enable_runtime_services(void) { u64 mapsize; @@ -133,19 +119,7 @@ static int __init arm64_enable_runtime_services(void) return 0; } -early_initcall(arm64_enable_runtime_services); - -static void efi_set_pgd(struct mm_struct *mm) -{ - if (mm == &init_mm) - cpu_set_reserved_ttbr0(); - else - cpu_switch_mm(mm->pgd, mm); - - flush_tlb_all(); - if (icache_is_aivivt()) - __flush_icache_all(); -} +early_initcall(arm_enable_runtime_services); void efi_virtmap_load(void) { diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 027ca212179f..cffa89b3317b 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -25,6 +25,8 @@ #include #include +#include + struct efi __read_mostly efi = { .mps = EFI_INVALID_TABLE_ADDR, .acpi = EFI_INVALID_TABLE_ADDR,