From patchwork Fri Jan 15 12:13:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022409 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 902EFC433E0 for ; Fri, 15 Jan 2021 12:16:09 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 46B492256F for ; Fri, 15 Jan 2021 12:16:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 46B492256F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=8qsaUjlUMnIx550EAAwvbS3j6Ol46MqcDj9tQH0lJN0=; b=OzVdZ0iPTiql+YQ5il3fK5dPTT UOI+WdIXedxn8glX599F9zIeJDeMEmYesG9GLc9A8cLl6I788799Wv+RfvXE5VxNItSr9BUjID+kE cB9RUZWKpj86XJLkbqQUMfdVcmS6SvXndgVwb7qD6aFNihEHqZmFLFSdoUBFEpXL5+Ujv1wo4lFWC yCIWHV9VBfPpkf747i2pjKOzJyQPjdxJ9owUOUymHFHUcXlOxPb89Nx63UPnqpMTz3T681/FTqSmq Gr7JqbhzR9Hbi9LScMnKePKnjP9arbTGJrGOjTRUnKcPnhpKGnactq3kmAWwy7+I56NEg19vlzNtU gpr41xbw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0NzP-00071a-8m; Fri, 15 Jan 2021 12:14:03 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0NzL-000713-NW for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:01 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 829EDED1; Fri, 15 Jan 2021 04:13:57 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id BD83A3F70D; Fri, 15 Jan 2021 04:13:52 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 01/15] iommu/arm-smmu-v3: Create a Context Descriptor library Date: Fri, 15 Jan 2021 17:43:28 +0530 Message-Id: <20210115121342.15093-2-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071400_079193_A10ED5C0 X-CRM114-Status: GOOD ( 30.90 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Para-virtualized iommu drivers in guest may require to create and manage context descriptor (CD) tables as part of PASID table allocations. The PASID tables are passed to host to configure stage-1 tables in hardware. Make way for a library driver for CD management to allow para- virtualized iommu driver call such code. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/arm/arm-smmu-v3/Makefile | 2 +- .../arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 223 ++++++++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 216 +---------------- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 + 4 files changed, 228 insertions(+), 216 deletions(-) create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile index 54feb1ecccad..ca1a05b8b8ad 100644 --- a/drivers/iommu/arm/arm-smmu-v3/Makefile +++ b/drivers/iommu/arm/arm-smmu-v3/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_ARM_SMMU_V3) += arm_smmu_v3.o -arm_smmu_v3-objs-y += arm-smmu-v3.o +arm_smmu_v3-objs-y += arm-smmu-v3.o arm-smmu-v3-cd-lib.o arm_smmu_v3-objs-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o arm_smmu_v3-objs := $(arm_smmu_v3-objs-y) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c new file mode 100644 index 000000000000..97d1786a8a70 --- /dev/null +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * arm-smmu-v3 context descriptor handling library driver + * + * Copyright (C) 2021 Arm Ltd. + */ + +#include + +#include "arm-smmu-v3.h" + +static int arm_smmu_alloc_cd_leaf_table(struct arm_smmu_device *smmu, + struct arm_smmu_l1_ctx_desc *l1_desc) +{ + size_t size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3); + + l1_desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, + &l1_desc->l2ptr_dma, GFP_KERNEL); + if (!l1_desc->l2ptr) { + dev_warn(smmu->dev, + "failed to allocate context descriptor table\n"); + return -ENOMEM; + } + return 0; +} + +static void arm_smmu_write_cd_l1_desc(__le64 *dst, + struct arm_smmu_l1_ctx_desc *l1_desc) +{ + u64 val = (l1_desc->l2ptr_dma & CTXDESC_L1_DESC_L2PTR_MASK) | + CTXDESC_L1_DESC_V; + + /* See comment in arm_smmu_write_ctx_desc() */ + WRITE_ONCE(*dst, cpu_to_le64(val)); +} + +static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain, + u32 ssid) +{ + __le64 *l1ptr; + unsigned int idx; + struct arm_smmu_l1_ctx_desc *l1_desc; + struct arm_smmu_device *smmu = smmu_domain->smmu; + struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg; + + if (smmu_domain->s1_cfg.s1fmt == STRTAB_STE_0_S1FMT_LINEAR) + return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS; + + idx = ssid >> CTXDESC_SPLIT; + l1_desc = &cdcfg->l1_desc[idx]; + if (!l1_desc->l2ptr) { + if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc)) + return NULL; + + l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS; + arm_smmu_write_cd_l1_desc(l1ptr, l1_desc); + /* An invalid L1CD can be cached */ + arm_smmu_sync_cd(smmu_domain, ssid, false); + } + idx = ssid & (CTXDESC_L2_ENTRIES - 1); + return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS; +} + +int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, + struct arm_smmu_ctx_desc *cd) +{ + /* + * This function handles the following cases: + * + * (1) Install primary CD, for normal DMA traffic (SSID = 0). + * (2) Install a secondary CD, for SID+SSID traffic. + * (3) Update ASID of a CD. Atomically write the first 64 bits of the + * CD, then invalidate the old entry and mappings. + * (4) Quiesce the context without clearing the valid bit. Disable + * translation, and ignore any translation fault. + * (5) Remove a secondary CD. + */ + u64 val; + bool cd_live; + __le64 *cdptr; + struct arm_smmu_device *smmu = smmu_domain->smmu; + + if (WARN_ON(ssid >= (1 << smmu_domain->s1_cfg.s1cdmax))) + return -E2BIG; + + cdptr = arm_smmu_get_cd_ptr(smmu_domain, ssid); + if (!cdptr) + return -ENOMEM; + + val = le64_to_cpu(cdptr[0]); + cd_live = !!(val & CTXDESC_CD_0_V); + + if (!cd) { /* (5) */ + val = 0; + } else if (cd == &quiet_cd) { /* (4) */ + val |= CTXDESC_CD_0_TCR_EPD0; + } else if (cd_live) { /* (3) */ + val &= ~CTXDESC_CD_0_ASID; + val |= FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid); + /* + * Until CD+TLB invalidation, both ASIDs may be used for tagging + * this substream's traffic + */ + } else { /* (1) and (2) */ + cdptr[1] = cpu_to_le64(cd->ttbr & CTXDESC_CD_1_TTB0_MASK); + cdptr[2] = 0; + cdptr[3] = cpu_to_le64(cd->mair); + + /* + * STE is live, and the SMMU might read dwords of this CD in any + * order. Ensure that it observes valid values before reading + * V=1. + */ + arm_smmu_sync_cd(smmu_domain, ssid, true); + + val = cd->tcr | +#ifdef __BIG_ENDIAN + CTXDESC_CD_0_ENDI | +#endif + CTXDESC_CD_0_R | CTXDESC_CD_0_A | + (cd->mm ? 0 : CTXDESC_CD_0_ASET) | + CTXDESC_CD_0_AA64 | + FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) | + CTXDESC_CD_0_V; + + /* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */ + if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE) + val |= CTXDESC_CD_0_S; + } + + /* + * The SMMU accesses 64-bit values atomically. See IHI0070Ca 3.21.3 + * "Configuration structures and configuration invalidation completion" + * + * The size of single-copy atomic reads made by the SMMU is + * IMPLEMENTATION DEFINED but must be at least 64 bits. Any single + * field within an aligned 64-bit span of a structure can be altered + * without first making the structure invalid. + */ + WRITE_ONCE(cdptr[0], cpu_to_le64(val)); + arm_smmu_sync_cd(smmu_domain, ssid, true); + return 0; +} + +int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain) +{ + int ret; + size_t l1size; + size_t max_contexts; + struct arm_smmu_device *smmu = smmu_domain->smmu; + struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg; + struct arm_smmu_ctx_desc_cfg *cdcfg = &cfg->cdcfg; + + max_contexts = 1 << cfg->s1cdmax; + + if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) || + max_contexts <= CTXDESC_L2_ENTRIES) { + cfg->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; + cdcfg->num_l1_ents = max_contexts; + + l1size = max_contexts * (CTXDESC_CD_DWORDS << 3); + } else { + cfg->s1fmt = STRTAB_STE_0_S1FMT_64K_L2; + cdcfg->num_l1_ents = DIV_ROUND_UP(max_contexts, + CTXDESC_L2_ENTRIES); + + cdcfg->l1_desc = devm_kcalloc(smmu->dev, cdcfg->num_l1_ents, + sizeof(*cdcfg->l1_desc), + GFP_KERNEL); + if (!cdcfg->l1_desc) + return -ENOMEM; + + l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3); + } + + cdcfg->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cdcfg->cdtab_dma, + GFP_KERNEL); + if (!cdcfg->cdtab) { + dev_warn(smmu->dev, "failed to allocate context descriptor\n"); + ret = -ENOMEM; + goto err_free_l1; + } + + return 0; + +err_free_l1: + if (cdcfg->l1_desc) { + devm_kfree(smmu->dev, cdcfg->l1_desc); + cdcfg->l1_desc = NULL; + } + return ret; +} + +void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain) +{ + int i; + size_t size, l1size; + struct arm_smmu_device *smmu = smmu_domain->smmu; + struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg; + + if (cdcfg->l1_desc) { + size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3); + + for (i = 0; i < cdcfg->num_l1_ents; i++) { + if (!cdcfg->l1_desc[i].l2ptr) + continue; + + dmam_free_coherent(smmu->dev, size, + cdcfg->l1_desc[i].l2ptr, + cdcfg->l1_desc[i].l2ptr_dma); + } + devm_kfree(smmu->dev, cdcfg->l1_desc); + cdcfg->l1_desc = NULL; + + l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3); + } else { + l1size = cdcfg->num_l1_ents * (CTXDESC_CD_DWORDS << 3); + } + + dmam_free_coherent(smmu->dev, l1size, cdcfg->cdtab, cdcfg->cdtab_dma); + cdcfg->cdtab_dma = 0; + cdcfg->cdtab = NULL; +} diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 51da068df4e9..13513f2f651a 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -894,8 +894,7 @@ void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid) arm_smmu_cmdq_issue_sync(smmu); } -static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain, - int ssid, bool leaf) +void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain, int ssid, bool leaf) { size_t i; unsigned long flags; @@ -922,219 +921,6 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain, arm_smmu_cmdq_batch_submit(smmu, &cmds); } -static int arm_smmu_alloc_cd_leaf_table(struct arm_smmu_device *smmu, - struct arm_smmu_l1_ctx_desc *l1_desc) -{ - size_t size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3); - - l1_desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, - &l1_desc->l2ptr_dma, GFP_KERNEL); - if (!l1_desc->l2ptr) { - dev_warn(smmu->dev, - "failed to allocate context descriptor table\n"); - return -ENOMEM; - } - return 0; -} - -static void arm_smmu_write_cd_l1_desc(__le64 *dst, - struct arm_smmu_l1_ctx_desc *l1_desc) -{ - u64 val = (l1_desc->l2ptr_dma & CTXDESC_L1_DESC_L2PTR_MASK) | - CTXDESC_L1_DESC_V; - - /* See comment in arm_smmu_write_ctx_desc() */ - WRITE_ONCE(*dst, cpu_to_le64(val)); -} - -static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain, - u32 ssid) -{ - __le64 *l1ptr; - unsigned int idx; - struct arm_smmu_l1_ctx_desc *l1_desc; - struct arm_smmu_device *smmu = smmu_domain->smmu; - struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg; - - if (smmu_domain->s1_cfg.s1fmt == STRTAB_STE_0_S1FMT_LINEAR) - return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS; - - idx = ssid >> CTXDESC_SPLIT; - l1_desc = &cdcfg->l1_desc[idx]; - if (!l1_desc->l2ptr) { - if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc)) - return NULL; - - l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS; - arm_smmu_write_cd_l1_desc(l1ptr, l1_desc); - /* An invalid L1CD can be cached */ - arm_smmu_sync_cd(smmu_domain, ssid, false); - } - idx = ssid & (CTXDESC_L2_ENTRIES - 1); - return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS; -} - -int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, - struct arm_smmu_ctx_desc *cd) -{ - /* - * This function handles the following cases: - * - * (1) Install primary CD, for normal DMA traffic (SSID = 0). - * (2) Install a secondary CD, for SID+SSID traffic. - * (3) Update ASID of a CD. Atomically write the first 64 bits of the - * CD, then invalidate the old entry and mappings. - * (4) Quiesce the context without clearing the valid bit. Disable - * translation, and ignore any translation fault. - * (5) Remove a secondary CD. - */ - u64 val; - bool cd_live; - __le64 *cdptr; - struct arm_smmu_device *smmu = smmu_domain->smmu; - - if (WARN_ON(ssid >= (1 << smmu_domain->s1_cfg.s1cdmax))) - return -E2BIG; - - cdptr = arm_smmu_get_cd_ptr(smmu_domain, ssid); - if (!cdptr) - return -ENOMEM; - - val = le64_to_cpu(cdptr[0]); - cd_live = !!(val & CTXDESC_CD_0_V); - - if (!cd) { /* (5) */ - val = 0; - } else if (cd == &quiet_cd) { /* (4) */ - val |= CTXDESC_CD_0_TCR_EPD0; - } else if (cd_live) { /* (3) */ - val &= ~CTXDESC_CD_0_ASID; - val |= FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid); - /* - * Until CD+TLB invalidation, both ASIDs may be used for tagging - * this substream's traffic - */ - } else { /* (1) and (2) */ - cdptr[1] = cpu_to_le64(cd->ttbr & CTXDESC_CD_1_TTB0_MASK); - cdptr[2] = 0; - cdptr[3] = cpu_to_le64(cd->mair); - - /* - * STE is live, and the SMMU might read dwords of this CD in any - * order. Ensure that it observes valid values before reading - * V=1. - */ - arm_smmu_sync_cd(smmu_domain, ssid, true); - - val = cd->tcr | -#ifdef __BIG_ENDIAN - CTXDESC_CD_0_ENDI | -#endif - CTXDESC_CD_0_R | CTXDESC_CD_0_A | - (cd->mm ? 0 : CTXDESC_CD_0_ASET) | - CTXDESC_CD_0_AA64 | - FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) | - CTXDESC_CD_0_V; - - /* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */ - if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE) - val |= CTXDESC_CD_0_S; - } - - /* - * The SMMU accesses 64-bit values atomically. See IHI0070Ca 3.21.3 - * "Configuration structures and configuration invalidation completion" - * - * The size of single-copy atomic reads made by the SMMU is - * IMPLEMENTATION DEFINED but must be at least 64 bits. Any single - * field within an aligned 64-bit span of a structure can be altered - * without first making the structure invalid. - */ - WRITE_ONCE(cdptr[0], cpu_to_le64(val)); - arm_smmu_sync_cd(smmu_domain, ssid, true); - return 0; -} - -static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain) -{ - int ret; - size_t l1size; - size_t max_contexts; - struct arm_smmu_device *smmu = smmu_domain->smmu; - struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg; - struct arm_smmu_ctx_desc_cfg *cdcfg = &cfg->cdcfg; - - max_contexts = 1 << cfg->s1cdmax; - - if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) || - max_contexts <= CTXDESC_L2_ENTRIES) { - cfg->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; - cdcfg->num_l1_ents = max_contexts; - - l1size = max_contexts * (CTXDESC_CD_DWORDS << 3); - } else { - cfg->s1fmt = STRTAB_STE_0_S1FMT_64K_L2; - cdcfg->num_l1_ents = DIV_ROUND_UP(max_contexts, - CTXDESC_L2_ENTRIES); - - cdcfg->l1_desc = devm_kcalloc(smmu->dev, cdcfg->num_l1_ents, - sizeof(*cdcfg->l1_desc), - GFP_KERNEL); - if (!cdcfg->l1_desc) - return -ENOMEM; - - l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3); - } - - cdcfg->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cdcfg->cdtab_dma, - GFP_KERNEL); - if (!cdcfg->cdtab) { - dev_warn(smmu->dev, "failed to allocate context descriptor\n"); - ret = -ENOMEM; - goto err_free_l1; - } - - return 0; - -err_free_l1: - if (cdcfg->l1_desc) { - devm_kfree(smmu->dev, cdcfg->l1_desc); - cdcfg->l1_desc = NULL; - } - return ret; -} - -static void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain) -{ - int i; - size_t size, l1size; - struct arm_smmu_device *smmu = smmu_domain->smmu; - struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg; - - if (cdcfg->l1_desc) { - size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3); - - for (i = 0; i < cdcfg->num_l1_ents; i++) { - if (!cdcfg->l1_desc[i].l2ptr) - continue; - - dmam_free_coherent(smmu->dev, size, - cdcfg->l1_desc[i].l2ptr, - cdcfg->l1_desc[i].l2ptr_dma); - } - devm_kfree(smmu->dev, cdcfg->l1_desc); - cdcfg->l1_desc = NULL; - - l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3); - } else { - l1size = cdcfg->num_l1_ents * (CTXDESC_CD_DWORDS << 3); - } - - dmam_free_coherent(smmu->dev, l1size, cdcfg->cdtab, cdcfg->cdtab_dma); - cdcfg->cdtab_dma = 0; - cdcfg->cdtab = NULL; -} - bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd) { bool free; diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h index 9cdccf5d79b3..a50a3e4874f9 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -784,6 +784,9 @@ extern struct arm_smmu_ctx_desc quiet_cd; int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, struct arm_smmu_ctx_desc *cd); +int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain); +void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain); +void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain, int ssid, bool leaf); void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid); bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd); int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid, From patchwork Fri Jan 15 12:13:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022407 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 A809FC433E6 for ; Fri, 15 Jan 2021 12:16:00 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 29BC8205F4 for ; Fri, 15 Jan 2021 12:16:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 29BC8205F4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=g31PrXon9miblY0l8/YMzHRrVtdMyroDB+3uNK435IE=; b=nVEdZ3Vyn9+394KoYg7y1QfAkX BIhaFBAOlXuyiLsFAv7fgRte1Fvm0N4Q2wK/jR5Y6re4ZhBTzMD8147spNU/IGLq8HxY/kY9PVbGU WapEduTrnHdFM70LHOid1BIUqmE6V/FAz+mZPMEC3G5rlYD2DjZUVkKhWLN05g1tH+mzFOGGlhw0+ 1+o8NP3B9vBaNEvBmt/bbMI7/V38brTBTZpt0fk9wyDsZrXWICs4GLr1gjxyOzoImK2Ba3J0K8CsA E3OrG+wgWo6WuiHxpwsVtdrGX01jch9TC114FVgFCBSp12NW57gjPNXPmWb8ICtHH5Z3Pz6EBRvaG 255pe0iw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0NzU-00072q-Hw; Fri, 15 Jan 2021 12:14:08 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0NzR-000722-93 for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:06 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 78F4211FB; Fri, 15 Jan 2021 04:14:02 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 01F233F70D; Fri, 15 Jan 2021 04:13:57 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 02/15] iommu: Add a simple PASID table library Date: Fri, 15 Jan 2021 17:43:29 +0530 Message-Id: <20210115121342.15093-3-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071405_436042_B8CB4994 X-CRM114-Status: GOOD ( 19.53 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a small API in iommu subsystem to handle PASID table allocation requests from different consumer drivers, such as a paravirtualized iommu driver. The API provides ops for allocating and freeing PASID table, writing to it and managing the table caches. This library also provides for registering a vendor API that attaches to these ops. The vendor APIs would eventually perform arch level implementations for these PASID tables. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/iommu-pasid-table.h | 134 ++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 drivers/iommu/iommu-pasid-table.h diff --git a/drivers/iommu/iommu-pasid-table.h b/drivers/iommu/iommu-pasid-table.h new file mode 100644 index 000000000000..bd4f57656f67 --- /dev/null +++ b/drivers/iommu/iommu-pasid-table.h @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PASID table management for the IOMMU + * + * Copyright (C) 2021 Arm Ltd. + */ +#ifndef __IOMMU_PASID_TABLE_H +#define __IOMMU_PASID_TABLE_H + +#include + +#include "arm/arm-smmu-v3/arm-smmu-v3.h" + +enum pasid_table_fmt { + PASID_TABLE_ARM_SMMU_V3, + PASID_TABLE_NUM_FMTS, +}; + +/** + * struct arm_smmu_cfg_info - arm-smmu-v3 specific configuration data + * + * @s1_cfg: arm-smmu-v3 stage1 config data + * @feat_flag: features supported by arm-smmu-v3 implementation + */ +struct arm_smmu_cfg_info { + struct arm_smmu_s1_cfg *s1_cfg; + u32 feat_flag; +}; + +/** + * struct iommu_vendor_psdtable_cfg - Configuration data for PASID tables + * + * @iommu_dev: device performing the DMA table walks + * @fmt: The PASID table format + * @base: DMA address of the allocated table, set by the vendor driver + * @cfg: arm-smmu-v3 specific config data + */ +struct iommu_vendor_psdtable_cfg { + struct device *iommu_dev; + enum pasid_table_fmt fmt; + dma_addr_t base; + union { + struct arm_smmu_cfg_info cfg; + } vendor; +}; + +struct iommu_vendor_psdtable_ops; + +/** + * struct iommu_pasid_table - describes a set of PASID tables + * + * @cookie: An opaque token provided by the IOMMU driver and passed back to any + * callback routine. + * @cfg: A copy of the PASID table configuration + * @ops: The PASID table operations in use for this set of page tables + */ +struct iommu_pasid_table { + void *cookie; + struct iommu_vendor_psdtable_cfg cfg; + struct iommu_vendor_psdtable_ops *ops; +}; + +#define pasid_table_cfg_to_table(pst_cfg) \ + container_of((pst_cfg), struct iommu_pasid_table, cfg) + +struct iommu_vendor_psdtable_ops { + int (*alloc)(struct iommu_vendor_psdtable_cfg *cfg); + void (*free)(struct iommu_vendor_psdtable_cfg *cfg); + void (*prepare)(struct iommu_vendor_psdtable_cfg *cfg, + struct io_pgtable_cfg *pgtbl_cfg, u32 asid); + int (*write)(struct iommu_vendor_psdtable_cfg *cfg, int ssid, + void *cookie); + void (*sync)(void *cookie, int ssid, bool leaf); +}; + +static inline int iommu_psdtable_alloc(struct iommu_pasid_table *tbl, + struct iommu_vendor_psdtable_cfg *cfg) +{ + if (!tbl->ops->alloc) + return -ENOSYS; + + return tbl->ops->alloc(cfg); +} + +static inline void iommu_psdtable_free(struct iommu_pasid_table *tbl, + struct iommu_vendor_psdtable_cfg *cfg) +{ + if (!tbl->ops->free) + return; + + tbl->ops->free(cfg); +} + +static inline int iommu_psdtable_prepare(struct iommu_pasid_table *tbl, + struct iommu_vendor_psdtable_cfg *cfg, + struct io_pgtable_cfg *pgtbl_cfg, + u32 asid) +{ + if (!tbl->ops->prepare) + return -ENOSYS; + + tbl->ops->prepare(cfg, pgtbl_cfg, asid); + return 0; +} + +static inline int iommu_psdtable_write(struct iommu_pasid_table *tbl, + struct iommu_vendor_psdtable_cfg *cfg, + int ssid, void *cookie) +{ + if (!tbl->ops->write) + return -ENOSYS; + + return tbl->ops->write(cfg, ssid, cookie); +} + +static inline int iommu_psdtable_sync(struct iommu_pasid_table *tbl, + void *cookie, int ssid, bool leaf) +{ + if (!tbl->ops->sync) + return -ENOSYS; + + tbl->ops->sync(cookie, ssid, leaf); + return 0; +} + +/* A placeholder to register vendor specific pasid layer */ +static inline struct iommu_pasid_table * +iommu_register_pasid_table(enum pasid_table_fmt fmt, + struct device *dev, void *cookie) +{ + return NULL; +} + +#endif /* __IOMMU_PASID_TABLE_H */ From patchwork Fri Jan 15 12:13:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022413 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 33157C433DB for ; Fri, 15 Jan 2021 12:16:35 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B1E11205F4 for ; Fri, 15 Jan 2021 12:16:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B1E11205F4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=ybClRiaZbFW2sVy8/JJQOULFpcgnsSKkultG//5CA+I=; b=ZgdOwK986pOPTaKT8rVzxXIwIG mu9fJqAO9VDh5BPknezqgGVRXB0YpM19ogapHse2Ci4uQm52Squ8YgPTBZ4vPWuWxvSZ/3yILJ6fF iQgXXg8sZT5RNbzVrYSUeg+g3b4P5f+jMiLFQ80yKDU7I9aUJpJy3MkuO64Ids6G1VOkRRPkqoUsl IMbnDUcOpoJcMgordGgpjGdZ6TmqqHsVl9sXjQgr5D7WmUAwvQDyhbPaF7OlP83G4PGfIMAwgL1kr e6WYgeTKxhJabXExi/FRiWeajwNOEtt5gBuWs035qJ8UsmXSFlTTed1YZFWUR9jy4RlO3e3tYZQnQ fZsk9qJA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzc-00075N-O9; Fri, 15 Jan 2021 12:14:16 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0NzV-00073C-5L for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:13 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id ABB7312FC; Fri, 15 Jan 2021 04:14:07 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id EC86A3F70D; Fri, 15 Jan 2021 04:14:02 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 03/15] iommu/arm-smmu-v3: Update drivers to work with iommu-pasid-table Date: Fri, 15 Jan 2021 17:43:30 +0530 Message-Id: <20210115121342.15093-4-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071409_402162_FD7CB2BC X-CRM114-Status: GOOD ( 25.45 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Update arm-smmu-v3 context descriptor (CD) library driver to work with iommu-pasid-table APIs. These APIs are then used in arm-smmu-v3 drivers to manage CD tables. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- .../arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 127 +++++++++++++----- .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 16 ++- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 47 ++++--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 7 +- drivers/iommu/iommu-pasid-table.h | 10 +- 5 files changed, 144 insertions(+), 63 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c index 97d1786a8a70..8a7187534706 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c @@ -8,17 +8,17 @@ #include #include "arm-smmu-v3.h" +#include "../../iommu-pasid-table.h" -static int arm_smmu_alloc_cd_leaf_table(struct arm_smmu_device *smmu, +static int arm_smmu_alloc_cd_leaf_table(struct device *dev, struct arm_smmu_l1_ctx_desc *l1_desc) { size_t size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3); - l1_desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, + l1_desc->l2ptr = dmam_alloc_coherent(dev, size, &l1_desc->l2ptr_dma, GFP_KERNEL); if (!l1_desc->l2ptr) { - dev_warn(smmu->dev, - "failed to allocate context descriptor table\n"); + dev_warn(dev, "failed to allocate context descriptor table\n"); return -ENOMEM; } return 0; @@ -34,35 +34,39 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst, WRITE_ONCE(*dst, cpu_to_le64(val)); } -static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain, +static __le64 *arm_smmu_get_cd_ptr(struct iommu_vendor_psdtable_cfg *pst_cfg, u32 ssid) { __le64 *l1ptr; unsigned int idx; + struct device *dev = pst_cfg->iommu_dev; + struct arm_smmu_cfg_info *cfgi = &pst_cfg->vendor.cfg; + struct arm_smmu_s1_cfg *s1cfg = cfgi->s1_cfg; + struct arm_smmu_ctx_desc_cfg *cdcfg = &s1cfg->cdcfg; struct arm_smmu_l1_ctx_desc *l1_desc; - struct arm_smmu_device *smmu = smmu_domain->smmu; - struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg; + struct iommu_pasid_table *tbl = pasid_table_cfg_to_table(pst_cfg); - if (smmu_domain->s1_cfg.s1fmt == STRTAB_STE_0_S1FMT_LINEAR) + if (s1cfg->s1fmt == STRTAB_STE_0_S1FMT_LINEAR) return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS; idx = ssid >> CTXDESC_SPLIT; l1_desc = &cdcfg->l1_desc[idx]; if (!l1_desc->l2ptr) { - if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc)) + if (arm_smmu_alloc_cd_leaf_table(dev, l1_desc)) return NULL; l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS; arm_smmu_write_cd_l1_desc(l1ptr, l1_desc); /* An invalid L1CD can be cached */ - arm_smmu_sync_cd(smmu_domain, ssid, false); + if (iommu_psdtable_sync(tbl, tbl->cookie, ssid, false)) + return NULL; } idx = ssid & (CTXDESC_L2_ENTRIES - 1); return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS; } -int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, - struct arm_smmu_ctx_desc *cd) +static int arm_smmu_write_ctx_desc(struct iommu_vendor_psdtable_cfg *pst_cfg, + int ssid, void *cookie) { /* * This function handles the following cases: @@ -78,12 +82,15 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, u64 val; bool cd_live; __le64 *cdptr; - struct arm_smmu_device *smmu = smmu_domain->smmu; + struct arm_smmu_cfg_info *cfgi = &pst_cfg->vendor.cfg; + struct arm_smmu_s1_cfg *s1cfg = cfgi->s1_cfg; + struct iommu_pasid_table *tbl = pasid_table_cfg_to_table(pst_cfg); + struct arm_smmu_ctx_desc *cd = cookie; - if (WARN_ON(ssid >= (1 << smmu_domain->s1_cfg.s1cdmax))) + if (WARN_ON(ssid >= (1 << s1cfg->s1cdmax))) return -E2BIG; - cdptr = arm_smmu_get_cd_ptr(smmu_domain, ssid); + cdptr = arm_smmu_get_cd_ptr(pst_cfg, ssid); if (!cdptr) return -ENOMEM; @@ -111,7 +118,8 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, * order. Ensure that it observes valid values before reading * V=1. */ - arm_smmu_sync_cd(smmu_domain, ssid, true); + if (iommu_psdtable_sync(tbl, tbl->cookie, ssid, true)) + return -ENOSYS; val = cd->tcr | #ifdef __BIG_ENDIAN @@ -124,7 +132,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, CTXDESC_CD_0_V; /* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */ - if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE) + if (cfgi->feat_flag & ARM_SMMU_FEAT_STALL_FORCE) val |= CTXDESC_CD_0_S; } @@ -138,33 +146,55 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, * without first making the structure invalid. */ WRITE_ONCE(cdptr[0], cpu_to_le64(val)); - arm_smmu_sync_cd(smmu_domain, ssid, true); + if (iommu_psdtable_sync(tbl, tbl->cookie, ssid, true)) + return -ENOSYS; + return 0; } -int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain) +static void arm_smmu_prepare_cd(struct iommu_vendor_psdtable_cfg *pst_cfg, + struct io_pgtable_cfg *pgtbl_cfg, u32 asid) +{ + struct arm_smmu_cfg_info *cfgi = &pst_cfg->vendor.cfg; + struct arm_smmu_s1_cfg *s1cfg = cfgi->s1_cfg; + typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr; + + s1cfg->cd.asid = (u16)asid; + s1cfg->cd.ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr; + s1cfg->cd.tcr = FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ, tcr->tsz) | + FIELD_PREP(CTXDESC_CD_0_TCR_TG0, tcr->tg) | + FIELD_PREP(CTXDESC_CD_0_TCR_IRGN0, tcr->irgn) | + FIELD_PREP(CTXDESC_CD_0_TCR_ORGN0, tcr->orgn) | + FIELD_PREP(CTXDESC_CD_0_TCR_SH0, tcr->sh) | + FIELD_PREP(CTXDESC_CD_0_TCR_IPS, tcr->ips) | + CTXDESC_CD_0_TCR_EPD1 | CTXDESC_CD_0_AA64; + s1cfg->cd.mair = pgtbl_cfg->arm_lpae_s1_cfg.mair; +} + +static int arm_smmu_alloc_cd_tables(struct iommu_vendor_psdtable_cfg *pst_cfg) { int ret; size_t l1size; size_t max_contexts; - struct arm_smmu_device *smmu = smmu_domain->smmu; - struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg; - struct arm_smmu_ctx_desc_cfg *cdcfg = &cfg->cdcfg; + struct device *dev = pst_cfg->iommu_dev; + struct arm_smmu_cfg_info *cfgi = &pst_cfg->vendor.cfg; + struct arm_smmu_s1_cfg *s1cfg = cfgi->s1_cfg; + struct arm_smmu_ctx_desc_cfg *cdcfg = &s1cfg->cdcfg; - max_contexts = 1 << cfg->s1cdmax; + max_contexts = 1 << s1cfg->s1cdmax; - if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) || + if (!(cfgi->feat_flag & ARM_SMMU_FEAT_2_LVL_CDTAB) || max_contexts <= CTXDESC_L2_ENTRIES) { - cfg->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; + s1cfg->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; cdcfg->num_l1_ents = max_contexts; l1size = max_contexts * (CTXDESC_CD_DWORDS << 3); } else { - cfg->s1fmt = STRTAB_STE_0_S1FMT_64K_L2; + s1cfg->s1fmt = STRTAB_STE_0_S1FMT_64K_L2; cdcfg->num_l1_ents = DIV_ROUND_UP(max_contexts, CTXDESC_L2_ENTRIES); - cdcfg->l1_desc = devm_kcalloc(smmu->dev, cdcfg->num_l1_ents, + cdcfg->l1_desc = devm_kcalloc(dev, cdcfg->num_l1_ents, sizeof(*cdcfg->l1_desc), GFP_KERNEL); if (!cdcfg->l1_desc) @@ -173,10 +203,10 @@ int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain) l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3); } - cdcfg->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cdcfg->cdtab_dma, + cdcfg->cdtab = dmam_alloc_coherent(dev, l1size, &cdcfg->cdtab_dma, GFP_KERNEL); if (!cdcfg->cdtab) { - dev_warn(smmu->dev, "failed to allocate context descriptor\n"); + dev_warn(dev, "failed to allocate context descriptor\n"); ret = -ENOMEM; goto err_free_l1; } @@ -185,18 +215,20 @@ int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain) err_free_l1: if (cdcfg->l1_desc) { - devm_kfree(smmu->dev, cdcfg->l1_desc); + devm_kfree(dev, cdcfg->l1_desc); cdcfg->l1_desc = NULL; } return ret; } -void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain) +static void arm_smmu_free_cd_tables(struct iommu_vendor_psdtable_cfg *pst_cfg) { int i; size_t size, l1size; - struct arm_smmu_device *smmu = smmu_domain->smmu; - struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg; + struct device *dev = pst_cfg->iommu_dev; + struct arm_smmu_cfg_info *cfgi = &pst_cfg->vendor.cfg; + struct arm_smmu_s1_cfg *s1cfg = cfgi->s1_cfg; + struct arm_smmu_ctx_desc_cfg *cdcfg = &s1cfg->cdcfg; if (cdcfg->l1_desc) { size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3); @@ -205,11 +237,11 @@ void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain) if (!cdcfg->l1_desc[i].l2ptr) continue; - dmam_free_coherent(smmu->dev, size, + dmam_free_coherent(dev, size, cdcfg->l1_desc[i].l2ptr, cdcfg->l1_desc[i].l2ptr_dma); } - devm_kfree(smmu->dev, cdcfg->l1_desc); + devm_kfree(dev, cdcfg->l1_desc); cdcfg->l1_desc = NULL; l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3); @@ -217,7 +249,30 @@ void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain) l1size = cdcfg->num_l1_ents * (CTXDESC_CD_DWORDS << 3); } - dmam_free_coherent(smmu->dev, l1size, cdcfg->cdtab, cdcfg->cdtab_dma); + dmam_free_coherent(dev, l1size, cdcfg->cdtab, cdcfg->cdtab_dma); cdcfg->cdtab_dma = 0; cdcfg->cdtab = NULL; } + +struct iommu_vendor_psdtable_ops arm_cd_table_ops = { + .alloc = arm_smmu_alloc_cd_tables, + .free = arm_smmu_free_cd_tables, + .prepare = arm_smmu_prepare_cd, + .write = arm_smmu_write_ctx_desc, + .sync = arm_smmu_sync_cd, +}; + +struct iommu_pasid_table *arm_smmu_register_cd_table(struct device *dev, + void *cookie) +{ + struct iommu_pasid_table *tbl; + + tbl = devm_kzalloc(dev, sizeof(tbl), GFP_KERNEL); + if (!tbl) + return NULL; + + tbl->cookie = cookie; + tbl->ops = &arm_cd_table_ops; + + return tbl; +} diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c index e13b092e6004..033eaf6c0f6c 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c @@ -11,6 +11,7 @@ #include "arm-smmu-v3.h" #include "../../iommu-sva-lib.h" #include "../../io-pgtable-arm.h" +#include "../../iommu-pasid-table.h" struct arm_smmu_mmu_notifier { struct mmu_notifier mn; @@ -48,6 +49,7 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid) struct arm_smmu_ctx_desc *cd; struct arm_smmu_device *smmu; struct arm_smmu_domain *smmu_domain; + struct iommu_pasid_table *tbl; cd = xa_load(&arm_smmu_asid_xa, asid); if (!cd) @@ -63,6 +65,7 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid) smmu_domain = container_of(cd, struct arm_smmu_domain, s1_cfg.cd); smmu = smmu_domain->smmu; + tbl = smmu_domain->tbl; ret = xa_alloc(&arm_smmu_asid_xa, &new_asid, cd, XA_LIMIT(1, (1 << smmu->asid_bits) - 1), GFP_KERNEL); @@ -79,7 +82,9 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid) * be some overlap between use of both ASIDs, until we invalidate the * TLB. */ - arm_smmu_write_ctx_desc(smmu_domain, 0, cd); + ret = iommu_psdtable_write(tbl, &tbl->cfg, 0, cd); + if (ret) + return ERR_PTR(-ENOSYS); /* Invalidate TLB entries previously associated with that context */ arm_smmu_tlb_inv_asid(smmu, asid); @@ -191,6 +196,7 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm) { struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn); struct arm_smmu_domain *smmu_domain = smmu_mn->domain; + struct iommu_pasid_table *tbl = smmu_domain->tbl; mutex_lock(&sva_lock); if (smmu_mn->cleared) { @@ -202,7 +208,7 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm) * DMA may still be running. Keep the cd valid to avoid C_BAD_CD events, * but disable translation. */ - arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, &quiet_cd); + iommu_psdtable_write(tbl, &tbl->cfg, mm->pasid, &quiet_cd); arm_smmu_tlb_inv_asid(smmu_domain->smmu, smmu_mn->cd->asid); arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, 0, 0); @@ -230,6 +236,7 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain, int ret; struct arm_smmu_ctx_desc *cd; struct arm_smmu_mmu_notifier *smmu_mn; + struct iommu_pasid_table *tbl = smmu_domain->tbl; list_for_each_entry(smmu_mn, &smmu_domain->mmu_notifiers, list) { if (smmu_mn->mn.mm == mm) { @@ -259,7 +266,7 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain, goto err_free_cd; } - ret = arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, cd); + ret = iommu_psdtable_write(tbl, &tbl->cfg, mm->pasid, cd); if (ret) goto err_put_notifier; @@ -279,12 +286,13 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn) struct mm_struct *mm = smmu_mn->mn.mm; struct arm_smmu_ctx_desc *cd = smmu_mn->cd; struct arm_smmu_domain *smmu_domain = smmu_mn->domain; + struct iommu_pasid_table *tbl = smmu_domain->tbl; if (!refcount_dec_and_test(&smmu_mn->refs)) return; list_del(&smmu_mn->list); - arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, NULL); + iommu_psdtable_write(tbl, &tbl->cfg, mm->pasid, NULL); /* * If we went through clear(), we've already invalidated, and no diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 13513f2f651a..2f86c6ac42b6 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -32,6 +32,7 @@ #include #include "arm-smmu-v3.h" +#include "../../iommu-pasid-table.h" static bool disable_bypass = true; module_param(disable_bypass, bool, 0444); @@ -894,12 +895,13 @@ void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid) arm_smmu_cmdq_issue_sync(smmu); } -void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain, int ssid, bool leaf) +void arm_smmu_sync_cd(void *cookie, int ssid, bool leaf) { size_t i; unsigned long flags; struct arm_smmu_master *master; struct arm_smmu_cmdq_batch cmds = {}; + struct arm_smmu_domain *smmu_domain = cookie; struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cmdq_ent cmd = { .opcode = CMDQ_OP_CFGI_CD, @@ -1797,6 +1799,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain) struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_s1_cfg *s1_cfg = &smmu_domain->s1_cfg; struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg; + struct iommu_pasid_table *tbl = smmu_domain->tbl; iommu_put_dma_cookie(domain); free_io_pgtable_ops(smmu_domain->pgtbl_ops); @@ -1806,7 +1809,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain) /* Prevent SVA from touching the CD while we're freeing it */ mutex_lock(&arm_smmu_asid_lock); if (s1_cfg->cdcfg.cdtab) - arm_smmu_free_cd_tables(smmu_domain); + iommu_psdtable_free(tbl, &tbl->cfg); arm_smmu_free_asid(&s1_cfg->cd); mutex_unlock(&arm_smmu_asid_lock); } @@ -1826,7 +1829,8 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain, u32 asid; struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg; - typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr; + struct iommu_vendor_psdtable_cfg *pst_cfg; + struct iommu_pasid_table *tbl; refcount_set(&cfg->cd.refs, 1); @@ -1837,29 +1841,40 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain, if (ret) goto out_unlock; + tbl = iommu_register_pasid_table(PASID_TABLE_ARM_SMMU_V3, smmu->dev, smmu_domain); + if (!tbl) { + ret = -ENOMEM; + goto out_free_asid; + } + + pst_cfg = &tbl->cfg; + + pst_cfg->iommu_dev = smmu->dev; + pst_cfg->fmt = PASID_TABLE_ARM_SMMU_V3; + pst_cfg->vendor.cfg.s1_cfg = &smmu_domain->s1_cfg; + + if (smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) + pst_cfg->vendor.cfg.feat_flag |= ARM_SMMU_FEAT_2_LVL_CDTAB; + if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE) + pst_cfg->vendor.cfg.feat_flag |= ARM_SMMU_FEAT_STALL_FORCE; + cfg->s1cdmax = master->ssid_bits; - ret = arm_smmu_alloc_cd_tables(smmu_domain); + smmu_domain->tbl = tbl; + ret = iommu_psdtable_alloc(tbl, pst_cfg); if (ret) goto out_free_asid; - cfg->cd.asid = (u16)asid; - cfg->cd.ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr; - cfg->cd.tcr = FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ, tcr->tsz) | - FIELD_PREP(CTXDESC_CD_0_TCR_TG0, tcr->tg) | - FIELD_PREP(CTXDESC_CD_0_TCR_IRGN0, tcr->irgn) | - FIELD_PREP(CTXDESC_CD_0_TCR_ORGN0, tcr->orgn) | - FIELD_PREP(CTXDESC_CD_0_TCR_SH0, tcr->sh) | - FIELD_PREP(CTXDESC_CD_0_TCR_IPS, tcr->ips) | - CTXDESC_CD_0_TCR_EPD1 | CTXDESC_CD_0_AA64; - cfg->cd.mair = pgtbl_cfg->arm_lpae_s1_cfg.mair; + ret = iommu_psdtable_prepare(tbl, pst_cfg, pgtbl_cfg, asid); + if (ret) + goto out_free_cd_tables; /* * Note that this will end up calling arm_smmu_sync_cd() before * the master has been added to the devices list for this domain. * This isn't an issue because the STE hasn't been installed yet. */ - ret = arm_smmu_write_ctx_desc(smmu_domain, 0, &cfg->cd); + ret = iommu_psdtable_write(tbl, pst_cfg, 0, &cfg->cd); if (ret) goto out_free_cd_tables; @@ -1867,7 +1882,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain, return 0; out_free_cd_tables: - arm_smmu_free_cd_tables(smmu_domain); + iommu_psdtable_free(tbl, pst_cfg); out_free_asid: arm_smmu_free_asid(&cfg->cd); out_unlock: diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h index a50a3e4874f9..7f35fbecf280 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -713,6 +713,7 @@ struct arm_smmu_domain { struct arm_smmu_s1_cfg s1_cfg; struct arm_smmu_s2_cfg s2_cfg; bool abort; + struct iommu_pasid_table *tbl; struct iommu_domain domain; @@ -782,11 +783,7 @@ extern struct xarray arm_smmu_asid_xa; extern struct mutex arm_smmu_asid_lock; extern struct arm_smmu_ctx_desc quiet_cd; -int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, - struct arm_smmu_ctx_desc *cd); -int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain); -void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain); -void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain, int ssid, bool leaf); +void arm_smmu_sync_cd(void *cookie, int ssid, bool leaf); void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid); bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd); int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid, diff --git a/drivers/iommu/iommu-pasid-table.h b/drivers/iommu/iommu-pasid-table.h index bd4f57656f67..7659157d14fa 100644 --- a/drivers/iommu/iommu-pasid-table.h +++ b/drivers/iommu/iommu-pasid-table.h @@ -123,12 +123,18 @@ static inline int iommu_psdtable_sync(struct iommu_pasid_table *tbl, return 0; } -/* A placeholder to register vendor specific pasid layer */ +struct iommu_pasid_table *arm_smmu_register_cd_table(struct device *dev, + void *cookie); + +/* Register vendor specific pasid table management layer */ static inline struct iommu_pasid_table * iommu_register_pasid_table(enum pasid_table_fmt fmt, struct device *dev, void *cookie) { - return NULL; + if (fmt == PASID_TABLE_ARM_SMMU_V3) + return arm_smmu_register_cd_table(dev, cookie); + else + return NULL; } #endif /* __IOMMU_PASID_TABLE_H */ From patchwork Fri Jan 15 12:13:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022415 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, 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 E0906C433E0 for ; Fri, 15 Jan 2021 12:16:41 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 92FCD223E0 for ; Fri, 15 Jan 2021 12:16:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 92FCD223E0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=O2k9+/50p5UdJ4VIWsCeJWQhr6W5np2g3BZ5mzyGG2Y=; b=doE2kC9WqkPknxF+1hdJabb1Yh v4heLXH6ktWS0+wfJoV7ViqFYfKryf70i//wxEvFigHNAQs9qnFvP3rUo7bq4psrBsNeK/8lU7ERp +IkhQBaMPvYef3693889EzT36A/mtLe+HTiQzqBXZodfm3XaHNcL5MUz9viaGvWRn8NQq3X97rQ0h hqDAzbrLTTkAg85Va5bWTIuj8da41eInukHF4kexB+6KejBvsZNHvIYPx5hyDxtoftBACDvhdd+10 h0YjPUQFwDfoucfQV65AHQB1a2Uffgd+3S8AJWT0E98OtNkXqoSk88AJIyIt9xa+EWnM379MSoXEQ SHCfZy+A==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzj-00077w-F6; Fri, 15 Jan 2021 12:14:23 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nza-00074z-Bf for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:17 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9E9881396; Fri, 15 Jan 2021 04:14:12 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 275AB3F70D; Fri, 15 Jan 2021 04:14:07 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 04/15] iommu/arm-smmu-v3: Update CD base address info for user-space Date: Fri, 15 Jan 2021 17:43:31 +0530 Message-Id: <20210115121342.15093-5-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071414_514600_DA36F6D2 X-CRM114-Status: GOOD ( 13.37 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Update base address information in vendor pasid table info to pass that to user-space for stage1 table management. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c index 8a7187534706..ec37476c8d09 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c @@ -55,6 +55,9 @@ static __le64 *arm_smmu_get_cd_ptr(struct iommu_vendor_psdtable_cfg *pst_cfg, if (arm_smmu_alloc_cd_leaf_table(dev, l1_desc)) return NULL; + if (s1cfg->s1fmt == STRTAB_STE_0_S1FMT_LINEAR) + pst_cfg->base = l1_desc->l2ptr_dma; + l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS; arm_smmu_write_cd_l1_desc(l1ptr, l1_desc); /* An invalid L1CD can be cached */ @@ -211,6 +214,9 @@ static int arm_smmu_alloc_cd_tables(struct iommu_vendor_psdtable_cfg *pst_cfg) goto err_free_l1; } + if (s1cfg->s1fmt == STRTAB_STE_0_S1FMT_64K_L2) + pst_cfg->base = cdcfg->cdtab_dma; + return 0; err_free_l1: From patchwork Fri Jan 15 12:13:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022419 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 6EE45C433DB for ; Fri, 15 Jan 2021 12:16:57 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 31BFC2256F for ; Fri, 15 Jan 2021 12:16:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 31BFC2256F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=HlzgK8/ojdaqLV42kbIEQlX8jQfsw/2JzKeoZw/ew3s=; b=Enje4H0nSVJfZh4baGDLLvsZUy EuDap0Z1wu6DkvZKW8y2tZ5V083rZYXISLr2gadRiXK3IHf44W7X3eLO9joRo3nxyypbekX/dT9sK Lv4INWXsoS0Wmb5+xgcrXvpQ7FErejok6qy7CzWmzSWpgiIvIgQ40Y4xAMk3Z/5KPUSOCvTzOGHjr 2W3v81rY2qrSlvjHMjZvBnIV+tK/kEIrEqtNjF619pU+27yoQqomuvYybwVrwsTOrsJxWLl87Ucxt 5+M8bbKfJlq1kex/Z86AWRUbn2AQ8YGnGXLnLH20LhVE2ltVxC2NBwd6Iguq6sBu31Y38CbBrrPx/ qfv4QMDQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzt-0007C9-6c; Fri, 15 Jan 2021 12:14:33 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzh-00077L-69 for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:23 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 97496139F; Fri, 15 Jan 2021 04:14:17 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1C3083F70D; Fri, 15 Jan 2021 04:14:12 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 05/15] iommu/arm-smmu-v3: Set sync op from consumer driver of cd-lib Date: Fri, 15 Jan 2021 17:43:32 +0530 Message-Id: <20210115121342.15093-6-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071421_472075_9B028372 X-CRM114-Status: GOOD ( 17.19 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Te change allows different consumers of arm-smmu-v3-cd-lib to set their respective sync op for pasid entries. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 1 - drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c index ec37476c8d09..acaa09acecdd 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c @@ -265,7 +265,6 @@ struct iommu_vendor_psdtable_ops arm_cd_table_ops = { .free = arm_smmu_free_cd_tables, .prepare = arm_smmu_prepare_cd, .write = arm_smmu_write_ctx_desc, - .sync = arm_smmu_sync_cd, }; struct iommu_pasid_table *arm_smmu_register_cd_table(struct device *dev, diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 2f86c6ac42b6..0c644be22b4b 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -1869,6 +1869,13 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain, if (ret) goto out_free_cd_tables; + /* + * Strange to setup an op here? + * cd-lib is the actual user of sync op, and therefore the platform + * drivers should assign this sync/maintenance ops as per need. + */ + tbl->ops->sync = arm_smmu_sync_cd; + /* * Note that this will end up calling arm_smmu_sync_cd() before * the master has been added to the devices list for this domain. From patchwork Fri Jan 15 12:13:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022411 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 4D5F4C433DB for ; Fri, 15 Jan 2021 12:16:15 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0C20320691 for ; Fri, 15 Jan 2021 12:16:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0C20320691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=LakLBI/ZjTfh09bZrnx3FDJjieMWaFVUYwf/1d4PdsY=; b=INYrJ2/U4wV+o51FVa23yKhV2E z2ZUEVca4+ZRcU8IGtQmTNv/3rLrRILEq0tRJlV9iK0hW/c3hPSjTi6nimPFZOkIObVU+OWPyRm0y NFZabrmgSuUdpaDOyAB6wZtAH5qLNHf4Cq/z4BGKZ1y89yP3L9gLupmqVd7Rjdq35rBKDfNQqvYso YjtKMA4gyEs6B/R1LjbJPTdN+17o6EQHGl6iqELPEUdur2LmXfJPYjNqdw0pWEG4yLTtd7re6/Or/ Ym+CwfN6C+/Gr5GX6OMRdUpGvZaZHAEebU76f1Q1qf+pxIMOFEcvECyocHDFV0WUAMkVR71hzbNgs 3wJoy1Zg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzz-0007EF-GS; Fri, 15 Jan 2021 12:14:39 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzn-00079n-Ff for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:29 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 87C8B13A1; Fri, 15 Jan 2021 04:14:22 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 111C63F70D; Fri, 15 Jan 2021 04:14:17 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 06/15] iommu/virtio: Add headers for table format probing Date: Fri, 15 Jan 2021 17:43:33 +0530 Message-Id: <20210115121342.15093-7-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071427_701008_E299734D X-CRM114-Status: GOOD ( 15.18 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jean-Philippe Brucker Add required UAPI defines for probing table format for underlying iommu hardware. The device may provide information about hardware tables and additional capabilities for each device. This allows guest to correctly fabricate stage-1 page tables. Signed-off-by: Jean-Philippe Brucker [Vivek: Use a single "struct virtio_iommu_probe_table_format" rather than separate structures for page table and pasid table format. Also update commit message.] Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- include/uapi/linux/virtio_iommu.h | 44 ++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/virtio_iommu.h b/include/uapi/linux/virtio_iommu.h index 237e36a280cb..43821e33e7af 100644 --- a/include/uapi/linux/virtio_iommu.h +++ b/include/uapi/linux/virtio_iommu.h @@ -2,7 +2,7 @@ /* * Virtio-iommu definition v0.12 * - * Copyright (C) 2019 Arm Ltd. + * Copyright (C) 2019-2021 Arm Ltd. */ #ifndef _UAPI_LINUX_VIRTIO_IOMMU_H #define _UAPI_LINUX_VIRTIO_IOMMU_H @@ -111,6 +111,12 @@ struct virtio_iommu_req_unmap { #define VIRTIO_IOMMU_PROBE_T_NONE 0 #define VIRTIO_IOMMU_PROBE_T_RESV_MEM 1 +#define VIRTIO_IOMMU_PROBE_T_PAGE_SIZE_MASK 2 +#define VIRTIO_IOMMU_PROBE_T_INPUT_RANGE 3 +#define VIRTIO_IOMMU_PROBE_T_OUTPUT_SIZE 4 +#define VIRTIO_IOMMU_PROBE_T_PASID_SIZE 5 +#define VIRTIO_IOMMU_PROBE_T_PAGE_TABLE_FMT 6 +#define VIRTIO_IOMMU_PROBE_T_PASID_TABLE_FMT 7 #define VIRTIO_IOMMU_PROBE_T_MASK 0xfff @@ -130,6 +136,42 @@ struct virtio_iommu_probe_resv_mem { __le64 end; }; +struct virtio_iommu_probe_page_size_mask { + struct virtio_iommu_probe_property head; + __u8 reserved[4]; + __le64 mask; +}; + +struct virtio_iommu_probe_input_range { + struct virtio_iommu_probe_property head; + __u8 reserved[4]; + __le64 start; + __le64 end; +}; + +struct virtio_iommu_probe_output_size { + struct virtio_iommu_probe_property head; + __u8 bits; + __u8 reserved[3]; +}; + +struct virtio_iommu_probe_pasid_size { + struct virtio_iommu_probe_property head; + __u8 bits; + __u8 reserved[3]; +}; + +/* Arm LPAE page table format */ +#define VIRTIO_IOMMU_FOMRAT_PGTF_ARM_LPAE 1 +/* Arm smmu-v3 type PASID table format */ +#define VIRTIO_IOMMU_FORMAT_PSTF_ARM_SMMU_V3 2 + +struct virtio_iommu_probe_table_format { + struct virtio_iommu_probe_property head; + __le16 format; + __u8 reserved[2]; +}; + struct virtio_iommu_req_probe { struct virtio_iommu_req_head head; __le32 endpoint; From patchwork Fri Jan 15 12:13:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022423 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 E1C73C433E6 for ; Fri, 15 Jan 2021 12:17:05 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9722E20691 for ; Fri, 15 Jan 2021 12:17:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9722E20691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=AYb+A67OnT7JnMXW23qbbEEdRNJwFlAmj8jvYYajD2A=; b=TKIhcq6u/OXpuFLafEfZyRZP44 0lSCkneAzzLEjVxEgqcDtTr1QqKMGKGWbkkHtrQLM75JaQ0mp8hD+vO9jsbL7RmQPM57FEeRCmzCb fQouvKpwpAB/RfoTSDBNbUaF8xGgGUCIhSvGZPikpt3zkA4V756tl7yjv0lJOtsaezn/iAqG+UGui uKW4+z5EN+QDHF3SbIXOSfq/Ou1FtAm38AvRtEKCIFC5hoWWrRSfgy1f8Xqqlsg+LBOu9ML6PtUt4 0RCa+bzqwnpoCD9HWdv3JNgVpq17jxl/TllHm4gMjkkq0le3RJ2mCgHgBbJLJ/+7GscNUxDUwSzTw kW08B1VQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0B-0007Il-C6; Fri, 15 Jan 2021 12:14:51 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzo-0007Ae-N0 for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:31 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7D53313D5; Fri, 15 Jan 2021 04:14:27 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 069603F70D; Fri, 15 Jan 2021 04:14:22 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 07/15] iommu/virtio: Add table format probing Date: Fri, 15 Jan 2021 17:43:34 +0530 Message-Id: <20210115121342.15093-8-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071428_903442_7F5FDA11 X-CRM114-Status: GOOD ( 19.19 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jean-Philippe Brucker The device may provide information about hardware tables and additional capabilities for each device. Parse the new probe fields. Signed-off-by: Jean-Philippe Brucker [Vivek: Refactor to use "struct virtio_iommu_probe_table_format" rather than separate structures for page table and pasid table format.] Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/virtio-iommu.c | 102 ++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 2bfdd5734844..12d73321dbf4 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -78,6 +78,17 @@ struct viommu_endpoint { struct viommu_dev *viommu; struct viommu_domain *vdomain; struct list_head resv_regions; + + /* properties of the physical IOMMU */ + u64 pgsize_mask; + u64 input_start; + u64 input_end; + u8 output_bits; + u8 pasid_bits; + /* Preferred PASID table format */ + void *pstf; + /* Preferred page table format */ + void *pgtf; }; struct viommu_request { @@ -457,6 +468,72 @@ static int viommu_add_resv_mem(struct viommu_endpoint *vdev, return 0; } +static int viommu_add_pgsize_mask(struct viommu_endpoint *vdev, + struct virtio_iommu_probe_page_size_mask *prop, + size_t len) +{ + if (len < sizeof(*prop)) + return -EINVAL; + vdev->pgsize_mask = le64_to_cpu(prop->mask); + return 0; +} + +static int viommu_add_input_range(struct viommu_endpoint *vdev, + struct virtio_iommu_probe_input_range *prop, + size_t len) +{ + if (len < sizeof(*prop)) + return -EINVAL; + vdev->input_start = le64_to_cpu(prop->start); + vdev->input_end = le64_to_cpu(prop->end); + return 0; +} + +static int viommu_add_output_size(struct viommu_endpoint *vdev, + struct virtio_iommu_probe_output_size *prop, + size_t len) +{ + if (len < sizeof(*prop)) + return -EINVAL; + vdev->output_bits = prop->bits; + return 0; +} + +static int viommu_add_pasid_size(struct viommu_endpoint *vdev, + struct virtio_iommu_probe_pasid_size *prop, + size_t len) +{ + if (len < sizeof(*prop)) + return -EINVAL; + vdev->pasid_bits = prop->bits; + return 0; +} + +static int viommu_add_pgtf(struct viommu_endpoint *vdev, void *pgtf, size_t len) +{ + /* Select the first page table format available */ + if (len < sizeof(struct virtio_iommu_probe_table_format) || vdev->pgtf) + return -EINVAL; + + vdev->pgtf = kmemdup(pgtf, len, GFP_KERNEL); + if (!vdev->pgtf) + return -ENOMEM; + + return 0; +} + +static int viommu_add_pstf(struct viommu_endpoint *vdev, void *pstf, size_t len) +{ + if (len < sizeof(struct virtio_iommu_probe_table_format) || vdev->pstf) + return -EINVAL; + + vdev->pstf = kmemdup(pstf, len, GFP_KERNEL); + if (!vdev->pstf) + return -ENOMEM; + + return 0; +} + static int viommu_probe_endpoint(struct viommu_dev *viommu, struct device *dev) { int ret; @@ -493,11 +570,30 @@ static int viommu_probe_endpoint(struct viommu_dev *viommu, struct device *dev) while (type != VIRTIO_IOMMU_PROBE_T_NONE && cur < viommu->probe_size) { + void *value = prop; len = le16_to_cpu(prop->length) + sizeof(*prop); switch (type) { case VIRTIO_IOMMU_PROBE_T_RESV_MEM: - ret = viommu_add_resv_mem(vdev, (void *)prop, len); + ret = viommu_add_resv_mem(vdev, value, len); + break; + case VIRTIO_IOMMU_PROBE_T_PAGE_SIZE_MASK: + ret = viommu_add_pgsize_mask(vdev, value, len); + break; + case VIRTIO_IOMMU_PROBE_T_INPUT_RANGE: + ret = viommu_add_input_range(vdev, value, len); + break; + case VIRTIO_IOMMU_PROBE_T_OUTPUT_SIZE: + ret = viommu_add_output_size(vdev, value, len); + break; + case VIRTIO_IOMMU_PROBE_T_PASID_SIZE: + ret = viommu_add_pasid_size(vdev, value, len); + break; + case VIRTIO_IOMMU_PROBE_T_PAGE_TABLE_FMT: + ret = viommu_add_pgtf(vdev, value, len); + break; + case VIRTIO_IOMMU_PROBE_T_PASID_TABLE_FMT: + ret = viommu_add_pstf(vdev, value, len); break; default: dev_err(dev, "unknown viommu prop 0x%x\n", type); @@ -899,6 +995,8 @@ static struct iommu_device *viommu_probe_device(struct device *dev) err_free_dev: generic_iommu_put_resv_regions(dev, &vdev->resv_regions); + kfree(vdev->pstf); + kfree(vdev->pgtf); kfree(vdev); return ERR_PTR(ret); @@ -915,6 +1013,8 @@ static void viommu_release_device(struct device *dev) vdev = dev_iommu_priv_get(dev); generic_iommu_put_resv_regions(dev, &vdev->resv_regions); + kfree(vdev->pstf); + kfree(vdev->pgtf); kfree(vdev); } From patchwork Fri Jan 15 12:13:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022429 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, 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 1E5D4C433DB for ; Fri, 15 Jan 2021 12:17:17 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D4BD120691 for ; Fri, 15 Jan 2021 12:17:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D4BD120691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=4v0rMIPX7mKEoog5tMvaOJuZk1JAKIEdtelCZ/v3zTE=; b=hP3xuFaDO4Iy7x1xt/lg9YXHVc XNleHO7N+geekO//1nYigA3bwhjR5fOXL/lNjhpJOo2YK2rJIFgQvvGGbrJT9rnaUXNdHgXLVMEzS +CRe2MYCJKUT4bZYxgtPt0LhackpIeiEWiOOaOH8ktXyAfv7SfjIVfGmv/MWADCjAwUlCA/nf3aM6 x8YiAY1kEEpxAybf7Pm0c7UwHFfZZJbHh0TRN1TZCJozkhqs9Xt2r0bqHHOsit+Pu54o+DgxeIkHf hGAkYESe0RwJ8im6l7GdgDG2fQ6YYxIHqKhGuki1HFKFfMl8aTe0IaMEdnmZZUkr9wetDKVRTT4LJ 8fFmBvFw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0P-0007Nn-DU; Fri, 15 Jan 2021 12:15:05 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzt-0007CK-Bx for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:34 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7BC48143B; Fri, 15 Jan 2021 04:14:32 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id F065D3F70D; Fri, 15 Jan 2021 04:14:27 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 08/15] iommu: Add asid_bits to arm smmu-v3 stage1 table info Date: Fri, 15 Jan 2021 17:43:35 +0530 Message-Id: <20210115121342.15093-9-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071433_491778_7686920F X-CRM114-Status: GOOD ( 13.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org aisd_bits data is required to prepare stage-1 tables for arm-smmu-v3. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- include/uapi/linux/iommu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h index 082d758dd016..96abbfc7c643 100644 --- a/include/uapi/linux/iommu.h +++ b/include/uapi/linux/iommu.h @@ -357,7 +357,7 @@ struct iommu_pasid_smmuv3 { __u32 version; __u8 s1fmt; __u8 s1dss; - __u8 padding[2]; + __u16 asid_bits; }; /** From patchwork Fri Jan 15 12:13:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022417 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, 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 86A7CC433DB for ; Fri, 15 Jan 2021 12:16:46 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 11BAC20691 for ; Fri, 15 Jan 2021 12:16:46 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 11BAC20691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=HFOcmfRGE80jfNr+GWWOKPGlLU8d8waGYsTZOEIcRWY=; b=i3vUrxIWmncK/W77s8rnH0DPP3 8baq82C0sB0F4D+UnFJrfdRquhvGVMCiGKSq+6MrY8GOn7sJ0hH1rwHx7d11pcyI99IMKZER6DZF1 dePmV9d1UU1ODNvC0uZwF9pV5d1QjnHFG/xAwwj2AMjSycI7lV6IWyrV7f/M1g9ZDccpOXp0+BmOd UC39aKNLQLv9BjfxUrYQeH1dwXcPSpWUKFG57sf2iBp4dimrj/dPDjPnCR5pXfjx3vnFwLKlVB6Pl uoAoOMe/xrWFEuW9EJrLngvXj84bUebu7w96e9rwM/3IXkKD0JMVszuhb+pFx+6RWBleaCL2kHthP 50YOUaTw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0c-0007V6-G4; Fri, 15 Jan 2021 12:15:18 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0Nzy-0007E7-3a for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:39 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 79D251474; Fri, 15 Jan 2021 04:14:37 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id EDEF23F70D; Fri, 15 Jan 2021 04:14:32 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 09/15] iommu/virtio: Update table format probing header Date: Fri, 15 Jan 2021 17:43:36 +0530 Message-Id: <20210115121342.15093-10-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071438_232521_2B870E80 X-CRM114-Status: GOOD ( 12.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add info about asid_bits and additional flags to table format probing header. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- include/uapi/linux/virtio_iommu.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/virtio_iommu.h b/include/uapi/linux/virtio_iommu.h index 43821e33e7af..8a0624bab4b2 100644 --- a/include/uapi/linux/virtio_iommu.h +++ b/include/uapi/linux/virtio_iommu.h @@ -169,7 +169,10 @@ struct virtio_iommu_probe_pasid_size { struct virtio_iommu_probe_table_format { struct virtio_iommu_probe_property head; __le16 format; - __u8 reserved[2]; + __le16 asid_bits; + + __le32 flags; + __u8 reserved[4]; }; struct virtio_iommu_req_probe { From patchwork Fri Jan 15 12:13:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022421 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 DC7C3C433DB for ; Fri, 15 Jan 2021 12:17:03 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 981CF20691 for ; Fri, 15 Jan 2021 12:17:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 981CF20691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=axhHUhw+91w7FfOqh1hCJPcVUNkfHuHFBbbFIunmRJA=; b=oGvvUB2A1wQRyk6ls+pZYJvsk7 3lI9npqNKPDdRk1KiI+Y3CjXg9FzEbpVXZEKPGAhMvBpcemgEmHCgnO1H7893drQiNKb/uIWjYkqx uZBCXjbQwaUSbjLh1Q1MPHgxvxMAzFn2jMEiRxRYbPmOTGvRVvsiCa1+c1NzR8N1XrrI4JzXNAPZN +5zXDGJfMtNECnsY4viusJRbBGcp9zno6BFx/0RH3dfQ+pX8wOJxeunpAp9gIOTJQLPUS/lUtM7dJ aeM99amIkad2Mm2w4jl00DBxRxPpo++TmlLWcH+2dk9z8SF/1ZI2wrGy1JYN8XkdK/1EdeLpafIK6 gYNspfDA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0k-0007Ys-Dt; Fri, 15 Jan 2021 12:15:26 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O03-0007GV-Ei for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:53 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6EE1C14BF; Fri, 15 Jan 2021 04:14:42 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id EC5FA3F70D; Fri, 15 Jan 2021 04:14:37 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 10/15] iommu/virtio: Prepare to add attach pasid table infrastructure Date: Fri, 15 Jan 2021 17:43:37 +0530 Message-Id: <20210115121342.15093-11-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071443_636627_D591AE8F X-CRM114-Status: GOOD ( 21.24 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org In preparation to add attach pasid table op, separate out the existing attach request code to a separate method. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/virtio-iommu.c | 73 +++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 12d73321dbf4..ae5dfd3f8269 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -52,6 +52,8 @@ struct viommu_dev { /* Supported MAP flags */ u32 map_flags; u32 probe_size; + + bool has_map:1; }; struct viommu_mapping { @@ -60,6 +62,11 @@ struct viommu_mapping { u32 flags; }; +struct viommu_mm { + struct io_pgtable_ops *ops; + struct viommu_domain *domain; +}; + struct viommu_domain { struct iommu_domain domain; struct viommu_dev *viommu; @@ -67,12 +74,20 @@ struct viommu_domain { unsigned int id; u32 map_flags; + /* Default address space when a table is bound */ + struct viommu_mm mm; + + /* When no table is bound, use generic mappings */ spinlock_t mappings_lock; struct rb_root_cached mappings; unsigned long nr_endpoints; }; +#define vdev_for_each_id(i, eid, vdev) \ + for (i = 0; i < vdev->dev->iommu->fwspec->num_ids && \ + ({ eid = vdev->dev->iommu->fwspec->ids[i]; 1; }); i++) + struct viommu_endpoint { struct device *dev; struct viommu_dev *viommu; @@ -750,12 +765,40 @@ static void viommu_domain_free(struct iommu_domain *domain) kfree(vdomain); } +static int viommu_simple_attach(struct viommu_domain *vdomain, + struct viommu_endpoint *vdev) +{ + int i, eid, ret; + struct virtio_iommu_req_attach req = { + .head.type = VIRTIO_IOMMU_T_ATTACH, + .domain = cpu_to_le32(vdomain->id), + }; + + if (!vdomain->viommu->has_map) + return -ENODEV; + + vdev_for_each_id(i, eid, vdev) { + req.endpoint = cpu_to_le32(eid); + + ret = viommu_send_req_sync(vdomain->viommu, &req, sizeof(req)); + if (ret) + return ret; + } + + if (!vdomain->nr_endpoints) { + /* + * This endpoint is the first to be attached to the domain. + * Replay existing mappings if any (e.g. SW MSI). + */ + ret = viommu_replay_mappings(vdomain); + } + + return ret; +} + static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) { - int i; int ret = 0; - struct virtio_iommu_req_attach req; - struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct viommu_endpoint *vdev = dev_iommu_priv_get(dev); struct viommu_domain *vdomain = to_viommu_domain(domain); @@ -790,25 +833,9 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) if (vdev->vdomain) vdev->vdomain->nr_endpoints--; - req = (struct virtio_iommu_req_attach) { - .head.type = VIRTIO_IOMMU_T_ATTACH, - .domain = cpu_to_le32(vdomain->id), - }; - - for (i = 0; i < fwspec->num_ids; i++) { - req.endpoint = cpu_to_le32(fwspec->ids[i]); - - ret = viommu_send_req_sync(vdomain->viommu, &req, sizeof(req)); - if (ret) - return ret; - } - - if (!vdomain->nr_endpoints) { - /* - * This endpoint is the first to be attached to the domain. - * Replay existing mappings (e.g. SW MSI). - */ - ret = viommu_replay_mappings(vdomain); + if (!vdomain->mm.ops) { + /* If we couldn't bind any table, use the mapping tree */ + ret = viommu_simple_attach(vdomain, vdev); if (ret) return ret; } @@ -1142,6 +1169,8 @@ static int viommu_probe(struct virtio_device *vdev) struct virtio_iommu_config, probe_size, &viommu->probe_size); + viommu->has_map = virtio_has_feature(vdev, VIRTIO_IOMMU_F_MAP_UNMAP); + viommu->geometry = (struct iommu_domain_geometry) { .aperture_start = input_start, .aperture_end = input_end, From patchwork Fri Jan 15 12:13:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022425 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 1CBA1C433DB for ; Fri, 15 Jan 2021 12:17:12 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D2866206D4 for ; Fri, 15 Jan 2021 12:17:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D2866206D4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=ZoW/dh0E65eYesjSp6QmXYs1/bPeIF9umjkrT1rIU3c=; b=y1cK/7+a8LFgnGQ4Dc/BkYh/LK CN+i7OF3rS4HTgd90TyJyjaa4MW6r2MYa5dPFYvb4O+Li970TOLdWMYxS9CAo8i/8z0fsH3MtbF03 Rav96e1TgRm8pw6xbHKASEMgPGN1sjRWSxPqND9PV2Zs5Eyu+cNr8763TnVqneA84D4B7b0ACUfq+ tWCbXiqlL3YVKhMCOpPIj9MZ379R3Nr9t2VskQv2YGCAuftr+FLEM7PzA6nMQQSz3Ck0WzIdj583Q ZGgRukJhEh4yagwHI7q2pth3Rst6Tw++7eiYCFcuGLLfHBrfl6ArLkZvvihb0eokQ2DTZ4XBSfOic eT6rH2Sw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0p-0007bL-OT; Fri, 15 Jan 2021 12:15:31 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O08-0007Ik-6Z for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:56 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 62FA11480; Fri, 15 Jan 2021 04:14:47 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id E01B63F70D; Fri, 15 Jan 2021 04:14:42 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 11/15] iommu/virtio: Add headers for binding pasid table in iommu Date: Fri, 15 Jan 2021 17:43:38 +0530 Message-Id: <20210115121342.15093-12-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071448_386887_A837A889 X-CRM114-Status: GOOD ( 14.03 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jean-Philippe Brucker Add the required UAPI defines for binding pasid tables in virtio-iommu. This mode allows to hand stage-1 page tables over to the guest. Signed-off-by: Jean-Philippe Brucker [Vivek: Refactor to cleanup headers for invalidation] Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- include/uapi/linux/virtio_iommu.h | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/include/uapi/linux/virtio_iommu.h b/include/uapi/linux/virtio_iommu.h index 8a0624bab4b2..3481e4a3dd24 100644 --- a/include/uapi/linux/virtio_iommu.h +++ b/include/uapi/linux/virtio_iommu.h @@ -16,6 +16,7 @@ #define VIRTIO_IOMMU_F_BYPASS 3 #define VIRTIO_IOMMU_F_PROBE 4 #define VIRTIO_IOMMU_F_MMIO 5 +#define VIRTIO_IOMMU_F_ATTACH_TABLE 6 struct virtio_iommu_range_64 { __le64 start; @@ -44,6 +45,8 @@ struct virtio_iommu_config { #define VIRTIO_IOMMU_T_MAP 0x03 #define VIRTIO_IOMMU_T_UNMAP 0x04 #define VIRTIO_IOMMU_T_PROBE 0x05 +#define VIRTIO_IOMMU_T_ATTACH_TABLE 0x06 +#define VIRTIO_IOMMU_T_INVALIDATE 0x07 /* Status types */ #define VIRTIO_IOMMU_S_OK 0x00 @@ -82,6 +85,37 @@ struct virtio_iommu_req_detach { struct virtio_iommu_req_tail tail; }; +struct virtio_iommu_req_attach_table { + struct virtio_iommu_req_head head; + __le32 domain; + __le32 endpoint; + __le16 format; + __u8 reserved[62]; + struct virtio_iommu_req_tail tail; +}; + +#define VIRTIO_IOMMU_PSTF_ARM_SMMU_V3_LINEAR 0x0 +#define VIRTIO_IOMMU_PSTF_ARM_SMMU_V3_4KL2 0x1 +#define VIRTIO_IOMMU_PSTF_ARM_SMMU_V3_64KL2 0x2 + +#define VIRTIO_IOMMU_PSTF_ARM_SMMU_V3_DSS_TERM 0x0 +#define VIRTIO_IOMMU_PSTF_ARM_SMMU_V3_DSS_BYPASS 0x1 +#define VIRTIO_IOMMU_PSTF_ARM_SMMU_V3_DSS_0 0x2 + +/* Arm SMMUv3 PASID Table Descriptor */ +struct virtio_iommu_req_attach_pst_arm { + struct virtio_iommu_req_head head; + __le32 domain; + __le32 endpoint; + __le16 format; + __u8 s1fmt; + __u8 s1dss; + __le64 s1contextptr; + __le32 s1cdmax; + __u8 reserved[48]; + struct virtio_iommu_req_tail tail; +}; + #define VIRTIO_IOMMU_MAP_F_READ (1 << 0) #define VIRTIO_IOMMU_MAP_F_WRITE (1 << 1) #define VIRTIO_IOMMU_MAP_F_MMIO (1 << 2) @@ -188,6 +222,40 @@ struct virtio_iommu_req_probe { */ }; +#define VIRTIO_IOMMU_INVAL_G_DOMAIN (1 << 0) +#define VIRTIO_IOMMU_INVAL_G_PASID (1 << 1) +#define VIRTIO_IOMMU_INVAL_G_VA (1 << 2) + +#define VIRTIO_IOMMU_INV_T_IOTLB (1 << 0) +#define VIRTIO_IOMMU_INV_T_DEV_IOTLB (1 << 1) +#define VIRTIO_IOMMU_INV_T_PASID (1 << 2) + +#define VIRTIO_IOMMU_INVAL_F_PASID (1 << 0) +#define VIRTIO_IOMMU_INVAL_F_ARCHID (1 << 1) +#define VIRTIO_IOMMU_INVAL_F_LEAF (1 << 2) + +struct virtio_iommu_req_invalidate { + struct virtio_iommu_req_head head; + __le16 inv_gran; + __le16 inv_type; + + __le16 flags; + __u8 reserved1[2]; + __le32 domain; + + __le32 pasid; + __u8 reserved2[4]; + + __le64 archid; + __le64 virt_start; + __le64 nr_pages; + + /* Page size, in nr of bits, typically 12 for 4k, 30 for 2MB, etc.) */ + __u8 granule; + __u8 reserved3[11]; + struct virtio_iommu_req_tail tail; +}; + /* Fault types */ #define VIRTIO_IOMMU_FAULT_R_UNKNOWN 0 #define VIRTIO_IOMMU_FAULT_R_DOMAIN 1 From patchwork Fri Jan 15 12:13:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022427 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=-14.2 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 1470DC433E0 for ; Fri, 15 Jan 2021 12:17:12 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CFDFD20691 for ; Fri, 15 Jan 2021 12:17:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CFDFD20691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=fqVymV5BX6YHk1CbaAXU8s12G1HzuwtnUCl4jXzSUfk=; b=wWzk0GllUXM969mOiwGarNLYJv OAR2D/t4zxYDo10B0jiDE0XXu5S8FYUCpTedI1mbN8EAa+BQ8xwNqmI0Xg5lG1Oblbn31pWD0+KU7 P+pcrvOiXiwCiAtDUAKtHNYn/DaFPwc72mkg7Ds4WG/+PG+2iZPutI/0hhz4pwfIUa3k+sUYiruo2 qJvmCXXg/N9AT2aAx0Ba5nJaOp0bL2jFJ9Qo7hwpaV3Q37xz9YNgIQ/bI7xxXkicrQpsVAmjd+OVP H7pUYY072DZRumVkp34KpOqaUV6eP91n404ElVtuPNaeKMqJ1hjBRmRvnmH+x4xDdWoy3cu1Cs2n5 Xi5Ofdmw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0u-0007eD-Mn; Fri, 15 Jan 2021 12:15:36 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0D-0007KW-CE for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:14:57 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 57C4214F6; Fri, 15 Jan 2021 04:14:52 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D41F23F70D; Fri, 15 Jan 2021 04:14:47 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 12/15] iommu/virtio: Add support for INVALIDATE request Date: Fri, 15 Jan 2021 17:43:39 +0530 Message-Id: <20210115121342.15093-13-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071453_613879_15A80E8F X-CRM114-Status: GOOD ( 18.26 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jean-Philippe Brucker Add support for tlb invalidation ops that can send invalidation requests to back-end virtio-iommu when stage-1 page tables are supported. Signed-off-by: Jean-Philippe Brucker [Vivek: Refactoring the iommu_flush_ops, and adding only one pasid sync op that's needed with current iommu-pasid-table infrastructure. Also updating uapi defines as required by latest changes] Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/virtio-iommu.c | 95 ++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index ae5dfd3f8269..004ea94e3731 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,8 @@ struct viommu_mapping { }; struct viommu_mm { + int pasid; + u64 archid; struct io_pgtable_ops *ops; struct viommu_domain *domain; }; @@ -692,6 +695,98 @@ static void viommu_event_handler(struct virtqueue *vq) virtqueue_kick(vq); } +/* PASID and pgtable APIs */ + +static void __viommu_flush_pasid_tlb_all(struct viommu_domain *vdomain, + int pasid, u64 arch_id, int type) +{ + struct virtio_iommu_req_invalidate req = { + .head.type = VIRTIO_IOMMU_T_INVALIDATE, + .inv_gran = cpu_to_le32(VIRTIO_IOMMU_INVAL_G_PASID), + .flags = cpu_to_le32(VIRTIO_IOMMU_INVAL_F_PASID), + .inv_type = cpu_to_le32(type), + + .domain = cpu_to_le32(vdomain->id), + .pasid = cpu_to_le32(pasid), + .archid = cpu_to_le64(arch_id), + }; + + if (viommu_send_req_sync(vdomain->viommu, &req, sizeof(req))) + pr_debug("could not send invalidate request\n"); +} + +static void viommu_flush_tlb_add(struct iommu_iotlb_gather *gather, + unsigned long iova, size_t granule, + void *cookie) +{ + struct viommu_mm *viommu_mm = cookie; + struct viommu_domain *vdomain = viommu_mm->domain; + struct iommu_domain *domain = &vdomain->domain; + + iommu_iotlb_gather_add_page(domain, gather, iova, granule); +} + +static void viommu_flush_tlb_walk(unsigned long iova, size_t size, + size_t granule, void *cookie) +{ + struct viommu_mm *viommu_mm = cookie; + struct viommu_domain *vdomain = viommu_mm->domain; + struct virtio_iommu_req_invalidate req = { + .head.type = VIRTIO_IOMMU_T_INVALIDATE, + .inv_gran = cpu_to_le32(VIRTIO_IOMMU_INVAL_G_VA), + .inv_type = cpu_to_le32(VIRTIO_IOMMU_INV_T_IOTLB), + .flags = cpu_to_le32(VIRTIO_IOMMU_INVAL_F_ARCHID), + + .domain = cpu_to_le32(vdomain->id), + .pasid = cpu_to_le32(viommu_mm->pasid), + .archid = cpu_to_le64(viommu_mm->archid), + .virt_start = cpu_to_le64(iova), + .nr_pages = cpu_to_le64(size / granule), + .granule = ilog2(granule), + }; + + if (viommu_add_req(vdomain->viommu, &req, sizeof(req))) + pr_debug("could not add invalidate request\n"); +} + +static void viommu_flush_tlb_all(void *cookie) +{ + struct viommu_mm *viommu_mm = cookie; + + if (!viommu_mm->archid) + return; + + __viommu_flush_pasid_tlb_all(viommu_mm->domain, viommu_mm->pasid, + viommu_mm->archid, + VIRTIO_IOMMU_INV_T_IOTLB); +} + +static struct iommu_flush_ops viommu_flush_ops = { + .tlb_flush_all = viommu_flush_tlb_all, + .tlb_flush_walk = viommu_flush_tlb_walk, + .tlb_add_page = viommu_flush_tlb_add, +}; + +static void viommu_flush_pasid(void *cookie, int pasid, bool leaf) +{ + struct viommu_domain *vdomain = cookie; + struct virtio_iommu_req_invalidate req = { + .head.type = VIRTIO_IOMMU_T_INVALIDATE, + .inv_gran = cpu_to_le32(VIRTIO_IOMMU_INVAL_G_PASID), + .inv_type = cpu_to_le32(VIRTIO_IOMMU_INV_T_PASID), + .flags = cpu_to_le32(VIRTIO_IOMMU_INVAL_F_PASID), + + .domain = cpu_to_le32(vdomain->id), + .pasid = cpu_to_le32(pasid), + }; + + if (leaf) + req.flags |= cpu_to_le32(VIRTIO_IOMMU_INVAL_F_LEAF); + + if (viommu_send_req_sync(vdomain->viommu, &req, sizeof(req))) + pr_debug("could not send invalidate request\n"); +} + /* IOMMU API */ static struct iommu_domain *viommu_domain_alloc(unsigned type) From patchwork Fri Jan 15 12:13:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022431 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 D11ADC433E0 for ; Fri, 15 Jan 2021 12:17:22 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8725620691 for ; Fri, 15 Jan 2021 12:17:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8725620691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=PE5+rmGlugSuTtKIt12OmTYSiSqD85plsBWQGz0tCEE=; b=1reNF5E53Csmr553vRXYXMpTxe pMAs+zlbw6BmL/vxp4CrTni8qjLH9IgALiunZGbD3aQkpIC75ECndWBp6cNfDnx1kz73iS76x4lUq USKgwv82KVnGi/qWIAChBj9QBq3RWhMMyBIBEsV+WynHYPeIJ0zEFd2lX6N4wa/61YJWoCWVUE8jD 9rEkFeTlO8+Szrjqim0SQ8Og8qGnOh2ihpQAYJSSsOBDcqVh+nVJ22Lz0qZnsib+vtFVZRcDtE2mp hLzBGHxE0NkOcMvsvoBdii+LBKwdaSTKoRNU2czVDFUmaZi2hVdE/fYx0aC2FfXFiTC4dOtAHavcq TGoe7qjw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O15-0007lo-Gt; Fri, 15 Jan 2021 12:15:47 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0I-0007NE-AD for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:15:06 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4D06E1509; Fri, 15 Jan 2021 04:14:57 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C9F1A3F70D; Fri, 15 Jan 2021 04:14:52 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 13/15] iommu/virtio: Attach Arm PASID tables when available Date: Fri, 15 Jan 2021 17:43:40 +0530 Message-Id: <20210115121342.15093-14-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071459_528734_DC82C9AB X-CRM114-Status: GOOD ( 27.39 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jean-Philippe Brucker When the ARM PASID table format is reported in a probe, send an attach request and install the page tables for iommu_map/iommu_unmap use. Architecture-specific components are already abstracted to libraries. We just need to pass config bits around and setup an alternative mechanism to the mapping tree. We reuse the convention already adopted by other IOMMU architectures (ARM SMMU and AMD IOMMU), that entry 0 in the PASID table is reserved for non-PASID traffic. Bind the PASID table, and setup entry 0 to be modified with iommu_map/unmap. Signed-off-by: Jean-Philippe Brucker [Vivek: Bunch of refactoring and clean-ups to use iommu-pasid-table APIs, creating iommu_pasid_table, and configuring based on reported pasid format. Couple of additional methods have also been created to configure vendor specific pasid configuration] Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/virtio-iommu.c | 314 +++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 004ea94e3731..b5222da1dc74 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -25,6 +25,7 @@ #include #include +#include "iommu-pasid-table.h" #define MSI_IOVA_BASE 0x8000000 #define MSI_IOVA_LENGTH 0x100000 @@ -33,6 +34,9 @@ #define VIOMMU_EVENT_VQ 1 #define VIOMMU_NR_VQS 2 +/* Some architectures need an Address Space ID for each page table */ +static DEFINE_IDA(asid_ida); + struct viommu_dev { struct iommu_device iommu; struct device *dev; @@ -55,6 +59,7 @@ struct viommu_dev { u32 probe_size; bool has_map:1; + bool has_table:1; }; struct viommu_mapping { @@ -76,6 +81,7 @@ struct viommu_domain { struct mutex mutex; /* protects viommu pointer */ unsigned int id; u32 map_flags; + struct iommu_pasid_table *pasid_tbl; /* Default address space when a table is bound */ struct viommu_mm mm; @@ -891,6 +897,285 @@ static int viommu_simple_attach(struct viommu_domain *vdomain, return ret; } +static int viommu_teardown_pgtable(struct viommu_domain *vdomain) +{ + struct iommu_vendor_psdtable_cfg *pst_cfg; + struct arm_smmu_cfg_info *cfgi; + u32 asid; + + if (!vdomain->mm.ops) + return 0; + + free_io_pgtable_ops(vdomain->mm.ops); + vdomain->mm.ops = NULL; + + if (vdomain->pasid_tbl) { + pst_cfg = &vdomain->pasid_tbl->cfg; + cfgi = &pst_cfg->vendor.cfg; + asid = cfgi->s1_cfg->cd.asid; + + iommu_psdtable_write(vdomain->pasid_tbl, pst_cfg, 0, NULL); + ida_simple_remove(&asid_ida, asid); + } + + return 0; +} + +static int viommu_setup_pgtable(struct viommu_endpoint *vdev, + struct viommu_domain *vdomain) +{ + int ret, id; + u32 asid; + enum io_pgtable_fmt fmt; + struct io_pgtable_ops *ops = NULL; + struct viommu_dev *viommu = vdev->viommu; + struct virtio_iommu_probe_table_format *desc = vdev->pgtf; + struct iommu_pasid_table *tbl = vdomain->pasid_tbl; + struct iommu_vendor_psdtable_cfg *pst_cfg; + struct arm_smmu_cfg_info *cfgi; + struct io_pgtable_cfg cfg = { + .iommu_dev = viommu->dev->parent, + .tlb = &viommu_flush_ops, + .pgsize_bitmap = vdev->pgsize_mask ? vdev->pgsize_mask : + vdomain->domain.pgsize_bitmap, + .ias = (vdev->input_end ? ilog2(vdev->input_end) : + ilog2(vdomain->domain.geometry.aperture_end)) + 1, + .oas = vdev->output_bits, + }; + + if (!desc) + return -EINVAL; + + if (!vdev->output_bits) + return -ENODEV; + + switch (le16_to_cpu(desc->format)) { + case VIRTIO_IOMMU_FOMRAT_PGTF_ARM_LPAE: + fmt = ARM_64_LPAE_S1; + break; + default: + dev_err(vdev->dev, "unsupported page table format 0x%x\n", + le16_to_cpu(desc->format)); + return -EINVAL; + } + + if (vdomain->mm.ops) { + /* + * TODO: attach additional endpoint to the domain. Check that + * the config is sane. + */ + return -EEXIST; + } + + vdomain->mm.domain = vdomain; + ops = alloc_io_pgtable_ops(fmt, &cfg, &vdomain->mm); + if (!ops) + return -ENOMEM; + + pst_cfg = &tbl->cfg; + cfgi = &pst_cfg->vendor.cfg; + id = ida_simple_get(&asid_ida, 1, 1 << desc->asid_bits, GFP_KERNEL); + if (id < 0) { + ret = id; + goto err_free_pgtable; + } + + asid = id; + ret = iommu_psdtable_prepare(tbl, pst_cfg, &cfg, asid); + if (ret) + goto err_free_asid; + + /* + * Strange to setup an op here? + * cd-lib is the actual user of sync op, and therefore the platform + * drivers should assign this sync/maintenance ops as per need. + */ + tbl->ops->sync = viommu_flush_pasid; + + /* Right now only PASID 0 supported ?? */ + ret = iommu_psdtable_write(tbl, pst_cfg, 0, &cfgi->s1_cfg->cd); + if (ret) + goto err_free_asid; + + vdomain->mm.ops = ops; + dev_dbg(vdev->dev, "using page table format 0x%x\n", fmt); + + return 0; + +err_free_asid: + ida_simple_remove(&asid_ida, asid); +err_free_pgtable: + free_io_pgtable_ops(ops); + return ret; +} + +static int viommu_config_arm_pst(struct iommu_vendor_psdtable_cfg *pst_cfg, + struct virtio_iommu_req_attach_pst_arm *req) +{ + struct arm_smmu_s1_cfg *s1_cfg = pst_cfg->vendor.cfg.s1_cfg; + + if (!s1_cfg) + return -ENODEV; + + req->format = cpu_to_le16(VIRTIO_IOMMU_FORMAT_PSTF_ARM_SMMU_V3); + req->s1fmt = s1_cfg->s1fmt; + req->s1dss = VIRTIO_IOMMU_PSTF_ARM_SMMU_V3_DSS_0; + req->s1contextptr = cpu_to_le64(pst_cfg->base); + req->s1cdmax = cpu_to_le32(s1_cfg->s1cdmax); + + return 0; +} + +static int viommu_config_pst(struct iommu_vendor_psdtable_cfg *pst_cfg, + void *req, enum pasid_table_fmt fmt) +{ + int ret; + + switch (fmt) { + case PASID_TABLE_ARM_SMMU_V3: + ret = viommu_config_arm_pst(pst_cfg, req); + break; + default: + ret = -EINVAL; + WARN_ON(1); + } + + return ret; +} + +static int viommu_prepare_arm_pst(struct viommu_endpoint *vdev, + struct iommu_vendor_psdtable_cfg *pst_cfg) +{ + struct virtio_iommu_probe_table_format *pgtf = vdev->pgtf; + struct arm_smmu_cfg_info *cfgi = &pst_cfg->vendor.cfg; + struct arm_smmu_s1_cfg *cfg; + + /* Some sanity checks */ + if (pgtf->asid_bits != 8 && pgtf->asid_bits != 16) + return -EINVAL; + + cfg = devm_kzalloc(pst_cfg->iommu_dev, sizeof(cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + + cfgi->s1_cfg = cfg; + cfg->s1cdmax = vdev->pasid_bits; + cfg->cd.asid = pgtf->asid_bits; + + pst_cfg->fmt = PASID_TABLE_ARM_SMMU_V3; + /* XXX HACK: set feature bit ARM_SMMU_FEAT_2_LVL_CDTAB */ + pst_cfg->vendor.cfg.feat_flag |= (1 << 1); + + return 0; +} + +static int viommu_prepare_pst(struct viommu_endpoint *vdev, + struct iommu_vendor_psdtable_cfg *pst_cfg, + enum pasid_table_fmt fmt) +{ + int ret; + + switch (fmt) { + case PASID_TABLE_ARM_SMMU_V3: + ret = viommu_prepare_arm_pst(vdev, pst_cfg); + break; + default: + dev_err(vdev->dev, "unsupported PASID table format 0x%x\n", fmt); + ret = -EINVAL; + } + + return ret; +} + +static int viommu_attach_pasid_table(struct viommu_endpoint *vdev, + struct viommu_domain *vdomain) +{ + int ret; + int i, eid; + enum pasid_table_fmt fmt = -1; + struct virtio_iommu_probe_table_format *desc = vdev->pstf; + struct virtio_iommu_req_attach_table req = { + .head.type = VIRTIO_IOMMU_T_ATTACH_TABLE, + .domain = cpu_to_le32(vdomain->id), + }; + struct viommu_dev *viommu = vdev->viommu; + struct iommu_pasid_table *tbl; + struct iommu_vendor_psdtable_cfg *pst_cfg; + + if (!viommu->has_table) + return 0; + + if (!desc) + return -ENODEV; + + /* Prepare PASID tables configuration */ + switch (le16_to_cpu(desc->format)) { + case VIRTIO_IOMMU_FORMAT_PSTF_ARM_SMMU_V3: + fmt = PASID_TABLE_ARM_SMMU_V3; + break; + default: + dev_err(vdev->dev, "unsupported PASID table format 0x%x\n", + le16_to_cpu(desc->format)); + return 0; + } + + if (!tbl) { + tbl = iommu_register_pasid_table(fmt, viommu->dev->parent, vdomain); + if (!tbl) + return -ENOMEM; + + vdomain->pasid_tbl = tbl; + pst_cfg = &tbl->cfg; + + pst_cfg->iommu_dev = viommu->dev->parent; + + /* Prepare PASID tables info to allocate a new table */ + ret = viommu_prepare_pst(vdev, pst_cfg, fmt); + if (ret) + return ret; + + ret = iommu_psdtable_alloc(tbl, pst_cfg); + if (ret) + return ret; + + pst_cfg->iommu_dev = viommu->dev->parent; + pst_cfg->fmt = PASID_TABLE_ARM_SMMU_V3; + + ret = viommu_setup_pgtable(vdev, vdomain); + if (ret) { + dev_err(vdev->dev, "could not install page tables\n"); + goto err_free_psdtable; + } + + /* Add arch-specific configuration */ + ret = viommu_config_pst(pst_cfg, (void *)&req, fmt); + if (ret) + goto err_free_ops; + + vdev_for_each_id(i, eid, vdev) { + req.endpoint = cpu_to_le32(eid); + ret = viommu_send_req_sync(viommu, &req, sizeof(req)); + if (ret) + goto err_free_ops; + } + } else { + /* TODO: otherwise, check for compatibility with vdev. */ + return -ENOSYS; + } + + dev_dbg(vdev->dev, "uses PASID table format 0x%x\n", fmt); + + return 0; + +err_free_ops: + if (vdomain->mm.ops) + viommu_teardown_pgtable(vdomain); +err_free_psdtable: + iommu_psdtable_free(tbl, &tbl->cfg); + + return ret; +} + static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) { int ret = 0; @@ -928,6 +1213,17 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) if (vdev->vdomain) vdev->vdomain->nr_endpoints--; + ret = viommu_attach_pasid_table(vdev, vdomain); + if (ret) { + /* + * No PASID support, too bad. Perhaps we can bind a single set + * of page tables? + */ + ret = viommu_setup_pgtable(vdev, vdomain); + if (ret) + dev_err(vdev->dev, "could not install tables\n"); + } + if (!vdomain->mm.ops) { /* If we couldn't bind any table, use the mapping tree */ ret = viommu_simple_attach(vdomain, vdev); @@ -948,6 +1244,10 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova, u32 flags; struct virtio_iommu_req_map map; struct viommu_domain *vdomain = to_viommu_domain(domain); + struct io_pgtable_ops *ops = vdomain->mm.ops; + + if (ops) + return ops->map(ops, iova, paddr, size, prot, gfp); flags = (prot & IOMMU_READ ? VIRTIO_IOMMU_MAP_F_READ : 0) | (prot & IOMMU_WRITE ? VIRTIO_IOMMU_MAP_F_WRITE : 0) | @@ -986,6 +1286,10 @@ static size_t viommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t unmapped; struct virtio_iommu_req_unmap unmap; struct viommu_domain *vdomain = to_viommu_domain(domain); + struct io_pgtable_ops *ops = vdomain->mm.ops; + + if (ops) + return ops->unmap(ops, iova, size, gather); unmapped = viommu_del_mappings(vdomain, iova, size); if (unmapped < size) @@ -1014,6 +1318,10 @@ static phys_addr_t viommu_iova_to_phys(struct iommu_domain *domain, struct viommu_mapping *mapping; struct interval_tree_node *node; struct viommu_domain *vdomain = to_viommu_domain(domain); + struct io_pgtable_ops *ops = vdomain->mm.ops; + + if (ops) + return ops->iova_to_phys(ops, iova); spin_lock_irqsave(&vdomain->mappings_lock, flags); node = interval_tree_iter_first(&vdomain->mappings, iova, iova); @@ -1264,7 +1572,12 @@ static int viommu_probe(struct virtio_device *vdev) struct virtio_iommu_config, probe_size, &viommu->probe_size); + viommu->has_table = virtio_has_feature(vdev, VIRTIO_IOMMU_F_ATTACH_TABLE); viommu->has_map = virtio_has_feature(vdev, VIRTIO_IOMMU_F_MAP_UNMAP); + if (!viommu->has_table && !viommu->has_map) { + ret = -EINVAL; + goto err_free_vqs; + } viommu->geometry = (struct iommu_domain_geometry) { .aperture_start = input_start, @@ -1356,6 +1669,7 @@ static unsigned int features[] = { VIRTIO_IOMMU_F_DOMAIN_RANGE, VIRTIO_IOMMU_F_PROBE, VIRTIO_IOMMU_F_MMIO, + VIRTIO_IOMMU_F_ATTACH_TABLE, }; static struct virtio_device_id id_table[] = { From patchwork Fri Jan 15 12:13:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022433 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 653C6C433DB for ; Fri, 15 Jan 2021 12:17:26 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2098720691 for ; Fri, 15 Jan 2021 12:17:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2098720691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=9Ho8M7GLwCHaI3jjnpraNWkPIWNmFID2S5gvRTBicRE=; b=kic3+sq/yJV1Dw1u2w8lwyvj0k UtFQ/TdlQ0OctK2A8TyMPMsbwl1n3QHEkRm14PmWWOgUNDEtaN+a9gI8brLznOBxhWYB6g1L1JAYi wcPyNvk6MIbFUnRM524Ux/Q4yoTJYY9qsMEFN61S6zvnvw0iP5bslg3uvBlQnd54I+aslMO5ePYS7 rFR9cOnR+QYFtRmFQ7SkQekWgd1QeKSt/1i6OcCuKptD5s3bQGJFYrZ0dQk+/IHc/QhINdxcJDRbS 1eZ7hOcz5XFhElPYk+15iaiyOVIleB+r94br6ASd8QIsk7ROzePsBXEFkFk+WkPEx687fZzm2QWsk pN4JP32Q==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O1E-0007pl-Qg; Fri, 15 Jan 2021 12:15:56 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0N-0007PD-36 for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:15:09 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4104E150C; Fri, 15 Jan 2021 04:15:02 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id BE7A53F70D; Fri, 15 Jan 2021 04:14:57 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 14/15] iommu/virtio: Add support for Arm LPAE page table format Date: Fri, 15 Jan 2021 17:43:41 +0530 Message-Id: <20210115121342.15093-15-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071503_307576_947B37D3 X-CRM114-Status: GOOD ( 21.98 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jean-Philippe Brucker When PASID isn't supported, we can still register one set of tables. Add support to register Arm LPAE based page table. Signed-off-by: Jean-Philippe Brucker [Vivek: Clean-ups to add right tcr definitions and accomodate with parent patches] Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/virtio-iommu.c | 131 +++++++++++++++++++++++++----- include/uapi/linux/virtio_iommu.h | 30 +++++++ 2 files changed, 139 insertions(+), 22 deletions(-) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index b5222da1dc74..9cc3d35125e9 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -135,6 +135,13 @@ struct viommu_event { #define to_viommu_domain(domain) \ container_of(domain, struct viommu_domain, domain) +#define VIRTIO_FIELD_PREP(_mask, _shift, _val) \ + ({ \ + (((_val) << VIRTIO_IOMMU_PGTF_ARM_ ## _shift) & \ + (VIRTIO_IOMMU_PGTF_ARM_ ## _mask << \ + VIRTIO_IOMMU_PGTF_ARM_ ## _shift)); \ + }) + static int viommu_get_req_errno(void *buf, size_t len) { struct virtio_iommu_req_tail *tail = buf + len - sizeof(*tail); @@ -897,6 +904,76 @@ static int viommu_simple_attach(struct viommu_domain *vdomain, return ret; } +static int viommu_config_arm_pgt(struct viommu_endpoint *vdev, + struct io_pgtable_cfg *cfg, + struct virtio_iommu_req_attach_pgt_arm *req, + u64 *asid) +{ + int id; + struct virtio_iommu_probe_table_format *pgtf = (void *)vdev->pgtf; + typeof(&cfg->arm_lpae_s1_cfg.tcr) tcr = &cfg->arm_lpae_s1_cfg.tcr; + u64 __tcr; + + if (pgtf->asid_bits != 8 && pgtf->asid_bits != 16) + return -EINVAL; + + id = ida_simple_get(&asid_ida, 1, 1 << pgtf->asid_bits, GFP_KERNEL); + if (id < 0) + return -ENOMEM; + + __tcr = VIRTIO_FIELD_PREP(T0SZ_MASK, T0SZ_SHIFT, tcr->tsz) | + VIRTIO_FIELD_PREP(IRGN0_MASK, IRGN0_SHIFT, tcr->irgn) | + VIRTIO_FIELD_PREP(ORGN0_MASK, ORGN0_SHIFT, tcr->orgn) | + VIRTIO_FIELD_PREP(SH0_MASK, SH0_SHIFT, tcr->sh) | + VIRTIO_FIELD_PREP(TG0_MASK, TG0_SHIFT, tcr->tg) | + VIRTIO_IOMMU_PGTF_ARM_EPD1 | VIRTIO_IOMMU_PGTF_ARM_HPD0 | + VIRTIO_IOMMU_PGTF_ARM_HPD1; + + req->format = cpu_to_le16(VIRTIO_IOMMU_FOMRAT_PGTF_ARM_LPAE); + req->ttbr = cpu_to_le64(cfg->arm_lpae_s1_cfg.ttbr); + req->tcr = cpu_to_le64(__tcr); + req->mair = cpu_to_le64(cfg->arm_lpae_s1_cfg.mair); + req->asid = cpu_to_le16(id); + + *asid = id; + return 0; +} + +static int viommu_attach_pgtable(struct viommu_endpoint *vdev, + struct viommu_domain *vdomain, + enum io_pgtable_fmt fmt, + struct io_pgtable_cfg *cfg, + u64 *asid) +{ + int ret; + int i, eid; + + struct virtio_iommu_req_attach_table req = { + .head.type = VIRTIO_IOMMU_T_ATTACH_TABLE, + .domain = cpu_to_le32(vdomain->id), + }; + + switch (fmt) { + case ARM_64_LPAE_S1: + ret = viommu_config_arm_pgt(vdev, cfg, (void *)&req, asid); + if (ret) + return ret; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + vdev_for_each_id(i, eid, vdev) { + req.endpoint = cpu_to_le32(eid); + ret = viommu_send_req_sync(vdomain->viommu, &req, sizeof(req)); + if (ret) + return ret; + } + + return 0; +} + static int viommu_teardown_pgtable(struct viommu_domain *vdomain) { struct iommu_vendor_psdtable_cfg *pst_cfg; @@ -972,32 +1049,42 @@ static int viommu_setup_pgtable(struct viommu_endpoint *vdev, if (!ops) return -ENOMEM; - pst_cfg = &tbl->cfg; - cfgi = &pst_cfg->vendor.cfg; - id = ida_simple_get(&asid_ida, 1, 1 << desc->asid_bits, GFP_KERNEL); - if (id < 0) { - ret = id; - goto err_free_pgtable; - } + if (!tbl) { + /* No PASID support, send attach_table */ + ret = viommu_attach_pgtable(vdev, vdomain, fmt, &cfg, + &vdomain->mm.archid); + if (ret) + goto err_free_pgtable; + } else { + pst_cfg = &tbl->cfg; + cfgi = &pst_cfg->vendor.cfg; + id = ida_simple_get(&asid_ida, 1, 1 << desc->asid_bits, GFP_KERNEL); + if (id < 0) { + ret = id; + goto err_free_pgtable; + } - asid = id; - ret = iommu_psdtable_prepare(tbl, pst_cfg, &cfg, asid); - if (ret) - goto err_free_asid; + asid = id; + ret = iommu_psdtable_prepare(tbl, pst_cfg, &cfg, asid); + if (ret) + goto err_free_asid; - /* - * Strange to setup an op here? - * cd-lib is the actual user of sync op, and therefore the platform - * drivers should assign this sync/maintenance ops as per need. - */ - tbl->ops->sync = viommu_flush_pasid; + /* + * Strange to setup an op here? + * cd-lib is the actual user of sync op, and therefore the + * cd-lib consumer drivers should assign this sync/maintenance + * ops as per need. + */ + tbl->ops->sync = viommu_flush_pasid; - /* Right now only PASID 0 supported ?? */ - ret = iommu_psdtable_write(tbl, pst_cfg, 0, &cfgi->s1_cfg->cd); - if (ret) - goto err_free_asid; + /* Right now only PASID 0 supported */ + ret = iommu_psdtable_write(tbl, pst_cfg, 0, &cfgi->s1_cfg->cd); + if (ret) + goto err_free_asid; + + vdomain->mm.ops = ops; + } - vdomain->mm.ops = ops; dev_dbg(vdev->dev, "using page table format 0x%x\n", fmt); return 0; diff --git a/include/uapi/linux/virtio_iommu.h b/include/uapi/linux/virtio_iommu.h index 3481e4a3dd24..608c8d642e1f 100644 --- a/include/uapi/linux/virtio_iommu.h +++ b/include/uapi/linux/virtio_iommu.h @@ -116,6 +116,36 @@ struct virtio_iommu_req_attach_pst_arm { struct virtio_iommu_req_tail tail; }; +/* TCR_EL1 fields from Arm LPAE format */ +#define VIRTIO_IOMMU_PGTF_ARM_HPD1 (1ULL << 42) +#define VIRTIO_IOMMU_PGTF_ARM_HPD0 (1ULL << 41) +#define VIRTIO_IOMMU_PGTF_ARM_EPD1 (1 << 23) + +#define VIRTIO_IOMMU_PGTF_ARM_TG0_SHIFT 14 +#define VIRTIO_IOMMU_PGTF_ARM_TG0_MASK 0x3 +#define VIRTIO_IOMMU_PGTF_ARM_SH0_SHIFT 12 +#define VIRTIO_IOMMU_PGTF_ARM_SH0_MASK 0x3 +#define VIRTIO_IOMMU_PGTF_ARM_ORGN0_SHIFT 10 +#define VIRTIO_IOMMU_PGTF_ARM_ORGN0_MASK 0x3 +#define VIRTIO_IOMMU_PGTF_ARM_IRGN0_SHIFT 8 +#define VIRTIO_IOMMU_PGTF_ARM_IRGN0_MASK 0x3 +#define VIRTIO_IOMMU_PGTF_ARM_T0SZ_SHIFT 0 +#define VIRTIO_IOMMU_PGTF_ARM_T0SZ_MASK 0x3f + +/* Arm LPAE Page Table Descriptor */ +struct virtio_iommu_req_attach_pgt_arm { + struct virtio_iommu_req_head head; + __le32 domain; + __le32 endpoint; + __le16 format; + __le16 asid; + __le64 tcr; + __le64 ttbr; + __le64 mair; + __u8 reserved[28]; + struct virtio_iommu_req_tail tail; +}; + #define VIRTIO_IOMMU_MAP_F_READ (1 << 0) #define VIRTIO_IOMMU_MAP_F_WRITE (1 << 1) #define VIRTIO_IOMMU_MAP_F_MMIO (1 << 2) From patchwork Fri Jan 15 12:13:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Kumar Gautam X-Patchwork-Id: 12022435 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=-17.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 646DEC433DB for ; Fri, 15 Jan 2021 12:17:36 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2EC7820691 for ; Fri, 15 Jan 2021 12:17:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2EC7820691 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=vDq+nsPu5cneYnfApaKSNA6PqwpsL1qQ3NFPdXucZyk=; b=MP9I58OJMRHZKMRsnYRqkWlAF8 OkdnbFCgJTnEDE0YnjWxNlU3nw3N3gG0VJE+AZo/yavQQ3uwe+wBe1qWJUEnLWNkw2womfYRWYLvs oCUrvgETuZzBDMzH1J0Gai9jgBQtoBxCgC4jDN1Gi3y0OPWmbdP1Pptpiph/Zyn41lySAXKxELl8l 0CoeWX6lgbR8j3J9VNG2znIqF0kbwCL3zJu15/uuMkuX4kb5Xbi1zWiC7MQcBWq0dQmCy8AxratTu 8/zvNADkLND8g717/b4JkLITyBgKY8UqnL6GONJQSMSrblz7IQTTu0jRkYJ/0dXSp5iUbAo6LrG53 4R1iAVtA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O1V-0007yI-Fq; Fri, 15 Jan 2021 12:16:13 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0O0R-0007NE-BU for linux-arm-kernel@lists.infradead.org; Fri, 15 Jan 2021 12:15:10 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 34C4D1529; Fri, 15 Jan 2021 04:15:07 -0800 (PST) Received: from usa.arm.com (a074945.blr.arm.com [10.162.16.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id B21A83F70D; Fri, 15 Jan 2021 04:15:02 -0800 (PST) From: Vivek Gautam To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org Subject: [PATCH RFC v1 15/15] iommu/virtio: Update fault type and reason info for viommu fault Date: Fri, 15 Jan 2021 17:43:42 +0530 Message-Id: <20210115121342.15093-16-vivek.gautam@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210115121342.15093-1-vivek.gautam@arm.com> References: <20210115121342.15093-1-vivek.gautam@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210115_071507_591004_DCA5DBE8 X-CRM114-Status: GOOD ( 16.35 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jean-philippe@linaro.org, kevin.tian@intel.com, jacob.jun.pan@linux.intel.com, mst@redhat.com, joro@8bytes.org, will.deacon@arm.com, shameerali.kolothum.thodi@huawei.com, eric.auger@redhat.com, alex.williamson@redhat.com, yi.l.liu@intel.com, vivek.gautam@arm.com, lorenzo.pieralisi@arm.com, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Fault type information can tell about a page request fault or an unreceoverable fault, and further additions to fault reasons and the related PASID information can help in handling faults efficiently. Signed-off-by: Vivek Gautam Cc: Joerg Roedel Cc: Will Deacon Cc: Michael S. Tsirkin Cc: Robin Murphy Cc: Jean-Philippe Brucker Cc: Eric Auger Cc: Alex Williamson Cc: Kevin Tian Cc: Jacob Pan Cc: Liu Yi L Cc: Lorenzo Pieralisi Cc: Shameerali Kolothum Thodi --- drivers/iommu/virtio-iommu.c | 27 +++++++++++++++++++++++++-- include/uapi/linux/virtio_iommu.h | 13 ++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 9cc3d35125e9..10ef9e98214a 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -652,9 +652,16 @@ static int viommu_fault_handler(struct viommu_dev *viommu, char *reason_str; u8 reason = fault->reason; + u16 type = fault->flt_type; u32 flags = le32_to_cpu(fault->flags); u32 endpoint = le32_to_cpu(fault->endpoint); u64 address = le64_to_cpu(fault->address); + u32 pasid = le32_to_cpu(fault->pasid); + + if (type == VIRTIO_IOMMU_FAULT_F_PAGE_REQ) { + dev_info(viommu->dev, "Page request fault - unhandled\n"); + return 0; + } switch (reason) { case VIRTIO_IOMMU_FAULT_R_DOMAIN: @@ -663,6 +670,21 @@ static int viommu_fault_handler(struct viommu_dev *viommu, case VIRTIO_IOMMU_FAULT_R_MAPPING: reason_str = "page"; break; + case VIRTIO_IOMMU_FAULT_R_WALK_EABT: + reason_str = "page walk external abort"; + break; + case VIRTIO_IOMMU_FAULT_R_PTE_FETCH: + reason_str = "pte fetch"; + break; + case VIRTIO_IOMMU_FAULT_R_PERMISSION: + reason_str = "permission"; + break; + case VIRTIO_IOMMU_FAULT_R_ACCESS: + reason_str = "access"; + break; + case VIRTIO_IOMMU_FAULT_R_OOR_ADDRESS: + reason_str = "output address"; + break; case VIRTIO_IOMMU_FAULT_R_UNKNOWN: default: reason_str = "unknown"; @@ -671,8 +693,9 @@ static int viommu_fault_handler(struct viommu_dev *viommu, /* TODO: find EP by ID and report_iommu_fault */ if (flags & VIRTIO_IOMMU_FAULT_F_ADDRESS) - dev_err_ratelimited(viommu->dev, "%s fault from EP %u at %#llx [%s%s%s]\n", - reason_str, endpoint, address, + dev_err_ratelimited(viommu->dev, + "%s fault from EP %u PASID %u at %#llx [%s%s%s]\n", + reason_str, endpoint, pasid, address, flags & VIRTIO_IOMMU_FAULT_F_READ ? "R" : "", flags & VIRTIO_IOMMU_FAULT_F_WRITE ? "W" : "", flags & VIRTIO_IOMMU_FAULT_F_EXEC ? "X" : ""); diff --git a/include/uapi/linux/virtio_iommu.h b/include/uapi/linux/virtio_iommu.h index 608c8d642e1f..a537d82777f7 100644 --- a/include/uapi/linux/virtio_iommu.h +++ b/include/uapi/linux/virtio_iommu.h @@ -290,19 +290,30 @@ struct virtio_iommu_req_invalidate { #define VIRTIO_IOMMU_FAULT_R_UNKNOWN 0 #define VIRTIO_IOMMU_FAULT_R_DOMAIN 1 #define VIRTIO_IOMMU_FAULT_R_MAPPING 2 +#define VIRTIO_IOMMU_FAULT_R_WALK_EABT 3 +#define VIRTIO_IOMMU_FAULT_R_PTE_FETCH 4 +#define VIRTIO_IOMMU_FAULT_R_PERMISSION 5 +#define VIRTIO_IOMMU_FAULT_R_ACCESS 6 +#define VIRTIO_IOMMU_FAULT_R_OOR_ADDRESS 7 #define VIRTIO_IOMMU_FAULT_F_READ (1 << 0) #define VIRTIO_IOMMU_FAULT_F_WRITE (1 << 1) #define VIRTIO_IOMMU_FAULT_F_EXEC (1 << 2) #define VIRTIO_IOMMU_FAULT_F_ADDRESS (1 << 8) +#define VIRTIO_IOMMU_FAULT_F_DMA_UNRECOV 1 +#define VIRTIO_IOMMU_FAULT_F_PAGE_REQ 2 + struct virtio_iommu_fault { __u8 reason; - __u8 reserved[3]; + __le16 flt_type; + __u8 reserved; __le32 flags; __le32 endpoint; __u8 reserved2[4]; __le64 address; + __le32 pasid; + __u8 reserved3[4]; }; #endif