From 097fd98bc3c301c8da0eb756ca58be4c4823545e Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Tue, 7 Jul 2026 19:38:49 -0300 Subject: [PATCH 1/2] cartesi: add Cartesi Machine platform support (6.18.38-ctsi) Bundle the Cartesi-specific changes on top of Linux 6.18.38: - drivers/cartesi: add cmio device (/dev/cmio) for guest-host communication via shared tx/rx buffers (mmap) and SBI yield, plus Kconfig/Makefile and cartesi_defconfig - riscv/sbi: forward the application exit status through the reboot reason and use the SBI v0.1 shutdown ABI even when v0.3+ is present - panic: halt the machine on kernel panic - reboot: lower restart/halt/poweroff messages from pr_emerg to pr_notice so they can be silenced via loglevel - selftests: add cmio echo and open-twice tests Co-authored-by: Victor Fusco <1221933+vfusco@users.noreply.github.com> Co-authored-by: Marcelo Politzer <251334+mpolitzer@users.noreply.github.com> Co-authored-by: Diego Nehab <1635557+diegonehab@users.noreply.github.com> --- Makefile | 2 +- arch/riscv/configs/cartesi_defconfig | 98 +++++++ arch/riscv/kernel/sbi.c | 20 +- drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/cartesi/Kconfig | 30 +++ drivers/cartesi/Makefile | 1 + drivers/cartesi/cmio.c | 240 ++++++++++++++++++ include/uapi/linux/cartesi/cmio.h | 42 +++ init/Kconfig | 3 +- kernel/panic.c | 5 + kernel/reboot.c | 10 +- tools/testing/selftests/Makefile | 1 + .../selftests/drivers/cartesi/Makefile | 8 + .../selftests/drivers/cartesi/cmio_echo.c | 42 +++ .../drivers/cartesi/cmio_open_twice.c | 29 +++ tools/testing/selftests/kselftest/runner.sh | 2 +- 17 files changed, 521 insertions(+), 15 deletions(-) create mode 100644 arch/riscv/configs/cartesi_defconfig create mode 100644 drivers/cartesi/Kconfig create mode 100644 drivers/cartesi/Makefile create mode 100644 drivers/cartesi/cmio.c create mode 100644 include/uapi/linux/cartesi/cmio.h create mode 100644 tools/testing/selftests/drivers/cartesi/Makefile create mode 100644 tools/testing/selftests/drivers/cartesi/cmio_echo.c create mode 100644 tools/testing/selftests/drivers/cartesi/cmio_open_twice.c diff --git a/Makefile b/Makefile index 7ee3beedcecaa..03ce211d790c3 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 6 PATCHLEVEL = 18 SUBLEVEL = 38 -EXTRAVERSION = +EXTRAVERSION = -ctsi-1 NAME = Baby Opossum Posse # *DOCUMENTATION* diff --git a/arch/riscv/configs/cartesi_defconfig b/arch/riscv/configs/cartesi_defconfig new file mode 100644 index 0000000000000..69320389516c3 --- /dev/null +++ b/arch/riscv/configs/cartesi_defconfig @@ -0,0 +1,98 @@ +CONFIG_DEFAULT_HOSTNAME="cartesi-machine" +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_CROSS_MEMORY_ATTACH is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_BPF=y +CONFIG_USER_NS=y +CONFIG_ARCH_VIRT=y +CONFIG_NONPORTABLE=y +CONFIG_HZ_100=y +CONFIG_RISCV_SBI_V01=y +CONFIG_RISCV_EMULATED_UNALIGNED_ACCESS=y +# CONFIG_RISCV_ISA_C is not set +# CONFIG_COMPAT is not set +CONFIG_CMDLINE="earlyprintk" +# CONFIG_EFI is not set +# CONFIG_SUSPEND is not set +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_JUMP_LABEL=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_PARTITION_ADVANCED=y +# CONFIG_MQ_IOSCHED_DEADLINE is not set +# CONFIG_MQ_IOSCHED_KYBER is not set +# CONFIG_COMPACTION is not set +CONFIG_NET=y +CONFIG_PACKET=y +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +CONFIG_BRIDGE=y +CONFIG_VSOCKETS=y +CONFIG_VIRTIO_VSOCKETS=y +# CONFIG_WIRELESS is not set +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_VIRTIO_BLK=y +CONFIG_NETDEVICES=y +CONFIG_TUN=y +CONFIG_VIRTIO_NET=y +# CONFIG_ETHERNET is not set +# CONFIG_WLAN is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_EARLYCON_RISCV_SBI=y +CONFIG_HVC_RISCV_SBI=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_HW_RANDOM_VIRTIO=y +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VHOST_NET=y +CONFIG_VHOST_VSOCK=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_LIBNVDIMM=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_FILE_DIRECT=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +CONFIG_9P_FS=y +CONFIG_FUSE_FS=y +CONFIG_EROFS_FS=y +CONFIG_OVERLAY_FS=y +CONFIG_PRINTK_TIME=y +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_BINFMT_MISC=y +CONFIG_SECURITY=y +CONFIG_FORTIFY_SOURCE=y +CONFIG_HARDENED_USERCOPY=y +CONFIG_SECURITY_LANDLOCK=y +CONFIG_CHECKPOINT_RESTORE=y \ No newline at end of file diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index c443337056ab7..4a7d2d63227e5 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -510,7 +510,7 @@ EXPORT_SYMBOL(sbi_remote_hfence_vvma_asid); static void sbi_srst_reset(unsigned long type, unsigned long reason) { - sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_RESET, type, reason, + sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, type, reason, 0, 0, 0, 0); pr_warn("%s: type=0x%lx reason=0x%lx failed\n", __func__, type, reason); @@ -519,10 +519,14 @@ static void sbi_srst_reset(unsigned long type, unsigned long reason) static int sbi_srst_reboot(struct notifier_block *this, unsigned long mode, void *cmd) { - sbi_srst_reset((mode == REBOOT_WARM || mode == REBOOT_SOFT) ? - SBI_SRST_RESET_TYPE_WARM_REBOOT : - SBI_SRST_RESET_TYPE_COLD_REBOOT, - SBI_SRST_RESET_REASON_NONE); + int32_t reason = 255; + /* use the original value if we fail to parse */ + if (kstrtoint(cmd, 10, &reason)) { + ; + } + + sbi_srst_reset(SBI_SRST_RESET_TYPE_SHUTDOWN, + reason); return NOTIFY_DONE; } @@ -658,7 +662,7 @@ void __init sbi_init(void) pr_info("SBI specification v%lu.%lu detected\n", sbi_major_version(), sbi_minor_version()); - if (!sbi_spec_is_0_1()) { + if (!sbi_spec_is_0_1() && !IS_ENABLED(CONFIG_RISCV_SBI_V01)) { pr_info("SBI implementation ID=0x%lx Version=0x%lx\n", sbi_get_firmware_id(), sbi_get_firmware_version()); if (sbi_probe_extension(SBI_EXT_TIME)) { @@ -702,6 +706,10 @@ void __init sbi_init(void) __sbi_set_timer = __sbi_set_timer_v01; __sbi_send_ipi = __sbi_send_ipi_v01; __sbi_rfence = __sbi_rfence_v01; + + sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot; + sbi_srst_reboot_nb.priority = 192; + register_restart_handler(&sbi_srst_reboot_nb); } if (!srst_power_off) diff --git a/drivers/Kconfig b/drivers/Kconfig index 4915a63866b01..5a2387e171c6b 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -251,4 +251,6 @@ source "drivers/hte/Kconfig" source "drivers/cdx/Kconfig" +source "drivers/cartesi/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 8e1ffa4358d5f..2918db62e1a52 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -197,3 +197,4 @@ obj-$(CONFIG_DPLL) += dpll/ obj-$(CONFIG_DIBS) += dibs/ obj-$(CONFIG_S390) += s390/ +obj-$(CONFIG_CARTESI_MACHINE) += cartesi/ diff --git a/drivers/cartesi/Kconfig b/drivers/cartesi/Kconfig new file mode 100644 index 0000000000000..33dfb45b89436 --- /dev/null +++ b/drivers/cartesi/Kconfig @@ -0,0 +1,30 @@ +menu "Cartesi Machine" + +config CARTESI_MACHINE + bool "Cartesi Machine" + depends on RISCV_SBI + default y if RISCV_SBI + help + Enable support for the Cartesi Machine RISC-V platform. + This enables the Cartesi Machine specific drivers and + configuration options. + +config CARTESI_MACHINE_IO_DRIVER + bool "Cartesi Machine IO Device" + depends on CARTESI_MACHINE + default y + help + Driver for the Cartesi Machine IO (cmio) device, which + provides guest-host communication via shared memory + buffers and SBI yield calls. Exposes /dev/cmio. + +config CARTESI_HALT_ON_PANIC + bool "Halt machine on kernel panic" + depends on CARTESI_MACHINE + default y + help + Halt the Cartesi Machine on kernel panic by issuing an + SBI shutdown call. This is useful for debugging to + prevent the machine from continuing in an undefined state. + +endmenu diff --git a/drivers/cartesi/Makefile b/drivers/cartesi/Makefile new file mode 100644 index 0000000000000..770e45f204ea0 --- /dev/null +++ b/drivers/cartesi/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CARTESI_MACHINE_IO_DRIVER) += cmio.o diff --git a/drivers/cartesi/cmio.c b/drivers/cartesi/cmio.c new file mode 100644 index 0000000000000..74eceb21758f7 --- /dev/null +++ b/drivers/cartesi/cmio.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Cartesi cmio device. + * Copyright (C) 2023 Cartesi Machine reference unit + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "cmio" +#define MODULE_DESC "Cartesi Machine " DEVICE_NAME " device" + +#define SBI_YIELD 9 + +struct cmio_device { + struct platform_device *pdev; + struct miscdevice mdev; + struct cmio_setup bufs; + atomic_t single_user_lock; +}; + +static struct cmio_device *to_cmio_device(struct file *file) +{ + struct miscdevice *dev = file->private_data; + return container_of(dev, struct cmio_device, mdev); +} + +static long cmio_ioctl_setup(struct cmio_device *me, unsigned long arg) +{ + if (copy_to_user((void __user *)arg, &me->bufs, sizeof me->bufs)) + return -EFAULT; + + return 0; +} + +static long cmio_ioctl_yield(struct cmio_device *me, unsigned long arg) +{ + __u64 req = 0, + rep = 0; + + if (copy_from_user(&req, (void __user *)arg, sizeof req)) + return -EFAULT; + + rep = sbi_ecall(SBI_YIELD, 0, req, 0, 0, 0, 0, 0).value; + + if (copy_to_user((void __user *)arg, &rep, sizeof rep)) + return -EFAULT; + + return 0; +} + +/* + * We enforce only one user at a time here with the open/release. + */ +static int cmio_open(struct inode *inode, struct file *file) +{ + struct cmio_device *cmio = to_cmio_device(file); + if (!cmio) + return -EBADF; + + if (!atomic_inc_and_test(&cmio->single_user_lock)) { + atomic_dec(&cmio->single_user_lock); + return -EBUSY; + } + return 0; +} + +static int cmio_release(struct inode *inode, struct file *file) +{ + struct cmio_device *cmio = to_cmio_device(file); + if (!cmio) + return -EBADF; + + atomic_dec(&cmio->single_user_lock); + return 0; +} + +static long cmio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct cmio_device *cmio = to_cmio_device(file); + if (!cmio) + return -EBADF; + + switch (cmd) { + case IOCTL_CMIO_SETUP: + return cmio_ioctl_setup(cmio, arg); + case IOCTL_CMIO_YIELD: + return cmio_ioctl_yield(cmio, arg); + } + return -ENOIOCTLCMD; +} + +static int cmio_mmap(struct file *file, struct vm_area_struct *vma) +{ + __u64 vma_size; + struct cmio_device *cmio = to_cmio_device(file); + if (!cmio) + return -EBADF; + + vma_size = vma->vm_end - vma->vm_start; + if (!((vma->vm_start == cmio->bufs.tx.data && vma_size == cmio->bufs.tx.length) + || (vma->vm_start == cmio->bufs.rx.data && vma_size == cmio->bufs.rx.length))) + return -EINVAL; + + return remap_pfn_range(vma, + vma->vm_start, + vma->vm_start >> PAGE_SHIFT, + vma_size, + vma->vm_page_prot); +} + +static const struct file_operations cmio_fileops = { + .open = cmio_open, + .release = cmio_release, + .unlocked_ioctl = cmio_ioctl, + .mmap = cmio_mmap, + .owner = THIS_MODULE, +}; + +static int setup_buffer(struct device_node *parent, const char *name, struct cmio_buffer *buf) +{ + u64 xs[2]; + int rc = -EIO; + struct device_node *node = NULL; + + if (!(node = of_find_node_by_name(parent, name))) + goto leave; + if (of_property_read_u64_array(node, "reg", xs, 2)) + goto leave; + if (!(buf->data = xs[0])) + goto leave; + if (!(buf->length = xs[1])) + goto leave; + rc = 0; +leave: + of_node_put(node); + return rc; +} + +static int check_yield_automatic_and_manual(struct device_node *node) +{ + return !(of_property_read_bool(node, "automatic") + && of_property_read_bool(node, "manual")); +} + +static int setup_io(struct cmio_device *cmio) +{ + int rc = -EIO; + struct device_node *cmio_node = NULL, + *yield_node = NULL; + + if (!(cmio_node = of_find_node_by_path("/cmio")) + || setup_buffer(cmio_node, "tx_buffer", &cmio->bufs.tx) + || setup_buffer(cmio_node, "rx_buffer", &cmio->bufs.rx)) + goto leave; + + if (!(yield_node = of_find_node_by_path("/yield")) + || check_yield_automatic_and_manual(yield_node)) + goto leave; + rc = 0; +leave: + of_node_put(yield_node); + of_node_put(cmio_node); + return rc; +} + +static int cmio_driver_probe(struct platform_device *pdev) +{ + int rc; + struct cmio_device *cmio; + + cmio = devm_kzalloc(&pdev->dev, sizeof(*cmio), GFP_KERNEL); + if (!cmio) + return -ENOMEM; + + atomic_set(&cmio->single_user_lock, -1); + cmio->mdev.minor = MISC_DYNAMIC_MINOR; + cmio->mdev.name = DEVICE_NAME; + cmio->mdev.fops = &cmio_fileops; + rc = misc_register(&cmio->mdev); + if (rc) { + dev_err(&pdev->dev, "failed to register miscdevice\n"); + goto leave; + } + + rc = setup_io(cmio); + if (rc) { + dev_err(&pdev->dev, "failed to parse device tree\n"); + goto deregister; + } + + platform_set_drvdata(pdev, cmio); + cmio->pdev = pdev; + + pr_info(MODULE_DESC ": Module loaded\n"); + return 0; + +deregister: + misc_deregister(&cmio->mdev); +leave: + return rc; +} + +static void cmio_driver_remove(struct platform_device *pdev) +{ + struct cmio_device *cmio = platform_get_drvdata(pdev); + misc_deregister(&cmio->mdev); + dev_info(&pdev->dev, "unregistered\n"); +} + +static const struct of_device_id cmio_match[] = { + {.compatible = "ctsi-cmio",}, {}, +}; +MODULE_DEVICE_TABLE(of, cmio_match); + +static struct platform_driver cmio_driver = { + .driver = { + .name = DEVICE_NAME, + .of_match_table = cmio_match, + }, + .probe = cmio_driver_probe, + .remove = cmio_driver_remove, +}; + +module_platform_driver(cmio_driver); + +MODULE_DESCRIPTION(MODULE_DESC); +MODULE_LICENSE("GPL"); diff --git a/include/uapi/linux/cartesi/cmio.h b/include/uapi/linux/cartesi/cmio.h new file mode 100644 index 0000000000000..c514e06a26a92 --- /dev/null +++ b/include/uapi/linux/cartesi/cmio.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Cartesi cmio device. + * Copyright (C) 2023-2024 Cartesi Machine reference unit + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _UAPI_LINUX_CARTESI_CMIO_H +#define _UAPI_LINUX_CARTESI_CMIO_H +#include +#include + +struct cmio_buffer { + __u64 data; + __u64 length; +}; + +struct cmio_setup { + struct cmio_buffer tx, rx; +}; + +/** Return a @p cmio_setup structure filled with tx and rx buffer details. Use + * these values to mmap them into the user-space. + * + * @return + * 0 on success. + * -1 on error and errno is set. + */ +#define IOCTL_CMIO_SETUP _IOR(0xd3, 0, struct cmio_setup) + +/** Yield the machine execution and transfer control back to the emulator. + * + * @return + * 0 on success. + * -1 on error and errno is set. + */ +#define IOCTL_CMIO_YIELD _IOWR(0xd3, 1, __u64) + +#endif diff --git a/init/Kconfig b/init/Kconfig index cab3ad28ca49e..59f6b6f501434 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -201,8 +201,7 @@ config BROKEN_ON_SMP config INIT_ENV_ARG_LIMIT int - default 32 if !UML - default 128 if UML + default 128 help Maximum of each of the number of arguments and environment variables passed to init from the kernel command line. diff --git a/kernel/panic.c b/kernel/panic.c index b13f040680ac1..c7f28668e8a6d 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -590,6 +590,11 @@ void vpanic(const char *fmt, va_list args) "twice on console to return to the boot prom\n"); } #endif + +#ifdef CONFIG_CARTESI_HALT_ON_PANIC + machine_restart("255"); +#endif + #if defined(CONFIG_S390) disabled_wait(); #endif diff --git a/kernel/reboot.c b/kernel/reboot.c index ec087827c85cd..d2671cd4759ba 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -291,9 +291,9 @@ void kernel_restart(char *cmd) migrate_to_reboot_cpu(); syscore_shutdown(); if (!cmd) - pr_emerg("Restarting system\n"); + pr_notice("Restarting system\n"); else - pr_emerg("Restarting system with command '%s'\n", cmd); + pr_notice("Restarting system with command '%s'\n", cmd); kmsg_dump(KMSG_DUMP_SHUTDOWN); machine_restart(cmd); } @@ -318,9 +318,9 @@ void kernel_halt(void) migrate_to_reboot_cpu(); syscore_shutdown(); if (poweroff_fallback_to_halt) - pr_emerg("Power off not available: System halted instead\n"); + pr_notice("Power off not available: System halted instead\n"); else - pr_emerg("System halted\n"); + pr_notice("System halted\n"); kmsg_dump(KMSG_DUMP_SHUTDOWN); machine_halt(); } @@ -708,7 +708,7 @@ void kernel_power_off(void) do_kernel_power_off_prepare(); migrate_to_reboot_cpu(); syscore_shutdown(); - pr_emerg("Power down\n"); + pr_notice("Power down\n"); pr_flush(1000, true); kmsg_dump(KMSG_DUMP_SHUTDOWN); machine_power_off(); diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index c46ebdb9b8ef7..a0f08a438ec83 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -26,6 +26,7 @@ TARGETS += drivers/net/team TARGETS += drivers/net/virtio_net TARGETS += drivers/platform/x86/intel/ifs TARGETS += dt +TARGETS += drivers/cartesi TARGETS += efivarfs TARGETS += exec TARGETS += fchmodat2 diff --git a/tools/testing/selftests/drivers/cartesi/Makefile b/tools/testing/selftests/drivers/cartesi/Makefile new file mode 100644 index 0000000000000..898ba5f65d207 --- /dev/null +++ b/tools/testing/selftests/drivers/cartesi/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-only +CFLAGS += -I../../../../../usr/include/ + +TEST_GEN_PROGS := cmio_echo cmio_open_twice + +top_srcdir ?=../../../../.. + +include ../../lib.mk diff --git a/tools/testing/selftests/drivers/cartesi/cmio_echo.c b/tools/testing/selftests/drivers/cartesi/cmio_echo.c new file mode 100644 index 0000000000000..082f71db981f1 --- /dev/null +++ b/tools/testing/selftests/drivers/cartesi/cmio_echo.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include "../../kselftest_harness.h" + +#define DEVICE_NAME "/dev/cmio" + +FIXTURE(cmio) { + int fd; +}; +FIXTURE_SETUP(cmio) { + self->fd = open(DEVICE_NAME, O_RDWR); + ASSERT_GT(self->fd, 0) { + TH_LOG("fixture error: %s\n", strerror(errno)); + } +} +FIXTURE_TEARDOWN(cmio) { + close(self->fd); +} + +TEST_F(cmio, echo) { + const int tx_prot = PROT_READ | PROT_WRITE, + rx_prot = PROT_READ; + + struct cmio_setup setup; + + ASSERT_EQ(ioctl(self->fd, IOCTL_CMIO_SETUP, (unsigned long) &setup), 0); + uint8_t *tx = mmap((void *)setup.tx.data, setup.tx.length, tx_prot, MAP_SHARED, self->fd, 0); + uint8_t *rx = mmap((void *)setup.rx.data, setup.rx.length, rx_prot, MAP_SHARED, self->fd, 0); + + ASSERT_NE(tx, MAP_FAILED); + ASSERT_NE(rx, MAP_FAILED); + uint64_t length = + setup.rx.length < setup.tx.length? + setup.rx.length : setup.tx.length; + memcpy(tx, rx, length); +} + +TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/drivers/cartesi/cmio_open_twice.c b/tools/testing/selftests/drivers/cartesi/cmio_open_twice.c new file mode 100644 index 0000000000000..74694b480c7a1 --- /dev/null +++ b/tools/testing/selftests/drivers/cartesi/cmio_open_twice.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include "../../kselftest_harness.h" + +#define DEVICE_NAME "/dev/cmio" + +FIXTURE(cmio) { + int fd; +}; +FIXTURE_SETUP(cmio) { + self->fd = open(DEVICE_NAME, O_RDWR); + ASSERT_GT(self->fd, 0) { + TH_LOG("fixture error: %s\n", strerror(errno)); + } +} +FIXTURE_TEARDOWN(cmio) { + close(self->fd); +} + +TEST_F(cmio, open_again) { + ASSERT_LT(open(DEVICE_NAME, O_RDWR), 0); +} + +TEST_HARNESS_MAIN + diff --git a/tools/testing/selftests/kselftest/runner.sh b/tools/testing/selftests/kselftest/runner.sh index 2c3c58e65a419..651f1f584dcd1 100644 --- a/tools/testing/selftests/kselftest/runner.sh +++ b/tools/testing/selftests/kselftest/runner.sh @@ -4,7 +4,7 @@ # Runs a set of tests in a given subdirectory. export skip_rc=4 export timeout_rc=124 -export logfile=/dev/stdout +export logfile=/dev/tty export per_test_logging= export RUN_IN_NETNS= From 3e60acf6ef138089b2fe1687a36915c8a38bacae Mon Sep 17 00:00:00 2001 From: Diego Nehab <1635557+diegonehab@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:57:39 +0100 Subject: [PATCH 2/2] ci: build linux.bin --- .github/workflows/build.yml | 97 +++++++++++++++++++++++++++++++++++++ .gitignore | 1 + 2 files changed, 98 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000000..f0c7fc070095a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,97 @@ +name: Build + +on: [push] + +permissions: + contents: read + +jobs: + build: + name: Build linux.bin + runs-on: ubuntu-latest + container: debian:trixie-20250811 + env: + DEBIAN_FRONTEND: noninteractive + steps: + - name: Install build dependencies + run: | + apt-get update + apt-get install --no-install-recommends -y \ + bc \ + bison \ + build-essential \ + ca-certificates \ + flex \ + gcc-riscv64-linux-gnu \ + git \ + python3 \ + rsync + + - name: Checkout Linux source code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Checkout OpenSBI source code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: cartesi/opensbi + ref: 5612514832be90d2df920eb1fe89a18c57bacbf5 # v1.3.1-ctsi-2 + path: .opensbi + + - name: Build Linux + shell: bash + run: | + SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD) + KERNEL_TIMESTAMP=$(date --utc --date="@${SOURCE_DATE_EPOCH}" --rfc-email) + LINUX_OPTS=( + -j"$(nproc)" + ARCH=riscv + CROSS_COMPILE=riscv64-linux-gnu- + KBUILD_BUILD_TIMESTAMP="${KERNEL_TIMESTAMP}" + KBUILD_BUILD_USER=dapp + KBUILD_BUILD_HOST=cartesi + ) + + make "${LINUX_OPTS[@]}" cartesi_defconfig + make "${LINUX_OPTS[@]}" olddefconfig + make "${LINUX_OPTS[@]}" vmlinux Image + + - name: Build linux.bin + run: | + make -C .opensbi -j"$(nproc)" \ + FW_PAYLOAD_PATH="${GITHUB_WORKSPACE}/arch/riscv/boot/Image" \ + FW_PAYLOAD=y \ + FW_OPTIONS=0x01 \ + PLATFORM=cartesi \ + CROSS_COMPILE=riscv64-linux-gnu- + cp .opensbi/build/platform/cartesi/firmware/fw_payload.bin linux.bin + sha512sum linux.bin > linux.bin.sha512 + + - name: Upload linux.bin + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: linux.bin + path: | + linux.bin + linux.bin.sha512 + compression-level: 0 + + release: + name: Publish linux.bin + if: startsWith(github.ref, 'refs/tags/v') + needs: build + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Download linux.bin + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: linux.bin + + - name: Publish release artifacts + uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 + with: + draft: true + files: | + linux.bin + linux.bin.sha512 diff --git a/.gitignore b/.gitignore index 86a1ba0d90353..6fbdeae7879ab 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ # Normal rules (sorted alphabetically) # .* +!/.github/ *.a *.asn1.[ch] *.bin