From patchwork Mon Aug 17 12:04:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 251753 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0F30C433E1 for ; Mon, 17 Aug 2020 12:04:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BE7802072E for ; Mon, 17 Aug 2020 12:04:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597665879; bh=6QoCSlJv7HkuQ6x9iDtVGVAgbwxMfnO85vY9IKlv7LI=; h=From:To:Cc:Subject:Date:List-ID:From; b=2eMi7M9rNpf1bvmxB3FYgmFvSeWfTTxx1PuXX86FStJMO5+QuEIuNuQGr1Rs9stP1 fthrXd9991DvTG8VWrn3mozgeYSaGS5Jo+Pf3bwr1KMcGxcXcEbRi6B7xKy5UN3oGX 8r5/SCbCWm/hjSXLNEodYfaGIUow5W8h/a4MRNl4= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726203AbgHQMEj (ORCPT ); Mon, 17 Aug 2020 08:04:39 -0400 Received: from mail.kernel.org ([198.145.29.99]:55338 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726457AbgHQMEh (ORCPT ); Mon, 17 Aug 2020 08:04:37 -0400 Received: from e123331-lin.nice.arm.com (ip-213-127-60-218.ip.prioritytelecom.net [213.127.60.218]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 0AC092067C; Mon, 17 Aug 2020 12:04:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597665876; bh=6QoCSlJv7HkuQ6x9iDtVGVAgbwxMfnO85vY9IKlv7LI=; h=From:To:Cc:Subject:Date:From; b=ggQScV1FjM1jxgw6fyAsXJtf35cyuhpfAB4Y7TT1PQUmChV+KFXsW6znBVRUICla3 UIAMMZL1vAh2dLNKJZ3os4V0YBTePI4HcyL73K75OAdpCS4FJ3Yrh4DU6nCmbrHgfE 2lQpU6Bd6tIirkxZWxNM/KBL1ozgFFGQVSyKwjEM= From: Ard Biesheuvel To: linux-acpi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, catalin.marinas@arm.com, will@kernel.org, lorenzo.pieralisi@arm.com, rjw@rjwysocki.net, lenb@kernel.org, Ard Biesheuvel Subject: [PATCH] ACPI: ioremap: avoid redundant rounding to OS page size Date: Mon, 17 Aug 2020 14:04:31 +0200 Message-Id: <20200817120431.32233-1-ardb@kernel.org> X-Mailer: git-send-email 2.17.1 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org The arm64 implementation of acpi_os_ioremap() was recently updated to tighten the checks around which parts of memory are permitted to be mapped by ACPI code, which generally only needs access to memory regions that are statically described by firmware, and any attempts to access memory that is in active use by the OS is generally a bug or a hacking attempt. This tightening is based on the EFI memory map, which describes all memory in the system. The AArch64 architecture permits page sizes of 16k and 64k in addition to the EFI default, which is 4k, which means that the EFI memory map may describe regions that cannot be mapped seamlessly if the OS page size is greater than 4k. This is usually not a problem, given that the EFI spec does not permit memory regions requiring different memory attributes to share a 64k page frame, and so the usual rounding to page size performed by ioremap() is sufficient to deal with this. However, this rounding does complicate our EFI memory map permission check, due to the loss of information that occurs when several small regions share a single 64k page frame (where rounding each of them will result in the same 64k single page region). However, due to the fact that the region check occurs *before* the call to ioremap() where the necessary rounding is performed, we can deal with this issue simply by removing the redundant rounding performed by acpi_os_map_iomem(), as it appears to be the only place where the arguments to a call to acpi_os_ioremap() are rounded up. So omit the rounding in the call, and instead, apply the necessary offset to the result of kmap(). Fixes: 1583052d111f ("arm64/acpi: disallow AML memory opregions to access kernel memory") Signed-off-by: Ard Biesheuvel --- drivers/acpi/osl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6ad8cb05f672..55dbdbbae3be 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -289,7 +289,8 @@ static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz) if (should_use_kmap(pfn)) { if (pg_sz > PAGE_SIZE) return NULL; - return (void __iomem __force *)kmap(pfn_to_page(pfn)); + pg_off &= ~PAGE_MASK; + return (void __iomem __force *)(kmap(pfn_to_page(pfn)) + pg_off); } else return acpi_os_ioremap(pg_off, pg_sz); } @@ -350,7 +351,7 @@ void __iomem __ref pg_off = round_down(phys, PAGE_SIZE); pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; - virt = acpi_map(pg_off, pg_sz); + virt = acpi_map(phys, size); if (!virt) { mutex_unlock(&acpi_ioremap_lock); kfree(map); @@ -358,7 +359,7 @@ void __iomem __ref } INIT_LIST_HEAD(&map->list); - map->virt = virt; + map->virt = (void *)((unsigned long)virt & PAGE_MASK); map->phys = pg_off; map->size = pg_sz; map->track.refcount = 1; @@ -367,7 +368,7 @@ void __iomem __ref out: mutex_unlock(&acpi_ioremap_lock); - return map->virt + (phys - map->phys); + return virt; } EXPORT_SYMBOL_GPL(acpi_os_map_iomem);