From a0a9ad95ddccaefa0f743d0af427cba936b9daac Mon Sep 17 00:00:00 2001 From: ye xingchen Date: Tue, 20 Sep 2022 06:30:53 +0000 Subject: um: Remove the unneeded result variable Return the value epoll_ctl() directly instead of storing it in another redundant variable. Reported-by: Zeal Robot Signed-off-by: ye xingchen Signed-off-by: Richard Weinberger --- arch/um/os-Linux/irq.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index 98ea910ef87c..cf7e49c08b21 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -127,12 +127,10 @@ int os_mod_epoll_fd(int events, int fd, void *data) int os_del_epoll_fd(int fd) { struct epoll_event event; - int result; /* This is quiet as we use this as IO ON/OFF - so it is often * invoked on a non-existent fd */ - result = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &event); - return result; + return epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &event); } void os_set_ioignore(void) -- cgit v1.2.3 From 28b2bb06a381816c2c111afba4984f8ea2c17e0f Mon Sep 17 00:00:00 2001 From: Yang Li Date: Wed, 21 Sep 2022 09:06:09 +0800 Subject: um: remove unneeded semicolon while(){}, semicolon do not need to be appended. Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=2237 Reported-by: Abaci Robot Signed-off-by: Yang Li Signed-off-by: Richard Weinberger --- arch/um/drivers/virtio_uml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 588930a0ced1..198aaed81ce6 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -412,7 +412,7 @@ static irqreturn_t vu_req_read_message(struct virtio_uml_device *vu_dev, if (msg.msg.header.flags & VHOST_USER_FLAG_NEED_REPLY) vhost_user_reply(vu_dev, &msg.msg, response); irq_rc = IRQ_HANDLED; - }; + } /* mask EAGAIN as we try non-blocking read until socket is empty */ vu_dev->recv_rc = (rc == -EAGAIN) ? 0 : rc; return irq_rc; -- cgit v1.2.3 From e0820368d0101452a9a35c903a549b7f32a6edff Mon Sep 17 00:00:00 2001 From: "Fabio M. De Francesco" Date: Thu, 13 Oct 2022 18:17:00 +0200 Subject: hostfs: Replace kmap() with kmap_local_page() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The use of kmap() is being deprecated in favor of kmap_local_page(). There are two main problems with kmap(): (1) It comes with an overhead as the mapping space is restricted and protected by a global lock for synchronization and (2) it also requires global TLB invalidation when the kmap’s pool wraps and it might block when the mapping space is fully utilized until a slot becomes available. With kmap_local_page() the mappings are per thread, CPU local, can take page faults, and can be called from any context (including interrupts). It is faster than kmap() in kernels with HIGHMEM enabled. Furthermore, the tasks can be preempted and, when they are scheduled to run again, the kernel virtual addresses are restored and still valid. Therefore, replace kmap() with kmap_local_page() in hostfs_kern.c, it being the only file with kmap() call sites currently left in fs/hostfs. Cc: "Venkataramanan, Anirudh" Suggested-by: Ira Weiny Signed-off-by: Fabio M. De Francesco Signed-off-by: Richard Weinberger --- fs/hostfs/hostfs_kern.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 277468783fee..609f69224643 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -412,7 +412,7 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc) if (page->index >= end_index) count = inode->i_size & (PAGE_SIZE-1); - buffer = kmap(page); + buffer = kmap_local_page(page); err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count); if (err != count) { @@ -428,9 +428,9 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc) err = 0; out: - kunmap(page); - + kunmap_local(buffer); unlock_page(page); + return err; } @@ -441,7 +441,7 @@ static int hostfs_read_folio(struct file *file, struct folio *folio) loff_t start = page_offset(page); int bytes_read, ret = 0; - buffer = kmap(page); + buffer = kmap_local_page(page); bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer, PAGE_SIZE); if (bytes_read < 0) { @@ -458,8 +458,9 @@ static int hostfs_read_folio(struct file *file, struct folio *folio) out: flush_dcache_page(page); - kunmap(page); + kunmap_local(buffer); unlock_page(page); + return ret; } @@ -484,9 +485,9 @@ static int hostfs_write_end(struct file *file, struct address_space *mapping, unsigned from = pos & (PAGE_SIZE - 1); int err; - buffer = kmap(page); + buffer = kmap_local_page(page); err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied); - kunmap(page); + kunmap_local(buffer); if (!PageUptodate(page) && err == PAGE_SIZE) SetPageUptodate(page); -- cgit v1.2.3 From 3271e27bba90f676fa530592ba8ec9fe51938abf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 18 Oct 2022 12:49:49 +0200 Subject: um: protect VMA iteration Due to changes in the iteration, there are now lockdep checks indicating that we're missing locking here. Add the missing locking where it's needed. Signed-off-by: Johannes Berg Acked-By: Anton Ivanov Signed-off-by: Richard Weinberger --- arch/um/kernel/tlb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index ad449173a1a1..fa43bcd9ba0b 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -597,6 +597,8 @@ void force_flush_all(void) struct vm_area_struct *vma; VMA_ITERATOR(vmi, mm, 0); + mmap_read_lock(mm); for_each_vma(vmi, vma) fix_range(mm, vma->vm_start, vma->vm_end, 1); + mmap_read_unlock(mm); } -- cgit v1.2.3 From 8f88c73afe481f93d40801596927e8c0047b6d96 Mon Sep 17 00:00:00 2001 From: Xiang Yang Date: Tue, 15 Nov 2022 15:32:25 +0800 Subject: um: vector: Fix memory leak in vector_config If the return value of the uml_parse_vector_ifspec function is NULL, we should call kfree(params) to prevent memory leak. Fixes: 49da7e64f33e ("High Performance UML Vector Network Driver") Signed-off-by: Xiang Yang Acked-By: Anton Ivanov Signed-off-by: Richard Weinberger --- arch/um/drivers/vector_kern.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index ded7c47d2fbe..131b7cb29576 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -767,6 +767,7 @@ static int vector_config(char *str, char **error_out) if (parsed == NULL) { *error_out = "vector_config failed to parse parameters"; + kfree(params); return -EINVAL; } -- cgit v1.2.3 From d119595f873e4cf4c7a03aa9ac00d960772487e1 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 22 Nov 2022 11:07:32 +0100 Subject: um: Switch printk calls to adhere to correct coding style This means having the string literal in one line and using __func__ where appropriate. Signed-off-by: Benjamin Berg Signed-off-by: Richard Weinberger --- arch/um/kernel/exec.c | 4 +- arch/um/os-Linux/skas/mem.c | 19 +++---- arch/um/os-Linux/skas/process.c | 121 ++++++++++++++++++++-------------------- 3 files changed, 69 insertions(+), 75 deletions(-) diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 58938d75871a..827a0d3fa589 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -29,8 +29,8 @@ void flush_thread(void) ret = unmap(¤t->mm->context.id, 0, TASK_SIZE, 1, &data); if (ret) { - printk(KERN_ERR "flush_thread - clearing address space failed, " - "err = %d\n", ret); + printk(KERN_ERR "%s - clearing address space failed, err = %d\n", + __func__, ret); force_sig(SIGKILL); } get_safe_registers(current_pt_regs()->regs.gp, diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 3b4975ee67e2..953fb10f3f93 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -60,8 +60,8 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) printk(UM_KERN_ERR "Registers - \n"); for (i = 0; i < MAX_REG_NR; i++) printk(UM_KERN_ERR "\t%d\t0x%lx\n", i, syscall_regs[i]); - panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", - -n); + panic("%s : PTRACE_SETREGS failed, errno = %d\n", + __func__, -n); } err = ptrace(PTRACE_CONT, pid, 0, 0); @@ -81,20 +81,17 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) offset = *((unsigned long *) mm_idp->stack + 1); if (offset) { data = (unsigned long *)(mm_idp->stack + offset - STUB_DATA); - printk(UM_KERN_ERR "do_syscall_stub : ret = %ld, offset = %ld, " - "data = %p\n", ret, offset, data); + printk(UM_KERN_ERR "%s : ret = %ld, offset = %ld, data = %p\n", + __func__, ret, offset, data); syscall = (unsigned long *)((unsigned long)data + data[0]); - printk(UM_KERN_ERR "do_syscall_stub: syscall %ld failed, " - "return value = 0x%lx, expected return value = 0x%lx\n", - syscall[0], ret, syscall[7]); - printk(UM_KERN_ERR " syscall parameters: " - "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", + printk(UM_KERN_ERR "%s: syscall %ld failed, return value = 0x%lx, expected return value = 0x%lx\n", + __func__, syscall[0], ret, syscall[7]); + printk(UM_KERN_ERR " syscall parameters: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", syscall[1], syscall[2], syscall[3], syscall[4], syscall[5], syscall[6]); for (n = 1; n < data[0]/sizeof(long); n++) { if (n == 1) - printk(UM_KERN_ERR " additional syscall " - "data:"); + printk(UM_KERN_ERR " additional syscall data:"); if (n % 4 == 1) printk("\n" UM_KERN_ERR " "); printk(" 0x%lx", data[n]); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index b24db6017ded..b1ea53285af1 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -118,8 +118,8 @@ void wait_stub_done(int pid) err = ptrace(PTRACE_CONT, pid, 0, 0); if (err) { - printk(UM_KERN_ERR "wait_stub_done : continue failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "%s : continue failed, errno = %d\n", + __func__, errno); fatal_sigsegv(); } } @@ -130,11 +130,10 @@ void wait_stub_done(int pid) bad_wait: err = ptrace_dump_regs(pid); if (err) - printk(UM_KERN_ERR "Failed to get registers from stub, " - "errno = %d\n", -err); - printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, " - "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno, - status); + printk(UM_KERN_ERR "Failed to get registers from stub, errno = %d\n", + -err); + printk(UM_KERN_ERR "%s : failed to wait for SIGTRAP, pid = %d, n = %d, errno = %d, status = 0x%x\n", + __func__, pid, n, errno, status); fatal_sigsegv(); } @@ -195,15 +194,15 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); if (err < 0) { - printk(UM_KERN_ERR "handle_trap - nullifying syscall " - "failed, errno = %d\n", errno); + printk(UM_KERN_ERR "%s - nullifying syscall failed, errno = %d\n", + __func__, errno); fatal_sigsegv(); } err = ptrace(PTRACE_SYSCALL, pid, 0, 0); if (err < 0) { - printk(UM_KERN_ERR "handle_trap - continuing to end of " - "syscall failed, errno = %d\n", errno); + printk(UM_KERN_ERR "%s - continuing to end of syscall failed, errno = %d\n", + __func__, errno); fatal_sigsegv(); } @@ -212,11 +211,10 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, (WSTOPSIG(status) != SIGTRAP + 0x80)) { err = ptrace_dump_regs(pid); if (err) - printk(UM_KERN_ERR "Failed to get registers " - "from process, errno = %d\n", -err); - printk(UM_KERN_ERR "handle_trap - failed to wait at " - "end of syscall, errno = %d, status = %d\n", - errno, status); + printk(UM_KERN_ERR "Failed to get registers from process, errno = %d\n", + -err); + printk(UM_KERN_ERR "%s - failed to wait at end of syscall, errno = %d, status = %d\n", + __func__, errno, status); fatal_sigsegv(); } } @@ -256,8 +254,8 @@ static int userspace_tramp(void *stack) addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE, PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); if (addr == MAP_FAILED) { - printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, " - "errno = %d\n", STUB_CODE, errno); + printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, errno = %d\n", + STUB_CODE, errno); exit(1); } @@ -267,8 +265,7 @@ static int userspace_tramp(void *stack) UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, offset); if (addr == MAP_FAILED) { - printk(UM_KERN_ERR "mapping segfault stack " - "at 0x%lx failed, errno = %d\n", + printk(UM_KERN_ERR "mapping segfault stack at 0x%lx failed, errno = %d\n", STUB_DATA, errno); exit(1); } @@ -286,8 +283,8 @@ static int userspace_tramp(void *stack) sa.sa_sigaction = (void *) v; sa.sa_restorer = NULL; if (sigaction(SIGSEGV, &sa, NULL) < 0) { - printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV " - "handler failed - errno = %d\n", errno); + printk(UM_KERN_ERR "%s - setting SIGSEGV handler failed - errno = %d\n", + __func__, errno); exit(1); } } @@ -322,8 +319,8 @@ int start_userspace(unsigned long stub_stack) MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (stack == MAP_FAILED) { err = -errno; - printk(UM_KERN_ERR "start_userspace : mmap failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "%s : mmap failed, errno = %d\n", + __func__, errno); return err; } @@ -336,8 +333,8 @@ int start_userspace(unsigned long stub_stack) pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); if (pid < 0) { err = -errno; - printk(UM_KERN_ERR "start_userspace : clone failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "%s : clone failed, errno = %d\n", + __func__, errno); return err; } @@ -345,31 +342,31 @@ int start_userspace(unsigned long stub_stack) CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); if (n < 0) { err = -errno; - printk(UM_KERN_ERR "start_userspace : wait failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "%s : wait failed, errno = %d\n", + __func__, errno); goto out_kill; } } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGALRM)); if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) { err = -EINVAL; - printk(UM_KERN_ERR "start_userspace : expected SIGSTOP, got " - "status = %d\n", status); + printk(UM_KERN_ERR "%s : expected SIGSTOP, got status = %d\n", + __func__, status); goto out_kill; } if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *) PTRACE_O_TRACESYSGOOD) < 0) { err = -errno; - printk(UM_KERN_ERR "start_userspace : PTRACE_OLDSETOPTIONS " - "failed, errno = %d\n", errno); + printk(UM_KERN_ERR "%s : PTRACE_OLDSETOPTIONS failed, errno = %d\n", + __func__, errno); goto out_kill; } if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) { err = -errno; - printk(UM_KERN_ERR "start_userspace : munmap failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "%s : munmap failed, errno = %d\n", + __func__, errno); goto out_kill; } @@ -403,14 +400,14 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) * just kill the process. */ if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) { - printk(UM_KERN_ERR "userspace - ptrace set regs " - "failed, errno = %d\n", errno); + printk(UM_KERN_ERR "%s - ptrace set regs failed, errno = %d\n", + __func__, errno); fatal_sigsegv(); } if (put_fp_registers(pid, regs->fp)) { - printk(UM_KERN_ERR "userspace - ptrace set fp regs " - "failed, errno = %d\n", errno); + printk(UM_KERN_ERR "%s - ptrace set fp regs failed, errno = %d\n", + __func__, errno); fatal_sigsegv(); } @@ -421,28 +418,28 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) singlestepping(NULL)); if (ptrace(op, pid, 0, 0)) { - printk(UM_KERN_ERR "userspace - ptrace continue " - "failed, op = %d, errno = %d\n", op, errno); + printk(UM_KERN_ERR "%s - ptrace continue failed, op = %d, errno = %d\n", + __func__, op, errno); fatal_sigsegv(); } CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); if (err < 0) { - printk(UM_KERN_ERR "userspace - wait failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "%s - wait failed, errno = %d\n", + __func__, errno); fatal_sigsegv(); } regs->is_user = 1; if (ptrace(PTRACE_GETREGS, pid, 0, regs->gp)) { - printk(UM_KERN_ERR "userspace - PTRACE_GETREGS failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "%s - PTRACE_GETREGS failed, errno = %d\n", + __func__, errno); fatal_sigsegv(); } if (get_fp_registers(pid, regs->fp)) { - printk(UM_KERN_ERR "userspace - get_fp_registers failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "%s - get_fp_registers failed, errno = %d\n", + __func__, errno); fatal_sigsegv(); } @@ -494,8 +491,8 @@ void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) unblock_signals_trace(); break; default: - printk(UM_KERN_ERR "userspace - child stopped " - "with signal %d\n", sig); + printk(UM_KERN_ERR "%s - child stopped with signal %d\n", + __func__, sig); fatal_sigsegv(); } pid = userspace_pid[0]; @@ -555,15 +552,15 @@ int copy_context_skas0(unsigned long new_stack, int pid) err = ptrace_setregs(pid, thread_regs); if (err < 0) { err = -errno; - printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_SETREGS " - "failed, pid = %d, errno = %d\n", pid, -err); + printk(UM_KERN_ERR "%s : PTRACE_SETREGS failed, pid = %d, errno = %d\n", + __func__, pid, -err); return err; } err = put_fp_registers(pid, thread_fp_regs); if (err < 0) { - printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers " - "failed, pid = %d, err = %d\n", pid, err); + printk(UM_KERN_ERR "%s : put_fp_registers failed, pid = %d, err = %d\n", + __func__, pid, err); return err; } @@ -574,8 +571,8 @@ int copy_context_skas0(unsigned long new_stack, int pid) err = ptrace(PTRACE_CONT, pid, 0, 0); if (err) { err = -errno; - printk(UM_KERN_ERR "Failed to continue new process, pid = %d, " - "errno = %d\n", pid, errno); + printk(UM_KERN_ERR "Failed to continue new process, pid = %d, errno = %d\n", + pid, errno); return err; } @@ -583,8 +580,8 @@ int copy_context_skas0(unsigned long new_stack, int pid) pid = data->parent_err; if (pid < 0) { - printk(UM_KERN_ERR "copy_context_skas0 - stub-parent reports " - "error %d\n", -pid); + printk(UM_KERN_ERR "%s - stub-parent reports error %d\n", + __func__, -pid); return pid; } @@ -594,8 +591,8 @@ int copy_context_skas0(unsigned long new_stack, int pid) */ wait_stub_done(pid); if (child_data->child_err != STUB_DATA) { - printk(UM_KERN_ERR "copy_context_skas0 - stub-child %d reports " - "error %ld\n", pid, data->child_err); + printk(UM_KERN_ERR "%s - stub-child %d reports error %ld\n", + __func__, pid, data->child_err); err = data->child_err; goto out_kill; } @@ -603,8 +600,8 @@ int copy_context_skas0(unsigned long new_stack, int pid) if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0) { err = -errno; - printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_OLDSETOPTIONS " - "failed, errno = %d\n", errno); + printk(UM_KERN_ERR "%s : PTRACE_OLDSETOPTIONS failed, errno = %d\n", + __func__, errno); goto out_kill; } @@ -672,8 +669,8 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) kmalloc_ok = 0; return 1; default: - printk(UM_KERN_ERR "Bad sigsetjmp return in " - "start_idle_thread - %d\n", n); + printk(UM_KERN_ERR "Bad sigsetjmp return in %s - %d\n", + __func__, n); fatal_sigsegv(); } longjmp(*switch_buf, 1); -- cgit v1.2.3 From d5dbcfe7ee31ccea85a8cbf7ff84a2808d6c8f76 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 22 Nov 2022 11:07:33 +0100 Subject: um: Declare fix_range_common as a static function It is only used within the same file. Signed-off-by: Benjamin Berg Signed-off-by: Richard Weinberger --- arch/um/kernel/tlb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index fa43bcd9ba0b..7d050ab0f78a 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -314,8 +314,8 @@ static inline int update_p4d_range(pgd_t *pgd, unsigned long addr, return ret; } -void fix_range_common(struct mm_struct *mm, unsigned long start_addr, - unsigned long end_addr, int force) +static void fix_range_common(struct mm_struct *mm, unsigned long start_addr, + unsigned long end_addr, int force) { pgd_t *pgd; struct host_vm_change hvc; -- cgit v1.2.3 From 905a77077573056d7af508f35373f66ed8b4a39e Mon Sep 17 00:00:00 2001 From: David Gow Date: Sat, 17 Dec 2022 12:44:34 +0800 Subject: rust: arch/um: Use 'pie' relocation mode under UML UML expects a position independent executable for some reason, so tell rustc to generate pie objects. Otherwise we get a bunch of relocations we can't deal with in libcore. Signed-off-by: David Gow Signed-off-by: Richard Weinberger --- arch/um/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/um/Makefile b/arch/um/Makefile index f1d4d67157be..ae321282dc6f 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -68,6 +68,8 @@ KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ -Din6addr_loopback=kernel_in6addr_loopback \ -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr +KBUILD_RUSTFLAGS += -Crelocation-model=pie + KBUILD_AFLAGS += $(ARCH_INCLUDE) USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \ -- cgit v1.2.3 From 8849818679478933dd1d9718741f4daa3f4e8b86 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sat, 17 Dec 2022 12:44:35 +0800 Subject: rust: arch/um: Disable FP/SIMD instruction to match x86 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kernel disables all SSE and similar FP/SIMD instructions on x86-based architectures (partly because we shouldn't be using floats in the kernel, and partly to avoid the need for stack alignment, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383 ) UML does not do the same thing, which isn't in itself a problem, but does add to the list of differences between UML and "normal" x86 builds. In addition, there was a crash bug with LLVM < 15 / rustc < 1.65 when building with SSE, so disabling it fixes rust builds with earlier compiler versions, see: https://github.com/Rust-for-Linux/linux/pull/881 Signed-off-by: David Gow Reviewed-by: Sergio González Collado Signed-off-by: Richard Weinberger --- arch/x86/Makefile.um | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/Makefile.um b/arch/x86/Makefile.um index b3c1ae084180..d2e95d1d4db7 100644 --- a/arch/x86/Makefile.um +++ b/arch/x86/Makefile.um @@ -1,6 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 core-y += arch/x86/crypto/ +# +# Disable SSE and other FP/SIMD instructions to match normal x86 +# +KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx +KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2 + ifeq ($(CONFIG_X86_32),y) START := 0x8048000 -- cgit v1.2.3 From 0438aadfa69a345136f5ba4f582e0f769450ee0d Mon Sep 17 00:00:00 2001 From: David Gow Date: Sat, 17 Dec 2022 12:44:36 +0800 Subject: rust: arch/um: Add support for CONFIG_RUST under x86_64 UML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_RUST currently supports x86_64, but does not support it under UML. With the previous patches applied, adding support is trivial: add CONFIG_HAVE_RUST to UML if X86_64 is set. The scripts/generate_rust_target.rs file already checks for CONFIG_X86_64, not CONFIG_X86, so is prepared for UML support. The Rust support does not currently support X86_32. Also, update the Rust architecture support documentation to not that this is being maintained: I intend to look after this as best I can. Signed-off-by: David Gow Reviewed-by: Sergio González Collado Tested-by: Sergio González Collado Signed-off-by: Richard Weinberger --- Documentation/rust/arch-support.rst | 2 ++ arch/um/Kconfig | 1 + 2 files changed, 3 insertions(+) diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst index 6982b63775da..a526ca1c688b 100644 --- a/Documentation/rust/arch-support.rst +++ b/Documentation/rust/arch-support.rst @@ -17,3 +17,5 @@ Architecture Level of support Constraints ============ ================ ============================================== ``x86`` Maintained ``x86_64`` only. ============ ================ ============================================== +``um`` Maintained ``x86_64`` only. +============ ================ ============================================== diff --git a/arch/um/Kconfig b/arch/um/Kconfig index ad4ff3b0e91e..4db186f019ae 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -28,6 +28,7 @@ config UML select TRACE_IRQFLAGS_SUPPORT select TTY # Needed for line.c select HAVE_ARCH_VMAP_STACK + select HAVE_RUST if X86_64 config MMU bool -- cgit v1.2.3 From 5541992e512de8c9133110809f767bd1b54ee10d Mon Sep 17 00:00:00 2001 From: Ammar Faizi Date: Sat, 24 Dec 2022 00:23:38 +0700 Subject: x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list The 'syscall' instruction clobbers '%rcx' and '%r11', but they are not listed in the inline Assembly that performs the syscall instruction. No real bug is found. It wasn't buggy by luck because '%rcx' and '%r11' are caller-saved registers, and not used in the functions, and the functions are never inlined. Add them to the clobber list for code correctness. Fixes: f1c2bb8b9964ed31de988910f8b1cfb586d30091 ("um: implement a x86_64 vDSO") Signed-off-by: Ammar Faizi Signed-off-by: Richard Weinberger --- arch/x86/um/vdso/um_vdso.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/x86/um/vdso/um_vdso.c b/arch/x86/um/vdso/um_vdso.c index 2112b8d14668..ff0f3b4b6c45 100644 --- a/arch/x86/um/vdso/um_vdso.c +++ b/arch/x86/um/vdso/um_vdso.c @@ -17,8 +17,10 @@ int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts) { long ret; - asm("syscall" : "=a" (ret) : - "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory"); + asm("syscall" + : "=a" (ret) + : "0" (__NR_clock_gettime), "D" (clock), "S" (ts) + : "rcx", "r11", "memory"); return ret; } @@ -29,8 +31,10 @@ int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) { long ret; - asm("syscall" : "=a" (ret) : - "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); + asm("syscall" + : "=a" (ret) + : "0" (__NR_gettimeofday), "D" (tv), "S" (tz) + : "rcx", "r11", "memory"); return ret; } -- cgit v1.2.3 From 2f2be5102480b1058182fa6c4b1e5c1732d6760c Mon Sep 17 00:00:00 2001 From: Peter Foley Date: Thu, 12 Jan 2023 23:49:07 -0500 Subject: um: Make the definition of cpu_data more compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Match the x86 implementation to improve build errors. Noticed when building allyesconfig. e.g. ../arch/um/include/asm/processor-generic.h:94:19: error: called object is not a function or function pointer 94 | #define cpu_data (&boot_cpu_data) | ~^~~~~~~~~~~~~~~ ../drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_topology.c:2157:16: note: in expansion of macro ‘cpu_data’ 2157 | return cpu_data(first_cpu_of_numa_node).apicid; Signed-off-by: Peter Foley Signed-off-by: Richard Weinberger --- arch/um/include/asm/processor-generic.h | 2 +- arch/um/kernel/um_arch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index bb5f06480da9..7414154b8e9a 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h @@ -91,7 +91,7 @@ struct cpuinfo_um { extern struct cpuinfo_um boot_cpu_data; -#define cpu_data (&boot_cpu_data) +#define cpu_data(cpu) boot_cpu_data #define current_cpu_data boot_cpu_data #define cache_line_size() (boot_cpu_data.cache_alignment) diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 786b44dc20c9..8dcda617b8bf 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -96,7 +96,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos < nr_cpu_ids ? cpu_data + *pos : NULL; + return *pos < nr_cpu_ids ? &boot_cpu_data + *pos : NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) -- cgit v1.2.3 From 2c4d3841a82b88ae8a7b518dc6206f84f68e705a Mon Sep 17 00:00:00 2001 From: Peter Foley Date: Thu, 12 Jan 2023 23:49:08 -0500 Subject: um: Avoid pcap multiple definition errors Change the function name in pcap_kern to avoid conflicting with libpcap.a. e.g. ld: /usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../lib64/libpcap.a(pcap.o): in function `pcap_init': (.text+0x7f0): multiple definition of `pcap_init'; arch/um/drivers/pcap_kern.o:pcap_kern.c:(.text.unlikely+0x0): first defined here Signed-off-by: Peter Foley Signed-off-by: Richard Weinberger --- arch/um/drivers/pcap_kern.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c index cfe4cb17694c..25ee2c97ca21 100644 --- a/arch/um/drivers/pcap_kern.c +++ b/arch/um/drivers/pcap_kern.c @@ -15,7 +15,7 @@ struct pcap_init { char *filter; }; -void pcap_init(struct net_device *dev, void *data) +void pcap_init_kern(struct net_device *dev, void *data) { struct uml_net_private *pri; struct pcap_data *ppri; @@ -44,7 +44,7 @@ static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) } static const struct net_kern_info pcap_kern_info = { - .init = pcap_init, + .init = pcap_init_kern, .protocol = eth_protocol, .read = pcap_read, .write = pcap_write, -- cgit v1.2.3 From 910dba41239224069c17bb6c30c9d43c1ba229f1 Mon Sep 17 00:00:00 2001 From: Peter Foley Date: Thu, 12 Jan 2023 23:49:09 -0500 Subject: um: Prevent building modules incompatible with MODVERSIONS The manual ld invocation in arch/um/drivers doesn't play nicely with genksyms. Given the problematic modules are deprecated anyway, just prevent building them when using MODVERSIONS. e.g. MODPOST Module.symvers arch/um/drivers/.pcap.o.cmd: No such file or directory Signed-off-by: Peter Foley Signed-off-by: Richard Weinberger --- arch/um/drivers/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig index a4f0a19fbe14..36911b1fddcf 100644 --- a/arch/um/drivers/Kconfig +++ b/arch/um/drivers/Kconfig @@ -261,6 +261,7 @@ config UML_NET_VECTOR config UML_NET_VDE bool "VDE transport (obsolete)" depends on UML_NET + depends on !MODVERSIONS select MAY_HAVE_RUNTIME_DEPS help This User-Mode Linux network transport allows one or more running @@ -309,6 +310,7 @@ config UML_NET_MCAST config UML_NET_PCAP bool "pcap transport (obsolete)" depends on UML_NET + depends on !MODVERSIONS select MAY_HAVE_RUNTIME_DEPS help The pcap transport makes a pcap packet stream on the host look -- cgit v1.2.3 From 6aa56115c73b37270e53aa91984bdb8b60164ec7 Mon Sep 17 00:00:00 2001 From: Peter Foley Date: Thu, 12 Jan 2023 23:49:10 -0500 Subject: um: Use CFLAGS_vmlinux link-vmlinux.sh doesn't use LDFLAGS_vmlinux when linking the kernel for UML. Move the LDFLAGS_EXESTACK options into CFLAGS_vmlinux so they're actually respected. e.g. /usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/bin/ld: warning: .tmp_vmlinux.kallsyms3.o: missing .note.GNU-stack section implies executable stack /usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker /usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/bin/ld: warning: vmlinux has a LOAD segment with RWX permissions Reviewed-by: David Gow Signed-off-by: Peter Foley Signed-off-by: Richard Weinberger --- arch/um/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/um/Makefile b/arch/um/Makefile index ae321282dc6f..d37cac5d9f43 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -141,11 +141,10 @@ ifeq ($(CONFIG_LD_IS_BFD),y) LDFLAGS_EXECSTACK += $(call ld-option,--no-warn-rwx-segments) endif -LD_FLAGS_CMDLINE = $(foreach opt,$(KBUILD_LDFLAGS),-Wl,$(opt)) +LD_FLAGS_CMDLINE = $(foreach opt,$(KBUILD_LDFLAGS) $(LDFLAGS_EXECSTACK),-Wl,$(opt)) # Used by link-vmlinux.sh which has special support for um link export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) -export LDFLAGS_vmlinux := $(LDFLAGS_EXECSTACK) # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. -- cgit v1.2.3 From f09c3fcf67a3294c981b861981143e38895c5a59 Mon Sep 17 00:00:00 2001 From: Peter Foley Date: Fri, 13 Jan 2023 11:56:11 -0500 Subject: um: put power options in a menu Because having them all dumped at top-level is a bit messy. Signed-off-by: Peter Foley Signed-off-by: Richard Weinberger --- arch/um/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 4db186f019ae..dc36ea6e508f 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -243,4 +243,8 @@ source "arch/um/drivers/Kconfig" config ARCH_SUSPEND_POSSIBLE def_bool y +menu "Power management options" + source "kernel/power/Kconfig" + +endmenu -- cgit v1.2.3 From 83e913f52aba69149261742aa9ea4ceea7bf182d Mon Sep 17 00:00:00 2001 From: Peter Foley Date: Fri, 13 Jan 2023 12:03:00 -0500 Subject: um: Support LTO Only a handful of changes are necessary to get it to work. Signed-off-by: Peter Foley Signed-off-by: Richard Weinberger --- arch/um/Kconfig | 2 ++ arch/um/Makefile | 2 +- arch/x86/um/vdso/Makefile | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/um/Kconfig b/arch/um/Kconfig index dc36ea6e508f..541a9b18e343 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -25,6 +25,8 @@ config UML select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select HAVE_GCC_PLUGINS + select ARCH_SUPPORTS_LTO_CLANG + select ARCH_SUPPORTS_LTO_CLANG_THIN select TRACE_IRQFLAGS_SUPPORT select TTY # Needed for line.c select HAVE_ARCH_VMAP_STACK diff --git a/arch/um/Makefile b/arch/um/Makefile index d37cac5d9f43..8186d4761bda 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -144,7 +144,7 @@ endif LD_FLAGS_CMDLINE = $(foreach opt,$(KBUILD_LDFLAGS) $(LDFLAGS_EXECSTACK),-Wl,$(opt)) # Used by link-vmlinux.sh which has special support for um link -export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) +export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) $(CC_FLAGS_LTO) # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile index 6fbe97c52c99..6825e146a62f 100644 --- a/arch/x86/um/vdso/Makefile +++ b/arch/x86/um/vdso/Makefile @@ -61,7 +61,7 @@ CFLAGS_REMOVE_um_vdso.o = -pg -fprofile-arcs -ftest-coverage # quiet_cmd_vdso = VDSO $@ cmd_vdso = $(CC) -nostdlib -o $@ \ - $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ + $(CC_FLAGS_LTO) $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' -- cgit v1.2.3 From 314a1408b79a844dafdcde867d90de5d509409b7 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Fri, 20 Jan 2023 09:02:32 +0100 Subject: um: virt-pci: implement pcibios_get_phb_of_node() Implement pcibios_get_phb_of_node() as x86 does in order to allow PCI busses to be associated with devicetree nodes. Signed-off-by: Vincent Whitchurch Acked-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/virt-pci.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index 3ac220dafec4..6884e1be38e4 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -533,6 +533,25 @@ static void um_pci_irq_vq_cb(struct virtqueue *vq) } } +/* Copied from arch/x86/kernel/devicetree.c */ +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) +{ + struct device_node *np; + + for_each_node_by_type(np, "pci") { + const void *prop; + unsigned int bus_min; + + prop = of_get_property(np, "bus-range", NULL); + if (!prop) + continue; + bus_min = be32_to_cpup(prop); + if (bus->number == bus_min) + return np; + } + return NULL; +} + static int um_pci_init_vqs(struct um_pci_device *dev) { struct virtqueue *vqs[2]; -- cgit v1.2.3 From 935f8f7a0123ffa0a2dd7234713dc2ebeeb08955 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Thu, 26 Jan 2023 11:47:10 +0100 Subject: um-virt-pci: Make max delay configurable There is a hard coded maximum time for which the driver busy-loops waiting for a response from the virtio device. This default time may be too short for some systems, so make it a module parameter so that it can be set via the kernel command line. Signed-off-by: Vincent Whitchurch Signed-off-by: Richard Weinberger --- arch/um/drivers/virt-pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index 6884e1be38e4..0aa71c08210d 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -54,7 +54,8 @@ 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)]; -#define UM_VIRT_PCI_MAXDELAY 40000 +static unsigned int um_pci_max_delay_us = 40000; +module_param_named(max_delay_us, um_pci_max_delay_us, uint, 0644); struct um_pci_message_buffer { struct virtio_pcidev_msg hdr; @@ -155,7 +156,7 @@ static int um_pci_send_cmd(struct um_pci_device *dev, kfree(completed); if (WARN_ONCE(virtqueue_is_broken(dev->cmd_vq) || - ++delay_count > UM_VIRT_PCI_MAXDELAY, + ++delay_count > um_pci_max_delay_us, "um virt-pci delay: %d", delay_count)) { ret = -EIO; break; -- cgit v1.2.3 From 522c532c4fe730258118fb146577ec9bedf6b807 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Fri, 27 Jan 2023 15:30:27 +0100 Subject: virt-pci: add platform bus support This driver registers PCI busses, but the underlying virtio protocol could just as easily be used to provide a platform bus instead. If the virtio device node in the devicetree indicates that it's compatible with simple-bus, register platform devices instead of handling it as a PCI bus. Only one platform bus is allowed and the logic MMIO region for the platform bus is placed at an arbitrarily-chosen address away from the PCI region. Signed-off-by: Vincent Whitchurch Signed-off-by: Richard Weinberger --- arch/um/drivers/virt-pci.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index 0aa71c08210d..2ba89347053a 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,8 @@ struct um_pci_device { unsigned long status; int irq; + + bool platform; }; struct um_pci_device_reg { @@ -48,6 +51,7 @@ struct um_pci_device_reg { static struct pci_host_bridge *bridge; static DEFINE_MUTEX(um_pci_mtx); +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; @@ -481,6 +485,9 @@ static void um_pci_handle_irq_message(struct virtqueue *vq, struct virtio_device *vdev = vq->vdev; struct um_pci_device *dev = vdev->priv; + if (!dev->irq) + return; + /* we should properly chain interrupts, but on ARCH=um we don't care */ switch (msg->op) { @@ -581,6 +588,55 @@ static int um_pci_init_vqs(struct um_pci_device *dev) return 0; } +static void __um_pci_virtio_platform_remove(struct virtio_device *vdev, + struct um_pci_device *dev) +{ + virtio_reset_device(vdev); + vdev->config->del_vqs(vdev); + + mutex_lock(&um_pci_mtx); + um_pci_platform_device = NULL; + mutex_unlock(&um_pci_mtx); + + kfree(dev); +} + +static int um_pci_virtio_platform_probe(struct virtio_device *vdev, + struct um_pci_device *dev) +{ + int ret; + + dev->platform = true; + + mutex_lock(&um_pci_mtx); + + if (um_pci_platform_device) { + mutex_unlock(&um_pci_mtx); + ret = -EBUSY; + goto out_free; + } + + ret = um_pci_init_vqs(dev); + if (ret) { + mutex_unlock(&um_pci_mtx); + goto out_free; + } + + um_pci_platform_device = dev; + + mutex_unlock(&um_pci_mtx); + + ret = of_platform_default_populate(vdev->dev.of_node, NULL, &vdev->dev); + if (ret) + __um_pci_virtio_platform_remove(vdev, dev); + + return ret; + +out_free: + kfree(dev); + return ret; +} + static int um_pci_virtio_probe(struct virtio_device *vdev) { struct um_pci_device *dev; @@ -594,6 +650,9 @@ static int um_pci_virtio_probe(struct virtio_device *vdev) dev->vdev = vdev; vdev->priv = dev; + if (of_device_is_compatible(vdev->dev.of_node, "simple-bus")) + return um_pci_virtio_platform_probe(vdev, dev); + mutex_lock(&um_pci_mtx); for (i = 0; i < MAX_DEVICES; i++) { if (um_pci_devices[i].dev) @@ -643,6 +702,12 @@ static void um_pci_virtio_remove(struct virtio_device *vdev) struct um_pci_device *dev = vdev->priv; int i; + if (dev->platform) { + of_platform_depopulate(&vdev->dev); + __um_pci_virtio_platform_remove(vdev, dev); + return; + } + /* Stop all virtqueues */ virtio_reset_device(vdev); vdev->config->del_vqs(vdev); @@ -880,6 +945,30 @@ void *pci_root_bus_fwnode(struct pci_bus *bus) return um_pci_fwnode; } +static long um_pci_map_platform(unsigned long offset, size_t size, + const struct logic_iomem_ops **ops, + void **priv) +{ + if (!um_pci_platform_device) + return -ENOENT; + + *ops = &um_pci_device_bar_ops; + *priv = &um_pci_platform_device->resptr[0]; + + return 0; +} + +static const struct logic_iomem_region_ops um_pci_platform_ops = { + .map = um_pci_map_platform, +}; + +static struct resource virt_platform_resource = { + .name = "platform", + .start = 0x10000000, + .end = 0x1fffffff, + .flags = IORESOURCE_MEM, +}; + static int __init um_pci_init(void) { int err, i; @@ -888,6 +977,8 @@ static int __init um_pci_init(void) &um_pci_cfgspace_ops)); WARN_ON(logic_iomem_add_region(&virt_iomem_resource, &um_pci_iomem_ops)); + WARN_ON(logic_iomem_add_region(&virt_platform_resource, + &um_pci_platform_ops)); if (WARN(CONFIG_UML_PCI_OVER_VIRTIO_DEVICE_ID < 0, "No virtio device ID configured for PCI - no PCI support\n")) -- cgit v1.2.3 From b99ddbe8336ee680257c8ab479f75051eaa49dcf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Feb 2023 01:41:56 +0900 Subject: UML: define RUNTIME_DISCARD_EXIT With CONFIG_VIRTIO_UML=y, GNU ld < 2.36 fails to link UML vmlinux (w/wo CONFIG_LD_SCRIPT_STATIC). `.exit.text' referenced in section `.uml.exitcall.exit' of arch/um/drivers/virtio_uml.o: defined in discarded section `.exit.text' of arch/um/drivers/virtio_uml.o collect2: error: ld returned 1 exit status This fix is similar to the following commits: - 4b9880dbf3bd ("powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT") - a494398bde27 ("s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36") - c1c551bebf92 ("sh: define RUNTIME_DISCARD_EXIT") Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv") Reported-by: SeongJae Park Signed-off-by: Masahiro Yamada Tested-by: SeongJae Park Signed-off-by: Richard Weinberger --- arch/um/kernel/vmlinux.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index 16e49bfa2b42..53d719c04ba9 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S @@ -1,4 +1,4 @@ - +#define RUNTIME_DISCARD_EXIT KERNEL_STACK_SIZE = 4096 * (1 << CONFIG_KERNEL_STACK_ORDER); #ifdef CONFIG_LD_SCRIPT_STATIC -- cgit v1.2.3 From 8a6ca543646f2940832665dbf4e04105262505e2 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Thu, 9 Feb 2023 10:00:02 +0100 Subject: um: virtio_uml: free command if adding to virtqueue failed If adding the command fails (i.e. the virtqueue is broken) then free it again if the function allocated a new buffer for it. Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Benjamin Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/virt-pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index 2ba89347053a..035c97aadb38 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -137,8 +137,11 @@ static int um_pci_send_cmd(struct um_pci_device *dev, out ? 1 : 0, posted ? cmd : HANDLE_NO_FREE(cmd), GFP_ATOMIC); - if (ret) + if (ret) { + if (posted) + kfree(cmd); goto out; + } if (posted) { virtqueue_kick(dev->cmd_vq); -- cgit v1.2.3 From 8e9cd85139a2149d5a7c121b05e0cdb8287311f9 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Thu, 9 Feb 2023 10:00:03 +0100 Subject: um: virtio_uml: mark device as unregistered when breaking it Mark the device as not registered anymore when scheduling the work to remove it. Otherwise we could end up scheduling the work multiple times in a row, including scheduling it while it is already running. Fixes: af9fb41ed315 ("um: virtio_uml: Fix broken device handling in time-travel") Signed-off-by: Benjamin Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/virtio_uml.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 198aaed81ce6..ecfaae7096e8 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -168,6 +168,8 @@ static void vhost_user_check_reset(struct virtio_uml_device *vu_dev, if (!vu_dev->registered) return; + vu_dev->registered = 0; + virtio_break_device(&vu_dev->vdev); schedule_work(&pdata->conn_broken_wk); } -- cgit v1.2.3 From abdeb4fa5e1b5b4918034f02236fd886f40c20c1 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Thu, 9 Feb 2023 10:00:04 +0100 Subject: um: virtio_uml: move device breaking into workqueue We should not be calling virtio_break_device from an IRQ context. Move breaking the device into the workqueue so that it is done from a reasonable context. Fixes: af9fb41ed315 ("um: virtio_uml: Fix broken device handling in time-travel") Signed-off-by: Benjamin Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/virtio_uml.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index ecfaae7096e8..8adca2000e51 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -170,7 +170,6 @@ static void vhost_user_check_reset(struct virtio_uml_device *vu_dev, vu_dev->registered = 0; - virtio_break_device(&vu_dev->vdev); schedule_work(&pdata->conn_broken_wk); } @@ -1138,6 +1137,15 @@ void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev, static void vu_of_conn_broken(struct work_struct *wk) { + struct virtio_uml_platform_data *pdata; + struct virtio_uml_device *vu_dev; + + pdata = container_of(wk, struct virtio_uml_platform_data, conn_broken_wk); + + vu_dev = platform_get_drvdata(pdata->pdev); + + virtio_break_device(&vu_dev->vdev); + /* * We can't remove the device from the devicetree so the only thing we * can do is warn. @@ -1268,8 +1276,14 @@ static int vu_unregister_cmdline_device(struct device *dev, void *data) static void vu_conn_broken(struct work_struct *wk) { struct virtio_uml_platform_data *pdata; + struct virtio_uml_device *vu_dev; pdata = container_of(wk, struct virtio_uml_platform_data, conn_broken_wk); + + vu_dev = platform_get_drvdata(pdata->pdev); + + virtio_break_device(&vu_dev->vdev); + vu_unregister_cmdline_device(&pdata->pdev->dev, NULL); } -- cgit v1.2.3 From 339b84dcd7113dd076419ea2a47128cc53450305 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Thu, 9 Feb 2023 10:00:05 +0100 Subject: um: virt-pci: properly remove PCI device from bus Triggering a bus rescan will not cause the PCI device to be removed. It is required to explicitly stop and remove the device from the bus. Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Benjamin Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/virt-pci.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index 035c97aadb38..7699ca5f35d4 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -711,22 +711,33 @@ static void um_pci_virtio_remove(struct virtio_device *vdev) return; } - /* Stop all virtqueues */ - virtio_reset_device(vdev); - vdev->config->del_vqs(vdev); - device_set_wakeup_enable(&vdev->dev, false); mutex_lock(&um_pci_mtx); for (i = 0; i < MAX_DEVICES; i++) { if (um_pci_devices[i].dev != dev) continue; + um_pci_devices[i].dev = NULL; irq_free_desc(dev->irq); + + break; } mutex_unlock(&um_pci_mtx); - um_pci_rescan(); + if (i < MAX_DEVICES) { + struct pci_dev *pci_dev; + + pci_dev = pci_get_slot(bridge->bus, i); + if (pci_dev) + pci_stop_and_remove_bus_device_locked(pci_dev); + } + + /* Stop all virtqueues */ + virtio_reset_device(vdev); + dev->cmd_vq = NULL; + dev->irq_vq = NULL; + vdev->config->del_vqs(vdev); kfree(dev); } -- cgit v1.2.3 From 6c7667c9bc12778d5566137fd4b34f03e1f36909 Mon Sep 17 00:00:00 2001 From: Carlos Bilbao Date: Thu, 9 Feb 2023 12:16:38 -0600 Subject: uml: vector: Remove unused definitions VECTOR_{WRITE,HEADERS} Remove definitions of VECTOR_WRITE and VECTOR_HEADERS since no longer used. Signed-off-by: Carlos Bilbao Acked-By: Anton Ivanov Signed-off-by: Richard Weinberger --- arch/um/drivers/vector_user.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/um/drivers/vector_user.h b/arch/um/drivers/vector_user.h index 3a73d17a0161..59ed5f9e6e41 100644 --- a/arch/um/drivers/vector_user.h +++ b/arch/um/drivers/vector_user.h @@ -68,8 +68,6 @@ struct vector_fds { }; #define VECTOR_READ 1 -#define VECTOR_WRITE (1 < 1) -#define VECTOR_HEADERS (1 < 2) extern struct arglist *uml_parse_vector_ifspec(char *arg); -- cgit v1.2.3 From 04df97e150c83d4640540008e95d0229cb188135 Mon Sep 17 00:00:00 2001 From: Bagas Sanjaya Date: Mon, 13 Feb 2023 15:59:20 +0700 Subject: Documentation: rust: Fix arch support table Stephen Rothwell reported htmldocs warning when merging uml tree: Documentation/rust/arch-support.rst:20: WARNING: Blank line required after table. Fix the arch support table by removing extraneous simple table marker. Link: https://lore.kernel.org/linux-next/20230213152714.78b844f4@canb.auug.org.au/ Fixes: 0438aadfa69a34 ("rust: arch/um: Add support for CONFIG_RUST under x86_64 UML") Reported-by: Stephen Rothwell Signed-off-by: Bagas Sanjaya Signed-off-by: Richard Weinberger --- Documentation/rust/arch-support.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst index a526ca1c688b..ed7f4f5b3cf1 100644 --- a/Documentation/rust/arch-support.rst +++ b/Documentation/rust/arch-support.rst @@ -16,6 +16,6 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file. Architecture Level of support Constraints ============ ================ ============================================== ``x86`` Maintained ``x86_64`` only. -============ ================ ============================================== ``um`` Maintained ``x86_64`` only. ============ ================ ============================================== + -- cgit v1.2.3