From patchwork Mon Apr 22 15:52:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: CLEMENT MATHIEU--DRIF X-Patchwork-Id: 13638647 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 010EDC4345F for ; Mon, 22 Apr 2024 15:53:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ryvyi-0007Gm-Oc; Mon, 22 Apr 2024 11:53:12 -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 1ryvyc-0007Em-KQ for qemu-devel@nongnu.org; Mon, 22 Apr 2024 11:53:07 -0400 Received: from smarthost4.eviden.com ([80.78.11.85]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ryvyZ-0007bS-Fx for qemu-devel@nongnu.org; Mon, 22 Apr 2024 11:53:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=eviden.com; i=@eviden.com; q=dns/txt; s=mail; t=1713801183; x=1745337183; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-id:content-transfer-encoding: mime-version; bh=liB5/3/LBFtQuwFWwuBS9Ju+8ITpXVCiihZJfH7mZeY=; b=qhZUrunvONVtrffB2As2wKE9TBDGBp1IgCcTR2zPKl3NDJIeQ3mN7S8R Oev/3LVtmtJ2NDJnj35Jh62yYOecf0QcZcAHCXkzsob8S8LKBJDLDlIOG ZKwVpQQ3gi0gqqwDx088jiNVtCaVk241+TjDJduW+83JXQsrLelUdg/qD YZJIEuD/vZRLeZfX43pqJGtX3lugOB5vGAgkgTgOlZQ0YWe+V2aAnfgJS vZlRhSx5gr6l1hYWphH4JybhVcL7DA5i1KXLk7hampZsqx02n+aUzJqNo 59LMeVpnMVzQHgdt1Lr9nA9rLI0IBbY7ZR5UqQnrNpzjwXuPqUKrBUlFK w==; X-IronPort-AV: E=Sophos;i="6.07,220,1708383600"; d="scan'208";a="11027675" X-MGA-submission: MDEmgtisbYvx7d4zZunQvzwQeiYVh8l7g9V+2iRKt2d//kZdUMwyXtL+Gf0NFhMMGqu21VHc6IIu71I665/j78F2EF/4zHwfS8I3YGiSHq5vRnYRa63j8Ssh4VDC/mvyG68C/l2F41V+iDbXMVpcIQiHTTAA5Ev0GthkgUVAp5awPA== Received: from mail-am0eur02lp2233.outbound.protection.outlook.com (HELO EUR02-AM0-obe.outbound.protection.outlook.com) ([104.47.11.233]) by smarthost4.eviden.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Apr 2024 17:52:57 +0200 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=arrz6NMmFcqWSBZgRz+pSt9tv5bq6E443SDYjuAShXfR2Ns3YhiLV3ZFhZhAoZ/FQ3jjbMZmRaoj2H6JGmhjHjIaOOsIMPN5SGaVTHVcPbcQtvG4wnuBEBrQIqs/mwvRxMFLqCmmQU981dskc4EB3wEIgXUS1jU2+aqSxEViL6rdD72RKtEwtYUjM2k64HZ2+6obbTXuc1PdJ6bMIX1sR5fvU7iP1B6GLek6kXcv55GiBwFVmcvfiwi+RmbFFShKfc2Y5s6USmuTssXkhg2Y1kwI0A3UNSRrcSeJMP/EFOr8tTsqjWwInXuRwo92Y1MmgYb99CJo0d0gbtObzfB5MQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=liB5/3/LBFtQuwFWwuBS9Ju+8ITpXVCiihZJfH7mZeY=; b=OueahUFXNWu24s+7nDZ+69DugkMuyVcxsua2lNPF/GbhXpSHlXzr0Z65lSiBIGLDOqWr3gKPR7SEufAwwvDNW3UeWRKxjAHJ9ZCTW3IrDdm+lxCHFh0IiN9QjTin+2iB70wUss3+j4Ljytqo0FEq/34ejyI9bkPAiqwOjQs43IXjUAeHymMtcyg4FU2x8jAVT26FWORpJYf3PReli4pcKsd2zh4sQ9+BZ7cKgYcO3Lxnf5/d03oiMUnKvqMZE28ZfFyy9qa4wnJizg2UY/q50JiI3u3cDHDNFCQUPQ4PiWAloVmRomYeBuJxOi/TlZKZapHL18nVZyoN4Rd3tPutfg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=eviden.com; dmarc=pass action=none header.from=eviden.com; dkim=pass header.d=eviden.com; arc=none Received: from AM8PR07MB7602.eurprd07.prod.outlook.com (2603:10a6:20b:24b::7) by DU0PR07MB9626.eurprd07.prod.outlook.com (2603:10a6:10:31e::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7472.44; Mon, 22 Apr 2024 15:52:55 +0000 Received: from AM8PR07MB7602.eurprd07.prod.outlook.com ([fe80::fbd7:ca71:b636:6f9d]) by AM8PR07MB7602.eurprd07.prod.outlook.com ([fe80::fbd7:ca71:b636:6f9d%5]) with mapi id 15.20.7472.044; Mon, 22 Apr 2024 15:52:55 +0000 From: CLEMENT MATHIEU--DRIF To: "qemu-devel@nongnu.org" CC: "jasowang@redhat.com" , CLEMENT MATHIEU--DRIF Subject: [PATCH intel_iommu 6/7] intel_iommu: add PASID-based IOTLB invalidation Thread-Topic: [PATCH intel_iommu 6/7] intel_iommu: add PASID-based IOTLB invalidation Thread-Index: AQHalM0jxDwfRa4+HUShrGVOuKfHWw== Date: Mon, 22 Apr 2024 15:52:53 +0000 Message-ID: <20240422155236.129179-7-clement.mathieu--drif@eviden.com> References: <20240422155236.129179-1-clement.mathieu--drif@eviden.com> In-Reply-To: <20240422155236.129179-1-clement.mathieu--drif@eviden.com> Accept-Language: en-GB, fr-FR, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=eviden.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: AM8PR07MB7602:EE_|DU0PR07MB9626:EE_ x-ms-office365-filtering-correlation-id: 8c73af8e-8d57-4f34-a228-08dc62e446a0 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: =?utf-8?q?WSBH126z8roqa3w97lb26Iuy7LMa1i/?= =?utf-8?q?TLfWz6NI2jNRGjeNcwFU3XUdz+OTXOv/VijWfc+xAgoqg5MjDtHAobw83dGjxHYkn?= =?utf-8?q?FZ8xuSJFONJycZ0lR0Asys7jWyXz4msXJDCWgUwYTd+Ca/fOW2SG65TTfpPobmcEb?= =?utf-8?q?sLI2AOCgjT3q3mr6TIDUEjMGbp3a79I7ydDxWyQF15H9rgOddwms0lQwOy6e3wGzw?= =?utf-8?q?0F2ck3V0qW4KZSXrTfrJeYlD1FKlfoRmCymQ87ZJE5H1LeBtcdduUgMN3prsiPJTw?= =?utf-8?q?cc9mk4jIwOlyO8RIVATRuAHBLjIx0ylZAt/Z9/rwTcLUhlud+ycmd5UXNtWhs7caL?= =?utf-8?q?yQwpIr9Sucxv665/Gyw/YWCLUTqEEQS7oXW9+SbNttpFOKs1cKG7IA1jbazSNxG3T?= =?utf-8?q?IF/NE4tOErF3veDcZLrfnA2wshtLVoiWjbjZtKwu2/SNlfigNkZacKPvitFs2ptYb?= =?utf-8?q?IAj+lV0JqETH5/HSJQizrYQ0jfzLGjpq39qdAYQp57+muQM1fQjeanARJZ0eBaTPG?= =?utf-8?q?NzWp8aCFmYMeuPXW6dmiUGC73h69Vv5Is3PctnG7vepJ6ZSuLB/dIu5fZSqq/qrl6?= =?utf-8?q?EQTWlET2Baz7oYqAxP7EomTVIZb/8K7hyGheKLf1yeEuUeSskJHKOKxAQNLW1Moi0?= =?utf-8?q?dl57CU25qEh85sw2502Ol8Z/RDyQZ1cuEV0Md5ib3YQfFkNd+maydrVAft2TXPxAt?= =?utf-8?q?YQw4tCbz71M/RjtpovZeWHxYo+KQLCrR5K+kvS7abxKP5FIX6lpS2ySLKGUrnW3xx?= =?utf-8?q?oAN6HD5p+UBJ4cRfV3t/hLg9hm4USKpBuTU1+APmt50NZGGDi7oVTWGQluaFu5cS8?= =?utf-8?q?aFTwub5yK1Oy41tLU9Wou0tm++sbXSnjpU++JkD4V+MGARxqRpep6Y7kv77sRYIBg?= =?utf-8?q?uLb+KcA/vHTIkL/pf9EGO6D73bRPKm+t+nds/z8PRJ36qy0E/Uly5boUm8uIAlIXc?= =?utf-8?q?fTEJWCEUcyKl8zz1TOtZS3PL5alv0BuZypqzVY//qA+3fn1eO2ZDj+soPebFMEaWG?= =?utf-8?q?X5eHBdoOve9Z7LS7I9jBriS9YPdy/0dfLD6irlsIAksNBBnc8ECY271bkSfddiY2x?= =?utf-8?q?n3JfH8Dm3T3bkOdjvCOTUYuQh06Hzl83s76X6merwVu9eAW9Aqy0HWJZsYTnFb8bu?= =?utf-8?q?yNlDnWBbZd2dyHgouJxehAC2DYTJOEOjoRGejtfyyItRraqtjQIpldIRO3M0vGP4g?= =?utf-8?q?RorB7xq1v7sUsT9tMhOJT5ozRoBoJSR1k3/8QOCTz0tQ0icpfJK0+0atGHp1Po7mQ?= =?utf-8?q?KDY0KgsDdoCcHBikpF4/b49/HASiYLm+2Jw=3D=3D?= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM8PR07MB7602.eurprd07.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(1800799015)(366007)(376005)(38070700009); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?utf-8?q?nh57FuGImG0YOzc9qlLF5gMhKQcN?= =?utf-8?q?mSFfDRWkLpJo5JJiJ51vZSeYVMEqPxGhQeCbeF4oKgHj30ebIagDNswciof1ndx90?= =?utf-8?q?B+Ex8u8+pWYUKQ8vjcmH/lWijKry160n16aiNEZYPKVprtRvFkmdC5XcJ9kXrRUI9?= =?utf-8?q?Wr3HGoD1Xf2eYNiFOg1HNInkn891C38vh9uA/1KElbXdgE4EY309pZrvxdMbtHbt1?= =?utf-8?q?rG4eRI6N5hOi34LZafTSOWP0iyZ17s17jJowmx5m5nPbLRChTG47jcRlRccRJUEju?= =?utf-8?q?vs0lWwrJaIANVCuTyon6hnd6sO9q2n/ktjK6zky04zpDTidZyT37NX3lWhxNBj3Yq?= =?utf-8?q?Tgx+eSOXQ16w9Pzn/zr5nDP5R/PFTuNQeusLTSpMaofDu4KHdPRA/W8X937/bw7l1?= =?utf-8?q?yarMgQkzOJZXrPGixiqy/6wGfgXNjSL/xPPySNe9eiOWOtupy4ky821Z1h2xyTjYH?= =?utf-8?q?zg4RLBht939UAfS1yMCarWfaxo9qHLvMkeCs1FDX2UL94We5Feecve7ETpHXsSX5Y?= =?utf-8?q?6fJGMLr1/aeWn0SaV7d5rctIypsSUBGRN/upaNqU9Kp6yLQM9ziZCodZspDdY998B?= =?utf-8?q?RKQOSzabR4ZGW4omlaDvhNkiEVRKLK7TkoRL0NvuoZkN0wGvPoiPi/4yY5mflB5h7?= =?utf-8?q?edO0QthfYNGPeSGn+NKDfUbMGsM8PS6OetDoLJ1IrhtXqg3ivKCGjX1bw3YjL0fqI?= =?utf-8?q?QqNrdyfl4jRJovK8IfusbwZOrZC76ceInD7Yh9YfHfC0ZzA+kxVsUznbvXh7yvEYN?= =?utf-8?q?iJWAm5fm5Ox3uqsC0ZEo/KsrRS/RbpI+sRT73qHosc9v7wbCiHPDHGl1lXJExuAvY?= =?utf-8?q?rYjjd5bg/e2fbwOpevkJdwVNMBttQ/eZV0Z2yVoIhyuZAm4rrPIUrv4dJ5a7k+wCQ?= =?utf-8?q?GqtBW3scbHBZmQad+Gi79u9g35ttC/SA15PJrABMr/XasLc55lddUUDSYYKemTeNR?= =?utf-8?q?YRloKQ210T78t1FsV2MQ4bPtkuR2PVyUxuOIGNRVToR1jUWEtIOwU6VwT4zLzGD2D?= =?utf-8?q?v4EZbJXUYNbFPHV5EURD7nsiYfT20Ln+i5X3d8WMq5Eyl0gOWvR8PlUG4AWpAGDPv?= =?utf-8?q?2q1b0trjCrU/Y8Ym3bYkFHgc451oJwtrdFBxOXU+9XHpcNYyXLonBAMIYHeY/Mzdr?= =?utf-8?q?62nn1yKsM9h4EzPhlKkPcOL2B7WXFwaTrbEORAwiirBNo703XbUsEl/iW8bcbPCOZ?= =?utf-8?q?lWhgRrztvoUrmfGDioYo7OcBwxU4Bbndgh5vLgkgeeZfR2MpARUMeWifvIUguogNY?= =?utf-8?q?ZtERqvlhWqLSWkTGGwOPON4/CHgKk7mxC0g65yh2zyLWORcce7vza3Qy5MqZ5FPCT?= =?utf-8?q?JRPmllTPJplpWRNxVRAbu4g62yo5O9vHwqugBHnhAoIQdH9HWdKTMgN19u1P33U4B?= =?utf-8?q?4wEQdG8GMawsTOKkXbnXSW959Bt+LOdihmqF7qNcD8EBXmyQxkmq2bjU+1FGGPt3x?= =?utf-8?q?HMeWMxkj5fCJSsI4TjsL6OtID56hMmlOHx4uLGBY4cBGonusf+Yjyym0b5clw6O5l?= =?utf-8?q?0YUC3Y6l57TPDctVCFOH6NouvdSnCnq1kkQbgyBqo7Kx6uTcxbIPQTY=3D?= Content-ID: <1D0AF3F45FD2584CB9B3FF76BA129135@eurprd07.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: eviden.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: AM8PR07MB7602.eurprd07.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8c73af8e-8d57-4f34-a228-08dc62e446a0 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Apr 2024 15:52:53.7869 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 7d1c7785-2d8a-437d-b842-1ed5d8fbe00a X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: GiZKjh03M7TB2IfANiuOZa+n/m6Ju+bn484FcHuX631oHfUplszFa+y3EvZRSfS45xAl/KXkAybI3QY3/9T9nm2iRqEyca/VNZDRlW/deLZJ29lg7/I/GOYd2K006EGA X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR07MB9626 Received-SPF: pass client-ip=80.78.11.85; envelope-from=clement.mathieu--drif@eviden.com; helo=smarthost4.eviden.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Clément Mathieu--Drif --- hw/i386/intel_iommu.c | 130 ++++++++++++++++++++++++++++++--- hw/i386/intel_iommu_internal.h | 51 +++++++------ 2 files changed, 150 insertions(+), 31 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index aaac61bf6a..4b54a45107 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -277,9 +277,22 @@ 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)); + return ( + (entry->domain_id == info->domain_id) && + (info->pasid == entry->pasid) + ) && ( + ((entry->gfn & info->mask) == gfn) || + (entry->gfn == gfn_tlb) + ); +} + +static gboolean vtd_hash_remove_by_pasid(gpointer key, gpointer value, + gpointer user_data) +{ + VTDIOTLBEntry *entry = (VTDIOTLBEntry *)value; + VTDIOTLBPasidEntryInvInfo *info = (VTDIOTLBPasidEntryInvInfo *)user_data; + return ((entry->domain_id == info->domain_id) && + (info->pasid == entry->pasid)); } /* Reset all the gen of VTDAddressSpace to zero and set the gen of @@ -1287,8 +1300,10 @@ static int vtd_iova_to_pte_sl(IntelIOMMUState *s, VTDContextEntry *ce, if (ret != 0) { return ret; } + *reads = (*reads) && (slpte & VTD_SL_R); *writes = (*writes) && (slpte & VTD_SL_W); + if ((slpte & access_right_check) != access_right_check) { error_report_once("%s: detected slpte permission error " "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", " @@ -2484,23 +2499,61 @@ static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s, } } +static VTDIOTLBPageInvInfo vtd_build_tlb_page_inv_info(uint16_t domain_id, + hwaddr addr, uint8_t am, + uint32_t pasid) +{ + assert(am <= VTD_MAMV); + VTDIOTLBPageInvInfo info = { + .domain_id = domain_id, + .addr = addr, + .mask = ~((1ULL << am) - 1), + .pasid = pasid + }; + return info; +} + static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id, hwaddr addr, uint8_t am) { - VTDIOTLBPageInvInfo info; + VTDIOTLBPageInvInfo info = vtd_build_tlb_page_inv_info(domain_id, addr, + am, PCI_NO_PASID); trace_vtd_inv_desc_iotlb_pages(domain_id, addr, am); - assert(am <= VTD_MAMV); - info.domain_id = domain_id; - info.addr = addr; - info.mask = ~((1 << am) - 1); vtd_iommu_lock(s); g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, &info); vtd_iommu_unlock(s); + vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am, PCI_NO_PASID); } +static void vtd_pasid_based_iotlb_page_invalidate(IntelIOMMUState *s, + uint16_t domain_id, + hwaddr addr, + uint8_t am, uint32_t pasid) +{ + VTDIOTLBPageInvInfo info = vtd_build_tlb_page_inv_info(domain_id, addr, + am, pasid); + vtd_iommu_lock(s); + g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, &info); + vtd_iommu_unlock(s); +} + +static void vtd_pasid_based_iotlb_invalidate(IntelIOMMUState *s, + uint16_t domain_id, + uint32_t pasid) +{ + assert(pasid != PCI_NO_PASID); + VTDIOTLBPasidEntryInvInfo info = { + .domain_id = domain_id, + .pasid = pasid + }; + vtd_iommu_lock(s); + g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_pasid, &info); + vtd_iommu_unlock(s); +} + /* Flush IOTLB * Returns the IOTLB Actual Invalidation Granularity. * @val: the content of the IOTLB_REG @@ -2759,7 +2812,7 @@ static bool vtd_get_inv_desc(IntelIOMMUState *s, static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) { if ((inv_desc->hi & VTD_INV_DESC_WAIT_RSVD_HI) || - (inv_desc->lo & VTD_INV_DESC_WAIT_RSVD_LO)) { + (inv_desc->lo & VTD_INV_DESC_WAIT_RSVD_LO(s->ecap))) { error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64 " (reserved nonzero)", __func__, inv_desc->hi, inv_desc->lo); @@ -2785,6 +2838,11 @@ static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) } else if (inv_desc->lo & VTD_INV_DESC_WAIT_IF) { /* Interrupt flag */ vtd_generate_completion_event(s); + } else if (inv_desc->lo & VTD_INV_DESC_WAIT_FN) { + /* + * SW = 0, IF = 0, FN = 1 + * Nothing to do as we process the events sequentially + */ } else { error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64 " (unknown type)", __func__, inv_desc->hi, @@ -2957,6 +3015,54 @@ done: return true; } +static bool vtd_process_piotlb_desc(IntelIOMMUState *s, + VTDInvDesc *inv_desc) +{ + uint32_t pasid; + uint16_t domain_id; + hwaddr addr; + uint8_t am; + + if ((inv_desc->lo & VTD_INV_DESC_IOTLB_PASID_RSVD_LO) || + (inv_desc->hi & VTD_INV_DESC_IOTLB_PASID_RSVD_HI)) { + error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64 + ", lo=0x%"PRIx64" (reserved bits unzero)", + __func__, inv_desc->hi, inv_desc->lo); + return false; + } + + domain_id = VTD_INV_DESC_IOTLB_DID(inv_desc->lo); + pasid = VTD_INV_DESC_IOTLB_PASID(inv_desc->lo); + addr = VTD_INV_DESC_IOTLB_ADDR(inv_desc->hi); + am = VTD_INV_DESC_IOTLB_AM(inv_desc->hi); + + switch (inv_desc->lo & VTD_INV_DESC_IOTLB_G) { + case VTD_INV_DESC_IOTLB_PASID_PASID: + vtd_pasid_based_iotlb_invalidate(s, domain_id, pasid); + break; + + case VTD_INV_DESC_IOTLB_PASID_PAGE: + if (am > VTD_MAMV) { + error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64 + ", lo=0x%"PRIx64" (am=%u > VTD_MAMV=%u)", + __func__, inv_desc->hi, inv_desc->lo, + am, (unsigned)VTD_MAMV); + return false; + } + vtd_pasid_based_iotlb_page_invalidate(s, domain_id, addr, am, pasid); + break; + + default: + error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64 + ", lo=0x%"PRIx64" (type mismatch: 0x%llx)", + __func__, inv_desc->hi, inv_desc->lo, + inv_desc->lo & VTD_INV_DESC_IOTLB_G); + return false; + } + + return true; +} + static bool vtd_process_inv_desc(IntelIOMMUState *s) { VTDInvDesc inv_desc; @@ -2988,7 +3094,7 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s) break; /* - * TODO: the entity of below two cases will be implemented in future series. + * TODO: the entity of below case will be implemented in future series. * To make guest (which integrates scalable mode support patch set in * iommu driver) work, just return true is enough so far. */ @@ -2996,6 +3102,10 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s) break; case VTD_INV_DESC_PIOTLB: + trace_vtd_inv_desc("piotlb", inv_desc.hi, inv_desc.lo); + if (!vtd_process_piotlb_desc(s, &inv_desc)) { + return false; + } break; case VTD_INV_DESC_WAIT: diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index ed61979934..4f734ce67b 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -193,6 +193,7 @@ #define VTD_ECAP_MHMV (15ULL << 20) #define VTD_ECAP_SRS (1ULL << 31) #define VTD_ECAP_PASID (1ULL << 40) +#define VTD_ECAP_PDS (1ULL << 42) #define VTD_ECAP_SMTS (1ULL << 43) #define VTD_ECAP_SLTS (1ULL << 46) #define VTD_ECAP_FLTS (1ULL << 47) @@ -386,12 +387,13 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_NONE 0 /* Not an Invalidate Descriptor */ /* Masks for Invalidation Wait Descriptor*/ -#define VTD_INV_DESC_WAIT_SW (1ULL << 5) -#define VTD_INV_DESC_WAIT_IF (1ULL << 4) -#define VTD_INV_DESC_WAIT_FN (1ULL << 6) -#define VTD_INV_DESC_WAIT_DATA_SHIFT 32 -#define VTD_INV_DESC_WAIT_RSVD_LO 0Xffffff80ULL -#define VTD_INV_DESC_WAIT_RSVD_HI 3ULL +#define VTD_INV_DESC_WAIT_SW (1ULL << 5) +#define VTD_INV_DESC_WAIT_IF (1ULL << 4) +#define VTD_INV_DESC_WAIT_FN (1ULL << 6) +#define VTD_INV_DESC_WAIT_DATA_SHIFT 32 +#define VTD_INV_DESC_WAIT_RSVD_LO(ecap) (0xffffff00ULL | \ + ((ecap & VTD_ECAP_PDS) ? 0 : (1 << 7))) +#define VTD_INV_DESC_WAIT_RSVD_HI 3ULL /* Masks for Context-cache Invalidation Descriptor */ #define VTD_INV_DESC_CC_G (3ULL << 4) @@ -404,20 +406,20 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_CC_RSVD 0xfffc00000000ffc0ULL /* Masks for IOTLB Invalidate Descriptor */ -#define VTD_INV_DESC_IOTLB_G (3ULL << 4) -#define VTD_INV_DESC_IOTLB_GLOBAL (1ULL << 4) -#define VTD_INV_DESC_IOTLB_DOMAIN (2ULL << 4) -#define VTD_INV_DESC_IOTLB_PAGE (3ULL << 4) -#define VTD_INV_DESC_IOTLB_DID(val) (((val) >> 16) & VTD_DOMAIN_ID_MASK) -#define VTD_INV_DESC_IOTLB_ADDR(val) ((val) & ~0xfffULL) -#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 +#define VTD_INV_DESC_IOTLB_G (3ULL << 4) +#define VTD_INV_DESC_IOTLB_GLOBAL (1ULL << 4) +#define VTD_INV_DESC_IOTLB_DOMAIN (2ULL << 4) +#define VTD_INV_DESC_IOTLB_PAGE (3ULL << 4) +#define VTD_INV_DESC_IOTLB_DID(val) (((val) >> 16) & VTD_DOMAIN_ID_MASK) +#define VTD_INV_DESC_IOTLB_ADDR(val) ((val) & ~0xfffULL) +#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 0xfff000000000ffc0ULL +#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) @@ -471,10 +473,17 @@ struct VTDIOTLBPageInvInfo { uint16_t domain_id; uint32_t pasid; uint64_t addr; - uint8_t mask; + uint64_t mask; }; typedef struct VTDIOTLBPageInvInfo VTDIOTLBPageInvInfo; +/* Information about PASID-selective IOTLB invalidate */ +struct VTDIOTLBPasidEntryInvInfo { + uint16_t domain_id; + uint32_t pasid; +}; +typedef struct VTDIOTLBPasidEntryInvInfo VTDIOTLBPasidEntryInvInfo; + /* Pagesize of VTD paging structures, including root and context tables */ #define VTD_PAGE_SHIFT 12 #define VTD_PAGE_SIZE (1ULL << VTD_PAGE_SHIFT)