From patchwork Wed Jul 26 15:10:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 9865263 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9136D60382 for ; Wed, 26 Jul 2017 15:12:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9859A27CAF for ; Wed, 26 Jul 2017 15:12:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8D287286A9; Wed, 26 Jul 2017 15:12:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.6 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EC38227CAF for ; Wed, 26 Jul 2017 15:12:42 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1daNxE-0008TB-LU; Wed, 26 Jul 2017 15:10:28 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1daNxD-0008SY-QZ for xen-devel@lists.xenproject.org; Wed, 26 Jul 2017 15:10:27 +0000 Received: from [85.158.139.211] by server-9.bemta-5.messagelabs.com id 35/49-01994-3E0B8795; Wed, 26 Jul 2017 15:10:27 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrNIsWRWlGSWpSXmKPExsVyMfS6i+6jDRW RBlcmi1l83zKZyYHR4/CHKywBjFGsmXlJ+RUJrBlv59kXdJtX9B+7z9bA+EO3i5GLQ0hgGqPE jObpTCAOi8BLFonLv7czgzgSAv2sEr8eT2HpYuQEcuIkmh93M0LYZRIXLs1kA7GFBJQkXu/cz AQxag6TxPuzrWBFbAIGEvvfPWEHsUWAiu6tmgxWxCzQwyjx8uAvZpCEsECCxIJHXWBFLAKqEt OWtwJt4+DgFXCSOD8tDmKZnMTNc53MIGFOAWeJ5x1KEHudJFY/X8g6gVFgASPDKkaN4tSistQ iXSMjvaSizPSMktzEzBxdQwNTvdzU4uLE9NScxKRiveT83E2MwMCqZ2Bg3MG4p93vEKMkB5OS KO8k04pIIb6k/JTKjMTijPii0pzU4kOMMhwcShK8QsBAFRIsSk1PrUjLzAGGOExagoNHSYT35 HqgNG9xQWJucWY6ROoUoyXHlSvrvjBxTDmwHUi+mvD/G5MQS15+XqqUOO8XkAYBkIaM0jy4cb A4vMQoKyXMy8jAwCDEU5BalJtZgir/ilGcg1FJmNcUZApPZl4J3NZXQAcxAR00Z0YpyEEliQg pqQbGqb/UxZsS1ilss7u0Q8dz/Zv+8ns1Iq/mGGziK59V/XTPsb08q05IfejzD3S8vSF/+7b3 h/rferC9qbTPOfWd8Xv+1yKXItsPnJMKvpTeFE1609oby2nSbTS3ruxJsivvOU2uWMGji7rLD XW3v+41XLCrq8NQ5PfrGTbOtwK1HX74VF/vjzqnxFKckWioxVxUnAgA8R6n/L4CAAA= X-Env-Sender: olekstysh@gmail.com X-Msg-Ref: server-16.tower-206.messagelabs.com!1501081825!88753421!1 X-Originating-IP: [209.85.215.68] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.25; banners=-,-,- X-VirusChecked: Checked Received: (qmail 27697 invoked from network); 26 Jul 2017 15:10:26 -0000 Received: from mail-lf0-f68.google.com (HELO mail-lf0-f68.google.com) (209.85.215.68) by server-16.tower-206.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 26 Jul 2017 15:10:26 -0000 Received: by mail-lf0-f68.google.com with SMTP id 65so2764635lfa.0 for ; Wed, 26 Jul 2017 08:10:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WcXG8vysXL41YPTO8XoaRJwbEJESg83FFk6qjfUTsyw=; b=gDwS7RhbDIyo2JXigySWhy6Mkrd1S9sAE7Gv9yPAOzGlsDwtalGKJyKx6zurcoWP57 utToHSB0yDYqcVOQdY4MbLsxUz9G9pCMPxIYRjc3TvzvInS7SavXBNLn5Bi4WfQBA/oQ hYoMt9dSc5GuVTwcpr2JeWbPvFiYV1kxtTmvQIJ9YT6gak/R95zrC0xjb76oeaag1sD6 NMPCavfeJsdZ60ICvGHS5IhBsbyNDape3Z2ngJeniwbqbNT5KHJ0G78TGNGDC1J1Ihb7 LWn4NKEDS9FxtiQNuLBRRn5KyMd0y08QKxNRbuL5fMma7ipAy1ZZi0T+NeHiQFHpPbsx OTHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WcXG8vysXL41YPTO8XoaRJwbEJESg83FFk6qjfUTsyw=; b=RdzhpdNrwjmoE4jtldzcj77wVUZMhjMEXhm7+SzZmFcGs3q/X+WsBcS4Lho5opJQwu IrF0zp5fUIq87J2wpNkY+Udr5m2HygcAvbTdOlAgQsUT1Cz1tvixDhnGvcz6hQURkhZa i9epxPHSBgUi50HY/mGB5yM+9ShfRZ/c1s4RE3zcUfVD59b0GMwMIQWW/nb4SrRpa5tJ 3HN32FS1eo7Fxy3BmCPqr+CiS6ufvR4t31RLfD8mLkJke6b3EwDdEzDoBBiFQr4BNrtE TZ0wajl//1ECXTDZrB348ST1cUBnB5IGQkjfkdcUIkueV5EXRwvEqExvXnLIUQdKrcQa pmDg== X-Gm-Message-State: AIVw113QQa5ohB0hjPtd0RlvktztEkwRfyHa8G9lTMv5jADxXI8SHrYN XRJkZtN4Q9kxrfaW X-Received: by 10.46.9.144 with SMTP id 138mr626362ljj.36.1501081825247; Wed, 26 Jul 2017 08:10:25 -0700 (PDT) Received: from otyshchenko.kyiv.epam.com (ll-52.209.223.85.sovam.net.ua. [85.223.209.52]) by smtp.gmail.com with ESMTPSA id d203sm3202565lfg.59.2017.07.26.08.10.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 26 Jul 2017 08:10:24 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org Date: Wed, 26 Jul 2017 18:10:04 +0300 Message-Id: <1501081804-4882-8-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1501081804-4882-1-git-send-email-olekstysh@gmail.com> References: <1501081804-4882-1-git-send-email-olekstysh@gmail.com> Cc: Oleksandr Tyshchenko , Julien Grall , Stefano Stabellini Subject: [Xen-devel] [RFC PATCH v1 7/7] iommu/arm: ipmmu-vmsa: Enable VMSAv8-64 mode if IPMMU HW supports it X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Oleksandr Tyshchenko The patch was ported from RFC patch for Linux and slightly modified in order to handle IOVA space above 32-bit. iommu/ipmmu-vmsa: Initial R-Car Gen3 VA64 mode support https://patchwork.kernel.org/patch/9532335/ Modifications to the original patch are: - Increase IOVA space from 32-bit to 39-bit - Print full IOVA in case of page fault - Setup TTBR1 as well as TTBR0 Signed-off-by: Oleksandr Tyshchenko CC: Julien Grall CC: Stefano Stabellini --- xen/drivers/passthrough/arm/ipmmu-vmsa.c | 55 ++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/xen/drivers/passthrough/arm/ipmmu-vmsa.c b/xen/drivers/passthrough/arm/ipmmu-vmsa.c index 2a04800..211ce39 100644 --- a/xen/drivers/passthrough/arm/ipmmu-vmsa.c +++ b/xen/drivers/passthrough/arm/ipmmu-vmsa.c @@ -220,6 +220,7 @@ struct ipmmu_features { bool has_eight_ctx; bool setup_imbuscr; bool twobit_imttbcr_sl0; + bool imctr_va64; }; #ifdef CONFIG_RCAR_DDR_BACKUP @@ -334,6 +335,7 @@ static void set_archdata(struct device *dev, struct ipmmu_vmsa_archdata *p) #define IM_CTX_SIZE 0x40 #define IMCTR 0x0000 +#define IMCTR_VA64 (1 << 29) #define IMCTR_TRE (1 << 17) #define IMCTR_AFE (1 << 16) #define IMCTR_RTSEL_MASK (3 << 4) @@ -381,7 +383,7 @@ static void set_archdata(struct device *dev, struct ipmmu_vmsa_archdata *p) #define IMTTBCR_SL0_LVL_2 (0 << 4) #define IMTTBCR_SL0_LVL_1 (1 << 4) #define IMTTBCR_TSZ0_MASK (7 << 0) -#define IMTTBCR_TSZ0_SHIFT O +#define IMTTBCR_TSZ0_SHIFT 0 #define IMTTBCR_SL0_TWOBIT_LVL_3 (0 << 6) #define IMTTBCR_SL0_TWOBIT_LVL_2 (1 << 6) @@ -424,6 +426,7 @@ static void set_archdata(struct device *dev, struct ipmmu_vmsa_archdata *p) #define IMMAIR_ATTR_IDX_DEV 2 #define IMEAR 0x0030 +#define IMEUAR 0x0034 #define IMPCTR 0x0200 #define IMPSTR 0x0208 @@ -770,7 +773,7 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain) */ domain->cfg.quirks = IO_PGTABLE_QUIRK_ARM_NS; domain->cfg.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K, - domain->cfg.ias = 32; + domain->cfg.ias = domain->root->features->imctr_va64 ? 39 : 32; domain->cfg.oas = 40; domain->cfg.tlb = &ipmmu_gather_ops; #if 0 /* Xen: Not needed */ @@ -783,8 +786,9 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain) */ domain->cfg.iommu_dev = domain->root->dev; - domain->iop = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &domain->cfg, - domain); + domain->iop = alloc_io_pgtable_ops(domain->root->features->imctr_va64 ? + ARM_64_LPAE_S1 : ARM_32_LPAE_S1, + &domain->cfg, domain); if (!domain->iop) return -EINVAL; @@ -818,6 +822,14 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain) ipmmu_ctx_write(domain, IMTTUBR0, ttbr >> 32); /* + * With enabling IMCTR_VA64 we need to setup TTBR1 as well + */ + if (domain->root->features->imctr_va64) { + ipmmu_ctx_write(domain, IMTTLBR1, ttbr); + ipmmu_ctx_write(domain, IMTTUBR1, ttbr >> 32); + } + + /* * TTBCR * We use long descriptors with inner-shareable WBWA tables and allocate * the whole 32-bit VA space to TTBR0. @@ -828,6 +840,19 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain) else tmp = IMTTBCR_SL0_LVL_1; + /* + * As we are going to use TTBR1 we need to setup attributes for the memory + * associated with the translation table walks using TTBR1. + * Also for using IMCTR_VA64 mode we need to calculate and setup + * TTBR0/TTBR1 addressed regions. + */ + if (domain->root->features->imctr_va64) { + tmp |= IMTTBCR_SH1_INNER_SHAREABLE | IMTTBCR_ORGN1_WB_WA | + IMTTBCR_IRGN1_WB_WA; + tmp |= (64ULL - domain->cfg.ias) << IMTTBCR_TSZ0_SHIFT; + tmp |= (64ULL - domain->cfg.ias) << IMTTBCR_TSZ1_SHIFT; + } + ipmmu_ctx_write(domain, IMTTBCR, IMTTBCR_EAE | IMTTBCR_SH0_INNER_SHAREABLE | IMTTBCR_ORGN0_WB_WA | IMTTBCR_IRGN0_WB_WA | tmp); @@ -855,7 +880,8 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain) * Xen: Enable the context for the root IPMMU only. */ ipmmu_ctx_write(domain, IMCTR, - IMCTR_INTEN | IMCTR_FLUSH | IMCTR_MMUEN); + (domain->root->features->imctr_va64 ? IMCTR_VA64 : 0) + | IMCTR_INTEN | IMCTR_FLUSH | IMCTR_MMUEN); return 0; } @@ -909,13 +935,14 @@ static irqreturn_t ipmmu_domain_irq(struct ipmmu_vmsa_domain *domain) const u32 err_mask = IMSTR_MHIT | IMSTR_ABORT | IMSTR_PF | IMSTR_TF; struct ipmmu_vmsa_device *mmu = domain->mmu; u32 status; - u32 iova; + u64 iova; status = ipmmu_ctx_read(domain, IMSTR); if (!(status & err_mask)) return IRQ_NONE; - iova = ipmmu_ctx_read(domain, IMEAR); + iova = ipmmu_ctx_read(domain, IMEAR) | + ((u64)ipmmu_ctx_read(domain, IMEUAR) << 32); /* * Clear the error status flags. Unlike traditional interrupt flag @@ -927,10 +954,10 @@ static irqreturn_t ipmmu_domain_irq(struct ipmmu_vmsa_domain *domain) /* Log fatal errors. */ if (status & IMSTR_MHIT) - dev_err_ratelimited(mmu->dev, "d%d: Multiple TLB hits @0x%08x\n", + dev_err_ratelimited(mmu->dev, "d%d: Multiple TLB hits @0x%"PRIx64"\n", domain->d->domain_id, iova); if (status & IMSTR_ABORT) - dev_err_ratelimited(mmu->dev, "d%d: Page Table Walk Abort @0x%08x\n", + dev_err_ratelimited(mmu->dev, "d%d: Page Table Walk Abort @0x%"PRIx64"\n", domain->d->domain_id, iova); if (!(status & (IMSTR_PF | IMSTR_TF))) @@ -946,7 +973,7 @@ static irqreturn_t ipmmu_domain_irq(struct ipmmu_vmsa_domain *domain) return IRQ_HANDLED; dev_err_ratelimited(mmu->dev, - "d%d: Unhandled fault: status 0x%08x iova 0x%08x\n", + "d%d: Unhandled fault: status 0x%08x iova 0x%"PRIx64"\n", domain->d->domain_id, status, iova); return IRQ_HANDLED; @@ -1219,8 +1246,7 @@ size_t ipmmu_unmap(struct iommu_domain *io_domain, unsigned long iova, size_t si if ((dma_addr_t)iova + size > max_iova) { printk("out-of-bound: iova 0x%lx + size 0x%zx > max_iova 0x%"PRIx64"\n", iova, size, max_iova); - /* TODO Return -EINVAL instead */ - return 0; + return -EINVAL; } /* @@ -1277,8 +1303,7 @@ int ipmmu_map(struct iommu_domain *io_domain, unsigned long iova, if ((dma_addr_t)iova + size > max_iova) { printk("out-of-bound: iova 0x%lx + size 0x%zx > max_iova 0x%"PRIx64"\n", iova, size, max_iova); - /* TODO Return -EINVAL instead */ - return 0; + return -EINVAL; } while (size) { @@ -1725,6 +1750,7 @@ static const struct ipmmu_features ipmmu_features_default = { .has_eight_ctx = false, .setup_imbuscr = true, .twobit_imttbcr_sl0 = false, + .imctr_va64 = false, }; static const struct ipmmu_features ipmmu_features_rcar_gen3 = { @@ -1733,6 +1759,7 @@ static const struct ipmmu_features ipmmu_features_rcar_gen3 = { .has_eight_ctx = true, .setup_imbuscr = false, .twobit_imttbcr_sl0 = true, + .imctr_va64 = true, }; static const struct of_device_id ipmmu_of_ids[] = {