Merge tag 'uml-for-linux-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux

Pull uml updates from Johannes Berg:
 "Mostly cleanups, except:

   - dynamic addition of vfio passthrough devices

   - implementation of HAVE_SYSCALL_TRACEPOINTS"

* tag 'uml-for-linux-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux:
  um: Replace __ASSEMBLY__ with __ASSEMBLER__ in the usermode headers
  um: Stop tracking stub's PID via userspace_pid[]
  um: Remove the pid parameter of handle_trap()
  um: Use err consistently in userspace()
  um: vfio: Support adding devices via mconsole
  um: rtc: Avoid shadowing err in uml_rtc_start()
  um: Avoid redefining ARCH_HAS_CACHE_LINE_SIZE
  um: Make mm_list and mm_list_lock static
  um: Make unscheduled_userspace_iterations static
  um: Re-evaluate thread flags repeatedly
  um: simplify syscall header files
  um/ptrace: Implement HAVE_SYSCALL_TRACEPOINTS
  um/x86: Add system call table to header file
  um: virt-pci: Switch to msi_create_parent_irq_domain()
  um: virtio_pcidev: Rename UM_PCI_STAT_WAITING
This commit is contained in:
Linus Torvalds
2025-07-29 20:31:45 -07:00
28 changed files with 151 additions and 151 deletions
+2 -3
View File
@@ -6,6 +6,7 @@ config UML
bool
default y
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
select ARCH_HAS_CACHE_LINE_SIZE
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
@@ -35,6 +36,7 @@ config UML
select HAVE_RUST
select ARCH_HAS_UBSAN
select HAVE_ARCH_TRACEHOOK
select HAVE_SYSCALL_TRACEPOINTS
select THREAD_INFO_IN_TASK
config MMU
@@ -82,9 +84,6 @@ config NR_CPUS
range 1 1
default 1
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
source "arch/$(HEADER_ARCH)/um/Kconfig"
config MAY_HAVE_RUNTIME_DEPS
+1
View File
@@ -160,6 +160,7 @@ config UML_RTC
config UML_PCI
bool
select FORCE_PCI
select IRQ_MSI_LIB
select UML_IOMEM_EMULATION
select UML_DMA_EMULATION
select PCI_MSI
+1 -1
View File
@@ -28,7 +28,7 @@ int uml_rtc_start(bool timetravel)
int err;
if (timetravel) {
int err = os_pipe(uml_rtc_irq_fds, 1, 1);
err = os_pipe(uml_rtc_irq_fds, 1, 1);
if (err)
goto fail;
} else {
+57 -5
View File
@@ -16,6 +16,7 @@
#include <init.h>
#include <os.h>
#include "mconsole_kern.h"
#include "virt-pci.h"
#include "vfio_user.h"
@@ -60,6 +61,7 @@ static LIST_HEAD(uml_vfio_groups);
static DEFINE_MUTEX(uml_vfio_groups_mtx);
static LIST_HEAD(uml_vfio_devices);
static DEFINE_MUTEX(uml_vfio_devices_mtx);
static int uml_vfio_set_container(int group_fd)
{
@@ -581,32 +583,44 @@ static struct uml_vfio_device *uml_vfio_find_device(const char *device)
return NULL;
}
static int uml_vfio_cmdline_set(const char *device, const struct kernel_param *kp)
static struct uml_vfio_device *uml_vfio_add_device(const char *device)
{
struct uml_vfio_device *dev;
int fd;
guard(mutex)(&uml_vfio_devices_mtx);
if (uml_vfio_container.fd < 0) {
fd = uml_vfio_user_open_container();
if (fd < 0)
return fd;
return ERR_PTR(fd);
uml_vfio_container.fd = fd;
}
if (uml_vfio_find_device(device))
return -EEXIST;
return ERR_PTR(-EEXIST);
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
dev->name = kstrdup(device, GFP_KERNEL);
if (!dev->name) {
kfree(dev);
return -ENOMEM;
return ERR_PTR(-ENOMEM);
}
list_add_tail(&dev->list, &uml_vfio_devices);
return dev;
}
static int uml_vfio_cmdline_set(const char *device, const struct kernel_param *kp)
{
struct uml_vfio_device *dev;
dev = uml_vfio_add_device(device);
if (IS_ERR(dev))
return PTR_ERR(dev);
return 0;
}
@@ -629,6 +643,42 @@ __uml_help(uml_vfio_cmdline_param_ops,
" through multiple PCI devices to UML.\n\n"
);
static int uml_vfio_mc_config(char *str, char **error_out)
{
struct uml_vfio_device *dev;
if (*str != '=') {
*error_out = "Invalid config";
return -EINVAL;
}
str += 1;
dev = uml_vfio_add_device(str);
if (IS_ERR(dev))
return PTR_ERR(dev);
uml_vfio_open_device(dev);
return 0;
}
static int uml_vfio_mc_id(char **str, int *start_out, int *end_out)
{
return -EOPNOTSUPP;
}
static int uml_vfio_mc_remove(int n, char **error_out)
{
return -EOPNOTSUPP;
}
static struct mc_device uml_vfio_mc = {
.list = LIST_HEAD_INIT(uml_vfio_mc.list),
.name = "vfio_uml.device",
.config = uml_vfio_mc_config,
.get_config = NULL,
.id = uml_vfio_mc_id,
.remove = uml_vfio_mc_remove,
};
static int __init uml_vfio_init(void)
{
struct uml_vfio_device *dev, *n;
@@ -639,6 +689,8 @@ static int __init uml_vfio_init(void)
list_for_each_entry_safe(dev, n, &uml_vfio_devices, list)
uml_vfio_open_device(dev);
mconsole_register_dev(&uml_vfio_mc);
return 0;
}
late_initcall(uml_vfio_init);
+21 -22
View File
@@ -7,6 +7,7 @@
#include <linux/pci.h>
#include <linux/logic_iomem.h>
#include <linux/of_platform.h>
#include <linux/irqchip/irq-msi-lib.h>
#include <linux/irqdomain.h>
#include <linux/msi.h>
#include <linux/unaligned.h>
@@ -29,7 +30,6 @@ static struct um_pci_device *um_pci_platform_device;
static struct um_pci_device_reg um_pci_devices[MAX_DEVICES];
static struct fwnode_handle *um_pci_fwnode;
static struct irq_domain *um_pci_inner_domain;
static struct irq_domain *um_pci_msi_domain;
static unsigned long um_pci_msi_used[BITS_TO_LONGS(MAX_MSI_VECTORS)];
static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset,
@@ -400,21 +400,24 @@ static void um_pci_inner_domain_free(struct irq_domain *domain,
}
static const struct irq_domain_ops um_pci_inner_domain_ops = {
.select = msi_lib_irq_domain_select,
.alloc = um_pci_inner_domain_alloc,
.free = um_pci_inner_domain_free,
};
static struct irq_chip um_pci_msi_irq_chip = {
.name = "UM virtual PCIe MSI",
.irq_mask = pci_msi_mask_irq,
.irq_unmask = pci_msi_unmask_irq,
};
#define UM_PCI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
MSI_FLAG_USE_DEF_CHIP_OPS | \
MSI_FLAG_NO_AFFINITY)
#define UM_PCI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
MSI_FLAG_PCI_MSIX)
static struct msi_domain_info um_pci_msi_domain_info = {
.flags = MSI_FLAG_USE_DEF_DOM_OPS |
MSI_FLAG_USE_DEF_CHIP_OPS |
MSI_FLAG_PCI_MSIX,
.chip = &um_pci_msi_irq_chip,
static const struct msi_parent_ops um_pci_msi_parent_ops = {
.required_flags = UM_PCI_MSI_FLAGS_REQUIRED,
.supported_flags = UM_PCI_MSI_FLAGS_SUPPORTED,
.bus_select_token = DOMAIN_BUS_NEXUS,
.bus_select_mask = MATCH_PCI_MSI,
.prefix = "UM-virtual-",
.init_dev_msi_info = msi_lib_init_dev_msi_info,
};
static struct resource busn_resource = {
@@ -559,17 +562,14 @@ static int __init um_pci_init(void)
goto free;
}
um_pci_inner_domain = irq_domain_create_linear(um_pci_fwnode, MAX_MSI_VECTORS,
&um_pci_inner_domain_ops, NULL);
if (!um_pci_inner_domain) {
err = -ENOMEM;
goto free;
}
struct irq_domain_info info = {
.fwnode = um_pci_fwnode,
.ops = &um_pci_inner_domain_ops,
.size = MAX_MSI_VECTORS,
};
um_pci_msi_domain = pci_msi_create_irq_domain(um_pci_fwnode,
&um_pci_msi_domain_info,
um_pci_inner_domain);
if (!um_pci_msi_domain) {
um_pci_inner_domain = msi_create_parent_irq_domain(&info, &um_pci_msi_parent_ops);
if (!um_pci_inner_domain) {
err = -ENOMEM;
goto free;
}
@@ -611,7 +611,6 @@ device_initcall(um_pci_init);
static void __exit um_pci_exit(void)
{
irq_domain_remove(um_pci_msi_domain);
irq_domain_remove(um_pci_inner_domain);
pci_free_resource_list(&bridge->windows);
pci_free_host_bridge(bridge);
+4 -4
View File
@@ -42,7 +42,7 @@ struct virtio_pcidev_device {
void *extra_ptrs[VIRTIO_PCIDEV_WRITE_BUFS + 1];
DECLARE_BITMAP(used_bufs, VIRTIO_PCIDEV_WRITE_BUFS);
#define UM_PCI_STAT_WAITING 0
#define VIRTIO_PCIDEV_STAT_WAITING 0
unsigned long status;
bool platform;
@@ -172,7 +172,7 @@ static int virtio_pcidev_send_cmd(struct virtio_pcidev_device *dev,
}
/* kick and poll for getting a response on the queue */
set_bit(UM_PCI_STAT_WAITING, &dev->status);
set_bit(VIRTIO_PCIDEV_STAT_WAITING, &dev->status);
virtqueue_kick(dev->cmd_vq);
ret = 0;
@@ -193,7 +193,7 @@ static int virtio_pcidev_send_cmd(struct virtio_pcidev_device *dev,
}
udelay(1);
}
clear_bit(UM_PCI_STAT_WAITING, &dev->status);
clear_bit(VIRTIO_PCIDEV_STAT_WAITING, &dev->status);
if (bounce_out)
memcpy(out, buf->data, out_size);
@@ -439,7 +439,7 @@ static void virtio_pcidev_cmd_vq_cb(struct virtqueue *vq)
void *cmd;
int len;
if (test_bit(UM_PCI_STAT_WAITING, &dev->status))
if (test_bit(VIRTIO_PCIDEV_STAT_WAITING, &dev->status))
return;
while ((cmd = virtqueue_get_buf(vq, &len)))
+2 -2
View File
@@ -4,7 +4,7 @@
#include <asm/processor.h>
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
#if defined(__KERNEL__) && !defined(__ASSEMBLER__)
#include <asm/asm.h>
#include <linux/bitops.h>
@@ -137,5 +137,5 @@ t_no:
#define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
boot_cpu_data.x86_model
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLER__) */
#endif /* _ASM_UM_CPUFEATURE_H */
+2 -2
View File
@@ -5,7 +5,7 @@
#include <linux/compiler.h>
#include <linux/threads.h>
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLER__
struct task_struct;
extern struct task_struct *cpu_tasks[NR_CPUS];
@@ -18,6 +18,6 @@ static __always_inline struct task_struct *get_current(void)
#define current get_current()
#endif /* __ASSEMBLY__ */
#endif /* __ASSEMBLER__ */
#endif /* __ASM_CURRENT_H */
+1 -8
View File
@@ -16,11 +16,6 @@
#define activate_mm activate_mm
static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
{
/*
* This is called by fs/exec.c and sys_unshare()
* when the new ->mm is used for the first time.
*/
__switch_mm(&new->context.id);
}
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
@@ -28,11 +23,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
{
unsigned cpu = smp_processor_id();
if(prev != next){
if (prev != next) {
cpumask_clear_cpu(cpu, mm_cpumask(prev));
cpumask_set_cpu(cpu, mm_cpumask(next));
if(next != &init_mm)
__switch_mm(&next->context.id);
}
}
+2 -2
View File
@@ -11,7 +11,7 @@
#include <vdso/page.h>
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLER__
struct page;
@@ -94,7 +94,7 @@ extern unsigned long uml_physmem;
#include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h>
#endif /* __ASSEMBLY__ */
#endif /* __ASSEMBLER__ */
#ifdef CONFIG_X86_32
#define __HAVE_ARCH_GATE_AREA 1
+1 -1
View File
@@ -6,7 +6,7 @@
#ifndef __UM_PTRACE_GENERIC_H
#define __UM_PTRACE_GENERIC_H
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLER__
#include <sysdep/ptrace.h>
+7 -1
View File
@@ -9,7 +9,7 @@
#define THREAD_SIZE_ORDER CONFIG_KERNEL_STACK_ORDER
#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLER__
#include <asm/types.h>
#include <asm/page.h>
@@ -43,6 +43,8 @@ struct thread_info {
#define TIF_NOTIFY_RESUME 8
#define TIF_SECCOMP 9 /* secure computing */
#define TIF_SINGLESTEP 10 /* single stepping userspace */
#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -50,7 +52,11 @@ struct thread_info {
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL | \
_TIF_NOTIFY_RESUME)
#endif
+1 -1
View File
@@ -26,7 +26,7 @@
#define STUB_DATA_PAGES 2 /* must be a power of two */
#define STUB_END (STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE)
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLER__
#include <sysdep/ptrace.h>
-2
View File
@@ -19,8 +19,6 @@ struct mm_id {
int syscall_fd_map[STUB_MAX_FDS];
};
void __switch_mm(struct mm_id *mm_idp);
void notify_mm_kill(int pid);
#endif
-1
View File
@@ -9,7 +9,6 @@
#include <sysdep/ptrace.h>
extern int using_seccomp;
extern int userspace_pid[];
extern void new_thread_handler(void);
extern void handle_syscall(struct uml_pt_regs *regs);
-2
View File
@@ -26,8 +26,6 @@ void flush_thread(void)
get_safe_registers(current_pt_regs()->regs.gp,
current_pt_regs()->regs.fp);
__switch_mm(&current->mm->context.id);
}
void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
+11 -7
View File
@@ -82,14 +82,18 @@ struct task_struct *__switch_to(struct task_struct *from, struct task_struct *to
void interrupt_end(void)
{
struct pt_regs *regs = &current->thread.regs;
unsigned long thread_flags;
if (need_resched())
schedule();
if (test_thread_flag(TIF_SIGPENDING) ||
test_thread_flag(TIF_NOTIFY_SIGNAL))
do_signal(regs);
if (test_thread_flag(TIF_NOTIFY_RESUME))
resume_user_mode_work(regs);
thread_flags = read_thread_flags();
while (thread_flags & _TIF_WORK_MASK) {
if (thread_flags & _TIF_NEED_RESCHED)
schedule();
if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs);
if (thread_flags & _TIF_NOTIFY_RESUME)
resume_user_mode_work(regs);
thread_flags = read_thread_flags();
}
}
int get_current_pid(void)
+9
View File
@@ -9,6 +9,9 @@
#include <linux/uaccess.h>
#include <asm/ptrace-abi.h>
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
void user_enable_single_step(struct task_struct *child)
{
set_tsk_thread_flag(child, TIF_SINGLESTEP);
@@ -126,6 +129,9 @@ int syscall_trace_enter(struct pt_regs *regs)
UPT_SYSCALL_ARG3(&regs->regs),
UPT_SYSCALL_ARG4(&regs->regs));
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, UPT_SYSCALL_NR(&regs->regs));
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return 0;
@@ -142,6 +148,9 @@ void syscall_trace_leave(struct pt_regs *regs)
if (test_thread_flag(TIF_SINGLESTEP))
send_sigtrap(&regs->regs, 0);
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_exit(regs, PT_REGS_SYSCALL_RET(regs));
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
+2 -2
View File
@@ -20,8 +20,8 @@
/* Ensure the stub_data struct covers the allocated area */
static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE);
spinlock_t mm_list_lock;
struct list_head mm_list;
static spinlock_t mm_list_lock;
static struct list_head mm_list;
int init_new_context(struct task_struct *task, struct mm_struct *mm)
{
-2
View File
@@ -26,8 +26,6 @@ static int __init start_kernel_proc(void *unused)
return 0;
}
extern int userspace_pid[];
static char cpu0_irqstack[THREAD_SIZE] __aligned(THREAD_SIZE);
int __init start_uml(void)

Some files were not shown because too many files have changed in this diff Show More