From patchwork Tue Jun 16 14:14:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Roth X-Patchwork-Id: 280348 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.5 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2284DC433DF for ; Tue, 16 Jun 2020 14:32:09 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id E9E06208D5 for ; Tue, 16 Jun 2020 14:32:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="u5aeK+Pm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E9E06208D5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45966 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jlCdE-0008VF-5U for qemu-devel@archiver.kernel.org; Tue, 16 Jun 2020 10:32:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57476) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlCPb-00021m-7V; Tue, 16 Jun 2020 10:18:04 -0400 Received: from mail-ot1-x32b.google.com ([2607:f8b0:4864:20::32b]:40778) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jlCPY-0006d8-0K; Tue, 16 Jun 2020 10:18:02 -0400 Received: by mail-ot1-x32b.google.com with SMTP id s13so16031640otd.7; Tue, 16 Jun 2020 07:17:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=MMeIQIaUT9cFLFVfOZAfkWHwj7aINzLWQ4+zAStdY7k=; b=u5aeK+PmjI9Gh6dreGsRPcHI3c5ubwISbKAmqwykBXANPcUkOun2bcjWcOet6y8M6V 8iSsqC63b1wKEZmX3AA1SwinCY70Miv6tUsFPDpDqPVFYPfU2ax88gpUuIjqG6gtuWTY YFRXWVdm/HYMxI/c9kmD+MpuLtz+WMkTPA5lxO6zwkO3hZghXMXTCTpufe5A21lIsQJC i1577QENYx1OTzlImWQsn7NoWPY65SZQR568o3pBHnJyI+t3+E3L0Qs7x755afFDWyOy 1G+VGGNyFFFEkqJ7VComtmF9i+WUixvwQmk+fXH84EAWofaRW9zhlqKaivZK4Q55VHzU hogQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=MMeIQIaUT9cFLFVfOZAfkWHwj7aINzLWQ4+zAStdY7k=; b=jVx734r/qMw0KL4ybeHSbJDdFM+w8zzJDdZFzvHFOp0Y6ymICTaqDP/nYxWQ9Nzo1E OolnfM8ycUCiRVPvN5l60QQsS1C/WrZZhMHGdZK5shhtBe14Lv/GJZiHsa9LohzPEpCe 7O3M5+IvzO9iPn4k3bnXus/eQkpgaYYhS8AGAifQNS44Lx2dwrqhqOzLeYth6EqQbBns 2jVmTtyJkfvfOnBAHowAjZx40LaJmZMlEvjnep8Bv5iXckGfG1DnTHwKh5rOofaJ5eT6 LSgOe73X4zHVUKBMPeAmCScbo1lccYwvWzR7Q3oGfAGm08p2a+tI+IDYsUKcOJd4emGk Gh2w== X-Gm-Message-State: AOAM531wAQwOS9BsCFYGjXZRCLbv5CjDj8eGjieu3paWWEMvksqTx6Bt pR69oKTFVoZ7Ho6znvQb00+GwB9a X-Google-Smtp-Source: ABdhPJyFoyihSpa1xCN5LGq4WjvgfluazLwKf9W0ZySOJyJld+CoB05Y/z2P3ApLNKd8qK6MGHtLDg== X-Received: by 2002:a9d:4602:: with SMTP id y2mr2629775ote.199.1592317078117; Tue, 16 Jun 2020 07:17:58 -0700 (PDT) Received: from localhost (76-251-165-188.lightspeed.austtx.sbcglobal.net. [76.251.165.188]) by smtp.gmail.com with ESMTPSA id s67sm4060121oif.0.2020.06.16.07.17.57 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 16 Jun 2020 07:17:57 -0700 (PDT) From: Michael Roth To: qemu-devel@nongnu.org Subject: [PATCH 24/78] intel_iommu: add present bit check for pasid table entries Date: Tue, 16 Jun 2020 09:14:53 -0500 Message-Id: <20200616141547.24664-25-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200616141547.24664-1-mdroth@linux.vnet.ibm.com> References: <20200616141547.24664-1-mdroth@linux.vnet.ibm.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::32b; envelope-from=flukshun@gmail.com; helo=mail-ot1-x32b.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: 0 X-Spam_score: 0.0 X-Spam_bar: / X-Spam_report: (0.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=1, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Tian , Jacob Pan , Yi Sun , "Michael S . Tsirkin" , qemu-stable@nongnu.org, Peter Xu , Liu Yi L Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Liu Yi L The present bit check for pasid entry (pe) and pasid directory entry (pdire) were missed in previous commits as fpd bit check doesn't require present bit as "Set". This patch adds the present bit check for callers which wants to get a valid pe/pdire. Cc: qemu-stable@nongnu.org Cc: Kevin Tian Cc: Jacob Pan Cc: Peter Xu Cc: Yi Sun Reviewed-by: Peter Xu Signed-off-by: Liu Yi L Message-Id: <1578058086-4288-3-git-send-email-yi.l.liu@intel.com> Reviewed-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin (cherry picked from commit 56fc1e6ac6bde95bc0369d358587f2234d4dddad) Signed-off-by: Michael Roth --- hw/i386/intel_iommu.c | 92 +++++++++++++++++++++++++++------- hw/i386/intel_iommu_internal.h | 1 + 2 files changed, 74 insertions(+), 19 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 00ebae4863..bfe8edb0ce 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -686,9 +686,18 @@ static inline bool vtd_pe_type_check(X86IOMMUState *x86_iommu, return true; } -static int vtd_get_pasid_dire(dma_addr_t pasid_dir_base, - uint32_t pasid, - VTDPASIDDirEntry *pdire) +static inline bool vtd_pdire_present(VTDPASIDDirEntry *pdire) +{ + return pdire->val & 1; +} + +/** + * Caller of this function should check present bit if wants + * to use pdir entry for futher usage except for fpd bit check. + */ +static int vtd_get_pdire_from_pdir_table(dma_addr_t pasid_dir_base, + uint32_t pasid, + VTDPASIDDirEntry *pdire) { uint32_t index; dma_addr_t addr, entry_size; @@ -703,18 +712,22 @@ static int vtd_get_pasid_dire(dma_addr_t pasid_dir_base, return 0; } -static int vtd_get_pasid_entry(IntelIOMMUState *s, - uint32_t pasid, - VTDPASIDDirEntry *pdire, - VTDPASIDEntry *pe) +static inline bool vtd_pe_present(VTDPASIDEntry *pe) +{ + return pe->val[0] & VTD_PASID_ENTRY_P; +} + +static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, + uint32_t pasid, + dma_addr_t addr, + VTDPASIDEntry *pe) { uint32_t index; - dma_addr_t addr, entry_size; + dma_addr_t entry_size; X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s); index = VTD_PASID_TABLE_INDEX(pasid); entry_size = VTD_PASID_ENTRY_SIZE; - addr = pdire->val & VTD_PASID_TABLE_BASE_ADDR_MASK; addr = addr + index * entry_size; if (dma_memory_read(&address_space_memory, addr, pe, entry_size)) { return -VTD_FR_PASID_TABLE_INV; @@ -732,25 +745,54 @@ static int vtd_get_pasid_entry(IntelIOMMUState *s, return 0; } -static int vtd_get_pasid_entry_from_pasid(IntelIOMMUState *s, - dma_addr_t pasid_dir_base, - uint32_t pasid, - VTDPASIDEntry *pe) +/** + * Caller of this function should check present bit if wants + * to use pasid entry for futher usage except for fpd bit check. + */ +static int vtd_get_pe_from_pdire(IntelIOMMUState *s, + uint32_t pasid, + VTDPASIDDirEntry *pdire, + VTDPASIDEntry *pe) +{ + dma_addr_t addr = pdire->val & VTD_PASID_TABLE_BASE_ADDR_MASK; + + return vtd_get_pe_in_pasid_leaf_table(s, pasid, addr, pe); +} + +/** + * This function gets a pasid entry from a specified pasid + * table (includes dir and leaf table) with a specified pasid. + * Sanity check should be done to ensure return a present + * pasid entry to caller. + */ +static int vtd_get_pe_from_pasid_table(IntelIOMMUState *s, + dma_addr_t pasid_dir_base, + uint32_t pasid, + VTDPASIDEntry *pe) { int ret; VTDPASIDDirEntry pdire; - ret = vtd_get_pasid_dire(pasid_dir_base, pasid, &pdire); + ret = vtd_get_pdire_from_pdir_table(pasid_dir_base, + pasid, &pdire); if (ret) { return ret; } - ret = vtd_get_pasid_entry(s, pasid, &pdire, pe); + if (!vtd_pdire_present(&pdire)) { + return -VTD_FR_PASID_TABLE_INV; + } + + ret = vtd_get_pe_from_pdire(s, pasid, &pdire, pe); if (ret) { return ret; } - return ret; + if (!vtd_pe_present(pe)) { + return -VTD_FR_PASID_TABLE_INV; + } + + return 0; } static int vtd_ce_get_rid2pasid_entry(IntelIOMMUState *s, @@ -763,7 +805,7 @@ static int vtd_ce_get_rid2pasid_entry(IntelIOMMUState *s, pasid = VTD_CE_GET_RID2PASID(ce); pasid_dir_base = VTD_CE_GET_PASID_DIR_TABLE(ce); - ret = vtd_get_pasid_entry_from_pasid(s, pasid_dir_base, pasid, pe); + ret = vtd_get_pe_from_pasid_table(s, pasid_dir_base, pasid, pe); return ret; } @@ -781,7 +823,11 @@ static int vtd_ce_get_pasid_fpd(IntelIOMMUState *s, pasid = VTD_CE_GET_RID2PASID(ce); pasid_dir_base = VTD_CE_GET_PASID_DIR_TABLE(ce); - ret = vtd_get_pasid_dire(pasid_dir_base, pasid, &pdire); + /* + * No present bit check since fpd is meaningful even + * if the present bit is clear. + */ + ret = vtd_get_pdire_from_pdir_table(pasid_dir_base, pasid, &pdire); if (ret) { return ret; } @@ -791,7 +837,15 @@ static int vtd_ce_get_pasid_fpd(IntelIOMMUState *s, return 0; } - ret = vtd_get_pasid_entry(s, pasid, &pdire, &pe); + if (!vtd_pdire_present(&pdire)) { + return -VTD_FR_PASID_TABLE_INV; + } + + /* + * No present bit check since fpd is meaningful even + * if the present bit is clear. + */ + ret = vtd_get_pe_from_pdire(s, pasid, &pdire, &pe); if (ret) { return ret; } diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index edcf9fc9bb..862033ebe6 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -479,6 +479,7 @@ typedef struct VTDRootEntry VTDRootEntry; #define VTD_PASID_ENTRY_FPD (1ULL << 1) /* Fault Processing Disable */ /* PASID Granular Translation Type Mask */ +#define VTD_PASID_ENTRY_P 1ULL #define VTD_SM_PASID_ENTRY_PGTT (7ULL << 6) #define VTD_SM_PASID_ENTRY_FLT (1ULL << 6) #define VTD_SM_PASID_ENTRY_SLT (2ULL << 6)