From 5f8539e2ff962e25b57742ca7106456403abbc94 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 31 Aug 2021 09:27:53 +0200 Subject: [PATCH 01/31] um: fix ndelay/udelay defines Many places in the kernel use 'udelay' as an identifier, and are broken with the current "#define udelay um_udelay". Fix this by adding an argument to the macro, and do the same to 'ndelay' as well, just in case. Fixes: 0bc8fb4dda2b ("um: Implement ndelay/udelay in time-travel mode") Reported-by: kernel test robot Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/include/asm/delay.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h index 56fc2b8f2dd0..e79b2ab6f40c 100644 --- a/arch/um/include/asm/delay.h +++ b/arch/um/include/asm/delay.h @@ -14,7 +14,7 @@ static inline void um_ndelay(unsigned long nsecs) ndelay(nsecs); } #undef ndelay -#define ndelay um_ndelay +#define ndelay(n) um_ndelay(n) static inline void um_udelay(unsigned long usecs) { @@ -26,5 +26,5 @@ static inline void um_udelay(unsigned long usecs) udelay(usecs); } #undef udelay -#define udelay um_udelay +#define udelay(n) um_udelay(n) #endif /* __UM_DELAY_H */ From bbe33504d4a7fdab9011211e55e262c869b3f6cc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 31 Aug 2021 09:11:15 +0200 Subject: [PATCH 02/31] um: rename set_signals() to um_set_signals() Rename set_signals() as there's at least one driver that uses the same name and can now be built on UM due to PCI support, and thus we can get symbol conflicts. Also rename set_signals_trace() to be consistent. Reported-by: kernel test robot Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/include/asm/irqflags.h | 4 ++-- arch/um/include/shared/longjmp.h | 2 +- arch/um/include/shared/os.h | 4 ++-- arch/um/kernel/ksyms.c | 2 +- arch/um/os-Linux/sigio.c | 6 +++--- arch/um/os-Linux/signal.c | 8 ++++---- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h index dab5744e9253..1e69ef5bc35e 100644 --- a/arch/um/include/asm/irqflags.h +++ b/arch/um/include/asm/irqflags.h @@ -3,7 +3,7 @@ #define __UM_IRQFLAGS_H extern int signals_enabled; -int set_signals(int enable); +int um_set_signals(int enable); void block_signals(void); void unblock_signals(void); @@ -16,7 +16,7 @@ static inline unsigned long arch_local_save_flags(void) #define arch_local_irq_restore arch_local_irq_restore static inline void arch_local_irq_restore(unsigned long flags) { - set_signals(flags); + um_set_signals(flags); } #define arch_local_irq_enable arch_local_irq_enable diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h index bdb2869b72b3..8863319039f3 100644 --- a/arch/um/include/shared/longjmp.h +++ b/arch/um/include/shared/longjmp.h @@ -18,7 +18,7 @@ extern void longjmp(jmp_buf, int); enable = *(volatile int *)&signals_enabled; \ n = setjmp(*buf); \ if(n != 0) \ - set_signals_trace(enable); \ + um_set_signals_trace(enable); \ n; }) #endif diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 96d400387c93..03ffbdddcc48 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -238,8 +238,8 @@ extern void send_sigio_to_self(void); extern int change_sig(int signal, int on); extern void block_signals(void); extern void unblock_signals(void); -extern int set_signals(int enable); -extern int set_signals_trace(int enable); +extern int um_set_signals(int enable); +extern int um_set_signals_trace(int enable); extern int os_is_signal_stack(void); extern void deliver_alarm(void); extern void register_pm_wake_signal(void); diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index b1e5634398d0..3a85bde3e173 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -6,7 +6,7 @@ #include #include -EXPORT_SYMBOL(set_signals); +EXPORT_SYMBOL(um_set_signals); EXPORT_SYMBOL(signals_enabled); EXPORT_SYMBOL(os_stat_fd); diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 6597ea1986ff..9e71794839e8 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -132,7 +132,7 @@ static void update_thread(void) int n; char c; - flags = set_signals_trace(0); + flags = um_set_signals_trace(0); CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c))); if (n != sizeof(c)) { printk(UM_KERN_ERR "update_thread : write failed, err = %d\n", @@ -147,7 +147,7 @@ static void update_thread(void) goto fail; } - set_signals_trace(flags); + um_set_signals_trace(flags); return; fail: /* Critical section start */ @@ -161,7 +161,7 @@ static void update_thread(void) close(write_sigio_fds[0]); close(write_sigio_fds[1]); /* Critical section end */ - set_signals_trace(flags); + um_set_signals_trace(flags); } int __add_sigio_fd(int fd) diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 6cf098c23a39..24a403a70a02 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -94,7 +94,7 @@ void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) sig_handler_common(sig, si, mc); - set_signals_trace(enabled); + um_set_signals_trace(enabled); } static void timer_real_alarm_handler(mcontext_t *mc) @@ -126,7 +126,7 @@ void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) signals_active &= ~SIGALRM_MASK; - set_signals_trace(enabled); + um_set_signals_trace(enabled); } void deliver_alarm(void) { @@ -348,7 +348,7 @@ void unblock_signals(void) } } -int set_signals(int enable) +int um_set_signals(int enable) { int ret; if (signals_enabled == enable) @@ -362,7 +362,7 @@ int set_signals(int enable) return ret; } -int set_signals_trace(int enable) +int um_set_signals_trace(int enable) { int ret; if (signals_enabled == enable) From 494545aa9b50a1dcaafcb235e2cb40b246c65169 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 28 Sep 2021 11:51:46 +0200 Subject: [PATCH 03/31] uml: x86: add FORCE to user_constants.h The build system has started warning when filechk is called without FORCE: arch/x86/um/Makefile:44: FORCE prerequisite is missing Add FORCE to make sure the file is checked/rebuilt when necessary (and to quiet up the warning.) Signed-off-by: Johannes Berg Reviewed-by: David Gow Signed-off-by: Richard Weinberger --- arch/x86/um/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile index 5ccb18290d71..ba5789c35809 100644 --- a/arch/x86/um/Makefile +++ b/arch/x86/um/Makefile @@ -40,7 +40,7 @@ $(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \ -Iarch/x86/include/generated targets += user-offsets.s -include/generated/user_constants.h: $(obj)/user-offsets.s +include/generated/user_constants.h: $(obj)/user-offsets.s FORCE $(call filechk,offsets,__USER_CONSTANT_H__) UNPROFILE_OBJS := stub_segv.o From 8bd18ef9eaac2e812b42da9eb19b2d59293aa25b Mon Sep 17 00:00:00 2001 From: Changcheng Deng Date: Fri, 27 Aug 2021 18:11:08 -0700 Subject: [PATCH 04/31] um: Replace if (cond) BUG() with BUG_ON() Fix the following coccinelle reports: ./arch/um/kernel/mem.c:89:2-5: WARNING: Use BUG_ON instead of if condition followed by BUG. Reported-by: Zeal Robot Signed-off-by: Changcheng Deng Signed-off-by: Richard Weinberger --- arch/um/kernel/mem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 0039771eb01c..15295c3237a0 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -85,8 +85,7 @@ static void __init one_md_table_init(pud_t *pud) __func__, PAGE_SIZE, PAGE_SIZE); set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table))); - if (pmd_table != pmd_offset(pud, 0)) - BUG(); + BUG_ON(pmd_table != pmd_offset(pud, 0)); #endif } From 077b7320942b64b0da182aefd83c374462a65535 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 12 Sep 2021 23:12:52 -0700 Subject: [PATCH 05/31] um: registers: Rename function names to avoid conflicts and build problems The function names init_registers() and restore_registers() are used in several net/ethernet/ and gpu/drm/ drivers for other purposes (not calls to UML functions), so rename them. This fixes multiple build errors. Signed-off-by: Randy Dunlap Cc: Jeff Dike Cc: Richard Weinberger Cc: Anton Ivanov Cc: linux-um@lists.infradead.org Signed-off-by: Richard Weinberger --- arch/um/include/shared/registers.h | 4 ++-- arch/um/os-Linux/registers.c | 4 ++-- arch/um/os-Linux/start_up.c | 2 +- arch/x86/um/syscalls_64.c | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h index 0c50fa6e8a55..fbb709a22283 100644 --- a/arch/um/include/shared/registers.h +++ b/arch/um/include/shared/registers.h @@ -16,8 +16,8 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs); extern int save_fpx_registers(int pid, unsigned long *fp_regs); extern int restore_fpx_registers(int pid, unsigned long *fp_regs); extern int save_registers(int pid, struct uml_pt_regs *regs); -extern int restore_registers(int pid, struct uml_pt_regs *regs); -extern int init_registers(int pid); +extern int restore_pid_registers(int pid, struct uml_pt_regs *regs); +extern int init_pid_registers(int pid); extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); extern unsigned long get_thread_reg(int reg, jmp_buf *buf); extern int get_fp_registers(int pid, unsigned long *regs); diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c index 2d9270508e15..b123955be7ac 100644 --- a/arch/um/os-Linux/registers.c +++ b/arch/um/os-Linux/registers.c @@ -21,7 +21,7 @@ int save_registers(int pid, struct uml_pt_regs *regs) return 0; } -int restore_registers(int pid, struct uml_pt_regs *regs) +int restore_pid_registers(int pid, struct uml_pt_regs *regs) { int err; @@ -36,7 +36,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs) static unsigned long exec_regs[MAX_REG_NR]; static unsigned long exec_fp_regs[FP_SIZE]; -int init_registers(int pid) +int init_pid_registers(int pid) { int err; diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 8a72c99994eb..e3ee4db58b40 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -368,7 +368,7 @@ void __init os_early_checks(void) check_tmpexec(); pid = start_ptraced_child(); - if (init_registers(pid)) + if (init_pid_registers(pid)) fatal("Failed to initialize default registers"); stop_ptraced_child(pid, 1, 1); } diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c index 58f51667e2e4..8249685b4096 100644 --- a/arch/x86/um/syscalls_64.c +++ b/arch/x86/um/syscalls_64.c @@ -11,6 +11,7 @@ #include #include /* XXX This should get the constants from libc */ #include +#include long arch_prctl(struct task_struct *task, int option, unsigned long __user *arg2) @@ -35,7 +36,7 @@ long arch_prctl(struct task_struct *task, int option, switch (option) { case ARCH_SET_FS: case ARCH_SET_GS: - ret = restore_registers(pid, ¤t->thread.regs.regs); + ret = restore_pid_registers(pid, ¤t->thread.regs.regs); if (ret) return ret; break; From 4b86366fdfbedec42f8f7ee037775f2839921d34 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 13 Sep 2021 10:17:29 +0200 Subject: [PATCH 06/31] um: gitignore: Add kernel/capflags.c This file is generated, we should ignore it. Fixes: d8fb32f4790f ("um: Add support for host CPU flags and alignment") Signed-off-by: Johannes Berg Acked-By: anton.ivanov@cambridgegreys.com Signed-off-by: Richard Weinberger --- arch/um/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/um/.gitignore b/arch/um/.gitignore index 6323e5571887..d69ea5b562ce 100644 --- a/arch/um/.gitignore +++ b/arch/um/.gitignore @@ -2,3 +2,4 @@ kernel/config.c kernel/config.tmp kernel/vmlinux.lds +kernel/capflags.c From d73820df6437b5d0a57be53faf39db46a0264b3a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 15 Sep 2021 20:30:20 +0200 Subject: [PATCH 07/31] um: virt-pci: Fix 32-bit compile There were a few 32-bit compile warnings that of course turned into errors with -Werror, fix the 32-bit build. Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Reported-by: Al Viro Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/virt-pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index c08066633023..0ab58016db22 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -181,15 +181,15 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset, /* buf->data is maximum size - we may only use parts of it */ struct um_pci_message_buffer *buf; u8 *data; - unsigned long ret = ~0ULL; + unsigned long ret = ULONG_MAX; if (!dev) - return ~0ULL; + return ULONG_MAX; buf = get_cpu_var(um_pci_msg_bufs); data = buf->data; - memset(data, 0xff, sizeof(data)); + memset(buf->data, 0xff, sizeof(buf->data)); switch (size) { case 1: @@ -304,7 +304,7 @@ static unsigned long um_pci_bar_read(void *priv, unsigned int offset, /* buf->data is maximum size - we may only use parts of it */ struct um_pci_message_buffer *buf; u8 *data; - unsigned long ret = ~0ULL; + unsigned long ret = ULONG_MAX; buf = get_cpu_var(um_pci_msg_bufs); data = buf->data; From 4e84139e14af5ea60772cc4f33d7059aec76e0eb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 15 Sep 2021 20:30:21 +0200 Subject: [PATCH 08/31] lib/logic_iomem: Fix 32-bit build On a 32-bit build, the (unsigned long long) casts throw warnings (or errors) due to being to a different integer size. Cast to uintptr_t first (with the __force for sparse) and then further to get the consistent print on 32 and 64-bit. Fixes: ca2e334232b6 ("lib: add iomem emulation (logic_iomem)") Reported-by: Al Viro Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- lib/logic_iomem.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/logic_iomem.c b/lib/logic_iomem.c index 9bdfde0c0f86..54fa601f3300 100644 --- a/lib/logic_iomem.c +++ b/lib/logic_iomem.c @@ -79,7 +79,7 @@ static void __iomem *real_ioremap(phys_addr_t offset, size_t size) static void real_iounmap(void __iomem *addr) { WARN(1, "invalid iounmap for addr 0x%llx\n", - (unsigned long long __force)addr); + (unsigned long long)(uintptr_t __force)addr); } #endif /* CONFIG_LOGIC_IOMEM_FALLBACK */ @@ -173,7 +173,7 @@ EXPORT_SYMBOL(iounmap); static u##sz real_raw_read ## op(const volatile void __iomem *addr) \ { \ WARN(1, "Invalid read" #op " at address %llx\n", \ - (unsigned long long __force)addr); \ + (unsigned long long)(uintptr_t __force)addr); \ return (u ## sz)~0ULL; \ } \ \ @@ -181,7 +181,8 @@ static void real_raw_write ## op(u ## sz val, \ volatile void __iomem *addr) \ { \ WARN(1, "Invalid writeq" #op " of 0x%llx at address %llx\n", \ - (unsigned long long)val, (unsigned long long __force)addr);\ + (unsigned long long)val, \ + (unsigned long long)(uintptr_t __force)addr);\ } \ MAKE_FALLBACK(b, 8); @@ -194,14 +195,14 @@ MAKE_FALLBACK(q, 64); static void real_memset_io(volatile void __iomem *addr, int value, size_t size) { WARN(1, "Invalid memset_io at address 0x%llx\n", - (unsigned long long __force)addr); + (unsigned long long)(uintptr_t __force)addr); } static void real_memcpy_fromio(void *buffer, const volatile void __iomem *addr, size_t size) { WARN(1, "Invalid memcpy_fromio at address 0x%llx\n", - (unsigned long long __force)addr); + (unsigned long long)(uintptr_t __force)addr); memset(buffer, 0xff, size); } @@ -210,7 +211,7 @@ static void real_memcpy_toio(volatile void __iomem *addr, const void *buffer, size_t size) { WARN(1, "Invalid memcpy_toio at address 0x%llx\n", - (unsigned long long __force)addr); + (unsigned long long)(uintptr_t __force)addr); } #endif /* CONFIG_LOGIC_IOMEM_FALLBACK */ From 4e8a5edac5010820e7c5303fc96f5a262e096bb6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 15 Sep 2021 20:30:22 +0200 Subject: [PATCH 09/31] lib/logic_iomem: Fix operation on 32-bit On 32-bit, the first entry might be at 0/NULL, but that's strange and leads to issues, e.g. where we check "if (ret)". Use a IOREMAP_BIAS/IOREMAP_MASK of 0x80000000UL to avoid this. This then requires reducing the number of areas (via MAX_AREAS), but we still have 128 areas, which is enough. Fixes: ca2e334232b6 ("lib: add iomem emulation (logic_iomem)") Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- lib/logic_iomem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/logic_iomem.c b/lib/logic_iomem.c index 54fa601f3300..549b22d4bcde 100644 --- a/lib/logic_iomem.c +++ b/lib/logic_iomem.c @@ -21,15 +21,15 @@ struct logic_iomem_area { #define AREA_SHIFT 24 #define MAX_AREA_SIZE (1 << AREA_SHIFT) -#define MAX_AREAS ((1ULL<<32) / MAX_AREA_SIZE) +#define MAX_AREAS ((1U << 31) / MAX_AREA_SIZE) #define AREA_BITS ((MAX_AREAS - 1) << AREA_SHIFT) #define AREA_MASK (MAX_AREA_SIZE - 1) #ifdef CONFIG_64BIT #define IOREMAP_BIAS 0xDEAD000000000000UL #define IOREMAP_MASK 0xFFFFFFFF00000000UL #else -#define IOREMAP_BIAS 0 -#define IOREMAP_MASK 0 +#define IOREMAP_BIAS 0x80000000UL +#define IOREMAP_MASK 0x80000000UL #endif static DEFINE_MUTEX(regions_mtx); From 85e73968a040c642fd38f6cba5b73b61f5d0f052 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Sep 2021 13:09:22 +0200 Subject: [PATCH 10/31] um: virtio_uml: Fix time-travel external time propagation When creating an external event, the current time needs to be propagated to other participants of a simulation. This is done in the places here where we kick a virtq etc. However, it must be done for _all_ external events, and that includes making the initial socket connection and later closing it. Call time_travel_propagate_time() to do this before making or closing the socket connection. Apparently, at least for the initial connection creation, due to the remote side in my use cases using microseconds (rather than nanoseconds), this wasn't a problem yet; only started failing between 5.14-rc1 and 5.15-rc1 (didn't test others much), or possibly depending on the configuration, where more delays happen before the virtio devices are initialized. Fixes: 88ce64249233 ("um: Implement time-travel=ext") Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/virtio_uml.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index d51e445df797..7755cb4ff9fc 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -1090,6 +1090,8 @@ static void virtio_uml_release_dev(struct device *d) container_of(d, struct virtio_device, dev); struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev); + time_travel_propagate_time(); + /* might not have been opened due to not negotiating the feature */ if (vu_dev->req_fd >= 0) { um_free_irq(vu_dev->irq, vu_dev); @@ -1136,6 +1138,8 @@ static int virtio_uml_probe(struct platform_device *pdev) vu_dev->pdev = pdev; vu_dev->req_fd = -1; + time_travel_propagate_time(); + do { rc = os_connect_socket(pdata->socket_path); } while (rc == -EINTR); From 8f5c84f3678e72bbba96b0755135adae66d35c0e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:47 +0000 Subject: [PATCH 11/31] uml: trim unused junk from arch/x86/um/sys_call_table_*.c a bunch of detritus there - definitions that are never expanded or checked. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/x86/um/sys_call_table_32.c | 4 ---- arch/x86/um/sys_call_table_64.c | 14 -------------- 2 files changed, 18 deletions(-) diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c index 0575decb5e54..89df5d89d664 100644 --- a/arch/x86/um/sys_call_table_32.c +++ b/arch/x86/um/sys_call_table_32.c @@ -9,8 +9,6 @@ #include #include -#define __NO_STUBS - /* * Below you can see, in terms of #define's, the differences between the x86-64 * and the UML syscall table. @@ -23,8 +21,6 @@ #define sys_vm86old sys_ni_syscall #define sys_vm86 sys_ni_syscall -#define old_mmap sys_old_mmap - #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) #define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c index 95725b5a41ac..82b695ed23c4 100644 --- a/arch/x86/um/sys_call_table_64.c +++ b/arch/x86/um/sys_call_table_64.c @@ -9,8 +9,6 @@ #include #include -#define __NO_STUBS - /* * Below you can see, in terms of #define's, the differences between the x86-64 * and the UML syscall table. @@ -20,21 +18,9 @@ #define sys_iopl sys_ni_syscall #define sys_ioperm sys_ni_syscall -/* - * The UML TLS problem. Note that x86_64 does not implement this, so the below - * is needed only for the ia32 compatibility. - */ - /* On UML we call it this way ("old" means it's not mmap2) */ #define sys_mmap old_mmap -#define stub_clone sys_clone -#define stub_fork sys_fork -#define stub_vfork sys_vfork -#define stub_execve sys_execve -#define stub_execveat sys_execveat -#define stub_rt_sigreturn sys_rt_sigreturn - #define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); #include From 577ade59b99e3473b2f1342b1eb9e496eed39b68 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:48 +0000 Subject: [PATCH 12/31] um: move amd64 variant of mmap(2) to arch/x86/um/syscalls_64.c Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/kernel/Makefile | 2 +- arch/um/kernel/syscall.c | 28 ------------------------- arch/x86/um/shared/sysdep/syscalls_64.h | 3 --- arch/x86/um/sys_call_table_64.c | 3 --- arch/x86/um/syscalls_64.c | 10 +++++++++ 5 files changed, 11 insertions(+), 35 deletions(-) delete mode 100644 arch/um/kernel/syscall.c diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 1d18e4e46989..7ab6d40558b6 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -16,7 +16,7 @@ extra-y := vmlinux.lds obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ - signal.o syscall.o sysrq.o time.o tlb.o trap.o \ + signal.o sysrq.o time.o tlb.o trap.o \ um_arch.o umid.o maccess.o kmsg_dump.o capflags.o skas/ obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c deleted file mode 100644 index eed54c53fbbb..000000000000 --- a/arch/um/kernel/syscall.c +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -long old_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long offset) -{ - long err = -EINVAL; - if (offset & ~PAGE_MASK) - goto out; - - err = ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); - out: - return err; -} diff --git a/arch/x86/um/shared/sysdep/syscalls_64.h b/arch/x86/um/shared/sysdep/syscalls_64.h index 8a7d5e1da98e..48d6cd12f8a5 100644 --- a/arch/x86/um/shared/sysdep/syscalls_64.h +++ b/arch/x86/um/shared/sysdep/syscalls_64.h @@ -23,9 +23,6 @@ extern syscall_handler_t *sys_call_table[]; UPT_SYSCALL_ARG5(®s->regs), \ UPT_SYSCALL_ARG6(®s->regs))) -extern long old_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff); extern syscall_handler_t sys_modify_ldt; extern syscall_handler_t sys_arch_prctl; diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c index 82b695ed23c4..b0b4cfd2308c 100644 --- a/arch/x86/um/sys_call_table_64.c +++ b/arch/x86/um/sys_call_table_64.c @@ -18,9 +18,6 @@ #define sys_iopl sys_ni_syscall #define sys_ioperm sys_ni_syscall -/* On UML we call it this way ("old" means it's not mmap2) */ -#define sys_mmap old_mmap - #define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); #include diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c index 8249685b4096..e768f54b118c 100644 --- a/arch/x86/um/syscalls_64.c +++ b/arch/x86/um/syscalls_64.c @@ -88,3 +88,13 @@ void arch_switch_to(struct task_struct *to) arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); } + +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, off) +{ + if (off & ~PAGE_MASK) + return -EINVAL; + + return ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); +} From 5f174ec3c1d62013f86db6597249174d8cb227b2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:49 +0000 Subject: [PATCH 13/31] logic_io instance of iounmap() needs volatile on argument ... same as the rest of implementations Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- include/asm-generic/logic_io.h | 2 +- lib/logic_iomem.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/asm-generic/logic_io.h b/include/asm-generic/logic_io.h index a53116b8c57e..8a59b6e567df 100644 --- a/include/asm-generic/logic_io.h +++ b/include/asm-generic/logic_io.h @@ -34,7 +34,7 @@ void __iomem *ioremap(phys_addr_t offset, size_t size); #define iounmap iounmap -void iounmap(void __iomem *addr); +void iounmap(void volatile __iomem *addr); #define __raw_readb __raw_readb u8 __raw_readb(const volatile void __iomem *addr); diff --git a/lib/logic_iomem.c b/lib/logic_iomem.c index 549b22d4bcde..8c3365f26e51 100644 --- a/lib/logic_iomem.c +++ b/lib/logic_iomem.c @@ -76,7 +76,7 @@ static void __iomem *real_ioremap(phys_addr_t offset, size_t size) return NULL; } -static void real_iounmap(void __iomem *addr) +static void real_iounmap(volatile void __iomem *addr) { WARN(1, "invalid iounmap for addr 0x%llx\n", (unsigned long long)(uintptr_t __force)addr); @@ -149,7 +149,7 @@ get_area(const volatile void __iomem *addr) return NULL; } -void iounmap(void __iomem *addr) +void iounmap(volatile void __iomem *addr) { struct logic_iomem_area *area = get_area(addr); From dbba7f704aa0c38e36c9908012e7592c8f6efc43 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:50 +0000 Subject: [PATCH 14/31] um: stop polluting the namespace with registers.h contents Only one extern in there is needed in processor-generic.h, and it's not needed anywhere else. So move it over there and get rid of the include in processor-generic.h, adding includes of registers.h to the few files that need the declarations in it. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/asm/processor-generic.h | 2 +- arch/um/include/shared/registers.h | 2 -- arch/um/kernel/exec.c | 1 + arch/um/kernel/process.c | 1 + arch/x86/um/os-Linux/registers.c | 1 + arch/x86/um/ptrace_32.c | 1 + arch/x86/um/ptrace_64.c | 1 + arch/x86/um/signal.c | 1 + arch/x86/um/syscalls_64.c | 1 + 9 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index 579692a40a55..6a4fe8b4e686 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h @@ -11,7 +11,6 @@ struct pt_regs; struct task_struct; #include -#include #include #include @@ -105,6 +104,7 @@ extern struct cpuinfo_um boot_cpu_data; #define current_cpu_data boot_cpu_data #define cache_line_size() (boot_cpu_data.cache_alignment) +extern unsigned long get_thread_reg(int reg, jmp_buf *buf); #define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf) extern unsigned long __get_wchan(struct task_struct *p); diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h index fbb709a22283..2f9c3ce5b45e 100644 --- a/arch/um/include/shared/registers.h +++ b/arch/um/include/shared/registers.h @@ -7,7 +7,6 @@ #define __REGISTERS_H #include -#include extern int save_i387_registers(int pid, unsigned long *fp_regs); extern int restore_i387_registers(int pid, unsigned long *fp_regs); @@ -19,7 +18,6 @@ extern int save_registers(int pid, struct uml_pt_regs *regs); extern int restore_pid_registers(int pid, struct uml_pt_regs *regs); extern int init_pid_registers(int pid); extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); -extern unsigned long get_thread_reg(int reg, jmp_buf *buf); extern int get_fp_registers(int pid, unsigned long *regs); extern int put_fp_registers(int pid, unsigned long *regs); diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 4d8498100341..c85e40c72779 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 82107373ac7e..7055cd446155 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -31,6 +31,7 @@ #include #include #include +#include #include /* diff --git a/arch/x86/um/os-Linux/registers.c b/arch/x86/um/os-Linux/registers.c index 3c423dfcd78b..df8f4b4bf98b 100644 --- a/arch/x86/um/os-Linux/registers.c +++ b/arch/x86/um/os-Linux/registers.c @@ -15,6 +15,7 @@ #include #include #include +#include int have_xstate_support; diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c index 2497bac56066..0bc4b73a9cde 100644 --- a/arch/x86/um/ptrace_32.c +++ b/arch/x86/um/ptrace_32.c @@ -7,6 +7,7 @@ #include #include #include +#include #include extern int arch_switch_tls(struct task_struct *to); diff --git a/arch/x86/um/ptrace_64.c b/arch/x86/um/ptrace_64.c index 1401899dee9b..289d0159b041 100644 --- a/arch/x86/um/ptrace_64.c +++ b/arch/x86/um/ptrace_64.c @@ -11,6 +11,7 @@ #define __FRAME_OFFSETS #include #include +#include #include /* diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c index 7c11c9e5d7ea..263e1d08f216 100644 --- a/arch/x86/um/signal.c +++ b/arch/x86/um/signal.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #ifdef CONFIG_X86_32 diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c index e768f54b118c..fe5323f0c42d 100644 --- a/arch/x86/um/syscalls_64.c +++ b/arch/x86/um/syscalls_64.c @@ -10,6 +10,7 @@ #include #include #include /* XXX This should get the constants from libc */ +#include #include #include From 2098e213dd64b1d10b8fc6fc66e3a2a80f841dbe Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:51 +0000 Subject: [PATCH 15/31] uml/i386: missing include in barrier.h we need cpufeatures.h there Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/x86/um/asm/barrier.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h index 165be7f9a964..4da336965698 100644 --- a/arch/x86/um/asm/barrier.h +++ b/arch/x86/um/asm/barrier.h @@ -2,6 +2,7 @@ #ifndef _ASM_UM_BARRIER_H_ #define _ASM_UM_BARRIER_H_ +#include #include /* From 6605a448668b9d03aa94fbd6be42612d49aa45c6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:52 +0000 Subject: [PATCH 16/31] um: kill unused cpu() Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/kern_util.h | 1 - arch/um/kernel/process.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index a2cfd42608a0..fbfff76065c5 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -53,7 +53,6 @@ extern void do_uml_exitcalls(void); extern int __cant_sleep(void); extern int get_current_pid(void); extern int copy_from_user_proc(void *to, void *from, int size); -extern int cpu(void); extern char *uml_strdup(const char *string); extern unsigned long to_irq_stack(unsigned long *mask_out); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 7055cd446155..4a420778ed87 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -264,11 +264,6 @@ int clear_user_proc(void __user *buf, int size) return clear_user(buf, size); } -int cpu(void) -{ - return current_thread_info()->cpu; -} - static atomic_t using_sysemu = ATOMIC_INIT(0); int sysemu_supported; From 7f5f156daec393d3f3433866dcc4d5c452f7feb6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:53 +0000 Subject: [PATCH 17/31] um: remove a dangling extern of syscall_trace() the function had been gone since 2012... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/kern_util.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index fbfff76065c5..d8b8b4f07e42 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -58,7 +58,6 @@ extern char *uml_strdup(const char *string); extern unsigned long to_irq_stack(unsigned long *mask_out); extern unsigned long from_irq_stack(int nested); -extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); extern int singlestepping(void *t); extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); From 21cba62bea84339ccdb7c40237dda8d5ba167c75 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:54 +0000 Subject: [PATCH 18/31] um: unexport handle_page_fault() Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/kernel/trap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index c32efb09db21..561a2b03c3cf 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -127,7 +127,6 @@ out_of_memory: pagefault_out_of_memory(); return 0; } -EXPORT_SYMBOL(handle_page_fault); static void show_segv_info(struct uml_pt_regs *regs) { From 2610ed63ead1e394f9f4a7e3518f2f589d10ee32 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:55 +0000 Subject: [PATCH 19/31] um, x86: bury crypto_tfm_ctx_offset unused since 2011 Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/common-offsets.h | 3 --- arch/x86/kernel/asm-offsets.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index edc90ab73734..b2483104e27f 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h @@ -18,9 +18,6 @@ DEFINE(UM_NR_CPUS, NR_CPUS); DEFINE(UM_GFP_KERNEL, GFP_KERNEL); DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC); -/* For crypto assembler code. */ -DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); - DEFINE(UM_THREAD_SIZE, THREAD_SIZE); DEFINE(UM_HZ, HZ); diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index ecd3fd6993d1..9fb0a2f8b62a 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c @@ -37,9 +37,6 @@ static void __used common(void) OFFSET(TASK_stack_canary, task_struct, stack_canary); #endif - BLANK(); - OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); - BLANK(); OFFSET(pbe_address, pbe, address); OFFSET(pbe_orig_address, pbe, orig_address); From 8e5d7cf3479abfc9c331a2d7faec0bac2b6f327a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:56 +0000 Subject: [PATCH 20/31] um: common-offsets.h debriding... Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/common-offsets.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index b2483104e27f..96195483fbd0 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h @@ -9,29 +9,17 @@ DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK); DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); -DEFINE(UM_ELF_CLASS, ELF_CLASS); -DEFINE(UM_ELFCLASS32, ELFCLASS32); -DEFINE(UM_ELFCLASS64, ELFCLASS64); - -DEFINE(UM_NR_CPUS, NR_CPUS); - DEFINE(UM_GFP_KERNEL, GFP_KERNEL); DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC); DEFINE(UM_THREAD_SIZE, THREAD_SIZE); -DEFINE(UM_HZ, HZ); - -DEFINE(UM_USEC_PER_SEC, USEC_PER_SEC); DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC); #ifdef CONFIG_PRINTK DEFINE(UML_CONFIG_PRINTK, CONFIG_PRINTK); #endif -#ifdef CONFIG_NO_HZ_COMMON -DEFINE(UML_CONFIG_NO_HZ_COMMON, CONFIG_NO_HZ_COMMON); -#endif #ifdef CONFIG_UML_X86 DEFINE(UML_CONFIG_UML_X86, CONFIG_UML_X86); #endif From ed4b1cc5900ecf67b70906a01850ba4ee11503c0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:57 +0000 Subject: [PATCH 21/31] um: header debriding - activate_ipi() ... had been dead for 15 years. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/irq_user.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h index 86a8a573b65c..da0f6eea30d0 100644 --- a/arch/um/include/shared/irq_user.h +++ b/arch/um/include/shared/irq_user.h @@ -20,6 +20,5 @@ void sigio_run_timetravel_handlers(void); extern void free_irq_by_fd(int fd); extern void deactivate_fd(int fd, int irqnum); extern int deactivate_all_fds(void); -extern int activate_ipi(int fd, int pid); #endif From bb1a2c4e2d48349f522fed3146a059135e0e5ac9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:58 +0000 Subject: [PATCH 22/31] um: header debriding - mem_user.h get_vm(), add_iomem(), phys_offset() dead since 2004; init_mem_user() and setup_memory() - since before the initial merge. Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/mem_user.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/um/include/shared/mem_user.h b/arch/um/include/shared/mem_user.h index cb84414e3e66..11a723a58545 100644 --- a/arch/um/include/shared/mem_user.h +++ b/arch/um/include/shared/mem_user.h @@ -46,16 +46,11 @@ extern int iomem_size; #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1)) -extern int init_mem_user(void); -extern void setup_memory(void *entry); extern unsigned long find_iomem(char *driver, unsigned long *len_out); extern void mem_total_pages(unsigned long physmem, unsigned long iomem, unsigned long highmem); -extern unsigned long get_vm(unsigned long len); extern void setup_physmem(unsigned long start, unsigned long usable, unsigned long len, unsigned long long highmem); -extern void add_iomem(char *name, int fd, unsigned long size); -extern unsigned long phys_offset(unsigned long phys); extern void map_memory(unsigned long virt, unsigned long phys, unsigned long len, int r, int w, int x); From b31ef6d89ddd3c24f28c969336d5f4bf6054a9d1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:32:59 +0000 Subject: [PATCH 23/31] um: header debriding - net_*.h externs dead since before the initial merge Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/net_kern.h | 2 -- arch/um/include/shared/net_user.h | 1 - 2 files changed, 3 deletions(-) diff --git a/arch/um/include/shared/net_kern.h b/arch/um/include/shared/net_kern.h index a87be13c5b87..441a8a309329 100644 --- a/arch/um/include/shared/net_kern.h +++ b/arch/um/include/shared/net_kern.h @@ -59,8 +59,6 @@ struct transport { const int setup_size; }; -extern struct net_device *ether_init(int); -extern unsigned short ether_protocol(struct sk_buff *); extern int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, char **gate_addr); extern void register_transport(struct transport *new); diff --git a/arch/um/include/shared/net_user.h b/arch/um/include/shared/net_user.h index 1b0531769a5e..ba92a4d93531 100644 --- a/arch/um/include/shared/net_user.h +++ b/arch/um/include/shared/net_user.h @@ -24,7 +24,6 @@ struct net_user_info { int mtu; }; -extern void ether_user_init(void *data, void *dev); extern void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, void *), void *arg); From 021fdaef807387113d8e7ec27b954b03cff7ff88 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:33:00 +0000 Subject: [PATCH 24/31] um: header debriding - os.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/os.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 03ffbdddcc48..00214059d9ec 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -159,20 +159,11 @@ extern int os_create_unix_socket(const char *file, int len, int close_on_exec); extern int os_shutdown_socket(int fd, int r, int w); extern void os_close_file(int fd); extern int os_rcv_fd(int fd, int *helper_pid_out); -extern int create_unix_socket(char *file, int len, int close_on_exec); extern int os_connect_socket(const char *name); extern int os_file_type(char *file); extern int os_file_mode(const char *file, struct openflags *mode_out); extern int os_lock_file(int fd, int excl); extern void os_flush_stdout(void); -extern int os_stat_filesystem(char *path, long *bsize_out, - long long *blocks_out, long long *bfree_out, - long long *bavail_out, long long *files_out, - long long *ffree_out, void *fsid_out, - int fsid_size, long *namelen_out, - long *spare_out); -extern int os_change_dir(char *dir); -extern int os_fchange_dir(int fd); extern unsigned os_major(unsigned long long dev); extern unsigned os_minor(unsigned long long dev); extern unsigned long long os_makedev(unsigned major, unsigned minor); @@ -232,7 +223,6 @@ extern char *get_umid(void); /* signal.c */ extern void timer_set_signal_handler(void); extern void set_sigstack(void *sig_stack, int size); -extern void remove_sigstack(void); extern void set_handler(int sig); extern void send_sigio_to_self(void); extern int change_sig(int signal, int on); @@ -266,7 +256,6 @@ extern int os_timer_create(void); extern int os_timer_set_interval(unsigned long long nsecs); extern int os_timer_one_shot(unsigned long long nsecs); extern void os_timer_disable(void); -extern void uml_idle_timer(void); extern long long os_persistent_clock_emulation(void); extern long long os_nsecs(void); @@ -290,8 +279,6 @@ extern int is_skas_winch(int pid, int fd, void *data); extern int start_userspace(unsigned long stub_stack); extern int copy_context_skas0(unsigned long stack, int pid); extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs); -extern int map_stub_pages(int fd, unsigned long code, unsigned long data, - unsigned long stack); extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); extern void switch_threads(jmp_buf *me, jmp_buf *you); extern int start_idle_thread(void *stack, jmp_buf *switch_buf); From 4c1f795773b3ef6e206ef84bc6a928803fa31b7d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Sep 2021 21:33:01 +0000 Subject: [PATCH 25/31] um: header debriding - sigio.h Signed-off-by: Al Viro Signed-off-by: Richard Weinberger --- arch/um/include/shared/sigio.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/um/include/shared/sigio.h b/arch/um/include/shared/sigio.h index 8fe8f57c05de..e60c8b227844 100644 --- a/arch/um/include/shared/sigio.h +++ b/arch/um/include/shared/sigio.h @@ -7,7 +7,6 @@ #define __SIGIO_H__ extern int write_sigio_irq(int fd); -extern int register_sigio_fd(int fd); extern void sigio_lock(void); extern void sigio_unlock(void); From 9b0da3f22307af693be80f5d3a89dc4c7f360a85 Mon Sep 17 00:00:00 2001 From: Yang Guang Date: Fri, 5 Nov 2021 14:12:59 +0800 Subject: [PATCH 26/31] um: Use swap() to make code cleaner Use the macro 'swap()' defined in 'include/linux/minmax.h' to avoid opencoding it. Reported-by: Zeal Robot Signed-off-by: Yang Guang Signed-off-by: Richard Weinberger --- arch/um/os-Linux/sigio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 9e71794839e8..37d60e72cf26 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -3,6 +3,7 @@ * Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) */ +#include #include #include #include @@ -50,7 +51,7 @@ static struct pollfds all_sigio_fds; static int write_sigio_thread(void *unused) { - struct pollfds *fds, tmp; + struct pollfds *fds; struct pollfd *p; int i, n, respond_fd; char c; @@ -77,9 +78,7 @@ static int write_sigio_thread(void *unused) "write_sigio_thread : " "read on socket failed, " "err = %d\n", errno); - tmp = current_poll; - current_poll = next_poll; - next_poll = tmp; + swap(current_poll, next_poll); respond_fd = sigio_private[1]; } else { From ce72750f04d68a45ef971c3547fe2d6f9cd4756e Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Fri, 5 Nov 2021 09:10:51 +0100 Subject: [PATCH 27/31] hostfs: Fix writeback of dirty pages Hostfs was not setting up the backing device information, which means it uses the noop bdi. The noop bdi does not have the writeback capability enabled, which in turns means dirty pages never got written back to storage. In other words programs using mmap to write to files on hostfs never actually got their data written out... Fix this by simply setting up the bdi with default settings as all the required code for writeback is already in place. Signed-off-by: Sjoerd Simons Reviewed-by: Christopher Obbard Tested-by: Ritesh Raj Sarraf Acked-By: Anton Ivanov Signed-off-by: Richard Weinberger --- fs/hostfs/hostfs_kern.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index d5c9d886cd9f..ef481c3d9019 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -924,6 +924,9 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) sb->s_op = &hostfs_sbops; sb->s_d_op = &simple_dentry_operations; sb->s_maxbytes = MAX_LFS_FILESIZE; + err = super_setup_bdi(sb); + if (err) + goto out; /* NULL is printed as '(null)' by printf(): avoid that. */ if (req_root == NULL) From 8bb227ac34c062b466a0d5fd21f060010375880b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 15 Dec 2021 17:56:12 +0100 Subject: [PATCH 28/31] um: remove set_fs Remove address space overrides using set_fs() for User Mode Linux. Note that just like the existing kernel access case of the uaccess routines the new nofault kernel handlers do not actually have any exception handling. This is probably broken, but not change to the status quo. Signed-off-by: Christoph Hellwig Signed-off-by: Richard Weinberger --- arch/um/Kconfig | 1 - arch/um/include/asm/thread_info.h | 4 ---- arch/um/include/asm/uaccess.h | 21 +++++++++++++++++++-- arch/um/kernel/skas/uaccess.c | 25 ------------------------- arch/x86/um/asm/segment.h | 8 -------- 5 files changed, 19 insertions(+), 40 deletions(-) diff --git a/arch/um/Kconfig b/arch/um/Kconfig index c18b45f75d41..aafdbb6e8059 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -21,7 +21,6 @@ config UML select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select HAVE_GCC_PLUGINS - select SET_FS select TRACE_IRQFLAGS_SUPPORT select TTY # Needed for line.c select HAVE_ARCH_VMAP_STACK diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index 3b1cb8b3b186..1395cbd7e340 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h @@ -22,9 +22,6 @@ struct thread_info { __u32 cpu; /* current CPU */ int preempt_count; /* 0 => preemptable, <0 => BUG */ - mm_segment_t addr_limit; /* thread address space: - 0-0xBFFFFFFF for user - 0-0xFFFFFFFF for kernel */ struct thread_info *real_thread; /* Points to non-IRQ stack */ unsigned long aux_fp_regs[FP_SIZE]; /* auxiliary fp_regs to save/restore them out-of-band */ @@ -36,7 +33,6 @@ struct thread_info { .flags = 0, \ .cpu = 0, \ .preempt_count = INIT_PREEMPT_COUNT, \ - .addr_limit = KERNEL_DS, \ .real_thread = NULL, \ } diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index 191ef36dd543..17d18cfd82a5 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -8,6 +8,7 @@ #define __UM_UACCESS_H #include +#include #define __under_task_size(addr, size) \ (((unsigned long) (addr) < TASK_SIZE) && \ @@ -39,8 +40,24 @@ static inline int __access_ok(unsigned long addr, unsigned long size) { return __addr_range_nowrap(addr, size) && (__under_task_size(addr, size) || - __access_ok_vsyscall(addr, size) || - uaccess_kernel()); + __access_ok_vsyscall(addr, size)); } +/* no pagefaults for kernel addresses in um */ +#define HAVE_GET_KERNEL_NOFAULT 1 + +#define __get_kernel_nofault(dst, src, type, err_label) \ +do { \ + *((type *)dst) = get_unaligned((type *)(src)); \ + if (0) /* make sure the label looks used to the compiler */ \ + goto err_label; \ +} while (0) + +#define __put_kernel_nofault(dst, src, type, err_label) \ +do { \ + put_unaligned(*((type *)src), (type *)(dst)); \ + if (0) /* make sure the label looks used to the compiler */ \ + goto err_label; \ +} while (0) + #endif diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index a509be911026..23775d01a2a6 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -146,11 +146,6 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg) unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - if (uaccess_kernel()) { - memcpy(to, (__force void*)from, n); - return 0; - } - return buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to); } EXPORT_SYMBOL(raw_copy_from_user); @@ -166,11 +161,6 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg) unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - if (uaccess_kernel()) { - memcpy((__force void *) to, from, n); - return 0; - } - return buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from); } EXPORT_SYMBOL(raw_copy_to_user); @@ -196,12 +186,6 @@ long strncpy_from_user(char *dst, const char __user *src, long count) if (!access_ok(src, 1)) return -EFAULT; - - if (uaccess_kernel()) { - strncpy(dst, (__force void *) src, count); - return strnlen(dst, count); - } - n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, &ptr); if (n != 0) @@ -218,11 +202,6 @@ static int clear_chunk(unsigned long addr, int len, void *unused) unsigned long __clear_user(void __user *mem, unsigned long len) { - if (uaccess_kernel()) { - memset((__force void*)mem, 0, len); - return 0; - } - return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL); } EXPORT_SYMBOL(__clear_user); @@ -245,10 +224,6 @@ long strnlen_user(const char __user *str, long len) if (!access_ok(str, 1)) return -EFAULT; - - if (uaccess_kernel()) - return strnlen((__force char*)str, len) + 1; - n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); if (n == 0) return count + 1; diff --git a/arch/x86/um/asm/segment.h b/arch/x86/um/asm/segment.h index 453db377150d..2ef507bc6989 100644 --- a/arch/x86/um/asm/segment.h +++ b/arch/x86/um/asm/segment.h @@ -8,12 +8,4 @@ extern int host_gdt_entry_tls_min; #define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min #define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) -typedef struct { - unsigned long seg; -} mm_segment_t; - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define KERNEL_DS MAKE_MM_SEG(~0UL) -#define USER_DS MAKE_MM_SEG(TASK_SIZE) - #endif From 361640b4fdc86167b0c25d8e73c08dcaa4ecd28a Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Wed, 8 Dec 2021 16:11:22 +0100 Subject: [PATCH 29/31] um: Extract load file helper from initrd.c The file loading support in initrd.c can be re-used for loading devicetrees. Move it out of initrd.c. Signed-off-by: Vincent Whitchurch Signed-off-by: Richard Weinberger --- arch/um/kernel/Makefile | 1 + arch/um/kernel/initrd.c | 48 ++++-------------------------- arch/um/kernel/load_file.c | 61 ++++++++++++++++++++++++++++++++++++++ arch/um/kernel/um_arch.h | 8 +++++ 4 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 arch/um/kernel/load_file.c create mode 100644 arch/um/kernel/um_arch.h diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 7ab6d40558b6..4ab4a0011043 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -18,6 +18,7 @@ obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ signal.o sysrq.o time.o tlb.o trap.o \ um_arch.o umid.o maccess.o kmsg_dump.o capflags.o skas/ +obj-y += load_file.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o obj-$(CONFIG_GPROF) += gprof_syms.o diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index c1981ffb7179..47b8cb1a1156 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -10,37 +10,21 @@ #include #include +#include "um_arch.h" + /* Changed by uml_initrd_setup, which is a setup */ static char *initrd __initdata = NULL; -static int load_initrd(char *filename, void *buf, int size); int __init read_initrd(void) { + unsigned long long size; void *area; - long long size; - int err; - if (initrd == NULL) + if (!initrd) return 0; - err = os_file_size(initrd, &size); - if (err) - return 0; - - /* - * This is necessary because alloc_bootmem craps out if you - * ask for no memory. - */ - if (size == 0) { - printk(KERN_ERR "\"%s\" is a zero-size initrd\n", initrd); - return 0; - } - - area = memblock_alloc(size, SMP_CACHE_BYTES); + area = uml_load_file(initrd, &size); if (!area) - panic("%s: Failed to allocate %llu bytes\n", __func__, size); - - if (load_initrd(initrd, area, size) == -1) return 0; initrd_start = (unsigned long) area; @@ -59,25 +43,3 @@ __uml_setup("initrd=", uml_initrd_setup, " This is used to boot UML from an initrd image. The argument is the\n" " name of the file containing the image.\n\n" ); - -static int load_initrd(char *filename, void *buf, int size) -{ - int fd, n; - - fd = os_open_file(filename, of_read(OPENFLAGS()), 0); - if (fd < 0) { - printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename, - -fd); - return -1; - } - n = os_read_file(fd, buf, size); - if (n != size) { - printk(KERN_ERR "Read of %d bytes from '%s' failed, " - "err = %d\n", size, - filename, -n); - return -1; - } - - os_close_file(fd); - return 0; -} diff --git a/arch/um/kernel/load_file.c b/arch/um/kernel/load_file.c new file mode 100644 index 000000000000..5cecd0e291fb --- /dev/null +++ b/arch/um/kernel/load_file.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + */ +#include +#include + +#include "um_arch.h" + +static int __init __uml_load_file(const char *filename, void *buf, int size) +{ + int fd, n; + + fd = os_open_file(filename, of_read(OPENFLAGS()), 0); + if (fd < 0) { + printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename, + -fd); + return -1; + } + n = os_read_file(fd, buf, size); + if (n != size) { + printk(KERN_ERR "Read of %d bytes from '%s' failed, " + "err = %d\n", size, + filename, -n); + return -1; + } + + os_close_file(fd); + return 0; +} + +void *uml_load_file(const char *filename, unsigned long long *size) +{ + void *area; + int err; + + *size = 0; + + if (!filename) + return NULL; + + err = os_file_size(filename, size); + if (err) + return NULL; + + if (*size == 0) { + printk(KERN_ERR "\"%s\" is empty\n", filename); + return NULL; + } + + area = memblock_alloc(*size, SMP_CACHE_BYTES); + if (!area) + panic("%s: Failed to allocate %llu bytes\n", __func__, *size); + + if (__uml_load_file(filename, area, *size)) { + memblock_free(area, *size); + return NULL; + } + + return area; +} diff --git a/arch/um/kernel/um_arch.h b/arch/um/kernel/um_arch.h new file mode 100644 index 000000000000..b195df3a09a0 --- /dev/null +++ b/arch/um/kernel/um_arch.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __UML_ARCH_H__ +#define __UML_ARCH_H__ + +extern void * __init uml_load_file(const char *filename, unsigned long long *size); + +#endif From b31297f04e86e4115ece79ca530d8ae1c454db75 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Wed, 8 Dec 2021 16:11:23 +0100 Subject: [PATCH 30/31] um: Add devicetree support Add a dtb= option to boot UML with a devicetree blob. This can be used for testing driver code using UML. Signed-off-by: Vincent Whitchurch [rw: Add dependency on CONFIG_OF] Signed-off-by: Richard Weinberger --- arch/um/Kconfig | 1 + arch/um/kernel/Makefile | 1 + arch/um/kernel/dtb.c | 41 ++++++++++++++++++++++++++++++++++++++++ arch/um/kernel/um_arch.c | 3 +++ arch/um/kernel/um_arch.h | 6 ++++++ 5 files changed, 52 insertions(+) create mode 100644 arch/um/kernel/dtb.c diff --git a/arch/um/Kconfig b/arch/um/Kconfig index aafdbb6e8059..b233db4f42b2 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -18,6 +18,7 @@ config UML select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_BUGVERBOSE select NO_DMA if !UML_DMA_EMULATION + select OF_EARLY_FLATTREE if OF select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select HAVE_GCC_PLUGINS diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 4ab4a0011043..1c2d4b29a3d4 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -22,6 +22,7 @@ obj-y += load_file.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o obj-$(CONFIG_GPROF) += gprof_syms.o +obj-$(CONFIG_OF) += dtb.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_GENERIC_PCI_IOMAP) += ioport.o diff --git a/arch/um/kernel/dtb.c b/arch/um/kernel/dtb.c new file mode 100644 index 000000000000..ca69d72025f3 --- /dev/null +++ b/arch/um/kernel/dtb.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include + +#include "um_arch.h" + +static char *dtb __initdata; + +void uml_dtb_init(void) +{ + long long size; + void *area; + + area = uml_load_file(dtb, &size); + if (!area) + return; + + if (!early_init_dt_scan(area)) { + pr_err("invalid DTB %s\n", dtb); + memblock_free(area, size); + return; + } + + unflatten_device_tree(); + early_init_fdt_scan_reserved_mem(); +} + +static int __init uml_dtb_setup(char *line, int *add) +{ + dtb = line; + return 0; +} + +__uml_setup("dtb=", uml_dtb_setup, +"dtb=\n" +" Boot the kernel with the devicetree blob from the specified file.\n" +); diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 54447690de11..abceeabe29b9 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -29,6 +29,8 @@ #include #include +#include "um_arch.h" + #define DEFAULT_COMMAND_LINE_ROOT "root=98:0" #define DEFAULT_COMMAND_LINE_CONSOLE "console=tty" @@ -407,6 +409,7 @@ void __init setup_arch(char **cmdline_p) stack_protections((unsigned long) &init_thread_info); setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); mem_total_pages(physmem_size, iomem_size, highmem); + uml_dtb_init(); read_initrd(); paging_init(); diff --git a/arch/um/kernel/um_arch.h b/arch/um/kernel/um_arch.h index b195df3a09a0..1e07fb7ee35e 100644 --- a/arch/um/kernel/um_arch.h +++ b/arch/um/kernel/um_arch.h @@ -5,4 +5,10 @@ extern void * __init uml_load_file(const char *filename, unsigned long long *size); +#ifdef CONFIG_OF +extern void __init uml_dtb_init(void); +#else +static inline void uml_dtb_init(void) { } +#endif + #endif From db0dd9cee82270e032123169ceff659eced5115d Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Tue, 21 Dec 2021 10:04:46 +0100 Subject: [PATCH 31/31] um: virtio_uml: Allow probing from devicetree Allow the virtio_uml device to be probed from the devicetree so that sub-devices can be specified using the standard virtio bindings, for example: virtio@1 { compatible = "virtio,uml"; socket-path = "i2c.sock"; virtio-device-id = <0x22>; i2c-controller { compatible = "virtio,device22"; #address-cells = <0x01>; #size-cells = <0x00>; light-sensor@01 { compatible = "ti,opt3001"; reg = <0x01>; }; }; }; Signed-off-by: Vincent Whitchurch Signed-off-by: Richard Weinberger --- arch/um/drivers/virtio_uml.c | 50 +++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 7755cb4ff9fc..ba562d68dc04 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -21,6 +21,7 @@ * Based on Virtio MMIO driver by Pawel Moll, copyright 2011-2014, ARM Ltd. */ #include +#include #include #include #include @@ -49,6 +50,7 @@ struct virtio_uml_platform_data { struct virtio_uml_device { struct virtio_device vdev; struct platform_device *pdev; + struct virtio_uml_platform_data *pdata; spinlock_t sock_lock; int sock, req_fd, irq; @@ -149,7 +151,7 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev, if (rc == -ECONNRESET && vu_dev->registered) { struct virtio_uml_platform_data *pdata; - pdata = vu_dev->pdev->dev.platform_data; + pdata = vu_dev->pdata; virtio_break_device(&vu_dev->vdev); schedule_work(&pdata->conn_broken_wk); @@ -1115,21 +1117,63 @@ void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev, no_vq_suspend ? "dis" : "en"); } +static void vu_of_conn_broken(struct work_struct *wk) +{ + /* + * We can't remove the device from the devicetree so the only thing we + * can do is warn. + */ + WARN_ON(1); +} + /* Platform device */ +static struct virtio_uml_platform_data * +virtio_uml_create_pdata(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct virtio_uml_platform_data *pdata; + int ret; + + if (!np) + return ERR_PTR(-EINVAL); + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + INIT_WORK(&pdata->conn_broken_wk, vu_of_conn_broken); + pdata->pdev = pdev; + + ret = of_property_read_string(np, "socket-path", &pdata->socket_path); + if (ret) + return ERR_PTR(ret); + + ret = of_property_read_u32(np, "virtio-device-id", + &pdata->virtio_device_id); + if (ret) + return ERR_PTR(ret); + + return pdata; +} + static int virtio_uml_probe(struct platform_device *pdev) { struct virtio_uml_platform_data *pdata = pdev->dev.platform_data; struct virtio_uml_device *vu_dev; int rc; - if (!pdata) - return -EINVAL; + if (!pdata) { + pdata = virtio_uml_create_pdata(pdev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + } vu_dev = kzalloc(sizeof(*vu_dev), GFP_KERNEL); if (!vu_dev) return -ENOMEM; + vu_dev->pdata = pdata; vu_dev->vdev.dev.parent = &pdev->dev; vu_dev->vdev.dev.release = virtio_uml_release_dev; vu_dev->vdev.config = &virtio_uml_config_ops;