From nobody Fri Apr 26 04:14:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1605882030; cv=none; d=zohomail.com; s=zohoarc; b=Pbqxvr4jFDmS1xdquf25oLyfvRIIRdoM32lONpuoCOqQx3OlvTXZYekcA99wmd++YAX8ydppKbBazYhzdswpsGCXAPaQi9Mp1ItFf5kT8bad+98364FqUEpRlEkLAXX5jE1beCEQUKIh2Gn1YaEZwz8gf+Ww+8aHMUOAlw3VoRA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605882030; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=srvGBIbIH8QMv/T0CJ9CEHCytUTLV9RD+W7Ot3EbOus=; b=QH2RCRJxNxRo/kIwSUypJcHIrOrKG8p3xNA6bwFvf9WB2y1jnkCHsW+9PPxvmdqYvkx2Ysm2L6wqi3inqkWAXHqp9W+jIYLL41lzNhRPBAFdLXOLmUGsOkZ/3G4qI3wysMfeNH8uCIzwnzREQeuOR4OBFIMR6pioLjFEXaH4uzE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 160588203020394.40301402531577; Fri, 20 Nov 2020 06:20:30 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.32245.63259 (Exim 4.92) (envelope-from ) id 1kg7Gm-00011d-Nj; Fri, 20 Nov 2020 14:20:12 +0000 Received: by outflank-mailman (output) from mailman id 32245.63259; Fri, 20 Nov 2020 14:20:12 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kg7Gm-00011W-Ka; Fri, 20 Nov 2020 14:20:12 +0000 Received: by outflank-mailman (input) for mailman id 32245; Fri, 20 Nov 2020 14:20:11 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kg7Gk-00011R-T9 for xen-devel@lists.xenproject.org; Fri, 20 Nov 2020 14:20:11 +0000 Received: from esa3.hc3370-68.iphmx.com (unknown [216.71.145.155]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 833713cc-579f-47d7-adad-50e4ed289afa; Fri, 20 Nov 2020 14:20:09 +0000 (UTC) Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kg7Gk-00011R-T9 for xen-devel@lists.xenproject.org; Fri, 20 Nov 2020 14:20:11 +0000 Received: from esa3.hc3370-68.iphmx.com (unknown [216.71.145.155]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 833713cc-579f-47d7-adad-50e4ed289afa; Fri, 20 Nov 2020 14:20:09 +0000 (UTC) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 833713cc-579f-47d7-adad-50e4ed289afa DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1605882010; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=Fqba70I57e6KRrSTc8lVRghlr06RGYUwzyNMoEC4v8Y=; b=Z4PzhSIDGE/AMt32gSoV7HlAuSG5Xm3e0wOnU4I8FVTPi12zetvTJF3m W+SXET0voXtIZM3nt2lDBnRc3OS7xEfDUe/8p+R2XDoEV2QVrE1U8h6OX mPvgAf0k4jrDOz+HHE/qtw+7D2KGIxYGqWhSKSLuIKQ3fZTvK4wVvP4Hs g=; Authentication-Results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: taekLhPy/xegJpCbbLPyk0QWtVOnZwIfwsiNlhu2OfMVLSXLqzx/pXa8cI92Mx38J22Qa29FSJ zQ+KKU3POUHpMHwzkK4erpHOfiHDGsS1tiTNXcF54wATgu9yKvBLCojlZj5aIgtj8H8xF/RmJj 4Vy2WTa0sm4SHpomNJi1RoHWgSYqhVQKhHMjSduwfNPa5NqQ56MnXNJtqXrG4LL9u0kSz7o0LA EcFvQHFU+DmcKInwmYz25u9sy3ZNSADKFrdzQmIUD2t7+v1Bx3kaXpX0d+PqGKjKFRK2AgMB9o wGs= X-SBRS: None X-MesageID: 31588333 X-Ironport-Server: esa3.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.78,356,1599537600"; d="scan'208";a="31588333" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , Wei Liu , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Paul Durrant Subject: [PATCH] amd-iommu: Fix Guest CR3 Table following c/s 3a7947b6901 Date: Fri, 20 Nov 2020 14:19:51 +0000 Message-ID: <20201120141951.13742-1-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) "amd-iommu: use a bitfield for DTE" renamed iommu_dte_set_guest_cr3()'s gcr3 parameter to gcr3_mfn but ended up with an off-by-PAGE_SIZE error when extracting bits from the address. First of all, get_guest_cr3_from_dte() and iommu_dte_set_guest_cr3() are (almost) getters and setters for the same field, so should live togethe= r. Rename them to dte_{get,set}_gcr3_table() to specifically avoid 'guest_cr3'= in the name. This field actually points to a table in memory containing an ar= ray of guest CR3 values. As these functions are used for different logical indirections, they shouldn't use gfn/mfn terminology for their parameters. Switch them to use straight uint64_t full addresses. Fixes: 3a7947b6901 ("amd-iommu: use a bitfield for DTE") Signed-off-by: Andrew Cooper Acked-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monn=C3=A9 CC: Paul Durrant Rebase over several years worth of changes. This code is unreachable, so completely untestable, but I think the end res= ult is better than it was previously. --- xen/drivers/passthrough/amd/iommu.h | 2 -- xen/drivers/passthrough/amd/iommu_guest.c | 36 +++++++++++++++++++++++++++= ---- xen/drivers/passthrough/amd/iommu_map.c | 21 ------------------ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/xen/drivers/passthrough/amd/iommu.h b/xen/drivers/passthrough/= amd/iommu.h index 28a44ceb85..ad089cb095 100644 --- a/xen/drivers/passthrough/amd/iommu.h +++ b/xen/drivers/passthrough/amd/iommu.h @@ -246,8 +246,6 @@ void amd_iommu_set_root_page_table(struct amd_iommu_dte= *dte, uint8_t paging_mode, bool valid); void iommu_dte_add_device_entry(struct amd_iommu_dte *dte, const struct ivrs_mappings *ivrs_dev); -void iommu_dte_set_guest_cr3(struct amd_iommu_dte *dte, uint16_t dom_id, - uint64_t gcr3_mfn, bool gv, uint8_t glx); =20 /* send cmd to iommu */ void amd_iommu_flush_all_pages(struct domain *d); diff --git a/xen/drivers/passthrough/amd/iommu_guest.c b/xen/drivers/passth= rough/amd/iommu_guest.c index 2a3def9a5d..00c5ccd7b5 100644 --- a/xen/drivers/passthrough/amd/iommu_guest.c +++ b/xen/drivers/passthrough/amd/iommu_guest.c @@ -68,11 +68,39 @@ static void guest_iommu_disable(struct guest_iommu *iom= mu) iommu->enabled =3D 0; } =20 -static uint64_t get_guest_cr3_from_dte(struct amd_iommu_dte *dte) +/* + * The Guest CR3 Table is a table written by the guest kernel, pointing at + * gCR3 values for PASID transactions to use. The Device Table Entry poin= ts + * at a system physical address. + * + * However, these helpers deliberately use untyped parameters without + * reference to gfn/mfn because they are used both for programming the real + * IOMMU, and interpreting a guests programming of its vIOMMU. + */ +static uint64_t dte_get_gcr3_table(const struct amd_iommu_dte *dte) { return (((uint64_t)dte->gcr3_trp_51_31 << 31) | (dte->gcr3_trp_30_15 << 15) | - (dte->gcr3_trp_14_12 << 12)) >> PAGE_SHIFT; + (dte->gcr3_trp_14_12 << 12)); +} + +static void dte_set_gcr3_table(struct amd_iommu_dte *dte, uint16_t dom_id, + uint64_t addr, bool gv, uint8_t glx) +{ +#define GCR3_MASK(hi, lo) (((1ul << ((hi) + 1)) - 1) & ~((1ul << (lo)) - 1= )) + + /* I bit must be set when gcr3 is enabled */ + dte->i =3D true; + + dte->gcr3_trp_14_12 =3D MASK_EXTR(addr, GCR3_MASK(14, 12)); + dte->gcr3_trp_30_15 =3D MASK_EXTR(addr, GCR3_MASK(30, 15)); + dte->gcr3_trp_51_31 =3D MASK_EXTR(addr, GCR3_MASK(51, 31)); + + dte->domain_id =3D dom_id; + dte->glx =3D glx; + dte->gv =3D gv; + +#undef GCR3_MASK } =20 static unsigned int host_domid(struct domain *d, uint64_t g_domid) @@ -389,7 +417,7 @@ static int do_invalidate_dte(struct domain *d, cmd_entr= y_t *cmd) gdte =3D &dte_base[gbdf % (PAGE_SIZE / sizeof(struct amd_iommu_dte))]; =20 gdom_id =3D gdte->domain_id; - gcr3_gfn =3D get_guest_cr3_from_dte(gdte); + gcr3_gfn =3D dte_get_gcr3_table(gdte) >> PAGE_SHIFT; glx =3D gdte->glx; gv =3D gdte->gv; =20 @@ -419,7 +447,7 @@ static int do_invalidate_dte(struct domain *d, cmd_entr= y_t *cmd) mdte =3D &dte_base[req_id]; =20 spin_lock_irqsave(&iommu->lock, flags); - iommu_dte_set_guest_cr3(mdte, hdom_id, gcr3_mfn, gv, glx); + dte_set_gcr3_table(mdte, hdom_id, gcr3_mfn << PAGE_SHIFT, gv, glx); =20 amd_iommu_flush_device(iommu, req_id); spin_unlock_irqrestore(&iommu->lock, flags); diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthro= ugh/amd/iommu_map.c index f773ab33fd..d3a8b1aec7 100644 --- a/xen/drivers/passthrough/amd/iommu_map.c +++ b/xen/drivers/passthrough/amd/iommu_map.c @@ -173,27 +173,6 @@ void __init iommu_dte_add_device_entry(struct amd_iomm= u_dte *dte, }; } =20 -void iommu_dte_set_guest_cr3(struct amd_iommu_dte *dte, uint16_t dom_id, - uint64_t gcr3_mfn, bool gv, uint8_t glx) -{ -#define GCR3_MASK(hi, lo) (((1ul << ((hi) + 1)) - 1) & ~((1ul << (lo)) - 1= )) -#define GCR3_SHIFT(lo) ((lo) - PAGE_SHIFT) - - /* I bit must be set when gcr3 is enabled */ - dte->i =3D true; - - dte->gcr3_trp_14_12 =3D (gcr3_mfn & GCR3_MASK(14, 12)) >> GCR3_SHIFT(1= 2); - dte->gcr3_trp_30_15 =3D (gcr3_mfn & GCR3_MASK(30, 15)) >> GCR3_SHIFT(1= 5); - dte->gcr3_trp_51_31 =3D (gcr3_mfn & GCR3_MASK(51, 31)) >> GCR3_SHIFT(3= 1); - - dte->domain_id =3D dom_id; - dte->glx =3D glx; - dte->gv =3D gv; - -#undef GCR3_SHIFT -#undef GCR3_MASK -} - /* Walk io page tables and build level page tables if necessary * {Re, un}mapping super page frames causes re-allocation of io * page tables. --=20 2.11.0