From patchwork Wed Aug 8 01:10:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 954756 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41lYHN6PZYz9s4V for ; Wed, 8 Aug 2018 11:11:12 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41lYHN355SzDqxs for ; Wed, 8 Aug 2018 11:11:12 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41lYHC6Q9HzDqC8 for ; Wed, 8 Aug 2018 11:11:03 +1000 (AEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w781Ap0D032527; Tue, 7 Aug 2018 20:10:52 -0500 Message-ID: Subject: [PATCH v2] fsi: sbefifo: Bump max command length From: Benjamin Herrenschmidt To: openbmc@lists.ozlabs.org Date: Wed, 08 Aug 2018 11:10:51 +1000 In-Reply-To: References: X-Mailer: Evolution 3.28.4 (3.28.4-1.fc28) Mime-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Eddie James Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Otherwise cronus putmem fails istep and BML fails to upload skiboot To do that, we still use our one-page command buffer for small commands for speed, and for anything bigger, with a limit of 1MB plus a page, we vmalloc a temporary buffer. The limit was chosen because Cronus will break up any data transfer into 1M chunks (the extra page is for the command header). Signed-off-by: Benjamin Herrenschmidt --- v2. Reduce max to 1MB + PAGE_SIZE which is enough for Cronus as it will break up transfers in 1MB chunks and we can make sure pdbg does the same. drivers/fsi/fsi-sbefifo.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c index f97ec3e4ddea..fd3b10527b68 100644 --- a/drivers/fsi/fsi-sbefifo.c +++ b/drivers/fsi/fsi-sbefifo.c @@ -30,6 +30,7 @@ #include #include #include +#include /* * The SBEFIFO is a pipe-like FSI device for communicating with @@ -110,7 +111,7 @@ enum sbe_state #define SBEFIFO_TIMEOUT_IN_RSP 1000 /* Other constants */ -#define SBEFIFO_MAX_CMD_LEN PAGE_SIZE +#define SBEFIFO_MAX_USER_CMD_LEN (0x100000 + PAGE_SIZE) #define SBEFIFO_RESET_MAGIC 0x52534554 /* "RSET" */ #define SBEFIFO_BENCH_MAGIC 0x424E4348 /* "BNCH" */ @@ -129,6 +130,7 @@ struct sbefifo { struct sbefifo_user { struct sbefifo *sbefifo; struct mutex file_lock; + void *cmd_page; void *pending_cmd; size_t pending_len; }; @@ -724,7 +726,7 @@ int sbefifo_submit(struct device *dev, const __be32 *command, size_t cmd_len, return -ENODEV; if (WARN_ON_ONCE(sbefifo->magic != SBEFIFO_MAGIC)) return -ENODEV; - if (!resp_len || !command || !response || cmd_len > SBEFIFO_MAX_CMD_LEN) + if (!resp_len || !command || !response) return -EINVAL; /* Prepare iov iterator */ @@ -760,8 +762,8 @@ static int sbefifo_user_open(struct inode *inode, struct file *file) file->private_data = user; user->sbefifo = sbefifo; - user->pending_cmd = (void *)__get_free_page(GFP_KERNEL); - if (!user->pending_cmd) { + user->cmd_page = (void *)__get_free_page(GFP_KERNEL); + if (!user->cmd_page) { kfree(user); return -ENOMEM; } @@ -814,6 +816,9 @@ static ssize_t sbefifo_user_read(struct file *file, char __user *buf, /* Extract the response length */ rc = len - iov_iter_count(&resp_iter); bail: + if (is_vmalloc_addr(user->pending_cmd)) + vfree(user->pending_cmd); + user->pending_cmd = NULL; user->pending_len = 0; mutex_unlock(&user->file_lock); return rc; @@ -859,13 +864,23 @@ static ssize_t sbefifo_user_write(struct file *file, const char __user *buf, if (!user) return -EINVAL; sbefifo = user->sbefifo; - if (len > SBEFIFO_MAX_CMD_LEN) + if (len > SBEFIFO_MAX_USER_CMD_LEN) return -EINVAL; if (len & 3) return -EINVAL; mutex_lock(&user->file_lock); + /* Can we use the pre-allocate buffer ? If not, allocate */ + if (len <= PAGE_SIZE) + user->pending_cmd = user->cmd_page; + else + user->pending_cmd = vmalloc(len); + if (!user->pending_cmd) { + rc = -ENOMEM; + goto bail; + } + /* Copy the command into the staging buffer */ if (copy_from_user(user->pending_cmd, buf, len)) { rc = -EFAULT; @@ -906,6 +921,11 @@ static ssize_t sbefifo_user_write(struct file *file, const char __user *buf, /* Update the staging buffer size */ user->pending_len = len; bail: + if (!user->pending_len) { + if (is_vmalloc_addr(user->pending_cmd)) + vfree(user->pending_cmd); + user->pending_cmd = NULL; + } mutex_unlock(&user->file_lock); /* And that's it, we'll issue the command on a read */ @@ -919,7 +939,9 @@ static int sbefifo_user_release(struct inode *inode, struct file *file) if (!user) return -EINVAL; - free_page((unsigned long)user->pending_cmd); + if (is_vmalloc_addr(user->pending_cmd)) + vfree(user->pending_cmd); + free_page((unsigned long)user->cmd_page); kfree(user); return 0;