Skip to contentSkip to conversation

firmware: add partial read support in request_firmware_into_buf

PATCH Superseded Scott Branden 4 participants 16 messages Apr 20, 2020 – May 5, 2020

Subsystems (11)

v3 of 10 Superseded Latest is v10 →

lore
Share & tools
lore

Scott Branden

author maintainer
#0 lore raw

v3 cover firmware: add partial read support in request_firmware_into_buf

This patch series adds partial read support in request_firmware_into_buf. In order to accept the enhanced API it has been requested that kernel selftests and upstreamed driver utilize the API enhancement and so are included in this patch series.

Also in this patch series is the addition of a new Broadcom VK driver utilizing the new request_firmware_into_buf enhanced API.

Changes from v2:
- remove unnecessary code and mutex locks in lib/test_firmware.c
- remove VK_IOCTL_ACCESS_BAR support from driver and use pci sysfs instead
- remove bitfields
- remove Kconfig default m
- adjust formatting and some naming based on feedback
- fix error handling conditions
- use appropriate return codes
- use memcpy_toio instead of direct access to PCIE bar
-

Scott Branden (7):
fs: introduce kernel_pread_file* support
firmware: add offset to request_firmware_into_buf
test_firmware: add partial read support for request_firmware_into_buf
firmware: test partial file reads of request_firmware_into_buf
bcm-vk: add bcm_vk UAPI
misc: bcm-vk: add Broadcom VK driver
MAINTAINERS: bcm-vk: add maintainer for Broadcom VK Driver

 MAINTAINERS                                   |    7 +
 drivers/base/firmware_loader/firmware.h       |    5 +
 drivers/base/firmware_loader/main.c           |   52 +-
 drivers/misc/Kconfig                          |    1 +
 drivers/misc/Makefile                         |    1 +
 drivers/misc/bcm-vk/Kconfig                   |   41 +
 drivers/misc/bcm-vk/Makefile                  |   12 +
 drivers/misc/bcm-vk/bcm_vk.h                  |  406 +++++
 drivers/misc/bcm-vk/bcm_vk_dev.c              | 1179 ++++++++++++++
 drivers/misc/bcm-vk/bcm_vk_legacy.c           |   89 ++
 drivers/misc/bcm-vk/bcm_vk_msg.c              | 1420 +++++++++++++++++
 drivers/misc/bcm-vk/bcm_vk_msg.h              |  215 +++
 drivers/misc/bcm-vk/bcm_vk_sg.c               |  271 ++++
 drivers/misc/bcm-vk/bcm_vk_sg.h               |   60 +
 drivers/misc/bcm-vk/bcm_vk_tty.c              |  323 ++++
 drivers/soc/qcom/mdt_loader.c                 |    7 +-
 fs/exec.c                                     |   96 +-
 include/linux/firmware.h                      |    8 +-
 include/linux/fs.h                            |   20 +
 include/uapi/linux/misc/bcm_vk.h              |   99 ++
 lib/test_firmware.c                           |  144 +-
 .../selftests/firmware/fw_filesystem.sh       |   80 +
 22 files changed, 4487 insertions(+), 49 deletions(-)
 create mode 100644 drivers/misc/bcm-vk/Kconfig
 create mode 100644 drivers/misc/bcm-vk/Makefile
 create mode 100644 drivers/misc/bcm-vk/bcm_vk.h
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_dev.c
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_legacy.c
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_msg.c
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_msg.h
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_sg.c
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_sg.h
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_tty.c
 create mode 100644 include/uapi/linux/misc/bcm_vk.h
Signature · 1 line
2.17.1
author maintainer
#1 lore raw

PATCH v3 1/7 fs: introduce kernel_pread_file* support

Add kernel_pread_file* support to kernel to allow for partial read of files with an offset into the file. Existing kernel_read_file functions call new kernel_pread_file functions with offset=0 and flags=KERNEL_PREAD_FLAG_WHOLE.

---
 fs/exec.c          | 96 ++++++++++++++++++++++++++++++++++++----------
 include/linux/fs.h | 20 ++++++++++
 2 files changed, 95 insertions(+), 21 deletions(-)
fs/exec.c +75 -21
index 06b4c550af5d..cfab212fab9d 100644
@@ -896,10 +896,14 @@ struct file *open_exec(const char *name)
 }
 EXPORT_SYMBOL(open_exec);
 
-int kernel_read_file(struct file *file, void **buf, loff_t *size,
-		     loff_t max_size, enum kernel_read_file_id id)
-{
-	loff_t i_size, pos;
+int kernel_pread_file(struct file *file, void **buf, loff_t *size,
+		      loff_t pos, loff_t max_size, unsigned int flags,
+		      enum kernel_read_file_id id)
+{
+	loff_t alloc_size;
+	loff_t buf_pos;
+	loff_t read_end;
+	loff_t i_size;
 	ssize_t bytes = 0;
 	int ret;
 
@@ -919,21 +923,31 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 		ret = -EINVAL;
 		goto out;
 	}
-	if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
+
+	/* Default read to end of file */
+	read_end = i_size;
+
+	/* Allow reading partial portion of file */
+	if ((flags & KERNEL_PREAD_FLAG_PART) &&
+	    (i_size > (pos + max_size)))
+		read_end = pos + max_size;
+
+	alloc_size = read_end - pos;
+	if (i_size > SIZE_MAX || (max_size > 0 && alloc_size > max_size)) {
 		ret = -EFBIG;
 		goto out;
 	}
 
 	if (id != READING_FIRMWARE_PREALLOC_BUFFER)
-		*buf = vmalloc(i_size);
+		*buf = vmalloc(alloc_size);
 	if (!*buf) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	pos = 0;
-	while (pos < i_size) {
-		bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
+	buf_pos = 0;
+	while (pos < read_end) {
+		bytes = kernel_read(file, *buf + buf_pos, read_end - pos, &pos);
 		if (bytes < 0) {
 			ret = bytes;
 			goto out_free;
@@ -941,14 +955,16 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 
 		if (bytes == 0)
 			break;
+
+		buf_pos += bytes;
 	}
 
-	if (pos != i_size) {
+	if (pos != read_end) {
 		ret = -EIO;
 		goto out_free;
 	}
 
-	ret = security_kernel_post_read_file(file, *buf, i_size, id);
+	ret = security_kernel_post_read_file(file, *buf, alloc_size, id);
 	if (!ret)
 		*size = pos;
 
@@ -964,10 +980,20 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 	allow_write_access(file);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(kernel_pread_file);
+
+int kernel_read_file(struct file *file, void **buf, loff_t *size,
+		     loff_t max_size, enum kernel_read_file_id id)
+{
+	return kernel_pread_file(file, buf, size, 0, max_size,
+				 KERNEL_PREAD_FLAG_WHOLE, id);
+}
 EXPORT_SYMBOL_GPL(kernel_read_file);
 
-int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
-			       loff_t max_size, enum kernel_read_file_id id)
+int kernel_pread_file_from_path(const char *path, void **buf,
+				loff_t *size, loff_t pos,
+				loff_t max_size, unsigned int flags,
+				enum kernel_read_file_id id)
 {
 	struct file *file;
 	int ret;
@@ -979,15 +1005,25 @@ int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, size, max_size, id);
+	ret = kernel_pread_file(file, buf, size, pos, max_size, flags, id);
 	fput(file);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(kernel_pread_file_from_path);
+
+int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
+			       loff_t max_size, enum kernel_read_file_id id)
+{
+	return kernel_pread_file_from_path(path, buf, size, 0, max_size,
+					   KERNEL_PREAD_FLAG_WHOLE, id);
+}
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
 
-int kernel_read_file_from_path_initns(const char *path, void **buf,
-				      loff_t *size, loff_t max_size,
-				      enum kernel_read_file_id id)
+extern int kernel_pread_file_from_path_initns(const char *path, void **buf,
+					      loff_t *size, loff_t pos,
+					      loff_t max_size,
+					      unsigned int flags,
+					      enum kernel_read_file_id id)
 {
 	struct file *file;
 	struct path root;
@@ -1005,14 +1041,24 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, size, max_size, id);
+	ret = kernel_pread_file(file, buf, size, pos, max_size, flags, id);
 	fput(file);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(kernel_pread_file_from_path_initns);
+
+int kernel_read_file_from_path_initns(const char *path, void **buf,
+				      loff_t *size, loff_t max_size,
+				      enum kernel_read_file_id id)
+{
+	return kernel_pread_file_from_path_initns(path, buf, size, 0, max_size,
+						  KERNEL_PREAD_FLAG_WHOLE, id);
+}
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
 
-int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
-			     enum kernel_read_file_id id)
+int kernel_pread_file_from_fd(int fd, void **buf, loff_t *size, loff_t pos,
+			      loff_t max_size, unsigned int flags,
+			      enum kernel_read_file_id id)
 {
 	struct fd f = fdget(fd);
 	int ret = -EBADF;
@@ -1020,11 +1066,19 @@ int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
 	if (!f.file)
 		goto out;
 
-	ret = kernel_read_file(f.file, buf, size, max_size, id);
+	ret = kernel_pread_file(f.file, buf, size, pos, max_size, flags, id);
 out:
 	fdput(f);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(kernel_pread_file_from_fd);
+
+int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
+			     enum kernel_read_file_id id)
+{
+	return kernel_pread_file_from_fd(fd, buf, size, 0, max_size,
+					 KERNEL_PREAD_FLAG_WHOLE, id);
+}
 EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);
 
 ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
