summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Kelly <mike@weatherwax.co.uk>2025-08-31 23:35:56 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2025-08-31 23:37:01 +0200
commit2ccdc970f7d83a4a5fc3c2c6e89f94a10e36d2ac (patch)
tree981a3c4210e700814a5eba2c091b3587bf9e3cf6
parenta632f784548f910522e13b7cdb683249b27712bd (diff)
rumpdisk: Set USER_DEVICE ktype on device ports
so that IPC messages destined for rumpdisk will use page lists rather than page map entries, to make them safe against swapping out.
-rw-r--r--configure.ac1
-rw-r--r--rumpdisk/block-rump.c22
2 files changed, 23 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index d7e33e56..4ddb1fe9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -153,6 +153,7 @@ AC_CACHE_CHECK([for libio],
# Check if libc contains these functions.
AC_CHECK_FUNCS(file_exec_paths exec_exec_paths _hurd_exec_paths)
AC_CHECK_FUNCS(_hurd_libc_proc_init)
+AC_CHECK_FUNCS(mach_port_set_ktype)
# Compatibility with glibc < 2.28
AC_CHECK_FUNCS(file_utimens)
diff --git a/rumpdisk/block-rump.c b/rumpdisk/block-rump.c
index d2fc0f1c..aa8afb4f 100644
--- a/rumpdisk/block-rump.c
+++ b/rumpdisk/block-rump.c
@@ -27,6 +27,7 @@
#include <mach.h>
#include <mach/gnumach.h>
+#include <mach/port.h>
#include <hurd.h>
#include <hurd/ports.h>
#include <device/device.h>
@@ -329,6 +330,27 @@ rumpdisk_device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_ty
return err;
}
+#ifdef HAVE_MACH_PORT_SET_KTYPE
+ /* Configure the receive port as a USER_DEVICE so that IPC messages
+ destined for rumpdisk will use page lists rather than page map
+ entries. This strategy prevents pages that are referenced in the
+ message body from being swapped out until the message has been
+ processed.
+ */
+ err = mach_port_set_ktype (master_host,
+ mach_task_self (),
+ bd->port.port_right,
+ MACH_PORT_RIGHT_RECEIVE,
+ MACH_PORT_KTYPE_USER_DEVICE);
+ if (err != 0)
+ {
+ fprintf (stderr,
+ "Warning: mach_port_set_ktype failed, swapping will be unreliable: %s\n",
+ strerror (err));
+ fflush (stderr);
+ }
+#endif
+
bd->taken = 1;
snprintf (bd->name, DISK_NAME_LEN, "%s", name);
bd->rump_fd = fd;