Index | Thread | Search

From:
Hans-Jörg Höxer <hshoexer@genua.de>
Subject:
vmd(8): Reset psp(4) on startup
To:
<tech@openbsd.org>
Date:
Mon, 4 Nov 2024 15:57:40 +0100

Download raw body.

Thread
  • Hans-Jörg Höxer:

    vmd(8): Reset psp(4) on startup

Hi,

let vmd(8) reset psp(4) by doing a shutdown and init.

This helps when hacking on vmd(8) and crashing it.  The psp(4) reset
cleans up all remnants of dead VMs from psp(4).  Otherwise one would
have to reboot the machine.

Take care,
HJ.

---------------------------------------------------------------------------
commit 1e62bba842a52179d151ccf0b37e7e9077dd75f0
Author: Hans-Joerg Hoexer <hshoexer@genua.de>
Date:   Tue Oct 1 16:04:09 2024 +0200

    vmd(8): Reset psp(4) on startup
    
    Use shutdown and init to reset psp(4) on vmd startup.
    
    This helps when hacking on vmd(8) and crashing it.  The psp(4) reset
    cleans up all remnants of dead VMs from psp(4).  Otherwise one would
    have to reboot the machine.

diff --git a/usr.sbin/vmd/psp.c b/usr.sbin/vmd/psp.c
index 70ab91b22b1..e0f93a0ee77 100644
--- a/usr.sbin/vmd/psp.c
+++ b/usr.sbin/vmd/psp.c
@@ -21,6 +21,8 @@
 
 #include <dev/ic/pspvar.h>
 
+#include <errno.h>
+#include <fcntl.h>
 #include <string.h>
 
 #include "vmd.h"
@@ -271,3 +273,62 @@ psp_guest_shutdown(uint32_t handle)
 
 	return (0);
 }
+
+/*
+ * Initialize PSP.
+ */
+static int
+psp_init(void)
+{
+	if (ioctl(env->vmd_psp_fd, PSP_IOC_INIT) < 0) {
+		log_warn("%s: ioctl", __func__);
+		return (-1);
+	}
+
+	return (0);
+}
+
+/*
+ * Shutdown PSP.
+ */
+static int
+psp_shutdown(void)
+{
+	if (ioctl(env->vmd_psp_fd, PSP_IOC_SHUTDOWN) < 0) {
+		log_warn("%s: ioctl", __func__);
+		return (-1);
+	}
+
+	return (0);
+}
+
+/*
+ * Reset PSP.
+ *
+ * Shut PSP down, then re-initialize it.  This clears and resets
+ * all active contexts.
+ */
+static int
+psp_reset(void)
+{
+	int	ret;
+
+	if ((ret = psp_shutdown()) < 0 || (ret = psp_init()) < 0)
+		return (ret);
+
+	return (0);
+}
+
+void
+psp_setup(void)
+{
+	env->vmd_psp_fd = open(PSP_NODE, O_RDWR);
+	if (env->vmd_psp_fd == -1) {
+		if (errno != ENXIO)
+			log_debug("%s: failed to open %s", __func__, PSP_NODE);
+		return;
+	}
+
+	if (psp_reset() < 0)
+		fatalx("%s: failed to reset PSP", __func__);
+}
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index 91ac69e6c0d..d433886ab66 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -842,11 +842,8 @@ main(int argc, char **argv)
 	if (!env->vmd_noaction)
 		proc_connect(ps);
 
-	if (env->vmd_noaction == 0 && proc_id == PROC_PARENT) {
-		env->vmd_psp_fd = open(PSP_NODE, O_RDWR);
-		if (env->vmd_psp_fd == -1)
-			log_debug("%s: failed to open %s", __func__, PSP_NODE);
-	}
+	if (env->vmd_noaction == 0 && proc_id == PROC_PARENT)
+		psp_setup();
 
 	if (vmd_configure() == -1)
 		fatalx("configuration failed");
diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h
index 8882b118a4d..d39248aa654 100644
--- a/usr.sbin/vmd/vmd.h
+++ b/usr.sbin/vmd/vmd.h
@@ -591,6 +591,7 @@ int	 psp_launch_measure(uint32_t);
 int	 psp_launch_finish(uint32_t);
 int	 psp_activate(uint32_t, uint32_t);
 int	 psp_guest_shutdown(uint32_t);
+void	 psp_setup(void);
 
 /* sev.c */
 int	sev_init(struct vmd_vm *);