include/linux/fs.h +20 -0
index 4f6f59b4f22a..03441fbcad6c 100644
@@ -3014,12 +3014,32 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
 	return kernel_read_file_str[id];
 }
 
+/* Flags used by kernel_pread_file functions */
+#define KERNEL_PREAD_FLAG_WHOLE	0x0000 /* Only Allow reading of whole file */
+#define KERNEL_PREAD_FLAG_PART	0x0001 /* Allow reading part of file */
+
+extern int kernel_pread_file(struct file *file, void **buf, loff_t *size,
+			     loff_t pos, loff_t max_size, unsigned int flags,
+			     enum kernel_read_file_id id);
 extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
 			    enum kernel_read_file_id);
+extern int kernel_pread_file_from_path(const char *path, void **buf,
+				       loff_t *size, loff_t pos,
+				       loff_t max_size, unsigned int flags,
+				       enum kernel_read_file_id id);
 extern int kernel_read_file_from_path(const char *, void **, loff_t *, loff_t,
 				      enum kernel_read_file_id);
+extern int kernel_pread_file_from_path_initns(const char *path, void **buf,
+					      loff_t *size, loff_t pos,
+					      loff_t max_size,
+					      unsigned int flags,
+					      enum kernel_read_file_id id);
 extern int kernel_read_file_from_path_initns(const char *, void **, loff_t *, loff_t,
 					     enum kernel_read_file_id);
+extern int kernel_pread_file_from_fd(int fd, void **buf, loff_t *size,
+				    loff_t pos, loff_t max_size,
+				    unsigned int flags,
+				    enum kernel_read_file_id id);
 extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t,
 				    enum kernel_read_file_id);
 extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
Signature · 1 line
2.17.1
author maintainer
#2 lore raw

PATCH v3 2/7 firmware: add offset to request_firmware_into_buf

In reply to Scott Branden

Add offset to request_firmware_into_buf to allow for portions of firmware file to be read into a buffer. Necessary where firmware needs to be loaded in portions from file in memory constrained systems.

---
 drivers/base/firmware_loader/firmware.h |  5 +++
 drivers/base/firmware_loader/main.c     | 52 +++++++++++++++++--------
 drivers/soc/qcom/mdt_loader.c           |  7 +++-
 include/linux/firmware.h                |  8 +++-
 lib/test_firmware.c                     |  4 +-
 5 files changed, 55 insertions(+), 21 deletions(-)
drivers/base/firmware_loader/firmware.h +5 -0
index 25836a6afc9f..1147dae01148 100644
@@ -32,6 +32,8 @@
  * @FW_OPT_FALLBACK_PLATFORM: Enable fallback to device fw copy embedded in
  *	the platform's main firmware. If both this fallback and the sysfs
  *      fallback are enabled, then this fallback will be tried first.
+ * @FW_OPT_PARTIAL: Allow partial read of firmware instead of needing to read
+ *	entire file.
  */
 enum fw_opt {
 	FW_OPT_UEVENT			= BIT(0),
@@ -41,6 +43,7 @@ enum fw_opt {
 	FW_OPT_NOCACHE			= BIT(4),
 	FW_OPT_NOFALLBACK_SYSFS		= BIT(5),
 	FW_OPT_FALLBACK_PLATFORM	= BIT(6),
+	FW_OPT_PARTIAL			= BIT(7),
 };
 
 enum fw_status {
@@ -68,6 +71,8 @@ struct fw_priv {
 	void *data;
 	size_t size;
 	size_t allocated_size;
+	size_t offset;
+	unsigned int flags;
 #ifdef CONFIG_FW_LOADER_PAGED_BUF
 	bool is_paged_buf;
 	struct page **pages;
drivers/base/firmware_loader/main.c +36 -16

158 lines not on this page · raw message

drivers/soc/qcom/mdt_loader.c +5 -2
index 24cd193dec55..00f3359f4f61 100644
@@ -246,8 +246,11 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
 		} else if (phdr->p_filesz) {
 			/* Firmware not large enough, load split-out segments */
 			sprintf(fw_name + fw_name_len - 3, "b%02d", i);
-			ret = request_firmware_into_buf(&seg_fw, fw_name, dev,
-							ptr, phdr->p_filesz);
+			ret = request_firmware_into_buf
+						(&seg_fw, fw_name, dev,
+						 ptr, phdr->p_filesz,
+						 0,
+						 KERNEL_PREAD_FLAG_WHOLE);
 			if (ret) {
 				dev_err(dev, "failed to load %s\n", fw_name);
 				break;
include/linux/firmware.h +6 -2
index 4bbd0afd91b7..b98d17fb3bd1 100644
@@ -4,6 +4,7 @@
 
 #include <linux/types.h>
 #include <linux/compiler.h>
+#include <linux/fs.h>
 #include <linux/gfp.h>
 
 #define FW_ACTION_NOHOTPLUG 0
@@ -53,7 +54,9 @@ int request_firmware_nowait(
 int request_firmware_direct(const struct firmware **fw, const char *name,
 			    struct device *device);
 int request_firmware_into_buf(const struct firmware **firmware_p,
-	const char *name, struct device *device, void *buf, size_t size);
+			      const char *name, struct device *device,
+			      void *buf, size_t size,
+			      size_t offset, unsigned int pread_flags);
 
 void release_firmware(const struct firmware *fw);
 #else
@@ -98,7 +101,8 @@ static inline int request_firmware_direct(const struct firmware **fw,
 }
 
 static inline int request_firmware_into_buf(const struct firmware **firmware_p,
-	const char *name, struct device *device, void *buf, size_t size)
+	const char *name, struct device *device, void *buf, size_t size,
+	size_t offset, unsigned int pread_flags)
 {
 	return -EINVAL;
 }
lib/test_firmware.c +3 -1
index 9fee2b93a8d1..55176b0a8318 100644
@@ -654,7 +654,9 @@ static int test_fw_run_batch_request(void *data)
 						    req->name,
 						    req->dev,
 						    test_buf,
-						    TEST_FIRMWARE_BUF_SIZE);
+						    TEST_FIRMWARE_BUF_SIZE,
+						    0,
+						    KERNEL_PREAD_FLAG_WHOLE);
 		if (!req->fw)
 			kfree(test_buf);
 	} else {
Signature · 1 line
2.17.1
author maintainer
#3 lore raw

PATCH v3 3/7 test_firmware: add partial read support for request_firmware_into_buf

In reply to Scott Branden

Add additional hooks to test_firmware to pass in support for partial file read using request_firmware_into_buf.
buf_size: size of buffer to request firmware into
partial: indicates that a partial file request is being made
file_offset: to indicate offset into file to request

---
 lib/test_firmware.c | 146 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 136 insertions(+), 10 deletions(-)
lib/test_firmware.c +136 -10
index 55176b0a8318..d1d2b48ed40e 100644
@@ -50,6 +50,9 @@ struct test_batched_req {
  * @name: the name of the firmware file to look for
  * @into_buf: when the into_buf is used if this is true
  *	request_firmware_into_buf() will be used instead.
+ * @buf_size: size of buf to allocate when into_buf is true
+ * @file_offset: file offset to request when calling request_firmware_into_buf
+ * @partial: partial read flag value when calling request_firmware_into_buf
  * @sync_direct: when the sync trigger is used if this is true
  *	request_firmware_direct() will be used instead.
  * @send_uevent: whether or not to send a uevent for async requests
@@ -89,6 +92,9 @@ struct test_batched_req {
 struct test_config {
 	char *name;
 	bool into_buf;
+	size_t buf_size;
+	size_t file_offset;
+	bool partial;
 	bool sync_direct;
 	bool send_uevent;
 	u8 num_requests;
@@ -183,6 +189,9 @@ static int __test_firmware_config_init(void)
 	test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
 	test_fw_config->send_uevent = true;
 	test_fw_config->into_buf = false;
+	test_fw_config->buf_size = TEST_FIRMWARE_BUF_SIZE;
+	test_fw_config->file_offset = 0;
+	test_fw_config->partial = false;
 	test_fw_config->sync_direct = false;
 	test_fw_config->req_firmware = request_firmware;
 	test_fw_config->test_result = 0;
@@ -236,28 +245,35 @@ static ssize_t config_show(struct device *dev,
 			dev_name(dev));
 
 	if (test_fw_config->name)
-		len += scnprintf(buf+len, PAGE_SIZE - len,
+		len += scnprintf(buf + len, PAGE_SIZE - len,
 				"name:\t%s\n",
 				test_fw_config->name);
 	else
-		len += scnprintf(buf+len, PAGE_SIZE - len,
+		len += scnprintf(buf + len, PAGE_SIZE - len,
 				"name:\tEMTPY\n");
 
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"num_requests:\t%u\n", test_fw_config->num_requests);
 
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"send_uevent:\t\t%s\n",
 			test_fw_config->send_uevent ?
 			"FW_ACTION_HOTPLUG" :
 			"FW_ACTION_NOHOTPLUG");
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"into_buf:\t\t%s\n",
 			test_fw_config->into_buf ? "true" : "false");
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
+			"buf_size:\t%zu\n", test_fw_config->buf_size);
+	len += scnprintf(buf + len, PAGE_SIZE - len,
+			"file_offset:\t%zu\n", test_fw_config->file_offset);
+	len += scnprintf(buf + len, PAGE_SIZE - len,
+			"partial:\t\t%s\n",
+			test_fw_config->partial ? "true" : "false");
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"sync_direct:\t\t%s\n",
 			test_fw_config->sync_direct ? "true" : "false");
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
 
 	mutex_unlock(&test_fw_mutex);
@@ -315,6 +331,30 @@ static ssize_t test_dev_config_show_bool(char *buf, bool val)
 	return snprintf(buf, PAGE_SIZE, "%d\n", val);
 }
 
