Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp4010480ybg; Fri, 25 Oct 2019 12:03:40 -0700 (PDT) X-Google-Smtp-Source: APXvYqwTHF6ZKDfBrIuvfK4abkWvF72V8P5qKYjseoyPZBg8ZGhK6ShFzRv2jvyeZpumbK0b8VLJ X-Received: by 2002:a17:906:19d9:: with SMTP id h25mr5121133ejd.60.1572030220041; Fri, 25 Oct 2019 12:03:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572030220; cv=none; d=google.com; s=arc-20160816; b=aWGsfx64nuq5h8hso2H02cETW8ZJQfQH9wo2cMlkJvWxbO81f7l5Ozx/YqLzcK4NSC CnLmRteE8edDPYBmf8acE70+2FbHdoX/92zUd+Uh0TBjcrqFbj2f/nr6kPG+KdkHFCbK ynqXuslt/h21g7Ur08Pq6cGHjvblcYhnVctG/wT2WZ8XPr7oHdQw0Isq9qiaAO7blr5M stejtjxlslOkVrDTrRBqG4GFvqni9acm5A4fi9SDUQjuieR/YRFMH3OlWRPbl8Sr/hdr xITTqW1ih1Aiocc3BW1RFW/LZpRpYBuUPBxVFQiO4t5UXP9zL0qAQJbiTFPYLE2xSygI xpug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=4AhGyrHdYRyO3F7aDrcFJmwwdUyrMEffM4HgbMCCETg=; b=zXlwRngi9OzGxeCxSpQcQR5jsUJagsP/zcMTkTbABI1j5ugy1i5xlD5MwircOdPNg+ nux75k+v11+Db6WLtxDKWxqBUFU09y5ygMka8VnOzUcQUVMfGZjak5jMwlz6j46XlUhL r8mWe5muKELy4RyG8x+hZmQ9m4NQh7TXgIoVSLsN6JvdXTYV0I6vpWYhl/OjVdO/YVaW uWZfshUYUKKVACc1/b/4b7Unfb53xefqnc6sJ3xqFQG5lpyfi5hNAllFVSPyA6z9ohPD YWi8bA9B0dcfkylOCsEhDmcms6x5Mc0lr5wp3mw3Obk51XFX2H7TYEYDPgJ+HAY6ck56 CK6g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u3si1774109edy.48.2019.10.25.12.03.16; Fri, 25 Oct 2019 12:03:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2408297AbfJXTv2 (ORCPT + 99 others); Thu, 24 Oct 2019 15:51:28 -0400 Received: from mga07.intel.com ([134.134.136.100]:62195 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437545AbfJXTup (ORCPT ); Thu, 24 Oct 2019 15:50:45 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 24 Oct 2019 12:50:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,225,1569308400"; d="scan'208";a="282043139" Received: from jacob-builder.jf.intel.com ([10.7.199.155]) by orsmga001.jf.intel.com with ESMTP; 24 Oct 2019 12:50:43 -0700 From: Jacob Pan To: iommu@lists.linux-foundation.org, LKML , Joerg Roedel , David Woodhouse , Alex Williamson , Jean-Philippe Brucker Cc: "Yi Liu" , "Tian, Kevin" , Raj Ashok , "Christoph Hellwig" , "Lu Baolu" , Jonathan Cameron , Eric Auger , Jacob Pan Subject: [PATCH v7 02/11] iommu/vt-d: Enlightened PASID allocation Date: Thu, 24 Oct 2019 12:54:55 -0700 Message-Id: <1571946904-86776-3-git-send-email-jacob.jun.pan@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1571946904-86776-1-git-send-email-jacob.jun.pan@linux.intel.com> References: <1571946904-86776-1-git-send-email-jacob.jun.pan@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lu Baolu Enabling IOMMU in a guest requires communication with the host driver for certain aspects. Use of PASID ID to enable Shared Virtual Addressing (SVA) requires managing PASID's in the host. VT-d 3.0 spec provides a Virtual Command Register (VCMD) to facilitate this. Writes to this register in the guest are trapped by QEMU which proxies the call to the host driver. This virtual command interface consists of a capability register, a virtual command register, and a virtual response register. Refer to section 10.4.42, 10.4.43, 10.4.44 for more information. This patch adds the enlightened PASID allocation/free interfaces via the virtual command interface. Cc: Ashok Raj Cc: Jacob Pan Cc: Kevin Tian Signed-off-by: Liu Yi L Signed-off-by: Lu Baolu Signed-off-by: Jacob Pan Reviewed-by: Eric Auger --- drivers/iommu/intel-pasid.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ drivers/iommu/intel-pasid.h | 13 ++++++++++- include/linux/intel-iommu.h | 2 ++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/intel-pasid.c b/drivers/iommu/intel-pasid.c index 040a445be300..d81e857d2b25 100644 --- a/drivers/iommu/intel-pasid.c +++ b/drivers/iommu/intel-pasid.c @@ -63,6 +63,62 @@ void *intel_pasid_lookup_id(int pasid) return p; } +int vcmd_alloc_pasid(struct intel_iommu *iommu, unsigned int *pasid) +{ + unsigned long flags; + u8 status_code; + int ret = 0; + u64 res; + + raw_spin_lock_irqsave(&iommu->register_lock, flags); + dmar_writeq(iommu->reg + DMAR_VCMD_REG, VCMD_CMD_ALLOC); + IOMMU_WAIT_OP(iommu, DMAR_VCRSP_REG, dmar_readq, + !(res & VCMD_VRSP_IP), res); + raw_spin_unlock_irqrestore(&iommu->register_lock, flags); + + status_code = VCMD_VRSP_SC(res); + switch (status_code) { + case VCMD_VRSP_SC_SUCCESS: + *pasid = VCMD_VRSP_RESULT(res); + break; + case VCMD_VRSP_SC_NO_PASID_AVAIL: + pr_info("IOMMU: %s: No PASID available\n", iommu->name); + ret = -ENOMEM; + break; + default: + ret = -ENODEV; + pr_warn("IOMMU: %s: Unexpected error code %d\n", + iommu->name, status_code); + } + + return ret; +} + +void vcmd_free_pasid(struct intel_iommu *iommu, unsigned int pasid) +{ + unsigned long flags; + u8 status_code; + u64 res; + + raw_spin_lock_irqsave(&iommu->register_lock, flags); + dmar_writeq(iommu->reg + DMAR_VCMD_REG, (pasid << 8) | VCMD_CMD_FREE); + IOMMU_WAIT_OP(iommu, DMAR_VCRSP_REG, dmar_readq, + !(res & VCMD_VRSP_IP), res); + raw_spin_unlock_irqrestore(&iommu->register_lock, flags); + + status_code = VCMD_VRSP_SC(res); + switch (status_code) { + case VCMD_VRSP_SC_SUCCESS: + break; + case VCMD_VRSP_SC_INVALID_PASID: + pr_info("IOMMU: %s: Invalid PASID\n", iommu->name); + break; + default: + pr_warn("IOMMU: %s: Unexpected error code %d\n", + iommu->name, status_code); + } +} + /* * Per device pasid table management: */ diff --git a/drivers/iommu/intel-pasid.h b/drivers/iommu/intel-pasid.h index fc8cd8f17de1..e413e884e685 100644 --- a/drivers/iommu/intel-pasid.h +++ b/drivers/iommu/intel-pasid.h @@ -23,6 +23,16 @@ #define is_pasid_enabled(entry) (((entry)->lo >> 3) & 0x1) #define get_pasid_dir_size(entry) (1 << ((((entry)->lo >> 9) & 0x7) + 7)) +/* Virtual command interface for enlightened pasid management. */ +#define VCMD_CMD_ALLOC 0x1 +#define VCMD_CMD_FREE 0x2 +#define VCMD_VRSP_IP 0x1 +#define VCMD_VRSP_SC(e) (((e) >> 1) & 0x3) +#define VCMD_VRSP_SC_SUCCESS 0 +#define VCMD_VRSP_SC_NO_PASID_AVAIL 1 +#define VCMD_VRSP_SC_INVALID_PASID 1 +#define VCMD_VRSP_RESULT(e) (((e) >> 8) & 0xfffff) + /* * Domain ID reserved for pasid entries programmed for first-level * only and pass-through transfer modes. @@ -95,5 +105,6 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu, struct device *dev, int pasid); void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev, int pasid); - +int vcmd_alloc_pasid(struct intel_iommu *iommu, unsigned int *pasid); +void vcmd_free_pasid(struct intel_iommu *iommu, unsigned int pasid); #endif /* __INTEL_PASID_H */ diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 2e1bed9b7eef..1d4b8dcdc5d8 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -161,6 +161,7 @@ #define ecap_smpwc(e) (((e) >> 48) & 0x1) #define ecap_flts(e) (((e) >> 47) & 0x1) #define ecap_slts(e) (((e) >> 46) & 0x1) +#define ecap_vcs(e) (((e) >> 44) & 0x1) #define ecap_smts(e) (((e) >> 43) & 0x1) #define ecap_dit(e) ((e >> 41) & 0x1) #define ecap_pasid(e) ((e >> 40) & 0x1) @@ -282,6 +283,7 @@ /* PRS_REG */ #define DMA_PRS_PPR ((u32)1) +#define DMA_VCS_PAS ((u64)1) #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ do { \ -- 2.7.4