Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Nov 2018 00:21:49 +0000 (UTC)
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r340421 - head/usr.sbin/cpucontrol
Message-ID:  <201811140021.wAE0LnWL008210@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Wed Nov 14 00:21:49 2018
New Revision: 340421
URL: https://svnweb.freebsd.org/changeset/base/340421

Log:
  cpucontrol(8): De-duplicate common update logic
  
  Every µcode-updater must open the cpucontrol devfs node RDWR, open a
  firmware file, validate the FW file has a positive length, mmap it, etc.
  De-duplicate that identical logic between every individual platform.
  
  Also, constify references to the readonly-mapped firmware files while here.
  
  Sponsored by:	Dell EMC Isilon

Modified:
  head/usr.sbin/cpucontrol/amd.c
  head/usr.sbin/cpucontrol/amd10h.c
  head/usr.sbin/cpucontrol/cpucontrol.c
  head/usr.sbin/cpucontrol/cpucontrol.h
  head/usr.sbin/cpucontrol/intel.c
  head/usr.sbin/cpucontrol/via.c

Modified: head/usr.sbin/cpucontrol/amd.c
==============================================================================
--- head/usr.sbin/cpucontrol/amd.c	Wed Nov 14 00:12:04 2018	(r340420)
+++ head/usr.sbin/cpucontrol/amd.c	Wed Nov 14 00:21:49 2018	(r340421)
@@ -73,16 +73,16 @@ amd_probe(int fd)
 }
 
 void