+static int test_dev_config_update_size_t(const char *buf,
+					 size_t size,
+					 size_t *cfg)
+{
+	int ret;
+	long new;
+
+	ret = kstrtol(buf, 10, &new);
+	if (ret)
+		return ret;
+
+	mutex_lock(&test_fw_mutex);
+	*(size_t *)cfg = new;
+	mutex_unlock(&test_fw_mutex);
+
+	/* Always return full write size even if we didn't consume all */
+	return size;
+}
+
+static ssize_t test_dev_config_show_size_t(char *buf, size_t val)
+{
+	return snprintf(buf, PAGE_SIZE, "%zu\n", val);
+}
+
 static ssize_t test_dev_config_show_int(char *buf, int val)
 {
 	return snprintf(buf, PAGE_SIZE, "%d\n", val);
@@ -400,6 +440,83 @@ static ssize_t config_into_buf_show(struct device *dev,
 }
 static DEVICE_ATTR_RW(config_into_buf);
 
+static ssize_t config_buf_size_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	int rc;
+
+	mutex_lock(&test_fw_mutex);
+	if (test_fw_config->reqs) {
+		pr_err("Must call release_all_firmware prior to changing config\n");
+		rc = -EINVAL;
+		mutex_unlock(&test_fw_mutex);
+		goto out;
+	}
+	mutex_unlock(&test_fw_mutex);
+
+	rc = test_dev_config_update_size_t(buf, count,
+					   &test_fw_config->buf_size);
+
+out:
+	return rc;
+}
+
+static ssize_t config_buf_size_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	return test_dev_config_show_size_t(buf, test_fw_config->buf_size);
+}
+static DEVICE_ATTR_RW(config_buf_size);
+
+static ssize_t config_file_offset_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	int rc;
+
+	mutex_lock(&test_fw_mutex);
+	if (test_fw_config->reqs) {
+		pr_err("Must call release_all_firmware prior to changing config\n");
+		rc = -EINVAL;
+		mutex_unlock(&test_fw_mutex);
+		goto out;
+	}
+	mutex_unlock(&test_fw_mutex);
+
+	rc = test_dev_config_update_size_t(buf, count,
+					   &test_fw_config->file_offset);
+
+out:
+	return rc;
+}
+
+static ssize_t config_file_offset_show(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	return test_dev_config_show_size_t(buf, test_fw_config->file_offset);
+}
+static DEVICE_ATTR_RW(config_file_offset);
+
+static ssize_t config_partial_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	return test_dev_config_update_bool(buf,
+					   count,
+					   &test_fw_config->partial);
+}
+
+static ssize_t config_partial_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	return test_dev_config_show_bool(buf, test_fw_config->partial);
+}
+static DEVICE_ATTR_RW(config_partial);
+
 static ssize_t config_sync_direct_store(struct device *dev,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
@@ -645,18 +762,24 @@ static int test_fw_run_batch_request(void *data)
 
 	if (test_fw_config->into_buf) {
 		void *test_buf;
+		unsigned int pread_flags;
 
 		test_buf = kzalloc(TEST_FIRMWARE_BUF_SIZE, GFP_KERNEL);
 		if (!test_buf)
 			return -ENOSPC;
 
+		if (test_fw_config->partial)
+			pread_flags = KERNEL_PREAD_FLAG_PART;
+		else
+			pread_flags = KERNEL_PREAD_FLAG_WHOLE;
+
 		req->rc = request_firmware_into_buf(&req->fw,
 						    req->name,
 						    req->dev,
 						    test_buf,
-						    TEST_FIRMWARE_BUF_SIZE,
-						    0,
-						    KERNEL_PREAD_FLAG_WHOLE);
+						    test_fw_config->buf_size,
+						    test_fw_config->file_offset,
+						    pread_flags);
 		if (!req->fw)
 			kfree(test_buf);
 	} else {
@@ -929,6 +1052,9 @@ static struct attribute *test_dev_attrs[] = {
 	TEST_FW_DEV_ATTR(config_name),
 	TEST_FW_DEV_ATTR(config_num_requests),
 	TEST_FW_DEV_ATTR(config_into_buf),
+	TEST_FW_DEV_ATTR(config_buf_size),
+	TEST_FW_DEV_ATTR(config_file_offset),
+	TEST_FW_DEV_ATTR(config_partial),
 	TEST_FW_DEV_ATTR(config_sync_direct),
 	TEST_FW_DEV_ATTR(config_send_uevent),
 	TEST_FW_DEV_ATTR(config_read_fw_idx),
Signature · 1 line
2.17.1
author maintainer
#4 lore raw

PATCH v3 4/7 firmware: test partial file reads of request_firmware_into_buf

In reply to Scott Branden

Add firmware tests for partial file reads of request_firmware_into_buf.

---
 .../selftests/firmware/fw_filesystem.sh       | 80 +++++++++++++++++++
 1 file changed, 80 insertions(+)
tools/testing/selftests/firmware/fw_filesystem.sh +80 -0
index fcc281373b4d..38e89ba1b4d3 100755
@@ -149,6 +149,26 @@ config_unset_into_buf()
 	echo 0 >  $DIR/config_into_buf
 }
 
+config_set_buf_size()
+{
+	echo $1 >  $DIR/config_buf_size
+}
+
+config_set_file_offset()
+{
+	echo $1 >  $DIR/config_file_offset
+}
+
+config_set_partial()
+{
+	echo 1 >  $DIR/config_partial
+}
+
+config_unset_partial()
+{
+	echo 0 >  $DIR/config_partial
+}
+
 config_set_sync_direct()
 {
 	echo 1 >  $DIR/config_sync_direct
@@ -207,6 +227,35 @@ read_firmwares()
 	done
 }
 
+read_firmwares_partial()
+{
+	if [ "$(cat $DIR/config_into_buf)" == "1" ]; then
+		fwfile="${FW_INTO_BUF}"
+	else
+		fwfile="${FW}"
+	fi
+
+	if [ "$1" = "xzonly" ]; then
+		fwfile="${fwfile}-orig"
+	fi
+
+	# Strip fwfile down to match partial offset and length
+	partial_data="$(cat $fwfile)"
+	partial_data="${partial_data:$2:$3}"
+
+	for i in $(seq 0 3); do
+		config_set_read_fw_idx $i
+
+		read_firmware="$(cat $DIR/read_firmware)"
+
+		# Verify the contents are what we expect.
+		if [ $read_firmware != $partial_data ]; then
+			echo "request #$i: partial firmware was not loaded" >&2
+			exit 1
+		fi
+	done
+}
+
 read_firmwares_expect_nofile()
 {
 	for i in $(seq 0 3); do
@@ -319,6 +368,21 @@ test_batched_request_firmware_into_buf()
 	echo "OK"
 }
 
+test_batched_request_firmware_into_buf_partial()
+{
+	echo -n "Batched request_firmware_into_buf_partial() $2 off=$3 size=$4 try #$1: "
+	config_reset
+	config_set_name $TEST_FIRMWARE_INTO_BUF_FILENAME
+	config_set_into_buf
+	config_set_partial
+	config_set_buf_size $4
+	config_set_file_offset $3
+	config_trigger_sync
+	read_firmwares_partial $2 $3 $4
+	release_all_firmware
+	echo "OK"
+}
+
 test_batched_request_firmware_direct()
 {
 	echo -n "Batched request_firmware_direct() $2 try #$1: "
@@ -371,6 +435,22 @@ for i in $(seq 1 5); do
 	test_batched_request_firmware_into_buf $i normal
 done
 
+for i in $(seq 1 5); do
+	test_batched_request_firmware_into_buf_partial $i normal 0 10
+done
+
+for i in $(seq 1 5); do
+	test_batched_request_firmware_into_buf_partial $i normal 0 5
+done
+
+for i in $(seq 1 5); do
+	test_batched_request_firmware_into_buf_partial $i normal 1 6
+done
+
+for i in $(seq 1 5); do
+	test_batched_request_firmware_into_buf_partial $i normal 2 10
+done
+
 for i in $(seq 1 5); do
 	test_batched_request_firmware_direct $i normal
 done
Signature · 1 line
2.17.1
author maintainer
#5 lore raw

PATCH v3 5/7 bcm-vk: add bcm_vk UAPI

In reply to Scott Branden

Add user space api for bcm-vk driver.

---
 include/uapi/linux/misc/bcm_vk.h | 99 ++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 include/uapi/linux/misc/bcm_vk.h
include/uapi/linux/misc/bcm_vk.h new file +99 -0
new file mode 100644
index 000000000000..783087b7c31f
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */
+/*
+ * Copyright 2018-2020 Broadcom.
+ */
+
+#ifndef __UAPI_LINUX_MISC_BCM_VK_H
+#define __UAPI_LINUX_MISC_BCM_VK_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define BCM_VK_MAX_FILENAME 64
+
+struct vk_image {
+	__u32 type; /* Type of image */
+#define VK_IMAGE_TYPE_BOOT1 1 /* 1st stage (load to SRAM) */
+#define VK_IMAGE_TYPE_BOOT2 2 /* 2nd stage (load to DDR) */
+	char filename[BCM_VK_MAX_FILENAME]; /* Filename of image */
+};
+
+struct vk_reset {
+	__u32 arg1;
+	__u32 arg2;
+};
+
+#define VK_MAGIC		0x5e
+
+/* Load image to Valkyrie */
+#define VK_IOCTL_LOAD_IMAGE	_IOW(VK_MAGIC, 0x2, struct vk_image)
+
+/* Send Reset to Valkyrie */
+#define VK_IOCTL_RESET		_IOW(VK_MAGIC, 0x4, struct vk_reset)
+
+/*
+ * message block - basic unit in the message where a message's size is always
+ *		   N x sizeof(basic_block)
+ */
+struct vk_msg_blk {
+	__u8 function_id;
+#define VK_FID_TRANS_BUF	5
+#define VK_FID_SHUTDOWN		8
+	__u8 size;
+	__u16 trans_id; /* transport id, queue & msg_id */
+	__u32 context_id;
+	__u32 args[2];
+#define VK_CMD_PLANES_MASK	0x000f /* number of planes to up/download */
+#define VK_CMD_UPLOAD		0x0400 /* memory transfer to vk */
+#define VK_CMD_DOWNLOAD		0x0500 /* memory transfer from vk */
+#define VK_CMD_MASK		0x0f00 /* command mask */
+};
+
+#define VK_BAR_FWSTS			0x41c
+#define VK_BAR_COP_FWSTS		0x428
+/* VK_FWSTS definitions */
+#define VK_FWSTS_RELOCATION_ENTRY	BIT(0)
+#define VK_FWSTS_RELOCATION_EXIT	BIT(1)
+#define VK_FWSTS_INIT_START		BIT(2)
+#define VK_FWSTS_ARCH_INIT_DONE		BIT(3)
+#define VK_FWSTS_PRE_KNL1_INIT_DONE	BIT(4)
+#define VK_FWSTS_PRE_KNL2_INIT_DONE	BIT(5)
+#define VK_FWSTS_POST_KNL_INIT_DONE	BIT(6)
+#define VK_FWSTS_INIT_DONE		BIT(7)
+#define VK_FWSTS_APP_INIT_START		BIT(8)
+#define VK_FWSTS_APP_INIT_DONE		BIT(9)
+#define VK_FWSTS_MASK			0xffffffff
+#define VK_FWSTS_READY			(VK_FWSTS_INIT_START | \
+					 VK_FWSTS_ARCH_INIT_DONE | \
+					 VK_FWSTS_PRE_KNL1_INIT_DONE | \
+					 VK_FWSTS_PRE_KNL2_INIT_DONE | \
+					 VK_FWSTS_POST_KNL_INIT_DONE | \
+					 VK_FWSTS_INIT_DONE | \
+					 VK_FWSTS_APP_INIT_START | \
+					 VK_FWSTS_APP_INIT_DONE)
+/* Deinit */
+#define VK_FWSTS_APP_DEINIT_START	BIT(23)
+#define VK_FWSTS_APP_DEINIT_DONE	BIT(24)
+#define VK_FWSTS_DRV_DEINIT_START	BIT(25)
+#define VK_FWSTS_DRV_DEINIT_DONE	BIT(26)
+#define VK_FWSTS_RESET_DONE		BIT(27)
+#define VK_FWSTS_DEINIT_TRIGGERED	(VK_FWSTS_APP_DEINIT_START | \
+					 VK_FWSTS_APP_DEINIT_DONE  | \
+					 VK_FWSTS_DRV_DEINIT_START | \
+					 VK_FWSTS_DRV_DEINIT_DONE)
+/* Last nibble for reboot reason */
+#define VK_FWSTS_RESET_REASON_SHIFT	28
+#define VK_FWSTS_RESET_REASON_MASK	(0xf << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_SYS_PWRUP	(0x0 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_MBOX_DB		(0x1 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_M7_WDOG		(0x2 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_TEMP		(0x3 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_PCI_FLR		(0x4 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_PCI_HOT		(0x5 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_PCI_WARM		(0x6 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_PCI_COLD		(0x7 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_L1		(0x8 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_L0		(0x9 << VK_FWSTS_RESET_REASON_SHIFT)
+#define VK_FWSTS_RESET_UNKNOWN		(0xf << VK_FWSTS_RESET_REASON_SHIFT)
+
+#endif /* __UAPI_LINUX_MISC_BCM_VK_H */
Signature · 1 line
2.17.1
author maintainer
#6 lore raw

