Skip to contentSkip to conversation

Unifying LKL into UML

RFC Superseded Hajime Tazaki 8 participants 248 messages Feb 5, 2020 – Mar 18, 2021 1 message not in the archive Page 3 of 3

Subsystems (10)
Documentation x86 Kbuild Kselftest +6 more subsystems
lore
Share & tools
lore
#173 lore raw

Re: [RFC v7 16/21] um: nommu: plug in the build system

In reply to Johannes Berg

(I removed UMMODE_LIB vs !MMU part, but leave replies to the others)

Quoted 15 lines · Johannes Berg
Quoted 2 lines

make defconfig ARCH=um UMMODE=library
make ARCH=um UMMODE=library

Why not make it a real Kconfig symbol? I find the ARCH=um tricky enough to remember all the time, so much I usually write a "GNUmakefile" with

export ARCH=um
include Makefile

:-)

Quoted 3 lines

+config UMMODE_LIB
+ bool "UML mode: library mode"
+ default y if "$(UMMODE)" = "library"

Quoted 6 lines

So wait, you _can_ switch that through Kconfig then, because you made it a visible option (string after "bool"). But it won't work, because then you later in the build system etc. still check UMMODE instead of CONFIG_UMMODE_LIB. Seems like something that ought to be fixed one way or the other - at the very least hide this symbol if setting it manually is invalid.

I now see what I went wrong..
thanks, will fix this with your suggestion not to use the command line argument.

Quoted 8 lines
Quoted 4 lines

+ help
+ This mode switches a mode to build a library of UML (Linux
+ Kernel Library/LKL). This switch is exclusive to "kernel mode"
+ of UML, which is traditional mode of UML.

Not sure if that historically made more sense, but you don't have any UMMODE_KERNEL option or something like that, so the help text seems confusing?

thanks, we will clarify this text.

Quoted 8 lines

arch/um/Makefile else

Quoted 6 lines
arch/um/Makefile +4 -0
+ifeq ($(UMMODE),library)
+  SUBARCH := um/nommu
+endif
 
 INSTALL_PATH=$(objtree)/tools/um
+ifeq ($(UMMODE),library)

Here a few places using UMMODE which must come from the command line.

will fix this too.

Quoted 6 lines
Quoted 4 lines

linux.o: vmlinux
@echo ' LINK $@'
- $(Q)$(OBJCOPY) -R .eh_frame $< $@
+ $(Q)$(OBJCOPY) -R .eh_frame -L sem_init -L sem_post -L sem_wait -L sem_destroy $< $@

Care to explain?

If we will link a userspace binary with liblinux.a (LKL) and libpthread, the the symbols sem_init, etc will conflict with the one in the kernel (ipc/sem.c). objcopy command with -L localizes the symbol specified to avoid this conflict.

We will add the description as a comment.

Quoted 5 lines
Quoted 3 lines

+ select UACCESS_MEMCPY
+ select ARCH_THREAD_STACK_ALLOCATOR
+ select ARCH_HAS_SYSCALL_WRAPPER

You never use this except for the selects, maybe can go elsewhere?

This is used at the patch 12/21, so add Kconfig earlier and move this to 12/21 would be better. We'll work on.

Quoted 19 lines
Quoted 19 lines
arch/um/nommu/um/Kconfig new file +19 -0
+config 64BIT
+ bool
+ default y
+
+config GENERIC_CSUM
+ def_bool y
+
+config GENERIC_ATOMIC64
+ bool
+ default y if !64BIT
+
+config SECCOMP
+ bool
+ default n
+
+config GENERIC_HWEIGHT
+ def_bool y
+
+config GENERIC_CALIBRATE_DELAY
Quoted 8 lines

arch/um/nommu/um/Kconfig line 32

Quoted 6 lines

+ bool
+ default n

arch/um/nommu/um/Kconfig new file +4 -0
+
+config STACKTRACE_SUPPORT
+ bool
+ default n

You ... were just changing these elsewhere, so one of that isn't needed?

you're right too. will fix it.

-- Hajime

#174 lore raw

RFC v7 17/21 um: host: add nommu build for ARCH=um

In reply to Hajime Tazaki

This patch adds the skeleton for the host library.

The host library is implementing the host operations needed by nommu mode and is split into host dependent (depends on a specific host, e.g. POSIX hosts) and host independent parts (will work on all supported hosts).

---
 tools/um/.gitignore                |   1 +
 tools/um/Makefile                  |  32 +++---
 tools/um/Targets                   |   3 +-
 tools/um/include/lkl.h             | 151 +++++++++++++++++++++++++++++
 tools/um/include/lkl_host.h        |  26 +++++
 tools/um/uml/Build                 |  16 ++-
 tools/um/uml/nommu/Build           |   1 +
 tools/um/uml/nommu/registers.c     |  21 ++++
 tools/um/uml/nommu/unimplemented.c |  21 ++++
 9 files changed, 252 insertions(+), 20 deletions(-)
 create mode 100644 tools/um/.gitignore
 create mode 100644 tools/um/include/lkl.h
 create mode 100644 tools/um/include/lkl_host.h
 create mode 100644 tools/um/uml/nommu/Build
 create mode 100644 tools/um/uml/nommu/registers.c
 create mode 100644 tools/um/uml/nommu/unimplemented.c
tools/um/.gitignore new file +1 -0
new file mode 100644
index 000000000000..0d20b6487c61
@@ -0,0 +1 @@
+*.pyc
tools/um/Makefile +17 -15
index 552ed5f1edae..bbd5e0dcadbc 100644
@@ -5,6 +5,7 @@
 MAKEFLAGS += -r --no-print-directory
 
 KCONFIG?=defconfig
+UMMODE?=kernel
 
 ifneq ($(silent),1)
   ifneq ($(V),1)
@@ -15,10 +16,8 @@ endif
 
 PREFIX   := /usr
 
-ifeq (,$(srctree))
-  srctree := $(patsubst %/,%,$(dir $(shell pwd)))
-  srctree := $(patsubst %/,%,$(dir $(srctree)))
-endif
+srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
 export srctree
 
 -include ../scripts/Makefile.include
@@ -32,9 +31,6 @@ endif
 export OUTPUT
 export objtree := $(OUTPUT)/../..
 
-
-all:
-
 export CFLAGS += -I$(OUTPUT)/include -Iinclude -Wall -g -O2 -Wextra -fPIC \
 	 -Wno-unused-parameter \
 	 -Wno-missing-field-initializers -fno-strict-aliasing
@@ -45,28 +41,34 @@ TARGETS := $(progs-y:%=$(OUTPUT)%)
 TARGETS += $(libs-y:%=$(OUTPUT)%)
 all: $(TARGETS)
 
-# rule to build linux.o
-$(OUTPUT)lib/linux.o:
-	$(Q)CFLAGS= $(MAKE) -C ../.. ARCH=um $(KOPT) $(KCONFIG)
-	$(Q)CFLAGS= $(MAKE) -C ../.. ARCH=um $(KOPT) install INSTALL_PATH=$(OUTPUT)
+$(objtree)/linux.o:
+	$(Q)echo ""
+	$(Q)echo ""
+	$(Q)echo "==> $@ isn't found; please make ARCH=um"
+	$(Q)echo ""
+	$(Q)echo ""
+	$(Q)exit 1
 
-$(OUTPUT)liblinux.a: $(OUTPUT)lib/linux.o $(OUTPUT)uml/liblinux-in.o $(OUTPUT)lib/liblinux-in.o
+$(OUTPUT)lib/linux.o: $(objtree)/linux.o
+	$(Q)cp $(objtree)/linux.o $(OUTPUT)lib/linux.o
+
+# rule to build linux.o
+$(OUTPUT)liblinux.a: $(OUTPUT)uml/liblinux-in.o $(OUTPUT)lib/liblinux-in.o $(OUTPUT)lib/linux.o
 	$(QUIET_AR)$(AR) -rc $@ $^
 
 # rule to link programs
 $(OUTPUT)%: $(OUTPUT)%-in.o $(OUTPUT)liblinux.a
 	$(QUIET_LINK)$(CC) $(LDFLAGS) $(LDFLAGS_$(notdir $*)-y) -o $@ $^ $(LDLIBS) $(LDLIBS_$(notdir $*)-y)
 
-$(OUTPUT)%-in.o: FORCE
-	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(patsubst %/,%,$(dir $*)) obj=$(notdir $*)
-
 # rule to build objects
 $(OUTPUT)%-in.o: $(OUTPUT)lib/linux.o FORCE
 	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(patsubst %/,%,$(dir $*)) obj=$(notdir $*)
 
+RM := rm -f
 clean:
 	$(call QUIET_CLEAN, objects)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd'\
 	 -delete -o -name '\.*.d' -delete
+	$(call QUIET_CLEAN, headers)$(RM) -r $(OUTPUT)/include/lkl/
 	$(call QUIET_CLEAN, liblinux.a)$(RM) $(OUTPUT)/liblinux.a
 	$(call QUIET_CLEAN, $(TARGETS))$(RM) $(TARGETS)
 
tools/um/Targets +2 -1
index a4711f1ef422..4e1f0f4d81a3 100644
@@ -1,4 +1,5 @@
 progs-y += uml/linux
-LDLIBS_linux-y := -lrt -lpthread -lutil
+
+LDLIBS := -lrt -lpthread -lutil
 LDFLAGS_linux-y := -no-pie -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 LDFLAGS_linux-$(UML_STATIC) += -static
tools/um/include/lkl.h new file +151 -0

151 lines not on this page · raw message

tools/um/include/lkl_host.h new file +26 -0
new file mode 100644
index 000000000000..85e80eb4ad0d
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_HOST_H
+#define _LKL_HOST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <lkl/asm/host_ops.h>
+#include <lkl.h>
+
+extern struct lkl_host_operations lkl_host_ops;
+
+/**
+ * lkl_printf - print a message via the host print operation
+ *
+ * @fmt: printf like format string
+ */
+int lkl_printf(const char *fmt, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
tools/um/uml/Build +12 -4
index 0d87d601bc06..a55c5cc3ebc0 100644
@@ -8,11 +8,19 @@ KCOV_INSTRUMENT                := n
 
 include $(objtree)/include/config/auto.conf
 
-liblinux-y += execvp.o file.o helper.o irq.o main.o mem.o process.o \
-	registers.o sigio.o signal.o start_up.o time.o tty.o \
-	umid.o util.o drivers/ skas/
+liblinux-y += execvp.o file.o helper.o irq.o mem.o process.o \
+	registers.o sigio.o signal.o time.o tty.o \
+	umid.o util.o drivers/
 
+ifdef CONFIG_MMU
+liblinux-y += main.o start_up.o skas/
+HEADER_ARCH 	:= x86
 liblinux-y += x86/
+else
+HEADER_ARCH 	:= um/nommu
+liblinux-y += nommu/
+endif
+
 
 liblinux-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
 
@@ -23,7 +31,6 @@ CFLAGS := -g -O2
 
 # from arch/um/Makefile
 ARCH_DIR := arch/um
-HEADER_ARCH 	:= x86
 HOST_DIR := arch/$(HEADER_ARCH)
 ifdef CONFIG_64BIT
   KBUILD_CFLAGS += -mcmodel=large
@@ -33,6 +40,7 @@ KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \
 	-Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \
 	-Din6addr_loopback=kernel_in6addr_loopback \
 	-Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr
+KBUILD_CFLAGS := $(filter-out -Dsigprocmask=kernel_sigprocmask,$(KBUILD_CFLAGS))
 SHARED_HEADERS	:= $(ARCH_DIR)/include/shared
 MODE_INCLUDE	+= -I$(srctree)/$(ARCH_DIR)/include/shared/skas
 ARCH_INCLUDE	:= -I$(srctree)/$(SHARED_HEADERS)
tools/um/uml/nommu/Build new file +1 -0
new file mode 100644
index 000000000000..98fd6b86a085
@@ -0,0 +1 @@
+liblinux-y = registers.o unimplemented.o
tools/um/uml/nommu/registers.c new file +21 -0
new file mode 100644
index 000000000000..11573a204720
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+
+struct uml_pt_regs;
+
+int get_fp_registers(int pid, unsigned long *regs)
+{
+	return 0;
+}
+
+int save_i387_registers(int pid, unsigned long *fp_regs)
+{
+	return 0;
+}
+
+void arch_init_registers(int pid)
+{
+}
+
+void get_regs_from_mc(struct uml_pt_regs *regs, void *mc)
+{
+}
tools/um/uml/nommu/unimplemented.c new file +21 -0
new file mode 100644
index 000000000000..9da3e5c8bafb
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <generated/user_constants.h>
+
+struct uml_pt_regs;
+
+/* os-Linux/skas/process.c */
+int userspace_pid[UM_NR_CPUS];
+void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
+{}
+
+
+/* x86/os-Linux/task_size.c */
+unsigned long os_get_top_address(void)
+{
+	return 0;
+}
+
+/* start-up.c */
+void os_early_checks(void)
+{
+}
Signature · 1 line
2.21.0 (Apple Git-122.2)
#175 lore raw

RFC v7 18/21 um: host: add utilities functions

In reply to Hajime Tazaki

Add basic utility functions for getting a string from a kernel error code and a fprintf like function that uses the host print operation. The latter is useful for informing the user about errors that occur in the host library.

---
 tools/um/lib/Build     |   4 +
 tools/um/lib/jmp_buf.c |  14 +++
 tools/um/lib/jmp_buf.h |   8 ++
 tools/um/lib/utils.c   | 210 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 tools/um/lib/Build
 create mode 100644 tools/um/lib/jmp_buf.c
 create mode 100644 tools/um/lib/jmp_buf.h
 create mode 100644 tools/um/lib/utils.c
tools/um/lib/Build new file +4 -0
new file mode 100644
index 000000000000..fc967af4104a
@@ -0,0 +1,4 @@
+include $(objtree)/include/config/auto.conf
+
+liblinux-$(CONFIG_UMMODE_LIB) += utils.o
+liblinux-$(CONFIG_UMMODE_LIB) += jmp_buf.o
tools/um/lib/jmp_buf.c new file +14 -0
new file mode 100644
index 000000000000..f6bdd7e4bd83
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <setjmp.h>
+#include <lkl_host.h>
+
+void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void))
+{
+	if (!setjmp(*((jmp_buf *)jmpb->buf)))
+		f();
+}
+
+void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val)
+{
+	longjmp(*((jmp_buf *)jmpb->buf), val);
+}
tools/um/lib/jmp_buf.h new file +8 -0
new file mode 100644
index 000000000000..8782cbaaf51f
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_LIB_JMP_BUF_H
+#define _LKL_LIB_JMP_BUF_H
+
+void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void));
+void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val);
+
+#endif
tools/um/lib/utils.c new file +210 -0

210 lines not on this page · raw message

Signature · 1 line
2.21.0 (Apple Git-122.2)
maintainer
#176 lore raw

Re: [RFC v7 18/21] um: host: add utilities functions

Quoted 67 lines · Hajime Tazaki

Add basic utility functions for getting a string from a kernel error code and a fprintf like function that uses the host print operation. The latter is useful for informing the user about errors that occur in the host library.

---
  tools/um/lib/Build     |   4 +
  tools/um/lib/jmp_buf.c |  14 +++
  tools/um/lib/jmp_buf.h |   8 ++
  tools/um/lib/utils.c   | 210 +++++++++++++++++++++++++++++++++++++++++
  4 files changed, 236 insertions(+)

create mode 100644 tools/um/lib/Build
create mode 100644 tools/um/lib/jmp_buf.c
create mode 100644 tools/um/lib/jmp_buf.h
create mode 100644 tools/um/lib/utils.c

tools/um/lib/Build new file +4 -0
new file mode 100644
index 000000000000..fc967af4104a
@@ -0,0 +1,4 @@
+include $(objtree)/include/config/auto.conf
+
+liblinux-$(CONFIG_UMMODE_LIB) += utils.o
+liblinux-$(CONFIG_UMMODE_LIB) += jmp_buf.o
tools/um/lib/jmp_buf.c new file +14 -0
new file mode 100644
index 000000000000..f6bdd7e4bd83
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <setjmp.h>
+#include <lkl_host.h>
+
+void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void))
+{
+	if (!setjmp(*((jmp_buf *)jmpb->buf)))
+		f();
+}
+
+void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val)
+{
+	longjmp(*((jmp_buf *)jmpb->buf), val);
+}
tools/um/lib/jmp_buf.h new file +8 -0
new file mode 100644
index 000000000000..8782cbaaf51f
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_LIB_JMP_BUF_H
+#define _LKL_LIB_JMP_BUF_H
+
+void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void));
+void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val);
+
+#endif
tools/um/lib/utils.c new file +0 -0
new file mode 100644
index 000000000000..4930479a8a35

tools/um/lib/utils.c line 5

Quoted 5 lines
tools/um/lib/utils.c new file +5 -0
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <lkl_host.h>

These are actually different on different architectures. These look like the x86 values.

IMHO a kernel strerror() would be the right way of dealing with this in the long term (i understand that we cannot call the platform one, because it may be different from the internal Linux errors). It will be useful in a lot of other places.

If we leave it as is, we need to make this arch specific at some point.

Quoted 206 lines
tools/um/lib/utils.c new file +205 -0
+
+static const char * const lkl_err_strings[] = {
+	"Success",
+	"Operation not permitted",
+	"No such file or directory",
+	"No such process",
+	"Interrupted system call",
+	"I/O error",
+	"No such device or address",
+	"Argument list too long",
+	"Exec format error",
+	"Bad file number",
+	"No child processes",
+	"Try again",
+	"Out of memory",
+	"Permission denied",
+	"Bad address",
+	"Block device required",
+	"Device or resource busy",
+	"File exists",
+	"Cross-device link",
+	"No such device",
+	"Not a directory",
+	"Is a directory",
+	"Invalid argument",
+	"File table overflow",
+	"Too many open files",
+	"Not a typewriter",
+	"Text file busy",
+	"File too large",
+	"No space left on device",
+	"Illegal seek",
+	"Read-only file system",
+	"Too many links",
+	"Broken pipe",
+	"Math argument out of domain of func",
+	"Math result not representable",
+	"Resource deadlock would occur",
+	"File name too long",
+	"No record locks available",
+	"Invalid system call number",
+	"Directory not empty",
+	"Too many symbolic links encountered",
+	"Bad error code", /* EWOULDBLOCK is EAGAIN */
+	"No message of desired type",
+	"Identifier removed",
+	"Channel number out of range",
+	"Level 2 not synchronized",
+	"Level 3 halted",
+	"Level 3 reset",
+	"Link number out of range",
+	"Protocol driver not attached",
+	"No CSI structure available",
+	"Level 2 halted",
+	"Invalid exchange",
+	"Invalid request descriptor",
+	"Exchange full",
+	"No anode",
+	"Invalid request code",
+	"Invalid slot",
+	"Bad error code", /* EDEADLOCK is EDEADLK */
+	"Bad font file format",
+	"Device not a stream",
+	"No data available",
+	"Timer expired",
+	"Out of streams resources",
+	"Machine is not on the network",
+	"Package not installed",
+	"Object is remote",
+	"Link has been severed",
+	"Advertise error",
+	"Srmount error",
+	"Communication error on send",
+	"Protocol error",
+	"Multihop attempted",
+	"RFS specific error",
+	"Not a data message",
+	"Value too large for defined data type",
+	"Name not unique on network",
+	"File descriptor in bad state",
+	"Remote address changed",
+	"Can not access a needed shared library",
+	"Accessing a corrupted shared library",
+	".lib section in a.out corrupted",
+	"Attempting to link in too many shared libraries",
+	"Cannot exec a shared library directly",
+	"Illegal byte sequence",
+	"Interrupted system call should be restarted",
+	"Streams pipe error",
+	"Too many users",
+	"Socket operation on non-socket",
+	"Destination address required",
+	"Message too long",
+	"Protocol wrong type for socket",
+	"Protocol not available",
+	"Protocol not supported",
+	"Socket type not supported",
+	"Operation not supported on transport endpoint",
+	"Protocol family not supported",
+	"Address family not supported by protocol",
+	"Address already in use",
+	"Cannot assign requested address",
+	"Network is down",
+	"Network is unreachable",
+	"Network dropped connection because of reset",
+	"Software caused connection abort",
+	"Connection reset by peer",
+	"No buffer space available",
+	"Transport endpoint is already connected",
+	"Transport endpoint is not connected",
+	"Cannot send after transport endpoint shutdown",
+	"Too many references: cannot splice",
+	"Connection timed out",
+	"Connection refused",
+	"Host is down",
+	"No route to host",
+	"Operation already in progress",
+	"Operation now in progress",
+	"Stale file handle",
+	"Structure needs cleaning",
+	"Not a XENIX named type file",
+	"No XENIX semaphores available",
+	"Is a named type file",
+	"Remote I/O error",
+	"Quota exceeded",
+	"No medium found",
+	"Wrong medium type",
+	"Operation Canceled",
+	"Required key not available",
+	"Key has expired",
+	"Key has been revoked",
+	"Key was rejected by service",
+	"Owner died",
+	"State not recoverable",
+	"Operation not possible due to RF-kill",
+	"Memory page has hardware error",
+};
+
+const char *lkl_strerror(int err)
+{
+	if (err < 0)
+		err = -err;
+
+	if ((size_t)err >= sizeof(lkl_err_strings) / sizeof(const char *))
+		return "Bad error code";
+
+	return lkl_err_strings[err];
+}
+
+void lkl_perror(char *msg, int err)
+{
+	const char *err_msg = lkl_strerror(err);
+	/* We need to use 'real' printf because lkl_host_ops.print can
+	 * be turned off when debugging is off.
+	 */
+	lkl_printf("%s: %s\n", msg, err_msg);
+}
+
+static int lkl_vprintf(const char *fmt, va_list args)
+{
+	int n;
+	char *buffer;
+	va_list copy;
+
+	if (!lkl_host_ops.print)
+		return 0;
+
+	va_copy(copy, args);
+	n = vsnprintf(NULL, 0, fmt, copy);
+	va_end(copy);
+
+	buffer = lkl_host_ops.mem_alloc(n + 1);
+	if (!buffer)
+		return (-1);
+
+	vsnprintf(buffer, n + 1, fmt, args);
+
+	lkl_host_ops.print(buffer, n);
+	lkl_host_ops.mem_free(buffer);
+
+	return n;
+}
+
+int lkl_printf(const char *fmt, ...)
+{
+	int n;
+	va_list args;
+
+	va_start(args, fmt);
+	n = lkl_vprintf(fmt, args);
+	va_end(args);
+
+	return n;
+}
+
+void lkl_bug(const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	lkl_vprintf(fmt, args);
+	va_end(args);
+
+	lkl_host_ops.panic();
+}
Signature · 3 lines
Anton R. Ivanov
Cambridgegreys Limited. Registered in England. Company Number 10273661
https://www.cambridgegreys.com/
maintainer
#177 lore raw

Re: [RFC v7 18/21] um: host: add utilities functions

Quoted 9 lines · Anton Ivanov

These are actually different on different architectures. These look like the x86 values.

IMHO a kernel strerror() would be the right way of dealing with this in the long term (i understand that we cannot call the platform one, because it may be different from the internal Linux errors). It will be useful in a lot of other places.

Quoted 7 lines

If we leave it as is, we need to make this arch specific at some point.

tools/um/lib/utils.c line 9

Quoted 4 lines
tools/um/lib/utils.c new file +4 -0
+
+static const char * const lkl_err_strings[] = {
+	"Success",
+	"Operation not permitted",

Might be possible to more or less address this (except for arch-specific errors that don't always exist) but using C99 initializers?

[0] = "Success",
[EPERM] = "Operation not permitted",
..

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#178 lore raw

Re: [RFC v7 18/21] um: host: add utilities functions

Quoted 20 lines · Johannes Berg
Quoted 8 lines · Anton Ivanov

These are actually different on different architectures. These look like the x86 values.

IMHO a kernel strerror() would be the right way of dealing with this in the long term (i understand that we cannot call the platform one, because it may be different from the internal Linux errors). It will be useful in a lot of other places.

Quoted 7 lines

If we leave it as is, we need to make this arch specific at some point.

tools/um/lib/utils.c line 9

Quoted 4 lines
tools/um/lib/utils.c new file +4 -0
+
+static const char * const lkl_err_strings[] = {
+	"Success",
+	"Operation not permitted",

Might be possible to more or less address this (except for arch-specific errors that don't always exist) but using C99 initializers?

Quoted 3 lines

[0] = "Success",
[EPERM] = "Operation not permitted",
..

But, on the other hand, is it needed at all? I don't think the kernel ever prints out the actual string ...

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#179 lore raw

Re: [RFC v7 18/21] um: host: add utilities functions

Quoted 20 lines · Johannes Berg
Quoted 19 lines · Johannes Berg
Quoted 8 lines · Anton Ivanov

These are actually different on different architectures. These look like the x86 values.

IMHO a kernel strerror() would be the right way of dealing with this in the long term (i understand that we cannot call the platform one, because it may be different from the internal Linux errors). It will be useful in a lot of other places.

Quoted 7 lines

If we leave it as is, we need to make this arch specific at some point.

tools/um/lib/utils.c line 9

Quoted 4 lines
tools/um/lib/utils.c new file +4 -0
+
+static const char * const lkl_err_strings[] = {
+	"Success",
+	"Operation not permitted",

Might be possible to more or less address this (except for arch-specific errors that don't always exist) but using C99 initializers?

Quoted 5 lines
Quoted 3 lines

[0] = "Success",
[EPERM] = "Operation not permitted",
..

But, on the other hand, is it needed at all? I don't think the kernel ever prints out the actual string ...

I can see the use case for a library in a multi-arch environment (which IMHO is the intended use case). It saves the user the effort of digging into the build and figuring out what does this error mean today :)

It is nice to have :)

If we will have it, however, it should be done as you suggested - C99 or some other way where it maps correctly to actual underlying error codes as they may end up being different depending on build config.

Quoted 8 lines

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

Signature · 3 lines
Anton R. Ivanov
Cambridgegreys Limited. Registered in England. Company Number 10273661
https://www.cambridgegreys.com/
#180 lore raw

Re: [RFC v7 18/21] um: host: add utilities functions

Quoted 7 lines · Anton Ivanov
Quoted 4 lines · Johannes Berg
Quoted 3 lines · Johannes Berg
Quoted 2 lines · Anton Ivanov

These are actually different on different architectures. These look like the x86 values.

Those variables are based on tools/um/include/lkl/asm-generic/errno.h, which is generated from include/uapi/asm-generic/errno.h, which LKL kernel eats for its values.

This is the part of patch 12/21.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

IMHO a kernel strerror() would be the right way of dealing with this in the long term (i understand that we cannot call the platform one, because it may be different from the internal Linux errors). It will be useful in a lot of other places.

If we leave it as is, we need to make this arch specific at some point.

So, this particular code does not contain arch specific part I believe.
# Tavi, correct me if I'm wrong.

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 4 lines

tools/um/lib/utils.c line 9

Quoted 4 lines
tools/um/lib/utils.c new file +4 -0
+
+static const char * const lkl_err_strings[] = {
+	"Success",
+	"Operation not permitted",

Might be possible to more or less address this (except for arch-specific errors that don't always exist) but using C99 initializers?

[0] = "Success",
[EPERM] = "Operation not permitted",
..

Quoted 8 lines
Quoted 2 lines

But, on the other hand, is it needed at all? I don't think the kernel ever prints out the actual string ...

I can see the use case for a library in a multi-arch environment (which IMHO is the intended use case). It saves the user the effort of digging into the build and figuring out what does this error mean today :)

It is nice to have :)

If we will have it, however, it should be done as you suggested - C99 or some other way where it maps correctly to actual underlying error codes as they may end up being different depending on build config.

So, this is not for the error values which underlying host generates, but the ones kernel generates. And the values should be tied with uapi/asm-generic/errno.h.

One possible failure that I can see is if uapi/asm-generic/errno{-base}.h are changed. In that case, yes, the way Johannes proposed would be the right way to handle. The outlook would be with the prefix and errno name (as follows).

[0] = "Success",
[LKL_EPERM] = "Operation not permitted",

-- Hajime

#181 lore raw

Re: [RFC v7 18/21] um: host: add utilities functions

Quoted 23 lines · Hajime Tazaki
Quoted 7 lines · Anton Ivanov
Quoted 4 lines · Johannes Berg
Quoted 3 lines · Johannes Berg
Quoted 2 lines · Anton Ivanov

These are actually different on different architectures. These look like the x86 values.

Those variables are based on tools/um/include/lkl/asm-generic/errno.h, which is generated from include/uapi/asm-generic/errno.h, which LKL kernel eats for its values.

This is the part of patch 12/21.

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

IMHO a kernel strerror() would be the right way of dealing with this in the long term (i understand that we cannot call the platform one, because it may be different from the internal Linux errors). It will be useful in a lot of other places.

Quoted 7 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

If we leave it as is, we need to make this arch specific at some point.

So, this particular code does not contain arch specific part I believe.
# Tavi, correct me if I'm wrong.

I think Anton was saying that we should do it properly with C99 to avoid potential issues with changes in configuration and I agree that is the way to go.

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#182 lore raw

Re: [RFC v7 18/21] um: host: add utilities functions

In reply to Anton Ivanov
Quoted 7 lines · Anton Ivanov
Quoted 4 lines · Johannes Berg
Quoted 3 lines · Johannes Berg
Quoted 2 lines · Anton Ivanov

These are actually different on different architectures. These look like the x86 values.

Those variables are based on tools/um/include/lkl/asm-generic/errno.h, which is generated from include/uapi/asm-generic/errno.h, which LKL kernel eats for its values.

This is the part of patch 12/21.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

IMHO a kernel strerror() would be the right way of dealing with this in the long term (i understand that we cannot call the platform one, because it may be different from the internal Linux errors). It will be useful in a lot of other places.

If we leave it as is, we need to make this arch specific at some point.

So, this particular code does not contain arch specific part I believe.
# Tavi, correct me if I'm wrong.

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 4 lines

tools/um/lib/utils.c line 9

Quoted 4 lines
tools/um/lib/utils.c new file +4 -0
+
+static const char * const lkl_err_strings[] = {
+	"Success",
+	"Operation not permitted",

Might be possible to more or less address this (except for arch-specific errors that don't always exist) but using C99 initializers?

[0] = "Success",
[EPERM] = "Operation not permitted",
..

Quoted 8 lines
Quoted 2 lines

But, on the other hand, is it needed at all? I don't think the kernel ever prints out the actual string ...

I can see the use case for a library in a multi-arch environment (which IMHO is the intended use case). It saves the user the effort of digging into the build and figuring out what does this error mean today :)

It is nice to have :)

If we will have it, however, it should be done as you suggested - C99 or some other way where it maps correctly to actual underlying error codes as they may end up being different depending on build config.

So, this is not for the error values which underlying host generates, but the ones kernel generates. And the values should be tied with uapi/asm-generic/errno.h.

One possible failure that I can see is if uapi/asm-generic/errno{-base}.h are changed. In that case, yes, the way Johannes proposed would be the right way to handle. The outlook would be with the prefix and errno name (as follows).

[0] = "Success",
[LKL_EPERM] = "Operation not permitted",

-- Hajime

#183 lore raw

RFC v7 19/21 um: host: posix host operations

In reply to Hajime Tazaki

This commit implements LKL host operations for POSIX hosts. The operations are implemented to be portable in various POSIX OSs.

---
 tools/um/lib/Build        |   2 +
 tools/um/lib/posix-host.c | 292 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 294 insertions(+)
 create mode 100644 tools/um/lib/posix-host.c
tools/um/lib/Build +2 -0
index fc967af4104a..dddff26a3b4e 100644
@@ -1,4 +1,6 @@
 include $(objtree)/include/config/auto.conf
+CFLAGS_posix-host.o += -D_FILE_OFFSET_BITS=64
 
 liblinux-$(CONFIG_UMMODE_LIB) += utils.o
+liblinux-$(CONFIG_UMMODE_LIB) += posix-host.o
 liblinux-$(CONFIG_UMMODE_LIB) += jmp_buf.o
tools/um/lib/posix-host.c new file +292 -0

292 lines not on this page · raw message

Signature · 1 line
2.21.0 (Apple Git-122.2)
#184 lore raw

RFC v7 20/21 um: host: add test programs

In reply to Hajime Tazaki

Add a simple LKL test application (boot) that starts the kernel and performs simple tests that minimally exercise the LKL API.

---
 tools/um/Makefile       |   5 +-
 tools/um/Targets        |   6 +
 tools/um/tests/Build    |   3 +
 tools/um/tests/boot.c   | 393 ++++++++++++++++++++++++++++++++++++++++
 tools/um/tests/boot.sh  |   9 +
 tools/um/tests/run.py   | 172 ++++++++++++++++++
 tools/um/tests/tap13.py | 209 +++++++++++++++++++++
 tools/um/tests/test.c   | 126 +++++++++++++
 tools/um/tests/test.h   |  72 ++++++++
 tools/um/tests/test.sh  | 181 ++++++++++++++++++
 10 files changed, 1175 insertions(+), 1 deletion(-)
 create mode 100644 tools/um/tests/Build
 create mode 100644 tools/um/tests/boot.c
 create mode 100755 tools/um/tests/boot.sh
 create mode 100755 tools/um/tests/run.py
 create mode 100644 tools/um/tests/tap13.py
 create mode 100644 tools/um/tests/test.c
 create mode 100644 tools/um/tests/test.h
 create mode 100644 tools/um/tests/test.sh
tools/um/Makefile +4 -1
index bbd5e0dcadbc..46d71b809bee 100644
@@ -72,7 +72,10 @@ clean:
 	$(call QUIET_CLEAN, liblinux.a)$(RM) $(OUTPUT)/liblinux.a
 	$(call QUIET_CLEAN, $(TARGETS))$(RM) $(TARGETS)
 
+run-tests:
+	./tests/run.py $(tests)
+
 FORCE: ;
-.PHONY: all clean FORCE
+.PHONY: all clean FORCE run-tests
 .IGNORE: clean
 .NOTPARALLEL : lib/linux.o
tools/um/Targets +6 -0
index 4e1f0f4d81a3..2bb90381843c 100644
@@ -1,4 +1,10 @@
+ifeq ($(UMMODE),library)
+progs-y += tests/boot
+else
 progs-y += uml/linux
+endif
+
+LDFLAGS_boot-y := -pie
 
 LDLIBS := -lrt -lpthread -lutil
 LDFLAGS_linux-y := -no-pie -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
tools/um/tests/Build new file +3 -0
new file mode 100644
index 000000000000..564560486f98
@@ -0,0 +1,3 @@
+boot-y += boot.o test.o
+
+CFLAGS_test.o += -Wno-implicit-fallthrough
tools/um/tests/boot.c new file +393 -0

393 lines not on this page · raw message

tools/um/tests/boot.sh new file +9 -0
new file mode 100755
index 000000000000..d985c04b0ac1
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0
+
+script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+source $script_dir/test.sh
+
+lkl_test_plan 1 "boot"
+lkl_test_run 1
+lkl_test_exec $script_dir/boot
tools/um/tests/run.py new file +172 -0

172 lines not on this page · raw message

tools/um/tests/tap13.py new file +209 -0

209 lines not on this page · raw message

tools/um/tests/test.c new file +126 -0

126 lines not on this page · raw message

tools/um/tests/test.h new file +72 -0

72 lines not on this page · raw message

tools/um/tests/test.sh new file +181 -0

181 lines not on this page · raw message

Signature · 1 line
2.21.0 (Apple Git-122.2)
maintainer
#185 lore raw

Re: [RFC v7 20/21] um: host: add test programs

Quoted 2 lines · Hajime Tazaki

+LKL_TEST_CALL(getpid, lkl_sys_getpid, 1)

Could that be unified with KUNIT somehow?

Quoted 9 lines

+++ b/tools/um/tests/run.py

tools/um/tests/run.py new file +7 -0
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: GPL-2.0
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License
+#

tools/um/tests/run.py line 17

Quoted 10 lines
tools/um/tests/run.py new file +10 -0
+# Author: Octavian Purdila <[email protected]>
+#
+
+from __future__ import print_function
+
+import argparse
+import os
+import subprocess
+import sys
+import tap13

ok, I see now, you're doing something with TAP (test anything protocol)...

Hmm. I must say I'm not a fan of adding a whole testing framework to the kernel like that, even if it's pretty simple.

tools/um/tests/run.py line 20

Quoted 3 lines
tools/um/tests/run.py new file +3 -0
+import xml.etree.ElementTree as ET
+
+from junit_xml import TestSuite, TestCase

yuck

Let's see if you can use KUNIT instead. Anything beyond that doesn't really need to live in the kernel, IMHO.

johanens

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#186 lore raw

Re: [RFC v7 20/21] um: host: add test programs

Quoted 33 lines · Johannes Berg
Quoted 2 lines · Hajime Tazaki

+LKL_TEST_CALL(getpid, lkl_sys_getpid, 1)

Could that be unified with KUNIT somehow?

Quoted 9 lines

+++ b/tools/um/tests/run.py

tools/um/tests/run.py new file +7 -0
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: GPL-2.0
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License
+#

tools/um/tests/run.py line 17

Quoted 10 lines
tools/um/tests/run.py new file +10 -0
+# Author: Octavian Purdila <[email protected]>
+#
+
+from __future__ import print_function
+
+import argparse
+import os
+import subprocess
+import sys
+import tap13

ok, I see now, you're doing something with TAP (test anything protocol)...

Hmm. I must say I'm not a fan of adding a whole testing framework to the kernel like that, even if it's pretty simple.

Quoted 8 lines

tools/um/tests/run.py line 20

Quoted 3 lines
tools/um/tests/run.py new file +3 -0
+import xml.etree.ElementTree as ET
+
+from junit_xml import TestSuite, TestCase

yuck

Let's see if you can use KUNIT instead. Anything beyond that doesn't really need to live in the kernel, IMHO.

I see the point.
I'm gonna play with kunit to check if it's doable.

Thanks,
-- Hajime

#187 lore raw

RFC v7 21/21 um: nommu: add block device support of UML

In reply to Hajime Tazaki

This commit adds block device support for nommu mode, and also added several host utilities to run a simple test program (tools/um/test/disk.c) successfully.

---
 arch/um/include/asm/xor.h                 |   3 +-
 arch/um/include/shared/as-layout.h        |   1 +
 arch/um/kernel/um_arch.c                  |   5 +
 arch/um/nommu/include/uapi/asm/host_ops.h |   7 +
 arch/um/nommu/include/uapi/asm/unistd.h   |   2 +
 arch/um/nommu/um/Kconfig                  |   8 +
 arch/um/nommu/um/setup.c                  |  12 +
 tools/um/Targets                          |   2 +
 tools/um/include/lkl.h                    | 206 ++++++++++
 tools/um/include/lkl_host.h               |   1 +
 tools/um/lib/Build                        |   1 +
 tools/um/lib/fs.c                         | 461 ++++++++++++++++++++++
 tools/um/lib/posix-host.c                 |   1 +
 tools/um/lib/utils.c                      |   3 +
 tools/um/tests/Build                      |   1 +
 tools/um/tests/cla.c                      | 159 ++++++++
 tools/um/tests/cla.h                      |  33 ++
 tools/um/tests/disk.c                     | 168 ++++++++
 tools/um/tests/disk.sh                    |  70 ++++
 tools/um/tests/run.py                     |   2 +
 20 files changed, 1145 insertions(+), 1 deletion(-)
 create mode 100644 tools/um/lib/fs.c
 create mode 100644 tools/um/tests/cla.c
 create mode 100644 tools/um/tests/cla.h
 create mode 100644 tools/um/tests/disk.c
 create mode 100755 tools/um/tests/disk.sh
arch/um/include/asm/xor.h +2 -1
index 36b33d62a35d..a5ea458a1ae9 100644
@@ -4,4 +4,5 @@
 
 /* pick an arbitrary one - measuring isn't possible with inf-cpu */
 #define XOR_SELECT_TEMPLATE(x)	\
-	(time_travel_mode == TT_MODE_INFCPU ? &xor_block_8regs : NULL)
+	(time_travel_mode == TT_MODE_INFCPU || (!IS_ENABLED(CONFIG_MMU)) ? \
+	 &xor_block_8regs : NULL)
arch/um/include/shared/as-layout.h +1 -0
index 5f286ef2721b..4423437a5ace 100644
@@ -57,6 +57,7 @@ extern unsigned long host_task_size;
 
 extern int linux_main(int argc, char **argv);
 extern void uml_finishsetup(void);
+extern void uml_set_args(char *args);
 
 struct siginfo;
 extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *);
arch/um/kernel/um_arch.c +5 -0
index e2cb76c03b25..da6e06cf2808 100644
@@ -41,6 +41,11 @@ static void __init add_arg(char *arg)
 	strcat(command_line, arg);
 }
 
+void __init uml_set_args(char *args)
+{
+	strcat(command_line, args);
+}
+
 /*
  * These fields are initialized at boot time and not changed.
  * XXX This structure is used only in the non-SMP case.  Maybe this
arch/um/nommu/include/uapi/asm/host_ops.h +7 -0
index 0811494c080c..1b2507502969 100644
@@ -15,6 +15,11 @@ struct lkl_jmp_buf {
  *
  * These operations must be provided by a host library or by the application
  * itself.
+ *
+ * @um_devices - string containg the list of UML devices in command line
+ * format. This string is appended to the kernel command line and
+ * is provided here for convenience to be implemented by the host library.
+ *
  * @print - optional operation that receives console messages
  * @panic - called during a kernel panic
  *
@@ -65,6 +70,8 @@ struct lkl_jmp_buf {
  *
  */
 struct lkl_host_operations {
+	const char *um_devices;
+
 	void (*print)(const char *str, int len);
 	void (*panic)(void);
 
arch/um/nommu/include/uapi/asm/unistd.h +2 -0
index 1762ebb829f5..320762099a62 100644
@@ -3,6 +3,8 @@
 #define __UM_NOMMU_UAPI_UNISTD_H
 
 #define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SET_GET_RLIMIT
+
 #include <asm/bitsperlong.h>
 
 #if __BITS_PER_LONG == 64
arch/um/nommu/um/Kconfig +8 -0
index 20b3eaccb6f0..c6a3f472fe75 100644
@@ -4,6 +4,10 @@ config UML_NOMMU
 	select UACCESS_MEMCPY
 	select ARCH_THREAD_STACK_ALLOCATOR
 	select ARCH_HAS_SYSCALL_WRAPPER
+	select VFAT_FS
+	select NLS_CODEPAGE_437
+	select NLS_ISO8859_1
+	select BTRFS_FS
 
 config 64BIT
 	bool
@@ -35,3 +39,7 @@ config STACKTRACE_SUPPORT
 config PRINTK_TIME
 	bool
 	default y
+
+config RAID6_PQ_BENCHMARK
+	bool
+	default n
arch/um/nommu/um/setup.c +12 -0
index 922188690139..d71d61979ad6 100644
@@ -45,13 +45,25 @@ static void __init *lkl_run_kernel(void *arg)
 	return NULL;
 }
 
+static char _cmd_line[COMMAND_LINE_SIZE];
 int __init lkl_start_kernel(struct lkl_host_operations *ops,
 			    const char *fmt, ...)
 {
+	va_list ap;
 	int ret;
 
 	lkl_ops = ops;
 
+	va_start(ap, fmt);
+	ret = vsnprintf(_cmd_line, COMMAND_LINE_SIZE, fmt, ap);
+	va_end(ap);
+
+	if (ops->um_devices)
+		strscpy(_cmd_line + ret, ops->um_devices,
+			COMMAND_LINE_SIZE - ret);
+
+	uml_set_args(_cmd_line);
+
 	init_sem = lkl_ops->sem_alloc(0);
 	if (!init_sem)
 		return -ENOMEM;
tools/um/Targets +2 -0
index 2bb90381843c..f5f8ec4b9dbb 100644
@@ -1,10 +1,12 @@
 ifeq ($(UMMODE),library)
 progs-y += tests/boot
+progs-y += tests/disk
 else
 progs-y += uml/linux
 endif
 
 LDFLAGS_boot-y := -pie
+LDFLAGS_disk-y := -pie
 
 LDLIBS := -lrt -lpthread -lutil
 LDFLAGS_linux-y := -no-pie -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
tools/um/include/lkl.h +206 -0

224 lines not on this page · raw message

tools/um/include/lkl_host.h +1 -0
index 85e80eb4ad0d..12dd95616e43 100644
@@ -10,6 +10,7 @@ extern "C" {
 #include <lkl.h>
 
 extern struct lkl_host_operations lkl_host_ops;
+extern char lkl_um_devs[4096];
 
 /**
  * lkl_printf - print a message via the host print operation
tools/um/lib/Build +1 -0
index dddff26a3b4e..29491b40746c 100644
@@ -4,3 +4,4 @@ CFLAGS_posix-host.o += -D_FILE_OFFSET_BITS=64
 liblinux-$(CONFIG_UMMODE_LIB) += utils.o
 liblinux-$(CONFIG_UMMODE_LIB) += posix-host.o
 liblinux-$(CONFIG_UMMODE_LIB) += jmp_buf.o
+liblinux-$(CONFIG_UMMODE_LIB) += fs.o
tools/um/lib/fs.c new file +461 -0

461 lines not on this page · raw message

tools/um/lib/posix-host.c +1 -0
index b6b5b2902254..8fd88031bf2b 100644
@@ -263,6 +263,7 @@ static void *tls_get(struct lkl_tls_key *key)
 }
 
 struct lkl_host_operations lkl_host_ops = {
+	.um_devices = lkl_um_devs,
 	.panic = panic,
 	.print = print,
 	.mem_alloc = (void *)malloc,
tools/um/lib/utils.c +3 -0
index 4930479a8a35..ac65cd744a14 100644
@@ -4,6 +4,9 @@
 #include <string.h>
 #include <lkl_host.h>
 
+/* XXX: find a better place */
+char lkl_um_devs[4096];
+
 static const char * const lkl_err_strings[] = {
 	"Success",
 	"Operation not permitted",
tools/um/tests/Build +1 -0
index 564560486f98..1aa78f9ed7ef 100644
@@ -1,3 +1,4 @@
 boot-y += boot.o test.o
+disk-y += disk.o test.o cla.o
 
 CFLAGS_test.o += -Wno-implicit-fallthrough
tools/um/tests/cla.c new file +159 -0

159 lines not on this page · raw message

tools/um/tests/cla.h new file +33 -0
new file mode 100644
index 000000000000..3d879233681f
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _LKL_TEST_CLA_H
+#define _LKL_TEST_CLA_H
+
+enum cl_arg_type {
+	CL_ARG_USER = 0,
+	CL_ARG_BOOL,
+	CL_ARG_INT,
+	CL_ARG_STR,
+	CL_ARG_STR_SET,
+	CL_ARG_IPV4,
+	CL_ARG_END,
+};
+
+struct cl_arg;
+
+typedef int (*cl_arg_parser_t)(struct cl_arg *arg, const char *value);
+
+struct cl_arg {
+	const char *long_name;
+	char short_name;
+	const char *help;
+	int has_arg;
+	enum cl_arg_type type;
+	void *store;
+	void *set;
+	cl_arg_parser_t parser;
+};
+
+int cla_parse_args(int argc, const char **argv, struct cl_arg *args);
+
+
+#endif /* _LKL_TEST_CLA_H */
tools/um/tests/disk.c new file +168 -0

168 lines not on this page · raw message

tools/um/tests/disk.sh new file +70 -0

70 lines not on this page · raw message

tools/um/tests/run.py +2 -0
index c96ede90b6ad..97d6dedc217c 100755
@@ -50,6 +50,8 @@ mydir=os.path.dirname(os.path.realpath(__file__))
 
 tests = [
     'boot.sh',
+    'disk.sh -t ext4',
+    'disk.sh -t vfat',
 ]
 
 parser = argparse.ArgumentParser(description='LKL test runner')
Signature · 1 line
2.21.0 (Apple Git-122.2)
maintainer
#188 lore raw

Re: [RFC v7 21/21] um: nommu: add block device support of UML

Quoted 126 lines · Hajime Tazaki

This commit adds block device support for nommu mode, and also added several host utilities to run a simple test program (tools/um/test/disk.c) successfully.

---
  arch/um/include/asm/xor.h                 |   3 +-
  arch/um/include/shared/as-layout.h        |   1 +
  arch/um/kernel/um_arch.c                  |   5 +
  arch/um/nommu/include/uapi/asm/host_ops.h |   7 +
  arch/um/nommu/include/uapi/asm/unistd.h   |   2 +
  arch/um/nommu/um/Kconfig                  |   8 +
  arch/um/nommu/um/setup.c                  |  12 +
  tools/um/Targets                          |   2 +
  tools/um/include/lkl.h                    | 206 ++++++++++
  tools/um/include/lkl_host.h               |   1 +
  tools/um/lib/Build                        |   1 +
  tools/um/lib/fs.c                         | 461 ++++++++++++++++++++++
  tools/um/lib/posix-host.c                 |   1 +
  tools/um/lib/utils.c                      |   3 +
  tools/um/tests/Build                      |   1 +
  tools/um/tests/cla.c                      | 159 ++++++++
  tools/um/tests/cla.h                      |  33 ++
  tools/um/tests/disk.c                     | 168 ++++++++
  tools/um/tests/disk.sh                    |  70 ++++
  tools/um/tests/run.py                     |   2 +
  20 files changed, 1145 insertions(+), 1 deletion(-)

create mode 100644 tools/um/lib/fs.c
create mode 100644 tools/um/tests/cla.c
create mode 100644 tools/um/tests/cla.h
create mode 100644 tools/um/tests/disk.c
create mode 100755 tools/um/tests/disk.sh

arch/um/include/asm/xor.h +2 -1
index 36b33d62a35d..a5ea458a1ae9 100644
@@ -4,4 +4,5 @@
 
  /* pick an arbitrary one - measuring isn't possible with inf-cpu */
  #define XOR_SELECT_TEMPLATE(x)	\
-	(time_travel_mode == TT_MODE_INFCPU ? &xor_block_8regs : NULL)
+	(time_travel_mode == TT_MODE_INFCPU || (!IS_ENABLED(CONFIG_MMU)) ? \
+	 &xor_block_8regs : NULL)
arch/um/include/shared/as-layout.h +1 -0
index 5f286ef2721b..4423437a5ace 100644
@@ -57,6 +57,7 @@ extern unsigned long host_task_size;
 
  extern int linux_main(int argc, char **argv);
  extern void uml_finishsetup(void);
+extern void uml_set_args(char *args);
 
  struct siginfo;
  extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *);
arch/um/kernel/um_arch.c +5 -0
index e2cb76c03b25..da6e06cf2808 100644
@@ -41,6 +41,11 @@ static void __init add_arg(char *arg)
  	strcat(command_line, arg);
  }
 
+void __init uml_set_args(char *args)
+{
+	strcat(command_line, args);
+}
+
  /*
   * These fields are initialized at boot time and not changed.
   * XXX This structure is used only in the non-SMP case.  Maybe this
arch/um/nommu/include/uapi/asm/host_ops.h +7 -0
index 0811494c080c..1b2507502969 100644
@@ -15,6 +15,11 @@ struct lkl_jmp_buf {
   *
   * These operations must be provided by a host library or by the application
   * itself.
+ *
+ * @um_devices - string containg the list of UML devices in command line
+ * format. This string is appended to the kernel command line and
+ * is provided here for convenience to be implemented by the host library.
+ *
   * @print - optional operation that receives console messages
   * @panic - called during a kernel panic
   *
@@ -65,6 +70,8 @@ struct lkl_jmp_buf {
   *
   */
  struct lkl_host_operations {
+	const char *um_devices;
+
  	void (*print)(const char *str, int len);
  	void (*panic)(void);
 
arch/um/nommu/include/uapi/asm/unistd.h +2 -0
index 1762ebb829f5..320762099a62 100644
@@ -3,6 +3,8 @@
  #define __UM_NOMMU_UAPI_UNISTD_H
 
  #define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SET_GET_RLIMIT
+
  #include <asm/bitsperlong.h>
 
  #if __BITS_PER_LONG == 64
arch/um/nommu/um/Kconfig +4 -0
index 20b3eaccb6f0..c6a3f472fe75 100644
@@ -4,6 +4,10 @@ config UML_NOMMU
  	select UACCESS_MEMCPY
  	select ARCH_THREAD_STACK_ALLOCATOR
  	select ARCH_HAS_SYSCALL_WRAPPER
+	select VFAT_FS
+	select NLS_CODEPAGE_437
+	select NLS_ISO8859_1
+	select BTRFS_FS
 
  config 64BIT
  	bool

arch/um/nommu/um/Kconfig config STACKTRACE_SUPPORT · line 45

Quoted 7 lines
arch/um/nommu/um/Kconfig +4 -0
@@ -35,3 +39,7 @@ config STACKTRACE_SUPPORT
  config PRINTK_TIME
  	bool
  	default y
+
+config RAID6_PQ_BENCHMARK
+	bool
+	default n

Why are we touching this? I thought this is already defined in lib/Kconfig?

Brgds,

A.

Quoted 1,268 lines
arch/um/nommu/um/setup.c +12 -0
index 922188690139..d71d61979ad6 100644
@@ -45,13 +45,25 @@ static void __init *lkl_run_kernel(void *arg)
  	return NULL;
  }
 
+static char _cmd_line[COMMAND_LINE_SIZE];
  int __init lkl_start_kernel(struct lkl_host_operations *ops,
  			    const char *fmt, ...)
  {
+	va_list ap;
  	int ret;
 
  	lkl_ops = ops;
 
+	va_start(ap, fmt);
+	ret = vsnprintf(_cmd_line, COMMAND_LINE_SIZE, fmt, ap);
+	va_end(ap);
+
+	if (ops->um_devices)
+		strscpy(_cmd_line + ret, ops->um_devices,
+			COMMAND_LINE_SIZE - ret);
+
+	uml_set_args(_cmd_line);
+
  	init_sem = lkl_ops->sem_alloc(0);
  	if (!init_sem)
  		return -ENOMEM;
tools/um/Targets +2 -0
index 2bb90381843c..f5f8ec4b9dbb 100644
@@ -1,10 +1,12 @@
  ifeq ($(UMMODE),library)
  progs-y += tests/boot
+progs-y += tests/disk
  else
  progs-y += uml/linux
  endif
 
  LDFLAGS_boot-y := -pie
+LDFLAGS_disk-y := -pie
 
  LDLIBS := -lrt -lpthread -lutil
  LDFLAGS_linux-y := -no-pie -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
tools/um/include/lkl.h +206 -0
index 707e01b64a70..4a9d874bfbf0 100644
@@ -113,6 +113,16 @@ static inline long lkl_sys_creat(const char *file, int mode)
  }
  #endif
 
+#ifdef __lkl__NR_faccessat
+/**
+ * lkl_sys_access - wrapper for lkl_sys_faccessat
+ */
+static inline long lkl_sys_access(const char *file, int mode)
+{
+	return lkl_sys_faccessat(LKL_AT_FDCWD, file, mode);
+}
+#endif
+
  #ifdef __lkl__NR_mkdirat
  /**
   * lkl_sys_mkdir - wrapper for lkl_sys_mkdirat
@@ -123,6 +133,36 @@ static inline long lkl_sys_mkdir(const char *path, mode_t mode)
  }
  #endif
 
+#ifdef __lkl__NR_unlinkat
+/**
+ * lkl_sys_rmdir - wrapper for lkl_sys_unlinkrat
+ */
+static inline long lkl_sys_rmdir(const char *path)
+{
+	return lkl_sys_unlinkat(LKL_AT_FDCWD, path, LKL_AT_REMOVEDIR);
+}
+#endif
+
+#ifdef __lkl__NR_unlinkat
+/**
+ * lkl_sys_unlink - wrapper for lkl_sys_unlinkat
+ */
+static inline long lkl_sys_unlink(const char *path)
+{
+	return lkl_sys_unlinkat(LKL_AT_FDCWD, path, 0);
+}
+#endif
+
+#ifdef __lkl__NR_mknodat
+/**
+ * lkl_sys_mknod - wrapper for lkl_sys_mknodat
+ */
+static inline long lkl_sys_mknod(const char *path, mode_t mode, dev_t dev)
+{
+	return lkl_sys_mknodat(LKL_AT_FDCWD, path, mode, dev);
+}
+#endif
+
  #ifdef __lkl__NR_epoll_create1
  /**
   * lkl_sys_epoll_create - wrapper for lkl_sys_epoll_create1
@@ -144,6 +184,172 @@ static inline long lkl_sys_epoll_wait(int fd, struct lkl_epoll_event *ev,
  }
  #endif
 
+/**
+ * struct lkl_dev_blk_ops - block device host operations, defined in lkl_host.h.
+ */
+struct lkl_dev_blk_ops;
+
+/**
+ * lkl_disk - host disk handle
+ *
+ * @dev - a pointer to private information for this disk backend
+ * @fd - a POSIX file descriptor that can be used by preadv/pwritev
+ * @handle - an NT file handle that can be used by ReadFile/WriteFile
+ */
+struct lkl_disk {
+	void *dev;
+	union {
+		int fd;
+		void *handle;
+	};
+	struct lkl_dev_blk_ops *ops;
+};
+
+/**
+ * lkl_disk_add - add a new disk
+ *
+ * @disk - the host disk handle
+ * @returns a disk id (0 is valid) or a strictly negative value in case of error
+ */
+int lkl_disk_add(struct lkl_disk *disk);
+
+/**
+ * lkl_disk_remove - remove a disk
+ *
+ * This function makes a cleanup of the @disk's private information
+ * that was initialized by lkl_disk_add before.
+ *
+ * @disk - the host disk handle
+ */
+int lkl_disk_remove(struct lkl_disk disk);
+
+/**
+ * lkl_encode_dev_from_sysfs_blkdev - extract device id from sysfs
+ *
+ * This function returns the device id for the given sysfs dev node.
+ * The content of the node has to be in the form 'MAJOR:MINOR'.
+ * Also, this function expects an absolute path which means that sysfs
+ * already has to be mounted at the given path
+ *
+ * @sysfs_path - absolute path to the sysfs dev node
+ * @pdevid - pointer to memory where dev id will be returned
+ * @returns - 0 on success, a negative value on error
+ */
+int lkl_encode_dev_from_sysfs(const char *sysfs_path, uint32_t *pdevid);
+
+/**
+ * lkl_mount_dev - mount a disk
+ *
+ * This functions creates a device file for the given disk, creates a mount
+ * point and mounts the device over the mount point.
+ *
+ * @disk_id - the disk id identifying the disk to be mounted
+ * @part - disk partition or zero for full disk
+ * @fs_type - filesystem type
+ * @flags - mount flags
+ * @opts - additional filesystem specific mount options
+ * @mnt_str - a string that will be filled by this function with the path where
+ * the filesystem has been mounted
+ * @mnt_str_len - size of mnt_str
+ * @returns - 0 on success, a negative value on error
+ */
+long lkl_mount_dev(unsigned int disk_id, unsigned int part, const char *fs_type,
+		   int flags, const char *opts,
+		   char *mnt_str, unsigned int mnt_str_len);
+
+/**
+ * lkl_umount_dev - umount a disk
+ *
+ * This functions umounts the given disks and removes the device file and the
+ * mount point.
+ *
+ * @disk_id - the disk id identifying the disk to be mounted
+ * @part - disk partition or zero for full disk
+ * @flags - umount flags
+ * @timeout_ms - timeout to wait for the kernel to flush closed files so that
+ * umount can succeed
+ * @returns - 0 on success, a negative value on error
+ */
+long lkl_umount_dev(unsigned int disk_id, unsigned int part, int flags,
+		    long timeout_ms);
+
+/**
+ * lkl_umount_timeout - umount filesystem with timeout
+ *
+ * @path - the path to unmount
+ * @flags - umount flags
+ * @timeout_ms - timeout to wait for the kernel to flush closed files so that
+ * umount can succeed
+ * @returns - 0 on success, a negative value on error
+ */
+long lkl_umount_timeout(char *path, int flags, long timeout_ms);
+
+/**
+ * lkl_opendir - open a directory
+ *
+ * @path - directory path
+ * @err - pointer to store the error in case of failure
+ * @returns - a handle to be used when calling lkl_readdir
+ */
+struct lkl_dir *lkl_opendir(const char *path, int *err);
+
+/**
+ * lkl_fdopendir - open a directory
+ *
+ * @fd - file descriptor
+ * @err - pointer to store the error in case of failure
+ * @returns - a handle to be used when calling lkl_readdir
+ */
+struct lkl_dir *lkl_fdopendir(int fd, int *err);
+
+/**
+ * lkl_rewinddir - reset directory stream
+ *
+ * @dir - the directory handler as returned by lkl_opendir
+ */
+void lkl_rewinddir(struct lkl_dir *dir);
+
+/**
+ * lkl_closedir - close the directory
+ *
+ * @dir - the directory handler as returned by lkl_opendir
+ */
+int lkl_closedir(struct lkl_dir *dir);
+
+/**
+ * lkl_readdir - get the next available entry of the directory
+ *
+ * @dir - the directory handler as returned by lkl_opendir
+ * @returns - a lkl_dirent64 entry or NULL if the end of the directory stream is
+ * reached or if an error occurred; check lkl_errdir() to distinguish between
+ * errors or end of the directory stream
+ */
+struct lkl_linux_dirent64 *lkl_readdir(struct lkl_dir *dir);
+
+/**
+ * lkl_errdir - checks if an error occurred during the last lkl_readdir call
+ *
+ * @dir - the directory handler as returned by lkl_opendir
+ * @returns - 0 if no error occurred, or a negative value otherwise
+ */
+int lkl_errdir(struct lkl_dir *dir);
+
+/**
+ * lkl_dirfd - gets the file descriptor associated with the directory handle
+ *
+ * @dir - the directory handle as returned by lkl_opendir
+ * @returns - a positive value,which is the LKL file descriptor associated with
+ * the directory handle, or a negative value otherwise
+ */
+int lkl_dirfd(struct lkl_dir *dir);
+
+/**
+ * lkl_mount_fs - mount a file system type like proc, sys
+ * @fstype - file system type. e.g. proc, sys
+ * @returns - 0 on success. 1 if it's already mounted. negative on failure.
+ */
+int lkl_mount_fs(char *fstype);
+
  #ifdef __cplusplus
  }
  #endif
tools/um/include/lkl_host.h +1 -0
index 85e80eb4ad0d..12dd95616e43 100644
@@ -10,6 +10,7 @@ extern "C" {
  #include <lkl.h>
 
  extern struct lkl_host_operations lkl_host_ops;
+extern char lkl_um_devs[4096];
 
  /**
   * lkl_printf - print a message via the host print operation
tools/um/lib/Build +1 -0
index dddff26a3b4e..29491b40746c 100644
@@ -4,3 +4,4 @@ CFLAGS_posix-host.o += -D_FILE_OFFSET_BITS=64
  liblinux-$(CONFIG_UMMODE_LIB) += utils.o
  liblinux-$(CONFIG_UMMODE_LIB) += posix-host.o
  liblinux-$(CONFIG_UMMODE_LIB) += jmp_buf.o
+liblinux-$(CONFIG_UMMODE_LIB) += fs.o
tools/um/lib/fs.c new file +461 -0
new file mode 100644
index 000000000000..948aac9730c2
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <lkl_host.h>
+
+#define MAX_FSTYPE_LEN 50
+
+static struct lkl_disk *lkl_disks[16];
+static int registered_blk_dev_idx;
+
+static int lkl_disk_um_add(struct lkl_disk *disk, const char *blkparams)
+{
+	/* concat strings */
+	snprintf(lkl_um_devs + strlen(lkl_um_devs), sizeof(lkl_um_devs),
+		 " ubd%d=%s", registered_blk_dev_idx, blkparams);
+
+	return registered_blk_dev_idx++;
+}
+
+int lkl_disk_add(struct lkl_disk *disk)
+{
+	int ret = -1;
+
+	ret = lkl_disk_um_add(disk, disk->dev);
+
+	lkl_disks[ret] = disk;
+
+	return ret;
+}
+
+int lkl_disk_remove(struct lkl_disk disk)
+{
+	/* FIXME */
+	return 0;
+}
+
+int lkl_mount_fs(char *fstype)
+{
+	char dir[MAX_FSTYPE_LEN+2] = "/";
+	int flags = 0, ret = 0;
+
+	strncat(dir, fstype, MAX_FSTYPE_LEN);
+
+	/* Create with regular umask */
+	ret = lkl_sys_mkdir(dir, 0xff);
+	if (ret && ret != -LKL_EEXIST) {
+		lkl_perror("mount_fs mkdir", ret);
+		return ret;
+	}
+
+	/* We have no use for nonzero flags right now */
+	ret = lkl_sys_mount("none", dir, fstype, flags, NULL);
+	if (ret && ret != -LKL_EBUSY) {
+		lkl_sys_rmdir(dir);
+		return ret;
+	}
+
+	if (ret == -LKL_EBUSY)
+		return 1;
+	return 0;
+}
+
+static uint32_t new_encode_dev(unsigned int major, unsigned int minor)
+{
+	return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
+}
+
+static int startswith(const char *str, const char *pre)
+{
+	return strncmp(pre, str, strlen(pre)) == 0;
+}
+
+static int get_node_with_prefix(const char *path, const char *prefix,
+				char *result, unsigned int result_len)
+{
+	struct lkl_dir *dir = NULL;
+	struct lkl_linux_dirent64 *dirent;
+	int ret;
+
+	dir = lkl_opendir(path, &ret);
+	if (!dir)
+		return ret;
+
+	ret = -LKL_ENOENT;
+
+	while ((dirent = lkl_readdir(dir))) {
+		if (startswith(dirent->d_name, prefix)) {
+			if (strlen(dirent->d_name) + 1 > result_len) {
+				ret = -LKL_ENOMEM;
+				break;
+			}
+			memcpy(result, dirent->d_name, strlen(dirent->d_name));
+			result[strlen(dirent->d_name)] = '\0';
+			ret = 0;
+			break;
+		}
+	}
+
+	lkl_closedir(dir);
+
+	return ret;
+}
+
+int lkl_encode_dev_from_sysfs(const char *sysfs_path, uint32_t *pdevid)
+{
+	int ret;
+	long fd;
+	int major, minor;
+	char buf[16] = { 0, };
+	char *bufptr;
+
+	fd = lkl_sys_open(sysfs_path, LKL_O_RDONLY, 0);
+	if (fd < 0)
+		return fd;
+
+	ret = lkl_sys_read(fd, buf, sizeof(buf));
+	if (ret < 0)
+		goto out_close;
+
+	if (ret == sizeof(buf)) {
+		ret = -LKL_ENOBUFS;
+		goto out_close;
+	}
+
+	bufptr = strchr(buf, ':');
+	if (bufptr == NULL) {
+		ret = -LKL_EINVAL;
+		goto out_close;
+	}
+	bufptr[0] = '\0';
+	bufptr++;
+
+	major = atoi(buf);
+	minor = atoi(bufptr);
+
+	*pdevid = new_encode_dev(major, minor);
+	ret = 0;
+
+out_close:
+	lkl_sys_close(fd);
+
+	return ret;
+}
+
+#define SYSFS_DEV_UMBLK_CMDLINE_PATH \
+	"/sysfs/devices/platform/uml-blkdev.%d"
+
+struct abuf {
+	char *mem, *ptr;
+	unsigned int len;
+};
+
+static int snprintf_append(struct abuf *buf, const char *fmt, ...)
+{
+	int ret;
+	va_list args;
+
+	if (!buf->ptr)
+		buf->ptr = buf->mem;
+
+	va_start(args, fmt);
+	ret = vsnprintf(buf->ptr, buf->len - (buf->ptr - buf->mem), fmt, args);
+	va_end(args);
+
+	if (ret < 0 || (ret >= (int)(buf->len - (buf->ptr - buf->mem))))
+		return -LKL_ENOMEM;
+
+	buf->ptr += ret;
+
+	return 0;
+}
+
+static int __lkl_get_blkdev(int disk_id, unsigned int part, uint32_t *pdevid,
+			    const char *sysfs_path_fmt, const char *drv_prefix,
+			    const char *disk_prefix)
+{
+	char sysfs_path[LKL_PATH_MAX];
+	char drv_name[LKL_PATH_MAX];
+	char disk_name[LKL_PATH_MAX];
+	struct abuf sysfs_path_buf = {
+		.mem = sysfs_path,
+		.len = sizeof(sysfs_path),
+	};
+	int ret;
+
+	if (disk_id < 0)
+		return -LKL_EINVAL;
+
+	ret = lkl_mount_fs("sysfs");
+	if (ret < 0)
+		return ret;
+
+	ret = snprintf_append(&sysfs_path_buf, sysfs_path_fmt, disk_id);
+	if (ret)
+		return ret;
+
+	ret = get_node_with_prefix(sysfs_path, drv_prefix, drv_name,
+				   sizeof(drv_name));
+	if (ret)
+		return ret;
+
+	ret = snprintf_append(&sysfs_path_buf, "/%s/block", drv_name);
+	if (ret)
+		return ret;
+
+	ret = get_node_with_prefix(sysfs_path, disk_prefix, disk_name,
+				   sizeof(disk_name));
+	if (ret)
+		return ret;
+
+	if (!part)
+		ret = snprintf_append(&sysfs_path_buf, "/%s/dev", disk_name);
+	else
+		ret = snprintf_append(&sysfs_path_buf, "/%s/%s%d/dev",
+				      disk_name, disk_name, part);
+	if (ret)
+		return ret;
+
+	return lkl_encode_dev_from_sysfs(sysfs_path, pdevid);
+}
+
+int lkl_get_blkdev(int disk_id, unsigned int part, uint32_t *pdevid)
+{
+	char *fmt;
+
+	fmt = SYSFS_DEV_UMBLK_CMDLINE_PATH;
+	return __lkl_get_blkdev(disk_id, part, pdevid, fmt, "", "ubd");
+}
+
+long lkl_mount_dev(unsigned int disk_id, unsigned int part,
+		   const char *fs_type, int flags,
+		   const char *data, char *mnt_str, unsigned int mnt_str_len)
+{
+	char dev_str[] = { "/dev/xxxxxxxx" };
+	unsigned int dev;
+	int err;
+	char _data[4096]; /* FIXME: PAGE_SIZE is not exported by LKL */
+
+	if (mnt_str_len < sizeof(dev_str))
+		return -LKL_ENOMEM;
+
+	err = lkl_get_blkdev(disk_id, part, &dev);
+	if (err < 0)
+		return err;
+
+	snprintf(dev_str, sizeof(dev_str), "/dev/%08x", dev);
+	snprintf(mnt_str, mnt_str_len, "/mnt/%08x", dev);
+
+	err = lkl_sys_access("/dev", LKL_S_IRWXO);
+	if (err < 0) {
+		if (err == -LKL_ENOENT)
+			err = lkl_sys_mkdir("/dev", 0700);
+		if (err < 0)
+			return err;
+	}
+
+	err = lkl_sys_mknod(dev_str, LKL_S_IFBLK | 0600, dev);
+	if (err < 0)
+		return err;
+
+	err = lkl_sys_access("/mnt", LKL_S_IRWXO);
+	if (err < 0) {
+		if (err == -LKL_ENOENT)
+			err = lkl_sys_mkdir("/mnt", 0700);
+		if (err < 0)
+			return err;
+	}
+
+	err = lkl_sys_mkdir(mnt_str, 0700);
+	if (err < 0) {
+		lkl_sys_unlink(dev_str);
+		return err;
+	}
+
+	/* kernel always copies a full page */
+	if (data) {
+		strncpy(_data, data, sizeof(_data));
+		_data[sizeof(_data) - 1] = 0;
+	} else {
+		_data[0] = 0;
+	}
+
+	err = lkl_sys_mount(dev_str, mnt_str, (char *)fs_type, flags, _data);
+	if (err < 0) {
+		lkl_sys_unlink(dev_str);
+		lkl_sys_rmdir(mnt_str);
+		return err;
+	}
+
+	return 0;
+}
+
+long lkl_umount_timeout(char *path, int flags, long timeout_ms)
+{
+	long incr = 10000000; /* 10 ms */
+	struct lkl_timespec ts = {
+		.tv_sec = 0,
+		.tv_nsec = incr,
+	};
+	long err;
+
+	do {
+		err = lkl_sys_umount(path, flags);
+		if (err == -LKL_EBUSY) {
+			lkl_sys_nanosleep((struct __lkl__kernel_timespec *)&ts,
+					  NULL);
+			timeout_ms -= incr / 1000000;
+		}
+	} while (err == -LKL_EBUSY && timeout_ms > 0);
+
+	return err;
+}
+
+long lkl_umount_dev(unsigned int disk_id, unsigned int part, int flags,
+		    long timeout_ms)
+{
+	char dev_str[] = { "/dev/xxxxxxxx" };
+	char mnt_str[] = { "/mnt/xxxxxxxx" };
+	unsigned int dev;
+	int err;
+
+	err = lkl_get_blkdev(disk_id, part, &dev);
+	if (err < 0)
+		return err;
+
+	snprintf(dev_str, sizeof(dev_str), "/dev/%08x", dev);
+	snprintf(mnt_str, sizeof(mnt_str), "/mnt/%08x", dev);
+
+	err = lkl_umount_timeout(mnt_str, flags, timeout_ms);
+	if (err)
+		return err;
+
+	err = lkl_sys_unlink(dev_str);
+	if (err)
+		return err;
+
+	return lkl_sys_rmdir(mnt_str);
+}
+
+struct lkl_dir {
+	int fd;
+	char buf[1024];
+	char *pos;
+	int len;
+};
+
+static struct lkl_dir *lkl_dir_alloc(int *err)
+{
+	struct lkl_dir *dir = lkl_host_ops.mem_alloc(sizeof(struct lkl_dir));
+
+	if (!dir) {
+		*err = -LKL_ENOMEM;
+		return NULL;
+	}
+
+	dir->len = 0;
+	dir->pos = NULL;
+
+	return dir;
+}
+
+struct lkl_dir *lkl_opendir(const char *path, int *err)
+{
+	struct lkl_dir *dir = lkl_dir_alloc(err);
+
+	if (!dir) {
+		*err = -LKL_ENOMEM;
+		return NULL;
+	}
+
+	dir->fd = lkl_sys_open(path, LKL_O_RDONLY | LKL_O_DIRECTORY, 0);
+	if (dir->fd < 0) {
+		*err = dir->fd;
+		lkl_host_ops.mem_free(dir);
+		return NULL;
+	}
+
+	*err = 0;
+
+	return dir;
+}
+
+struct lkl_dir *lkl_fdopendir(int fd, int *err)
+{
+	struct lkl_dir *dir = lkl_dir_alloc(err);
+
+	if (!dir)
+		return NULL;
+
+	dir->fd = fd;
+
+	return dir;
+}
+
+void lkl_rewinddir(struct lkl_dir *dir)
+{
+	lkl_sys_lseek(dir->fd, 0, LKL_SEEK_SET);
+	dir->len = 0;
+	dir->pos = NULL;
+}
+
+int lkl_closedir(struct lkl_dir *dir)
+{
+	int ret;
+
+	ret = lkl_sys_close(dir->fd);
+	lkl_host_ops.mem_free(dir);
+
+	return ret;
+}
+
+struct lkl_linux_dirent64 *lkl_readdir(struct lkl_dir *dir)
+{
+	struct lkl_linux_dirent64 *de;
+
+	if (dir->len < 0)
+		return NULL;
+
+	if (!dir->pos || dir->pos - dir->buf >= dir->len)
+		goto read_buf;
+
+return_de:
+	de = (struct lkl_linux_dirent64 *)dir->pos;
+	dir->pos += de->d_reclen;
+
+	return de;
+
+read_buf:
+	dir->pos = NULL;
+	de = (struct lkl_linux_dirent64 *)dir->buf;
+	dir->len = lkl_sys_getdents64(dir->fd, de, sizeof(dir->buf));
+	if (dir->len <= 0)
+		return NULL;
+
+	dir->pos = dir->buf;
+	goto return_de;
+}
+
+int lkl_errdir(struct lkl_dir *dir)
+{
+	if (dir->len >= 0)
+		return 0;
+
+	return dir->len;
+}
+
+int lkl_dirfd(struct lkl_dir *dir)
+{
+	return dir->fd;
+}
+
+int lkl_set_fd_limit(unsigned int fd_limit)
+{
+	struct lkl_rlimit rlim = {
+		.rlim_cur = fd_limit,
+		.rlim_max = fd_limit,
+	};
+	return lkl_sys_setrlimit(LKL_RLIMIT_NOFILE, &rlim);
+}
tools/um/lib/posix-host.c +1 -0
index b6b5b2902254..8fd88031bf2b 100644
@@ -263,6 +263,7 @@ static void *tls_get(struct lkl_tls_key *key)
  }
 
  struct lkl_host_operations lkl_host_ops = {
+	.um_devices = lkl_um_devs,
  	.panic = panic,
  	.print = print,
  	.mem_alloc = (void *)malloc,
tools/um/lib/utils.c +3 -0
index 4930479a8a35..ac65cd744a14 100644
@@ -4,6 +4,9 @@
  #include <string.h>
  #include <lkl_host.h>
 
+/* XXX: find a better place */
+char lkl_um_devs[4096];
+
  static const char * const lkl_err_strings[] = {
  	"Success",
  	"Operation not permitted",
tools/um/tests/Build +1 -0
index 564560486f98..1aa78f9ed7ef 100644
@@ -1,3 +1,4 @@
  boot-y += boot.o test.o
+disk-y += disk.o test.o cla.o
 
  CFLAGS_test.o += -Wno-implicit-fallthrough
tools/um/tests/cla.c new file +159 -0
new file mode 100644
index 000000000000..694e3a3822be
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifdef __MINGW32__
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#include "cla.h"
+
+static int cl_arg_parse_bool(struct cl_arg *arg, const char *value)
+{
+	*((int *)arg->store) = 1;
+	return 0;
+}
+
+static int cl_arg_parse_str(struct cl_arg *arg, const char *value)
+{
+	*((const char **)arg->store) = value;
+	return 0;
+}
+
+static int cl_arg_parse_int(struct cl_arg *arg, const char *value)
+{
+	errno = 0;
+	*((int *)arg->store) = strtol(value, NULL, 0);
+	return errno == 0;
+}
+
+static int cl_arg_parse_str_set(struct cl_arg *arg, const char *value)
+{
+	const char **set = arg->set;
+	int i;
+
+	for (i = 0; set[i] != NULL; i++) {
+		if (strcmp(set[i], value) == 0) {
+			*((int *)arg->store) = i;
+			return 0;
+		}
+	}
+
+	return (-1);
+}
+
+static int cl_arg_parse_ipv4(struct cl_arg *arg, const char *value)
+{
+	unsigned int addr;
+
+	if (!value)
+		return (-1);
+
+	addr = inet_addr(value);
+	if (addr == INADDR_NONE)
+		return (-1);
+	*((unsigned int *)arg->store) = addr;
+	return 0;
+}
+
+static cl_arg_parser_t parsers[] = {
+	[CL_ARG_BOOL] = cl_arg_parse_bool,
+	[CL_ARG_INT] = cl_arg_parse_int,
+	[CL_ARG_STR] = cl_arg_parse_str,
+	[CL_ARG_STR_SET] = cl_arg_parse_str_set,
+	[CL_ARG_IPV4] = cl_arg_parse_ipv4,
+};
+
+static struct cl_arg *find_short_arg(char name, struct cl_arg *args)
+{
+	struct cl_arg *arg;
+
+	for (arg = args; arg->short_name != 0; arg++) {
+		if (arg->short_name == name)
+			return arg;
+	}
+
+	return NULL;
+}
+
+static struct cl_arg *find_long_arg(const char *name, struct cl_arg *args)
+{
+	struct cl_arg *arg;
+
+	for (arg = args; arg->long_name; arg++) {
+		if (strcmp(arg->long_name, name) == 0)
+			return arg;
+	}
+
+	return NULL;
+}
+
+static void print_help(struct cl_arg *args)
+{
+	struct cl_arg *arg;
+
+	fprintf(stderr, "usage:\n");
+	for (arg = args; arg->long_name; arg++) {
+		fprintf(stderr, "-%c, --%-20s %s", arg->short_name,
+			arg->long_name, arg->help);
+		if (arg->type == CL_ARG_STR_SET) {
+			const char **set = arg->set;
+
+			fprintf(stderr, " [ ");
+			while (*set != NULL)
+				fprintf(stderr, "%s ", *(set++));
+			fprintf(stderr, "]");
+		}
+		fprintf(stderr, "\n");
+	}
+}
+
+int cla_parse_args(int argc, const char **argv, struct cl_arg *args)
+{
+	int i;
+
+	for (i = 1; i < argc; i++) {
+		struct cl_arg *arg = NULL;
+		cl_arg_parser_t parser;
+
+		if (argv[i][0] == '-') {
+			if (argv[i][1] != '-')
+				arg = find_short_arg(argv[i][1], args);
+			else
+				arg = find_long_arg(&argv[i][2], args);
+		}
+
+		if (!arg) {
+			fprintf(stderr, "unknown option '%s'\n", argv[i]);
+			print_help(args);
+			return (-1);
+		}
+
+		if (arg->type == CL_ARG_USER || arg->type >= CL_ARG_END)
+			parser = arg->parser;
+		else
+			parser = parsers[arg->type];
+
+		if (!parser) {
+			fprintf(stderr, "can't parse --'%s'/-'%c'\n",
+				arg->long_name, args->short_name);
+			return (-1);
+		}
+
+		if (parser(arg, argv[i + 1]) < 0) {
+			fprintf(stderr, "can't parse '%s'\n", argv[i]);
+			print_help(args);
+			return (-1);
+		}
+
+		if (arg->has_arg)
+			i++;
+	}
+
+	return 0;
+}
tools/um/tests/cla.h new file +33 -0
new file mode 100644
index 000000000000..3d879233681f
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _LKL_TEST_CLA_H
+#define _LKL_TEST_CLA_H
+
+enum cl_arg_type {
+	CL_ARG_USER = 0,
+	CL_ARG_BOOL,
+	CL_ARG_INT,
+	CL_ARG_STR,
+	CL_ARG_STR_SET,
+	CL_ARG_IPV4,
+	CL_ARG_END,
+};
+
+struct cl_arg;
+
+typedef int (*cl_arg_parser_t)(struct cl_arg *arg, const char *value);
+
+struct cl_arg {
+	const char *long_name;
+	char short_name;
+	const char *help;
+	int has_arg;
+	enum cl_arg_type type;
+	void *store;
+	void *set;
+	cl_arg_parser_t parser;
+};
+
+int cla_parse_args(int argc, const char **argv, struct cl_arg *args);
+
+
+#endif /* _LKL_TEST_CLA_H */
tools/um/tests/disk.c new file +168 -0
new file mode 100644
index 000000000000..325934935e6a
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <lkl.h>
+#include <lkl_host.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "test.h"
+#include "cla.h"
+
+static struct {
+	int printk;
+	const char *disk;
+	const char *fstype;
+	int partition;
+} cla;
+
+struct cl_arg args[] = {
+	{"disk", 'd', "disk file to use", 1, CL_ARG_STR, &cla.disk},
+	{"partition", 'P', "partition to mount", 1, CL_ARG_INT, &cla.partition},
+	{"type", 't', "filesystem type", 1, CL_ARG_STR, &cla.fstype},
+	{0},
+};
+
+
+static struct lkl_disk disk;
+static int disk_id = -1;
+
+int lkl_test_disk_add(void)
+{
+	disk.fd = open(cla.disk, O_RDWR);
+	if (disk.fd < 0)
+		goto out_unlink;
+
+	disk.ops = NULL;
+	disk.dev = (char *)cla.disk;
+
+	disk_id = lkl_disk_add(&disk);
+	if (disk_id < 0)
+		goto out_close;
+
+	goto out;
+
+out_close:
+	close(disk.fd);
+
+out_unlink:
+	unlink(cla.disk);
+
+out:
+	lkl_test_logf("disk fd/handle %x disk_id %d", disk.fd, disk_id);
+
+	if (disk_id >= 0)
+		return TEST_SUCCESS;
+
+	return TEST_FAILURE;
+}
+
+int lkl_test_disk_remove(void)
+{
+	int ret;
+
+	ret = lkl_disk_remove(disk);
+
+	close(disk.fd);
+
+	if (ret == 0)
+		return TEST_SUCCESS;
+
+	return TEST_FAILURE;
+}
+
+
+static char mnt_point[32];
+
+LKL_TEST_CALL(mount_dev, lkl_mount_dev, 0, disk_id, cla.partition, cla.fstype,
+	      0, NULL, mnt_point, sizeof(mnt_point))
+
+static int lkl_test_umount_dev(void)
+{
+	long ret, ret2;
+
+	ret = lkl_sys_chdir("/");
+
+	ret2 = lkl_umount_dev(disk_id, cla.partition, 0, 1000);
+
+	lkl_test_logf("%ld %ld", ret, ret2);
+
+	if (!ret && !ret2)
+		return TEST_SUCCESS;
+
+	return TEST_FAILURE;
+}
+
+struct lkl_dir *dir;
+
+static int lkl_test_opendir(void)
+{
+	int err;
+
+	dir = lkl_opendir(mnt_point, &err);
+
+	lkl_test_logf("lkl_opedir(%s) = %d %s\n", mnt_point, err,
+		      lkl_strerror(err));
+
+	if (err == 0)
+		return TEST_SUCCESS;
+
+	return TEST_FAILURE;
+}
+
+static int lkl_test_readdir(void)
+{
+	struct lkl_linux_dirent64 *de = lkl_readdir(dir);
+	int wr = 0;
+
+	while (de) {
+		wr += lkl_test_logf("%s ", de->d_name);
+		if (wr >= 70) {
+			lkl_test_logf("\n");
+			wr = 0;
+			break;
+		}
+		de = lkl_readdir(dir);
+	}
+
+	if (lkl_errdir(dir) == 0)
+		return TEST_SUCCESS;
+
+	return TEST_FAILURE;
+}
+
+LKL_TEST_CALL(closedir, lkl_closedir, 0, dir);
+LKL_TEST_CALL(chdir_mnt_point, lkl_sys_chdir, 0, mnt_point);
+LKL_TEST_CALL(start_kernel, lkl_start_kernel, 0, &lkl_host_ops,
+	     "mem=16M loglevel=8");
+LKL_TEST_CALL(stop_kernel, lkl_sys_halt, 0);
+
+struct lkl_test tests[] = {
+	LKL_TEST(disk_add),
+	LKL_TEST(start_kernel),
+	LKL_TEST(mount_dev),
+	LKL_TEST(chdir_mnt_point),
+	LKL_TEST(opendir),
+	LKL_TEST(readdir),
+	LKL_TEST(closedir),
+	LKL_TEST(umount_dev),
+	LKL_TEST(stop_kernel),
+	LKL_TEST(disk_remove),
+
+};
+
+int main(int argc, const char **argv)
+{
+	if (cla_parse_args(argc, argv, args) < 0)
+		return (-1);
+
+	lkl_host_ops.print = lkl_test_log;
+
+	return lkl_test_run(tests, sizeof(tests)/sizeof(struct lkl_test),
+			    "disk %s", cla.fstype);
+}
tools/um/tests/disk.sh new file +70 -0
new file mode 100755
index 000000000000..e2ec6cf69d4b
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0
+
+script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+
+source $script_dir/test.sh
+
+function prepfs()
+{
+    set -e
+
+    file=`mktemp`
+
+    dd if=/dev/zero of=$file bs=1024 count=204800
+
+    yes | mkfs.$1 $file
+
+    if ! [ -z $ANDROID_WDIR ]; then
+        adb shell mkdir -p $ANDROID_WDIR
+        adb push $file $ANDROID_WDIR
+        rm $file
+        file=$ANDROID_WDIR/$(basename $file)
+    fi
+    if ! [ -z $BSD_WDIR ]; then
+        $MYSSH mkdir -p $BSD_WDIR
+        ssh_copy $file $BSD_WDIR
+        rm $file
+        file=$BSD_WDIR/$(basename $file)
+    fi
+
+    export_vars file
+}
+
+function cleanfs()
+{
+    set -e
+
+    if ! [ -z $ANDROID_WDIR ]; then
+        adb shell rm $1
+        adb shell rm $ANDROID_WDIR/disk
+    elif ! [ -z $BSD_WDIR ]; then
+        $MYSSH rm $1
+        $MYSSH rm $BSD_WDIR/disk
+    else
+        rm $1
+    fi
+}
+
+if [ "$1" = "-t" ]; then
+    shift
+    fstype=$1
+    shift
+fi
+
+if [ -z "$fstype" ]; then
+    fstype="ext4"
+fi
+
+if [ -z $(which mkfs.$fstype) ]; then
+    lkl_test_plan 0 "disk $fstype"
+    echo "no mkfs.$fstype command"
+    exit 0
+fi
+
+lkl_test_plan 1 "disk $fstype"
+lkl_test_run 1 prepfs $fstype
+lkl_test_exec $script_dir/disk -d $file -t $fstype $@
+lkl_test_plan 1 "disk $fstype"
+lkl_test_run 1 cleanfs $file
+
tools/um/tests/run.py +2 -0
index c96ede90b6ad..97d6dedc217c 100755
@@ -50,6 +50,8 @@ mydir=os.path.dirname(os.path.realpath(__file__))
 
  tests = [
      'boot.sh',
+    'disk.sh -t ext4',
+    'disk.sh -t vfat',
  ]
 
  parser = argparse.ArgumentParser(description='LKL test runner')
Signature · 3 lines
Anton R. Ivanov
Cambridgegreys Limited. Registered in England. Company Number 10273661
https://www.cambridgegreys.com/
#189 lore raw

Re: [RFC v7 21/21] um: nommu: add block device support of UML

Quoted 16 lines · Anton Ivanov
Quoted 16 lines
arch/um/nommu/um/Kconfig +4 -0
index 20b3eaccb6f0..c6a3f472fe75 100644
@@ -4,6 +4,10 @@ config UML_NOMMU
  	select UACCESS_MEMCPY
  	select ARCH_THREAD_STACK_ALLOCATOR
  	select ARCH_HAS_SYSCALL_WRAPPER
+	select VFAT_FS
+	select NLS_CODEPAGE_437
+	select NLS_ISO8859_1
+	select BTRFS_FS
    config 64BIT
  	bool
@@ -35,3 +39,7 @@ config STACKTRACE_SUPPORT
  config PRINTK_TIME
Quoted 8 lines

arch/um/nommu/um/Kconfig config STACKTRACE_SUPPORT · line 45

Quoted 6 lines
arch/um/nommu/um/Kconfig +4 -0
  	bool
  	default y
+
+config RAID6_PQ_BENCHMARK
+	bool
+	default n

Why are we touching this? I thought this is already defined in lib/Kconfig?

With the scheduler which LKL implements, it has the same issue with what time-travel=inf-cpu has when CONFIG_BTRFS_FS is enable. I tried to follow the way of the commit d65197a (below), but if I added "depends on !RAID6_PQ_BENCHMARK" to config UMMODE_LIB, I got "error:
recursive dependency detected!".

https://github.com/thehajime/linux/commit/d65197ad52494bed3b5e64708281b8295f76c391#diff-c170aa964ad412630a2b5addf306ff14

Thus, to avoid this situation, I did the above additional config RAID6_PQ_BENCHMARK just for UMMODE_LIB.

I plan to rework on Kconfig (UMMODE_LIB and !MMU) and will figure out more appropriate way.

-- Hajime

maintainer
#190 lore raw
In reply to Hajime Tazaki
Quoted 12 lines · Hajime Tazaki

This is another spin of the unification of LKL into UML. Based on the discussion of v4 patchset, we have tried to address issue raised and rewrote the patchset from scratch. The summary is listed in the changelog below.

Although there are still bugs in the patchset, we'd like to ask your opinions on the design we changed.

The milestone section is also updated: this patchset is for the milestone 1, though the common init API is still not implemented yet.

Quoted 5 lines

Changes in rfc v7:
- preserve make ARCH=um syntax to build UML
- introduce make ARCH=um UMMODE=library to build library mode
- fix undefined symbols issue during modpost
- clean up makefiles (arch/um, tools/um)

Hi Hajime, hi Tavi,

Our starting point should be that it does not break the existing build. It still does.

If I build a "stock configuration" UML after applying the patchset the resulting vmlinux is not executable.

On the positive side, it builds cleanly now. I will try to go through the rest of the patchset later today and see if there is anything else that needs fixing before we do the next version.

Brgds,

A.

Quoted 437 lines

Changes in rfc v6:
- rebase with the current linus tree

Changes in rfc v5:
- rewrite whole patchset from scratch
- move arch-dependent code of arch/um and arch/x86/um to tools/um
- mainly code under os-Linux/ involved
- introduce 2-stage build (kernel, and host-dependent parts)
- clean up vmlinux.lds.S
- put LKL-specific implementations as a SUBARCH under arch/um/nommu
- introduce !CONFIG_MMU in arch/um
- use struct arch_thread and arch_switch_to() for subarch-specific thread implementation
- integrate with the IRQ infrastructure of UML
- tested with block device drivers (ubd) for the proof

Changes in rfc v4: (https://lwn.net/Articles/816276/)
- Rebase on the current uml/master branch
- Fix IRQ handling (bug fix)
- drop a patch for CONFIG_GENERIC_ATOMIC64 (comment by Peter Zijlstra)
- implement vector net driver for UMMODE_LIB (comment by Anton)
- clean up uapi headers to avoid duplicates
- clean up IRQ handling code (comment by Anton)
- fix error handling in test code (comments by David Disseldorp)

Changes in rfc v3:
- use UML drivers (net, block) from LKL programs
- drop virtio device implementations
- drop mingw32 (Windows) host
- drop android (arm/aarch64) host
- drop FreeBSD (x86_64) host
- drop LD_PRELOAD (hijack) support
- update milestone

rfc v2:
- use UMMODE instead of SUBARCH to switch UML or LKL
- tools/lkl directory is still there. I confirmed we can move under arch/um (e.g., arch/um/lkl/hosts). I will move it IF this is preferable.
- drop several patches involved non-uml directory
- drop several patches which are not required
- refine commit logs
- document updated

LKL (Linux Kernel Library) is aiming to allow reusing the Linux kernel code as extensively as possible with minimal effort and reduced maintenance overhead.

Examples of how LKL can be used are: creating userspace applications (running on Linux and other operating systems) that can read or write Linux filesystems or can use the Linux networking stack, creating kernel drivers for other operating systems that can read Linux filesystems, bootloaders support for reading/writing Linux filesystems, etc.

With LKL, the kernel code is compiled into an object file that can be directly linked by applications. The API offered by LKL is based on the Linux system call interface.

LKL is originally implemented as an architecture port in arch/lkl, but this series of commits tries to integrate this into arch/um as one of the mode of UML. This was discussed during RFC email of LKL (*1).

The latest LKL version can be found at https://github.com/lkl/linux

Milestone
=========
This patches is a first step toward upstreaming *library mode* of Linux kernel, but we think we need to have several steps toward our goal, describing in the below.

Milestone 1: LKL lib on top of UML
* Kernel - Host build split
- Build UML as a relocatable object using the UML's kernel linker script.
- Move the ptrace and other well isolated os code out of arch/um to tools/um
- Use standard host toolchain to create a static library stripped of the ptrace code. Use standard host toolchain to build the main UML executable.
- Add library init API that creates the UML kernel process and starts UML.
* System calls APIs
- Add new system call interface based on UML's irq facility.
- Use the LKL scripts to export the required headers to create system calls APIs that use the UML system calls infrastructure.
- Keep the underlying host and driver operations (threads, irqs, etc.) as they are now in UML.
* Boot test
- Port the LKL boot test to verify that we are able to programatically issue system calls.

Milestone 2: add virtio disk support
* Export asm/io.h operations to host/os. Create IO access operations and redirect them to weak os_ variants that use the current UML implementation.
* Add the LKL IO access layer including generic virtio handling and the virtio block device code.
* Port LKL disk test and disk apps (lklfuse, fs2tar, cptofs)

Milestone 3: new arch ports
* Abstract the system call / IRQ mode the move the implementation to host
* Abstract the thread model and move the implementation to host
* Add LKL thread model and LKL ports

Building LKL the host library and LKL applications
==================================================

% cd tools/um
% make

will build LKL as a object file, it will install it in tools/um/lib together with the headers files in tools/um/include then will build the host library, tests and a few of application examples:

* tests/boot - a simple applications that uses LKL and exercises the basic LKL APIs

% make run-tests

should run the above tests/boot and tests/net-test and report errors if there are any.

Supported hosts
===============

Currently LKL supports Linux userspace applications. New hosts can be added relatively easy if the host supports gcc and GNU ld. Previous versions of LKL supported Windows kernel and Haiku kernel hosts, and we also have WIP patches with rump-hypercall interface, used in UEFI, as well as macOS userspace (part of POSIX).

There is also musl-libc port for LKL, which might be interested in for some folks.

Further readings about LKL
=========================

- Discussion in github LKL issue
https://github.com/lkl/linux/issues/304

- LKL (an article)
https://www.researchgate.net/profile/Nicolae_Tapus2/publication/224164682_LKL_The_Linux_kernel_library/links/02bfe50fd921ab4f7c000000.pdf

*1 RFC email to LKML (back in 2015)
https://www.mail-archive.com/[email protected]/msg1012277.html

Please review the following changes for suitability for inclusion. If you have any objections or suggestions for improvement, please respond to the patches. If you agree with the changes, please provide your Acked-by.

The following changes since commit 805c6d3c19210c90c109107d189744e960eae025:

   Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs (2020-09-22 15:08:41 -0700)

are available in the Git repository at:

   git://github.com/thehajime/linux a8686efcbad3c445d3e5bde054c04a58877915f1
   https://github.com/thehajime/linux/tree/uml-lkl-5.9rc6-v7

Hajime Tazaki (18):
um: move arch/um/os-Linux dir to tools/um/uml
um: move arch/x86/um/os-Linux to tools/um/uml/
scritps: um: suppress warnings if SRCARCH=um
um: extend arch_switch_to for alternate SUBARCH
um: add nommu mode for UML library mode
um: nommu: host interface
um: nommu: memory handling
um: nommu: kernel thread support
um: nommu: system call interface and application API
um: nommu: basic console support
um: nommu: initialization and cleanup
um: nommu: integrate with irq infrastructure of UML
um: nommu: plug in the build system
um: host: add nommu build for ARCH=um
um: host: add utilities functions
um: host: posix host operations
um: host: add test programs
um: nommu: add block device support of UML

Octavian Purdila (3):
um: split build in kernel and host parts
um: add os init and exit calls
um: host: implement os_initcalls and os_exitcalls

  arch/um/Kconfig                               |  29 +-
  arch/um/Makefile                              |  35 +-
  arch/um/drivers/Makefile                      |  10 +-
  .../um/{os-Linux => }/drivers/ethertap_kern.c |   0
  arch/um/{os-Linux => }/drivers/tuntap_kern.c  |   0
  arch/um/include/asm/common.lds.S              |  99 ----
  arch/um/include/asm/host_ops.h                |   9 +
  arch/um/include/asm/mmu.h                     |   3 +
  arch/um/include/asm/mmu_context.h             |   8 +
  arch/um/include/asm/page.h                    |  15 +
  arch/um/include/asm/pgtable.h                 |  27 +
  arch/um/include/asm/thread_info.h             |  24 +
  arch/um/include/asm/uaccess.h                 |   6 +
  arch/um/include/asm/xor.h                     |   3 +-
  arch/um/include/shared/as-layout.h            |   1 +
  .../drivers => include/shared}/etap.h         |   0
  arch/um/include/shared/init.h                 |  19 +-
  arch/um/include/shared/os.h                   |   1 +
  .../drivers => include/shared}/tuntap.h       |   0
  arch/um/include/uapi/asm/Kbuild               |   2 +
  arch/um/kernel/Makefile                       |  13 +-
  arch/um/kernel/dyn.lds.S                      | 171 -------
  arch/um/kernel/irq.c                          |  13 +
  arch/um/kernel/process.c                      |  14 +-
  arch/um/kernel/reboot.c                       |   5 +
  arch/um/kernel/time.c                         |   2 +
  arch/um/kernel/um_arch.c                      |  16 +
  arch/um/kernel/uml.lds.S                      | 115 -----
  arch/um/{os-Linux => kernel}/user_syms.c      |   0
  arch/um/kernel/vmlinux.lds.S                  |  91 +++-
  arch/um/nommu/Makefile                        |   1 +
  arch/um/nommu/Makefile.um                     |  22 +
  arch/um/nommu/include/asm/Kbuild              |   6 +
  arch/um/nommu/include/asm/archparam.h         |   1 +
  arch/um/nommu/include/asm/atomic.h            |  11 +
  arch/um/nommu/include/asm/atomic64.h          | 114 +++++
  arch/um/nommu/include/asm/bitsperlong.h       |  12 +
  arch/um/nommu/include/asm/byteorder.h         |   7 +
  arch/um/nommu/include/asm/cpu.h               |  16 +
  arch/um/nommu/include/asm/elf.h               |  15 +
  arch/um/nommu/include/asm/mm_context.h        |   8 +
  arch/um/nommu/include/asm/processor.h         |  46 ++
  arch/um/nommu/include/asm/ptrace.h            |  21 +
  arch/um/nommu/include/asm/sched.h             |  23 +
  arch/um/nommu/include/asm/segment.h           |   9 +
  arch/um/nommu/include/asm/syscall_wrapper.h   |  57 +++
  arch/um/nommu/include/asm/syscalls.h          |  15 +
  arch/um/nommu/include/uapi/asm/Kbuild         |   6 +
  arch/um/nommu/include/uapi/asm/bitsperlong.h  |  11 +
  arch/um/nommu/include/uapi/asm/byteorder.h    |  11 +
  arch/um/nommu/include/uapi/asm/host_ops.h     | 122 +++++
  arch/um/nommu/include/uapi/asm/sigcontext.h   |  12 +
  arch/um/nommu/include/uapi/asm/syscalls.h     | 287 +++++++++++
  arch/um/nommu/include/uapi/asm/unistd.h       |  17 +
  arch/um/nommu/um/Kconfig                      |  45 ++
  arch/um/nommu/um/Makefile                     |   4 +
  arch/um/nommu/um/bootmem.c                    |  87 ++++
  arch/um/nommu/um/console.c                    |  42 ++
  arch/um/nommu/um/cpu.c                        | 247 ++++++++++
  arch/um/nommu/um/delay.c                      |  31 ++
  arch/um/nommu/um/setup.c                      | 179 +++++++
  arch/um/nommu/um/shared/sysdep/archsetjmp.h   |  13 +
  arch/um/nommu/um/shared/sysdep/faultinfo.h    |   8 +
  .../nommu/um/shared/sysdep/kernel-offsets.h   |  12 +
  arch/um/nommu/um/shared/sysdep/mcontext.h     |   9 +
  arch/um/nommu/um/shared/sysdep/ptrace.h       |  42 ++
  arch/um/nommu/um/shared/sysdep/ptrace_user.h  |   7 +
  arch/um/nommu/um/syscalls.c                   | 199 ++++++++
  arch/um/nommu/um/threads.c                    | 262 ++++++++++
  arch/um/nommu/um/unimplemented.c              |  70 +++
  arch/um/nommu/um/user_constants.h             |  13 +
  arch/um/os-Linux/Makefile                     |  19 -
  arch/um/os-Linux/drivers/Makefile             |  13 -
  arch/um/scripts/headers_install.py            | 197 ++++++++
  arch/x86/um/Makefile                          |   2 +-
  arch/x86/um/os-Linux/Makefile                 |  13 -
  arch/x86/um/ptrace_32.c                       |   2 +-
  arch/x86/um/syscalls_64.c                     |   2 +-
  scripts/headers_install.sh                    |   4 +
  scripts/link-vmlinux.sh                       |  42 +-
  tools/um/.gitignore                           |   1 +
  tools/um/Makefile                             |  81 +++
  tools/um/Targets                              |  13 +
  tools/um/include/lkl.h                        | 357 ++++++++++++++
  tools/um/include/lkl_host.h                   |  27 +
  tools/um/lib/Build                            |   7 +
  tools/um/lib/fs.c                             | 461 ++++++++++++++++++
  tools/um/lib/jmp_buf.c                        |  14 +
  tools/um/lib/jmp_buf.h                        |   8 +
  tools/um/lib/posix-host.c                     | 293 +++++++++++
  tools/um/lib/utils.c                          | 213 ++++++++
  tools/um/tests/Build                          |   4 +
  tools/um/tests/boot.c                         | 393 +++++++++++++++
  tools/um/tests/boot.sh                        |   9 +
  tools/um/tests/cla.c                          | 159 ++++++
  tools/um/tests/cla.h                          |  33 ++
  tools/um/tests/disk.c                         | 168 +++++++
  tools/um/tests/disk.sh                        |  70 +++
  tools/um/tests/run.py                         | 174 +++++++
  tools/um/tests/tap13.py                       | 209 ++++++++
  tools/um/tests/test.c                         | 126 +++++
  tools/um/tests/test.h                         |  72 +++
  tools/um/tests/test.sh                        | 181 +++++++
  tools/um/uml/Build                            |  58 +++
  tools/um/uml/drivers/Build                    |  10 +
  .../um/uml}/drivers/ethertap_user.c           |   0
  .../um/uml}/drivers/tuntap_user.c             |   0
  {arch/um/os-Linux => tools/um/uml}/elf_aux.c  |   0
  {arch/um/os-Linux => tools/um/uml}/execvp.c   |   4 -
  {arch/um/os-Linux => tools/um/uml}/file.c     |   0
  {arch/um/os-Linux => tools/um/uml}/helper.c   |   0
  {arch/um/os-Linux => tools/um/uml}/irq.c      |   0
  {arch/um/os-Linux => tools/um/uml}/main.c     |   0
  {arch/um/os-Linux => tools/um/uml}/mem.c      |   0
  tools/um/uml/nommu/Build                      |   1 +
  tools/um/uml/nommu/registers.c                |  21 +
  tools/um/uml/nommu/unimplemented.c            |  21 +
  {arch/um/os-Linux => tools/um/uml}/process.c  |   2 +
  .../um/os-Linux => tools/um/uml}/registers.c  |   0
  {arch/um/os-Linux => tools/um/uml}/sigio.c    |   0
  {arch/um/os-Linux => tools/um/uml}/signal.c   |  12 +-
  .../skas/Makefile => tools/um/uml/skas/Build  |   6 +-
  {arch/um/os-Linux => tools/um/uml}/skas/mem.c |   0
  .../os-Linux => tools/um/uml}/skas/process.c  |   3 +-
  {arch/um/os-Linux => tools/um/uml}/start_up.c |   0
  {arch/um/os-Linux => tools/um/uml}/time.c     |   0
  {arch/um/os-Linux => tools/um/uml}/tty.c      |   0
  {arch/um/os-Linux => tools/um/uml}/umid.c     |   0
  {arch/um/os-Linux => tools/um/uml}/util.c     |  26 +
  tools/um/uml/x86/Build                        |  11 +
  .../os-Linux => tools/um/uml/x86}/mcontext.c  |   0
  .../um/os-Linux => tools/um/uml/x86}/prctl.c  |   0
  .../os-Linux => tools/um/uml/x86}/registers.c |   0
  .../os-Linux => tools/um/uml/x86}/task_size.c |   0
  .../um/os-Linux => tools/um/uml/x86}/tls.c    |   0
  135 files changed, 5870 insertions(+), 523 deletions(-)

rename arch/um/{os-Linux => }/drivers/ethertap_kern.c (100%) rename arch/um/{os-Linux => }/drivers/tuntap_kern.c (100%) delete mode 100644 arch/um/include/asm/common.lds.S
create mode 100644 arch/um/include/asm/host_ops.h
rename arch/um/{os-Linux/drivers => include/shared}/etap.h (100%) rename arch/um/{os-Linux/drivers => include/shared}/tuntap.h (100%) create mode 100644 arch/um/include/uapi/asm/Kbuild
delete mode 100644 arch/um/kernel/dyn.lds.S
delete mode 100644 arch/um/kernel/uml.lds.S
rename arch/um/{os-Linux => kernel}/user_syms.c (100%) create mode 100644 arch/um/nommu/Makefile
create mode 100644 arch/um/nommu/Makefile.um
create mode 100644 arch/um/nommu/include/asm/Kbuild
create mode 100644 arch/um/nommu/include/asm/archparam.h create mode 100644 arch/um/nommu/include/asm/atomic.h
create mode 100644 arch/um/nommu/include/asm/atomic64.h create mode 100644 arch/um/nommu/include/asm/bitsperlong.h create mode 100644 arch/um/nommu/include/asm/byteorder.h create mode 100644 arch/um/nommu/include/asm/cpu.h
create mode 100644 arch/um/nommu/include/asm/elf.h
create mode 100644 arch/um/nommu/include/asm/mm_context.h create mode 100644 arch/um/nommu/include/asm/processor.h create mode 100644 arch/um/nommu/include/asm/ptrace.h
create mode 100644 arch/um/nommu/include/asm/sched.h
create mode 100644 arch/um/nommu/include/asm/segment.h create mode 100644 arch/um/nommu/include/asm/syscall_wrapper.h create mode 100644 arch/um/nommu/include/asm/syscalls.h create mode 100644 arch/um/nommu/include/uapi/asm/Kbuild create mode 100644 arch/um/nommu/include/uapi/asm/bitsperlong.h create mode 100644 arch/um/nommu/include/uapi/asm/byteorder.h create mode 100644 arch/um/nommu/include/uapi/asm/host_ops.h create mode 100644 arch/um/nommu/include/uapi/asm/sigcontext.h create mode 100644 arch/um/nommu/include/uapi/asm/syscalls.h create mode 100644 arch/um/nommu/include/uapi/asm/unistd.h create mode 100644 arch/um/nommu/um/Kconfig
create mode 100644 arch/um/nommu/um/Makefile
create mode 100644 arch/um/nommu/um/bootmem.c
create mode 100644 arch/um/nommu/um/console.c
create mode 100644 arch/um/nommu/um/cpu.c
create mode 100644 arch/um/nommu/um/delay.c
create mode 100644 arch/um/nommu/um/setup.c
create mode 100644 arch/um/nommu/um/shared/sysdep/archsetjmp.h create mode 100644 arch/um/nommu/um/shared/sysdep/faultinfo.h create mode 100644 arch/um/nommu/um/shared/sysdep/kernel-offsets.h create mode 100644 arch/um/nommu/um/shared/sysdep/mcontext.h create mode 100644 arch/um/nommu/um/shared/sysdep/ptrace.h create mode 100644 arch/um/nommu/um/shared/sysdep/ptrace_user.h create mode 100644 arch/um/nommu/um/syscalls.c
create mode 100644 arch/um/nommu/um/threads.c
create mode 100644 arch/um/nommu/um/unimplemented.c
create mode 100644 arch/um/nommu/um/user_constants.h
delete mode 100644 arch/um/os-Linux/Makefile
delete mode 100644 arch/um/os-Linux/drivers/Makefile
create mode 100755 arch/um/scripts/headers_install.py
delete mode 100644 arch/x86/um/os-Linux/Makefile
create mode 100644 tools/um/.gitignore
create mode 100644 tools/um/Makefile
create mode 100644 tools/um/Targets
create mode 100644 tools/um/include/lkl.h
create mode 100644 tools/um/include/lkl_host.h
create mode 100644 tools/um/lib/Build
create mode 100644 tools/um/lib/fs.c
create mode 100644 tools/um/lib/jmp_buf.c
create mode 100644 tools/um/lib/jmp_buf.h
create mode 100644 tools/um/lib/posix-host.c
create mode 100644 tools/um/lib/utils.c
create mode 100644 tools/um/tests/Build
create mode 100644 tools/um/tests/boot.c
create mode 100755 tools/um/tests/boot.sh
create mode 100644 tools/um/tests/cla.c
create mode 100644 tools/um/tests/cla.h
create mode 100644 tools/um/tests/disk.c
create mode 100755 tools/um/tests/disk.sh
create mode 100755 tools/um/tests/run.py
create mode 100644 tools/um/tests/tap13.py
create mode 100644 tools/um/tests/test.c
create mode 100644 tools/um/tests/test.h
create mode 100644 tools/um/tests/test.sh
create mode 100644 tools/um/uml/Build
create mode 100644 tools/um/uml/drivers/Build
rename {arch/um/os-Linux => tools/um/uml}/drivers/ethertap_user.c (100%) rename {arch/um/os-Linux => tools/um/uml}/drivers/tuntap_user.c (100%) rename {arch/um/os-Linux => tools/um/uml}/elf_aux.c (100%) rename {arch/um/os-Linux => tools/um/uml}/execvp.c (98%) rename {arch/um/os-Linux => tools/um/uml}/file.c (100%) rename {arch/um/os-Linux => tools/um/uml}/helper.c (100%) rename {arch/um/os-Linux => tools/um/uml}/irq.c (100%) rename {arch/um/os-Linux => tools/um/uml}/main.c (100%) rename {arch/um/os-Linux => tools/um/uml}/mem.c (100%) create mode 100644 tools/um/uml/nommu/Build
create mode 100644 tools/um/uml/nommu/registers.c
create mode 100644 tools/um/uml/nommu/unimplemented.c
rename {arch/um/os-Linux => tools/um/uml}/process.c (99%) rename {arch/um/os-Linux => tools/um/uml}/registers.c (100%) rename {arch/um/os-Linux => tools/um/uml}/sigio.c (100%) rename {arch/um/os-Linux => tools/um/uml}/signal.c (96%) rename arch/um/os-Linux/skas/Makefile => tools/um/uml/skas/Build (56%) rename {arch/um/os-Linux => tools/um/uml}/skas/mem.c (100%) rename {arch/um/os-Linux => tools/um/uml}/skas/process.c (99%) rename {arch/um/os-Linux => tools/um/uml}/start_up.c (100%) rename {arch/um/os-Linux => tools/um/uml}/time.c (100%) rename {arch/um/os-Linux => tools/um/uml}/tty.c (100%) rename {arch/um/os-Linux => tools/um/uml}/umid.c (100%) rename {arch/um/os-Linux => tools/um/uml}/util.c (89%) create mode 100644 tools/um/uml/x86/Build
rename {arch/x86/um/os-Linux => tools/um/uml/x86}/mcontext.c (100%) rename {arch/x86/um/os-Linux => tools/um/uml/x86}/prctl.c (100%) rename {arch/x86/um/os-Linux => tools/um/uml/x86}/registers.c (100%) rename {arch/x86/um/os-Linux => tools/um/uml/x86}/task_size.c (100%) rename {arch/x86/um/os-Linux => tools/um/uml/x86}/tls.c (100%)

Signature · 3 lines
Anton R. Ivanov
Cambridgegreys Limited. Registered in England. Company Number 10273661
https://www.cambridgegreys.com/
#191 lore raw

Hello Anton,

Quoted 21 lines · Anton Ivanov
Quoted 12 lines · Hajime Tazaki

This is another spin of the unification of LKL into UML. Based on the discussion of v4 patchset, we have tried to address issue raised and rewrote the patchset from scratch. The summary is listed in the changelog below.

Although there are still bugs in the patchset, we'd like to ask your opinions on the design we changed.

The milestone section is also updated: this patchset is for the milestone 1, though the common init API is still not implemented yet.

Quoted 5 lines

Changes in rfc v7:
- preserve make ARCH=um syntax to build UML
- introduce make ARCH=um UMMODE=library to build library mode
- fix undefined symbols issue during modpost
- clean up makefiles (arch/um, tools/um)

Quoted 3 lines

Hi Hajime, hi Tavi,

Our starting point should be that it does not break the existing build. It still does.

I agree with the starting point.

Quoted 2 lines

If I build a "stock configuration" UML after applying the patchset the resulting vmlinux is not executable.

Ah, I confirmed the issue.
I was only trying to make the linux binary compatible, not vmlinux.

Because vmlinux is now build as a relocatable object, this is something we need to figure out if we wish to keep vmlinux executable.

Do you think we should make vmlinux executable even if we have the file linux executable ? If yes, we will work on this to fix the issue.

Quoted 3 lines

On the positive side, it builds cleanly now. I will try to go through the rest of the patchset later today and see if there is anything else that needs fixing before we do the next version.

thanks for your time.

-- Hajime

maintainer
#192 lore raw
Quoted 30 lines · Hajime Tazaki

Hello Anton,

Quoted 14 lines · Anton Ivanov
Quoted 12 lines · Hajime Tazaki

This is another spin of the unification of LKL into UML. Based on the discussion of v4 patchset, we have tried to address issue raised and rewrote the patchset from scratch. The summary is listed in the changelog below.

Although there are still bugs in the patchset, we'd like to ask your opinions on the design we changed.

The milestone section is also updated: this patchset is for the milestone 1, though the common init API is still not implemented yet.

Quoted 8 lines
Quoted 5 lines

Changes in rfc v7:
- preserve make ARCH=um syntax to build UML
- introduce make ARCH=um UMMODE=library to build library mode
- fix undefined symbols issue during modpost
- clean up makefiles (arch/um, tools/um)

Hi Hajime, hi Tavi,

Our starting point should be that it does not break the existing build. It still does.

I agree with the starting point.

Quoted 2 lines

If I build a "stock configuration" UML after applying the patchset the resulting vmlinux is not executable.

Quoted 8 lines

Ah, I confirmed the issue.
I was only trying to make the linux binary compatible, not vmlinux.

Because vmlinux is now build as a relocatable object, this is something we need to figure out if we wish to keep vmlinux executable.

Do you think we should make vmlinux executable even if we have the file linux executable ? If yes, we will work on this to fix the issue.

In my opinion, any relocatable objects, etc should be clearly named - either .o, .so, etc depending on what they are. We should not try to reuse any of the existing files for a different purpose.

I also agree with Johannes that we are not using the tools/ directory for its intended purpose.

We are not trying to build a tool. We are trying to build a sub-architecture. IMHO, the build should use a subdirectory under arch/um.

Quoted 8 lines
Quoted 3 lines

On the positive side, it builds cleanly now. I will try to go through the rest of the patchset later today and see if there is anything else that needs fixing before we do the next version.

thanks for your time.

-- Hajime

Signature · 3 lines
Anton R. Ivanov
Cambridgegreys Limited. Registered in England. Company Number 10273661
https://www.cambridgegreys.com/
#193 lore raw
Quoted 39 lines · Anton Ivanov
Quoted 36 lines · Hajime Tazaki

Hello Anton,

Quoted 14 lines · Anton Ivanov
Quoted 12 lines · Hajime Tazaki

This is another spin of the unification of LKL into UML. Based on the discussion of v4 patchset, we have tried to address issue raised and rewrote the patchset from scratch. The summary is listed in the changelog below.

Although there are still bugs in the patchset, we'd like to ask your opinions on the design we changed.

The milestone section is also updated: this patchset is for the milestone 1, though the common init API is still not implemented yet.

Quoted 8 lines
Quoted 5 lines

Changes in rfc v7:
- preserve make ARCH=um syntax to build UML
- introduce make ARCH=um UMMODE=library to build library mode
- fix undefined symbols issue during modpost
- clean up makefiles (arch/um, tools/um)

Hi Hajime, hi Tavi,

Our starting point should be that it does not break the existing build. It still does.

I agree with the starting point.

Quoted 2 lines

If I build a "stock configuration" UML after applying the patchset the resulting vmlinux is not executable.

Ah, I confirmed the issue.
I was only trying to make the linux binary compatible, not vmlinux.

Because vmlinux is now build as a relocatable object, this is something we need to figure out if we wish to keep vmlinux executable.

Quoted 9 lines
Quoted 2 lines

Do you think we should make vmlinux executable even if we have the file linux executable ? If yes, we will work on this to fix the issue.

In my opinion, any relocatable objects, etc should be clearly named - either .o, .so, etc depending on what they are. We should not try to reuse any of the existing files for a different purpose.

I also agree with Johannes that we are not using the tools/ directory for its intended purpose.

We are not trying to build a tool. We are trying to build a sub-architecture. IMHO, the build should use a subdirectory under arch/um.

Hi Anton, Johannes,

From strictly the UML point of view, I can see how this would be a sub-architecture build since we are doing both the kernel build and the UML binary as a single step.

If we look at arch/um as just the kernel that enables many applications, just one of which it is uml, I believe it is cleaner to build specific applications elsewhere. That is why we proposed to do a two step build process: one that builds the kernel as a relocatable object and one that uses this object to build programs, shared libraries, etc. Besides allowing us to create multiple tools / applications it also makes it much easier to support multiple OSes or other environments (e.g. bare-metal applications). As you can see, this allowed us to remove the linker script for UML and instead just used the target compiler to build the executable.

We have picked tools because it has the infrastructure to build programs, shared libraries, and it is the single place (AFAIK) where we don't link the code in there with the kernel binary.

Thanks,
Tavi

maintainer
#194 lore raw
Quoted 53 lines · Octavian Purdila
Quoted 37 lines · Anton Ivanov
Quoted 35 lines · Hajime Tazaki

Hello Anton,

Quoted 13 lines · Anton Ivanov
Quoted 12 lines · Hajime Tazaki

This is another spin of the unification of LKL into UML. Based on the discussion of v4 patchset, we have tried to address issue raised and rewrote the patchset from scratch. The summary is listed in the changelog below.

Although there are still bugs in the patchset, we'd like to ask your opinions on the design we changed.

The milestone section is also updated: this patchset is for the milestone 1, though the common init API is still not implemented yet.

Quoted 8 lines
Quoted 5 lines

Changes in rfc v7:
- preserve make ARCH=um syntax to build UML
- introduce make ARCH=um UMMODE=library to build library mode
- fix undefined symbols issue during modpost
- clean up makefiles (arch/um, tools/um)

Hi Hajime, hi Tavi,

Our starting point should be that it does not break the existing build. It still does.

I agree with the starting point.

Quoted 2 lines

If I build a "stock configuration" UML after applying the patchset the resulting vmlinux is not executable.

Ah, I confirmed the issue.
I was only trying to make the linux binary compatible, not vmlinux.

Because vmlinux is now build as a relocatable object, this is something we need to figure out if we wish to keep vmlinux executable.

Quoted 8 lines
Quoted 2 lines

Do you think we should make vmlinux executable even if we have the file linux executable ? If yes, we will work on this to fix the issue.

In my opinion, any relocatable objects, etc should be clearly named - either .o, .so, etc depending on what they are. We should not try to reuse any of the existing files for a different purpose.

I also agree with Johannes that we are not using the tools/ directory for its intended purpose.

We are not trying to build a tool. We are trying to build a sub-architecture. IMHO, the build should use a subdirectory under arch/um.

Hi Anton, Johannes,

From strictly the UML point of view, I can see how this would be a
sub-architecture build since we are doing both the kernel build and the UML binary as a single step.

Quoted 10 lines

If we look at arch/um as just the kernel that enables many applications, just one of which it is uml, I believe it is cleaner to build specific applications elsewhere. That is why we proposed to do a two step build process: one that builds the kernel as a relocatable object and one that uses this object to build programs, shared libraries, etc. Besides allowing us to create multiple tools / applications it also makes it much easier to support multiple OSes or other environments (e.g. bare-metal applications). As you can see, this allowed us to remove the linker script for UML and instead just used the target compiler to build the executable.

I have no objection to the proposal. In fact I like it very much.

My only concern is that we end up with files which are named identically to already existing ones.

IMHO, the kernel relocatable object should be vmlinux.a or vmlinux.so or vmlinux.o. It should not replace an already existing file which behaves differently.

Brgds,

A.

Quoted 8 lines

We have picked tools because it has the infrastructure to build programs, shared libraries, and it is the single place (AFAIK) where we don't link the code in there with the kernel binary.

Thanks,
Tavi

Signature · 3 lines
Anton R. Ivanov
Cambridgegreys Limited. Registered in England. Company Number 10273661
https://www.cambridgegreys.com/
#195 lore raw
Quoted 66 lines · Anton Ivanov
Quoted 53 lines · Octavian Purdila
Quoted 37 lines · Anton Ivanov
Quoted 35 lines · Hajime Tazaki

Hello Anton,

Quoted 13 lines · Anton Ivanov
Quoted 12 lines · Hajime Tazaki

This is another spin of the unification of LKL into UML. Based on the discussion of v4 patchset, we have tried to address issue raised and rewrote the patchset from scratch. The summary is listed in the changelog below.

Although there are still bugs in the patchset, we'd like to ask your opinions on the design we changed.

The milestone section is also updated: this patchset is for the milestone 1, though the common init API is still not implemented yet.

Quoted 8 lines
Quoted 5 lines

Changes in rfc v7:
- preserve make ARCH=um syntax to build UML
- introduce make ARCH=um UMMODE=library to build library mode
- fix undefined symbols issue during modpost
- clean up makefiles (arch/um, tools/um)

Hi Hajime, hi Tavi,

Our starting point should be that it does not break the existing build. It still does.

I agree with the starting point.

Quoted 2 lines

If I build a "stock configuration" UML after applying the patchset the resulting vmlinux is not executable.

Ah, I confirmed the issue.
I was only trying to make the linux binary compatible, not vmlinux.

Because vmlinux is now build as a relocatable object, this is something we need to figure out if we wish to keep vmlinux executable.

Quoted 8 lines
Quoted 2 lines

Do you think we should make vmlinux executable even if we have the file linux executable ? If yes, we will work on this to fix the issue.

In my opinion, any relocatable objects, etc should be clearly named - either .o, .so, etc depending on what they are. We should not try to reuse any of the existing files for a different purpose.

I also agree with Johannes that we are not using the tools/ directory for its intended purpose.

We are not trying to build a tool. We are trying to build a sub-architecture. IMHO, the build should use a subdirectory under arch/um.

Hi Anton, Johannes,

From strictly the UML point of view, I can see how this would be a
sub-architecture build since we are doing both the kernel build and the UML binary as a single step.

Quoted 10 lines

If we look at arch/um as just the kernel that enables many applications, just one of which it is uml, I believe it is cleaner to build specific applications elsewhere. That is why we proposed to do a two step build process: one that builds the kernel as a relocatable object and one that uses this object to build programs, shared libraries, etc. Besides allowing us to create multiple tools / applications it also makes it much easier to support multiple OSes or other environments (e.g. bare-metal applications). As you can see, this allowed us to remove the linker script for UML and instead just used the target compiler to build the executable.

Quoted 9 lines

I have no objection to the proposal. In fact I like it very much.

My only concern is that we end up with files which are named identically to already existing ones.

IMHO, the kernel relocatable object should be vmlinux.a or vmlinux.so or vmlinux.o. It should not replace an already existing file which behaves differently.

Got it, we will change that for the next patch series.

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#196 lore raw

v8 cover Unifying LKL into UML

In reply to Hajime Tazaki

This is another spin of the unification of LKL into UML. Updated and fixed comments from our v7 patches. The summary is listed in the changelog below.

Note that the whole patchset requires the patch "um: ubd: fix command line handling of ubd" to be correctly tested, which I previously submitted.

Changes in rfc v8:
- stop using the term "nommu" mode, "library" mode instead
- generic atomic64 rewrite to use gcc builtin atomics
- use kernel-doc format for comments
- stop using a collection of function pointer (struct lkl_host_operations), but weak functions
- use python3, not python
- use c99 initializers for strerror
- add comments/descriptions about thread implementation
- remove redundant Kconfig entries (RAID6_PQ_BENCHMARK, STACKTRACE_SUPPORT, etc)
- refine code comments
- stop using NPROC for the internal -j flag
- remove make argument of "UMMODE=library"
- preserve the vmlinux file as it is
- rework commit history with reasonable files
- rework test framework using kselftest (tools/testing/selftests/um/)
- add documentation, MAINTAINERS

Changes in rfc v7:
- preserve make ARCH=um syntax to build UML
- introduce make ARCH=um UMMODE=library to build library mode
- fix undefined symbols issue during modpost
- clean up makefiles (arch/um, tools/um)

Changes in rfc v6:
- rebase with the current linus tree

Changes in rfc v5:
- rewrite whole patchset from scratch
- move arch-dependent code of arch/um and arch/x86/um to tools/um
- mainly code under os-Linux/ involved
- introduce 2-stage build (kernel, and host-dependent parts)
- clean up vmlinux.lds.S
- put LKL-specific implementations as a SUBARCH under arch/um/nommu
- introduce !CONFIG_MMU in arch/um
- use struct arch_thread and arch_switch_to() for subarch-specific thread implementation
- integrate with the IRQ infrastructure of UML
- tested with block device drivers (ubd) for the proof

Changes in rfc v4: (https://lwn.net/Articles/816276/)
- Rebase on the current uml/master branch
- Fix IRQ handling (bug fix)
- drop a patch for CONFIG_GENERIC_ATOMIC64 (comment by Peter Zijlstra)
- implement vector net driver for UMMODE_LIB (comment by Anton)
- clean up uapi headers to avoid duplicates
- clean up IRQ handling code (comment by Anton)
- fix error handling in test code (comments by David Disseldorp)

Changes in rfc v3:
- use UML drivers (net, block) from LKL programs
- drop virtio device implementations
- drop mingw32 (Windows) host
- drop android (arm/aarch64) host
- drop FreeBSD (x86_64) host
- drop LD_PRELOAD (hijack) support
- update milestone

rfc v2:
- use UMMODE instead of SUBARCH to switch UML or LKL
- tools/lkl directory is still there. I confirmed we can move under arch/um (e.g., arch/um/lkl/hosts). I will move it IF this is preferable.
- drop several patches involved non-uml directory
- drop several patches which are not required
- refine commit logs
- document updated

LKL (Linux Kernel Library) is aiming to allow reusing the Linux kernel code as extensively as possible with minimal effort and reduced maintenance overhead.

Examples of how LKL can be used are: creating userspace applications (running on Linux and other operating systems) that can read or write Linux filesystems or can use the Linux networking stack, creating kernel drivers for other operating systems that can read Linux filesystems, bootloaders support for reading/writing Linux filesystems, etc.

With LKL, the kernel code is compiled into an object file that can be directly linked by applications. The API offered by LKL is based on the Linux system call interface.

LKL is originally implemented as an architecture port in arch/lkl, but this series of commits tries to integrate this into arch/um as one of the mode of UML. This was discussed during RFC email of LKL (*1).

The latest LKL version can be found at https://github.com/lkl/linux

Milestone
=========
This patches is a first step toward upstreaming *library mode* of Linux kernel, but we think we need to have several steps toward our goal, describing in the below.

Milestone 1: LKL lib on top of UML
* Kernel - Host build split
- Build UML as a relocatable object using the UML's kernel linker script.
- Move the ptrace and other well isolated os code out of arch/um to tools/um
- Use standard host toolchain to create a static library stripped of the ptrace code. Use standard host toolchain to build the main UML executable.
- Add library init API that creates the UML kernel process and starts UML.
* System calls APIs
- Add new system call interface based on UML's irq facility.
- Use the LKL scripts to export the required headers to create system calls APIs that use the UML system calls infrastructure.
- Keep the underlying host and driver operations (threads, irqs, etc.) as they are now in UML.
* Boot test
- Port the LKL boot test to verify that we are able to programatically issue system calls.

Milestone 2: add virtio disk support
* Export asm/io.h operations to host/os. Create IO access operations and redirect them to weak os_ variants that use the current UML implementation.
* Add the LKL IO access layer including generic virtio handling and the virtio block device code.
* Port LKL disk test and disk apps (lklfuse, fs2tar, cptofs)

Milestone 3: new arch ports
* Abstract the system call / IRQ mode the move the implementation to host
* Abstract the thread model and move the implementation to host
* Add LKL thread model and LKL ports

Building LKL the host library and LKL applications
==================================================

% make ARCH=um SUBARCH=lkl defconfig
% make ARCH=um SUBARCH=lkl

will build LKL as a object file, it will install it in tools/um/libtogether with the headers files in tools/um/include then will build the host library, tests and a few of application examples:

* tools/testing/selftests/um/boot.c - a simple applications that uses LKL and exercises the basic LKL APIs

* tools/testing/selftests/um/disk.c - a simple applications that tests LKL and exercises the basic filesystem-related LKL APIs

Those tests can run with the following kselftest command:

    $ make ARCH=um SUBARCH=lkl TARGETS="um" kselftest

Supported hosts
===============

Currently LKL supports Linux userspace applications. New hosts can be added relatively easy if the host supports gcc and GNU ld. Previous versions of LKL supported Windows kernel and Haiku kernel hosts, and we also have WIP patches with rump-hypercall interface, used in UEFI, as well as macOS userspace (part of POSIX).

There is also musl-libc port for LKL, which might be interested in for some folks.

Further readings about LKL
=========================

- Discussion in github LKL issue
https://github.com/lkl/linux/issues/304

- LKL (an article)
https://www.researchgate.net/profile/Nicolae_Tapus2/publication/224164682_LKL_The_Linux_kernel_library/links/02bfe50fd921ab4f7c000000.pdf

*1 RFC email to LKML (back in 2015)
https://www.mail-archive.com/[email protected]/msg1012277.html

Please review the following changes for suitability for inclusion. If you have any objections or suggestions for improvement, please respond to the patches. If you agree with the changes, please provide your Acked-by.

The following changes since commit 19c329f6808995b142b3966301f217c831e7cf31:

Linux 5.11-rc4 (2021-01-17 16:37:05 -0800)

are available in the Git repository at:

git://github.com/thehajime/linux 043677211bb5562397c511911e7861c3e217611b
https://github.com/thehajime/linux/tree/uml-lkl-5.11rc4-v8

Hajime Tazaki (18):
um: move arch/um/os-Linux dir to tools/um/uml
um: move arch/x86/um/os-Linux to tools/um/uml/
um: extend arch_switch_to for alternate SUBARCH
um: add UML library mode
um: lkl: host interface
um: lkl: memory handling
um: lkl: kernel thread support
um: lkl: system call interface and application API
um: lkl: basic console support
um: lkl: initialization and cleanup
um: lkl: integrate with irq infrastructure of UML
um: lkl: plug in the build system
um: host: add library mode build for ARCH=um
um: host: add utilities functions
um: host: posix host operations
selftests/um: lkl: add test programs for library mode of UML
um: lkl: add block device support of UML
um: lkl: add documentation

Octavian Purdila (2):
um: split build in kernel and host parts
um: implement os_initcalls and os_exitcalls

 Documentation/virt/uml/lkl.txt                |  48 ++
 MAINTAINERS                                   |  10 +
 arch/um/Kconfig                               |  37 +-
 arch/um/Makefile                              |  41 +-
 arch/um/configs/lkl_defconfig                 |  73 +++
 arch/um/drivers/Makefile                      |  10 +-
 .../um/{os-Linux => }/drivers/ethertap_kern.c |   0
 arch/um/{os-Linux => }/drivers/tuntap_kern.c  |   0
 arch/um/include/asm/common.lds.S              |  99 ----
 arch/um/include/asm/host_ops.h                |   9 +
 arch/um/include/asm/mmu.h                     |   3 +
 arch/um/include/asm/mmu_context.h             |  10 +
 arch/um/include/asm/page.h                    |  15 +
 arch/um/include/asm/pgtable.h                 |  27 +
 arch/um/include/asm/thread_info.h             |  24 +
 arch/um/include/asm/uaccess.h                 |   6 +
 arch/um/include/asm/xor.h                     |   3 +-
 arch/um/include/shared/as-layout.h            |   1 +
 .../drivers => include/shared}/etap.h         |   0
 arch/um/include/shared/init.h                 |  19 +-
 arch/um/include/shared/os.h                   |   1 +
 .../drivers => include/shared}/tuntap.h       |   0
 arch/um/kernel/Makefile                       |  13 +-
 arch/um/kernel/dyn.lds.S                      | 171 -------
 arch/um/kernel/irq.c                          |  13 +
 arch/um/kernel/process.c                      |  14 +-
 arch/um/kernel/reboot.c                       |   5 +
 arch/um/kernel/time.c                         |   2 +
 arch/um/kernel/um_arch.c                      |  16 +
 arch/um/kernel/uml.lds.S                      | 115 -----
 arch/um/{os-Linux => kernel}/user_syms.c      |   0
 arch/um/kernel/vmlinux.lds.S                  |  92 +++-
 arch/um/lkl/Makefile                          |   2 +
 arch/um/lkl/Makefile.um                       |  18 +
 arch/um/lkl/include/asm/Kbuild                |   7 +
 arch/um/lkl/include/asm/archparam.h           |   1 +
 arch/um/lkl/include/asm/atomic.h              |  11 +
 arch/um/lkl/include/asm/atomic64.h            |  91 ++++
 arch/um/lkl/include/asm/cpu.h                 |  15 +
 arch/um/lkl/include/asm/elf.h                 |  19 +
 arch/um/lkl/include/asm/mm_context.h          |   8 +
 arch/um/lkl/include/asm/processor.h           |  48 ++
 arch/um/lkl/include/asm/ptrace.h              |  21 +
 arch/um/lkl/include/asm/sched.h               |  23 +
 arch/um/lkl/include/asm/segment.h             |   9 +
 arch/um/lkl/include/asm/syscall_wrapper.h     |  57 +++
 arch/um/lkl/include/asm/syscalls.h            |  15 +
 arch/um/lkl/include/uapi/asm/Kbuild           |   6 +
 arch/um/lkl/include/uapi/asm/bitsperlong.h    |  16 +
 arch/um/lkl/include/uapi/asm/byteorder.h      |  13 +
 arch/um/lkl/include/uapi/asm/host_ops.h       | 280 +++++++++++
 arch/um/lkl/include/uapi/asm/sigcontext.h     |  12 +
 arch/um/lkl/include/uapi/asm/syscalls.h       | 301 ++++++++++++
 arch/um/lkl/include/uapi/asm/unistd.h         |  17 +
 arch/um/lkl/um/Kconfig                        |  21 +
 arch/um/lkl/um/Makefile                       |   4 +
 arch/um/lkl/um/bootmem.c                      | 107 ++++
 arch/um/lkl/um/console.c                      |  41 ++
 arch/um/lkl/um/cpu.c                          | 269 ++++++++++
 arch/um/lkl/um/delay.c                        |  31 ++
 arch/um/lkl/um/setup.c                        | 179 +++++++
 arch/um/lkl/um/shared/sysdep/archsetjmp.h     |  13 +
 arch/um/lkl/um/shared/sysdep/faultinfo.h      |   8 +
 arch/um/lkl/um/shared/sysdep/kernel-offsets.h |  12 +
 arch/um/lkl/um/shared/sysdep/mcontext.h       |   9 +
 arch/um/lkl/um/shared/sysdep/ptrace.h         |  42 ++
 arch/um/lkl/um/shared/sysdep/ptrace_user.h    |   7 +
 arch/um/lkl/um/syscalls.c                     | 193 ++++++++
 arch/um/lkl/um/threads.c                      | 261 ++++++++++
 arch/um/lkl/um/unimplemented.c                |  70 +++
 arch/um/lkl/um/user_constants.h               |  13 +
 arch/um/os-Linux/Makefile                     |  21 -
 arch/um/os-Linux/drivers/Makefile             |  13 -
 arch/um/scripts/headers_install.py            | 200 ++++++++
 arch/x86/um/Makefile                          |   2 +-
 arch/x86/um/os-Linux/Makefile                 |  13 -
 arch/x86/um/ptrace_32.c                       |   2 +-
 arch/x86/um/syscalls_64.c                     |   2 +-
 scripts/headers_install.sh                    |   6 +-
 scripts/link-vmlinux.sh                       |  42 +-
 tools/testing/selftests/Makefile              |   3 +
 tools/testing/selftests/um/Makefile           |  16 +
 tools/testing/selftests/um/boot.c             | 376 ++++++++++++++
 tools/testing/selftests/um/cla.c              | 159 ++++++
 tools/testing/selftests/um/cla.h              |  33 ++
 tools/testing/selftests/um/disk-ext4.sh       |   6 +
 tools/testing/selftests/um/disk-vfat.sh       |   6 +
 tools/testing/selftests/um/disk.c             | 166 +++++++
 tools/testing/selftests/um/disk.sh            |  67 +++
 tools/testing/selftests/um/test.c             | 128 +++++
 tools/testing/selftests/um/test.h             |  72 +++
 tools/testing/selftests/um/test.sh            | 181 +++++++
 tools/um/.gitignore                           |   1 +
 tools/um/Makefile                             |  76 +++
 tools/um/Targets                              |   9 +
 tools/um/include/lkl.h                        | 364 ++++++++++++++
 tools/um/include/lkl_host.h                   |  19 +
 tools/um/lib/Build                            |   7 +
 tools/um/lib/fs.c                             | 461 ++++++++++++++++++
 tools/um/lib/jmp_buf.c                        |  14 +
 tools/um/lib/posix-host.c                     | 273 +++++++++++
 tools/um/lib/utils.c                          | 207 ++++++++
 tools/um/uml/Build                            |  59 +++
 tools/um/uml/drivers/Build                    |  10 +
 .../um/uml}/drivers/ethertap_user.c           |   0
 .../um/uml}/drivers/tuntap_user.c             |   0
 {arch/um/os-Linux => tools/um/uml}/elf_aux.c  |   0
 {arch/um/os-Linux => tools/um/uml}/execvp.c   |   4 -
 {arch/um/os-Linux => tools/um/uml}/file.c     |   0
 {arch/um/os-Linux => tools/um/uml}/helper.c   |   0
 {arch/um/os-Linux => tools/um/uml}/irq.c      |   0
 tools/um/uml/lkl/Build                        |   1 +
 tools/um/uml/lkl/registers.c                  |  21 +
 tools/um/uml/lkl/unimplemented.c              |  21 +
 {arch/um/os-Linux => tools/um/uml}/main.c     |   0
 {arch/um/os-Linux => tools/um/uml}/mem.c      |   0
 {arch/um/os-Linux => tools/um/uml}/process.c  |   2 +
 .../um/os-Linux => tools/um/uml}/registers.c  |   0
 {arch/um/os-Linux => tools/um/uml}/sigio.c    |   0
 {arch/um/os-Linux => tools/um/uml}/signal.c   |  12 +-
 .../skas/Makefile => tools/um/uml/skas/Build  |   6 +-
 {arch/um/os-Linux => tools/um/uml}/skas/mem.c |   0
 .../os-Linux => tools/um/uml}/skas/process.c  |   3 +-
 {arch/um/os-Linux => tools/um/uml}/start_up.c |   0
 {arch/um/os-Linux => tools/um/uml}/time.c     |   0
 {arch/um/os-Linux => tools/um/uml}/tty.c      |   0
 {arch/um/os-Linux => tools/um/uml}/umid.c     |   0
 {arch/um/os-Linux => tools/um/uml}/util.c     |  26 +
 tools/um/uml/x86/Build                        |  11 +
 .../os-Linux => tools/um/uml/x86}/mcontext.c  |   0
 .../um/os-Linux => tools/um/uml/x86}/prctl.c  |   0
 .../os-Linux => tools/um/uml/x86}/registers.c |   0
 .../os-Linux => tools/um/uml/x86}/task_size.c |   0
 .../um/os-Linux => tools/um/uml/x86}/tls.c    |   0
 134 files changed, 5743 insertions(+), 525 deletions(-)
 create mode 100644 Documentation/virt/uml/lkl.txt
 create mode 100644 arch/um/configs/lkl_defconfig
 rename arch/um/{os-Linux => }/drivers/ethertap_kern.c (100%)
 rename arch/um/{os-Linux => }/drivers/tuntap_kern.c (100%)
 delete mode 100644 arch/um/include/asm/common.lds.S
 create mode 100644 arch/um/include/asm/host_ops.h
 rename arch/um/{os-Linux/drivers => include/shared}/etap.h (100%)
 rename arch/um/{os-Linux/drivers => include/shared}/tuntap.h (100%)
 delete mode 100644 arch/um/kernel/dyn.lds.S
 delete mode 100644 arch/um/kernel/uml.lds.S
 rename arch/um/{os-Linux => kernel}/user_syms.c (100%)
 create mode 100644 arch/um/lkl/Makefile
 create mode 100644 arch/um/lkl/Makefile.um
 create mode 100644 arch/um/lkl/include/asm/Kbuild
 create mode 100644 arch/um/lkl/include/asm/archparam.h
 create mode 100644 arch/um/lkl/include/asm/atomic.h
 create mode 100644 arch/um/lkl/include/asm/atomic64.h
 create mode 100644 arch/um/lkl/include/asm/cpu.h
 create mode 100644 arch/um/lkl/include/asm/elf.h
 create mode 100644 arch/um/lkl/include/asm/mm_context.h
 create mode 100644 arch/um/lkl/include/asm/processor.h
 create mode 100644 arch/um/lkl/include/asm/ptrace.h
 create mode 100644 arch/um/lkl/include/asm/sched.h
 create mode 100644 arch/um/lkl/include/asm/segment.h
 create mode 100644 arch/um/lkl/include/asm/syscall_wrapper.h
 create mode 100644 arch/um/lkl/include/asm/syscalls.h
 create mode 100644 arch/um/lkl/include/uapi/asm/Kbuild
 create mode 100644 arch/um/lkl/include/uapi/asm/bitsperlong.h
 create mode 100644 arch/um/lkl/include/uapi/asm/byteorder.h
 create mode 100644 arch/um/lkl/include/uapi/asm/host_ops.h
 create mode 100644 arch/um/lkl/include/uapi/asm/sigcontext.h
 create mode 100644 arch/um/lkl/include/uapi/asm/syscalls.h
 create mode 100644 arch/um/lkl/include/uapi/asm/unistd.h
 create mode 100644 arch/um/lkl/um/Kconfig
 create mode 100644 arch/um/lkl/um/Makefile
 create mode 100644 arch/um/lkl/um/bootmem.c
 create mode 100644 arch/um/lkl/um/console.c
 create mode 100644 arch/um/lkl/um/cpu.c
 create mode 100644 arch/um/lkl/um/delay.c
 create mode 100644 arch/um/lkl/um/setup.c
 create mode 100644 arch/um/lkl/um/shared/sysdep/archsetjmp.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/faultinfo.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/kernel-offsets.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/mcontext.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/ptrace.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/ptrace_user.h
 create mode 100644 arch/um/lkl/um/syscalls.c
 create mode 100644 arch/um/lkl/um/threads.c
 create mode 100644 arch/um/lkl/um/unimplemented.c
 create mode 100644 arch/um/lkl/um/user_constants.h
 delete mode 100644 arch/um/os-Linux/Makefile
 delete mode 100644 arch/um/os-Linux/drivers/Makefile
 create mode 100755 arch/um/scripts/headers_install.py
 delete mode 100644 arch/x86/um/os-Linux/Makefile
 create mode 100644 tools/testing/selftests/um/Makefile
 create mode 100644 tools/testing/selftests/um/boot.c
 create mode 100644 tools/testing/selftests/um/cla.c
 create mode 100644 tools/testing/selftests/um/cla.h
 create mode 100755 tools/testing/selftests/um/disk-ext4.sh
 create mode 100755 tools/testing/selftests/um/disk-vfat.sh
 create mode 100644 tools/testing/selftests/um/disk.c
 create mode 100755 tools/testing/selftests/um/disk.sh
 create mode 100644 tools/testing/selftests/um/test.c
 create mode 100644 tools/testing/selftests/um/test.h
 create mode 100644 tools/testing/selftests/um/test.sh
 create mode 100644 tools/um/.gitignore
 create mode 100644 tools/um/Makefile
 create mode 100644 tools/um/Targets
 create mode 100644 tools/um/include/lkl.h
 create mode 100644 tools/um/include/lkl_host.h
 create mode 100644 tools/um/lib/Build
 create mode 100644 tools/um/lib/fs.c
 create mode 100644 tools/um/lib/jmp_buf.c
 create mode 100644 tools/um/lib/posix-host.c
 create mode 100644 tools/um/lib/utils.c
 create mode 100644 tools/um/uml/Build
 create mode 100644 tools/um/uml/drivers/Build
 rename {arch/um/os-Linux => tools/um/uml}/drivers/ethertap_user.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/drivers/tuntap_user.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/elf_aux.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/execvp.c (98%)
 rename {arch/um/os-Linux => tools/um/uml}/file.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/helper.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/irq.c (100%)
 create mode 100644 tools/um/uml/lkl/Build
 create mode 100644 tools/um/uml/lkl/registers.c
 create mode 100644 tools/um/uml/lkl/unimplemented.c
 rename {arch/um/os-Linux => tools/um/uml}/main.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/mem.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/process.c (99%)
 rename {arch/um/os-Linux => tools/um/uml}/registers.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/sigio.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/signal.c (96%)
 rename arch/um/os-Linux/skas/Makefile => tools/um/uml/skas/Build (56%)
 rename {arch/um/os-Linux => tools/um/uml}/skas/mem.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/skas/process.c (99%)
 rename {arch/um/os-Linux => tools/um/uml}/start_up.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/time.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/tty.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/umid.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/util.c (89%)
 create mode 100644 tools/um/uml/x86/Build
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/mcontext.c (100%)
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/prctl.c (100%)
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/registers.c (100%)
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/task_size.c (100%)
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/tls.c (100%)
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#197 lore raw

RFC v8 1/20 um: split build in kernel and host parts

From: Octavian Purdila <[email protected]>

This patch splits the UML build in two parts: a kernel part that generates a relocatable object (linux.o) and a host build part that links the relocatable object into an executable.

This allows us to simplify the linker script since we can now remove the host bits (e.g. .rel sections). It also gives us greater flexibility since it will be much easier to support other architectures and OSes if we use the standard linker script.

The host build part has been implemented in tools/um so that we can reuse the available host build infrastructure.

The patch preserves the way to invoke the UML build as follows,

 $ make ARCH=um defconfig
 $ make ARCH=um

but it internally calls tools/um/Makefile in order to complete the full build to link the relocatable object and the rest of files.

This commit also relaxes the condition of UML in scripts/link-vmlinux.sh since we can postpone the link process with host libraries (-lpthread, etc) to the 2nd starge.

---
 arch/um/Kconfig                  |  12 +--
 arch/um/Makefile                 |  29 ++++--
 arch/um/include/asm/common.lds.S |  99 ------------------
 arch/um/kernel/dyn.lds.S         | 171 -------------------------------
 arch/um/kernel/uml.lds.S         | 115 ---------------------
 arch/um/kernel/vmlinux.lds.S     |  92 +++++++++++++++--
 scripts/link-vmlinux.sh          |  42 +++-----
 tools/um/Makefile                |  74 +++++++++++++
 tools/um/Targets                 |   4 +
 tools/um/uml/Build               |   0
 10 files changed, 200 insertions(+), 438 deletions(-)
 delete mode 100644 arch/um/include/asm/common.lds.S
 delete mode 100644 arch/um/kernel/dyn.lds.S
 delete mode 100644 arch/um/kernel/uml.lds.S
 create mode 100644 tools/um/Makefile
 create mode 100644 tools/um/Targets
 create mode 100644 tools/um/uml/Build
arch/um/Kconfig +1 -11
index 34d302d1a07f..9e2d9efbcdd1 100644
@@ -21,6 +21,7 @@ config UML
 	select HAVE_GCC_PLUGINS
 	select SET_FS
 	select TTY # Needed for line.c
+	select MODULE_REL_CRCS if MODVERSIONS
 
 config MMU
 	bool
@@ -80,17 +81,6 @@ config STATIC_LINK
 	  NOTE: This option is incompatible with some networking features which
 	  depend on features that require being dynamically loaded (like NSS).
 
-config LD_SCRIPT_STATIC
-	bool
-	default y
-	depends on STATIC_LINK
-
-config LD_SCRIPT_DYN
-	bool
-	default y
-	depends on !LD_SCRIPT_STATIC
-	select MODULE_REL_CRCS if MODVERSIONS
-
 config HOSTFS
 	tristate "Host filesystem"
 	help
arch/um/Makefile +23 -6
index 1cea46ff9bb7..48fbbc3a0032 100644
@@ -95,14 +95,30 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include \
 KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
 			 -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES))
 KBUILD_CFLAGS += $(KERNEL_DEFINES)
+LDFLAGS_vmlinux += -r
 
-PHONY += linux
-
+INSTALL_PATH=$(objtree)/tools/um
 all: linux
-
-linux: vmlinux
-	@echo '  LINK $@'
-	$(Q)ln -f $< $@
+pre-2nd: linux.o
+	@echo "  INSTALL $(INSTALL_PATH)/lib/$<"
+	@mkdir -p $(INSTALL_PATH)/lib/
+	@cp $< $(INSTALL_PATH)/lib/
+
+PHONY += linux.o
+
+linux: pre-2nd
+	$(Q)$(MAKE) -C $(srctree)/tools/um
+	$(Q)cp $(objtree)/tools/um/uml/linux $(objtree)/
+	$(Q)cp $(objtree)/linux $(objtree)/vmlinux
+
+linux.o: vmlinux
+#revert vmlinux file from vmlinux.a
+ifneq ("$(wildcard vmlinux.a)","")
+	$(Q)cp vmlinux.a vmlinux
+endif
+	$(Q)cp vmlinux vmlinux.a
+	@echo "  LINK    $@"
+	$(Q)$(OBJCOPY) -R .eh_frame $< $@
 
 define archhelp
   echo '* linux		- Binary kernel image (./linux) - for backward'
@@ -144,5 +160,6 @@ MRPROPER_FILES += arch/$(SUBARCH)/include/generated
 archclean:
 	@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
 		-o -name '*.gcov' \) -type f -print | xargs rm -f
+	$(Q)$(MAKE) -C $(srctree)/tools/um clean
 
 export HEADER_ARCH SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS DEV_NULL_PATH
arch/um/include/asm/common.lds.S deleted +0 -99

99 lines not on this page · raw message

arch/um/kernel/dyn.lds.S deleted +0 -171

171 lines not on this page · raw message

arch/um/kernel/uml.lds.S deleted +0 -115

115 lines not on this page · raw message

arch/um/kernel/vmlinux.lds.S +86 -6

94 lines not on this page · raw message

scripts/link-vmlinux.sh +12 -30

48 lines not on this page · raw message

tools/um/Makefile new file +74 -0

74 lines not on this page · raw message

tools/um/Targets new file +4 -0
new file mode 100644
index 000000000000..cfe1d3c3c6ff
@@ -0,0 +1,4 @@
+progs-y += uml/linux
+LDLIBS_linux-y := -lrt -lpthread -lutil
+LDFLAGS_linux-y := -no-pie -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+LDFLAGS_linux-$(CONFIG_STATIC_LINK) += -static
tools/um/uml/Build new file +0 -0
new file mode 100644
index 000000000000..e69de29bb2d1
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#198 lore raw

RFC v8 2/20 um: move arch/um/os-Linux dir to tools/um/uml

In reply to Hajime Tazaki

This patch moves underlying OS dependent part under arch/um to tools/um directory so that arch/um code does not need to build host build facilities (e.g., libc).

---
 arch/um/Makefile                              |  3 +-
 arch/um/drivers/Makefile                      |  2 +
 .../um/{os-Linux => }/drivers/ethertap_kern.c |  0
 arch/um/{os-Linux => }/drivers/tuntap_kern.c  |  0
 .../drivers => include/shared}/etap.h         |  0
 arch/um/include/shared/init.h                 |  5 ++
 .../drivers => include/shared}/tuntap.h       |  0
 arch/um/kernel/Makefile                       |  1 +
 arch/um/{os-Linux => kernel}/user_syms.c      |  0
 arch/um/os-Linux/Makefile                     | 21 --------
 arch/um/os-Linux/drivers/Makefile             | 13 -----
 tools/um/Makefile                             |  4 +-
 tools/um/uml/Build                            | 50 +++++++++++++++++++
 tools/um/uml/drivers/Build                    | 10 ++++
 .../um/uml}/drivers/ethertap_user.c           |  0
 .../um/uml}/drivers/tuntap_user.c             |  0
 {arch/um/os-Linux => tools/um/uml}/elf_aux.c  |  0
 {arch/um/os-Linux => tools/um/uml}/execvp.c   |  4 --
 {arch/um/os-Linux => tools/um/uml}/file.c     |  0
 {arch/um/os-Linux => tools/um/uml}/helper.c   |  0
 {arch/um/os-Linux => tools/um/uml}/irq.c      |  0
 {arch/um/os-Linux => tools/um/uml}/main.c     |  0
 {arch/um/os-Linux => tools/um/uml}/mem.c      |  0
 {arch/um/os-Linux => tools/um/uml}/process.c  |  0
 .../um/os-Linux => tools/um/uml}/registers.c  |  0
 {arch/um/os-Linux => tools/um/uml}/sigio.c    |  0
 {arch/um/os-Linux => tools/um/uml}/signal.c   |  0
 .../skas/Makefile => tools/um/uml/skas/Build  |  6 +--
 {arch/um/os-Linux => tools/um/uml}/skas/mem.c |  0
 .../os-Linux => tools/um/uml}/skas/process.c  |  3 +-
 {arch/um/os-Linux => tools/um/uml}/start_up.c |  0
 {arch/um/os-Linux => tools/um/uml}/time.c     |  0
 {arch/um/os-Linux => tools/um/uml}/tty.c      |  0
 {arch/um/os-Linux => tools/um/uml}/umid.c     |  0
 {arch/um/os-Linux => tools/um/uml}/util.c     |  0
 35 files changed, 73 insertions(+), 49 deletions(-)
 rename arch/um/{os-Linux => }/drivers/ethertap_kern.c (100%)
 rename arch/um/{os-Linux => }/drivers/tuntap_kern.c (100%)
 rename arch/um/{os-Linux/drivers => include/shared}/etap.h (100%)
 rename arch/um/{os-Linux/drivers => include/shared}/tuntap.h (100%)
 rename arch/um/{os-Linux => kernel}/user_syms.c (100%)
 delete mode 100644 arch/um/os-Linux/Makefile
 delete mode 100644 arch/um/os-Linux/drivers/Makefile
 create mode 100644 tools/um/uml/drivers/Build
 rename {arch/um/os-Linux => tools/um/uml}/drivers/ethertap_user.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/drivers/tuntap_user.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/elf_aux.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/execvp.c (98%)
 rename {arch/um/os-Linux => tools/um/uml}/file.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/helper.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/irq.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/main.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/mem.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/process.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/registers.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/sigio.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/signal.c (100%)
 rename arch/um/os-Linux/skas/Makefile => tools/um/uml/skas/Build (56%)
 rename {arch/um/os-Linux => tools/um/uml}/skas/mem.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/skas/process.c (99%)
 rename {arch/um/os-Linux => tools/um/uml}/start_up.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/time.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/tty.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/umid.c (100%)
 rename {arch/um/os-Linux => tools/um/uml}/util.c (100%)
arch/um/Makefile +1 -2
index 48fbbc3a0032..bce0cccae085 100644
@@ -24,8 +24,7 @@ OS := $(shell uname -s)
 SHELL := /bin/bash
 
 core-y			+= $(ARCH_DIR)/kernel/		\
-			   $(ARCH_DIR)/drivers/		\
-			   $(ARCH_DIR)/os-$(OS)/
+			   $(ARCH_DIR)/drivers/
 
 MODE_INCLUDE	+= -I$(srctree)/$(ARCH_DIR)/include/shared/skas
 
arch/um/drivers/Makefile +2 -0
index 2a249f619467..ae96c83e312d 100644
@@ -48,6 +48,8 @@ obj-$(CONFIG_UML_NET_VECTOR) += vector.o
 obj-$(CONFIG_UML_NET_VDE) += vde.o
 obj-$(CONFIG_UML_NET_MCAST) += umcast.o
 obj-$(CONFIG_UML_NET_PCAP) += pcap.o
+obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap_kern.o
+obj-$(CONFIG_UML_NET_TUNTAP) += tuntap_kern.o
 obj-$(CONFIG_UML_NET) += net.o 
 obj-$(CONFIG_MCONSOLE) += mconsole.o
 obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
arch/um/drivers/ethertap_kern.c renamed from arch/um/os-Linux/drivers/ethertap_kern.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/drivers/ethertap_kern.c
rename to arch/um/drivers/ethertap_kern.c
arch/um/drivers/tuntap_kern.c renamed from arch/um/os-Linux/drivers/tuntap_kern.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/drivers/tuntap_kern.c
rename to arch/um/drivers/tuntap_kern.c
arch/um/include/shared/etap.h renamed from arch/um/os-Linux/drivers/etap.h +0 -0
similarity index 100%
rename from arch/um/os-Linux/drivers/etap.h
rename to arch/um/include/shared/etap.h
arch/um/include/shared/init.h +5 -0
index 1a659e2e8cc3..fa2d3138d497 100644
@@ -41,7 +41,12 @@
 typedef int (*initcall_t)(void);
 typedef void (*exitcall_t)(void);
 
+#ifndef __UM_HOST__
 #include <linux/compiler_types.h>
+#else
+#define __used                          __attribute__((__used__))
+#define __section(S)                    __attribute__((__section__(#S)))
+#endif
 
 /* These are for everybody (although not all archs will actually
    discard it in modules) */
arch/um/include/shared/tuntap.h renamed from arch/um/os-Linux/drivers/tuntap.h +0 -0
similarity index 100%
rename from arch/um/os-Linux/drivers/tuntap.h
rename to arch/um/include/shared/tuntap.h
arch/um/kernel/Makefile +1 -0
index 5aa882011e04..9b63831a69e1 100644
@@ -24,6 +24,7 @@ obj-$(CONFIG_GPROF)	+= gprof_syms.o
 obj-$(CONFIG_GCOV)	+= gmon_syms.o
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-y += user_syms.o
 
 USER_OBJS := config.o
 
arch/um/kernel/user_syms.c renamed from arch/um/os-Linux/user_syms.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/user_syms.c
rename to arch/um/kernel/user_syms.c
arch/um/os-Linux/Makefile deleted +0 -21
deleted file mode 100644
index 77ac50baa3f8..000000000000
@@ -1,21 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# 
-# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
-#
-
-# Don't instrument UML-specific code
-KCOV_INSTRUMENT                := n
-
-obj-y = execvp.o file.o helper.o irq.o main.o mem.o process.o \
-	registers.o sigio.o signal.o start_up.o time.o tty.o \
-	umid.o user_syms.o util.o drivers/ skas/
-
-CFLAGS_signal.o += -Wframe-larger-than=4096
-
-obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
-
-USER_OBJS := $(user-objs-y) elf_aux.o execvp.o file.o helper.o irq.o \
-	main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
-	tty.o umid.o util.o
-
-include arch/um/scripts/Makefile.rules
arch/um/os-Linux/drivers/Makefile deleted +0 -13
deleted file mode 100644
index d79e75f1b69a..000000000000
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# 
-# Copyright (C) 2000, 2002 Jeff Dike ([email protected])
-#
-
-ethertap-objs := ethertap_kern.o ethertap_user.o
-tuntap-objs := tuntap_kern.o tuntap_user.o
-
-obj-y = 
-obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
-obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
-
-include arch/um/scripts/Makefile.rules
tools/um/Makefile +2 -2
index 2b4e6b63355b..0fdf77261e74 100644
@@ -50,7 +50,7 @@ $(objtree)/linux.o:
 $(OUTPUT)lib/linux.o: $(objtree)/linux.o
 	$(Q)cp $(objtree)/linux.o $(OUTPUT)lib/linux.o
 
-$(OUTPUT)liblinux.a: $(OUTPUT)lib/linux.o $(OUTPUT)uml/liblinux-in.o
+$(OUTPUT)liblinux.a: $(OUTPUT)lib/linux.o $(OUTPUT)uml/liblinux-in.o $(OUTPUT)lib/liblinux-in.o
 	$(QUIET_AR)$(AR) -rc $@ $^
 
 # rule to link programs
@@ -58,7 +58,7 @@ $(OUTPUT)%: $(OUTPUT)%-in.o $(OUTPUT)liblinux.a
 	$(QUIET_LINK)$(CC) $(LDFLAGS) $(LDFLAGS_$(notdir $*)-y) -o $@ $^ $(LDLIBS) $(LDLIBS_$(notdir $*)-y)
 
 # rule to build objects
-$(OUTPUT)%-in.o: FORCE
+$(OUTPUT)%-in.o: $(OUTPUT)lib/linux.o FORCE
 	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(patsubst %/,%,$(dir $*)) obj=$(notdir $*)
 
 RM := rm -f
tools/um/uml/Build +50 -0

50 lines not on this page · raw message

tools/um/uml/drivers/Build new file +10 -0
new file mode 100644
index 000000000000..c7a8eaa97d72
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2000, 2002 Jeff Dike ([email protected])
+#
+
+include $(objtree)/include/config/auto.conf
+
+
+liblinux-$(CONFIG_UML_NET_ETHERTAP) += ethertap_user.o
+liblinux-$(CONFIG_UML_NET_TUNTAP) += tuntap_user.o
tools/um/uml/drivers/ethertap_user.c renamed from arch/um/os-Linux/drivers/ethertap_user.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/drivers/ethertap_user.c
rename to tools/um/uml/drivers/ethertap_user.c
tools/um/uml/drivers/tuntap_user.c renamed from arch/um/os-Linux/drivers/tuntap_user.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/drivers/tuntap_user.c
rename to tools/um/uml/drivers/tuntap_user.c
tools/um/uml/elf_aux.c renamed from arch/um/os-Linux/elf_aux.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/elf_aux.c
rename to tools/um/uml/elf_aux.c
tools/um/uml/execvp.c renamed from arch/um/os-Linux/execvp.c +0 -4
similarity index 98%
rename from arch/um/os-Linux/execvp.c
rename to tools/um/uml/execvp.c
index 84a0777c2a45..c105e0e7b778 100644
@@ -26,12 +26,8 @@
 #include <errno.h>
 #include <limits.h>
 
-#ifndef TEST
-#include <um_malloc.h>
-#else
 #include <stdio.h>
 #define um_kmalloc malloc
-#endif
 #include <os.h>
 
 /* Execute FILE, searching in the `PATH' environment variable if it contains
tools/um/uml/file.c renamed from arch/um/os-Linux/file.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/file.c
rename to tools/um/uml/file.c
tools/um/uml/helper.c renamed from arch/um/os-Linux/helper.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/helper.c
rename to tools/um/uml/helper.c
tools/um/uml/irq.c renamed from arch/um/os-Linux/irq.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/irq.c
rename to tools/um/uml/irq.c
tools/um/uml/main.c renamed from arch/um/os-Linux/main.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/main.c
rename to tools/um/uml/main.c
tools/um/uml/mem.c renamed from arch/um/os-Linux/mem.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/mem.c
rename to tools/um/uml/mem.c
tools/um/uml/process.c renamed from arch/um/os-Linux/process.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/process.c
rename to tools/um/uml/process.c
tools/um/uml/registers.c renamed from arch/um/os-Linux/registers.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/registers.c
rename to tools/um/uml/registers.c
tools/um/uml/sigio.c renamed from arch/um/os-Linux/sigio.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/sigio.c
rename to tools/um/uml/sigio.c
tools/um/uml/signal.c renamed from arch/um/os-Linux/signal.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/signal.c
rename to tools/um/uml/signal.c
tools/um/uml/skas/Build renamed from arch/um/os-Linux/skas/Makefile +1 -5
similarity index 56%
rename from arch/um/os-Linux/skas/Makefile
rename to tools/um/uml/skas/Build
index c4566e788815..5fc9d62df863 100644
@@ -3,8 +3,4 @@
 # Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
 #
 
-obj-y := mem.o process.o
-
-USER_OBJS := $(obj-y)
-
-include arch/um/scripts/Makefile.rules
+liblinux-y += mem.o process.o
tools/um/uml/skas/mem.c renamed from arch/um/os-Linux/skas/mem.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/skas/mem.c
rename to tools/um/uml/skas/mem.c
tools/um/uml/skas/process.c renamed from arch/um/os-Linux/skas/process.c +1 -2
similarity index 99%
rename from arch/um/os-Linux/skas/process.c
rename to tools/um/uml/skas/process.c
index 0621d521208e..0af44c2857b8 100644
@@ -21,7 +21,6 @@
 #include <registers.h>
 #include <skas.h>
 #include <sysdep/stub.h>
-#include <linux/threads.h>
 
 int is_skas_winch(int pid, int fd, void *data)
 {
@@ -248,7 +247,7 @@ static int userspace_tramp(void *stack)
 	return 0;
 }
 
-int userspace_pid[NR_CPUS];
+int userspace_pid[UM_NR_CPUS];
 
 /**
  * start_userspace() - prepare a new userspace process
tools/um/uml/start_up.c renamed from arch/um/os-Linux/start_up.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/start_up.c
rename to tools/um/uml/start_up.c
tools/um/uml/time.c renamed from arch/um/os-Linux/time.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/time.c
rename to tools/um/uml/time.c
tools/um/uml/tty.c renamed from arch/um/os-Linux/tty.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/tty.c
rename to tools/um/uml/tty.c
tools/um/uml/umid.c renamed from arch/um/os-Linux/umid.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/umid.c
rename to tools/um/uml/umid.c
tools/um/uml/util.c renamed from arch/um/os-Linux/util.c +0 -0
similarity index 100%
rename from arch/um/os-Linux/util.c
rename to tools/um/uml/util.c
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#199 lore raw

RFC v8 3/20 um: move arch/x86/um/os-Linux to tools/um/uml/

In reply to Hajime Tazaki

Similar to arch/um/os-Linux code, arch/x86 also contains OS dependent part as well. This patch moves underlying OS dependent part to tools/um directory so that arch/x86 code does not need to build host build facilities (e.g., libc).

---
 arch/x86/um/Makefile                                |  2 +-
 arch/x86/um/os-Linux/Makefile                       | 13 -------------
 tools/um/uml/Build                                  |  1 +
 tools/um/uml/x86/Build                              | 11 +++++++++++
 .../x86/um/os-Linux => tools/um/uml/x86}/mcontext.c |  0
 {arch/x86/um/os-Linux => tools/um/uml/x86}/prctl.c  |  0
 .../um/os-Linux => tools/um/uml/x86}/registers.c    |  0
 .../um/os-Linux => tools/um/uml/x86}/task_size.c    |  0
 {arch/x86/um/os-Linux => tools/um/uml/x86}/tls.c    |  0
 9 files changed, 13 insertions(+), 14 deletions(-)
 delete mode 100644 arch/x86/um/os-Linux/Makefile
 create mode 100644 tools/um/uml/x86/Build
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/mcontext.c (100%)
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/prctl.c (100%)
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/registers.c (100%)
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/task_size.c (100%)
 rename {arch/x86/um/os-Linux => tools/um/uml/x86}/tls.c (100%)
arch/x86/um/Makefile +1 -1
index 77f70b969d14..25e9846b36a2 100644
@@ -13,7 +13,7 @@ obj-y = bugs_$(BITS).o delay.o fault.o ldt.o \
 	ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \
 	stub_$(BITS).o stub_segv.o \
 	sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \
-	mem_$(BITS).o subarch.o os-$(OS)/
+	mem_$(BITS).o subarch.o
 
 ifeq ($(CONFIG_X86_32),y)
 
arch/x86/um/os-Linux/Makefile deleted +0 -13
deleted file mode 100644
index 253bfb8cb702..000000000000
@@ -1,13 +0,0 @@
-#
-# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
-# Licensed under the GPL
-#
-
-obj-y = registers.o task_size.o mcontext.o
-
-obj-$(CONFIG_X86_32) += tls.o
-obj-$(CONFIG_64BIT) += prctl.o
-
-USER_OBJS := $(obj-y)
-
-include arch/um/scripts/Makefile.rules
tools/um/uml/Build +1 -0
index 0e629c9cb8eb..810aa99f8409 100644
@@ -14,6 +14,7 @@ liblinux-y += execvp.o file.o helper.o irq.o main.o mem.o process.o \
 
 CFLAGS_signal.o += -Wframe-larger-than=4096
 
+liblinux-y += x86/
 liblinux-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
 
 export O = $(srctree)
tools/um/uml/x86/Build new file +11 -0
new file mode 100644
index 000000000000..16bbc7eb19d1
@@ -0,0 +1,11 @@
+#
+# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+# Licensed under the GPL
+#
+
+include $(objtree)/include/config/auto.conf
+
+liblinux-y = registers.o task_size.o mcontext.o
+
+liblinux-$(CONFIG_X86_32) += tls.o
+liblinux-$(CONFIG_64BIT) += prctl.o
tools/um/uml/x86/mcontext.c renamed from arch/x86/um/os-Linux/mcontext.c +0 -0
similarity index 100%
rename from arch/x86/um/os-Linux/mcontext.c
rename to tools/um/uml/x86/mcontext.c
tools/um/uml/x86/prctl.c renamed from arch/x86/um/os-Linux/prctl.c +0 -0
similarity index 100%
rename from arch/x86/um/os-Linux/prctl.c
rename to tools/um/uml/x86/prctl.c
tools/um/uml/x86/registers.c renamed from arch/x86/um/os-Linux/registers.c +0 -0
similarity index 100%
rename from arch/x86/um/os-Linux/registers.c
rename to tools/um/uml/x86/registers.c
tools/um/uml/x86/task_size.c renamed from arch/x86/um/os-Linux/task_size.c +0 -0
similarity index 100%
rename from arch/x86/um/os-Linux/task_size.c
rename to tools/um/uml/x86/task_size.c
tools/um/uml/x86/tls.c renamed from arch/x86/um/os-Linux/tls.c +0 -0
similarity index 100%
rename from arch/x86/um/os-Linux/tls.c
rename to tools/um/uml/x86/tls.c
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#200 lore raw

RFC v8 4/20 um: implement os_initcalls and os_exitcalls

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This patch implements the init and exit calls for host code. It uses the automatic __start_<section> and __stop_<section> variables that are defined by gcc / ld when using custom sections.

Note that this patch should be merged with "um: move arch/um/os-Linux dir to tools/um" but for now it is separate to make the review easier.

---
 arch/um/include/shared/init.h | 14 ++++----------
 arch/um/kernel/reboot.c       |  5 +++++
 arch/um/kernel/um_arch.c      | 11 +++++++++++
 tools/um/uml/util.c           | 26 ++++++++++++++++++++++++++
 4 files changed, 46 insertions(+), 10 deletions(-)
arch/um/include/shared/init.h +4 -10
index fa2d3138d497..0d6de61c0f37 100644
@@ -114,19 +114,13 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
 
 #ifdef __UM_HOST__
 
-#define __define_initcall(level,fn) \
-	static initcall_t __initcall_##fn __used \
-	__attribute__((__section__(".initcall" level ".init"))) = fn
-
-/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll
- * make them run first.
- */
-#define __initcall(fn) __define_initcall("1", fn)
+#undef __uml_exit_call
+#define __uml_exit_call		__used __section(os_exitcalls)
+#define __init_call		__used __section(os_initcalls)
 
+#define __initcall(fn) static initcall_t __initcall_##fn __init_call = fn
 #define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
 
-#define __init_call	__used __section(".initcall.init")
-
 #endif
 
 #endif /* _LINUX_UML_INIT_H */
arch/um/kernel/reboot.c +5 -0
index 48c0610d506e..5420aec411f4 100644
@@ -35,10 +35,15 @@ static void kill_off_processes(void)
 	read_unlock(&tasklist_lock);
 }
 
+void __weak os_exitcalls(void)
+{
+}
+
 void uml_cleanup(void)
 {
 	kmalloc_ok = 0;
 	do_uml_exitcalls();
+	os_exitcalls();
 	kill_off_processes();
 }
 
arch/um/kernel/um_arch.c +11 -0
index 31d356b1ffd8..dfc6194b5ac7 100644
@@ -444,3 +444,14 @@ static int init_pm_wake_signal(void)
 
 late_initcall(init_pm_wake_signal);
 #endif
+
+int __weak os_initcalls(void)
+{
+	return 0;
+}
+
+int __init run_os_initcalls(void)
+{
+	return os_initcalls();
+}
+early_initcall(run_os_initcalls);
tools/um/uml/util.c +26 -0
index 07327425d06e..8a3382c47f98 100644
@@ -186,3 +186,29 @@ void os_warn(const char *fmt, ...)
 	vfprintf(stderr, fmt, list);
 	va_end(list);
 }
+
+extern void (*__start_os_exitcalls)(void);
+extern void (*__stop_os_exitcalls)(void);
+
+void os_exitcalls(void)
+{
+	exitcall_t *call;
+
+	call = &__stop_os_exitcalls;
+	while (--call >= &__start_os_exitcalls && (*call))
+		(*call)();
+}
+
+extern int (*__start_os_initcalls)(void);
+extern int (*__stop_os_initcalls)(void);
+
+int os_initcalls(void)
+{
+	initcall_t *call;
+
+	call = &__stop_os_initcalls;
+	while (--call >= &__start_os_initcalls && (*call))
+		(*call)();
+
+	return 0;
+}
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#201 lore raw

RFC v8 5/20 um: extend arch_switch_to for alternate SUBARCH

In reply to Hajime Tazaki

This commit introduces additional argument of previous task when context switch happens. New SUBARCH can use the new information to switch tasks in a subarch-specific manner.

The patch is particularly required by library mode, implemented as a SUBARCH of UML. Having access to the previous thread will be required in the library mode for it to implement thread switching correctly.

---
 arch/um/kernel/process.c  | 6 +++---
 arch/x86/um/ptrace_32.c   | 2 +-
 arch/x86/um/syscalls_64.c | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)
arch/um/kernel/process.c +3 -3
index 2a986ece5478..9b0a36f64339 100644
@@ -83,7 +83,7 @@ static inline void set_current(struct task_struct *task)
 		{ external_pid(), task });
 }
 
-extern void arch_switch_to(struct task_struct *to);
+extern void arch_switch_to(struct task_struct *from, struct task_struct *to);
 
 void *__switch_to(struct task_struct *from, struct task_struct *to)
 {
@@ -91,7 +91,7 @@ void *__switch_to(struct task_struct *from, struct task_struct *to)
 	set_current(to);
 
 	switch_threads(&from->thread.switch_buf, &to->thread.switch_buf);
-	arch_switch_to(current);
+	arch_switch_to(from, to);
 
 	return current->thread.prev_sched;
 }
@@ -149,7 +149,7 @@ void fork_handler(void)
 	 * arch_switch_to isn't needed. We could want to apply this to
 	 * improve performance. -bb
 	 */
-	arch_switch_to(current);
+	arch_switch_to(NULL, current);
 
 	current->thread.prev_sched = NULL;
 
arch/x86/um/ptrace_32.c +1 -1
index 2497bac56066..0f184710d4ca 100644
@@ -11,7 +11,7 @@
 
 extern int arch_switch_tls(struct task_struct *to);
 
-void arch_switch_to(struct task_struct *to)
+void arch_switch_to(struct task_struct *from, struct task_struct *to)
 {
 	int err = arch_switch_tls(to);
 	if (!err)
arch/x86/um/syscalls_64.c +1 -1
index 58f51667e2e4..2ef9474d2bd2 100644
@@ -80,7 +80,7 @@ SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 	return arch_prctl(current, option, (unsigned long __user *) arg2);
 }
 
-void arch_switch_to(struct task_struct *to)
+void arch_switch_to(struct task_struct *from, struct task_struct *to)
 {
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
 		return;
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#202 lore raw

RFC v8 6/20 um: add UML library mode

In reply to Hajime Tazaki

This patch introduces the library mode with UML code so that applications can link the Linux kernel code as a reusable library.

The library mode is implemented as SUBARCH of arch/um, which places at arch/um/lkl. This SUBARCH defines mode-specific code of memory management as well as thread implementation, along with the uapi headers to be exported to users.

The headers we introduce in this patch are simple wrappers to the asm-generic headers or stubs for things we don't support, such as ptrace, DMA, signals, ELF handling and low level processor operations.

library mode shares most of arch/um code (irq, thread_info, process scheduling) but implements its own facilities, which are memory management (nommu), thread primitives (struct arch_thread), system call interface, and console.

The outlook of updated directory structure is as follows:

arch/um

   |-- configs         (untouched)
   |-- drivers         unuse stdio_console.c for !MMU
   |-- include
   |   |-- asm         updated with !CONFIG_MMU
   |   |-- linux       (untouched)
   |   `-- shared      updated with new functions
   |       `-- skas    (untouched)
   |   `-- uapi        added for upai header installation
   |-- kernel          updated to integrate with !MMU
   |   `-- skas        (untouched, don't use for !MMU)
   |-- lkl             SUBARCH dir (internally =um/lkl)
   |   |-- include
   |   |   |-- asm     headers for subarch specific info
   |   |   `-- uapi    headers for user-visible APIs
   |   `-- um
   |       `-- shared  headers for subarch specific info

`-- scripts added a script for header installation

---
 arch/um/Kconfig                               | 20 +++-
 arch/um/lkl/Makefile                          |  2 +
 arch/um/lkl/Makefile.um                       |  2 +
 arch/um/lkl/include/asm/Kbuild                |  7 ++
 arch/um/lkl/include/asm/archparam.h           |  1 +
 arch/um/lkl/include/asm/atomic.h              | 11 +++
 arch/um/lkl/include/asm/atomic64.h            | 91 +++++++++++++++++++
 arch/um/lkl/include/asm/elf.h                 | 19 ++++
 arch/um/lkl/include/asm/mm_context.h          |  8 ++
 arch/um/lkl/include/asm/processor.h           | 48 ++++++++++
 arch/um/lkl/include/asm/ptrace.h              | 21 +++++
 arch/um/lkl/include/asm/segment.h             |  9 ++
 arch/um/lkl/include/uapi/asm/bitsperlong.h    | 13 +++
 arch/um/lkl/include/uapi/asm/byteorder.h      | 11 +++
 arch/um/lkl/include/uapi/asm/sigcontext.h     | 12 +++
 arch/um/lkl/um/Kconfig                        | 21 +++++
 arch/um/lkl/um/delay.c                        | 31 +++++++
 arch/um/lkl/um/shared/sysdep/archsetjmp.h     | 13 +++
 arch/um/lkl/um/shared/sysdep/faultinfo.h      |  8 ++
 arch/um/lkl/um/shared/sysdep/kernel-offsets.h | 12 +++
 arch/um/lkl/um/shared/sysdep/mcontext.h       |  9 ++
 arch/um/lkl/um/shared/sysdep/ptrace.h         | 42 +++++++++
 arch/um/lkl/um/shared/sysdep/ptrace_user.h    |  7 ++
 arch/um/lkl/um/unimplemented.c                | 70 ++++++++++++++
 arch/um/lkl/um/user_constants.h               | 13 +++
 25 files changed, 498 insertions(+), 3 deletions(-)
 create mode 100644 arch/um/lkl/Makefile
 create mode 100644 arch/um/lkl/Makefile.um
 create mode 100644 arch/um/lkl/include/asm/Kbuild
 create mode 100644 arch/um/lkl/include/asm/archparam.h
 create mode 100644 arch/um/lkl/include/asm/atomic.h
 create mode 100644 arch/um/lkl/include/asm/atomic64.h
 create mode 100644 arch/um/lkl/include/asm/elf.h
 create mode 100644 arch/um/lkl/include/asm/mm_context.h
 create mode 100644 arch/um/lkl/include/asm/processor.h
 create mode 100644 arch/um/lkl/include/asm/ptrace.h
 create mode 100644 arch/um/lkl/include/asm/segment.h
 create mode 100644 arch/um/lkl/include/uapi/asm/bitsperlong.h
 create mode 100644 arch/um/lkl/include/uapi/asm/byteorder.h
 create mode 100644 arch/um/lkl/include/uapi/asm/sigcontext.h
 create mode 100644 arch/um/lkl/um/Kconfig
 create mode 100644 arch/um/lkl/um/delay.c
 create mode 100644 arch/um/lkl/um/shared/sysdep/archsetjmp.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/faultinfo.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/kernel-offsets.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/mcontext.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/ptrace.h
 create mode 100644 arch/um/lkl/um/shared/sysdep/ptrace_user.h
 create mode 100644 arch/um/lkl/um/unimplemented.c
 create mode 100644 arch/um/lkl/um/user_constants.h
arch/um/Kconfig +17 -3
index 9e2d9efbcdd1..53c7919ec5b7 100644
@@ -23,9 +23,23 @@ config UML
 	select TTY # Needed for line.c
 	select MODULE_REL_CRCS if MODVERSIONS
 
+config UMMODE_LIB
+	bool "UML mode: library mode"
+	depends on !SMP
+	select UACCESS_MEMCPY
+	select ARCH_THREAD_STACK_ALLOCATOR
+	help
+	 This mode switches a mode to build a library of UML (Linux
+	 Kernel Library/LKL).  If this is Y, the build only generates,
+	 library files so, standalone executable of linux/vmlinux will
+	 not be created.
+
+	 For more detail about LKL, see
+	 <file:Documentation/virt/uml/lkl.txt>.
+
 config MMU
 	bool
-	default y
+	default y if !UMMODE_LIB
 
 config NO_IOMEM
 	def_bool y
@@ -46,12 +60,12 @@ config LOCKDEP_SUPPORT
 
 config STACKTRACE_SUPPORT
 	bool
-	default y
+	default y if !UMMODE_LIB
 	select STACKTRACE
 
 config GENERIC_CALIBRATE_DELAY
 	bool
-	default y
+	default y if !UMMODE_LIB
 
 config HZ
 	int
arch/um/lkl/Makefile new file +2 -0
new file mode 100644
index 000000000000..0ea94aaf5c95
@@ -0,0 +1,2 @@
+# empty file to avoid `include arch/$(SRCARCH)/Makefile` error
+# at $(srctree)/Makefile
arch/um/lkl/Makefile.um new file +2 -0
new file mode 100644
index 000000000000..7d3f590d88a2
@@ -0,0 +1,2 @@
+KBUILD_CFLAGS += -fno-builtin -fPIC
+ELF_FORMAT=$(shell $(LD) -r -print-output-format)
arch/um/lkl/include/asm/Kbuild new file +7 -0
new file mode 100644
index 000000000000..54ffd5cfa69c
@@ -0,0 +1,7 @@
+generic-y += bitsperlong.h
+generic-y += cmpxchg.h
+generic-y += local64.h
+generic-y += seccomp.h
+generic-y += string.h
+generic-y += syscall.h
+generic-y += user.h
arch/um/lkl/include/asm/archparam.h new file +1 -0
new file mode 100644
index 000000000000..ea32a7d3cf1b
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0 */
arch/um/lkl/include/asm/atomic.h new file +11 -0
new file mode 100644
index 000000000000..849148f43ef3
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_ATOMIC_H
+#define __UM_LIBMODE_ATOMIC_H
+
+#include <asm-generic/atomic.h>
+
+#ifndef CONFIG_GENERIC_ATOMIC64
+#include "atomic64.h"
+#endif /* !CONFIG_GENERIC_ATOMIC64 */
+
+#endif
arch/um/lkl/include/asm/atomic64.h new file +91 -0

91 lines not on this page · raw message

arch/um/lkl/include/asm/elf.h new file +19 -0
new file mode 100644
index 000000000000..9716174154c7
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_ELF_H
+#define __UM_LIBMODE_ELF_H
+
+/* no proper elf loader support yet */
+#define elf_check_arch(x) 0
+
+#ifdef CONFIG_64BIT
+#define ELF_CLASS ELFCLASS64
+#else
+#define ELF_CLASS ELFCLASS32
+#endif
+
+/*
+ * ELF register definitions.
+ */
+#define elf_gregset_t long
+#define elf_fpregset_t double
+#endif
arch/um/lkl/include/asm/mm_context.h new file +8 -0
new file mode 100644
index 000000000000..b76e728bacd0
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_MM_CONTEXT_H
+#define __UM_LIBMODE_MM_CONTEXT_H
+
+struct uml_arch_mm_context {
+};
+
+#endif
arch/um/lkl/include/asm/processor.h new file +48 -0

48 lines not on this page · raw message

arch/um/lkl/include/asm/ptrace.h new file +21 -0
new file mode 100644
index 000000000000..83f4e10fb677
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_PTRACE_H
+#define __UM_LIBMODE_PTRACE_H
+
+#include <linux/errno.h>
+
+static int reg_dummy __attribute__((unused));
+
+#define PT_REGS_ORIG_SYSCALL(r) (reg_dummy)
+#define PT_REGS_SYSCALL_RET(r) (reg_dummy)
+#define PT_REGS_SET_SYSCALL_RETURN(r, res) (reg_dummy = (res))
+#define REGS_SP(r) (reg_dummy)
+
+#define user_mode(regs) 0
+#define kernel_mode(regs) 1
+#define profile_pc(regs) 0
+#define user_stack_pointer(regs) 0
+
+extern void new_thread_handler(void);
+
+#endif
arch/um/lkl/include/asm/segment.h new file +9 -0
new file mode 100644
index 000000000000..1f6746866b8b
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_SEGMENT_H
+#define __UM_LIBMODE_SEGMENT_H
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#endif /* _ASM_LKL_SEGMENT_H */
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +13 -0
new file mode 100644
index 000000000000..f6657ba0ff9b
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_UAPI_BITSPERLONG_H
+#define __UM_LIBMODE_UAPI_BITSPERLONG_H
+
+#ifdef CONFIG_64BIT
+#define __BITS_PER_LONG 64
+#else
+#define __BITS_PER_LONG 32
+#endif
+
+#include <asm-generic/bitsperlong.h>
+
+#endif
arch/um/lkl/include/uapi/asm/byteorder.h new file +11 -0
new file mode 100644
index 000000000000..a4ae973f440b
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_UAPI_BYTEORDER_H
+#define __UM_LIBMODE_UAPI_BYTEORDER_H
+
+#if defined(CONFIG_BIG_ENDIAN)
+#include <linux/byteorder/big_endian.h>
+#else
+#include <linux/byteorder/little_endian.h>
+#endif
+
+#endif
arch/um/lkl/include/uapi/asm/sigcontext.h new file +12 -0
new file mode 100644
index 000000000000..9481e6e92203
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_UAPI_SIGCONTEXT_H
+#define __UM_LIBMODE_UAPI_SIGCONTEXT_H
+
+#include <asm/ptrace-generic.h>
+
+struct sigcontext {
+	struct pt_regs regs;
+	unsigned long oldmask;
+};
+
+#endif
arch/um/lkl/um/Kconfig new file +21 -0
new file mode 100644
index 000000000000..4e15bc0dd0a3
@@ -0,0 +1,21 @@
+config 64BIT
+	bool
+	default y
+
+config GENERIC_CSUM
+	def_bool y
+
+config GENERIC_ATOMIC64
+	bool
+	default y if !64BIT
+
+config SECCOMP
+	bool
+	default n
+
+config GENERIC_HWEIGHT
+	def_bool y
+
+config PRINTK_TIME
+	bool
+	default y
arch/um/lkl/um/delay.c new file +31 -0
new file mode 100644
index 000000000000..58a366d9b5f0
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <os.h>
+
+void __ndelay(unsigned long nsecs)
+{
+	long long start = os_nsecs();
+
+	while (os_nsecs() < start + nsecs)
+		;
+}
+
+void __udelay(unsigned long usecs)
+{
+	__ndelay(usecs * NSEC_PER_USEC);
+}
+
+void __const_udelay(unsigned long xloops)
+{
+	__udelay(xloops / 0x10c7ul);
+}
+
+void __delay(unsigned long loops)
+{
+	__ndelay(loops / 5);
+}
+
+void calibrate_delay(void)
+{
+}
arch/um/lkl/um/shared/sysdep/archsetjmp.h new file +13 -0
new file mode 100644
index 000000000000..4a5c10d7521b
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ARCH_UM_SETJMP_H
+#define __ARCH_UM_SETJMP_H
+
+struct __jmp_buf {
+	unsigned long __dummy;
+};
+#define JB_IP __dummy
+#define JB_SP __dummy
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* __ARCH_UM_SETJMP_H */
arch/um/lkl/um/shared/sysdep/faultinfo.h new file +8 -0
new file mode 100644
index 000000000000..49210742212d
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ARCH_UM_FAULTINFO_H
+#define __ARCH_UM_FAULTINFO_H
+
+struct faultinfo {
+};
+
+#endif /* __ARCH_UM_FAULTINFO_H */
arch/um/lkl/um/shared/sysdep/kernel-offsets.h new file +12 -0
new file mode 100644
index 000000000000..a004bffb7b8d
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/elf.h>
+#include <linux/crypto.h>
+#include <linux/kbuild.h>
+#include <asm/mman.h>
+
+void foo(void)
+{
+#include <common-offsets.h>
+}
arch/um/lkl/um/shared/sysdep/mcontext.h new file +9 -0
new file mode 100644
index 000000000000..b734012a74da
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ARCH_UM_MCONTEXT_H
+#define __ARCH_UM_MCONTEXT_H
+
+extern void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc);
+
+#define GET_FAULTINFO_FROM_MC(fi, mc) (fi = fi)
+
+#endif /* __ARCH_UM_MCONTEXT_H */
arch/um/lkl/um/shared/sysdep/ptrace.h new file +42 -0

42 lines not on this page · raw message

arch/um/lkl/um/shared/sysdep/ptrace_user.h new file +7 -0
new file mode 100644
index 000000000000..86d5cb20fb9f
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ARCH_UM_PTRACE_USER_H
+#define __ARCH_UM_PTRACE_USER_H
+
+#define FP_SIZE 1
+
+#endif
arch/um/lkl/um/unimplemented.c new file +70 -0

70 lines not on this page · raw message

arch/um/lkl/um/user_constants.h new file +13 -0
new file mode 100644
index 000000000000..2eb692a86c9c
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_USER_CONSTANTS_H
+#define __UM_LIBMODE_USER_CONSTANTS_H
+
+/* XXX: put dummy values */
+#define UM_FRAME_SIZE 4
+#define HOST_FP_SIZE 1
+#define HOST_IP 1
+#define HOST_SP 2
+#define HOST_BP 3
+#define UM_NR_CPUS 1
+
+#endif
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#203 lore raw

Re: [RFC v8 06/20] um: add UML library mode

arch/um/lkl/include/asm/atomic.h line 9

Quoted 12 lines · Hajime Tazaki

+++ b/arch/um/lkl/include/asm/atomic.h

arch/um/lkl/include/asm/atomic.h new file +9 -0
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_ATOMIC_H
+#define __UM_LIBMODE_ATOMIC_H
+
+#include <asm-generic/atomic.h>
+
+#ifndef CONFIG_GENERIC_ATOMIC64
+#include "atomic64.h"
+#endif /* !CONFIG_GENERIC_ATOMIC64 */

That's not actually configurable, is it? When is this on or off?

arch/um/lkl/include/asm/processor.h line 32

Quoted 10 lines
arch/um/lkl/include/asm/processor.h new file +10 -0
+static inline void cpu_relax(void)
+{
+	unsigned long flags;
+
+	/* since this is usually called in a tight loop waiting for some
+	 * external condition (e.g. jiffies) lets run interrupts now to allow
+	 * the external condition to propagate
+	 */
+	local_irq_save(flags);
+	local_irq_restore(flags);

Hmm?

If interrupts are enabled, then you'll get them anyway, and if not, then this does nothing?

arch/um/lkl/include/asm/processor.h line 46

Quoted 5 lines
arch/um/lkl/include/asm/processor.h new file +5 -0
+static inline void arch_copy_thread(struct arch_thread *from,
+				    struct arch_thread *to)
+{
+	panic("unimplemented %s: fork isn't supported yet", __func__);
+}

"yet" seems kind of misleading - I mean, it really *won't* be, since that's basically what UML is, no?

I mean, in principle, nothing actually stops you from building a linux.so instead of linux binary, and having main() renamed to linux_main() so the application can start up whenever it needs to, or something like that?

Quoted 50 lines
(quoted diff) +1 -0
+#endif
arch/um/lkl/include/asm/ptrace.h new file +21 -0
new file mode 100644
index 000000000000..83f4e10fb677
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_PTRACE_H
+#define __UM_LIBMODE_PTRACE_H
+
+#include <linux/errno.h>
+
+static int reg_dummy __attribute__((unused));
+
+#define PT_REGS_ORIG_SYSCALL(r) (reg_dummy)
+#define PT_REGS_SYSCALL_RET(r) (reg_dummy)
+#define PT_REGS_SET_SYSCALL_RETURN(r, res) (reg_dummy = (res))
+#define REGS_SP(r) (reg_dummy)
+
+#define user_mode(regs) 0
+#define kernel_mode(regs) 1
+#define profile_pc(regs) 0
+#define user_stack_pointer(regs) 0
+
+extern void new_thread_handler(void);
+
+#endif
arch/um/lkl/include/asm/segment.h new file +9 -0
new file mode 100644
index 000000000000..1f6746866b8b
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_SEGMENT_H
+#define __UM_LIBMODE_SEGMENT_H
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#endif /* _ASM_LKL_SEGMENT_H */
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +1 -0
new file mode 100644
index 000000000000..f6657ba0ff9b
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */

arch/um/lkl/include/uapi/asm/bitsperlong.h line 11

Quoted 10 lines
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +10 -0
+#ifndef __UM_LIBMODE_UAPI_BITSPERLONG_H
+#define __UM_LIBMODE_UAPI_BITSPERLONG_H
+
+#ifdef CONFIG_64BIT
+#define __BITS_PER_LONG 64
+#else
+#define __BITS_PER_LONG 32
+#endif
+
+#include <asm-generic/bitsperlong.h>

First, that include does nothing. Second, the comment there says:

/*
* There seems to be no way of detecting this automatically from user
* space, so 64 bit architectures should override this in their
* bitsperlong.h. In particular, an architecture that supports
* both 32 and 64 bit user space must not rely on CONFIG_64BIT
* to decide it, but rather check a compiler provided macro. */

So you're doing exactly what it says *not* to?

In fact, that totally makes sense - I mean, this is *uapi* and applications don't have access to CONFIG_ defines etc.

Do you expose that somehow to LKL users that makes this OK-ish? But it's still very confusing, and you've not made sure the necessary header is actually included. IIUC, lkl builds a (shared?) library, so it won't really work this way?

arch/um/lkl/include/uapi/asm/bitsperlong.h line 6

Quoted 8 lines
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +7 -0
+++ b/arch/um/lkl/include/uapi/asm/byteorder.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_UAPI_BYTEORDER_H
+#define __UM_LIBMODE_UAPI_BYTEORDER_H
+
+#if defined(CONFIG_BIG_ENDIAN)
+#include <linux/byteorder/big_endian.h>

Same here.

arch/um/lkl/include/uapi/asm/bitsperlong.h line 11

Quoted 13 lines
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +12 -0
+++ b/arch/um/lkl/um/delay.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <os.h>
+
+void __ndelay(unsigned long nsecs)
+{
+	long long start = os_nsecs();
+
+	while (os_nsecs() < start + nsecs)
+		;

At least do something like cpu_relax()? Although ... you made that do nothing, so you probably want an arch-specific thing here?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#204 lore raw

Re: [RFC v8 06/20] um: add UML library mode

Quoted 16 lines · Johannes Berg

arch/um/lkl/include/asm/atomic.h line 9

Quoted 12 lines · Hajime Tazaki

+++ b/arch/um/lkl/include/asm/atomic.h

arch/um/lkl/include/asm/atomic.h new file +9 -0
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_ATOMIC_H
+#define __UM_LIBMODE_ATOMIC_H
+
+#include <asm-generic/atomic.h>
+
+#ifndef CONFIG_GENERIC_ATOMIC64
+#include "atomic64.h"
+#endif /* !CONFIG_GENERIC_ATOMIC64 */

That's not actually configurable, is it? When is this on or off?

This is off when CONFIG_64BIT is off, because in that case (!64BIT) we use generic atomic64 facility of in-kernel.

Quoted 13 lines

arch/um/lkl/include/asm/processor.h line 32

Quoted 10 lines
arch/um/lkl/include/asm/processor.h new file +10 -0
+static inline void cpu_relax(void)
+{
+	unsigned long flags;
+
+	/* since this is usually called in a tight loop waiting for some
+	 * external condition (e.g. jiffies) lets run interrupts now to allow
+	 * the external condition to propagate
+	 */
+	local_irq_save(flags);
+	local_irq_restore(flags);

Hmm?

Quoted 2 lines

If interrupts are enabled, then you'll get them anyway, and if not, then this does nothing?

You might be right; the original LKL does yield-like operation if this function is called, but this might not be the case after the integration with UML. I will investigate this and fix it.

Quoted 9 lines

arch/um/lkl/include/asm/processor.h line 46

Quoted 5 lines
arch/um/lkl/include/asm/processor.h new file +5 -0
+static inline void arch_copy_thread(struct arch_thread *from,
+				    struct arch_thread *to)
+{
+	panic("unimplemented %s: fork isn't supported yet", __func__);
+}

"yet" seems kind of misleading - I mean, it really *won't* be, since that's basically what UML is, no?

Quoted 4 lines

I mean, in principle, nothing actually stops you from building a linux.so instead of linux binary, and having main() renamed to linux_main() so the application can start up whenever it needs to, or something like that?

I commented this in the reply-thread of the [00/20] patch.

Quoted 11 lines
Quoted 11 lines
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +5 -0
new file mode 100644
index 000000000000..f6657ba0ff9b
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_UAPI_BITSPERLONG_H
+#define __UM_LIBMODE_UAPI_BITSPERLONG_H
+
+#ifdef CONFIG_64BIT
Quoted 8 lines

arch/um/lkl/include/uapi/asm/bitsperlong.h line 11

Quoted 6 lines
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +6 -0
+#define __BITS_PER_LONG 64
+#else
+#define __BITS_PER_LONG 32
+#endif
+
+#include <asm-generic/bitsperlong.h>

First, that include does nothing.

We followed the way of arch/x86 (and other archs) for this.

This actually includes include/asm-generic/bitsperlong.h, which does something I think.

Quoted 11 lines

Second, the comment there says:

/*
* There seems to be no way of detecting this automatically from user
* space, so 64 bit architectures should override this in their
* bitsperlong.h. In particular, an architecture that supports
* both 32 and 64 bit user space must not rely on CONFIG_64BIT
* to decide it, but rather check a compiler provided macro. */

Quoted 4 lines

So you're doing exactly what it says *not* to?

In fact, that totally makes sense - I mean, this is *uapi* and applications don't have access to CONFIG_ defines etc.

Sorry, this patch is wrong. There is additional diff in [10/20], which should be in the same patch here, which eliminates not to rely on CONFIG_*.

I will fix this.

Quoted 5 lines

Do you expose that somehow to LKL users that makes this OK-ish? But it's still very confusing, and you've not made sure the necessary header is actually included. IIUC, lkl builds a (shared?) library, so it won't really work this way?

Quoted 10 lines

arch/um/lkl/include/uapi/asm/bitsperlong.h line 6

Quoted 8 lines
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +7 -0
+++ b/arch/um/lkl/include/uapi/asm/byteorder.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_UAPI_BYTEORDER_H
+#define __UM_LIBMODE_UAPI_BYTEORDER_H
+
+#if defined(CONFIG_BIG_ENDIAN)
+#include <linux/byteorder/big_endian.h>

Same here.

Same problem here; we should not split this in the patch and [10/20]. Will fix this too.

Quoted 8 lines
Quoted 8 lines
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +7 -0
+++ b/arch/um/lkl/um/delay.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <os.h>
+
+void __ndelay(unsigned long nsecs)
Quoted 8 lines

arch/um/lkl/include/uapi/asm/bitsperlong.h line 11

Quoted 5 lines
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +5 -0
+{
+	long long start = os_nsecs();
+
+	while (os_nsecs() < start + nsecs)
+		;

At least do something like cpu_relax()? Although ... you made that do nothing, so you probably want an arch-specific thing here?

I think this isn't efficient at all, but portable enough, which is (sub)arch-specific requirement.

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#205 lore raw

RFC v8 7/20 um: lkl: host interface

In reply to Hajime Tazaki

This patch introduces the host operations that define the interface between the LKL and the host. These operations must be provided either by a host library or by the application itself.

---
 arch/um/include/asm/host_ops.h          |  9 +++++++++
 arch/um/lkl/include/uapi/asm/host_ops.h | 23 +++++++++++++++++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 arch/um/include/asm/host_ops.h
 create mode 100644 arch/um/lkl/include/uapi/asm/host_ops.h
arch/um/include/asm/host_ops.h new file +9 -0
new file mode 100644
index 000000000000..f52423cc4ced
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_HOST_OPS_H
+#define _ASM_LKL_HOST_OPS_H
+
+#include <uapi/asm/host_ops.h>
+
+extern struct lkl_host_operations *lkl_ops;
+
+#endif
arch/um/lkl/include/uapi/asm/host_ops.h new file +23 -0
new file mode 100644
index 000000000000..5d141784541d
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_UAPI_HOST_OPS_H
+#define __UM_LIBMODE_UAPI_HOST_OPS_H
+
+/**
+ * struct lkl_host_operations - host operations used by the Linux kernel
+ *
+ * These operations must be provided by a host library or by the application
+ * itself.
+ *
+ */
+struct lkl_host_operations {
+};
+
+/**
+ * lkl_bug - call lkl_panic with a message
+ *
+ * @fmt: message format with parameters
+ *
+ */
+void lkl_bug(const char *fmt, ...);
+
+#endif
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#206 lore raw

Re: [RFC v8 07/20] um: lkl: host interface

arch/um/lkl/include/uapi/asm/host_ops.h line 13

Quoted 10 lines
arch/um/lkl/include/uapi/asm/host_ops.h new file +9 -0
+/**
+ * struct lkl_host_operations - host operations used by the Linux kernel
+ *
+ * These operations must be provided by a host library or by the application
+ * itself.
+ *
+ */
+struct lkl_host_operations {
+};

IIRC, in previous reviews we discussed this and you said you'd look at just making those extern functions, instead of function pointers, since realistically there's no use in being able to switch these at runtime. What happened to that? Any particular reason not to?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#207 lore raw

Re: [RFC v8 07/20] um: lkl: host interface

Quoted 16 lines · Johannes Berg

arch/um/lkl/include/uapi/asm/host_ops.h line 13

Quoted 11 lines
arch/um/lkl/include/uapi/asm/host_ops.h new file +9 -0
+/**
+ * struct lkl_host_operations - host operations used by the Linux kernel
+ *
+ * These operations must be provided by a host library or by the application
+ * itself.
+ *
+ */
+struct lkl_host_operations {
+};

IIRC, in previous reviews we discussed this and you said you'd look at just making those extern functions, instead of function pointers, since realistically there's no use in being able to switch these at runtime. What happened to that? Any particular reason not to?

Yes, I followed your suggestion that we just use functions instead of function pointers ([17/20]).

Though we won't use pointers, we still need this structure to inform userspace side (of LKL) to kernel. [19/20], block device implementation uses this.

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#208 lore raw

RFC v8 8/20 um: lkl: memory handling

In reply to Hajime Tazaki

library mode follows the way !CONFIG_MMU architecture of other linux archs. There is not much work left to do other than initializing the boot allocator and providing the page and page table definitions.

The backstore memory is allocated via host functions and the memory size to be used is specified when the kernel is started, in the lkl_start_kernel call.

---
 arch/um/include/asm/mmu.h               |   3 +
 arch/um/include/asm/mmu_context.h       |  10 +++
 arch/um/include/asm/page.h              |  15 ++++
 arch/um/include/asm/pgtable.h           |  27 ++++++
 arch/um/include/asm/uaccess.h           |   6 ++
 arch/um/lkl/include/uapi/asm/host_ops.h |  16 ++++
 arch/um/lkl/um/bootmem.c                | 107 ++++++++++++++++++++++++
 7 files changed, 184 insertions(+)
 create mode 100644 arch/um/lkl/um/bootmem.c
arch/um/include/asm/mmu.h +3 -0
index 5b072aba5b65..c06d6cb67dd7 100644
@@ -13,6 +13,9 @@ typedef struct mm_context {
 	struct mm_id id;
 	struct uml_arch_mm_context arch;
 	struct page *stub_pages[2];
+#ifndef CONFIG_MMU
+	unsigned long		end_brk;
+#endif
 } mm_context_t;
 
 extern void __switch_mm(struct mm_id * mm_idp);
arch/um/include/asm/mmu_context.h +10 -0
index f8a100770691..4bf627feaa0c 100644
@@ -6,6 +6,7 @@
 #ifndef __UM_MMU_CONTEXT_H
 #define __UM_MMU_CONTEXT_H
 
+#ifdef CONFIG_MMU
 #include <linux/sched.h>
 #include <linux/mm_types.h>
 #include <linux/mmap_lock.h>
@@ -73,4 +74,13 @@ extern void destroy_context(struct mm_struct *mm);
 
 #include <asm-generic/mmu_context.h>
 
+#else
+
+#include <asm-generic/nommu_context.h>
+
+extern void force_flush_all(void);
+
+#endif /* CONFIG_MMU */
+
+
 #endif
arch/um/include/asm/page.h +15 -0
index 95af12e82a32..c9d5e487ac6b 100644
@@ -7,6 +7,8 @@
 #ifndef __UM_PAGE_H
 #define __UM_PAGE_H
 
+#ifdef CONFIG_MMU
+
 #include <linux/const.h>
 
 /* PAGE_SHIFT determines the page size */
@@ -120,4 +122,17 @@ extern unsigned long uml_physmem;
 #define __HAVE_ARCH_GATE_AREA 1
 #endif
 
+#else  /* CONFIG_MMU */
+#define CONFIG_KERNEL_RAM_BASE_ADDRESS memory_start
+#include <asm-generic/page.h>
+
+#define __va_space (8*1024*1024)
+
+#ifndef __ASSEMBLY__
+#include <mem.h>
+void free_mem(void);
+#endif
+
+#endif /* !CONFIG_MMU  */
+
 #endif	/* __UM_PAGE_H */
arch/um/include/asm/pgtable.h +27 -0
index 39376bb63abf..58638d888b95 100644
@@ -21,6 +21,8 @@
 #define _PAGE_PROTNONE	0x010	/* if the user mapped it with PROT_NONE;
 				   pte_present gives true */
 
+#ifdef CONFIG_MMU
+
 #ifdef CONFIG_3_LEVEL_PGTABLES
 #include <asm/pgtable-3level.h>
 #else
@@ -326,4 +328,29 @@ do {						\
 	__flush_tlb_one((vaddr));		\
 } while (0)
 
+#else  /* CONFIG_MMU */
+
+#include <asm-generic/pgtable-nopud.h>
+
+#define swapper_pg_dir		((pgd_t *)0)
+#define PAGE_KERNEL             __pgprot(0)
+#define PGDIR_SHIFT		21
+#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+
+#define VMALLOC_START	0
+#define VMALLOC_END	0xffffffff
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long *empty_zero_page;
+#define ZERO_PAGE(vaddr)	(virt_to_page(empty_zero_page))
+
+extern unsigned long end_iomem;
+
+#endif /* !CONFIG_MMU */
+
+
 #endif
arch/um/include/asm/uaccess.h +6 -0
index fe66d659acad..95db8f06d295 100644
@@ -21,6 +21,7 @@
 #define __addr_range_nowrap(addr, size) \
 	((unsigned long) (addr) <= ((unsigned long) (addr) + (size)))
 
+#ifdef CONFIG_MMU
 extern unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n);
 extern unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n);
 extern long __strncpy_from_user(char *dst, const char __user *src, long count);
@@ -46,4 +47,9 @@ static inline int __access_ok(unsigned long addr, unsigned long size)
 		uaccess_kernel());
 }
 
+#else
+#include <asm-generic/uaccess.h>
+#endif /* CONFIG_MMU */
+
+
 #endif
arch/um/lkl/include/uapi/asm/host_ops.h +16 -0
index 5d141784541d..17219802fa1d 100644
@@ -20,4 +20,20 @@ struct lkl_host_operations {
  */
 void lkl_bug(const char *fmt, ...);
 
+/**
+ * lkl_mem_alloc - allocate memory
+ *
+ * @mem: the size of memory requested
+ *
+ */
+void *lkl_mem_alloc(unsigned long mem);
+
+/**
+ * lkl_mem_free - free memory
+ *
+ * @mem: the address of memory to be freed
+ *
+ */
+void lkl_mem_free(void *mem);
+
 #endif
arch/um/lkl/um/bootmem.c new file +107 -0

107 lines not on this page · raw message

Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#209 lore raw

Re: [RFC v8 08/20] um: lkl: memory handling

arch/um/include/asm/mmu_context.h extern void destroy_context(struct mm_struct *mm); · line 81

Quoted 8 lines
arch/um/include/asm/mmu_context.h +5 -0
+#else
+
+#include <asm-generic/nommu_context.h>
+
+extern void force_flush_all(void);

nit: no need for "extern"

arch/um/include/asm/page.h extern unsigned long uml_physmem; · line 132

Quoted 7 lines
arch/um/include/asm/page.h +7 -0
+#define CONFIG_KERNEL_RAM_BASE_ADDRESS memory_start
+#include <asm-generic/page.h>
+
+#define __va_space (8*1024*1024)
+
+#ifndef __ASSEMBLY__
+#include <mem.h>

Is that <shared/mem.h>? I think we should start including only with that prefix.

arch/um/lkl/um/bootmem.c line 77

Quoted 5 lines
arch/um/lkl/um/bootmem.c new file +5 -0
+
+void *uml_kmalloc(int size, int flags)
+{
+	return kmalloc(size, flags);
+}

That could probably still be shared?

Quoted 9 lines
arch/um/lkl/um/bootmem.c new file +9 -0
+int set_memory_ro(unsigned long addr, int numpages)
+{
+	return -EOPNOTSUPP;
+}
+
+int set_memory_rw(unsigned long addr, int numpages)
+{
+	return -EOPNOTSUPP;
+}

arch/um/lkl/um/bootmem.c line 107

Quoted 10 lines
arch/um/lkl/um/bootmem.c new file +10 -0
+
+int set_memory_nx(unsigned long addr, int numpages)
+{
+	return -EOPNOTSUPP;
+}
+
+int set_memory_x(unsigned long addr, int numpages)
+{
+	return -EOPNOTSUPP;
+}

UML for now no longer has these either.

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#210 lore raw

Re: [RFC v8 08/20] um: lkl: memory handling

Quoted 10 lines · Johannes Berg

arch/um/include/asm/mmu_context.h extern void destroy_context(struct mm_struct *mm); · line 81

Quoted 9 lines
arch/um/include/asm/mmu_context.h +5 -0
+#else
+
+#include <asm-generic/nommu_context.h>
+
+extern void force_flush_all(void);

nit: no need for "extern"

thanks, will fix this.

Quoted 10 lines

arch/um/include/asm/page.h extern unsigned long uml_physmem; · line 132

Quoted 7 lines
arch/um/include/asm/page.h +7 -0
+#define CONFIG_KERNEL_RAM_BASE_ADDRESS memory_start
+#include <asm-generic/page.h>
+
+#define __va_space (8*1024*1024)
+
+#ifndef __ASSEMBLY__
+#include <mem.h>

Is that <shared/mem.h>? I think we should start including only with that prefix.

okay, will fix it.

Quoted 7 lines

arch/um/lkl/um/bootmem.c line 77

Quoted 5 lines
arch/um/lkl/um/bootmem.c new file +5 -0
+
+void *uml_kmalloc(int size, int flags)
+{
+	return kmalloc(size, flags);
+}

That could probably still be shared?

This function is a stub of arch/um/kernel/mem.c, which LKL doesn't use for the build. Thus we defined here.

Or are you suggesting to not stubbing this function, but extracting the function from mem.c ?

Quoted 13 lines
Quoted 13 lines
arch/um/lkl/um/bootmem.c new file +13 -0
+int set_memory_ro(unsigned long addr, int numpages)
+{
+	return -EOPNOTSUPP;
+}
+
+int set_memory_rw(unsigned long addr, int numpages)
+{
+	return -EOPNOTSUPP;
+}
+
+int set_memory_nx(unsigned long addr, int numpages)
+{
+	return -EOPNOTSUPP;
Quoted 8 lines

arch/um/lkl/um/bootmem.c line 107

Quoted 6 lines
arch/um/lkl/um/bootmem.c new file +6 -0
+}
+
+int set_memory_x(unsigned long addr, int numpages)
+{
+	return -EOPNOTSUPP;
+}

UML for now no longer has these either.

Ah, I see the changes. Will fix them.

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#211 lore raw

Re: [RFC v8 08/20] um: lkl: memory handling

Quoted 8 lines · Hajime Tazaki
Quoted 7 lines

arch/um/lkl/um/bootmem.c line 77

Quoted 5 lines
arch/um/lkl/um/bootmem.c new file +4 -0
+void *uml_kmalloc(int size, int flags)
+{
+	return kmalloc(size, flags);
+}

That could probably still be shared?

Quoted 5 lines

This function is a stub of arch/um/kernel/mem.c, which LKL doesn't use for the build. Thus we defined here.

Or are you suggesting to not stubbing this function, but extracting the function from mem.c ?

Yes, that's kind of what I was thinking.

OTOH, I guess it's in os-Linux today?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#212 lore raw

Re: [RFC v8 08/20] um: lkl: memory handling

Hello,

Quoted 10 lines · Johannes Berg
Quoted 8 lines · Hajime Tazaki
Quoted 7 lines

arch/um/lkl/um/bootmem.c line 77

Quoted 5 lines
arch/um/lkl/um/bootmem.c new file +4 -0
+void *uml_kmalloc(int size, int flags)
+{
+	return kmalloc(size, flags);
+}

That could probably still be shared?

Quoted 7 lines
Quoted 5 lines

This function is a stub of arch/um/kernel/mem.c, which LKL doesn't use for the build. Thus we defined here.

Or are you suggesting to not stubbing this function, but extracting the function from mem.c ?

Yes, that's kind of what I was thinking.

Okay, I'll look for a fix with this approach.

Quoted 1 line

OTOH, I guess it's in os-Linux today?

sorry, I didn't get this line. uml_kmalloc() is in kernel/mem.c but what is in os-Linux ?

Thanks,
-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#214 lore raw

RFC v8 9/20 um: lkl: kernel thread support

In reply to Hajime Tazaki

library mode does not support user processes but it must support kernel threads as part as the normal kernel work-flow. It uses host functions to create and terminate host threads that are going to run the kernel threads. It also uses semaphores to synchronize those threads and to allow the Linux kernel scheduler to control how the kernel threads run.

Each kernel thread runs in a host thread and has a host semaphore associated with it - the thread's scheduling semaphore. The semaphore counter is initialized to 0. The first thing a kernel thread does after getting spawned, before running any kernel code, is to perform a down operation to block the thread.

The kernel controls host threads scheduling by performing up and down operations on the scheduling semaphore. In __switch_context an up operation on the next thread is performed to wake up a blocked thread, and a down operation is performed on the prev thread to block it.

A thread is terminated by marking it in free_thread_info and performing an up operation on the scheduling semaphore at which point the marked thread will terminate itself.

Kernel threads are executed with the synchronization to other context primitivecs of kernel, such as idle thread, system calls, interrupts, "reentrancy", CPU shutdown, imbalance wake up, which are not controllable with a simple synchronization mechanism. Thus we introduced a logical CPU entity, struct lkl_cpu, to run Linux code with multiple threads; CPU get/put functions (lkl_cpu_put/lkl_cpu_get) is used to serialize access between LKL threads and host threads that issue direct calls.

UML common part (process.c) is extended to call idle functions of SUBARCH as well as kernel thread detection with a flag information of TIF_HOST_THREAD.

---
 arch/um/include/asm/thread_info.h       |  24 +++
 arch/um/kernel/process.c                |   8 +-
 arch/um/lkl/include/asm/cpu.h           |  11 +
 arch/um/lkl/include/asm/sched.h         |  23 +++
 arch/um/lkl/include/uapi/asm/host_ops.h | 164 +++++++++++++++
 arch/um/lkl/um/cpu.c                    | 223 ++++++++++++++++++++
 arch/um/lkl/um/threads.c                | 258 ++++++++++++++++++++++++
 7 files changed, 710 insertions(+), 1 deletion(-)
 create mode 100644 arch/um/lkl/include/asm/cpu.h
 create mode 100644 arch/um/lkl/include/asm/sched.h
 create mode 100644 arch/um/lkl/um/cpu.c
 create mode 100644 arch/um/lkl/um/threads.c
arch/um/include/asm/thread_info.h +24 -0
index 3b1cb8b3b186..528e0347a9d8 100644
@@ -40,6 +40,7 @@ struct thread_info {
 	.real_thread = NULL,			\
 }
 
+#ifndef CONFIG_UMMODE_LIB
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
 {
@@ -52,6 +53,27 @@ static inline struct thread_info *current_thread_info(void)
 	return ti;
 }
 
+#else /* CONFIG_UMMODE_LIB */
+
+#define __HAVE_THREAD_FUNCTIONS
+#define task_thread_info(task)	((struct thread_info *)(task)->stack)
+#define task_stack_page(task)	((task)->stack)
+#define end_of_stack(p) (&task_thread_info(p)->aux_fp_regs[FP_SIZE-1])
+
+void threads_init(void);
+void threads_cleanup(void);
+
+unsigned long *alloc_thread_stack_node(struct task_struct *p, int node);
+void setup_thread_stack(struct task_struct *p, struct task_struct *org);
+void free_thread_stack(struct task_struct *tsk);
+
+extern struct thread_info *_current_thread_info;
+static inline struct thread_info *current_thread_info(void)
+{
+	return _current_thread_info;
+}
+#endif /* CONFIG_UMMODE_LIB */
+
 #endif
 
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
@@ -64,6 +86,8 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_RESTORE_SIGMASK	7
 #define TIF_NOTIFY_RESUME	8
 #define TIF_SECCOMP		9	/* secure computing */
+#define TIF_SCHED_JB		10	/* thread is configured with jump buffer */
+#define TIF_HOST_THREAD	11	/* thread is a host task */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
arch/um/kernel/process.c +7 -1
index 9b0a36f64339..535ba738f2f5 100644
@@ -160,7 +160,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 		unsigned long arg, struct task_struct * p, unsigned long tls)
 {
 	void (*handler)(void);
-	int kthread = current->flags & PF_KTHREAD;
+	int kthread = current->flags & PF_KTHREAD ||
+		test_ti_thread_flag(current_thread_info(), TIF_HOST_THREAD);
 	int ret = 0;
 
 	p->thread = (struct thread_struct) INIT_THREAD;
@@ -214,10 +215,15 @@ void um_idle_sleep(void)
 		os_idle_sleep();
 }
 
+void __weak subarch_cpu_idle(void)
+{
+}
+
 void arch_cpu_idle(void)
 {
 	cpu_tasks[current_thread_info()->cpu].pid = os_getpid();
 	um_idle_sleep();
+	subarch_cpu_idle();
 	raw_local_irq_enable();
 }
 
arch/um/lkl/include/asm/cpu.h new file +11 -0
new file mode 100644
index 000000000000..c1164187151e
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_CPU_H
+#define __UM_LIBMODE_CPU_H
+
+int lkl_cpu_get(void);
+void lkl_cpu_put(void);
+int lkl_cpu_init(void);
+void lkl_cpu_wait_shutdown(void);
+void lkl_cpu_change_owner(lkl_thread_t owner);
+
+#endif
arch/um/lkl/include/asm/sched.h new file +23 -0
new file mode 100644
index 000000000000..1ac063ed987c
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_SCHED_H
+#define __UM_LIBMODE_SCHED_H
+
+#include <linux/sched.h>
+#include <uapi/asm/host_ops.h>
+
+static inline void thread_sched_jb(void)
+{
+	if (test_ti_thread_flag(current_thread_info(), TIF_HOST_THREAD)) {
+		set_ti_thread_flag(current_thread_info(), TIF_SCHED_JB);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		lkl_jmp_buf_set(&current_thread_info()->task->thread.arch.sched_jb,
+				     schedule);
+	} else {
+		lkl_bug("%s can be used only for host task", __func__);
+	}
+}
+
+void switch_to_host_task(struct task_struct *);
+int host_task_stub(void *unused);
+
+#endif
arch/um/lkl/include/uapi/asm/host_ops.h +164 -0

174 lines not on this page · raw message

arch/um/lkl/um/cpu.c new file +223 -0

223 lines not on this page · raw message

arch/um/lkl/um/threads.c new file +258 -0

258 lines not on this page · raw message

Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#215 lore raw

Re: [RFC v8 09/20] um: lkl: kernel thread support

arch/um/kernel/process.c void um_idle_sleep(void) · line 226

Quoted 9 lines · Hajime Tazaki
arch/um/kernel/process.c +4 -0
+void __weak subarch_cpu_idle(void)
+{
+}
+

 void arch_cpu_idle(void)
 {
  cpu_tasks[current_thread_info()->cpu].pid = os_getpid(); um_idle_sleep();

arch/um/kernel/process.c +1 -0
+	subarch_cpu_idle();

Not sure that belongs into this patch in the first place, but wouldn't it make some sense to move the um_idle_sleep() into the subarch_cpu_idle() so LKL (or apps using it) can get full control?

Quoted 9 lines

+/*
+ * This structure is used to get access to the "LKL CPU" that allows us to run
+ * Linux code. Because we have to deal with various synchronization requirements
+ * between idle thread, system calls, interrupts, "reentrancy", CPU shutdown,
+ * imbalance wake up (i.e. acquire the CPU from one thread and release it from
+ * another), we can't use a simple synchronization mechanism such as (recursive)
+ * mutex or semaphore. Instead, we use a mutex and a bunch of status data plus a
+ * semaphore.
+ */

Honestly, some of that documentation, and perhaps even the whole API for LKL feels like it should come earlier in the series.

E.g. now here I see all those lkl_mutex_lock() (where btw documentation doesn't always match the function name), so you *don't* have the function ops pointer struct anymore?

It'd be nice to have some high-level view of what applications *must* do, and what they *can* do, at the beginning of this series.

arch/um/lkl/um/cpu.c line 42

Quoted 5 lines
arch/um/lkl/um/cpu.c new file +5 -0
+	 *
+	 * This algorithm assumes that we never have more the MAX_THREADS
+	 * requesting CPU access.
+	 */
+	#define MAX_THREADS 1000000

What implications does that value have? It seems several orders of magnitude too large?

arch/um/lkl/um/cpu.c line 64

Quoted 6 lines
arch/um/lkl/um/cpu.c new file +6 -0
+static int __cpu_try_get_lock(int n)
+{
+	lkl_thread_t self;
+
+	if (__sync_fetch_and_add(&cpu.shutdown_gate, n) >= MAX_THREADS)
+		return -2;

Feels like that could be some kind of enum here instead of -2 and -1 and all that magic.

arch/um/lkl/um/cpu.c line 114

Quoted 3 lines
arch/um/lkl/um/cpu.c new file +3 -0
+	/* when somebody holds a lock, sleep until released,
+	 * with obtaining a semaphore (cpu.sem)
+	 */

nit: /*
* use this comment style
*/

arch/um/lkl/um/threads.c line 73

Quoted 4 lines
arch/um/lkl/um/threads.c new file +4 -0
+void switch_threads(jmp_buf *me, jmp_buf *you)
+{
+	/* NOP */
+}

Why, actually?

Again, goes back to the high-level design thing I alluded to above, but it's not clear to me why you need idle (which implies you're running the scheduler) but not this (which implies you're *not* running the scheduler)?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#216 lore raw

Re: [RFC v8 09/20] um: lkl: kernel thread support

Quoted 17 lines · Johannes Berg

arch/um/kernel/process.c void um_idle_sleep(void) · line 226

Quoted 9 lines · Hajime Tazaki
arch/um/kernel/process.c +4 -0
+void __weak subarch_cpu_idle(void)
+{
+}
+

 void arch_cpu_idle(void)
 {
  cpu_tasks[current_thread_info()->cpu].pid = os_getpid(); um_idle_sleep();

arch/um/kernel/process.c +1 -0
+	subarch_cpu_idle();

Not sure that belongs into this patch in the first place, but wouldn't it make some sense to move the um_idle_sleep() into the subarch_cpu_idle() so LKL (or apps using it) can get full control?

Agree. I'll move that part to um_idle_sleep.

Quoted 10 lines
Quoted 9 lines

+/*
+ * This structure is used to get access to the "LKL CPU" that allows us to run
+ * Linux code. Because we have to deal with various synchronization requirements
+ * between idle thread, system calls, interrupts, "reentrancy", CPU shutdown,
+ * imbalance wake up (i.e. acquire the CPU from one thread and release it from
+ * another), we can't use a simple synchronization mechanism such as (recursive)
+ * mutex or semaphore. Instead, we use a mutex and a bunch of status data plus a
+ * semaphore.
+ */

Quoted 6 lines

Honestly, some of that documentation, and perhaps even the whole API for LKL feels like it should come earlier in the series.

E.g. now here I see all those lkl_mutex_lock() (where btw documentation doesn't always match the function name), so you *don't* have the function ops pointer struct anymore?

I will check the inconsistency of names.
# and, yes, we don't have function ops anymore.

Quoted 2 lines

It'd be nice to have some high-level view of what applications *must* do, and what they *can* do, at the beginning of this series.

agree.

Quoted 8 lines

arch/um/lkl/um/cpu.c line 42

Quoted 5 lines
arch/um/lkl/um/cpu.c new file +5 -0
+	 *
+	 * This algorithm assumes that we never have more the MAX_THREADS
+	 * requesting CPU access.
+	 */
+	#define MAX_THREADS 1000000

What implications does that value have? It seems several orders of magnitude too large?

I guess this is a kind of random number, but will justify (or make it smaller) after some investigation.

Quoted 9 lines

arch/um/lkl/um/cpu.c line 64

Quoted 6 lines
arch/um/lkl/um/cpu.c new file +6 -0
+static int __cpu_try_get_lock(int n)
+{
+	lkl_thread_t self;
+
+	if (__sync_fetch_and_add(&cpu.shutdown_gate, n) >= MAX_THREADS)
+		return -2;

Feels like that could be some kind of enum here instead of -2 and -1 and all that magic.

agree; I will update with an enum.

Quoted 7 lines

arch/um/lkl/um/cpu.c line 114

Quoted 3 lines
arch/um/lkl/um/cpu.c new file +3 -0
+	/* when somebody holds a lock, sleep until released,
+	 * with obtaining a semaphore (cpu.sem)
+	 */

nit: /*
* use this comment style
*/

thanks, it should be. will fix this.

Quoted 6 lines

arch/um/lkl/um/threads.c line 73

Quoted 4 lines
arch/um/lkl/um/threads.c new file +4 -0
+void switch_threads(jmp_buf *me, jmp_buf *you)
+{
+	/* NOP */
+}

Why, actually?

Our threads doesn't use the UML jmp_buf (use pthread instead) so, this function has to do nothing.

We can add a comment of this here.

Quoted 4 lines

Again, goes back to the high-level design thing I alluded to above, but it's not clear to me why you need idle (which implies you're running the scheduler) but not this (which implies you're *not* running the scheduler)?

okay, will write a separate document for the high-level description of what this is.

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#217 lore raw

RFC v8 10/20 um: lkl: system call interface and application API

In reply to Hajime Tazaki

The application API is based on the kernel system call interface in order to offer a stable API to applications. Note that we can't offer the full Linux system call interface due to the limitations of library mode such as lack of virtual memory, signal, user processes, etc.

The host is using dedicated kernel thread, which is switched upon the entry of lkl_syscall so that numbers of context switches can be reduced for the faster performance.

To expose the API definitions to applications, this commit uses syscall_wrapper to define arch-specific information of syscall, and this is used to generate syscall_defs.h for lkl so that it can be used as a template of the list of syscall available for LKL apps.

To avoid collisions between the Linux API and the LKL API (e.g. struct stat, MKNOD, etc.) we use a python script to modify the user headers and to prefix all of the global symbols (structures, typedefs, defines) with LKL, lkl, _LKL, _lkl, __LKL or __lkl.

This commit also added an exception to SPDX-License-Identifier for the library mode of UML, since applications may statically link the library, thus this the GPL exception to the exported headers doesn't apply to.

---
 arch/um/Kconfig                            |   1 +
 arch/um/lkl/Makefile.um                    |  16 ++
 arch/um/lkl/include/asm/syscall_wrapper.h  |  57 ++++
 arch/um/lkl/include/asm/syscalls.h         |  15 +
 arch/um/lkl/include/uapi/asm/Kbuild        |   6 +
 arch/um/lkl/include/uapi/asm/bitsperlong.h |   5 +-
 arch/um/lkl/include/uapi/asm/byteorder.h   |   6 +-
 arch/um/lkl/include/uapi/asm/host_ops.h    |  43 +++
 arch/um/lkl/include/uapi/asm/syscalls.h    | 301 +++++++++++++++++++++
 arch/um/lkl/include/uapi/asm/unistd.h      |  15 +
 arch/um/lkl/um/syscalls.c                  | 193 +++++++++++++
 arch/um/scripts/headers_install.py         | 200 ++++++++++++++
 scripts/headers_install.sh                 |   6 +-
 13 files changed, 860 insertions(+), 4 deletions(-)
 create mode 100644 arch/um/lkl/include/asm/syscall_wrapper.h
 create mode 100644 arch/um/lkl/include/asm/syscalls.h
 create mode 100644 arch/um/lkl/include/uapi/asm/Kbuild
 create mode 100644 arch/um/lkl/include/uapi/asm/syscalls.h
 create mode 100644 arch/um/lkl/include/uapi/asm/unistd.h
 create mode 100644 arch/um/lkl/um/syscalls.c
 create mode 100755 arch/um/scripts/headers_install.py
arch/um/Kconfig +1 -0
index 53c7919ec5b7..24c6596260de 100644
@@ -28,6 +28,7 @@ config UMMODE_LIB
 	depends on !SMP
 	select UACCESS_MEMCPY
 	select ARCH_THREAD_STACK_ALLOCATOR
+	select ARCH_HAS_SYSCALL_WRAPPER
 	help
 	 This mode switches a mode to build a library of UML (Linux
 	 Kernel Library/LKL).  If this is Y, the build only generates,
arch/um/lkl/Makefile.um +16 -0
index 7d3f590d88a2..8c3f4f1a2032 100644
@@ -1,2 +1,18 @@
 KBUILD_CFLAGS += -fno-builtin -fPIC
 ELF_FORMAT=$(shell $(LD) -r -print-output-format)
+
+INSTALL_PATH ?= $(objtree)/tools/um
+SYSCALL_DEFS_H := $(objtree)/$(HOST_DIR)/include/generated/uapi/asm/syscall_defs.h
+REPLACED_SYSCALL_DEFS_H := $(INSTALL_PATH)/include/lkl/asm/syscall_defs.h
+
+um_headers_install: $(REPLACED_SYSCALL_DEFS_H) scripts_unifdef
+
+$(REPLACED_SYSCALL_DEFS_H): $(SYSCALL_DEFS_H) $(srctree)/$(ARCH_DIR)/scripts/headers_install.py
+	$(Q)$(srctree)/$(ARCH_DIR)/scripts/headers_install.py \
+		$(INSTALL_PATH)/include
+
+$(objtree)/$(HOST_DIR)/include/generated/uapi/asm/syscall_defs.h: vmlinux
+	$(Q)$(OBJCOPY) -j .syscall_defs -O binary --set-section-flags \
+		       .syscall_defs=alloc $< $@
+	$(Q) export tmpfile=$(shell mktemp); \
+	sed 's/\x0//g' $@ > $$tmpfile; mv $$tmpfile $@ ; rm -f $$tmpfile
arch/um/lkl/include/asm/syscall_wrapper.h new file +57 -0

57 lines not on this page · raw message

arch/um/lkl/include/asm/syscalls.h new file +15 -0
new file mode 100644
index 000000000000..6061d9415dad
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+int syscalls_init(void);
+void syscalls_cleanup(void);
+long lkl_syscall(long no, long *params);
+void wakeup_idle_host_task(void);
+
+#define sys_mmap sys_ni_syscall
+#define sys_rt_sigreturn sys_ni_syscall
+#define sys_arch_prctl sys_ni_syscall
+#define sys_iopl sys_ni_syscall
+#define sys_ioperm sys_ni_syscall
+#define sys_clone sys_ni_syscall
+
+int run_syscalls(void);
arch/um/lkl/include/uapi/asm/Kbuild new file +6 -0
new file mode 100644
index 000000000000..1c89a1640263
@@ -0,0 +1,6 @@
+# UAPI Header export list
+
+generated-y += syscall_defs.h
+
+# generated-y file is parsed by special user headers handling
+# see arch/um/script/headers_install.py
arch/um/lkl/include/uapi/asm/bitsperlong.h +4 -1
index f6657ba0ff9b..b3a5adf0b04f 100644
@@ -2,7 +2,10 @@
 #ifndef __UM_LIBMODE_UAPI_BITSPERLONG_H
 #define __UM_LIBMODE_UAPI_BITSPERLONG_H
 
-#ifdef CONFIG_64BIT
+/* need to add new arch defines here, as we cannot use CONFIG_64BIT here
+ * to avoid CONFIG leaks to userspace
+ */
+#if defined(__x86_64__)
 #define __BITS_PER_LONG 64
 #else
 #define __BITS_PER_LONG 32
arch/um/lkl/include/uapi/asm/byteorder.h +4 -2
index a4ae973f440b..ed19f6a836c6 100644
@@ -2,10 +2,12 @@
 #ifndef __UM_LIBMODE_UAPI_BYTEORDER_H
 #define __UM_LIBMODE_UAPI_BYTEORDER_H
 
-#if defined(CONFIG_BIG_ENDIAN)
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 #include <linux/byteorder/big_endian.h>
-#else
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 #include <linux/byteorder/little_endian.h>
+#else
+#error "cannot detect endian of the target"
 #endif
 
 #endif
arch/um/lkl/include/uapi/asm/host_ops.h +43 -0

47 lines not on this page · raw message

arch/um/lkl/include/uapi/asm/syscalls.h new file +301 -0

301 lines not on this page · raw message

arch/um/lkl/include/uapi/asm/unistd.h new file +15 -0
new file mode 100644
index 000000000000..6f5d67b45fbd
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __UM_LIBMODE_UAPI_UNISTD_H
+#define __UM_LIBMODE_UAPI_UNISTD_H
+
+#define __ARCH_WANT_NEW_STAT
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#define __ARCH_WANT_SYS_NEWFSTATAT
+#endif
+
+#include <asm-generic/unistd.h>
+
+
+#endif
arch/um/lkl/um/syscalls.c new file +193 -0

193 lines not on this page · raw message

arch/um/scripts/headers_install.py new file +200 -0

200 lines not on this page · raw message

scripts/headers_install.sh +5 -1
index dd554bd436cc..d44b92979db4 100755
@@ -24,7 +24,11 @@ TMPFILE=$OUTFILE.tmp
 trap 'rm -f $OUTFILE $TMPFILE' EXIT
 
 # SPDX-License-Identifier with GPL variants must have "WITH Linux-syscall-note"
-if [ -n "$(sed -n -e "/SPDX-License-Identifier:.*GPL-/{/WITH Linux-syscall-note/!p}" $INFILE)" ]; then
+#
+# ARCH=um with library mode exposes uapi headers but applications may be linked
+# statically, thus this GPL exception doesn't apply to.
+if [ -n "$(sed -n -e "/SPDX-License-Identifier:.*GPL-/{/WITH Linux-syscall-note/!p}" $INFILE)" ] &&
+	[ "$SRCARCH" != "um" ]; then
 	echo "error: $INFILE: missing \"WITH Linux-syscall-note\" for SPDX-License-Identifier" >&2
 	exit 1
 fi
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#218 lore raw

RFC v8 11/20 um: lkl: basic console support

In reply to Hajime Tazaki

This patch adds a basic structure of console support in kernel. Write operations are deferred to the host print operation.

This commit also disables stdio-console of UML when library mode to avoid conflicts between multiple consoles.

---
 arch/um/drivers/Makefile                |  8 ++++-
 arch/um/lkl/include/uapi/asm/host_ops.h |  9 ++++++
 arch/um/lkl/um/console.c                | 41 +++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 1 deletion(-)
 create mode 100644 arch/um/lkl/um/console.c
arch/um/drivers/Makefile +7 -1
index ae96c83e312d..dc0d32d62294 100644
@@ -37,7 +37,13 @@ $(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o
 # When the above is fixed, don't forget to add this too!
 #targets += $(obj)/pcap.o
 
-obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
+ifndef CONFIG_UMMODE_LIB
+obj-y := stdio_console.o
+else
+obj-y :=
+endif
+obj-y += fd.o chan_kern.o chan_user.o line.o
+
 obj-$(CONFIG_SSL) += ssl.o
 obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
 
arch/um/lkl/include/uapi/asm/host_ops.h +9 -0
index b97aa1099a17..976fc4301b3d 100644
@@ -243,4 +243,13 @@ int lkl_tls_set(struct lkl_tls_key *key, void *data);
  */
 void *lkl_tls_get(struct lkl_tls_key *key);
 
+/**
+ * lkl_print - optional operation that receives console messages
+ *
+ * @str: strings to be printed
+ * @len: the length of @str
+ *
+ */
+void lkl_print(const char *str, int len);
+
 #endif
arch/um/lkl/um/console.c new file +41 -0

41 lines not on this page · raw message

Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#219 lore raw

Re: [RFC v8 11/20] um: lkl: basic console support

arch/um/drivers/Makefile $(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o · line 45

Quoted 9 lines
arch/um/drivers/Makefile +6 -1
-obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
+ifndef CONFIG_UMMODE_LIB
+obj-y := stdio_console.o
+else
+obj-y :=
+endif
+obj-y += fd.o chan_kern.o chan_user.o line.o

Might nicer to do via Kconfig, such as

config STDIO_CONSOLE
def_bool y
depends on !UMMODE_LIB

and then

obj-$(CONFIG_STDIO_CONSOLE) += stdio_console.o

here. Similar to CONFIG_STDDER_CONSOLE, after all.

Quoted 2 lines

+/**
+ * lkl_print - optional operation that receives console messages

How is it optional? I don't see you having a __weak definition?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#220 lore raw

Re: [RFC v8 11/20] um: lkl: basic console support

Quoted 17 lines · Johannes Berg

arch/um/drivers/Makefile $(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o · line 45

Quoted 10 lines
arch/um/drivers/Makefile +6 -1
-obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
+ifndef CONFIG_UMMODE_LIB
+obj-y := stdio_console.o
+else
+obj-y :=
+endif
+obj-y += fd.o chan_kern.o chan_user.o line.o

Might nicer to do via Kconfig, such as

config STDIO_CONSOLE
def_bool y
depends on !UMMODE_LIB

Quoted 5 lines

and then

obj-$(CONFIG_STDIO_CONSOLE) += stdio_console.o

here. Similar to CONFIG_STDDER_CONSOLE, after all.

Agree. I'll fix them.

Quoted 4 lines
Quoted 2 lines

+/**
+ * lkl_print - optional operation that receives console messages

How is it optional? I don't see you having a __weak definition?

Optional is misleading... I will fix the comment.

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#221 lore raw

RFC v8 12/20 um: lkl: initialization and cleanup

In reply to Hajime Tazaki

Add the lkl_start_kernel and lkl_sys_halt APIs that start and respectively stops the Linux kernel.

lkl_start_kernel creates a separate threads that will run the initial and idle kernel thread. It waits for the kernel to complete initialization before returning, to avoid races with system calls issues by the host application.

During the setup phase, we create "/init" in initial ramfs root filesystem to avoid mounting the "real" rootfs since ramfs is good enough for now.

lkl_sys_halt will shutdown the kernel, terminate all threads and free all host resources used by the kernel before returning.

---
 arch/um/lkl/include/uapi/asm/host_ops.h |  20 +++
 arch/um/lkl/um/setup.c                  | 162 ++++++++++++++++++++++++
 tools/um/uml/process.c                  |   2 +
 3 files changed, 184 insertions(+)
 create mode 100644 arch/um/lkl/um/setup.c
arch/um/lkl/include/uapi/asm/host_ops.h +20 -0
index 976fc4301b3d..85d7d4790602 100644
@@ -252,4 +252,24 @@ void *lkl_tls_get(struct lkl_tls_key *key);
  */
 void lkl_print(const char *str, int len);
 
+/**
+ * lkl_panic - called during a kernel panic
+ *
+ */
+void lkl_panic(void);
+
+/**
+ * lkl_start_kernel() - registers the host operations and starts the kernel
+ *
+ * @ops: pointer to host operations
+ * @fmt: format for command line string that is going to be used to
+ * generate the Linux kernel command line
+ *
+ * Return: 0 if there is no error; otherwise non-zero value returns.
+ *
+ * The function returns only after the kernel is shutdown with lkl_sys_halt.
+ */
+int lkl_start_kernel(struct lkl_host_operations *ops,
+		     const char *fmt, ...);
+
 #endif
arch/um/lkl/um/setup.c new file +162 -0

162 lines not on this page · raw message

tools/um/uml/process.c +2 -0
index e52dd37ddadc..c39d914e80ac 100644
@@ -114,6 +114,8 @@ void os_kill_process(int pid, int reap_child)
 
 void os_kill_ptraced_process(int pid, int reap_child)
 {
+	if (pid == 0)
+		return;
 	kill(pid, SIGKILL);
 	ptrace(PTRACE_KILL, pid);
 	ptrace(PTRACE_CONT, pid);
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#222 lore raw

Re: [RFC v8 12/20] um: lkl: initialization and cleanup

arch/um/lkl/um/setup.c line 37

Quoted 2 lines · Hajime Tazaki
arch/um/lkl/um/setup.c new file +1 -0
+	panic_blink = lkl_panic_blink;

Using a panic notifier would seem more appropriate?

arch/um/lkl/um/setup.c line 53

Quoted 1 line
arch/um/lkl/um/setup.c new file +1 -0
+	init_sem = lkl_sem_alloc(0);

what's the deal with this?

Quoted 5 lines
arch/um/lkl/um/setup.c new file +5 -0
+	if (!init_sem)
+		return -ENOMEM;
+
+	ret = lkl_cpu_init();
+	if (ret)

arch/um/lkl/um/setup.c line 68

Quoted 10 lines
arch/um/lkl/um/setup.c new file +10 -0
+		goto out_free_init_sem;
+
+	ret = lkl_thread_create(lkl_run_kernel, NULL);
+	if (!ret) {
+		ret = -ENOMEM;
+		goto out_free_init_sem;
+	}
+
+	lkl_sem_down(init_sem);
+	lkl_sem_free(init_sem);

You free it before the kernel really even started?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#223 lore raw

Re: [RFC v8 12/20] um: lkl: initialization and cleanup

Quoted 6 lines · Johannes Berg

arch/um/lkl/um/setup.c line 37

Quoted 2 lines · Hajime Tazaki
arch/um/lkl/um/setup.c new file +1 -0
+	panic_blink = lkl_panic_blink;

Using a panic notifier would seem more appropriate?

I understand; will investigate if we can change.

Quoted 13 lines

arch/um/lkl/um/setup.c line 53

Quoted 1 line
arch/um/lkl/um/setup.c new file +1 -0
+	init_sem = lkl_sem_alloc(0);

what's the deal with this?

Quoted 9 lines
arch/um/lkl/um/setup.c new file +9 -0
+	if (!init_sem)
+		return -ENOMEM;
+
+	ret = lkl_cpu_init();
+	if (ret)
+		goto out_free_init_sem;
+
+	ret = lkl_thread_create(lkl_run_kernel, NULL);
+	if (!ret) {
Quoted 8 lines

arch/um/lkl/um/setup.c line 68

Quoted 6 lines
arch/um/lkl/um/setup.c new file +6 -0
+		ret = -ENOMEM;
+		goto out_free_init_sem;
+	}
+
+	lkl_sem_down(init_sem);
+	lkl_sem_free(init_sem);

You free it before the kernel really even started?

The semaphore (init_sem) is unlocked at lkl_run_init(), so this waits for finishing the init call. After the initialization ends, it's safe to free as it's no longer used.

I may add some description here to make it clear.

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#224 lore raw

RFC v8 13/20 um: lkl: integrate with irq infrastructure of UML

In reply to Hajime Tazaki

In order to cooperate with UML's irq infrastructure and LKL threads based on host threads, irq handlers shall synchronize the our scheduler which is controlled by struct lkl_cpu. To do that, the irq infra notifies its entry of handlers by obtaining cpu access of thread scheduler (lkl_cpu_try_run_irq) and its release (lkl_cpu_put).

In additon to that, in order to stick the signal handler's thread to the one of the idle thread, several required configurations of (thread's) signal mask are added: otherwise handlers running on arbitrary thread cannot obtain cpu access and immediately fall into pending interrupt which may slow down the delivery of signals.

---
 arch/um/include/shared/os.h   |  1 +
 arch/um/kernel/irq.c          | 13 ++++++++++
 arch/um/kernel/time.c         |  2 ++
 arch/um/lkl/include/asm/cpu.h |  4 +++
 arch/um/lkl/um/cpu.c          | 46 +++++++++++++++++++++++++++++++++++
 arch/um/lkl/um/setup.c        |  5 ++++
 arch/um/lkl/um/threads.c      |  3 +++
 tools/um/uml/signal.c         | 12 +++++++--
 8 files changed, 84 insertions(+), 2 deletions(-)
arch/um/include/shared/os.h +1 -0
index 13d86f94cf0f..cd8583e4df12 100644
@@ -243,6 +243,7 @@ extern int set_signals_trace(int enable);
 extern int os_is_signal_stack(void);
 extern void deliver_alarm(void);
 extern void register_pm_wake_signal(void);
+extern void set_pending_signals(int sig);
 
 /* util.c */
 extern void stack_protections(unsigned long address);
arch/um/kernel/irq.c +13 -0
index 3741d2380060..d632156b52ac 100644
@@ -21,6 +21,7 @@
 #include <irq_user.h>
 #include <irq_kern.h>
 #include <as-layout.h>
+#include <asm/cpu.h>
 
 
 extern void free_irqs(void);
@@ -563,6 +564,11 @@ unsigned long to_irq_stack(unsigned long *mask_out)
 	unsigned long mask, old;
 	int nested;
 
+#ifdef CONFIG_UMMODE_LIB
+	if (!lkl_irq_enter(ffs(*mask_out) - 1))
+		return 1;
+#endif
+
 	mask = xchg(&pending_mask, *mask_out);
 	if (mask != 0) {
 		/*
@@ -579,6 +585,10 @@ unsigned long to_irq_stack(unsigned long *mask_out)
 			old |= mask;
 			mask = xchg(&pending_mask, old);
 		} while (mask != old);
+
+#ifdef CONFIG_UMMODE_LIB
+		lkl_irq_exit();
+#endif
 		return 1;
 	}
 
@@ -616,6 +626,9 @@ unsigned long from_irq_stack(int nested)
 	*to = *ti;
 
 	mask = xchg(&pending_mask, 0);
+#ifdef CONFIG_UMMODE_LIB
+	lkl_irq_exit();
+#endif
 	return mask & ~1;
 }
 
arch/um/kernel/time.c +2 -0
index f4db89b5b5a6..07d705ec5193 100644
@@ -659,11 +659,13 @@ static struct clock_event_device timer_clockevent = {
 
 static irqreturn_t um_timer(int irq, void *dev)
 {
+#ifndef CONFIG_UMMODE_LIB
 	if (get_current()->mm != NULL)
 	{
         /* userspace - relay signal, results in correct userspace timers */
 		os_alarm_process(get_current()->mm->context.id.u.pid);
 	}
+#endif
 
 	(*timer_clockevent.event_handler)(&timer_clockevent);
 
arch/um/lkl/include/asm/cpu.h +4 -0
index c1164187151e..b241b5bbdc53 100644
@@ -8,4 +8,8 @@ int lkl_cpu_init(void);
 void lkl_cpu_wait_shutdown(void);
 void lkl_cpu_change_owner(lkl_thread_t owner);
 
+int lkl_cpu_try_run_irq(int irq);
+void lkl_irq_exit(void);
+int lkl_irq_enter(int sig);
+
 #endif
arch/um/lkl/um/cpu.c +46 -0

76 lines not on this page · raw message

arch/um/lkl/um/setup.c +5 -0
index ba8338d4fc23..12b235826573 100644
@@ -36,6 +36,8 @@ static void __init *lkl_run_kernel(void *arg)
 
 	panic_blink = lkl_panic_blink;
 
+	/* signal should be received at this thread (main and idle threads) */
+	init_new_thread_signals();
 	threads_init();
 	lkl_cpu_get();
 	start_kernel();
@@ -58,6 +60,9 @@ int __init lkl_start_kernel(struct lkl_host_operations *ops,
 	if (ret)
 		goto out_free_init_sem;
 
+	change_sig(SIGALRM, 0);
+	change_sig(SIGIO, 0);
+
 	ret = lkl_thread_create(lkl_run_kernel, NULL);
 	if (!ret) {
 		ret = -ENOMEM;
arch/um/lkl/um/threads.c +3 -0
index 7ef9b9f2a6b7..c7ff578b7a91 100644
@@ -152,6 +152,9 @@ static void *thread_bootstrap(void *_tba)
 	int (*f)(void *) = tba->f;
 	void *arg = tba->arg;
 
+	change_sig(SIGALRM, 0);
+	change_sig(SIGIO, 0);
+
 	lkl_sem_down(ti->task->thread.arch.sched_sem);
 	kfree(tba);
 	if (ti->task->thread.prev_sched)
tools/um/uml/signal.c +10 -2
index 96f511d1aabe..de04b0dd34bb 100644
@@ -230,8 +230,8 @@ void set_handler(int sig)
 
 	sigemptyset(&sig_mask);
 	sigaddset(&sig_mask, sig);
-	if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
-		panic("sigprocmask failed - errno = %d\n", errno);
+	if (pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
+		panic("pthread_sigmask failed - errno = %d\n", errno);
 }
 
 void send_sigio_to_self(void)
@@ -375,3 +375,11 @@ int os_is_signal_stack(void)
 
 	return ss.ss_flags & SS_ONSTACK;
 }
+
+void set_pending_signals(int sig)
+{
+	if (sig == SIGIO)
+		signals_pending |= SIGIO_MASK;
+	else if (sig == SIGALRM)
+		signals_pending |= SIGALRM_MASK;
+}
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#225 lore raw

Re: [RFC v8 13/20] um: lkl: integrate with irq infrastructure of UML

Quoted 4 lines · Hajime Tazaki

 static irqreturn_t um_timer(int irq, void *dev)
 {
+#ifndef CONFIG_UMMODE_LIB
  if (get_current()->mm != NULL)

Why is the ifdef needed - get_current()->mm should always be NULL for LKL? Surely get_current() must still work?

tools/um/uml/signal.c void set_handler(int sig) · line 234

Quoted 6 lines

  sigemptyset(&sig_mask);
  sigaddset(&sig_mask, sig);

tools/um/uml/signal.c +2 -2
-	if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
-		panic("sigprocmask failed - errno = %d\n", errno);
+	if (pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
+		panic("pthread_sigmask failed - errno = %d\n", errno);

UML doesn't normally link with libpthread, and LKL doesn't actually appear to require it either (since it has its lkl_thread and all), so this seems wrong?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#226 lore raw

Re: [RFC v8 13/20] um: lkl: integrate with irq infrastructure of UML

Quoted 9 lines · Johannes Berg
Quoted 4 lines · Hajime Tazaki

 static irqreturn_t um_timer(int irq, void *dev)
 {
+#ifndef CONFIG_UMMODE_LIB
  if (get_current()->mm != NULL)

Why is the ifdef needed - get_current()->mm should always be NULL for LKL? Surely get_current() must still work?

What we tried to ifdef is to avoid the following call;

   os_alarm_process(get_current()->mm->context.id.u.pid);

because we didn't use/update get_current()->mm->context.id (struct mm_id) and calling kill(0, SIGALRM) makes a program puzzled thus, eliminate it.

Quoted 10 lines

tools/um/uml/signal.c void set_handler(int sig) · line 234

Quoted 6 lines

  sigemptyset(&sig_mask);
  sigaddset(&sig_mask, sig);

tools/um/uml/signal.c +2 -2
-	if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
-		panic("sigprocmask failed - errno = %d\n", errno);
+	if (pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
+		panic("pthread_sigmask failed - errno = %d\n", errno);

UML doesn't normally link with libpthread, and LKL doesn't actually appear to require it either (since it has its lkl_thread and all), so this seems wrong?

I think both UML/LKL link with libpthread. See old scripts/link-vmlinux.sh, or [01/20] patch.

- ${CC} ${CFLAGS_vmlinux} \
- ${strip_debug} \
- -o ${output} \
- -Wl,-T,${lds} \
- ${objects} \
- -lutil -lrt -lpthread
- rm -f linux

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#227 lore raw

Re: [RFC v8 13/20] um: lkl: integrate with irq infrastructure of UML

Quoted 13 lines · Hajime Tazaki
Quoted 9 lines

tools/um/uml/signal.c void set_handler(int sig) · line 234

Quoted 5 lines
tools/um/uml/signal.c +2 -2
-	if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
-		panic("sigprocmask failed - errno = %d\n", errno);
+	if (pthread_sigmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
+		panic("pthread_sigmask failed - errno = %d\n", errno);

UML doesn't normally link with libpthread, and LKL doesn't actually appear to require it either (since it has its lkl_thread and all), so this seems wrong?

I think both UML/LKL link with libpthread. See old scripts/link-vmlinux.sh, or [01/20] patch.

Review

Quoted 7 lines
(quoted diff) +0 -7
-		${CC} ${CFLAGS_vmlinux}				\
-			${strip_debug}				\
-			-o ${output}				\
-			-Wl,-T,${lds}				\
-			${objects}				\
-			-lutil -lrt -lpthread
-		rm -f linux

Interesting. You're right, I really didn't expect that, nor did I ever see that before.

How does this interact with all the clone() calls etc. that UML does?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#228 lore raw

RFC v8 14/20 um: lkl: plug in the build system

In reply to Hajime Tazaki

Basic Makefiles for building library of library mode. Add a new architecture specific target for installing the resulting library files and headers.

To make LKL binaries build, we can specify the SUBARCH name as "lkl" to switch the output file of build: kernel (default), or library (library mode). Those modes are not able to be ON at the same time.

To build on library mode, users do the following:

make defconfig ARCH=um SUBARCH=lkl
make ARCH=um SUBARCH=lkl

---
 arch/um/Makefile              | 27 +++++++++----
 arch/um/configs/lkl_defconfig | 73 +++++++++++++++++++++++++++++++++++
 arch/um/kernel/Makefile       | 14 ++++---
 arch/um/lkl/um/Makefile       |  4 ++
 tools/um/Makefile             |  3 +-
 tools/um/Targets              |  3 ++
 6 files changed, 111 insertions(+), 13 deletions(-)
 create mode 100644 arch/um/configs/lkl_defconfig
 create mode 100644 arch/um/lkl/um/Makefile
arch/um/Makefile +20 -7
index bce0cccae085..6ddc900604a5 100644
@@ -34,6 +34,10 @@ ifneq ($(filter $(SUBARCH),x86 x86_64 i386),)
 	HEADER_ARCH := x86
 endif
 
+ifeq ($(SUBARCH),lkl)
+	HEADER_ARCH := um/lkl
+endif
+
 ifdef CONFIG_64BIT
 	KBUILD_CFLAGS += -mcmodel=large
 endif
@@ -97,19 +101,27 @@ KBUILD_CFLAGS += $(KERNEL_DEFINES)
 LDFLAGS_vmlinux += -r
 
 INSTALL_PATH=$(objtree)/tools/um
-all: linux
-pre-2nd: linux.o
-	@echo "  INSTALL $(INSTALL_PATH)/lib/$<"
-	@mkdir -p $(INSTALL_PATH)/lib/
-	@cp $< $(INSTALL_PATH)/lib/
+ifeq ($(CONFIG_UMMODE_LIB),y)
+all: pre-2nd
+	$(Q)$(MAKE) -C $(srctree)/tools/um
 
-PHONY += linux.o
+pre-2nd: linux.o um_headers_install
+
+else
+all: linux
 
 linux: pre-2nd
 	$(Q)$(MAKE) -C $(srctree)/tools/um
 	$(Q)cp $(objtree)/tools/um/uml/linux $(objtree)/
 	$(Q)cp $(objtree)/linux $(objtree)/vmlinux
 
+pre-2nd: linux.o
+endif
+	@echo "  INSTALL $(INSTALL_PATH)/lib/$<"
+	@mkdir -p $(INSTALL_PATH)/lib/
+	@cp $< $(INSTALL_PATH)/lib/
+
+PHONY += linux.o
 linux.o: vmlinux
 #revert vmlinux file from vmlinux.a
 ifneq ("$(wildcard vmlinux.a)","")
@@ -117,7 +129,8 @@ ifneq ("$(wildcard vmlinux.a)","")
 endif
 	$(Q)cp vmlinux vmlinux.a
 	@echo "  LINK    $@"
-	$(Q)$(OBJCOPY) -R .eh_frame $< $@
+# symbols in ipc/sem.c conflict with sem_init(3) etc, thus localize the kernel one.
+	$(Q)$(OBJCOPY) -R .eh_frame -L sem_init -L sem_post -L sem_wait -L sem_destroy $< $@
 
 define archhelp
   echo '* linux		- Binary kernel image (./linux) - for backward'
arch/um/configs/lkl_defconfig new file +73 -0

73 lines not on this page · raw message

arch/um/kernel/Makefile +9 -5
index 9b63831a69e1..781c39b21403 100644
@@ -14,17 +14,21 @@ CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START)		\
 			$(LDS_EXTRA)
 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 \
-	um_arch.o umid.o maccess.o kmsg_dump.o skas/
+obj-y = config.o exitcode.o irq.o ksyms.o \
+	process.o reboot.o sigio.o \
+	signal.o syscall.o time.o \
+	um_arch.o umid.o maccess.o kmsg_dump.o
+
+ifndef CONFIG_UMMODE_LIB
+obj-y += exec.o mem.o physmem.o ptrace.o sysrq.o tlb.o trap.o skas/
+endif
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
 obj-$(CONFIG_GPROF)	+= gprof_syms.o
 obj-$(CONFIG_GCOV)	+= gmon_syms.o
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
-obj-y += user_syms.o
+obj-$(CONFIG_MMU) += user_syms.o
 
 USER_OBJS := config.o
 
arch/um/lkl/um/Makefile new file +4 -0
new file mode 100644
index 000000000000..b29b598a1bac
@@ -0,0 +1,4 @@
+include/generated/user_constants.h: $(srctree)/arch/um/lkl/um/user_constants.h
+	$(Q)cp -f $^ $@
+
+obj-y = bootmem.o console.o cpu.o delay.o setup.o syscalls.o threads.o unimplemented.o
tools/um/Makefile +2 -1
index 0fdf77261e74..877d0bdefa67 100644
@@ -32,6 +32,7 @@ export CFLAGS += -I$(OUTPUT)/include -Iinclude -Wall -g -O2 -Wextra -fPIC \
 	 -Wno-unused-parameter \
 	 -Wno-missing-field-initializers -fno-strict-aliasing
 
+-include $(OUTPUT)/../../include/config/auto.conf
 -include Targets
 
 TARGETS := $(progs-y:%=$(OUTPUT)%)
@@ -69,6 +70,6 @@ clean:
 	$(call QUIET_CLEAN, $(TARGETS))$(RM) $(TARGETS)
 
 FORCE: ;
-.PHONY: all clean FORCE
+.PHONY: all clean FORCE $(OUTPUT)/../../include/config/auto.conf
 .IGNORE: clean
 .NOTPARALLEL : lib/linux.o
tools/um/Targets +3 -0
index cfe1d3c3c6ff..e8b43c7758fe 100644
@@ -1,4 +1,7 @@
+ifneq ($(CONFIG_UMMODE_LIB),y)
 progs-y += uml/linux
+endif
+
 LDLIBS_linux-y := -lrt -lpthread -lutil
 LDFLAGS_linux-y := -no-pie -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 LDFLAGS_linux-$(CONFIG_STATIC_LINK) += -static
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#229 lore raw

RFC v8 15/20 um: host: add library mode build for ARCH=um

In reply to Hajime Tazaki

This patch adds the skeleton for the host library.

The host library is implementing the host operations needed by library mode and splits into host dependent (e.g., POSIX hosts) and host independent parts.

---
 tools/um/.gitignore              |   1 +
 tools/um/Makefile                |   1 +
 tools/um/Targets                 |   6 +-
 tools/um/include/lkl.h           | 135 +++++++++++++++++++++++++++++++
 tools/um/include/lkl_host.h      |  18 +++++
 tools/um/uml/Build               |  16 +++-
 tools/um/uml/lkl/Build           |   1 +
 tools/um/uml/lkl/registers.c     |  21 +++++
 tools/um/uml/lkl/unimplemented.c |  21 +++++
 9 files changed, 214 insertions(+), 6 deletions(-)
 create mode 100644 tools/um/.gitignore
 create mode 100644 tools/um/include/lkl.h
 create mode 100644 tools/um/include/lkl_host.h
 create mode 100644 tools/um/uml/lkl/Build
 create mode 100644 tools/um/uml/lkl/registers.c
 create mode 100644 tools/um/uml/lkl/unimplemented.c
tools/um/.gitignore new file +1 -0
new file mode 100644
index 000000000000..0d20b6487c61
@@ -0,0 +1 @@
+*.pyc
tools/um/Makefile +1 -0
index 877d0bdefa67..c07e91a93372 100644
@@ -66,6 +66,7 @@ RM := rm -f
 clean:
 	$(call QUIET_CLEAN, objects)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd'\
 	 -delete -o -name '\.*.d' -delete
+	$(call QUIET_CLEAN, headers)$(RM) -r $(OUTPUT)/include/lkl/
 	$(call QUIET_CLEAN, liblinux.a)$(RM) $(OUTPUT)/liblinux.a
 	$(call QUIET_CLEAN, $(TARGETS))$(RM) $(TARGETS)
 
tools/um/Targets +4 -2
index e8b43c7758fe..ae6c8d8b168e 100644
@@ -1,7 +1,9 @@
-ifneq ($(CONFIG_UMMODE_LIB),y)
+ifeq ($(CONFIG_UMMODE_LIB),y)
+libs-y += liblinux.a
+else
 progs-y += uml/linux
 endif
 
-LDLIBS_linux-y := -lrt -lpthread -lutil
+LDLIBS := -lrt -lpthread -lutil
 LDFLAGS_linux-y := -no-pie -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 LDFLAGS_linux-$(CONFIG_STATIC_LINK) += -static
tools/um/include/lkl.h new file +135 -0

135 lines not on this page · raw message

tools/um/include/lkl_host.h new file +18 -0
new file mode 100644
index 000000000000..5fe7a64dc4dd
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_HOST_H
+#define _LKL_HOST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <lkl/asm/host_ops.h>
+#include <lkl.h>
+
+extern struct lkl_host_operations lkl_host_ops;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
tools/um/uml/Build +12 -4
index 810aa99f8409..b523923afd45 100644
@@ -8,13 +8,21 @@ KCOV_INSTRUMENT                := n
 
 include $(objtree)/include/config/auto.conf
 
-liblinux-y += execvp.o file.o helper.o irq.o main.o mem.o process.o \
-	registers.o sigio.o signal.o start_up.o time.o tty.o \
-	umid.o util.o drivers/ skas/
+liblinux-y += execvp.o file.o helper.o irq.o mem.o process.o \
+	registers.o sigio.o signal.o time.o tty.o \
+	umid.o util.o drivers/
 
 CFLAGS_signal.o += -Wframe-larger-than=4096
 
+ifndef CONFIG_UMMODE_LIB
+liblinux-y += main.o start_up.o skas/
+HEADER_ARCH 	:= x86
 liblinux-y += x86/
+else
+HEADER_ARCH 	:= um/lkl
+liblinux-y += lkl/
+endif
+
 liblinux-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
 
 export O = $(srctree)
@@ -24,7 +32,6 @@ CFLAGS := -g -O2
 
 # from arch/um/Makefile
 ARCH_DIR := arch/um
-HEADER_ARCH 	:= x86
 HOST_DIR := arch/$(HEADER_ARCH)
 ifdef CONFIG_64BIT
   KBUILD_CFLAGS += -mcmodel=large
@@ -34,6 +41,7 @@ KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \
 	-Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \
 	-Din6addr_loopback=kernel_in6addr_loopback \
 	-Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr
+KBUILD_CFLAGS := $(filter-out -Dsigprocmask=kernel_sigprocmask,$(KBUILD_CFLAGS))
 SHARED_HEADERS	:= $(ARCH_DIR)/include/shared
 MODE_INCLUDE	+= -I$(srctree)/$(ARCH_DIR)/include/shared/skas
 ARCH_INCLUDE	:= -I$(srctree)/$(SHARED_HEADERS)
tools/um/uml/lkl/Build new file +1 -0
new file mode 100644
index 000000000000..98fd6b86a085
@@ -0,0 +1 @@
+liblinux-y = registers.o unimplemented.o
tools/um/uml/lkl/registers.c new file +21 -0
new file mode 100644
index 000000000000..11573a204720
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+
+struct uml_pt_regs;
+
+int get_fp_registers(int pid, unsigned long *regs)
+{
+	return 0;
+}
+
+int save_i387_registers(int pid, unsigned long *fp_regs)
+{
+	return 0;
+}
+
+void arch_init_registers(int pid)
+{
+}
+
+void get_regs_from_mc(struct uml_pt_regs *regs, void *mc)
+{
+}
tools/um/uml/lkl/unimplemented.c new file +21 -0
new file mode 100644
index 000000000000..9da3e5c8bafb
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <generated/user_constants.h>
+
+struct uml_pt_regs;
+
+/* os-Linux/skas/process.c */
+int userspace_pid[UM_NR_CPUS];
+void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
+{}
+
+
+/* x86/os-Linux/task_size.c */
+unsigned long os_get_top_address(void)
+{
+	return 0;
+}
+
+/* start-up.c */
+void os_early_checks(void)
+{
+}
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#230 lore raw

RFC v8 16/20 um: host: add utilities functions

In reply to Hajime Tazaki

Add basic utility functions for getting a string from a kernel error code and a fprintf like function that uses the host print operation. The latter is useful for informing the user about errors that occur in the host library.

---
 tools/um/include/lkl.h |  23 +++++
 tools/um/lib/Build     |   3 +
 tools/um/lib/utils.c   | 205 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 231 insertions(+)
 create mode 100644 tools/um/lib/Build
 create mode 100644 tools/um/lib/utils.c
tools/um/include/lkl.h +23 -0
index 2417ed5ccf71..97da2d11502f 100644
@@ -27,6 +27,29 @@ extern "C" {
 #undef class
 #endif
 
+/**
+ * lkl_printf - print a message via the host print operation
+ *
+ * @fmt: printf like format string
+ */
+int lkl_printf(const char *fmt, ...);
+
+/**
+ * lkl_strerror - returns a string describing the given error code
+ *
+ * @err - error code
+ * @returns - string for the given error code
+ */
+const char *lkl_strerror(int err);
+
+/**
+ * lkl_perror - prints a string describing the given error code
+ *
+ * @msg - prefix for the error message
+ * @err - error code
+ */
+void lkl_perror(char *msg, int err);
+
 #if __LKL__BITS_PER_LONG == 64
 #define lkl_sys_fstatat lkl_sys_newfstatat
 #define lkl_sys_fstat lkl_sys_newfstat
tools/um/lib/Build new file +3 -0
new file mode 100644
index 000000000000..77acd6f55e76
@@ -0,0 +1,3 @@
+include $(objtree)/include/config/auto.conf
+
+liblinux-$(CONFIG_UMMODE_LIB) += utils.o
tools/um/lib/utils.c new file +205 -0

205 lines not on this page · raw message

Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#231 lore raw

RFC v8 17/20 um: host: posix host operations

In reply to Hajime Tazaki

This commit implements LKL host operations for POSIX hosts. The operations are implemented to be portable in various POSIX OSs.

---
 tools/um/lib/Build        |   3 +
 tools/um/lib/jmp_buf.c    |  14 ++
 tools/um/lib/posix-host.c | 272 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 289 insertions(+)
 create mode 100644 tools/um/lib/jmp_buf.c
 create mode 100644 tools/um/lib/posix-host.c
tools/um/lib/Build +3 -0
index 77acd6f55e76..dddff26a3b4e 100644
@@ -1,3 +1,6 @@
 include $(objtree)/include/config/auto.conf
+CFLAGS_posix-host.o += -D_FILE_OFFSET_BITS=64
 
 liblinux-$(CONFIG_UMMODE_LIB) += utils.o
+liblinux-$(CONFIG_UMMODE_LIB) += posix-host.o
+liblinux-$(CONFIG_UMMODE_LIB) += jmp_buf.o
tools/um/lib/jmp_buf.c new file +14 -0
new file mode 100644
index 000000000000..fcb15bbaa38a
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <setjmp.h>
+#include <lkl_host.h>
+
+void lkl_jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void))
+{
+	if (!setjmp(*((jmp_buf *)jmpb->buf)))
+		f();
+}
+
+void lkl_jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val)
+{
+	longjmp(*((jmp_buf *)jmpb->buf), val);
+}
tools/um/lib/posix-host.c new file +272 -0

272 lines not on this page · raw message

Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#232 lore raw

RFC v8 18/20 selftests/um: lkl: add test programs for library mode of UML

In reply to Hajime Tazaki

Add a simple LKL test application (boot) that starts the kernel and performs simple tests that minimally exercise the LKL API. The tests are implemented on kselftest framework, which can be invoked with

make ARCH=um SUBARCH=lkl TARGETS="um" kselftest

Additionally, this commits add a skip for headers_install for ARCH=um since UML (even with library mode) doesn't have headers install.

```
 cat /tmp/um-test.tap | sed "s/^# selftests/     \# Subtest: selftests/"
|  sed "s/^#/    /" | sed "s/version 13/version 14/" | sed "s/\(ok
[0-9]* \)/\1- /" | ./tools/testing/kunit/kunit.py parse
```

this makes tap14 converter for the kselftest results.

---
 tools/testing/selftests/Makefile    |   3 +
 tools/testing/selftests/um/Makefile |  13 +
 tools/testing/selftests/um/boot.c   | 376 ++++++++++++++++++++++++++++
 tools/testing/selftests/um/test.c   | 128 ++++++++++
 tools/testing/selftests/um/test.h   |  72 ++++++
 tools/testing/selftests/um/test.sh  | 181 +++++++++++++
 6 files changed, 773 insertions(+)
 create mode 100644 tools/testing/selftests/um/Makefile
 create mode 100644 tools/testing/selftests/um/boot.c
 create mode 100644 tools/testing/selftests/um/test.c
 create mode 100644 tools/testing/selftests/um/test.h
 create mode 100644 tools/testing/selftests/um/test.sh
tools/testing/selftests/Makefile +3 -0
index 8a917cb4426a..26b6fc800778 100644
@@ -65,6 +65,7 @@ TARGETS += timers
 endif
 TARGETS += tmpfs
 TARGETS += tpm2
+TARGETS += um
 TARGETS += user
 TARGETS += vDSO
 TARGETS += vm
@@ -154,12 +155,14 @@ endif
 # Local build cases: "make kselftest", "make -C" - headers are installed
 # in the default INSTALL_HDR_PATH usr/include.
 khdr:
+ifneq (um,$(ARCH))
 ifeq (1,$(DEFAULT_INSTALL_HDR_PATH))
 	$(MAKE) --no-builtin-rules ARCH=$(ARCH) -C $(top_srcdir) headers_install
 else
 	$(MAKE) --no-builtin-rules INSTALL_HDR_PATH=$$BUILD/usr \
 		ARCH=$(ARCH) -C $(top_srcdir) headers_install
 endif
+endif
 
 all: khdr
 	@ret=1;							\
tools/testing/selftests/um/Makefile new file +13 -0
new file mode 100644
index 000000000000..1b915f4bb751
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+top_srcdir = ../../../../
+top_objdir = $(OUTPUT)/../../
+
+CFLAGS := -fPIC -I$(top_objdir)/tools/um/include/ -I$(top_srcdir)/tools/um/include/ -g
+CFLAGS += test.c
+LDFLAGS := -pie
+LDLIBS := -L$(top_objdir)/tools/um -L$(top_srcdir)/tools/um -llinux -lpthread -lrt -lutil
+
+TEST_GEN_PROGS := boot
+
+include ../lib.mk
tools/testing/selftests/um/boot.c new file +376 -0

376 lines not on this page · raw message

tools/testing/selftests/um/test.c new file +128 -0

128 lines not on this page · raw message

tools/testing/selftests/um/test.h new file +72 -0

72 lines not on this page · raw message

tools/testing/selftests/um/test.sh new file +181 -0

181 lines not on this page · raw message

Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#233 lore raw

RFC v8 19/20 um: lkl: add block device support of UML

In reply to Hajime Tazaki

This commit adds block device support for library mode, and also added several host utilities to run a simple test program (tools/um/test/disk.c) successfully.

---
 arch/um/Kconfig                         |   4 +
 arch/um/include/asm/xor.h               |   3 +-
 arch/um/include/shared/as-layout.h      |   1 +
 arch/um/kernel/um_arch.c                |   5 +
 arch/um/lkl/include/uapi/asm/host_ops.h |   5 +
 arch/um/lkl/include/uapi/asm/unistd.h   |   2 +
 arch/um/lkl/um/setup.c                  |  12 +
 tools/testing/selftests/um/Makefile     |   5 +-
 tools/testing/selftests/um/cla.c        | 159 ++++++++
 tools/testing/selftests/um/cla.h        |  33 ++
 tools/testing/selftests/um/disk-ext4.sh |   6 +
 tools/testing/selftests/um/disk-vfat.sh |   6 +
 tools/testing/selftests/um/disk.c       | 166 +++++++++
 tools/testing/selftests/um/disk.sh      |  67 ++++
 tools/um/include/lkl.h                  | 206 +++++++++++
 tools/um/include/lkl_host.h             |   1 +
 tools/um/lib/Build                      |   1 +
 tools/um/lib/fs.c                       | 461 ++++++++++++++++++++++++
 tools/um/lib/posix-host.c               |   1 +
 tools/um/lib/utils.c                    |   2 +
 20 files changed, 1144 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/um/cla.c
 create mode 100644 tools/testing/selftests/um/cla.h
 create mode 100755 tools/testing/selftests/um/disk-ext4.sh
 create mode 100755 tools/testing/selftests/um/disk-vfat.sh
 create mode 100644 tools/testing/selftests/um/disk.c
 create mode 100755 tools/testing/selftests/um/disk.sh
 create mode 100644 tools/um/lib/fs.c
arch/um/Kconfig +4 -0
index 24c6596260de..5fb6a852d058 100644
@@ -29,6 +29,10 @@ config UMMODE_LIB
 	select UACCESS_MEMCPY
 	select ARCH_THREAD_STACK_ALLOCATOR
 	select ARCH_HAS_SYSCALL_WRAPPER
+	select VFAT_FS
+	select NLS_CODEPAGE_437
+	select NLS_ISO8859_1
+	select BTRFS_FS
 	help
 	 This mode switches a mode to build a library of UML (Linux
 	 Kernel Library/LKL).  If this is Y, the build only generates,
arch/um/include/asm/xor.h +2 -1
index 36b33d62a35d..934a576ec4b2 100644
@@ -4,4 +4,5 @@
 
 /* pick an arbitrary one - measuring isn't possible with inf-cpu */
 #define XOR_SELECT_TEMPLATE(x)	\
-	(time_travel_mode == TT_MODE_INFCPU ? &xor_block_8regs : NULL)
+	(time_travel_mode == TT_MODE_INFCPU || \
+	 (IS_ENABLED(CONFIG_UMMODE_LIB)) ? &xor_block_8regs : NULL)
arch/um/include/shared/as-layout.h +1 -0
index 5f286ef2721b..4423437a5ace 100644
@@ -57,6 +57,7 @@ extern unsigned long host_task_size;
 
 extern int linux_main(int argc, char **argv);
 extern void uml_finishsetup(void);
+extern void uml_set_args(char *args);
 
 struct siginfo;
 extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *);
arch/um/kernel/um_arch.c +5 -0
index dfc6194b5ac7..3968842346a2 100644
@@ -42,6 +42,11 @@ static void __init add_arg(char *arg)
 	strcat(command_line, arg);
 }
 
+void __init uml_set_args(char *args)
+{
+	strcat(command_line, args);
+}
+
 /*
  * These fields are initialized at boot time and not changed.
  * XXX This structure is used only in the non-SMP case.  Maybe this
arch/um/lkl/include/uapi/asm/host_ops.h +5 -0
index 85d7d4790602..c7239df7f807 100644
@@ -12,11 +12,16 @@ struct lkl_jmp_buf {
 /**
  * struct lkl_host_operations - host operations used by the Linux kernel
  *
+ * @um_devices: string containg the list of UML devices in command line
+ * format. This string is appended to the kernel command line and
+ * is provided here for convenience to be implemented by the host library.
+ *
  * These operations must be provided by a host library or by the application
  * itself.
  *
  */
 struct lkl_host_operations {
+	const char *um_devices;
 };
 
 /**
arch/um/lkl/include/uapi/asm/unistd.h +2 -0
index 6f5d67b45fbd..d777e4b597d2 100644
@@ -3,6 +3,8 @@
 #define __UM_LIBMODE_UAPI_UNISTD_H
 
 #define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SET_GET_RLIMIT
+
 #include <asm/bitsperlong.h>
 
 #if __BITS_PER_LONG == 64
arch/um/lkl/um/setup.c +12 -0
index 12b235826573..f33e9f477b7a 100644
@@ -45,13 +45,25 @@ static void __init *lkl_run_kernel(void *arg)
 	return NULL;
 }
 
+static char _cmd_line[COMMAND_LINE_SIZE];
 int __init lkl_start_kernel(struct lkl_host_operations *ops,
 			    const char *fmt, ...)
 {
+	va_list ap;
 	int ret;
 
 	lkl_ops = ops;
 
+	va_start(ap, fmt);
+	ret = vsnprintf(_cmd_line, COMMAND_LINE_SIZE, fmt, ap);
+	va_end(ap);
+
+	if (ops->um_devices)
+		strscpy(_cmd_line + ret, ops->um_devices,
+			COMMAND_LINE_SIZE - ret);
+
+	uml_set_args(_cmd_line);
+
 	init_sem = lkl_sem_alloc(0);
 	if (!init_sem)
 		return -ENOMEM;
tools/testing/selftests/um/Makefile +4 -1
index 1b915f4bb751..df9561a0b3b4 100644
@@ -4,10 +4,13 @@ top_srcdir = ../../../../
 top_objdir = $(OUTPUT)/../../
 
 CFLAGS := -fPIC -I$(top_objdir)/tools/um/include/ -I$(top_srcdir)/tools/um/include/ -g
-CFLAGS += test.c
+CFLAGS += test.c cla.c
 LDFLAGS := -pie
 LDLIBS := -L$(top_objdir)/tools/um -L$(top_srcdir)/tools/um -llinux -lpthread -lrt -lutil
 
 TEST_GEN_PROGS := boot
+TEST_PROGS := disk-ext4.sh disk-vfat.sh
+TEST_PROGS_EXTENDED := test.sh disk.sh
+TEST_GEN_FILES := disk
 
 include ../lib.mk
tools/testing/selftests/um/cla.c new file +159 -0

159 lines not on this page · raw message

tools/testing/selftests/um/cla.h new file +33 -0
new file mode 100644
index 000000000000..3d879233681f
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _LKL_TEST_CLA_H
+#define _LKL_TEST_CLA_H
+
+enum cl_arg_type {
+	CL_ARG_USER = 0,
+	CL_ARG_BOOL,
+	CL_ARG_INT,
+	CL_ARG_STR,
+	CL_ARG_STR_SET,
+	CL_ARG_IPV4,
+	CL_ARG_END,
+};
+
+struct cl_arg;
+
+typedef int (*cl_arg_parser_t)(struct cl_arg *arg, const char *value);
+
+struct cl_arg {
+	const char *long_name;
+	char short_name;
+	const char *help;
+	int has_arg;
+	enum cl_arg_type type;
+	void *store;
+	void *set;
+	cl_arg_parser_t parser;
+};
+
+int cla_parse_args(int argc, const char **argv, struct cl_arg *args);
+
+
+#endif /* _LKL_TEST_CLA_H */
tools/testing/selftests/um/disk-ext4.sh new file +6 -0
new file mode 100755
index 000000000000..a021f0efd057
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0
+
+script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+
+${script_dir}/disk.sh -t ext4
tools/testing/selftests/um/disk-vfat.sh new file +6 -0
new file mode 100755
index 000000000000..955ccec40193
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0
+
+script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+
+${script_dir}/disk.sh -t vfat
tools/testing/selftests/um/disk.c new file +166 -0

166 lines not on this page · raw message

tools/testing/selftests/um/disk.sh new file +67 -0

67 lines not on this page · raw message

tools/um/include/lkl.h +206 -0

224 lines not on this page · raw message

tools/um/include/lkl_host.h +1 -0
index 5fe7a64dc4dd..1a2794ef47a0 100644
@@ -10,6 +10,7 @@ extern "C" {
 #include <lkl.h>
 
 extern struct lkl_host_operations lkl_host_ops;
+extern char lkl_um_devs[4096];
 
 #ifdef __cplusplus
 }
tools/um/lib/Build +1 -0
index dddff26a3b4e..29491b40746c 100644
@@ -4,3 +4,4 @@ CFLAGS_posix-host.o += -D_FILE_OFFSET_BITS=64
 liblinux-$(CONFIG_UMMODE_LIB) += utils.o
 liblinux-$(CONFIG_UMMODE_LIB) += posix-host.o
 liblinux-$(CONFIG_UMMODE_LIB) += jmp_buf.o
+liblinux-$(CONFIG_UMMODE_LIB) += fs.o
tools/um/lib/fs.c new file +461 -0

461 lines not on this page · raw message

tools/um/lib/posix-host.c +1 -0
index f7c170fd3fd9..5fc7d6822a7f 100644
@@ -268,5 +268,6 @@ void *lkl_tls_get(struct lkl_tls_key *key)
 }
 
 struct lkl_host_operations lkl_host_ops = {
+	.um_devices = lkl_um_devs,
 };
 
tools/um/lib/utils.c +2 -0
index 3b38e1a95124..03841f70f73e 100644
@@ -4,6 +4,8 @@
 #include <string.h>
 #include <lkl_host.h>
 
+char lkl_um_devs[4096];
+
 static const char * const lkl_err_strings[] = {
 	[0]			= "Success",
 	[LKL_EPERM]		= "Operation not permitted",
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#234 lore raw

Re: [RFC v8 19/20] um: lkl: add block device support of UML

arch/um/Kconfig config UMMODE_LIB · line 35

Quoted 13 lines · Hajime Tazaki
arch/um/Kconfig +0 -0
index 24c6596260de..5fb6a852d058 100644
@@ -29,6 +29,10 @@ config UMMODE_LIB

  select UACCESS_MEMCPY
  select ARCH_THREAD_STACK_ALLOCATOR
  select ARCH_HAS_SYSCALL_WRAPPER

arch/um/Kconfig +4 -0
+	select VFAT_FS
+	select NLS_CODEPAGE_437
+	select NLS_ISO8859_1
+	select BTRFS_FS

That doesn't really seem to make sense - the sample might need it, but generally LKL doesn't/shouldn't?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#235 lore raw

Re: [RFC v8 19/20] um: lkl: add block device support of UML

Quoted 18 lines · Johannes Berg

arch/um/Kconfig config UMMODE_LIB · line 35

Quoted 13 lines · Hajime Tazaki
arch/um/Kconfig +0 -0
index 24c6596260de..5fb6a852d058 100644
@@ -29,6 +29,10 @@ config UMMODE_LIB

  select UACCESS_MEMCPY
  select ARCH_THREAD_STACK_ALLOCATOR
  select ARCH_HAS_SYSCALL_WRAPPER

arch/um/Kconfig +4 -0
+	select VFAT_FS
+	select NLS_CODEPAGE_437
+	select NLS_ISO8859_1
+	select BTRFS_FS

That doesn't really seem to make sense - the sample might need it, but generally LKL doesn't/shouldn't?

I'm trying to understand your comment;
Do you mean that enabling those options in Kconfig doesn't make sense ?

and if you mean the sample as sample code, is the added test case (e.g., tools/testing/selftests/um/disk.c, which is included in the same patch) for this purpose ?

-- HAjime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#236 lore raw

Re: [RFC v8 19/20] um: lkl: add block device support of UML

Quoted 15 lines · Hajime Tazaki
Quoted 14 lines

arch/um/Kconfig config UMMODE_LIB · line 35

Quoted 11 lines
arch/um/Kconfig +0 -0
@@ -29,6 +29,10 @@ config UMMODE_LIB

  select UACCESS_MEMCPY
  select ARCH_THREAD_STACK_ALLOCATOR
  select ARCH_HAS_SYSCALL_WRAPPER

arch/um/Kconfig +4 -0
+	select VFAT_FS
+	select NLS_CODEPAGE_437
+	select NLS_ISO8859_1
+	select BTRFS_FS

That doesn't really seem to make sense - the sample might need it, but generally LKL doesn't/shouldn't?

Quoted 2 lines

I'm trying to understand your comment;
Do you mean that enabling those options in Kconfig doesn't make sense ?

I mean *always* enabling them doesn't make sense. Why shouldn't somebody be allowed to build UMMODE_LIB *without* btrfs? If they have no need for btrfs, why should it select it?

I can understand that your sample code wants btrfs just to show what it can do, but IMHO it doesn't make sense to *always* enable it.

Quoted 3 lines

and if you mean the sample as sample code, is the added test case (e.g., tools/testing/selftests/um/disk.c, which is included in the same patch) for this purpose ?

yes, that's what I mean by "sample code"

joahnnes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#237 lore raw

Re: [RFC v8 19/20] um: lkl: add block device support of UML

Quoted 20 lines · Johannes Berg
Quoted 15 lines · Hajime Tazaki
Quoted 14 lines

arch/um/Kconfig config UMMODE_LIB · line 35

Quoted 11 lines
arch/um/Kconfig +4 -0
@@ -29,6 +29,10 @@ config UMMODE_LIB
  select UACCESS_MEMCPY
  select ARCH_THREAD_STACK_ALLOCATOR
  select ARCH_HAS_SYSCALL_WRAPPER
+ select VFAT_FS
+ select NLS_CODEPAGE_437
+ select NLS_ISO8859_1
+ select BTRFS_FS

That doesn't really seem to make sense - the sample might need it, but generally LKL doesn't/shouldn't?

Quoted 2 lines

I'm trying to understand your comment;
Do you mean that enabling those options in Kconfig doesn't make sense ?

Quoted 7 lines

I mean *always* enabling them doesn't make sense. Why shouldn't somebody be allowed to build UMMODE_LIB *without* btrfs? If they have no need for btrfs, why should it select it?

I can understand that your sample code wants btrfs just to show what it can do, but IMHO it doesn't make sense to *always* enable it.

I agree. I think these can stay in defconfigs but here is where a library introduces complications which I don't know how is best to handle. Should we have the defconfig in arch/um or should we have it in tools/testing/selftests/um? Or perhaps both places, one being a generic config that would be used by most applications and one customized?

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#238 lore raw

Re: [RFC v8 19/20] um: lkl: add block device support of UML

Quoted 2 lines · Octavian Purdila
Quoted 2 lines

I can understand that your sample code wants btrfs just to show what it can do, but IMHO it doesn't make sense to *always* enable it.

Btw, what I said there also didn't distinguish between "always enable it" and "always force it enabled".

Right now this patch did the latter, but the former might sort of make sense, but would take the form of a defconfig rather than a Kconfig code change.

Quoted 7 lines

I agree. I think these can stay in defconfigs but here is where a library introduces complications which I don't know how is best to handle. Should we have the defconfig in arch/um or should we have it in tools/testing/selftests/um? Or perhaps both places, one being a generic config that would be used by most applications and one customized?

Yeah, that's a question - and in that sense LKL will never be a general- purpose "library" since then you'd have to basically build it with "allyesconfig" instead of other things.

Maybe just put a note there with the tools, and maybe a defconfig, and then have some kind of detection at example/tool build or even runtime that the necessary options are selected?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#239 lore raw

Re: [RFC v8 19/20] um: lkl: add block device support of UML

Quoted 11 lines · Johannes Berg
Quoted 2 lines · Octavian Purdila
Quoted 2 lines

I can understand that your sample code wants btrfs just to show what it can do, but IMHO it doesn't make sense to *always* enable it.

Btw, what I said there also didn't distinguish between "always enable it" and "always force it enabled".

Right now this patch did the latter, but the former might sort of make sense, but would take the form of a defconfig rather than a Kconfig code change.

Thanks, I understand the situation.
I agree that using defconfig should be good in this case. Will fix this.

Quoted 7 lines
Quoted 6 lines

I agree. I think these can stay in defconfigs but here is where a library introduces complications which I don't know how is best to handle. Should we have the defconfig in arch/um or should we have it in tools/testing/selftests/um? Or perhaps both places, one being a generic config that would be used by most applications and one customized?

Quoted 7 lines

Yeah, that's a question - and in that sense LKL will never be a general- purpose "library" since then you'd have to basically build it with "allyesconfig" instead of other things.

Maybe just put a note there with the tools, and maybe a defconfig, and then have some kind of detection at example/tool build or even runtime that the necessary options are selected?

preparing multiple defconfigs (e.g., tiny, normal, allyes) would be one option for build-time selection.

Other possibilities (rather radical) could be to prepare multiple sub-libraries (liblinux-core.so liblinux-fs-ext4.so, liblinux-net.so, etc) so that users can pick only necessary codes when it's build (or open during runtime). This needs to handle dependencies as kernel modules do, thus it's more complicated once we have this ?

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#240 lore raw

Re: [RFC v8 19/20] um: lkl: add block device support of UML

Quoted 36 lines · Hajime Tazaki
Quoted 11 lines · Johannes Berg
Quoted 2 lines · Octavian Purdila
Quoted 2 lines

I can understand that your sample code wants btrfs just to show what it can do, but IMHO it doesn't make sense to *always* enable it.

Btw, what I said there also didn't distinguish between "always enable it" and "always force it enabled".

Right now this patch did the latter, but the former might sort of make sense, but would take the form of a defconfig rather than a Kconfig code change.

Thanks, I understand the situation.
I agree that using defconfig should be good in this case. Will fix this.

Quoted 7 lines
Quoted 6 lines

I agree. I think these can stay in defconfigs but here is where a library introduces complications which I don't know how is best to handle. Should we have the defconfig in arch/um or should we have it in tools/testing/selftests/um? Or perhaps both places, one being a generic config that would be used by most applications and one customized?

Quoted 7 lines

Yeah, that's a question - and in that sense LKL will never be a general- purpose "library" since then you'd have to basically build it with "allyesconfig" instead of other things.

Maybe just put a note there with the tools, and maybe a defconfig, and then have some kind of detection at example/tool build or even runtime that the necessary options are selected?

Quoted 9 lines

preparing multiple defconfigs (e.g., tiny, normal, allyes) would be one option for build-time selection.

Other possibilities (rather radical) could be to prepare multiple sub-libraries (liblinux-core.so liblinux-fs-ext4.so, liblinux-net.so, etc) so that users can pick only necessary codes when it's build (or open during runtime). This needs to handle dependencies as kernel modules do, thus it's more complicated once we have this ?

Yes, this would be nice as it would allow distributions to build a package for liblinux and simplify building applications with it. We may be able to reuse some of the module work, maybe just the dependency part as relocation should already be handled.

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#241 lore raw

RFC v8 20/20 um: lkl: add documentation

In reply to Hajime Tazaki

A document describing brief introduction of LKL, why it is needed, and how it is used is added. The document is located under uml/ directory.

---
 Documentation/virt/uml/lkl.txt | 48 ++++++++++++++++++++++++++++++++++
 MAINTAINERS                    | 10 +++++++
 2 files changed, 58 insertions(+)
 create mode 100644 Documentation/virt/uml/lkl.txt
Documentation/virt/uml/lkl.txt new file +48 -0
new file mode 100644
index 000000000000..4942b7f093c5
@@ -0,0 +1,48 @@
+
+Introduction
+============
+
+Library mode of UML, a.k.a. LKL (Linux Kernel Library), is aiming to allow
+reusing the Linux kernel code as extensively as possible with minimal effort and
+reduced maintenance overhead.
+
+Examples of how LKL can be used are: creating userspace applications (running on
+Linux and other operating systems) that can read or write Linux filesystems or
+can use the Linux networking stack, creating kernel drivers for other operating
+systems that can read Linux filesystems, bootloaders support for reading/writing
+Linux filesystems, etc.
+
+With LKL, the kernel code is compiled into an object file that can be directly
+linked by applications. The API offered by LKL is based on the Linux system call
+interface.
+
+LKL is implemented as one of the mode of UML (arch/um), and it internally uses
+sub-architecture (SUBARCH) of UML (SUBARCH=lkl). It uses host operations
+defined by the application or a host library (tools/um).
+
+
+Supported hosts
+===============
+
+The supported host for now is Linux (x86 architecture) userspace applications.
+
+
+Building LKL the host library and LKL applications
+==================================================
+
+    $ make ARCH=um SUBARCH=lkl defconfig
+    $ make ARCH=um SUBARCH=lkl
+
+will build LKL as a object file, it will install it in tools/um together with
+the headers files in tools/um/include then will build the host library, tests
+and a few of application examples:
+
+* tools/testing/selftests/um/boot.c - a simple applications that uses LKL and
+  exercises the basic LKL APIs
+
+* tools/testing/selftests/um/disk.c - a simple applications that tests LKL and
+  exercises the basic filesystem-related LKL APIs
+
+Those tests can run with the following kselftest command:
+
+    $ make ARCH=um SUBARCH=lkl TARGETS="um" kselftest
MAINTAINERS +10 -0
index 00836f6452f0..8587a9715020 100644
@@ -18613,6 +18613,16 @@ F:	arch/um/
 F:	arch/x86/um/
 F:	fs/hostfs/
 
+USER-MODE LINUX (UML) LIBRARY MODE
+M:	Octavian Purdila <[email protected]>
+M:	Hajime Tazaki <[email protected]>
+L:	[email protected]
+S:	Maintained
+T:	https://github.com/lkl/linux
+F:	arch/um/lkl/
+F:	tools/testing/selftests/um/
+F:	tools/um/
+
 USERSPACE COPYIN/COPYOUT (UIOVEC)
 M:	Alexander Viro <[email protected]>
 S:	Maintained
Signature · 7 lines
2.21.0 (Apple Git-122.2)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
maintainer
#242 lore raw
In reply to Hajime Tazaki

Hi,

So I'm still a bit lost here with this, and what exactly you're doing in places.

For example, you simulate a single CPU ("depends on !SMP", and anyway UML only supports that right now), yet on the other hand do a *LOT* of extra work with lkl_sem, lkl_thread, lkl_mutex, and all that. It's not clear to me why? Are you trying to model kernel threads as actual userspace pthreads, but then run only one at a time by way of exclusive locking?

I think we probably need a bit more architecture introduction here in the cover letter or the documentation patch. The doc patch basically just explains what it does, but not how it does anything, or why it was done in this way.

For example, I'm asking myself:
* Why NOMMU? UML doesn't really do _much_ with memory protection unless you add userspace, which you don't have.
* Why pthreads and all? You already require jump_buf, so UML's switch_threads() ought to be just fine for scheduling? It almost seems like you're doing this just so you can serialize against "other threads" (application threads), but wouldn't that trivially be handled by the application? You could let it hook into switch_to() or something, but why should a single "LKL" CPU ever require multiple threads? Seems to me that the userspace could be required to "lkl_run()" or so (vs. lkl_start()). Heck, you could even exit lkl_run() every time you switch tasks in the kernel, and leave scheduling the kernel vs. the application entirely up to the application? (A trivial application would be simply doing something like "while (1) { lkl_run(); pause(); }" mimicking the idle loop of UML.

And - kind of the theme behind all these questions - why is this not making UML actually be a binary that uses LKL? If the design were like what I'm alluding to above, that should actually be possible? Why should it not be possible? Why would it not be desirable? (I'm actually thinking that might be really useful to some of the things I'm doing.) Yes, if the application actually supports userspace running then it has som limitations on what it can do (in particular wrt. signals etc.), but that could be documented and would be OK?

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#243 lore raw

Hello,

First of all, thanks for all the comments to the patchset which has been a bit stale. I'll reply them.

Quoted 13 lines · Johannes Berg

Hi,

So I'm still a bit lost here with this, and what exactly you're doing in places.

For example, you simulate a single CPU ("depends on !SMP", and anyway UML only supports that right now), yet on the other hand do a *LOT* of extra work with lkl_sem, lkl_thread, lkl_mutex, and all that. It's not clear to me why? Are you trying to model kernel threads as actual userspace pthreads, but then run only one at a time by way of exclusive locking?

Quoted 4 lines

I think we probably need a bit more architecture introduction here in the cover letter or the documentation patch. The doc patch basically just explains what it does, but not how it does anything, or why it was done in this way.

We didn't write down the details, which are already described in the LKL's paper (*1). But I think we can extract/summarize some of important information from the paper to the document so that the design is more understandable.

*1 LKL's paper (pointer is also in the cover letter)
https://www.researchgate.net/profile/Nicolae_Tapus2/publication/224164682_LKL_The_Linux_kernel_library/links/02bfe50fd921ab4f7c000000.pdf

Quoted 3 lines

For example, I'm asking myself:
* Why NOMMU? UML doesn't really do _much_ with memory protection unless you add userspace, which you don't have.

My interpretation of MMU/NOMMU is like this;

With (emulated) MMU architecture you will have more smooth integration with other subsystems of kernel tree, because some subsystems/features are written with "#ifdef CONFIG_MMU". While NOMMU doesn't, it will bring a simplified design with better portability.

LKL takes rather to benefit better portability.

Quoted 5 lines

* Why pthreads and all? You already require jump_buf, so UML's switch_threads() ought to be just fine for scheduling? It almost seems like you're doing this just so you can serialize against "other threads" (application threads), but wouldn't that trivially be handled by the application? You could let it hook into switch_to() or

Quoted 8 lines

something, but why should a single "LKL" CPU ever require multiple threads? Seems to me that the userspace could be required to "lkl_run()" or so (vs. lkl_start()). Heck, you could even exit lkl_run() every time you switch tasks in the kernel, and leave scheduling the kernel vs. the application entirely up to the application? (A trivial application would be simply doing something like "while (1) { lkl_run(); pause(); }" mimicking the idle loop of UML.

There is a description about this design choice in the LKL paper (*1);

"implementations based on setjmp - longjmp require usage of a single stack space partitioned between all threads. As the Linux kernel uses deep stacks (especially in the VFS layer), in an environment with small stack sizes (e.g. inside another operating system's kernel) this will place a very low limit on the number of possible threads."

(from page 2, Section II, 2) Thread Support)

This is a reason of using pthread as a context primitive.

And instead of manually doing lkl_run() to schedule threads and relying on host scheduler, LKL associates each kernel thread with a host-provided semaphore so that Linux scheduler has a control of host scheduler (prepared by pthread).

This is also described (and hasn't changed since then) in the paper *1 (from page 2, Section II, 3) Thread Switching).

Quoted 8 lines

And - kind of the theme behind all these questions - why is this not making UML actually be a binary that uses LKL? If the design were like what I'm alluding to above, that should actually be possible? Why should it not be possible? Why would it not be desirable? (I'm actually thinking that might be really useful to some of the things I'm doing.) Yes, if the application actually supports userspace running then it has som limitations on what it can do (in particular wrt. signals etc.), but that could be documented and would be OK?

Let me try to describe how I think why not just generate liblinux.so from current UML.

Making UML to build a library, which has been a long wanted features, can be started;

I think there are several functions which the library offers;

- applications can link the library and call functions in the library
- the library will be used as a replacement of libc.a for syscall operations

to design that with UML, what we need to do are;

1) change Makefile to output liblinux.a
we faced linker script issue, which is related with generating relocatable object in the middle.

2) make the linker-script clean with 2-stage build we fix the linker issues of (1)

3) expose syscall as a function call conflicts names (link-time and compile-time conflicts)

4) header rename, object localization
to fix the issue (3)

This is a common set of modifications to a library of UML.

Other parts are a choice of design, I believe.
Because a library is more _reusable_ than an executable (by it means), the choice of LKL is to be portable, which the current UML doesn't pursue it extensibly (focus on intel platforms). Thus,

5) memory: NOMMU
6) schedule (of irq/thread): pthread-based rather than setjmp/longjmp

Implementing with alternate options 5) and 6) (MMU, jmpbuf) diminishes the strength of LKL, which we would like to avoid. But as you mentioned, nothing prevents us to implement the alternate options 5) and 6) so, we can share the common part (1-4) if we will start to implement.

I hope this makes it a bit clear, but let me know if you found anything unclear.

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#244 lore raw

Hi,

Quoted 2 lines

First of all, thanks for all the comments to the patchset which has been a bit stale. I'll reply them.

Yeah, sorry. I had it marked unread ("to look at") since you posted it.

Quoted 7 lines

We didn't write down the details, which are already described in the LKL's paper (*1). But I think we can extract/summarize some of important information from the paper to the document so that the design is more understandable.

*1 LKL's paper (pointer is also in the cover letter)
https://www.researchgate.net/profile/Nicolae_Tapus2/publication/224164682_LKL_The_Linux_kernel_library/links/02bfe50fd921ab4f7c000000.pdf

OK, I guess I should take a look. Probably I never did, always thinking that it was more of an overview than technical details and design decisions.

Quoted 9 lines

My interpretation of MMU/NOMMU is like this;

With (emulated) MMU architecture you will have more smooth integration with other subsystems of kernel tree, because some subsystems/features are written with "#ifdef CONFIG_MMU". While NOMMU doesn't, it will bring a simplified design with better portability.

LKL takes rather to benefit better portability.

I don't think it *matters* so much for portability? I mean, every system under the sun is going to allow some kind of "mprotect", right? You don't really want to port LKL to systems that don't have even that?

Quoted 23 lines
Quoted 5 lines

 * Why pthreads and all? You already require jump_buf, so UML's switch_threads() ought to be just fine for scheduling? It almost seems like you're doing this just so you can serialize against "other threads" (application threads), but wouldn't that trivially be handled by the application? You could let it hook into switch_to() or

Quoted 8 lines

   something, but why should a single "LKL" CPU ever require multiple threads? Seems to me that the userspace could be required to "lkl_run()" or so (vs. lkl_start()). Heck, you could even exit lkl_run() every time you switch tasks in the kernel, and leave scheduling the kernel vs. the application entirely up to the application? (A trivial application would be simply doing something like "while (1) { lkl_run(); pause(); }" mimicking the idle loop of UML.

There is a description about this design choice in the LKL paper (*1);

  "implementations based on setjmp - longjmp require usage of a single stack space partitioned between all threads. As the Linux kernel uses deep stacks (especially in the VFS layer), in an environment with small stack sizes (e.g. inside another operating system's kernel) this will place a very low limit on the number of possible threads."

Quoted 3 lines

(from page 2, Section II, 2) Thread Support)

This is a reason of using pthread as a context primitive.

That impliciation (setjmp doesnt do stacks, so must use pthread) really isn't true, you also have posix contexts or windows fibers. That would probably be much easier to understands, since real threads imply that you have actual concurrency, which _shouldn't_ be true in the case of Linux emulated as being on a single CPU.

Perhaps that just means you chose the wrong abstraction.

In usfstl (something I've been working on) for example, we have an abstraction called (execution) "contexts", and they can be implemented using pthreads, fibers, or posix contexts, and you switch between them.

(see https://github.com/linux-test-project/usfstl/blob/main/src/ctx-common.c)

Using real pthreads implies that you have real threading, but then you need access to real mutexes, etc.

If your abstraction was instead "switch context" then you could still implement it using pthreads+mutexes, or you could implement it using fibers on windows, or posix contexts - but you'd have a significantly reduced API surface, since you'd only expose __switch_to() or similar, and maybe a new stack allocation etc.

Additionally, I do wonder how UML does this now, it *does* use setjmp, so are you saying it doesn't properly use the kernel stacks?

Quoted 4 lines

And instead of manually doing lkl_run() to schedule threads and relying on host scheduler, LKL associates each kernel thread with a host-provided semaphore so that Linux scheduler has a control of host scheduler (prepared by pthread).

Right.

That's in line with what I did in my test framework in
https://github.com/linux-test-project/usfstl/blob/main/src/ctx-pthread.c

but like I said above, I think it's the wrong abstraction. Your abstraction should be "switch context" (or "switch thread"), not dealing with pthread, mutexes, etc.

Quoted 12 lines
Quoted 8 lines

And - kind of the theme behind all these questions - why is this not making UML actually be a binary that uses LKL? If the design were like what I'm alluding to above, that should actually be possible? Why should it not be possible? Why would it not be desirable? (I'm actually thinking that might be really useful to some of the things I'm doing.) Yes, if the application actually supports userspace running then it has som limitations on what it can do (in particular wrt. signals etc.), but that could be documented and would be OK?

Let me try to describe how I think why not just generate liblinux.so from current UML.

Quoted 7 lines

Making UML to build a library, which has been a long wanted features, can be started;

I think there are several functions which the library offers;

- applications can link the library and call functions in the library

Right.

Quoted 1 line

- the library will be used as a replacement of libc.a for syscall operations

Not sure I see this, is that really useful? I mean, most applications don't live "standalone" in their own world? Dunno. Maybe it's useful.

Quoted 3 lines

to design that with UML, what we need to do are;

1) change Makefile to output liblinux.a

or liblinux.so, I guess, dynamic linking should be ok.

Quoted 6 lines

we faced linker script issue, which is related with generating relocatable object in the middle.

2) make the linker-script clean with 2-stage build we fix the linker issues of (1)

Quoted 7 lines

3) expose syscall as a function call conflicts names (link-time and compile-time conflicts)

4) header rename, object localization
to fix the issue (3)

This is a common set of modifications to a library of UML.

All of this is just _build_ issues. It doesn't mean you couldn't take some minimal code + liblinux.a and link it to get a "linux" equivalent to the current UML?

TBH, I started thinking that it might be _really_ nice to be able to write an application that's *not quite UML* but has all the properties of UML built into it, i.e. can run userspace etc.

Quoted 5 lines

Other parts are a choice of design, I believe.
Because a library is more _reusable_ than an executable (by it means), the choice of LKL is to be portable, which the current UML doesn't pursue it extensibly (focus on intel platforms).

I don't think this really conflicts.

You could have a liblinux.a/liblinux.so and some code that links it all together to get "linux" (UML). Having userspace running inside the UML (liblinux) might only be supported on x86 for now, MMU vs. NOMMU might be something that's configurable at build time, and if you pick NOMMU you cannot run userspace either, etc.

But conceptually, why wouldn't it be possible to have a liblinux.so that *does* build with MMU and userspace support, and UML is a wrapper around it?

Quoted 2 lines

I hope this makes it a bit clear, but let me know if you found anything unclear.

See above, I guess :)

Thanks for all the discussion!

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#245 lore raw
Quoted 2 lines · Johannes Berg

Hi,

Hi Johannes,

Quoted 7 lines
Quoted 7 lines

My interpretation of MMU/NOMMU is like this;

With (emulated) MMU architecture you will have more smooth integration with other subsystems of kernel tree, because some subsystems/features are written with "#ifdef CONFIG_MMU". While NOMMU doesn't, it will bring a simplified design with better portability.

Quoted 6 lines
Quoted 1 line

LKL takes rather to benefit better portability.

I don't think it *matters* so much for portability? I mean, every system under the sun is going to allow some kind of "mprotect", right? You don't really want to port LKL to systems that don't have even that?

One use case where this matters are non OS environments such as bootloaders [1], running on bare-bone hardware or kernel drivers [2, 3]. IMO it would be nice to keep these properties.

[1] https://www.freelists.org/post/linux-kernel-library/UEFI-LKL-port
[2] https://github.com/lkl/lkl-win-fsd
[3] https://www.haiku-os.org/tags/lkl-haiku-fsd/

Quoted 41 lines
Quoted 23 lines
Quoted 5 lines

* Why pthreads and all? You already require jump_buf, so UML's switch_threads() ought to be just fine for scheduling? It almost seems like you're doing this just so you can serialize against "other threads" (application threads), but wouldn't that trivially be handled by the application? You could let it hook into switch_to() or

Quoted 8 lines

something, but why should a single "LKL" CPU ever require multiple threads? Seems to me that the userspace could be required to "lkl_run()" or so (vs. lkl_start()). Heck, you could even exit lkl_run() every time you switch tasks in the kernel, and leave scheduling the kernel vs. the application entirely up to the application? (A trivial application would be simply doing something like "while (1) { lkl_run(); pause(); }" mimicking the idle loop of UML.

There is a description about this design choice in the LKL paper (*1);

"implementations based on setjmp - longjmp require usage of a single stack space partitioned between all threads. As the Linux kernel uses deep stacks (especially in the VFS layer), in an environment with small stack sizes (e.g. inside another operating system's kernel) this will place a very low limit on the number of possible threads."

Quoted 3 lines

(from page 2, Section II, 2) Thread Support)

This is a reason of using pthread as a context primitive.

That impliciation (setjmp doesnt do stacks, so must use pthread) really isn't true, you also have posix contexts or windows fibers. That would probably be much easier to understands, since real threads imply that you have actual concurrency, which _shouldn't_ be true in the case of Linux emulated as being on a single CPU.

Perhaps that just means you chose the wrong abstraction.

In usfstl (something I've been working on) for example, we have an abstraction called (execution) "contexts", and they can be implemented using pthreads, fibers, or posix contexts, and you switch between them.

(see https://github.com/linux-test-project/usfstl/blob/main/src/ctx-common.c)

Quoted 9 lines

Using real pthreads implies that you have real threading, but then you need access to real mutexes, etc.

If your abstraction was instead "switch context" then you could still implement it using pthreads+mutexes, or you could implement it using fibers on windows, or posix contexts - but you'd have a significantly reduced API surface, since you'd only expose __switch_to() or similar, and maybe a new stack allocation etc.

You are right. When I started the implementation for ucontext it was obvious that it would be much simpler to have abstractions closer to what Linux has (alloc, free and switch threads). But I never got to finish that and then things went into a different direction.

Quoted 3 lines

Additionally, I do wonder how UML does this now, it *does* use setjmp, so are you saying it doesn't properly use the kernel stacks?

To clarify a bit the statement in the paper, the context there was that we should push the thread implementation to the application/environment we run rather than providing "LKL" threads. This was particularly important for running LKL in other OSes kernel drivers. But you are right, we can use the switch abstraction and implement it with threads and mutexes for those environments where it helps.

Quoted 42 lines
Quoted 3 lines

to design that with UML, what we need to do are;

1) change Makefile to output liblinux.a

or liblinux.so, I guess, dynamic linking should be ok.

Quoted 6 lines

we faced linker script issue, which is related with generating relocatable object in the middle.

2) make the linker-script clean with 2-stage build we fix the linker issues of (1)

Quoted 7 lines

3) expose syscall as a function call conflicts names (link-time and compile-time conflicts)

4) header rename, object localization
to fix the issue (3)

This is a common set of modifications to a library of UML.

All of this is just _build_ issues. It doesn't mean you couldn't take some minimal code + liblinux.a and link it to get a "linux" equivalent to the current UML?

TBH, I started thinking that it might be _really_ nice to be able to write an application that's *not quite UML* but has all the properties of UML built into it, i.e. can run userspace etc.

Quoted 5 lines

Other parts are a choice of design, I believe.
Because a library is more _reusable_ than an executable (by it means), the choice of LKL is to be portable, which the current UML doesn't pursue it extensibly (focus on intel platforms).

I don't think this really conflicts.

You could have a liblinux.a/liblinux.so and some code that links it all together to get "linux" (UML). Having userspace running inside the UML (liblinux) might only be supported on x86 for now, MMU vs. NOMMU might be something that's configurable at build time, and if you pick NOMMU you cannot run userspace either, etc.

Quoted 4 lines

But conceptually, why wouldn't it be possible to have a liblinux.so that *does* build with MMU and userspace support, and UML is a wrapper around it?

This is an interesting idea. Conceptually I think it is possible. There are lots of details to be figured out before we do this. I think that having a NOMMU version could be a good step in the right direction, especially since I think a liblinux.so has more NOMMU usecases than MMU usecases - but I haven't given too much thought to the MMU usecases.

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#246 lore raw

Hi,

Quoted 3 lines

One use case where this matters are non OS environments such as bootloaders [1], running on bare-bone hardware or kernel drivers [2, 3]. IMO it would be nice to keep these properties.

OK, that makes sense. Still, it seems it could be a compile-time decision, and doesn't necessarily mean LKL has to be NOMMU, just that it could support both?

I'm really trying to see if we can't get UML to be a user of LKL. IMHO that would be good for the code, and even be good for LKL since then it's maintained as part of UML as well, not "just" as its own use case.

Quoted 10 lines
Quoted 5 lines

If your abstraction was instead "switch context" then you could still implement it using pthreads+mutexes, or you could implement it using fibers on windows, or posix contexts - but you'd have a significantly reduced API surface, since you'd only expose __switch_to() or similar, and maybe a new stack allocation etc.

You are right. When I started the implementation for ucontext it was obvious that it would be much simpler to have abstractions closer to what Linux has (alloc, free and switch threads). But I never got to finish that and then things went into a different direction.

OK, sounds like you came to the same conclusion, more or less.

Quoted 11 lines
Quoted 3 lines

Additionally, I do wonder how UML does this now, it *does* use setjmp, so are you saying it doesn't properly use the kernel stacks?

To clarify a bit the statement in the paper, the context there was that we should push the thread implementation to the application/environment we run rather than providing "LKL" threads. This was particularly important for running LKL in other OSes kernel drivers. But you are right, we can use the switch abstraction and implement it with threads and mutexes for those environments where it helps.

Right - like I pointed to USFSTL framework, you could have posix ucontext, fiber and pthread at least, and obviously other things in other environments (ThreadX anyone? ;-) )

Quoted 11 lines
Quoted 4 lines

But conceptually, why wouldn't it be possible to have a liblinux.so that *does* build with MMU and userspace support, and UML is a wrapper around it?

This is an interesting idea. Conceptually I think it is possible. There are lots of details to be figured out before we do this. I think that having a NOMMU version could be a good step in the right direction, especially since I think a liblinux.so has more NOMMU usecases than MMU usecases - but I haven't given too much thought to the MMU usecases.

Yeah, maybe UML would be the primary use case. I have been thinking that there would be cases where you could combine kunit and having userspace though, or unit-style testing but not with kunit which is "inside" the kernel, but instead having the test code more "outside" the test kernel. That's all kind of handwaving though and not really that crystallized in my mind.

That said, I'm not entirely sure NOMMU would be the right path towards this - if we do want to go this route it'll probably need changes in both LKL and UML to converge to this point, and at least build it into the abstractions.

For example the "idle" abstraction discussed elsewhere (is it part of the app or part of the kernel?), or the thread discussion above (it is part of the app but how is it implemented?) etc.

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

#247 lore raw

Hello,

Quoted 40 lines · Johannes Berg

Hi,

Quoted 3 lines

One use case where this matters are non OS environments such as bootloaders [1], running on bare-bone hardware or kernel drivers [2, 3]. IMO it would be nice to keep these properties.

OK, that makes sense. Still, it seems it could be a compile-time decision, and doesn't necessarily mean LKL has to be NOMMU, just that it could support both?

I'm really trying to see if we can't get UML to be a user of LKL. IMHO that would be good for the code, and even be good for LKL since then it's maintained as part of UML as well, not "just" as its own use case.

Quoted 10 lines
Quoted 5 lines

If your abstraction was instead "switch context" then you could still implement it using pthreads+mutexes, or you could implement it using fibers on windows, or posix contexts - but you'd have a significantly reduced API surface, since you'd only expose __switch_to() or similar, and maybe a new stack allocation etc.

You are right. When I started the implementation for ucontext it was obvious that it would be much simpler to have abstractions closer to what Linux has (alloc, free and switch threads). But I never got to finish that and then things went into a different direction.

OK, sounds like you came to the same conclusion, more or less.

Quoted 11 lines
Quoted 3 lines

Additionally, I do wonder how UML does this now, it *does* use setjmp, so are you saying it doesn't properly use the kernel stacks?

To clarify a bit the statement in the paper, the context there was that we should push the thread implementation to the application/environment we run rather than providing "LKL" threads. This was particularly important for running LKL in other OSes kernel drivers. But you are right, we can use the switch abstraction and implement it with threads and mutexes for those environments where it helps.

Quoted 3 lines

Right - like I pointed to USFSTL framework, you could have posix ucontext, fiber and pthread at least, and obviously other things in other environments (ThreadX anyone? ;-) )

I also have an idea for a ThreadX in future, which also implements actual context in the application/environment/host side (not in kernel side, as others do). Though this environment may not provide mprotect-like features, there is still a value that the application can run Linux code (e.g., network stack) for instance.

# This story is about our old work of network simulation.
https://lwn.net/Articles/639333/

Quoted 19 lines
Quoted 11 lines
Quoted 4 lines

But conceptually, why wouldn't it be possible to have a liblinux.so that *does* build with MMU and userspace support, and UML is a wrapper around it?

This is an interesting idea. Conceptually I think it is possible. There are lots of details to be figured out before we do this. I think that having a NOMMU version could be a good step in the right direction, especially since I think a liblinux.so has more NOMMU usecases than MMU usecases - but I haven't given too much thought to the MMU usecases.

Yeah, maybe UML would be the primary use case. I have been thinking that there would be cases where you could combine kunit and having userspace though, or unit-style testing but not with kunit which is "inside" the kernel, but instead having the test code more "outside" the test kernel. That's all kind of handwaving though and not really that crystallized in my mind.

Quoted 8 lines

That said, I'm not entirely sure NOMMU would be the right path towards this - if we do want to go this route it'll probably need changes in both LKL and UML to converge to this point, and at least build it into the abstractions.

For example the "idle" abstraction discussed elsewhere (is it part of the app or part of the kernel?), or the thread discussion above (it is part of the app but how is it implemented?) etc.

I agree that LKL (or the library mode) can conceptually offer both NOMMU/MMU capabilities.

I also think that NOMMU library could be the first step and a minimum product as MMU implementation may involve a lot of refactoring which may need more consideration to the current codebase.

We tried with MMU mode library, by sharing build system (Kconfig/Makefile) and runtime facilities (thread/irq/memory). But, we could only do share irq handling for this first step.

When we implement the MMU mode library in future, we may come up with another abstraction/refactoring into the UML design, which could be a good outcome. But I think it is beyond the minimum given (already) big changes with the current patchset.

-- Hajime

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um

maintainer
#248 lore raw

Hi,

Quoted 5 lines

I also have an idea for a ThreadX in future, which also implements actual context in the application/environment/host side (not in kernel side, as others do). Though this environment may not provide mprotect-like features, there is still a value that the application can run Linux code (e.g., network stack) for instance.

Heh. Right.

Quoted 7 lines

I agree that LKL (or the library mode) can conceptually offer both NOMMU/MMU capabilities.

I also think that NOMMU library could be the first step and a minimum product as MMU implementation may involve a lot of refactoring which may need more consideration to the current codebase.

Quoted 8 lines

We tried with MMU mode library, by sharing build system (Kconfig/Makefile) and runtime facilities (thread/irq/memory). But, we could only do share irq handling for this first step.

When we implement the MMU mode library in future, we may come up with another abstraction/refactoring into the UML design, which could be a good outcome. But I think it is beyond the minimum given (already) big changes with the current patchset.

Well, arguably that depends on how you look at it.

Understandably, you're looking at this from the POV of getting an "MVP" (minimum viable product) into mainline as soon as possible.

I can understand why you would do that, and this patchset achieves it:
you get an LKL in mainline that's useful, even if it doesn't achieve the best possible architecture and code sharing.

But look at it from the opposite side, from mainline's view (at least in my opinion, others may disagree): getting an LKL (whether as an MVP or not) isn't really that important! Getting the architecture and code sharing right are likely the *primary* goals for mainline this integration.

So from my POV it's *more important* to get the shared facilities, proper abstraction and refactoring right, likely to the point where UML is actually "small binary using the library" (in some fashion). Even if that initially means there actually *won't* be NOMMU mode and a library that's useful for the LKL use cases.

Yes, that's the longer road into mainline, but it also means that each step along the way is actually useful to mainline, I'm assuming here that the necessary code refactoring, abstraction, etc. will by itself provide some value to UML, but given the messy state it's in, I think that's almost certainly going to be true.

So a sense "getting LKL into UML" is at odds with "get LKL working quickly". However, doing it this way may ultimately get it into mainline faster because it's a much easier incremental route. Say you want to get all this thread stuff out of the way that we discussed - then if you need to keep UML working but *using* the abstraction you're adding (in order to work towards the goal of it using the library) then it becomes fairly obvious that you cannot use the abstraction that you have with pthreads, mutexes, and semaphores exposed via APIs, but need to build the API on "thread switching" primitives instead. I would expect similar things to be true for other places.

Now, are you/we up for that? I don't know. On the one hand, I know you're persistent and interested in this, but on the other hand it's somewhat at odds with your goals. I believe for mainline it'd be better because the code is no worse off each step along the way.

Taking the thread example again, if we have a thread switching abstraction and an implementation in UML, worst case (e.g. if you lose interest) is that it's a somewhat pointless abstraction there, but it doesn't really make the code significantly worse or more complex.

OTOH, having what we have now with pthreads/mutexes/semaphores *does* make the code significantly more complex and harder to maintain (IMHO) because it adds all kinds of special cases, and they're somewhat more difficult to exercise (yes, there are examples, still).

In any case, I don't think I'm the one making the decisions here, so take this with a grain of salt.

johannes

_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um