diff --git a/include/sys/sysmacros.h b/include/sys/sysmacros.h
index 35f7cb5c1e..29dcda7fa7 100644
--- a/include/sys/sysmacros.h
+++ b/include/sys/sysmacros.h
@@ -143,7 +143,7 @@
 
 /* Missing globals */
 extern char spl_version[16];
-extern long spl_hostid;
+extern unsigned long spl_hostid;
 extern char hw_serial[11];
 
 /* Missing misc functions */
diff --git a/module/spl/spl-generic.c b/module/spl/spl-generic.c
index 2b43f0c337..680655d0f8 100644
--- a/module/spl/spl-generic.c
+++ b/module/spl/spl-generic.c
@@ -52,8 +52,10 @@
 char spl_version[16] = "SPL v" SPL_META_VERSION;
 EXPORT_SYMBOL(spl_version);
 
-long spl_hostid = 0;
+unsigned long spl_hostid = 0;
 EXPORT_SYMBOL(spl_hostid);
+module_param(spl_hostid, ulong, 0644);
+MODULE_PARM_DESC(spl_hostid, "The system hostid.");
 
 char hw_serial[HW_HOSTID_LEN] = "<none>";
 EXPORT_SYMBOL(hw_serial);
@@ -362,13 +364,18 @@ struct new_utsname *__utsname(void)
 }
 EXPORT_SYMBOL(__utsname);
 
+#define GET_HOSTID_CMD \
+	"exec 0</dev/null " \
+	"     1>/proc/sys/kernel/spl/hostid " \
+	"     2>/dev/null; " \
+	"hostid"
+
 static int
 set_hostid(void)
 {
-	char sh_path[] = "/bin/sh";
-	char *argv[] = { sh_path,
+	char *argv[] = { "/bin/sh",
 	                 "-c",
-	                 "/usr/bin/hostid >/proc/sys/kernel/spl/hostid",
+	                 GET_HOSTID_CMD,
 	                 NULL };
 	char *envp[] = { "HOME=/",
 	                 "TERM=linux",
@@ -382,7 +389,7 @@ set_hostid(void)
 	 * '/usr/bin/hostid' and redirect the result to /proc/sys/spl/hostid
 	 * for us to use.  It's a horrific solution but it will do for now.
 	 */
-	rc = call_usermodehelper(sh_path, argv, envp, 1);
+	rc = call_usermodehelper(argv[0], argv, envp, 1);
 	if (rc)
 		printk("SPL: Failed user helper '%s %s %s', rc = %d\n",
 		       argv[0], argv[1], argv[2], rc);
@@ -475,7 +482,8 @@ __init spl_init(void)
 	if ((rc = zlib_init()))
 		SGOTO(out9, rc);
 
-	if ((rc = set_hostid()))
+	/* Get the hostid if it was not passed as a module parameter. */
+	if (spl_hostid == 0 && (rc = set_hostid()))
 		SGOTO(out10, rc = -EADDRNOTAVAIL);
 
 #ifndef HAVE_KALLSYMS_LOOKUP_NAME
diff --git a/module/spl/spl-proc.c b/module/spl/spl-proc.c
index d2b295ce0a..fa0d1fb3d3 100644
--- a/module/spl/spl-proc.c
+++ b/module/spl/spl-proc.c
@@ -487,7 +487,6 @@ SPL_PROC_HANDLER(proc_doslab)
 SPL_PROC_HANDLER(proc_dohostid)
 {
         int len, rc = 0;
-        int32_t val;
         char *end, str[32];
         SENTRY;
 
@@ -499,17 +498,15 @@ SPL_PROC_HANDLER(proc_dohostid)
                 if (rc < 0)
                         SRETURN(rc);
 
-                val = simple_strtol(str, &end, 16);
+                spl_hostid = simple_strtoul(str, &end, 16);
                 if (str == end)
                         SRETURN(-EINVAL);
 
-                spl_hostid = (long) val;
-                (void) snprintf(hw_serial, HW_HOSTID_LEN, "%u",
-                               (val >= 0) ? val : -val);
+                (void) snprintf(hw_serial, HW_HOSTID_LEN, "%lu", spl_hostid);
                 hw_serial[HW_HOSTID_LEN - 1] = '\0';
                 *ppos += *lenp;
         } else {
-                len = snprintf(str, sizeof(str), "%lx", spl_hostid);
+                len = snprintf(str, sizeof(str), "%lux", spl_hostid);
                 if (*ppos >= len)
                         rc = 0;
                 else