PATCH v3 6/7 misc: bcm-vk: add Broadcom VK driver

In reply to Scott Branden

Add Broadcom VK driver offload engine.
This driver interfaces to the VK PCIe offload engine to perform should offload functions as video transcoding on multiple streams in parallel. VK device is booted from files loaded using request_firmware_into_buf mechanism. After booted card status is updated and messages can then be sent to the card.
Such messages contain scatter gather list of addresses
to pull data from the host to perform operations on.

---
 drivers/misc/Kconfig                |    1 +
 drivers/misc/Makefile               |    1 +
 drivers/misc/bcm-vk/Kconfig         |   41 +
 drivers/misc/bcm-vk/Makefile        |   12 +
 drivers/misc/bcm-vk/bcm_vk.h        |  406 ++++++++
 drivers/misc/bcm-vk/bcm_vk_dev.c    | 1179 ++++++++++++++++++++++
 drivers/misc/bcm-vk/bcm_vk_legacy.c |   89 ++
 drivers/misc/bcm-vk/bcm_vk_msg.c    | 1420 +++++++++++++++++++++++++++
 drivers/misc/bcm-vk/bcm_vk_msg.h    |  215 ++++
 drivers/misc/bcm-vk/bcm_vk_sg.c     |  271 +++++
 drivers/misc/bcm-vk/bcm_vk_sg.h     |   60 ++
 drivers/misc/bcm-vk/bcm_vk_tty.c    |  323 ++++++
 12 files changed, 4018 insertions(+)
 create mode 100644 drivers/misc/bcm-vk/Kconfig
 create mode 100644 drivers/misc/bcm-vk/Makefile
 create mode 100644 drivers/misc/bcm-vk/bcm_vk.h
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_dev.c
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_legacy.c
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_msg.c
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_msg.h
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_sg.c
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_sg.h
 create mode 100644 drivers/misc/bcm-vk/bcm_vk_tty.c
drivers/misc/Kconfig +1 -0
index 99e151475d8f..1cfd5c4ce5e8 100644
@@ -478,6 +478,7 @@ source "drivers/misc/genwqe/Kconfig"
 source "drivers/misc/echo/Kconfig"
 source "drivers/misc/cxl/Kconfig"
 source "drivers/misc/ocxl/Kconfig"
+source "drivers/misc/bcm-vk/Kconfig"
 source "drivers/misc/cardreader/Kconfig"
 source "drivers/misc/habanalabs/Kconfig"
 source "drivers/misc/uacce/Kconfig"
drivers/misc/Makefile +1 -0
index 9abf2923d831..31c2b89e9b24 100644
@@ -53,6 +53,7 @@ obj-$(CONFIG_VEXPRESS_SYSCFG)	+= vexpress-syscfg.o
 obj-$(CONFIG_CXL_BASE)		+= cxl/
 obj-$(CONFIG_PCI_ENDPOINT_TEST)	+= pci_endpoint_test.o
 obj-$(CONFIG_OCXL)		+= ocxl/
+obj-$(CONFIG_BCM_VK)		+= bcm-vk/
 obj-y				+= cardreader/
 obj-$(CONFIG_PVPANIC)   	+= pvpanic.o
 obj-$(CONFIG_HABANA_AI)		+= habanalabs/
drivers/misc/bcm-vk/Kconfig new file +41 -0

41 lines not on this page · raw message

drivers/misc/bcm-vk/Makefile new file +12 -0
new file mode 100644
index 000000000000..cbc2a933e2ad
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for Broadcom VK driver
+#
+
+obj-$(CONFIG_BCM_VK) += bcm_vk.o
+bcm_vk-objs := \
+	bcm_vk_dev.o \
+	bcm_vk_legacy.o \
+	bcm_vk_msg.o \
+	bcm_vk_sg.o \
+	bcm_vk_tty.o
drivers/misc/bcm-vk/bcm_vk.h new file +406 -0

