From nobody Tue Feb 10 21:41:00 2026 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510701336934704.9148360518312; Tue, 14 Nov 2017 15:15:36 -0800 (PST) Received: from localhost ([::1]:33956 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEkQP-00052X-Lh for importer@patchew.org; Tue, 14 Nov 2017 18:15:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58022) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEkPF-0004QT-2V for qemu-devel@nongnu.org; Tue, 14 Nov 2017 18:14:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eEkP9-0006fV-Pf for qemu-devel@nongnu.org; Tue, 14 Nov 2017 18:14:13 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:43186) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eEkP9-0006dL-Di for qemu-devel@nongnu.org; Tue, 14 Nov 2017 18:14:07 -0500 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id vAENE5Bb027437 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 14 Nov 2017 23:14:06 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id vAENE3BK009768 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 14 Nov 2017 23:14:04 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id vAENE3V3016954; Tue, 14 Nov 2017 23:14:03 GMT Received: from pslinux.us.oracle.com (/10.129.250.229) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 14 Nov 2017 15:14:03 -0800 From: prasad.singamsetty@oracle.com To: qemu-devel@nongnu.org, pbonzini@redhat.com, rth@twiddle.net, ehabkost@redhat.com, mst@redhat.com, imammedo@redhat.com Date: Tue, 14 Nov 2017 18:13:49 -0500 Message-Id: <20171114231350.286025-2-prasad.singamsetty@oracle.com> X-Mailer: git-send-email 2.14.0-rc1 In-Reply-To: <20171114231350.286025-1-prasad.singamsetty@oracle.com> References: <20171114231350.286025-1-prasad.singamsetty@oracle.com> X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] [fuzzy] X-Received-From: 141.146.126.69 Subject: [Qemu-devel] [PATCH v1 1/2] intel-iommu: Redefine macros to enable supporting 48 bit 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: peterx@redhat.com, konrad.wilk@oracle.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Prasad Singamsetty The current implementation of Intel IOMMU code only supports 39 bits host/iova address width so number of macros use hard coded values based on that. This patch is to redefine them so they can be used with variable address widths. This patch doesn't add any new functionality but enables adding support for 48 bit address width. Signed-off-by: Prasad Singamsetty --- hw/i386/intel_iommu.c | 54 ++++++++++++++++++++++++--------------= ---- hw/i386/intel_iommu_internal.h | 34 +++++++++++++++++++------- include/hw/i386/intel_iommu.h | 6 +++-- 3 files changed, 61 insertions(+), 33 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 3a5bb0bc2e..53b3bf244d 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -523,7 +523,7 @@ static inline dma_addr_t vtd_ce_get_slpt_base(VTDContex= tEntry *ce) =20 static inline uint64_t vtd_get_slpte_addr(uint64_t slpte) { - return slpte & VTD_SL_PT_BASE_ADDR_MASK; + return slpte & VTD_SL_PT_BASE_ADDR_MASK(VTD_HOST_ADDRESS_WIDTH); } =20 /* Whether the pte indicates the address of the page frame */ @@ -624,19 +624,12 @@ static inline bool vtd_iova_range_check(uint64_t iova= , VTDContextEntry *ce) return !(iova & ~(vtd_iova_limit(ce) - 1)); } =20 -static const uint64_t vtd_paging_entry_rsvd_field[] =3D { - [0] =3D ~0ULL, - /* For not large page */ - [1] =3D 0x800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM), - [2] =3D 0x800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM), - [3] =3D 0x800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM), - [4] =3D 0x880ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM), - /* For large page */ - [5] =3D 0x800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM), - [6] =3D 0x1ff800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM), - [7] =3D 0x3ffff800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM), - [8] =3D 0x880ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM), -}; +/* + * Rsvd field masks for spte: + * Index [1] to [4] 4k pages + * Index [5] to [8] large pages + */ +static uint64_t vtd_paging_entry_rsvd_field[9]; =20 static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level) { @@ -874,7 +867,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)) { + if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD(VTD_HOST_ADDRESS_WIDTH)))= { trace_vtd_re_invalid(re.rsvd, re.val); return -VTD_FR_ROOT_ENTRY_RSVD; } @@ -891,7 +884,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)) { + (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO(VTD_HOST_ADDRESS_WIDTH)= )) { trace_vtd_ce_invalid(ce->hi, ce->lo); return -VTD_FR_CONTEXT_ENTRY_RSVD; } @@ -1207,7 +1200,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->root &=3D VTD_RTADDR_ADDR_MASK(VTD_HOST_ADDRESS_WIDTH); =20 trace_vtd_reg_dmar_root(s->root, s->root_extended); } @@ -1223,7 +1216,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->intr_root =3D value & VTD_IRTA_ADDR_MASK(VTD_HOST_ADDRESS_WIDTH); s->intr_eime =3D value & VTD_IRTA_EIME; =20 /* Notify global invalidation */ @@ -1479,7 +1472,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->iq =3D iqa_val & VTD_IQA_IQA_MASK(VTD_HOST_ADDRESS_WIDTH); /* 2^(x+8) entries */ s->iq_size =3D 1UL << ((iqa_val & VTD_IQA_QS) + 8); s->qi_enabled =3D true; @@ -2772,12 +2765,12 @@ static void vtd_address_space_unmap(VTDAddressSpace= *as, IOMMUNotifier *n) * VT-d spec), otherwise we need to consider overflow of 64 bits. */ =20 - if (end > VTD_ADDRESS_SIZE) { + if (end > VTD_ADDRESS_SIZE(VTD_HOST_ADDRESS_WIDTH)) { /* * Don't need to unmap regions that is bigger than the whole * VT-d supported address space size */ - end =3D VTD_ADDRESS_SIZE; + end =3D VTD_ADDRESS_SIZE(VTD_HOST_ADDRESS_WIDTH); } =20 assert(start <=3D end); @@ -2866,6 +2859,7 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iommu= _mr, IOMMUNotifier *n) static void vtd_init(IntelIOMMUState *s) { X86IOMMUState *x86_iommu =3D X86_IOMMU_DEVICE(s); + uint8_t aw_bits =3D VTD_HOST_ADDRESS_WIDTH; =20 memset(s->csr, 0, DMAR_REG_SIZE); memset(s->wmask, 0, DMAR_REG_SIZE); @@ -2882,10 +2876,24 @@ static void vtd_init(IntelIOMMUState *s) s->qi_enabled =3D false; s->iq_last_desc_type =3D VTD_INV_DESC_NONE; s->next_frcd_reg =3D 0; - s->cap =3D VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MGAW | - VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS; + 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(VTD_HOST_ADDRESS_WIDTH); s->ecap =3D VTD_ECAP_QI | VTD_ECAP_IRO; =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(aw_bits); + vtd_paging_entry_rsvd_field[2] =3D VTD_SPTE_PAGE_L2_RSVD_MASK(aw_bits); + vtd_paging_entry_rsvd_field[3] =3D VTD_SPTE_PAGE_L3_RSVD_MASK(aw_bits); + vtd_paging_entry_rsvd_field[4] =3D VTD_SPTE_PAGE_L4_RSVD_MASK(aw_bits); + vtd_paging_entry_rsvd_field[5] =3D VTD_SPTE_LPAGE_L1_RSVD_MASK(aw_bits= ); + vtd_paging_entry_rsvd_field[6] =3D VTD_SPTE_LPAGE_L2_RSVD_MASK(aw_bits= ); + vtd_paging_entry_rsvd_field[7] =3D VTD_SPTE_LPAGE_L3_RSVD_MASK(aw_bits= ); + vtd_paging_entry_rsvd_field[8] =3D VTD_SPTE_LPAGE_L4_RSVD_MASK(aw_bits= ); + if (x86_iommu->intr_supported) { s->ecap |=3D VTD_ECAP_IR | VTD_ECAP_MHMV; if (s->intr_eim =3D=3D ON_OFF_AUTO_ON) { diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 0e73a65bf2..77e4a9833a 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -172,10 +172,10 @@ =20 /* RTADDR_REG */ #define VTD_RTADDR_RTT (1ULL << 11) -#define VTD_RTADDR_ADDR_MASK (VTD_HAW_MASK ^ 0xfffULL) +#define VTD_RTADDR_ADDR_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL) =20 /* IRTA_REG */ -#define VTD_IRTA_ADDR_MASK (VTD_HAW_MASK ^ 0xfffULL) +#define VTD_IRTA_ADDR_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL) #define VTD_IRTA_EIME (1ULL << 11) #define VTD_IRTA_SIZE_MASK (0xfULL) =20 @@ -198,8 +198,8 @@ #define VTD_DOMAIN_ID_MASK ((1UL << VTD_DOMAIN_ID_SHIFT) - 1) #define VTD_CAP_ND (((VTD_DOMAIN_ID_SHIFT - 4) / 2) & 7UL= L) #define VTD_MGAW 39 /* Maximum Guest Address Width */ -#define VTD_ADDRESS_SIZE (1ULL << VTD_MGAW) -#define VTD_CAP_MGAW (((VTD_MGAW - 1) & 0x3fULL) << 16) +#define VTD_ADDRESS_SIZE(aw) (1ULL << (aw)) +#define VTD_CAP_MGAW(aw) ((((aw) - 1) & 0x3fULL) << 16) #define VTD_MAMV 18ULL #define VTD_CAP_MAMV (VTD_MAMV << 48) #define VTD_CAP_PSI (1ULL << 39) @@ -219,7 +219,7 @@ #define VTD_IQT_QT(val) (((val) >> 4) & 0x7fffULL) =20 /* IQA_REG */ -#define VTD_IQA_IQA_MASK (VTD_HAW_MASK ^ 0xfffULL) +#define VTD_IQA_IQA_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL) #define VTD_IQA_QS 0x7ULL =20 /* IQH_REG */ @@ -373,6 +373,24 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8 =20 +/* Rsvd field masks for spte */ +#define VTD_SPTE_PAGE_L1_RSVD_MASK(aw) \ + (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) +#define VTD_SPTE_PAGE_L2_RSVD_MASK(aw) \ + (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) +#define VTD_SPTE_PAGE_L3_RSVD_MASK(aw) \ + (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_LPAGE_L1_RSVD_MASK(aw) \ + (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) +#define VTD_SPTE_LPAGE_L2_RSVD_MASK(aw) \ + (0x1ff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) +#define VTD_SPTE_LPAGE_L3_RSVD_MASK(aw) \ + (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)) + /* Information about page-selective IOTLB invalidate */ struct VTDIOTLBPageInvInfo { uint16_t domain_id; @@ -403,7 +421,7 @@ typedef struct VTDRootEntry VTDRootEntry; #define VTD_ROOT_ENTRY_CTP (~0xfffULL) =20 #define VTD_ROOT_ENTRY_NR (VTD_PAGE_SIZE / sizeof(VTDRootEntry)) -#define VTD_ROOT_ENTRY_RSVD (0xffeULL | ~VTD_HAW_MASK) +#define VTD_ROOT_ENTRY_RSVD(aw) (0xffeULL | ~VTD_HAW_MASK(aw)) =20 /* Masks for struct VTDContextEntry */ /* lo */ @@ -415,7 +433,7 @@ typedef struct VTDRootEntry VTDRootEntry; #define VTD_CONTEXT_TT_PASS_THROUGH (2ULL << 2) /* Second Level Page Translation Pointer*/ #define VTD_CONTEXT_ENTRY_SLPTPTR (~0xfffULL) -#define VTD_CONTEXT_ENTRY_RSVD_LO (0xff0ULL | ~VTD_HAW_MASK) +#define VTD_CONTEXT_ENTRY_RSVD_LO(aw) (0xff0ULL | ~VTD_HAW_MASK(aw)) /* hi */ #define VTD_CONTEXT_ENTRY_AW 7ULL /* Adjusted guest-address-width */ #define VTD_CONTEXT_ENTRY_DID(val) (((val) >> 8) & VTD_DOMAIN_ID_MASK) @@ -439,7 +457,7 @@ typedef struct VTDRootEntry VTDRootEntry; #define VTD_SL_RW_MASK 3ULL #define VTD_SL_R 1ULL #define VTD_SL_W (1ULL << 1) -#define VTD_SL_PT_BASE_ADDR_MASK (~(VTD_PAGE_SIZE - 1) & VTD_HAW_MASK) +#define VTD_SL_PT_BASE_ADDR_MASK(aw) (~(VTD_PAGE_SIZE - 1) & VTD_HAW_MASK(= aw)) #define VTD_SL_IGN_COM 0xbff0000000000000ULL =20 #endif diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index ac15e6be14..372b06df45 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -46,8 +46,10 @@ #define VTD_SID_TO_DEVFN(sid) ((sid) & 0xff) =20 #define DMAR_REG_SIZE 0x230 -#define VTD_HOST_ADDRESS_WIDTH 39 -#define VTD_HAW_MASK ((1ULL << VTD_HOST_ADDRESS_WIDTH) - 1) +#define VTD_HOST_AW_39BIT 39 +#define VTD_HOST_AW_48BIT 48 +#define VTD_HOST_ADDRESS_WIDTH VTD_HOST_AW_39BIT +#define VTD_HAW_MASK(aw) ((1ULL << (aw)) - 1) =20 #define DMAR_REPORT_F_INTR (1) =20 --=20 2.14.0-rc1