-amd_update(const char *dev, const char *path)
+amd_update(const struct ucode_update_params *params)
 {
-	int fd, devfd;
+	int devfd;
 	unsigned int i;
-	struct stat st;
-	uint32_t *fw_image;
-	amd_fw_header_t *fw_header;
+	const char *dev, *path;
+	const uint32_t *fw_image;
+	const amd_fw_header_t *fw_header;
 	uint32_t sum;
 	uint32_t signature;
-	uint32_t *fw_data;
+	const uint32_t *fw_data;
 	size_t fw_size;
 	cpuctl_cpuid_args_t idargs = {
 		.level  = 1,	/* Request signature. */
@@ -90,16 +90,14 @@ amd_update(const char *dev, const char *path)
 	cpuctl_update_args_t args;
 	int error;
 
+	dev = params->dev_path;
+	path = params->fw_path;
+	devfd = params->devfd;
+	fw_image = params->fwimage;
+
 	assert(path);
 	assert(dev);
 
-	fd  = -1;
-	fw_image = MAP_FAILED;
-	devfd = open(dev, O_RDWR);
-	if (devfd < 0) {
-		WARN(0, "could not open %s for writing", dev);
-		return;
-	}
 	error = ioctl(devfd, CPUCTL_CPUID, &idargs);
 	if (error < 0) {
 		WARN(0, "ioctl()");
@@ -115,37 +113,18 @@ amd_update(const char *dev, const char *path)
 	/*
 	 * Open the firmware file.
 	 */
-	fd = open(path, O_RDONLY, 0);
-	if (fd < 0) {
-		WARN(0, "open(%s)", path);
-		goto fail;
-	}
-	error = fstat(fd, &st);
-	if (error != 0) {
-		WARN(0, "fstat(%s)", path);
-		goto fail;
-	}
-	if (st.st_size < 0 || (unsigned)st.st_size < sizeof(*fw_header)) {
+	if (params->fwsize < sizeof(*fw_header)) {
 		WARNX(2, "file too short: %s", path);
 		goto fail;
 	}
-	/*
-	 * mmap the whole image.
-	 */
-	fw_image = (uint32_t *)mmap(NULL, st.st_size, PROT_READ,
-	    MAP_PRIVATE, fd, 0);
-	if  (fw_image == MAP_FAILED) {
-		WARN(0, "mmap(%s)", path);
-		goto fail;
-	}
-	fw_header = (amd_fw_header_t *)fw_image;
+	fw_header = (const amd_fw_header_t *)fw_image;
 	if ((fw_header->magic >> 8) != AMD_MAGIC) {
 		WARNX(2, "%s is not a valid amd firmware: version mismatch",
 		    path);
 		goto fail;
 	}
-	fw_data = (uint32_t *)(fw_header + 1);
-	fw_size = (st.st_size - sizeof(*fw_header)) / sizeof(uint32_t);
+	fw_data = (const uint32_t *)(fw_header + 1);
+	fw_size = (params->fwsize - sizeof(*fw_header)) / sizeof(uint32_t);
 
 	/*
 	 * Check the primary checksum.
@@ -160,8 +139,8 @@ amd_update(const char *dev, const char *path)
 	if (signature == fw_header->signature) {
 		fprintf(stderr, "%s: updating cpu %s... ", path, dev);
 
-		args.data = fw_image;
-		args.size = st.st_size;
+		args.data = __DECONST(void *, fw_image);
+		args.size = params->fwsize;
 		error = ioctl(devfd, CPUCTL_UPDATE, &args);
 		if (error < 0) {
 			fprintf(stderr, "failed.\n");
@@ -172,12 +151,5 @@ amd_update(const char *dev, const char *path)
 	}
 
 fail:
-	if (fd >= 0)
-		close(fd);
-	if (devfd >= 0)
-		close(devfd);
-	if (fw_image != MAP_FAILED)
-		if(munmap(fw_image, st.st_size) != 0)
-			warn("munmap(%s)", path);
 	return;
 }

Modified: head/usr.sbin/cpucontrol/amd10h.c
==============================================================================
--- head/usr.sbin/cpucontrol/amd10h.c	Wed Nov 14 00:12:04 2018	(r340420)
+++ head/usr.sbin/cpucontrol/amd10h.c	Wed Nov 14 00:21:49 2018	(r340421)
@@ -88,9 +88,8 @@ amd10h_probe(int fd)
  * source code.
  */
 void
-amd10h_update(const char *dev, const char *path)
+amd10h_update(const struct ucode_update_params *params)
 {
-	struct stat st;
 	cpuctl_cpuid_args_t idargs;
 	cpuctl_msr_args_t msrargs;
 	cpuctl_update_args_t args;
@@ -100,27 +99,27 @@ amd10h_update(const char *dev, const char *path)
 	const section_header_t *section_header;
 	const container_header_t *container_header;
 	const uint8_t *fw_data;
-	uint8_t *fw_image;
+	const uint8_t *fw_image;
+	const char *dev, *path;
 	size_t fw_size;
 	size_t selected_size;
 	uint32_t revision;
 	uint32_t new_rev;
 	uint32_t signature;
 	uint16_t equiv_id;
-	int fd, devfd;
+	int devfd;
 	unsigned int i;
 	int error;
 
+	dev = params->dev_path;
+	path = params->fw_path;
+	devfd = params->devfd;
+	fw_image = params->fwimage;
+	fw_size = params->fwsize;
+
 	assert(path);
 	assert(dev);
 
-	fd = -1;
-	fw_image = MAP_FAILED;
-	devfd = open(dev, O_RDWR);
-	if (devfd < 0) {
-		WARN(0, "could not open %s for writing", dev);
-		return;
-	}
 	idargs.level = 1;
 	error = ioctl(devfd, CPUCTL_CPUID, &idargs);
 	if (error < 0) {
@@ -149,33 +148,15 @@ amd10h_update(const char *dev, const char *path)
 	 * Open the firmware file.
 	 */
 	WARNX(1, "checking %s for update.", path);
-	fd = open(path, O_RDONLY, 0);
-	if (fd < 0) {
-		WARN(0, "open(%s)", path);
-		goto done;
-	}
-	error = fstat(fd, &st);
-	if (error != 0) {
-		WARN(0, "fstat(%s)", path);
-		goto done;
-	}
-	if (st.st_size < 0 || (size_t)st.st_size <
+	if (fw_size <
 	    (sizeof(*container_header) + sizeof(*section_header))) {
 		WARNX(2, "file too short: %s", path);
 		goto done;
 	}
-	fw_size = st.st_size;
 
 	/*
 	 * mmap the whole image.
 	 */
-	fw_image = (uint8_t *)mmap(NULL, st.st_size, PROT_READ,
-	    MAP_PRIVATE, fd, 0);
-	if (fw_image == MAP_FAILED) {
-		WARN(0, "mmap(%s)", path);
-		goto done;
-	}
-
 	fw_data = fw_image;
 	container_header = (const container_header_t *)fw_data;
 	if (container_header->magic != AMD_10H_MAGIC) {
@@ -306,12 +287,5 @@ amd10h_update(const char *dev, const char *path)
 		WARNX(0, "revision after update %#x", new_rev);
 
 done:
-	if (fd >= 0)
-		close(fd);
-	if (devfd >= 0)
-		close(devfd);
-	if (fw_image != MAP_FAILED)
-		if (munmap(fw_image, st.st_size) != 0)
-			warn("munmap(%s)", path);
 	return;
 }

Modified: head/usr.sbin/cpucontrol/cpucontrol.c
==============================================================================
--- head/usr.sbin/cpucontrol/cpucontrol.c	Wed Nov 14 00:12:04 2018	(r340420)
+++ head/usr.sbin/cpucontrol/cpucontrol.c	Wed Nov 14 00:21:49 2018	(r340421)
@@ -34,18 +34,20 @@
 __FBSDID("$FreeBSD$");
 
 #include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <fcntl.h>
-#include <err.h>
 #include <sysexits.h>
-#include <dirent.h>
 
 #include <sys/queue.h>
 #include <sys/param.h>
 #include <sys/types.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/cpuctl.h>
@@ -74,16 +76,6 @@ int	verbosity_level = 0;
 #define	HIGH(val)	(uint32_t)(((val) >> 32) & 0xffffffff)
 #define	LOW(val)	(uint32_t)((val) & 0xffffffff)
 
-/*
- * Macros for freeing SLISTs, probably must be in /sys/queue.h
- */
-#define	SLIST_FREE(head, field, freef) do {				\
-		typeof(SLIST_FIRST(head)) __elm0;			\
-		typeof(SLIST_FIRST(head)) __elm;			\
-		SLIST_FOREACH_SAFE(__elm, (head), field, __elm0)	\
-			(void)(freef)(__elm);				\
-} while(0);
-
 struct datadir {
 	const char		*path;
 	SLIST_ENTRY(datadir)	next;
@@ -102,7 +94,6 @@ static struct ucode_handler {
 #define NHANDLERS (sizeof(handlers) / sizeof(*handlers))
 
 static void	usage(void);
-static int	isdir(const char *path);
 static int	do_cpuid(const char *cmdarg, const char *dev);
 static int	do_cpuid_count(const char *cmdarg, const char *dev);
 static int	do_msr(const char *cmdarg, const char *dev);
@@ -123,20 +114,6 @@ usage(void)
 }
 
 static int
-isdir(const char *path)
-{
-	int error;
-	struct stat st;
-
-	error = stat(path, &st);
-	if (error < 0) {
-		WARN(0, "stat(%s)", path);
-		return (error);
-	}
-	return (st.st_mode & S_IFDIR);
-}
-
-static int
 do_cpuid(const char *cmdarg, const char *dev)
 {
 	unsigned int level;
@@ -361,16 +338,77 @@ do_eval_cpu_features(const char *dev)
 }
 
 static int
+try_a_fw_image(const char *dev_path, int devfd, int fwdfd, const char *dpath,
+    const char *fname, struct ucode_handler *handler)
+{
+	struct ucode_update_params parm;
+	struct stat st;
+	char *fw_path;
+	void *fw_map;
+	int fwfd, rc;
+
+	rc = 0;
+	fw_path = NULL;
+	fw_map = MAP_FAILED;
+	fwfd = openat(fwdfd, fname, O_RDONLY);
+	if (fwfd < 0) {
+		WARN(0, "openat(%s, %s)", dpath, fname);
+		goto out;
+	}
+
+	rc = asprintf(&fw_path, "%s/%s", dpath, fname);
+	if (rc == -1) {
+		WARNX(0, "out of memory");
+		rc = ENOMEM;
+		goto out;
+	}
+
+	rc = fstat(fwfd, &st);
+	if (rc != 0) {
+		WARN(0, "fstat(%s)", fw_path);
+		rc = 0;
+		goto out;
+	}
+	if (st.st_size <= 0) {
+		WARN(0, "%s: empty", fw_path);
+		goto out;
+	}
+
+	fw_map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fwfd, 0);
+	if (fw_map == MAP_FAILED) {
+		WARN(0, "mmap(%s)", fw_path);
+		goto out;
+	}
+
+
+	memset(&parm, 0, sizeof(parm));
+	parm.devfd = devfd;
+	parm.fwimage = fw_map;
+	parm.fwsize = st.st_size;
+	parm.dev_path = dev_path;
+	parm.fw_path = fw_path;
+
+	handler->update(&parm);
+
+out:
+	if (fw_map != MAP_FAILED)
+		munmap(fw_map, st.st_size);
+	free(fw_path);
+	if (fwfd >= 0)
+		close(fwfd);
+	return (rc);
+}
+
+static int
 do_update(const char *dev)
 {
-	int fd;
+	int fd, fwdfd;
 	unsigned int i;
 	int error;
 	struct ucode_handler *handler;
 	struct datadir *dir;
 	DIR *dirp;
 	struct dirent *direntry;
-	char buf[MAXPATHLEN];
 
 	fd = open(dev, O_RDONLY);
 	if (fd < 0) {
@@ -379,7 +417,7 @@ do_update(const char *dev)
 	}
 
 	/*
-	 * Find the appropriate handler for device.
+	 * Find the appropriate handler for CPU.
 	 */
 	for (i = 0; i < NHANDLERS; i++)
 		if (handlers[i].probe(fd) == 0)
@@ -387,39 +425,54 @@ do_update(const char *dev)
 	if (i < NHANDLERS)
 		handler = &handlers[i];
 	else {
-		WARNX(0, "cannot find the appropriate handler for device");
+		WARNX(0, "cannot find the appropriate handler for %s", dev);
 		close(fd);
 		return (1);
 	}
 	close(fd);
 
+	fd = open(dev, O_RDWR);
+	if (fd < 0) {
+		WARN(0, "error opening %s for writing", dev);
+		return (1);
+	}
+
 	/*
 	 * Process every image in specified data directories.
 	 */
 	SLIST_FOREACH(dir, &datadirs, next) {
-		dirp = opendir(dir->path);
-		if (dirp == NULL) {
-			WARNX(1, "skipping directory %s: not accessible", dir->path);
+		fwdfd = open(dir->path, O_RDONLY);
+		if (fwdfd < 0) {
+			WARN(1, "skipping directory %s: not accessible", dir->path);
 			continue;
 		}
+		dirp = fdopendir(fwdfd);
+		if (dirp == NULL) {
+			WARNX(0, "out of memory");
+			close(fwdfd);
+			close(fd);
+			return (1);
+		}
+
 		while ((direntry = readdir(dirp)) != NULL) {
 			if (direntry->d_namlen == 0)
 				continue;
-			error = snprintf(buf, sizeof(buf), "%s/%s", dir->path,
-			    direntry->d_name);
-			if ((unsigned)error >= sizeof(buf))
-				WARNX(0, "skipping %s, buffer too short",
-				    direntry->d_name);
-			if (isdir(buf) != 0) {
-				WARNX(2, "skipping %s: is a directory", buf);
+			if (direntry->d_type == DT_DIR)
 				continue;
+
+			error = try_a_fw_image(dev, fd, fwdfd, dir->path,
+			    direntry->d_name, handler);
+			if (error != 0) {
+				closedir(dirp);
+				close(fd);
+				return (1);
 			}
-			handler->update(dev, buf);
 		}
 		error = closedir(dirp);
 		if (error != 0)
 			WARN(0, "closedir(%s)", dir->path);
 	}
+	close(fd);
 	return (0);
 }
 
@@ -441,6 +494,7 @@ datadir_add(const char *path)
 int
 main(int argc, char *argv[])
 {
+	struct datadir *elm;
 	int c, flags;
 	const char *cmdarg;
 	const char *dev;
@@ -511,6 +565,9 @@ main(int argc, char *argv[])
 	default:
 		usage();	/* Only one command can be selected. */
 	}
-	SLIST_FREE(&datadirs, next, free);
+	while ((elm = SLIST_FIRST(&datadirs)) != NULL) {
+		SLIST_REMOVE_HEAD(&datadirs, next);
+		free(elm);
+	}
 	return (error == 0 ? 0 : 1);
 }

Modified: head/usr.sbin/cpucontrol/cpucontrol.h
==============================================================================
--- head/usr.sbin/cpucontrol/cpucontrol.h	Wed Nov 14 00:12:04 2018	(r340420)
+++ head/usr.sbin/cpucontrol/cpucontrol.h	Wed Nov 14 00:21:49 2018	(r340421)
@@ -30,8 +30,17 @@
 #ifndef CPUCONTROL_H
 #define	CPUCONTROL_H
 
+#include <stddef.h>
+
 typedef int ucode_probe_t(int fd);
-typedef void ucode_update_t(const char *dev, const char *image);
+struct ucode_update_params {
+	int devfd;		/* RDWR handle to cpucontrol device */
+	const void *fwimage;	/* READ mapping of firmware image */
+	size_t fwsize;		/* Non-zero size of firmware image */
+	const char *dev_path;	/* cpucontrol device path, for logging */
+	const char *fw_path;	/* firmware image path, for logging */
+};
+typedef void ucode_update_t(const struct ucode_update_params *params);
 
 extern int verbosity_level;
 

Modified: head/usr.sbin/cpucontrol/intel.c
==============================================================================
--- head/usr.sbin/cpucontrol/intel.c	Wed Nov 14 00:12:04 2018	(r340420)
+++ head/usr.sbin/cpucontrol/intel.c	Wed Nov 14 00:21:49 2018	(r340421)
@@ -76,23 +76,23 @@ intel_probe(int fd)
 }
 
 void
-intel_update(const char *dev, const char *path)
+intel_update(const struct ucode_update_params *params)
 {
-	int fd, devfd;
-	struct stat st;
-	uint32_t *fw_image;
+	int devfd;
+	const char *dev, *path;
+	const uint32_t *fw_image;
 	int have_ext_table;
 	uint32_t sum;
 	unsigned int i;
 	size_t payload_size;
-	intel_fw_header_t *fw_header;
-	intel_cpu_signature_t *ext_table;
-	intel_ext_header_t *ext_header;
+	const intel_fw_header_t *fw_header;
+	const intel_cpu_signature_t *ext_table;
+	const intel_ext_header_t *ext_header;
 	uint32_t sig, signature, flags;
 	int32_t revision;
 	ssize_t ext_size;
 	size_t ext_table_size;
-	void *fw_data;
+	const void *fw_data;
 	size_t data_size, total_size;
 	cpuctl_msr_args_t msrargs = {
 		.msr = MSR_BIOS_SIGN,
@@ -104,18 +104,17 @@ intel_update(const char *dev, const char *path)
 	cpuctl_update_args_t args;
 	int error;
 
+	dev = params->dev_path;
+	path = params->fw_path;
+	devfd = params->devfd;
+	fw_image = params->fwimage;
+
 	assert(path);
 	assert(dev);
 
-	fd = -1;
-	fw_image = MAP_FAILED;
 	ext_table = NULL;
 	ext_header = NULL;
-	devfd = open(dev, O_RDWR);
-	if (devfd < 0) {
-		WARN(0, "could not open %s for writing", dev);
-		return;
-	}
+
 	error = ioctl(devfd, CPUCTL_WRMSR, &msrargs);
 	if (error < 0) {
 		WARN(0, "ioctl(%s)", dev);
@@ -151,31 +150,12 @@ intel_update(const char *dev, const char *path)
 	/*
 	 * Open firmware image.
 	 */
-	fd = open(path, O_RDONLY, 0);
-	if (fd < 0) {
-		WARN(0, "open(%s)", path);
-		goto fail;
-	}
-	error = fstat(fd, &st);
-	if (error != 0) {
-		WARN(0, "fstat(%s)", path);
-		goto fail;
-	}
-	if (st.st_size < 0 || (unsigned)st.st_size < sizeof(*fw_header)) {
+	if (params->fwsize < sizeof(*fw_header)) {
 		WARNX(2, "file too short: %s", path);
 		goto fail;
 	}
 
-	/*
-	 * mmap the whole image.
-	 */
-	fw_image = (uint32_t *)mmap(NULL, st.st_size, PROT_READ,
-	    MAP_PRIVATE, fd, 0);
-	if  (fw_image == MAP_FAILED) {
-		WARN(0, "mmap(%s)", path);
-		goto fail;
-	}
-	fw_header = (intel_fw_header_t *)fw_image;
+	fw_header = (const intel_fw_header_t *)fw_image;
 	if (fw_header->header_version != INTEL_HEADER_VERSION ||
 	    fw_header->loader_revision != INTEL_LOADER_REVISION) {
 		WARNX(2, "%s is not a valid intel firmware: version mismatch",
@@ -193,7 +173,7 @@ intel_update(const char *dev, const char *path)
 		total_size = data_size + sizeof(*fw_header);
 	else
 		total_size = fw_header->total_size;
-	if (total_size > (unsigned)st.st_size || st.st_size < 0) {
+	if (total_size > params->fwsize) {
 		WARNX(2, "file too short: %s", path);
 		goto fail;
 	}
@@ -204,7 +184,7 @@ intel_update(const char *dev, const char *path)
 	 */
 	sum = 0;
 	for (i = 0; i < (payload_size / sizeof(uint32_t)); i++)
-		sum += *((uint32_t *)fw_image + i);
+		sum += *((const uint32_t *)fw_image + i);
 	if (sum != 0) {
 		WARNX(2, "%s: update data checksum invalid", path);
 		goto fail;
@@ -217,9 +197,9 @@ intel_update(const char *dev, const char *path)
 	have_ext_table = 0;
 
 	if (ext_size > (signed)sizeof(*ext_header)) {
-		ext_header =
-		    (intel_ext_header_t *)((char *)fw_image + payload_size);
-		ext_table = (intel_cpu_signature_t *)(ext_header + 1);
+		ext_header = (const intel_ext_header_t *)
+		    ((const char *)fw_image + payload_size);
+		ext_table = (const intel_cpu_signature_t *)(ext_header + 1);
 
 		/*
 		 * Check the extended table size.
@@ -236,7 +216,7 @@ intel_update(const char *dev, const char *path)
 		 */
 		sum = 0;
 		for (i = 0; i < (ext_table_size / sizeof(uint32_t)); i++)
-			sum += *((uint32_t *)ext_header + i);
+			sum += *((const uint32_t *)ext_header + i);
 		if (sum != 0) {
 			WARNX(2,
 			    "%s: extended signature table checksum invalid",
@@ -273,7 +253,7 @@ matched:
 	}
 	fprintf(stderr, "%s: updating cpu %s from rev %#x to rev %#x... ",
 	    path, dev, revision, fw_header->revision);
-	args.data = fw_data;
+	args.data = __DECONST(void *, fw_data);
 	args.size = data_size;
 	error = ioctl(devfd, CPUCTL_UPDATE, &args);
 	if (error < 0) {
@@ -286,11 +266,5 @@ matched:
 	fprintf(stderr, "done.\n");
 
 fail:
-	if (fw_image != MAP_FAILED)
-		if (munmap(fw_image, st.st_size) != 0)
-			warn("munmap(%s)", path);
-	if (devfd >= 0)
-		close(devfd);
-	if (fd >= 0)
-		close(fd);
+	return;
 }

Modified: head/usr.sbin/cpucontrol/via.c
==============================================================================
--- head/usr.sbin/cpucontrol/via.c	Wed Nov 14 00:12:04 2018	(r340420)
+++ head/usr.sbin/cpucontrol/via.c	Wed Nov 14 00:21:49 2018	(r340421)
@@ -76,18 +76,18 @@ via_probe(int fd)
 }
 
 void
-via_update(const char *dev, const char *path)
+via_update(const struct ucode_update_params *params)
 {
-	int fd, devfd;
-	struct stat st;
-	uint32_t *fw_image;
+	int devfd;
+	const char *dev, *path;
+	const uint32_t *fw_image;
 	uint32_t sum;
 	unsigned int i;
 	size_t payload_size;
-	via_fw_header_t *fw_header;
+	const via_fw_header_t *fw_header;
 	uint32_t signature;
 	int32_t revision;
-	void *fw_data;
+	const void *fw_data;
 	size_t data_size, total_size;
 	cpuctl_msr_args_t msrargs = {
 		.msr = MSR_IA32_PLATFORM_ID,
@@ -98,17 +98,14 @@ via_update(const char *dev, const char *path)
 	cpuctl_update_args_t args;
 	int error;
 
+	dev = params->dev_path;
+	path = params->fw_path;
+	devfd = params->devfd;
+	fw_image = params->fwimage;
+
 	assert(path);
 	assert(dev);
 
-	fd = -1;
-	devfd = -1;
-	fw_image = MAP_FAILED;
-	devfd = open(dev, O_RDWR);
-	if (devfd < 0) {
-		WARN(0, "could not open %s for writing", dev);
-		return;
-	}
 	error = ioctl(devfd, CPUCTL_CPUID, &idargs);
 	if (error < 0) {
 		WARN(0, "ioctl(%s)", dev);
@@ -134,34 +131,13 @@ via_update(const char *dev, const char *path)
 	WARNX(2, "found cpu type %#x family %#x model %#x stepping %#x.",
 	    (signature >> 12) & 0x03, (signature >> 8) & 0x0f,
 	    (signature >> 4) & 0x0f, (signature >> 0) & 0x0f);
-	/*
-	 * Open firmware image.
-	 */
-	fd = open(path, O_RDONLY, 0);
-	if (fd < 0) {
-		WARN(0, "open(%s)", path);
-		goto fail;
-	}
-	error = fstat(fd, &st);
-	if (error != 0) {
-		WARN(0, "fstat(%s)", path);
-		goto fail;
-	}
-	if (st.st_size < 0 || (unsigned)st.st_size < sizeof(*fw_header)) {
+
+	if (params->fwsize < sizeof(*fw_header)) {
 		WARNX(2, "file too short: %s", path);
 		goto fail;
 	}
 
-	/*
-	 * mmap the whole image.
-	 */
-	fw_image = (uint32_t *)mmap(NULL, st.st_size, PROT_READ,
-	    MAP_PRIVATE, fd, 0);
-	if  (fw_image == MAP_FAILED) {
-		WARN(0, "mmap(%s)", path);
-		goto fail;
-	}
-	fw_header = (via_fw_header_t *)fw_image;
+	fw_header = (const via_fw_header_t *)fw_image;
 	if (fw_header->signature != VIA_HEADER_SIGNATURE ||
 	    fw_header->loader_revision != VIA_LOADER_REVISION) {
 		WARNX(2, "%s is not a valid via firmware: version mismatch",
@@ -170,7 +146,7 @@ via_update(const char *dev, const char *path)
 	}
 	data_size = fw_header->data_size;
 	total_size = fw_header->total_size;
-	if (total_size > (unsigned)st.st_size || st.st_size < 0) {
+	if (total_size > params->fwsize) {
 		WARNX(2, "file too short: %s", path);
 		goto fail;
 	}
@@ -181,7 +157,7 @@ via_update(const char *dev, const char *path)
 	 */
 	sum = 0;
 	for (i = 0; i < (payload_size / sizeof(uint32_t)); i++)
-		sum += *((uint32_t *)fw_image + i);
+		sum += *((const uint32_t *)fw_image + i);
 	if (sum != 0) {
 		WARNX(2, "%s: update data checksum invalid", path);
 		goto fail;
@@ -202,25 +178,18 @@ via_update(const char *dev, const char *path)
 	}
 	fprintf(stderr, "%s: updating cpu %s from rev %#x to rev %#x... ",
 			path, dev, revision, fw_header->revision);
-	args.data = fw_data;
+	args.data = __DECONST(void *, fw_data);
 	args.size = data_size;
 	error = ioctl(devfd, CPUCTL_UPDATE, &args);
 	if (error < 0) {
                error = errno;
-		fprintf(stderr, "failed.\n");
+	       fprintf(stderr, "failed.\n");
                errno = error;
-		WARN(0, "ioctl()");
-		goto fail;
+	       WARN(0, "ioctl()");
+	       goto fail;
 	}
 	fprintf(stderr, "done.\n");
 
 fail:
-	if (fw_image != MAP_FAILED)
-		if (munmap(fw_image, st.st_size) != 0)
-			warn("munmap(%s)", path);
-	if (devfd >= 0)
-		close(devfd);
-	if (fd >= 0)
-		close(fd);
 	return;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811140021.wAE0LnWL008210>