406 lines not on this page · raw message

drivers/misc/bcm-vk/bcm_vk_dev.c new file +1179 -0

1,179 lines not on this page · raw message

drivers/misc/bcm-vk/bcm_vk_legacy.c new file +89 -0

89 lines not on this page · raw message

drivers/misc/bcm-vk/bcm_vk_msg.c new file +1420 -0

1,259 lines not on this page · raw message

drivers/misc/bcm-vk/bcm_vk_msg.h new file +215 -0

215 lines not on this page · raw message

drivers/misc/bcm-vk/bcm_vk_sg.c new file +271 -0

271 lines not on this page · raw message

drivers/misc/bcm-vk/bcm_vk_sg.h new file +60 -0

60 lines not on this page · raw message

drivers/misc/bcm-vk/bcm_vk_tty.c new file +323 -0

323 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.17.1

Part of the diff is not shown here. View the raw message.

#7 lore raw

Re: [PATCH v3 6/7] misc: bcm-vk: add Broadcom VK driver

I love your patch! Perhaps something to improve:

Hi Scott,

I love your patch! Perhaps something to improve:

[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on next-20200421]
[cannot apply to char-misc/char-misc-testing kselftest/next linus/master v5.7-rc2] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Scott-Branden/firmware-add-partial-read-support-in-request_firmware_into_buf/20200422-114528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 55623260bb33e2ab849af76edf2253bc04cb241f
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-191-gc51a0382-dirty
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate

sparse warnings: (new ones prefixed by >>)

>> drivers/misc/bcm-vk/bcm_vk_dev.c:189:15: sparse: sparse: incorrect type in assignment (different address spaces) @@    expected struct bcm_vk_peer_log *p_ctl @@    got struct bcm_vk_peer_log *p_ctl @@
>> drivers/misc/bcm-vk/bcm_vk_dev.c:189:15: sparse:    expected struct bcm_vk_peer_log *p_ctl
>> drivers/misc/bcm-vk/bcm_vk_dev.c:189:15: sparse:    got void [noderef] <asn:2> *
>> drivers/misc/bcm-vk/bcm_vk_dev.c:685:36: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void const [noderef] <asn:1> *from @@    got oderef] <asn:1> *from @@
>> drivers/misc/bcm-vk/bcm_vk_dev.c:685:36: sparse:    expected void const [noderef] <asn:1> *from
>> drivers/misc/bcm-vk/bcm_vk_dev.c:685:36: sparse:    got struct vk_image *arg
   drivers/misc/bcm-vk/bcm_vk_dev.c:780:36: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected void const [noderef] <asn:1> *from @@    got oderef] <asn:1> *from @@
   drivers/misc/bcm-vk/bcm_vk_dev.c:780:36: sparse:    expected void const [noderef] <asn:1> *from
