Received: by 2002:a05:7412:37c9:b0:e2:908c:2ebd with SMTP id jz9csp2433109rdb; Thu, 21 Sep 2023 20:23:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGjjD3y7IkwCYglvEQUkt0u5GYq7gqOESQCw1VGGiiozuFLQd4fnRbee2biNZgRIxpbNjj0 X-Received: by 2002:a05:6a21:3395:b0:130:7ef2:ff21 with SMTP id yy21-20020a056a21339500b001307ef2ff21mr2402827pzb.19.1695353017479; Thu, 21 Sep 2023 20:23:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695353017; cv=none; d=google.com; s=arc-20160816; b=Q/WyHzdONPXCG+tnPw00BgULtO0AoD6EPZ6s+PQOtWZHoE0WFmrhZyIzJ6V6i1FWX6 1kCpsm+sHcN0yPmvo0EsEgtPEuSksQcIW5i1lmANhb4LwqToIF1HJhOf4dfQClNMnwp5 ERZ91Aia4H561HxMKDALTbM+4rx4VXnR3ewMCCYioPG7EX4l1uAF80vWzbySbEdxOf4C M+bbsI5+wb1NOhPZxLB906kc6T4Y0ryhhYOU/xDg1I+w+Pg0u7mbsu4/+F6MmREZBUoL V5hVtTnEWPa8FBVZbE8Gix1frDqtf0wivk1/NhBq7Jd7pa2hvF1IeiBx2NwwiMeYObiV 49Hw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=/5Z5+c1XIKFByh/O88M1hFMZvo+HIaGI6QQ9mXZwLnQ=; fh=4LHR+mUxVAoNBe0WLhXgnzbMgf2Oz4cgAvP5fO84YrI=; b=TDetGNjbE1FavsfzOd0PGo6cDgcBVZC9Ora4X7aIysipYagjO5KFnKcYaCQH17OIpL udkBLuzwFmCvvVs4oo1WUG1IB9BghvT2un3b0dhlPmlPuoSQwvtNKZJ8HCsaq7Q9jBoK NpM+Ah6GZsktIt64lajce7GouAZyxD+85lvFebCYpIcxgZcOuo3V1HU/cYtIM4nQNAZj n1rpmAZARHN58M2e5T28wHdMp0JbL5eULwgywtXBIUjxUWRjs6uNHqPGtJ9924OLhouT o5s8LShSAu/NCq+ohfFpT28Y9bORp6WnyJG3So1oPqdqE3xi/L+3cRMRdDEynU+FrFJg PZiA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=RUnbErXM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from agentk.vger.email (agentk.vger.email. [23.128.96.32]) by mx.google.com with ESMTPS id k5-20020a634b45000000b00578b8d202b0si2768889pgl.536.2023.09.21.20.23.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Sep 2023 20:23:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) client-ip=23.128.96.32; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=RUnbErXM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id 1D440805BCA7; Thu, 21 Sep 2023 13:20:59 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230402AbjIUUUU (ORCPT + 99 others); Thu, 21 Sep 2023 16:20:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53706 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230010AbjIUUT0 (ORCPT ); Thu, 21 Sep 2023 16:19:26 -0400 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF75D7EC4; Thu, 21 Sep 2023 10:11:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695316261; x=1726852261; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8kLHHoEGx8VOMsxlCOgaSdq9RP42gUjf6mYcaQ0jE14=; b=RUnbErXMBGqXSAaid93iOklccURgEiJnbkOhAy/V5qhJEAEYn6WJsT6O H5Rg1aUFhJuCsK4JpPfBVdiuzswelqWLTdP6XvovTOEsMjIUymGnYor2H /FEfquaYXh8E+KW5puSGdyjzxbWMH4qZ0ZNf26H2baeY/HlE5lnd9BbZP kuh7jut5IB2YkYppHPu76fwWVCrgjbA0AE8x4f03rrWSKOM2a9nZqJ6RI FW1XJfdMeTpi2jo9E0z2jfhVN1ozJQCZVREHhBgIpMxL6Ib+Ue4NRiYRb wX5xnVGAqQN3mVbma7hXQj0eAL2BWBne8CPwBW4w3XChmzm81h0llWmVt w==; X-IronPort-AV: E=McAfee;i="6600,9927,10839"; a="370764411" X-IronPort-AV: E=Sophos;i="6.03,164,1694761200"; d="scan'208";a="370764411" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Sep 2023 00:54:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10839"; a="812523097" X-IronPort-AV: E=Sophos;i="6.03,164,1694761200"; d="scan'208";a="812523097" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by fmsmga008.fm.intel.com with ESMTP; 21 Sep 2023 00:54:47 -0700 From: Yi Liu To: joro@8bytes.org, alex.williamson@redhat.com, jgg@nvidia.com, kevin.tian@intel.com, robin.murphy@arm.com, baolu.lu@linux.intel.com Cc: cohuck@redhat.com, eric.auger@redhat.com, nicolinc@nvidia.com, kvm@vger.kernel.org, mjrosato@linux.ibm.com, chao.p.peng@linux.intel.com, yi.l.liu@intel.com, yi.y.sun@linux.intel.com, peterx@redhat.com, jasowang@redhat.com, shameerali.kolothum.thodi@huawei.com, lulu@redhat.com, suravee.suthikulpanit@amd.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, zhenzhong.duan@intel.com, joao.m.martins@oracle.com, Jacob Pan Subject: [PATCH v5 04/11] iommu/vt-d: Add helper to setup pasid nested translation Date: Thu, 21 Sep 2023 00:54:24 -0700 Message-Id: <20230921075431.125239-5-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230921075431.125239-1-yi.l.liu@intel.com> References: <20230921075431.125239-1-yi.l.liu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Thu, 21 Sep 2023 13:21:00 -0700 (PDT) From: Lu Baolu The configurations are passed in from the user when the user domain is allocated. This helper interprets these configurations according to the data structure defined in uapi/linux/iommufd.h. The EINVAL error will be returned if any of configurations are not compatible with the hardware capabilities. The caller can retry with another compatible user domain. The encoding of fields of each pasid entry is defined in section 9.6 of the VT-d spec. Signed-off-by: Jacob Pan Signed-off-by: Lu Baolu Signed-off-by: Yi Liu --- drivers/iommu/intel/pasid.c | 125 ++++++++++++++++++++++++++++++++++++ drivers/iommu/intel/pasid.h | 2 + 2 files changed, 127 insertions(+) diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index 8f92b92f3d2a..8a290ab07697 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -335,6 +335,15 @@ static inline void pasid_set_fault_enable(struct pasid_entry *pe) pasid_set_bits(&pe->val[0], 1 << 1, 0); } +/* + * Setup the SRE(Supervisor Request Enable) field (Bit 128) of a + * scalable mode PASID entry. + */ +static inline void pasid_set_sre(struct pasid_entry *pe) +{ + pasid_set_bits(&pe->val[2], 1 << 0, 1); +} + /* * Setup the WPE(Write Protect Enable) field (Bit 132) of a * scalable mode PASID entry. @@ -402,6 +411,15 @@ pasid_set_flpm(struct pasid_entry *pe, u64 value) pasid_set_bits(&pe->val[2], GENMASK_ULL(3, 2), value << 2); } +/* + * Setup the Extended Access Flag Enable (EAFE) field (Bit 135) + * of a scalable mode PASID entry. + */ +static inline void pasid_set_eafe(struct pasid_entry *pe) +{ + pasid_set_bits(&pe->val[2], 1 << 7, 1 << 7); +} + static void pasid_cache_invalidation_with_pasid(struct intel_iommu *iommu, u16 did, u32 pasid) @@ -713,3 +731,110 @@ void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu, if (!cap_caching_mode(iommu->cap)) devtlb_invalidation_with_pasid(iommu, dev, pasid); } + +/** + * intel_pasid_setup_nested() - Set up PASID entry for nested translation. + * @iommu: IOMMU which the device belong to + * @dev: Device to be set up for translation + * @pasid: PASID to be programmed in the device PASID table + * @domain: User first-level domain nested on a s2 domain + * + * This is used for nested translation based vIOMMU. e.g. guest IOVA and + * guest shared virtual address. In this case, the first-level page tables + * are used for GVA/GIOVA-GPA translation in the guest, the second-level + * page tables are used for GPA-HPA translation. + */ +int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev, + u32 pasid, struct dmar_domain *domain) +{ + struct iommu_hwpt_vtd_s1 *s1_cfg = &domain->s1_cfg; + pgd_t *s1_gpgd = (pgd_t *)(uintptr_t)domain->s1_pgtbl; + struct dmar_domain *s2_domain = domain->s2_domain; + u16 did = domain_id_iommu(domain, iommu); + struct dma_pte *pgd = s2_domain->pgd; + struct pasid_entry *pte; + + if (!ecap_nest(iommu->ecap)) { + pr_err_ratelimited("%s: No nested translation support\n", + iommu->name); + return -ENODEV; + } + + /* + * Address width should match in two dimensions: CPU vs. IOMMU, + * guest vs. host. + */ + switch (s1_cfg->addr_width) { + case ADDR_WIDTH_4LEVEL: + break; +#ifdef CONFIG_X86 + case ADDR_WIDTH_5LEVEL: + if (!cpu_feature_enabled(X86_FEATURE_LA57) || + !cap_fl5lp_support(iommu->cap)) { + dev_err_ratelimited(dev, + "5-level paging not supported\n"); + return -EINVAL; + } + break; +#endif + default: + dev_err_ratelimited(dev, "Invalid guest address width %d\n", + s1_cfg->addr_width); + return -EINVAL; + } + + if ((s1_cfg->flags & IOMMU_VTD_S1_SRE) && !ecap_srs(iommu->ecap)) { + pr_err_ratelimited("No supervisor request support on %s\n", + iommu->name); + return -EINVAL; + } + + if ((s1_cfg->flags & IOMMU_VTD_S1_EAFE) && !ecap_eafs(iommu->ecap)) { + pr_err_ratelimited("No extended access flag support on %s\n", + iommu->name); + return -EINVAL; + } + + spin_lock(&iommu->lock); + pte = intel_pasid_get_entry(dev, pasid); + if (!pte) { + spin_unlock(&iommu->lock); + return -ENODEV; + } + if (pasid_pte_is_present(pte)) { + spin_unlock(&iommu->lock); + return -EBUSY; + } + + pasid_clear_entry(pte); + + if (s1_cfg->addr_width == ADDR_WIDTH_5LEVEL) + pasid_set_flpm(pte, 1); + + pasid_set_flptr(pte, (uintptr_t)s1_gpgd); + + if (s1_cfg->flags & IOMMU_VTD_S1_SRE) { + pasid_set_sre(pte); + if (s1_cfg->flags & IOMMU_VTD_S1_WPE) + pasid_set_wpe(pte); + } + + if (s1_cfg->flags & IOMMU_VTD_S1_EAFE) + pasid_set_eafe(pte); + + if (s2_domain->force_snooping) + pasid_set_pgsnp(pte); + + pasid_set_slptr(pte, virt_to_phys(pgd)); + pasid_set_fault_enable(pte); + pasid_set_domain_id(pte, did); + pasid_set_address_width(pte, s2_domain->agaw); + pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap)); + pasid_set_translation_type(pte, PASID_ENTRY_PGTT_NESTED); + pasid_set_present(pte); + spin_unlock(&iommu->lock); + + pasid_flush_caches(iommu, pte, pasid, did); + + return 0; +} diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h index 4e9e68c3c388..7906d73f4ded 100644 --- a/drivers/iommu/intel/pasid.h +++ b/drivers/iommu/intel/pasid.h @@ -109,6 +109,8 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu, int intel_pasid_setup_pass_through(struct intel_iommu *iommu, struct dmar_domain *domain, struct device *dev, u32 pasid); +int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev, + u32 pasid, struct dmar_domain *domain); void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev, u32 pasid, bool fault_ignore); -- 2.34.1