From patchwork Fri Jun 28 22:23:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 2802611 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9209E9F245 for ; Fri, 28 Jun 2013 22:23:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 644272028F for ; Fri, 28 Jun 2013 22:23:00 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 7C87220286 for ; Fri, 28 Jun 2013 22:22:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 864EBE6726 for ; Fri, 28 Jun 2013 15:22:59 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from shiva.localdomain (unknown [209.20.75.48]) by gabe.freedesktop.org (Postfix) with ESMTP id 4916EE5FD7 for ; Fri, 28 Jun 2013 15:20:36 -0700 (PDT) Received: by shiva.localdomain (Postfix, from userid 99) id DD38A8864E; Fri, 28 Jun 2013 22:20:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from lundgren.kumite (c-24-21-100-90.hsd1.or.comcast.net [24.21.100.90]) by shiva.localdomain (Postfix) with ESMTPSA id EB69F88652; Fri, 28 Jun 2013 22:20:34 +0000 (UTC) From: Ben Widawsky To: Intel GFX Date: Fri, 28 Jun 2013 15:23:36 -0700 Message-Id: <1372458217-2053-6-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1372458217-2053-1-git-send-email-ben@bwidawsk.net> References: <1372458217-2053-1-git-send-email-ben@bwidawsk.net> Cc: Paul Berry , Ben Widawsky Subject: [Intel-gfx] [PATCH 5/6] drm/i915: Let userspace create a faultable pad page X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Virus-Scanned: ClamAV using ClamSMTP Whenever userspace allocates a BO, add one more page. On maps of this BO, make sure that last page will fault if accessed. We don't need to do this for the kernel, since our bugs should be fairly easy to catch already. The code could be optimized to allocate one less page for this, but it requires a lot of work to make that happen. Instead, do everything as we normally would, and clear out the last page after it's all done. NOTE: This does not convert previously allocated objects. Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 7 +++++++ drivers/gpu/drm/i915/i915_gem_gtt.c | 22 +++++++++++++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c9e38a6..3b2046b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1180,6 +1180,7 @@ typedef struct drm_i915_private { #define I915_DEBUG_NONE 0 #define I915_SCRATCH_FAULTS (1<<0) #define I915_SYNC_EXECBUF (1<<1) +#define I915_PAD_PAGE (1<<2) u64 debug_flags; } drm_i915_private_t; @@ -1307,6 +1308,7 @@ struct drm_i915_gem_object { unsigned int has_aliasing_ppgtt_mapping:1; unsigned int has_global_gtt_mapping:1; unsigned int has_dma_mapping:1; + unsigned int has_pad_page:1; struct sg_table *pages; int pages_pin_count; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c68b90f..f84aada 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -205,6 +205,7 @@ i915_gem_create(struct drm_file *file, uint64_t size, uint32_t *handle_p) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; int ret; u32 handle; @@ -213,11 +214,17 @@ i915_gem_create(struct drm_file *file, if (size == 0) return -EINVAL; + if (dev_priv->debug_flags & I915_PAD_PAGE) + size += PAGE_SIZE; + /* Allocate the new object */ obj = i915_gem_alloc_object(dev, size); if (obj == NULL) return -ENOMEM; + if (dev_priv->debug_flags & I915_PAD_PAGE) + obj->has_pad_page = 1; + ret = drm_gem_handle_create(file, &obj->base, &handle); if (ret) { drm_gem_object_release(&obj->base); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index f71636e..187738f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -43,6 +43,7 @@ #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) /* Use a pattern to make debug a bit easier */ #define GEN6_PTE_FAULT 0xbaddc0de +#define GEN6_PAD_PTE_FAULT 0x0c0ffee static gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, dma_addr_t addr, @@ -200,6 +201,9 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, if (unlikely(dev_priv->debug_flags & I915_SCRATCH_FAULTS)) scratch_pte = GEN6_PTE_FAULT; + if (unlikely(dev_priv->debug_flags & I915_PAD_PAGE)) + scratch_pte = GEN6_PAD_PTE_FAULT; + while (num_entries) { last_pte = first_pte + num_entries; if (last_pte > I915_PPGTT_PT_ENTRIES) @@ -385,9 +389,13 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_object *obj, enum i915_cache_level cache_level) { - ppgtt->insert_entries(ppgtt, obj->pages, - obj->gtt_space->start >> PAGE_SHIFT, - cache_level); + unsigned int first = obj->gtt_space->start >> PAGE_SHIFT; + + ppgtt->insert_entries(ppgtt, obj->pages, first, cache_level); + if (unlikely(obj->has_pad_page)) { + first += (obj->gtt_space->size >> PAGE_SHIFT) - 1; + ppgtt->clear_range(ppgtt, first, 1); + } } void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, @@ -529,6 +537,8 @@ static void gen6_ggtt_clear_range(struct drm_device *dev, I915_CACHE_LLC); if (unlikely(dev_priv->debug_flags & I915_SCRATCH_FAULTS)) scratch_pte = GEN6_PTE_FAULT; + if (unlikely(dev_priv->debug_flags & I915_PAD_PAGE)) + scratch_pte = GEN6_PAD_PTE_FAULT; for (i = 0; i < num_entries; i++) iowrite32(scratch_pte, >t_base[i]); readl(gtt_base); @@ -560,10 +570,15 @@ void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj, { struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + unsigned int first = obj->gtt_space->start >> PAGE_SHIFT; dev_priv->gtt.gtt_insert_entries(dev, obj->pages, obj->gtt_space->start >> PAGE_SHIFT, cache_level); + if (unlikely(obj->has_pad_page)) { + first += (obj->gtt_space->size >> PAGE_SHIFT) - 1; + dev_priv->gtt.gtt_clear_range(dev, first, 1); + } obj->has_global_gtt_mapping = 1; } @@ -632,6 +647,7 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long hole_start, hole_end; BUILD_BUG_ON(GEN6_PTE_FAULT & GEN6_PTE_VALID); + BUILD_BUG_ON(GEN6_PAD_PTE_FAULT & GEN6_PTE_VALID); BUG_ON(mappable_end > end); /* Subtract the guard page ... */