>> drivers/misc/bcm-vk/bcm_vk_dev.c:780:36: sparse:    got struct vk_reset *arg
>> drivers/misc/bcm-vk/bcm_vk_dev.c:858:45: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected struct vk_image *arg @@    got void [nstruct vk_image *arg @@
>> drivers/misc/bcm-vk/bcm_vk_dev.c:858:45: sparse:    expected struct vk_image *arg
>> drivers/misc/bcm-vk/bcm_vk_dev.c:858:45: sparse:    got void [noderef] <asn:1> *argp
>> drivers/misc/bcm-vk/bcm_vk_dev.c:862:40: sparse: sparse: incorrect type in argument 2 (different address spaces) @@    expected struct vk_reset *arg @@    got void [nstruct vk_reset *arg @@
>> drivers/misc/bcm-vk/bcm_vk_dev.c:862:40: sparse:    expected struct vk_reset *arg
   drivers/misc/bcm-vk/bcm_vk_dev.c:862:40: sparse:    got void [noderef] <asn:1> *argp
--
>> drivers/misc/bcm-vk/bcm_vk_msg.c:507:17: sparse: sparse: cast removes address space '<asn:2>' of expression

drivers/misc/bcm-vk/bcm_vk_msg.c:707:15: sparse: sparse: cast removes address space '<asn:2>' of expression drivers/misc/bcm-vk/bcm_vk_msg.c:715:23: sparse: sparse: cast removes address space '<asn:2>' of expression drivers/misc/bcm-vk/bcm_vk_msg.c:871:31: sparse: sparse: cast removes address space '<asn:2>' of expression drivers/misc/bcm-vk/bcm_vk_msg.c:899:47: sparse: sparse: cast removes address space '<asn:2>' of expression

vim +189 drivers/misc/bcm-vk/bcm_vk_dev.c

180
181 static void bcm_vk_dump_peer_log(struct bcm_vk *vk)
182 {
183 struct bcm_vk_peer_log log, *p_ctl;
184 char loc_buf[BCM_VK_PEER_LOG_LINE_MAX];
185 int cnt;
186 struct device *dev = &vk->pdev->dev;
187 uint data_offset;
188

 > 189		p_ctl = vk->bar[BAR_2] + vk->peerlog_off;

190 log = *p_ctl;
191 /* do a rmb() to make sure log is updated */
192 rmb();
193
194 dev_dbg(dev, "Peer PANIC: Size 0x%x(0x%x), [Rd Wr] = [%d %d]\n",
195 log.buf_size, log.mask, log.rd_idx, log.wr_idx);
196
197 cnt = 0;
198 data_offset = vk->peerlog_off + sizeof(struct bcm_vk_peer_log);
199 while (log.rd_idx != log.wr_idx) {
200 loc_buf[cnt] = vkread8(vk, BAR_2, data_offset + log.rd_idx);
201
202 if ((loc_buf[cnt] == '\0') ||
203 (cnt == (BCM_VK_PEER_LOG_LINE_MAX - 1))) {
204 dev_err(dev, "%s", loc_buf);
205 cnt = 0;
206 } else {
207 cnt++;
208 }
209 log.rd_idx = (log.rd_idx + 1) & log.mask;
210 }
211 /* update rd idx at the end */
212 vkwrite32(vk, log.rd_idx, BAR_2, vk->peerlog_off);
213 }
214

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#8 lore raw

Re: [PATCH v3 6/7] misc: bcm-vk: add Broadcom VK driver

Quoted 11 lines · kbuild test robot

Hi Scott,

I love your patch! Perhaps something to improve:

[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on next-20200421]
[cannot apply to char-misc/char-misc-testing kselftest/next linus/master v5.7-rc2] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

Quoted 7 lines
url:    https://github.com/0day-ci/linux/commits/Scott-Branden/firmware-add-partial-read-support-in-request_firmware_into_buf/20200422-114528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 55623260bb33e2ab849af76edf2253bc04cb241f
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-191-gc51a0382-dirty
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
                                           ^^^^^^^^^^^^^^^^^^^

Sorry, you asked me about this earlier. You will need to add -D__CHECK_ENDIAN__ to enable these Sparse warnings.

regards,
dan carpenter

#9 lore raw

Re: [PATCH v3 6/7] misc: bcm-vk: add Broadcom VK driver

Quoted 2 lines · Dan Carpenter

Sorry, you asked me about this earlier. You will need to add -D__CHECK_ENDIAN__ to enable these Sparse warnings.

Endian checking has been enabled by default for quite a while.

author maintainer
#10 lore raw

Re: [PATCH v3 6/7] misc: bcm-vk: add Broadcom VK driver

In reply to Dan Carpenter
Quoted 19 lines · Dan Carpenter
Quoted 11 lines · kbuild test robot

Hi Scott,

I love your patch! Perhaps something to improve:

[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on next-20200421]
[cannot apply to char-misc/char-misc-testing kselftest/next linus/master v5.7-rc2] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

Quoted 7 lines
url:    https://github.com/0day-ci/linux/commits/Scott-Branden/firmware-add-partial-read-support-in-request_firmware_into_buf/20200422-114528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 55623260bb33e2ab849af76edf2253bc04cb241f
reproduce:
         # apt-get install sparse
         # sparse version: v0.6.1-191-gc51a0382-dirty
         make ARCH=x86_64 allmodconfig
         make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
Quoted 4 lines
                                            ^^^^^^^^^^^^^^^^^^^

Sorry, you asked me about this earlier. You will need to add -D__CHECK_ENDIAN__ to enable these Sparse warnings.

This is strange.  I ran the sparse build and thought I had fixed all the issues.
I'll have to try again.

One other question with the sparse build.  I get many of the messages printed but the build seems to go to the end (even without my patches applied):
./arch/x86/include/asm/paravirt.h:333:9: error: got __inline ./arch/x86/include/asm/paravirt.h:338:9: error: Expected ( after asm ./arch/x86/include/asm/paravirt.h:338:9: error: got __inline ./arch/x86/include/asm/paravirt.h:343:9: error: Expected ( after asm ./arch/x86/include/asm/paravirt.h:343:9: error: got __inline ./arch/x86/include/asm/paravirt.h:348:9: error: Expected ( after asm ./arch/x86/include/asm/paravirt.h:348:9: error: too many errors

Any way to suppress or I am doing something wrong?  I just run the 2 make commands:

make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

Quoted 3 lines

regards,
dan carpenter

author maintainer
#11 lore raw

Re: [PATCH v3 6/7] misc: bcm-vk: add Broadcom VK driver

Quoted 48 lines · Scott Branden
Quoted 26 lines · Dan Carpenter
Quoted 21 lines · kbuild test robot

Hi Scott,

I love your patch! Perhaps something to improve:

[auto build test WARNING on driver-core/driver-core-testing] [also build test WARNING on next-20200421]
[cannot apply to char-misc/char-misc-testing kselftest/next linus/master v5.7-rc2]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see
https://stackoverflow.com/a/37406982]

url:
https://github.com/0day-ci/linux/commits/Scott-Branden/firmware-add-partial-read-support-in-request_firmware_into_buf/20200422-114528
base:
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
55623260bb33e2ab849af76edf2253bc04cb241f
reproduce:

Quoted 4 lines
         # apt-get install sparse
         # sparse version: v0.6.1-191-gc51a0382-dirty
         make ARCH=x86_64 allmodconfig
         make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
Quoted 4 lines

                                            ^^^^^^^^^^^^^^^^^^^

Sorry, you asked me about this earlier.  You will need to add -D__CHECK_ENDIAN__ to enable these Sparse warnings.

This is strange.  I ran the sparse build and thought I had fixed all the issues.
I'll have to try again.

One other question with the sparse build.  I get many of the messages printed but the build seems to go to the end (even without my patches applied):
./arch/x86/include/asm/paravirt.h:333:9: error: got __inline ./arch/x86/include/asm/paravirt.h:338:9: error: Expected ( after asm ./arch/x86/include/asm/paravirt.h:338:9: error: got __inline ./arch/x86/include/asm/paravirt.h:343:9: error: Expected ( after asm ./arch/x86/include/asm/paravirt.h:343:9: error: got __inline ./arch/x86/include/asm/paravirt.h:348:9: error: Expected ( after asm ./arch/x86/include/asm/paravirt.h:348:9: error: too many errors

Quoted 5 lines

Any way to suppress or I am doing something wrong?  I just run the 2 make commands:

        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

I figured out the sparse utility on ubuntu 18.04 is out of date causing the issue.

Quoted 5 lines
Quoted 4 lines

regards,
dan carpenter

author maintainer
#12 lore raw

Re: [PATCH v3 6/7] misc: bcm-vk: add Broadcom VK driver

In reply to kbuild test robot

All the kbuild and sparse issues should be resolved in PATCH v4.

Quoted 88 lines · kbuild test robot

Hi Scott,

I love your patch! Perhaps something to improve:

[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on next-20200421]
[cannot apply to char-misc/char-misc-testing kselftest/next linus/master v5.7-rc2] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Scott-Branden/firmware-add-partial-read-support-in-request_firmware_into_buf/20200422-114528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 55623260bb33e2ab849af76edf2253bc04cb241f
reproduce:
         # apt-get install sparse
         # sparse version: v0.6.1-191-gc51a0382-dirty
         make ARCH=x86_64 allmodconfig
         make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate

sparse warnings: (new ones prefixed by >>)

Quoted 6 lines
Quoted 6 lines

drivers/misc/bcm-vk/bcm_vk_dev.c:189:15: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct bcm_vk_peer_log *p_ctl @@ got struct bcm_vk_peer_log *p_ctl @@
drivers/misc/bcm-vk/bcm_vk_dev.c:189:15: sparse: expected struct bcm_vk_peer_log *p_ctl
drivers/misc/bcm-vk/bcm_vk_dev.c:189:15: sparse: got void [noderef] <asn:2> *
drivers/misc/bcm-vk/bcm_vk_dev.c:685:36: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void const [noderef] <asn:1> *from @@ got oderef] <asn:1> *from @@
drivers/misc/bcm-vk/bcm_vk_dev.c:685:36: sparse: expected void const [noderef] <asn:1> *from
drivers/misc/bcm-vk/bcm_vk_dev.c:685:36: sparse: got struct vk_image *arg

drivers/misc/bcm-vk/bcm_vk_dev.c:780:36: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void const [noderef] <asn:1> *from @@ got oderef] <asn:1> *from @@
drivers/misc/bcm-vk/bcm_vk_dev.c:780:36: sparse: expected void const [noderef] <asn:1> *from

Quoted 6 lines
Quoted 6 lines

drivers/misc/bcm-vk/bcm_vk_dev.c:780:36: sparse: got struct vk_reset *arg
drivers/misc/bcm-vk/bcm_vk_dev.c:858:45: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct vk_image *arg @@ got void [nstruct vk_image *arg @@
drivers/misc/bcm-vk/bcm_vk_dev.c:858:45: sparse: expected struct vk_image *arg
drivers/misc/bcm-vk/bcm_vk_dev.c:858:45: sparse: got void [noderef] <asn:1> *argp
drivers/misc/bcm-vk/bcm_vk_dev.c:862:40: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct vk_reset *arg @@ got void [nstruct vk_reset *arg @@
drivers/misc/bcm-vk/bcm_vk_dev.c:862:40: sparse: expected struct vk_reset *arg

    drivers/misc/bcm-vk/bcm_vk_dev.c:862:40: sparse:    got void [noderef] <asn:1> *argp

--

Quoted 1 line
Quoted 1 line

drivers/misc/bcm-vk/bcm_vk_msg.c:507:17: sparse: sparse: cast removes address space '<asn:2>' of expression

drivers/misc/bcm-vk/bcm_vk_msg.c:707:15: sparse: sparse: cast removes address space '<asn:2>' of expression drivers/misc/bcm-vk/bcm_vk_msg.c:715:23: sparse: sparse: cast removes address space '<asn:2>' of expression drivers/misc/bcm-vk/bcm_vk_msg.c:871:31: sparse: sparse: cast removes address space '<asn:2>' of expression drivers/misc/bcm-vk/bcm_vk_msg.c:899:47: sparse: sparse: cast removes address space '<asn:2>' of expression

vim +189 drivers/misc/bcm-vk/bcm_vk_dev.c

    180	
    181	static void bcm_vk_dump_peer_log(struct bcm_vk *vk)
    182	{
    183		struct bcm_vk_peer_log log, *p_ctl;
    184		char loc_buf[BCM_VK_PEER_LOG_LINE_MAX];
    185		int cnt;
    186		struct device *dev = &vk->pdev->dev;
    187		uint data_offset;
    188	
Quoted 1 line

189 p_ctl = vk->bar[BAR_2] + vk->peerlog_off;

    190		log = *p_ctl;
    191		/* do a rmb() to make sure log is updated */
    192		rmb();
    193	
    194		dev_dbg(dev, "Peer PANIC: Size 0x%x(0x%x), [Rd Wr] = [%d %d]\n",
    195			log.buf_size, log.mask, log.rd_idx, log.wr_idx);
    196	
    197		cnt = 0;
    198		data_offset = vk->peerlog_off + sizeof(struct bcm_vk_peer_log);
    199		while (log.rd_idx != log.wr_idx) {
    200			loc_buf[cnt] = vkread8(vk, BAR_2, data_offset + log.rd_idx);
    201	
    202			if ((loc_buf[cnt] == '\0') ||
    203			    (cnt == (BCM_VK_PEER_LOG_LINE_MAX - 1))) {
    204				dev_err(dev, "%s", loc_buf);
    205				cnt = 0;
    206			} else {
    207				cnt++;
    208			}
    209			log.rd_idx = (log.rd_idx + 1) & log.mask;
    210		}
    211		/* update rd idx at the end */
    212		vkwrite32(vk, log.rd_idx, BAR_2, vk->peerlog_off);
    213	}
    214	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#13 lore raw

Re: [PATCH v3 6/7] misc: bcm-vk: add Broadcom VK driver

In reply to Scott Branden
I love your patch! Perhaps something to improve:

Hi Scott,

I love your patch! Perhaps something to improve:

[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on next-20200421]
[cannot apply to char-misc/char-misc-testing kselftest/next linus/master v5.7-rc2] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Scott-Branden/firmware-add-partial-read-support-in-request_firmware_into_buf/20200422-114528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 55623260bb33e2ab849af76edf2253bc04cb241f
config: arc-allyesconfig (attached as .config)
compiler: arc-elf-gcc (GCC) 9.3.0

reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day GCC_VERSION=9.3.0 make.cross ARCH=arc

If you fix the issue, kindly add following tag as appropriate

All warnings (new ones prefixed by >>):

In file included from include/linux/printk.h:326,
from include/linux/kernel.h:15, from include/linux/delay.h:22, from drivers/misc/bcm-vk/bcm_vk_msg.c:6:
drivers/misc/bcm-vk/bcm_vk_msg.c: In function 'bcm_vk_read':

>> drivers/misc/bcm-vk/bcm_vk_msg.c:1096:15: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'size_t' {aka 'unsigned int'} [-Wformat=]
    1096 |  dev_dbg(dev, "Buf count %ld\n", count);
         |               ^~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:125:15: note: in definition of macro '__dynamic_func_call'
     125 |   func(&id, ##__VA_ARGS__);  \
         |               ^~~~~~~~~~~
   include/linux/dynamic_debug.h:157:2: note: in expansion of macro '_dynamic_func_call'
     157 |  _dynamic_func_call(fmt,__dynamic_dev_dbg,   \
         |  ^~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:114:2: note: in expansion of macro 'dynamic_dev_dbg'
     114 |  dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |  ^~~~~~~~~~~~~~~
   include/linux/dev_printk.h:114:23: note: in expansion of macro 'dev_fmt'
     114 |  dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                       ^~~~~~~
>> drivers/misc/bcm-vk/bcm_vk_msg.c:1096:2: note: in expansion of macro 'dev_dbg'
    1096 |  dev_dbg(dev, "Buf count %ld\n", count);
         |  ^~~~~~~
   drivers/misc/bcm-vk/bcm_vk_msg.c:1096:28: note: format string is defined here
    1096 |  dev_dbg(dev, "Buf count %ld\n", count);
         |                          ~~^
         |                            |
         |                            long int
         |                          %d
   In file included from include/linux/printk.h:326,
                    from include/linux/kernel.h:15,
                    from include/linux/delay.h:22,
                    from drivers/misc/bcm-vk/bcm_vk_msg.c:6:
   drivers/misc/bcm-vk/bcm_vk_msg.c: In function 'bcm_vk_write':
   drivers/misc/bcm-vk/bcm_vk_msg.c:1168:15: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'size_t' {aka 'unsigned int'} [-Wformat=]
    1168 |  dev_dbg(dev, "Msg count %ld\n", count);
         |               ^~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:125:15: note: in definition of macro '__dynamic_func_call'
     125 |   func(&id, ##__VA_ARGS__);  \
         |               ^~~~~~~~~~~
   include/linux/dynamic_debug.h:157:2: note: in expansion of macro '_dynamic_func_call'
     157 |  _dynamic_func_call(fmt,__dynamic_dev_dbg,   \
         |  ^~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:114:2: note: in expansion of macro 'dynamic_dev_dbg'
     114 |  dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |  ^~~~~~~~~~~~~~~
   include/linux/dev_printk.h:114:23: note: in expansion of macro 'dev_fmt'
     114 |  dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
         |                       ^~~~~~~
   drivers/misc/bcm-vk/bcm_vk_msg.c:1168:2: note: in expansion of macro 'dev_dbg'
    1168 |  dev_dbg(dev, "Msg count %ld\n", count);
         |  ^~~~~~~
   drivers/misc/bcm-vk/bcm_vk_msg.c:1168:28: note: format string is defined here
    1168 |  dev_dbg(dev, "Msg count %ld\n", count);
         |                          ~~^
         |                            |
         |                            long int
         |                          %d
   In file included from include/linux/device.h:15,
                    from include/linux/pci.h:37,
                    from drivers/misc/bcm-vk/bcm_vk.h:11,
                    from drivers/misc/bcm-vk/bcm_vk_msg.c:15:
   drivers/misc/bcm-vk/bcm_vk_msg.c:1172:16: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'size_t' {aka 'unsigned int'} [-Wformat=]
    1172 |   dev_err(dev, "Failure with size %ld not multiple of %ld\n",
         |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:19:22: note: in definition of macro 'dev_fmt'
      19 | #define dev_fmt(fmt) fmt
         |                      ^~~
>> drivers/misc/bcm-vk/bcm_vk_msg.c:1172:3: note: in expansion of macro 'dev_err'
    1172 |   dev_err(dev, "Failure with size %ld not multiple of %ld\n",
         |   ^~~~~~~
   drivers/misc/bcm-vk/bcm_vk_msg.c:1172:37: note: format string is defined here
    1172 |   dev_err(dev, "Failure with size %ld not multiple of %ld\n",
         |                                   ~~^
         |                                     |
         |                                     long int
         |                                   %d
   In file included from include/linux/device.h:15,
                    from include/linux/pci.h:37,
                    from drivers/misc/bcm-vk/bcm_vk.h:11,
                    from drivers/misc/bcm-vk/bcm_vk_msg.c:15:
>> drivers/misc/bcm-vk/bcm_vk_msg.c:1172:16: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'unsigned int' [-Wformat=]
    1172 |   dev_err(dev, "Failure with size %ld not multiple of %ld\n",
         |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dev_printk.h:19:22: note: in definition of macro 'dev_fmt'
      19 | #define dev_fmt(fmt) fmt
         |                      ^~~
>> drivers/misc/bcm-vk/bcm_vk_msg.c:1172:3: note: in expansion of macro 'dev_err'
    1172 |   dev_err(dev, "Failure with size %ld not multiple of %ld\n",
         |   ^~~~~~~
   drivers/misc/bcm-vk/bcm_vk_msg.c:1172:57: note: format string is defined here
    1172 |   dev_err(dev, "Failure with size %ld not multiple of %ld\n",
         |                                                       ~~^
         |                                                         |
         |                                                         long int
         |                                                       %d

vim +1096 drivers/misc/bcm-vk/bcm_vk_msg.c

1076
1077 ssize_t bcm_vk_read(struct file *p_file,

  1078			    char __user *buf,
  1079			    size_t count,
  1080			    loff_t *f_pos)
  1081	{
  1082		ssize_t rc = -ENOMSG;
  1083		struct bcm_vk_ctx *ctx = p_file->private_data;
  1084		struct bcm_vk *vk = container_of(ctx->miscdev, struct bcm_vk,
  1085						 miscdev);
  1086		struct device *dev = &vk->pdev->dev;
  1087		struct bcm_vk_msg_chan *chan = &vk->to_h_msg_chan;
  1088		struct bcm_vk_wkent *entry = NULL;
  1089		uint32_t q_num;
  1090		uint32_t rsp_length;
  1091		bool found = false;
  1092	
  1093		if (!bcm_vk_drv_access_ok(vk))
  1094			return -EPERM;
  1095	
> 1096		dev_dbg(dev, "Buf count %ld\n", count);
  1097		found = false;
  1098	
  1099		/*
  1100		 * search through the pendq on the to_h chan, and return only those
  1101		 * that belongs to the same context.  Search is always from the high to
  1102		 * the low priority queues
  1103		 */
  1104		spin_lock(&chan->pendq_lock);
  1105		for (q_num = 0; q_num < chan->q_nr; q_num++) {
  1106			list_for_each_entry(entry, &chan->pendq[q_num], node) {
  1107				if (entry->ctx->idx == ctx->idx) {
  1108					if (count >=
  1109					    (entry->to_h_blks * VK_MSGQ_BLK_SIZE)) {
  1110						list_del(&entry->node);
  1111						ctx->pend_cnt--;
  1112						found = true;
  1113					} else {
  1114						/* buffer not big enough */
  1115						rc = -EMSGSIZE;
  1116					}
  1117					goto read_loop_exit;
  1118				}
  1119			}
  1120		}
  1121	read_loop_exit:
  1122		spin_unlock(&chan->pendq_lock);
  1123	
  1124		if (found) {
  1125			/* retrieve the passed down msg_id */
  1126			BCM_VK_SET_MSG_ID(&entry->to_h_msg[0], entry->usr_msg_id);
  1127			rsp_length = entry->to_h_blks * VK_MSGQ_BLK_SIZE;
  1128			if (copy_to_user(buf, entry->to_h_msg, rsp_length) == 0)
  1129				rc = rsp_length;
  1130	
  1131			bcm_vk_free_wkent(dev, entry);
  1132		} else if (rc == -EMSGSIZE) {
  1133			struct vk_msg_blk tmp_msg = entry->to_h_msg[0];
  1134	
  1135			/*
  1136			 * in this case, return just the first block, so
  1137			 * that app knows what size it is looking for.
  1138			 */
  1139			BCM_VK_SET_MSG_ID(&tmp_msg, entry->usr_msg_id);
  1140			tmp_msg.size = entry->to_h_blks - 1;
  1141			if (copy_to_user(buf, &tmp_msg, VK_MSGQ_BLK_SIZE) != 0) {
  1142				dev_err(dev, "Error return 1st block in -EMSGSIZE\n");
  1143				rc = -EFAULT;
  1144			}
  1145		}
  1146		return rc;
  1147	}
  1148	
  1149	ssize_t bcm_vk_write(struct file *p_file,
  1150			     const char __user *buf,
  1151			     size_t count,
  1152			     loff_t *f_pos)
  1153	{
  1154		ssize_t rc;
  1155		struct bcm_vk_ctx *ctx = p_file->private_data;
  1156		struct bcm_vk *vk = container_of(ctx->miscdev, struct bcm_vk,
  1157						 miscdev);
  1158		struct bcm_vk_msgq *msgq;
  1159		struct device *dev = &vk->pdev->dev;
  1160		struct bcm_vk_wkent *entry;
  1161		uint32_t sgl_extra_blks;
  1162		uint32_t q_num;
  1163		uint32_t msg_size;
  1164	
  1165		if (!bcm_vk_drv_access_ok(vk))
  1166			return -EPERM;
  1167	
  1168		dev_dbg(dev, "Msg count %ld\n", count);
  1169	
  1170		/* first, do sanity check where count should be multiple of basic blk */
  1171		if (count & (VK_MSGQ_BLK_SIZE - 1)) {
> 1172			dev_err(dev, "Failure with size %ld not multiple of %ld\n",

1173 count, VK_MSGQ_BLK_SIZE);
1174 rc = -EINVAL;
1175 goto write_err;
1176 }
1177
1178 /* allocate the work entry + buffer for size count and inband sgl */
1179 entry = kzalloc(sizeof(*entry) + count + vk->ib_sgl_size,
1180 GFP_KERNEL);
1181 if (!entry) {
1182 rc = -ENOMEM;
1183 goto write_err;
1184 }
1185
1186 /* now copy msg from user space, and then formulate the work entry */
1187 if (copy_from_user(&entry->to_v_msg[0], buf, count)) {
1188 rc = -EFAULT;
1189 goto write_free_ent;
1190 }
1191
1192 entry->to_v_blks = count >> VK_MSGQ_BLK_SZ_SHIFT;
1193 entry->ctx = ctx;
1194
1195 /* do a check on the blk size which could not exceed queue space */
1196 q_num = BCM_VK_GET_Q(&entry->to_v_msg[0]);
1197 msgq = vk->to_v_msg_chan.msgq[q_num];
1198 if (entry->to_v_blks + (vk->ib_sgl_size >> VK_MSGQ_BLK_SZ_SHIFT)
1199 > (msgq->size - 1)) {
1200 dev_err(dev, "Blk size %d exceed max queue size allowed %d\n",
1201 entry->to_v_blks, msgq->size - 1);
1202 rc = -EINVAL;
1203 goto write_free_ent;
1204 }
1205
1206 /* Use internal message id */
1207 entry->usr_msg_id = BCM_VK_GET_MSG_ID(&entry->to_v_msg[0]);
1208 rc = bcm_vk_get_msg_id(vk);
1209 if (rc == VK_MSG_ID_OVERFLOW) {
1210 dev_err(dev, "msg_id overflow\n");
1211 rc = -EOVERFLOW;
1212 goto write_free_ent;
1213 }
1214 BCM_VK_SET_MSG_ID(&entry->to_v_msg[0], rc);
1215
1216 dev_dbg(dev,
1217 "Message ctx id %d, usr_msg_id 0x%x sent msg_id 0x%x\n",
1218 ctx->idx, entry->usr_msg_id,
1219 BCM_VK_GET_MSG_ID(&entry->to_v_msg[0]));
1220
1221 /* Convert any pointers to sg list */
1222 if (entry->to_v_msg[0].function_id == VK_FID_TRANS_BUF) {
1223 unsigned int num_planes;
1224 int dir;
1225 struct _vk_data *data;
1226
1227 /*
1228 * check if we are in reset, if so, no buffer transfer is
1229 * allowed and return error.
1230 */
1231 if (vk->reset_pid) {
1232 dev_dbg(dev, "No Transfer allowed during reset, pid %d.\n",
1233 ctx->pid);
1234 rc = -EACCES;
1235 goto write_free_msgid;
1236 }
1237
1238 num_planes = entry->to_v_msg[0].args[0] & VK_CMD_PLANES_MASK;
1239 if ((entry->to_v_msg[0].args[0] & VK_CMD_MASK)
1240 == VK_CMD_DOWNLOAD) {
1241 dir = DMA_FROM_DEVICE;
1242 } else {
1243 dir = DMA_TO_DEVICE;
1244 }
1245
1246 /* Calculate vk_data location */
1247 /* Go to end of the message */
1248 msg_size = entry->to_v_msg[0].size;
1249 if (msg_size > entry->to_v_blks) {
1250 rc = -EMSGSIZE;
1251 goto write_free_msgid;
1252 }
1253
1254 data = (struct _vk_data *)&entry->to_v_msg[msg_size + 1];
1255
1256 /* Now back up to the start of the pointers */
1257 data -= num_planes;
1258
1259 /* Convert user addresses to DMA SG List */
1260 rc = bcm_vk_sg_alloc(dev, entry->dma, dir, data, num_planes);
1261 if (rc)
1262 goto write_free_msgid;
1263
1264 /* try to embed inband sgl */
1265 sgl_extra_blks = bcm_vk_append_ib_sgl(vk, entry, data,
1266 num_planes);
1267 entry->to_v_blks += sgl_extra_blks;
1268 entry->to_v_msg[0].size += sgl_extra_blks;
1269 }
1270
1271 /*
1272 * store work entry to pending queue until a response is received.
1273 * This needs to be done before enqueuing the message
1274 */
1275 bcm_vk_append_pendq(&vk->to_v_msg_chan, q_num, entry);
1276
1277 rc = bcm_to_v_msg_enqueue(vk, entry);
1278 if (rc) {
1279 dev_err(dev, "Fail to enqueue msg to to_v queue\n");
1280
1281 /* remove message from pending list */
1282 entry = bcm_vk_dequeue_pending
1283 (vk,
1284 &vk->to_v_msg_chan,
1285 q_num,
1286 BCM_VK_GET_MSG_ID(&entry->to_v_msg[0]));
1287 goto write_free_ent;
1288 }
1289
1290 return count;
1291
1292 write_free_msgid:
1293 bcm_vk_msgid_bitmap_clear(vk,
1294 BCM_VK_GET_MSG_ID(&entry->to_v_msg[0]), 1);
1295 write_free_ent:
1296 kfree(entry);
1297 write_err:
1298 return rc;
1299 }
1300

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#14 lore raw

Re: [PATCH v3 6/7] misc: bcm-vk: add Broadcom VK driver

In reply to Scott Branden
I love your patch! Perhaps something to improve:

Hi Scott,

I love your patch! Perhaps something to improve:

[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on next-20200421]
[cannot apply to char-misc/char-misc-testing kselftest/next linus/master v5.7-rc2] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Scott-Branden/firmware-add-partial-read-support-in-request_firmware_into_buf/20200422-114528
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 55623260bb33e2ab849af76edf2253bc04cb241f
config: i386-allyesconfig (attached as .config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

If you fix the issue, kindly add following tag as appropriate

All warnings (new ones prefixed by >>):

drivers/misc/bcm-vk/bcm_vk_dev.c: In function 'bcm_vk_sync_card_info':

>> drivers/misc/bcm-vk/bcm_vk_dev.c:329:31: warning: right shift count >= width of type [-Wshift-count-overflow]
      vkwrite32(vk, vk->tdma_addr >> 32, BAR_1,
                                  ^~
   drivers/misc/bcm-vk/bcm_vk_dev.c: In function 'bcm_vk_buf_notify':
   drivers/misc/bcm-vk/bcm_vk_dev.c:377:30: warning: right shift count >= width of type [-Wshift-count-overflow]
     vkwrite32(vk, host_buf_addr >> 32, BAR_1,
                                 ^~

vim +329 drivers/misc/bcm-vk/bcm_vk_dev.c

314
315 static int bcm_vk_sync_card_info(struct bcm_vk *vk)
316 {
317 uint32_t rdy_marker = vkread32(vk, BAR_1, VK_BAR1_MSGQ_DEF_RDY);
318
319 /* check for marker, but allow diags mode to skip sync */
320 if (!bcm_vk_msgq_marker_valid(vk))
321 return (rdy_marker == VK_BAR1_DIAG_RDY_MARKER ? 0 : -EINVAL);
322
323 /*
324 * Write down scratch addr which is used for DMA. For
325 * signed part, BAR1 is accessible only after boot2 has come
326 * up
327 */
328 if (vk->tdma_addr) {

 > 329			vkwrite32(vk, vk->tdma_addr >> 32, BAR_1,

330 VK_BAR1_SCRATCH_OFF_LO);
331 vkwrite32(vk, (uint32_t)vk->tdma_addr, BAR_1,
332 VK_BAR1_SCRATCH_OFF_HI);
333 vkwrite32(vk, nr_scratch_pages * PAGE_SIZE, BAR_1,
334 VK_BAR1_SCRATCH_SZ_ADDR);
335 }
336
337 /* get static card info, only need to read once */
338 bcm_vk_get_card_info(vk);
339
340 return 0;
341 }
342

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

author maintainer
#15 lore raw

PATCH v3 7/7 MAINTAINERS: bcm-vk: add maintainer for Broadcom VK Driver

In reply to Scott Branden

Add maintainer entry for new Broadcom VK Driver

---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)
MAINTAINERS +7 -0
index e64e5db31497..ca6a66c09db3 100644
@@ -3610,6 +3610,13 @@ L:	[email protected]
 S:	Supported
 F:	drivers/net/ethernet/broadcom/tg3.*
 
+BROADCOM VK DRIVER
+M:	Scott Branden <[email protected]>
+L:	[email protected]
+S:	Supported
+F:	drivers/misc/bcm-vk/
+F:	include/uapi/linux/misc/bcm_vk.h
+
 BROCADE BFA FC SCSI DRIVER
 M:	Anil Gurumurthy <[email protected]>
 M:	Sudarsana Kalluru <[email protected]>
Signature · 1 line
2.17.1