summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-02-13 11:24:38 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2026-02-13 11:24:38 -0800
commitc87c79345ea8ff917354e9223d44034e4aef2690 (patch)
treeab1e6748dc6b9bc22ec54d8949b51299205c349c
parentb52343d1cb47bb27ca32a3f4952cc2fd3cd165bf (diff)
parent68e25613ed4d06c987a42b0589f54ce88c13477c (diff)
Merge tag 'uml-for-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux
Pull UML updates from Johannes Berg: "UML was _really_ quiet, with just four small commits: - two signal handling fixes - dynamic addition of virtio devices - a single code cleanup" * tag 'uml-for-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux: arch/um: remove unused varible err in remove_files_and_dir() um: virtio_uml: Support adding devices via mconsole um: Handle SIGCHLD in seccomp mode like other IRQ signals um: Preserve errno within signal handler
-rw-r--r--arch/um/drivers/virtio_uml.c51
-rw-r--r--arch/um/os-Linux/signal.c9
-rw-r--r--arch/um/os-Linux/umid.c3
3 files changed, 57 insertions, 6 deletions
diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
index 6cf1152a1a4e..c24da0cf1627 100644
--- a/arch/um/drivers/virtio_uml.c
+++ b/arch/um/drivers/virtio_uml.c
@@ -34,6 +34,7 @@
#include <irq_kern.h>
#include <init.h>
#include <os.h>
+#include "mconsole_kern.h"
#include "vhost_user.h"
#define MAX_SUPPORTED_QUEUE_SIZE 256
@@ -1282,6 +1283,7 @@ static struct device vu_cmdline_parent = {
.release = vu_cmdline_release_dev,
};
+static DEFINE_MUTEX(vu_cmdline_lock);
static bool vu_cmdline_parent_registered;
static int vu_cmdline_id;
@@ -1309,7 +1311,7 @@ static void vu_conn_broken(struct work_struct *wk)
vu_unregister_cmdline_device(&pdata->pdev->dev, NULL);
}
-static int vu_cmdline_set(const char *device, const struct kernel_param *kp)
+static int vu_cmdline_set_device(const char *device)
{
const char *ids = strchr(device, ':');
unsigned int virtio_device_id;
@@ -1321,6 +1323,8 @@ static int vu_cmdline_set(const char *device, const struct kernel_param *kp)
if (!ids || ids == device)
return -EINVAL;
+ guard(mutex)(&vu_cmdline_lock);
+
processed = sscanf(ids, ":%u%n:%d%n",
&virtio_device_id, &consumed,
&vu_cmdline_id, &consumed);
@@ -1366,6 +1370,11 @@ free:
return err;
}
+static int vu_cmdline_set(const char *device, const struct kernel_param *kp)
+{
+ return vu_cmdline_set_device(device);
+}
+
static int vu_cmdline_get_device(struct device *dev, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1380,6 +1389,8 @@ static int vu_cmdline_get_device(struct device *dev, void *data)
static int vu_cmdline_get(char *buffer, const struct kernel_param *kp)
{
+ guard(mutex)(&vu_cmdline_lock);
+
buffer[0] = '\0';
if (vu_cmdline_parent_registered)
device_for_each_child(&vu_cmdline_parent, buffer,
@@ -1403,6 +1414,8 @@ __uml_help(vu_cmdline_param_ops,
static void vu_unregister_cmdline_devices(void)
{
+ guard(mutex)(&vu_cmdline_lock);
+
if (vu_cmdline_parent_registered) {
device_for_each_child(&vu_cmdline_parent, NULL,
vu_unregister_cmdline_device);
@@ -1411,6 +1424,42 @@ static void vu_unregister_cmdline_devices(void)
}
}
+static int vu_mc_config(char *str, char **error_out)
+{
+ if (*str != '=') {
+ *error_out = "Invalid config";
+ return -EINVAL;
+ }
+ str += 1;
+ return vu_cmdline_set_device(str);
+}
+
+static int vu_mc_id(char **str, int *start_out, int *end_out)
+{
+ return -EOPNOTSUPP;
+}
+
+static int vu_mc_remove(int n, char **error_out)
+{
+ return -EOPNOTSUPP;
+}
+
+static struct mc_device virtio_uml_mc = {
+ .list = LIST_HEAD_INIT(virtio_uml_mc.list),
+ .name = "virtio_uml.device",
+ .config = vu_mc_config,
+ .get_config = NULL,
+ .id = vu_mc_id,
+ .remove = vu_mc_remove,
+};
+
+static int __init virtio_uml_mc_init(void)
+{
+ mconsole_register_dev(&virtio_uml_mc);
+ return 0;
+}
+late_initcall(virtio_uml_mc_init);
+
/* Platform driver */
static const struct of_device_id virtio_uml_match[] = {
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 327fb3c52fc7..6c993bc8c78e 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -16,6 +16,7 @@
#include <as-layout.h>
#include <kern_util.h>
#include <os.h>
+#include <skas.h>
#include <sysdep/mcontext.h>
#include <um_malloc.h>
#include <sys/ucontext.h>
@@ -36,7 +37,6 @@ void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *, void *mc) =
static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
{
struct uml_pt_regs r;
- int save_errno = errno;
r.is_user = 0;
if (sig == SIGSEGV) {
@@ -50,8 +50,6 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
unblock_signals_trace();
(*sig_info[sig])(sig, si, &r, mc);
-
- errno = save_errno;
}
/*
@@ -207,8 +205,11 @@ static void hard_handler(int sig, siginfo_t *si, void *p)
{
ucontext_t *uc = p;
mcontext_t *mc = &uc->uc_mcontext;
+ int save_errno = errno;
(*handlers[sig])(sig, (struct siginfo *)si, mc);
+
+ errno = save_errno;
}
void set_handler(int sig)
@@ -224,6 +225,8 @@ void set_handler(int sig)
sigaddset(&action.sa_mask, SIGIO);
sigaddset(&action.sa_mask, SIGWINCH);
sigaddset(&action.sa_mask, SIGALRM);
+ if (using_seccomp)
+ sigaddset(&action.sa_mask, SIGCHLD);
if (sig == SIGSEGV)
flags |= SA_NODEFER;
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index eb523ab1e218..6b488be2c545 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -136,7 +136,7 @@ out:
static inline int is_umdir_used(char *dir)
{
char pid[sizeof("nnnnnnnnn")], *end, *file;
- int fd, p, n, err;
+ int fd, p, n;
size_t filelen = strlen(dir) + sizeof("/pid") + 1;
file = malloc(filelen);
@@ -155,7 +155,6 @@ static inline int is_umdir_used(char *dir)
goto out;
}
- err = 0;
n = read(fd, pid, sizeof(pid));
if (n < 0) {
printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "