Skip to contentSkip to conversation

Unifying LKL into UML

RFC PATCH Superseded Hajime Tazaki 10 participants 132 messages Oct 23, 2019 – Mar 2, 2020 Page 1 of 2

Subsystems (16)
Documentation x86 Kbuild Library code +12 more subsystems

v1 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

cover Unifying LKL into UML

This RFC patchset is to ask opinions from UML people, whether LKL codes is good to integrate into UML code base. We wish to have any kind of feedback from your kind reviews. There are numbers of commits which should be asked for reviews to other mailing lists; we will do it later once we got discussed in this mailing list.

# sorry for the long list of patches: we can make it smaller by only
  including basic set of LKL (e.g., removing foreign OS support, etc) if
  you wish.

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 just 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.

1. Put LKL code under arch/um (arch/um/lkl), and build it in a separate way from UML.
2. Share common parts of implementation between UML and LKL.
3. Reimplement UML features with LKL API (if we wish)

For the step 1, we put LKL as one of SUBARCH in order to make less effort to integrate (make ARCH=um SUBARCH=lkl). The modification to existing UML code is trying to be minimized.

The RFC patches also includes and a bit of step 2 as a proof of possibility to share the code. For this, we used the virtio device code of LKL and use it from UML by enabling virtio-mmio driver with UML code.

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

% cd tools/lkl
% make

will build LKL as a object file, it will install it in tools/lkl/lib together with the headers files in tools/lkl/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

* tests/net-test - a simple applications that uses network feature of LKL and exercises the basic network-related APIs

* fs2tar - a tool that converts a filesystem image to a tar archive

* cptofs/cpfromfs - a tool that copies files to/from a filesystem image

% 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 POSIX and Windows 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 (not included in this RFC) 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 73625ed66389d4c620520058d828f43a93ab4d0c:

um: irq: Fix LAST_IRQ usage in init_IRQ() (2019-09-16 08:38:58 +0200)

are available in the Git repository at:

git://github.com/thehajime/linux d380ec02dd0cd97afe08706093b59329e6b09fe2
https://github.com/thehajime/linux/tree/upstream-to-uml-5.5-rc1

Akira Moroo (2):
Revert "vmlinux.lds.h: remove stale <linux/export.h> include" um lkl: use ARCH=um SUBARCH=lkl for tools/lkl

Andreas Abel (1):
kallsyms: Add a config option to select section for kallsyms

Hajime Tazaki (9):
lkl: Android ARM (arm/arm64) support
Revert "export.h: remove code for prefixing symbols with underscore" Revert "linux/linkage.h: replace VMLINUX_SYMBOL_STR() with

    __stringify()"

Revert "vmlinux.lds.h: remove no-op macro VMLINUX_SYMBOL()" Revert "kbuild: remove CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" Revert "kallsyms: remove symbol prefix support"
um lkl: add CI tests
um: use lkl virtio_net_tap device as UML device
um: add lkl virtio-blk device

Octavian Purdila (34):
asm-generic: atomic64: allow using generic atomic64 on 64bit platforms
kbuild: allow architectures to automatically define kconfig symbols
lkl: architecture skeleton for Linux kernel library
lkl: host interface
lkl: memory handling
lkl: kernel threads support
lkl: interrupt support
lkl: system call interface and application API
lkl: timers, time and delay support
lkl: memory mapped I/O support
lkl: basic kernel console support
lkl: initialization and cleanup
lkl: plug in the build system
lkl tools: skeleton for host side library, tests and tools lkl tools: host lib: add utilities functions
lkl tools: host lib: memory mapped I/O helpers
lkl tools: host lib: virtio devices
lkl tools: host lib: virtio block device
lkl tools: host lib: filesystem helpers
lkl tools: host lib: posix host operations
lkl tools: "boot" test
lkl tools: tool that converts a filesystem image to tar lkl tools: tool that reads/writes to/from a filesystem image lkl tools: virtio: add network device support
lkl: add support for Windows hosts
lkl tools: add support for Windows host
lkl tools: add lklfuse
lkl: add initial system call hijack support (a.k.a. NUSE of libos)
lkl: add documentation
cpu: add cpu_yield_to_irqs
signal: use CONFIG_X86_32 instead of __i386__
arch: add __SYSCALL_DEFINE_ARCH
xfs: support for non-mmu architectures
checkpatch: avoid showing BIT_ULL warnings for tools/ files

Thomas Liebetraut (1):
tools: Add the lkl host library to the common tools Makefile

 .circleci/config.yml                          | 248 +++++
 Documentation/lkl.txt                         | 470 +++++++++
 MAINTAINERS                                   |   8 +
 Makefile                                      |   3 +
 README.md                                     |   1 +
 arch/Kconfig                                  |   6 +
 arch/um/Kconfig                               |  56 +-
 arch/um/Makefile                              | 115 +--
 arch/um/Makefile.um                           | 121 +++
 arch/um/auto.conf                             |   0
 arch/um/configs/x86_64_defconfig              |   6 +
 arch/um/include/asm/Kbuild                    |   6 +
 arch/um/include/asm/io.h                      |   4 +
 arch/um/lkl/.gitignore                        |   2 +
 arch/um/lkl/Kconfig                           |  96 ++
 arch/um/lkl/Kconfig.debug                     |   0
 arch/um/lkl/Makefile                          |   0
 arch/um/lkl/Makefile.um                       |  70 ++
 arch/um/lkl/auto.conf                         |   1 +
 arch/um/lkl/configs/lkl_defconfig             |  95 ++
 arch/um/lkl/include/asm/Kbuild                |  80 ++
 arch/um/lkl/include/asm/bitsperlong.h         |  11 +
 arch/um/lkl/include/asm/byteorder.h           |   7 +
 arch/um/lkl/include/asm/cpu.h                 |  14 +
 arch/um/lkl/include/asm/elf.h                 |  15 +
 arch/um/lkl/include/asm/host_ops.h            |  12 +
 arch/um/lkl/include/asm/io.h                  | 104 ++
 arch/um/lkl/include/asm/irq.h                 |  15 +
 arch/um/lkl/include/asm/mutex.h               |   7 +
 arch/um/lkl/include/asm/page.h                |  14 +
 arch/um/lkl/include/asm/pgtable.h             |  62 ++
 arch/um/lkl/include/asm/processor.h           |  60 ++
 arch/um/lkl/include/asm/ptrace.h              |  25 +
 arch/um/lkl/include/asm/sched.h               |  23 +
 arch/um/lkl/include/asm/setup.h               |   7 +
 arch/um/lkl/include/asm/syscalls.h            |  18 +
 arch/um/lkl/include/asm/syscalls_32.h         |  43 +
 arch/um/lkl/include/asm/thread_info.h         |  70 ++
 arch/um/lkl/include/asm/tlb.h                 |  12 +
 arch/um/lkl/include/asm/uaccess.h             |  64 ++
 arch/um/lkl/include/asm/unistd.h              |  29 +
 arch/um/lkl/include/asm/unistd_32.h           |  31 +
 arch/um/lkl/include/asm/vmlinux.lds.h         |  14 +
 arch/um/lkl/include/asm/xor.h                 |   9 +
 arch/um/lkl/include/system/stdarg.h           |   2 +
 arch/um/lkl/include/uapi/asm/Kbuild           |   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/host_ops.h       | 153 +++
 arch/um/lkl/include/uapi/asm/irq.h            |  36 +
 arch/um/lkl/include/uapi/asm/sigcontext.h     |  16 +
 arch/um/lkl/include/uapi/asm/siginfo.h        |  11 +
 arch/um/lkl/include/uapi/asm/swab.h           |  11 +
 arch/um/lkl/include/uapi/asm/syscalls.h       | 348 +++++++
 arch/um/lkl/include/uapi/asm/unistd.h         |  18 +
 arch/um/lkl/kernel/Makefile                   |   4 +
 arch/um/lkl/kernel/asm-offsets.c              |   2 +
 arch/um/lkl/kernel/console.c                  |  42 +
 arch/um/lkl/kernel/cpu.c                      | 223 +++++
 arch/um/lkl/kernel/irq.c                      | 193 ++++
 arch/um/lkl/kernel/misc.c                     |  60 ++
 arch/um/lkl/kernel/setup.c                    | 193 ++++
 arch/um/lkl/kernel/syscalls.c                 | 246 +++++
 arch/um/lkl/kernel/syscalls_32.c              | 159 +++
 arch/um/lkl/kernel/threads.c                  | 227 +++++
 arch/um/lkl/kernel/time.c                     | 145 +++
 arch/um/lkl/kernel/vmlinux.lds.S              |  51 +
 arch/um/lkl/mm/Makefile                       |   1 +
 arch/um/lkl/mm/bootmem.c                      |  66 ++
 arch/um/lkl/scripts/headers_install.py        | 195 ++++
 arch/um/lkl/um/Makefile                       |   1 +
 .../um/lkl/um/include/sysdep/kernel-offsets.h |   4 +
 arch/um/os-Linux/Makefile                     |   5 +
 arch/um/os-Linux/lkl_dev.c                    | 188 ++++
 arch/x86/um/syscalls_64.c                     |  53 +
 crypto/xor.c                                  |   2 +
 fs/xfs/xfs_buf.c                              |  26 +
 include/asm-generic/atomic64.h                |   2 +
 include/asm-generic/export.h                  |  34 +-
 include/asm-generic/vmlinux.lds.h             | 293 +++---
 include/linux/compiler_attributes.h           |   4 +
 include/linux/cpu.h                           |   1 +
 include/linux/export.h                        |  23 +-
 include/linux/linkage.h                       |  12 +-
 include/linux/syscalls.h                      |   6 +
 init/Kconfig                                  |  12 +
 kernel/cpu.c                                  |   5 +
 kernel/signal.c                               |   2 +-
 lib/.gitignore                                |   2 +
 lib/raid6/.gitignore                          |   1 +
 lib/raid6/algos.c                             |   9 +-
 scripts/.gitignore                            |   2 +
 scripts/Makefile.build                        |   7 +-
 scripts/adjust_autoksyms.sh                   |   7 +-
 scripts/basic/.gitignore                      |   1 +
 scripts/checkpatch.pl                         |   3 +-
 scripts/kallsyms.c                            |  58 +-
 scripts/kconfig/.gitignore                    |   1 +
 scripts/link-vmlinux.sh                       |  10 +
 scripts/mod/.gitignore                        |   1 +
 tools/Makefile                                |  11 +-
 tools/lkl/.gitignore                          |  14 +
 tools/lkl/Build                               |   6 +
 tools/lkl/Makefile                            | 130 +++
 tools/lkl/Makefile.autoconf                   | 114 +++
 tools/lkl/Targets                             |  27 +
 tools/lkl/bin/arm-linux-androideabi-ld        |   1 +
 tools/lkl/bin/lkl-hijack.sh                   |  23 +
 tools/lkl/cptofs.c                            | 635 ++++++++++++
 tools/lkl/fs2tar.c                            | 410 ++++++++
 tools/lkl/include/.gitignore                  |   1 +
 tools/lkl/include/lkl.h                       | 928 ++++++++++++++++++
 tools/lkl/include/lkl_config.h                |  61 ++
 tools/lkl/include/lkl_host.h                  | 160 +++
 tools/lkl/include/mingw32/sys/socket.h        |   4 +
 tools/lkl/lib/.gitignore                      |   3 +
 tools/lkl/lib/Build                           |  25 +
 tools/lkl/lib/Makefile                        |  32 +
 tools/lkl/lib/config.c                        | 793 +++++++++++++++
 tools/lkl/lib/dbg.c                           | 300 ++++++
 tools/lkl/lib/dbg_handler.c                   |  44 +
 tools/lkl/lib/endian.h                        |  31 +
 tools/lkl/lib/fs.c                            | 433 ++++++++
 tools/lkl/lib/hijack/Build                    |   4 +
 tools/lkl/lib/hijack/hijack.c                 | 618 ++++++++++++
 tools/lkl/lib/hijack/init.c                   | 252 +++++
 tools/lkl/lib/hijack/init.h                   |   8 +
 tools/lkl/lib/hijack/xlate.c                  | 613 ++++++++++++
 tools/lkl/lib/hijack/xlate.h                  |  13 +
 tools/lkl/lib/iomem.c                         |  88 ++
 tools/lkl/lib/iomem.h                         |  15 +
 tools/lkl/lib/jmp_buf.c                       |  14 +
 tools/lkl/lib/jmp_buf.h                       |   8 +
 tools/lkl/lib/net.c                           | 818 +++++++++++++++
 tools/lkl/lib/nt-host.c                       | 375 +++++++
 tools/lkl/lib/posix-host.c                    | 439 +++++++++
 tools/lkl/lib/utils.c                         | 266 +++++
 tools/lkl/lib/virtio.c                        | 644 ++++++++++++
 tools/lkl/lib/virtio.h                        | 115 +++
 tools/lkl/lib/virtio_blk.c                    | 132 +++
 tools/lkl/lib/virtio_net.c                    | 342 +++++++
 tools/lkl/lib/virtio_net_dpdk.c               | 480 +++++++++
 tools/lkl/lib/virtio_net_fd.c                 | 195 ++++
 tools/lkl/lib/virtio_net_fd.h                 |  50 +
 tools/lkl/lib/virtio_net_macvtap.c            |  32 +
 tools/lkl/lib/virtio_net_pipe.c               |  76 ++
 tools/lkl/lib/virtio_net_raw.c                |  94 ++
 tools/lkl/lib/virtio_net_tap.c                | 111 +++
 tools/lkl/lib/virtio_net_vde.c                | 168 ++++
 tools/lkl/lklfuse.c                           | 658 +++++++++++++
 tools/lkl/scripts/checkpatch.sh               |  60 ++
 tools/lkl/scripts/dpdk-sdk-build.sh           |  18 +
 tools/lkl/scripts/lkl-jenkins.sh              |  21 +
 tools/lkl/tests/Build                         |   3 +
 tools/lkl/tests/boot.c                        | 562 +++++++++++
 tools/lkl/tests/boot.sh                       |   9 +
 tools/lkl/tests/cla.c                         | 159 +++
 tools/lkl/tests/cla.h                         |  33 +
 tools/lkl/tests/disk.c                        | 189 ++++
 tools/lkl/tests/disk.sh                       |  70 ++
 tools/lkl/tests/hijack-test.sh                | 760 ++++++++++++++
 tools/lkl/tests/lklfuse.sh                    | 110 +++
 tools/lkl/tests/net-setup.sh                  | 134 +++
 tools/lkl/tests/net-test.c                    | 317 ++++++
 tools/lkl/tests/net.sh                        | 186 ++++
 tools/lkl/tests/run.py                        | 186 ++++
 tools/lkl/tests/run_netperf.sh                |  98 ++
 tools/lkl/tests/tap13.py                      | 209 ++++
 tools/lkl/tests/test.c                        | 126 +++
 tools/lkl/tests/test.h                        |  72 ++
 tools/lkl/tests/test.sh                       | 240 +++++
 tools/lkl/tests/valgrind.supp                 |  85 ++
 tools/lkl/tests/valgrind2xunit.py             |  69 ++
 173 files changed, 19464 insertions(+), 330 deletions(-)
 create mode 100644 .circleci/config.yml
 create mode 100644 Documentation/lkl.txt
 create mode 120000 README.md
 create mode 100644 arch/um/Makefile.um
 create mode 100644 arch/um/auto.conf
 create mode 100644 arch/um/lkl/.gitignore
 create mode 100644 arch/um/lkl/Kconfig
 create mode 100644 arch/um/lkl/Kconfig.debug
 create mode 100644 arch/um/lkl/Makefile
 create mode 100644 arch/um/lkl/Makefile.um
 create mode 100644 arch/um/lkl/auto.conf
 create mode 100644 arch/um/lkl/configs/lkl_defconfig
 create mode 100644 arch/um/lkl/include/asm/Kbuild
 create mode 100644 arch/um/lkl/include/asm/bitsperlong.h
 create mode 100644 arch/um/lkl/include/asm/byteorder.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/host_ops.h
 create mode 100644 arch/um/lkl/include/asm/io.h
 create mode 100644 arch/um/lkl/include/asm/irq.h
 create mode 100644 arch/um/lkl/include/asm/mutex.h
 create mode 100644 arch/um/lkl/include/asm/page.h
 create mode 100644 arch/um/lkl/include/asm/pgtable.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/setup.h
 create mode 100644 arch/um/lkl/include/asm/syscalls.h
 create mode 100644 arch/um/lkl/include/asm/syscalls_32.h
 create mode 100644 arch/um/lkl/include/asm/thread_info.h
 create mode 100644 arch/um/lkl/include/asm/tlb.h
 create mode 100644 arch/um/lkl/include/asm/uaccess.h
 create mode 100644 arch/um/lkl/include/asm/unistd.h
 create mode 100644 arch/um/lkl/include/asm/unistd_32.h
 create mode 100644 arch/um/lkl/include/asm/vmlinux.lds.h
 create mode 100644 arch/um/lkl/include/asm/xor.h
 create mode 100644 arch/um/lkl/include/system/stdarg.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/irq.h
 create mode 100644 arch/um/lkl/include/uapi/asm/sigcontext.h
 create mode 100644 arch/um/lkl/include/uapi/asm/siginfo.h
 create mode 100644 arch/um/lkl/include/uapi/asm/swab.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/kernel/Makefile
 create mode 100644 arch/um/lkl/kernel/asm-offsets.c
 create mode 100644 arch/um/lkl/kernel/console.c
 create mode 100644 arch/um/lkl/kernel/cpu.c
 create mode 100644 arch/um/lkl/kernel/irq.c
 create mode 100644 arch/um/lkl/kernel/misc.c
 create mode 100644 arch/um/lkl/kernel/setup.c
 create mode 100644 arch/um/lkl/kernel/syscalls.c
 create mode 100644 arch/um/lkl/kernel/syscalls_32.c
 create mode 100644 arch/um/lkl/kernel/threads.c
 create mode 100644 arch/um/lkl/kernel/time.c
 create mode 100644 arch/um/lkl/kernel/vmlinux.lds.S
 create mode 100644 arch/um/lkl/mm/Makefile
 create mode 100644 arch/um/lkl/mm/bootmem.c
 create mode 100755 arch/um/lkl/scripts/headers_install.py
 create mode 100644 arch/um/lkl/um/Makefile
 create mode 100644 arch/um/lkl/um/include/sysdep/kernel-offsets.h
 create mode 100644 arch/um/os-Linux/lkl_dev.c
 create mode 100644 tools/lkl/.gitignore
 create mode 100644 tools/lkl/Build
 create mode 100644 tools/lkl/Makefile
 create mode 100644 tools/lkl/Makefile.autoconf
 create mode 100644 tools/lkl/Targets
 create mode 120000 tools/lkl/bin/arm-linux-androideabi-ld
 create mode 100755 tools/lkl/bin/lkl-hijack.sh
 create mode 100644 tools/lkl/cptofs.c
 create mode 100644 tools/lkl/fs2tar.c
 create mode 100644 tools/lkl/include/.gitignore
 create mode 100644 tools/lkl/include/lkl.h
 create mode 100644 tools/lkl/include/lkl_config.h
 create mode 100644 tools/lkl/include/lkl_host.h
 create mode 100644 tools/lkl/include/mingw32/sys/socket.h
 create mode 100644 tools/lkl/lib/.gitignore
 create mode 100644 tools/lkl/lib/Build
 create mode 100644 tools/lkl/lib/Makefile
 create mode 100644 tools/lkl/lib/config.c
 create mode 100644 tools/lkl/lib/dbg.c
 create mode 100644 tools/lkl/lib/dbg_handler.c
 create mode 100644 tools/lkl/lib/endian.h
 create mode 100644 tools/lkl/lib/fs.c
 create mode 100644 tools/lkl/lib/hijack/Build
 create mode 100644 tools/lkl/lib/hijack/hijack.c
 create mode 100644 tools/lkl/lib/hijack/init.c
 create mode 100644 tools/lkl/lib/hijack/init.h
 create mode 100644 tools/lkl/lib/hijack/xlate.c
 create mode 100644 tools/lkl/lib/hijack/xlate.h
 create mode 100644 tools/lkl/lib/iomem.c
 create mode 100644 tools/lkl/lib/iomem.h
 create mode 100644 tools/lkl/lib/jmp_buf.c
 create mode 100644 tools/lkl/lib/jmp_buf.h
 create mode 100644 tools/lkl/lib/net.c
 create mode 100644 tools/lkl/lib/nt-host.c
 create mode 100644 tools/lkl/lib/posix-host.c
 create mode 100644 tools/lkl/lib/utils.c
 create mode 100644 tools/lkl/lib/virtio.c
 create mode 100644 tools/lkl/lib/virtio.h
 create mode 100644 tools/lkl/lib/virtio_blk.c
 create mode 100644 tools/lkl/lib/virtio_net.c
 create mode 100644 tools/lkl/lib/virtio_net_dpdk.c
 create mode 100644 tools/lkl/lib/virtio_net_fd.c
 create mode 100644 tools/lkl/lib/virtio_net_fd.h
 create mode 100644 tools/lkl/lib/virtio_net_macvtap.c
 create mode 100644 tools/lkl/lib/virtio_net_pipe.c
 create mode 100644 tools/lkl/lib/virtio_net_raw.c
 create mode 100644 tools/lkl/lib/virtio_net_tap.c
 create mode 100644 tools/lkl/lib/virtio_net_vde.c
 create mode 100644 tools/lkl/lklfuse.c
 create mode 100755 tools/lkl/scripts/checkpatch.sh
 create mode 100755 tools/lkl/scripts/dpdk-sdk-build.sh
 create mode 100755 tools/lkl/scripts/lkl-jenkins.sh
 create mode 100644 tools/lkl/tests/Build
 create mode 100644 tools/lkl/tests/boot.c
 create mode 100755 tools/lkl/tests/boot.sh
 create mode 100644 tools/lkl/tests/cla.c
 create mode 100644 tools/lkl/tests/cla.h
 create mode 100644 tools/lkl/tests/disk.c
 create mode 100755 tools/lkl/tests/disk.sh
 create mode 100755 tools/lkl/tests/hijack-test.sh
 create mode 100755 tools/lkl/tests/lklfuse.sh
 create mode 100644 tools/lkl/tests/net-setup.sh
 create mode 100644 tools/lkl/tests/net-test.c
 create mode 100755 tools/lkl/tests/net.sh
 create mode 100755 tools/lkl/tests/run.py
 create mode 100755 tools/lkl/tests/run_netperf.sh
 create mode 100644 tools/lkl/tests/tap13.py
 create mode 100644 tools/lkl/tests/test.c
 create mode 100644 tools/lkl/tests/test.h
 create mode 100644 tools/lkl/tests/test.sh
 create mode 100644 tools/lkl/tests/valgrind.supp
 create mode 100755 tools/lkl/tests/valgrind2xunit.py
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 1/47 asm-generic: atomic64: allow using generic atomic64 on 64bit platforms

From: Octavian Purdila <[email protected]>

---
 include/asm-generic/atomic64.h | 2 ++
 1 file changed, 2 insertions(+)
include/asm-generic/atomic64.h +2 -0
index 370f01d4450f..9b15847baae5 100644
@@ -9,9 +9,11 @@
 #define _ASM_GENERIC_ATOMIC64_H
 #include <linux/types.h>
 
+#ifndef CONFIG_64BIT
 typedef struct {
 	s64 counter;
 } atomic64_t;
+#endif
 
 #define ATOMIC64_INIT(i)	{ (i) }
 
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 2/47 kbuild: allow architectures to automatically define kconfig symbols

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This patch calls an architecture hook during the kernel config process that allows the architecture to automatically define kconfig symbols. This can be done by exporting environment variables from the new architecture hook.

---
 Makefile | 1 +
 1 file changed, 1 insertion(+)
Makefile +1 -0
index 0cbe8717bdb3..8c1f7422d0bc 100644
@@ -605,6 +605,7 @@ endif
 export KBUILD_MODULES KBUILD_BUILTIN
 
 ifeq ($(dot-config),1)
+include arch/$(SRCARCH)/auto.conf
 include include/config/auto.conf
 endif
 
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 3/47 lkl: architecture skeleton for Linux kernel library

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Adds the LKL Kconfig, vmlinux linker script, basic architecture headers and miscellaneous basic functions or stubs such as dump_stack(), show_regs() and cpuinfo proc ops.

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.

The kernel configuration is automatically updated to reflect the endianness of the host, 64bit support or the output format for vmlinux's linker script. We do this by looking at the ld's default output format.

---
 MAINTAINERS                                |   8 +
 arch/um/lkl/.gitignore                     |   2 +
 arch/um/lkl/Kconfig                        |  96 ++++++
 arch/um/lkl/Kconfig.debug                  |   0
 arch/um/lkl/Makefile                       |   0
 arch/um/lkl/Makefile.um                    |  70 +++++
 arch/um/lkl/configs/lkl_defconfig          |  95 ++++++
 arch/um/lkl/include/asm/Kbuild             |  80 +++++
 arch/um/lkl/include/asm/bitsperlong.h      |  11 +
 arch/um/lkl/include/asm/byteorder.h        |   7 +
 arch/um/lkl/include/asm/cpu.h              |  14 +
 arch/um/lkl/include/asm/elf.h              |  15 +
 arch/um/lkl/include/asm/mutex.h            |   7 +
 arch/um/lkl/include/asm/processor.h        |  60 ++++
 arch/um/lkl/include/asm/ptrace.h           |  25 ++
 arch/um/lkl/include/asm/sched.h            |  23 ++
 arch/um/lkl/include/asm/syscalls.h         |  18 ++
 arch/um/lkl/include/asm/syscalls_32.h      |  43 +++
 arch/um/lkl/include/asm/tlb.h              |  12 +
 arch/um/lkl/include/asm/uaccess.h          |  64 ++++
 arch/um/lkl/include/asm/unistd_32.h        |  31 ++
 arch/um/lkl/include/asm/vmlinux.lds.h      |  14 +
 arch/um/lkl/include/asm/xor.h              |   9 +
 arch/um/lkl/include/uapi/asm/Kbuild        |   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/siginfo.h     |  11 +
 arch/um/lkl/include/uapi/asm/swab.h        |  11 +
 arch/um/lkl/include/uapi/asm/syscalls.h    | 348 +++++++++++++++++++++
 arch/um/lkl/kernel/asm-offsets.c           |   2 +
 arch/um/lkl/kernel/misc.c                  |  60 ++++
 arch/um/lkl/kernel/vmlinux.lds.S           |  51 +++
 32 files changed, 1220 insertions(+)
 create mode 100644 arch/um/lkl/.gitignore
 create mode 100644 arch/um/lkl/Kconfig
 create mode 100644 arch/um/lkl/Kconfig.debug
 create mode 100644 arch/um/lkl/Makefile
 create mode 100644 arch/um/lkl/Makefile.um
 create mode 100644 arch/um/lkl/configs/lkl_defconfig
 create mode 100644 arch/um/lkl/include/asm/Kbuild
 create mode 100644 arch/um/lkl/include/asm/bitsperlong.h
 create mode 100644 arch/um/lkl/include/asm/byteorder.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/mutex.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/syscalls.h
 create mode 100644 arch/um/lkl/include/asm/syscalls_32.h
 create mode 100644 arch/um/lkl/include/asm/tlb.h
 create mode 100644 arch/um/lkl/include/asm/uaccess.h
 create mode 100644 arch/um/lkl/include/asm/unistd_32.h
 create mode 100644 arch/um/lkl/include/asm/vmlinux.lds.h
 create mode 100644 arch/um/lkl/include/asm/xor.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/siginfo.h
 create mode 100644 arch/um/lkl/include/uapi/asm/swab.h
 create mode 100644 arch/um/lkl/include/uapi/asm/syscalls.h
 create mode 100644 arch/um/lkl/kernel/asm-offsets.c
 create mode 100644 arch/um/lkl/kernel/misc.c
 create mode 100644 arch/um/lkl/kernel/vmlinux.lds.S
MAINTAINERS +8 -0
index e7a47b5210fd..6832972ad54b 100644
@@ -9369,6 +9369,14 @@ F:	Documentation/core-api/atomic_ops.rst
 F:	Documentation/core-api/refcount-vs-atomic.rst
 F:	Documentation/memory-barriers.txt
 
+LINUX KERNEL LIBRARY
+M:	Octavian Purdila <[email protected]>
+M:	Hajime Tazaki <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	arch/lkl/
+F:	tools/lkl/
+
 LIS3LV02D ACCELEROMETER DRIVER
 M:	Eric Piel <[email protected]>
 S:	Maintained
arch/um/lkl/.gitignore new file +2 -0
new file mode 100644
index 000000000000..ced1c60d8235
@@ -0,0 +1,2 @@
+kernel/vmlinux.lds
+include/generated
arch/um/lkl/Kconfig new file +96 -0

96 lines not on this page · raw message

arch/um/lkl/Kconfig.debug new file +0 -0
new file mode 100644
index 000000000000..e69de29bb2d1
arch/um/lkl/Makefile new file +0 -0
new file mode 100644
index 000000000000..e69de29bb2d1
arch/um/lkl/Makefile.um new file +70 -0

70 lines not on this page · raw message

arch/um/lkl/configs/lkl_defconfig new file +95 -0

95 lines not on this page · raw message

arch/um/lkl/include/asm/Kbuild new file +80 -0

80 lines not on this page · raw message

arch/um/lkl/include/asm/bitsperlong.h new file +11 -0
new file mode 100644
index 000000000000..5745d5e51274
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LKL_BITSPERLONG_H
+#define __LKL_BITSPERLONG_H
+
+#include <uapi/asm/bitsperlong.h>
+
+#define BITS_PER_LONG __BITS_PER_LONG
+
+#define BITS_PER_LONG_LONG 64
+
+#endif
arch/um/lkl/include/asm/byteorder.h new file +7 -0
new file mode 100644
index 000000000000..5d0c4efaa44b
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_BYTEORDER_H
+#define _ASM_LKL_BYTEORDER_H
+
+#include <uapi/asm/byteorder.h>
+
+#endif /* _ASM_LKL_BYTEORDER_H */
arch/um/lkl/include/asm/cpu.h new file +14 -0
new file mode 100644
index 000000000000..d2b8c501c7b1
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_CPU_H
+#define _ASM_LKL_CPU_H
+
+int lkl_cpu_get(void);
+void lkl_cpu_put(void);
+int lkl_cpu_try_run_irq(int irq);
+int lkl_cpu_init(void);
+void lkl_cpu_shutdown(void);
+void lkl_cpu_wait_shutdown(void);
+void lkl_cpu_change_owner(lkl_thread_t owner);
+void lkl_cpu_set_irqs_pending(void);
+
+#endif /* _ASM_LKL_CPU_H */
arch/um/lkl/include/asm/elf.h new file +15 -0
new file mode 100644
index 000000000000..bb2456d638f4
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_ELF_H
+#define _ASM_LKL_ELF_H
+
+#define elf_check_arch(x) 0
+
+#ifdef CONFIG_64BIT
+#define ELF_CLASS ELFCLASS64
+#else
+#define ELF_CLASS ELFCLASS32
+#endif
+
+#define elf_gregset_t long
+#define elf_fpregset_t double
+#endif
arch/um/lkl/include/asm/mutex.h new file +7 -0
new file mode 100644
index 000000000000..492d04183f9c
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_MUTEX_H
+#define _ASM_LKL_MUTEX_H
+
+#include <asm-generic/mutex-dec.h>
+
+#endif
arch/um/lkl/include/asm/processor.h new file +60 -0

60 lines not on this page · raw message

arch/um/lkl/include/asm/ptrace.h new file +25 -0
new file mode 100644
index 000000000000..28199be26dc0
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_PTRACE_H
+#define _ASM_LKL_PTRACE_H
+
+#include <linux/errno.h>
+
+struct task_struct;
+
+#define user_mode(regs) 0
+#define kernel_mode(regs) 1
+#define profile_pc(regs) 0
+#define instruction_pointer(regs) 0
+#define user_stack_pointer(regs) 0
+
+static inline long arch_ptrace(struct task_struct *child, long request,
+			       unsigned long addr, unsigned long data)
+{
+	return -EINVAL;
+}
+
+static inline void ptrace_disable(struct task_struct *child)
+{
+}
+
+#endif
arch/um/lkl/include/asm/sched.h new file +23 -0
new file mode 100644
index 000000000000..4c2635921ec8
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_SCHED_H
+#define _ASM_LKL_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_ops->jmp_buf_set(&current_thread_info()->sched_jb,
+				     schedule);
+	} else {
+		lkl_bug("%s() can be used only for host task\n", __func__);
+	}
+}
+
+void switch_to_host_task(struct task_struct *);
+int host_task_stub(void *unused);
+
+#endif /*  _ASM_LKL_SCHED_H */
arch/um/lkl/include/asm/syscalls.h new file +18 -0
new file mode 100644
index 000000000000..2eaa870a9020
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_SYSCALLS_H
+#define _ASM_LKL_SYSCALLS_H
+
+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_mmap_pgoff
+#define sys_mmap2 sys_mmap_pgoff
+#define sys_clone sys_ni_syscall
+#define sys_vfork sys_ni_syscall
+#define sys_rt_sigreturn sys_ni_syscall
+
+#include <asm-generic/syscalls.h>
+
+#endif /* _ASM_LKL_SYSCALLS_H */
arch/um/lkl/include/asm/syscalls_32.h new file +43 -0

43 lines not on this page · raw message

arch/um/lkl/include/asm/tlb.h new file +12 -0
new file mode 100644
index 000000000000..d474890d317d
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_TLB_H
+#define _ASM_LKL_TLB_H
+
+#define tlb_start_vma(tlb, vma)				do { } while (0)
+#define tlb_end_vma(tlb, vma)				do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, pte, address)	do { } while (0)
+#define tlb_flush(tlb)					do { } while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_LKL_TLB_H */
arch/um/lkl/include/asm/uaccess.h new file +64 -0

64 lines not on this page · raw message

arch/um/lkl/include/asm/unistd_32.h new file +31 -0
new file mode 100644
index 000000000000..8582a55e61e2
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#ifndef __SYSCALL
+#define __SYSCALL(x, y)
+#endif
+
+#if __BITS_PER_LONG == 32
+__SYSCALL(__NR3264_truncate, sys32_truncate64)
+__SYSCALL(__NR3264_ftruncate, sys32_ftruncate64)
+
+#ifdef CONFIG_MMU
+__SYSCALL(__NR3264_mmap, sys32_mmap)
+#endif
+
+__SYSCALL(__NR_wait4, sys32_wait4)
+
+__SYSCALL(__NR_pread64, sys32_pread64)
+__SYSCALL(__NR_pwrite64, sys32_pwrite64)
+
+__SYSCALL(__NR_readahead, sys32_readahead)
+#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
+__SYSCALL(__NR_sync_file_range2, sys32_sync_file_range2)
+#else
+__SYSCALL(__NR_sync_file_range, sys32_sync_file_range)
+#endif
+/* mm/fadvise.c */
+__SYSCALL(__NR3264_fadvise64, sys32_fadvise64_64)
+__SYSCALL(__NR_fallocate, sys32_fallocate)
+
+#endif
arch/um/lkl/include/asm/vmlinux.lds.h new file +14 -0
new file mode 100644
index 000000000000..a3c285882dc4
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_VMLINUX_LDS_H
+#define _LKL_VMLINUX_LDS_H
+
+/* we encode our own __ro_after_init section */
+#define RO_AFTER_INIT_DATA
+
+#ifdef __MINGW32__
+#define RODATA_SECTION .rdata
+#endif
+
+#include <asm-generic/vmlinux.lds.h>
+
+#endif
arch/um/lkl/include/asm/xor.h new file +9 -0
new file mode 100644
index 000000000000..286ce75b5d9d
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_XOR_H
+#define _ASM_LKL_XOR_H
+
+#include <asm-generic/xor.h>
+
+#define XOR_SELECT_TEMPLATE(x) (&xor_block_8regs)
+
+#endif /* _ASM_LKL_XOR_H */
arch/um/lkl/include/uapi/asm/Kbuild new file +9 -0
new file mode 100644
index 000000000000..39d9a1f2e8f5
@@ -0,0 +1,9 @@
+# UAPI Header export list
+
+generic-y += elf.h
+generic-y += kvm_para.h
+generic-y += shmparam.h
+generic-y += timex.h
+
+# no header-y since we need special user headers handling
+# see arch/lkl/script/headers.py
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +13 -0
new file mode 100644
index 000000000000..8b4ebf2b0264
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_BITSPERLONG_H
+#define _ASM_UAPI_LKL_BITSPERLONG_H
+
+#ifdef CONFIG_64BIT
+#define __BITS_PER_LONG 64
+#else
+#define __BITS_PER_LONG 32
+#endif
+
+#define __ARCH_WANT_STAT64
+
+#endif /* _ASM_UAPI_LKL_BITSPERLONG_H */
arch/um/lkl/include/uapi/asm/byteorder.h new file +11 -0
new file mode 100644
index 000000000000..3c4a58d2062f
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_BYTEORDER_H
+#define _ASM_UAPI_LKL_BYTEORDER_H
+
+#if defined(CONFIG_BIG_ENDIAN)
+#include <linux/byteorder/big_endian.h>
+#else
+#include <linux/byteorder/little_endian.h>
+#endif
+
+#endif /* _ASM_UAPI_LKL_BYTEORDER_H */
arch/um/lkl/include/uapi/asm/siginfo.h new file +11 -0
new file mode 100644
index 000000000000..811916cf42c8
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_LKL_SIGINFO_H
+#define _ASM_LKL_SIGINFO_H
+
+#ifdef CONFIG_64BIT
+#define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
+#endif
+
+#include <asm-generic/siginfo.h>
+
+#endif /* _ASM_LKL_SIGINFO_H */
arch/um/lkl/include/uapi/asm/swab.h new file +11 -0
new file mode 100644
index 000000000000..1a1773e1bd35
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_LKL_SWAB_H
+#define _ASM_LKL_SWAB_H
+
+#ifndef __arch_swab32
+#define __arch_swab32(x) ___constant_swab32(x)
+#endif
+
+#include <asm-generic/swab.h>
+
+#endif /* _ASM_LKL_SWAB_H */
arch/um/lkl/include/uapi/asm/syscalls.h new file +348 -0

348 lines not on this page · raw message

arch/um/lkl/kernel/asm-offsets.c new file +2 -0
new file mode 100644
index 000000000000..6be0763698dc
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */
arch/um/lkl/kernel/misc.c new file +60 -0

60 lines not on this page · raw message

arch/um/lkl/kernel/vmlinux.lds.S new file +51 -0

51 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

Re: [RFC PATCH 03/47] lkl: architecture skeleton for Linux kernel library

MAINTAINERS F: Documentation/core-api/atomic_ops.rst · line 9379

Quoted 10 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

MAINTAINERS +8 -0
+LINUX KERNEL LIBRARY
+M:     Octavian Purdila <[email protected]>
+M:     Hajime Tazaki <[email protected]>
+L:     [email protected]
+S:     Maintained
+F:     arch/lkl/
+F:     tools/lkl/
+

The arch/lkl path is outdated.
So, you and Octavian will maintain LKL?

Do you want to be sub maintainers of arch/um/lkl and send pull requests to me or co-maintain the whole UML ecosystem together with me and Anton?

I'm perfectly fine with both variants but tend to the latter one since it is less overhead.
In case you need your PGP keys signed, next week I'll be in Lyon at OSS, ELCE, ...

Signature · 7 lines
Thanks,
//richard

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

Re: [RFC PATCH 03/47] lkl: architecture skeleton for Linux kernel library

# dropping two Cc's since those are not reachable..
Quoted 14 lines · Richard Weinberger

MAINTAINERS F: Documentation/core-api/atomic_ops.rst · line 9379

Quoted 10 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

MAINTAINERS +8 -0
+LINUX KERNEL LIBRARY
+M:     Octavian Purdila <[email protected]>
+M:     Hajime Tazaki <[email protected]>
+L:     [email protected]
+S:     Maintained
+F:     arch/lkl/
+F:     tools/lkl/
+

The arch/lkl path is outdated.

Ah, should be updated. We will fix it.

Quoted 1 line

So, you and Octavian will maintain LKL?

Yes.

Quoted 5 lines

Do you want to be sub maintainers of arch/um/lkl and send pull requests to me or co-maintain the whole UML ecosystem together with me and Anton?

I'm perfectly fine with both variants but tend to the latter one since it is less overhead.

I was not thinking well enough for the maintenance procedure; I agree that the latter case is better, but for the early stage of this integration, I think starting with the former (send pull-req from LKL to you/Anton) would be nice.

LKL is now on github and utilizes several useful features (CI test at each pull request, issue tracking, wiki), and if possible I'd also like to migrate those tools, or make them available to UML because this makes easier maintenance for LKL.

What do you think ?

Quoted 2 lines

In case you need your PGP keys signed, next week I'll be in Lyon at OSS, ELCE, ...

I won't be there, unfortunately..

-- Hajime

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

#6 lore raw

Re: [RFC PATCH 03/47] lkl: architecture skeleton for Linux kernel library

Hello, Hajime

I can't get how UML&LKL is going to unify even I read
the cover-letter of the patchset. After quick glance, what I understand is that the patchset just puts LKL under arch/um/lkl rather than arch/lkl. It is still separated "arch" for me.

Could you put me in more detail of the plan to unify them please?

Thanks
Lai

Quoted 44 lines · Hajime Tazaki

# dropping two Cc's since those are not reachable..
Quoted 14 lines · Richard Weinberger

MAINTAINERS F: Documentation/core-api/atomic_ops.rst · line 9379

Quoted 10 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

MAINTAINERS +8 -0
+LINUX KERNEL LIBRARY
+M:     Octavian Purdila <[email protected]>
+M:     Hajime Tazaki <[email protected]>
+L:     [email protected]
+S:     Maintained
+F:     arch/lkl/
+F:     tools/lkl/
+

The arch/lkl path is outdated.

Ah, should be updated. We will fix it.

Quoted 1 line

So, you and Octavian will maintain LKL?

Yes.

Quoted 5 lines

Do you want to be sub maintainers of arch/um/lkl and send pull requests to me or co-maintain the whole UML ecosystem together with me and Anton?

I'm perfectly fine with both variants but tend to the latter one since it is less overhead.

I was not thinking well enough for the maintenance procedure; I agree that the latter case is better, but for the early stage of this integration, I think starting with the former (send pull-req from LKL to you/Anton) would be nice.

LKL is now on github and utilizes several useful features (CI test at each pull request, issue tracking, wiki), and if possible I'd also like to migrate those tools, or make them available to UML because this makes easier maintenance for LKL.

Quoted 8 lines

What do you think ?

Quoted 2 lines

In case you need your PGP keys signed, next week I'll be in Lyon at OSS, ELCE, ...

I won't be there, unfortunately..

-- Hajime

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

#7 lore raw

Re: [RFC PATCH 03/47] lkl: architecture skeleton for Linux kernel library

Hello Lai,

Quoted 9 lines · Lai Jiangshan

Hello, Hajime

I can't get how UML&LKL is going to unify even I read
the cover-letter of the patchset. After quick glance, what I understand is that the patchset just puts LKL under arch/um/lkl rather than arch/lkl. It is still separated "arch" for me.

Could you put me in more detail of the plan to unify them please?

Thanks for the comment.

You're right: current patchset only share Makefile(s) between UML and LKL. This is the first step toward the unification in my plan, described in the milestone of the cover letter (copy-pasted below).

Quoted 7 lines

Milestone
=========
(snip)
1. Put LKL code under arch/um (arch/um/lkl), and build it in a separate way from UML.
2. Share common parts of implementation between UML and LKL.
3. Reimplement UML features with LKL API (if we wish)

For the step 2, [PATCH 46/47] and [47/47] are the kind of examples for this level of unification (sorry for the very dirty code).

For the step 3, I don't have any WIP code nor detailed plan. Implementing ptrace-based (or similar) syscall interception would be one of the development (I believe there are more).

Offering UML feature-sets, keeping compatibility, while benefiting from LKL (e.g., various underlying environment support) would be very high-level goal since there are many users of UML (various test tool projects, including coming Kunit).

Having similar archs in Linux kernel is not likely to happen; that was feedback after RFC email of LKL (in 2015). This motivates us to upstream the LKL code into arch/um.

-- Hajime

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

maintainer
#8 lore raw

Re: [RFC PATCH 03/47] lkl: architecture skeleton for Linux kernel library

Hi,

Quoted 21 lines

You're right: current patchset only share Makefile(s) between UML and LKL. This is the first step toward the unification in my plan, described in the milestone of the cover letter (copy-pasted below).

Quoted 7 lines

Milestone
=========
(snip)
1. Put LKL code under arch/um (arch/um/lkl), and build it in a separate way from UML.
2. Share common parts of implementation between UML and LKL.
3. Reimplement UML features with LKL API (if we wish)

For the step 2, [PATCH 46/47] and [47/47] are the kind of examples for this level of unification (sorry for the very dirty code).

For the step 3, I don't have any WIP code nor detailed plan. Implementing ptrace-based (or similar) syscall interception would be one of the development (I believe there are more).

Quoted 5 lines

Offering UML feature-sets, keeping compatibility, while benefiting from LKL (e.g., various underlying environment support) would be very high-level goal since there are many users of UML (various test tool projects, including coming Kunit).

Aren't you going about this the wrong way around?

I mean, this reads like you're proposing to start from LKL and reimplement UML on top of it, but we currently have UML in the tree and LKL isn't. Seems backward to me.

Also, looking at the patches, I'm not a huge fan of the whole "drop LKL into UML". UML is already complex enough as is, with its memory model and all, mixing in LKL makes it way more complex.

I don't think "drop LKL under UML" was what people had in mind when they suggested that the two merge ...

johannes

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

#9 lore raw

Re: [RFC PATCH 03/47] lkl: architecture skeleton for Linux kernel library

----- Ursprüngliche Mail -----

Quoted 39 lines

Von: "Johannes Berg" <[email protected]>
An: "Hajime Tazaki" <[email protected]>, [email protected]
CC: [email protected], [email protected], [email protected], "Richard Weinberger" <[email protected]>, [email protected], [email protected], "linux-um" <[email protected]>, [email protected], [email protected], "tavi purdila" <[email protected]>, [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], "luca dariz" <[email protected]>, [email protected]
Gesendet: Dienstag, 29. Oktober 2019 08:57:43
Betreff: Re: [RFC PATCH 03/47] lkl: architecture skeleton for Linux kernel library

Hi,

Quoted 21 lines

You're right: current patchset only share Makefile(s) between UML and LKL. This is the first step toward the unification in my plan, described in the milestone of the cover letter (copy-pasted below).

Quoted 7 lines

Milestone
=========
(snip)
1. Put LKL code under arch/um (arch/um/lkl), and build it in a separate way from UML.
2. Share common parts of implementation between UML and LKL.
3. Reimplement UML features with LKL API (if we wish)

For the step 2, [PATCH 46/47] and [47/47] are the kind of examples for this level of unification (sorry for the very dirty code).

For the step 3, I don't have any WIP code nor detailed plan. Implementing ptrace-based (or similar) syscall interception would be one of the development (I believe there are more).

Quoted 5 lines

Offering UML feature-sets, keeping compatibility, while benefiting from LKL (e.g., various underlying environment support) would be very high-level goal since there are many users of UML (various test tool projects, including coming Kunit).

Quoted 5 lines

Aren't you going about this the wrong way around?

I mean, this reads like you're proposing to start from LKL and reimplement UML on top of it, but we currently have UML in the tree and LKL isn't. Seems backward to me.

This is surely not intended.

Quoted 6 lines

Also, looking at the patches, I'm not a huge fan of the whole "drop LKL into UML". UML is already complex enough as is, with its memory model and all, mixing in LKL makes it way more complex.

I don't think "drop LKL under UML" was what people had in mind when they suggested that the two merge ...

Yes, just having a lkl folder under arch/um/ is for sure not the final solution. The goal is merging as much as possible.
But having purely lkl stuff in a subfolder like arch/um/lkl/ is not a big deal.

This patch series is just a start not the final solution which will get merged. :-)

Thanks,
//richard

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

#10 lore raw

Re: [RFC PATCH 03/47] lkl: architecture skeleton for Linux kernel library

In reply to Johannes Berg

Hello,

Quoted 11 lines · Johannes Berg
Quoted 5 lines

Offering UML feature-sets, keeping compatibility, while benefiting from LKL (e.g., various underlying environment support) would be very high-level goal since there are many users of UML (various test tool projects, including coming Kunit).

Aren't you going about this the wrong way around?

I mean, this reads like you're proposing to start from LKL and reimplement UML on top of it, but we currently have UML in the tree and LKL isn't. Seems backward to me.

I see your point.

Our basic standpoint is to follow the project idea listed in the old UML web page.

http://user-mode-linux.sourceforge.net/old/projects.html

Especially LKL should be able to contribute the following ideas to UML.

- Architecture Ports (e.g., run on arm32)
- OS Ports (e.g., Windows host)
- UML as a normal userspace library

I wish I'm not going to break any existing facility of UML in this introduction. If you found any, I'm happy to fix such problems.

Quoted 6 lines

Also, looking at the patches, I'm not a huge fan of the whole "drop LKL into UML". UML is already complex enough as is, with its memory model and all, mixing in LKL makes it way more complex.

I don't think "drop LKL under UML" was what people had in mind when they suggested that the two merge ...

As Richard explained, putting new arch/um/lkl folder should not be our final goal.

-- Hajime

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

#11 lore raw

RFC PATCH 4/47 lkl: host interface

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

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/lkl/include/asm/host_ops.h      |  12 ++
 arch/um/lkl/include/uapi/asm/host_ops.h | 153 ++++++++++++++++++++++++
 2 files changed, 165 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/host_ops.h
 create mode 100644 arch/um/lkl/include/uapi/asm/host_ops.h
arch/um/lkl/include/asm/host_ops.h new file +12 -0
new file mode 100644
index 000000000000..a31b10c33a5b
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_HOST_OPS_H
+#define _ASM_LKL_HOST_OPS_H
+
+#include "irq.h"
+#include <uapi/asm/host_ops.h>
+
+extern struct lkl_host_operations *lkl_ops;
+
+#define lkl_puts(text) lkl_ops->print(text, strlen(text))
+
+#endif
arch/um/lkl/include/uapi/asm/host_ops.h new file +153 -0

153 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 5/47 lkl: memory handling

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

LKL is a non MMU architecture and hence 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 a host operation and the memory size to be used is specified when the kernel is started, in the lkl_start_kernel call.

---
 arch/um/lkl/include/asm/page.h    | 14 +++++++
 arch/um/lkl/include/asm/pgtable.h | 62 +++++++++++++++++++++++++++++
 arch/um/lkl/mm/bootmem.c          | 66 +++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/page.h
 create mode 100644 arch/um/lkl/include/asm/pgtable.h
 create mode 100644 arch/um/lkl/mm/bootmem.c
arch/um/lkl/include/asm/page.h new file +14 -0
new file mode 100644
index 000000000000..e77f3da22031
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_PAGE_H
+#define _ASM_LKL_PAGE_H
+
+#define CONFIG_KERNEL_RAM_BASE_ADDRESS memory_start
+
+#ifndef __ASSEMBLY__
+void free_mem(void);
+void bootmem_init(unsigned long mem_size);
+#endif
+
+#include <asm-generic/page.h>
+
+#endif /* _ASM_LKL_PAGE_H */
arch/um/lkl/include/asm/pgtable.h new file +62 -0

62 lines not on this page · raw message

arch/um/lkl/mm/bootmem.c new file +66 -0

66 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 6/47 lkl: kernel threads support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

LKL does not support user processes but it must support kernel threads as part as the normal kernel work-flow. It uses host operations 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 threads 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.

---
 arch/um/lkl/include/asm/thread_info.h |  70 ++++++++
 arch/um/lkl/kernel/cpu.c              | 223 +++++++++++++++++++++++++
 arch/um/lkl/kernel/threads.c          | 227 ++++++++++++++++++++++++++
 3 files changed, 520 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/thread_info.h
 create mode 100644 arch/um/lkl/kernel/cpu.c
 create mode 100644 arch/um/lkl/kernel/threads.c
arch/um/lkl/include/asm/thread_info.h new file +70 -0
new file mode 100644
index 000000000000..da4e75fc7b10
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_THREAD_INFO_H
+#define _ASM_LKL_THREAD_INFO_H
+
+#define THREAD_SIZE	       (4096)
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+#include <asm/processor.h>
+#include <asm/host_ops.h>
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+struct thread_info {
+	struct task_struct *task;
+	unsigned long flags;
+	int preempt_count;
+	mm_segment_t addr_limit;
+	struct lkl_sem *sched_sem;
+	struct lkl_jmp_buf sched_jb;
+	bool dead;
+	lkl_thread_t tid;
+	struct task_struct *prev_sched;
+	unsigned long stackend;
+};
+
+#define INIT_THREAD_INFO(tsk)				\
+{							\
+	.task		= &tsk,				\
+	.preempt_count	= INIT_PREEMPT_COUNT,		\
+	.flags		= 0,				\
+	.addr_limit	= KERNEL_DS,			\
+}
+
+/* how to get the thread information struct from C */
+extern struct thread_info *_current_thread_info;
+static inline struct thread_info *current_thread_info(void)
+{
+	return _current_thread_info;
+}
+
+/* thread information allocation */
+unsigned long *alloc_thread_stack_node(struct task_struct *, int node);
+void free_thread_stack(struct task_struct *tsk);
+
+void threads_init(void);
+void threads_cleanup(void);
+
+#define TIF_SYSCALL_TRACE		0
+#define TIF_NOTIFY_RESUME		1
+#define TIF_SIGPENDING			2
+#define TIF_NEED_RESCHED		3
+#define TIF_RESTORE_SIGMASK		4
+#define TIF_MEMDIE			5
+#define TIF_NOHZ			6
+#define TIF_SCHED_JB			7
+#define TIF_HOST_THREAD			8
+
+#define __HAVE_THREAD_FUNCTIONS
+
+#define task_thread_info(task)	((struct thread_info *)(task)->stack)
+#define task_stack_page(task)	((task)->stack)
+void setup_thread_stack(struct task_struct *p, struct task_struct *org);
+#define end_of_stack(p) (&task_thread_info(p)->stackend)
+
+#endif /* __ASSEMBLY__ */
+
+#endif
arch/um/lkl/kernel/cpu.c new file +223 -0

223 lines not on this page · raw message

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

227 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 7/47 lkl: interrupt support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add APIs that allows the host to reserve and free and interrupt number and also to trigger an interrupt.

The trigger operation will simply store the interrupt data in queue. The interrupt handler is run later, at the first opportunity it has to avoid races with any kernel threads.

Currently, interrupts are run on the first interrupt enable operation if interrupts are disabled and if we are not already in interrupt context.

When triggering an interrupt the host can also send a void pointer that is going to be available to the handler routine via get_irq_regs()->irq_data. This allows to easly create host <-> kernel synchronous communication channels and is currently used by the system call interface.

---
 arch/um/lkl/include/asm/irq.h             |  15 ++
 arch/um/lkl/include/uapi/asm/irq.h        |  36 ++++
 arch/um/lkl/include/uapi/asm/sigcontext.h |  16 ++
 arch/um/lkl/kernel/irq.c                  | 193 ++++++++++++++++++++++
 4 files changed, 260 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/irq.h
 create mode 100644 arch/um/lkl/include/uapi/asm/irq.h
 create mode 100644 arch/um/lkl/include/uapi/asm/sigcontext.h
 create mode 100644 arch/um/lkl/kernel/irq.c
arch/um/lkl/include/asm/irq.h new file +15 -0
new file mode 100644
index 000000000000..36af9e36be1c
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_IRQ_H
+#define _ASM_LKL_IRQ_H
+
+#ifndef __arch_um__
+#define IRQ_STATUS_BITS		(sizeof(long) * 8)
+#define NR_IRQS			((int)(IRQ_STATUS_BITS * IRQ_STATUS_BITS))
+#endif	/* __arch_um__ */
+
+void run_irqs(void);
+void set_irq_pending(int irq);
+
+#include <uapi/asm/irq.h>
+
+#endif
arch/um/lkl/include/uapi/asm/irq.h new file +36 -0
new file mode 100644
index 000000000000..666628b233eb
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_IRQ_H
+#define _ASM_UAPI_LKL_IRQ_H
+
+/**
+ * lkl_trigger_irq - generate an interrupt
+ *
+ * This function is used by the device host side to signal its Linux counterpart
+ * that some event happened.
+ *
+ * @irq - the irq number to signal
+ */
+int lkl_trigger_irq(int irq);
+
+/**
+ * lkl_get_free_irq - find and reserve a free IRQ number
+ *
+ * This function is called by the host device code to find an unused IRQ number
+ * and reserved it for its own use.
+ *
+ * @user - a string to identify the user
+ * @returns - and irq number that can be used by request_irq or an negative
+ * value in case of an error
+ */
+int lkl_get_free_irq(const char *user);
+
+/**
+ * lkl_put_irq - release an IRQ number previously obtained with lkl_get_free_irq
+ *
+ * @irq - irq number to release
+ * @user - string identifying the user; should be the same as the one passed to
+ * lkl_get_free_irq when the irq number was obtained
+ */
+void lkl_put_irq(int irq, const char *name);
+
+#endif
arch/um/lkl/include/uapi/asm/sigcontext.h new file +16 -0
new file mode 100644
index 000000000000..2f4848843d1d
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_SIGCONTEXT_H
+#define _ASM_UAPI_LKL_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+struct pt_regs {
+	void *irq_data;
+};
+
+struct sigcontext {
+	struct pt_regs regs;
+	unsigned long oldmask;
+};
+
+#endif
arch/um/lkl/kernel/irq.c new file +193 -0

193 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 8/47 lkl: system call interface and application API

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

The LKL 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 LKL limitations such as lack of virtual memory, signal, user processes, etc.

The host is using the LKL interrupt mechanism (lkl_trigger_irq) to initiate a system call. The system call is executed in the context of the init process.

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.

---
 arch/um/lkl/include/asm/unistd.h       |  29 +++
 arch/um/lkl/include/uapi/asm/unistd.h  |  18 ++
 arch/um/lkl/kernel/syscalls.c          | 246 +++++++++++++++++++++++++
 arch/um/lkl/kernel/syscalls_32.c       | 159 ++++++++++++++++
 arch/um/lkl/scripts/headers_install.py | 195 ++++++++++++++++++++
 5 files changed, 647 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/unistd.h
 create mode 100644 arch/um/lkl/include/uapi/asm/unistd.h
 create mode 100644 arch/um/lkl/kernel/syscalls.c
 create mode 100644 arch/um/lkl/kernel/syscalls_32.c
 create mode 100755 arch/um/lkl/scripts/headers_install.py
arch/um/lkl/include/asm/unistd.h new file +29 -0
new file mode 100644
index 000000000000..c0efc68bf41f
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <uapi/asm/unistd.h>
+
+__SYSCALL(__NR_virtio_mmio_device_add, sys_virtio_mmio_device_add)
+
+#define __SC_ASCII(t, a) #t "," #a
+
+#define __ASCII_MAP0(m, ...)
+#define __ASCII_MAP1(m, t, a) m(t, a)
+#define __ASCII_MAP2(m, t, a, ...) m(t, a) "," __ASCII_MAP1(m, __VA_ARGS__)
+#define __ASCII_MAP3(m, t, a, ...) m(t, a) "," __ASCII_MAP2(m, __VA_ARGS__)
+#define __ASCII_MAP4(m, t, a, ...) m(t, a) "," __ASCII_MAP3(m, __VA_ARGS__)
+#define __ASCII_MAP5(m, t, a, ...) m(t, a) "," __ASCII_MAP4(m, __VA_ARGS__)
+#define __ASCII_MAP6(m, t, a, ...) m(t, a) "," __ASCII_MAP5(m, __VA_ARGS__)
+#define __ASCII_MAP(n, ...) __ASCII_MAP##n(__VA_ARGS__)
+
+#ifdef __MINGW32__
+#define SECTION_ATTRS "n0"
+#else
+#define SECTION_ATTRS "a"
+#endif
+
+#define __SYSCALL_DEFINE_ARCH(x, name, ...)				\
+	asm(".section .syscall_defs,\"" SECTION_ATTRS "\"\n"		\
+	    ".ascii \"#ifdef __NR" #name "\\n\"\n"			\
+	    ".ascii \"SYSCALL_DEFINE" #x "(" #name ","			\
+	    __ASCII_MAP(x, __SC_ASCII, __VA_ARGS__) ")\\n\"\n"		\
+	    ".ascii \"#endif\\n\"\n"					\
+	    ".section .text\n");
arch/um/lkl/include/uapi/asm/unistd.h new file +18 -0
new file mode 100644
index 000000000000..561a7036821e
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#define __ARCH_WANT_SYSCALL_NO_AT
+#define __ARCH_WANT_SYSCALL_DEPRECATED
+#define __ARCH_WANT_SYSCALL_NO_FLAGS
+#define __ARCH_WANT_RENAMEAT
+#define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SET_GET_RLIMIT
+#define __ARCH_WANT_TIME32_SYSCALLS
+
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#define __ARCH_WANT_SYS_NEWFSTATAT
+#endif
+
+#include <asm-generic/unistd.h>
+
+#define __NR_virtio_mmio_device_add		(__NR_arch_specific_syscall + 0)
arch/um/lkl/kernel/syscalls.c new file +246 -0

246 lines not on this page · raw message

arch/um/lkl/kernel/syscalls_32.c new file +159 -0

159 lines not on this page · raw message

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

195 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 9/47 lkl: timers, time and delay support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Clockevent driver based on host timer operations and clocksource driver and udelay support based on host time operations.

---
 arch/um/lkl/kernel/time.c | 145 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 arch/um/lkl/kernel/time.c
arch/um/lkl/kernel/time.c new file +145 -0
new file mode 100644
index 000000000000..b8320e1bfa53
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/host_ops.h>
+
+static unsigned long long boot_time;
+
+void __ndelay(unsigned long nsecs)
+{
+	unsigned long long start = lkl_ops->time();
+
+	while (lkl_ops->time() < start + nsecs)
+		;
+}
+
+void __udelay(unsigned long usecs)
+{
+	__ndelay(usecs * NSEC_PER_USEC);
+}
+
+void __const_udelay(unsigned long xloops)
+{
+	__udelay(xloops / 0x10c7ul);
+}
+
+void calibrate_delay(void)
+{
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+	*ts = ns_to_timespec(lkl_ops->time());
+}
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ *
+ */
+unsigned long long sched_clock(void)
+{
+	if (!boot_time)
+		return 0;
+
+	return lkl_ops->time() - boot_time;
+}
+
+static u64 clock_read(struct clocksource *cs)
+{
+	return lkl_ops->time();
+}
+
+static struct clocksource clocksource = {
+	.name	= "lkl",
+	.rating = 499,
+	.read	= clock_read,
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+	.mask	= CLOCKSOURCE_MASK(64),
+};
+
+static void *timer;
+
+static int timer_irq;
+
+static void timer_fn(void *arg)
+{
+	lkl_trigger_irq(timer_irq);
+}
+
+static int clockevent_set_state_shutdown(struct clock_event_device *evt)
+{
+	if (timer) {
+		lkl_ops->timer_free(timer);
+		timer = NULL;
+	}
+
+	return 0;
+}
+
+static int clockevent_set_state_oneshot(struct clock_event_device *evt)
+{
+	timer = lkl_ops->timer_alloc(timer_fn, NULL);
+	if (!timer)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static irqreturn_t timer_irq_handler(int irq, void *dev_id)
+{
+	struct clock_event_device *dev = (struct clock_event_device *)dev_id;
+
+	dev->event_handler(dev);
+
+	return IRQ_HANDLED;
+}
+
+static int clockevent_next_event(unsigned long ns,
+				 struct clock_event_device *evt)
+{
+	return lkl_ops->timer_set_oneshot(timer, ns);
+}
+
+static struct clock_event_device clockevent = {
+	.name			= "lkl",
+	.features		= CLOCK_EVT_FEAT_ONESHOT,
+	.set_state_oneshot	= clockevent_set_state_oneshot,
+	.set_next_event		= clockevent_next_event,
+	.set_state_shutdown	= clockevent_set_state_shutdown,
+};
+
+static struct irqaction irq0  = {
+	.handler	= timer_irq_handler,
+	.flags		= IRQF_NOBALANCING | IRQF_TIMER,
+	.dev_id		= &clockevent,
+	.name		= "timer"
+};
+
+void __init time_init(void)
+{
+	int ret;
+
+	if (!lkl_ops->timer_alloc || !lkl_ops->timer_free ||
+	    !lkl_ops->timer_set_oneshot || !lkl_ops->time) {
+		pr_err("lkl: no time or timer support provided by host\n");
+		return;
+	}
+
+	timer_irq = lkl_get_free_irq("timer");
+	setup_irq(timer_irq, &irq0);
+
+	ret = clocksource_register_khz(&clocksource, 1000000);
+	if (ret)
+		pr_err("lkl: unable to register clocksource\n");
+
+	clockevents_config_and_register(&clockevent, NSEC_PER_SEC, 1,
+					ULONG_MAX);
+
+	boot_time = lkl_ops->time();
+	pr_info("lkl: time and timers initialized (irq%d)\n", timer_irq);
+}
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 10/47 lkl: memory mapped I/O support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

All memory mapped I/O access is redirected to the host via the iomem_access host operation. The host can setup the memory mapped I/O region via the ioremap operation.

This allows the host to implement support for various devices, such as block or network devices.

---
 arch/um/lkl/include/asm/io.h | 104 +++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/io.h
arch/um/lkl/include/asm/io.h new file +104 -0
new file mode 100644
index 000000000000..33d4e1a7feb2
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_IO_H
+#define _ASM_LKL_IO_H
+
+#include <asm/bug.h>
+#include <asm/host_ops.h>
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+	int ret;
+	u8 value;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 0);
+	WARN(ret, "error reading iomem %p", addr);
+
+	return value;
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+	int ret;
+	u16 value;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 0);
+	WARN(ret, "error reading iomem %p", addr);
+
+	return value;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+	int ret;
+	u32 value;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 0);
+	WARN(ret, "error reading iomem %p", addr);
+
+	return value;
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_readq __raw_readq
+static inline u64 __raw_readq(const volatile void __iomem *addr)
+{
+	int ret;
+	u64 value;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 0);
+	WARN(ret, "error reading iomem %p", addr);
+
+	return value;
+}
+#endif /* CONFIG_64BIT */
+
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 value, volatile void __iomem *addr)
+{
+	int ret;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 1);
+	WARN(ret, "error writing iomem %p", addr);
+}
+
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 value, volatile void __iomem *addr)
+{
+	int ret;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 1);
+	WARN(ret, "error writing iomem %p", addr);
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 value, volatile void __iomem *addr)
+{
+	int ret;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 1);
+	WARN(ret, "error writing iomem %p", addr);
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_writeq __raw_writeq
+static inline void __raw_writeq(u64 value, volatile void __iomem *addr)
+{
+	int ret;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 1);
+	WARN(ret, "error writing iomem %p", addr);
+}
+#endif /* CONFIG_64BIT */
+
+#define ioremap ioremap
+static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
+{
+	return (void __iomem *)lkl_ops->ioremap(offset, size);
+}
+
+#include <asm-generic/io.h>
+
+#endif /* _ASM_LKL_IO_H */
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 11/47 lkl: basic kernel console support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Write operations are deferred to the host print operation.

---
 arch/um/lkl/kernel/console.c | 42 ++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 arch/um/lkl/kernel/console.c
arch/um/lkl/kernel/console.c new file +42 -0
new file mode 100644
index 000000000000..54d7f756c6da
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <asm/host_ops.h>
+
+static void console_write(struct console *con, const char *str,
+			  unsigned int len)
+{
+	if (lkl_ops->print)
+		lkl_ops->print(str, len);
+}
+
+#ifdef CONFIG_LKL_EARLY_CONSOLE
+static struct console lkl_boot_console = {
+	.name	= "lkl_boot_console",
+	.write	= console_write,
+	.flags	= CON_PRINTBUFFER | CON_BOOT,
+	.index	= -1,
+};
+
+int __init lkl_boot_console_init(void)
+{
+	register_console(&lkl_boot_console);
+	return 0;
+}
+early_initcall(lkl_boot_console_init);
+#endif
+
+static struct console lkl_console = {
+	.name	= "lkl_console",
+	.write	= console_write,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1,
+};
+
+static int __init lkl_console_init(void)
+{
+	register_console(&lkl_console);
+	return 0;
+}
+core_initcall(lkl_console_init);
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 12/47 lkl: initialization and cleanup

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

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_stop_kernel will shutdown the kernel, terminate all threads and free all host resources used by the kernel before returning.

This patch also introduces idle CPU handling since it is closely related to the shutdown process. A host semaphore is used to wait for new interrupts when the kernel switches the CPU to idle to avoid wasting host CPU cycles. When the kernel is shutdown we terminate the idle thread at the first CPU idle event.

---
 arch/um/lkl/include/asm/setup.h |   7 ++
 arch/um/lkl/kernel/setup.c      | 193 ++++++++++++++++++++++++++++++++
 2 files changed, 200 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/setup.h
 create mode 100644 arch/um/lkl/kernel/setup.c
arch/um/lkl/include/asm/setup.h new file +7 -0
new file mode 100644
index 000000000000..b40955208cc6
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_SETUP_H
+#define _ASM_LKL_SETUP_H
+
+#define COMMAND_LINE_SIZE 4096
+
+#endif
arch/um/lkl/kernel/setup.c new file +193 -0

193 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 13/47 lkl: plug in the build system

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

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

---
 arch/um/Makefile.um         | 117 ++++++++++++++++++++++++++++++++++++
 arch/um/lkl/auto.conf       |   1 +
 arch/um/lkl/kernel/Makefile |   4 ++
 arch/um/lkl/mm/Makefile     |   1 +
 4 files changed, 123 insertions(+)
 create mode 100644 arch/um/Makefile.um
 create mode 100644 arch/um/lkl/auto.conf
 create mode 100644 arch/um/lkl/kernel/Makefile
 create mode 100644 arch/um/lkl/mm/Makefile
arch/um/Makefile.um new file +117 -0
new file mode 100644
index 000000000000..24a088e5df04
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+# Licensed under the GPL
+#
+
+core-y			+= $(ARCH_DIR)/kernel/		\
+			 $(ARCH_DIR)/drivers/		\
+			 $(ARCH_DIR)/os-$(OS)/
+
+ifdef CONFIG_64BIT
+	KBUILD_CFLAGS += -mcmodel=large
+endif
+
+SHARED_HEADERS	:= $(ARCH_DIR)/include/shared
+ARCH_INCLUDE	:= -I$(srctree)/$(SHARED_HEADERS)
+ARCH_INCLUDE	+= -I$(srctree)/$(HOST_DIR)/um/shared
+KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um
+
+# -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so
+# named - it's a common symbol in libpcap, so we get a binary which crashes.
+#
+# Same things for in6addr_loopback and mktime - found in libc. For these two we
+# only get link-time error, luckily.
+#
+# -Dlongjmp=kernel_longjmp prevents anything from referencing the libpthread.a
+# embedded copy of longjmp, same thing for setjmp.
+#
+# These apply to USER_CFLAGS to.
+
+KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \
+	$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap	\
+	-Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \
+	-Din6addr_loopback=kernel_in6addr_loopback \
+	-Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr
+
+KBUILD_AFLAGS += $(ARCH_INCLUDE)
+
+USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
+		$(ARCH_INCLUDE) $(MODE_INCLUDE) $(filter -I%,$(CFLAGS)) \
+		-D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \
+		-idirafter $(obj)/include -D__KERNEL__ -D__UM_HOST__
+
+#This will adjust *FLAGS accordingly to the platform.
+include $(ARCH_DIR)/Makefile-os-$(OS)
+
+KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include \
+		   -I$(srctree)/$(HOST_DIR)/include/uapi \
+		   -I$(objtree)/$(HOST_DIR)/include/generated \
+		   -I$(objtree)/$(HOST_DIR)/include/generated/uapi
+
+# -Derrno=kernel_errno - This turns all kernel references to errno into
+# kernel_errno to separate them from the libc errno.  This allows -fno-common
+# in KBUILD_CFLAGS.  Otherwise, it would cause ld to complain about the two different
+# errnos.
+# These apply to kernelspace only.
+#
+# strip leading and trailing whitespace to make the USER_CFLAGS removal of these
+# defines more robust
+
+KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
+			 -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES))
+KBUILD_CFLAGS += $(KERNEL_DEFINES)
+
+PHONY += linux
+
+all: linux
+
+linux: vmlinux
+	@echo '  LINK $@'
+	$(Q)ln -f $< $@
+
+define archhelp
+  echo '* linux		- Binary kernel image (./linux) - for backward'
+  echo '		   compatibility only, this creates a hard link to the'
+  echo '		   real kernel binary, the "vmlinux" binary you'
+  echo '		   find in the kernel root.'
+endef
+
+archheaders:
+	$(Q)$(MAKE) -f $(srctree)/Makefile ARCH=$(HEADER_ARCH) asm-generic archheaders
+
+archprepare:
+	$(Q)$(MAKE) $(build)=$(HOST_DIR)/um include/generated/user_constants.h
+
+LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
+LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib $(call cc-option, -no-pie)
+
+CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
+	$(call cc-option, -fno-stack-protector,) \
+	$(call cc-option, -fno-stack-protector-all,)
+
+# Options used by linker script
+export LDS_START      := $(START)
+export LDS_ELF_ARCH   := $(ELF_ARCH)
+export LDS_ELF_FORMAT := $(ELF_FORMAT)
+
+# The wrappers will select whether using "malloc" or the kernel allocator.
+LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+
+LD_FLAGS_CMDLINE = $(foreach opt,$(KBUILD_LDFLAGS),-Wl,$(opt))
+
+# Used by link-vmlinux.sh which has special support for um link
+export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE)
+
+# When cleaning we don't include .config, so we don't include
+# TT or skas makefiles and don't clean skas_ptregs.h.
+CLEAN_FILES += linux x.i gmon.out
+
+archclean:
+	@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
+		-o -name '*.gcov' \) -type f -print | xargs rm -f
+
+export USER_CFLAGS CFLAGS_NO_HARDENING OS DEV_NULL_PATH
arch/um/lkl/auto.conf new file +1 -0
new file mode 100644
index 000000000000..4bfd65a02d73
@@ -0,0 +1 @@
+export OUTPUT_FORMAT=$(shell $(LD) -r -print-output-format)
arch/um/lkl/kernel/Makefile new file +4 -0
new file mode 100644
index 000000000000..ef489f2f7176
@@ -0,0 +1,4 @@
+extra-y := vmlinux.lds
+
+obj-y = setup.o threads.o irq.o time.o syscalls.o misc.o console.o \
+	syscalls_32.o cpu.o
arch/um/lkl/mm/Makefile new file +1 -0
new file mode 100644
index 000000000000..2af6e3051897
@@ -0,0 +1 @@
+obj-y = bootmem.o
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 14/47 lkl tools: skeleton for host side library, tests and tools

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This patch adds the skeleton for the host library, tests and application examples.

The host library is implementing the host operations needed by LKL 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/lkl/.gitignore         |  14 +
 tools/lkl/Build              |   6 +
 tools/lkl/Makefile           | 130 +++++
 tools/lkl/Makefile.autoconf  | 114 +++++
 tools/lkl/Targets            |  27 +
 tools/lkl/include/.gitignore |   1 +
 tools/lkl/include/lkl.h      | 928 +++++++++++++++++++++++++++++++++++
 tools/lkl/include/lkl_host.h | 160 ++++++
 tools/lkl/lib/.gitignore     |   3 +
 tools/lkl/lib/Build          |  25 +
 10 files changed, 1408 insertions(+)
 create mode 100644 tools/lkl/.gitignore
 create mode 100644 tools/lkl/Build
 create mode 100644 tools/lkl/Makefile
 create mode 100644 tools/lkl/Makefile.autoconf
 create mode 100644 tools/lkl/Targets
 create mode 100644 tools/lkl/include/.gitignore
 create mode 100644 tools/lkl/include/lkl.h
 create mode 100644 tools/lkl/include/lkl_host.h
 create mode 100644 tools/lkl/lib/.gitignore
 create mode 100644 tools/lkl/lib/Build
tools/lkl/.gitignore new file +14 -0
new file mode 100644
index 000000000000..796785986336
@@ -0,0 +1,14 @@
+tests/boot
+fs2tar
+cptofs
+cpfromfs
+lklfuse
+tests/valgrind*.xml
+*.exe
+*.dll
+tests/net-test
+tests/disk
+Makefile.conf
+include/lkl_autoconf.h
+tests/autoconf.sh
+*.pyc
tools/lkl/Build new file +6 -0
new file mode 100644
index 000000000000..6048440d0e1b
@@ -0,0 +1,6 @@
+CFLAGS_lklfuse.o += -D_FILE_OFFSET_BITS=64
+
+cptofs-$(LKL_HOST_CONFIG_ARCHIVE) += cptofs.o
+fs2tar-$(LKL_HOST_CONFIG_ARCHIVE) += fs2tar.o
+lklfuse-$(LKL_HOST_CONFIG_FUSE) += lklfuse.o
+
tools/lkl/Makefile new file +130 -0

130 lines not on this page · raw message

tools/lkl/Makefile.autoconf new file +114 -0

114 lines not on this page · raw message

tools/lkl/Targets new file +27 -0
new file mode 100644
index 000000000000..e6394fae4526
@@ -0,0 +1,27 @@
+libs-y += lib/liblkl
+
+ifneq ($(LKL_HOST_CONFIG_BSD),y)
+libs-$(LKL_HOST_CONFIG_POSIX) += lib/hijack/liblkl-hijack
+endif
+LDFLAGS_lib/hijack/liblkl-hijack-y += -shared -nodefaultlibs
+LDLIBS_lib/hijack/liblkl-hijack-y += -ldl
+LDLIBS_lib/hijack/liblkl-hijack-$(LKL_HOST_CONFIG_ARM) += -lgcc -lc
+LDLIBS_lib/hijack/liblkl-hijack-$(LKL_HOST_CONFIG_AARCH64) += -lc
+LDLIBS_lib/hijack/liblkl-hijack-$(LKL_HOST_CONFIG_I386) += -lc_nonshared
+
+progs-$(LKL_HOST_CONFIG_FUSE) += lklfuse
+LDLIBS_lklfuse-y := -lfuse
+
+progs-$(LKL_HOST_CONFIG_ARCHIVE) += fs2tar
+LDLIBS_fs2tar-y := -larchive
+LDLIBS_fs2tar-$(LKL_HOST_CONFIG_NEEDS_LARGP) += -largp
+
+
+progs-$(LKL_HOST_CONFIG_ARCHIVE) += cptofs
+LDLIBS_cptofs-y := -larchive
+LDLIBS_cptofs-$(LKL_HOST_CONFIG_NEEDS_LARGP) += -largp
+
+progs-y += tests/boot
+progs-y += tests/disk
+progs-y += tests/net-test
+
tools/lkl/include/.gitignore new file +1 -0
new file mode 100644
index 000000000000..c41a463c898d
@@ -0,0 +1 @@
+lkl/
\ No newline at end of file
tools/lkl/include/lkl.h new file +928 -0

928 lines not on this page · raw message

tools/lkl/include/lkl_host.h new file +160 -0

160 lines not on this page · raw message

tools/lkl/lib/.gitignore new file +3 -0
new file mode 100644
index 000000000000..427ae0273fdd
@@ -0,0 +1,3 @@
+lkl.o
+liblkl.a
+
tools/lkl/lib/Build new file +25 -0
new file mode 100644
index 000000000000..719c7308c830
@@ -0,0 +1,25 @@
+CFLAGS_posix-host.o += -D_FILE_OFFSET_BITS=64
+CFLAGS_virtio_net_vde.o += $(pkg-config --cflags vdeplug 2>/dev/null)
+CFLAGS_nt-host.o += -D_WIN32_WINNT=0x0600
+
+liblkl-y += fs.o
+liblkl-y += iomem.o
+liblkl-y += net.o
+liblkl-y += jmp_buf.o
+liblkl-$(LKL_HOST_CONFIG_POSIX) += posix-host.o
+liblkl-$(LKL_HOST_CONFIG_NT) += nt-host.o
+liblkl-y += utils.o
+liblkl-y += virtio_blk.o
+liblkl-y += virtio.o
+liblkl-y += dbg.o
+liblkl-y += dbg_handler.o
+liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net.o
+liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_fd.o
+liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_tap.o
+liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_raw.o
+liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET_MACVTAP) += virtio_net_macvtap.o
+liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET_DPDK) += virtio_net_dpdk.o
+liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET_VDE) += virtio_net_vde.o
+liblkl-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_pipe.o
+liblkl-y += ../../perf/pmu-events/jsmn.o
+liblkl-y += config.o
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 15/47 lkl tools: host lib: add utilities functions

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

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.

Other configuration and debug utilities are also added.

---
 tools/lkl/include/lkl_config.h |  61 +++
 tools/lkl/lib/config.c         | 793 +++++++++++++++++++++++++++++++++
 tools/lkl/lib/dbg.c            | 300 +++++++++++++
 tools/lkl/lib/dbg_handler.c    |  44 ++
 tools/lkl/lib/endian.h         |  31 ++
 tools/lkl/lib/jmp_buf.c        |  14 +
 tools/lkl/lib/jmp_buf.h        |   8 +
 tools/lkl/lib/utils.c          | 266 +++++++++++
 8 files changed, 1517 insertions(+)
 create mode 100644 tools/lkl/include/lkl_config.h
 create mode 100644 tools/lkl/lib/config.c
 create mode 100644 tools/lkl/lib/dbg.c
 create mode 100644 tools/lkl/lib/dbg_handler.c
 create mode 100644 tools/lkl/lib/endian.h
 create mode 100644 tools/lkl/lib/jmp_buf.c
 create mode 100644 tools/lkl/lib/jmp_buf.h
 create mode 100644 tools/lkl/lib/utils.c
tools/lkl/include/lkl_config.h new file +61 -0
new file mode 100644
index 000000000000..d3edf8b414cf
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_LIB_CONFIG_H
+#define _LKL_LIB_CONFIG_H
+
+#define LKL_CONFIG_JSON_TOKEN_MAX 300
+
+struct lkl_config_iface {
+	struct lkl_config_iface *next;
+	struct lkl_netdev *nd;
+
+	/* OBSOLETE: should use IFTYPE and IFPARAMS */
+	char *iftap;
+	char *iftype;
+	char *ifparams;
+	char *ifmtu_str;
+	char *ifip;
+	char *ifipv6;
+	char *ifgateway;
+	char *ifgateway6;
+	char *ifmac_str;
+	char *ifnetmask_len;
+	char *ifnetmask6_len;
+	char *ifoffload_str;
+	char *ifneigh_entries;
+	char *ifqdisc_entries;
+};
+
+struct lkl_config {
+	int ifnum;
+	struct lkl_config_iface *ifaces;
+
+	char *gateway;
+	char *gateway6;
+	char *debug;
+	char *mount;
+	/* single_cpu mode:
+	 * 0: Don't pin to single CPU (default).
+	 * 1: Pin only LKL kernel threads to single CPU.
+	 * 2: Pin all LKL threads to single CPU including all LKL kernel threads
+	 * and device polling threads. Avoid this mode if having busy polling
+	 * threads.
+	 *
+	 * mode 2 can achieve better TCP_RR but worse TCP_STREAM than mode 1.
+	 * You should choose the best for your application and virtio device
+	 * type.
+	 */
+	char *single_cpu;
+	char *sysctls;
+	char *boot_cmdline;
+	char *dump;
+	char *delay_main;
+};
+
+int lkl_load_config_json(struct lkl_config *cfg, char *jstr);
+int lkl_load_config_env(struct lkl_config *cfg);
+void lkl_show_config(struct lkl_config *cfg);
+int lkl_load_config_pre(struct lkl_config *cfg);
+int lkl_load_config_post(struct lkl_config *cfg);
+int lkl_unload_config(struct lkl_config *cfg);
+
+#endif /* _LKL_LIB_CONFIG_H */
tools/lkl/lib/config.c new file +793 -0

793 lines not on this page · raw message

tools/lkl/lib/dbg.c new file +300 -0

300 lines not on this page · raw message

tools/lkl/lib/dbg_handler.c new file +44 -0

44 lines not on this page · raw message

tools/lkl/lib/endian.h new file +31 -0
new file mode 100644
index 000000000000..aaccfa0edb65
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_LIB_ENDIAN_H
+#define _LKL_LIB_ENDIAN_H
+
+#if defined(__FreeBSD__)
+#include <sys/endian.h>
+#elif defined(__ANDROID__)
+#include <sys/endian.h>
+#elif defined(__MINGW32__)
+#include <winsock.h>
+#define le32toh(x) (x)
+#define le16toh(x) (x)
+#define htole32(x) (x)
+#define htole16(x) (x)
+#define le64toh(x) (x)
+#define htobe32(x) htonl(x)
+#define htobe16(x) htons(x)
+#define be32toh(x) ntohl(x)
+#define be16toh(x) ntohs(x)
+#else
+#include <endian.h>
+#endif
+
+#ifndef htonl
+#define htonl(x) htobe32(x)
+#define htons(x) htobe16(x)
+#define ntohl(x) be32toh(x)
+#define ntohs(x) be16toh(x)
+#endif
+
+#endif /* _LKL_LIB_ENDIAN_H */
tools/lkl/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/lkl/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/lkl/lib/utils.c new file +266 -0

266 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 16/47 lkl tools: host lib: memory mapped I/O helpers

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This patch adds helpers for implementing the memory mapped I/O host operations that can be used by code that implements host devices. Generic host operations for lkl_ioremap and lkl_iomem_access are provided that allows multiplexing multiple I/O memory mapped regions.

The host device code can create a new memory mapped I/O region with register_iomem(). Read and write access functions need to be provided by the caller.

---
 tools/lkl/lib/iomem.c | 88 +++++++++++++++++++++++++++++++++++++++++++
 tools/lkl/lib/iomem.h | 15 ++++++++
 2 files changed, 103 insertions(+)
 create mode 100644 tools/lkl/lib/iomem.c
 create mode 100644 tools/lkl/lib/iomem.h
tools/lkl/lib/iomem.c new file +88 -0
new file mode 100644
index 000000000000..2301fe4e5ad5
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include <stdint.h>
+#include <lkl_host.h>
+
+#include "iomem.h"
+
+#define IOMEM_OFFSET_BITS		24
+#define MAX_IOMEM_REGIONS		256
+
+#define IOMEM_ADDR_TO_INDEX(addr) \
+	(((uintptr_t)addr) >> IOMEM_OFFSET_BITS)
+#define IOMEM_ADDR_TO_OFFSET(addr) \
+	(((uintptr_t)addr) & ((1 << IOMEM_OFFSET_BITS) - 1))
+#define IOMEM_INDEX_TO_ADDR(i) \
+	(void *)(uintptr_t)(i << IOMEM_OFFSET_BITS)
+
+static struct iomem_region {
+	void *data;
+	int size;
+	const struct lkl_iomem_ops *ops;
+} iomem_regions[MAX_IOMEM_REGIONS];
+
+void *register_iomem(void *data, int size, const struct lkl_iomem_ops *ops)
+{
+	int i;
+
+	if (size > (1 << IOMEM_OFFSET_BITS) - 1)
+		return NULL;
+
+	for (i = 1; i < MAX_IOMEM_REGIONS; i++)
+		if (!iomem_regions[i].ops)
+			break;
+
+	if (i >= MAX_IOMEM_REGIONS)
+		return NULL;
+
+	iomem_regions[i].data = data;
+	iomem_regions[i].size = size;
+	iomem_regions[i].ops = ops;
+	return IOMEM_INDEX_TO_ADDR(i);
+}
+
+void unregister_iomem(void *base)
+{
+	unsigned int index = IOMEM_ADDR_TO_INDEX(base);
+
+	if (index >= MAX_IOMEM_REGIONS) {
+		lkl_printf("%s: invalid iomem_addr %p\n", __func__, base);
+		return;
+	}
+
+	iomem_regions[index].size = 0;
+	iomem_regions[index].ops = NULL;
+}
+
+void *lkl_ioremap(long addr, int size)
+{
+	int index = IOMEM_ADDR_TO_INDEX(addr);
+	struct iomem_region *iomem = &iomem_regions[index];
+
+	if (index >= MAX_IOMEM_REGIONS)
+		return NULL;
+
+	if (iomem->ops && size <= iomem->size)
+		return IOMEM_INDEX_TO_ADDR(index);
+
+	return NULL;
+}
+
+int lkl_iomem_access(const volatile void *addr, void *res, int size, int write)
+{
+	int index = IOMEM_ADDR_TO_INDEX(addr);
+	struct iomem_region *iomem = &iomem_regions[index];
+	int offset = IOMEM_ADDR_TO_OFFSET(addr);
+	int ret;
+
+	if (index > MAX_IOMEM_REGIONS || !iomem_regions[index].ops ||
+	    offset + size > iomem_regions[index].size)
+		return -1;
+
+	if (write)
+		ret = iomem->ops->write(iomem->data, offset, res, size);
+	else
+		ret = iomem->ops->read(iomem->data, offset, res, size);
+
+	return ret;
+}
tools/lkl/lib/iomem.h new file +15 -0
new file mode 100644
index 000000000000..0ad80ccc2626
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_LIB_IOMEM_H
+#define _LKL_LIB_IOMEM_H
+
+struct lkl_iomem_ops {
+	int (*read)(void *data, int offset, void *res, int size);
+	int (*write)(void *data, int offset, void *value, int size);
+};
+
+void *register_iomem(void *data, int size, const struct lkl_iomem_ops *ops);
+void unregister_iomem(void *iomem_base);
+void *lkl_ioremap(long addr, int size);
+int lkl_iomem_access(const volatile void *addr, void *res, int size, int write);
+
+#endif /* _LKL_LIB_IOMEM_H */
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 17/47 lkl tools: host lib: virtio devices

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add helpers for implementing host virtio devices. It uses the memory mapped I/O helpers to interact with the Linux MMIO virtio transport driver and offers support to setup and add a new virtio device, dispatch requests from the incoming queues as well as support for completing requests.

All added virtio devices are stored in lkl_virtio_devs as strings, per the Linux MMIO virtio transport driver command line specification.

---
 tools/lkl/lib/virtio.c | 631 +++++++++++++++++++++++++++++++++++++++++
 tools/lkl/lib/virtio.h |  93 ++++++
 2 files changed, 724 insertions(+)
 create mode 100644 tools/lkl/lib/virtio.c
 create mode 100644 tools/lkl/lib/virtio.h
tools/lkl/lib/virtio.c new file +631 -0
new file mode 100644
index 000000000000..4b3dbba607c3
@@ -0,0 +1,631 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <lkl_host.h>
+#include <lkl/linux/virtio_ring.h>
+#include "iomem.h"
+#include "virtio.h"
+#include "endian.h"
+
+#define VIRTIO_DEV_MAGIC		0x74726976
+#define VIRTIO_DEV_VERSION		2
+
+#define VIRTIO_MMIO_MAGIC_VALUE		0x000
+#define VIRTIO_MMIO_VERSION		0x004
+#define VIRTIO_MMIO_DEVICE_ID		0x008
+#define VIRTIO_MMIO_VENDOR_ID		0x00c
+#define VIRTIO_MMIO_DEVICE_FEATURES	0x010
+#define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014
+#define VIRTIO_MMIO_DRIVER_FEATURES	0x020
+#define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024
+#define VIRTIO_MMIO_QUEUE_SEL		0x030
+#define VIRTIO_MMIO_QUEUE_NUM_MAX	0x034
+#define VIRTIO_MMIO_QUEUE_NUM		0x038
+#define VIRTIO_MMIO_QUEUE_READY		0x044
+#define VIRTIO_MMIO_QUEUE_NOTIFY	0x050
+#define VIRTIO_MMIO_INTERRUPT_STATUS	0x060
+#define VIRTIO_MMIO_INTERRUPT_ACK	0x064
+#define VIRTIO_MMIO_STATUS		0x070
+#define VIRTIO_MMIO_QUEUE_DESC_LOW	0x080
+#define VIRTIO_MMIO_QUEUE_DESC_HIGH	0x084
+#define VIRTIO_MMIO_QUEUE_AVAIL_LOW	0x090
+#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH	0x094
+#define VIRTIO_MMIO_QUEUE_USED_LOW	0x0a0
+#define VIRTIO_MMIO_QUEUE_USED_HIGH	0x0a4
+#define VIRTIO_MMIO_CONFIG_GENERATION	0x0fc
+#define VIRTIO_MMIO_CONFIG		0x100
+#define VIRTIO_MMIO_INT_VRING		0x01
+#define VIRTIO_MMIO_INT_CONFIG		0x02
+
+#define BIT(x) (1ULL << x)
+
+#define virtio_panic(msg, ...) do {					\
+		lkl_printf("LKL virtio error" msg, ##__VA_ARGS__);	\
+		lkl_host_ops.panic();					\
+	} while (0)
+
+struct virtio_queue {
+	uint32_t num_max;
+	uint32_t num;
+	uint32_t ready;
+	uint32_t max_merge_len;
+
+	struct lkl_vring_desc *desc;
+	struct lkl_vring_avail *avail;
+	struct lkl_vring_used *used;
+	uint16_t last_avail_idx;
+	uint16_t last_used_idx_signaled;
+};
+
+struct _virtio_req {
+	struct virtio_req req;
+	struct virtio_dev *dev;
+	struct virtio_queue *q;
+	uint16_t idx;
+};
+
+
+static inline uint16_t virtio_get_used_event(struct virtio_queue *q)
+{
+	return q->avail->ring[q->num];
+}
+
+static inline void virtio_set_avail_event(struct virtio_queue *q, uint16_t val)
+{
+	*((uint16_t *)&q->used->ring[q->num]) = val;
+}
+
+static inline void virtio_deliver_irq(struct virtio_dev *dev)
+{
+	dev->int_status |= VIRTIO_MMIO_INT_VRING;
+	/* Make sure all memory writes before are visible to the driver. */
+	__sync_synchronize();
+	lkl_trigger_irq(dev->irq);
+}
+
+static inline uint16_t virtio_get_used_idx(struct virtio_queue *q)
+{
+	return le16toh(q->used->idx);
+}
+
+static inline void virtio_add_used(struct virtio_queue *q, uint16_t used_idx,
+				   uint16_t avail_idx, uint16_t len)
+{
+	uint16_t desc_idx = q->avail->ring[avail_idx & (q->num - 1)];
+
+	used_idx = used_idx & (q->num - 1);
+	q->used->ring[used_idx].id = desc_idx;
+	q->used->ring[used_idx].len = htole16(len);
+}
+
+/*
+ * Make sure all memory writes before are visible to the driver before updating
+ * the idx.  We need it here even we already have one in virtio_deliver_irq()
+ * because there might already be an driver thread reading the idx and dequeuing
+ * used buffers.
+ */
+static inline void virtio_sync_used_idx(struct virtio_queue *q, uint16_t idx)
+{
+	__sync_synchronize();
+	q->used->idx = htole16(idx);
+}
+
+#define min_len(a, b) (a < b ? a : b)
+
+void virtio_req_complete(struct virtio_req *req, uint32_t len)
+{
+	int send_irq = 0;
+	struct _virtio_req *_req = container_of(req, struct _virtio_req, req);
+	struct virtio_queue *q = _req->q;
+	uint16_t avail_idx = _req->idx;
+	uint16_t used_idx = virtio_get_used_idx(_req->q);
+	int i;
+
+	/*
+	 * We've potentially used up multiple (non-chained) descriptors and have
+	 * to create one "used" entry for each descriptor we've consumed.
+	 */
+	for (i = 0; i < req->buf_count; i++) {
+		uint16_t used_len;
+
+		if (!q->max_merge_len)
+			used_len = len;
+		else
+			used_len = min_len(len,  req->buf[i].iov_len);
+
+		virtio_add_used(q, used_idx++, avail_idx++, used_len);
+
+		len -= used_len;
+		if (!len)
+			break;
+	}
+	virtio_sync_used_idx(q, used_idx);
+	q->last_avail_idx = avail_idx;
+
+	/*
+	 * Triggers the irq whenever there is no available buffer.
+	 */
+	if (q->last_avail_idx == le16toh(q->avail->idx))
+		send_irq = 1;
+
+	/*
+	 * There are two rings: q->avail and q->used for each of the rx and tx
+	 * queues that are used to pass buffers between kernel driver and the
+	 * virtio device implementation.
+	 *
+	 * Kernel maitains the first one and appends buffers to it. In rx queue,
+	 * it's empty buffers kernel offers to store received packets. In tx
+	 * queue, it's buffers containing packets to transmit. Kernel notifies
+	 * the device by mmio write (see VIRTIO_MMIO_QUEUE_NOTIFY below).
+	 *
+	 * The virtio device (here in this file) maintains the
+	 * q->used and appends buffer to it after consuming it from q->avail.
+	 *
+	 * The device needs to notify the driver by triggering irq here. The
+	 * LKL_VIRTIO_RING_F_EVENT_IDX is enabled in this implementation so
+	 * kernel can set virtio_get_used_event(q) to tell the device to "only
+	 * trigger the irq when this item in q->used ring is populated."
+	 *
+	 * Because driver and device are run in two different threads. When
+	 * driver sets virtio_get_used_event(q), q->used->idx may already be
+	 * increased to a larger one. So we need to trigger the irq when
+	 * virtio_get_used_event(q) < q->used->idx.
+	 *
+	 * To avoid unnessary irqs for each packet after
+	 * virtio_get_used_event(q) < q->used->idx, last_used_idx_signaled is
+	 * stored and irq is only triggered if
+	 * last_used_idx_signaled <= virtio_get_used_event(q) < q->used->idx
+	 *
+	 * This is what lkl_vring_need_event() checks and it evens covers the
+	 * case when those numbers wrap up.
+	 */
+	if (send_irq || lkl_vring_need_event(le16toh(virtio_get_used_event(q)),
+					     virtio_get_used_idx(q),
+					     q->last_used_idx_signaled)) {
+		q->last_used_idx_signaled = virtio_get_used_idx(q);
+		virtio_deliver_irq(_req->dev);
+	}
+}
+
+/*
+ * Grab the vring_desc from the queue at the appropriate index in the
+ * queue's circular buffer, converting from little-endian to
+ * the host's endianness.
+ */
+static inline
+struct lkl_vring_desc *vring_desc_at_le_idx(struct virtio_queue *q,
+					    __lkl__virtio16 le_idx)
+{
+	return &q->desc[le16toh(le_idx) & (q->num - 1)];
+}
+
+static inline
+struct lkl_vring_desc *vring_desc_at_avail_idx(struct virtio_queue *q,
+					       uint16_t idx)
+{
+	uint16_t desc_idx = q->avail->ring[idx & (q->num - 1)];
+
+	return vring_desc_at_le_idx(q, desc_idx);
+}
+
+/* Initialize buf to hold the same info as the vring_desc */
+static void add_dev_buf_from_vring_desc(struct virtio_req *req,
+					struct lkl_vring_desc *vring_desc)
+{
+	struct iovec *buf = &req->buf[req->buf_count++];
+
+	buf->iov_base = (void *)(uintptr_t)le64toh(vring_desc->addr);
+	buf->iov_len = le32toh(vring_desc->len);
+
+	if (!(buf->iov_base && buf->iov_len))
+		virtio_panic("bad vring_desc: %p %d\n",
+			     buf->iov_base, buf->iov_len);
+
+	req->total_len += buf->iov_len;
+}
+
+static struct lkl_vring_desc *get_next_desc(struct virtio_queue *q,
+					    struct lkl_vring_desc *desc,
+					    uint16_t *idx)
+{
+	uint16_t desc_idx;
+
+	if (q->max_merge_len) {
+		if (++(*idx) == le16toh(q->avail->idx))
+			return NULL;
+		desc_idx = q->avail->ring[*idx & (q->num - 1)];
+		return vring_desc_at_le_idx(q, desc_idx);
+	}
+
+	if (!(le16toh(desc->flags) & LKL_VRING_DESC_F_NEXT))
+		return NULL;
+	return vring_desc_at_le_idx(q, desc->next);
+}
+
+/*
+ * Below there are two distinctly different (per packet) buffer allocation
+ * schemes for us to deal with:
+ *
+ * 1. One or more descriptors chained through "next" as indicated by the
+ *    LKL_VRING_DESC_F_NEXT flag,
+ * 2. One or more descriptors from the ring sequentially, as many as are
+ *    available and needed. This is the RX only "mergeable_rx_bufs" mode.
+ *    The mode is entered when the VIRTIO_NET_F_MRG_RXBUF device feature
+ *    is enabled.
+ */
+static int virtio_process_one(struct virtio_dev *dev, int qidx)
+{
+	struct virtio_queue *q = &dev->queue[qidx];
+	uint16_t idx = q->last_avail_idx;
+	struct _virtio_req _req = {
+		.dev = dev,
+		.q = q,
+		.idx = idx,
+	};
+	struct virtio_req *req = &_req.req;
+	struct lkl_vring_desc *desc = vring_desc_at_avail_idx(q, _req.idx);
+
+	do {
+		add_dev_buf_from_vring_desc(req, desc);
+		if (q->max_merge_len && req->total_len > q->max_merge_len)
+			break;
+		desc = get_next_desc(q, desc, &idx);
+	} while (desc && req->buf_count < VIRTIO_REQ_MAX_BUFS);
+
+	if (desc && le16toh(desc->flags) & LKL_VRING_DESC_F_NEXT)
+		virtio_panic("too many chained bufs");
+
+	return dev->ops->enqueue(dev, qidx, req);
+}
+
+/* NB: we can enter this function two different ways in the case of
+ * netdevs --- either through a tx/rx thread poll (which the LKL
+ * scheduler knows nothing about) or through virtio_write called
+ * inside an interrupt handler, so to be safe, it's not enough to
+ * synchronize only the tx/rx polling threads.
+ *
+ * At the moment, it seems like only netdevs require the
+ * synchronization we do here (i.e. locking around operations on a
+ * particular virtqueue, with dev->ops->acquire_queue), since they
+ * have these two different entry points, one of which isn't managed
+ * by the LKL scheduler. So only devs corresponding to netdevs will
+ * have non-NULL acquire/release_queue.
+ *
+ * In the future, this may change. If you see errors thrown in virtio
+ * driver code by block/console devices, you should be suspicious of
+ * the synchronization going on here.
+ */
+void virtio_process_queue(struct virtio_dev *dev, uint32_t qidx)
+{
+	struct virtio_queue *q = &dev->queue[qidx];
+
+	if (!q->ready)
+		return;
+
+	if (dev->ops->acquire_queue)
+		dev->ops->acquire_queue(dev, qidx);
+
+	while (q->last_avail_idx != le16toh(q->avail->idx)) {
+		/*
+		 * Make sure following loads happens after loading
+		 * q->avail->idx.
+		 */
+		__sync_synchronize();
+		if (virtio_process_one(dev, qidx) < 0)
+			break;
+		if (q->last_avail_idx == le16toh(q->avail->idx))
+			virtio_set_avail_event(q, q->avail->idx);
+	}
+
+	if (dev->ops->release_queue)
+		dev->ops->release_queue(dev, qidx);
+}
+
+static inline uint32_t virtio_read_device_features(struct virtio_dev *dev)
+{
+	if (dev->device_features_sel)
+		return (uint32_t)(dev->device_features >> 32);
+
+	return (uint32_t)dev->device_features;
+}
+
+static inline void virtio_write_driver_features(struct virtio_dev *dev,
+						uint32_t val)
+{
+	uint64_t tmp;
+
+	if (dev->driver_features_sel) {
+		tmp = dev->driver_features & 0xFFFFFFFF;
+		dev->driver_features = tmp | (uint64_t)val << 32;
+	} else {
+		tmp = dev->driver_features & 0xFFFFFFFF00000000;
+		dev->driver_features = tmp | val;
+	}
+}
+
+static int virtio_read(void *data, int offset, void *res, int size)
+{
+	uint32_t val;
+	struct virtio_dev *dev = (struct virtio_dev *)data;
+
+	if (offset >= VIRTIO_MMIO_CONFIG) {
+		offset -= VIRTIO_MMIO_CONFIG;
+		if (offset + size > dev->config_len)
+			return -LKL_EINVAL;
+		memcpy(res, dev->config_data + offset, size);
+		return 0;
+	}
+
+	if (size != sizeof(uint32_t))
+		return -LKL_EINVAL;
+
+	switch (offset) {
+	case VIRTIO_MMIO_MAGIC_VALUE:
+		val = VIRTIO_DEV_MAGIC;
+		break;
+	case VIRTIO_MMIO_VERSION:
+		val = VIRTIO_DEV_VERSION;
+		break;
+	case VIRTIO_MMIO_DEVICE_ID:
+		val = dev->device_id;
+		break;
+	case VIRTIO_MMIO_VENDOR_ID:
+		val = dev->vendor_id;
+		break;
+	case VIRTIO_MMIO_DEVICE_FEATURES:
+		val = virtio_read_device_features(dev);
+		break;
+	case VIRTIO_MMIO_QUEUE_NUM_MAX:
+		val = dev->queue[dev->queue_sel].num_max;
+		break;
+	case VIRTIO_MMIO_QUEUE_READY:
+		val = dev->queue[dev->queue_sel].ready;
+		break;
+	case VIRTIO_MMIO_INTERRUPT_STATUS:
+		val = dev->int_status;
+		break;
+	case VIRTIO_MMIO_STATUS:
+		val = dev->status;
+		break;
+	case VIRTIO_MMIO_CONFIG_GENERATION:
+		val = dev->config_gen;
+		break;
+	default:
+		return -1;
+	}
+
+	*(uint32_t *)res = htole32(val);
+
+	return 0;
+}
+
+static inline void set_ptr_low(void **ptr, uint32_t val)
+{
+	uint64_t tmp = (uintptr_t)*ptr;
+
+	tmp = (tmp & 0xFFFFFFFF00000000) | val;
+	*ptr = (void *)(long)tmp;
+}
+
+static inline void set_ptr_high(void **ptr, uint32_t val)
+{
+	uint64_t tmp = (uintptr_t)*ptr;
+
+	tmp = (tmp & 0x00000000FFFFFFFF) | ((uint64_t)val << 32);
+	*ptr = (void *)(long)tmp;
+}
+
+static inline void set_status(struct virtio_dev *dev, uint32_t val)
+{
+	if ((val & LKL_VIRTIO_CONFIG_S_FEATURES_OK) &&
+	    (!(dev->driver_features & BIT(LKL_VIRTIO_F_VERSION_1)) ||
+	     !(dev->driver_features & BIT(LKL_VIRTIO_RING_F_EVENT_IDX)) ||
+	     dev->ops->check_features(dev)))
+		val &= ~LKL_VIRTIO_CONFIG_S_FEATURES_OK;
+	dev->status = val;
+}
+
+static int virtio_write(void *data, int offset, void *res, int size)
+{
+	struct virtio_dev *dev = (struct virtio_dev *)data;
+	struct virtio_queue *q = &dev->queue[dev->queue_sel];
+	uint32_t val;
+	int ret = 0;
+
+	if (offset >= VIRTIO_MMIO_CONFIG) {
+		offset -= VIRTIO_MMIO_CONFIG;
+
+		if (offset + size >= dev->config_len)
+			return -LKL_EINVAL;
+		memcpy(dev->config_data + offset, res, size);
+		return 0;
+	}
+
+	if (size != sizeof(uint32_t))
+		return -LKL_EINVAL;
+
+	val = le32toh(*(uint32_t *)res);
+
+	switch (offset) {
+	case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
+		if (val > 1)
+			return -LKL_EINVAL;
+		dev->device_features_sel = val;
+		break;
+	case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
+		if (val > 1)
+			return -LKL_EINVAL;
+		dev->driver_features_sel = val;
+		break;
+	case VIRTIO_MMIO_DRIVER_FEATURES:
+		virtio_write_driver_features(dev, val);
+		break;
+	case VIRTIO_MMIO_QUEUE_SEL:
+		dev->queue_sel = val;
+		break;
+	case VIRTIO_MMIO_QUEUE_NUM:
+		dev->queue[dev->queue_sel].num = val;
+		break;
+	case VIRTIO_MMIO_QUEUE_READY:
+		dev->queue[dev->queue_sel].ready = val;
+		break;
+	case VIRTIO_MMIO_QUEUE_NOTIFY:
+		virtio_process_queue(dev, val);
+		break;
+	case VIRTIO_MMIO_INTERRUPT_ACK:
+		dev->int_status = 0;
+		break;
+	case VIRTIO_MMIO_STATUS:
+		set_status(dev, val);
+		break;
+	case VIRTIO_MMIO_QUEUE_DESC_LOW:
+		set_ptr_low((void **)&q->desc, val);
+		break;
+	case VIRTIO_MMIO_QUEUE_DESC_HIGH:
+		set_ptr_high((void **)&q->desc, val);
+		break;
+	case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
+		set_ptr_low((void **)&q->avail, val);
+		break;
+	case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
+		set_ptr_high((void **)&q->avail, val);
+		break;
+	case VIRTIO_MMIO_QUEUE_USED_LOW:
+		set_ptr_low((void **)&q->used, val);
+		break;
+	case VIRTIO_MMIO_QUEUE_USED_HIGH:
+		set_ptr_high((void **)&q->used, val);
+		break;
+	default:
+		ret = -1;
+	}
+
+	return ret;
+}
+
+static const struct lkl_iomem_ops virtio_ops = {
+	.read = virtio_read,
+	.write = virtio_write,
+};
+
+char lkl_virtio_devs[4096];
+static char *devs = lkl_virtio_devs;
+static uint32_t lkl_num_virtio_boot_devs;
+
+void virtio_set_queue_max_merge_len(struct virtio_dev *dev, int q, int len)
+{
+	dev->queue[q].max_merge_len = len;
+}
+
+int virtio_dev_setup(struct virtio_dev *dev, int queues, int num_max)
+{
+	int qsize = queues * sizeof(*dev->queue);
+	int avail, mmio_size;
+	int i;
+	int num_bytes;
+	int ret;
+
+	dev->irq = lkl_get_free_irq("virtio");
+	if (dev->irq < 0)
+		return dev->irq;
+
+	dev->int_status = 0;
+	dev->device_features |= BIT(LKL_VIRTIO_F_VERSION_1) |
+		BIT(LKL_VIRTIO_RING_F_EVENT_IDX);
+	dev->queue = lkl_host_ops.mem_alloc(qsize);
+	if (!dev->queue)
+		return -LKL_ENOMEM;
+
+	memset(dev->queue, 0, qsize);
+	for (i = 0; i < queues; i++)
+		dev->queue[i].num_max = num_max;
+
+	mmio_size = VIRTIO_MMIO_CONFIG + dev->config_len;
+	dev->base = register_iomem(dev, mmio_size, &virtio_ops);
+	if (!dev->base) {
+		lkl_host_ops.mem_free(dev->queue);
+		return -LKL_ENOMEM;
+	}
+
+	if (!lkl_is_running()) {
+		avail = sizeof(lkl_virtio_devs) - (devs - lkl_virtio_devs);
+		num_bytes = snprintf(devs, avail,
+				     " virtio_mmio.device=%d@0x%"PRIxPTR":%d",
+				     mmio_size, (uintptr_t) dev->base,
+				     dev->irq);
+		if (num_bytes < 0 || num_bytes >= avail) {
+			lkl_put_irq(dev->irq, "virtio");
+			unregister_iomem(dev->base);
+			lkl_host_ops.mem_free(dev->queue);
+			return -LKL_ENOMEM;
+		}
+		devs += num_bytes;
+		dev->virtio_mmio_id = lkl_num_virtio_boot_devs++;
+	} else {
+		ret =
+		    lkl_sys_virtio_mmio_device_add((long)dev->base, mmio_size,
+						   dev->irq);
+		if (ret < 0) {
+			lkl_printf("can't register mmio device\n");
+			return -1;
+		}
+		dev->virtio_mmio_id = lkl_num_virtio_boot_devs + ret;
+	}
+
+	return 0;
+}
+
+int virtio_dev_cleanup(struct virtio_dev *dev)
+{
+	char devname[100];
+	long fd, ret;
+	long mount_ret;
+
+	if (!lkl_is_running())
+		goto skip_unbind;
+
+	mount_ret = lkl_mount_fs("sysfs");
+	if (mount_ret < 0)
+		return mount_ret;
+
+	if (dev->virtio_mmio_id >= virtio_get_num_bootdevs())
+		ret = snprintf(devname, sizeof(devname), "virtio-mmio.%d.auto",
+			       dev->virtio_mmio_id - virtio_get_num_bootdevs());
+	else
+		ret = snprintf(devname, sizeof(devname), "virtio-mmio.%d",
+			       dev->virtio_mmio_id);
+	if (ret < 0 || (size_t) ret >= sizeof(devname))
+		return -LKL_ENOMEM;
+
+	fd = lkl_sys_open("/sysfs/bus/platform/drivers/virtio-mmio/unbind",
+			  LKL_O_WRONLY, 0);
+	if (fd < 0)
+		return fd;
+
+	ret = lkl_sys_write(fd, devname, strlen(devname));
+	if (ret < 0)
+		return ret;
+
+	ret = lkl_sys_close(fd);
+	if (ret < 0)
+		return ret;
+
+	if (mount_ret == 0) {
+		ret = lkl_sys_umount("/sysfs", 0);
+		if (ret < 0)
+			return ret;
+	}
+
+skip_unbind:
+	lkl_put_irq(dev->irq, "virtio");
+	unregister_iomem(dev->base);
+	lkl_host_ops.mem_free(dev->queue);
+	return 0;
+}
+
+uint32_t virtio_get_num_bootdevs(void)
+{
+	return lkl_num_virtio_boot_devs;
+}
tools/lkl/lib/virtio.h new file +93 -0

93 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 18/47 lkl tools: host lib: virtio block device

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Host independent implementation for virtio block devices. The host dependent part of the host library must provide an implementation for lkl_dev_block_ops.

Disks can be added to the LKL configuration via lkl_disk_add(), a new LKL application API.

---
 tools/lkl/lib/virtio_blk.c | 132 +++++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 tools/lkl/lib/virtio_blk.c
tools/lkl/lib/virtio_blk.c new file +132 -0
new file mode 100644
index 000000000000..9e23316c5d99
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <lkl_host.h>
+#include "virtio.h"
+#include "endian.h"
+
+struct virtio_blk_dev {
+	struct virtio_dev dev;
+	struct lkl_virtio_blk_config config;
+	struct lkl_dev_blk_ops *ops;
+	struct lkl_disk disk;
+};
+
+struct virtio_blk_req_trailer {
+	uint8_t status;
+};
+
+static int blk_check_features(struct virtio_dev *dev)
+{
+	if (dev->driver_features == dev->device_features)
+		return 0;
+
+	return -LKL_EINVAL;
+}
+
+static int blk_enqueue(struct virtio_dev *dev, int q, struct virtio_req *req)
+{
+	struct virtio_blk_dev *blk_dev;
+	struct lkl_virtio_blk_outhdr *h;
+	struct virtio_blk_req_trailer *t;
+	struct lkl_blk_req lkl_req;
+
+	if (req->buf_count < 3) {
+		lkl_printf("virtio_blk: no status buf\n");
+		goto out;
+	}
+
+	h = req->buf[0].iov_base;
+	t = req->buf[req->buf_count - 1].iov_base;
+	blk_dev = container_of(dev, struct virtio_blk_dev, dev);
+
+	t->status = LKL_DEV_BLK_STATUS_IOERR;
+
+	if (req->buf[0].iov_len != sizeof(*h)) {
+		lkl_printf("virtio_blk: bad header buf\n");
+		goto out;
+	}
+
+	if (req->buf[req->buf_count - 1].iov_len != sizeof(*t)) {
+		lkl_printf("virtio_blk: bad status buf\n");
+		goto out;
+	}
+
+	lkl_req.type = le32toh(h->type);
+	lkl_req.prio = le32toh(h->ioprio);
+	lkl_req.sector = le32toh(h->sector);
+	lkl_req.buf = &req->buf[1];
+	lkl_req.count = req->buf_count - 2;
+
+	t->status = blk_dev->ops->request(blk_dev->disk, &lkl_req);
+
+out:
+	virtio_req_complete(req, 0);
+	return 0;
+}
+
+static struct virtio_dev_ops blk_ops = {
+	.check_features = blk_check_features,
+	.enqueue = blk_enqueue,
+};
+
+
+int lkl_disk_add(struct lkl_disk *disk)
+{
+	struct virtio_blk_dev *dev;
+	unsigned long long capacity;
+	int ret;
+
+	dev = lkl_host_ops.mem_alloc(sizeof(*dev));
+	if (!dev)
+		return -LKL_ENOMEM;
+
+	disk->dev = dev;
+
+	dev->dev.device_id = LKL_VIRTIO_ID_BLOCK;
+	dev->dev.vendor_id = 0;
+	dev->dev.device_features = 0;
+	dev->dev.config_gen = 0;
+	dev->dev.config_data = &dev->config;
+	dev->dev.config_len = sizeof(dev->config);
+	dev->dev.ops = &blk_ops;
+	if (disk->ops)
+		dev->ops = disk->ops;
+	else
+		dev->ops = &lkl_dev_blk_ops;
+	dev->disk = *disk;
+
+	ret = dev->ops->get_capacity(*disk, &capacity);
+	if (ret) {
+		ret = -LKL_ENOMEM;
+		goto out_free;
+	}
+	dev->config.capacity = capacity / 512;
+
+	ret = virtio_dev_setup(&dev->dev, 1, 32);
+	if (ret)
+		goto out_free;
+
+	return dev->dev.virtio_mmio_id;
+
+out_free:
+	lkl_host_ops.mem_free(dev);
+
+	return ret;
+}
+
+int lkl_disk_remove(struct lkl_disk disk)
+{
+	struct virtio_blk_dev *dev;
+	int ret;
+
+	dev = (struct virtio_blk_dev *)disk.dev;
+	if (!dev)
+		return -LKL_EINVAL;
+
+	ret = virtio_dev_cleanup(&dev->dev);
+	if (ret < 0)
+		return ret;
+
+	lkl_host_ops.mem_free(dev);
+
+	return 0;
+}
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 19/47 lkl tools: host lib: filesystem helpers

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add LKL applications APIs to mount and unmount a filesystem from a disk added via lkl_disk_add().

Also add open/close/read directory wrappers on top of lkl_sys_getdents64.

---
 tools/lkl/lib/fs.c | 433 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 433 insertions(+)
 create mode 100644 tools/lkl/lib/fs.c
tools/lkl/lib/fs.c new file +433 -0
new file mode 100644
index 000000000000..c6f197aec3fb
@@ -0,0 +1,433 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <lkl_host.h>
+
+#include "virtio.h"
+
+#define MAX_FSTYPE_LEN 50
+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_VIRTIO_PLATFORM_PATH \
+	"/sysfs/devices/platform/virtio-mmio.%d.auto"
+#define SYSFS_DEV_VIRTIO_CMDLINE_PATH \
+	"/sysfs/devices/virtio-mmio-cmdline/virtio-mmio.%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 >= (buf->len - (buf->ptr - buf->mem))))
+		return -LKL_ENOMEM;
+
+	buf->ptr += ret;
+
+	return 0;
+}
+
+int lkl_get_virtio_blkdev(int disk_id, unsigned int part, uint32_t *pdevid)
+{
+	char sysfs_path[LKL_PATH_MAX];
+	char virtio_name[LKL_PATH_MAX];
+	char disk_name[LKL_PATH_MAX];
+	struct abuf sysfs_path_buf = {
+		.mem = sysfs_path,
+		.len = sizeof(sysfs_path),
+	};
+	char *fmt;
+	int ret;
+
+	if (disk_id < 0)
+		return -LKL_EINVAL;
+
+	ret = lkl_mount_fs("sysfs");
+	if (ret < 0)
+		return ret;
+
+	if ((uint32_t) disk_id >= virtio_get_num_bootdevs()) {
+		fmt = SYSFS_DEV_VIRTIO_PLATFORM_PATH;
+		disk_id -= virtio_get_num_bootdevs();
+	} else {
+		fmt = SYSFS_DEV_VIRTIO_CMDLINE_PATH;
+	}
+
+	ret = snprintf_append(&sysfs_path_buf, fmt, disk_id);
+	if (ret)
+		return ret;
+
+	ret = get_node_with_prefix(sysfs_path, "virtio", virtio_name,
+				   sizeof(virtio_name));
+	if (ret)
+		return ret;
+
+	ret = snprintf_append(&sysfs_path_buf, "/%s/block", virtio_name);
+	if (ret)
+		return ret;
+
+	ret = get_node_with_prefix(sysfs_path, "vd", 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);
+}
+
+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_virtio_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_virtio_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);
+}
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 20/47 lkl tools: host lib: posix host operations

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Implement LKL host operations for POSIX hosts.

---
 Makefile                   |   2 +
 tools/lkl/lib/posix-host.c | 439 +++++++++++++++++++++++++++++++++++++
 2 files changed, 441 insertions(+)
 create mode 100644 tools/lkl/lib/posix-host.c
Makefile +2 -0
index 8c1f7422d0bc..cf88c66fba2e 100644
@@ -1124,7 +1124,9 @@ archprepare: archheaders archscripts scripts prepare3 outputmakefile \
 	asm-generic $(version_h) $(autoksyms_h) include/generated/utsrelease.h
 
 prepare0: archprepare
+ifeq ($(findstring elf,$(if $(CONFIG_OUTPUT_FORMAT),$(CONFIG_OUTPUT_FORMAT),elf)),elf)
 	$(Q)$(MAKE) $(build)=scripts/mod
+endif
 	$(Q)$(MAKE) $(build)=.
 
 # All the preparing..
tools/lkl/lib/posix-host.c new file +439 -0

439 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 21/47 lkl tools: "boot" test

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add a simple LKL test applications that starts the kernel and performs simple tests that minimally exercise the LKL API.

---
 tools/lkl/tests/Build             |   3 +
 tools/lkl/tests/boot.c            | 562 ++++++++++++++++++++++++++++++
 tools/lkl/tests/boot.sh           |   9 +
 tools/lkl/tests/cla.c             | 159 +++++++++
 tools/lkl/tests/cla.h             |  33 ++
 tools/lkl/tests/disk.c            | 189 ++++++++++
 tools/lkl/tests/disk.sh           |  70 ++++
 tools/lkl/tests/run.py            | 186 ++++++++++
 tools/lkl/tests/tap13.py          | 209 +++++++++++
 tools/lkl/tests/test.c            | 126 +++++++
 tools/lkl/tests/test.h            |  72 ++++
 tools/lkl/tests/test.sh           | 240 +++++++++++++
 tools/lkl/tests/valgrind.supp     |  85 +++++
 tools/lkl/tests/valgrind2xunit.py |  69 ++++
 14 files changed, 2012 insertions(+)
 create mode 100644 tools/lkl/tests/Build
 create mode 100644 tools/lkl/tests/boot.c
 create mode 100755 tools/lkl/tests/boot.sh
 create mode 100644 tools/lkl/tests/cla.c
 create mode 100644 tools/lkl/tests/cla.h
 create mode 100644 tools/lkl/tests/disk.c
 create mode 100755 tools/lkl/tests/disk.sh
 create mode 100755 tools/lkl/tests/run.py
 create mode 100644 tools/lkl/tests/tap13.py
 create mode 100644 tools/lkl/tests/test.c
 create mode 100644 tools/lkl/tests/test.h
 create mode 100644 tools/lkl/tests/test.sh
 create mode 100644 tools/lkl/tests/valgrind.supp
 create mode 100755 tools/lkl/tests/valgrind2xunit.py
tools/lkl/tests/Build new file +3 -0
new file mode 100644
index 000000000000..ace86a3d3438
@@ -0,0 +1,3 @@
+boot-y += boot.o test.o
+disk-y += disk.o cla.o test.o
+net-test-y += net-test.o cla.o test.o
tools/lkl/tests/boot.c new file +562 -0

562 lines not on this page · raw message

tools/lkl/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/lkl/tests/cla.c new file +159 -0

159 lines not on this page · raw message

tools/lkl/tests/cla.h new file +33 -0
new file mode 100644
index 000000000000..f8369be02e5a
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#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 parse_args(int argc, const char **argv, struct cl_arg *args);
+
+
+#endif /* _LKL_TEST_CLA_H */
tools/lkl/tests/disk.c new file +189 -0

189 lines not on this page · raw message

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

70 lines not on this page · raw message

tools/lkl/tests/run.py new file +186 -0

186 lines not on this page · raw message

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

209 lines not on this page · raw message

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

126 lines not on this page · raw message

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

72 lines not on this page · raw message

tools/lkl/tests/test.sh new file +240 -0

240 lines not on this page · raw message

tools/lkl/tests/valgrind.supp new file +85 -0

86 lines not on this page · raw message

tools/lkl/tests/valgrind2xunit.py new file +69 -0

69 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 22/47 lkl tools: tool that converts a filesystem image to tar

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Simple utility that converts a filesystem image to a tar file, preserving file rights and extended attributes.

---
 tools/lkl/fs2tar.c | 410 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 410 insertions(+)
 create mode 100644 tools/lkl/fs2tar.c
tools/lkl/fs2tar.c new file +410 -0
new file mode 100644
index 000000000000..d2834afcce93
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <argp.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <archive.h>
+#include <archive_entry.h>
+#include <lkl.h>
+#include <lkl_host.h>
+
+char doc[] = "";
+char args_doc[] = "-t fstype fsimage_path tar_path";
+static struct argp_option options[] = {
+	{"enable-printk", 'p', 0, 0, "show Linux printks"},
+	{"partition", 'P', "int", 0, "partition number"},
+	{"filesystem-type", 't', "string", 0,
+	 "select filesystem type - mandatory"},
+	{"selinux-contexts", 's', "file", 0,
+	 "export selinux contexts to file"},
+	{0},
+};
+
+static struct cl_args {
+	int printk;
+	int part;
+	const char *fsimg_type;
+	const char *fsimg_path;
+	const char *tar_path;
+	FILE *selinux;
+} cla;
+
+static error_t parse_opt(int key, char *arg, struct argp_state *state)
+{
+	struct cl_args *cla = state->input;
+
+	switch (key) {
+	case 'p':
+		cla->printk = 1;
+		break;
+	case 'P':
+		cla->part = atoi(arg);
+		break;
+	case 't':
+		cla->fsimg_type = arg;
+		break;
+	case 's':
+		cla->selinux = fopen(arg, "w");
+		if (!cla->selinux) {
+			fprintf(stderr,
+				"failed to open selinux contexts file: %s\n",
+				strerror(errno));
+			return -1;
+		}
+		break;
+	case ARGP_KEY_ARG:
+		if (!cla->fsimg_path)
+			cla->fsimg_path = arg;
+		else if (!cla->tar_path)
+			cla->tar_path = arg;
+		else
+			return -1;
+		break;
+	case ARGP_KEY_END:
+		if (state->arg_num < 2 || !cla->fsimg_type)
+			argp_usage(state);
+	default:
+		return ARGP_ERR_UNKNOWN;
+	}
+
+	return 0;
+}
+
+static struct argp argp = { options, parse_opt, args_doc, doc };
+
+static struct archive *tar;
+
+static int searchdir(const char *fsimg_path, const char *path);
+
+static int copy_file(const char *fsimg_path, const char *path)
+{
+	long fsimg_fd;
+	char buff[4096];
+	long len, wrote;
+	int ret = 0;
+
+	fsimg_fd = lkl_sys_open(fsimg_path, LKL_O_RDONLY, 0);
+	if (fsimg_fd < 0) {
+		fprintf(stderr, "fsimg error opening %s: %s\n", fsimg_path,
+			lkl_strerror(fsimg_fd));
+		return fsimg_fd;
+	}
+
+	do {
+		len = lkl_sys_read(fsimg_fd, buff, sizeof(buff));
+		if (len > 0) {
+			wrote = archive_write_data(tar, buff, len);
+			if (wrote != len) {
+				fprintf(stderr,
+					"error writing file %s to archive: %s [%d %ld]\n",
+					path, archive_error_string(tar), ret,
+					len);
+				ret = -archive_errno(tar);
+				break;
+			}
+		}
+
+		if (len < 0) {
+			fprintf(stderr, "error reading fsimg file %s: %s\n",
+				fsimg_path, lkl_strerror(len));
+			ret = len;
+		}
+
+	} while (len > 0);
+
+	lkl_sys_close(fsimg_fd);
+
+	return ret;
+}
+
+static int add_link(const char *fsimg_path, const char *path,
+		    struct archive_entry *entry)
+{
+	char buf[4096] = { 0, };
+	long len;
+
+	len = lkl_sys_readlink(fsimg_path, buf, sizeof(buf));
+	if (len < 0) {
+		fprintf(stderr, "fsimg readlink error %s: %s\n",
+			fsimg_path, lkl_strerror(len));
+		return len;
+	}
+
+	archive_entry_set_symlink(entry, buf);
+
+	return 0;
+}
+
+static inline void fsimg_copy_stat(struct stat *st, struct lkl_stat *fst)
+{
+	st->st_dev = fst->st_dev;
+	st->st_ino = fst->st_ino;
+	st->st_mode = fst->st_mode;
+	st->st_nlink = fst->st_nlink;
+	st->st_uid = fst->st_uid;
+	st->st_gid = fst->st_gid;
+	st->st_rdev = fst->st_rdev;
+	st->st_size = fst->st_size;
+	st->st_blksize = fst->st_blksize;
+	st->st_blocks = fst->st_blocks;
+	st->st_atim.tv_sec = fst->lkl_st_atime;
+	st->st_atim.tv_nsec = fst->st_atime_nsec;
+	st->st_mtim.tv_sec = fst->lkl_st_mtime;
+	st->st_mtim.tv_nsec = fst->st_mtime_nsec;
+	st->st_ctim.tv_sec = fst->lkl_st_ctime;
+	st->st_ctim.tv_nsec = fst->st_ctime_nsec;
+}
+
+static int copy_xattr(const char *fsimg_path, const char *path,
+		      struct archive_entry *entry)
+{
+	long ret;
+	char *xattr_list, *i;
+	long xattr_list_size;
+
+	ret = lkl_sys_llistxattr(fsimg_path, NULL, 0);
+	if (ret < 0) {
+		fprintf(stderr, "fsimg llistxattr(%s) error: %s\n",
+			path, lkl_strerror(ret));
+		return ret;
+	}
+
+	if (!ret)
+		return 0;
+
+	xattr_list = malloc(ret);
+
+	ret = lkl_sys_llistxattr(fsimg_path, xattr_list, ret);
+	if (ret < 0) {
+		fprintf(stderr, "fsimg llistxattr(%s) error: %s\n", path,
+			lkl_strerror(ret));
+		free(xattr_list);
+		return ret;
+	}
+
+	xattr_list_size = ret;
+
+	for (i = xattr_list; i - xattr_list < xattr_list_size;
+	     i += strlen(i) + 1) {
+		void *xattr_buf;
+
+		ret = lkl_sys_lgetxattr(fsimg_path, i, NULL, 0);
+		if (ret < 0) {
+			fprintf(stderr, "fsimg lgetxattr(%s) error: %s\n", path,
+				lkl_strerror(ret));
+			free(xattr_list);
+			return ret;
+		}
+
+		xattr_buf = malloc(ret);
+
+		ret = lkl_sys_lgetxattr(fsimg_path, i, xattr_buf, ret);
+		if (ret < 0) {
+			fprintf(stderr, "fsimg lgetxattr2(%s) error: %s\n",
+				path, lkl_strerror(ret));
+			free(xattr_list);
+			free(xattr_buf);
+			return ret;
+		}
+
+		if (cla.selinux && strcmp(i, "security.selinux") == 0)
+			fprintf(cla.selinux, "%s %s\n", path,
+				(char *)xattr_buf);
+
+		archive_entry_xattr_clear(entry);
+		archive_entry_xattr_add_entry(entry, i, xattr_buf, ret);
+
+		free(xattr_buf);
+	}
+
+	free(xattr_list);
+
+	return 0;
+}
+
+static int do_entry(const char *fsimg_path, const char *path,
+		    const struct lkl_linux_dirent64 *de)
+{
+	char fsimg_new_path[PATH_MAX], new_path[PATH_MAX];
+	struct lkl_stat fsimg_stat;
+	struct stat stat;
+	struct archive_entry *entry;
+	int ftype;
+	long ret;
+
+	snprintf(new_path, sizeof(new_path), "%s/%s", path, de->d_name);
+	snprintf(fsimg_new_path, sizeof(fsimg_new_path), "%s/%s", fsimg_path,
+		 de->d_name);
+
+	ret = lkl_sys_lstat(fsimg_new_path, &fsimg_stat);
+	if (ret) {
+		fprintf(stderr, "fsimg lstat(%s) error: %s\n",
+			path, lkl_strerror(ret));
+		return ret;
+	}
+
+	entry = archive_entry_new();
+
+	archive_entry_set_pathname(entry, new_path);
+	fsimg_copy_stat(&stat, &fsimg_stat);
+	archive_entry_copy_stat(entry, &stat);
+	ret = copy_xattr(fsimg_new_path, new_path, entry);
+	if (ret)
+		return ret;
+	/* TODO: ACLs */
+
+	ftype = stat.st_mode & S_IFMT;
+
+	switch (ftype) {
+	case S_IFREG:
+		archive_write_header(tar, entry);
+		ret = copy_file(fsimg_new_path, new_path);
+		break;
+	case S_IFDIR:
+		archive_write_header(tar, entry);
+		ret = searchdir(fsimg_new_path, new_path);
+		break;
+	case S_IFLNK:
+		ret = add_link(fsimg_new_path, new_path, entry);
+		/* fall through */
+	case S_IFSOCK:
+	case S_IFBLK:
+	case S_IFCHR:
+	case S_IFIFO:
+		if (ret)
+			break;
+		archive_write_header(tar, entry);
+		break;
+	default:
+		printf("skipping %s: unsupported entry type %d\n", new_path,
+		       ftype);
+	}
+
+	archive_entry_free(entry);
+
+	if (ret)
+		printf("error processing entry %s, aborting\n", new_path);
+
+	return ret;
+}
+
+static int searchdir(const char *fsimg_path, const char *path)
+{
+	long ret, fd;
+	char buf[1024], *pos;
+	long buf_len;
+
+	fd = lkl_sys_open(fsimg_path, LKL_O_RDONLY | LKL_O_DIRECTORY, 0);
+	if (fd < 0) {
+		fprintf(stderr, "failed to open dir %s: %s", fsimg_path,
+			lkl_strerror(fd));
+		return fd;
+	}
+
+	do {
+		struct lkl_linux_dirent64 *de;
+
+		de = (struct lkl_linux_dirent64 *) buf;
+		buf_len = lkl_sys_getdents64(fd, de, sizeof(buf));
+		if (buf_len < 0) {
+			fprintf(stderr, "gentdents64 error: %s\n",
+				lkl_strerror(buf_len));
+			break;
+		}
+
+		for (pos = buf; pos - buf < buf_len; pos += de->d_reclen) {
+			de = (struct lkl_linux_dirent64 *)pos;
+
+			if (!strcmp(de->d_name, ".") ||
+			    !strcmp(de->d_name, ".."))
+				continue;
+
+			ret = do_entry(fsimg_path, path, de);
+			if (ret)
+				goto out;
+		}
+
+	} while (buf_len > 0);
+
+out:
+	lkl_sys_close(fd);
+	return ret;
+}
+
+int main(int argc, char **argv)
+{
+	struct lkl_disk disk;
+	long ret;
+	char mpoint[32];
+	unsigned int disk_id;
+
+	if (argp_parse(&argp, argc, argv, 0, 0, &cla) < 0)
+		return -1;
+
+	if (!cla.printk)
+		lkl_host_ops.print = NULL;
+
+	disk.fd = open(cla.fsimg_path, O_RDONLY);
+	if (disk.fd < 0) {
+		fprintf(stderr, "can't open fsimg %s: %s\n", cla.fsimg_path,
+			strerror(errno));
+		ret = 1;
+		goto out;
+	}
+
+	disk.ops = NULL;
+
+	ret = lkl_disk_add(&disk);
+	if (ret < 0) {
+		fprintf(stderr, "can't add disk: %s\n", lkl_strerror(ret));
+		goto out_close;
+	}
+	disk_id = ret;
+
+	lkl_start_kernel(&lkl_host_ops, "mem=10M");
+
+	ret = lkl_mount_dev(disk_id, cla.part, cla.fsimg_type, LKL_MS_RDONLY,
+			    NULL, mpoint, sizeof(mpoint));
+	if (ret) {
+		fprintf(stderr, "can't mount disk: %s\n", lkl_strerror(ret));
+		goto out_close;
+	}
+
+	ret = lkl_sys_chdir(mpoint);
+	if (ret) {
+		fprintf(stderr, "can't chdir to %s: %s\n", mpoint,
+			lkl_strerror(ret));
+		goto out_umount;
+	}
+
+	tar = archive_write_new();
+	archive_write_set_format_pax_restricted(tar);
+	archive_write_open_filename(tar, cla.tar_path);
+
+	ret = searchdir(mpoint, "");
+
+	archive_write_free(tar);
+
+	if (cla.selinux)
+		fclose(cla.selinux);
+
+out_umount:
+	lkl_umount_dev(disk_id, cla.part, 0, 1000);
+
+out_close:
+	close(disk.fd);
+
+out:
+	lkl_sys_halt();
+
+	return ret;
+}
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 23/47 lkl tools: tool that reads/writes to/from a filesystem image

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

cptofs will be built with.

---
 tools/lkl/cptofs.c | 635 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 635 insertions(+)
 create mode 100644 tools/lkl/cptofs.c
tools/lkl/cptofs.c new file +635 -0
new file mode 100644
index 000000000000..dd490435d5b7
@@ -0,0 +1,635 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <argp.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <dirent.h>
+#include <lkl.h>
+#include <lkl_host.h>
+
+static const char doc_cptofs[] = "Copy files to a filesystem image";
+static const char doc_cpfromfs[] = "Copy files from a filesystem image";
+static const char args_doc_cptofs[] = "-t fstype -i fsimage path... fs_path";
+static const char args_doc_cpfromfs[] = "-t fstype -i fsimage fs_path... path";
+
+static struct argp_option options[] = {
+	{"enable-printk", 'p', 0, 0, "show Linux printks"},
+	{"partition", 'P', "int", 0, "partition number"},
+	{"filesystem-type", 't', "string", 0,
+	 "select filesystem type - mandatory"},
+	{"filesystem-image", 'i', "string", 0,
+	 "path to the filesystem image - mandatory"},
+	{"selinux", 's', "string", 0, "selinux attributes for destination"},
+	{0},
+};
+
+static struct cl_args {
+	int printk;
+	int part;
+	const char *fsimg_type;
+	const char *fsimg_path;
+	int npaths;
+	char **paths;
+	const char *selinux;
+} cla;
+
+static int cptofs;
+
+static error_t parse_opt(int key, char *arg, struct argp_state *state)
+{
+	struct cl_args *cla = state->input;
+
+	switch (key) {
+	case 'p':
+		cla->printk = 1;
+		break;
+	case 'P':
+		cla->part = atoi(arg);
+		break;
+	case 't':
+		cla->fsimg_type = arg;
+		break;
+	case 'i':
+		cla->fsimg_path = arg;
+		break;
+	case 's':
+		cla->selinux = arg;
+		break;
+	case ARGP_KEY_ARG:
+		// Capture all remaining arguments in our paths array and stop
+		// parsing here. We treat the last one as the destination and
+		// everything before it as sources, just like cp does.
+		cla->paths = &state->argv[state->next - 1];
+		cla->npaths = state->argc - state->next + 1;
+		state->next = state->argc;
+		break;
+	default:
+		return ARGP_ERR_UNKNOWN;
+	}
+
+	return 0;
+}
+
+static struct argp argp_cptofs = {
+	.options = options,
+	.parser = parse_opt,
+	.args_doc = args_doc_cptofs,
+	.doc = doc_cptofs,
+};
+
+static struct argp argp_cpfromfs = {
+	.options = options,
+	.parser = parse_opt,
+	.args_doc = args_doc_cpfromfs,
+	.doc = doc_cpfromfs,
+};
+
+static int searchdir(const char *fs_path, const char *path, const char *match);
+
+static int open_src(const char *path)
+{
+	int fd;
+
+	if (cptofs)
+		fd = open(path, O_RDONLY, 0);
+	else
+		fd = lkl_sys_open(path, LKL_O_RDONLY, 0);
+
+	if (fd < 0)
+		fprintf(stderr, "unable to open file %s for reading: %s\n",
+			path, cptofs ? strerror(errno) : lkl_strerror(fd));
+
+	return fd;
+}
+
+static int open_dst(const char *path, int mode)
+{
+	int fd;
+
+	if (cptofs)
+		fd = lkl_sys_open(path, LKL_O_RDWR | LKL_O_TRUNC | LKL_O_CREAT,
+				  mode);
+	else
+		fd = open(path, O_RDWR | O_TRUNC | O_CREAT, mode);
+
+	if (fd < 0)
+		fprintf(stderr, "unable to open file %s for writing: %s\n",
+			path, cptofs ? lkl_strerror(fd) : strerror(errno));
+
+	if (cla.selinux && cptofs) {
+		int ret = lkl_sys_fsetxattr(fd, "security.selinux", cla.selinux,
+					    strlen(cla.selinux), 0);
+		if (ret)
+			fprintf(stderr,
+				"unable to set selinux attribute on %s: %s\n",
+				path, lkl_strerror(ret));
+	}
+
+	return fd;
+}
+
+static int read_src(int fd, char *buf, int len)
+{
+	int ret;
+
+	if (cptofs)
+		ret = read(fd, buf, len);
+	else
+		ret = lkl_sys_read(fd, buf, len);
+
+	if (ret < 0)
+		fprintf(stderr, "error reading file: %s\n",
+			cptofs ? strerror(errno) : lkl_strerror(ret));
+
+	return ret;
+}
+
+static int write_dst(int fd, char *buf, int len)
+{
+	int ret;
+
+	if (cptofs)
+		ret = lkl_sys_write(fd, buf, len);
+	else
+		ret = write(fd, buf, len);
+
+	if (ret < 0)
+		fprintf(stderr, "error writing file: %s\n",
+			cptofs ? lkl_strerror(ret) : strerror(errno));
+
+	return ret;
+}
+
+static void close_src(int fd)
+{
+	if (cptofs)
+		close(fd);
+	else
+		lkl_sys_close(fd);
+}
+
+static void close_dst(int fd)
+{
+	if (cptofs)
+		lkl_sys_close(fd);
+	else
+		close(fd);
+}
+
+static int copy_file(const char *src, const char *dst, int mode)
+{
+	long len, to_write, wrote;
+	char buf[4096], *ptr;
+	int ret = 0;
+	int fd_src, fd_dst;
+
+	fd_src = open_src(src);
+	if (fd_src < 0)
+		return fd_src;
+
+	fd_dst = open_dst(dst, mode);
+	if (fd_dst < 0)
+		return fd_dst;
+
+	do {
+		len = read_src(fd_src, buf, sizeof(buf));
+
+		if (len > 0) {
+			ptr = buf;
+			to_write = len;
+			do {
+				wrote = write_dst(fd_dst, ptr, to_write);
+
+				if (wrote < 0) {
+					ret = wrote;
+					goto out;
+				}
+
+				to_write -= wrote;
+				ptr += len;
+
+			} while (to_write > 0);
+		}
+
+		if (len < 0)
+			ret = len;
+
+	} while (len > 0);
+
+out:
+	close_src(fd_src);
+	close_dst(fd_dst);
+
+	return ret;
+}
+
+static int stat_src(const char *path, unsigned int *type, unsigned int *mode,
+		    long long *size, struct lkl_timespec *mtime,
+		    struct lkl_timespec *atime)
+{
+	struct stat stat;
+	struct lkl_stat lkl_stat;
+	int ret;
+
+	if (cptofs) {
+		ret = lstat(path, &stat);
+		if (type)
+			*type = stat.st_mode & S_IFMT;
+		if (mode)
+			*mode = stat.st_mode & ~S_IFMT;
+		if (size)
+			*size = stat.st_size;
+		if (mtime) {
+			mtime->tv_sec = stat.st_mtim.tv_sec;
+			mtime->tv_nsec = stat.st_mtim.tv_nsec;
+		}
+		if (atime) {
+			atime->tv_sec = stat.st_atim.tv_sec;
+			atime->tv_nsec = stat.st_atim.tv_nsec;
+		}
+	} else {
+		ret = lkl_sys_lstat(path, &lkl_stat);
+		if (type)
+			*type = lkl_stat.st_mode & S_IFMT;
+		if (mode)
+			*mode = lkl_stat.st_mode & ~S_IFMT;
+		if (size)
+			*size = lkl_stat.st_size;
+		if (mtime) {
+			mtime->tv_sec = lkl_stat.lkl_st_mtime;
+			mtime->tv_nsec = lkl_stat.st_mtime_nsec;
+		}
+		if (atime) {
+			atime->tv_sec = lkl_stat.lkl_st_atime;
+			atime->tv_nsec = lkl_stat.st_atime_nsec;
+		}
+	}
+
+	if (ret)
+		fprintf(stderr, "fsimg lstat(%s) error: %s\n",
+			path, cptofs ? strerror(errno) : lkl_strerror(ret));
+
+	return ret;
+}
+
+static int mkdir_dst(const char *path, unsigned int mode)
+{
+	int ret;
+
+	if (cptofs) {
+		ret = lkl_sys_mkdir(path, mode);
+		if (ret == -LKL_EEXIST)
+			ret = 0;
+	} else {
+		ret = mkdir(path, mode);
+		if (ret < 0 && errno == EEXIST)
+			ret = 0;
+	}
+
+	if (ret)
+		fprintf(stderr, "unable to create directory %s: %s\n",
+			path, cptofs ? strerror(errno) : lkl_strerror(ret));
+
+	return ret;
+}
+
+static int readlink_src(const char *src, char *out, int outsize)
+{
+	int ret;
+
+	if (cptofs)
+		ret = readlink(src, out, outsize);
+	else
+		ret = lkl_sys_readlink(src, out, outsize);
+
+	if (ret < 0)
+		fprintf(stderr, "unable to readlink '%s': %s\n", src,
+			cptofs ? strerror(errno) : lkl_strerror(ret));
+
+	return ret;
+}
+
+static int symlink_dst(const char *path, const char *target)
+{
+	int ret;
+
+	if (cptofs)
+		ret = lkl_sys_symlink(target, path);
+	else
+		ret = symlink(target, path);
+
+	if (ret)
+		fprintf(stderr, "unable to symlink '%s' with target '%s': %s\n",
+			path, target, cptofs ? lkl_strerror(ret) :
+			strerror(errno));
+
+	return ret;
+}
+
+static int copy_symlink(const char *src, const char *dst)
+{
+	int ret;
+	long long size, actual_size;
+	char *target = NULL;
+
+	ret = stat_src(src, NULL, NULL, &size, NULL, NULL);
+	if (ret) {
+		ret = -1;
+		goto out;
+	}
+
+	target = malloc(size + 1);
+	if (!target) {
+		fprintf(stderr, "Unable to allocate memory (%lld bytes)\n",
+			size + 1);
+		ret = -1;
+		goto out;
+	}
+
+	actual_size = readlink_src(src, target, size);
+	if (actual_size != size) {
+		fprintf(stderr,
+			"readlink(%s) bad size: got %lld, expected %lld\n",
+			src, actual_size, size);
+		ret = -1;
+		goto out;
+	}
+	target[size] = 0; // readlink doesn't append the trailing null byte
+
+	ret = symlink_dst(dst, target);
+	if (ret)
+		ret = -1;
+
+out:
+	if (target)
+		free(target);
+
+	return ret;
+}
+
+static int do_entry(const char *_src, const char *_dst, const char *name)
+{
+	char src[PATH_MAX], dst[PATH_MAX];
+	struct lkl_timespec mtime, atime;
+	unsigned int type, mode;
+	int ret;
+
+	snprintf(src, sizeof(src), "%s/%s", _src, name);
+	snprintf(dst, sizeof(dst), "%s/%s", _dst, name);
+
+	ret = stat_src(src, &type, &mode, NULL, &mtime, &atime);
+
+	switch (type) {
+	case S_IFREG:
+	{
+		ret = copy_file(src, dst, mode);
+		break;
+	}
+	case S_IFDIR:
+		ret = mkdir_dst(dst, mode);
+		if (ret)
+			break;
+		ret = searchdir(src, dst, NULL);
+		break;
+	case S_IFLNK:
+		ret = copy_symlink(src, dst);
+		break;
+	case S_IFSOCK:
+	case S_IFBLK:
+	case S_IFCHR:
+	case S_IFIFO:
+	default:
+		printf("skipping %s: unsupported entry type %d\n", src, type);
+	}
+
+	if (!ret) {
+		if (cptofs) {
+			struct lkl_timespec lkl_ts[] = { atime, mtime };
+
+			ret = lkl_sys_utimensat(-1, dst,
+						(struct __lkl__kernel_timespec
+						 *)lkl_ts,
+						LKL_AT_SYMLINK_NOFOLLOW);
+		} else {
+			struct timespec ts[] = {
+				{ .tv_sec = atime.tv_sec,
+				  .tv_nsec = atime.tv_nsec, },
+				{ .tv_sec = mtime.tv_sec,
+				  .tv_nsec = mtime.tv_nsec, },
+			};
+
+			ret = utimensat(-1, dst, ts, AT_SYMLINK_NOFOLLOW);
+		}
+	}
+
+	if (ret)
+		printf("error processing entry %s, aborting\n", src);
+
+	return ret;
+}
+
+static DIR *open_dir(const char *path)
+{
+	DIR *dir;
+	int err;
+
+	if (cptofs)
+		dir = opendir(path);
+	else
+		dir = (DIR *)lkl_opendir(path, &err);
+
+	if (!dir)
+		fprintf(stderr, "unable to open directory %s: %s\n",
+			path, cptofs ? strerror(errno) : lkl_strerror(err));
+	return dir;
+}
+
+static const char *read_dir(DIR *dir, const char *path)
+{
+	struct lkl_dir *lkl_dir = (struct lkl_dir *)dir;
+	const char *name = NULL;
+	const char *err = NULL;
+
+	if (cptofs) {
+		struct dirent *de = readdir(dir);
+
+		if (de)
+			name = de->d_name;
+	} else {
+		struct lkl_linux_dirent64 *de = lkl_readdir(lkl_dir);
+
+		if (de)
+			name = de->d_name;
+	}
+
+	if (!name) {
+		if (cptofs) {
+			if (errno)
+				err = strerror(errno);
+		} else {
+			if (lkl_errdir(lkl_dir))
+				err = lkl_strerror(lkl_errdir(lkl_dir));
+		}
+	}
+
+	if (err)
+		fprintf(stderr, "error while reading directory %s: %s\n",
+			path, err);
+	return name;
+}
+
+static void close_dir(DIR *dir)
+{
+	if (cptofs)
+		closedir(dir);
+	else
+		lkl_closedir((struct lkl_dir *)dir);
+}
+
+static int searchdir(const char *src, const char *dst, const char *match)
+{
+	DIR *dir;
+	const char *name;
+	int ret = 0;
+
+	dir = open_dir(src);
+	if (!dir)
+		return -1;
+
+	while ((name = read_dir(dir, src))) {
+		if (!strcmp(name, ".") || !strcmp(name, "..") ||
+		    (match && fnmatch(match, name, 0) != 0))
+			continue;
+
+		ret = do_entry(src, dst, name);
+		if (ret)
+			goto out;
+	}
+
+out:
+	close_dir(dir);
+
+	return ret;
+}
+
+static int match_root(const char *src)
+{
+	const char *c = src;
+
+	while (*c) {
+		switch (*c) {
+		case '.':
+			if (c > src && c[-1] == '.')
+				return 0;
+			break;
+		case '/':
+			break;
+		default:
+			return 0;
+		}
+		c++;
+	}
+
+	return 1;
+}
+
+int copy_one(const char *src, const char *mpoint, const char *dst)
+{
+	char *src_path_dir, *src_path_base;
+	char src_path[PATH_MAX], dst_path[PATH_MAX];
+
+	if (cptofs) {
+		snprintf(src_path, sizeof(src_path),  "%s", src);
+		snprintf(dst_path, sizeof(dst_path),  "%s/%s", mpoint, dst);
+	} else {
+		snprintf(src_path, sizeof(src_path),  "%s/%s", mpoint, src);
+		snprintf(dst_path, sizeof(dst_path),  "%s", dst);
+	}
+
+	if (match_root(src))
+		return searchdir(src_path, dst, NULL);
+
+	src_path_dir = dirname(strdup(src_path));
+	src_path_base = basename(strdup(src_path));
+
+	return searchdir(src_path_dir, dst_path, src_path_base);
+}
+
+int main(int argc, char **argv)
+{
+	struct lkl_disk disk;
+	long ret, umount_ret;
+	int i;
+	char mpoint[32];
+	unsigned int disk_id;
+
+	if (strstr(argv[0], "cptofs")) {
+		cptofs = 1;
+		ret = argp_parse(&argp_cptofs, argc, argv, 0, 0, &cla);
+	} else {
+		ret = argp_parse(&argp_cpfromfs, argc, argv, 0, 0, &cla);
+	}
+
+	if (ret < 0)
+		return -1;
+
+	if (!cla.printk)
+		lkl_host_ops.print = NULL;
+
+	disk.fd = open(cla.fsimg_path, cptofs ? O_RDWR : O_RDONLY);
+	if (disk.fd < 0) {
+		fprintf(stderr, "can't open fsimg %s: %s\n", cla.fsimg_path,
+			strerror(errno));
+		ret = 1;
+		goto out;
+	}
+
+	disk.ops = NULL;
+
+	ret = lkl_disk_add(&disk);
+	if (ret < 0) {
+		fprintf(stderr, "can't add disk: %s\n", lkl_strerror(ret));
+		goto out_close;
+	}
+	disk_id = ret;
+
+	lkl_start_kernel(&lkl_host_ops, "mem=100M");
+
+	ret = lkl_mount_dev(disk_id, cla.part, cla.fsimg_type,
+			    cptofs ? 0 : LKL_MS_RDONLY,
+			    NULL, mpoint, sizeof(mpoint));
+	if (ret) {
+		fprintf(stderr, "can't mount disk: %s\n", lkl_strerror(ret));
+		goto out_close;
+	}
+
+	lkl_sys_umask(0);
+
+	for (i = 0; i < cla.npaths - 1; i++) {
+		ret = copy_one(cla.paths[i], mpoint, cla.paths[cla.npaths - 1]);
+		if (ret)
+			break;
+	}
+
+	umount_ret = lkl_umount_dev(disk_id, cla.part, 0, 1000);
+	if (ret == 0)
+		ret = umount_ret;
+
+out_close:
+	close(disk.fd);
+
+out:
+	lkl_sys_halt();
+
+	return ret;
+}
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 24/47 lkl tools: virtio: add network device support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This also adds various virtio_net backend to be used as network devices.

---
 tools/lkl/lib/net.c                 | 818 ++++++++++++++++++++++++++++
 tools/lkl/lib/virtio_net.c          | 321 +++++++++++
 tools/lkl/lib/virtio_net_dpdk.c     | 480 ++++++++++++++++
 tools/lkl/lib/virtio_net_fd.c       | 217 ++++++++
 tools/lkl/lib/virtio_net_fd.h       |  28 +
 tools/lkl/lib/virtio_net_macvtap.c  |  32 ++
 tools/lkl/lib/virtio_net_pipe.c     |  76 +++
 tools/lkl/lib/virtio_net_raw.c      |  94 ++++
 tools/lkl/lib/virtio_net_tap.c      | 111 ++++
 tools/lkl/lib/virtio_net_vde.c      | 168 ++++++
 tools/lkl/scripts/dpdk-sdk-build.sh |  18 +
 tools/lkl/tests/net-setup.sh        | 134 +++++
 tools/lkl/tests/net-test.c          | 317 +++++++++++
 tools/lkl/tests/net.sh              | 186 +++++++
 14 files changed, 3000 insertions(+)
 create mode 100644 tools/lkl/lib/net.c
 create mode 100644 tools/lkl/lib/virtio_net.c
 create mode 100644 tools/lkl/lib/virtio_net_dpdk.c
 create mode 100644 tools/lkl/lib/virtio_net_fd.c
 create mode 100644 tools/lkl/lib/virtio_net_fd.h
 create mode 100644 tools/lkl/lib/virtio_net_macvtap.c
 create mode 100644 tools/lkl/lib/virtio_net_pipe.c
 create mode 100644 tools/lkl/lib/virtio_net_raw.c
 create mode 100644 tools/lkl/lib/virtio_net_tap.c
 create mode 100644 tools/lkl/lib/virtio_net_vde.c
 create mode 100755 tools/lkl/scripts/dpdk-sdk-build.sh
 create mode 100644 tools/lkl/tests/net-setup.sh
 create mode 100644 tools/lkl/tests/net-test.c
 create mode 100755 tools/lkl/tests/net.sh
tools/lkl/lib/net.c new file +818 -0
new file mode 100644
index 000000000000..316965ffd21e
@@ -0,0 +1,818 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include <stdio.h>
+#include "endian.h"
+#include <lkl_host.h>
+
+#ifdef __MINGW32__
+#include <ws2tcpip.h>
+
+int lkl_inet_pton(int af, const char *src, void *dst)
+{
+	struct addrinfo hint, *res = NULL;
+	int err;
+
+	memset(&hint, 0, sizeof(struct addrinfo));
+
+	hint.ai_family = af;
+	hint.ai_flags = AI_NUMERICHOST;
+
+	err = getaddrinfo(src, NULL, &hint, &res);
+	if (err)
+		return 0;
+
+	switch (af) {
+	case AF_INET:
+		*(struct in_addr *)dst =
+			((struct sockaddr_in *)&res->ai_addr)->sin_addr;
+		break;
+	case AF_INET6:
+		*(struct in6_addr *)dst =
+			((struct sockaddr_in6 *)&res->ai_addr)->sin6_addr;
+		break;
+	default:
+		freeaddrinfo(res);
+		return 0;
+	}
+
+	freeaddrinfo(res);
+	return 1;
+}
+#endif
+
+static inline void set_sockaddr(struct lkl_sockaddr_in *sin, unsigned int addr,
+				unsigned short port)
+{
+	sin->sin_family = LKL_AF_INET;
+	sin->sin_addr.lkl_s_addr = addr;
+	sin->sin_port = port;
+}
+
+static inline int ifindex_to_name(int sock, struct lkl_ifreq *ifr, int ifindex)
+{
+	ifr->lkl_ifr_ifindex = ifindex;
+	return lkl_sys_ioctl(sock, LKL_SIOCGIFNAME, (long)ifr);
+}
+
+int lkl_ifname_to_ifindex(const char *name)
+{
+	struct lkl_ifreq ifr;
+	int fd, ret;
+
+	fd = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+	if (fd < 0)
+		return fd;
+
+	strcpy(ifr.lkl_ifr_name, name);
+
+	ret = lkl_sys_ioctl(fd, LKL_SIOCGIFINDEX, (long)&ifr);
+	if (ret < 0)
+		return ret;
+
+	return ifr.lkl_ifr_ifindex;
+}
+
+int lkl_if_up(int ifindex)
+{
+	struct lkl_ifreq ifr;
+	int err, sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+
+	if (sock < 0)
+		return sock;
+	err = ifindex_to_name(sock, &ifr, ifindex);
+	if (err < 0)
+		return err;
+
+	err = lkl_sys_ioctl(sock, LKL_SIOCGIFFLAGS, (long)&ifr);
+	if (!err) {
+		ifr.lkl_ifr_flags |= LKL_IFF_UP;
+		err = lkl_sys_ioctl(sock, LKL_SIOCSIFFLAGS, (long)&ifr);
+	}
+
+	lkl_sys_close(sock);
+
+	return err;
+}
+
+int lkl_if_down(int ifindex)
+{
+	struct lkl_ifreq ifr;
+	int err, sock;
+
+	sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+	if (sock < 0)
+		return sock;
+
+	err = ifindex_to_name(sock, &ifr, ifindex);
+	if (err < 0)
+		return err;
+
+	err = lkl_sys_ioctl(sock, LKL_SIOCGIFFLAGS, (long)&ifr);
+	if (!err) {
+		ifr.lkl_ifr_flags &= ~LKL_IFF_UP;
+		err = lkl_sys_ioctl(sock, LKL_SIOCSIFFLAGS, (long)&ifr);
+	}
+
+	lkl_sys_close(sock);
+
+	return err;
+}
+
+int lkl_if_set_mtu(int ifindex, int mtu)
+{
+	struct lkl_ifreq ifr;
+	int err, sock;
+
+	sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+	if (sock < 0)
+		return sock;
+
+	err = ifindex_to_name(sock, &ifr, ifindex);
+	if (err < 0)
+		return err;
+
+	ifr.lkl_ifr_mtu = mtu;
+
+	err = lkl_sys_ioctl(sock, LKL_SIOCSIFMTU, (long)&ifr);
+
+	lkl_sys_close(sock);
+
+	return err;
+}
+
+int lkl_if_set_ipv4(int ifindex, unsigned int addr, unsigned int netmask_len)
+{
+	return lkl_if_add_ip(ifindex, LKL_AF_INET, &addr, netmask_len);
+}
+
+int lkl_if_set_ipv4_gateway(int ifindex, unsigned int src_addr,
+		unsigned int src_masklen, unsigned int via_addr)
+{
+	int err;
+
+	err = lkl_if_add_rule_from_saddr(ifindex, LKL_AF_INET, &src_addr);
+	if (err)
+		return err;
+	err = lkl_if_add_linklocal(ifindex, LKL_AF_INET,
+					&src_addr, src_masklen);
+	if (err)
+		return err;
+	return lkl_if_add_gateway(ifindex, LKL_AF_INET, &via_addr);
+}
+
+int lkl_set_ipv4_gateway(unsigned int addr)
+{
+	return lkl_add_gateway(LKL_AF_INET, &addr);
+}
+
+int lkl_netdev_get_ifindex(int id)
+{
+	struct lkl_ifreq ifr;
+	int sock, ret;
+
+	sock = lkl_sys_socket(LKL_AF_INET, LKL_SOCK_DGRAM, 0);
+	if (sock < 0)
+		return sock;
+
+	snprintf(ifr.lkl_ifr_name, sizeof(ifr.lkl_ifr_name), "eth%d", id);
+	ret = lkl_sys_ioctl(sock, LKL_SIOCGIFINDEX, (long)&ifr);
+	lkl_sys_close(sock);
+
+	return ret < 0 ? ret : ifr.lkl_ifr_ifindex;
+}
+
+static int netlink_sock(unsigned int groups)
+{
+	struct lkl_sockaddr_nl la;
+	int fd, err;
+
+	fd = lkl_sys_socket(LKL_AF_NETLINK, LKL_SOCK_DGRAM, LKL_NETLINK_ROUTE);
+	if (fd < 0)
+		return fd;
+
+	memset(&la, 0, sizeof(la));
+	la.nl_family = LKL_AF_NETLINK;
+	la.nl_groups = groups;
+	err = lkl_sys_bind(fd, (struct lkl_sockaddr *)&la, sizeof(la));
+	if (err < 0)
+		return err;
+
+	return fd;
+}
+
+static int parse_rtattr(struct lkl_rtattr *tb[], int max,
+			struct lkl_rtattr *rta, int len)
+{
+	unsigned short type;
+
+	memset(tb, 0, sizeof(struct lkl_rtattr *) * (max + 1));
+	while (LKL_RTA_OK(rta, len)) {
+		type = rta->rta_type;
+		if ((type <= max) && (!tb[type]))
+			tb[type] = rta;
+		rta = LKL_RTA_NEXT(rta, len);
+	}
+	if (len)
+		lkl_printf("!!!Deficit %d, rta_len=%d\n", len,
+			rta->rta_len);
+	return 0;
+}
+
+struct addr_filter {
+	unsigned int ifindex;
+	void *addr;
+};
+
+static unsigned int get_ifa_flags(struct lkl_ifaddrmsg *ifa,
+				  struct lkl_rtattr *ifa_flags_attr)
+{
+	return ifa_flags_attr ? *(unsigned int *)LKL_RTA_DATA(ifa_flags_attr) :
+				ifa->ifa_flags;
+}
+
+/* returns:
+ * 0 - dad succeed.
+ * -1 - dad failed or other error.
+ * 1 - should wait for new msg.
+ */
+static int check_ipv6_dad(struct lkl_sockaddr_nl *nladdr,
+			  struct lkl_nlmsghdr *n, void *arg)
+{
+	struct addr_filter *filter = arg;
+	struct lkl_ifaddrmsg *ifa = LKL_NLMSG_DATA(n);
+	struct lkl_rtattr *rta_tb[LKL_IFA_MAX+1];
+	unsigned int ifa_flags;
+	int len = n->nlmsg_len;
+
+	if (n->nlmsg_type != LKL_RTM_NEWADDR)
+		return 1;
+
+	len -= LKL_NLMSG_LENGTH(sizeof(*ifa));
+	if (len < 0) {
+		lkl_printf("BUG: wrong nlmsg len %d\n", len);
+		return -1;
+	}
+
+	parse_rtattr(rta_tb, LKL_IFA_MAX, LKL_IFA_RTA(ifa),
+		     n->nlmsg_len - LKL_NLMSG_LENGTH(sizeof(*ifa)));
+
+	ifa_flags = get_ifa_flags(ifa, rta_tb[LKL_IFA_FLAGS]);
+
+	if (ifa->ifa_index != filter->ifindex)
+		return 1;
+	if (ifa->ifa_family != LKL_AF_INET6)
+		return 1;
+
+	if (!rta_tb[LKL_IFA_LOCAL])
+		rta_tb[LKL_IFA_LOCAL] = rta_tb[LKL_IFA_ADDRESS];
+
+	if (!rta_tb[LKL_IFA_LOCAL] ||
+	    (filter->addr && memcmp(LKL_RTA_DATA(rta_tb[LKL_IFA_LOCAL]),
+				    filter->addr, 16))) {
+		return 1;
+	}
+	if (ifa_flags & LKL_IFA_F_DADFAILED) {
+		lkl_printf("IPV6 DAD failed.\n");
+		return -1;
+	}
+	if (!(ifa_flags & LKL_IFA_F_TENTATIVE))
+		return 0;
+	return 1;
+}
+
+/* Copied from iproute2/lib/ */
+static int rtnl_listen(int fd, int (*handler)(struct lkl_sockaddr_nl *nladdr,
+					      struct lkl_nlmsghdr *, void *),
+		       void *arg)
+{
+	int status;
+	struct lkl_nlmsghdr *h;
+	struct lkl_sockaddr_nl nladdr = { .nl_family = LKL_AF_NETLINK };
+	struct lkl_iovec iov;
+	struct lkl_user_msghdr msg = {
+		.msg_name = &nladdr,
+		.msg_namelen = sizeof(nladdr),
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+	};
+	char   buf[16384];
+
+	iov.iov_base = buf;
+	while (1) {
+		iov.iov_len = sizeof(buf);
+		status = lkl_sys_recvmsg(fd, &msg, 0);
+
+		if (status < 0) {
+			if (status == -LKL_EINTR || status == -LKL_EAGAIN)
+				continue;
+			lkl_printf("netlink receive error %s (%d)\n",
+				lkl_strerror(status), status);
+			if (status == -LKL_ENOBUFS)
+				continue;
+			return status;
+		}
+		if (status == 0) {
+			lkl_printf("EOF on netlink\n");
+			return -1;
+		}
+		if (msg.msg_namelen != sizeof(nladdr)) {
+			lkl_printf("Sender address length == %d\n",
+				msg.msg_namelen);
+			return -1;
+		}
+
+		for (h = (struct lkl_nlmsghdr *)buf;
+		     (unsigned int)status >= sizeof(*h);) {
+			int err;
+			int len = h->nlmsg_len;
+			int l = len - sizeof(*h);
+
+			if (l < 0 || len > status) {
+				if (msg.msg_flags & LKL_MSG_TRUNC) {
+					lkl_printf("Truncated message\n");
+					return -1;
+				}
+				lkl_printf("!!!malformed message: len=%d\n",
+					len);
+				return -1;
+			}
+
+			err = handler(&nladdr, h, arg);
+			if (err <= 0)
+				return err;
+
+			status -= LKL_NLMSG_ALIGN(len);
+			h = (struct lkl_nlmsghdr *)((char *)h +
+						    LKL_NLMSG_ALIGN(len));
+		}
+		if (msg.msg_flags & LKL_MSG_TRUNC) {
+			lkl_printf("Message truncated\n");
+			continue;
+		}
+		if (status) {
+			lkl_printf("!!!Remnant of size %d\n", status);
+			return -1;
+		}
+	}
+}
+
+int lkl_if_wait_ipv6_dad(int ifindex, void *addr)
+{
+	struct addr_filter filter = {.ifindex = ifindex, .addr = addr};
+	int fd, ret;
+	struct {
+		struct lkl_nlmsghdr		nlmsg_info;
+		struct lkl_ifaddrmsg	ifaddrmsg_info;
+	} req;
+
+	fd = netlink_sock(1 << (LKL_RTNLGRP_IPV6_IFADDR - 1));
+	if (fd < 0)
+		return fd;
+
+	memset(&req, 0, sizeof(req));
+	req.nlmsg_info.nlmsg_len =
+			LKL_NLMSG_LENGTH(sizeof(struct lkl_ifaddrmsg));
+	req.nlmsg_info.nlmsg_flags = LKL_NLM_F_REQUEST | LKL_NLM_F_DUMP;
+	req.nlmsg_info.nlmsg_type = LKL_RTM_GETADDR;
+	req.ifaddrmsg_info.ifa_family = LKL_AF_INET6;
+	req.ifaddrmsg_info.ifa_index = ifindex;
+	ret = lkl_sys_send(fd, &req, req.nlmsg_info.nlmsg_len, 0);
+	if (ret < 0) {
+		lkl_perror("lkl_sys_send", ret);
+		return ret;
+	}
+	ret = rtnl_listen(fd, check_ipv6_dad, (void *)&filter);
+	lkl_sys_close(fd);
+	return ret;
+}
+
+int lkl_if_set_ipv6(int ifindex, void *addr, unsigned int netprefix_len)
+{
+	int err = lkl_if_add_ip(ifindex, LKL_AF_INET6, addr, netprefix_len);
+
+	if (err)
+		return err;
+	return lkl_if_wait_ipv6_dad(ifindex, addr);
+}
+
+int lkl_if_set_ipv6_gateway(int ifindex, void *src_addr,
+		unsigned int src_masklen, void *via_addr)
+{
+	int err;
+
+	err = lkl_if_add_rule_from_saddr(ifindex, LKL_AF_INET6, src_addr);
+	if (err)
+		return err;
+	err = lkl_if_add_linklocal(ifindex, LKL_AF_INET6,
+					src_addr, src_masklen);
+	if (err)
+		return err;
+	return lkl_if_add_gateway(ifindex, LKL_AF_INET6, via_addr);
+}
+
+int lkl_set_ipv6_gateway(void *addr)
+{
+	return lkl_add_gateway(LKL_AF_INET6, addr);
+}
+
+/* returns:
+ * 0 - succeed.
+ * < 0 - error number.
+ * 1 - should wait for new msg.
+ */
+static int check_error(struct lkl_sockaddr_nl *nladdr, struct lkl_nlmsghdr *n,
+		       void *arg)
+{
+	unsigned int s = *(unsigned int *)arg;
+
+	if (nladdr->nl_pid != 0 || n->nlmsg_seq != s) {
+		/* Don't forget to skip that message. */
+		return 1;
+	}
+
+	if (n->nlmsg_type == LKL_NLMSG_ERROR) {
+		struct lkl_nlmsgerr *err =
+			(struct lkl_nlmsgerr *)LKL_NLMSG_DATA(n);
+		int l = n->nlmsg_len - sizeof(*n);
+
+		if (l < (int)sizeof(struct lkl_nlmsgerr))
+			lkl_printf("ERROR truncated\n");
+		else if (!err->error)
+			return 0;
+
+		lkl_printf("RTNETLINK answers: %s\n",
+			lkl_strerror(-err->error));
+		return err->error;
+	}
+	lkl_printf("Unexpected reply!!!\n");
+	return -1;
+}
+
+static unsigned int seq;
+static int rtnl_talk(int fd, struct lkl_nlmsghdr *n)
+{
+	int status;
+	struct lkl_sockaddr_nl nladdr = {.nl_family = LKL_AF_NETLINK};
+	struct lkl_iovec iov = {.iov_base = (void *)n, .iov_len = n->nlmsg_len};
+	struct lkl_user_msghdr msg = {
+			.msg_name = &nladdr,
+			.msg_namelen = sizeof(nladdr),
+			.msg_iov = &iov,
+			.msg_iovlen = 1,
+	};
+
+	n->nlmsg_seq = seq;
+	n->nlmsg_flags |= LKL_NLM_F_ACK;
+
+	status = lkl_sys_sendmsg(fd, &msg, 0);
+	if (status < 0) {
+		lkl_perror("Cannot talk to rtnetlink", status);
+		return status;
+	}
+
+	status = rtnl_listen(fd, check_error, (void *)&seq);
+	seq++;
+	return status;
+}
+
+static int addattr_l(struct lkl_nlmsghdr *n, unsigned int maxlen,
+		     int type, const void *data, int alen)
+{
+	int len = LKL_RTA_LENGTH(alen);
+	struct lkl_rtattr *rta;
+
+	if (LKL_NLMSG_ALIGN(n->nlmsg_len) + LKL_RTA_ALIGN(len) > maxlen) {
+		lkl_printf("%s ERROR: message exceeded bound of %d\n", __func__,
+			   maxlen);
+		return -1;
+	}
+	rta = ((struct lkl_rtattr *) (((void *) (n)) +
+				      LKL_NLMSG_ALIGN(n->nlmsg_len)));
+	rta->rta_type = type;
+	rta->rta_len = len;
+	memcpy(LKL_RTA_DATA(rta), data, alen);
+	n->nlmsg_len = LKL_NLMSG_ALIGN(n->nlmsg_len) + LKL_RTA_ALIGN(len);
+	return 0;
+}
+
+int lkl_add_neighbor(int ifindex, int af, void *ip, void *mac)
+{
+	struct {
+		struct lkl_nlmsghdr n;
+		struct lkl_ndmsg r;
+		char buf[1024];
+	} req = {
+		.n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_ndmsg)),
+		.n.nlmsg_type = LKL_RTM_NEWNEIGH,
+		.n.nlmsg_flags = LKL_NLM_F_REQUEST |
+				 LKL_NLM_F_CREATE | LKL_NLM_F_REPLACE,
+		.r.ndm_family = af,
+		.r.ndm_ifindex = ifindex,
+		.r.ndm_state = LKL_NUD_PERMANENT,
+
+	};
+	int err, addr_sz;
+	int fd;
+
+	if (af == LKL_AF_INET)
+		addr_sz = 4;
+	else if (af == LKL_AF_INET6)
+		addr_sz = 16;
+	else {
+		lkl_printf("Bad address family: %d\n", af);
+		return -1;
+	}
+
+	fd = netlink_sock(0);
+	if (fd < 0)
+		return fd;
+
+	// create the IP attribute
+	addattr_l(&req.n, sizeof(req), LKL_NDA_DST, ip, addr_sz);
+
+	// create the MAC attribute
+	addattr_l(&req.n, sizeof(req), LKL_NDA_LLADDR, mac, 6);
+
+	err = rtnl_talk(fd, &req.n);
+	lkl_sys_close(fd);
+	return err;
+}
+
+static int ipaddr_modify(int cmd, int flags, int ifindex, int af, void *addr,
+			 unsigned int netprefix_len)
+{
+	struct {
+		struct lkl_nlmsghdr n;
+		struct lkl_ifaddrmsg ifa;
+		char buf[256];
+	} req = {
+		.n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_ifaddrmsg)),
+		.n.nlmsg_flags = LKL_NLM_F_REQUEST | flags,
+		.n.nlmsg_type = cmd,
+		.ifa.ifa_family = af,
+		.ifa.ifa_prefixlen = netprefix_len,
+		.ifa.ifa_index = ifindex,
+	};
+	int err, addr_sz;
+	int fd;
+
+	if (af == LKL_AF_INET)
+		addr_sz = 4;
+	else if (af == LKL_AF_INET6)
+		addr_sz = 16;
+	else {
+		lkl_printf("Bad address family: %d\n", af);
+		return -1;
+	}
+
+	fd = netlink_sock(0);
+	if (fd < 0)
+		return fd;
+
+	// create the IP attribute
+	addattr_l(&req.n, sizeof(req), LKL_IFA_LOCAL, addr, addr_sz);
+
+	err = rtnl_talk(fd, &req.n);
+
+	lkl_sys_close(fd);
+	return err;
+}
+
+int lkl_if_add_ip(int ifindex, int af, void *addr, unsigned int netprefix_len)
+{
+	return ipaddr_modify(LKL_RTM_NEWADDR, LKL_NLM_F_CREATE | LKL_NLM_F_EXCL,
+			     ifindex, af, addr, netprefix_len);
+}
+
+int lkl_if_del_ip(int ifindex, int af, void *addr, unsigned int netprefix_len)
+{
+	return ipaddr_modify(LKL_RTM_DELADDR, 0, ifindex, af,
+			     addr, netprefix_len);
+}
+
+static int iproute_modify(int cmd, unsigned int flags, int ifindex, int af,
+		void *route_addr, int route_masklen, void *gwaddr)
+{
+	struct {
+		struct lkl_nlmsghdr	n;
+		struct lkl_rtmsg	r;
+		char			buf[1024];
+	} req = {
+		.n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_rtmsg)),
+		.n.nlmsg_flags = LKL_NLM_F_REQUEST | flags,
+		.n.nlmsg_type = cmd,
+		.r.rtm_family = af,
+		.r.rtm_table = LKL_RT_TABLE_MAIN,
+		.r.rtm_scope = LKL_RT_SCOPE_UNIVERSE,
+	};
+	int err, addr_sz;
+	int i, fd;
+
+	fd = netlink_sock(0);
+	if (fd < 0) {
+		lkl_printf("netlink_sock error: %d\n", fd);
+		return fd;
+	}
+
+	if (af == LKL_AF_INET)
+		addr_sz = 4;
+	else if (af == LKL_AF_INET6)
+		addr_sz = 16;
+	else {
+		lkl_printf("Bad address family: %d\n", af);
+		return -1;
+	}
+
+	if (cmd != LKL_RTM_DELROUTE) {
+		req.r.rtm_protocol = LKL_RTPROT_BOOT;
+		req.r.rtm_scope = LKL_RT_SCOPE_UNIVERSE;
+		req.r.rtm_type = LKL_RTN_UNICAST;
+	}
+
+	if (gwaddr)
+		addattr_l(&req.n, sizeof(req),
+				LKL_RTA_GATEWAY, gwaddr, addr_sz);
+
+	if (af == LKL_AF_INET && route_addr) {
+		unsigned int netaddr = *(unsigned int *)route_addr;
+
+		netaddr = ntohl(netaddr);
+		netaddr = (netaddr >> (32 - route_masklen));
+		netaddr = (netaddr << (32 - route_masklen));
+		netaddr =  htonl(netaddr);
+		*(unsigned int *)route_addr = netaddr;
+		req.r.rtm_dst_len = route_masklen;
+		addattr_l(&req.n, sizeof(req), LKL_RTA_DST,
+					route_addr, addr_sz);
+	}
+
+	if (af == LKL_AF_INET6 && route_addr) {
+		struct lkl_in6_addr netaddr =
+			*(struct lkl_in6_addr *)route_addr;
+		int rmbyte = route_masklen/8;
+		int rmbit = route_masklen%8;
+
+		for (i = 0; i < rmbyte; i++)
+			netaddr.in6_u.u6_addr8[15-i] = 0;
+		netaddr.in6_u.u6_addr8[15-rmbyte] =
+			(netaddr.in6_u.u6_addr8[15-rmbyte] >> rmbit);
+		netaddr.in6_u.u6_addr8[15-rmbyte] =
+			(netaddr.in6_u.u6_addr8[15-rmbyte] << rmbit);
+		*(struct lkl_in6_addr *)route_addr = netaddr;
+		req.r.rtm_dst_len = route_masklen;
+		addattr_l(&req.n, sizeof(req), LKL_RTA_DST,
+					route_addr, addr_sz);
+	}
+
+	if (ifindex != LKL_RT_TABLE_MAIN) {
+		if (af == LKL_AF_INET)
+			req.r.rtm_table = ifindex * 2;
+		else if (af == LKL_AF_INET6)
+			req.r.rtm_table = ifindex * 2 + 1;
+		addattr_l(&req.n, sizeof(req), LKL_RTA_OIF, &ifindex, addr_sz);
+	}
+	err = rtnl_talk(fd, &req.n);
+	lkl_sys_close(fd);
+	return err;
+}
+
+int lkl_if_add_linklocal(int ifindex, int af,  void *addr, int netprefix_len)
+{
+	return iproute_modify(LKL_RTM_NEWROUTE, LKL_NLM_F_CREATE|LKL_NLM_F_EXCL,
+			ifindex, af, addr, netprefix_len, NULL);
+}
+
+int lkl_if_add_gateway(int ifindex, int af, void *gwaddr)
+{
+	return iproute_modify(LKL_RTM_NEWROUTE, LKL_NLM_F_CREATE|LKL_NLM_F_EXCL,
+			ifindex, af, NULL, 0, gwaddr);
+}
+
+int lkl_add_gateway(int af, void *gwaddr)
+{
+	return iproute_modify(LKL_RTM_NEWROUTE, LKL_NLM_F_CREATE|LKL_NLM_F_EXCL,
+			LKL_RT_TABLE_MAIN, af, NULL, 0, gwaddr);
+}
+
+static int iprule_modify(int cmd, int ifindex, int af, void *saddr)
+{
+	struct {
+		struct lkl_nlmsghdr	n;
+		struct lkl_rtmsg		r;
+		char			buf[1024];
+	} req = {
+		.n.nlmsg_type = cmd,
+		.n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_rtmsg)),
+		.n.nlmsg_flags = LKL_NLM_F_REQUEST,
+		.r.rtm_protocol = LKL_RTPROT_BOOT,
+		.r.rtm_scope = LKL_RT_SCOPE_UNIVERSE,
+		.r.rtm_family = af,
+		.r.rtm_type = LKL_RTN_UNSPEC,
+	};
+	int fd, err;
+	int addr_sz;
+
+	if (af == LKL_AF_INET)
+		addr_sz = 4;
+	else if (af == LKL_AF_INET6)
+		addr_sz = 16;
+	else {
+		lkl_printf("Bad address family: %d\n", af);
+		return -1;
+	}
+
+	fd = netlink_sock(0);
+	if (fd < 0)
+		return fd;
+
+	if (cmd == LKL_RTM_NEWRULE) {
+		req.n.nlmsg_flags |= LKL_NLM_F_CREATE|LKL_NLM_F_EXCL;
+		req.r.rtm_type = LKL_RTN_UNICAST;
+	}
+
+	//set from address
+	req.r.rtm_src_len = 8 * addr_sz;
+	addattr_l(&req.n, sizeof(req), LKL_FRA_SRC, saddr, addr_sz);
+
+	//use ifindex as table id
+	if (af == LKL_AF_INET)
+		req.r.rtm_table = ifindex * 2;
+	else if (af == LKL_AF_INET6)
+		req.r.rtm_table = ifindex * 2 + 1;
+	err = rtnl_talk(fd, &req.n);
+
+	lkl_sys_close(fd);
+	return err;
+}
+
+int lkl_if_add_rule_from_saddr(int ifindex, int af, void *saddr)
+{
+	return iprule_modify(LKL_RTM_NEWRULE, ifindex, af, saddr);
+}
+
+static int qdisc_add(int cmd, int flags, int ifindex,
+		     const char *root, const char *type)
+{
+	struct {
+		struct lkl_nlmsghdr n;
+		struct lkl_tcmsg tc;
+		char buf[2*1024];
+	} req = {
+		.n.nlmsg_len = LKL_NLMSG_LENGTH(sizeof(struct lkl_tcmsg)),
+		.n.nlmsg_flags = LKL_NLM_F_REQUEST|flags,
+		.n.nlmsg_type = cmd,
+		.tc.tcm_family = LKL_AF_UNSPEC,
+	};
+	int err, fd;
+
+	if (!root || !type) {
+		lkl_printf("root and type arguments\n");
+		return -1;
+	}
+
+	if (strcmp(root, "root") == 0)
+		req.tc.tcm_parent = LKL_TC_H_ROOT;
+	req.tc.tcm_ifindex = ifindex;
+
+	fd = netlink_sock(0);
+	if (fd < 0)
+		return fd;
+
+	// create the qdisc attribute
+	addattr_l(&req.n, sizeof(req), LKL_TCA_KIND, type, strlen(type)+1);
+
+	err = rtnl_talk(fd, &req.n);
+	lkl_sys_close(fd);
+	return err;
+}
+
+int lkl_qdisc_add(int ifindex, const char *root, const char *type)
+{
+	return qdisc_add(LKL_RTM_NEWQDISC, LKL_NLM_F_CREATE | LKL_NLM_F_EXCL,
+			 ifindex, root, type);
+}
+
+/* Add a qdisc entry for an interface in the form of
+ * "root|type;root|type;..."
+ */
+void lkl_qdisc_parse_add(int ifindex, const char *entries)
+{
+	char *saveptr = NULL, *token = NULL;
+	char *root = NULL, *type = NULL;
+	char strings[256];
+	int ret = 0;
+
+	strcpy(strings, entries);
+
+	for (token = strtok_r(strings, ";", &saveptr); token;
+	     token = strtok_r(NULL, ";", &saveptr)) {
+		root = strtok(token, "|");
+		type = strtok(NULL, "|");
+		ret = lkl_qdisc_add(ifindex, root, type);
+		if (ret) {
+			lkl_printf("Failed to add qdisc entry: %s\n",
+				   lkl_strerror(ret));
+			return;
+		}
+	}
+}
tools/lkl/lib/virtio_net.c new file +321 -0

321 lines not on this page · raw message

tools/lkl/lib/virtio_net_dpdk.c new file +480 -0

480 lines not on this page · raw message

tools/lkl/lib/virtio_net_fd.c new file +217 -0

217 lines not on this page · raw message

tools/lkl/lib/virtio_net_fd.h new file +28 -0
new file mode 100644
index 000000000000..713ba13cca7c
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _VIRTIO_NET_FD_H
+#define _VIRTIO_NET_FD_H
+
+struct ifreq;
+
+/**
+ * lkl_register_netdev_linux_fdnet - register a file descriptor-based network
+ * device as a NIC
+ *
+ * @fd_rx - a POSIX file descriptor number for input
+ * @fd_tx - a POSIX file descriptor number for output
+ * @returns a struct lkl_netdev_linux_fdnet entry for virtio-net
+ */
+struct lkl_netdev *lkl_register_netdev_fd(int fd_rx, int fd_tx);
+
+
+/**
+ * lkl_netdev_tap_init - initialize tap related structure fot lkl_netdev.
+ *
+ * @path - the path to open the device.
+ * @offload - offload bits for the device
+ * @ifr - struct ifreq for ioctl.
+ */
+struct lkl_netdev *lkl_netdev_tap_init(const char *path, int offload,
+				       struct ifreq *ifr);
+
+#endif /* _VIRTIO_NET_FD_H*/
tools/lkl/lib/virtio_net_macvtap.c new file +32 -0
new file mode 100644
index 000000000000..5d6d2c822f2d
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * macvtap based virtual network interface feature for LKL
+ * Copyright (c) 2016 Hajime Tazaki
+ *
+ * Author: Hajime Tazaki <[email protected]>
+ *
+ * Current implementation is linux-specific.
+ */
+
+/*
+ * You need to configure host device in advance.
+ *
+ * sudo ip link add link eth0 name vtap0 type macvtap mode passthru
+ * sudo ip link set dev vtap0 up
+ * sudo chown thehajime /dev/tap22
+ */
+
+#include <net/if.h>
+#include <linux/if_tun.h>
+
+#include "virtio.h"
+#include "virtio_net_fd.h"
+
+struct lkl_netdev *lkl_netdev_macvtap_create(const char *path, int offload)
+{
+	struct ifreq ifr = {
+		.ifr_flags = IFF_TAP | IFF_NO_PI,
+	};
+
+	return lkl_netdev_tap_init(path, offload, &ifr);
+}
tools/lkl/lib/virtio_net_pipe.c new file +76 -0

76 lines not on this page · raw message

tools/lkl/lib/virtio_net_raw.c new file +94 -0

94 lines not on this page · raw message

tools/lkl/lib/virtio_net_tap.c new file +111 -0

111 lines not on this page · raw message

tools/lkl/lib/virtio_net_vde.c new file +168 -0

168 lines not on this page · raw message

tools/lkl/scripts/dpdk-sdk-build.sh new file +18 -0
new file mode 100755
index 000000000000..59de4ad8db51
@@ -0,0 +1,18 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+dpdk_version="17.02"
+
+git clone -b v${dpdk_version} git://dpdk.org/dpdk dpdk-${dpdk_version}
+
+RTE_SDK=$(pwd)/dpdk-${dpdk_version}
+RTE_TARGET=$(uname -m)-native-linuxapp-gcc
+export RTE_SDK
+export RTE_TARGET
+export EXTRA_CFLAGS="-fPIC -O0 -g3"
+
+set -e
+cd dpdk-${dpdk_version}
+make -j1 T=${RTE_TARGET} config
+make -j3 \
+  || (echo "dpdk build failed" && exit 1)
tools/lkl/tests/net-setup.sh new file +134 -0

134 lines not on this page · raw message

tools/lkl/tests/net-test.c new file +317 -0

317 lines not on this page · raw message

tools/lkl/tests/net.sh new file +186 -0

186 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 25/47 lkl: add support for Windows hosts

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This patch allows LKL to be compiled for windows hosts with the mingw toolchain. Note that patches [1] that fix weak symbols linking are required to successfully compile LKL with mingw.

The patch disables the modpost pass over vmlinux since modpost only works with ELF objects.

It also adds and workaround to an #include_next <stdard.h> error which is apparently caused by using -nosdtinc.

[1] https://sourceware.org/ml/binutils/2015-10/msg00234.html

---
 arch/um/lkl/include/system/stdarg.h | 2 ++
 include/linux/compiler_attributes.h | 4 ++++
 lib/.gitignore                      | 2 ++
 lib/raid6/.gitignore                | 1 +
 scripts/.gitignore                  | 2 ++
 scripts/basic/.gitignore            | 1 +
 scripts/kconfig/.gitignore          | 1 +
 scripts/link-vmlinux.sh             | 2 ++
 scripts/mod/.gitignore              | 1 +
 9 files changed, 16 insertions(+)
 create mode 100644 arch/um/lkl/include/system/stdarg.h
arch/um/lkl/include/system/stdarg.h new file +2 -0
new file mode 100644
index 000000000000..12077a36828c
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* empty file to avoid #include_next<stdarg.h> error */
include/linux/compiler_attributes.h +4 -0
index 6b318efd8a74..1981b1c323c1 100644
@@ -154,7 +154,11 @@
  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-format-function-attribute
  * clang: https://clang.llvm.org/docs/AttributeReference.html#format
  */
+#ifdef __MINGW32__
+#define __printf(a, b)             __attribute__((__format__(gnu_printf, a, b)))
+#else
 #define __printf(a, b)                  __attribute__((__format__(printf, a, b)))
+#endif
 #define __scanf(a, b)                   __attribute__((__format__(scanf, a, b)))
 
 /*
lib/.gitignore +2 -0
index f2a39c9e5485..eb9f11b81fe1 100644
@@ -2,7 +2,9 @@
 # Generated files
 #
 gen_crc32table
+gen_crc32table.exe
 gen_crc64table
+gen_crc64table.exe
 crc32table.h
 crc64table.h
 oid_registry_data.c
lib/raid6/.gitignore +1 -0
index 3de0d8921286..80e3566535aa 100644
@@ -1,4 +1,5 @@
 mktables
+mktables.exe
 altivec*.c
 int*.c
 tables.c
scripts/.gitignore +2 -0
index 17f8cef88fa8..ec9138a39b25 100644
@@ -4,8 +4,10 @@
 bin2c
 conmakehash
 kallsyms
+kallsyms.exe
 pnmtologo
 unifdef
+unifdef.exe
 recordmcount
 sortextable
 asn1_compiler
scripts/basic/.gitignore +1 -0
index a776371a3502..77ce153243fa 100644
@@ -1 +1,2 @@
 fixdep
+fixdep.exe
scripts/kconfig/.gitignore +1 -0
index b5bf92f66d11..aa27000d896f 100644
@@ -8,6 +8,7 @@
 # configuration programs
 #
 conf
+conf.exe
 mconf
 nconf
 qconf
scripts/link-vmlinux.sh +2 -0
index 915775eb2921..27d2066238c7 100755
@@ -205,6 +205,7 @@ fi;
 # final build of init/
 ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init
 
+if [ -e scripts/mod/modpost ]; then
 #link vmlinux.o
 info LD vmlinux.o
 modpost_link vmlinux.o
@@ -214,6 +215,7 @@ ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1
 
 info MODINFO modules.builtin.modinfo
 ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo
+fi
 
 kallsymso=""
 kallsyms_vmlinux=""
scripts/mod/.gitignore +1 -0
index 3bd11b603173..cd67845e326d 100644
@@ -1,4 +1,5 @@
 elfconfig.h
 mk_elfconfig
 modpost
+modpost.exe
 devicetable-offsets.h
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 26/47 lkl tools: add support for Windows host

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add host operations for Windows host and virtio disk support.

Trivial changes to the generic virtio host code are made since mingw %p format is different then what the MMIO virtion driver expects.

The boot test is updated to support Window hosts as well.

---
 tools/lkl/include/mingw32/sys/socket.h |   4 +
 tools/lkl/lib/nt-host.c                | 375 +++++++++++++++++++++++++
 2 files changed, 379 insertions(+)
 create mode 100644 tools/lkl/include/mingw32/sys/socket.h
 create mode 100644 tools/lkl/lib/nt-host.c
tools/lkl/include/mingw32/sys/socket.h new file +4 -0
new file mode 100644
index 000000000000..f9ede3170d03
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* fake file to avoid #include <sys/socket.h> error on non-posix
+ * host (e.g., mingw32)
+ */
tools/lkl/lib/nt-host.c new file +375 -0

375 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 27/47 lkl: Android ARM (arm/arm64) support

In reply to Hajime Tazaki

Initial attempt to run an application with hijack library on Android platform. Tested mostly on Android 6.x and 7.x.

The build process assumes that the android ndk toolchain is installed in a host system as circle.yml does in its test. arm32 build uses alternate linker, stored in tools/lkl/bin directory, in order to avoid the link issue (issue #59).

The CircleCI test infrastructure requires to use ubuntu 14.04 for this test.

* Limitations
- aarch64 isn't tested on circleci due to difficulties on aarch64 emulator.
- bionic libc on android-24 emulator (arm32) doesn't call destructor, so some of tests in hijack-test.sh fail.
- net.sh doesn't properly test network related issue.

Fixes #59.

---
 tools/lkl/bin/arm-linux-androideabi-ld | 1 +
 1 file changed, 1 insertion(+)
 create mode 120000 tools/lkl/bin/arm-linux-androideabi-ld
tools/lkl/bin/arm-linux-androideabi-ld new file +1 -0
new file mode 120000
index 000000000000..4194d24c4b5c
@@ -0,0 +1 @@
+arm-linux-androideabi-ld.gold
\ No newline at end of file
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 28/47 lkl tools: add lklfuse

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add a simple fuse based program that can mount filesystem in userspace using LKL.

---
 tools/lkl/lklfuse.c        | 658 +++++++++++++++++++++++++++++++++++++
 tools/lkl/tests/lklfuse.sh | 110 +++++++
 2 files changed, 768 insertions(+)
 create mode 100644 tools/lkl/lklfuse.c
 create mode 100755 tools/lkl/tests/lklfuse.sh
tools/lkl/lklfuse.c new file +658 -0
new file mode 100644
index 000000000000..4e6c8fe250d0
@@ -0,0 +1,658 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#define FUSE_USE_VERSION 26
+#include <fuse.h>
+#include <fuse/fuse_opt.h>
+#include <fuse/fuse_lowlevel.h>
+#include <lkl.h>
+#include <lkl_host.h>
+
+#define LKLFUSE_VERSION "0.1"
+
+struct lklfuse {
+	const char *file;
+	const char *log;
+	const char *type;
+	const char *opts;
+	struct lkl_disk disk;
+	int disk_id;
+	int part;
+	int ro;
+	int mb;
+} lklfuse = {
+	.mb = 64,
+};
+
+#define LKLFUSE_OPT(t, p, v) { t, offsetof(struct lklfuse, p), v }
+
+enum {
+	KEY_HELP,
+	KEY_VERSION,
+};
+
+static struct fuse_opt lklfuse_opts[] = {
+	LKLFUSE_OPT("log=%s", log, 0),
+	LKLFUSE_OPT("type=%s", type, 0),
+	LKLFUSE_OPT("mb=%d", mb, 0),
+	LKLFUSE_OPT("opts=%s", opts, 0),
+	LKLFUSE_OPT("part=%d", part, 0),
+	FUSE_OPT_KEY("-h", KEY_HELP),
+	FUSE_OPT_KEY("--help", KEY_HELP),
+	FUSE_OPT_KEY("-V",             KEY_VERSION),
+	FUSE_OPT_KEY("--version",      KEY_VERSION),
+	FUSE_OPT_END
+};
+
+static void usage(void)
+{
+	printf(
+"usage: lklfuse file mountpoint [options]\n"
+"\n"
+"general options:\n"
+"    -o opt,[opt...]        mount options\n"
+"    -h   --help            print help\n"
+"    -V   --version         print version\n"
+"\n"
+"lklfuse options:\n"
+"    -o log=FILE            log file\n"
+"    -o type=fstype         filesystem type\n"
+"    -o mb=memory in mb     ammount of memory to allocate\n"
+"    -o part=parition       partition to mount\n"
+"    -o ro                  open file read-only\n"
+"    -o opts=options        mount options (use \\ to escape , and =)\n"
+);
+}
+
+static int lklfuse_opt_proc(void *data, const char *arg, int key,
+			  struct fuse_args *args)
+{
+	switch (key) {
+	case FUSE_OPT_KEY_OPT:
+		if (strcmp(arg, "ro") == 0)
+			lklfuse.ro = 1;
+		return 1;
+
+	case FUSE_OPT_KEY_NONOPT:
+		if (!lklfuse.file) {
+			lklfuse.file = strdup(arg);
+			return 0;
+		}
+		return 1;
+
+	case KEY_HELP:
+		usage();
+		fuse_opt_add_arg(args, "-ho");
+		fuse_main(args->argc, args->argv, NULL, NULL);
+		exit(1);
+
+	case KEY_VERSION:
+		printf("lklfuse version %s\n", LKLFUSE_VERSION);
+		fuse_opt_add_arg(args, "--version");
+		fuse_main(args->argc, args->argv, NULL, NULL);
+		exit(0);
+
+	default:
+		fprintf(stderr, "internal error\n");
+		abort();
+	}
+}
+
+static void lklfuse_xlat_stat(const struct lkl_stat *in, struct stat *st)
+{
+	st->st_dev = in->st_dev;
+	st->st_ino = in->st_ino;
+	st->st_mode = in->st_mode;
+	st->st_nlink = in->st_nlink;
+	st->st_uid = in->st_uid;
+	st->st_gid = in->st_gid;
+	st->st_rdev = in->st_rdev;
+	st->st_size = in->st_size;
+	st->st_blksize = in->st_blksize;
+	st->st_blocks = in->st_blocks;
+	st->st_atim.tv_sec = in->lkl_st_atime;
+	st->st_atim.tv_nsec = in->st_atime_nsec;
+	st->st_mtim.tv_sec = in->lkl_st_mtime;
+	st->st_mtim.tv_nsec = in->st_mtime_nsec;
+	st->st_ctim.tv_sec = in->lkl_st_ctime;
+	st->st_ctim.tv_nsec = in->st_ctime_nsec;
+}
+
+static int lklfuse_fgetattr(const char *path, struct stat *st,
+			    struct fuse_file_info *fi)
+{
+	long ret;
+	struct lkl_stat lkl_stat;
+
+	ret = lkl_sys_fstat(fi->fh, &lkl_stat);
+	if (ret)
+		return ret;
+
+	lklfuse_xlat_stat(&lkl_stat, st);
+	return 0;
+}
+
+static int lklfuse_getattr(const char *path, struct stat *st)
+{
+	long ret;
+	struct lkl_stat lkl_stat;
+
+	ret = lkl_sys_lstat(path, &lkl_stat);
+	if (ret)
+		return ret;
+
+	lklfuse_xlat_stat(&lkl_stat, st);
+	return 0;
+}
+
+static int lklfuse_readlink(const char *path, char *buf, size_t len)
+{
+	long ret;
+
+	ret = lkl_sys_readlink(path, buf, len);
+	if (ret < 0)
+		return ret;
+
+	if ((size_t)ret == len)
+		ret = len - 1;
+
+	buf[ret] = 0;
+
+	return 0;
+}
+
+static int lklfuse_mknod(const char *path, mode_t mode, dev_t dev)
+{
+	return lkl_sys_mknod(path, mode, dev);
+}
+
+static int lklfuse_mkdir(const char *path, mode_t mode)
+{
+	return lkl_sys_mkdir(path, mode);
+}
+
+static int lklfuse_unlink(const char *path)
+{
+	return lkl_sys_unlink(path);
+}
+
+static int lklfuse_rmdir(const char *path)
+{
+	return lkl_sys_rmdir(path);
+}
+
+static int lklfuse_symlink(const char *oldname, const char *newname)
+{
+	return lkl_sys_symlink(oldname, newname);
+}
+
+
+static int lklfuse_rename(const char *oldname, const char *newname)
+{
+	return lkl_sys_rename(oldname, newname);
+}
+
+static int lklfuse_link(const char *oldname, const char *newname)
+{
+	return lkl_sys_link(oldname, newname);
+}
+
+static int lklfuse_chmod(const char *path, mode_t mode)
+{
+	return lkl_sys_chmod(path, mode);
+}
+
+
+static int lklfuse_chown(const char *path, uid_t uid, gid_t gid)
+{
+	return lkl_sys_fchownat(LKL_AT_FDCWD, path, uid, gid,
+				LKL_AT_SYMLINK_NOFOLLOW);
+}
+
+static int lklfuse_truncate(const char *path, off_t off)
+{
+	return lkl_sys_truncate(path, off);
+}
+
+static int lklfuse_open3(const char *path, bool create, mode_t mode,
+			 struct fuse_file_info *fi)
+{
+	long ret;
+	int flags;
+
+	if ((fi->flags & O_ACCMODE) == O_RDONLY)
+		flags = LKL_O_RDONLY;
+	else if ((fi->flags & O_ACCMODE) == O_WRONLY)
+		flags = LKL_O_WRONLY;
+	else if ((fi->flags & O_ACCMODE) == O_RDWR)
+		flags = LKL_O_RDWR;
+	else
+		return -EINVAL;
+
+	if (create)
+		flags |= LKL_O_CREAT;
+
+	ret = lkl_sys_open(path, flags, mode);
+	if (ret < 0)
+		return ret;
+
+	fi->fh = ret;
+
+	return 0;
+}
+
+static int lklfuse_create(const char *path, mode_t mode,
+			  struct fuse_file_info *fi)
+{
+	return lklfuse_open3(path, true, mode, fi);
+}
+
+static int lklfuse_open(const char *path, struct fuse_file_info *fi)
+{
+	return lklfuse_open3(path, false, 0, fi);
+}
+
+static int lklfuse_read(const char *path, char *buf, size_t size, off_t offset,
+		      struct fuse_file_info *fi)
+{
+	long ret;
+	ssize_t orig_size = size;
+
+	do {
+		ret = lkl_sys_pread64(fi->fh, buf, size, offset);
+		if (ret <= 0)
+			break;
+		size -= ret;
+		offset += ret;
+		buf += ret;
+	} while (size > 0);
+
+	return ret < 0 ? ret : orig_size - (ssize_t)size;
+
+}
+
+static int lklfuse_write(const char *path, const char *buf, size_t size,
+		       off_t offset, struct fuse_file_info *fi)
+{
+	long ret;
+	ssize_t orig_size = size;
+
+	do {
+		ret = lkl_sys_pwrite64(fi->fh, buf, size, offset);
+		if (ret <= 0)
+			break;
+		size -= ret;
+		offset += ret;
+		buf += ret;
+	} while (size > 0);
+
+	return ret < 0 ? ret : orig_size - (ssize_t)size;
+}
+
+
+static int lklfuse_statfs(const char *path, struct statvfs *stat)
+{
+	long ret;
+	struct lkl_statfs lkl_statfs;
+
+	ret = lkl_sys_statfs(path, &lkl_statfs);
+	if (ret < 0)
+		return ret;
+
+	stat->f_bsize = lkl_statfs.f_bsize;
+	stat->f_frsize = lkl_statfs.f_frsize;
+	stat->f_blocks = lkl_statfs.f_blocks;
+	stat->f_bfree = lkl_statfs.f_bfree;
+	stat->f_bavail = lkl_statfs.f_bavail;
+	stat->f_files = lkl_statfs.f_files;
+	stat->f_ffree = lkl_statfs.f_ffree;
+	stat->f_favail = stat->f_ffree;
+	stat->f_fsid = *(unsigned long *)&lkl_statfs.f_fsid.val[0];
+	stat->f_flag = lkl_statfs.f_flags;
+	stat->f_namemax = lkl_statfs.f_namelen;
+
+	return 0;
+}
+
+static int lklfuse_flush(const char *path, struct fuse_file_info *fi)
+{
+	return 0;
+}
+
+static int lklfuse_release(const char *path, struct fuse_file_info *fi)
+{
+	return lkl_sys_close(fi->fh);
+}
+
+static int lklfuse_fsync(const char *path, int datasync,
+		       struct fuse_file_info *fi)
+{
+	if (datasync)
+		return lkl_sys_fdatasync(fi->fh);
+	else
+		return lkl_sys_fsync(fi->fh);
+}
+
+static int lklfuse_setxattr(const char *path, const char *name, const char *val,
+		   size_t size, int flags)
+{
+	return lkl_sys_setxattr(path, name, val, size, flags);
+}
+
+static int lklfuse_getxattr(const char *path, const char *name, char *val,
+			  size_t size)
+{
+	return lkl_sys_getxattr(path, name, val, size);
+}
+
+static int lklfuse_listxattr(const char *path, char *list, size_t size)
+{
+	return lkl_sys_listxattr(path, list, size);
+}
+
+static int lklfuse_removexattr(const char *path, const char *name)
+{
+	return lkl_sys_removexattr(path, name);
+}
+
+static int lklfuse_opendir(const char *path, struct fuse_file_info *fi)
+{
+	struct lkl_dir *dir;
+	int err;
+
+	dir = lkl_opendir(path, &err);
+	if (!dir)
+		return err;
+
+	fi->fh = (uintptr_t)dir;
+
+	return 0;
+}
+
+/** Read directory
+ *
+ * This supersedes the old getdir() interface.  New applications
+ * should use this.
+ *
+ * The filesystem may choose between two modes of operation:
+ *
+ * 1) The readdir implementation ignores the offset parameter, and
+ * passes zero to the filler function's offset.  The filler
+ * function will not return '1' (unless an error happens), so the
+ * whole directory is read in a single readdir operation.  This
+ * works just like the old getdir() method.
+ *
+ * 2) The readdir implementation keeps track of the offsets of the
+ * directory entries.  It uses the offset parameter and always
+ * passes non-zero offset to the filler function.  When the buffer
+ * is full (or an error happens) the filler function will return
+ * '1'.
+ *
+ * Introduced in version 2.3
+ */
+static int lklfuse_readdir(const char *path, void *buf, fuse_fill_dir_t fill,
+			 off_t off, struct fuse_file_info *fi)
+{
+	struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh;
+	struct lkl_linux_dirent64 *de;
+
+	while ((de = lkl_readdir(dir))) {
+		struct stat st = { 0, };
+
+		st.st_ino = de->d_ino;
+		st.st_mode = de->d_type << 12;
+
+		if (fill(buf, de->d_name, &st, 0))
+			break;
+	}
+
+	if (!de)
+		return lkl_errdir(dir);
+
+	return 0;
+}
+
+static int lklfuse_releasedir(const char *path, struct fuse_file_info *fi)
+{
+	struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh;
+
+	return lkl_closedir(dir);
+}
+
+static int lklfuse_fsyncdir(const char *path, int datasync,
+			  struct fuse_file_info *fi)
+{
+	struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh;
+	int fd = lkl_dirfd(dir);
+
+	if (datasync)
+		return lkl_sys_fdatasync(fd);
+	else
+		return lkl_sys_fsync(fd);
+}
+
+static int lklfuse_access(const char *path, int mode)
+{
+	return lkl_sys_access(path, mode);
+}
+
+static int lklfuse_utimens(const char *path, const struct timespec tv[2])
+{
+	struct lkl_timespec ts[2];
+
+	ts[0].tv_sec = tv[0].tv_sec;
+	ts[0].tv_nsec = tv[0].tv_nsec;
+	ts[1].tv_sec = tv[0].tv_sec;
+	ts[1].tv_nsec = tv[0].tv_nsec;
+
+	return lkl_sys_utimensat(-1, path, (struct __lkl__kernel_timespec *)ts,
+				 LKL_AT_SYMLINK_NOFOLLOW);
+}
+
+static int lklfuse_fallocate(const char *path, int mode, off_t offset,
+			     off_t len, struct fuse_file_info *fi)
+{
+	return lkl_sys_fallocate(fi->fh, mode, offset, len);
+}
+
+const struct fuse_operations lklfuse_ops = {
+	.flag_nullpath_ok = 1,
+	.flag_nopath = 1,
+	.flag_utime_omit_ok = 1,
+
+	.getattr = lklfuse_getattr,
+	.readlink = lklfuse_readlink,
+	.mknod = lklfuse_mknod,
+	.mkdir = lklfuse_mkdir,
+	.unlink = lklfuse_unlink,
+	.rmdir = lklfuse_rmdir,
+	.symlink = lklfuse_symlink,
+	.rename = lklfuse_rename,
+	.link = lklfuse_link,
+	.chmod = lklfuse_chmod,
+	.chown = lklfuse_chown,
+	.truncate = lklfuse_truncate,
+	.open = lklfuse_open,
+	.read = lklfuse_read,
+	.write = lklfuse_write,
+	.statfs = lklfuse_statfs,
+	.flush = lklfuse_flush,
+	.release = lklfuse_release,
+	.fsync = lklfuse_fsync,
+	.setxattr = lklfuse_setxattr,
+	.getxattr = lklfuse_getxattr,
+	.listxattr = lklfuse_listxattr,
+	.removexattr = lklfuse_removexattr,
+	.opendir = lklfuse_opendir,
+	.readdir = lklfuse_readdir,
+	.releasedir = lklfuse_releasedir,
+	.fsyncdir = lklfuse_fsyncdir,
+	.access = lklfuse_access,
+	.create = lklfuse_create,
+	.fgetattr = lklfuse_fgetattr,
+	/* .lock, */
+	.utimens = lklfuse_utimens,
+	/* .bmap, */
+	/* .ioctl, */
+	/* .poll, */
+	/* .write_buf, (SG io) */
+	/* .read_buf, (SG io) */
+	/* .flock, */
+	.fallocate = lklfuse_fallocate,
+};
+
+static int start_lkl(void)
+{
+	long ret;
+	char mpoint[32], cmdline[16];
+
+	snprintf(cmdline, sizeof(cmdline), "mem=%dM", lklfuse.mb);
+	ret = lkl_start_kernel(&lkl_host_ops, cmdline);
+	if (ret) {
+		fprintf(stderr, "can't start kernel: %s\n", lkl_strerror(ret));
+		goto out;
+	}
+
+	ret = lkl_mount_dev(lklfuse.disk_id, lklfuse.part, lklfuse.type,
+			    lklfuse.ro ? LKL_MS_RDONLY : 0, lklfuse.opts,
+			    mpoint, sizeof(mpoint));
+
+	if (ret) {
+		fprintf(stderr, "can't mount disk: %s\n", lkl_strerror(ret));
+		goto out_halt;
+	}
+
+	ret = lkl_sys_chroot(mpoint);
+	if (ret) {
+		fprintf(stderr, "can't chdir to %s: %s\n", mpoint,
+			lkl_strerror(ret));
+		goto out_umount;
+	}
+
+	return 0;
+
+out_umount:
+	lkl_umount_dev(lklfuse.disk_id, lklfuse.part, 0, 1000);
+
+out_halt:
+	lkl_sys_halt();
+
+out:
+	return ret;
+}
+
+static void stop_lkl(void)
+{
+	int ret;
+
+	ret = lkl_sys_chdir("/");
+	if (ret)
+		fprintf(stderr, "can't chdir to /: %s\n", lkl_strerror(ret));
+	ret = lkl_sys_umount("/", 0);
+	if (ret)
+		fprintf(stderr, "failed to umount disk: %d: %s\n",
+			lklfuse.disk_id, lkl_strerror(ret));
+	lkl_sys_halt();
+}
+
+int main(int argc, char **argv)
+{
+	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+	struct fuse_chan *ch;
+	struct fuse *fuse;
+	struct stat st;
+	char *mnt;
+	int fg, mt, ret;
+
+	if (fuse_opt_parse(&args, &lklfuse, lklfuse_opts, lklfuse_opt_proc))
+		return 1;
+
+	if (!lklfuse.file || !lklfuse.type) {
+		fprintf(stderr, "no file or filesystem type specified\n");
+		return 1;
+	}
+
+	if (fuse_parse_cmdline(&args, &mnt, &mt, &fg))
+		return 1;
+
+	ret = stat(mnt, &st);
+	if (ret) {
+		perror(mnt);
+		goto out_free;
+	}
+
+	ret = open(lklfuse.file, lklfuse.ro ? O_RDONLY : O_RDWR);
+	if (ret < 0) {
+		perror(lklfuse.file);
+		goto out_free;
+	}
+
+	lklfuse.disk.fd = ret;
+
+	ret = lkl_disk_add(&lklfuse.disk);
+	if (ret < 0) {
+		fprintf(stderr, "can't add disk: %s\n", lkl_strerror(ret));
+		goto out_close_disk;
+	}
+
+	lklfuse.disk_id = ret;
+
+	ch = fuse_mount(mnt, &args);
+	if (!ch) {
+		ret = -1;
+		goto out_close_disk;
+	}
+
+	fuse = fuse_new(ch, &args, &lklfuse_ops, sizeof(lklfuse_ops), NULL);
+	if (!fuse) {
+		ret = -1;
+		goto out_fuse_unmount;
+	}
+
+	fuse_opt_free_args(&args);
+
+	if (fuse_daemonize(fg) ||
+	    fuse_set_signal_handlers(fuse_get_session(fuse))) {
+		ret = -1;
+		goto out_fuse_destroy;
+	}
+
+	ret = start_lkl();
+	if (ret) {
+		ret = -1;
+		goto out_remove_signals;
+	}
+
+	if (mt)
+		fprintf(stderr, "warning: multithreaded mode not supported\n");
+
+	ret = fuse_loop(fuse);
+
+	stop_lkl();
+
+out_remove_signals:
+	fuse_remove_signal_handlers(fuse_get_session(fuse));
+
+out_fuse_unmount:
+	if (ch)
+		fuse_unmount(mnt, ch);
+
+out_fuse_destroy:
+	if (fuse)
+		fuse_destroy(fuse);
+
+out_close_disk:
+	close(lklfuse.disk.fd);
+
+out_free:
+	free(mnt);
+
+	return ret < 0 ? 1 : 0;
+}
tools/lkl/tests/lklfuse.sh new file +110 -0

110 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 29/47 lkl: add initial system call hijack support (a.k.a. NUSE of libos)

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This commit introduces initial support of system call hijack, based on LD_PRELOAD with POSIX applications on a host.

Note that system call hijack by renaming symbol by LD_PRELOAD is not a complete solution: it must address various issues with dirty tricks.

Those tricks/issues are:
- introduce file descriptor offset (i.e., fd + offset)
- path name isolation (i.e., chrooted)
- need of handling mixture of fd between host and lkl-ed ones
- un-hijackable symbol (__socket inside if_nametoindex() of linux glibc) needs to be hijacked by upper call (i.e., if_nametoindex)

Nevertheless, it is powerful in some case such as replacing network stack only for an application.

It has been tested with socket(AF_INET/AF_INET6/AF_NETLINK) without any external netdevices, i.e. only works with localhost (127.0.0.1/::1). It may need more work on non-Linux host.

select(2)/poll(2)/epoll_create(2) need more work.

The below should work on Linux.
% ./tools/lkl/bin/hijack.sh ip ad

---
 tools/lkl/bin/lkl-hijack.sh    |  23 +
 tools/lkl/lib/hijack/Build     |   4 +
 tools/lkl/lib/hijack/hijack.c  | 618 +++++++++++++++++++++++++++
 tools/lkl/lib/hijack/init.c    | 252 +++++++++++
 tools/lkl/lib/hijack/init.h    |   8 +
 tools/lkl/lib/hijack/xlate.c   | 613 ++++++++++++++++++++++++++
 tools/lkl/lib/hijack/xlate.h   |  13 +
 tools/lkl/tests/hijack-test.sh | 760 +++++++++++++++++++++++++++++++++
 tools/lkl/tests/run_netperf.sh |  98 +++++
 9 files changed, 2389 insertions(+)
 create mode 100755 tools/lkl/bin/lkl-hijack.sh
 create mode 100644 tools/lkl/lib/hijack/Build
 create mode 100644 tools/lkl/lib/hijack/hijack.c
 create mode 100644 tools/lkl/lib/hijack/init.c
 create mode 100644 tools/lkl/lib/hijack/init.h
 create mode 100644 tools/lkl/lib/hijack/xlate.c
 create mode 100644 tools/lkl/lib/hijack/xlate.h
 create mode 100755 tools/lkl/tests/hijack-test.sh
 create mode 100755 tools/lkl/tests/run_netperf.sh
tools/lkl/bin/lkl-hijack.sh new file +23 -0
new file mode 100755
index 000000000000..7cf92856dfad
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: GPL-2.0
+
+##
+## This wrapper script works to replace system calls symbols such as
+## socket(2), recvmsg(2) for the redirection to LKL. Ideally it works
+## with any applications, but in practice (tm) it depends on the maturity
+## of hijack library (liblkl-hijack.so).
+##
+## Since LD_PRELOAD technique with setuid/setgid binary is tricky, you may
+## need to use sudo (or equivalents) to do it (e.g., ping).
+##
+## % sudo hijack.sh ping 127.0.0.1
+##
+
+script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+
+export LD_LIBRARY_PATH=${script_dir}/../lib/hijack
+if [ -n ${LKL_HIJACK_DEBUG+x}  ]
+then
+  trap '' TSTP
+fi
+LD_PRELOAD=liblkl-hijack.so $*
tools/lkl/lib/hijack/Build new file +4 -0
new file mode 100644
index 000000000000..e68e93a3328a
@@ -0,0 +1,4 @@
+liblkl-hijack-y += hijack.o
+liblkl-hijack-y += init.o
+liblkl-hijack-y += xlate.o
+
tools/lkl/lib/hijack/hijack.c new file +618 -0

618 lines not on this page · raw message

tools/lkl/lib/hijack/init.c new file +252 -0

252 lines not on this page · raw message

tools/lkl/lib/hijack/init.h new file +8 -0
new file mode 100644
index 000000000000..c4039e018b2b
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_HIJACK_INIT_H
+#define _LKL_HIJACK_INIT_H
+
+extern int lkl_running;
+extern int dual_fds[];
+
+#endif /*_LKL_HIJACK_INIT_H */
tools/lkl/lib/hijack/xlate.c new file +613 -0

613 lines not on this page · raw message

tools/lkl/lib/hijack/xlate.h new file +13 -0
new file mode 100644
index 000000000000..0c0281f241a6
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_HIJACK_XLATE_H
+#define _LKL_HIJACK_XLATE_H
+
+long lkl_set_errno(long err);
+int lkl_soname_xlate(int soname);
+int lkl_solevel_xlate(int solevel);
+unsigned long lkl_ioctl_req_xlate(unsigned long req);
+int lkl_fcntl_cmd_xlate(int cmd);
+
+#define LKL_FD_OFFSET (FD_SETSIZE/2)
+
+#endif /* _LKL_HIJACK_XLATE_H */
tools/lkl/tests/hijack-test.sh new file +760 -0

760 lines not on this page · raw message

tools/lkl/tests/run_netperf.sh new file +98 -0

98 lines not on this page · raw message

Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 30/47 lkl: add documentation

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

We also added a symlink to README.md to display at github.

---
 Documentation/lkl.txt | 470 ++++++++++++++++++++++++++++++++++++++++++
 README.md             |   1 +
 2 files changed, 471 insertions(+)
 create mode 100644 Documentation/lkl.txt
 create mode 120000 README.md
Documentation/lkl.txt new file +470 -0
new file mode 100644
index 000000000000..97fe407b0bc6
@@ -0,0 +1,470 @@
+
+Introduction
+============
+
+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 an architecture port in arch/lkl. It uses host operations
+defined by the application or a host library (tools/lkl/lib).
+
+
+Supported hosts
+===============
+
+The supported hosts for now are POSIX and Windows userspace applications.
+
+
+Building LKL, the host library and LKL based tools
+==================================================
+
+    $ make -C tools/lkl
+
+will build LKL as a object file, it will install it in tools/lkl/lib together
+with the headers files in tools/lkl/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
+
+* fs2tar - a tool that converts a filesystem image to a tar archive
+
+* cptofs/cpfromfs - a tool that copies files to/from a filesystem image
+
+* lklfuse - a tool that can mount a filesystem image in userspace,
+  without root privileges, using FUSE
+
+
+Building LKL on FreeBSD
+-----------------------
+
+    $ pkg install binutils gcc gnubc gmake gsed coreutils bison flex python argp-standalone
+
+    #Prefer ports binutils and GNU bc(1):
+    $ export PATH=/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/lib64/ccache
+
+    $ gmake -C tools/lkl
+
+Building LKL on Ubuntu
+-----------------------
+
+    $ sudo apt-get install libfuse-dev libarchive-dev xfsprogs
+
+    # Optional, if you would like to be able to run tests
+    $ sudo apt-get install btrfs-tools
+    $ pip install yamlish junit_xml
+
+    $ make -C tools/lkl
+
+    # To check that everything works:
+    $ cd tools/lkl
+    $ make run-tests
+
+
+Building LKL for Windows
+------------------------
+
+In order to build LKL for Win32 the mingw cross compiler needs to be installed
+on the host (e.g. on Ubuntu the following packages are required:
+binutils-mingw-w64-i686, gcc-mingw-w64-base, gcc-mingw-w64-i686
+mingw-w64-common, mingw-w64-i686-dev).
+
+Due to a bug in mingw regarding weak symbols the following patches needs to be
+applied to mingw-binutils:
+
+https://sourceware.org/ml/binutils/2015-10/msg00234.html
+
+and i686-w64-mingw32-gas, i686-w64-mingw32-ld and i686-w64-mingw32-objcopy need
+to be recompiled.
+
+With that pre-requisites fullfilled you can now build LKL for Win32 with the
+following command:
+
+    $ make CROSS_COMPILE=i686-w64-mingw32- -C tools/lkl
+
+
+
+Building LKL on Windows
+------------------------
+
+To build on Windows, certain GNU tools need to be installed. These tools can come
+from several different projects, such as cygwin, unxutils, gnu-win32 or busybox-w32.
+Below is one minimal/modular set-up based on msys2.
+
+### Common build dependencies:
+* [MSYS2](https://sourceforge.net/projects/msys2/) (provides GNU bash and many other utilities)
+* Extra utilities from MSYS2/pacman: bc, base-devel
+
+### General considerations:
+* No spaces in pathnames (source, prefix, destination,...)!
+* Make sure that all utilities are in the PATH.
+* Win64 (and MinGW 64-bit crt) is LLP64, which causes conflicts in size of "long" in the
+Linux source. Linux (and lkl) can (currently) not
+be built on LLP64.
+* Cygwin (and msys2) are LP64, like linux.
+
+### For MSYS2 (and Cygwin):
+Msys2 will install a gcc tool chain as part of the base-devel bundle. Binutils (2.26) is already
+patched for NT weak externals. Using the msys2 shell, cd to the lkl sources and run:
+
+    $ make -C tools/lkl
+
+### For MinGW:
+Install mingw-w64-i686-toolchain via pacman, mingw-w64-i686-binutils (2.26) is already patched
+for NT weak externals. Start a MinGW Win32 shell (64-bit will not work, see above)
+and run:
+
+    $ make -C tools/lkl
+
+
+LKL hijack library
+==================
+
+LKL hijack library (liblkl-hijack.so) is used to replace system calls used by an
+application on the fly so that the application can use LKL instead of the kernel
+of host operating system. LD_PRELOAD is used to dynamically override system
+calls with this library when you execute a program.
+
+You can usually use this library via a wrapper script.
+
+    $ cd tools/lkl
+    $ ./bin/lkl-hijack.sh ip address show
+
+In order to configure the behavior of LKL, a json file can be used. You can
+specify json file with environmental variables (LKL_HIJACK_CONFIG_FILE). If
+there is nothing specified, LKL tries to find with the name 'lkl-hijack.json'
+for the configuration file.  You can also use the old-style configuration with
+environmental variables (e.g., LKL_HIJACK_NET_IFTYPE) but those are overridden
+if a json file is specified.
+
+```
+     $ cat conf.json
+     {
+       "gateway":"192.168.0.1",
+       "gateway6":"2001:db8:0:f101::1",
+       "debug":"1",
+       "singlecpu":"1",
+       "sysctl":"net.ipv4.tcp_wmem=4096 87380 2147483647",
+       "boot_cmdline":"ip=dhcp",
+       "interfaces":[
+               {
+                       "mac":"12:34:56:78:9a:bc",
+                       "type":"tap",
+                       "param":"tap7",
+                       "ip":"192.168.0.2",
+                       "masklen":"24",
+                       "ifgateway":"192.168.0.1",
+                       "ipv6":"2001:db8:0:f101::2",
+                       "masklen6":"64",
+                       "ifgateway6":"2001:db8:0:f101::1",
+                       "offload":"0xc803"
+               },
+               {
+                       "mac":"12:34:56:78:9a:bd",
+                       "type":"tap",
+                       "param":"tap77",
+                       "ip":"192.168.1.2",
+                       "masklen":"24",
+                       "ifgateway":"192.168.1.1",
+                       "ipv6":"2001:db8:0:f102::2",
+                       "masklen6":"64",
+                       "ifgateway6":"2001:db8:0:f102::1",
+                       "offload":"0xc803"
+               }
+       ]
+     }
+     $ LKL_HIJACK_CONFIG_FILE="conf.json" lkl-hijack.sh ip addr s
+```
+
+The following are the list of keys to describe a JSON file.
+
+* IPv4 gateway address
+
+  key: "gateway"
+  value type: string
+
+  the gateway IPv4 address of LKL network stack.
+```
+     "gateway":"192.168.0.1"
+```
+
+* IPv6 gateway address
+
+  key: "gateway6"
+  value type: string
+
+  the gateway IPv6 address of LKL network stack.
+```
+     "gateway6":"2001:db8:0:f101::1"
+```
+
+* Debug
+
+  key: "debug"
+  value type: string
+
+  Setting it causes some debug information (both from the kernel and the
+  LKL library) to be enabled.  If zero' is specified it is disabled.
+  It is also used as a bit mask to turn on specific debugging facilities.
+  E.g., setting it to "0x100" will cause the LKL kernel to pause after
+  the hijack'ed app exits. This allows one to debug or collect info from
+  the LKL kernel before it quits.
+```
+     "debug":"1"
+```
+
+* Single CPU pinning
+
+  key: "singlecpu"
+  value type: string
+
+  Pin LKL kernel threads on to a single host cpu. value "1" pins
+  only LKL kernel threads while value "2" also pins polling
+  threads.
+```
+     "singlecpu":"1"
+```
+
+* SYSCTL
+
+  key: "sysctl"
+  value type: string
+
+  Configure sysctl values of the booted kernel via the hijack library. Multiple
+  entries can be specified.
+```
+     "sysctl":"net.ipv4.tcp_wmem=4096 87380 2147483647"
+```
+
+* Boot command line
+
+  key: "boot_cmdline"
+  value type: string
+
+  Specify the command line to the kernel boot so that change the configuration
+  on a kernel instance.  For instance, you can change the memory size with
+  below.
+```
+     "boot_cmdline": "mem=1G"
+```
+
+* Mount
+
+  key: "mount"
+  value type: string
+
+```
+     "mount": "proc,sysfs"
+```
+
+* Network Interface Configuration
+
+  key: "interfaces"
+  value type: array of objects
+
+  This key takes a set of sub-keys to configure a single interface. Each key is defined as follows.
+  ```
+       "interfaces":[{....},{....}]
+  ```
+
+
+	* Interface type
+
+	  key: "type"
+	  value type: string
+
+	  The interface type in host operating system to connect to LKL.
+	  The following example specifies a tap interface.
+	```
+	     "type":"tap"
+	```
+
+	* Interface parameter
+
+	  key: "param"
+	  value type: string
+
+	  Additional configuration parameters for the interface specified by Interface type (type).
+	  The parameters depend on the interface type.
+	```
+	     "type":"tap",
+	     "param":"tap0"
+	```
+
+	* Interface MTU size
+
+	  key: "mtu"
+	  value type: string
+
+	  the MTU size of the interface.
+	```
+	     "mtu":"1280"
+	```
+
+	* Interface IPv4 address
+
+	  key: "ip"
+	  value type: string
+
+	  the IPv4 address of the interface.
+	  If you want to use DHCP for the IP address assignment,
+	  use "boot_cmdline" with "ip=dhcp" option.
+	```
+	     "ip":"192.168.0.2"
+	```
+	```
+	     "boot_cmdline":"ip=dhcp"
+	```
+
+	* Interface IPv4 netmask length
+
+	  key: "masklen"
+	  value type: string
+
+	  the network mask length of the interface.
+	```
+	     "ip":"192.168.0.2",
+	     "masklen":"24"
+	```
+
+	* Interface IPv4 gateway on routing policy table
+
+	  key: "ifgateway"
+	  value type: string
+
+	  If you specify this parameter, LKL adds routing policy table.
+	  And then LKL creates link local and gateway route on this table.
+	  Table SELECTOR is "from" and PREFIX is address you assigned to this interface.
+	  Table id is 2 * (interface index).
+	  This parameter could be used to configure LKL for mptcp, for example.
+
+	```
+	     "ip":"192.168.0.2",
+	     "masklen":"24",
+	     "ifgateway":"192.168.0.1"
+	```
+
+	* Interface IPv6 address
+
+	  key: "ipv6"
+	  value type: string
+
+	  the IPv6 address of the interface.
+	```
+	     "ipv6":"2001:db8:0:f101::2"
+	```
+
+	* Interface IPv6 netmask length
+
+	  key: "masklen6"
+	  value type: string
+
+	  the network mask length of the interface.
+	```
+	     "ipv6":"2001:db8:0:f101::2",
+	     "masklen":"64"
+	```
+
+	* Interface IPv6 gateway on routing policy table
+
+	  key: "ifgateway6"
+	  value type: string
+
+	  If you specify this parameter, LKL adds routing policy table.
+	  And then LKL creates link local and gateway route on this table.
+	  Table SELECTOR is "from" and PREFIX is address you assigned to this interface.
+	  Table id is 2 * (interface index) + 1.
+	  This parameter could be used to configure LKL for mptcp, for example.
+	```
+	     "ipv6":"2001:db8:0:f101::2",
+	     "masklen":"64"
+	     "ifgateway6":"2001:db8:0:f101::1",
+	```
+
+	* Interface MAC address
+
+	  key: "mac"
+	  value type: string
+
+	  the MAC address of the interface.
+	```
+	     "mac":"12:34:56:78:9a:bc"
+	```
+
+	* Interfac neighbor entries
+
+	  key: "neigh"
+	  value type: string
+
+	  Add a list of permanent neighbor entries in the form of "ip|mac;ip|mac;...". ipv6 are supported
+	```
+	     "neigh":"192.168.0.1|12:34:56:78:9a:bc;2001:db8:0:f101::1|12:34:56:78:9a:be"
+	```
+
+	* Interface qdisc entries
+
+	  key: "qdisc"
+	  value type: string
+
+	  Add a qdisc entry in the form of "root|type;root|type;...".
+	```
+	     "qdisc":"root|fq"
+	```
+
+	* Interface offload
+
+	  key: "offload"
+	  value type: string
+
+	  Work as a bit mask to enable selective device offload features. E.g.,
+	  to enable "mergeable RX buffer" (LKL_VIRTIO_NET_F_MRG_RXBUF) +
+	  "guest csum" (LKL_VIRTIO_NET_F_GUEST_CSUM) device features, simply set
+	  it to 0x8002.
+	  See virtio_net.h for a list of offload features and their bit masks.
+	```
+	     "offload":"0x8002"
+	```
+
+* Delay
+
+  key: "delay_main"
+  value type: string
+
+  The delay before calling main() function of the application after the
+  initialization of LKL.  Some subsystems in Linux tree require a certain
+  amount of time before accepting a request from application, such as
+  delivery of address assignment to an network interface.  This parameter
+  is used in such case.  The value is described as a microsecond value.
+```
+     "delay_main":"500000"
+```
+
+FAQ
+===
+
+Q: How is LKL different from UML?
+
+A: UML prodivides a full OS environment (e.g. user/kernel separation, user
+processes) and also has requirements (a filesystem, processes, etc.) that makes
+it hard to use it for standalone applications. UML also relies heavily on Linux
+hosts. On the other hand LKL is designed to be linked directly with the
+application and hence does not have user/kernel separation which makes it easier
+to use it in standalone applications.
+
+
+Q: How is LKL different from LibOS?
+
+A: LibOS re-implements high-level kernel APIs for timers, softirqs, scheduling,
+sysctl, SLAB/SLUB, etc. LKL behaves like any arch port, implementing the arch
+level operations requested by the Linux kernel. LKL also offers a host interface
+so that support for multiple hosts can be implemented.
README.md new file +1 -0
new file mode 120000
index 000000000000..35c47a921f67
@@ -0,0 +1 @@
+Documentation/lkl.txt
\ No newline at end of file
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 31/47 cpu: add cpu_yield_to_irqs

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add a new architecture function that should be called in loops that rely on interrupts to exit the loop (e.g. loops that use a jiffies expression for the exit condition).

This is needed for architectures where interrupts can not preempt the currently running thread (e.g. lkl).

---
 crypto/xor.c        | 2 ++
 include/linux/cpu.h | 1 +
 kernel/cpu.c        | 5 +++++
 lib/raid6/algos.c   | 9 ++++++---
 4 files changed, 14 insertions(+), 3 deletions(-)
crypto/xor.c +2 -0
index ea7349e6ed23..c55a89a9e659 100644
@@ -14,6 +14,7 @@
 #include <linux/raid/xor.h>
 #include <linux/jiffies.h>
 #include <linux/preempt.h>
+#include <linux/cpu.h>
 #include <asm/xor.h>
 
 #ifndef XOR_SELECT_TEMPLATE
@@ -85,6 +86,7 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
 			mb();
 			count++;
 			mb();
+			cpu_yield_to_irqs();
 		}
 		if (count > max)
 			max = count;
include/linux/cpu.h +1 -0
index fcb1386bb0d4..887702d29498 100644
@@ -180,6 +180,7 @@ int cpu_report_state(int cpu);
 int cpu_check_up_prepare(int cpu);
 void cpu_set_state_online(int cpu);
 void play_idle(unsigned long duration_ms);
+void cpu_yield_to_irqs(void);
 
 #ifdef CONFIG_HOTPLUG_CPU
 bool cpu_wait_death(unsigned int cpu, int seconds);
kernel/cpu.c +5 -0
index e84c0873559e..9ca61a55ed0c 100644
@@ -2339,6 +2339,11 @@ void __init boot_cpu_hotplug_init(void)
 	this_cpu_write(cpuhp_state.state, CPUHP_ONLINE);
 }
 
+void __weak cpu_yield_to_irqs(void)
+{
+}
+EXPORT_SYMBOL(cpu_yield_to_irqs);
+
 enum cpu_mitigations cpu_mitigations __ro_after_init = CPU_MITIGATIONS_AUTO;
 
 static int __init mitigations_parse_cmdline(char *arg)
lib/raid6/algos.c +6 -3
index 17417eee0866..7e6121443ebc 100644
@@ -18,6 +18,7 @@
 #else
 #include <linux/module.h>
 #include <linux/gfp.h>
+#include <linux/cpu.h>
 #if !RAID6_USE_EMPTY_ZERO_PAGE
 /* In .bss so it's zeroed */
 const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
@@ -29,7 +30,7 @@ struct raid6_calls raid6_call;
 EXPORT_SYMBOL_GPL(raid6_call);
 
 const struct raid6_calls * const raid6_algos[] = {
-#if defined(__i386__) && !defined(__arch_um__)
+#ifdef CONFIG_X86_32
 #ifdef CONFIG_AS_AVX512
 	&raid6_avx512x2,
 	&raid6_avx512x1,
@@ -45,7 +46,7 @@ const struct raid6_calls * const raid6_algos[] = {
 	&raid6_mmxx2,
 	&raid6_mmxx1,
 #endif
-#if defined(__x86_64__) && !defined(__arch_um__)
+#ifdef CONFIG_X86_64
 #ifdef CONFIG_AS_AVX512
 	&raid6_avx512x4,
 	&raid6_avx512x2,
@@ -79,7 +80,7 @@ const struct raid6_calls * const raid6_algos[] = {
 	&raid6_neonx2,
 	&raid6_neonx1,
 #endif
-#if defined(__ia64__)
+#ifdef CONFIG_IA64
 	&raid6_intx32,
 	&raid6_intx16,
 #endif
@@ -173,6 +174,7 @@ static inline const struct raid6_calls *raid6_choose_gen(
 					    j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
 				(*algo)->gen_syndrome(disks, PAGE_SIZE, *dptrs);
 				perf++;
+				cpu_yield_to_irqs();
 			}
 			preempt_enable();
 
@@ -197,6 +199,7 @@ static inline const struct raid6_calls *raid6_choose_gen(
 				(*algo)->xor_syndrome(disks, start, stop,
 						      PAGE_SIZE, *dptrs);
 				perf++;
+				cpu_yield_to_irqs();
 			}
 			preempt_enable();
 
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 32/47 tools: Add the lkl host library to the common tools Makefile

In reply to Hajime Tazaki

From: Thomas Liebetraut <[email protected]>

This patch includes the lkl host library to the Kernel tools buildsystem. This also means that lkl can now be compiled like any other "tool" using:

  $ make tools/lkl
[Octavian: remove make ARCH=lkl defconfig as it is not (yet) necessary]
---
 tools/Makefile | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
tools/Makefile +6 -5
index 68defd7ecf5d..0506d7dde63f 100644
@@ -23,6 +23,7 @@ help:
 	@echo '  kvm_stat               - top-like utility for displaying kvm statistics'
 	@echo '  leds                   - LEDs  tools'
 	@echo '  liblockdep             - user-space wrapper for kernel locking-validator'
+	@echo '  lkl                    - The Linux Kernel Library host libraries and tools'
 	@echo '  bpf                    - misc BPF tools'
 	@echo '  pci                    - PCI tools'
 	@echo '  perf                   - Linux performance measurement and analysis tool'
@@ -63,7 +64,7 @@ acpi: FORCE
 cpupower: FORCE
 	$(call descend,power/$@)
 
-cgroup firewire hv guest spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging: FORCE
+cgroup firewire hv guest lkl spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging: FORCE
 	$(call descend,$@)
 
 liblockdep: FORCE
@@ -107,7 +108,7 @@ acpi_install:
 cpupower_install:
 	$(call descend,power/$(@:_install=),install)
 
-cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install:
+cgroup_install firewire_install gpio_install hv_install iio_install lkl_install perf_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install:
 	$(call descend,$(@:_install=),install)
 
 liblockdep_install:
@@ -133,7 +134,7 @@ install: acpi_install cgroup_install cpupower_install gpio_install \
 		perf_install selftests_install turbostat_install usb_install \
 		virtio_install vm_install bpf_install x86_energy_perf_policy_install \
 		tmon_install freefall_install objtool_install kvm_stat_install \
-		wmi_install pci_install debugging_install intel-speed-select_install
+		wmi_install lkl_install pci_install debugging_install intel-speed-select_install
 
 acpi_clean:
 	$(call descend,power/acpi,clean)
@@ -141,7 +142,7 @@ acpi_clean:
 cpupower_clean:
 	$(call descend,power/cpupower,clean)
 
-cgroup_clean hv_clean firewire_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean:
+cgroup_clean hv_clean firewire_clean lkl_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean:
 	$(call descend,$(@:_clean=),clean)
 
 liblockdep_clean:
@@ -179,7 +180,7 @@ clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
 		perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \
 		vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
 		freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \
-		gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
+		gpio_clean objtool_clean leds_clean wmi_clean lkl_clean pci_clean firmware_clean debugging_clean \
 		intel-speed-select_clean
 
 .PHONY: FORCE
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 33/47 signal: use CONFIG_X86_32 instead of __i386__

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This allows um/lkl to build/run ?
[XXX: need to check if this requires or not]

---
 kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/signal.c +1 -1
index 534fec266a33..561de0e1e66a 100644
@@ -1241,7 +1241,7 @@ static void print_fatal_signal(int signr)
 	struct pt_regs *regs = signal_pt_regs();
 	pr_info("potentially unexpected fatal signal %d.\n", signr);
 
-#if defined(__i386__) && !defined(__arch_um__)
+#ifdef CONFIG_X86_32
 	pr_info("code at %08lx: ", regs->ip);
 	{
 		int i;
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 34/47 arch: add __SYSCALL_DEFINE_ARCH

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This allows the architecture code to process the system call definitions. It is used by LKL to create strong typed function definitions for system calls.

---
 include/linux/syscalls.h | 6 ++++++
 1 file changed, 6 insertions(+)
include/linux/syscalls.h +6 -0
index 88145da7d140..77e52fe19923 100644
@@ -203,9 +203,14 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
 }
 #endif
 
+#ifndef __SYSCALL_DEFINE_ARCH
+#define __SYSCALL_DEFINE_ARCH(x, sname, ...)
+#endif
+
 #ifndef SYSCALL_DEFINE0
 #define SYSCALL_DEFINE0(sname)					\
 	SYSCALL_METADATA(_##sname, 0);				\
+	__SYSCALL_DEFINE_ARCH(0, _##sname);			\
 	asmlinkage long sys_##sname(void);			\
 	ALLOW_ERROR_INJECTION(sys_##sname, ERRNO);		\
 	asmlinkage long sys_##sname(void)
@@ -222,6 +227,7 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
 
 #define SYSCALL_DEFINEx(x, sname, ...)				\
 	SYSCALL_METADATA(sname, x, __VA_ARGS__)			\
+	__SYSCALL_DEFINE_ARCH(x, sname, __VA_ARGS__)		\
 	__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
 
 #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 35/47 xfs: support for non-mmu architectures

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Naive implementation for non-mmu architectures: allocate physically contiguous xfs buffers with alloc_pages. Terribly inefficient with memory and fragmentation on high I/O loads but it may be good enough for basic usage (which most non-mmu architectures will need).

---
 fs/xfs/xfs_buf.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
fs/xfs/xfs_buf.c +26 -0
index ca0849043f54..c4bb390cc9b0 100644
@@ -313,6 +313,7 @@ xfs_buf_free(
 	ASSERT(list_empty(&bp->b_lru));
 
 	if (bp->b_flags & _XBF_PAGES) {
+#ifdef CONFIG_MMU
 		uint		i;
 
 		if (xfs_buf_is_vmapped(bp))
@@ -324,6 +325,10 @@ xfs_buf_free(
 
 			__free_page(page);
 		}
+#else
+		free_pages((unsigned long)page_to_virt(bp->b_pages[0]),
+			   order_base_2(bp->b_page_count));
+#endif
 	} else if (bp->b_flags & _XBF_KMEM)
 		kmem_free(bp->b_addr);
 	_xfs_buf_free_pages(bp);
@@ -390,7 +395,14 @@ xfs_buf_allocate_memory(
 		struct page	*page;
 		uint		retries = 0;
 retry:
+#ifdef CONFIG_MMU
 		page = alloc_page(gfp_mask);
+#else
+		if (i == 0)
+			page = alloc_pages(gfp_mask, order_base_2(page_count));
+		else
+			page = bp->b_pages[0] + i;
+#endif
 		if (unlikely(page == NULL)) {
 			if (flags & XBF_READ_AHEAD) {
 				bp->b_page_count = i;
@@ -425,8 +437,10 @@ xfs_buf_allocate_memory(
 	return 0;
 
 out_free_pages:
+#ifdef CONFIG_MMU
 	for (i = 0; i < bp->b_page_count; i++)
 		__free_page(bp->b_pages[i]);
+#endif
 	bp->b_flags &= ~_XBF_PAGES;
 	return error;
 }
@@ -446,6 +460,7 @@ _xfs_buf_map_pages(
 	} else if (flags & XBF_UNMAPPED) {
 		bp->b_addr = NULL;
 	} else {
+#ifdef CONFIG_MMU
 		int retried = 0;
 		unsigned nofs_flag;
 
@@ -466,6 +481,9 @@ _xfs_buf_map_pages(
 			vm_unmap_aliases();
 		} while (retried++ <= 1);
 		memalloc_nofs_restore(nofs_flag);
+#else
+		bp->b_addr = page_to_virt(bp->b_pages[0]);
+#endif
 
 		if (!bp->b_addr)
 			return -ENOMEM;
@@ -915,11 +933,19 @@ xfs_buf_get_uncached(
 	if (error)
 		goto fail_free_buf;
 
+#ifdef CONFIG_MMU
 	for (i = 0; i < page_count; i++) {
 		bp->b_pages[i] = alloc_page(xb_to_gfp(flags));
 		if (!bp->b_pages[i])
 			goto fail_free_mem;
 	}
+#else
+	bp->b_pages[0] = alloc_pages(flags, order_base_2(page_count));
+	if (!bp->b_pages[0])
+		goto fail_free_buf;
+	for (i = 1; i < page_count; i++)
+		bp->b_pages[i] = bp->b_pages[i-1] + 1;
+#endif
 	bp->b_flags |= _XBF_PAGES;
 
 	error = _xfs_buf_map_pages(bp, 0);
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 36/47 checkpatch: avoid showing BIT_ULL warnings for tools/ files

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Directly using shift operations in userspace compiled code should not trigger warnings as BIT_ULL macros are not available outside the kernel.

---
 scripts/checkpatch.pl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
scripts/checkpatch.pl +2 -1
index 93a7edfe0f05..e739f565497e 100755
@@ -6313,7 +6313,8 @@ sub process {
 		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
 			my $ull = "";
 			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
-			if (CHK("BIT_MACRO",
+			if ($realfile !~ m@\btools/@ &&
+			    CHK("BIT_MACRO",
 				"Prefer using the BIT$ull macro\n" . $herecurr) &&
 			    $fix) {
 				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 37/47 Revert "vmlinux.lds.h: remove stale <linux/export.h> include"

In reply to Hajime Tazaki

From: Akira Moroo <[email protected]>

This reverts commit 7953002a7c6561c93defd19c81737012ef5a10dc.

---
 include/asm-generic/vmlinux.lds.h | 2 ++
 1 file changed, 2 insertions(+)
include/asm-generic/vmlinux.lds.h +2 -0
index cd28f63bfbc7..8c923ca77d56 100644
@@ -54,6 +54,8 @@
 #define LOAD_OFFSET 0
 #endif
 
+#include <linux/export.h>
+
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 38/47 Revert "export.h: remove code for prefixing symbols with underscore"

In reply to Hajime Tazaki

for lkl, mingw32 requires underscore-ed symbols.

This reverts commit 94e58e0ac31284fa26597c0e00a9b1d87a691d02.

---
 include/asm-generic/export.h | 34 ++++++++++++++++++++++------------
 include/linux/export.h       | 23 ++++++++++++++++++-----
 2 files changed, 40 insertions(+), 17 deletions(-)
include/asm-generic/export.h +22 -12
index 294d6ae785d4..69ce0914b025 100644
@@ -27,32 +27,42 @@
 #endif
 .endm
 
+#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
+#define KSYM(name) _##name
+#else
+#define KSYM(name) name
+#endif
+
 /*
  * note on .section use: @progbits vs %progbits nastiness doesn't matter,
  * since we immediately emit into those sections anyway.
  */
 .macro ___EXPORT_SYMBOL name,val,sec
 #ifdef CONFIG_MODULES
-	.globl __ksymtab_\name
+	.globl KSYM(__ksymtab_\name)
 	.section ___ksymtab\sec+\name,"a"
 	.balign KSYM_ALIGN
-__ksymtab_\name:
-	__put \val, __kstrtab_\name
+KSYM(__ksymtab_\name):
+	__put \val, KSYM(__kstrtab_\name)
 	.previous
 	.section __ksymtab_strings,"a"
-__kstrtab_\name:
+KSYM(__kstrtab_\name):
+#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
+	.asciz "_\name"
+#else
 	.asciz "\name"
+#endif
 	.previous
 #ifdef CONFIG_MODVERSIONS
 	.section ___kcrctab\sec+\name,"a"
 	.balign KCRC_ALIGN
-__kcrctab_\name:
+KSYM(__kcrctab_\name):
 #if defined(CONFIG_MODULE_REL_CRCS)
-	.long __crc_\name - .
+	.long KSYM(__crc_\name) - .
 #else
-	.long __crc_\name
+	.long KSYM(__crc_\name)
 #endif
-	.weak __crc_\name
+	.weak KSYM(__crc_\name)
 	.previous
 #endif
 #endif
@@ -85,12 +95,12 @@ __ksym_marker_\sym:
 #endif
 
 #define EXPORT_SYMBOL(name)					\
-	__EXPORT_SYMBOL(name, KSYM_FUNC(name),)
+	__EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)),)
 #define EXPORT_SYMBOL_GPL(name) 				\
-	__EXPORT_SYMBOL(name, KSYM_FUNC(name), _gpl)
+	__EXPORT_SYMBOL(name, KSYM_FUNC(KSYM(name)), _gpl)
 #define EXPORT_DATA_SYMBOL(name)				\
-	__EXPORT_SYMBOL(name, name,)
+	__EXPORT_SYMBOL(name, KSYM(name),)
 #define EXPORT_DATA_SYMBOL_GPL(name)				\
-	__EXPORT_SYMBOL(name, name,_gpl)
+	__EXPORT_SYMBOL(name, KSYM(name),_gpl)
 
 #endif
include/linux/export.h +18 -5
index fd8711ed9ac4..34c34d09103c 100644
@@ -10,6 +10,19 @@
  * hackers place grumpy comments in header files.
  */
 
+/* Some toolchains use a `_' prefix for all user symbols. */
+#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
+#define __VMLINUX_SYMBOL(x) _##x
+#define __VMLINUX_SYMBOL_STR(x) "_" #x
+#else
+#define __VMLINUX_SYMBOL(x) x
+#define __VMLINUX_SYMBOL_STR(x) #x
+#endif
+
+/* Indirect, so macros are expanded before pasting. */
+#define VMLINUX_SYMBOL(x) __VMLINUX_SYMBOL(x)
+#define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x)
+
 #ifndef __ASSEMBLY__
 #ifdef MODULE
 extern struct module __this_module;
@@ -27,14 +40,14 @@ extern struct module __this_module;
 #if defined(CONFIG_MODULE_REL_CRCS)
 #define __CRC_SYMBOL(sym, sec)						\
 	asm("	.section \"___kcrctab" sec "+" #sym "\", \"a\"	\n"	\
-	    "	.weak	__crc_" #sym "				\n"	\
-	    "	.long	__crc_" #sym " - .			\n"	\
+	    "	.weak	" VMLINUX_SYMBOL_STR(__crc_##sym) "	\n"	\
+	    "	.long	" VMLINUX_SYMBOL_STR(__crc_##sym) " - .	\n"	\
 	    "	.previous					\n");
 #else
 #define __CRC_SYMBOL(sym, sec)						\
 	asm("	.section \"___kcrctab" sec "+" #sym "\", \"a\"	\n"	\
-	    "	.weak	__crc_" #sym "				\n"	\
-	    "	.long	__crc_" #sym "				\n"	\
+	    "	.weak	" VMLINUX_SYMBOL_STR(__crc_##sym) "	\n"	\
+	    "	.long	" VMLINUX_SYMBOL_STR(__crc_##sym) "	\n"	\
 	    "	.previous					\n");
 #endif
 #else
@@ -80,7 +93,7 @@ struct kernel_symbol {
 	__CRC_SYMBOL(sym, sec)						\
 	static const char __kstrtab_##sym[]				\
 	__attribute__((section("__ksymtab_strings"), used, aligned(1)))	\
-	= #sym;								\
+	= VMLINUX_SYMBOL_STR(#sym);					\
 	__KSYMTAB_ENTRY(sym, sec)
 
 #if defined(__DISABLE_EXPORTS)
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 39/47 Revert "linux/linkage.h: replace VMLINUX_SYMBOL_STR() with __stringify()"

In reply to Hajime Tazaki

for lkl, mingw32 requires underscore-ed symbols.

This reverts commit 00979ce4fcc90d488c7f27f750097adc6b11bd07.

---
 include/linux/linkage.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
include/linux/linkage.h +6 -6
index 7e020782ade2..d287823ee947 100644
@@ -24,16 +24,16 @@
 
 #ifndef cond_syscall
 #define cond_syscall(x)	asm(				\
-	".weak " __stringify(x) "\n\t"			\
-	".set  " __stringify(x) ","			\
-		 __stringify(sys_ni_syscall))
+	".weak " VMLINUX_SYMBOL_STR(x) "\n\t"		\
+	".set  " VMLINUX_SYMBOL_STR(x) ","		\
+		 VMLINUX_SYMBOL_STR(sys_ni_syscall))
 #endif
 
 #ifndef SYSCALL_ALIAS
 #define SYSCALL_ALIAS(alias, name) asm(			\
-	".globl " __stringify(alias) "\n\t"		\
-	".set   " __stringify(alias) ","		\
-		  __stringify(name))
+	".globl " VMLINUX_SYMBOL_STR(alias) "\n\t"	\
+	".set   " VMLINUX_SYMBOL_STR(alias) ","		\
+		  VMLINUX_SYMBOL_STR(name))
 #endif
 
 #define __page_aligned_data	__section(.data..page_aligned) __aligned(PAGE_SIZE)
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 40/47 Revert "vmlinux.lds.h: remove no-op macro VMLINUX_SYMBOL()"

In reply to Hajime Tazaki

for lkl, mingw32 requires underscore-ed symbols.

This reverts commit a6214385005333202c8cc1744c7075a9e1a26b9a.

---
 include/asm-generic/vmlinux.lds.h | 291 +++++++++++++++---------------
 1 file changed, 146 insertions(+), 145 deletions(-)
include/asm-generic/vmlinux.lds.h +146 -145
index 8c923ca77d56..e5cbf009bc31 100644
@@ -119,67 +119,67 @@
 			__stop_mcount_loc = .;
 #else
 #define MCOUNT_REC()	. = ALIGN(8);				\
-			__start_mcount_loc = .;			\
+			VMLINUX_SYMBOL(__start_mcount_loc) = .; \
 			KEEP(*(__mcount_loc))			\
-			__stop_mcount_loc = .;
+			VMLINUX_SYMBOL(__stop_mcount_loc) = .;
 #endif
 #else
 #define MCOUNT_REC()
 #endif
 
 #ifdef CONFIG_TRACE_BRANCH_PROFILING
-#define LIKELY_PROFILE()	__start_annotated_branch_profile = .;	\
-				KEEP(*(_ftrace_annotated_branch))	\
-				__stop_annotated_branch_profile = .;
+#define LIKELY_PROFILE()	VMLINUX_SYMBOL(__start_annotated_branch_profile) = .; \
+				*(_ftrace_annotated_branch)			      \
+				VMLINUX_SYMBOL(__stop_annotated_branch_profile) = .;
 #else
 #define LIKELY_PROFILE()
 #endif
 
 #ifdef CONFIG_PROFILE_ALL_BRANCHES
-#define BRANCH_PROFILE()	__start_branch_profile = .;		\
-				KEEP(*(_ftrace_branch))			\
-				__stop_branch_profile = .;
+#define BRANCH_PROFILE()	VMLINUX_SYMBOL(__start_branch_profile) = .;   \
+				*(_ftrace_branch)			      \
+				VMLINUX_SYMBOL(__stop_branch_profile) = .;
 #else
 #define BRANCH_PROFILE()
 #endif
 
 #ifdef CONFIG_KPROBES
 #define KPROBE_BLACKLIST()	. = ALIGN(8);				      \
-				__start_kprobe_blacklist = .;		      \
+				VMLINUX_SYMBOL(__start_kprobe_blacklist) = .; \
 				KEEP(*(_kprobe_blacklist))		      \
-				__stop_kprobe_blacklist = .;
+				VMLINUX_SYMBOL(__stop_kprobe_blacklist) = .;
 #else
 #define KPROBE_BLACKLIST()
 #endif
 
 #ifdef CONFIG_FUNCTION_ERROR_INJECTION
 #define ERROR_INJECT_WHITELIST()	STRUCT_ALIGN();			      \
-			__start_error_injection_whitelist = .;		      \
+			VMLINUX_SYMBOL(__start_error_injection_whitelist) = .;\
 			KEEP(*(_error_injection_whitelist))		      \
-			__stop_error_injection_whitelist = .;
+			VMLINUX_SYMBOL(__stop_error_injection_whitelist) = .;
 #else
 #define ERROR_INJECT_WHITELIST()
 #endif
 
 #ifdef CONFIG_EVENT_TRACING
 #define FTRACE_EVENTS()	. = ALIGN(8);					\
-			__start_ftrace_events = .;			\
+			VMLINUX_SYMBOL(__start_ftrace_events) = .;	\
 			KEEP(*(_ftrace_events))				\
-			__stop_ftrace_events = .;			\
-			__start_ftrace_eval_maps = .;			\
+			VMLINUX_SYMBOL(__stop_ftrace_events) = .;	\
+			VMLINUX_SYMBOL(__start_ftrace_eval_maps) = .;	\
 			KEEP(*(_ftrace_eval_map))			\
-			__stop_ftrace_eval_maps = .;
+			VMLINUX_SYMBOL(__stop_ftrace_eval_maps) = .;
 #else
 #define FTRACE_EVENTS()
 #endif
 
 #ifdef CONFIG_TRACING
-#define TRACE_PRINTKS()	 __start___trace_bprintk_fmt = .;      \
+#define TRACE_PRINTKS() VMLINUX_SYMBOL(__start___trace_bprintk_fmt) = .;      \
 			 KEEP(*(__trace_printk_fmt)) /* Trace_printk fmt' pointer */ \
-			 __stop___trace_bprintk_fmt = .;
-#define TRACEPOINT_STR() __start___tracepoint_str = .;	\
+			 VMLINUX_SYMBOL(__stop___trace_bprintk_fmt) = .;
+#define TRACEPOINT_STR() VMLINUX_SYMBOL(__start___tracepoint_str) = .;	\
 			 KEEP(*(__tracepoint_str)) /* Trace_printk fmt' pointer */ \
-			 __stop___tracepoint_str = .;
+			 VMLINUX_SYMBOL(__stop___tracepoint_str) = .;
 #else
 #define TRACE_PRINTKS()
 #define TRACEPOINT_STR()
@@ -187,27 +187,27 @@
 
 #ifdef CONFIG_FTRACE_SYSCALLS
 #define TRACE_SYSCALLS() . = ALIGN(8);					\
-			 __start_syscalls_metadata = .;			\
+			 VMLINUX_SYMBOL(__start_syscalls_metadata) = .;	\
 			 KEEP(*(__syscalls_metadata))			\
-			 __stop_syscalls_metadata = .;
+			 VMLINUX_SYMBOL(__stop_syscalls_metadata) = .;
 #else
 #define TRACE_SYSCALLS()
 #endif
 
 #ifdef CONFIG_BPF_EVENTS
 #define BPF_RAW_TP() STRUCT_ALIGN();					\
-			 __start__bpf_raw_tp = .;			\
+			 VMLINUX_SYMBOL(__start__bpf_raw_tp) = .;	\
 			 KEEP(*(__bpf_raw_tp_map))			\
-			 __stop__bpf_raw_tp = .;
+			 VMLINUX_SYMBOL(__stop__bpf_raw_tp) = .;
 #else
 #define BPF_RAW_TP()
 #endif
 
 #ifdef CONFIG_SERIAL_EARLYCON
 #define EARLYCON_TABLE() . = ALIGN(8);				\
-			 __earlycon_table = .;			\
+			 VMLINUX_SYMBOL(__earlycon_table) = .;	\
 			 KEEP(*(__earlycon_table))		\
-			 __earlycon_table_end = .;
+			 VMLINUX_SYMBOL(__earlycon_table_end) = .;
 #else
 #define EARLYCON_TABLE()
 #endif
@@ -227,7 +227,7 @@
 #define _OF_TABLE_0(name)
 #define _OF_TABLE_1(name)						\
 	. = ALIGN(8);							\
-	__##name##_of_table = .;					\
+	VMLINUX_SYMBOL(__##name##_of_table) = .;			\
 	KEEP(*(__##name##_of_table))					\
 	KEEP(*(__##name##_of_table_end))
 
@@ -241,9 +241,9 @@
 #ifdef CONFIG_ACPI
 #define ACPI_PROBE_TABLE(name)						\
 	. = ALIGN(8);							\
-	__##name##_acpi_probe_table = .;				\
+	VMLINUX_SYMBOL(__##name##_acpi_probe_table) = .;		\
 	KEEP(*(__##name##_acpi_probe_table))				\
-	__##name##_acpi_probe_table_end = .;
+	VMLINUX_SYMBOL(__##name##_acpi_probe_table_end) = .;
 #else
 #define ACPI_PROBE_TABLE(name)
 #endif
@@ -260,9 +260,9 @@
 
 #define KERNEL_DTB()							\
 	STRUCT_ALIGN();							\
-	__dtb_start = .;						\
+	VMLINUX_SYMBOL(__dtb_start) = .;				\
 	KEEP(*(.dtb.init.rodata))					\
-	__dtb_end = .;
+	VMLINUX_SYMBOL(__dtb_end) = .;
 
 /*
  * .data section
@@ -275,16 +275,16 @@
 	MEM_KEEP(init.data*)						\
 	MEM_KEEP(exit.data*)						\
 	*(.data.unlikely)						\
-	__start_once = .;						\
+	VMLINUX_SYMBOL(__start_once) = .;				\
 	*(.data.once)							\
-	__end_once = .;							\
+	VMLINUX_SYMBOL(__end_once) = .;					\
 	STRUCT_ALIGN();							\
 	*(__tracepoints)						\
 	/* implement dynamic printk debug */				\
 	. = ALIGN(8);							\
-	__start___verbose = .;						\
+	VMLINUX_SYMBOL(__start___verbose) = .;                          \
 	KEEP(*(__verbose))                                              \
-	__stop___verbose = .;						\
+	VMLINUX_SYMBOL(__stop___verbose) = .;				\
 	LIKELY_PROFILE()		       				\
 	BRANCH_PROFILE()						\
 	TRACE_PRINTKS()							\
@@ -296,10 +296,10 @@
  */
 #define NOSAVE_DATA							\
 	. = ALIGN(PAGE_SIZE);						\
-	__nosave_begin = .;						\
+	VMLINUX_SYMBOL(__nosave_begin) = .;				\
 	*(.data..nosave)						\
 	. = ALIGN(PAGE_SIZE);						\
-	__nosave_end = .;
+	VMLINUX_SYMBOL(__nosave_end) = .;
 
 #define PAGE_ALIGNED_DATA(page_align)					\
 	. = ALIGN(page_align);						\
@@ -316,19 +316,19 @@
 
 #define INIT_TASK_DATA(align)						\
 	. = ALIGN(align);						\
-	__start_init_task = .;						\
-	init_thread_union = .;						\
-	init_stack = .;							\
-	KEEP(*(.data..init_task))					\
-	KEEP(*(.data..init_thread_info))				\
-	. = __start_init_task + THREAD_SIZE;				\
-	__end_init_task = .;
+	VMLINUX_SYMBOL(__start_init_task) = .;				\
+	VMLINUX_SYMBOL(init_thread_union) = .;				\
+	VMLINUX_SYMBOL(init_stack) = .;					\
+	*(.data..init_task)						\
+	*(.data..init_thread_info)					\
+	. = VMLINUX_SYMBOL(__start_init_task) + THREAD_SIZE;		\
+	VMLINUX_SYMBOL(__end_init_task) = .;
 
 #define JUMP_TABLE_DATA							\
 	. = ALIGN(8);							\
-	__start___jump_table = .;					\
+	VMLINUX_SYMBOL(__start___jump_table) = .;                       \
 	KEEP(*(__jump_table))						\
-	__stop___jump_table = .;
+	VMLINUX_SYMBOL(__stop___jump_table) = .;
 
 /*
  * Allow architectures to handle ro_after_init data on their
@@ -336,10 +336,10 @@
  */
 #ifndef RO_AFTER_INIT_DATA
 #define RO_AFTER_INIT_DATA						\
-	__start_ro_after_init = .;					\
+	VMLINUX_SYMBOL(__start_ro_after_init) = .;			\
 	*(.data..ro_after_init)						\
 	JUMP_TABLE_DATA							\
-	__end_ro_after_init = .;
+	VMLINUX_SYMBOL(__end_ro_after_init) = .;
 #endif
 
 /*
@@ -347,14 +347,14 @@
  */
 #define RO_DATA_SECTION(align)						\
 	. = ALIGN((align));						\
-	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
-		__start_rodata = .;					\
-		*(.rodata) *(.rodata.*)					\
+	RODATA_SECTION    : AT(ADDR(RODATA_SECTION) - LOAD_OFFSET) {	\
+		VMLINUX_SYMBOL(__start_rodata) = .;			\
+		*(RODATA_SECTION) *(RODATA_SECTION.*)			\
 		RO_AFTER_INIT_DATA	/* Read only after init */	\
 		. = ALIGN(8);						\
-		__start___tracepoints_ptrs = .;				\
+		VMLINUX_SYMBOL(__start___tracepoints_ptrs) = .;		\
 		KEEP(*(__tracepoints_ptrs)) /* Tracepoints: pointer array */ \
-		__stop___tracepoints_ptrs = .;				\
+		VMLINUX_SYMBOL(__stop___tracepoints_ptrs) = .;		\
 		*(__tracepoints_strings)/* Tracepoints: strings */	\
 	}								\
 									\
@@ -364,109 +364,109 @@
 									\
 	/* PCI quirks */						\
 	.pci_fixup        : AT(ADDR(.pci_fixup) - LOAD_OFFSET) {	\
-		__start_pci_fixups_early = .;				\
+		VMLINUX_SYMBOL(__start_pci_fixups_early) = .;		\
 		KEEP(*(.pci_fixup_early))				\
-		__end_pci_fixups_early = .;				\
-		__start_pci_fixups_header = .;				\
+		VMLINUX_SYMBOL(__end_pci_fixups_early) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_header) = .;		\
 		KEEP(*(.pci_fixup_header))				\
-		__end_pci_fixups_header = .;				\
-		__start_pci_fixups_final = .;				\
+		VMLINUX_SYMBOL(__end_pci_fixups_header) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_final) = .;		\
 		KEEP(*(.pci_fixup_final))				\
-		__end_pci_fixups_final = .;				\
-		__start_pci_fixups_enable = .;				\
+		VMLINUX_SYMBOL(__end_pci_fixups_final) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_enable) = .;		\
 		KEEP(*(.pci_fixup_enable))				\
-		__end_pci_fixups_enable = .;				\
-		__start_pci_fixups_resume = .;				\
+		VMLINUX_SYMBOL(__end_pci_fixups_enable) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_resume) = .;		\
 		KEEP(*(.pci_fixup_resume))				\
-		__end_pci_fixups_resume = .;				\
-		__start_pci_fixups_resume_early = .;			\
+		VMLINUX_SYMBOL(__end_pci_fixups_resume) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_resume_early) = .;	\
 		KEEP(*(.pci_fixup_resume_early))			\
-		__end_pci_fixups_resume_early = .;			\
-		__start_pci_fixups_suspend = .;				\
+		VMLINUX_SYMBOL(__end_pci_fixups_resume_early) = .;	\
+		VMLINUX_SYMBOL(__start_pci_fixups_suspend) = .;		\
 		KEEP(*(.pci_fixup_suspend))				\
-		__end_pci_fixups_suspend = .;				\
-		__start_pci_fixups_suspend_late = .;			\
+		VMLINUX_SYMBOL(__end_pci_fixups_suspend) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_suspend_late) = .;	\
 		KEEP(*(.pci_fixup_suspend_late))			\
-		__end_pci_fixups_suspend_late = .;			\
+		VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .;	\
 	}								\
 									\
 	/* Built-in firmware blobs */					\
 	.builtin_fw        : AT(ADDR(.builtin_fw) - LOAD_OFFSET) {	\
-		__start_builtin_fw = .;					\
+		VMLINUX_SYMBOL(__start_builtin_fw) = .;			\
 		KEEP(*(.builtin_fw))					\
-		__end_builtin_fw = .;					\
+		VMLINUX_SYMBOL(__end_builtin_fw) = .;			\
 	}								\
 									\
 	TRACEDATA							\
 									\
 	/* Kernel symbol table: Normal symbols */			\
 	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
-		__start___ksymtab = .;					\
+		VMLINUX_SYMBOL(__start___ksymtab) = .;			\
 		KEEP(*(SORT(___ksymtab+*)))				\
-		__stop___ksymtab = .;					\
+		VMLINUX_SYMBOL(__stop___ksymtab) = .;			\
 	}								\
 									\
 	/* Kernel symbol table: GPL-only symbols */			\
 	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {	\
-		__start___ksymtab_gpl = .;				\
+		VMLINUX_SYMBOL(__start___ksymtab_gpl) = .;		\
 		KEEP(*(SORT(___ksymtab_gpl+*)))				\
-		__stop___ksymtab_gpl = .;				\
+		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\
 	}								\
 									\
 	/* Kernel symbol table: Normal unused symbols */		\
 	__ksymtab_unused  : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) {	\
-		__start___ksymtab_unused = .;				\
+		VMLINUX_SYMBOL(__start___ksymtab_unused) = .;		\
 		KEEP(*(SORT(___ksymtab_unused+*)))			\
-		__stop___ksymtab_unused = .;				\
+		VMLINUX_SYMBOL(__stop___ksymtab_unused) = .;		\
 	}								\
 									\
 	/* Kernel symbol table: GPL-only unused symbols */		\
 	__ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \
-		__start___ksymtab_unused_gpl = .;			\
+		VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .;	\
 		KEEP(*(SORT(___ksymtab_unused_gpl+*)))			\
-		__stop___ksymtab_unused_gpl = .;			\
+		VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .;	\
 	}								\
 									\
 	/* Kernel symbol table: GPL-future-only symbols */		\
 	__ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
-		__start___ksymtab_gpl_future = .;			\
+		VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .;	\
 		KEEP(*(SORT(___ksymtab_gpl_future+*)))			\
-		__stop___ksymtab_gpl_future = .;			\
+		VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .;	\
 	}								\
 									\
 	/* Kernel symbol table: Normal symbols */			\
 	__kcrctab         : AT(ADDR(__kcrctab) - LOAD_OFFSET) {		\
-		__start___kcrctab = .;					\
+		VMLINUX_SYMBOL(__start___kcrctab) = .;			\
 		KEEP(*(SORT(___kcrctab+*)))				\
-		__stop___kcrctab = .;					\
+		VMLINUX_SYMBOL(__stop___kcrctab) = .;			\
 	}								\
 									\
 	/* Kernel symbol table: GPL-only symbols */			\
 	__kcrctab_gpl     : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) {	\
-		__start___kcrctab_gpl = .;				\
+		VMLINUX_SYMBOL(__start___kcrctab_gpl) = .;		\
 		KEEP(*(SORT(___kcrctab_gpl+*)))				\
-		__stop___kcrctab_gpl = .;				\
+		VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .;		\
 	}								\
 									\
 	/* Kernel symbol table: Normal unused symbols */		\
 	__kcrctab_unused  : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) {	\
-		__start___kcrctab_unused = .;				\
+		VMLINUX_SYMBOL(__start___kcrctab_unused) = .;		\
 		KEEP(*(SORT(___kcrctab_unused+*)))			\
-		__stop___kcrctab_unused = .;				\
+		VMLINUX_SYMBOL(__stop___kcrctab_unused) = .;		\
 	}								\
 									\
 	/* Kernel symbol table: GPL-only unused symbols */		\
 	__kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \
-		__start___kcrctab_unused_gpl = .;			\
+		VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .;	\
 		KEEP(*(SORT(___kcrctab_unused_gpl+*)))			\
-		__stop___kcrctab_unused_gpl = .;			\
+		VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .;	\
 	}								\
 									\
 	/* Kernel symbol table: GPL-future-only symbols */		\
 	__kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
-		__start___kcrctab_gpl_future = .;			\
+		VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .;	\
 		KEEP(*(SORT(___kcrctab_gpl_future+*)))			\
-		__stop___kcrctab_gpl_future = .;			\
+		VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .;	\
 	}								\
 									\
 	/* Kernel symbol table: strings */				\
@@ -483,18 +483,18 @@
 									\
 	/* Built-in module parameters. */				\
 	__param : AT(ADDR(__param) - LOAD_OFFSET) {			\
-		__start___param = .;					\
+		VMLINUX_SYMBOL(__start___param) = .;			\
 		KEEP(*(__param))					\
-		__stop___param = .;					\
+		VMLINUX_SYMBOL(__stop___param) = .;			\
 	}								\
 									\
 	/* Built-in module versions. */					\
 	__modver : AT(ADDR(__modver) - LOAD_OFFSET) {			\
-		__start___modver = .;					\
+		VMLINUX_SYMBOL(__start___modver) = .;			\
 		KEEP(*(__modver))					\
-		__stop___modver = .;					\
+		VMLINUX_SYMBOL(__stop___modver) = .;			\
 		. = ALIGN((align));					\
-		__end_rodata = .;					\
+		VMLINUX_SYMBOL(__end_rodata) = .;			\
 	}								\
 	. = ALIGN((align));
 
@@ -524,47 +524,47 @@
  * address even at second ld pass when generating System.map */
 #define SCHED_TEXT							\
 		ALIGN_FUNCTION();					\
-		__sched_text_start = .;					\
+		VMLINUX_SYMBOL(__sched_text_start) = .;			\
 		*(.sched.text)						\
-		__sched_text_end = .;
+		VMLINUX_SYMBOL(__sched_text_end) = .;
 
 /* spinlock.text is aling to function alignment to secure we have same
  * address even at second ld pass when generating System.map */
 #define LOCK_TEXT							\
 		ALIGN_FUNCTION();					\
-		__lock_text_start = .;					\
+		VMLINUX_SYMBOL(__lock_text_start) = .;			\
 		*(.spinlock.text)					\
-		__lock_text_end = .;
+		VMLINUX_SYMBOL(__lock_text_end) = .;
 
 #define CPUIDLE_TEXT							\
 		ALIGN_FUNCTION();					\
-		__cpuidle_text_start = .;				\
+		VMLINUX_SYMBOL(__cpuidle_text_start) = .;		\
 		*(.cpuidle.text)					\
-		__cpuidle_text_end = .;
+		VMLINUX_SYMBOL(__cpuidle_text_end) = .;
 
 #define KPROBES_TEXT							\
 		ALIGN_FUNCTION();					\
-		__kprobes_text_start = .;				\
+		VMLINUX_SYMBOL(__kprobes_text_start) = .;		\
 		*(.kprobes.text)					\
-		__kprobes_text_end = .;
+		VMLINUX_SYMBOL(__kprobes_text_end) = .;
 
 #define ENTRY_TEXT							\
 		ALIGN_FUNCTION();					\
-		__entry_text_start = .;					\
+		VMLINUX_SYMBOL(__entry_text_start) = .;			\
 		*(.entry.text)						\
-		__entry_text_end = .;
+		VMLINUX_SYMBOL(__entry_text_end) = .;
 
 #define IRQENTRY_TEXT							\
 		ALIGN_FUNCTION();					\
-		__irqentry_text_start = .;				\
+		VMLINUX_SYMBOL(__irqentry_text_start) = .;		\
 		*(.irqentry.text)					\
-		__irqentry_text_end = .;
+		VMLINUX_SYMBOL(__irqentry_text_end) = .;
 
 #define SOFTIRQENTRY_TEXT						\
 		ALIGN_FUNCTION();					\
-		__softirqentry_text_start = .;				\
+		VMLINUX_SYMBOL(__softirqentry_text_start) = .;		\
 		*(.softirqentry.text)					\
-		__softirqentry_text_end = .;
+		VMLINUX_SYMBOL(__softirqentry_text_end) = .;
 
 /* Section used for early init (in .S files) */
 #define HEAD_TEXT  KEEP(*(.head.text))
@@ -580,9 +580,9 @@
 #define EXCEPTION_TABLE(align)						\
 	. = ALIGN(align);						\
 	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {		\
-		__start___ex_table = .;					\
+		VMLINUX_SYMBOL(__start___ex_table) = .;			\
 		KEEP(*(__ex_table))					\
-		__stop___ex_table = .;					\
+		VMLINUX_SYMBOL(__stop___ex_table) = .;			\
 	}
 
 /*
@@ -596,11 +596,11 @@
 
 #ifdef CONFIG_CONSTRUCTORS
 #define KERNEL_CTORS()	. = ALIGN(8);			   \
-			__ctors_start = .;		   \
+			VMLINUX_SYMBOL(__ctors_start) = .; \
 			KEEP(*(.ctors))			   \
 			KEEP(*(SORT(.init_array.*)))	   \
 			KEEP(*(.init_array))		   \
-			__ctors_end = .;
+			VMLINUX_SYMBOL(__ctors_end) = .;
 #else
 #define KERNEL_CTORS()
 #endif
@@ -736,9 +736,9 @@
 #define BUG_TABLE							\
 	. = ALIGN(8);							\
 	__bug_table : AT(ADDR(__bug_table) - LOAD_OFFSET) {		\
-		__start___bug_table = .;				\
+		VMLINUX_SYMBOL(__start___bug_table) = .;		\
 		KEEP(*(__bug_table))					\
-		__stop___bug_table = .;					\
+		VMLINUX_SYMBOL(__stop___bug_table) = .;			\
 	}
 #else
 #define BUG_TABLE
@@ -748,22 +748,22 @@
 #define ORC_UNWIND_TABLE						\
 	. = ALIGN(4);							\
 	.orc_unwind_ip : AT(ADDR(.orc_unwind_ip) - LOAD_OFFSET) {	\
-		__start_orc_unwind_ip = .;				\
+		VMLINUX_SYMBOL(__start_orc_unwind_ip) = .;		\
 		KEEP(*(.orc_unwind_ip))					\
-		__stop_orc_unwind_ip = .;				\
+		VMLINUX_SYMBOL(__stop_orc_unwind_ip) = .;		\
 	}								\
 	. = ALIGN(2);							\
 	.orc_unwind : AT(ADDR(.orc_unwind) - LOAD_OFFSET) {		\
-		__start_orc_unwind = .;					\
+		VMLINUX_SYMBOL(__start_orc_unwind) = .;			\
 		KEEP(*(.orc_unwind))					\
-		__stop_orc_unwind = .;					\
+		VMLINUX_SYMBOL(__stop_orc_unwind) = .;			\
 	}								\
 	. = ALIGN(4);							\
 	.orc_lookup : AT(ADDR(.orc_lookup) - LOAD_OFFSET) {		\
-		orc_lookup = .;						\
+		VMLINUX_SYMBOL(orc_lookup) = .;				\
 		. += (((SIZEOF(.text) + LOOKUP_BLOCK_SIZE - 1) /	\
 			LOOKUP_BLOCK_SIZE) + 1) * 4;			\
-		orc_lookup_end = .;					\
+		VMLINUX_SYMBOL(orc_lookup_end) = .;			\
 	}
 #else
 #define ORC_UNWIND_TABLE
@@ -773,9 +773,9 @@
 #define TRACEDATA							\
 	. = ALIGN(4);							\
 	.tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {		\
-		__tracedata_start = .;					\
+		VMLINUX_SYMBOL(__tracedata_start) = .;			\
 		KEEP(*(.tracedata))					\
-		__tracedata_end = .;					\
+		VMLINUX_SYMBOL(__tracedata_end) = .;			\
 	}
 #else
 #define TRACEDATA
@@ -783,24 +783,24 @@
 
 #define NOTES								\
 	.notes : AT(ADDR(.notes) - LOAD_OFFSET) {			\
-		__start_notes = .;					\
-		KEEP(*(.note.*))					\
-		__stop_notes = .;					\
+		VMLINUX_SYMBOL(__start_notes) = .;			\
+		*(.note.*)						\
+		VMLINUX_SYMBOL(__stop_notes) = .;			\
 	}
 
 #define INIT_SETUP(initsetup_align)					\
 		. = ALIGN(initsetup_align);				\
-		__setup_start = .;					\
+		VMLINUX_SYMBOL(__setup_start) = .;			\
 		KEEP(*(.init.setup))					\
-		__setup_end = .;
+		VMLINUX_SYMBOL(__setup_end) = .;
 
 #define INIT_CALLS_LEVEL(level)						\
-		__initcall##level##_start = .;				\
+		VMLINUX_SYMBOL(__initcall##level##_start) = .;		\
 		KEEP(*(.initcall##level##.init))			\
 		KEEP(*(.initcall##level##s.init))			\
 
 #define INIT_CALLS							\
-		__initcall_start = .;					\
+		VMLINUX_SYMBOL(__initcall_start) = .;			\
 		KEEP(*(.initcallearly.init))				\
 		INIT_CALLS_LEVEL(0)					\
 		INIT_CALLS_LEVEL(1)					\
@@ -811,17 +811,17 @@
 		INIT_CALLS_LEVEL(rootfs)				\
 		INIT_CALLS_LEVEL(6)					\
 		INIT_CALLS_LEVEL(7)					\
-		__initcall_end = .;
+		VMLINUX_SYMBOL(__initcall_end) = .;
 
 #define CON_INITCALL							\
-		__con_initcall_start = .;				\
+		VMLINUX_SYMBOL(__con_initcall_start) = .;		\
 		KEEP(*(.con_initcall.init))				\
-		__con_initcall_end = .;
+		VMLINUX_SYMBOL(__con_initcall_end) = .;
 
 #ifdef CONFIG_BLK_DEV_INITRD
 #define INIT_RAM_FS							\
 	. = ALIGN(4);							\
-	__initramfs_start = .;						\
+	VMLINUX_SYMBOL(__initramfs_start) = .;				\
 	KEEP(*(.init.ramfs))						\
 	. = ALIGN(8);							\
 	KEEP(*(.init.ramfs.info))
@@ -877,7 +877,7 @@
  * sharing between subsections for different purposes.
  */
 #define PERCPU_INPUT(cacheline)						\
-	__per_cpu_start = .;						\
+	VMLINUX_SYMBOL(__per_cpu_start) = .;				\
 	*(.data..percpu..first)						\
 	. = ALIGN(PAGE_SIZE);						\
 	*(.data..percpu..page_aligned)					\
@@ -887,7 +887,7 @@
 	*(.data..percpu)						\
 	*(.data..percpu..shared_aligned)				\
 	PERCPU_DECRYPTED_SECTION					\
-	__per_cpu_end = .;
+	VMLINUX_SYMBOL(__per_cpu_end) = .;
 
 /**
  * PERCPU_VADDR - define output section for percpu area
@@ -914,11 +914,12 @@
  * address, use PERCPU_SECTION.
  */
 #define PERCPU_VADDR(cacheline, vaddr, phdr)				\
-	__per_cpu_load = .;						\
-	.data..percpu vaddr : AT(__per_cpu_load - LOAD_OFFSET) {	\
+	VMLINUX_SYMBOL(__per_cpu_load) = .;				\
+	.data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load)		\
+				- LOAD_OFFSET) {			\
 		PERCPU_INPUT(cacheline)					\
 	} phdr								\
-	. = __per_cpu_load + SIZEOF(.data..percpu);
+	. = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu);
 
 /**
  * PERCPU_SECTION - define output section for percpu area, simple version
@@ -935,7 +936,7 @@
 #define PERCPU_SECTION(cacheline)					\
 	. = ALIGN(PAGE_SIZE);						\
 	.data..percpu	: AT(ADDR(.data..percpu) - LOAD_OFFSET) {	\
-		__per_cpu_load = .;					\
+		VMLINUX_SYMBOL(__per_cpu_load) = .;			\
 		PERCPU_INPUT(cacheline)					\
 	}
 
@@ -974,9 +975,9 @@
 #define INIT_TEXT_SECTION(inittext_align)				\
 	. = ALIGN(inittext_align);					\
 	.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {		\
-		_sinittext = .;						\
+		VMLINUX_SYMBOL(_sinittext) = .;				\
 		INIT_TEXT						\
-		_einittext = .;						\
+		VMLINUX_SYMBOL(_einittext) = .;				\
 	}
 
 #define INIT_DATA_SECTION(initsetup_align)				\
@@ -990,8 +991,8 @@
 
 #define BSS_SECTION(sbss_align, bss_align, stop_align)			\
 	. = ALIGN(sbss_align);						\
-	__bss_start = .;						\
+	VMLINUX_SYMBOL(__bss_start) = .;				\
 	SBSS(sbss_align)						\
 	BSS(bss_align)							\
 	. = ALIGN(stop_align);						\
-	__bss_stop = .;
+	VMLINUX_SYMBOL(__bss_stop) = .;
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 41/47 Revert "kbuild: remove CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX"

In reply to Hajime Tazaki

This reverts commit 704db5433fb43acbf1486303721bd0cbb65af251.

for lkl, mingw32 requires underscore-ed symbols.

---
 arch/Kconfig                | 6 ++++++
 scripts/Makefile.build      | 7 ++++++-
 scripts/adjust_autoksyms.sh | 7 ++++++-
 3 files changed, 18 insertions(+), 2 deletions(-)
arch/Kconfig +6 -0
index a7b57dd42c26..a01df2ae6a1b 100644
@@ -594,6 +594,12 @@ config MODULES_USE_ELF_REL
 	  Modules only use ELF REL relocations.  Modules with ELF RELA
 	  relocations will give an error.
 
+config HAVE_UNDERSCORE_SYMBOL_PREFIX
+	bool
+	help
+	  Some architectures generate an _ in front of C symbols; things like
+	  module loading and assembly files need to know about this.
+
 config HAVE_IRQ_EXIT_ON_IRQ_STACK
 	bool
 	help
scripts/Makefile.build +6 -1
index 2f66ed388d1c..c6fe3e092ae0 100644
@@ -444,10 +444,15 @@ targets += $(lib-target)
 
 dummy-object = $(obj)/.lib_exports.o
 ksyms-lds = $(dot-target).lds
+ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
+ref_prefix = EXTERN(_
+else
+ref_prefix = EXTERN(
+endif
 
 quiet_cmd_export_list = EXPORTS $@
 cmd_export_list = $(OBJDUMP) -h $< | \
-	sed -ne '/___ksymtab/s/.*+\([^ ]*\).*/EXTERN(\1)/p' >$(ksyms-lds);\
+	sed -ne '/___ksymtab/s/.*+\([^ ]*\).*/$(ref_prefix)\1)/p' >$(ksyms-lds);\
 	rm -f $(dummy-object);\
 	echo | $(CC) $(a_flags) -c -o $(dummy-object) -x assembler -;\
 	$(LD) $(ld_flags) -r -o $@ -T $(ksyms-lds) $(dummy-object);\
scripts/adjust_autoksyms.sh +6 -1
index a904bf1f5e67..10e49e00a1f6 100755
@@ -49,7 +49,12 @@ EOT
 sed 's/ko$/mod/' modules.order |
 xargs -n1 sed -n -e '2{s/ /\n/g;/^$/!p;}' -- |
 sort -u |
-sed -e 's/\(.*\)/#define __KSYM_\1 1/' >> "$new_ksyms_file"
+while read sym; do
+	if [ -n "$CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" ]; then
+		sym="${sym#_}"
+	fi
+	echo "#define __KSYM_${sym} 1"
+done >> "$new_ksyms_file"
 
 # Special case for modversions (see modpost.c)
 if [ -n "$CONFIG_MODVERSIONS" ]; then
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 42/47 Revert "kallsyms: remove symbol prefix support"

In reply to Hajime Tazaki

This reverts commit 534c9f2ec4c92adbe8791125e7ba66d5023ad51f.

for lkl, mingw32 requires underscore-ed symbols.

---
 scripts/kallsyms.c      | 49 +++++++++++++++++++++++++++++++----------
 scripts/link-vmlinux.sh |  4 ++++
 2 files changed, 41 insertions(+), 12 deletions(-)
scripts/kallsyms.c +37 -12
index ae6504d07fd6..8a62e1b6cf22 100644
@@ -60,6 +60,7 @@ static struct sym_entry *table;
 static unsigned int table_size, table_cnt;
 static int all_symbols = 0;
 static int absolute_percpu = 0;
+static char symbol_prefix_char = '\0';
 static int base_relative = 0;
 
 static int token_profit[0x10000];
@@ -72,6 +73,7 @@ static unsigned char best_table_len[256];
 static void usage(void)
 {
 	fprintf(stderr, "Usage: kallsyms [--all-symbols] "
+			"[--symbol-prefix=<prefix char>] "
 			"[--base-relative] < in.map > out.S\n");
 	exit(1);
 }
@@ -109,22 +111,28 @@ static int check_symbol_range(const char *sym, unsigned long long addr,
 
 static int read_symbol(FILE *in, struct sym_entry *s)
 {
-	char sym[500], stype;
+	char str[500];
+	char *sym, stype;
 	int rc;
 
-	rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, sym);
+	rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
 	if (rc != 3) {
-		if (rc != EOF && fgets(sym, 500, in) == NULL)
+		if (rc != EOF && fgets(str, 500, in) == NULL)
 			fprintf(stderr, "Read error or end of file.\n");
 		return -1;
 	}
-	if (strlen(sym) >= KSYM_NAME_LEN) {
-		fprintf(stderr, "Symbol %s too long for kallsyms (%zu >= %d).\n"
+	if (strlen(str) > KSYM_NAME_LEN) {
+		fprintf(stderr, "Symbol %s too long for kallsyms (%zu vs %d).\n"
 				"Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n",
-			sym, strlen(sym), KSYM_NAME_LEN);
+			str, strlen(str), KSYM_NAME_LEN);
 		return -1;
 	}
 
+	sym = str;
+	/* skip prefix char */
+	if (symbol_prefix_char && str[0] == symbol_prefix_char)
+		sym++;
+
 	/* Ignore most absolute/undefined (?) symbols. */
 	if (strcmp(sym, "_text") == 0)
 		_text = s->addr;
@@ -145,7 +153,7 @@ static int read_symbol(FILE *in, struct sym_entry *s)
 		 is_arm_mapping_symbol(sym))
 		return -1;
 	/* exclude also MIPS ELF local symbols ($L123 instead of .L123) */
-	else if (sym[0] == '$')
+	else if (str[0] == '$')
 		return -1;
 	/* exclude debugging symbols */
 	else if (stype == 'N' || stype == 'n')
@@ -156,14 +164,14 @@ static int read_symbol(FILE *in, struct sym_entry *s)
 
 	/* include the type field in the symbol name, so that it gets
 	 * compressed together */
-	s->len = strlen(sym) + 1;
+	s->len = strlen(str) + 1;
 	s->sym = malloc(s->len + 1);
 	if (!s->sym) {
 		fprintf(stderr, "kallsyms failure: "
 			"unable to allocate required amount of memory\n");
 		exit(EXIT_FAILURE);
 	}
-	strcpy((char *)s->sym + 1, sym);
+	strcpy((char *)s->sym + 1, str);
 	s->sym[0] = stype;
 
 	s->percpu_absolute = 0;
@@ -226,6 +234,11 @@ static int symbol_valid(struct sym_entry *s)
 	int i;
 	char *sym_name = (char *)s->sym + 1;
 
+	/* skip prefix char */
+	if (symbol_prefix_char && *sym_name == symbol_prefix_char)
+		sym_name++;
+
+
 	/* if --all-symbols is not specified, then symbols outside the text
 	 * and inittext sections are discarded */
 	if (!all_symbols) {
@@ -290,9 +303,15 @@ static void read_map(FILE *in)
 
 static void output_label(char *label)
 {
-	printf(".globl %s\n", label);
+	if (symbol_prefix_char)
+		printf(".globl %c%s\n", symbol_prefix_char, label);
+	else
+		printf(".globl %s\n", label);
 	printf("\tALGN\n");
-	printf("%s:\n", label);
+	if (symbol_prefix_char)
+		printf("%c%s:\n", symbol_prefix_char, label);
+	else
+		printf("%s:\n", label);
 }
 
 /* uncompress a compressed symbol. When this function is called, the best table
@@ -749,7 +768,13 @@ int main(int argc, char **argv)
 				absolute_percpu = 1;
 			else if (strcmp(argv[i], "--base-relative") == 0)
 				base_relative = 1;
-			else
+			else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) {
+				char *p = &argv[i][16];
+				/* skip quote */
+				if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\''))
+					p++;
+				symbol_prefix_char = *p;
+			} else
 				usage();
 		}
 	} else if (argc != 1)
scripts/link-vmlinux.sh +4 -0
index 27d2066238c7..553d966a1986 100755
@@ -117,6 +117,10 @@ kallsyms()
 	info KSYM ${2}
 	local kallsymopt;
 
+	if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then
+		kallsymopt="${kallsymopt} --symbol-prefix=_"
+	fi
+
 	if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
 		kallsymopt="${kallsymopt} --all-symbols"
 	fi
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 43/47 kallsyms: Add a config option to select section for kallsyms

In reply to Hajime Tazaki

From: Andreas Abel <[email protected]>

This commit adds a kernel config option to select whether the kallsyms data should be in the .rodata section (the default for non-LKL builds), or in the .data section (the default for LKL).

This is to avoid relocations in the text segment (TEXTRELs) that would otherwise occur with LKL when the .rodata and the .text section end up in the same segment.

Having TEXTRELs can lead to a number of issues:

1. If a shared library contains a TEXTREL, the corresponding memory pages cannot be shared.

2. Android >=6 and SELinux do not support binaries with TEXTRELs
(http://android-developers.blogspot.com/2016/06/android-changes-for-ndk-developers.html).

3. If a program has a TEXTREL, uses an ifunc, and is compiled with early binding, this can lead to a segmentation fault when processing the relocation for the ifunc during dynamic linking because the text segment is made temporarily non-executable to process the TEXTREL (line 248 in dl_reloc.c).

---
 init/Kconfig            | 12 ++++++++++++
 scripts/kallsyms.c      |  9 ++++++++-
 scripts/link-vmlinux.sh |  4 ++++
 3 files changed, 24 insertions(+), 1 deletion(-)
init/Kconfig +12 -0
index 81293d78a6ad..bd1a846e0ee0 100644
@@ -1385,6 +1385,18 @@ config POSIX_TIMERS
 
 	  If unsure say y.
 
+config KALLSYMS_USE_DATA_SECTION
+	bool "Use .data instead of .rodata section for kallsyms"
+	depends on KALLSYMS
+	default n
+	help
+	  Enabling this option will put the kallsyms data in the .data section
+	  instead of the .rodata section.
+
+	  This is useful when building the kernel as a library, as it avoids
+	  relocations in the text segment that could otherwise occur if the
+	  .rodata section is in the same segment as the .text section.
+
 config PRINTK
 	default y
 	bool "Enable support for printk" if EXPERT
scripts/kallsyms.c +8 -1
index 8a62e1b6cf22..11d01516e1c8 100644
@@ -59,6 +59,7 @@ static struct addr_range percpu_range = {
 static struct sym_entry *table;
 static unsigned int table_size, table_cnt;
 static int all_symbols = 0;
+static int use_data_section;
 static int absolute_percpu = 0;
 static char symbol_prefix_char = '\0';
 static int base_relative = 0;
@@ -73,6 +74,7 @@ static unsigned char best_table_len[256];
 static void usage(void)
 {
 	fprintf(stderr, "Usage: kallsyms [--all-symbols] "
+			"[--use-data-section] "
 			"[--symbol-prefix=<prefix char>] "
 			"[--base-relative] < in.map > out.S\n");
 	exit(1);
@@ -362,7 +364,10 @@ static void write_src(void)
 	printf("#define ALGN .balign 4\n");
 	printf("#endif\n");
 
-	printf("\t.section .rodata, \"a\"\n");
+	if (use_data_section)
+		printf("\t.section .data\n");
+	else
+		printf("\t.section .rodata, \"a\"\n");
 
 	/* Provide proper symbols relocatability by their relativeness
 	 * to a fixed anchor point in the runtime image, either '_text'
@@ -768,6 +773,8 @@ int main(int argc, char **argv)
 				absolute_percpu = 1;
 			else if (strcmp(argv[i], "--base-relative") == 0)
 				base_relative = 1;
+			else if (strcmp(argv[i], "--use-data-section") == 0)
+				use_data_section = 1;
 			else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) {
 				char *p = &argv[i][16];
 				/* skip quote */
scripts/link-vmlinux.sh +4 -0
index 553d966a1986..3fc1fc406b38 100755
@@ -133,6 +133,10 @@ kallsyms()
 		kallsymopt="${kallsymopt} --base-relative"
 	fi
 
+	if [ -n "${CONFIG_KALLSYMS_USE_DATA_SECTION}" ]; then
+		kallsymopt="${kallsymopt} --use-data-section"
+	fi
+
 	local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL}               \
 		      ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
 
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 44/47 um lkl: use ARCH=um SUBARCH=lkl for tools/lkl

In reply to Hajime Tazaki

From: Akira Moroo <[email protected]>

This unifies LKL code under arch/um so that we can treat LKL as one of mode inside UML.

---
 arch/um/Kconfig                               |  50 ++++----
 arch/um/Makefile                              | 115 ++----------------
 arch/um/auto.conf                             |   0
 arch/um/include/asm/Kbuild                    |   5 +
 arch/um/lkl/um/Makefile                       |   1 +
 .../um/lkl/um/include/sysdep/kernel-offsets.h |   4 +
 6 files changed, 44 insertions(+), 131 deletions(-)
 create mode 100644 arch/um/auto.conf
 create mode 100644 arch/um/lkl/um/Makefile
 create mode 100644 arch/um/lkl/um/include/sysdep/kernel-offsets.h
arch/um/Kconfig +26 -24
index 3c3adfc486f2..d7e9af63cf8f 100644
@@ -5,23 +5,23 @@ menu "UML-specific options"
 config UML
 	bool
 	default y
-	select ARCH_HAS_KCOV
-	select ARCH_NO_PREEMPT
-	select HAVE_ARCH_AUDITSYSCALL
-	select HAVE_ARCH_SECCOMP_FILTER
-	select HAVE_UID16
-	select HAVE_FUTEX_CMPXCHG if FUTEX
-	select HAVE_DEBUG_KMEMLEAK
-	select HAVE_DEBUG_BUGVERBOSE
-	select GENERIC_IRQ_SHOW
-	select GENERIC_CPU_DEVICES
-	select GENERIC_CLOCKEVENTS
-	select HAVE_GCC_PLUGINS
-	select TTY # Needed for line.c
+	select ARCH_HAS_KCOV if !UML_LKL
+	select ARCH_NO_PREEMPT if !UML_LKL
+	select HAVE_ARCH_AUDITSYSCALL if !UML_LKL
+	select HAVE_ARCH_SECCOMP_FILTER if !UML_LKL
+	select HAVE_UID16 if !UML_LKL
+	select HAVE_FUTEX_CMPXCHG if (FUTEX && !UML_LKL)
+	select HAVE_DEBUG_KMEMLEAK if !UML_LKL
+	select HAVE_DEBUG_BUGVERBOSE if !UML_LKL
+	select GENERIC_IRQ_SHOW if !UML_LKL
+	select GENERIC_CPU_DEVICES if !UML_LKL
+	select GENERIC_CLOCKEVENTS if !UML_LKL
+	select HAVE_GCC_PLUGINS if !UML_LKL
+	select TTY if !UML_LKL # Needed for line.c
 
 config MMU
 	bool
-	default y
+	default y if !UML_LKL
 
 config NO_IOMEM
 	def_bool y
@@ -34,20 +34,20 @@ config SBUS
 
 config TRACE_IRQFLAGS_SUPPORT
 	bool
-	default y
+	default y if !UML_LKL
 
 config LOCKDEP_SUPPORT
 	bool
-	default y
+	default y if !UML_LKL
 
 config STACKTRACE_SUPPORT
 	bool
-	default y
-	select STACKTRACE
+	default y if !UML_LKL
+	select STACKTRACE if !UML_LKL
 
 config GENERIC_CALIBRATE_DELAY
 	bool
-	default y
+	default y if !UML_LKL
 
 config HZ
 	int
@@ -73,12 +73,12 @@ config STATIC_LINK
 
 config LD_SCRIPT_STATIC
 	bool
-	default y
+	default y if !UML_LKL
 	depends on STATIC_LINK
 
 config LD_SCRIPT_DYN
 	bool
-	default y
+	default y if !UML_LKL
 	depends on !LD_SCRIPT_STATIC
 	select MODULE_REL_CRCS if MODVERSIONS
 
@@ -106,7 +106,7 @@ config HOSTFS
 config MCONSOLE
 	bool "Management console"
 	depends on PROC_FS
-	default y
+	default y if !UML_LKL
 	help
 	  The user mode linux management console is a low-level interface to
 	  the kernel, somewhat like the i386 SysRq interface.  Since there is
@@ -169,7 +169,7 @@ config PGTABLE_LEVELS
 	default 2
 
 config SECCOMP
-	def_bool y
+	def_bool y if !UML_LKL
 	prompt "Enable seccomp to safely compute untrusted bytecode"
 	---help---
 	  This kernel feature is useful for number crunching applications
@@ -198,4 +198,6 @@ config UML_TIME_TRAVEL_SUPPORT
 
 endmenu
 
-source "arch/um/drivers/Kconfig"
+if !UML_LKL
+	source "arch/um/drivers/Kconfig"
+endif
arch/um/Makefile +8 -107

132 lines not on this page · raw message

arch/um/auto.conf new file +0 -0
new file mode 100644
index 000000000000..e69de29bb2d1
arch/um/include/asm/Kbuild +5 -0
index 398006d27e40..6c2aa280f1d9 100644
@@ -17,6 +17,11 @@ generic-y += kdebug.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
 generic-y += mmiowb.h
+generic-$(UML_LKL) += mmu.h
+generic-$(UML_LKL) += mmu_context.h
+generic-$(UML_LKL) += module.h
+generic-$(UML_LKL) += msgbuf.h
+generic-$(UML_LKL) += page.h
 generic-y += param.h
 generic-y += pci.h
 generic-y += percpu.h
arch/um/lkl/um/Makefile new file +1 -0
new file mode 100644
index 000000000000..f66554cd5c45
@@ -0,0 +1 @@
+# SPDX-License-Identifier: GPL-2.0
arch/um/lkl/um/include/sysdep/kernel-offsets.h new file +4 -0
new file mode 100644
index 000000000000..27004731b0ab
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Dummy kernel-offsets.h file. Required by kbuild and ready to be used
+ * - hint!
+ */
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 45/47 um lkl: add CI tests

In reply to Hajime Tazaki

We use CircleCI for the tests, which should check regressions before merging.

---
 .circleci/config.yml             | 246 +++++++++++++++++++++++++++++++
 tools/lkl/scripts/checkpatch.sh  |  60 ++++++++
 tools/lkl/scripts/lkl-jenkins.sh |  21 +++
 3 files changed, 327 insertions(+)
 create mode 100644 .circleci/config.yml
 create mode 100755 tools/lkl/scripts/checkpatch.sh
 create mode 100755 tools/lkl/scripts/lkl-jenkins.sh
.circleci/config.yml new file +246 -0
new file mode 100644
index 000000000000..7d140d9a2acb
@@ -0,0 +1,246 @@
+version: 2
+general:
+  artifacts:
+
+do_steps: &do_steps
+ steps:
+  - run: echo "$CROSS_COMPILE" > ~/_cross_compile
+  - restore_cache:
+      key: code-tree-shallow-{{ .Environment.CACHE_VERSION }}
+  - run:
+      name: checkout build tree
+      command: |
+        mkdir -p ~/.ssh/
+        ssh-keyscan -H github.com >> ~/.ssh/known_hosts
+        if ! [ -d .git ]; then
+          git clone --depth=1 $CIRCLE_REPOSITORY_URL .;
+        fi
+        if [[ $CIRCLE_BRANCH == pull/* ]]; then
+           git fetch --depth=1 origin $CIRCLE_BRANCH/head;
+        else
+           git fetch --depth=1 origin $CIRCLE_BRANCH;
+        fi
+        git reset --hard $CIRCLE_SHA1
+  - save_cache:
+      key: code-tree-shallow-{{ .Environment.CACHE_VERSION }}-{{ epoch }}
+      paths:
+        - /home/ubuntu/project/.git
+  - run:
+      name: clean
+      command: |
+        make mrproper
+        cd tools/lkl && make clean-conf
+        rm -rf ~/junit
+  - run: mkdir -p /home/ubuntu/.ccache
+  - restore_cache:
+      key: compiler-cache-{{ checksum "~/_cross_compile" }}-{{ .Environment.CACHE_VERSION }}
+  - run:
+      name: build DPDK
+      command: |
+        if [ "$MKARG" = "dpdk=yes" ]; then
+          sudo apt-get update
+          if ! sudo apt-get install -y linux-headers-$(uname -r) ; then
+             cd /lib/modules && sudo ln -sf 4.4.0-97-generic `uname -r` && \
+               cd /home/ubuntu/project
+          fi
+          cd tools/lkl && ./scripts/dpdk-sdk-build.sh;
+        fi
+  - run:
+      name: copy mingw binutils
+      command: |
+        if [ "$CROSS_COMPILE" = "i686-w64-mingw32-" ]; then
+          wget https://github.com/lkl/linux/raw/master/tools/lkl/bin/i686-w64-mingw32-as
+          wget https://github.com/lkl/linux/raw/master/tools/lkl/bin/i686-w64-mingw32-ld
+          wget https://github.com/lkl/linux/raw/master/tools/lkl/bin/i686-w64-mingw32-objcopy
+          sudo cp i686-w64-mingw32-* /usr/bin;
+        elif [ "$CROSS_COMPILE" = "arm-linux-androideabi-" ]; then
+          wget https://github.com/lkl/linux/raw/master/tools/lkl/bin/arm-linux-androideabi-ld.gold
+          sudo cp arm-linux-androideabi-ld.gold /usr/bin/arm-linux-androideabi-ld;
+        fi
+  - run:
+      name: start emulator
+      command: |
+        if [[ $CROSS_COMPILE == *android* ]]; then
+          emulator -avd Nexus5_API24 -no-window -no-audio -no-boot-anim;
+        elif [[ $CROSS_COMPILE == *freebsd* ]]; then
+          cd /home/ubuntu && $QEMU
+        fi
+      background: true
+  - run: cd tools/lkl && make -j8 ${MKARG}
+  - run: mkdir -p ~/destdir && cd tools/lkl && make DESTDIR=~/destdir
+  - save_cache:
+     paths:
+       - /home/ubuntu/.ccache
+     key: compiler-cache-{{ checksum "~/_cross_compile" }}-{{ .Environment.CACHE_VERSION }}-{{ epoch }}
+  - run:
+      name: wait emulator to boot
+      command: |
+        if [[ $CROSS_COMPILE == *android* ]]; then
+          /home/ubuntu/circle-android.sh wait-for-boot;
+        elif [[ $CROSS_COMPILE == *freebsd* ]]; then
+          while ! $MYSSH -o ConnectTimeout=1 exit 2> /dev/null
+          do
+             sleep 5
+          done
+        fi
+  - run:
+      name: run tests
+      command: |
+        mkdir -p ~/junit
+        make -C tools/lkl run-tests tests="--junit-dir ~/junit"
+        find ./tools/lkl/ -type f -name "*.xml" -exec mv {} ~/junit/ \;
+      no_output_timeout: "90m"
+  - store_test_results:
+      path: ~/junit
+  - store_artifacts:
+      path: ~/junit
+
+
+do_uml_steps: &do_uml_steps
+ steps:
+  - run: echo "$CROSS_COMPILE" > ~/_cross_compile
+  - restore_cache:
+      key: code-tree-shallow-{{ .Environment.CACHE_VERSION }}
+  - run:
+      name: checkout build tree
+      command: |
+        mkdir -p ~/.ssh/
+        ssh-keyscan -H github.com >> ~/.ssh/known_hosts
+        if ! [ -d .git ]; then
+          git clone --depth=1 $CIRCLE_REPOSITORY_URL .;
+        fi
+        if [[ $CIRCLE_BRANCH == pull/* ]]; then
+           git fetch --depth=1 origin $CIRCLE_BRANCH/head;
+        else
+           git fetch --depth=1 origin $CIRCLE_BRANCH;
+        fi
+        git reset --hard $CIRCLE_SHA1
+  - save_cache:
+      key: code-tree-shallow-{{ .Environment.CACHE_VERSION }}-{{ epoch }}
+      paths:
+        - /home/ubuntu/project/.git
+  - run: mkdir -p /home/ubuntu/.ccache
+  - restore_cache:
+      key: compiler-cache-{{ checksum "~/_cross_compile" }}-{{ .Environment.CACHE_VERSION }}
+  - run:
+      name: build
+      command: |
+        make -C tools/lkl/
+        make defconfig ARCH=um
+        make ARCH=um
+  - save_cache:
+     paths:
+       - /home/ubuntu/.ccache
+     key: compiler-cache-{{ checksum "~/_cross_compile" }}-{{ .Environment.CACHE_VERSION }}-{{ epoch }}
+  - run:
+      name: test
+      command: |
+        ./linux rootfstype=hostfs ro mem=1g loglevel=10 init="/bin/bash -c exit" || export RETVAL=$?
+        # SIGABRT=6 => 128+6
+        if [ $RETVAL != "134" ]; then
+          exit 1
+        fi
+
+## Customize the test machine
+jobs:
+  x86_64:
+   docker:
+     - image: lkldocker/circleci-x86_64:0.7
+   environment:
+     CROSS_COMPILE: ""
+     MKARG: "dpdk=no"
+   <<: *do_steps
+
+  i386:
+   docker:
+     - image: lkldocker/circleci-i386:0.1
+   environment:
+     CROSS_COMPILE: ""
+   <<: *do_steps
+
+  mingw32:
+   docker:
+     - image: lkldocker/circleci-mingw:0.6
+   environment:
+     CROSS_COMPILE: "i686-w64-mingw32-"
+   <<: *do_steps
+
+  android-arm32:
+   docker:
+     - image: lkldocker/circleci-android-arm32:0.6
+   environment:
+     CROSS_COMPILE: "arm-linux-androideabi-"
+     LKL_ANDROID_TEST: 1
+     ANDROID_SDK_ROOT: /home/ubuntu/android-sdk
+   <<: *do_steps
+
+  android-aarch64:
+   docker:
+     - image: lkldocker/circleci-android-arm64:0.6
+   environment:
+     CROSS_COMPILE: "aarch64-linux-android-"
+     LKL_ANDROID_TEST: 1
+     ANDROID_SDK_ROOT: /home/ubuntu/android-sdk
+   <<: *do_steps
+
+  freebsd11_x86_64:
+   docker:
+     - image: lkldocker/circleci-freebsd11-x86_64:0.4
+   environment:
+     CROSS_COMPILE: "x86_64-pc-freebsd11-"
+   <<: *do_steps
+
+  x86_64_valgrind:
+   docker:
+     - image: lkldocker/circleci-x86_64:0.7
+   environment:
+     CROSS_COMPILE: ""
+     MKARG: "dpdk=no"
+     VALGRIND: 1
+   <<: *do_steps
+
+  x86_64_uml:
+   docker:
+     - image: lkldocker/circleci-x86_64:0.7
+   environment:
+     CROSS_COMPILE: ""
+     TMPDIR: "/tmp" # required for not using /dev/shm
+   <<: *do_uml_steps
+
+  checkpatch:
+   docker:
+     - image: lkldocker/circleci:0.5
+   environment:
+   steps:
+     - restore_cache:
+        key: code-tree-full-history-{{ .Environment.CACHE_VERSION }}
+     - checkout
+     - run: tools/lkl/scripts/checkpatch.sh
+     - save_cache:
+        key: code-tree-full-history-{{ .Environment.CACHE_VERSION }}-{{ epoch }}
+        paths:
+          - /home/ubuntu/project/.git
+        when: always
+
+workflows:
+  version: 2
+  build:
+    jobs:
+     - x86_64
+     - mingw32
+     - android-arm32
+     - android-aarch64
+     - freebsd11_x86_64
+     - checkpatch
+     - i386
+     - x86_64_uml
+  nightly:
+    triggers:
+      - schedule:
+          cron: "0 0 * * *"
+          filters:
+            branches:
+              only:
+                - master
+    jobs:
+      - x86_64_valgrind
tools/lkl/scripts/checkpatch.sh new file +60 -0

60 lines not on this page · raw message

tools/lkl/scripts/lkl-jenkins.sh new file +21 -0
new file mode 100755
index 000000000000..eaadc6e90143
@@ -0,0 +1,21 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+set -e
+
+script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+basedir=$(cd $script_dir/../../..; pwd)
+
+export PATH=$PATH:/sbin
+
+build_and_test()
+{
+    cd $basedir
+    make mrproper
+    cd tools/lkl
+    make clean-conf
+    make -j4
+    make run-tests
+}
+
+build_and_test
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 46/47 um: use lkl virtio_net_tap device as UML device

In reply to Hajime Tazaki

This also expands supporting virtio-mmio driver, which involves multiple addition to Kconfig as well.

---
 .circleci/config.yml             |   2 +-
 arch/um/Kconfig                  |   6 --
 arch/um/Makefile.um              |   4 +
 arch/um/configs/x86_64_defconfig |   5 ++
 arch/um/include/asm/Kbuild       |   1 +
 arch/um/include/asm/io.h         |   4 +
 arch/um/os-Linux/Makefile        |   5 ++
 arch/um/os-Linux/lkl_dev.c       | 134 +++++++++++++++++++++++++++++++
 arch/x86/um/syscalls_64.c        |  53 ++++++++++++
 tools/lkl/lib/Makefile           |  32 ++++++++
 tools/lkl/lib/virtio.c           |  17 +++-
 tools/lkl/lib/virtio.h           |  22 +++++
 tools/lkl/lib/virtio_net.c       |  23 +++++-
 tools/lkl/lib/virtio_net_fd.c    |  22 -----
 tools/lkl/lib/virtio_net_fd.h    |  22 +++++
 15 files changed, 320 insertions(+), 32 deletions(-)
 create mode 100644 arch/um/os-Linux/lkl_dev.c
 create mode 100644 tools/lkl/lib/Makefile
.circleci/config.yml +1 -1
index 7d140d9a2acb..cec55ad93dc6 100644
@@ -135,7 +135,7 @@ do_uml_steps: &do_uml_steps
   - run:
       name: test
       command: |
-        ./linux rootfstype=hostfs ro mem=1g loglevel=10 init="/bin/bash -c exit" || export RETVAL=$?
+        ./linux rootfstype=hostfs ro mem=1g loglevel=10 veth0=tap,tap0,0xc803 init="/bin/bash -c exit" || export RETVAL=$?
         # SIGABRT=6 => 128+6
         if [ $RETVAL != "134" ]; then
           exit 1
arch/um/Kconfig +0 -6
index d7e9af63cf8f..a32dd84f0bf2 100644
@@ -23,9 +23,6 @@ config MMU
 	bool
 	default y if !UML_LKL
 
-config NO_IOMEM
-	def_bool y
-
 config ISA
 	bool
 
@@ -160,9 +157,6 @@ config MMAPPER
 	  This driver allows a host file to be used as emulated IO memory inside
 	  UML.
 
-config NO_DMA
-	def_bool y
-
 config PGTABLE_LEVELS
 	int
 	default 3 if 3_LEVEL_PGTABLES
arch/um/Makefile.um +4 -0
index 24a088e5df04..65cfc4393e3d 100644
@@ -11,6 +11,8 @@ core-y			+= $(ARCH_DIR)/kernel/		\
 			 $(ARCH_DIR)/drivers/		\
 			 $(ARCH_DIR)/os-$(OS)/
 
+core-y			+= $(srctree)/tools/lkl/lib/
+
 ifdef CONFIG_64BIT
 	KBUILD_CFLAGS += -mcmodel=large
 endif
@@ -52,6 +54,8 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include \
 		   -I$(objtree)/$(HOST_DIR)/include/generated \
 		   -I$(objtree)/$(HOST_DIR)/include/generated/uapi
 
+KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/lkl/include -I$(srctree)/$(ARCH_DIR)/
+
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
 # in KBUILD_CFLAGS.  Otherwise, it would cause ld to complain about the two different
arch/um/configs/x86_64_defconfig +5 -0
index 3281d7600225..917982b6cd60 100644
@@ -70,3 +70,8 @@ CONFIG_NLS=y
 CONFIG_DEBUG_INFO=y
 CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_KERNEL=y
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_MENU=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+CONFIG_VIRTIO_NET=y
arch/um/include/asm/Kbuild +1 -0
index 6c2aa280f1d9..54037cdb320e 100644
@@ -5,6 +5,7 @@ generic-y += compat.h
 generic-y += current.h
 generic-y += delay.h
 generic-y += device.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += extable.h
arch/um/include/asm/io.h +4 -0
index 96f77b5232aa..f23700d3c071 100644
@@ -2,11 +2,15 @@
 #ifndef _ASM_UM_IO_H
 #define _ASM_UM_IO_H
 
+#ifndef CONFIG_HAS_IOMEM
 #define ioremap ioremap
 static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
 {
 	return (void __iomem *)(unsigned long)offset;
 }
+#else
+#include <lkl/include/asm/io.h>
+#endif
 
 #define iounmap iounmap
 static inline void iounmap(void __iomem *addr)
arch/um/os-Linux/Makefile +5 -0
index 839915b8c31c..d90d88a2f34e 100644
@@ -11,9 +11,14 @@ obj-y = execvp.o file.o helper.o irq.o main.o mem.o process.o \
 	umid.o user_syms.o util.o drivers/ skas/
 
 obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
+obj-y += lkl_dev.o
+
+CFLAGS_lkl_dev.o:=-I$(srctree)/tools/lkl/include -Wno-undef
 
 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
 
+USER_OBJS += lkl_dev.o
+
 include arch/um/scripts/Makefile.rules
arch/um/os-Linux/lkl_dev.c new file +134 -0

134 lines not on this page · raw message

arch/x86/um/syscalls_64.c +53 -0

62 lines not on this page · raw message

tools/lkl/lib/Makefile new file +32 -0
new file mode 100644
index 000000000000..8dc0009c680e
@@ -0,0 +1,32 @@
+
+USER_CFLAGS += -I$(srctree)/tools/lkl/include \
+		-Wno-strict-prototypes -Wno-undef \
+		-Wframe-larger-than=20480 -O0 -g
+
+USER_OBJS += fs.o iomem.o net.o jmp_buf.o virtio.o virtio_net.o \
+	 virtio_net_fd.o virtio_net_tap.o utils.o posix-host.o \
+	../../perf/pmu-events/jsmn.o
+
+#obj-y += fs.o
+obj-y += iomem.o
+#obj-y += net.o
+obj-y += jmp_buf.o
+obj-y += posix-host.o
+#obj-$(LKL_HOST_CONFIG_NT) += nt-host.o
+obj-y += utils.o
+#obj-y += virtio_blk.o
+obj-y += virtio.o
+#obj-y += dbg.o
+#obj-y += dbg_handler.o
+obj-y += virtio_net.o
+obj-y += virtio_net_fd.o
+obj-y += virtio_net_tap.o
+#obj-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_raw.o
+#obj-$(LKL_HOST_CONFIG_VIRTIO_NET_MACVTAP) += virtio_net_macvtap.o
+#obj-$(LKL_HOST_CONFIG_VIRTIO_NET_DPDK) += virtio_net_dpdk.o
+#obj-$(LKL_HOST_CONFIG_VIRTIO_NET_VDE) += virtio_net_vde.o
+#obj-$(LKL_HOST_CONFIG_VIRTIO_NET) += virtio_net_pipe.o
+obj-y += ../../perf/pmu-events/jsmn.o
+#obj-y += config.o
+
+include arch/um/scripts/Makefile.rules
tools/lkl/lib/virtio.c +15 -2
index 4b3dbba607c3..98539e270320 100644
@@ -46,6 +46,12 @@
 		lkl_host_ops.panic();					\
 	} while (0)
 
+#ifdef __arch_um__
+extern unsigned long uml_physmem;
+#else
+static unsigned long uml_physmem;
+#endif
+
 struct virtio_queue {
 	uint32_t num_max;
 	uint32_t num;
@@ -216,7 +222,8 @@ static void add_dev_buf_from_vring_desc(struct virtio_req *req,
 {
 	struct iovec *buf = &req->buf[req->buf_count++];
 
-	buf->iov_base = (void *)(uintptr_t)le64toh(vring_desc->addr);
+	buf->iov_base = (void *)(uintptr_t)le64toh(vring_desc->addr)
+		+ uml_physmem;
 	buf->iov_len = le32toh(vring_desc->len);
 
 	if (!(buf->iov_base && buf->iov_len))
@@ -304,8 +311,10 @@ void virtio_process_queue(struct virtio_dev *dev, uint32_t qidx)
 	if (!q->ready)
 		return;
 
+#ifndef __arch_um__
 	if (dev->ops->acquire_queue)
 		dev->ops->acquire_queue(dev, qidx);
+#endif
 
 	while (q->last_avail_idx != le16toh(q->avail->idx)) {
 		/*
@@ -319,8 +328,10 @@ void virtio_process_queue(struct virtio_dev *dev, uint32_t qidx)
 			virtio_set_avail_event(q, q->avail->idx);
 	}
 
+#ifndef __arch_um__
 	if (dev->ops->release_queue)
 		dev->ops->release_queue(dev, qidx);
+#endif
 }
 
 static inline uint32_t virtio_read_device_features(struct virtio_dev *dev)
@@ -406,7 +417,7 @@ static inline void set_ptr_low(void **ptr, uint32_t val)
 	uint64_t tmp = (uintptr_t)*ptr;
 
 	tmp = (tmp & 0xFFFFFFFF00000000) | val;
-	*ptr = (void *)(long)tmp;
+	*ptr = (void *)(long)tmp + uml_physmem;
 }
 
 static inline void set_ptr_high(void **ptr, uint32_t val)
@@ -579,6 +590,7 @@ int virtio_dev_setup(struct virtio_dev *dev, int queues, int num_max)
 
 int virtio_dev_cleanup(struct virtio_dev *dev)
 {
+#ifndef __arch_um__
 	char devname[100];
 	long fd, ret;
 	long mount_ret;
@@ -622,6 +634,7 @@ int virtio_dev_cleanup(struct virtio_dev *dev)
 	lkl_put_irq(dev->irq, "virtio");
 	unregister_iomem(dev->base);
 	lkl_host_ops.mem_free(dev->queue);
+#endif
 	return 0;
 }
 
tools/lkl/lib/virtio.h +22 -0
index 7427aa8fad79..be06ef09f8b0 100644
@@ -87,6 +87,28 @@ void virtio_req_complete(struct virtio_req *req, uint32_t len);
 void virtio_process_queue(struct virtio_dev *dev, uint32_t qidx);
 void virtio_set_queue_max_merge_len(struct virtio_dev *dev, int q, int len);
 
+#ifdef __arch_um__
+//#include <irq_kern.h>
+#include <irq_user.h>
+enum irqreturn {
+	IRQ_HANDLED		= (1 << 0),
+	IRQ_WAKE_THREAD		= (1 << 1),
+};
+
+typedef enum irqreturn irqreturn_t;
+typedef irqreturn_t (*irq_handler_t)(int, void *);
+
+#define IRQF_SHARED		0x00000080
+
+extern int um_request_irq(unsigned int irq, int fd, int type,
+			  irq_handler_t handler,
+			  unsigned long irqflags,  const char *devname,
+			  void *dev_id);
+
+long sys_virtio_mmio_device_add(long base, long size, unsigned int irq);
+#define lkl_sys_virtio_mmio_device_add sys_virtio_mmio_device_add
+#endif /* __arch_um__ */
+
 #define container_of(ptr, type, member) \
 	(type *)((char *)(ptr) - __builtin_offsetof(type, member))
 
tools/lkl/lib/virtio_net.c +22 -1
index 60743109215b..224d7bf50702 100644
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <lkl_host.h>
 #include "virtio.h"
+#include "virtio_net_fd.h"
 #include "endian.h"
 
 #include <lkl/linux/virtio_net.h>
@@ -211,9 +212,21 @@ static struct lkl_mutex **init_queue_locks(int num_queues)
 	return ret;
 }
 
+#ifdef __arch_um__
+static irqreturn_t um_virtio_intr(int irq, void *dev_id)
+{
+	struct virtio_dev *dev = dev_id;
+
+	virtio_process_queue(dev, 0);
+	return 0;
+}
+#endif
+
 int lkl_netdev_add(struct lkl_netdev *nd, struct lkl_netdev_args *args)
 {
 	struct virtio_net_dev *dev;
+	struct lkl_netdev_fd *nd_fd =
+		container_of(nd, struct lkl_netdev_fd, dev);
 	int ret = -LKL_ENOMEM;
 
 	dev = lkl_host_ops.mem_alloc(sizeof(*dev));
@@ -251,16 +264,22 @@ int lkl_netdev_add(struct lkl_netdev *nd, struct lkl_netdev_args *args)
 	if (ret)
 		goto out_free;
 
+#ifdef __arch_um__
+	um_request_irq(dev->dev.irq, nd_fd->fd_rx, IRQ_READ, um_virtio_intr,
+		       IRQF_SHARED, "virtio", dev);
+#endif
+
 	/*
 	 * We may receive upto 64KB TSO packet so collect as many descriptors as
 	 * there are available up to 64KB in total len.
 	 */
 	if (dev->dev.device_features & BIT(LKL_VIRTIO_NET_F_MRG_RXBUF))
 		virtio_set_queue_max_merge_len(&dev->dev, RX_QUEUE_IDX, 65536);
-
+#ifndef __arch_um__
 	dev->poll_tid = lkl_host_ops.thread_create(poll_thread, dev);
 	if (dev->poll_tid == 0)
 		goto out_cleanup_dev;
+#endif
 
 	ret = dev_register(dev);
 	if (ret < 0)
@@ -279,6 +298,7 @@ int lkl_netdev_add(struct lkl_netdev *nd, struct lkl_netdev_args *args)
 	return ret;
 }
 
+#ifndef __arch_um__
 /* Return 0 for success, -1 for failure. */
 void lkl_netdev_remove(int id)
 {
@@ -314,6 +334,7 @@ void lkl_netdev_remove(int id)
 	free_queue_locks(dev->queue_locks, NUM_QUEUES);
 	lkl_host_ops.mem_free(dev);
 }
+#endif
 
 void lkl_netdev_free(struct lkl_netdev *nd)
 {
tools/lkl/lib/virtio_net_fd.c +0 -22
index f8664455e696..a19193cfeca9 100644
@@ -25,28 +25,6 @@
 #include "virtio.h"
 #include "virtio_net_fd.h"
 
-struct lkl_netdev_fd {
-	struct lkl_netdev dev;
-	/* file-descriptor based device */
-	int fd_rx;
-	int fd_tx;
-	/*
-	 * Controlls the poll mask for fd. Can be acccessed concurrently from
-	 * poll, tx, or rx routines but there is no need for syncronization
-	 * because:
-	 *
-	 * (a) TX and RX routines set different variables so even if they update
-	 * at the same time there is no race condition
-	 *
-	 * (b) Even if poll and TX / RX update at the same time poll cannot
-	 * stall: when poll resets the poll variable we know that TX / RX will
-	 * run which means that eventually the poll variable will be set.
-	 */
-	int poll_tx, poll_rx;
-	/* controle pipe */
-	int pipe[2];
-};
-
 static int fd_net_tx(struct lkl_netdev *nd, struct iovec *iov, int cnt)
 {
 	int ret;
tools/lkl/lib/virtio_net_fd.h +22 -0
index 713ba13cca7c..fe6d6d8e3ab4 100644
@@ -4,6 +4,28 @@
 
 struct ifreq;
 
+struct lkl_netdev_fd {
+	struct lkl_netdev dev;
+	/* file-descriptor based device */
+	int fd_rx;
+	int fd_tx;
+	/*
+	 * Controlls the poll mask for fd. Can be acccessed concurrently from
+	 * poll, tx, or rx routines but there is no need for syncronization
+	 * because:
+	 *
+	 * (a) TX and RX routines set different variables so even if they update
+	 * at the same time there is no race condition
+	 *
+	 * (b) Even if poll and TX / RX update at the same time poll cannot
+	 * stall: when poll resets the poll variable we know that TX / RX will
+	 * run which means that eventually the poll variable will be set.
+	 */
+	int poll_tx, poll_rx;
+	/* controle pipe */
+	int pipe[2];
+};
+
 /**
  * lkl_register_netdev_linux_fdnet - register a file descriptor-based network
  * device as a NIC
Signature · 7 lines
2.20.1 (Apple Git-117)


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

RFC PATCH 47/47 um: add lkl virtio-blk device

In reply to Hajime Tazaki

Now uml can use a virtio-blk device via 'vubd0=<filename>' over virtio-mmio driver.

---
 .circleci/config.yml             |  4 ++-
 arch/um/configs/x86_64_defconfig |  1 +
 arch/um/os-Linux/lkl_dev.c       | 56 +++++++++++++++++++++++++++++++-
 tools/lkl/lib/Makefile           |  6 ++--
 4 files changed, 62 insertions(+), 5 deletions(-)
.circleci/config.yml +3 -1
index cec55ad93dc6..266ed58b6fd7 100644
@@ -135,7 +135,9 @@ do_uml_steps: &do_uml_steps
   - run:
       name: test
       command: |
-        ./linux rootfstype=hostfs ro mem=1g loglevel=10 veth0=tap,tap0,0xc803 init="/bin/bash -c exit" || export RETVAL=$?
+        dd if=/dev/zero of=disk.img bs=1024 count=20480
+        mkfs.ext4 disk.img
+        ./linux rootfstype=hostfs ro mem=1g loglevel=10 veth0=tap,tap0,0xc803 vubd0=disk.img init='/bin/bash -x -c "mount -t ext4 /dev/vda /mnt ; ls -l /mnt/; ip addr ; exit"' || export RETVAL=$?
         # SIGABRT=6 => 128+6
         if [ $RETVAL != "134" ]; then
           exit 1
arch/um/configs/x86_64_defconfig +1 -0
index 917982b6cd60..e5b7c048a701 100644
@@ -75,3 +75,4 @@ CONFIG_VIRTIO_MENU=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
 CONFIG_VIRTIO_NET=y
+CONFIG_VIRTIO_BLK=y
\ No newline at end of file
arch/um/os-Linux/lkl_dev.c +55 -1

80 lines not on this page · raw message

tools/lkl/lib/Makefile +3 -3
index 8dc0009c680e..3cee5b0133b1 100644
@@ -3,9 +3,9 @@ USER_CFLAGS += -I$(srctree)/tools/lkl/include \
 		-Wno-strict-prototypes -Wno-undef \
 		-Wframe-larger-than=20480 -O0 -g
 
-USER_OBJS += fs.o iomem.o net.o jmp_buf.o virtio.o virtio_net.o \
+USER_OBJS += iomem.o jmp_buf.o virtio.o virtio_net.o \
 	 virtio_net_fd.o virtio_net_tap.o utils.o posix-host.o \
-	../../perf/pmu-events/jsmn.o
+	 virtio_blk.o ../../perf/pmu-events/jsmn.o
 
 #obj-y += fs.o
 obj-y += iomem.o
@@ -14,7 +14,7 @@ obj-y += jmp_buf.o
 obj-y += posix-host.o
 #obj-$(LKL_HOST_CONFIG_NT) += nt-host.o
 obj-y += utils.o
-#obj-y += virtio_blk.o
+obj-y += virtio_blk.o
 obj-y += virtio.o
 #obj-y += dbg.o
 #obj-y += dbg_handler.o
Signature · 7 lines
2.20.1 (Apple Git-117)


_______________________________________________
linux-um mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-um
#55 lore raw
In reply to Hajime Tazaki
Quoted 6 lines · Hajime Tazaki

This RFC patchset is to ask opinions from UML people, whether LKL codes is good to integrate into UML code base. We wish to have any kind of feedback from your kind reviews. There are numbers of commits which should be asked for reviews to other mailing lists; we will do it later once we got discussed in this mailing list.

Thanks a lot for doing this, this effort is much appreciated! :-)

Quoted 3 lines
# sorry for the long list of patches: we can make it smaller by only
  including basic set of LKL (e.g., removing foreign OS support, etc) if
  you wish.

Let use see how the review goes. First I'll give it a high level review to make sure we all talk about the same things.

Please CC [email protected] for the next patch round. Integrating LKL (into arch/um/) is something which needs more audience and feedback from Arnd Bergmann, our global arch maintainer.

Quoted 22 lines

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

Quoted 8 lines

Milestone
=========
This patches is just 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.

1. Put LKL code under arch/um (arch/um/lkl), and build it in a separate way from UML.

Makes sense.

Quoted 1 line

2. Share common parts of implementation between UML and LKL.

Since both UML and LKL are usermode ports there is a lot of potential.

#56 lore raw

Hello Richard,

Thanks for the review.

Quoted 9 lines · Richard Weinberger
Quoted 6 lines · Hajime Tazaki

This RFC patchset is to ask opinions from UML people, whether LKL codes is good to integrate into UML code base. We wish to have any kind of feedback from your kind reviews. There are numbers of commits which should be asked for reviews to other mailing lists; we will do it later once we got discussed in this mailing list.

Quoted 8 lines

Thanks a lot for doing this, this effort is much appreciated! :-)

Quoted 3 lines
# sorry for the long list of patches: we can make it smaller by only
  including basic set of LKL (e.g., removing foreign OS support, etc) if
  you wish.

Let use see how the review goes. First I'll give it a high level review to make sure we all talk about the same things.

Thanks.

Quoted 3 lines

Please CC [email protected] for the next patch round. Integrating LKL (into arch/um/) is something which needs more audience and feedback from Arnd Bergmann, our global arch maintainer.

Sure, will Cc.

Quoted 30 lines
Quoted 21 lines

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

Quoted 8 lines

Milestone
=========
This patches is just 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.

1. Put LKL code under arch/um (arch/um/lkl), and build it in a separate way from UML.

Quoted 8 lines

Makes sense.

Quoted 1 line

2. Share common parts of implementation between UML and LKL.

Since both UML and LKL are usermode ports there is a lot of potential. From my side it is also no big deal if there is some duplication which can be resolved in later releases. Unifiing needs deep thoughts and miding odd corner cases.

I understand.

Quoted 3 lines
Quoted 1 line

3. Reimplement UML features with LKL API (if we wish)

Yep. In the last release UML got virtio support, so there is hope. ;-)

Good news.

Quoted 6 lines
Quoted 3 lines

For the step 1, we put LKL as one of SUBARCH in order to make less effort to integrate (make ARCH=um SUBARCH=lkl). The modification to existing UML code is trying to be minimized.

I'm not sure if SUBARCH is the right approach. How do I build a i386 lkl on x86_64?

This is currently handled under tools/lkl: building arch/um/lkl part only requires toolchain information (e.g., CROSS_COMPILE=).

So to build i386 liblkl.a, do make ARCH=um SUBARCH=lkl, which might not be intuitive..

Quoted 1 line

Maybe we can use another variable like UMMODE={library,kernel}?

We will try to find this way to switch the mode instead.

Quoted 6 lines
Quoted 6 lines

The RFC patches also includes and a bit of step 2 as a proof of possibility to share the code. For this, we used the virtio device code of LKL and use it from UML by enabling virtio-mmio driver with UML code.

Quoted 7 lines
Quoted 5 lines

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

% cd tools/lkl
% make

Is there a reason why tool/lkl is not under arch/um?

I thought that this way makes clear distinction between host hardware/environment *dependent* (tools/lkl) part and *independent* (arch/um/lkl).

We can rename it to tools/um instead.

But if using new tools directory makes noisy, we would try to move those under arch/um.

-- Hajime

maintainer
#57 lore raw
In reply to Hajime Tazaki
Quoted 4 lines · Hajime Tazaki

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

[snip]

Can you comment a bit on what's what?

For example, I look at patch 24 ("lkl tools: virtio: add network device support") and wonder what that really is? Is it a hypervisor-side implementation of the virtio-net device? If so, why is that considered "tools"? (In ARCH=um, the hv-code usually lives in arch/um/drivers/*_user.c or similar.)

Also, taking that as an example again, I think that's something we should rather leave out initially - it looks like it has hooks into DPDK and all kinds of other network interfaces on the host, which duplicates a lot of existing functionality in ARCH=um.

Additionally, we (Intel) recently contributed a vhost-user backend, so we don't really *need* a hypervisor implementation of e.g. DPDK integration at all, that should be possible over vhost-user instead.

Looking further at the series - many of your patches really need better commit logs explaining what and why they do something. Particularly the reverts, but even trivial patches like the first one in the series.

patch 2: doesn't explain why it's necessary - how is this not covered by adding a "config SOMETHING\n def_bool y" in the architecture?

patch 4: kernel-doc doesn't parse, it's also very awkward to add this without any users, why not add a very simple version of the struct with the first patch needing it, and then extend it in each next patch?

[oops, out of time, will continue later]

johannes

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

#58 lore raw

Hello Johannes,

Thanks for the review.

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

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

Quoted 6 lines

[snip]

Can you comment a bit on what's what?

For example, I look at patch 24 ("lkl tools: virtio: add network device support") and wonder what that really is?

Indeed.... We will describe more to be understandable.

Quoted 3 lines

Is it a hypervisor-side implementation of the virtio-net device? If so, why is that considered "tools"? (In ARCH=um, the hv-code usually lives in arch/um/drivers/*_user.c or similar.)

Yes, this was a device (hv)-side implementation.

LKL currently takes 2-stage build: pure kernel part (arch/um/lkl) and userspace one (tools/lkl). Though I think it's good to have clear distinction in different directories, we can move tools/lkl under arch/um, if this is the better way.

Quoted 8 lines

Also, taking that as an example again, I think that's something we should rather leave out initially - it looks like it has hooks into DPDK and all kinds of other network interfaces on the host, which duplicates a lot of existing functionality in ARCH=um.

Additionally, we (Intel) recently contributed a vhost-user backend, so we don't really *need* a hypervisor implementation of e.g. DPDK integration at all, that should be possible over vhost-user instead.

I understand.

If there is a need for in-process virtio device implementation (as LKL does), connecting to vanilla virtio mmio driver, I hope it's still valuable.

Quoted 3 lines

Looking further at the series - many of your patches really need better commit logs explaining what and why they do something. Particularly the reverts, but even trivial patches like the first one in the series.

thanks. the revert commits are required for Windows host target, which uses '_' prefix for the symbols.

We will refine the log thorough the all commits and get you back.

Quoted 2 lines

patch 2: doesn't explain why it's necessary - how is this not covered by adding a "config SOMETHING\n def_bool y" in the architecture?

ah, good catch.
maybe giving an example of the contents of auto.conf should be helpful. We will address this in next patchset.

Quoted 3 lines

patch 4: kernel-doc doesn't parse, it's also very awkward to add this without any users, why not add a very simple version of the struct with the first patch needing it, and then extend it in each next patch?

I agree to start with simple struct and expand it afterward. We will address this in next round.

kernel-doc is something we didn't test so far.
We will also test in advance.

Quoted 1 line

[oops, out of time, will continue later]

Thank you again for the detailed review.

-- Hajime

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

#59 lore raw

v2 cover Unifying LKL into UML

In reply to Hajime Tazaki

This RFC patchset is to ask opinions from folks, whether LKL codes is good to integrate into UML code base. We wish to have any kind of feedback from your kind reviews. There are numbers of commits which should be asked for reviews to other mailing lists; we will do it later once we got discussed in this mailing list.

# sorry for the long list of patches: we can make it smaller by only
  including basic set of LKL (e.g., removing foreign OS support, etc) if
  you wish.

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 just 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.

1. Put LKL code under arch/um (arch/um/lkl), and build it in a separate way from UML.
2. Share common parts of implementation between UML and LKL.
3. Reimplement UML features with LKL API (if we wish)

For the step 1, we put LKL as one of UMMODE in order to make less effort to integrate (make ARCH=um UMMODE=library). The modification to existing UML code is trying to be minimized.

The RFC patches also includes and a bit of step 2 as a proof of possibility to share the code. For this, we used the virtio device code of LKL and use it from UML by enabling virtio-mmio driver with UML code.

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

% cd tools/lkl
% make

will build LKL as a object file, it will install it in tools/lkl/lib together with the headers files in tools/lkl/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

* tests/net-test - a simple applications that uses network feature of LKL and exercises the basic network-related APIs

* fs2tar - a tool that converts a filesystem image to a tar archive

* cptofs/cpfromfs - a tool that copies files to/from a filesystem image

% 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 POSIX and Windows 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 (not included in this RFC) 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 73625ed66389d4c620520058d828f43a93ab4d0c:

um: irq: Fix LAST_IRQ usage in init_IRQ() (2019-09-16 08:38:58 +0200)

are available in the Git repository at:

git://github.com/thehajime/linux 61b15bfb52c7f1f066685c90a1cfe8346b3faec9
https://github.com/thehajime/linux/tree/upstream-to-uml-5.5-rc1-v2

Andreas Abel (1):
kallsyms: Add a config option to select section for kallsyms

Hajime Tazaki (6):
lkl: add system call hijack support
scripts: revert CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX patches
lkl: Android ARM (arm/arm64) support
um lkl: add CI tests
um: use lkl virtio_net_tap device as UML device
um: add lkl virtio-blk device

Octavian Purdila (29):
asm-generic: atomic64: allow using generic atomic64 on 64bit platforms
arch: add __SYSCALL_DEFINE_ARCH
lkl: architecture skeleton for Linux kernel library
lkl: host interface
lkl: memory handling
lkl: kernel threads support
lkl: interrupt support
lkl: system call interface and application API
lkl: timers, time and delay support
lkl: memory mapped I/O support
lkl: basic kernel console support
lkl: initialization and cleanup
lkl: plug in the build system
lkl tools: skeleton for host side library, tests and tools lkl tools: host lib: add utilities functions
lkl tools: host lib: memory mapped I/O helpers
lkl tools: host lib: virtio devices
lkl tools: host lib: virtio block device
lkl tools: host lib: filesystem helpers
lkl tools: host lib: posix host operations
lkl tools: "boot" test
lkl tools: tool that reads/writes to/from a filesystem image lkl tools: tool that converts a filesystem image to tar lkl tools: virtio: add network device support
checkpatch: avoid showing BIT_ULL warnings for tools/ files lkl tools: add lklfuse
lkl: add documentation
lkl: add support for Windows hosts
lkl tools: add support for Windows host

Thomas Liebetraut (1):
tools: Add the lkl host library to the common tools Makefile

 .circleci/config.yml                       | 276 ++++++
 Documentation/virt/uml/lkl.txt             | 453 ++++++++++
 MAINTAINERS                                |   8 +
 Makefile                                   |   4 +-
 arch/Kconfig                               |   6 +
 arch/um/Kconfig                            |  32 +-
 arch/um/Makefile                           | 151 +---
 arch/um/Makefile.um                        | 152 ++++
 arch/um/configs/x86_64_defconfig           |   6 +
 arch/um/include/asm/Kbuild                 |   1 +
 arch/um/include/asm/io.h                   |   4 +
 arch/um/kernel/syscall.c                   |  53 ++
 arch/um/lkl/.gitignore                     |   2 +
 arch/um/lkl/Kconfig                        |  91 ++
 arch/um/lkl/Kconfig.debug                  |   0
 arch/um/lkl/Makefile                       |  69 ++
 arch/um/lkl/auto.conf                      |   1 +
 arch/um/lkl/configs/lkl_defconfig          |  91 ++
 arch/um/lkl/include/asm/Kbuild             |  80 ++
 arch/um/lkl/include/asm/bitsperlong.h      |  11 +
 arch/um/lkl/include/asm/byteorder.h        |   7 +
 arch/um/lkl/include/asm/cpu.h              |  14 +
 arch/um/lkl/include/asm/elf.h              |  15 +
 arch/um/lkl/include/asm/host_ops.h         |  10 +
 arch/um/lkl/include/asm/io.h               | 104 +++
 arch/um/lkl/include/asm/irq.h              |  15 +
 arch/um/lkl/include/asm/mutex.h            |   7 +
 arch/um/lkl/include/asm/page.h             |  14 +
 arch/um/lkl/include/asm/pgtable.h          |  62 ++
 arch/um/lkl/include/asm/processor.h        |  60 ++
 arch/um/lkl/include/asm/ptrace.h           |  25 +
 arch/um/lkl/include/asm/sched.h            |  23 +
 arch/um/lkl/include/asm/setup.h            |   7 +
 arch/um/lkl/include/asm/syscalls.h         |  18 +
 arch/um/lkl/include/asm/syscalls_32.h      |  43 +
 arch/um/lkl/include/asm/thread_info.h      |  70 ++
 arch/um/lkl/include/asm/tlb.h              |  12 +
 arch/um/lkl/include/asm/uaccess.h          |  64 ++
 arch/um/lkl/include/asm/unistd.h           |  29 +
 arch/um/lkl/include/asm/unistd_32.h        |  31 +
 arch/um/lkl/include/asm/vmlinux.lds.h      |  14 +
 arch/um/lkl/include/asm/xor.h              |   9 +
 arch/um/lkl/include/system/stdarg.h        |   2 +
 arch/um/lkl/include/uapi/asm/Kbuild        |   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/host_ops.h    | 153 ++++
 arch/um/lkl/include/uapi/asm/irq.h         |  36 +
 arch/um/lkl/include/uapi/asm/sigcontext.h  |  16 +
 arch/um/lkl/include/uapi/asm/siginfo.h     |  11 +
 arch/um/lkl/include/uapi/asm/swab.h        |  11 +
 arch/um/lkl/include/uapi/asm/syscalls.h    | 348 ++++++++
 arch/um/lkl/include/uapi/asm/unistd.h      |  18 +
 arch/um/lkl/kernel/Makefile                |   4 +
 arch/um/lkl/kernel/asm-offsets.c           |   2 +
 arch/um/lkl/kernel/console.c               |  42 +
 arch/um/lkl/kernel/cpu.c                   | 223 +++++
 arch/um/lkl/kernel/irq.c                   | 193 +++++
 arch/um/lkl/kernel/misc.c                  |  60 ++
 arch/um/lkl/kernel/setup.c                 | 193 +++++
 arch/um/lkl/kernel/syscalls.c              | 246 ++++++
 arch/um/lkl/kernel/syscalls_32.c           | 159 ++++
 arch/um/lkl/kernel/threads.c               | 227 +++++
 arch/um/lkl/kernel/time.c                  | 145 ++++
 arch/um/lkl/kernel/vmlinux.lds.S           |  51 ++
 arch/um/lkl/mm/Makefile                    |   1 +
 arch/um/lkl/mm/bootmem.c                   |  66 ++
 arch/um/lkl/scripts/headers_install.py     | 195 +++++
 arch/um/os-Linux/Makefile                  |   5 +
 arch/um/os-Linux/lkl_dev.c                 | 188 +++++
 certs/system_certificates.S                |  16 +-
 include/asm-generic/atomic64.h             |   2 +
 include/asm-generic/export.h               |  34 +-
 include/asm-generic/vmlinux.lds.h          | 279 ++++---
 include/linux/compiler_attributes.h        |   4 +
 include/linux/export.h                     |  23 +-
 include/linux/linkage.h                    |  12 +-
 include/linux/syscalls.h                   |   6 +
 init/Kconfig                               |  12 +
 lib/.gitignore                             |   2 +
 lib/raid6/.gitignore                       |   1 +
 scripts/.gitignore                         |   2 +
 scripts/Makefile.build                     |   9 +-
 scripts/adjust_autoksyms.sh                |   6 +
 scripts/basic/.gitignore                   |   1 +
 scripts/checkpatch.pl                      |  13 +-
 scripts/depmod.sh                          |  25 +-
 scripts/genksyms/genksyms.c                |  11 +-
 scripts/kallsyms.c                         |  54 +-
 scripts/kconfig/.gitignore                 |   1 +
 scripts/link-vmlinux.sh                    |  10 +
 scripts/mod/.gitignore                     |   1 +
 scripts/mod/modpost.c                      |  30 +-
 tools/Makefile                             |  11 +-
 tools/lkl/.gitignore                       |  15 +
 tools/lkl/Build                            |   6 +
 tools/lkl/Makefile                         | 130 +++
 tools/lkl/Makefile.autoconf                | 114 +++
 tools/lkl/Targets                          |  25 +
 tools/lkl/bin/lkl-hijack.sh                |  23 +
 tools/lkl/cptofs.c                         | 635 ++++++++++++++
 tools/lkl/fs2tar.c                         | 410 +++++++++
 tools/lkl/include/.gitignore               |   1 +
 tools/lkl/include/lkl.h                    | 928 +++++++++++++++++++++
 tools/lkl/include/lkl_config.h             |  61 ++
 tools/lkl/include/lkl_host.h               | 160 ++++
 tools/lkl/include/mingw32/sys/socket.h     |   4 +
 tools/lkl/lib/.gitignore                   |   3 +
 tools/lkl/lib/Build                        |  26 +
 tools/lkl/lib/Makefile                     |  33 +
 tools/lkl/lib/config.c                     | 793 ++++++++++++++++++
 tools/lkl/lib/dbg.c                        | 300 +++++++
 tools/lkl/lib/dbg_handler.c                |  44 +
 tools/lkl/lib/endian.h                     |  31 +
 tools/lkl/lib/fs.c                         | 433 ++++++++++
 tools/lkl/lib/hijack/Build                 |   4 +
 tools/lkl/lib/hijack/hijack.c              | 620 ++++++++++++++
 tools/lkl/lib/hijack/init.c                | 252 ++++++
 tools/lkl/lib/hijack/init.h                |   8 +
 tools/lkl/lib/hijack/xlate.c               | 613 ++++++++++++++
 tools/lkl/lib/hijack/xlate.h               |  13 +
 tools/lkl/lib/iomem.c                      |  88 ++
 tools/lkl/lib/iomem.h                      |  15 +
 tools/lkl/lib/jmp_buf.c                    |  14 +
 tools/lkl/lib/jmp_buf.h                    |   8 +
 tools/lkl/lib/net.c                        | 818 ++++++++++++++++++
 tools/lkl/lib/nt-host.c                    | 375 +++++++++
 tools/lkl/lib/posix-host.c                 | 439 ++++++++++
 tools/lkl/lib/utils.c                      | 266 ++++++
 tools/lkl/lib/virtio.c                     | 644 ++++++++++++++
 tools/lkl/lib/virtio.h                     | 115 +++
 tools/lkl/lib/virtio_blk.c                 | 132 +++
 tools/lkl/lib/virtio_net.c                 | 345 ++++++++
 tools/lkl/lib/virtio_net_dpdk.c            | 480 +++++++++++
 tools/lkl/lib/virtio_net_fd.c              | 195 +++++
 tools/lkl/lib/virtio_net_fd.h              |  50 ++
 tools/lkl/lib/virtio_net_macvtap.c         |  32 +
 tools/lkl/lib/virtio_net_pipe.c            |  76 ++
 tools/lkl/lib/virtio_net_raw.c             |  94 +++
 tools/lkl/lib/virtio_net_tap.c             | 111 +++
 tools/lkl/lib/virtio_net_vde.c             | 168 ++++
 tools/lkl/lklfuse.c                        | 658 +++++++++++++++
 tools/lkl/scripts/checkpatch.sh            |  60 ++
 tools/lkl/scripts/lkl-jenkins.sh           |  21 +
 tools/lkl/tests/Build                      |   3 +
 tools/lkl/tests/boot.c                     | 562 +++++++++++++
 tools/lkl/tests/boot.sh                    |   9 +
 tools/lkl/tests/cla.c                      | 159 ++++
 tools/lkl/tests/cla.h                      |  33 +
 tools/lkl/tests/disk.c                     | 189 +++++
 tools/lkl/tests/disk.sh                    |  70 ++
 tools/lkl/tests/hijack-test.sh             | 760 +++++++++++++++++
 tools/lkl/tests/lklfuse.sh                 | 110 +++
 tools/lkl/tests/net-setup.sh               | 134 +++
 tools/lkl/tests/net-test.c                 | 317 +++++++
 tools/lkl/tests/net.sh                     | 186 +++++
 tools/lkl/tests/run.py                     | 182 ++++
 tools/lkl/tests/run_netperf.sh             |  98 +++
 tools/lkl/tests/tap13.py                   | 209 +++++
 tools/lkl/tests/test.c                     | 126 +++
 tools/lkl/tests/test.h                     |  72 ++
 tools/lkl/tests/test.sh                    | 240 ++++++
 tools/lkl/tests/valgrind.supp              |  85 ++
 tools/lkl/tests/valgrind2xunit.py          |  69 ++
 usr/initramfs_data.S                       |   4 +-
 165 files changed, 19489 insertions(+), 354 deletions(-)
 create mode 100644 .circleci/config.yml
 create mode 100644 Documentation/virt/uml/lkl.txt
 create mode 100644 arch/um/Makefile.um
 create mode 100644 arch/um/lkl/.gitignore
 create mode 100644 arch/um/lkl/Kconfig
 create mode 100644 arch/um/lkl/Kconfig.debug
 create mode 100644 arch/um/lkl/Makefile
 create mode 100644 arch/um/lkl/auto.conf
 create mode 100644 arch/um/lkl/configs/lkl_defconfig
 create mode 100644 arch/um/lkl/include/asm/Kbuild
 create mode 100644 arch/um/lkl/include/asm/bitsperlong.h
 create mode 100644 arch/um/lkl/include/asm/byteorder.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/host_ops.h
 create mode 100644 arch/um/lkl/include/asm/io.h
 create mode 100644 arch/um/lkl/include/asm/irq.h
 create mode 100644 arch/um/lkl/include/asm/mutex.h
 create mode 100644 arch/um/lkl/include/asm/page.h
 create mode 100644 arch/um/lkl/include/asm/pgtable.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/setup.h
 create mode 100644 arch/um/lkl/include/asm/syscalls.h
 create mode 100644 arch/um/lkl/include/asm/syscalls_32.h
 create mode 100644 arch/um/lkl/include/asm/thread_info.h
 create mode 100644 arch/um/lkl/include/asm/tlb.h
 create mode 100644 arch/um/lkl/include/asm/uaccess.h
 create mode 100644 arch/um/lkl/include/asm/unistd.h
 create mode 100644 arch/um/lkl/include/asm/unistd_32.h
 create mode 100644 arch/um/lkl/include/asm/vmlinux.lds.h
 create mode 100644 arch/um/lkl/include/asm/xor.h
 create mode 100644 arch/um/lkl/include/system/stdarg.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/irq.h
 create mode 100644 arch/um/lkl/include/uapi/asm/sigcontext.h
 create mode 100644 arch/um/lkl/include/uapi/asm/siginfo.h
 create mode 100644 arch/um/lkl/include/uapi/asm/swab.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/kernel/Makefile
 create mode 100644 arch/um/lkl/kernel/asm-offsets.c
 create mode 100644 arch/um/lkl/kernel/console.c
 create mode 100644 arch/um/lkl/kernel/cpu.c
 create mode 100644 arch/um/lkl/kernel/irq.c
 create mode 100644 arch/um/lkl/kernel/misc.c
 create mode 100644 arch/um/lkl/kernel/setup.c
 create mode 100644 arch/um/lkl/kernel/syscalls.c
 create mode 100644 arch/um/lkl/kernel/syscalls_32.c
 create mode 100644 arch/um/lkl/kernel/threads.c
 create mode 100644 arch/um/lkl/kernel/time.c
 create mode 100644 arch/um/lkl/kernel/vmlinux.lds.S
 create mode 100644 arch/um/lkl/mm/Makefile
 create mode 100644 arch/um/lkl/mm/bootmem.c
 create mode 100755 arch/um/lkl/scripts/headers_install.py
 create mode 100644 arch/um/os-Linux/lkl_dev.c
 create mode 100644 tools/lkl/.gitignore
 create mode 100644 tools/lkl/Build
 create mode 100644 tools/lkl/Makefile
 create mode 100644 tools/lkl/Makefile.autoconf
 create mode 100644 tools/lkl/Targets
 create mode 100755 tools/lkl/bin/lkl-hijack.sh
 create mode 100644 tools/lkl/cptofs.c
 create mode 100644 tools/lkl/fs2tar.c
 create mode 100644 tools/lkl/include/.gitignore
 create mode 100644 tools/lkl/include/lkl.h
 create mode 100644 tools/lkl/include/lkl_config.h
 create mode 100644 tools/lkl/include/lkl_host.h
 create mode 100644 tools/lkl/include/mingw32/sys/socket.h
 create mode 100644 tools/lkl/lib/.gitignore
 create mode 100644 tools/lkl/lib/Build
 create mode 100644 tools/lkl/lib/Makefile
 create mode 100644 tools/lkl/lib/config.c
 create mode 100644 tools/lkl/lib/dbg.c
 create mode 100644 tools/lkl/lib/dbg_handler.c
 create mode 100644 tools/lkl/lib/endian.h
 create mode 100644 tools/lkl/lib/fs.c
 create mode 100644 tools/lkl/lib/hijack/Build
 create mode 100644 tools/lkl/lib/hijack/hijack.c
 create mode 100644 tools/lkl/lib/hijack/init.c
 create mode 100644 tools/lkl/lib/hijack/init.h
 create mode 100644 tools/lkl/lib/hijack/xlate.c
 create mode 100644 tools/lkl/lib/hijack/xlate.h
 create mode 100644 tools/lkl/lib/iomem.c
 create mode 100644 tools/lkl/lib/iomem.h
 create mode 100644 tools/lkl/lib/jmp_buf.c
 create mode 100644 tools/lkl/lib/jmp_buf.h
 create mode 100644 tools/lkl/lib/net.c
 create mode 100644 tools/lkl/lib/nt-host.c
 create mode 100644 tools/lkl/lib/posix-host.c
 create mode 100644 tools/lkl/lib/utils.c
 create mode 100644 tools/lkl/lib/virtio.c
 create mode 100644 tools/lkl/lib/virtio.h
 create mode 100644 tools/lkl/lib/virtio_blk.c
 create mode 100644 tools/lkl/lib/virtio_net.c
 create mode 100644 tools/lkl/lib/virtio_net_dpdk.c
 create mode 100644 tools/lkl/lib/virtio_net_fd.c
 create mode 100644 tools/lkl/lib/virtio_net_fd.h
 create mode 100644 tools/lkl/lib/virtio_net_macvtap.c
 create mode 100644 tools/lkl/lib/virtio_net_pipe.c
 create mode 100644 tools/lkl/lib/virtio_net_raw.c
 create mode 100644 tools/lkl/lib/virtio_net_tap.c
 create mode 100644 tools/lkl/lib/virtio_net_vde.c
 create mode 100644 tools/lkl/lklfuse.c
 create mode 100755 tools/lkl/scripts/checkpatch.sh
 create mode 100755 tools/lkl/scripts/lkl-jenkins.sh
 create mode 100644 tools/lkl/tests/Build
 create mode 100644 tools/lkl/tests/boot.c
 create mode 100755 tools/lkl/tests/boot.sh
 create mode 100644 tools/lkl/tests/cla.c
 create mode 100644 tools/lkl/tests/cla.h
 create mode 100644 tools/lkl/tests/disk.c
 create mode 100755 tools/lkl/tests/disk.sh
 create mode 100755 tools/lkl/tests/hijack-test.sh
 create mode 100755 tools/lkl/tests/lklfuse.sh
 create mode 100644 tools/lkl/tests/net-setup.sh
 create mode 100644 tools/lkl/tests/net-test.c
 create mode 100755 tools/lkl/tests/net.sh
 create mode 100755 tools/lkl/tests/run.py
 create mode 100755 tools/lkl/tests/run_netperf.sh
 create mode 100644 tools/lkl/tests/tap13.py
 create mode 100644 tools/lkl/tests/test.c
 create mode 100644 tools/lkl/tests/test.h
 create mode 100644 tools/lkl/tests/test.sh
 create mode 100644 tools/lkl/tests/valgrind.supp
 create mode 100755 tools/lkl/tests/valgrind2xunit.py
Signature · 1 line
2.20.1 (Apple Git-117)
#60 lore raw

RFC v2 1/37 asm-generic: atomic64: allow using generic atomic64 on 64bit platforms

From: Octavian Purdila <[email protected]>

With CONFIG_64BIT enabled, atomic64 via CONFIG_GENERIC_ATOMIC64 options are not compiled due to type conflict of atomic64_t defined in linux/type.h.

This commit fixes the issue and allow using generic atomic64 ops.

---
 include/asm-generic/atomic64.h | 2 ++
 1 file changed, 2 insertions(+)
include/asm-generic/atomic64.h +2 -0
index 370f01d4450f..9b15847baae5 100644
@@ -9,9 +9,11 @@
 #define _ASM_GENERIC_ATOMIC64_H
 #include <linux/types.h>
 
+#ifndef CONFIG_64BIT
 typedef struct {
 	s64 counter;
 } atomic64_t;
+#endif
 
 #define ATOMIC64_INIT(i)	{ (i) }
 
Signature · 1 line
2.20.1 (Apple Git-117)
#61 lore raw

Re: [RFC v2 01/37] asm-generic: atomic64: allow using generic atomic64 on 64bit platforms

Quoted 8 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

With CONFIG_64BIT enabled, atomic64 via CONFIG_GENERIC_ATOMIC64 options are not compiled due to type conflict of atomic64_t defined in linux/type.h.

This commit fixes the issue and allow using generic atomic64 ops.

Hmm, why is this specific to LKL?
This need a review from core developers.

Quoted 29 lines
---
 include/asm-generic/atomic64.h | 2 ++
 1 file changed, 2 insertions(+)
include/asm-generic/atomic64.h +2 -1
index 370f01d4450f..9b15847baae5 100644
@@ -9,9 +9,11 @@
 #define _ASM_GENERIC_ATOMIC64_H
 #include <linux/types.h>
 
+#ifndef CONFIG_64BIT
 typedef struct {
        s64 counter;
 } atomic64_t;
+#endif
 
 #define ATOMIC64_INIT(i)       { (i) }
 
--

2.20.1 (Apple Git-117)

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

Signature · 2 lines
Thanks,
//richard
#62 lore raw

Re: [RFC v2 01/37] asm-generic: atomic64: allow using generic atomic64 on 64bit platforms

Quoted 5 lines · Richard Weinberger
Quoted 3 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

Quoted 7 lines
Quoted 5 lines

With CONFIG_64BIT enabled, atomic64 via CONFIG_GENERIC_ATOMIC64 options are not compiled due to type conflict of atomic64_t defined in linux/type.h.

This commit fixes the issue and allow using generic atomic64 ops.

Hmm, why is this specific to LKL?

Currently, LKL is only the user which defines GENERIC_ATOMIC64 (lib/atomic64.c) under CONFIG_64BIT environment. Thus, there would be no issues in the current tree.

If you manually define select GENERIC_ATOMIC64 in UML's Kconfig and build it on a 64BIT host, the same problem would happen.

Quoted 1 line

This need a review from core developers.

I will explicitly Cc to maintainers (ATOMIC INFRASTRUCTURE) from the next round.

Thanks,

-- Hajime

Quoted 20 lines
Quoted 20 lines
---
 include/asm-generic/atomic64.h | 2 ++
 1 file changed, 2 insertions(+)
include/asm-generic/atomic64.h +2 -0
index 370f01d4450f..9b15847baae5 100644
@@ -9,9 +9,11 @@
 #define _ASM_GENERIC_ATOMIC64_H
 #include <linux/types.h>
 
+#ifndef CONFIG_64BIT
 typedef struct {
        s64 counter;
 } atomic64_t;
+#endif
 
 #define ATOMIC64_INIT(i)       { (i) }
#63 lore raw

RFC v2 2/37 arch: add __SYSCALL_DEFINE_ARCH

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

This allows the architecture code to process the system call definitions. It is used by LKL to create strong typed function definitions for system calls.

---
 include/linux/syscalls.h | 6 ++++++
 1 file changed, 6 insertions(+)
include/linux/syscalls.h +6 -0
index 88145da7d140..77e52fe19923 100644
@@ -203,9 +203,14 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
 }
 #endif
 
+#ifndef __SYSCALL_DEFINE_ARCH
+#define __SYSCALL_DEFINE_ARCH(x, sname, ...)
+#endif
+
 #ifndef SYSCALL_DEFINE0
 #define SYSCALL_DEFINE0(sname)					\
 	SYSCALL_METADATA(_##sname, 0);				\
+	__SYSCALL_DEFINE_ARCH(0, _##sname);			\
 	asmlinkage long sys_##sname(void);			\
 	ALLOW_ERROR_INJECTION(sys_##sname, ERRNO);		\
 	asmlinkage long sys_##sname(void)
@@ -222,6 +227,7 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
 
 #define SYSCALL_DEFINEx(x, sname, ...)				\
 	SYSCALL_METADATA(sname, x, __VA_ARGS__)			\
+	__SYSCALL_DEFINE_ARCH(x, sname, __VA_ARGS__)		\
 	__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
 
 #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)
Signature · 1 line
2.20.1 (Apple Git-117)
#64 lore raw

Re: [RFC v2 02/37] arch: add __SYSCALL_DEFINE_ARCH

Quoted 10 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

This allows the architecture code to process the system call definitions. It is used by LKL to create strong typed function definitions for system calls.

---
 include/linux/syscalls.h | 6 ++++++

Same here, core developers need to agree on this.

Quoted 37 lines
 1 file changed, 6 insertions(+)
include/linux/syscalls.h +6 -1
index 88145da7d140..77e52fe19923 100644
@@ -203,9 +203,14 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
 }
 #endif
 
+#ifndef __SYSCALL_DEFINE_ARCH
+#define __SYSCALL_DEFINE_ARCH(x, sname, ...)
+#endif
+
 #ifndef SYSCALL_DEFINE0
 #define SYSCALL_DEFINE0(sname)                                 \
        SYSCALL_METADATA(_##sname, 0);                          \
+       __SYSCALL_DEFINE_ARCH(0, _##sname);                     \
        asmlinkage long sys_##sname(void);                      \
        ALLOW_ERROR_INJECTION(sys_##sname, ERRNO);              \
        asmlinkage long sys_##sname(void)
@@ -222,6 +227,7 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
 
 #define SYSCALL_DEFINEx(x, sname, ...)                         \
        SYSCALL_METADATA(sname, x, __VA_ARGS__)                 \
+       __SYSCALL_DEFINE_ARCH(x, sname, __VA_ARGS__)            \
        __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
 
 #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)
--

2.20.1 (Apple Git-117)

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

Signature · 2 lines
Thanks,
//richard
#65 lore raw

Re: [RFC v2 02/37] arch: add __SYSCALL_DEFINE_ARCH

Quoted 9 lines · Richard Weinberger
Quoted 7 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

This allows the architecture code to process the system call definitions. It is used by LKL to create strong typed function definitions for system calls.

Quoted 5 lines
Quoted 3 lines
---
 include/linux/syscalls.h | 6 ++++++

Same here, core developers need to agree on this.

Okay, I'll also Cc linux-api@ from the next round.

-- Hajime

#66 lore raw

RFC v2 3/37 lkl: architecture skeleton for Linux kernel library

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Adds the LKL Kconfig, vmlinux linker script, basic architecture headers and miscellaneous basic functions or stubs such as dump_stack(), show_regs() and cpuinfo proc ops.

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.

The kernel configuration is automatically updated to reflect the endianness of the host, 64bit support or the output format for vmlinux's linker script. We do this by looking at the ld's default output format.

---
 MAINTAINERS                                |   8 +
 arch/um/lkl/.gitignore                     |   2 +
 arch/um/lkl/Kconfig                        |  95 ++++++
 arch/um/lkl/Kconfig.debug                  |   0
 arch/um/lkl/configs/lkl_defconfig          |  91 ++++++
 arch/um/lkl/include/asm/Kbuild             |  80 +++++
 arch/um/lkl/include/asm/bitsperlong.h      |  11 +
 arch/um/lkl/include/asm/byteorder.h        |   7 +
 arch/um/lkl/include/asm/cpu.h              |  14 +
 arch/um/lkl/include/asm/elf.h              |  15 +
 arch/um/lkl/include/asm/mutex.h            |   7 +
 arch/um/lkl/include/asm/processor.h        |  60 ++++
 arch/um/lkl/include/asm/ptrace.h           |  25 ++
 arch/um/lkl/include/asm/sched.h            |  23 ++
 arch/um/lkl/include/asm/syscalls.h         |  18 ++
 arch/um/lkl/include/asm/syscalls_32.h      |  43 +++
 arch/um/lkl/include/asm/tlb.h              |  12 +
 arch/um/lkl/include/asm/uaccess.h          |  64 ++++
 arch/um/lkl/include/asm/unistd_32.h        |  31 ++
 arch/um/lkl/include/asm/vmlinux.lds.h      |  14 +
 arch/um/lkl/include/asm/xor.h              |   9 +
 arch/um/lkl/include/uapi/asm/Kbuild        |   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/siginfo.h     |  11 +
 arch/um/lkl/include/uapi/asm/swab.h        |  11 +
 arch/um/lkl/include/uapi/asm/syscalls.h    | 348 +++++++++++++++++++++
 arch/um/lkl/kernel/asm-offsets.c           |   2 +
 arch/um/lkl/kernel/misc.c                  |  60 ++++
 arch/um/lkl/kernel/vmlinux.lds.S           |  51 +++
 30 files changed, 1145 insertions(+)
 create mode 100644 arch/um/lkl/.gitignore
 create mode 100644 arch/um/lkl/Kconfig
 create mode 100644 arch/um/lkl/Kconfig.debug
 create mode 100644 arch/um/lkl/configs/lkl_defconfig
 create mode 100644 arch/um/lkl/include/asm/Kbuild
 create mode 100644 arch/um/lkl/include/asm/bitsperlong.h
 create mode 100644 arch/um/lkl/include/asm/byteorder.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/mutex.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/syscalls.h
 create mode 100644 arch/um/lkl/include/asm/syscalls_32.h
 create mode 100644 arch/um/lkl/include/asm/tlb.h
 create mode 100644 arch/um/lkl/include/asm/uaccess.h
 create mode 100644 arch/um/lkl/include/asm/unistd_32.h
 create mode 100644 arch/um/lkl/include/asm/vmlinux.lds.h
 create mode 100644 arch/um/lkl/include/asm/xor.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/siginfo.h
 create mode 100644 arch/um/lkl/include/uapi/asm/swab.h
 create mode 100644 arch/um/lkl/include/uapi/asm/syscalls.h
 create mode 100644 arch/um/lkl/kernel/asm-offsets.c
 create mode 100644 arch/um/lkl/kernel/misc.c
 create mode 100644 arch/um/lkl/kernel/vmlinux.lds.S
MAINTAINERS +8 -0
index e7a47b5210fd..df8151c6fd9e 100644
@@ -9369,6 +9369,14 @@ F:	Documentation/core-api/atomic_ops.rst
 F:	Documentation/core-api/refcount-vs-atomic.rst
 F:	Documentation/memory-barriers.txt
 
+LINUX KERNEL LIBRARY
+M:	Octavian Purdila <[email protected]>
+M:	Hajime Tazaki <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	arch/um/lkl/
+F:	tools/lkl/
+
 LIS3LV02D ACCELEROMETER DRIVER
 M:	Eric Piel <[email protected]>
 S:	Maintained
arch/um/lkl/.gitignore new file +2 -0
new file mode 100644
index 000000000000..ced1c60d8235
@@ -0,0 +1,2 @@
+kernel/vmlinux.lds
+include/generated
arch/um/lkl/Kconfig new file +95 -0

95 lines not on this page · raw message

arch/um/lkl/Kconfig.debug new file +0 -0
new file mode 100644
index 000000000000..e69de29bb2d1
arch/um/lkl/configs/lkl_defconfig new file +91 -0

91 lines not on this page · raw message

arch/um/lkl/include/asm/Kbuild new file +80 -0

80 lines not on this page · raw message

arch/um/lkl/include/asm/bitsperlong.h new file +11 -0
new file mode 100644
index 000000000000..5745d5e51274
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LKL_BITSPERLONG_H
+#define __LKL_BITSPERLONG_H
+
+#include <uapi/asm/bitsperlong.h>
+
+#define BITS_PER_LONG __BITS_PER_LONG
+
+#define BITS_PER_LONG_LONG 64
+
+#endif
arch/um/lkl/include/asm/byteorder.h new file +7 -0
new file mode 100644
index 000000000000..5d0c4efaa44b
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_BYTEORDER_H
+#define _ASM_LKL_BYTEORDER_H
+
+#include <uapi/asm/byteorder.h>
+
+#endif /* _ASM_LKL_BYTEORDER_H */
arch/um/lkl/include/asm/cpu.h new file +14 -0
new file mode 100644
index 000000000000..d2b8c501c7b1
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_CPU_H
+#define _ASM_LKL_CPU_H
+
+int lkl_cpu_get(void);
+void lkl_cpu_put(void);
+int lkl_cpu_try_run_irq(int irq);
+int lkl_cpu_init(void);
+void lkl_cpu_shutdown(void);
+void lkl_cpu_wait_shutdown(void);
+void lkl_cpu_change_owner(lkl_thread_t owner);
+void lkl_cpu_set_irqs_pending(void);
+
+#endif /* _ASM_LKL_CPU_H */
arch/um/lkl/include/asm/elf.h new file +15 -0
new file mode 100644
index 000000000000..bb2456d638f4
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_ELF_H
+#define _ASM_LKL_ELF_H
+
+#define elf_check_arch(x) 0
+
+#ifdef CONFIG_64BIT
+#define ELF_CLASS ELFCLASS64
+#else
+#define ELF_CLASS ELFCLASS32
+#endif
+
+#define elf_gregset_t long
+#define elf_fpregset_t double
+#endif
arch/um/lkl/include/asm/mutex.h new file +7 -0
new file mode 100644
index 000000000000..492d04183f9c
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_MUTEX_H
+#define _ASM_LKL_MUTEX_H
+
+#include <asm-generic/mutex-dec.h>
+
+#endif
arch/um/lkl/include/asm/processor.h new file +60 -0

60 lines not on this page · raw message

arch/um/lkl/include/asm/ptrace.h new file +25 -0
new file mode 100644
index 000000000000..28199be26dc0
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_PTRACE_H
+#define _ASM_LKL_PTRACE_H
+
+#include <linux/errno.h>
+
+struct task_struct;
+
+#define user_mode(regs) 0
+#define kernel_mode(regs) 1
+#define profile_pc(regs) 0
+#define instruction_pointer(regs) 0
+#define user_stack_pointer(regs) 0
+
+static inline long arch_ptrace(struct task_struct *child, long request,
+			       unsigned long addr, unsigned long data)
+{
+	return -EINVAL;
+}
+
+static inline void ptrace_disable(struct task_struct *child)
+{
+}
+
+#endif
arch/um/lkl/include/asm/sched.h new file +23 -0
new file mode 100644
index 000000000000..4c2635921ec8
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_SCHED_H
+#define _ASM_LKL_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_ops->jmp_buf_set(&current_thread_info()->sched_jb,
+				     schedule);
+	} else {
+		lkl_bug("%s() can be used only for host task\n", __func__);
+	}
+}
+
+void switch_to_host_task(struct task_struct *);
+int host_task_stub(void *unused);
+
+#endif /*  _ASM_LKL_SCHED_H */
arch/um/lkl/include/asm/syscalls.h new file +18 -0
new file mode 100644
index 000000000000..2eaa870a9020
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_SYSCALLS_H
+#define _ASM_LKL_SYSCALLS_H
+
+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_mmap_pgoff
+#define sys_mmap2 sys_mmap_pgoff
+#define sys_clone sys_ni_syscall
+#define sys_vfork sys_ni_syscall
+#define sys_rt_sigreturn sys_ni_syscall
+
+#include <asm-generic/syscalls.h>
+
+#endif /* _ASM_LKL_SYSCALLS_H */
arch/um/lkl/include/asm/syscalls_32.h new file +43 -0

43 lines not on this page · raw message

arch/um/lkl/include/asm/tlb.h new file +12 -0
new file mode 100644
index 000000000000..d474890d317d
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_TLB_H
+#define _ASM_LKL_TLB_H
+
+#define tlb_start_vma(tlb, vma)				do { } while (0)
+#define tlb_end_vma(tlb, vma)				do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, pte, address)	do { } while (0)
+#define tlb_flush(tlb)					do { } while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_LKL_TLB_H */
arch/um/lkl/include/asm/uaccess.h new file +64 -0

64 lines not on this page · raw message

arch/um/lkl/include/asm/unistd_32.h new file +31 -0
new file mode 100644
index 000000000000..8582a55e61e2
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#ifndef __SYSCALL
+#define __SYSCALL(x, y)
+#endif
+
+#if __BITS_PER_LONG == 32
+__SYSCALL(__NR3264_truncate, sys32_truncate64)
+__SYSCALL(__NR3264_ftruncate, sys32_ftruncate64)
+
+#ifdef CONFIG_MMU
+__SYSCALL(__NR3264_mmap, sys32_mmap)
+#endif
+
+__SYSCALL(__NR_wait4, sys32_wait4)
+
+__SYSCALL(__NR_pread64, sys32_pread64)
+__SYSCALL(__NR_pwrite64, sys32_pwrite64)
+
+__SYSCALL(__NR_readahead, sys32_readahead)
+#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
+__SYSCALL(__NR_sync_file_range2, sys32_sync_file_range2)
+#else
+__SYSCALL(__NR_sync_file_range, sys32_sync_file_range)
+#endif
+/* mm/fadvise.c */
+__SYSCALL(__NR3264_fadvise64, sys32_fadvise64_64)
+__SYSCALL(__NR_fallocate, sys32_fallocate)
+
+#endif
arch/um/lkl/include/asm/vmlinux.lds.h new file +14 -0
new file mode 100644
index 000000000000..a3c285882dc4
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LKL_VMLINUX_LDS_H
+#define _LKL_VMLINUX_LDS_H
+
+/* we encode our own __ro_after_init section */
+#define RO_AFTER_INIT_DATA
+
+#ifdef __MINGW32__
+#define RODATA_SECTION .rdata
+#endif
+
+#include <asm-generic/vmlinux.lds.h>
+
+#endif
arch/um/lkl/include/asm/xor.h new file +9 -0
new file mode 100644
index 000000000000..286ce75b5d9d
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_XOR_H
+#define _ASM_LKL_XOR_H
+
+#include <asm-generic/xor.h>
+
+#define XOR_SELECT_TEMPLATE(x) (&xor_block_8regs)
+
+#endif /* _ASM_LKL_XOR_H */
arch/um/lkl/include/uapi/asm/Kbuild new file +9 -0
new file mode 100644
index 000000000000..39d9a1f2e8f5
@@ -0,0 +1,9 @@
+# UAPI Header export list
+
+generic-y += elf.h
+generic-y += kvm_para.h
+generic-y += shmparam.h
+generic-y += timex.h
+
+# no header-y since we need special user headers handling
+# see arch/lkl/script/headers.py
arch/um/lkl/include/uapi/asm/bitsperlong.h new file +13 -0
new file mode 100644
index 000000000000..8b4ebf2b0264
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_BITSPERLONG_H
+#define _ASM_UAPI_LKL_BITSPERLONG_H
+
+#ifdef CONFIG_64BIT
+#define __BITS_PER_LONG 64
+#else
+#define __BITS_PER_LONG 32
+#endif
+
+#define __ARCH_WANT_STAT64
+
+#endif /* _ASM_UAPI_LKL_BITSPERLONG_H */
arch/um/lkl/include/uapi/asm/byteorder.h new file +11 -0
new file mode 100644
index 000000000000..3c4a58d2062f
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_BYTEORDER_H
+#define _ASM_UAPI_LKL_BYTEORDER_H
+
+#if defined(CONFIG_BIG_ENDIAN)
+#include <linux/byteorder/big_endian.h>
+#else
+#include <linux/byteorder/little_endian.h>
+#endif
+
+#endif /* _ASM_UAPI_LKL_BYTEORDER_H */
arch/um/lkl/include/uapi/asm/siginfo.h new file +11 -0
new file mode 100644
index 000000000000..811916cf42c8
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_LKL_SIGINFO_H
+#define _ASM_LKL_SIGINFO_H
+
+#ifdef CONFIG_64BIT
+#define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
+#endif
+
+#include <asm-generic/siginfo.h>
+
+#endif /* _ASM_LKL_SIGINFO_H */
arch/um/lkl/include/uapi/asm/swab.h new file +11 -0
new file mode 100644
index 000000000000..1a1773e1bd35
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_LKL_SWAB_H
+#define _ASM_LKL_SWAB_H
+
+#ifndef __arch_swab32
+#define __arch_swab32(x) ___constant_swab32(x)
+#endif
+
+#include <asm-generic/swab.h>
+
+#endif /* _ASM_LKL_SWAB_H */
arch/um/lkl/include/uapi/asm/syscalls.h new file +348 -0

348 lines not on this page · raw message

arch/um/lkl/kernel/asm-offsets.c new file +2 -0
new file mode 100644
index 000000000000..6be0763698dc
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */
arch/um/lkl/kernel/misc.c new file +60 -0

60 lines not on this page · raw message

arch/um/lkl/kernel/vmlinux.lds.S new file +51 -0

51 lines not on this page · raw message

Signature · 1 line
2.20.1 (Apple Git-117)
#67 lore raw

Re: [RFC v2 03/37] lkl: architecture skeleton for Linux kernel library

Quoted 27 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

Adds the LKL Kconfig, vmlinux linker script, basic architecture headers and miscellaneous basic functions or stubs such as dump_stack(), show_regs() and cpuinfo proc ops.

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.

The kernel configuration is automatically updated to reflect the endianness of the host, 64bit support or the output format for vmlinux's linker script. We do this by looking at the ld's default output format.

Quoted 8 lines

Can we please have this chain cleaned up?
Please see process/submitting-patches.rst.

Quoted 20 lines
---
 MAINTAINERS                                |   8 +
 arch/um/lkl/.gitignore                     |   2 +
 arch/um/lkl/Kconfig                        |  95 ++++++
 arch/um/lkl/Kconfig.debug                  |   0
 arch/um/lkl/configs/lkl_defconfig          |  91 ++++++
 arch/um/lkl/include/asm/Kbuild             |  80 +++++
 arch/um/lkl/include/asm/bitsperlong.h      |  11 +
 arch/um/lkl/include/asm/byteorder.h        |   7 +
 arch/um/lkl/include/asm/cpu.h              |  14 +
 arch/um/lkl/include/asm/elf.h              |  15 +
 arch/um/lkl/include/asm/mutex.h            |   7 +
 arch/um/lkl/include/asm/processor.h        |  60 ++++
 arch/um/lkl/include/asm/ptrace.h           |  25 ++
 arch/um/lkl/include/asm/sched.h            |  23 ++
 arch/um/lkl/include/asm/syscalls.h         |  18 ++
 arch/um/lkl/include/asm/syscalls_32.h      |  43 +++
 arch/um/lkl/include/asm/tlb.h              |  12 +
 arch/um/lkl/include/asm/uaccess.h          |  64 ++++
 arch/um/lkl/include/asm/unistd_32.h        |  31 ++
Quoted 8 lines
 arch/um/lkl/include/asm/vmlinux.lds.h      |  14 +
 arch/um/lkl/include/asm/xor.h              |   9 +
 arch/um/lkl/include/uapi/asm/Kbuild        |   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/siginfo.h     |  11 +
 arch/um/lkl/include/uapi/asm/swab.h        |  11 +
 arch/um/lkl/include/uapi/asm/syscalls.h    | 348 +++++++++++++++++++++

I think this is the first big thing which needs a unification.

In UML we try hard to re-use headers from x86.
We also have some headers in arch/x86/um/.

LKL should do the same. At least try hard to avoid duplication.

Signature · 2 lines
Thanks,
//richard
#68 lore raw

Re: [RFC v2 03/37] lkl: architecture skeleton for Linux kernel library

Quoted 70 lines · Richard Weinberger
Quoted 27 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

Adds the LKL Kconfig, vmlinux linker script, basic architecture headers and miscellaneous basic functions or stubs such as dump_stack(), show_regs() and cpuinfo proc ops.

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.

The kernel configuration is automatically updated to reflect the endianness of the host, 64bit support or the output format for vmlinux's linker script. We do this by looking at the ld's default output format.

Quoted 8 lines

Can we please have this chain cleaned up?
Please see process/submitting-patches.rst.

Quoted 20 lines
---
 MAINTAINERS                                |   8 +
 arch/um/lkl/.gitignore                     |   2 +
 arch/um/lkl/Kconfig                        |  95 ++++++
 arch/um/lkl/Kconfig.debug                  |   0
 arch/um/lkl/configs/lkl_defconfig          |  91 ++++++
 arch/um/lkl/include/asm/Kbuild             |  80 +++++
 arch/um/lkl/include/asm/bitsperlong.h      |  11 +
 arch/um/lkl/include/asm/byteorder.h        |   7 +
 arch/um/lkl/include/asm/cpu.h              |  14 +
 arch/um/lkl/include/asm/elf.h              |  15 +
 arch/um/lkl/include/asm/mutex.h            |   7 +
 arch/um/lkl/include/asm/processor.h        |  60 ++++
 arch/um/lkl/include/asm/ptrace.h           |  25 ++
 arch/um/lkl/include/asm/sched.h            |  23 ++
 arch/um/lkl/include/asm/syscalls.h         |  18 ++
 arch/um/lkl/include/asm/syscalls_32.h      |  43 +++
 arch/um/lkl/include/asm/tlb.h              |  12 +
 arch/um/lkl/include/asm/uaccess.h          |  64 ++++
 arch/um/lkl/include/asm/unistd_32.h        |  31 ++
Quoted 8 lines
 arch/um/lkl/include/asm/vmlinux.lds.h      |  14 +
 arch/um/lkl/include/asm/xor.h              |   9 +
 arch/um/lkl/include/uapi/asm/Kbuild        |   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/siginfo.h     |  11 +
 arch/um/lkl/include/uapi/asm/swab.h        |  11 +
 arch/um/lkl/include/uapi/asm/syscalls.h    | 348 +++++++++++++++++++++
Quoted 7 lines

I think this is the first big thing which needs a unification.

In UML we try hard to re-use headers from x86.
We also have some headers in arch/x86/um/.

LKL should do the same. At least try hard to avoid duplication.

In LKL we tried to avoid coupling the kernel build part to a particular architecture, to make it easier to port it (to different arches, but as well to other OSes or special environments [1][2]). That is the main reason for having two build steps, one for kernel proper, and one for the host. That is why the host part was placed into tools/lkl to make it clear that is not part of the kernel proper.

I think this is one of the biggest differences between UML and LKL and it would be helpful to get feedback of what people think of a potential similar split for UML.

[1] https://www.haiku-os.org/blog/lucian/2010-07-08_booting_lkl_inside_haiku/
[2] https://github.com/lkl/lkl-ntk-driver-poc

#69 lore raw

Re: [RFC v2 03/37] lkl: architecture skeleton for Linux kernel library

In reply to Richard Weinberger
Quoted 1 line · Richard Weinberger

(snip)

Quoted 21 lines
Quoted 12 lines
Quoted 8 lines
Quoted 2 lines

Can we please have this chain cleaned up?
Please see process/submitting-patches.rst.

Do you mean "this chain" by the long list of Signed-off-by lines, or something else ?

We were trying to put all of contributors on the list. I was failed to interpret process/submitting-patches.rst on which part is not appropriate.

If you could be more specific, it would be definitely helpful.

# sorry to disturb you...

btw, currently we have more than 15 patches, which I may need to drop some of them for the first step.

-- Hajime

#70 lore raw

Re: [RFC v2 03/37] lkl: architecture skeleton for Linux kernel library

----- Ursprüngliche Mail -----

Quoted 37 lines

Von: "Hajime Tazaki" <[email protected]>
An: "Richard Weinberger" <[email protected]>
CC: "linux-um" <[email protected]>, "linux-arch" <[email protected]>, "pscollins" <[email protected]>, "levex" <[email protected]>, "mattator" <[email protected]>, "cem" <[email protected]>, "tavi purdila" <[email protected]>, "staal1978" <[email protected]>, "motomuman" <[email protected]>, "jiangshanlai" <[email protected]>, "retrage01" <[email protected]>, "petrosagg" <[email protected]>, "liuyuan" <[email protected]>, "xiaoj" <[email protected]>, "mark" <[email protected]>, "linux-kernel-library" <[email protected]>, "phh" <[email protected]>, "sigmaepsilon92" <[email protected]>, "luca dariz" <[email protected]>, "edisonmcastro" <[email protected]>
Gesendet: Dienstag, 26. November 2019 15:17:26
Betreff: Re: [RFC v2 03/37] lkl: architecture skeleton for Linux kernel library

Quoted 1 line · Richard Weinberger

(snip)

Quoted 21 lines
Quoted 20 lines
Quoted 5 lines
Quoted 2 lines

Can we please have this chain cleaned up?
Please see process/submitting-patches.rst.

Do you mean "this chain" by the long list of Signed-off-by lines, or something else ?

The long list is rather unusual.

Quoted 2 lines

We were trying to put all of contributors on the list. I was failed to interpret process/submitting-patches.rst on which part is not appropriate.

If every contributor is also a Co-Author. Okay. But having such a long list of authors is still a little odd.

Thanks,
//richard

#71 lore raw

Re: [RFC v2 03/37] lkl: architecture skeleton for Linux kernel library

On Wed, 27 Nov 2019 01:02:12 +0900,
Richard Weinberger wrote:

(snip)

Quoted 10 lines
Quoted 2 lines

Do you mean "this chain" by the long list of Signed-off-by lines, or something else ?

The long list is rather unusual.

Quoted 2 lines

We were trying to put all of contributors on the list. I was failed to interpret process/submitting-patches.rst on which part is not appropriate.

If every contributor is also a Co-Author. Okay. But having such a long list of authors is still a little odd.

I've replaced most of Signed-off-by: to Cc: in v3 patches.

-- Hajime

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

#72 lore raw

RFC v2 4/37 lkl: host interface

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

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/lkl/include/asm/host_ops.h      | 10 ++++++++++
 arch/um/lkl/include/uapi/asm/host_ops.h | 26 +++++++++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/host_ops.h
 create mode 100644 arch/um/lkl/include/uapi/asm/host_ops.h
arch/um/lkl/include/asm/host_ops.h new file +10 -0
new file mode 100644
index 000000000000..65850f394b79
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_HOST_OPS_H
+#define _ASM_LKL_HOST_OPS_H
+
+#include "irq.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 +26 -0
new file mode 100644
index 000000000000..7cfb0a93e6a6
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_HOST_OPS_H
+#define _ASM_UAPI_LKL_HOST_OPS_H
+
+/* Defined in {posix,nt}-host.c */
+struct lkl_mutex;
+struct lkl_sem;
+struct lkl_tls_key;
+typedef unsigned long lkl_thread_t;
+struct lkl_jmp_buf {
+	unsigned long buf[32];
+};
+
+/**
+ * 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 {
+};
+
+void lkl_bug(const char *fmt, ...);
+
+#endif
Signature · 1 line
2.20.1 (Apple Git-117)
#73 lore raw

RFC v2 5/37 lkl: memory handling

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

LKL is a non MMU architecture and hence 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 a host operation and the memory size to be used is specified when the kernel is started, in the lkl_start_kernel call.

---
 arch/um/lkl/include/asm/page.h          | 14 ++++++
 arch/um/lkl/include/asm/pgtable.h       | 62 +++++++++++++++++++++++
 arch/um/lkl/include/uapi/asm/host_ops.h |  5 ++
 arch/um/lkl/mm/bootmem.c                | 66 +++++++++++++++++++++++++
 4 files changed, 147 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/page.h
 create mode 100644 arch/um/lkl/include/asm/pgtable.h
 create mode 100644 arch/um/lkl/mm/bootmem.c
arch/um/lkl/include/asm/page.h new file +14 -0
new file mode 100644
index 000000000000..e77f3da22031
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_PAGE_H
+#define _ASM_LKL_PAGE_H
+
+#define CONFIG_KERNEL_RAM_BASE_ADDRESS memory_start
+
+#ifndef __ASSEMBLY__
+void free_mem(void);
+void bootmem_init(unsigned long mem_size);
+#endif
+
+#include <asm-generic/page.h>
+
+#endif /* _ASM_LKL_PAGE_H */
arch/um/lkl/include/asm/pgtable.h new file +62 -0

62 lines not on this page · raw message

arch/um/lkl/include/uapi/asm/host_ops.h +5 -0
index 7cfb0a93e6a6..6bbc94c120be 100644
@@ -17,8 +17,13 @@ struct lkl_jmp_buf {
  * These operations must be provided by a host library or by the application
  * itself.
  *
+ * @mem_alloc - allocate memory
+ * @mem_free - free memory
+ *
  */
 struct lkl_host_operations {
+	void *(*mem_alloc)(unsigned long mem);
+	void (*mem_free)(void *mem);
 };
 
 void lkl_bug(const char *fmt, ...);
arch/um/lkl/mm/bootmem.c new file +66 -0

66 lines not on this page · raw message

Signature · 1 line
2.20.1 (Apple Git-117)
#74 lore raw

Re: [RFC v2 05/37] lkl: memory handling

Quoted 16 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

LKL is a non MMU architecture and hence 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 a host operation and the memory size to be used is specified when the kernel is started, in the lkl_start_kernel call.

Quoted 5 lines
---
 arch/um/lkl/include/asm/page.h          | 14 ++++++
 arch/um/lkl/include/asm/pgtable.h       | 62 +++++++++++++++++++++++
 arch/um/lkl/include/uapi/asm/host_ops.h |  5 ++
 arch/um/lkl/mm/bootmem.c                | 66 +++++++++++++++++++++++++

This is also something which needs unification with UML. UML in NOMMU mode would be LKL then...

--
Thanks,
//richard

#75 lore raw

Re: [RFC v2 05/37] lkl: memory handling

Quoted 24 lines · Richard Weinberger
Quoted 16 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

LKL is a non MMU architecture and hence 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 a host operation and the memory size to be used is specified when the kernel is started, in the lkl_start_kernel call.

Quoted 5 lines
---
 arch/um/lkl/include/asm/page.h          | 14 ++++++
 arch/um/lkl/include/asm/pgtable.h       | 62 +++++++++++++++++++++++
 arch/um/lkl/include/uapi/asm/host_ops.h |  5 ++
 arch/um/lkl/mm/bootmem.c                | 66 +++++++++++++++++++++++++
Quoted 2 lines

This is also something which needs unification with UML. UML in NOMMU mode would be LKL then...

At this moment, I leave those part as is; changing LKL to MMU mode makes less possibility to host various underlying environments (non-Linux hosts, non-x86 subarchs).

If you have nice suggestions (such as adding texts to docs), it would be definitely helpful.

-- Hajime

#76 lore raw

RFC v2 6/37 lkl: kernel threads support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

LKL does not support user processes but it must support kernel threads as part as the normal kernel work-flow. It uses host operations 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 threads 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.

---
 arch/um/lkl/include/asm/thread_info.h   |  70 ++++++++
 arch/um/lkl/include/uapi/asm/host_ops.h |  55 ++++++
 arch/um/lkl/kernel/cpu.c                | 223 +++++++++++++++++++++++
 arch/um/lkl/kernel/threads.c            | 227 ++++++++++++++++++++++++
 4 files changed, 575 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/thread_info.h
 create mode 100644 arch/um/lkl/kernel/cpu.c
 create mode 100644 arch/um/lkl/kernel/threads.c
arch/um/lkl/include/asm/thread_info.h new file +70 -0
new file mode 100644
index 000000000000..da4e75fc7b10
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_THREAD_INFO_H
+#define _ASM_LKL_THREAD_INFO_H
+
+#define THREAD_SIZE	       (4096)
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+#include <asm/processor.h>
+#include <asm/host_ops.h>
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+struct thread_info {
+	struct task_struct *task;
+	unsigned long flags;
+	int preempt_count;
+	mm_segment_t addr_limit;
+	struct lkl_sem *sched_sem;
+	struct lkl_jmp_buf sched_jb;
+	bool dead;
+	lkl_thread_t tid;
+	struct task_struct *prev_sched;
+	unsigned long stackend;
+};
+
+#define INIT_THREAD_INFO(tsk)				\
+{							\
+	.task		= &tsk,				\
+	.preempt_count	= INIT_PREEMPT_COUNT,		\
+	.flags		= 0,				\
+	.addr_limit	= KERNEL_DS,			\
+}
+
+/* how to get the thread information struct from C */
+extern struct thread_info *_current_thread_info;
+static inline struct thread_info *current_thread_info(void)
+{
+	return _current_thread_info;
+}
+
+/* thread information allocation */
+unsigned long *alloc_thread_stack_node(struct task_struct *, int node);
+void free_thread_stack(struct task_struct *tsk);
+
+void threads_init(void);
+void threads_cleanup(void);
+
+#define TIF_SYSCALL_TRACE		0
+#define TIF_NOTIFY_RESUME		1
+#define TIF_SIGPENDING			2
+#define TIF_NEED_RESCHED		3
+#define TIF_RESTORE_SIGMASK		4
+#define TIF_MEMDIE			5
+#define TIF_NOHZ			6
+#define TIF_SCHED_JB			7
+#define TIF_HOST_THREAD			8
+
+#define __HAVE_THREAD_FUNCTIONS
+
+#define task_thread_info(task)	((struct thread_info *)(task)->stack)
+#define task_stack_page(task)	((task)->stack)
+void setup_thread_stack(struct task_struct *p, struct task_struct *org);
+#define end_of_stack(p) (&task_thread_info(p)->stackend)
+
+#endif /* __ASSEMBLY__ */
+
+#endif
arch/um/lkl/include/uapi/asm/host_ops.h +55 -0

70 lines not on this page · raw message

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

223 lines not on this page · raw message

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

227 lines not on this page · raw message

Signature · 1 line
2.20.1 (Apple Git-117)
#77 lore raw

RFC v2 7/37 lkl: interrupt support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add APIs that allows the host to reserve and free and interrupt number and also to trigger an interrupt.

The trigger operation will simply store the interrupt data in queue. The interrupt handler is run later, at the first opportunity it has to avoid races with any kernel threads.

Currently, interrupts are run on the first interrupt enable operation if interrupts are disabled and if we are not already in interrupt context.

When triggering an interrupt, it uses GCC's built-in functions for atomic memory access to synchronize and simple boolean flags.

---
 arch/um/lkl/include/asm/irq.h             |  13 ++
 arch/um/lkl/include/uapi/asm/irq.h        |  36 ++++
 arch/um/lkl/include/uapi/asm/sigcontext.h |  16 ++
 arch/um/lkl/kernel/irq.c                  | 193 ++++++++++++++++++++++
 4 files changed, 258 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/irq.h
 create mode 100644 arch/um/lkl/include/uapi/asm/irq.h
 create mode 100644 arch/um/lkl/include/uapi/asm/sigcontext.h
 create mode 100644 arch/um/lkl/kernel/irq.c
arch/um/lkl/include/asm/irq.h new file +13 -0
new file mode 100644
index 000000000000..948fc54cb76c
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_IRQ_H
+#define _ASM_LKL_IRQ_H
+
+#define IRQ_STATUS_BITS		(sizeof(long) * 8)
+#define NR_IRQS			((int)(IRQ_STATUS_BITS * IRQ_STATUS_BITS))
+
+void run_irqs(void);
+void set_irq_pending(int irq);
+
+#include <uapi/asm/irq.h>
+
+#endif
arch/um/lkl/include/uapi/asm/irq.h new file +36 -0
new file mode 100644
index 000000000000..666628b233eb
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_IRQ_H
+#define _ASM_UAPI_LKL_IRQ_H
+
+/**
+ * lkl_trigger_irq - generate an interrupt
+ *
+ * This function is used by the device host side to signal its Linux counterpart
+ * that some event happened.
+ *
+ * @irq - the irq number to signal
+ */
+int lkl_trigger_irq(int irq);
+
+/**
+ * lkl_get_free_irq - find and reserve a free IRQ number
+ *
+ * This function is called by the host device code to find an unused IRQ number
+ * and reserved it for its own use.
+ *
+ * @user - a string to identify the user
+ * @returns - and irq number that can be used by request_irq or an negative
+ * value in case of an error
+ */
+int lkl_get_free_irq(const char *user);
+
+/**
+ * lkl_put_irq - release an IRQ number previously obtained with lkl_get_free_irq
+ *
+ * @irq - irq number to release
+ * @user - string identifying the user; should be the same as the one passed to
+ * lkl_get_free_irq when the irq number was obtained
+ */
+void lkl_put_irq(int irq, const char *name);
+
+#endif
arch/um/lkl/include/uapi/asm/sigcontext.h new file +16 -0
new file mode 100644
index 000000000000..2f4848843d1d
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_UAPI_LKL_SIGCONTEXT_H
+#define _ASM_UAPI_LKL_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+struct pt_regs {
+	void *irq_data;
+};
+
+struct sigcontext {
+	struct pt_regs regs;
+	unsigned long oldmask;
+};
+
+#endif
arch/um/lkl/kernel/irq.c new file +193 -0

193 lines not on this page · raw message

Signature · 1 line
2.20.1 (Apple Git-117)
#78 lore raw

Re: [RFC v2 07/37] lkl: interrupt support

Quoted 17 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add APIs that allows the host to reserve and free and interrupt number and also to trigger an interrupt.

The trigger operation will simply store the interrupt data in queue. The interrupt handler is run later, at the first opportunity it has to avoid races with any kernel threads.

Currently, interrupts are run on the first interrupt enable operation if interrupts are disabled and if we are not already in interrupt context.

When triggering an interrupt, it uses GCC's built-in functions for atomic memory access to synchronize and simple boolean flags.

Quoted 8 lines
---
 arch/um/lkl/include/asm/irq.h             |  13 ++
 arch/um/lkl/include/uapi/asm/irq.h        |  36 ++++
 arch/um/lkl/include/uapi/asm/sigcontext.h |  16 ++
 arch/um/lkl/kernel/irq.c                  | 193 ++++++++++++++++++++++

Like I said before, this also something to unify with UML.
I'm aware that this is easily said but we cannot have too much duplication.

Feel free to ask if UML internals give you headache. :-)

--
Thanks,
//richard

#79 lore raw

Re: [RFC v2 07/37] lkl: interrupt support

Quoted 28 lines · Richard Weinberger
Quoted 17 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add APIs that allows the host to reserve and free and interrupt number and also to trigger an interrupt.

The trigger operation will simply store the interrupt data in queue. The interrupt handler is run later, at the first opportunity it has to avoid races with any kernel threads.

Currently, interrupts are run on the first interrupt enable operation if interrupts are disabled and if we are not already in interrupt context.

When triggering an interrupt, it uses GCC's built-in functions for atomic memory access to synchronize and simple boolean flags.

Quoted 8 lines
---
 arch/um/lkl/include/asm/irq.h             |  13 ++
 arch/um/lkl/include/uapi/asm/irq.h        |  36 ++++
 arch/um/lkl/include/uapi/asm/sigcontext.h |  16 ++
 arch/um/lkl/kernel/irq.c                  | 193 ++++++++++++++++++++++
Quoted 4 lines

Like I said before, this also something to unify with UML.
I'm aware that this is easily said but we cannot have too much duplication.

Feel free to ask if UML internals give you headache. :-)

Same as nommu implementation, I left this part as-is.

Triggering interrupts with fd events (delivered by epoll&co) is a hard part to implement host-independent interrupts of LKL. OTOH, the v3 patchset shows that it is doable to use UML drivers with the LKL interrupt facility.

I may also need more time to evaluate/find a right direction, though. Your comments are always welcome.

-- Hajime

#80 lore raw

Re: [RFC v2 07/37] lkl: interrupt support

Quoted 34 lines · Hajime Tazaki
Quoted 31 lines · Richard Weinberger
Quoted 17 lines · Hajime Tazaki

From: Octavian Purdila <[email protected]>

Add APIs that allows the host to reserve and free and interrupt number and also to trigger an interrupt.

The trigger operation will simply store the interrupt data in queue. The interrupt handler is run later, at the first opportunity it has to avoid races with any kernel threads.

Currently, interrupts are run on the first interrupt enable operation if interrupts are disabled and if we are not already in interrupt context.

When triggering an interrupt, it uses GCC's built-in functions for atomic memory access to synchronize and simple boolean flags.

Quoted 8 lines
---
  arch/um/lkl/include/asm/irq.h             |  13 ++
  arch/um/lkl/include/uapi/asm/irq.h        |  36 ++++
  arch/um/lkl/include/uapi/asm/sigcontext.h |  16 ++
  arch/um/lkl/kernel/irq.c                  | 193 ++++++++++++++++++++++

Like I said before, this also something to unify with UML.
I'm aware that this is easily said but we cannot have too much duplication.

Quoted 8 lines
Quoted 1 line

Feel free to ask if UML internals give you headache. :-)

Same as nommu implementation, I left this part as-is.

Triggering interrupts with fd events (delivered by epoll&co) is a hard part to implement host-independent interrupts of LKL. OTOH, the v3 patchset shows that it is doable to use UML drivers with the LKL interrupt facility.

Make sure you are testing with the vector network devices, the legacy ones are scheduled to be obsoleted at some point

I know this will cause a headache on non-Linux, I am happy to write wrappers/emulators for recvmms/sendmmsg so these build on the systems which do not support them.

Brgds,

Quoted 12 lines

I may also need more time to evaluate/find a right direction, though. Your comments are always welcome.

-- Hajime

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

Signature · 2 lines
Anton R. Ivanov
https://www.kot-begemot.co.uk/
#81 lore raw

Re: [RFC v2 07/37] lkl: interrupt support

Hello Anton,

Quoted 12 lines · Anton Ivanov
Quoted 12 lines
Quoted 9 lines
Quoted 4 lines
  arch/um/lkl/include/asm/irq.h             |  13 ++
  arch/um/lkl/include/uapi/asm/irq.h        |  36 ++++
  arch/um/lkl/include/uapi/asm/sigcontext.h |  16 ++
  arch/um/lkl/kernel/irq.c                  | 193 ++++++++++++++++++++++

Like I said before, this also something to unify with UML.
I'm aware that this is easily said but we cannot have too much duplication.

Feel free to ask if UML internals give you headache. :-)

Same as nommu implementation, I left this part as-is.

Quoted 7 lines
Quoted 4 lines

Triggering interrupts with fd events (delivered by epoll&co) is a hard part to implement host-independent interrupts of LKL. OTOH, the v3 patchset shows that it is doable to use UML drivers with the LKL interrupt facility.

Make sure you are testing with the vector network devices, the legacy ones are scheduled to be obsoleted at some point

I was aware of the commit to obsolete several backend with the vector device, but did not include in the patchset and tests. I will try to do it for the next round.

Quoted 3 lines

I know this will cause a headache on non-Linux, I am happy to write wrappers/emulators for recvmms/sendmmsg so these build on the systems which do not support them.

If UML is going to extend to support non-Linux host, yes, those kind of wrappers will be helpful.

Right now, the patchset only focuses on x86 hosts so, this can be postponed.

-- Hajime

#82 lore raw

Re: [RFC v2 07/37] lkl: interrupt support

Hello,

Quoted 6 lines · Hajime Tazaki
Quoted 2 lines

Make sure you are testing with the vector network devices, the legacy ones are scheduled to be obsoleted at some point

I was aware of the commit to obsolete several backend with the vector device, but did not include in the patchset and tests. I will try to do it for the next round.

So I added a vector device support, tested with tap backend. Here is a list of numbers with various configurations that v3+ patch have.

disclaimer: the experiment is immature, not apple-to-apple in many aspects. So this result only presents one of the parameter set that I took. I will update/clean up later if there are interests.

- testbed

               +--docker0--+
               |           |     10GbE
 netperf +---tap0        eth0 +==========+ eth0 +---+ netserver
 (client)                (ixgbe)          (ixgbe)

<-- Linux box (4.18.5) --> <-- Linux box (4.17.19) -->

- setup
varied client side (netperf) with different net drivers/devices. tso,tx/rx csum are enabled if possible.

- netperf 10secs (Mbps) result

|TCP_STREAM | TCP_MAERTS
-------------------- --------------------------

UMMODE_LIB (um-tap)  | 2290.42    |    1.04
UMMODE_LIB (vec-tap) | 3699.98    | 5682.40
UMMODE_LIB (virtio)  | 8029.13    | 9384.78
UMMODE_KERN (um-tap) | 2233.17    |    7.85
UMMODE_KERN (vec-tap)| 5527.37    | 9414.00

# UMMODE_LIB (virtio) isn't included in v3 patches.

full output log is here;
https://gist.github.com/thehajime/a71878cccf7830a23a23f8f8e8cc8753

result of UMMODE_LIB (vec-tap) is not stable: it sometimes shows over 8Gbps (TCP_STREAM) while most of the times lower.

But I suppose UMMODE_LIB with vector driver isn't that bad, though there is still a gap to UMMODE_KERN (vector).

-- Hajime

#83 lore raw

RFC v2 8/37 lkl: system call interface and application API

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

The LKL 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 LKL limitations such as lack of virtual memory, signal, user processes, etc.

The host is using the LKL interrupt mechanism (lkl_trigger_irq) to initiate a system call. The system call is executed in the context of the init process.

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.

---
 arch/um/lkl/include/asm/unistd.h        |  29 +++
 arch/um/lkl/include/uapi/asm/host_ops.h |  14 ++
 arch/um/lkl/include/uapi/asm/unistd.h   |  18 ++
 arch/um/lkl/kernel/syscalls.c           | 246 ++++++++++++++++++++++++
 arch/um/lkl/kernel/syscalls_32.c        | 159 +++++++++++++++
 arch/um/lkl/scripts/headers_install.py  | 195 +++++++++++++++++++
 6 files changed, 661 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/unistd.h
 create mode 100644 arch/um/lkl/include/uapi/asm/unistd.h
 create mode 100644 arch/um/lkl/kernel/syscalls.c
 create mode 100644 arch/um/lkl/kernel/syscalls_32.c
 create mode 100755 arch/um/lkl/scripts/headers_install.py
arch/um/lkl/include/asm/unistd.h new file +29 -0
new file mode 100644
index 000000000000..c0efc68bf41f
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <uapi/asm/unistd.h>
+
+__SYSCALL(__NR_virtio_mmio_device_add, sys_virtio_mmio_device_add)
+
+#define __SC_ASCII(t, a) #t "," #a
+
+#define __ASCII_MAP0(m, ...)
+#define __ASCII_MAP1(m, t, a) m(t, a)
+#define __ASCII_MAP2(m, t, a, ...) m(t, a) "," __ASCII_MAP1(m, __VA_ARGS__)
+#define __ASCII_MAP3(m, t, a, ...) m(t, a) "," __ASCII_MAP2(m, __VA_ARGS__)
+#define __ASCII_MAP4(m, t, a, ...) m(t, a) "," __ASCII_MAP3(m, __VA_ARGS__)
+#define __ASCII_MAP5(m, t, a, ...) m(t, a) "," __ASCII_MAP4(m, __VA_ARGS__)
+#define __ASCII_MAP6(m, t, a, ...) m(t, a) "," __ASCII_MAP5(m, __VA_ARGS__)
+#define __ASCII_MAP(n, ...) __ASCII_MAP##n(__VA_ARGS__)
+
+#ifdef __MINGW32__
+#define SECTION_ATTRS "n0"
+#else
+#define SECTION_ATTRS "a"
+#endif
+
+#define __SYSCALL_DEFINE_ARCH(x, name, ...)				\
+	asm(".section .syscall_defs,\"" SECTION_ATTRS "\"\n"		\
+	    ".ascii \"#ifdef __NR" #name "\\n\"\n"			\
+	    ".ascii \"SYSCALL_DEFINE" #x "(" #name ","			\
+	    __ASCII_MAP(x, __SC_ASCII, __VA_ARGS__) ")\\n\"\n"		\
+	    ".ascii \"#endif\\n\"\n"					\
+	    ".section .text\n");
arch/um/lkl/include/uapi/asm/host_ops.h +14 -0
index 19924fc7c718..1c839d7139f8 100644
@@ -36,6 +36,15 @@ struct lkl_jmp_buf {
  * @thread_join - wait for the given thread to terminate. Returns 0
  * for success, -1 otherwise
  *
+ * @tls_alloc - allocate a thread local storage key; returns 0 if successful; if
+ * destructor is not NULL it will be called when a thread terminates with its
+ * argument set to the current thread local storage value
+ * @tls_free - frees a thread local storage key; returns 0 if successful
+ * @tls_set - associate data to the thread local storage key; returns 0 if
+ * successful
+ * @tls_get - return data associated with the thread local storage key or NULL
+ * on error
+ *
  * @mem_alloc - allocate memory
  * @mem_free - free memory
  *
@@ -71,6 +80,11 @@ struct lkl_host_operations {
 	lkl_thread_t (*thread_self)(void);
 	int (*thread_equal)(lkl_thread_t a, lkl_thread_t b);
 
+	struct lkl_tls_key *(*tls_alloc)(void (*destructor)(void *));
+	void (*tls_free)(struct lkl_tls_key *key);
+	int (*tls_set)(struct lkl_tls_key *key, void *data);
+	void *(*tls_get)(struct lkl_tls_key *key);
+
 	void *(*mem_alloc)(unsigned long mem);
 	void (*mem_free)(void *mem);
 
arch/um/lkl/include/uapi/asm/unistd.h new file +18 -0
new file mode 100644
index 000000000000..561a7036821e
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#define __ARCH_WANT_SYSCALL_NO_AT
+#define __ARCH_WANT_SYSCALL_DEPRECATED
+#define __ARCH_WANT_SYSCALL_NO_FLAGS
+#define __ARCH_WANT_RENAMEAT
+#define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SET_GET_RLIMIT
+#define __ARCH_WANT_TIME32_SYSCALLS
+
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#define __ARCH_WANT_SYS_NEWFSTATAT
+#endif
+
+#include <asm-generic/unistd.h>
+
+#define __NR_virtio_mmio_device_add		(__NR_arch_specific_syscall + 0)
arch/um/lkl/kernel/syscalls.c new file +246 -0

246 lines not on this page · raw message

arch/um/lkl/kernel/syscalls_32.c new file +159 -0

159 lines not on this page · raw message

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

195 lines not on this page · raw message

Signature · 1 line
2.20.1 (Apple Git-117)
#84 lore raw

RFC v2 9/37 lkl: timers, time and delay support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Clockevent driver based on host timer operations and clocksource driver and udelay support based on host time operations.

---
 arch/um/lkl/include/uapi/asm/host_ops.h |  13 +++
 arch/um/lkl/kernel/time.c               | 145 ++++++++++++++++++++++++
 2 files changed, 158 insertions(+)
 create mode 100644 arch/um/lkl/kernel/time.c
arch/um/lkl/include/uapi/asm/host_ops.h +13 -0
index 1c839d7139f8..c9f77dd7fbe7 100644
@@ -48,6 +48,13 @@ struct lkl_jmp_buf {
  * @mem_alloc - allocate memory
  * @mem_free - free memory
  *
+ * @timer_create - allocate a host timer that runs fn(arg) when the timer
+ * fires.
+ * @timer_free - disarms and free the timer
+ * @timer_set_oneshot - arm the timer to fire once, after delta ns.
+ * @timer_set_periodic - arm the timer to fire periodically, with a period of
+ * delta ns.
+ *
  * @gettid - returns the host thread id of the caller, which need not
  * be the same as the handle returned by thread_create
  *
@@ -88,6 +95,12 @@ struct lkl_host_operations {
 	void *(*mem_alloc)(unsigned long mem);
 	void (*mem_free)(void *mem);
 
+	unsigned long long (*time)(void);
+
+	void *(*timer_alloc)(void (*fn)(void *), void *arg);
+	int (*timer_set_oneshot)(void *timer, unsigned long delta);
+	void (*timer_free)(void *timer);
+
 	long (*gettid)(void);
 
 	void (*jmp_buf_set)(struct lkl_jmp_buf *jmpb, void (*f)(void));
arch/um/lkl/kernel/time.c new file +145 -0

145 lines not on this page · raw message

Signature · 1 line
2.20.1 (Apple Git-117)
#85 lore raw

RFC v2 10/37 lkl: memory mapped I/O support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

All memory mapped I/O access is redirected to the host via the iomem_access host operation. The host can setup the memory mapped I/O region via the ioremap operation.

This allows the host to implement support for various devices, such as block or network devices.

---
 arch/um/lkl/include/asm/io.h            | 104 ++++++++++++++++++++++++
 arch/um/lkl/include/uapi/asm/host_ops.h |  10 +++
 2 files changed, 114 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/io.h
arch/um/lkl/include/asm/io.h new file +104 -0
new file mode 100644
index 000000000000..33d4e1a7feb2
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_IO_H
+#define _ASM_LKL_IO_H
+
+#include <asm/bug.h>
+#include <asm/host_ops.h>
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+	int ret;
+	u8 value;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 0);
+	WARN(ret, "error reading iomem %p", addr);
+
+	return value;
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+	int ret;
+	u16 value;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 0);
+	WARN(ret, "error reading iomem %p", addr);
+
+	return value;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+	int ret;
+	u32 value;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 0);
+	WARN(ret, "error reading iomem %p", addr);
+
+	return value;
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_readq __raw_readq
+static inline u64 __raw_readq(const volatile void __iomem *addr)
+{
+	int ret;
+	u64 value;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 0);
+	WARN(ret, "error reading iomem %p", addr);
+
+	return value;
+}
+#endif /* CONFIG_64BIT */
+
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 value, volatile void __iomem *addr)
+{
+	int ret;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 1);
+	WARN(ret, "error writing iomem %p", addr);
+}
+
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 value, volatile void __iomem *addr)
+{
+	int ret;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 1);
+	WARN(ret, "error writing iomem %p", addr);
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 value, volatile void __iomem *addr)
+{
+	int ret;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 1);
+	WARN(ret, "error writing iomem %p", addr);
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_writeq __raw_writeq
+static inline void __raw_writeq(u64 value, volatile void __iomem *addr)
+{
+	int ret;
+
+	ret = lkl_ops->iomem_access(addr, &value, sizeof(value), 1);
+	WARN(ret, "error writing iomem %p", addr);
+}
+#endif /* CONFIG_64BIT */
+
+#define ioremap ioremap
+static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
+{
+	return (void __iomem *)lkl_ops->ioremap(offset, size);
+}
+
+#include <asm-generic/io.h>
+
+#endif /* _ASM_LKL_IO_H */
arch/um/lkl/include/uapi/asm/host_ops.h +10 -0
index c9f77dd7fbe7..7c0c0967c44a 100644
@@ -55,6 +55,12 @@ struct lkl_jmp_buf {
  * @timer_set_periodic - arm the timer to fire periodically, with a period of
  * delta ns.
  *
+ * @ioremap - searches for an I/O memory region identified by addr and size and
+ * returns a pointer to the start of the address range that can be used by
+ * iomem_access
+ * @iomem_access - reads or writes to and I/O memory region; addr must be in the
+ * range returned by ioremap
+ *
  * @gettid - returns the host thread id of the caller, which need not
  * be the same as the handle returned by thread_create
  *
@@ -101,6 +107,10 @@ struct lkl_host_operations {
 	int (*timer_set_oneshot)(void *timer, unsigned long delta);
 	void (*timer_free)(void *timer);
 
+	void *(*ioremap)(long addr, int size);
+	int (*iomem_access)(const volatile void *addr, void *val, int size,
+			    int write);
+
 	long (*gettid)(void);
 
 	void (*jmp_buf_set)(struct lkl_jmp_buf *jmpb, void (*f)(void));
Signature · 1 line
2.20.1 (Apple Git-117)
#86 lore raw

RFC v2 11/37 lkl: basic kernel console support

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

Write operations are deferred to the host print operation.

---
 arch/um/lkl/include/uapi/asm/host_ops.h |  4 +++
 arch/um/lkl/kernel/console.c            | 42 +++++++++++++++++++++++++
 2 files changed, 46 insertions(+)
 create mode 100644 arch/um/lkl/kernel/console.c
arch/um/lkl/include/uapi/asm/host_ops.h +4 -0
index 7c0c0967c44a..6ae781419ce6 100644
@@ -17,6 +17,8 @@ struct lkl_jmp_buf {
  * These operations must be provided by a host library or by the application
  * itself.
  *
+ * @print - optional operation that receives console messages
+ *
  * @sem_alloc - allocate a host semaphore an initialize it to count
  * @sem_free - free a host semaphore
  * @sem_up - perform an up operation on the semaphore
@@ -76,6 +78,8 @@ struct lkl_jmp_buf {
  * @jmp_buf_longjmp - perform a jump back to the saved jump buffer
  */
 struct lkl_host_operations {
+	void (*print)(const char *str, int len);
+
 	struct lkl_sem *(*sem_alloc)(int count);
 	void (*sem_free)(struct lkl_sem *sem);
 	void (*sem_up)(struct lkl_sem *sem);
arch/um/lkl/kernel/console.c new file +42 -0

42 lines not on this page · raw message

Signature · 1 line
2.20.1 (Apple Git-117)
#87 lore raw

RFC v2 12/37 lkl: initialization and cleanup

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

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_stop_kernel will shutdown the kernel, terminate all threads and free all host resources used by the kernel before returning.

This patch also introduces idle CPU handling since it is closely related to the shutdown process. A host semaphore is used to wait for new interrupts when the kernel switches the CPU to idle to avoid wasting host CPU cycles. When the kernel is shutdown we terminate the idle thread at the first CPU idle event.

---
 arch/um/lkl/include/asm/setup.h         |   7 +
 arch/um/lkl/include/uapi/asm/host_ops.h |  26 ++++
 arch/um/lkl/kernel/setup.c              | 193 ++++++++++++++++++++++++
 3 files changed, 226 insertions(+)
 create mode 100644 arch/um/lkl/include/asm/setup.h
 create mode 100644 arch/um/lkl/kernel/setup.c
arch/um/lkl/include/asm/setup.h new file +7 -0
new file mode 100644
index 000000000000..b40955208cc6
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LKL_SETUP_H
+#define _ASM_LKL_SETUP_H
+
+#define COMMAND_LINE_SIZE 4096
+
+#endif
arch/um/lkl/include/uapi/asm/host_ops.h +26 -0
index 6ae781419ce6..5f26e61f4b18 100644
@@ -17,8 +17,14 @@ struct lkl_jmp_buf {
  * These operations must be provided by a host library or by the application
  * itself.
  *
+ * @virtio_devices - string containg the list of virtio devices in virtio mmio
+ * 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
+ *
  * @sem_alloc - allocate a host semaphore an initialize it to count
  * @sem_free - free a host semaphore
  * @sem_up - perform an up operation on the semaphore
@@ -78,7 +84,10 @@ struct lkl_jmp_buf {
  * @jmp_buf_longjmp - perform a jump back to the saved jump buffer
  */
 struct lkl_host_operations {
+	const char *virtio_devices;
+
 	void (*print)(const char *str, int len);
+	void (*panic)(void);
 
 	struct lkl_sem *(*sem_alloc)(int count);
 	void (*sem_free)(struct lkl_sem *sem);
@@ -121,6 +130,23 @@ struct lkl_host_operations {
 	void (*jmp_buf_longjmp)(struct lkl_jmp_buf *jmpb, int val);
 };
 
+/**
+ * lkl_start_kernel - registers the host operations and starts the kernel
+ *
+ * The function returns only after the kernel is shutdown with lkl_sys_halt.
+ *
+ * @lkl_ops - pointer to host operations
+ * @cmd_line - format for command line string that is going to be used to
+ * generate the Linux kernel command line
+ */
+int lkl_start_kernel(struct lkl_host_operations *lkl_ops, const char *cmd_line,
+		     ...);
+
+/**
+ * lkl_is_running - returns 1 if the kernel is currently running
+ */
+int lkl_is_running(void);
+
 int lkl_printf(const char *fmt, ...);
 void lkl_bug(const char *fmt, ...);
 
arch/um/lkl/kernel/setup.c new file +193 -0

193 lines not on this page · raw message

Signature · 1 line
2.20.1 (Apple Git-117)
#88 lore raw

RFC v2 13/37 lkl: plug in the build system

In reply to Hajime Tazaki

From: Octavian Purdila <[email protected]>

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

To make LKL binaries build, UML introduced an additional option, UMMODE variable, to switch the output file of build: kernel (default), or library (LKL). 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 UMMODE=library
make ARCH=um UMMODE=library

---
 arch/um/Kconfig             |  26 +++++++
 arch/um/Makefile            | 151 +++---------------------------------
 arch/um/Makefile.um         | 149 +++++++++++++++++++++++++++++++++++
 arch/um/lkl/Kconfig         |  17 ++--
 arch/um/lkl/Makefile        |  69 ++++++++++++++++
 arch/um/lkl/auto.conf       |   1 +
 arch/um/lkl/kernel/Makefile |   4 +
 arch/um/lkl/mm/Makefile     |   1 +
 8 files changed, 264 insertions(+), 154 deletions(-)
 create mode 100644 arch/um/Makefile.um
 create mode 100644 arch/um/lkl/Makefile
 create mode 100644 arch/um/lkl/auto.conf
 create mode 100644 arch/um/lkl/kernel/Makefile
 create mode 100644 arch/um/lkl/mm/Makefile
arch/um/Kconfig +26 -0
index 3c3adfc486f2..c46bdb2987ce 100644
@@ -5,6 +5,10 @@ menu "UML-specific options"
 config UML
 	bool
 	default y
+
+config UMMODE_KERN
+	bool "UML mode: kernel mode"
+	default y if "$(UMMODE)" = "kernel"
 	select ARCH_HAS_KCOV
 	select ARCH_NO_PREEMPT
 	select HAVE_ARCH_AUDITSYSCALL
@@ -18,7 +22,25 @@ config UML
 	select GENERIC_CLOCKEVENTS
 	select HAVE_GCC_PLUGINS
 	select TTY # Needed for line.c
+        help
+	  This mode switches a mode to build a regular kernel executable
+          of UML.
+
+config UMMODE_LIB
+	bool "UML mode: library mode"
+	depends on !UMMODE_KERN
+	select LKL
+	default y if "$(UMMODE)" = "library"
+	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.
+
+	  For more detail about LKL, see
+	  <file:Documentation/virt/uml/lkl.txt>.
 
+
+if UMMODE_KERN
 config MMU
 	bool
 	default y
@@ -196,6 +218,10 @@ config UML_TIME_TRAVEL_SUPPORT
 
 	  It is safe to say Y, but you probably don't need this.
 
+endif #UMMODE_KERN
+
 endmenu
 
 source "arch/um/drivers/Kconfig"
+
+source "arch/um/lkl/Kconfig"
arch/um/Makefile +9 -142

157 lines not on this page · raw message

arch/um/Makefile.um new file +149 -0

149 lines not on this page · raw message

arch/um/lkl/Kconfig +5 -12
index 1dae70f16c43..07b3699095ae 100644
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 
-config UML_LKL
+menu "LKL-specific options"
+
+config LKL
        def_bool y
        depends on !SMP && !MMU && !COREDUMP && !SECCOMP && !UPROBES && !COMPAT && !USER_RETURN_NOTIFIER
        select ARCH_THREAD_STACK_ALLOCATOR
@@ -59,7 +61,7 @@ config BIG_ENDIAN
        def_bool n
 
 config GENERIC_CSUM
-       def_bool y
+       def_bool LKL
 
 config GENERIC_HWEIGHT
        def_bool y
@@ -83,13 +85,4 @@ config HZ
         int
         default 100
 
-config CONSOLE_LOGLEVEL_QUIET
-	int "quiet console loglevel (1-15)"
-	range 1 15
-	default "4"
-	help
-	  loglevel to use when "quiet" is passed on the kernel commandline.
-
-	  When "quiet" is passed on the kernel commandline this loglevel
-	  will be used as the loglevel. IOW passing "quiet" will be the
-	  equivalent of passing "loglevel=<CONSOLE_LOGLEVEL_QUIET>"
+endmenu
arch/um/lkl/Makefile new file +69 -0

69 lines not on this page · raw message

arch/um/lkl/auto.conf new file +1 -0
new file mode 100644
index 000000000000..4bfd65a02d73
@@ -0,0 +1 @@
+export OUTPUT_FORMAT=$(shell $(LD) -r -print-output-format)
arch/um/lkl/kernel/Makefile new file +4 -0
new file mode 100644
index 000000000000..ef489f2f7176
@@ -0,0 +1,4 @@
+extra-y := vmlinux.lds
+
+obj-y = setup.o threads.o irq.o time.o syscalls.o misc.o console.o \
+	syscalls_32.o cpu.o
arch/um/lkl/mm/Makefile new file +1 -0
new file mode 100644
index 000000000000..2af6e3051897
@@ -0,0 +1 @@
+obj-y = bootmem.o
Signature · 1 line
2.20.1 (Apple Git-117)