From nobody Fri May 3 19:21:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.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 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541764557163829.6013264383785; Fri, 9 Nov 2018 03:55:57 -0800 (PST) Received: from localhost ([::1]:33419 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5OA-0000lz-Nu for importer@patchew.org; Fri, 09 Nov 2018 06:55:50 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53743) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5KQ-0004Wt-0a for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:51:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL5KN-000715-6V for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:51:57 -0500 Received: from mga05.intel.com ([192.55.52.43]:56443) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL5KM-0006y2-T8 for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:51:55 -0500 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Nov 2018 03:51:54 -0800 Received: from zhangyu-optiplex-9020.bj.intel.com ([10.238.135.159]) by FMSMGA003.fm.intel.com with ESMTP; 09 Nov 2018 03:51:52 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,483,1534834800"; d="scan'208";a="94993234" From: Yu Zhang To: qemu-devel@nongnu.org Date: Fri, 9 Nov 2018 19:49:45 +0800 Message-Id: <1541764187-10732-2-git-send-email-yu.c.zhang@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1541764187-10732-1-git-send-email-yu.c.zhang@linux.intel.com> References: <1541764187-10732-1-git-send-email-yu.c.zhang@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.43 Subject: [Qemu-devel] [PATCH v1 1/3] intel-iommu: differentiate host address width from IOVA address width. 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: Eduardo Habkost , "Michael S. Tsirkin" , Peter Xu , Paolo Bonzini , Igor Mammedov , Richard Henderson 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" Currently, vIOMMU is using the value of IOVA address width, instead of the host address width(HAW) to calculate the number of reserved bits in data structures such as root entries, context entries, and entries of DMA paging structures etc. However values of IOVA address width and of the HAW may not equal. For example, a 48-bit IOVA can only be mapped to host addresses no wider than 46 bits. Using 48, instead of 46 to calculate the reserved bit may result in an invalid IOVA being accepted. To fix this, a new field - haw_bits is introduced in struct IntelIOMMUState, whose value is initialized based on the maximum physical address set to guest CPU. Also, definitions such as VTD_HOST_AW_39/48BIT etc. are renamed to clarify. Signed-off-by: Yu Zhang --- Cc: "Michael S. Tsirkin" =20 Cc: Igor Mammedov =20 Cc: Marcel Apfelbaum Cc: Paolo Bonzini =20 Cc: Richard Henderson =20 Cc: Eduardo Habkost Cc: Peter Xu --- hw/i386/acpi-build.c | 2 +- hw/i386/intel_iommu.c | 54 +++++++++++++++++++++++----------------= ---- include/hw/i386/intel_iommu.h | 9 ++++---- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 236a20e..b989523 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2431,7 +2431,7 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker) } =20 dmar =3D acpi_data_push(table_data, sizeof(*dmar)); - dmar->host_address_width =3D intel_iommu->aw_bits - 1; + dmar->host_address_width =3D intel_iommu->haw_bits - 1; dmar->flags =3D dmar_flags; =20 /* DMAR Remapping Hardware Unit Definition structure */ diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index d97bcbc..e772fca 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -706,8 +706,8 @@ static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState= *s, uint8_t bus_num) * of the translation, can be used for deciding the size of large page. */ static int vtd_iova_to_slpte(VTDContextEntry *ce, uint64_t iova, bool is_w= rite, - uint64_t *slptep, uint32_t *slpte_level, - bool *reads, bool *writes, uint8_t aw_bits) + uint64_t *slptep, uint32_t *slpte_level, bool= *reads, + bool *writes, uint8_t aw_bits, uint8_t haw_bi= ts) { dma_addr_t addr =3D vtd_ce_get_slpt_base(ce); uint32_t level =3D vtd_ce_get_level(ce); @@ -760,7 +760,7 @@ static int vtd_iova_to_slpte(VTDContextEntry *ce, uint6= 4_t iova, bool is_write, *slpte_level =3D level; return 0; } - addr =3D vtd_get_slpte_addr(slpte, aw_bits); + addr =3D vtd_get_slpte_addr(slpte, haw_bits); level--; } } @@ -887,6 +887,7 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_= t start, uint64_t iova =3D start; uint64_t iova_next; int ret =3D 0; + uint8_t haw =3D info->as->iommu_state->haw_bits; =20 trace_vtd_page_walk_level(addr, level, start, end); =20 @@ -925,7 +926,7 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_= t start, * This is a valid PDE (or even bigger than PDE). We need * to walk one further level. */ - ret =3D vtd_page_walk_level(vtd_get_slpte_addr(slpte, info->aw= ), + ret =3D vtd_page_walk_level(vtd_get_slpte_addr(slpte, haw), iova, MIN(iova_next, end), level - 1, read_cur, write_cur, info); } else { @@ -942,7 +943,7 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_= t start, entry.perm =3D IOMMU_ACCESS_FLAG(read_cur, write_cur); entry.addr_mask =3D ~subpage_mask; /* NOTE: this is only meaningful if entry_valid =3D=3D true */ - entry.translated_addr =3D vtd_get_slpte_addr(slpte, info->aw); + entry.translated_addr =3D vtd_get_slpte_addr(slpte, haw); ret =3D vtd_page_walk_one(&entry, info); } =20 @@ -1002,7 +1003,7 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *= s, uint8_t bus_num, return -VTD_FR_ROOT_ENTRY_P; } =20 - if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD(s->aw_bits))) { + if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD(s->haw_bits))) { trace_vtd_re_invalid(re.rsvd, re.val); return -VTD_FR_ROOT_ENTRY_RSVD; } @@ -1019,7 +1020,7 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *= s, uint8_t bus_num, } =20 if ((ce->hi & VTD_CONTEXT_ENTRY_RSVD_HI) || - (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO(s->aw_bits))) { + (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO(s->haw_bits))) { trace_vtd_ce_invalid(ce->hi, ce->lo); return -VTD_FR_CONTEXT_ENTRY_RSVD; } @@ -1360,7 +1361,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *v= td_as, PCIBus *bus, } =20 ret_fr =3D vtd_iova_to_slpte(&ce, addr, is_write, &slpte, &level, - &reads, &writes, s->aw_bits); + &reads, &writes, s->aw_bits, s->haw_bits); if (ret_fr) { ret_fr =3D -ret_fr; if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) { @@ -1378,7 +1379,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *v= td_as, PCIBus *bus, out: vtd_iommu_unlock(s); entry->iova =3D addr & page_mask; - entry->translated_addr =3D vtd_get_slpte_addr(slpte, s->aw_bits) & pag= e_mask; + entry->translated_addr =3D vtd_get_slpte_addr(slpte, s->haw_bits) & pa= ge_mask; entry->addr_mask =3D ~page_mask; entry->perm =3D access_flags; return true; @@ -1396,7 +1397,7 @@ static void vtd_root_table_setup(IntelIOMMUState *s) { s->root =3D vtd_get_quad_raw(s, DMAR_RTADDR_REG); s->root_extended =3D s->root & VTD_RTADDR_RTT; - s->root &=3D VTD_RTADDR_ADDR_MASK(s->aw_bits); + s->root &=3D VTD_RTADDR_ADDR_MASK(s->haw_bits); =20 trace_vtd_reg_dmar_root(s->root, s->root_extended); } @@ -1412,7 +1413,7 @@ static void vtd_interrupt_remap_table_setup(IntelIOMM= UState *s) uint64_t value =3D 0; value =3D vtd_get_quad_raw(s, DMAR_IRTA_REG); s->intr_size =3D 1UL << ((value & VTD_IRTA_SIZE_MASK) + 1); - s->intr_root =3D value & VTD_IRTA_ADDR_MASK(s->aw_bits); + s->intr_root =3D value & VTD_IRTA_ADDR_MASK(s->haw_bits); s->intr_eime =3D value & VTD_IRTA_EIME; =20 /* Notify global invalidation */ @@ -1689,7 +1690,7 @@ static void vtd_handle_gcmd_qie(IntelIOMMUState *s, b= ool en) trace_vtd_inv_qi_enable(en); =20 if (en) { - s->iq =3D iqa_val & VTD_IQA_IQA_MASK(s->aw_bits); + s->iq =3D iqa_val & VTD_IQA_IQA_MASK(s->haw_bits); /* 2^(x+8) entries */ s->iq_size =3D 1UL << ((iqa_val & VTD_IQA_QS) + 8); s->qi_enabled =3D true; @@ -2629,7 +2630,7 @@ static Property vtd_properties[] =3D { ON_OFF_AUTO_AUTO), DEFINE_PROP_BOOL("x-buggy-eim", IntelIOMMUState, buggy_eim, false), DEFINE_PROP_UINT8("x-aw-bits", IntelIOMMUState, aw_bits, - VTD_HOST_ADDRESS_WIDTH), + VTD_ADDRESS_WIDTH), DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE), DEFINE_PROP_END_OF_LIST(), }; @@ -3100,6 +3101,8 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iommu= _mr, IOMMUNotifier *n) static void vtd_init(IntelIOMMUState *s) { X86IOMMUState *x86_iommu =3D X86_IOMMU_DEVICE(s); + CPUState *cs =3D first_cpu; + X86CPU *cpu =3D X86_CPU(cs); =20 memset(s->csr, 0, DMAR_REG_SIZE); memset(s->wmask, 0, DMAR_REG_SIZE); @@ -3119,23 +3122,24 @@ static void vtd_init(IntelIOMMUState *s) s->cap =3D VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS | VTD_CAP_SAGAW_39bit | VTD_CAP_MGAW(s->aw_bits); - if (s->aw_bits =3D=3D VTD_HOST_AW_48BIT) { + if (s->aw_bits =3D=3D VTD_AW_48BIT) { s->cap |=3D VTD_CAP_SAGAW_48bit; } s->ecap =3D VTD_ECAP_QI | VTD_ECAP_IRO; + s->haw_bits =3D cpu->phys_bits; =20 /* * Rsvd field masks for spte */ vtd_paging_entry_rsvd_field[0] =3D ~0ULL; - vtd_paging_entry_rsvd_field[1] =3D VTD_SPTE_PAGE_L1_RSVD_MASK(s->aw_bi= ts); - vtd_paging_entry_rsvd_field[2] =3D VTD_SPTE_PAGE_L2_RSVD_MASK(s->aw_bi= ts); - vtd_paging_entry_rsvd_field[3] =3D VTD_SPTE_PAGE_L3_RSVD_MASK(s->aw_bi= ts); - vtd_paging_entry_rsvd_field[4] =3D VTD_SPTE_PAGE_L4_RSVD_MASK(s->aw_bi= ts); - vtd_paging_entry_rsvd_field[5] =3D VTD_SPTE_LPAGE_L1_RSVD_MASK(s->aw_b= its); - vtd_paging_entry_rsvd_field[6] =3D VTD_SPTE_LPAGE_L2_RSVD_MASK(s->aw_b= its); - vtd_paging_entry_rsvd_field[7] =3D VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_b= its); - vtd_paging_entry_rsvd_field[8] =3D VTD_SPTE_LPAGE_L4_RSVD_MASK(s->aw_b= its); + vtd_paging_entry_rsvd_field[1] =3D VTD_SPTE_PAGE_L1_RSVD_MASK(s->haw_b= its); + vtd_paging_entry_rsvd_field[2] =3D VTD_SPTE_PAGE_L2_RSVD_MASK(s->haw_b= its); + vtd_paging_entry_rsvd_field[3] =3D VTD_SPTE_PAGE_L3_RSVD_MASK(s->haw_b= its); + vtd_paging_entry_rsvd_field[4] =3D VTD_SPTE_PAGE_L4_RSVD_MASK(s->haw_b= its); + vtd_paging_entry_rsvd_field[5] =3D VTD_SPTE_LPAGE_L1_RSVD_MASK(s->haw_= bits); + vtd_paging_entry_rsvd_field[6] =3D VTD_SPTE_LPAGE_L2_RSVD_MASK(s->haw_= bits); + vtd_paging_entry_rsvd_field[7] =3D VTD_SPTE_LPAGE_L3_RSVD_MASK(s->haw_= bits); + vtd_paging_entry_rsvd_field[8] =3D VTD_SPTE_LPAGE_L4_RSVD_MASK(s->haw_= bits); =20 if (x86_iommu->intr_supported) { s->ecap |=3D VTD_ECAP_IR | VTD_ECAP_MHMV; @@ -3261,10 +3265,10 @@ static bool vtd_decide_config(IntelIOMMUState *s, E= rror **errp) } =20 /* Currently only address widths supported are 39 and 48 bits */ - if ((s->aw_bits !=3D VTD_HOST_AW_39BIT) && - (s->aw_bits !=3D VTD_HOST_AW_48BIT)) { + if ((s->aw_bits !=3D VTD_AW_39BIT) && + (s->aw_bits !=3D VTD_AW_48BIT)) { error_setg(errp, "Supported values for x-aw-bits are: %d, %d", - VTD_HOST_AW_39BIT, VTD_HOST_AW_48BIT); + VTD_AW_39BIT, VTD_AW_48BIT); return false; } =20 diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index ed4e758..820451c 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -47,9 +47,9 @@ #define VTD_SID_TO_DEVFN(sid) ((sid) & 0xff) =20 #define DMAR_REG_SIZE 0x230 -#define VTD_HOST_AW_39BIT 39 -#define VTD_HOST_AW_48BIT 48 -#define VTD_HOST_ADDRESS_WIDTH VTD_HOST_AW_39BIT +#define VTD_AW_39BIT 39 +#define VTD_AW_48BIT 48 +#define VTD_ADDRESS_WIDTH VTD_AW_39BIT #define VTD_HAW_MASK(aw) ((1ULL << (aw)) - 1) =20 #define DMAR_REPORT_F_INTR (1) @@ -244,7 +244,8 @@ struct IntelIOMMUState { bool intr_eime; /* Extended interrupt mode enabled */ OnOffAuto intr_eim; /* Toggle for EIM cabability */ bool buggy_eim; /* Force buggy EIM unless eim=3Doff */ - uint8_t aw_bits; /* Host/IOVA address width (in bits) */ + uint8_t aw_bits; /* IOVA address width (in bits) */ + uint8_t haw_bits; /* Hardware address width (in bits) */ =20 /* * Protects IOMMU states in general. Currently it protects the --=20 1.9.1 From nobody Fri May 3 19:21:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.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 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541764430218144.98072549698122; Fri, 9 Nov 2018 03:53:50 -0800 (PST) Received: from localhost ([::1]:33406 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5MC-00071H-3q for importer@patchew.org; Fri, 09 Nov 2018 06:53:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53748) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5KQ-0004Wv-7m for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:51:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL5KO-00076M-Tw for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:51:58 -0500 Received: from mga05.intel.com ([192.55.52.43]:56447) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL5KO-00074h-Kd for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:51:56 -0500 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Nov 2018 03:51:55 -0800 Received: from zhangyu-optiplex-9020.bj.intel.com ([10.238.135.159]) by FMSMGA003.fm.intel.com with ESMTP; 09 Nov 2018 03:51:54 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,483,1534834800"; d="scan'208";a="94993237" From: Yu Zhang To: qemu-devel@nongnu.org Date: Fri, 9 Nov 2018 19:49:46 +0800 Message-Id: <1541764187-10732-3-git-send-email-yu.c.zhang@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1541764187-10732-1-git-send-email-yu.c.zhang@linux.intel.com> References: <1541764187-10732-1-git-send-email-yu.c.zhang@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.43 Subject: [Qemu-devel] [PATCH v1 2/3] intel-iommu: extend VTD emulation to allow 57-bit IOVA address width. 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: Eduardo Habkost , "Michael S. Tsirkin" , Peter Xu , Paolo Bonzini , Richard Henderson 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" A 5-level paging capable VM may choose to use 57-bit IOVA address width. E.g. guest applications like DPDK prefer to use its VA as IOVA when performing VFIO map/unmap operations, to avoid the burden of managing the IOVA space. This patch extends the current vIOMMU logic to cover the extended address width. When creating a VM with 5-level paging feature, one can choose to create a virtual VTD with 5-level paging capability, with configurations like "-device intel-iommu,x-aw-bits=3D57". Signed-off-by: Yu Zhang --- Cc: "Michael S. Tsirkin" Cc: Marcel Apfelbaum Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Peter Xu --- hw/i386/intel_iommu.c | 54 ++++++++++++++++++++++++++++++++------= ---- hw/i386/intel_iommu_internal.h | 6 +++++ include/hw/i386/intel_iommu.h | 1 + 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index e772fca..9cdf755 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -664,16 +664,16 @@ static inline bool vtd_iova_range_check(uint64_t iova= , VTDContextEntry *ce, =20 /* * Rsvd field masks for spte: - * Index [1] to [4] 4k pages - * Index [5] to [8] large pages + * Index [1] to [5] 4k pages + * Index [6] to [10] large pages */ -static uint64_t vtd_paging_entry_rsvd_field[9]; +static uint64_t vtd_paging_entry_rsvd_field[11]; =20 static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level) { if (slpte & VTD_SL_PT_PAGE_SIZE_MASK) { /* Maybe large page */ - return slpte & vtd_paging_entry_rsvd_field[level + 4]; + return slpte & vtd_paging_entry_rsvd_field[level + 5]; } else { return slpte & vtd_paging_entry_rsvd_field[level]; } @@ -3125,6 +3125,9 @@ static void vtd_init(IntelIOMMUState *s) if (s->aw_bits =3D=3D VTD_AW_48BIT) { s->cap |=3D VTD_CAP_SAGAW_48bit; } + else if (s->aw_bits =3D=3D VTD_AW_57BIT) { + s->cap |=3D VTD_CAP_SAGAW_57bit | VTD_CAP_SAGAW_48bit; + } s->ecap =3D VTD_ECAP_QI | VTD_ECAP_IRO; s->haw_bits =3D cpu->phys_bits; =20 @@ -3136,10 +3139,12 @@ static void vtd_init(IntelIOMMUState *s) vtd_paging_entry_rsvd_field[2] =3D VTD_SPTE_PAGE_L2_RSVD_MASK(s->haw_b= its); vtd_paging_entry_rsvd_field[3] =3D VTD_SPTE_PAGE_L3_RSVD_MASK(s->haw_b= its); vtd_paging_entry_rsvd_field[4] =3D VTD_SPTE_PAGE_L4_RSVD_MASK(s->haw_b= its); - vtd_paging_entry_rsvd_field[5] =3D VTD_SPTE_LPAGE_L1_RSVD_MASK(s->haw_= bits); - vtd_paging_entry_rsvd_field[6] =3D VTD_SPTE_LPAGE_L2_RSVD_MASK(s->haw_= bits); - vtd_paging_entry_rsvd_field[7] =3D VTD_SPTE_LPAGE_L3_RSVD_MASK(s->haw_= bits); - vtd_paging_entry_rsvd_field[8] =3D VTD_SPTE_LPAGE_L4_RSVD_MASK(s->haw_= bits); + vtd_paging_entry_rsvd_field[5] =3D VTD_SPTE_PAGE_L5_RSVD_MASK(s->haw_b= its); + vtd_paging_entry_rsvd_field[6] =3D VTD_SPTE_LPAGE_L1_RSVD_MASK(s->haw_= bits); + vtd_paging_entry_rsvd_field[7] =3D VTD_SPTE_LPAGE_L2_RSVD_MASK(s->haw_= bits); + vtd_paging_entry_rsvd_field[8] =3D VTD_SPTE_LPAGE_L3_RSVD_MASK(s->haw_= bits); + vtd_paging_entry_rsvd_field[9] =3D VTD_SPTE_LPAGE_L4_RSVD_MASK(s->haw_= bits); + vtd_paging_entry_rsvd_field[10] =3D VTD_SPTE_LPAGE_L5_RSVD_MASK(s->haw= _bits); =20 if (x86_iommu->intr_supported) { s->ecap |=3D VTD_ECAP_IR | VTD_ECAP_MHMV; @@ -3238,6 +3243,23 @@ static AddressSpace *vtd_host_dma_iommu(PCIBus *bus,= void *opaque, int devfn) return &vtd_as->as; } =20 +static bool host_has_la57(void) +{ + uint32_t ecx, unused; + + host_cpuid(7, 0, &unused, &unused, &ecx, &unused); + return ecx & CPUID_7_0_ECX_LA57; +} + +static bool guest_has_la57(void) +{ + CPUState *cs =3D first_cpu; + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + return env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57; +} + static bool vtd_decide_config(IntelIOMMUState *s, Error **errp) { X86IOMMUState *x86_iommu =3D X86_IOMMU_DEVICE(s); @@ -3264,11 +3286,19 @@ static bool vtd_decide_config(IntelIOMMUState *s, E= rror **errp) } } =20 - /* Currently only address widths supported are 39 and 48 bits */ + /* Currently address widths supported are 39, 48, and 57 bits */ if ((s->aw_bits !=3D VTD_AW_39BIT) && - (s->aw_bits !=3D VTD_AW_48BIT)) { - error_setg(errp, "Supported values for x-aw-bits are: %d, %d", - VTD_AW_39BIT, VTD_AW_48BIT); + (s->aw_bits !=3D VTD_AW_48BIT) && + (s->aw_bits !=3D VTD_AW_57BIT)) { + error_setg(errp, "Supported values for x-aw-bits are: %d, %d, %d", + VTD_AW_39BIT, VTD_AW_48BIT, VTD_AW_57BIT); + return false; + } + + if ((s->aw_bits =3D=3D VTD_AW_57BIT) && + !(host_has_la57() && guest_has_la57())) { + error_setg(errp, "Do not support 57-bit DMA address, unless both " + "host and guest are capable of 5-level paging.\n"= ); return false; } =20 diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index d084099..a7ef24b 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -212,6 +212,8 @@ #define VTD_CAP_SAGAW_39bit (0x2ULL << VTD_CAP_SAGAW_SHIFT) /* 48-bit AGAW, 4-level page-table */ #define VTD_CAP_SAGAW_48bit (0x4ULL << VTD_CAP_SAGAW_SHIFT) + /* 57-bit AGAW, 5-level page-table */ +#define VTD_CAP_SAGAW_57bit (0x8ULL << VTD_CAP_SAGAW_SHIFT) =20 /* IQT_REG */ #define VTD_IQT_QT(val) (((val) >> 4) & 0x7fffULL) @@ -379,6 +381,8 @@ typedef union VTDInvDesc VTDInvDesc; (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) #define VTD_SPTE_PAGE_L4_RSVD_MASK(aw) \ (0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) +#define VTD_SPTE_PAGE_L5_RSVD_MASK(aw) \ + (0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) #define VTD_SPTE_LPAGE_L1_RSVD_MASK(aw) \ (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) #define VTD_SPTE_LPAGE_L2_RSVD_MASK(aw) \ @@ -387,6 +391,8 @@ typedef union VTDInvDesc VTDInvDesc; (0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) #define VTD_SPTE_LPAGE_L4_RSVD_MASK(aw) \ (0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) +#define VTD_SPTE_LPAGE_L5_RSVD_MASK(aw) \ + (0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) =20 /* Information about page-selective IOTLB invalidate */ struct VTDIOTLBPageInvInfo { diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 820451c..7474c4f 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -49,6 +49,7 @@ #define DMAR_REG_SIZE 0x230 #define VTD_AW_39BIT 39 #define VTD_AW_48BIT 48 +#define VTD_AW_57BIT 57 #define VTD_ADDRESS_WIDTH VTD_AW_39BIT #define VTD_HAW_MASK(aw) ((1ULL << (aw)) - 1) =20 --=20 1.9.1 From nobody Fri May 3 19:21:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.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 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1541764428914821.5173031042135; Fri, 9 Nov 2018 03:53:48 -0800 (PST) Received: from localhost ([::1]:33407 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5MB-00072Q-OS for importer@patchew.org; Fri, 09 Nov 2018 06:53:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53770) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL5KR-0004X3-8c for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:52:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL5KQ-00077Y-9G for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:51:59 -0500 Received: from mga05.intel.com ([192.55.52.43]:56447) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gL5KP-00074h-V0 for qemu-devel@nongnu.org; Fri, 09 Nov 2018 06:51:58 -0500 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Nov 2018 03:51:57 -0800 Received: from zhangyu-optiplex-9020.bj.intel.com ([10.238.135.159]) by FMSMGA003.fm.intel.com with ESMTP; 09 Nov 2018 03:51:56 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,483,1534834800"; d="scan'208";a="94993239" From: Yu Zhang To: qemu-devel@nongnu.org Date: Fri, 9 Nov 2018 19:49:47 +0800 Message-Id: <1541764187-10732-4-git-send-email-yu.c.zhang@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1541764187-10732-1-git-send-email-yu.c.zhang@linux.intel.com> References: <1541764187-10732-1-git-send-email-yu.c.zhang@linux.intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.43 Subject: [Qemu-devel] [PATCH v1 3/3] intel-iommu: search iotlb for levels supported by the address width. 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: Eduardo Habkost , "Michael S. Tsirkin" , Peter Xu , Paolo Bonzini , Richard Henderson 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" This patch updates vtd_lookup_iotlb() to search cached mappings only for all page levels supported by address width of current vIOMMU. Also, to cover 57-bit width, the shift of source id(VTD_IOTLB_SID_SHIFT) and of page level(VTD_IOTLB_LVL_SHIFT) are enlarged by 9 - the stride of one paging structure level. Signed-off-by: Yu Zhang --- Cc: "Michael S. Tsirkin" Cc: Marcel Apfelbaum Cc: Paolo Bonzini =20 Cc: Richard Henderson =20 Cc: Eduardo Habkost Cc: Peter Xu --- hw/i386/intel_iommu.c | 5 +++-- hw/i386/intel_iommu_internal.h | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 9cdf755..ce7e17e 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -254,11 +254,12 @@ static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32= _t level) static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source= _id, hwaddr addr) { - VTDIOTLBEntry *entry; + VTDIOTLBEntry *entry =3D NULL; uint64_t key; int level; + int max_level =3D (s->aw_bits - VTD_PAGE_SHIFT_4K) / VTD_SL_LEVEL_BITS; =20 - for (level =3D VTD_SL_PT_LEVEL; level < VTD_SL_PML4_LEVEL; level++) { + for (level =3D VTD_SL_PT_LEVEL; level < max_level; level++) { key =3D vtd_get_iotlb_key(vtd_get_iotlb_gfn(addr, level), source_id, level); entry =3D g_hash_table_lookup(s->iotlb, &key); diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index a7ef24b..bdf2b7c 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -114,8 +114,8 @@ VTD_INTERRUPT_ADDR_FIRST + 1) =20 /* The shift of source_id in the key of IOTLB hash table */ -#define VTD_IOTLB_SID_SHIFT 36 -#define VTD_IOTLB_LVL_SHIFT 52 +#define VTD_IOTLB_SID_SHIFT 45 +#define VTD_IOTLB_LVL_SHIFT 61 #define VTD_IOTLB_MAX_SIZE 1024 /* Max size of the hash table = */ =20 /* IOTLB_REG */ @@ -450,9 +450,6 @@ typedef struct VTDRootEntry VTDRootEntry; #define VTD_SL_LEVEL_BITS 9 =20 /* Second Level Paging Structure */ -#define VTD_SL_PML4_LEVEL 4 -#define VTD_SL_PDP_LEVEL 3 -#define VTD_SL_PD_LEVEL 2 #define VTD_SL_PT_LEVEL 1 #define VTD_SL_PT_ENTRY_NR 512 =20 --=20 1.9.1