From nobody Fri Nov 7 23:19:28 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.intel.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1551363826211900.8176309736754; Thu, 28 Feb 2019 06:23:46 -0800 (PST) Received: from localhost ([127.0.0.1]:39275 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzMb8-0003ic-2S for importer@patchew.org; Thu, 28 Feb 2019 09:23:42 -0500 Received: from eggs.gnu.org ([209.51.188.92]:45523) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzMZ0-0002XN-Pq for qemu-devel@nongnu.org; Thu, 28 Feb 2019 09:21:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gzMYy-00073t-Im for qemu-devel@nongnu.org; Thu, 28 Feb 2019 09:21:30 -0500 Received: from mga07.intel.com ([134.134.136.100]:44789) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gzMYy-000731-8k for qemu-devel@nongnu.org; Thu, 28 Feb 2019 09:21:28 -0500 Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Feb 2019 06:21:27 -0800 Received: from yisun1-ubuntu2.bj.intel.com ([10.238.144.135]) by orsmga008.jf.intel.com with ESMTP; 28 Feb 2019 06:21:24 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,423,1544515200"; d="scan'208";a="121524701" From: Yi Sun To: qemu-devel@nongnu.org Date: Thu, 28 Feb 2019 21:47:56 +0800 Message-Id: <1551361677-28933-3-git-send-email-yi.y.sun@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1551361677-28933-1-git-send-email-yi.y.sun@linux.intel.com> References: <1551361677-28933-1-git-send-email-yi.y.sun@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.100 Subject: [Qemu-devel] [RFC v2 2/3] intel_iommu: add 256 bits qi_desc support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kevin.tian@intel.com, yi.l.liu@intel.com, Yi Sun , ehabkost@redhat.com, mst@redhat.com, jasowang@redhat.com, peterx@redhat.com, yi.y.sun@intel.com, pbonzini@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Liu, Yi L" Per Intel(R) VT-d 3.0, the qi_desc is 256 bits in Scalable Mode. This patch adds emulation of 256bits qi_desc. Signed-off-by: Liu, Yi L [Yi Sun is co-developer to rebase and refine the patch.] Signed-off-by: Yi Sun Reviewed-by: Peter Xu --- v2: - modify s-o-b position. - remove unnecessary macros. - change 'iq_dw' type to bool. - remove initialization to 'inv_desc->val[]'. - modify 'VTDInvDesc' to add a union 'val[4]' to be compatible with both legacy mode and scalable mode. --- hw/i386/intel_iommu.c | 40 +++++++++++++++++++++++++++++---------= -- hw/i386/intel_iommu_internal.h | 9 ++++++++- include/hw/i386/intel_iommu.h | 1 + 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 109fdbc..d1eb0c5 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -2028,7 +2028,7 @@ static void vtd_handle_gcmd_qie(IntelIOMMUState *s, b= ool en) if (en) { s->iq =3D iqa_val & VTD_IQA_IQA_MASK(s->aw_bits); /* 2^(x+8) entries */ - s->iq_size =3D 1UL << ((iqa_val & VTD_IQA_QS) + 8); + s->iq_size =3D 1UL << ((iqa_val & VTD_IQA_QS) + 8 - (s->iq_dw ? 1 = : 0)); s->qi_enabled =3D true; trace_vtd_inv_qi_setup(s->iq, s->iq_size); /* Ok - report back to driver */ @@ -2195,19 +2195,24 @@ static void vtd_handle_iotlb_write(IntelIOMMUState = *s) } =20 /* Fetch an Invalidation Descriptor from the Invalidation Queue */ -static bool vtd_get_inv_desc(dma_addr_t base_addr, uint32_t offset, +static bool vtd_get_inv_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) { - dma_addr_t addr =3D base_addr + offset * sizeof(*inv_desc); - if (dma_memory_read(&address_space_memory, addr, inv_desc, - sizeof(*inv_desc))) { - error_report_once("Read INV DESC failed"); - inv_desc->lo =3D 0; - inv_desc->hi =3D 0; + dma_addr_t base_addr =3D s->iq; + uint32_t offset =3D s->iq_head; + uint32_t dw =3D s->iq_dw ? 32 : 16; + dma_addr_t addr =3D base_addr + offset * dw; + + if (dma_memory_read(&address_space_memory, addr, inv_desc, dw)) { + error_report_once("Read INV DESC failed."); return false; } inv_desc->lo =3D le64_to_cpu(inv_desc->lo); inv_desc->hi =3D le64_to_cpu(inv_desc->hi); + if (dw =3D=3D 32) { + inv_desc->val[2] =3D le64_to_cpu(inv_desc->val[2]); + inv_desc->val[3] =3D le64_to_cpu(inv_desc->val[3]); + } return true; } =20 @@ -2413,10 +2418,11 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s) uint8_t desc_type; =20 trace_vtd_inv_qi_head(s->iq_head); - if (!vtd_get_inv_desc(s->iq, s->iq_head, &inv_desc)) { + if (!vtd_get_inv_desc(s, &inv_desc)) { s->iq_last_desc_type =3D VTD_INV_DESC_NONE; return false; } + desc_type =3D inv_desc.lo & VTD_INV_DESC_TYPE; /* FIXME: should update at first or at last? */ s->iq_last_desc_type =3D desc_type; @@ -2501,7 +2507,12 @@ static void vtd_handle_iqt_write(IntelIOMMUState *s) { uint64_t val =3D vtd_get_quad_raw(s, DMAR_IQT_REG); =20 - s->iq_tail =3D VTD_IQT_QT(val); + if (s->iq_dw && val & VTD_IQT_QT_256_RSV_BIT) { + error_report_once("%s: RSV bit is set: val=3D0x%"PRIx64, + __func__, val); + return; + } + s->iq_tail =3D VTD_IQT_QT(s->iq_dw, val); trace_vtd_inv_qi_tail(s->iq_tail); =20 if (s->qi_enabled && !(vtd_get_long_raw(s, DMAR_FSTS_REG) & VTD_FSTS_I= QE)) { @@ -2770,6 +2781,12 @@ static void vtd_mem_write(void *opaque, hwaddr addr, } else { vtd_set_quad(s, addr, val); } + if (s->ecap & VTD_ECAP_SMTS && + val & VTD_IQA_DW_MASK) { + s->iq_dw =3D true; + } else { + s->iq_dw =3D false; + } break; =20 case DMAR_IQA_REG_HI: @@ -3477,6 +3494,7 @@ static void vtd_init(IntelIOMMUState *s) s->iq_size =3D 0; s->qi_enabled =3D false; s->iq_last_desc_type =3D VTD_INV_DESC_NONE; + s->iq_dw =3D false; s->next_frcd_reg =3D 0; s->cap =3D VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS | @@ -3554,7 +3572,7 @@ static void vtd_init(IntelIOMMUState *s) =20 vtd_define_quad(s, DMAR_IQH_REG, 0, 0, 0); vtd_define_quad(s, DMAR_IQT_REG, 0, 0x7fff0ULL, 0); - vtd_define_quad(s, DMAR_IQA_REG, 0, 0xfffffffffffff007ULL, 0); + vtd_define_quad(s, DMAR_IQA_REG, 0, 0xfffffffffffff807ULL, 0); vtd_define_long(s, DMAR_ICS_REG, 0, 0, 0x1UL); vtd_define_long(s, DMAR_IECTL_REG, 0x80000000UL, 0x80000000UL, 0); vtd_define_long(s, DMAR_IEDATA_REG, 0, 0xffffffffUL, 0); diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index fe72bc3..016fa4c 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -190,6 +190,7 @@ #define VTD_ECAP_EIM (1ULL << 4) #define VTD_ECAP_PT (1ULL << 6) #define VTD_ECAP_MHMV (15ULL << 20) +#define VTD_ECAP_SMTS (1ULL << 43) =20 /* CAP_REG */ /* (offset >> 4) << 24 */ @@ -218,11 +219,14 @@ #define VTD_CAP_SAGAW_48bit (0x4ULL << VTD_CAP_SAGAW_SHIFT) =20 /* IQT_REG */ -#define VTD_IQT_QT(val) (((val) >> 4) & 0x7fffULL) +#define VTD_IQT_QT(dw_bit, val) (dw_bit ? (((val) >> 5) & 0x3fffULL) := \ + (((val) >> 4) & 0x7fffULL)) +#define VTD_IQT_QT_256_RSV_BIT 0x10 =20 /* IQA_REG */ #define VTD_IQA_IQA_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL) #define VTD_IQA_QS 0x7ULL +#define VTD_IQA_DW_MASK 0x800 =20 /* IQH_REG */ #define VTD_IQH_QH_SHIFT 4 @@ -324,6 +328,9 @@ union VTDInvDesc { uint64_t lo; uint64_t hi; }; + struct { + uint64_t val[4]; + }; union { VTDInvDescIEC iec; }; diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 72c5ca6..2877c94 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -238,6 +238,7 @@ struct IntelIOMMUState { uint16_t iq_tail; /* Current invalidation queue tail */ dma_addr_t iq; /* Current invalidation queue pointer = */ uint16_t iq_size; /* IQ Size in number of entries */ + bool iq_dw; /* IQ descriptor width 256bit or not */ bool qi_enabled; /* Set if the QI is enabled */ uint8_t iq_last_desc_type; /* The type of last completed descript= or */ =20 --=20 1.9.1