From patchwork Mon Apr 25 20:06:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Fleming X-Patchwork-Id: 66607 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp1232959qge; Mon, 25 Apr 2016 13:07:49 -0700 (PDT) X-Received: by 10.66.118.70 with SMTP id kk6mr51581851pab.74.1461614868142; Mon, 25 Apr 2016 13:07:48 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id lc4si8617459pab.144.2016.04.25.13.07.47; Mon, 25 Apr 2016 13:07:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeblueprint-co-uk.20150623.gappssmtp.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964949AbcDYUHl (ORCPT + 29 others); Mon, 25 Apr 2016 16:07:41 -0400 Received: from mail-wm0-f43.google.com ([74.125.82.43]:38358 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964879AbcDYUHh (ORCPT ); Mon, 25 Apr 2016 16:07:37 -0400 Received: by mail-wm0-f43.google.com with SMTP id u206so145144012wme.1 for ; Mon, 25 Apr 2016 13:07:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeblueprint-co-uk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4/v5slKICJRYYaPYwi07pzGbSf72AQd0tw6mxt2CNME=; b=y83dHLV8sceLrS/8yCiBDF/r0DQPO3c0MZhzj+tEUuLS4B1+p4arv5NQwaNc8GV3eW 9IGkUfwbviZUNTN+iFDLKftn2SE4Sb4Afqr1ic7GlXAT2LVqIXEodyc9Dokc2ycP0I+k kqmva2T2MWdIckvWLvVulaATFaapIsymnC9KggEFeA9IZ+dWD3JEQXKo/MJzgszi0+Vf W67SLLqZwIecASArxrTjtkAxiS075YjG8XH8VpWrSQR2rE1Ea3pgqd3XUQzHyStO0gFq /GL0V7SaFTAD5GbDdI0RVJyfp9qGM/4zkj1wXZ9QvhoCONWWO5ULMvJrJt9Rb9h4sNnT y8Nw== 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=4/v5slKICJRYYaPYwi07pzGbSf72AQd0tw6mxt2CNME=; b=Tkes6waW8pWIIhkHu+e/xVsn1FTmZ7jKmLzMZWK1nBMSk6r90w/ZjqKHHso8kfYqRy EEvVoultjBGAmZf36psQVFGNFa3SXY98GCE0etGjJS3o2Iya0PBLHoAPHu/MYadPlaEO Uav17WILrACUlAiI2uqwZgzwwweSXx6HV6LgrccO0GPX98XdFefHOOCWDEYL0lwZtRJD MSEuSCtlJghOEjntX4ey8sOFb42nGVZTVBt1uavm69ZFi3779AjFNTaQJg+xUZyasQMc sVnGXyykPU0RZHMFEKzmgbX/8GZhC3+TqDayx3jFjCujHI6w5cMwRmyUAVKO79CgVNmD hCeg== X-Gm-Message-State: AOPr4FWTERPn2qaD6kk1qL5iiGiRyqjtrzcEiWiZqmdQ5i+mxK1FMNYFFXab7n5xHTBxuA== X-Received: by 10.28.91.17 with SMTP id p17mr13606026wmb.86.1461614855957; Mon, 25 Apr 2016 13:07:35 -0700 (PDT) Received: from localhost (bcdc58e5.skybroadband.com. [188.220.88.229]) by smtp.gmail.com with ESMTPSA id k139sm20323451wmg.24.2016.04.25.13.07.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Apr 2016 13:07:35 -0700 (PDT) From: Matt Fleming To: Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, Matt Fleming , Catalin Marinas , Leif Lindholm , Mark Rutland , Peter Jones , Sai Praneeth Prakhya , Will Deacon Subject: [PATCH 11/40] arm64: efi: Apply strict permissons for UEFI Runtime Services regions Date: Mon, 25 Apr 2016 21:06:43 +0100 Message-Id: <1461614832-17633-12-git-send-email-matt@codeblueprint.co.uk> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1461614832-17633-1-git-send-email-matt@codeblueprint.co.uk> References: <1461614832-17633-1-git-send-email-matt@codeblueprint.co.uk> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ard Biesheuvel Recent UEFI versions expose permission attributes for runtime services memory regions, either in the UEFI memory map or in the separate memory attributes table. This allows the kernel to map these regions with stricter permissions, rather than the RWX permissions that are used by default. So wire this up in our mapping routine. Note that in the absence of permission attributes, we still only map regions of type EFI_RUNTIME_SERVICE_CODE with the executable bit set. Also, we base the mapping attributes of EFI_MEMORY_MAPPED_IO on the type directly rather than on the absence of the EFI_MEMORY_WB attribute. This is more correct, but is also required for compatibility with the upcoming support for the Memory Attributes Table, which only carries permission attributes, not memory type attributes. Signed-off-by: Ard Biesheuvel Cc: Mark Rutland Cc: Catalin Marinas Cc: Will Deacon Cc: Leif Lindholm Cc: Peter Jones Cc: Sai Praneeth Prakhya Signed-off-by: Matt Fleming --- arch/arm64/kernel/efi.c | 54 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 14 deletions(-) -- 2.7.3 diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index b6abc852f2a1..33a6da160a50 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -17,22 +17,48 @@ #include -int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) +/* + * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be + * executable, everything else can be mapped with the XN bits + * set. Also take the new (optional) RO/XP bits into account. + */ +static __init pteval_t create_mapping_protection(efi_memory_desc_t *md) { - pteval_t prot_val; + u64 attr = md->attribute; + u32 type = md->type; - /* - * 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); + if (type == EFI_MEMORY_MAPPED_IO) + return PROT_DEVICE_nGnRE; + + if (WARN_ONCE(!PAGE_ALIGNED(md->phys_addr), + "UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?")) + /* + * If the region is not aligned to the page size of the OS, we + * can not use strict permissions, since that would also affect + * the mapping attributes of the adjacent regions. + */ + return pgprot_val(PAGE_KERNEL_EXEC); + + /* R-- */ + if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) == + (EFI_MEMORY_XP | EFI_MEMORY_RO)) + return pgprot_val(PAGE_KERNEL_RO); + + /* R-X */ + if (attr & EFI_MEMORY_RO) + return pgprot_val(PAGE_KERNEL_ROX); + + /* RW- */ + if (attr & EFI_MEMORY_XP || type != EFI_RUNTIME_SERVICES_CODE) + return pgprot_val(PAGE_KERNEL); + + /* RWX */ + return pgprot_val(PAGE_KERNEL_EXEC); +} + +int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) +{ + pteval_t prot_val = create_mapping_protection(md); create_pgd_mapping(mm, md->phys_addr, md->virt_addr, md->num_pages << EFI_PAGE_SHIFT,