From patchwork Mon Sep 11 19:02:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Jernej_=C5=A0krabec?= X-Patchwork-Id: 13379593 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 D67F0C71153 for ; Mon, 11 Sep 2023 19:02:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=YePsY4mn4slit5YXdhl+rDuYCiY9+N66vwXMSKiAe/U=; b=dWFa3I9AA4Ga+o yxbWA8cLMmatigmnKC3cxrVwXSNnlzTiDYyr9BesYI+ROh69Cy4OcUN0xc62PW5w4cNeN3qhSHbWE 0aRtfrk0YOxB+WCPJyxBI1AP91Vh17b79tMfdwNOq6y/QTL8uwY6LS6T/LNdc5hY80df0a86eGCs1 D7b7Y6brHexlQ9U06OYBxnu2idMWgryJGCoVDJIIgTbABfcMzPOUkKV5ua6Uo5uaWAkyCqQSLudkL SfPr/lyq4PupW1TTJJ7zssCdXcw1E2zIkAAQezFWV3hQL1Rz4v4971pt6x6PHDQzIr7lI737tseby AkP063Dc4Wk9ic4jK5VA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qfmB4-001ACj-09; Mon, 11 Sep 2023 19:02:30 +0000 Received: from mail-ej1-x62a.google.com ([2a00:1450:4864:20::62a]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qfmB1-001ACF-0w for linux-arm-kernel@lists.infradead.org; Mon, 11 Sep 2023 19:02:28 +0000 Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-99cce6f7de2so609695566b.3 for ; Mon, 11 Sep 2023 12:02:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694458945; x=1695063745; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=3y2BGukH6url/m3nyh3PLmZ/imBVQiEyAeDipRiBwe0=; b=IFJyhf4hV4OazdjETcYTCFe8BaiQsenoJoOvVFbtf8CwPSoEwqGo/POs705JvMWqVT Zc5ClWwlTTebwLhNGLkKXblUO/cmNqF1oQn6qRrwB5ch8JqGg4Nhsa9D07GdHgBoZnLB WbR55afGl4WgexXU67nssqdiCA1shHrOtrsMV1t9HG9MEGx/o95IzgbqAiUuoKf6+fNt BfkQSVCiY1Zxjmt2DOaIv0HIRRiGbqus+7Y28ApkX98Y87qG4HQEd1pxpIzsbLsedAHe blftQKbH7EdpwAjtpsJVSp5NtAqvZYvfiaqeJMFfkWZl6FC6gEdbO27B0+lcLFdV5A4m C3OA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694458945; x=1695063745; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=3y2BGukH6url/m3nyh3PLmZ/imBVQiEyAeDipRiBwe0=; b=fHUIiss8kle0aHNm1eKq4ukm2tb0rj23DhRTEJ/VQJ8Y2zuWW3GEKy4Rjv+ZhM1h0E y3TNErab/lOp8es8TehtR1nz8neCBvz6Z1XhFbfJc6yAsVy0Ts/TnwFprVDsm5U/BvoW fS9Vr0fvzpzZWzTJnFK3PLAk/gHdg5WiDq/u6te32moXO+tAAhc84Lqe7sTzILJd5tNd jiXLvwRBu10LzuZUtMUIW1FW4suhFe3wNVAycRS9UmgqdgQ1m1UTL3FR8++mI26lyHog ESrIwjrBkOS/z5xvjqKa1qqRyWcUb8Osu9UYC93p9lFllT0Yn0KFd9w4xwF6USopEOUd /Kfg== X-Gm-Message-State: AOJu0YyVB4m0rDkVD2RYhp2THevF/XuGfVI++dgxAIwAzT5Mny1r8FQ2 c6c3DGIMnX2JeH/wZBaB73w= X-Google-Smtp-Source: AGHT+IFpgox4BFKnt0rNPbRceB2bQ3Z76YQCI6/Tvh13dhWuZo0yy8xGtqPL7TTMQCkN8A9GyXFFKg== X-Received: by 2002:a17:906:2189:b0:99b:de31:6666 with SMTP id 9-20020a170906218900b0099bde316666mr8837593eju.22.1694458945409; Mon, 11 Sep 2023 12:02:25 -0700 (PDT) Received: from localhost.localdomain (82-149-12-148.dynamic.telemach.net. [82.149.12.148]) by smtp.gmail.com with ESMTPSA id re1-20020a170906d8c100b00993a37aebc5sm5697324ejb.50.2023.09.11.12.02.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Sep 2023 12:02:25 -0700 (PDT) From: Jernej Skrabec To: joro@8bytes.org, will@kernel.org, robin.murphy@arm.com Cc: wens@csie.org, samuel@sholland.org, iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, Jernej Skrabec Subject: [PATCH] iommu/sun50i: Allow page sizes between 4K and 1M Date: Mon, 11 Sep 2023 21:02:18 +0200 Message-ID: <20230911190218.1758812-1-jernej.skrabec@gmail.com> X-Mailer: git-send-email 2.42.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230911_120227_347740_DD75DF97 X-CRM114-Status: GOOD ( 19.17 ) 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 While peripheral supports only 4K page sizes, we can easily emulate support for bigger page sizes, up to 1M. This is done by making multiple entries in map function or clearing multiple entries in unmap. Signed-off-by: Jernej Skrabec --- drivers/iommu/sun50i-iommu.c | 49 +++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c index 74c5cb93e900..93077575d60f 100644 --- a/drivers/iommu/sun50i-iommu.c +++ b/drivers/iommu/sun50i-iommu.c @@ -95,6 +95,10 @@ #define SPAGE_SIZE 4096 +#define SUN50I_IOMMU_PGSIZES (SZ_4K | SZ_8K | SZ_16K | SZ_32K | \ + SZ_64K | SZ_128K | SZ_256K | \ + SZ_512K | SZ_1M) + struct sun50i_iommu { struct iommu_device iommu; @@ -593,10 +597,12 @@ static int sun50i_iommu_map(struct iommu_domain *domain, unsigned long iova, { struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain); struct sun50i_iommu *iommu = sun50i_domain->iommu; - u32 pte_index; + u32 pte_index, pages, i; u32 *page_table, *pte_addr; int ret = 0; + pages = size / SPAGE_SIZE; + page_table = sun50i_dte_get_page_table(sun50i_domain, iova, gfp); if (IS_ERR(page_table)) { ret = PTR_ERR(page_table); @@ -604,18 +610,22 @@ static int sun50i_iommu_map(struct iommu_domain *domain, unsigned long iova, } pte_index = sun50i_iova_get_pte_index(iova); - pte_addr = &page_table[pte_index]; - if (unlikely(sun50i_pte_is_page_valid(*pte_addr))) { - phys_addr_t page_phys = sun50i_pte_get_page_address(*pte_addr); - dev_err(iommu->dev, - "iova %pad already mapped to %pa cannot remap to %pa prot: %#x\n", - &iova, &page_phys, &paddr, prot); - ret = -EBUSY; - goto out; + for (i = 0; i < pages; i++) { + pte_addr = &page_table[pte_index + i]; + if (unlikely(sun50i_pte_is_page_valid(*pte_addr))) { + phys_addr_t page_phys = sun50i_pte_get_page_address(*pte_addr); + + dev_err(iommu->dev, + "iova %pad already mapped to %pa cannot remap to %pa prot: %#x\n", + &iova, &page_phys, &paddr, prot); + ret = -EBUSY; + goto out; + } + *pte_addr = sun50i_mk_pte(paddr, prot); + paddr += SPAGE_SIZE; } - *pte_addr = sun50i_mk_pte(paddr, prot); - sun50i_table_flush(sun50i_domain, pte_addr, 1); + sun50i_table_flush(sun50i_domain, &page_table[pte_index], pages); out: return ret; @@ -626,8 +636,10 @@ static size_t sun50i_iommu_unmap(struct iommu_domain *domain, unsigned long iova { struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain); phys_addr_t pt_phys; + u32 dte, pages, i; u32 *pte_addr; - u32 dte; + + pages = size / SPAGE_SIZE; dte = sun50i_domain->dt[sun50i_iova_get_dte_index(iova)]; if (!sun50i_dte_is_pt_valid(dte)) @@ -636,13 +648,14 @@ static size_t sun50i_iommu_unmap(struct iommu_domain *domain, unsigned long iova pt_phys = sun50i_dte_get_pt_address(dte); pte_addr = (u32 *)phys_to_virt(pt_phys) + sun50i_iova_get_pte_index(iova); - if (!sun50i_pte_is_page_valid(*pte_addr)) - return 0; + for (i = 0; i < pages; i++) + if (!sun50i_pte_is_page_valid(pte_addr[i])) + return 0; - memset(pte_addr, 0, sizeof(*pte_addr)); - sun50i_table_flush(sun50i_domain, pte_addr, 1); + memset(pte_addr, 0, sizeof(*pte_addr) * pages); + sun50i_table_flush(sun50i_domain, pte_addr, pages); - return SZ_4K; + return size; } static phys_addr_t sun50i_iommu_iova_to_phys(struct iommu_domain *domain, @@ -827,7 +840,7 @@ static int sun50i_iommu_of_xlate(struct device *dev, } static const struct iommu_ops sun50i_iommu_ops = { - .pgsize_bitmap = SZ_4K, + .pgsize_bitmap = SUN50I_IOMMU_PGSIZES, .device_group = sun50i_iommu_device_group, .domain_alloc = sun50i_iommu_domain_alloc, .of_xlate = sun50i_iommu_of_xlate,