From patchwork Thu Oct 24 16:25:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mostafa Saleh X-Patchwork-Id: 13849395 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BBCF5CE8E92 for ; Thu, 24 Oct 2024 16:31:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:Cc:To:From:Subject:Message-ID:References:Mime-Version: In-Reply-To:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=guhxqgoLzafkK+NdizG3et2iwgEsPQIVl8nGkP9yeqs=; b=sHOEdkLuArFYAtvndmx53mnyBu UycwP2oWXu4gYymqCn09peO7zufm2dpBh5jaQOXOFYXPxVq6+t2k2oOf9PTZfR1Ym0JiTMlYbFd7F w8GhpwoBfhOBNYm+Y9sMHk+uVfRcC7PEl3cefH8Zsm7iELnT13uL/tcpusf0qo3ZuYQjzisAmx/09 3r4F9FiWqJodVxH6JMIPdLe1+8Fwmnnhmpzm5qakGgD06hU636gpWbq+fAudsvUmWBbdlzR5hq4AP z9UaT88uvXcR0ZU4YZpEGYYQo99ngZKkVEPpTYiPn5RGa79ZqXA2OmkU7TydNii2LdTT3uTMmd7FN p2l9QESQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1t40ju-000000016Ep-1L30; Thu, 24 Oct 2024 16:31:10 +0000 Received: from mail-wm1-x349.google.com ([2a00:1450:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1t40eZ-000000015AP-0XUI for linux-arm-kernel@lists.infradead.org; Thu, 24 Oct 2024 16:25:40 +0000 Received: by mail-wm1-x349.google.com with SMTP id 5b1f17b1804b1-4315d98a873so8077625e9.1 for ; Thu, 24 Oct 2024 09:25:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1729787137; x=1730391937; darn=lists.infradead.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=guhxqgoLzafkK+NdizG3et2iwgEsPQIVl8nGkP9yeqs=; b=0hjf1ihjUFhDh7vtCS6+x7qBPWyZ1YArq+JFvK9plWwSeUxxn0PLuYfToWRvPKlOtS 4Uk0zrzFS3H5hJt6zT0kMV8uCK50UXfcwthv3OTRHQyjKajhS/SAJVKLJzgJuD2AJf7Z cvItF2p0bejEFWRtbYGLMPyp9vbMeI9qLA5/gumWXe9Bip+0pitEUAEfHPjPm75bOlC6 Gh3CmHm4K+/Cm8EakPCdSsL3A2YK6+y1dSkzGkfn/qiiE96R3O9kMwV/yEldnRWWaqTH uAvJR7N57CFHBmMNzWjf+m3uU3cHL6Qgdp1NQqUgRPM49uplfGel0QclKK5t/t9Xxuof fUYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729787137; x=1730391937; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=guhxqgoLzafkK+NdizG3et2iwgEsPQIVl8nGkP9yeqs=; b=he5JBXtXNBsSOTyHn8sX4UOg0IGmwkQtxDY31imApUa53h40SOpvozkeTxiyhJ47gq dGlwWDbPajXam2ubFzRtENx1qeWHjxgWEH0TitP4JiBTJ9s01PyHqqPYBWvVbA8eyELe nmsQ//Ry1Ipvl4XESKrnj034Dmu98o5TsWIib82E+xOeuTIKfvnNS63+bpUGfl20dcb1 MJxqxs+p4NaLDgpba0mL/gVu8c4kZccITz3+JM3kBE9Vu5sTlFGQE+MZAmQCJzE6WKYU 0IaVUJMHxOwHORFx0ycu97FZ59k6nzxDNOQfuNKCZWtEFnzwnz2zPIsO71eFkIyNYSgo yCpg== X-Forwarded-Encrypted: i=1; AJvYcCWRcozIuD8c46iyr0z1DadFjh9WSkVbWNDDLPkdlDJ6/8ycgeQCFySswxRPFBLezC7klZTsTHAgTqIRQP15lVYt@lists.infradead.org X-Gm-Message-State: AOJu0YykJHfuWtptiltzhoFu0M1DzmwyhVCFR9e4Imzxew6l3UO0l+mU j218Tb8uOPtXJlt09ETrBF4om3D12MgpneRyPL0WCOrgudTbpNvjs1eZtKq2RCxneMj9dAUhEed YP78yBQhmgg== X-Google-Smtp-Source: AGHT+IErwzIVqMN+PjdLzUqLsxxxqsZOGGGMsnJi1kecA66UnaTLfYW8QeE2ETnjOUdJ0m1UCN25TK06TL0pAg== X-Received: from mostafa.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:333c]) (user=smostafa job=sendgmr) by 2002:a7b:cb52:0:b0:430:5759:867e with SMTP id 5b1f17b1804b1-4318c76eba5mr266065e9.7.1729787137481; Thu, 24 Oct 2024 09:25:37 -0700 (PDT) Date: Thu, 24 Oct 2024 16:25:15 +0000 In-Reply-To: <20241024162516.2005652-1-smostafa@google.com> Mime-Version: 1.0 References: <20241024162516.2005652-1-smostafa@google.com> X-Mailer: git-send-email 2.47.0.105.g07ac214952-goog Message-ID: <20241024162516.2005652-2-smostafa@google.com> Subject: [PATCH 1/2] iommu/io-pgtable-arm: Fix stage-2 map/umap for concatenated tables From: Mostafa Saleh To: linux-kernel@vger.kernel.org, iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: will@kernel.org, robin.murphy@arm.com, joro@8bytes.org, Mostafa Saleh X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241024_092539_191095_31C8BE8D X-CRM114-Status: GOOD ( 15.42 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org When calculating the max number of entries in a table, Where RM_LPAE_LVL_IDX() understands the concatenated pgds and can return an index spanning more than one concatenated table (for ex for 4K page size > 512). But then, max_entries is calculated as follows: max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start; This leads to a negative index in the page table, where for: - map: do nothing (no OOB) as fortunately all comparisons are signed, but it would return a negative mapped value. - unmap: it would leak any child tables as it skips the loop over “__arm_lpae_free_pgtable” This bug only happens when map/unmap is requested with a page size equals to the first level of the concatenated table (for 40 bits input and 4K granule would be 1GB) and can be triggered from userspace with VFIO, by choosing a VM IPA in a concatenated table > 0 and using huge pages to mmap with the first level size. For example, I was able to reproduce it with the following command with mainline linux and mainline kvmtool: ./lkvm run --irqchip gicv3 -k {$KERNEL} -p "earlycon" -d {$ROOTFS} --force-pci -c \ `nproc` --debug -m 4096@525312 --vfio-pci 0000:00:03.0 --hugetlbfs /hugepages Where huge pages with 1GB would be used and using IPA in the second table (512GB for 40 bits SMMU and 4K granule). Signed-off-by: Mostafa Saleh --- drivers/iommu/io-pgtable-arm.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 0e67f1721a3d..3ecbc024e440 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -199,6 +199,17 @@ static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte, return (paddr | (paddr << (48 - 12))) & (ARM_LPAE_PTE_ADDR_MASK << 4); } +/* + * Using an index returned from ARM_LPAE_PGD_IDX(), which can point to + * concatenated PGD concatenated, get the max entries of a that table. + */ +static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data) +{ + int ptes_per_table = ARM_LPAE_PTES_PER_TABLE(data); + + return ptes_per_table - (i & (ptes_per_table - 1)); +} + static bool selftest_running = false; static dma_addr_t __arm_lpae_dma_addr(void *pages) @@ -390,7 +401,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, /* If we can install a leaf entry at this level, then do so */ if (size == block_size) { - max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start; + max_entries = arm_lpae_max_entries(map_idx_start, data); num_entries = min_t(int, pgcount, max_entries); ret = arm_lpae_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep); if (!ret) @@ -592,7 +603,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, if (size == split_sz) { unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data); - max_entries = ptes_per_table - unmap_idx_start; + max_entries = arm_lpae_max_entries(unmap_idx_start, data); num_entries = min_t(int, pgcount, max_entries); } @@ -650,7 +661,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data, /* If the size matches this level, we're in the right place */ if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) { - max_entries = ARM_LPAE_PTES_PER_TABLE(data) - unmap_idx_start; + max_entries = arm_lpae_max_entries(unmap_idx_start, data); num_entries = min_t(int, pgcount, max_entries); /* Find and handle non-leaf entries */ From patchwork Thu Oct 24 16:25:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mostafa Saleh X-Patchwork-Id: 13849396 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D0C2DCE8E92 for ; Thu, 24 Oct 2024 16:33:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=UsCpK9EL3WBrTQl/LxYwj8dMuww/QQmOZNLTkcqzgvw=; b=23FiRNn+uEW//eqYcJ/Lhc170j A25Pa7eeX04L7TgXz+tUjdGeTtnJMyKIXVtHDrp9iUmppJQkCHQ4XkTR1sXKgME2A94ZQqYgFVRXy cLSv7doF8JmthdsTLmQQHztPkua1h2K0lZRh0MAxB7vS4OfwANqnGp+BmnuyKmMBUbcUxNSCrEM3N dz/PnX9ioJObJHfu53+8VP2gtBZ/V+nsdzER872hTsjX1f59MggZOHyMn5FMReFbqZ8GqMyJ48gfw v3tKywJ+knlAvGidxRbKkaqi0dLHdPfF1LAIzs6Oc9BmUUy2Zrhi3rVMSAuVTOdjaE52p1Q5INgjP KkkSju1w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1t40m3-000000016g6-2Yef; Thu, 24 Oct 2024 16:33:23 +0000 Received: from mail-wm1-x34a.google.com ([2a00:1450:4864:20::34a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1t40ee-000000015CQ-1OzZ for linux-arm-kernel@lists.infradead.org; Thu, 24 Oct 2024 16:25:45 +0000 Received: by mail-wm1-x34a.google.com with SMTP id 5b1f17b1804b1-43159c07193so11276865e9.0 for ; Thu, 24 Oct 2024 09:25:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1729787142; x=1730391942; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=UsCpK9EL3WBrTQl/LxYwj8dMuww/QQmOZNLTkcqzgvw=; b=MXhgbB6PEIXCh4ZU7k8LCyCrdhx3m0HodS2f12Yd6MyuRRk5tej3SQ+7JBpC30h5sD /V3wALi4C3re36NskgaRF3AwYRhOA1OzlYnRPmGILapJkglRSpuVsuKfgnYZ8/6dqZOW iYgU21fZGWuGm3suMNI3nUSNJ9JmkknHutAf2aB4hxFxmffEFvGr00fwCOnAS0SVITo4 9s8D46QWeRBfxvgTD9Ryt1nVRS4alNDhm5XF5qDnRx9gysy9P38vmkpnHdEl3TIndEl6 ljPY57zVM/PtYZf/Chl3PxT0j8D6urVhQbbzwdqDs4IyVfV2fM+LzVYugiNm0zRw4ccg 8rBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729787142; x=1730391942; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=UsCpK9EL3WBrTQl/LxYwj8dMuww/QQmOZNLTkcqzgvw=; b=BO/3ygNa1II4uBGGPtOIcYSu8uvwPdD2prKNwH9lXku1731PA8HnLc0xmmyrXmKipa m9OrAOz4RECWWRESXzReRzlGHUXWO7i1Xb4iNxTj2pBrNJ4HrGQseakjsKmlRTkBWa3w J05ZcvDMW6hzhGYBLuh7e8gaOCwWmSww5VI16flsU7edmzmG0PBMvsSjB4UYVBnZCHEB gFcb2MNaW58f31tebZ+lPQcHW6oOxVMWv9YRdombBcMri3CydiMiqQcVrsy1ejB+RSjB bz5/zK3ADobc40dlXoPFqJX22466ZttvlAATJLFPXdSydm4N0RrgL0trRPS1TiPdeFNL KpCg== X-Forwarded-Encrypted: i=1; AJvYcCUGe8pfZC8R+zUQTmsFrdK3kft7M5iD1GF7b4ITrSaCWJikATGU7ux0oic9iCQBjcNx2OmoYwN+NnFe5xP8Sru/@lists.infradead.org X-Gm-Message-State: AOJu0YzvZQMGv1/n2lKmuayfWFFfyEdIyg6Dche+K931KMW77Ug51aU2 KGdlfm1aAljZctS5TCMgrHh6X6c5y/vrA5L546hKtXuba/0C0IvuhJvRMItUde2m3aYd5uIZYek iBH2a8DKGPQ== X-Google-Smtp-Source: AGHT+IG9pePnfv6Q2uIrCeDhwlQCCiK/QZZKTazhUEbVv0rozU2r0vhyS6+O/NBsXh3MroRlMS7z8qAoBEUUYg== X-Received: from mostafa.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:333c]) (user=smostafa job=sendgmr) by 2002:a05:600c:6b6c:b0:42c:a585:5ec3 with SMTP id 5b1f17b1804b1-4318c72bd26mr65625e9.4.1729787141740; Thu, 24 Oct 2024 09:25:41 -0700 (PDT) Date: Thu, 24 Oct 2024 16:25:16 +0000 In-Reply-To: <20241024162516.2005652-1-smostafa@google.com> Mime-Version: 1.0 References: <20241024162516.2005652-1-smostafa@google.com> X-Mailer: git-send-email 2.47.0.105.g07ac214952-goog Message-ID: <20241024162516.2005652-3-smostafa@google.com> Subject: [PATCH 2/2] iommu/io-pgtable-arm: Add self test for the last page in the IAS From: Mostafa Saleh To: linux-kernel@vger.kernel.org, iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: will@kernel.org, robin.murphy@arm.com, joro@8bytes.org, Mostafa Saleh X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241024_092544_403048_0D5A7E92 X-CRM114-Status: GOOD ( 13.18 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a case in the selftests that can detect some bugs with concatenated page tables, where it maps the biggest supported page size at the end of the IAS, this test would fail without the previous fix. Signed-off-by: Mostafa Saleh --- drivers/iommu/io-pgtable-arm.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 3ecbc024e440..71e8046671a4 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -1393,6 +1393,23 @@ static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg) iova += SZ_1G; } + /* + * Map/unmap the last largest supported page of the IAS, this can + * trigger corner cases in the concatednated page tables. + */ + mapped = 0; + size = 1UL << __fls(cfg->pgsize_bitmap); + iova = (1UL << cfg->ias) - size; + if (ops->map_pages(ops, iova, iova, size, 1, + IOMMU_READ | IOMMU_WRITE | + IOMMU_NOEXEC | IOMMU_CACHE, + GFP_KERNEL, &mapped)) + return __FAIL(ops, i); + if (mapped != size) + return __FAIL(ops, i); + if (ops->unmap_pages(ops, iova, size, 1, NULL) != size) + return __FAIL(ops, i); + free_io_pgtable_ops(ops); }