From patchwork Wed May 29 13:52:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timo Aaltonen X-Patchwork-Id: 1107159 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ubuntu.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45DXG65pt0z9s3l; Wed, 29 May 2019 23:52:30 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hVz0D-00072x-7n; Wed, 29 May 2019 13:52:25 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1hVz0B-00072l-LX for kernel-team@lists.ubuntu.com; Wed, 29 May 2019 13:52:23 +0000 Received: from kryptik.nebulazone.fi ([83.145.237.38] helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1hVz0B-0006YJ-9h for kernel-team@lists.ubuntu.com; Wed, 29 May 2019 13:52:23 +0000 From: Timo Aaltonen To: kernel-team@lists.ubuntu.com Subject: [PATCH 1/1] drm/i915/gvt: Fix mmap range check Date: Wed, 29 May 2019 16:52:21 +0300 Message-Id: <20190529135221.4819-2-tjaalton@ubuntu.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190529135221.4819-1-tjaalton@ubuntu.com> References: <20190529135221.4819-1-tjaalton@ubuntu.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Zhenyu Wang This is to fix missed mmap range check on vGPU bar2 region and only allow to map vGPU allocated GMADDR range, which means user space should support sparse mmap to get proper offset for mmap vGPU aperture. And this takes care of actual pgoff in mmap request as original code always does from beginning of vGPU aperture. Fixes: 659643f7d814 ("drm/i915/gvt/kvmgt: add vfio/mdev support to KVMGT") Cc: "Monroy, Rodrigo Axel" Cc: "Orrala Contreras, Alfredo" Cc: stable@vger.kernel.org # v4.10+ Reviewed-by: Hang Yuan Signed-off-by: Zhenyu Wang CVE-2019-11085 (cherry picked from commit 51b00d8509dc69c98740da2ad07308b630d3eb7d) Signed-off-by: Timo Aaltonen Acked-by: Kleber Sacilotto de Souza Acked-by: Tyler Hicks --- drivers/gpu/drm/i915/gvt/kvmgt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 14dce5c201d5..8f23d1f064c6 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -940,7 +940,7 @@ static int intel_vgpu_mmap(struct mdev_device *mdev, struct vm_area_struct *vma) { unsigned int index; u64 virtaddr; - unsigned long req_size, pgoff = 0; + unsigned long req_size, pgoff, req_start; pgprot_t pg_prot; struct intel_vgpu *vgpu = mdev_get_drvdata(mdev); @@ -958,7 +958,17 @@ static int intel_vgpu_mmap(struct mdev_device *mdev, struct vm_area_struct *vma) pg_prot = vma->vm_page_prot; virtaddr = vma->vm_start; req_size = vma->vm_end - vma->vm_start; - pgoff = vgpu_aperture_pa_base(vgpu) >> PAGE_SHIFT; + pgoff = vma->vm_pgoff & + ((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1); + req_start = pgoff << PAGE_SHIFT; + + if (!intel_vgpu_in_aperture(vgpu, req_start)) + return -EINVAL; + if (req_start + req_size > + vgpu_aperture_offset(vgpu) + vgpu_aperture_sz(vgpu)) + return -EINVAL; + + pgoff = (gvt_aperture_pa_base(vgpu->gvt) >> PAGE_SHIFT) + pgoff; return remap_pfn_range(vma, virtaddr, pgoff, req_size, pg_prot); } From patchwork Tue Jun 11 08:33:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Righi X-Patchwork-Id: 1113576 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45NNb339g4z9sBp; Tue, 11 Jun 2019 18:34:23 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hacEV-0002LB-L5; Tue, 11 Jun 2019 08:34:19 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1hacET-0002Jr-4d for kernel-team@lists.ubuntu.com; Tue, 11 Jun 2019 08:34:17 +0000 Received: from mail-wm1-f72.google.com ([209.85.128.72]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1hacES-00044U-Qp for kernel-team@lists.ubuntu.com; Tue, 11 Jun 2019 08:34:16 +0000 Received: by mail-wm1-f72.google.com with SMTP id o127so324447wmo.0 for ; Tue, 11 Jun 2019 01:34:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/XmTtIzadqZlXmJtxJqfOpE0AuAIrIKVnr+5ogq7zs0=; b=EM1bouenAo0F2nfLeZhODWLQk+V3seAMtz481eOaP43pM3ayB4h8xwe7pJBos5LTy0 n3D/g+z+fxV0DVoZCFCzOJgJ30s2uIks96A0p0kTothZoGqbPrh+KWdymw3L2vZj1LLL vHGpQrhampDD3u1OOeWnu0nESI59B6QtfHZPqsAnellj6/lS0GcrrdIewH0p7nRXZ0mx Z+EYqQbXaU4ZtKP/k7bdl2MeFDcbZEF07JZ2sMD7xmzVaSTRanUvflP1Kd39C7g028MG jojQoaOiio30WdmB+PR8zQIC8qqtnHI/V57LpnxkwLaBzPvF4MryvKidokkmnbvATYmQ 2Q+w== X-Gm-Message-State: APjAAAX/EIVpooFddXGjdzcnaUaoE9uIuOodWrD1Ld7zOP6vZtHYyrFO ta0MoPuot7Pvh/+WE2w3JNoH1Kvo0niaJgCQu6YIh6i8CumvFW/rm2ReERfMoj9LYGfEex/sbiK u1L4e/pZxM9DfbXIwekQiH3weTVogltpXgx1Ckn6p4w== X-Received: by 2002:a5d:5702:: with SMTP id a2mr4048820wrv.89.1560242056295; Tue, 11 Jun 2019 01:34:16 -0700 (PDT) X-Google-Smtp-Source: APXvYqxEmjkHXy4T2THR89i6JuDa50crR/NkdCFerMKQs8EeQjDFAjVD8KxShOmLRZdO/VwiYQiZ+g== X-Received: by 2002:a5d:5702:: with SMTP id a2mr4048795wrv.89.1560242056049; Tue, 11 Jun 2019 01:34:16 -0700 (PDT) Received: from xps-13.homenet.telecomitalia.it (host224-133-dynamic.10-87-r.retail.telecomitalia.it. [87.10.133.224]) by smtp.gmail.com with ESMTPSA id t140sm1925402wmt.0.2019.06.11.01.34.15 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 11 Jun 2019 01:34:15 -0700 (PDT) From: Andrea Righi To: Timo Aaltonen Subject: [PATCH 2/2] drm/i915/gvt: Fix aperture read/write emulation when enable x-no-mmap=on Date: Tue, 11 Jun 2019 10:33:46 +0200 Message-Id: <20190611083346.22428-3-andrea.righi@canonical.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190611083346.22428-1-andrea.righi@canonical.com> References: <20190529135221.4819-1-tjaalton@ubuntu.com> <20190611083346.22428-1-andrea.righi@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kernel-team@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Changbin Du When add 'x-no-mmap=on' for vfio-pci option, aperture access in guest is emulated. But the vgpu_aperture_rw() function take wrong offset when do memcpy, since vgpu->gm.aperture_va is not the base of entire aperture. This mistake cause GPU command in guest get lost and so the seqno is not updated in engine HWSP. This patch fix this, and it also move the emulation code to kvmgt. Because only vfio need to emulate it. Put aperture rw to MMIO emulation path breaks assumptions in xengt. v2: Remove PAGE_ALIGN for size (zhenyu) CVE-2019-11085 Fixes: f090a00df9ec ("drm/i915/gvt: Add emulation for BAR2 (aperture) with normal file RW approach") Signed-off-by: Changbin Du Signed-off-by: Zhi Wang Signed-off-by: Rodrigo Vivi (backported from commit d480b28a41a628e356dbacfa1c9f6d05b9baf838) Signed-off-by: Andrea Righi --- drivers/gpu/drm/i915/gvt/cfg_space.c | 15 +--------- drivers/gpu/drm/i915/gvt/gvt.h | 1 - drivers/gpu/drm/i915/gvt/kvmgt.c | 36 +++++++++++++++++++++-- drivers/gpu/drm/i915/gvt/mmio.c | 44 ---------------------------- 4 files changed, 35 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index 4ce2e6bd0680..a992ed54809e 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -119,16 +119,6 @@ static int map_aperture(struct intel_vgpu *vgpu, bool map) if (map == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked) return 0; - if (map) { - vgpu->gm.aperture_va = memremap(aperture_pa, aperture_sz, - MEMREMAP_WC); - if (!vgpu->gm.aperture_va) - return -ENOMEM; - } else { - memunmap(vgpu->gm.aperture_va); - vgpu->gm.aperture_va = NULL; - } - val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_2]; if (val & PCI_BASE_ADDRESS_MEM_TYPE_64) val = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2); @@ -141,11 +131,8 @@ static int map_aperture(struct intel_vgpu *vgpu, bool map) aperture_pa >> PAGE_SHIFT, aperture_sz >> PAGE_SHIFT, map); - if (ret) { - memunmap(vgpu->gm.aperture_va); - vgpu->gm.aperture_va = NULL; + if (ret) return ret; - } vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked = map; return 0; diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 33af72acb6b2..0b07bdb70ba8 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -80,7 +80,6 @@ struct intel_gvt_device_info { struct intel_vgpu_gm { u64 aperture_sz; u64 hidden_sz; - void *aperture_va; struct drm_mm_node low_gm_node; struct drm_mm_node high_gm_node; }; diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 9d36a3c31062..81050b16c161 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -653,6 +653,39 @@ static int intel_vgpu_bar_rw(struct intel_vgpu *vgpu, int bar, uint64_t off, return ret; } +static inline bool intel_vgpu_in_aperture(struct intel_vgpu *vgpu, uint64_t off) +{ + return off >= vgpu_aperture_offset(vgpu) && + off < vgpu_aperture_offset(vgpu) + vgpu_aperture_sz(vgpu); +} + +static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t off, + void *buf, unsigned long count, bool is_write) +{ + void *aperture_va; + + if (!intel_vgpu_in_aperture(vgpu, off) || + !intel_vgpu_in_aperture(vgpu, off + count)) { + gvt_vgpu_err("Invalid aperture offset %llu\n", off); + return -EINVAL; + } + + aperture_va = io_mapping_map_wc(&vgpu->gvt->dev_priv->ggtt.iomap, + ALIGN_DOWN(off, PAGE_SIZE), + count + offset_in_page(off)); + if (!aperture_va) + return -EIO; + + if (is_write) + memcpy(aperture_va + offset_in_page(off), buf, count); + else + memcpy(buf, aperture_va + offset_in_page(off), count); + + io_mapping_unmap(aperture_va); + + return 0; +} + static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, size_t count, loff_t *ppos, bool is_write) { @@ -681,8 +714,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, buf, count, is_write); break; case VFIO_PCI_BAR2_REGION_INDEX: - ret = intel_vgpu_bar_rw(vgpu, PCI_BASE_ADDRESS_2, pos, - buf, count, is_write); + ret = intel_vgpu_aperture_rw(vgpu, pos, buf, count, is_write); break; case VFIO_PCI_BAR1_REGION_INDEX: case VFIO_PCI_BAR3_REGION_INDEX: diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c index 1e1310f50289..45af3fc71a16 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.c +++ b/drivers/gpu/drm/i915/gvt/mmio.c @@ -56,38 +56,6 @@ int intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa) (reg >= gvt->device_info.gtt_start_offset \ && reg < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt)) -static bool vgpu_gpa_is_aperture(struct intel_vgpu *vgpu, uint64_t gpa) -{ - u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2); - u64 aperture_sz = vgpu_aperture_sz(vgpu); - - return gpa >= aperture_gpa && gpa < aperture_gpa + aperture_sz; -} - -static int vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t gpa, - void *pdata, unsigned int size, bool is_read) -{ - u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2); - u64 offset = gpa - aperture_gpa; - - if (!vgpu_gpa_is_aperture(vgpu, gpa + size - 1)) { - gvt_vgpu_err("Aperture rw out of range, offset %llx, size %d\n", - offset, size); - return -EINVAL; - } - - if (!vgpu->gm.aperture_va) { - gvt_vgpu_err("BAR is not enabled\n"); - return -ENXIO; - } - - if (is_read) - memcpy(pdata, vgpu->gm.aperture_va + offset, size); - else - memcpy(vgpu->gm.aperture_va + offset, pdata, size); - return 0; -} - static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa, void *p_data, unsigned int bytes, bool read) { @@ -164,12 +132,6 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa, } mutex_lock(&gvt->lock); - if (vgpu_gpa_is_aperture(vgpu, pa)) { - ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, true); - mutex_unlock(&gvt->lock); - return ret; - } - if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { struct intel_vgpu_guest_page *gp; @@ -261,12 +223,6 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa, mutex_lock(&gvt->lock); - if (vgpu_gpa_is_aperture(vgpu, pa)) { - ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, false); - mutex_unlock(&gvt->lock); - return ret; - } - if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { struct intel_vgpu_guest_page *gp;