From patchwork Fri Aug 2 19:51:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Herring X-Patchwork-Id: 170450 Delivered-To: patch@linaro.org Received: by 2002:a92:512:0:0:0:0:0 with SMTP id q18csp1223189ile; Fri, 2 Aug 2019 12:52:08 -0700 (PDT) X-Google-Smtp-Source: APXvYqwMjpTdKCqeRkjW6Gb/QGDfGYke61HpbZn8YCs+WQRiS268inCJ2DZ8kclF3HSjZuFlc0ON X-Received: by 2002:a63:4404:: with SMTP id r4mr123742024pga.245.1564775528237; Fri, 02 Aug 2019 12:52:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564775528; cv=none; d=google.com; s=arc-20160816; b=Qqw7v0ZmEQr2iIRchCOUszd7IO10vdFz1A6xvrBV8AyRkvYu5/BZ5+V1WtjoCpyZ8Y 9KeEsshhdMRzcVVD4qHScFfxwXVPqvk+S0q2SgzJGTf1IYkjLuP6zZqAOh0jlt4wdddn LI7lkGtJjDgq7NRphHObMBzYKRQng9tK64GF0Rk/VdI8wHyTPlL9uMT5jATz9hjIQswj V5fg8m/oa8ONdHPUxSiuX4ZOv5+3T/e0k+EvLxNNccjmow2AzmxH1We98Perg/7XExgD Z05i3rhpxZ8LUKka8WSDf/wrWubVNJdkJ7RXSuf0+9vlR1jUfDVHl+VxLZVXdq7OMFlz 0NWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:mime-version:references:in-reply-to:message-id:date :subject:to:from:delivered-to; bh=2OMkWvWucXvxkrKStU9S2WLgx992rjvei2VlSl6j6Yc=; b=LQfq+y/JmU5IyXD7Fg2IZZ4YbMuQqQqf6VJ83t6gyvImG+Pl3Q/xNmoZAng+YluAMl AJT9ywa/NDXRBxrjc0yEmDYE8aO4mTcclQF8OGz7DyG67IHVeEDJ/NFIE45Z3hbAOW6P YymSSAUPy/E5ZXA5YKvczpTr+4wbIXFnPzEUBv2KaTXZNQyC6oJYutXWIckX2X7EOFIg kQ3oE2o1k44N7QchkM5wgBZYCsSNCqxkXM/xx8Wyacj7XWWbHReKgWQPQyvC3m69CvwH 2Zknt04kjufSoIjiwe1ImjbfNIbYFbwnXPsvTFEmGltdfczqSvotcPkbLA7hexfn6WCe I1+A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [2610:10:20:722:a800:ff:fe36:1795]) by mx.google.com with ESMTPS id i21si28189557pgj.37.2019.08.02.12.52.07 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 02 Aug 2019 12:52:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) client-ip=2610:10:20:722:a800:ff:fe36:1795; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0AAD96EDD3; Fri, 2 Aug 2019 19:52:05 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-io1-f68.google.com (mail-io1-f68.google.com [209.85.166.68]) by gabe.freedesktop.org (Postfix) with ESMTPS id 41B266ED77 for ; Fri, 2 Aug 2019 19:52:00 +0000 (UTC) Received: by mail-io1-f68.google.com with SMTP id h6so29497737iom.7 for ; Fri, 02 Aug 2019 12:52:00 -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=0B7YsWfa7Gubc5+AucI1/YcPyBYyFfn+BChBWv9hC7o=; b=Duccol9b5qpWaWNe/O573sHH6zYAdV1pkLNDsKlGv3LTbLP8RpuzDLNGcuyxWM0vZt 1qbbxyWrzfBy2ewDV31ARXzHQFuDWU6Mtvn2mLBIJ4xOf9q8Hk9vs1RCz+R4LIuEmYhi q3aAdQ5+P4DaDbm1It41pSHbRXZqZRC/EBrc3+lv/BsAxE56lE2wI0RvdhPPO54Ih7QS 52PJ9bw4vKgzacxzZ86N7WtuA4OF52CqufBcQZwZOia+5wFoZIOf99ZQ1OYfkP6cnjQd JLQoO7rnsgk4yRDYphyUWlFLCEbLfM5ZK70WNmCDJ69Okc7dYLKIEhS6Kx2Pmgd/loUc ztKQ== X-Gm-Message-State: APjAAAVnEjB+IszK8Ybbzv+EP7om8pl94jvesnERrvB1mdEZVD58TJaF IT9Vl7Xh7eiLTEGRMFDUd7f3U60= X-Received: by 2002:a6b:ce19:: with SMTP id p25mr14425741iob.201.1564775518805; Fri, 02 Aug 2019 12:51:58 -0700 (PDT) Received: from xps15.herring.priv ([64.188.179.254]) by smtp.googlemail.com with ESMTPSA id s4sm98419934iop.25.2019.08.02.12.51.57 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Fri, 02 Aug 2019 12:51:58 -0700 (PDT) From: Rob Herring To: dri-devel@lists.freedesktop.org Subject: [PATCH v3 5/8] drm/panfrost: Add a no execute flag for BO allocations Date: Fri, 2 Aug 2019 13:51:47 -0600 Message-Id: <20190802195150.23207-6-robh@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190802195150.23207-1-robh@kernel.org> References: <20190802195150.23207-1-robh@kernel.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tomeu Vizoso , Maxime Ripard , Sean Paul , Steven Price , David Airlie , Boris Brezillon , Alyssa Rosenzweig , Robin Murphy Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Executable buffers have an alignment restriction that they can't cross 16MB boundary as the GPU program counter is 24-bits. This restriction is currently not handled and we just get lucky. As current userspace assumes all BOs are executable, that has to remain the default. So add a new PANFROST_BO_NOEXEC flag to allow userspace to indicate which BOs are not executable. There is also a restriction that executable buffers cannot start or end on a 4GB boundary. This is mostly avoided as there is only 4GB of space currently and the beginning is already blocked out for NULL ptr detection. Add support to handle this restriction fully regardless of the current constraints. For existing userspace, all created BOs remain executable, but the GPU VA alignment will be increased to the size of the BO. This shouldn't matter as there is plenty of GPU VA space. Cc: Tomeu Vizoso Cc: Boris Brezillon Cc: Robin Murphy Reviewed-by: Steven Price Acked-by: Alyssa Rosenzweig Signed-off-by: Rob Herring --- drivers/gpu/drm/panfrost/panfrost_drv.c | 30 ++++++++++++++++++++++++- drivers/gpu/drm/panfrost/panfrost_gem.c | 18 +++++++++++++-- drivers/gpu/drm/panfrost/panfrost_gem.h | 3 ++- drivers/gpu/drm/panfrost/panfrost_mmu.c | 3 +++ include/uapi/drm/panfrost_drm.h | 2 ++ 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index d354b92964d5..7ebd82d8d570 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -49,7 +49,8 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data, struct panfrost_gem_object *bo; struct drm_panfrost_create_bo *args = data; - if (!args->size || args->flags || args->pad) + if (!args->size || args->pad || + (args->flags & ~PANFROST_BO_NOEXEC)) return -EINVAL; bo = panfrost_gem_create_with_handle(file, dev, args->size, args->flags, @@ -367,6 +368,32 @@ static struct drm_driver panfrost_drm_driver = { .gem_prime_mmap = drm_gem_prime_mmap, }; +#define PFN_4G (SZ_4G >> PAGE_SHIFT) +#define PFN_4G_MASK (PFN_4G - 1) +#define PFN_16M (SZ_16M >> PAGE_SHIFT) + +static void panfrost_drm_mm_color_adjust(const struct drm_mm_node *node, + unsigned long color, + u64 *start, u64 *end) +{ + /* Executable buffers can't start or end on a 4GB boundary */ + if (!(color & PANFROST_BO_NOEXEC)) { + u64 next_seg; + + if ((*start & PFN_4G_MASK) == 0) + (*start)++; + + if ((*end & PFN_4G_MASK) == 0) + (*end)--; + + next_seg = ALIGN(*start, PFN_4G); + if (next_seg - *start <= PFN_16M) + *start = next_seg + 1; + + *end = min(*end, ALIGN(*start, PFN_4G) - 1); + } +} + static int panfrost_probe(struct platform_device *pdev) { struct panfrost_device *pfdev; @@ -394,6 +421,7 @@ static int panfrost_probe(struct platform_device *pdev) /* 4G enough for now. can be 48-bit */ drm_mm_init(&pfdev->mm, SZ_32M >> PAGE_SHIFT, (SZ_4G - SZ_32M) >> PAGE_SHIFT); + pfdev->mm.color_adjust = panfrost_drm_mm_color_adjust; pm_runtime_use_autosuspend(pfdev->dev); pm_runtime_set_autosuspend_delay(pfdev->dev, 50); /* ~3 frames */ diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index df70dcf3cb2f..63731f6c5223 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -66,11 +66,23 @@ static int panfrost_gem_map(struct panfrost_device *pfdev, struct panfrost_gem_o { int ret; size_t size = bo->base.base.size; - u64 align = size >= SZ_2M ? SZ_2M >> PAGE_SHIFT : 0; + u64 align; + unsigned long color = bo->noexec ? PANFROST_BO_NOEXEC : 0; + + /* + * Executable buffers cannot cross a 16MB boundary as the program + * counter is 24-bits. We assume executable buffers will be less than + * 16MB and aligning executable buffers to their size will avoid + * crossing a 16MB boundary. + */ + if (!bo->noexec) + align = size >> PAGE_SHIFT; + else + align = size >= SZ_2M ? SZ_2M >> PAGE_SHIFT : 0; spin_lock(&pfdev->mm_lock); ret = drm_mm_insert_node_generic(&pfdev->mm, &bo->node, - size >> PAGE_SHIFT, align, 0, 0); + size >> PAGE_SHIFT, align, color, 0); spin_unlock(&pfdev->mm_lock); if (ret) return ret; @@ -96,6 +108,7 @@ panfrost_gem_create_with_handle(struct drm_file *file_priv, return ERR_CAST(shmem); bo = to_panfrost_bo(&shmem->base); + bo->noexec = !!(flags & PANFROST_BO_NOEXEC); ret = panfrost_gem_map(pfdev, bo); if (ret) @@ -123,6 +136,7 @@ panfrost_gem_prime_import_sg_table(struct drm_device *dev, return ERR_CAST(obj); pobj = to_panfrost_bo(obj); + pobj->noexec = true; ret = panfrost_gem_map(pfdev, pobj); if (ret) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h index ce065270720b..132f02399b7b 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.h +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h @@ -11,7 +11,8 @@ struct panfrost_gem_object { struct drm_gem_shmem_object base; struct drm_mm_node node; - bool is_mapped; + bool is_mapped :1; + bool noexec :1; }; static inline diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index b4ac149b2399..eba6ce785ef0 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -190,6 +190,9 @@ int panfrost_mmu_map(struct panfrost_gem_object *bo) if (WARN_ON(bo->is_mapped)) return 0; + if (bo->noexec) + prot |= IOMMU_NOEXEC; + sgt = drm_gem_shmem_get_pages_sgt(obj); if (WARN_ON(IS_ERR(sgt))) return PTR_ERR(sgt); diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h index b5d370638846..17fb5d200f7a 100644 --- a/include/uapi/drm/panfrost_drm.h +++ b/include/uapi/drm/panfrost_drm.h @@ -82,6 +82,8 @@ struct drm_panfrost_wait_bo { __s64 timeout_ns; /* absolute */ }; +#define PANFROST_BO_NOEXEC 1 + /** * struct drm_panfrost_create_bo - ioctl argument for creating Panfrost BOs. *