From patchwork Mon Aug 5 06:27:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968891 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=eotNDFJH; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WcmnQ3fL3z1yYD for ; Mon, 5 Aug 2024 16:32:10 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarEh-0001sG-Df; Mon, 05 Aug 2024 02:30:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEY-0001pg-Sq for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:19 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEV-00029V-Rd for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839416; x=1754375416; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=l41BcR440mA6+TiRFU1SKZpG3Xu4CcWqtyCJGTHJaqo=; b=eotNDFJHYNMl4R551kbJv1y3sI2bMuUn8g0upu71x4QK0/m0oPua+uxQ YmXkMxWn4gxGrkKwM9FKBQlABSgyaHSy9xR3lhQVdBmCNqzgcn+NKsFe5 hnJbo8IbP0ivVvfUgahcAakua2xTeMx04j4koGVUOCOnpe533S2Av3HMU ILg6SOI8C1QTbRZ0+l+s1gJXa6zE6rLT6Bgv9786IlNnHYeRASCP2Y5lq die2gfvpUROXGQe7Vrmk69CN70gukTPYT7WU/I7QysNJtEZGEaUrVbuFx wK94jxe0MNC9w+/ePT+PbwnRXm+8TUutEaPpNWg9PcuDJg/kN9aq6vfSQ g==; X-CSE-ConnectionGUID: 3qneI/VFScSUaILTdOZAKQ== X-CSE-MsgGUID: LEz19P0MRcq0txB3SE0pqw== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282667" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282667" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:12 -0700 X-CSE-ConnectionGUID: rfFOoNioQ5CYCFX+8iPI4A== X-CSE-MsgGUID: VxP9kF4XRTaxIGphVK8KIw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786491" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:07 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Eduardo Habkost Subject: [PATCH v2 01/17] intel_iommu: Use the latest fault reasons defined by spec Date: Mon, 5 Aug 2024 14:27:11 +0800 Message-Id: <20240805062727.2307552-2-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Yu Zhang Spec revision 3.0 or above defines more detailed fault reasons for scalable mode. So introduce them into emulation code, see spec section 7.1.2 for details. Note spec revision has no relation with VERSION register, Guest kernel should not use that register to judge what features are supported. Instead cap/ecap bits should be checked. Signed-off-by: Yu Zhang Signed-off-by: Zhenzhong Duan Reviewed-by: Clément Mathieu--Drif Reviewed-by: Yi Liu --- hw/i386/intel_iommu_internal.h | 9 ++++++++- hw/i386/intel_iommu.c | 25 ++++++++++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 5f32c36943..8fa27c7f3b 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -311,7 +311,14 @@ typedef enum VTDFaultReason { * request while disabled */ VTD_FR_IR_SID_ERR = 0x26, /* Invalid Source-ID */ - VTD_FR_PASID_TABLE_INV = 0x58, /*Invalid PASID table entry */ + /* PASID directory entry access failure */ + VTD_FR_PASID_DIR_ACCESS_ERR = 0x50, + /* The Present(P) field of pasid directory entry is 0 */ + VTD_FR_PASID_DIR_ENTRY_P = 0x51, + VTD_FR_PASID_TABLE_ACCESS_ERR = 0x58, /* PASID table entry access failure */ + /* The Present(P) field of pasid table entry is 0 */ + VTD_FR_PASID_ENTRY_P = 0x59, + VTD_FR_PASID_TABLE_ENTRY_INV = 0x5b, /*Invalid PASID table entry */ /* Output address in the interrupt address range for scalable mode */ VTD_FR_SM_INTERRUPT_ADDR = 0x87, diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 16d2885fcc..c52912f593 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -796,7 +796,7 @@ static int vtd_get_pdire_from_pdir_table(dma_addr_t pasid_dir_base, addr = pasid_dir_base + index * entry_size; if (dma_memory_read(&address_space_memory, addr, pdire, entry_size, MEMTXATTRS_UNSPECIFIED)) { - return -VTD_FR_PASID_TABLE_INV; + return -VTD_FR_PASID_DIR_ACCESS_ERR; } pdire->val = le64_to_cpu(pdire->val); @@ -814,6 +814,7 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, dma_addr_t addr, VTDPASIDEntry *pe) { + uint8_t pgtt; uint32_t index; dma_addr_t entry_size; X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s); @@ -823,7 +824,7 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, addr = addr + index * entry_size; if (dma_memory_read(&address_space_memory, addr, pe, entry_size, MEMTXATTRS_UNSPECIFIED)) { - return -VTD_FR_PASID_TABLE_INV; + return -VTD_FR_PASID_TABLE_ACCESS_ERR; } for (size_t i = 0; i < ARRAY_SIZE(pe->val); i++) { pe->val[i] = le64_to_cpu(pe->val[i]); @@ -831,11 +832,13 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, /* Do translation type check */ if (!vtd_pe_type_check(x86_iommu, pe)) { - return -VTD_FR_PASID_TABLE_INV; + return -VTD_FR_PASID_TABLE_ENTRY_INV; } - if (!vtd_is_level_supported(s, VTD_PE_GET_LEVEL(pe))) { - return -VTD_FR_PASID_TABLE_INV; + pgtt = VTD_PE_GET_TYPE(pe); + if (pgtt == VTD_SM_PASID_ENTRY_SLT && + !vtd_is_level_supported(s, VTD_PE_GET_LEVEL(pe))) { + return -VTD_FR_PASID_TABLE_ENTRY_INV; } return 0; @@ -876,7 +879,7 @@ static int vtd_get_pe_from_pasid_table(IntelIOMMUState *s, } if (!vtd_pdire_present(&pdire)) { - return -VTD_FR_PASID_TABLE_INV; + return -VTD_FR_PASID_DIR_ENTRY_P; } ret = vtd_get_pe_from_pdire(s, pasid, &pdire, pe); @@ -885,7 +888,7 @@ static int vtd_get_pe_from_pasid_table(IntelIOMMUState *s, } if (!vtd_pe_present(pe)) { - return -VTD_FR_PASID_TABLE_INV; + return -VTD_FR_PASID_ENTRY_P; } return 0; @@ -938,7 +941,7 @@ static int vtd_ce_get_pasid_fpd(IntelIOMMUState *s, } if (!vtd_pdire_present(&pdire)) { - return -VTD_FR_PASID_TABLE_INV; + return -VTD_FR_PASID_DIR_ENTRY_P; } /* @@ -1795,7 +1798,11 @@ static const bool vtd_qualified_faults[] = { [VTD_FR_ROOT_ENTRY_RSVD] = false, [VTD_FR_PAGING_ENTRY_RSVD] = true, [VTD_FR_CONTEXT_ENTRY_TT] = true, - [VTD_FR_PASID_TABLE_INV] = false, + [VTD_FR_PASID_DIR_ACCESS_ERR] = false, + [VTD_FR_PASID_DIR_ENTRY_P] = true, + [VTD_FR_PASID_TABLE_ACCESS_ERR] = false, + [VTD_FR_PASID_ENTRY_P] = true, + [VTD_FR_PASID_TABLE_ENTRY_INV] = true, [VTD_FR_SM_INTERRUPT_ADDR] = true, [VTD_FR_MAX] = false, }; From patchwork Mon Aug 5 06:27:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968885 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=jbJgskTy; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmmp2Hfjz1yf5 for ; Mon, 5 Aug 2024 16:31:38 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarEj-00021V-Ov; Mon, 05 Aug 2024 02:30:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEZ-0001qf-QV for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:26 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEX-00029G-VW for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839418; x=1754375418; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9LXohiLjp21YRrEmBqMb76SuUIhUz5QsAFu7IDNctFw=; b=jbJgskTyfJmzJbmSYgav8Pu46LY645DQWvkKguHpOvKV9sZ+ODlJx4LA JvzLVYEJKWKiPCELzO2KWC8MZL6rYQxgG8NPo6AjVfANf3AufxP9GaFbz 0Nh3FHHtA8sAJGIG0SPeNvGpQ8prmjHel/IaRPqBWqdM0Ie1P+FN4DcPu q7+ZVOR4Bt2HRttPrPAK/VrFJojONqwUXXF64ctMW9TB6wB40RrcRkWZy EB4U+dhjRHlUh/kJy5GhVeG7omrP2/g9eSt/fV6vXBpTu81PzOt38nN6g 1BYX3fVZzfDWZ+ZPnDaYX2bgDg5q3MfiVWlzU831gJ+azl9jPyf1Q9Qr/ g==; X-CSE-ConnectionGUID: BS1w6hjlSay9QSoF2Oi+FA== X-CSE-MsgGUID: zMZzhrqUTHS1S0kq1cBoww== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282678" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282678" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:17 -0700 X-CSE-ConnectionGUID: 7hwHcRP+Qume+MRc7RYDpA== X-CSE-MsgGUID: avZsAvnQQQWPmkqNZ5AkTg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786546" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:12 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Eduardo Habkost Subject: [PATCH v2 02/17] intel_iommu: Make pasid entry type check accurate Date: Mon, 5 Aug 2024 14:27:12 +0800 Message-Id: <20240805062727.2307552-3-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org When guest configures Nested Translation(011b) or First-stage Translation only (001b), type check passed unaccurately. Fails the type check in those cases as their simulation isn't supported yet. Fixes: fb43cf739e1 ("intel_iommu: scalable mode emulation") Suggested-by: Yi Liu Signed-off-by: Zhenzhong Duan Reviewed-by: Clément Mathieu--Drif Reviewed-by: Yi Liu --- hw/i386/intel_iommu.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index c52912f593..e3465fc27d 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -759,20 +759,16 @@ static inline bool vtd_pe_type_check(X86IOMMUState *x86_iommu, VTDPASIDEntry *pe) { switch (VTD_PE_GET_TYPE(pe)) { - case VTD_SM_PASID_ENTRY_FLT: case VTD_SM_PASID_ENTRY_SLT: - case VTD_SM_PASID_ENTRY_NESTED: - break; + return true; case VTD_SM_PASID_ENTRY_PT: - if (!x86_iommu->pt_supported) { - return false; - } - break; + return x86_iommu->pt_supported; + case VTD_SM_PASID_ENTRY_FLT: + case VTD_SM_PASID_ENTRY_NESTED: default: /* Unknown type */ return false; } - return true; } static inline bool vtd_pdire_present(VTDPASIDDirEntry *pdire) From patchwork Mon Aug 5 06:27:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968888 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=kPiN7yX3; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmn60J5hz1yYD for ; Mon, 5 Aug 2024 16:31:54 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarEj-0001yk-CO; Mon, 05 Aug 2024 02:30:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEe-0001qy-WE for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:26 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEc-00029G-42 for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839422; x=1754375422; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MsprqmxtgK1HuYvpPYAbr8ekbcHQ69W7VlCS7gqHGXM=; b=kPiN7yX3j9Lko/t/rkxacNp0WmUEZD2W8a4JVvwzohT/1unEuLlz7U0q v6kS39rt0mLdvVcgqNUHDk8K7JB25+Ts0saFIJb8IstYYH7gck1Yyg88y m1oWEQYR5viEOV1l4W2arsro1uhbM6Np5pkv7y3QUy/niPjfPPVzKQVW4 MinkM1SSDdnBfV0sAYS2uyAHPVwzUIsssqpsA52+fnHojKiy7AcTmi0eu TgWCNfh7lVH2RLfsBYTJ6GOGRb38TAgfswpiggVLps81A5LJK3JxeskA1 kUL9JrZb/BqznDC6zXzXHI2uUdTNk+uclowfwtmAhqNGogxSbrwWmLjMb w==; X-CSE-ConnectionGUID: GwAGK9MqSdiQ+AzK0OX7AQ== X-CSE-MsgGUID: cwXf4B0IRxeCeuWEtb/qmw== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282687" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282687" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:22 -0700 X-CSE-ConnectionGUID: tBna07eAT8u3JMg038EitQ== X-CSE-MsgGUID: U4Mf0B7lRZWDyHloVLhExA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786578" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:17 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum Subject: [PATCH v2 03/17] intel_iommu: Add a placeholder variable for scalable modern mode Date: Mon, 5 Aug 2024 14:27:13 +0800 Message-Id: <20240805062727.2307552-4-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add an new element scalable_mode in IntelIOMMUState to mark scalable modern mode, this element will be exposed as an intel_iommu property finally. For now, it's only a placehholder and used for address width compatibility check and block host device passthrough until nesting is supported. Signed-off-by: Yi Liu Signed-off-by: Zhenzhong Duan --- include/hw/i386/intel_iommu.h | 1 + hw/i386/intel_iommu.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 1eb05c29fc..788ed42477 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -262,6 +262,7 @@ struct IntelIOMMUState { bool caching_mode; /* RO - is cap CM enabled? */ bool scalable_mode; /* RO - is Scalable Mode supported? */ + bool scalable_modern; /* RO - is modern SM supported? */ bool snoop_control; /* RO - is SNP filed supported? */ dma_addr_t root; /* Current root table pointer */ diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index e3465fc27d..c1382a5651 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -3872,7 +3872,13 @@ static bool vtd_check_hiod(IntelIOMMUState *s, HostIOMMUDevice *hiod, return false; } - return true; + if (!s->scalable_modern) { + /* All checks requested by VTD non-modern mode pass */ + return true; + } + + error_setg(errp, "host device is unsupported in scalable modern mode yet"); + return false; } static bool vtd_dev_set_iommu_device(PCIBus *bus, void *opaque, int devfn, @@ -4262,9 +4268,9 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp) } } - /* Currently only address widths supported are 39 and 48 bits */ if ((s->aw_bits != VTD_HOST_AW_39BIT) && - (s->aw_bits != VTD_HOST_AW_48BIT)) { + (s->aw_bits != VTD_HOST_AW_48BIT) && + !s->scalable_modern) { error_setg(errp, "Supported values for aw-bits are: %d, %d", VTD_HOST_AW_39BIT, VTD_HOST_AW_48BIT); return false; From patchwork Mon Aug 5 06:27:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968895 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=h5onyc1A; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmnc6Sd8z1yf1 for ; Mon, 5 Aug 2024 16:32:20 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarEq-0002R2-85; Mon, 05 Aug 2024 02:30:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEn-0002EL-2Q for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:34 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEg-00029G-OK for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839427; x=1754375427; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NZt17FWZUx2Aa1+AVbgbpJyQ9o1iDE5qgd6Cq+0OOXk=; b=h5onyc1AjIkH+49VZY/sOoG/kQJBC9mNL/GfDaWWfmKJivNv7pLnpi2S 7CN7QdYl7WqD9Nmya0V4oysQldfWrHFRnhSQzESUyWScgPcqEjJwQG8EC JqMEH30OcKZrF25Dt8YevG42tqvu2z1sgx9Mic/+ukD8AALJeCM0onPot jzlKYqmWf7RaXZxibsN4a0gIgBjzNgZcEZ1VX/xqyjbPGqh29HB4z82Ez r1k4haHHIrlnCy2UQ6iVypIYIg8q+O1CJAn4N2F3SE+qnvEfkm7cy7ZcW VcV+Y2XbowamTu3EzWnN5mqP1MPba7Cc5tQ57XYpKwYrlAg0Mrq91z6T8 g==; X-CSE-ConnectionGUID: LCyz9CVETIOo71kvaQPCQQ== X-CSE-MsgGUID: iRCkZkhCQmeBySXW3cfLag== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282698" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282698" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:26 -0700 X-CSE-ConnectionGUID: W8Ajc3dfSW2R+ACkQ0qOTw== X-CSE-MsgGUID: A+u4vpSMTz2joKprmi/MMA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786631" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:21 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum Subject: [PATCH v2 04/17] intel_iommu: Flush stage-2 cache in PASID-selective PASID-based iotlb invalidation Date: Mon, 5 Aug 2024 14:27:14 +0800 Message-Id: <20240805062727.2307552-5-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Per spec 6.5.2.4, PADID-selective PASID-based iotlb invalidation will flush stage-2 iotlb entries with matching domain id and pasid. With scalable modern mode introduced, guest could send PASID-selective PASID-based iotlb invalidation to flush both stage-1 and stage-2 entries. By this chance, remove old IOTLB related definition. Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu_internal.h | 14 +++--- hw/i386/intel_iommu.c | 81 ++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 8fa27c7f3b..19e4ed52ca 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -402,11 +402,6 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_IOTLB_AM(val) ((val) & 0x3fULL) #define VTD_INV_DESC_IOTLB_RSVD_LO 0xffffffff0000ff00ULL #define VTD_INV_DESC_IOTLB_RSVD_HI 0xf80ULL -#define VTD_INV_DESC_IOTLB_PASID_PASID (2ULL << 4) -#define VTD_INV_DESC_IOTLB_PASID_PAGE (3ULL << 4) -#define VTD_INV_DESC_IOTLB_PASID(val) (((val) >> 32) & VTD_PASID_ID_MASK) -#define VTD_INV_DESC_IOTLB_PASID_RSVD_LO 0xfff00000000001c0ULL -#define VTD_INV_DESC_IOTLB_PASID_RSVD_HI 0xf80ULL /* Mask for Device IOTLB Invalidate Descriptor */ #define VTD_INV_DESC_DEVICE_IOTLB_ADDR(val) ((val) & 0xfffffffffffff000ULL) @@ -438,6 +433,15 @@ typedef union VTDInvDesc VTDInvDesc; (0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \ (0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) +/* Masks for PIOTLB Invalidate Descriptor */ +#define VTD_INV_DESC_PIOTLB_G (3ULL << 4) +#define VTD_INV_DESC_PIOTLB_ALL_IN_PASID (2ULL << 4) +#define VTD_INV_DESC_PIOTLB_PSI_IN_PASID (3ULL << 4) +#define VTD_INV_DESC_PIOTLB_DID(val) (((val) >> 16) & VTD_DOMAIN_ID_MASK) +#define VTD_INV_DESC_PIOTLB_PASID(val) (((val) >> 32) & 0xfffffULL) +#define VTD_INV_DESC_PIOTLB_RSVD_VAL0 0xfff000000000f1c0ULL +#define VTD_INV_DESC_PIOTLB_RSVD_VAL1 0xf80ULL + /* Information about page-selective IOTLB invalidate */ struct VTDIOTLBPageInvInfo { uint16_t domain_id; diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index c1382a5651..df591419b7 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -2656,6 +2656,83 @@ static bool vtd_process_iotlb_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) return true; } +static gboolean vtd_hash_remove_by_pasid(gpointer key, gpointer value, + gpointer user_data) +{ + VTDIOTLBEntry *entry = (VTDIOTLBEntry *)value; + VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data; + + return ((entry->domain_id == info->domain_id) && + (entry->pasid == info->pasid)); +} + +static void vtd_piotlb_pasid_invalidate(IntelIOMMUState *s, + uint16_t domain_id, uint32_t pasid) +{ + VTDIOTLBPageInvInfo info; + VTDAddressSpace *vtd_as; + VTDContextEntry ce; + + info.domain_id = domain_id; + info.pasid = pasid; + + vtd_iommu_lock(s); + g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_pasid, + &info); + vtd_iommu_unlock(s); + + QLIST_FOREACH(vtd_as, &s->vtd_as_with_notifiers, next) { + if (!vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus), + vtd_as->devfn, &ce) && + domain_id == vtd_get_domain_id(s, &ce, vtd_as->pasid)) { + uint32_t rid2pasid = VTD_CE_GET_RID2PASID(&ce); + + if ((vtd_as->pasid != PCI_NO_PASID || pasid != rid2pasid) && + vtd_as->pasid != pasid) { + continue; + } + + if (!s->scalable_modern) { + vtd_address_space_sync(vtd_as); + } + } + } +} + +static bool vtd_process_piotlb_desc(IntelIOMMUState *s, + VTDInvDesc *inv_desc) +{ + uint16_t domain_id; + uint32_t pasid; + + if ((inv_desc->val[0] & VTD_INV_DESC_PIOTLB_RSVD_VAL0) || + (inv_desc->val[1] & VTD_INV_DESC_PIOTLB_RSVD_VAL1)) { + error_report_once("%s: invalid piotlb inv desc hi=0x%"PRIx64 + " lo=0x%"PRIx64" (reserved bits unzero)", + __func__, inv_desc->val[1], inv_desc->val[0]); + return false; + } + + domain_id = VTD_INV_DESC_PIOTLB_DID(inv_desc->val[0]); + pasid = VTD_INV_DESC_PIOTLB_PASID(inv_desc->val[0]); + switch (inv_desc->val[0] & VTD_INV_DESC_PIOTLB_G) { + case VTD_INV_DESC_PIOTLB_ALL_IN_PASID: + vtd_piotlb_pasid_invalidate(s, domain_id, pasid); + break; + + case VTD_INV_DESC_PIOTLB_PSI_IN_PASID: + break; + + default: + error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64 + ", lo=0x%"PRIx64" (type mismatch: 0x%llx)", + __func__, inv_desc->val[1], inv_desc->val[0], + inv_desc->val[0] & VTD_INV_DESC_IOTLB_G); + return false; + } + return true; +} + static bool vtd_process_inv_iec_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) { @@ -2775,6 +2852,10 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s) break; case VTD_INV_DESC_PIOTLB: + trace_vtd_inv_desc("p-iotlb", inv_desc.val[1], inv_desc.val[0]); + if (!vtd_process_piotlb_desc(s, &inv_desc)) { + return false; + } break; case VTD_INV_DESC_WAIT: From patchwork Mon Aug 5 06:27:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968900 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=GNksszw4; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WcmpF0VSyz1yYD for ; Mon, 5 Aug 2024 16:32:53 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarEv-0002hx-Nz; Mon, 05 Aug 2024 02:30:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEs-0002ZB-9D for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:38 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEo-0002As-2n for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839434; x=1754375434; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fWZ1WlrVINaIDCPhcdvPghs2mVgyi9km0PrX588cEfA=; b=GNksszw4DKUs1ZuwDNrCQaOsg8/Wi457tYjRh3ukDnXf4IYSOR+WEsF2 z78a28iDXuIENMnmRfXudu6EXYpBb/f0ZLp7xXmjnXRfrTb4qG33uS+HO 503HjXMtK4i9DC+mBSnCZa4ei4iWREdLoTkYatGhlnx+xLAGorHfLtgUR 2NuEFlOyMDhNEX35P3SFU0r+LGMbGfmpIv0F60yGnSuFCslZTV7J1OUEP NMCiAS2TxyWhuD2vlvxTvquzzeHHqkY/8UPpJ0Z0iCnLLbwZyjMaCnu80 EGP6Q9ho/l9afwSIzE5tNWw67a+G9NrJG/Pmyr97aUY1sMtzX/1oq+92E A==; X-CSE-ConnectionGUID: 1UhcLr8iT5OUot55DJGp+g== X-CSE-MsgGUID: iZA+scaSQNahZGHGXNMaVg== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282707" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282707" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:31 -0700 X-CSE-ConnectionGUID: CDKQ4TiNT7qVg1H4ede6RA== X-CSE-MsgGUID: rPzjJYx8ROykk2H1dkUF+Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786692" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:26 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum Subject: [PATCH v2 05/17] intel_iommu: Rename slpte to pte Date: Mon, 5 Aug 2024 14:27:15 +0800 Message-Id: <20240805062727.2307552-6-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Yi Liu Because we will support both FST(a.k.a, FLT) and SST(a.k.a, SLT) translation, rename variable and functions from slpte to pte whenever possible. But some are SST only, they are renamed with sl_ prefix. Signed-off-by: Yi Liu Co-developed-by: Clément Mathieu--Drif Signed-off-by: Clément Mathieu--Drif Signed-off-by: Yi Sun Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu_internal.h | 24 +++--- include/hw/i386/intel_iommu.h | 2 +- hw/i386/intel_iommu.c | 129 +++++++++++++++++---------------- 3 files changed, 78 insertions(+), 77 deletions(-) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 19e4ed52ca..1fa4add9e2 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -528,24 +528,24 @@ typedef struct VTDRootEntry VTDRootEntry; /* Second Level Page Translation Pointer*/ #define VTD_SM_PASID_ENTRY_SLPTPTR (~0xfffULL) -/* Paging Structure common */ -#define VTD_SL_PT_PAGE_SIZE_MASK (1ULL << 7) -/* Bits to decide the offset for each level */ -#define VTD_SL_LEVEL_BITS 9 - /* 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 - /* Masks for Second Level Paging Entry */ #define VTD_SL_RW_MASK 3ULL #define VTD_SL_R 1ULL #define VTD_SL_W (1ULL << 1) -#define VTD_SL_PT_BASE_ADDR_MASK(aw) (~(VTD_PAGE_SIZE - 1) & VTD_HAW_MASK(aw)) #define VTD_SL_IGN_COM 0xbff0000000000000ULL #define VTD_SL_TM (1ULL << 62) +/* Common for both First Level and Second Level */ +#define VTD_PML4_LEVEL 4 +#define VTD_PDP_LEVEL 3 +#define VTD_PD_LEVEL 2 +#define VTD_PT_LEVEL 1 +#define VTD_PT_ENTRY_NR 512 +#define VTD_PT_PAGE_SIZE_MASK (1ULL << 7) +#define VTD_PT_BASE_ADDR_MASK(aw) (~(VTD_PAGE_SIZE - 1) & VTD_HAW_MASK(aw)) + +/* Bits to decide the offset for each level */ +#define VTD_LEVEL_BITS 9 + #endif diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 788ed42477..fe9057c50d 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -152,7 +152,7 @@ struct VTDIOTLBEntry { uint64_t gfn; uint16_t domain_id; uint32_t pasid; - uint64_t slpte; + uint64_t pte; uint64_t mask; uint8_t access_flags; }; diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index df591419b7..46d64a38b2 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -48,7 +48,8 @@ /* pe operations */ #define VTD_PE_GET_TYPE(pe) ((pe)->val[0] & VTD_SM_PASID_ENTRY_PGTT) -#define VTD_PE_GET_LEVEL(pe) (2 + (((pe)->val[0] >> 2) & VTD_SM_PASID_ENTRY_AW)) +#define VTD_PE_GET_SL_LEVEL(pe) \ + (2 + (((pe)->val[0] >> 2) & VTD_SM_PASID_ENTRY_AW)) /* * PCI bus number (or SID) is not reliable since the device is usaully @@ -284,15 +285,15 @@ static gboolean vtd_hash_remove_by_domain(gpointer key, gpointer value, } /* The shift of an addr for a certain level of paging structure */ -static inline uint32_t vtd_slpt_level_shift(uint32_t level) +static inline uint32_t vtd_pt_level_shift(uint32_t level) { assert(level != 0); - return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_SL_LEVEL_BITS; + return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_LEVEL_BITS; } -static inline uint64_t vtd_slpt_level_page_mask(uint32_t level) +static inline uint64_t vtd_pt_level_page_mask(uint32_t level) { - return ~((1ULL << vtd_slpt_level_shift(level)) - 1); + return ~((1ULL << vtd_pt_level_shift(level)) - 1); } static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value, @@ -349,7 +350,7 @@ static void vtd_reset_caches(IntelIOMMUState *s) static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t level) { - return (addr & vtd_slpt_level_page_mask(level)) >> VTD_PAGE_SHIFT_4K; + return (addr & vtd_pt_level_page_mask(level)) >> VTD_PAGE_SHIFT_4K; } /* Must be called with IOMMU lock held */ @@ -360,7 +361,7 @@ static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id, VTDIOTLBEntry *entry; unsigned level; - for (level = VTD_SL_PT_LEVEL; level < VTD_SL_PML4_LEVEL; level++) { + for (level = VTD_PT_LEVEL; level < VTD_PML4_LEVEL; level++) { key.gfn = vtd_get_iotlb_gfn(addr, level); key.level = level; key.sid = source_id; @@ -377,7 +378,7 @@ out: /* Must be with IOMMU lock held */ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, - uint16_t domain_id, hwaddr addr, uint64_t slpte, + uint16_t domain_id, hwaddr addr, uint64_t pte, uint8_t access_flags, uint32_t level, uint32_t pasid) { @@ -385,7 +386,7 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, struct vtd_iotlb_key *key = g_malloc(sizeof(*key)); uint64_t gfn = vtd_get_iotlb_gfn(addr, level); - trace_vtd_iotlb_page_update(source_id, addr, slpte, domain_id); + trace_vtd_iotlb_page_update(source_id, addr, pte, domain_id); if (g_hash_table_size(s->iotlb) >= VTD_IOTLB_MAX_SIZE) { trace_vtd_iotlb_reset("iotlb exceeds size limit"); vtd_reset_iotlb_locked(s); @@ -393,9 +394,9 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, entry->gfn = gfn; entry->domain_id = domain_id; - entry->slpte = slpte; + entry->pte = pte; entry->access_flags = access_flags; - entry->mask = vtd_slpt_level_page_mask(level); + entry->mask = vtd_pt_level_page_mask(level); entry->pasid = pasid; key->gfn = gfn; @@ -710,32 +711,32 @@ static inline dma_addr_t vtd_ce_get_slpt_base(VTDContextEntry *ce) return ce->lo & VTD_CONTEXT_ENTRY_SLPTPTR; } -static inline uint64_t vtd_get_slpte_addr(uint64_t slpte, uint8_t aw) +static inline uint64_t vtd_get_pte_addr(uint64_t pte, uint8_t aw) { - return slpte & VTD_SL_PT_BASE_ADDR_MASK(aw); + return pte & VTD_PT_BASE_ADDR_MASK(aw); } /* Whether the pte indicates the address of the page frame */ -static inline bool vtd_is_last_slpte(uint64_t slpte, uint32_t level) +static inline bool vtd_is_last_pte(uint64_t pte, uint32_t level) { - return level == VTD_SL_PT_LEVEL || (slpte & VTD_SL_PT_PAGE_SIZE_MASK); + return level == VTD_PT_LEVEL || (pte & VTD_PT_PAGE_SIZE_MASK); } -/* Get the content of a spte located in @base_addr[@index] */ -static uint64_t vtd_get_slpte(dma_addr_t base_addr, uint32_t index) +/* Get the content of a pte located in @base_addr[@index] */ +static uint64_t vtd_get_pte(dma_addr_t base_addr, uint32_t index) { - uint64_t slpte; + uint64_t pte; - assert(index < VTD_SL_PT_ENTRY_NR); + assert(index < VTD_PT_ENTRY_NR); if (dma_memory_read(&address_space_memory, - base_addr + index * sizeof(slpte), - &slpte, sizeof(slpte), MEMTXATTRS_UNSPECIFIED)) { - slpte = (uint64_t)-1; - return slpte; + base_addr + index * sizeof(pte), + &pte, sizeof(pte), MEMTXATTRS_UNSPECIFIED)) { + pte = (uint64_t)-1; + return pte; } - slpte = le64_to_cpu(slpte); - return slpte; + pte = le64_to_cpu(pte); + return pte; } /* Given an iova and the level of paging structure, return the offset @@ -743,12 +744,12 @@ static uint64_t vtd_get_slpte(dma_addr_t base_addr, uint32_t index) */ static inline uint32_t vtd_iova_level_offset(uint64_t iova, uint32_t level) { - return (iova >> vtd_slpt_level_shift(level)) & - ((1ULL << VTD_SL_LEVEL_BITS) - 1); + return (iova >> vtd_pt_level_shift(level)) & + ((1ULL << VTD_LEVEL_BITS) - 1); } /* Check Capability Register to see if the @level of page-table is supported */ -static inline bool vtd_is_level_supported(IntelIOMMUState *s, uint32_t level) +static inline bool vtd_is_sl_level_supported(IntelIOMMUState *s, uint32_t level) { return VTD_CAP_SAGAW_MASK & s->cap & (1ULL << (level - 2 + VTD_CAP_SAGAW_SHIFT)); @@ -833,7 +834,7 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, pgtt = VTD_PE_GET_TYPE(pe); if (pgtt == VTD_SM_PASID_ENTRY_SLT && - !vtd_is_level_supported(s, VTD_PE_GET_LEVEL(pe))) { + !vtd_is_sl_level_supported(s, VTD_PE_GET_SL_LEVEL(pe))) { return -VTD_FR_PASID_TABLE_ENTRY_INV; } @@ -972,7 +973,7 @@ static uint32_t vtd_get_iova_level(IntelIOMMUState *s, if (s->root_scalable) { vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid); - return VTD_PE_GET_LEVEL(&pe); + return VTD_PE_GET_SL_LEVEL(&pe); } return vtd_ce_get_level(ce); @@ -1040,9 +1041,9 @@ static inline uint64_t vtd_iova_limit(IntelIOMMUState *s, } /* Return true if IOVA passes range check, otherwise false. */ -static inline bool vtd_iova_range_check(IntelIOMMUState *s, - uint64_t iova, VTDContextEntry *ce, - uint8_t aw, uint32_t pasid) +static inline bool vtd_iova_sl_range_check(IntelIOMMUState *s, + uint64_t iova, VTDContextEntry *ce, + uint8_t aw, uint32_t pasid) { /* * Check if @iova is above 2^X-1, where X is the minimum of MGAW @@ -1083,17 +1084,17 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level) /* * We should have caught a guest-mis-programmed level earlier, - * via vtd_is_level_supported. + * via vtd_is_sl_level_supported. */ assert(level < VTD_SPTE_RSVD_LEN); /* - * Zero level doesn't exist. The smallest level is VTD_SL_PT_LEVEL=1 and - * checked by vtd_is_last_slpte(). + * Zero level doesn't exist. The smallest level is VTD_PT_LEVEL=1 and + * checked by vtd_is_last_pte(). */ assert(level); - if ((level == VTD_SL_PD_LEVEL || level == VTD_SL_PDP_LEVEL) && - (slpte & VTD_SL_PT_PAGE_SIZE_MASK)) { + if ((level == VTD_PD_LEVEL || level == VTD_PDP_LEVEL) && + (slpte & VTD_PT_PAGE_SIZE_MASK)) { /* large page */ rsvd_mask = vtd_spte_rsvd_large[level]; } else { @@ -1119,7 +1120,7 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce, uint64_t access_right_check; uint64_t xlat, size; - if (!vtd_iova_range_check(s, iova, ce, aw_bits, pasid)) { + if (!vtd_iova_sl_range_check(s, iova, ce, aw_bits, pasid)) { error_report_once("%s: detected IOVA overflow (iova=0x%" PRIx64 "," "pasid=0x%" PRIx32 ")", __func__, iova, pasid); return -VTD_FR_ADDR_BEYOND_MGAW; @@ -1130,7 +1131,7 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce, while (true) { offset = vtd_iova_level_offset(iova, level); - slpte = vtd_get_slpte(addr, offset); + slpte = vtd_get_pte(addr, offset); if (slpte == (uint64_t)-1) { error_report_once("%s: detected read error on DMAR slpte " @@ -1161,17 +1162,17 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce, return -VTD_FR_PAGING_ENTRY_RSVD; } - if (vtd_is_last_slpte(slpte, level)) { + if (vtd_is_last_pte(slpte, level)) { *slptep = slpte; *slpte_level = level; break; } - addr = vtd_get_slpte_addr(slpte, aw_bits); + addr = vtd_get_pte_addr(slpte, aw_bits); level--; } - xlat = vtd_get_slpte_addr(*slptep, aw_bits); - size = ~vtd_slpt_level_page_mask(level) + 1; + xlat = vtd_get_pte_addr(*slptep, aw_bits); + size = ~vtd_pt_level_page_mask(level) + 1; /* * From VT-d spec 3.14: Untranslated requests and translation @@ -1322,14 +1323,14 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start, trace_vtd_page_walk_level(addr, level, start, end); - subpage_size = 1ULL << vtd_slpt_level_shift(level); - subpage_mask = vtd_slpt_level_page_mask(level); + subpage_size = 1ULL << vtd_pt_level_shift(level); + subpage_mask = vtd_pt_level_page_mask(level); while (iova < end) { iova_next = (iova & subpage_mask) + subpage_size; offset = vtd_iova_level_offset(iova, level); - slpte = vtd_get_slpte(addr, offset); + slpte = vtd_get_pte(addr, offset); if (slpte == (uint64_t)-1) { trace_vtd_page_walk_skip_read(iova, iova_next); @@ -1352,12 +1353,12 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start, */ entry_valid = read_cur | write_cur; - if (!vtd_is_last_slpte(slpte, level) && entry_valid) { + if (!vtd_is_last_pte(slpte, level) && entry_valid) { /* * This is a valid PDE (or even bigger than PDE). We need * to walk one further level. */ - ret = vtd_page_walk_level(vtd_get_slpte_addr(slpte, info->aw), + ret = vtd_page_walk_level(vtd_get_pte_addr(slpte, info->aw), iova, MIN(iova_next, end), level - 1, read_cur, write_cur, info); } else { @@ -1374,7 +1375,7 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start, event.entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur); event.entry.addr_mask = ~subpage_mask; /* NOTE: this is only meaningful if entry_valid == true */ - event.entry.translated_addr = vtd_get_slpte_addr(slpte, info->aw); + event.entry.translated_addr = vtd_get_pte_addr(slpte, info->aw); event.type = event.entry.perm ? IOMMU_NOTIFIER_MAP : IOMMU_NOTIFIER_UNMAP; ret = vtd_page_walk_one(&event, info); @@ -1408,11 +1409,11 @@ static int vtd_page_walk(IntelIOMMUState *s, VTDContextEntry *ce, dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce, pasid); uint32_t level = vtd_get_iova_level(s, ce, pasid); - if (!vtd_iova_range_check(s, start, ce, info->aw, pasid)) { + if (!vtd_iova_sl_range_check(s, start, ce, info->aw, pasid)) { return -VTD_FR_ADDR_BEYOND_MGAW; } - if (!vtd_iova_range_check(s, end, ce, info->aw, pasid)) { + if (!vtd_iova_sl_range_check(s, end, ce, info->aw, pasid)) { /* Fix end so that it reaches the maximum */ end = vtd_iova_limit(s, ce, info->aw, pasid); } @@ -1527,7 +1528,7 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num, /* Check if the programming of context-entry is valid */ if (!s->root_scalable && - !vtd_is_level_supported(s, vtd_ce_get_level(ce))) { + !vtd_is_sl_level_supported(s, vtd_ce_get_level(ce))) { error_report_once("%s: invalid context entry: hi=%"PRIx64 ", lo=%"PRIx64" (level %d not supported)", __func__, ce->hi, ce->lo, @@ -1897,7 +1898,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, VTDContextEntry ce; uint8_t bus_num = pci_bus_num(bus); VTDContextCacheEntry *cc_entry; - uint64_t slpte, page_mask; + uint64_t pte, page_mask; uint32_t level, pasid = vtd_as->pasid; uint16_t source_id = PCI_BUILD_BDF(bus_num, devfn); int ret_fr; @@ -1918,13 +1919,13 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, cc_entry = &vtd_as->context_cache_entry; - /* Try to fetch slpte form IOTLB, we don't need RID2PASID logic */ + /* Try to fetch pte form IOTLB, we don't need RID2PASID logic */ if (!rid2pasid) { iotlb_entry = vtd_lookup_iotlb(s, source_id, pasid, addr); if (iotlb_entry) { - trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte, + trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->pte, iotlb_entry->domain_id); - slpte = iotlb_entry->slpte; + pte = iotlb_entry->pte; access_flags = iotlb_entry->access_flags; page_mask = iotlb_entry->mask; goto out; @@ -1996,20 +1997,20 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, return true; } - /* Try to fetch slpte form IOTLB for RID2PASID slow path */ + /* Try to fetch pte form IOTLB for RID2PASID slow path */ if (rid2pasid) { iotlb_entry = vtd_lookup_iotlb(s, source_id, pasid, addr); if (iotlb_entry) { - trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte, + trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->pte, iotlb_entry->domain_id); - slpte = iotlb_entry->slpte; + pte = iotlb_entry->pte; access_flags = iotlb_entry->access_flags; page_mask = iotlb_entry->mask; goto out; } } - ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &slpte, &level, + ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &pte, &level, &reads, &writes, s->aw_bits, pasid); if (ret_fr) { vtd_report_fault(s, -ret_fr, is_fpd_set, source_id, @@ -2017,14 +2018,14 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, goto error; } - page_mask = vtd_slpt_level_page_mask(level); + page_mask = vtd_pt_level_page_mask(level); access_flags = IOMMU_ACCESS_FLAG(reads, writes); vtd_update_iotlb(s, source_id, vtd_get_domain_id(s, &ce, pasid), - addr, slpte, access_flags, level, pasid); + addr, pte, access_flags, level, pasid); out: vtd_iommu_unlock(s); entry->iova = addr & page_mask; - entry->translated_addr = vtd_get_slpte_addr(slpte, s->aw_bits) & page_mask; + entry->translated_addr = vtd_get_pte_addr(pte, s->aw_bits) & page_mask; entry->addr_mask = ~page_mask; entry->perm = access_flags; return true; From patchwork Mon Aug 5 06:27:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968886 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=eETMDC4J; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmmp27TTz1yf1 for ; Mon, 5 Aug 2024 16:31:38 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFM-0002uD-Ef; Mon, 05 Aug 2024 02:31:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarF5-0002n7-8M for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:57 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEr-00029G-63 for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839437; x=1754375437; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZMD1nZYXnxUStb0fZkTlvaJ3hXuOvSHu+K3/+x7BoH8=; b=eETMDC4J5XyQciKp4YmTQfk9/x6gX8YorDY548ovldlHSO/VeRoYtAD4 DDWuvLlCffcuNxP6WMfp0B05FHe7e8GcewDHNT0hpF7XegWDBufAxEKTh dgBDPaodsG1CV+Oq03q0i4TY/IQ2K3Dvk9T7S7yYDc+twfqGUcLTRe2DQ dF7ojD3SLGaHQadTHNls5KMm0PigxNGnIvCSR/4HsrCjLSgVe1aYqszFm JCCNy4ASnOBhbOQcBqeBS/JDdyAF3cOI2A93vH0NKziRWMfyIHr2Kmu45 UwCsDU4VRXFDgGI9SZ2qQ//iW/0jJOpyOe3FA4OFAfnKPrihpuUUU4J0n g==; X-CSE-ConnectionGUID: 8LLwEKhtQgmvpb2R/m02/Q== X-CSE-MsgGUID: WMW2Va4RR7W50tbm8j4TKA== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282716" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282716" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:36 -0700 X-CSE-ConnectionGUID: HpS6XagMTRCC9ybZLq/9nw== X-CSE-MsgGUID: pB672pTLTxWvcTTZlui/lA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786724" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:31 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Eduardo Habkost Subject: [PATCH v2 06/17] intel_iommu: Implement stage-1 translation Date: Mon, 5 Aug 2024 14:27:16 +0800 Message-Id: <20240805062727.2307552-7-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Yi Liu This adds stage-1 page table walking to support stage-1 only transltion in scalable modern mode. Signed-off-by: Yi Liu Co-developed-by: Clément Mathieu--Drif Signed-off-by: Clément Mathieu--Drif Signed-off-by: Yi Sun Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu_internal.h | 23 ++++++ hw/i386/intel_iommu.c | 146 ++++++++++++++++++++++++++++++++- 2 files changed, 165 insertions(+), 4 deletions(-) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 1fa4add9e2..51e9b1fc43 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -433,6 +433,21 @@ typedef union VTDInvDesc VTDInvDesc; (0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \ (0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM)) +/* Rsvd field masks for fpte */ +#define VTD_FS_UPPER_IGNORED 0xfff0000000000000ULL +#define VTD_FPTE_PAGE_L1_RSVD_MASK(aw) \ + (~(VTD_HAW_MASK(aw) | VTD_FS_UPPER_IGNORED)) +#define VTD_FPTE_PAGE_L2_RSVD_MASK(aw) \ + (~(VTD_HAW_MASK(aw) | VTD_FS_UPPER_IGNORED)) +#define VTD_FPTE_PAGE_L3_RSVD_MASK(aw) \ + (~(VTD_HAW_MASK(aw) | VTD_FS_UPPER_IGNORED)) +#define VTD_FPTE_PAGE_L3_FS1GP_RSVD_MASK(aw) \ + (0x3fffe000ULL | ~(VTD_HAW_MASK(aw) | VTD_FS_UPPER_IGNORED)) +#define VTD_FPTE_PAGE_L2_FS2MP_RSVD_MASK(aw) \ + (0x1fe000ULL | ~(VTD_HAW_MASK(aw) | VTD_FS_UPPER_IGNORED)) +#define VTD_FPTE_PAGE_L4_RSVD_MASK(aw) \ + (0x80ULL | ~(VTD_HAW_MASK(aw) | VTD_FS_UPPER_IGNORED)) + /* Masks for PIOTLB Invalidate Descriptor */ #define VTD_INV_DESC_PIOTLB_G (3ULL << 4) #define VTD_INV_DESC_PIOTLB_ALL_IN_PASID (2ULL << 4) @@ -525,6 +540,14 @@ typedef struct VTDRootEntry VTDRootEntry; #define VTD_SM_PASID_ENTRY_AW 7ULL /* Adjusted guest-address-width */ #define VTD_SM_PASID_ENTRY_DID(val) ((val) & VTD_DOMAIN_ID_MASK) +#define VTD_SM_PASID_ENTRY_FLPM 3ULL +#define VTD_SM_PASID_ENTRY_FLPTPTR (~0xfffULL) + +/* First Level Paging Structure */ +/* Masks for First Level Paging Entry */ +#define VTD_FL_P 1ULL +#define VTD_FL_RW_MASK (1ULL << 1) + /* Second Level Page Translation Pointer*/ #define VTD_SM_PASID_ENTRY_SLPTPTR (~0xfffULL) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 46d64a38b2..0bcbd5b777 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -48,6 +48,8 @@ /* pe operations */ #define VTD_PE_GET_TYPE(pe) ((pe)->val[0] & VTD_SM_PASID_ENTRY_PGTT) +#define VTD_PE_GET_FL_LEVEL(pe) \ + (4 + (((pe)->val[2] >> 2) & VTD_SM_PASID_ENTRY_FLPM)) #define VTD_PE_GET_SL_LEVEL(pe) \ (2 + (((pe)->val[0] >> 2) & VTD_SM_PASID_ENTRY_AW)) @@ -755,6 +757,11 @@ static inline bool vtd_is_sl_level_supported(IntelIOMMUState *s, uint32_t level) (1ULL << (level - 2 + VTD_CAP_SAGAW_SHIFT)); } +static inline bool vtd_is_fl_level_supported(IntelIOMMUState *s, uint32_t level) +{ + return level == VTD_PML4_LEVEL; +} + /* Return true if check passed, otherwise false */ static inline bool vtd_pe_type_check(X86IOMMUState *x86_iommu, VTDPASIDEntry *pe) @@ -838,6 +845,11 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, return -VTD_FR_PASID_TABLE_ENTRY_INV; } + if (pgtt == VTD_SM_PASID_ENTRY_FLT && + !vtd_is_fl_level_supported(s, VTD_PE_GET_FL_LEVEL(pe))) { + return -VTD_FR_PASID_TABLE_ENTRY_INV; + } + return 0; } @@ -973,7 +985,11 @@ static uint32_t vtd_get_iova_level(IntelIOMMUState *s, if (s->root_scalable) { vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid); - return VTD_PE_GET_SL_LEVEL(&pe); + if (s->scalable_modern) { + return VTD_PE_GET_FL_LEVEL(&pe); + } else { + return VTD_PE_GET_SL_LEVEL(&pe); + } } return vtd_ce_get_level(ce); @@ -1060,7 +1076,11 @@ static dma_addr_t vtd_get_iova_pgtbl_base(IntelIOMMUState *s, if (s->root_scalable) { vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid); - return pe.val[0] & VTD_SM_PASID_ENTRY_SLPTPTR; + if (s->scalable_modern) { + return pe.val[2] & VTD_SM_PASID_ENTRY_FLPTPTR; + } else { + return pe.val[0] & VTD_SM_PASID_ENTRY_SLPTPTR; + } } return vtd_ce_get_slpt_base(ce); @@ -1862,6 +1882,104 @@ out: trace_vtd_pt_enable_fast_path(source_id, success); } +/* + * Rsvd field masks for fpte: + * vtd_fpte_rsvd 4k pages + * vtd_fpte_rsvd_large large pages + * + * We support only 4-level page tables. + */ +#define VTD_FPTE_RSVD_LEN 5 +static uint64_t vtd_fpte_rsvd[VTD_FPTE_RSVD_LEN]; +static uint64_t vtd_fpte_rsvd_large[VTD_FPTE_RSVD_LEN]; + +static bool vtd_flpte_nonzero_rsvd(uint64_t flpte, uint32_t level) +{ + uint64_t rsvd_mask; + + /* + * We should have caught a guest-mis-programmed level earlier, + * via vtd_is_fl_level_supported. + */ + assert(level < VTD_SPTE_RSVD_LEN); + /* + * Zero level doesn't exist. The smallest level is VTD_PT_LEVEL=1 and + * checked by vtd_is_last_pte(). + */ + assert(level); + + if ((level == VTD_PD_LEVEL || level == VTD_PDP_LEVEL) && + (flpte & VTD_PT_PAGE_SIZE_MASK)) { + /* large page */ + rsvd_mask = vtd_fpte_rsvd_large[level]; + } else { + rsvd_mask = vtd_fpte_rsvd[level]; + } + + return flpte & rsvd_mask; +} + +static inline bool vtd_flpte_present(uint64_t flpte) +{ + return !!(flpte & VTD_FL_P); +} + +/* + * Given the @iova, get relevant @flptep. @flpte_level will be the last level + * of the translation, can be used for deciding the size of large page. + */ +static int vtd_iova_to_flpte(IntelIOMMUState *s, VTDContextEntry *ce, + uint64_t iova, bool is_write, + uint64_t *flptep, uint32_t *flpte_level, + bool *reads, bool *writes, uint8_t aw_bits, + uint32_t pasid) +{ + dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce, pasid); + uint32_t level = vtd_get_iova_level(s, ce, pasid); + uint32_t offset; + uint64_t flpte; + + while (true) { + offset = vtd_iova_level_offset(iova, level); + flpte = vtd_get_pte(addr, offset); + + if (flpte == (uint64_t)-1) { + if (level == vtd_get_iova_level(s, ce, pasid)) { + /* Invalid programming of context-entry */ + return -VTD_FR_CONTEXT_ENTRY_INV; + } else { + return -VTD_FR_PAGING_ENTRY_INV; + } + } + if (!vtd_flpte_present(flpte)) { + *reads = false; + *writes = false; + return -VTD_FR_PAGING_ENTRY_INV; + } + *reads = true; + *writes = (*writes) && (flpte & VTD_FL_RW_MASK); + if (is_write && !(flpte & VTD_FL_RW_MASK)) { + return -VTD_FR_WRITE; + } + if (vtd_flpte_nonzero_rsvd(flpte, level)) { + error_report_once("%s: detected flpte reserved non-zero " + "iova=0x%" PRIx64 ", level=0x%" PRIx32 + "flpte=0x%" PRIx64 ", pasid=0x%" PRIX32 ")", + __func__, iova, level, flpte, pasid); + return -VTD_FR_PAGING_ENTRY_RSVD; + } + + if (vtd_is_last_pte(flpte, level)) { + *flptep = flpte; + *flpte_level = level; + return 0; + } + + addr = vtd_get_pte_addr(flpte, aw_bits); + level--; + } +} + static void vtd_report_fault(IntelIOMMUState *s, int err, bool is_fpd_set, uint16_t source_id, @@ -2010,8 +2128,13 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, } } - ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &pte, &level, - &reads, &writes, s->aw_bits, pasid); + if (s->scalable_modern && s->root_scalable) { + ret_fr = vtd_iova_to_flpte(s, &ce, addr, is_write, &pte, &level, + &reads, &writes, s->aw_bits, pasid); + } else { + ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &pte, &level, + &reads, &writes, s->aw_bits, pasid); + } if (ret_fr) { vtd_report_fault(s, -ret_fr, is_fpd_set, source_id, addr, is_write, pasid != PCI_NO_PASID, pasid); @@ -4239,6 +4362,21 @@ static void vtd_init(IntelIOMMUState *s) vtd_spte_rsvd_large[3] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits, x86_iommu->dt_supported); + /* + * Rsvd field masks for fpte + */ + vtd_fpte_rsvd[0] = ~0ULL; + vtd_fpte_rsvd[1] = VTD_FPTE_PAGE_L1_RSVD_MASK(s->aw_bits); + vtd_fpte_rsvd[2] = VTD_FPTE_PAGE_L2_RSVD_MASK(s->aw_bits); + vtd_fpte_rsvd[3] = VTD_FPTE_PAGE_L3_RSVD_MASK(s->aw_bits); + vtd_fpte_rsvd[4] = VTD_FPTE_PAGE_L4_RSVD_MASK(s->aw_bits); + + vtd_fpte_rsvd_large[0] = ~0ULL; + vtd_fpte_rsvd_large[1] = ~0ULL; + vtd_fpte_rsvd_large[2] = VTD_FPTE_PAGE_L2_FS2MP_RSVD_MASK(s->aw_bits); + vtd_fpte_rsvd_large[3] = VTD_FPTE_PAGE_L3_FS1GP_RSVD_MASK(s->aw_bits); + vtd_fpte_rsvd_large[4] = ~0ULL; + if (s->scalable_mode || s->snoop_control) { vtd_spte_rsvd[1] &= ~VTD_SPTE_SNP; vtd_spte_rsvd_large[2] &= ~VTD_SPTE_SNP; From patchwork Mon Aug 5 06:27:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968898 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=lJrcLQeZ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmnw2W78z1yYD for ; Mon, 5 Aug 2024 16:32:36 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFM-0002vA-Pl; Mon, 05 Aug 2024 02:31:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarF5-0002n6-8x for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:57 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarEv-0002As-RQ for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839442; x=1754375442; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=38HYgjgTWR4uxnvcTJKXQdnXnLtWPR0LnXj/4FiurfI=; b=lJrcLQeZzjtuOUMXXXS+vCPLVG3oFUbT7ZffWRHjsfGOrmo3w3GjbFuo x9rdDb/W91vPyDr2OakEoCgymHQq6ai7NdL2ktQWNlzQhMixmgeZSD/sA NMk1/YEAVVr5J+Iec1LWGUTiPMDdRL/jOLqYynFR/Mp9/osoWBND/TMwx OqegfLMZh0oErsnLHuciJiZDmCgbpwdtoN3R4STpYmbdwTA8IhFo7CFO8 pz3YCTLwj5Llle3flg9rt3xV6wlfUSLLPFDZx6rjb1DOj1q8mJmtOjAxe 67CDJJkeyv9jl6/iyPtckcMpheBraJd90pOXQ86x/HKdAJfXZxFMlUtWE A==; X-CSE-ConnectionGUID: UuNAPx9bQHm7wrlSaT8BTA== X-CSE-MsgGUID: 6Lte/eJUShOBeUn4C63baQ== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282727" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282727" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:41 -0700 X-CSE-ConnectionGUID: BkuhIYXdT8eOZDQIf/89rg== X-CSE-MsgGUID: 6HhGqKy8TcWWIfSGbvzXeA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786784" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:36 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Eduardo Habkost Subject: [PATCH v2 07/17] intel_iommu: Check if the input address is canonical Date: Mon, 5 Aug 2024 14:27:17 +0800 Message-Id: <20240805062727.2307552-8-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Clément Mathieu--Drif First stage translation must fail if the address to translate is not canonical. Signed-off-by: Clément Mathieu--Drif Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu_internal.h | 2 ++ hw/i386/intel_iommu.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 51e9b1fc43..668583aeca 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -320,6 +320,8 @@ typedef enum VTDFaultReason { VTD_FR_PASID_ENTRY_P = 0x59, VTD_FR_PASID_TABLE_ENTRY_INV = 0x5b, /*Invalid PASID table entry */ + VTD_FR_FS_NON_CANONICAL = 0x80, /* SNG.1 : Address for FS not canonical.*/ + /* Output address in the interrupt address range for scalable mode */ VTD_FR_SM_INTERRUPT_ADDR = 0x87, VTD_FR_MAX, /* Guard */ diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 0bcbd5b777..6121cca4cd 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -1821,6 +1821,7 @@ static const bool vtd_qualified_faults[] = { [VTD_FR_PASID_ENTRY_P] = true, [VTD_FR_PASID_TABLE_ENTRY_INV] = true, [VTD_FR_SM_INTERRUPT_ADDR] = true, + [VTD_FR_FS_NON_CANONICAL] = true, [VTD_FR_MAX] = false, }; @@ -1924,6 +1925,20 @@ static inline bool vtd_flpte_present(uint64_t flpte) return !!(flpte & VTD_FL_P); } +/* Return true if IOVA is canonical, otherwise false. */ +static bool vtd_iova_fl_check_canonical(IntelIOMMUState *s, uint64_t iova, + VTDContextEntry *ce, uint32_t pasid) +{ + uint64_t iova_limit = vtd_iova_limit(s, ce, s->aw_bits, pasid); + uint64_t upper_bits_mask = ~(iova_limit - 1); + uint64_t upper_bits = iova & upper_bits_mask; + bool msb = ((iova & (iova_limit >> 1)) != 0); + return !( + (!msb && (upper_bits != 0)) || + (msb && (upper_bits != upper_bits_mask)) + ); +} + /* * Given the @iova, get relevant @flptep. @flpte_level will be the last level * of the translation, can be used for deciding the size of large page. @@ -1939,6 +1954,12 @@ static int vtd_iova_to_flpte(IntelIOMMUState *s, VTDContextEntry *ce, uint32_t offset; uint64_t flpte; + if (!vtd_iova_fl_check_canonical(s, iova, ce, pasid)) { + error_report_once("%s: detected non canonical IOVA (iova=0x%" PRIx64 "," + "pasid=0x%" PRIx32 ")", __func__, iova, pasid); + return -VTD_FR_FS_NON_CANONICAL; + } + while (true) { offset = vtd_iova_level_offset(iova, level); flpte = vtd_get_pte(addr, offset); From patchwork Mon Aug 5 06:27:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968889 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=nJGfexGL; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmn63bGYz1yf1 for ; Mon, 5 Aug 2024 16:31:54 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFP-000334-Um; Mon, 05 Aug 2024 02:31:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarF7-0002n8-8C for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:57 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarF3-0002Cr-NC for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839450; x=1754375450; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tyTUGMCms0hzjN7qnTn/8Dv0La9ACcHcXuKiSuT8dg8=; b=nJGfexGLJs5v4T19zEYPwz6VHjQ1PLAlt/Egp7vKHqVxfDogAEufA8d/ YBqskRAWoCd9sAGY25DGLsM/z/5ZuV4TyeYons3feIX0Gqz5MAkV9FnZx tS+Goy70khL5vIxc4yQtmMqja1JcK1CSsymGx4FTpK1zqCDsmB9ptL9IE R03hUeDTcufBwkmu/RcILWX5FcJwLmJ4uHUtF8aQ1bTr9mj5DyeA9OCwI fw3NfTm9QpbSdFhhUiCiQKUS+ns4lxM21w1ZrrUWqbjaXzdG8V2mSYykn 9ddYy4im1FlhnYnCLmkOPWtP3bLO0xMC8fFMBUBo7r/DuT8ih+ja9MDjo A==; X-CSE-ConnectionGUID: ymP9SDMtTpmlJ/8yZxbjZw== X-CSE-MsgGUID: FRzJ8aIeT3yQIIZVjzqQNw== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282736" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282736" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:45 -0700 X-CSE-ConnectionGUID: nh3FWfN/TKqDTejqjXTZnA== X-CSE-MsgGUID: zyfkortoRFWe22vjy3+64Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786824" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:40 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum Subject: [PATCH v2 08/17] intel_iommu: Set accessed and dirty bits during first stage translation Date: Mon, 5 Aug 2024 14:27:18 +0800 Message-Id: <20240805062727.2307552-9-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Clément Mathieu--Drif Signed-off-by: Clément Mathieu--Drif Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu_internal.h | 3 +++ hw/i386/intel_iommu.c | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 668583aeca..7786ef7624 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -324,6 +324,7 @@ typedef enum VTDFaultReason { /* Output address in the interrupt address range for scalable mode */ VTD_FR_SM_INTERRUPT_ADDR = 0x87, + VTD_FR_FS_BIT_UPDATE_FAILED = 0x91, /* SFS.10 */ VTD_FR_MAX, /* Guard */ } VTDFaultReason; @@ -549,6 +550,8 @@ typedef struct VTDRootEntry VTDRootEntry; /* Masks for First Level Paging Entry */ #define VTD_FL_P 1ULL #define VTD_FL_RW_MASK (1ULL << 1) +#define VTD_FL_A 0x20 +#define VTD_FL_D 0x40 /* Second Level Page Translation Pointer*/ #define VTD_SM_PASID_ENTRY_SLPTPTR (~0xfffULL) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 6121cca4cd..3c2ceed284 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -1822,6 +1822,7 @@ static const bool vtd_qualified_faults[] = { [VTD_FR_PASID_TABLE_ENTRY_INV] = true, [VTD_FR_SM_INTERRUPT_ADDR] = true, [VTD_FR_FS_NON_CANONICAL] = true, + [VTD_FR_FS_BIT_UPDATE_FAILED] = true, [VTD_FR_MAX] = false, }; @@ -1939,6 +1940,20 @@ static bool vtd_iova_fl_check_canonical(IntelIOMMUState *s, uint64_t iova, ); } +static MemTxResult vtd_set_flag_in_pte(dma_addr_t base_addr, uint32_t index, + uint64_t pte, uint64_t flag) +{ + if (pte & flag) { + return MEMTX_OK; + } + pte |= flag; + pte = cpu_to_le64(pte); + return dma_memory_write(&address_space_memory, + base_addr + index * sizeof(pte), + &pte, sizeof(pte), + MEMTXATTRS_UNSPECIFIED); +} + /* * Given the @iova, get relevant @flptep. @flpte_level will be the last level * of the translation, can be used for deciding the size of large page. @@ -1990,7 +2005,16 @@ static int vtd_iova_to_flpte(IntelIOMMUState *s, VTDContextEntry *ce, return -VTD_FR_PAGING_ENTRY_RSVD; } + if (vtd_set_flag_in_pte(addr, offset, flpte, VTD_FL_A) != MEMTX_OK) { + return -VTD_FR_FS_BIT_UPDATE_FAILED; + } + if (vtd_is_last_pte(flpte, level)) { + if (is_write && + (vtd_set_flag_in_pte(addr, offset, flpte, VTD_FL_D) != + MEMTX_OK)) { + return -VTD_FR_FS_BIT_UPDATE_FAILED; + } *flptep = flpte; *flpte_level = level; return 0; From patchwork Mon Aug 5 06:27:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968892 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=UEMQv9Kl; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WcmnS4ym4z1yYD for ; Mon, 5 Aug 2024 16:32:12 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFY-0003U3-2A; Mon, 05 Aug 2024 02:31:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFB-0002qh-7Y for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:00 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarF6-0002As-1i for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:30:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839452; x=1754375452; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=m4ThjNCM+ztmp4/NlatLnd9isOs4KHWEXK2mLLxhJb0=; b=UEMQv9Klt0ZnXm0JvGRxGfP0sguGZagCanVx7rI2fS53S9F1cXkaT0wu hLQ+WNZ9H3gBksYiQSITFP7mWZvYVSjLFaRSR51ejY8uIl7ogqdIPZzQu 0LwsOYfdQ3M0ptFSSEKxmBvw2BGTtQ78lUf/ckQ1s/JPw5sJI74IUkTgR 0175RfNjVSlN2V/srJs/pPXsY+oVZl5HpwPMTl19cJNBHBF/DNmfKjyv3 Bl1Vb3fc9OdCn6xrmumlL1rPztCQtzP6RhCk92zU7eKltalTFXy6+0etk YuHBCb8s0YdNiFWtz8TlDaKPBV4oEsFm68QSgZTQ2lU1sDOnUGpUuN+nK g==; X-CSE-ConnectionGUID: +w+zXUj3SE+ZyiWsFpXlAw== X-CSE-MsgGUID: PIciy/KKRRqti9EQJO94bg== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282747" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282747" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:50 -0700 X-CSE-ConnectionGUID: lJr5GNtkQaO7SJhrNEMYyQ== X-CSE-MsgGUID: w1m5Y1noRVuFxr11+ShtXA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786841" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:45 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Eduardo Habkost Subject: [PATCH v2 09/17] intel_iommu: Flush stage-1 cache in iotlb invalidation Date: Mon, 5 Aug 2024 14:27:19 +0800 Message-Id: <20240805062727.2307552-10-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org According to spec, Page-Selective-within-Domain Invalidation (11b): 1. IOTLB entries caching second-stage mappings (PGTT=010b) or pass-through (PGTT=100b) mappings associated with the specified domain-id and the input-address range are invalidated. 2. IOTLB entries caching first-stage (PGTT=001b) or nested (PGTT=011b) mapping associated with specified domain-id are invalidated. So per spec definition the Page-Selective-within-Domain Invalidation needs to flush first stage and nested cached IOTLB enties as well. We don't support nested yet and pass-through mapping is never cached, so what in iotlb cache are only first-stage and second-stage mappings. Add a tag pgtt in VTDIOTLBEntry to mark PGTT type of the mapping and invalidate entries based on PGTT type. Signed-off-by: Zhenzhong Duan Reviewed-by: Clément Mathieu--Drif --- include/hw/i386/intel_iommu.h | 1 + hw/i386/intel_iommu.c | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index fe9057c50d..b843d069cc 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -155,6 +155,7 @@ struct VTDIOTLBEntry { uint64_t pte; uint64_t mask; uint8_t access_flags; + uint8_t pgtt; }; /* VT-d Source-ID Qualifier types */ diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 3c2ceed284..68ff7fa2fd 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -305,9 +305,21 @@ static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value, VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data; uint64_t gfn = (info->addr >> VTD_PAGE_SHIFT_4K) & info->mask; uint64_t gfn_tlb = (info->addr & entry->mask) >> VTD_PAGE_SHIFT_4K; - return (entry->domain_id == info->domain_id) && - (((entry->gfn & info->mask) == gfn) || - (entry->gfn == gfn_tlb)); + + if (entry->domain_id != info->domain_id) { + return false; + } + + /* + * According to spec, IOTLB entries caching first-stage (PGTT=001b) or + * nested (PGTT=011b) mapping associated with specified domain-id are + * invalidated. Nested isn't supported yet, so only need to check 001b. + */ + if (entry->pgtt == VTD_SM_PASID_ENTRY_FLT) { + return true; + } + + return (entry->gfn & info->mask) == gfn || entry->gfn == gfn_tlb; } /* Reset all the gen of VTDAddressSpace to zero and set the gen of @@ -382,7 +394,7 @@ out: static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, uint16_t domain_id, hwaddr addr, uint64_t pte, uint8_t access_flags, uint32_t level, - uint32_t pasid) + uint32_t pasid, uint8_t pgtt) { VTDIOTLBEntry *entry = g_malloc(sizeof(*entry)); struct vtd_iotlb_key *key = g_malloc(sizeof(*key)); @@ -400,6 +412,7 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, entry->access_flags = access_flags; entry->mask = vtd_pt_level_page_mask(level); entry->pasid = pasid; + entry->pgtt = pgtt; key->gfn = gfn; key->sid = source_id; @@ -2068,7 +2081,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, bool is_fpd_set = false; bool reads = true; bool writes = true; - uint8_t access_flags; + uint8_t access_flags, pgtt; bool rid2pasid = (pasid == PCI_NO_PASID) && s->root_scalable; VTDIOTLBEntry *iotlb_entry; @@ -2176,9 +2189,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, if (s->scalable_modern && s->root_scalable) { ret_fr = vtd_iova_to_flpte(s, &ce, addr, is_write, &pte, &level, &reads, &writes, s->aw_bits, pasid); + pgtt = VTD_SM_PASID_ENTRY_FLT; } else { ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &pte, &level, &reads, &writes, s->aw_bits, pasid); + pgtt = VTD_SM_PASID_ENTRY_SLT; } if (ret_fr) { vtd_report_fault(s, -ret_fr, is_fpd_set, source_id, @@ -2189,7 +2204,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, page_mask = vtd_pt_level_page_mask(level); access_flags = IOMMU_ACCESS_FLAG(reads, writes); vtd_update_iotlb(s, source_id, vtd_get_domain_id(s, &ce, pasid), - addr, pte, access_flags, level, pasid); + addr, pte, access_flags, level, pasid, pgtt); out: vtd_iommu_unlock(s); entry->iova = addr & page_mask; From patchwork Mon Aug 5 06:27:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968887 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=aJbTXxSk; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmms6z6Sz1yYD for ; Mon, 5 Aug 2024 16:31:41 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFU-0003Hw-SR; Mon, 05 Aug 2024 02:31:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFO-0002yp-8A for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:10 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFB-0002DM-S3 for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839458; x=1754375458; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JLcnrItrrzDpyC7V9okUnNUmynMmXNRhQ5KA0Ku8/g0=; b=aJbTXxSkiElpr6F9/uMfHGWFVNUr+W/mcmZi2YVgEFekowAdCVkVDl62 7GXL9WQWLFecMpMoA2xztBqt+O6JgOOqQrvIMMoR1LChcRUnmZk+O3YvV XScCnwCKG0n9DfFIokiufpXecgnrau3TrL6mZkhkFyOTSin7WwQfkJ9Tg P5O44bufb75lGzdqXVQo9RsL9/xo7gy++JH03uv0fqB9gp9xx8Volw23i wk1e/J+ePg24RLr2vnYSj9jP4GN3j3bzPJoTHIjSeo/klCsPKlaMPBF0k IdNCoN6TBL9FgeAbQOR2d13cDsJptCd3g9eAq+qfx9NJuz4HGAHHeTC6R Q==; X-CSE-ConnectionGUID: QlyZrI8SSkuzOy3hg7hgqw== X-CSE-MsgGUID: XxCstEjGRFGQzCbV9+OXLw== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282758" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282758" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:55 -0700 X-CSE-ConnectionGUID: mzHouVUKTSGByIjJPq/UGA== X-CSE-MsgGUID: 13Y2r/5ES1G/VjgWxRJ0Mg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786877" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:50 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Eduardo Habkost Subject: [PATCH v2 10/17] intel_iommu: Process PASID-based iotlb invalidation Date: Mon, 5 Aug 2024 14:27:20 +0800 Message-Id: <20240805062727.2307552-11-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org PASID-based iotlb (piotlb) is used during walking Intel VT-d stage-1 page table. This emulates the stage-1 page table iotlb invalidation requested by a PASID-based IOTLB Invalidate Descriptor (P_IOTLB). Signed-off-by: Yi Liu Signed-off-by: Zhenzhong Duan Reviewed-by: Clément Mathieu--Drif --- hw/i386/intel_iommu_internal.h | 3 +++ hw/i386/intel_iommu.c | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 7786ef7624..4f2c3a9350 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -457,6 +457,9 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_PIOTLB_PSI_IN_PASID (3ULL << 4) #define VTD_INV_DESC_PIOTLB_DID(val) (((val) >> 16) & VTD_DOMAIN_ID_MASK) #define VTD_INV_DESC_PIOTLB_PASID(val) (((val) >> 32) & 0xfffffULL) +#define VTD_INV_DESC_PIOTLB_AM(val) ((val) & 0x3fULL) +#define VTD_INV_DESC_PIOTLB_IH(val) (((val) >> 6) & 0x1) +#define VTD_INV_DESC_PIOTLB_ADDR(val) ((val) & ~0xfffULL) #define VTD_INV_DESC_PIOTLB_RSVD_VAL0 0xfff000000000f1c0ULL #define VTD_INV_DESC_PIOTLB_RSVD_VAL1 0xf80ULL diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 68ff7fa2fd..1bedb65bd8 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -322,6 +322,28 @@ static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value, return (entry->gfn & info->mask) == gfn || entry->gfn == gfn_tlb; } +static gboolean vtd_hash_remove_by_page_piotlb(gpointer key, gpointer value, + gpointer user_data) +{ + VTDIOTLBEntry *entry = (VTDIOTLBEntry *)value; + VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data; + uint64_t gfn = (info->addr >> VTD_PAGE_SHIFT_4K) & info->mask; + uint64_t gfn_tlb = (info->addr & entry->mask) >> VTD_PAGE_SHIFT_4K; + + /* + * According to spec, PASID-based-IOTLB Invalidation in page granularity + * doesn't invalidate IOTLB entries caching second-stage (PGTT=010b) + * or pass-through (PGTT=100b) mappings. Nested isn't supported yet, + * so only need to check first-stage (PGTT=001b) mappings. + */ + if (entry->pgtt != VTD_SM_PASID_ENTRY_FLT) { + return false; + } + + return entry->domain_id == info->domain_id && entry->pasid == info->pasid && + ((entry->gfn & info->mask) == gfn || entry->gfn == gfn_tlb); +} + /* Reset all the gen of VTDAddressSpace to zero and set the gen of * IntelIOMMUState to 1. Must be called with IOMMU lock held. */ @@ -2883,11 +2905,30 @@ static void vtd_piotlb_pasid_invalidate(IntelIOMMUState *s, } } +static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id, + uint32_t pasid, hwaddr addr, uint8_t am, + bool ih) +{ + VTDIOTLBPageInvInfo info; + + info.domain_id = domain_id; + info.pasid = pasid; + info.addr = addr; + info.mask = ~((1 << am) - 1); + + vtd_iommu_lock(s); + g_hash_table_foreach_remove(s->iotlb, + vtd_hash_remove_by_page_piotlb, &info); + vtd_iommu_unlock(s); +} + static bool vtd_process_piotlb_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) { uint16_t domain_id; uint32_t pasid; + uint8_t am; + hwaddr addr; if ((inv_desc->val[0] & VTD_INV_DESC_PIOTLB_RSVD_VAL0) || (inv_desc->val[1] & VTD_INV_DESC_PIOTLB_RSVD_VAL1)) { @@ -2905,6 +2946,10 @@ static bool vtd_process_piotlb_desc(IntelIOMMUState *s, break; case VTD_INV_DESC_PIOTLB_PSI_IN_PASID: + am = VTD_INV_DESC_PIOTLB_AM(inv_desc->val[1]); + addr = (hwaddr) VTD_INV_DESC_PIOTLB_ADDR(inv_desc->val[1]); + vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am, + VTD_INV_DESC_PIOTLB_IH(inv_desc->val[1])); break; default: From patchwork Mon Aug 5 06:27:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968899 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=mJTxjdPM; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WcmpF0jhXz1yf1 for ; Mon, 5 Aug 2024 16:32:53 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFa-0003fY-Ru; Mon, 05 Aug 2024 02:31:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFP-00033R-VE for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:15 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFN-0002As-L0 for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839469; x=1754375469; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7FKPsNxVa+rQoT4fL8eP4XHT0WdjEShcvYbsGsA1oeY=; b=mJTxjdPMh9W6NfgftgR8pFcN7eTKmRHIAQcOF27gbJCrC/G176HQgqat TEPLsG7++wGtsvZ2KuMuVfhtm/YCLH1FU1FEvNwX5wk0TvcuCF77DhPpU sOprQa9gd3TTZu8FbhAJl5zmL+okdkMiG9U6FE4CghssI4cLagr/u5fM6 k0oZqJBVTQzNnUlB4uEzCcDEqktG9VSqE0PzcAwRqjI2C4xmAksp24q7B BpJHbaad4zXiTKxqXEqA5sHV2Td+agLTbQkejKVPyFhER1PwYhfcxwc+S uRUQ2bomxm0fJbQsrcaBbP4qRgfrjkND/yyWBd4okCI0e9W34R+ylXOIx g==; X-CSE-ConnectionGUID: fV8/9XnGTuij3CoTEo4D2g== X-CSE-MsgGUID: P/vlUr8xQoqdQBTUdoekcA== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282777" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282777" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:00 -0700 X-CSE-ConnectionGUID: AOw0hgq2QwiZy9dSEscQKQ== X-CSE-MsgGUID: uMCm1aV5TLWakQftVDWx6A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786917" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:55 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum Subject: [PATCH v2 11/17] intel_iommu: Add an internal API to find an address space with PASID Date: Mon, 5 Aug 2024 14:27:21 +0800 Message-Id: <20240805062727.2307552-12-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Clément Mathieu--Drif This will be used to implement the device IOTLB invalidation Signed-off-by: Clément Mathieu--Drif Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 1bedb65bd8..5e4f22cd1d 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -70,6 +70,11 @@ struct vtd_hiod_key { uint8_t devfn; }; +struct vtd_as_raw_key { + uint16_t sid; + uint32_t pasid; +}; + struct vtd_iotlb_key { uint64_t gfn; uint32_t pasid; @@ -1875,29 +1880,33 @@ static inline bool vtd_is_interrupt_addr(hwaddr addr) return VTD_INTERRUPT_ADDR_FIRST <= addr && addr <= VTD_INTERRUPT_ADDR_LAST; } -static gboolean vtd_find_as_by_sid(gpointer key, gpointer value, - gpointer user_data) +static gboolean vtd_find_as_by_sid_and_pasid(gpointer key, gpointer value, + gpointer user_data) { struct vtd_as_key *as_key = (struct vtd_as_key *)key; - uint16_t target_sid = *(uint16_t *)user_data; + struct vtd_as_raw_key target = *(struct vtd_as_raw_key *)user_data; uint16_t sid = PCI_BUILD_BDF(pci_bus_num(as_key->bus), as_key->devfn); - return sid == target_sid; + + return (as_key->pasid == target.pasid) && + (sid == target.sid); } -static VTDAddressSpace *vtd_get_as_by_sid(IntelIOMMUState *s, uint16_t sid) +static VTDAddressSpace *vtd_get_as_by_sid_and_pasid(IntelIOMMUState *s, + uint16_t sid, + uint32_t pasid) { - uint8_t bus_num = PCI_BUS_NUM(sid); - VTDAddressSpace *vtd_as = s->vtd_as_cache[bus_num]; - - if (vtd_as && - (sid == PCI_BUILD_BDF(pci_bus_num(vtd_as->bus), vtd_as->devfn))) { - return vtd_as; - } + struct vtd_as_raw_key key = { + .sid = sid, + .pasid = pasid + }; - vtd_as = g_hash_table_find(s->vtd_address_spaces, vtd_find_as_by_sid, &sid); - s->vtd_as_cache[bus_num] = vtd_as; + return g_hash_table_find(s->vtd_address_spaces, + vtd_find_as_by_sid_and_pasid, &key); +} - return vtd_as; +static VTDAddressSpace *vtd_get_as_by_sid(IntelIOMMUState *s, uint16_t sid) +{ + return vtd_get_as_by_sid_and_pasid(s, sid, PCI_NO_PASID); } static void vtd_pt_enable_fast_path(IntelIOMMUState *s, uint16_t source_id) From patchwork Mon Aug 5 06:27:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968901 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=D0bY4JGT; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WcmpN6lFHz1yYD for ; Mon, 5 Aug 2024 16:33:00 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFZ-0003bA-Qn; Mon, 05 Aug 2024 02:31:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFQ-000358-D1 for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:15 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFO-0002Dg-D4 for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839470; x=1754375470; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QP64vK2fBLBjbfQIYILpjG9ab6+W+KFz+plubNiHobY=; b=D0bY4JGT03d8FHJlpkiXgVWbfb6sZObwzpEudp1fWMg16CEE9XEEK3jo eMq6klrpmXCGWgY7iRNqhf8xq5Y+Stt81ioJlwfwBib2h4DMeGD1zlRhp C9p6tgw22jf1+jV/8iSaRiStOCtLaM1AQZOQWrpkM8Gkpl4R0k84jAGlc O/l3KhuyJUChsMLfsPVMcKoYwDXkdRvNiBLGNlyKzctzibHhncIBH84ts kRXkiPRuqtmOOvWByJajHjrj4lg9afQhiBhfG12YyiAba+D2QkPmYOmO5 FhgHPtkSTSMczMfmV0ImLthPVCTT6spMA4bWR8xDCXncRbfOQBROcd7Hp w==; X-CSE-ConnectionGUID: xvqyC/GTSKGxsBwJ4N0j2A== X-CSE-MsgGUID: MiOR0bALREiQDyPtcVCfmQ== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282802" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282802" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:03 -0700 X-CSE-ConnectionGUID: JkdqRoRHScuXaEJbUi31cQ== X-CSE-MsgGUID: cCAGScW4QjezAGf7+xHDfQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56786945" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:30:59 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Eduardo Habkost Subject: [PATCH v2 12/17] intel_iommu: Add support for PASID-based device IOTLB invalidation Date: Mon, 5 Aug 2024 14:27:22 +0800 Message-Id: <20240805062727.2307552-13-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Clément Mathieu--Drif Signed-off-by: Clément Mathieu--Drif Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu_internal.h | 11 ++++++++ hw/i386/intel_iommu.c | 50 ++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 4f2c3a9350..52bdbf3bc5 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -375,6 +375,7 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_WAIT 0x5 /* Invalidation Wait Descriptor */ #define VTD_INV_DESC_PIOTLB 0x6 /* PASID-IOTLB Invalidate Desc */ #define VTD_INV_DESC_PC 0x7 /* PASID-cache Invalidate Desc */ +#define VTD_INV_DESC_DEV_PIOTLB 0x8 /* PASID-based-DIOTLB inv_desc*/ #define VTD_INV_DESC_NONE 0 /* Not an Invalidate Descriptor */ /* Masks for Invalidation Wait Descriptor*/ @@ -413,6 +414,16 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8 +/* Mask for PASID Device IOTLB Invalidate Descriptor */ +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_ADDR(val) ((val) & \ + 0xfffffffffffff000ULL) +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_SIZE(val) ((val >> 11) & 0x1) +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_GLOBAL(val) ((val) & 0x1) +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_SID(val) (((val) >> 16) & 0xffffULL) +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_PASID(val) ((val >> 32) & 0xfffffULL) +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI 0x7feULL +#define VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO 0xfff000000000f000ULL + /* Rsvd field masks for spte */ #define VTD_SPTE_SNP 0x800ULL diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 5e4f22cd1d..fa00f85fd7 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -3016,6 +3016,49 @@ static void do_invalidate_device_tlb(VTDAddressSpace *vtd_dev_as, memory_region_notify_iommu(&vtd_dev_as->iommu, 0, event); } +static bool vtd_process_device_piotlb_desc(IntelIOMMUState *s, + VTDInvDesc *inv_desc) +{ + uint16_t sid; + VTDAddressSpace *vtd_dev_as; + bool size; + bool global; + hwaddr addr; + uint32_t pasid; + + if ((inv_desc->hi & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_HI) || + (inv_desc->lo & VTD_INV_DESC_PASID_DEVICE_IOTLB_RSVD_LO)) { + error_report_once("%s: invalid pasid-based dev iotlb inv desc:" + "hi=%"PRIx64 "(reserved nonzero)", + __func__, inv_desc->hi); + return false; + } + + global = VTD_INV_DESC_PASID_DEVICE_IOTLB_GLOBAL(inv_desc->hi); + size = VTD_INV_DESC_PASID_DEVICE_IOTLB_SIZE(inv_desc->hi); + addr = VTD_INV_DESC_PASID_DEVICE_IOTLB_ADDR(inv_desc->hi); + sid = VTD_INV_DESC_PASID_DEVICE_IOTLB_SID(inv_desc->lo); + if (global) { + QLIST_FOREACH(vtd_dev_as, &s->vtd_as_with_notifiers, next) { + if ((vtd_dev_as->pasid != PCI_NO_PASID) && + (PCI_BUILD_BDF(pci_bus_num(vtd_dev_as->bus), + vtd_dev_as->devfn) == sid)) { + do_invalidate_device_tlb(vtd_dev_as, size, addr); + } + } + } else { + pasid = VTD_INV_DESC_PASID_DEVICE_IOTLB_PASID(inv_desc->lo); + vtd_dev_as = vtd_get_as_by_sid_and_pasid(s, sid, pasid); + if (!vtd_dev_as) { + return true; + } + + do_invalidate_device_tlb(vtd_dev_as, size, addr); + } + + return true; +} + static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) { @@ -3110,6 +3153,13 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s) } break; + case VTD_INV_DESC_DEV_PIOTLB: + trace_vtd_inv_desc("device-piotlb", inv_desc.hi, inv_desc.lo); + if (!vtd_process_device_piotlb_desc(s, &inv_desc)) { + return false; + } + break; + case VTD_INV_DESC_DEVICE: trace_vtd_inv_desc("device", inv_desc.hi, inv_desc.lo); if (!vtd_process_device_iotlb_desc(s, &inv_desc)) { From patchwork Mon Aug 5 06:27:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968893 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=J5kys9ju; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WcmnZ2ZCfz1yYD for ; Mon, 5 Aug 2024 16:32:18 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFY-0003U0-2l; Mon, 05 Aug 2024 02:31:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFR-0003AF-O6 for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:15 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFO-0002DM-RJ for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839470; x=1754375470; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HxQt+ElF7mrJns/ADRBCw0L2nr7XnpTAqOvZ+vtE2kc=; b=J5kys9jundmYx0Xj2D/DSaRoR222fZg/RHSHoLg65M6aGBJNyabT3GZM 0eNyegVJusUlUW55I2WsK1z7N6elb3UALlQ7jVuJr9FluSYiQY9zPHU+5 XrKifLVotZnl5R7bB/RsvIww/vuuXh7gmNx8kvY9reok2xWxLF1fdBsb0 qRHXh1gQSMjVpCT3V+YQr6ckdLdMZTAEM1FAMY5xjaEvX+mgWr2wO219h a0GlTG9EpUdU9Sjyt+G3mKLWLNaleo+LY1nPhFoawMZ4hHlIOPWAmIkGl 1jsWCeAcgySrBDrTnKghzG8Bi6Mo4s4ydhH6FwvsS1sfDOKoUdhyCkbmQ g==; X-CSE-ConnectionGUID: fCNk2XqMQW2x7RH2zQLDJw== X-CSE-MsgGUID: nizyGoaDTMCS4qldAHzNSw== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282843" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282843" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:08 -0700 X-CSE-ConnectionGUID: 0hEBrKbXShiaff6cLz561g== X-CSE-MsgGUID: eymxisgBTLK8ERjwX12Cuw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56787015" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:04 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum Subject: [PATCH v2 13/17] intel_iommu: piotlb invalidation should notify unmap Date: Mon, 5 Aug 2024 14:27:23 +0800 Message-Id: <20240805062727.2307552-14-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This is used by some emulated devices which caches address translation result. When piotlb invalidation issued in guest, those caches should be refreshed. Signed-off-by: Yi Sun Signed-off-by: Zhenzhong Duan Reviewed-by: Clément Mathieu--Drif --- hw/i386/intel_iommu.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index fa00f85fd7..317e630e08 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -2907,7 +2907,7 @@ static void vtd_piotlb_pasid_invalidate(IntelIOMMUState *s, continue; } - if (!s->scalable_modern) { + if (!s->scalable_modern || !vtd_as_has_map_notifier(vtd_as)) { vtd_address_space_sync(vtd_as); } } @@ -2919,6 +2919,9 @@ static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id, bool ih) { VTDIOTLBPageInvInfo info; + VTDAddressSpace *vtd_as; + VTDContextEntry ce; + hwaddr size = (1 << am) * VTD_PAGE_SIZE; info.domain_id = domain_id; info.pasid = pasid; @@ -2929,6 +2932,36 @@ static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id, g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page_piotlb, &info); vtd_iommu_unlock(s); + + QLIST_FOREACH(vtd_as, &s->vtd_as_with_notifiers, next) { + if (!vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus), + vtd_as->devfn, &ce) && + domain_id == vtd_get_domain_id(s, &ce, vtd_as->pasid)) { + uint32_t rid2pasid = VTD_CE_GET_RID2PASID(&ce); + IOMMUTLBEvent event; + + if ((vtd_as->pasid != PCI_NO_PASID || pasid != rid2pasid) && + vtd_as->pasid != pasid) { + continue; + } + + /* + * Page-Selective-within-PASID PASID-based-IOTLB Invalidation + * does not flush stage-2 entries. See spec section 6.5.2.4 + */ + if (!s->scalable_modern) { + continue; + } + + event.type = IOMMU_NOTIFIER_UNMAP; + event.entry.target_as = &address_space_memory; + event.entry.iova = addr; + event.entry.perm = IOMMU_NONE; + event.entry.addr_mask = size - 1; + event.entry.translated_addr = 0; + memory_region_notify_iommu(&vtd_as->iommu, 0, event); + } + } } static bool vtd_process_piotlb_desc(IntelIOMMUState *s, From patchwork Mon Aug 5 06:27:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968897 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=AnzDJfX/; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmnp7472z1yYD for ; Mon, 5 Aug 2024 16:32:30 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFw-00053A-Na; Mon, 05 Aug 2024 02:31:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFY-0003XM-SI for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:21 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFU-0002DM-Oy for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839476; x=1754375476; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GFvOFa9P+mYkjosgDpkYes8UGBsmHawsSqhMW/hkTRs=; b=AnzDJfX/pRxevqhBSXTOuHm3H/xe7I1ibRMX/QSOuUsQQwiM+Z7qWYMC Gz1Pc1qwx+hvfTsu3hi00ZSZWnFDROAbMuzHFAFzMUAfXjckRik/8YJc0 79Ii9pt8ItGY/3w4ACvIc/TThPZkQ2mSLFVYmLK9a7ZDCro+f9LfKbREc sv4UYzoDXs3WLMY6UB/VvTnEVw21XnNX/zz/tY6Xosg8OaAHPsU+cckAR kWK4vwdqMHw9m9+fEHaecQeseJ0RpIOW9ubNNEoK9FC/I9bL+YwHhofVW uCY6NvsIjRiUcbyG5Yp/vN5uol5v+le7x7uENbw+DygpBKd82gWu/DDQx A==; X-CSE-ConnectionGUID: rGouqvh7T6qrP5Ol4t18Qw== X-CSE-MsgGUID: JfmfLLysRomire3QgKL62Q== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282879" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282879" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:13 -0700 X-CSE-ConnectionGUID: c/I1cMjFSq2yMGtwbjl+fQ== X-CSE-MsgGUID: JYtLWmxRQcqWf6wsUYVyag== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56787061" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:09 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Eduardo Habkost Subject: [PATCH v2 14/17] intel_iommu: Set default aw_bits to 48 in scalable modren mode Date: Mon, 5 Aug 2024 14:27:24 +0800 Message-Id: <20240805062727.2307552-15-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org According to VTD spec, stage-1 page table could support 4-level and 5-level paging. However, 5-level paging translation emulation is unsupported yet. That means the only supported value for aw_bits is 48. So default aw_bits to 48 in scalable modern mode. In other cases, it is still default to 39 for compatibility. Add a check to ensure user specified value is 48 in modern mode for now. Signed-off-by: Zhenzhong Duan Reviewed-by: Clément Mathieu--Drif Reviewed-by: Clément Mathieu--Drif --- include/hw/i386/intel_iommu.h | 2 +- hw/i386/intel_iommu.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index b843d069cc..48134bda11 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -45,7 +45,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(IntelIOMMUState, INTEL_IOMMU_DEVICE) #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_HOST_AW_AUTO 0xff #define VTD_HAW_MASK(aw) ((1ULL << (aw)) - 1) #define DMAR_REPORT_F_INTR (1) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 317e630e08..5469ab4f9b 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -3770,7 +3770,7 @@ static Property vtd_properties[] = { ON_OFF_AUTO_AUTO), DEFINE_PROP_BOOL("x-buggy-eim", IntelIOMMUState, buggy_eim, false), DEFINE_PROP_UINT8("aw-bits", IntelIOMMUState, aw_bits, - VTD_HOST_ADDRESS_WIDTH), + VTD_HOST_AW_AUTO), DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE), DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE), DEFINE_PROP_BOOL("snoop-control", IntelIOMMUState, snoop_control, false), @@ -4685,6 +4685,14 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp) } } + if (s->aw_bits == VTD_HOST_AW_AUTO) { + if (s->scalable_modern) { + s->aw_bits = VTD_HOST_AW_48BIT; + } else { + s->aw_bits = VTD_HOST_AW_39BIT; + } + } + if ((s->aw_bits != VTD_HOST_AW_39BIT) && (s->aw_bits != VTD_HOST_AW_48BIT) && !s->scalable_modern) { @@ -4693,6 +4701,12 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp) return false; } + if ((s->aw_bits != VTD_HOST_AW_48BIT) && s->scalable_modern) { + error_setg(errp, "Supported values for aw-bits are: %d", + VTD_HOST_AW_48BIT); + return false; + } + if (s->scalable_mode && !s->dma_drain) { error_setg(errp, "Need to set dma_drain for scalable mode"); return false; From patchwork Mon Aug 5 06:27:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968884 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=TTMqXM/F; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmmp25wMz1yYD for ; Mon, 5 Aug 2024 16:31:38 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFe-0003rr-59; Mon, 05 Aug 2024 02:31:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFa-0003eF-HJ for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:22 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFY-0002Ek-Be for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839480; x=1754375480; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lM5Q+xxz8bPYCwNtaOw3pHfsq3bdb1ineJ7VWmFGFa0=; b=TTMqXM/F+fp28mJMUtDVCTbXzIdnqNoRguZVGsZwCJKsH1Z0V7JbGWXt DtNuv0YTarwcUi7gfX8HgPUnBeVtatNiaUNf+98TyEIpRFis/0eNvCRKE ka3yUSvphC5Tg+dh/mUvPJy7PWGCl1B3R1LAJl90aJ0Q7FVh5S3wEBTvJ Zx9GZ2mt6w8z0XGibiboBrFlG3ovacUhcxDCoc+TnWxLfCkcEjKyW3492 sZv9SV9Q508+FCKwjH26DvOImsA+BlqpEobMdYNp2CWkflaJcW+C2joCR I7KAZRS2p+iXgcxkRTHYGGmjSJmnlvIZ4SUihTriaKqUhzHa6jAM0AcAO Q==; X-CSE-ConnectionGUID: ub38+sd+RpO1Nwe/GXoNRw== X-CSE-MsgGUID: azpMmegNS6Oa4UD2+VMBsw== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282905" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282905" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:18 -0700 X-CSE-ConnectionGUID: 8skcEn5yTWiiJ/nRtMY2ug== X-CSE-MsgGUID: h0csB4qMT1CBUjtv3q3QWA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56787118" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:13 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum Subject: [PATCH v2 15/17] intel_iommu: Modify x-scalable-mode to be string option to expose scalable modern mode Date: Mon, 5 Aug 2024 14:27:25 +0800 Message-Id: <20240805062727.2307552-16-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Yi Liu Intel VT-d 3.0 introduces scalable mode, and it has a bunch of capabilities related to scalable mode translation, thus there are multiple combinations. While this vIOMMU implementation wants to simplify it for user by providing typical combinations. User could config it by "x-scalable-mode" option. The usage is as below: "-device intel-iommu,x-scalable-mode=["legacy"|"modern"|"off"]" - "legacy": gives support for stage-2 page table - "modern": gives support for stage-1 page table - "off": no scalable mode support - any other string, will throw error If x-scalable-mode is not configured, it is equivalent to x-scalable-mode=off. With scalable modern mode exposed to user, also accurate the pasid entry check in vtd_pe_type_check(). Signed-off-by: Yi Liu Signed-off-by: Yi Sun Signed-off-by: Zhenzhong Duan Signed-off-by: Yi Liu Signed-off-by: Yi Sun Signed-off-by: Zhenzhong Duan --- hw/i386/intel_iommu_internal.h | 2 ++ include/hw/i386/intel_iommu.h | 1 + hw/i386/intel_iommu.c | 46 ++++++++++++++++++++++++++-------- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 52bdbf3bc5..af99deb4cd 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -195,6 +195,7 @@ #define VTD_ECAP_PASID (1ULL << 40) #define VTD_ECAP_SMTS (1ULL << 43) #define VTD_ECAP_SLTS (1ULL << 46) +#define VTD_ECAP_FLTS (1ULL << 47) /* CAP_REG */ /* (offset >> 4) << 24 */ @@ -211,6 +212,7 @@ #define VTD_CAP_SLLPS ((1ULL << 34) | (1ULL << 35)) #define VTD_CAP_DRAIN_WRITE (1ULL << 54) #define VTD_CAP_DRAIN_READ (1ULL << 55) +#define VTD_CAP_FS1GP (1ULL << 56) #define VTD_CAP_DRAIN (VTD_CAP_DRAIN_READ | VTD_CAP_DRAIN_WRITE) #define VTD_CAP_CM (1ULL << 7) #define VTD_PASID_ID_SHIFT 20 diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 48134bda11..650641544c 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -263,6 +263,7 @@ struct IntelIOMMUState { bool caching_mode; /* RO - is cap CM enabled? */ bool scalable_mode; /* RO - is Scalable Mode supported? */ + char *scalable_mode_str; /* RO - admin's Scalable Mode config */ bool scalable_modern; /* RO - is modern SM supported? */ bool snoop_control; /* RO - is SNP filed supported? */ diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 5469ab4f9b..9e973bd710 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -803,16 +803,18 @@ static inline bool vtd_is_fl_level_supported(IntelIOMMUState *s, uint32_t level) } /* Return true if check passed, otherwise false */ -static inline bool vtd_pe_type_check(X86IOMMUState *x86_iommu, - VTDPASIDEntry *pe) +static inline bool vtd_pe_type_check(IntelIOMMUState *s, VTDPASIDEntry *pe) { switch (VTD_PE_GET_TYPE(pe)) { - case VTD_SM_PASID_ENTRY_SLT: - return true; - case VTD_SM_PASID_ENTRY_PT: - return x86_iommu->pt_supported; case VTD_SM_PASID_ENTRY_FLT: + return !!(s->ecap & VTD_ECAP_FLTS); + case VTD_SM_PASID_ENTRY_SLT: + return !!(s->ecap & VTD_ECAP_SLTS) || !(s->ecap & VTD_ECAP_SMTS); case VTD_SM_PASID_ENTRY_NESTED: + /* Not support NESTED page table type yet */ + return false; + case VTD_SM_PASID_ENTRY_PT: + return !!(s->ecap & VTD_ECAP_PT); default: /* Unknown type */ return false; @@ -861,7 +863,6 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, uint8_t pgtt; uint32_t index; dma_addr_t entry_size; - X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s); index = VTD_PASID_TABLE_INDEX(pasid); entry_size = VTD_PASID_ENTRY_SIZE; @@ -875,7 +876,7 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, } /* Do translation type check */ - if (!vtd_pe_type_check(x86_iommu, pe)) { + if (!vtd_pe_type_check(s, pe)) { return -VTD_FR_PASID_TABLE_ENTRY_INV; } @@ -3772,7 +3773,7 @@ static Property vtd_properties[] = { DEFINE_PROP_UINT8("aw-bits", IntelIOMMUState, aw_bits, VTD_HOST_AW_AUTO), DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE), - DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE), + DEFINE_PROP_STRING("x-scalable-mode", IntelIOMMUState, scalable_mode_str), DEFINE_PROP_BOOL("snoop-control", IntelIOMMUState, snoop_control, false), DEFINE_PROP_BOOL("x-pasid-mode", IntelIOMMUState, pasid, false), DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true), @@ -4503,7 +4504,10 @@ static void vtd_cap_init(IntelIOMMUState *s) } /* TODO: read cap/ecap from host to decide which cap to be exposed. */ - if (s->scalable_mode) { + if (s->scalable_modern) { + s->ecap |= VTD_ECAP_SMTS | VTD_ECAP_FLTS; + s->cap |= VTD_CAP_FS1GP; + } else if (s->scalable_mode) { s->ecap |= VTD_ECAP_SMTS | VTD_ECAP_SRS | VTD_ECAP_SLTS; } @@ -4685,6 +4689,28 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp) } } + if (s->scalable_mode_str && + (strcmp(s->scalable_mode_str, "off") && + strcmp(s->scalable_mode_str, "modern") && + strcmp(s->scalable_mode_str, "legacy"))) { + error_setg(errp, "Invalid x-scalable-mode config," + "Please use \"modern\", \"legacy\" or \"off\""); + return false; + } + + if (s->scalable_mode_str && + !strcmp(s->scalable_mode_str, "legacy")) { + s->scalable_mode = true; + s->scalable_modern = false; + } else if (s->scalable_mode_str && + !strcmp(s->scalable_mode_str, "modern")) { + s->scalable_mode = true; + s->scalable_modern = true; + } else { + s->scalable_mode = false; + s->scalable_modern = false; + } + if (s->aw_bits == VTD_HOST_AW_AUTO) { if (s->scalable_modern) { s->aw_bits = VTD_HOST_AW_48BIT; From patchwork Mon Aug 5 06:27:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968894 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=cIsP9xSq; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmnc6JGlz1yYD for ; Mon, 5 Aug 2024 16:32:20 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFy-0005RT-Qz; Mon, 05 Aug 2024 02:31:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFi-0004Bl-Fm for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:30 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFf-0002FJ-Pg for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839487; x=1754375487; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+/iT+1PlOBLDvVOFj8Pdp2LZI5Rw1SSeDRcMpgXV3ys=; b=cIsP9xSqhsz79tfUBs0mfyvVI27aLLLGjukxFOxBhfwiNowuvpss8p6c FbfDwVgrQYHTjU1z8vq3amOzctWBJezC2nvvlrhcH5W3QVfycB/4NqDOT nYggZiHdqpaLlCZwCOFct2stXQ3O+6GhBHILfGdqi3MmUTuFdBvfXKJKI bmxknHtKFzOurFZnTHmf5HaV/8UYVdXGXIa7o9/SQ1T3Hw1AjxhFZkVKZ vT5bui/vvXBVzitB6rsgvEFfUMvRBawbmiR4xCxCO1/sr5tilUNUH+Uri +S1kmC7U8t4H+PYDDHgJNsdVNBPVbBV/xThoDWY3BVmsJYI+S/ID7KjOa Q==; X-CSE-ConnectionGUID: NuR+j1A8S8KMR5qgcxTS4g== X-CSE-MsgGUID: HxjPKBEySOq9ZWZg7piJww== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282923" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282923" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:23 -0700 X-CSE-ConnectionGUID: G9meqiI4SZWbaWWIKEo4Sw== X-CSE-MsgGUID: zM53ChTtQKGstNUoVYgcpQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56787175" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:18 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Paolo Bonzini , Richard Henderson , Eduardo Habkost , Marcel Apfelbaum Subject: [PATCH v2 16/17] intel_iommu: Introduce a property to control FS1GP cap bit setting Date: Mon, 5 Aug 2024 14:27:26 +0800 Message-Id: <20240805062727.2307552-17-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org When host IOMMU doesn't support FS1GP but vIOMMU does, host IOMMU can't translate stage-1 page table from guest correctly. Add a property x-cap-fs1gp for user to turn FS1GP off so that nested page table on host side works. This property has no effect when vIOMMU isn't in scalable modern mode. Signed-off-by: Zhenzhong Duan Reviewed-by: Clément Mathieu--Drif --- include/hw/i386/intel_iommu.h | 1 + hw/i386/intel_iommu.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 650641544c..f6d9b41b80 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -308,6 +308,7 @@ struct IntelIOMMUState { bool dma_drain; /* Whether DMA r/w draining enabled */ bool dma_translation; /* Whether DMA translation supported */ bool pasid; /* Whether to support PASID */ + bool fs1gp; /* First Stage 1-GByte Page Support */ /* * Protects IOMMU states in general. Currently it protects the diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 9e973bd710..d7e7354db4 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -3778,6 +3778,7 @@ static Property vtd_properties[] = { DEFINE_PROP_BOOL("x-pasid-mode", IntelIOMMUState, pasid, false), DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true), DEFINE_PROP_BOOL("dma-translation", IntelIOMMUState, dma_translation, true), + DEFINE_PROP_BOOL("x-cap-fs1gp", IntelIOMMUState, fs1gp, true), DEFINE_PROP_END_OF_LIST(), }; @@ -4506,7 +4507,9 @@ static void vtd_cap_init(IntelIOMMUState *s) /* TODO: read cap/ecap from host to decide which cap to be exposed. */ if (s->scalable_modern) { s->ecap |= VTD_ECAP_SMTS | VTD_ECAP_FLTS; - s->cap |= VTD_CAP_FS1GP; + if (s->fs1gp) { + s->cap |= VTD_CAP_FS1GP; + } } else if (s->scalable_mode) { s->ecap |= VTD_ECAP_SMTS | VTD_ECAP_SRS | VTD_ECAP_SLTS; } From patchwork Mon Aug 5 06:27:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Duan, Zhenzhong" X-Patchwork-Id: 1968896 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=N/cEqF6w; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Wcmnj1vLSz1yYD for ; Mon, 5 Aug 2024 16:32:25 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sarFy-0005Pm-5f; Mon, 05 Aug 2024 02:31:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFm-0004QB-2f for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:36 -0400 Received: from mgamail.intel.com ([192.198.163.8]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sarFj-0002FJ-Fm for qemu-devel@nongnu.org; Mon, 05 Aug 2024 02:31:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1722839491; x=1754375491; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+gTPb7kGR/A9WlIO3Qas3Y/8henOtiHRKV6x1G6ILnU=; b=N/cEqF6wsY4nkSx3Ri/eQM7RZoKkypiLfiCGl/j/SKnwV1nhQKpwbjTp GPf8PMzEIvc4+0At/ZdwGN3GAv4FYwh6az2fzM8Pn5x47v+wFLp8DUfUJ i0Vt7iyssHyNwA3PyFzxAyVzw0jOZJ8+Bsko8Zw4bduP70WciKrrxjwH5 YAeBWVx9uI1uCKL1l2w9DHXEM9+unB+QDxCHOcoHzVDY4CMA4dLLPZFpx 8XFPh8Tl2NxD8Dk1Z1ZFYvKpS/cfZsTWKXKgvxY24Xj2QJfqOjGPzJQxh xL1nv06NLVFaFGN7Nqfj+vv6rAodLSGlhjSfb+HozecI49I3a1EA3R7so w==; X-CSE-ConnectionGUID: Wd+1EXyISaClsvr8h/pYtw== X-CSE-MsgGUID: vof6zuwbQ5+6yCinxNpRIg== X-IronPort-AV: E=McAfee;i="6700,10204,11154"; a="38282934" X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="38282934" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:27 -0700 X-CSE-ConnectionGUID: ZkXQbJ9ARaOca9OKR20anw== X-CSE-MsgGUID: q/XYb0LFTa+YzFz2dbx/TQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,263,1716274800"; d="scan'208";a="56787193" Received: from spr-s2600bt.bj.intel.com ([10.240.192.127]) by orviesa008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2024 23:31:23 -0700 From: Zhenzhong Duan To: qemu-devel@nongnu.org Cc: alex.williamson@redhat.com, clg@redhat.com, eric.auger@redhat.com, mst@redhat.com, peterx@redhat.com, jasowang@redhat.com, jgg@nvidia.com, nicolinc@nvidia.com, joao.m.martins@oracle.com, clement.mathieu--drif@eviden.com, kevin.tian@intel.com, yi.l.liu@intel.com, chao.p.peng@intel.com, Zhenzhong Duan , Marcel Apfelbaum , Thomas Huth , Laurent Vivier , Paolo Bonzini Subject: [PATCH v2 17/17] tests/qtest: Add intel-iommu test Date: Mon, 5 Aug 2024 14:27:27 +0800 Message-Id: <20240805062727.2307552-18-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805062727.2307552-1-zhenzhong.duan@intel.com> References: <20240805062727.2307552-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.198.163.8; envelope-from=zhenzhong.duan@intel.com; helo=mgamail.intel.com X-Spam_score_int: -44 X-Spam_score: -4.5 X-Spam_bar: ---- X-Spam_report: (-4.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.145, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add the framework to test the intel-iommu device. Currently only tested cap/ecap bits correctness in scalable modern mode. Also tested cap/ecap bits consistency before and after system reset. Signed-off-by: Zhenzhong Duan Reviewed-by: Clément Mathieu--Drif Acked-by: Thomas Huth --- MAINTAINERS | 1 + include/hw/i386/intel_iommu.h | 1 + tests/qtest/intel-iommu-test.c | 70 ++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 1 + 4 files changed, 73 insertions(+) create mode 100644 tests/qtest/intel-iommu-test.c diff --git a/MAINTAINERS b/MAINTAINERS index e34c2bd4cd..c9a2321f1c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3673,6 +3673,7 @@ S: Supported F: hw/i386/intel_iommu.c F: hw/i386/intel_iommu_internal.h F: include/hw/i386/intel_iommu.h +F: tests/qtest/intel-iommu-test.c AMD-Vi Emulation S: Orphan diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index f6d9b41b80..0c9bb8eab6 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -47,6 +47,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(IntelIOMMUState, INTEL_IOMMU_DEVICE) #define VTD_HOST_AW_48BIT 48 #define VTD_HOST_AW_AUTO 0xff #define VTD_HAW_MASK(aw) ((1ULL << (aw)) - 1) +#define VTD_MGAW_FROM_CAP(cap) ((cap >> 16) & 0x3fULL) #define DMAR_REPORT_F_INTR (1) diff --git a/tests/qtest/intel-iommu-test.c b/tests/qtest/intel-iommu-test.c new file mode 100644 index 0000000000..fa9169f1a3 --- /dev/null +++ b/tests/qtest/intel-iommu-test.c @@ -0,0 +1,70 @@ +/* + * QTest testcase for intel-iommu + * + * Copyright (c) 2024 Intel, Inc. + * + * Author: Zhenzhong Duan + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "libqtest.h" +#include "hw/i386/intel_iommu_internal.h" + +#define CAP_MODERN_FIXED1 (VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | \ + VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS) +#define ECAP_MODERN_FIXED1 (VTD_ECAP_QI | VTD_ECAP_IR | VTD_ECAP_IRO | \ + VTD_ECAP_MHMV | VTD_ECAP_SMTS | VTD_ECAP_FLTS) + +static inline uint32_t vtd_reg_readl(QTestState *s, uint64_t offset) +{ + return qtest_readl(s, Q35_HOST_BRIDGE_IOMMU_ADDR + offset); +} + +static inline uint64_t vtd_reg_readq(QTestState *s, uint64_t offset) +{ + return qtest_readq(s, Q35_HOST_BRIDGE_IOMMU_ADDR + offset); +} + +static void test_intel_iommu_modern(void) +{ + uint8_t init_csr[DMAR_REG_SIZE]; /* register values */ + uint8_t post_reset_csr[DMAR_REG_SIZE]; /* register values */ + uint64_t cap, ecap, tmp; + QTestState *s; + + s = qtest_init("-M q35 -device intel-iommu,x-scalable-mode=modern"); + + cap = vtd_reg_readq(s, DMAR_CAP_REG); + g_assert((cap & CAP_MODERN_FIXED1) == CAP_MODERN_FIXED1); + + tmp = cap & VTD_CAP_SAGAW_MASK; + g_assert(tmp == (VTD_CAP_SAGAW_39bit | VTD_CAP_SAGAW_48bit)); + + tmp = VTD_MGAW_FROM_CAP(cap); + g_assert(tmp == VTD_HOST_AW_48BIT - 1); + + ecap = vtd_reg_readq(s, DMAR_ECAP_REG); + g_assert((ecap & ECAP_MODERN_FIXED1) == ECAP_MODERN_FIXED1); + + qtest_memread(s, Q35_HOST_BRIDGE_IOMMU_ADDR, init_csr, DMAR_REG_SIZE); + + qobject_unref(qtest_qmp(s, "{ 'execute': 'system_reset' }")); + qtest_qmp_eventwait(s, "RESET"); + + qtest_memread(s, Q35_HOST_BRIDGE_IOMMU_ADDR, post_reset_csr, DMAR_REG_SIZE); + /* Ensure registers are consistent after hard reset */ + g_assert(!memcmp(init_csr, post_reset_csr, DMAR_REG_SIZE)); + + qtest_quit(s); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + qtest_add_func("/q35/intel-iommu/modern", test_intel_iommu_modern); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 2f0d3ef080..76d183df74 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -79,6 +79,7 @@ qtests_i386 = \ (config_all_devices.has_key('CONFIG_SB16') ? ['fuzz-sb16-test'] : []) + \ (config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \ (config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \ + (config_all_devices.has_key('CONFIG_VTD') ? ['intel-iommu-test'] : []) + \ (host_os != 'windows' and \ config_all_devices.has_key('CONFIG_ACPI_ERST') ? ['erst-test'] : []) + \ (config_all_devices.has_key('CONFIG_PCIE_PORT') and \