diff options
Diffstat (limited to 'arch/um')
26 files changed, 178 insertions, 123 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index f08e8a7fac93..9083bfdb7735 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -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 diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig index 34085bfc6d41..6a0354ca032f 100644 --- a/arch/um/drivers/Kconfig +++ b/arch/um/drivers/Kconfig @@ -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 diff --git a/arch/um/drivers/rtc_user.c b/arch/um/drivers/rtc_user.c index 51e79f3148cd..67912fcf7b28 100644 --- a/arch/um/drivers/rtc_user.c +++ b/arch/um/drivers/rtc_user.c @@ -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 { diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index c5e6545f6fcf..8e8a8bf518b6 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -41,7 +41,7 @@ int start_io_thread(struct os_helper_thread **td_out, int *fd_out) *fd_out = fds[1]; err = os_set_fd_block(*fd_out, 0); - err = os_set_fd_block(kernel_fd, 0); + err |= os_set_fd_block(kernel_fd, 0); if (err) { printk("start_io_thread - failed to set nonblocking I/O.\n"); goto out_close; diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index f292e0b4ff8b..9bbbddfe866b 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -1625,35 +1625,19 @@ static void vector_eth_configure( device->dev = dev; - *vp = ((struct vector_private) - { - .list = LIST_HEAD_INIT(vp->list), - .dev = dev, - .unit = n, - .options = get_transport_options(def), - .rx_irq = 0, - .tx_irq = 0, - .parsed = def, - .max_packet = get_mtu(def) + ETH_HEADER_OTHER, - /* TODO - we need to calculate headroom so that ip header - * is 16 byte aligned all the time - */ - .headroom = get_headroom(def), - .form_header = NULL, - .verify_header = NULL, - .header_rxbuffer = NULL, - .header_txbuffer = NULL, - .header_size = 0, - .rx_header_size = 0, - .rexmit_scheduled = false, - .opened = false, - .transport_data = NULL, - .in_write_poll = false, - .coalesce = 2, - .req_size = get_req_size(def), - .in_error = false, - .bpf = NULL - }); + INIT_LIST_HEAD(&vp->list); + vp->dev = dev; + vp->unit = n; + vp->options = get_transport_options(def); + vp->parsed = def; + vp->max_packet = get_mtu(def) + ETH_HEADER_OTHER; + /* + * TODO - we need to calculate headroom so that ip header + * is 16 byte aligned all the time + */ + vp->headroom = get_headroom(def); + vp->coalesce = 2; + vp->req_size = get_req_size(def); dev->features = dev->hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST); INIT_WORK(&vp->reset_tx, vector_reset_tx); diff --git a/arch/um/drivers/vfio_kern.c b/arch/um/drivers/vfio_kern.c index b51fc9888ae1..915812a79bfc 100644 --- a/arch/um/drivers/vfio_kern.c +++ b/arch/um/drivers/vfio_kern.c @@ -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) { @@ -570,29 +572,55 @@ static void uml_vfio_release_device(struct uml_vfio_device *dev) kfree(dev); } -static int uml_vfio_cmdline_set(const char *device, const struct kernel_param *kp) +static struct uml_vfio_device *uml_vfio_find_device(const char *device) +{ + struct uml_vfio_device *dev; + + list_for_each_entry(dev, ¨_vfio_devices, list) { + if (!strcmp(dev->name, device)) + return dev; + } + return NULL; +} + +static struct uml_vfio_device *uml_vfio_add_device(const char *device) { struct uml_vfio_device *dev; int fd; + guard(mutex)(¨_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 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, ¨_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; } @@ -615,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; @@ -625,6 +689,8 @@ static int __init uml_vfio_init(void) list_for_each_entry_safe(dev, n, ¨_vfio_devices, list) uml_vfio_open_device(dev); + mconsole_register_dev(¨_vfio_mc); + return 0; } late_initcall(uml_vfio_init); diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index 0fe207ca4b72..557d93aea00a 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -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, -}; - -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, +#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 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); diff --git a/arch/um/drivers/virtio_pcidev.c b/arch/um/drivers/virtio_pcidev.c index 3c4c4c928fdd..e9e23cc3f357 100644 --- a/arch/um/drivers/virtio_pcidev.c +++ b/arch/um/drivers/virtio_pcidev.c @@ -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))) diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 04ab3b653a48..b6810db24ca4 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -15,7 +15,6 @@ generic-y += mcs_spinlock.h generic-y += mmiowb.h generic-y += module.h generic-y += module.lds.h -generic-y += param.h generic-y += parport.h generic-y += percpu.h generic-y += preempt.h diff --git a/arch/um/include/asm/cpufeature.h b/arch/um/include/asm/cpufeature.h index 1eb8b834fbec..4354f6984271 100644 --- a/arch/um/include/asm/cpufeature.h +++ b/arch/um/include/asm/cpufeature.h @@ -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 */ diff --git a/arch/um/include/asm/current.h b/arch/um/include/asm/current.h index de64e032d66c..8accc6d6f502 100644 --- a/arch/um/include/asm/current.h +++ b/arch/um/include/asm/current.h @@ -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 */ diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index 23dcc914d44e..0bbb24868557 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h @@ -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); } } diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index 3d516f3ca9c7..6f54254aaf44 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -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 diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index ca2a519d53ab..24fdea6f88c3 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -314,7 +314,7 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -static inline int pte_swp_exclusive(pte_t pte) +static inline bool pte_swp_exclusive(pte_t pte) { return pte_get_bits(pte, _PAGE_SWP_EXCLUSIVE); } diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index 4696f24d1492..86d74f9d33cf 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -6,7 +6,7 @@ #ifndef __UM_PTRACE_GENERIC_H #define __UM_PTRACE_GENERIC_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <sysdep/ptrace.h> diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index f9ad06fcc991..7a6f4dc99fa1 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h @@ -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 diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 4f44dcce8a7c..2f9bfd99460a 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -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> diff --git a/arch/um/include/shared/skas/mm_id.h b/arch/um/include/shared/skas/mm_id.h index 89df9a55fbea..4f977ef5dda5 100644 --- a/arch/um/include/shared/skas/mm_id.h +++ b/arch/um/include/shared/skas/mm_id.h @@ -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 diff --git a/arch/um/include/shared/skas/skas.h b/arch/um/include/shared/skas/skas.h index 7d1de4cab551..807514e10538 100644 --- a/arch/um/include/shared/skas/skas.h +++ b/arch/um/include/shared/skas/skas.h @@ -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); diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index cb8b5cd9285c..13812fa97eee 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -26,8 +26,6 @@ void flush_thread(void) get_safe_registers(current_pt_regs()->regs.gp, current_pt_regs()->regs.fp); - - __switch_mm(¤t->mm->context.id); } void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 0cd6fad3d908..1be644de9e41 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -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 = ¤t->thread.regs; - - 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); + unsigned long thread_flags; + + 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) diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 2124624b7817..fdbb37b5c399 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -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(®s->regs), UPT_SYSCALL_ARG4(®s->regs)); + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) + trace_sys_enter(regs, UPT_SYSCALL_NR(®s->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(®s->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; diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 849fafa4b54f..afe9a2f251ef 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -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) { diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 05dcdc057af9..5881b17eb987 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -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) diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index a5beaea2967e..ba7494f9bfe4 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c @@ -9,8 +9,8 @@ #include <kern_util.h> #include <sysdep/ptrace.h> #include <sysdep/ptrace_user.h> -#include <sysdep/syscalls.h> #include <linux/time-internal.h> +#include <asm/syscall.h> #include <asm/unistd.h> #include <asm/delay.h> @@ -43,7 +43,14 @@ void handle_syscall(struct uml_pt_regs *r) tt_extra_sched_jiffies += 1; if (syscall >= 0 && syscall < __NR_syscalls) { - unsigned long ret = EXECUTE_SYSCALL(syscall, regs); + unsigned long ret; + + ret = (*sys_call_table[syscall])(UPT_SYSCALL_ARG1(®s->regs), + UPT_SYSCALL_ARG2(®s->regs), + UPT_SYSCALL_ARG3(®s->regs), + UPT_SYSCALL_ARG4(®s->regs), + UPT_SYSCALL_ARG5(®s->regs), + UPT_SYSCALL_ARG6(®s->regs)); PT_REGS_SET_SYSCALL_RETURN(regs, ret); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index e42ffac23e3c..78f48fa9db8b 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -267,7 +267,7 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi) memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); } -static void handle_trap(int pid, struct uml_pt_regs *regs) +static void handle_trap(struct uml_pt_regs *regs) { if ((UPT_IP(regs) >= STUB_START) && (UPT_IP(regs) < STUB_END)) fatal_sigsegv(); @@ -434,7 +434,6 @@ static int __init init_stub_exe_fd(void) __initcall(init_stub_exe_fd); int using_seccomp; -int userspace_pid[NR_CPUS]; /** * start_userspace() - prepare a new userspace process @@ -548,12 +547,12 @@ out_close: return err; } -int unscheduled_userspace_iterations; +static int unscheduled_userspace_iterations; extern unsigned long tt_extra_sched_jiffies; void userspace(struct uml_pt_regs *regs) { - int err, status, op, pid = userspace_pid[0]; + int err, status, op; siginfo_t si_ptrace; siginfo_t *si; int sig; @@ -562,6 +561,8 @@ void userspace(struct uml_pt_regs *regs) interrupt_end(); while (1) { + struct mm_id *mm_id = current_mm_id(); + /* * When we are in time-travel mode, userspace can theoretically * do a *lot* of work without being scheduled. The problem with @@ -590,14 +591,12 @@ void userspace(struct uml_pt_regs *regs) current_mm_sync(); if (using_seccomp) { - struct mm_id *mm_id = current_mm_id(); struct stub_data *proc_data = (void *) mm_id->stack; - int ret; - ret = set_stub_state(regs, proc_data, singlestepping()); - if (ret) { + err = set_stub_state(regs, proc_data, singlestepping()); + if (err) { printk(UM_KERN_ERR "%s - failed to set regs: %d", - __func__, ret); + __func__, err); fatal_sigsegv(); } @@ -623,10 +622,10 @@ void userspace(struct uml_pt_regs *regs) mm_id->syscall_data_len = 0; mm_id->syscall_fd_num = 0; - ret = get_stub_state(regs, proc_data, NULL); - if (ret) { + err = get_stub_state(regs, proc_data, NULL); + if (err) { printk(UM_KERN_ERR "%s - failed to get regs: %d", - __func__, ret); + __func__, err); fatal_sigsegv(); } @@ -645,8 +644,10 @@ void userspace(struct uml_pt_regs *regs) GET_FAULTINFO_FROM_MC(regs->faultinfo, mcontext); } } else { + int pid = mm_id->pid; + /* Flush out any pending syscalls */ - err = syscall_stub_flush(current_mm_id()); + err = syscall_stub_flush(mm_id); if (err) { if (err == -ENOMEM) report_enomem(); @@ -756,7 +757,7 @@ void userspace(struct uml_pt_regs *regs) handle_syscall(regs); break; case SIGTRAP + 0x80: - handle_trap(pid, regs); + handle_trap(regs); break; case SIGTRAP: relay_signal(SIGTRAP, (struct siginfo *)si, regs, NULL); @@ -777,7 +778,6 @@ void userspace(struct uml_pt_regs *regs) __func__, sig); fatal_sigsegv(); } - pid = userspace_pid[0]; interrupt_end(); /* Avoid -ERESTARTSYS handling in host */ @@ -902,8 +902,3 @@ void reboot_skas(void) block_signals_trace(); UML_LONGJMP(&initial_jmpbuf, noreboot ? INIT_JMP_HALT : INIT_JMP_REBOOT); } - -void __switch_mm(struct mm_id *mm_idp) -{ - userspace_pid[0] = mm_idp->pid; -} |