From patchwork Thu Jul 10 21:50:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oded Gabbay X-Patchwork-Id: 4528761 Return-Path: X-Original-To: patchwork-dri-devel@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 62BF99F3B4 for ; Thu, 10 Jul 2014 23:34:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3EFF7201F4 for ; Thu, 10 Jul 2014 23:34:24 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 5105C201B4 for ; Thu, 10 Jul 2014 23:34:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 59CF16E7C3; Thu, 10 Jul 2014 16:33:26 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wi0-f169.google.com (mail-wi0-f169.google.com [209.85.212.169]) by gabe.freedesktop.org (Postfix) with ESMTP id D6EA76E163 for ; Thu, 10 Jul 2014 14:51:27 -0700 (PDT) Received: by mail-wi0-f169.google.com with SMTP id hi2so5150449wib.4 for ; Thu, 10 Jul 2014 14:51:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BxVKDfC/pr2MzdIPstlrRIw2oscc3CTI/Av7Otxi9Bc=; b=QkAlUy13vJiPDm4Rl+Rx7CebustJqxqwvkGnm3kZmCvgo6e7fJkEpNbvdEI3kXYWF9 UJpkA/Zr4975J1dKVZq1YAiDJNF4e+ebOyY1KfFvHx9/80Vi3jgerzlcpT5kiLlewtie EYL6ziTcqvs9BH251IzWKb6iGHRRhuU53KU9kLEQtRSK3trYii+MmBHt2evwBQxX0U++ 7OIUl+9y/R5zM+NLRAa/uksGHE2fUwJ0Xbsk2otIhGCv1TrNRzbdubonNyTuElmolcIV UeQsdYrDleKCqfaYNlLCRbns8P73UIQX7Rs7UrRzbEFfemZGJx+TVfii3j+NxG9seEXt ue+w== X-Received: by 10.180.13.230 with SMTP id k6mr22444206wic.1.1405029085905; Thu, 10 Jul 2014 14:51:25 -0700 (PDT) Received: from localhost.localdomain ([77.127.59.49]) by mx.google.com with ESMTPSA id n2sm805353wjf.40.2014.07.10.14.51.23 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 10 Jul 2014 14:51:25 -0700 (PDT) From: Oded Gabbay X-Google-Original-From: Oded Gabbay To: David Airlie , Alex Deucher , Jerome Glisse Subject: [PATCH 12/83] hsa/radeon: Add kfd mmap handler Date: Fri, 11 Jul 2014 00:50:12 +0300 Message-Id: <1405029027-6085-11-git-send-email-oded.gabbay@amd.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1405029027-6085-1-git-send-email-oded.gabbay@amd.com> References: <1405029027-6085-1-git-send-email-oded.gabbay@amd.com> X-Mailman-Approved-At: Thu, 10 Jul 2014 16:33:12 -0700 Cc: Andrew Lewycky , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.0 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_WEB, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds the kfd mmap handler that maps the physical address of a doorbell page to a user-space virtual address. That virtual address belongs to the process that uses the doorbell page. This mmap handler is called only from within the kernel and not to be called from user-mode mmap of /dev/kfd. Signed-off-by: Oded Gabbay --- drivers/gpu/hsa/radeon/kfd_chardev.c | 20 +++++++++ drivers/gpu/hsa/radeon/kfd_doorbell.c | 85 +++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/drivers/gpu/hsa/radeon/kfd_chardev.c b/drivers/gpu/hsa/radeon/kfd_chardev.c index 7a56a8f..0b5bc74 100644 --- a/drivers/gpu/hsa/radeon/kfd_chardev.c +++ b/drivers/gpu/hsa/radeon/kfd_chardev.c @@ -39,6 +39,7 @@ static const struct file_operations kfd_fops = { .owner = THIS_MODULE, .unlocked_ioctl = kfd_ioctl, .open = kfd_open, + .mmap = kfd_mmap, }; static int kfd_char_dev_major = -1; @@ -131,3 +132,22 @@ kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) return err; } + +static int +kfd_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long pgoff = vma->vm_pgoff; + struct kfd_process *process; + + process = radeon_kfd_get_process(current); + if (IS_ERR(process)) + return PTR_ERR(process); + + if (pgoff < KFD_MMAP_DOORBELL_START) + return -EINVAL; + + if (pgoff < KFD_MMAP_DOORBELL_END) + return radeon_kfd_doorbell_mmap(process, vma); + + return -EINVAL; +} diff --git a/drivers/gpu/hsa/radeon/kfd_doorbell.c b/drivers/gpu/hsa/radeon/kfd_doorbell.c index 79a9d4b..e1d8506 100644 --- a/drivers/gpu/hsa/radeon/kfd_doorbell.c +++ b/drivers/gpu/hsa/radeon/kfd_doorbell.c @@ -70,3 +70,88 @@ void radeon_kfd_doorbell_init(struct kfd_dev *kfd) kfd->doorbell_process_limit = doorbell_process_limit; } +/* This is the /dev/kfd mmap (for doorbell) implementation. We intend that this is only called through map_doorbells, +** not through user-mode mmap of /dev/kfd. */ +int radeon_kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma) +{ + unsigned int device_index; + struct kfd_dev *dev; + phys_addr_t start; + + BUG_ON(vma->vm_pgoff < KFD_MMAP_DOORBELL_START || vma->vm_pgoff >= KFD_MMAP_DOORBELL_END); + + /* For simplicitly we only allow mapping of the entire doorbell allocation of a single device & process. */ + if (vma->vm_end - vma->vm_start != doorbell_process_allocation()) + return -EINVAL; + + /* device_index must be GPU ID!! */ + device_index = vma->vm_pgoff - KFD_MMAP_DOORBELL_START; + + dev = radeon_kfd_device_by_id(device_index); + if (dev == NULL) + return -EINVAL; + + vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | VM_DONTDUMP | VM_PFNMAP; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + start = dev->doorbell_base + process->pasid * doorbell_process_allocation(); + + pr_debug("kfd: mapping doorbell page in radeon_kfd_doorbell_mmap\n" + " target user address == 0x%016llX\n" + " physical address == 0x%016llX\n" + " vm_flags == 0x%08lX\n" + " size == 0x%08lX\n", + (long long unsigned int) vma->vm_start, start, vma->vm_flags, + doorbell_process_allocation()); + + return io_remap_pfn_range(vma, + vma->vm_start, + start >> PAGE_SHIFT, + doorbell_process_allocation(), + vma->vm_page_prot); +} + +/* Map the doorbells for a single process & device. This will indirectly call radeon_kfd_doorbell_mmap. +** This assumes that the process mutex is being held. */ +static int +map_doorbells(struct file *devkfd, struct kfd_process *process, struct kfd_dev *dev) +{ + struct kfd_process_device *pdd = radeon_kfd_get_process_device_data(dev, process); + + if (pdd == NULL) + return -ENOMEM; + + if (pdd->doorbell_mapping == NULL) { + unsigned long offset = (KFD_MMAP_DOORBELL_START + dev->id) << PAGE_SHIFT; + doorbell_t __user *doorbell_mapping; + + doorbell_mapping = (doorbell_t __user *)vm_mmap(devkfd, 0, doorbell_process_allocation(), PROT_WRITE, + MAP_SHARED, offset); + if (IS_ERR(doorbell_mapping)) + return PTR_ERR(doorbell_mapping); + + pdd->doorbell_mapping = doorbell_mapping; + } + + return 0; +} + +/* Get the user-mode address of a doorbell. Assumes that the process mutex is being held. */ +doorbell_t __user *radeon_kfd_get_doorbell(struct file *devkfd, struct kfd_process *process, struct kfd_dev *dev, + unsigned int doorbell_index) +{ + struct kfd_process_device *pdd; + int err; + + BUG_ON(doorbell_index > MAX_DOORBELL_INDEX); + + err = map_doorbells(devkfd, process, dev); + if (err) + return ERR_PTR(err); + + pdd = radeon_kfd_get_process_device_data(dev, process); + BUG_ON(pdd == NULL); /* map_doorbells would have failed otherwise */ + + return &pdd->doorbell_mapping[doorbell_index]; +} +