From patchwork Mon Nov 23 09:06:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 57125 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp1318728lbb; Mon, 23 Nov 2015 01:15:45 -0800 (PST) X-Received: by 10.68.237.5 with SMTP id uy5mr8190721pbc.8.1448270145450; Mon, 23 Nov 2015 01:15:45 -0800 (PST) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id dv5si18516429pbb.226.2015.11.23.01.15.45 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 23 Nov 2015 01:15:45 -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 1a0nCQ-0002H7-7j; Mon, 23 Nov 2015 09:14:14 +0000 Received: from mail-wm0-x22a.google.com ([2a00:1450:400c:c09::22a]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1a0n5s-0003IT-5P for linux-arm-kernel@lists.infradead.org; Mon, 23 Nov 2015 09:07:31 +0000 Received: by wmuu63 with SMTP id u63so44709792wmu.0 for ; Mon, 23 Nov 2015 01:07:06 -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=SmWre/Z5un0yH5LAXI0qnjKz0oKJJxrZ7sKvwsZ6VwQ=; b=ij7szwAz9FBCvdLljduq96PYy7m+SQ0MncoMcTo/0TcLrBXNO5FpgVqYhK2ntbL3A6 PD4Nyrf9PfJ53DA+R6w/Izffd0f+OE2n3HIx2DHfwImzGfqmC2jEjNUONAGd3IcMkXCc 21oAcPhCe+QAqKlSCKAtBQ1ncgqdxuNVYoPfQEpllu9Ptyz5FswDsA4/lzqjmvoZRApw +JMElyE1tsQfNfRiQegIOho8D/pxUHosPJudARrLCz9mV5h9MI3OLWDFx/v0htfWrhgq KmCNWWhwO4ENx/WJsntT4lG42T+4UUcpRmVSDQ2lChWiwown6SqalEL8OEt2wVXUbJh9 S5kg== 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=SmWre/Z5un0yH5LAXI0qnjKz0oKJJxrZ7sKvwsZ6VwQ=; b=FsPZA7MeO3ypItpG50/AOjnSMSb7W2ucIJgWKkcGoAayjVFrmGKQu1yHmc3mMJWm2K 4wo3iqs0oXyHvLFL1/ZHgUg5sY+1Ij3s9Qjw+OTijYQ6LCDrAnhHPkFwS3yJewji1zau VUFn3lPJHjiylnGxI+EPN44/zlk1kBfqKJyswWHUYQ5BdEalNCOaKIwel/eR9Z1jwwFF +5GPPYw76XGimbQjbqrtc5eQTd+xOXKYfXhAc+39bbXjTaIAJj6f/HDPpxoTDXwXYTs6 O7Y6TQgEuL/ta7m2NPPA254fcJuRf5HqTkorca4waAfchP83yR1FvIZxs6K/FHjoQ4cM ycIg== X-Gm-Message-State: ALoCoQlePfVtVTPfuSBa/YowtI/oZ4rBNK80mxoi64aVmpbjBm+uw05wSZs/3rGAgVk19jb0yzyt X-Received: by 10.28.35.66 with SMTP id j63mr18087327wmj.10.1448269626561; Mon, 23 Nov 2015 01:07:06 -0800 (PST) Received: from localhost.localdomain ([2.44.140.166]) by smtp.gmail.com with ESMTPSA id h189sm12241754wme.1.2015.11.23.01.07.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 23 Nov 2015 01:07:06 -0800 (PST) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, catalin.marinas@arm.com, will.deacon@arm.com, mark.rutland@arm.com, linux-efi@vger.kernel.org, leif.lindholm@linaro.org, matt@codeblueprint.co.uk Subject: [PATCH v3 05/13] arm64/efi: refactor EFI init and runtime code for reuse by 32-bit ARM Date: Mon, 23 Nov 2015 10:06:25 +0100 Message-Id: <1448269593-20758-6-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1448269593-20758-1-git-send-email-ard.biesheuvel@linaro.org> References: <1448269593-20758-1-git-send-email-ard.biesheuvel@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151123_010728_531409_7DFCC193 X-CRM114-Status: GOOD ( 19.07 ) 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:22a 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: kuleshovmail@gmail.com, Ard Biesheuvel , roy.franz@linaro.org, linux-mm@kvack.org, ryan.harkin@linaro.org, msalter@redhat.com, grant.likely@linaro.org, akpm@linux-foundation.org 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 | 9 ++++ arch/arm64/kernel/efi.c | 28 +++++++++++ drivers/firmware/efi/arm-init.c | 7 +-- drivers/firmware/efi/arm-runtime.c | 53 ++++++-------------- drivers/firmware/efi/efi.c | 2 + 5 files changed, 59 insertions(+), 40 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..8e88a696c9cb 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,11 @@ 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) +{ + switch_mm(NULL, mm, NULL); +} + 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..2bba918d6a2f 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -17,6 +17,34 @@ #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 | PTE_NG)); + 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 ffdd76a51929..9e15d571b53c 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 @@ -107,7 +108,7 @@ static int __init uefi_init(void) goto out; } 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 22b11752185e..c949f098d7da 100644 --- a/drivers/firmware/efi/arm-runtime.c +++ b/drivers/firmware/efi/arm-runtime.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -23,18 +24,14 @@ #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,40 +43,27 @@ static bool __init efi_virtmap_init(void) { efi_memory_desc_t *md; + efi_mm.pgd = pgd_alloc(&efi_mm); init_new_context(NULL, &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, - __pgprot(pgprot_val(prot) | PTE_NG)); + 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; } @@ -89,7 +73,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; @@ -136,12 +120,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) -{ - switch_mm(NULL, mm, NULL); -} +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,