From nobody Fri Nov 7 23:13:51 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 1548827140028532.671562433058; Tue, 29 Jan 2019 21:45:40 -0800 (PST) Received: from localhost ([127.0.0.1]:60848 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goigs-0005rY-Jd for importer@patchew.org; Wed, 30 Jan 2019 00:45:38 -0500 Received: from eggs.gnu.org ([209.51.188.92]:54318) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goie3-0004IJ-Vd for qemu-devel@nongnu.org; Wed, 30 Jan 2019 00:42:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1goie1-0005MD-JI for qemu-devel@nongnu.org; Wed, 30 Jan 2019 00:42:43 -0500 Received: from mga02.intel.com ([134.134.136.20]:63856) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1goidm-0005Hp-G3 for qemu-devel@nongnu.org; Wed, 30 Jan 2019 00:42:32 -0500 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Jan 2019 21:42:23 -0800 Received: from yisun1-ubuntu2.bj.intel.com ([10.238.145.74]) by fmsmga004.fm.intel.com with ESMTP; 29 Jan 2019 21:42:20 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,539,1539673200"; d="scan'208";a="139979633" From: Yi Sun To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 13:09:12 +0800 Message-Id: <1548824953-23413-3-git-send-email-yi.y.sun@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1548824953-23413-1-git-send-email-yi.y.sun@linux.intel.com> References: <1548824953-23413-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.20 Subject: [Qemu-devel] [RFC v1 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, 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. [Yi Sun is co-developer to rebase and refine the patch.] Signed-off-by: Yi Sun Signed-off-by: Liu, Yi L --- hw/i386/intel_iommu.c | 182 +++++++++++++++++++++++++------------= ---- hw/i386/intel_iommu_internal.h | 8 +- include/hw/i386/intel_iommu.h | 1 + 3 files changed, 116 insertions(+), 75 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 396ac8e..3664a00 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -38,6 +38,7 @@ #include "trace.h" =20 #define vtd_devfn_check(devfn) ((devfn & VTD_DEVFN_CHECK_MASK) ? true : fa= lse) +#define vtd_ecap_smts(s) ((s)->ecap & VTD_ECAP_SMTS) =20 /* context entry operations */ #define vtd_get_ce_size(s, ce) \ @@ -65,6 +66,9 @@ #define vtd_pe_get_slpt_base(pe) ((pe)->val[0] & VTD_SM_PASID_ENTRY_SLPTPT= R) #define vtd_pe_get_domain_id(pe) VTD_SM_PASID_ENTRY_DID((pe)->val[1]) =20 +/* invalidation desc */ +#define vtd_get_inv_desc_width(s) ((s)->iq_dw ? 32 : 16) + static void vtd_address_space_refresh_all(IntelIOMMUState *s); static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n); =20 @@ -1759,6 +1763,11 @@ static void vtd_root_table_setup(IntelIOMMUState *s) s->root_scalable =3D s->root & VTD_RTADDR_SMT; s->root &=3D VTD_RTADDR_ADDR_MASK(s->aw_bits); =20 + /* if Scalable mode is not enabled, enforce iq_dw to be 16 byte */ + if (!s->root_scalable) { + s->iq_dw =3D 0; + } + trace_vtd_reg_dmar_root(s->root, s->root_extended); } =20 @@ -2052,7 +2061,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 */ @@ -2219,54 +2228,66 @@ 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 vtd_get_inv_desc_width(s); + dma_addr_t addr =3D base_addr + offset * dw; + + /* init */ + inv_desc->val[0] =3D 0; + inv_desc->val[1] =3D 0; + inv_desc->val[2] =3D 0; + inv_desc->val[3] =3D 0; + + 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); + inv_desc->val[0] =3D le64_to_cpu(inv_desc->val[0]); + inv_desc->val[1] =3D le64_to_cpu(inv_desc->val[1]); + 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 static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) { - if ((inv_desc->hi & VTD_INV_DESC_WAIT_RSVD_HI) || - (inv_desc->lo & VTD_INV_DESC_WAIT_RSVD_LO)) { - error_report_once("%s: invalid wait desc: hi=3D%"PRIx64", lo=3D%"P= RIx64 - " (reserved nonzero)", __func__, inv_desc->hi, - inv_desc->lo); + if ((inv_desc->val[1] & VTD_INV_DESC_WAIT_RSVD_HI) || + (inv_desc->val[0] & VTD_INV_DESC_WAIT_RSVD_LO)) { + error_report_once("%s: invalid wait desc: val[1]=3D%"PRIx64 + ", val[0]=3D%"PRIx64 + " (reserved nonzero)", __func__, inv_desc->val[1= ], + inv_desc->val[0]); return false; } - if (inv_desc->lo & VTD_INV_DESC_WAIT_SW) { + if (inv_desc->val[0] & VTD_INV_DESC_WAIT_SW) { /* Status Write */ - uint32_t status_data =3D (uint32_t)(inv_desc->lo >> + uint32_t status_data =3D (uint32_t)(inv_desc->val[0] >> VTD_INV_DESC_WAIT_DATA_SHIFT); =20 - assert(!(inv_desc->lo & VTD_INV_DESC_WAIT_IF)); + assert(!(inv_desc->val[0] & VTD_INV_DESC_WAIT_IF)); =20 /* FIXME: need to be masked with HAW? */ - dma_addr_t status_addr =3D inv_desc->hi; + dma_addr_t status_addr =3D inv_desc->val[1]; trace_vtd_inv_desc_wait_sw(status_addr, status_data); status_data =3D cpu_to_le32(status_data); if (dma_memory_write(&address_space_memory, status_addr, &status_d= ata, sizeof(status_data))) { - trace_vtd_inv_desc_wait_write_fail(inv_desc->hi, inv_desc->lo); + trace_vtd_inv_desc_wait_write_fail(inv_desc->val[1], + inv_desc->val[0]); return false; } - } else if (inv_desc->lo & VTD_INV_DESC_WAIT_IF) { + } else if (inv_desc->val[0] & VTD_INV_DESC_WAIT_IF) { /* Interrupt flag */ vtd_generate_completion_event(s); } else { - error_report_once("%s: invalid wait desc: hi=3D%"PRIx64", lo=3D%"P= RIx64 - " (unknown type)", __func__, inv_desc->hi, - inv_desc->lo); + error_report_once("%s: invalid wait desc: val[1]=3D%"PRIx64 + ", val[0]=3D%"PRIx64 + " (unknown type)", __func__, inv_desc->val[1], + inv_desc->val[0]); return false; } return true; @@ -2277,31 +2298,33 @@ static bool vtd_process_context_cache_desc(IntelIOM= MUState *s, { uint16_t sid, fmask; =20 - if ((inv_desc->lo & VTD_INV_DESC_CC_RSVD) || inv_desc->hi) { - error_report_once("%s: invalid cc inv desc: hi=3D%"PRIx64", lo=3D%= "PRIx64 - " (reserved nonzero)", __func__, inv_desc->hi, - inv_desc->lo); + if ((inv_desc->val[0] & VTD_INV_DESC_CC_RSVD) || inv_desc->val[1]) { + error_report_once("%s: invalid cc inv desc: val[1]=3D%"PRIx64 + ", val[0]=3D%"PRIx64 + " (reserved nonzero)", __func__, inv_desc->val[1= ], + inv_desc->val[0]); return false; } - switch (inv_desc->lo & VTD_INV_DESC_CC_G) { + switch (inv_desc->val[0] & VTD_INV_DESC_CC_G) { case VTD_INV_DESC_CC_DOMAIN: trace_vtd_inv_desc_cc_domain( - (uint16_t)VTD_INV_DESC_CC_DID(inv_desc->lo)); + (uint16_t)VTD_INV_DESC_CC_DID(inv_desc->val[0])); /* Fall through */ case VTD_INV_DESC_CC_GLOBAL: vtd_context_global_invalidate(s); break; =20 case VTD_INV_DESC_CC_DEVICE: - sid =3D VTD_INV_DESC_CC_SID(inv_desc->lo); - fmask =3D VTD_INV_DESC_CC_FM(inv_desc->lo); + sid =3D VTD_INV_DESC_CC_SID(inv_desc->val[0]); + fmask =3D VTD_INV_DESC_CC_FM(inv_desc->val[0]); vtd_context_device_invalidate(s, sid, fmask); break; =20 default: - error_report_once("%s: invalid cc inv desc: hi=3D%"PRIx64", lo=3D%= "PRIx64 - " (invalid type)", __func__, inv_desc->hi, - inv_desc->lo); + error_report_once("%s: invalid cc inv desc: val[1]=3D%"PRIx64 + ", val[0]=3D%"PRIx64 + " (invalid type)", __func__, inv_desc->val[1], + inv_desc->val[0]); return false; } return true; @@ -2313,32 +2336,32 @@ static bool vtd_process_iotlb_desc(IntelIOMMUState = *s, VTDInvDesc *inv_desc) uint8_t am; hwaddr addr; =20 - if ((inv_desc->lo & VTD_INV_DESC_IOTLB_RSVD_LO) || - (inv_desc->hi & VTD_INV_DESC_IOTLB_RSVD_HI)) { - error_report_once("%s: invalid iotlb inv desc: hi=3D0x%"PRIx64 - ", lo=3D0x%"PRIx64" (reserved bits unzero)\n", - __func__, inv_desc->hi, inv_desc->lo); + if ((inv_desc->val[0] & VTD_INV_DESC_IOTLB_RSVD_LO) || + (inv_desc->val[1] & VTD_INV_DESC_IOTLB_RSVD_HI)) { + error_report_once("%s: invalid iotlb inv desc: val[1]=3D0x%"PRIx64 + ", val[0]=3D0x%"PRIx64" (reserved bits unzero)\n= ", + __func__, inv_desc->val[1], inv_desc->val[0]); return false; } =20 - switch (inv_desc->lo & VTD_INV_DESC_IOTLB_G) { + switch (inv_desc->val[0] & VTD_INV_DESC_IOTLB_G) { case VTD_INV_DESC_IOTLB_GLOBAL: vtd_iotlb_global_invalidate(s); break; =20 case VTD_INV_DESC_IOTLB_DOMAIN: - domain_id =3D VTD_INV_DESC_IOTLB_DID(inv_desc->lo); + domain_id =3D VTD_INV_DESC_IOTLB_DID(inv_desc->val[0]); vtd_iotlb_domain_invalidate(s, domain_id); break; =20 case VTD_INV_DESC_IOTLB_PAGE: - domain_id =3D VTD_INV_DESC_IOTLB_DID(inv_desc->lo); - addr =3D VTD_INV_DESC_IOTLB_ADDR(inv_desc->hi); - am =3D VTD_INV_DESC_IOTLB_AM(inv_desc->hi); + domain_id =3D VTD_INV_DESC_IOTLB_DID(inv_desc->val[0]); + addr =3D VTD_INV_DESC_IOTLB_ADDR(inv_desc->val[1]); + am =3D VTD_INV_DESC_IOTLB_AM(inv_desc->val[1]); if (am > VTD_MAMV) { - error_report_once("%s: invalid iotlb inv desc: hi=3D0x%"PRIx64 - ", lo=3D0x%"PRIx64" (am=3D%u > VTD_MAMV=3D%u= )\n", - __func__, inv_desc->hi, inv_desc->lo, + error_report_once("%s: invalid iotlb inv desc: val[1]=3D0x%"PR= Ix64 + ", val[0]=3D0x%"PRIx64" (am=3D%u > VTD_MAMV= =3D%u)\n", + __func__, inv_desc->val[1], inv_desc->val[0], am, (unsigned)VTD_MAMV); return false; } @@ -2346,10 +2369,10 @@ static bool vtd_process_iotlb_desc(IntelIOMMUState = *s, VTDInvDesc *inv_desc) break; =20 default: - error_report_once("%s: invalid iotlb inv desc: hi=3D0x%"PRIx64 - ", lo=3D0x%"PRIx64" (type mismatch: 0x%llx)\n", - __func__, inv_desc->hi, inv_desc->lo, - inv_desc->lo & VTD_INV_DESC_IOTLB_G); + error_report_once("%s: invalid iotlb inv desc: val[1]=3D0x%"PRIx64 + ", val[0]=3D0x%"PRIx64" (type mismatch: 0x%llx)\= n", + __func__, inv_desc->val[1], inv_desc->val[0], + inv_desc->val[0] & VTD_INV_DESC_IOTLB_G); return false; } return true; @@ -2381,17 +2404,17 @@ static bool vtd_process_device_iotlb_desc(IntelIOMM= UState *s, bool size; uint8_t bus_num; =20 - addr =3D VTD_INV_DESC_DEVICE_IOTLB_ADDR(inv_desc->hi); - sid =3D VTD_INV_DESC_DEVICE_IOTLB_SID(inv_desc->lo); + addr =3D VTD_INV_DESC_DEVICE_IOTLB_ADDR(inv_desc->val[1]); + sid =3D VTD_INV_DESC_DEVICE_IOTLB_SID(inv_desc->val[0]); devfn =3D sid & 0xff; bus_num =3D sid >> 8; - size =3D VTD_INV_DESC_DEVICE_IOTLB_SIZE(inv_desc->hi); + size =3D VTD_INV_DESC_DEVICE_IOTLB_SIZE(inv_desc->val[1]); =20 - if ((inv_desc->lo & VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO) || - (inv_desc->hi & VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI)) { - error_report_once("%s: invalid dev-iotlb inv desc: hi=3D%"PRIx64 - ", lo=3D%"PRIx64" (reserved nonzero)", __func__, - inv_desc->hi, inv_desc->lo); + if ((inv_desc->val[0] & VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO) || + (inv_desc->val[1] & VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI)) { + error_report_once("%s: invalid dev-iotlb inv desc: val[1]=3D%"PRIx= 64 + ", val[0]=3D%"PRIx64" (reserved nonzero)", __fun= c__, + inv_desc->val[1], inv_desc->val[0]); return false; } =20 @@ -2437,54 +2460,64 @@ 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; + if (inv_desc.val[3] || inv_desc.val[2]) { + error_report_once("%s: invalid inv desc: val[3]=3D%"PRIx64 + ", val[2]=3D%"PRIx64 + " (detect reserve non-zero)", __func__, + inv_desc.val[3], + inv_desc.val[2]); + return false; + } + + desc_type =3D inv_desc.val[0] & VTD_INV_DESC_TYPE; /* FIXME: should update at first or at last? */ s->iq_last_desc_type =3D desc_type; =20 switch (desc_type) { case VTD_INV_DESC_CC: - trace_vtd_inv_desc("context-cache", inv_desc.hi, inv_desc.lo); + trace_vtd_inv_desc("context-cache", inv_desc.val[1], inv_desc.val[= 0]); if (!vtd_process_context_cache_desc(s, &inv_desc)) { return false; } break; =20 case VTD_INV_DESC_IOTLB: - trace_vtd_inv_desc("iotlb", inv_desc.hi, inv_desc.lo); + trace_vtd_inv_desc("iotlb", inv_desc.val[1], inv_desc.val[0]); if (!vtd_process_iotlb_desc(s, &inv_desc)) { return false; } break; =20 case VTD_INV_DESC_WAIT: - trace_vtd_inv_desc("wait", inv_desc.hi, inv_desc.lo); + trace_vtd_inv_desc("wait", inv_desc.val[1], inv_desc.val[0]); if (!vtd_process_wait_desc(s, &inv_desc)) { return false; } break; =20 case VTD_INV_DESC_IEC: - trace_vtd_inv_desc("iec", inv_desc.hi, inv_desc.lo); + trace_vtd_inv_desc("iec", inv_desc.val[1], inv_desc.val[0]); if (!vtd_process_inv_iec_desc(s, &inv_desc)) { return false; } break; =20 case VTD_INV_DESC_DEVICE: - trace_vtd_inv_desc("device", inv_desc.hi, inv_desc.lo); + trace_vtd_inv_desc("device", inv_desc.val[1], inv_desc.val[0]); if (!vtd_process_device_iotlb_desc(s, &inv_desc)) { return false; } break; =20 default: - error_report_once("%s: invalid inv desc: hi=3D%"PRIx64", lo=3D%"PR= Ix64 - " (unknown type)", __func__, inv_desc.hi, - inv_desc.lo); + error_report_once("%s: invalid inv desc: val[1]=3D%"PRIx64 + ", val[0]=3D%"PRIx64 + " (unknown type)", __func__, inv_desc.val[1], + inv_desc.val[0]); return false; } s->iq_head++; @@ -2525,7 +2558,7 @@ 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); + 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)) { @@ -2794,6 +2827,11 @@ static void vtd_mem_write(void *opaque, hwaddr addr, } else { vtd_set_quad(s, addr, val); } + if (vtd_ecap_smts(s)) { + s->iq_dw =3D val & VTD_IQA_DW_MASK; + } else { + s->iq_dw =3D 0; + } break; =20 case DMAR_IQA_REG_HI: @@ -3577,7 +3615,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 02674f9..2a753c5 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,13 @@ #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)) =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 @@ -321,8 +324,7 @@ typedef struct VTDInvDescIEC VTDInvDescIEC; /* Queued Invalidation Descriptor */ union VTDInvDesc { struct { - uint64_t lo; - uint64_t hi; + uint64_t val[4]; }; union { VTDInvDescIEC iec; diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index ff13ff27..a5da139 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -230,6 +230,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 */ + uint16_t iq_dw; /* IQ descriptor width */ 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