virt_linux: disable SMP for arm_v7 and change to tiny rcu

When SMP is enabled multicore specific instructions (e.g., pldw) are
generated. These are not supported and lead to invalid instruction
faults on uni-processor systems (like Cortex-A8). Therefore, we disable
SMP for arm_v7 in Linux code. This requires also a switch from the RCU
tree implementation to RCU tiny, which we shadow and dummy implemented.

issue #5104
This commit is contained in:
Sebastian Sumpf
2024-02-01 09:39:12 +01:00
committed by Christian Helmuth
parent 651eb9d4f2
commit 7e8661f8bf
6 changed files with 91 additions and 4 deletions

View File

@@ -27,7 +27,6 @@ SRC_C += lx_emul/shadow/kernel/irq_work.c
SRC_C += lx_emul/shadow/kernel/locking/spinlock.c
SRC_C += lx_emul/shadow/kernel/pid.c
SRC_C += lx_emul/shadow/kernel/printk/printk.c
SRC_C += lx_emul/shadow/kernel/rcu/tree.c
SRC_C += lx_emul/shadow/kernel/sched/cputime.c
SRC_C += lx_emul/shadow/kernel/sched/core.c
SRC_C += lx_emul/shadow/kernel/sched/fair.c
@@ -51,6 +50,13 @@ SRC_CC += lx_kit/scheduler.cc
SRC_CC += lx_kit/task.cc
SRC_CC += lx_kit/timeout.cc
# RCU for UP
ifdef RCU_TINY
SRC_C += lx_emul/shadow/kernel/rcu/tiny.c
else
SRC_C += lx_emul/shadow/kernel/rcu/tree.c
endif
ifeq ($(filter-out $(SPECS),x86_32),)
LX_ARCH := x86
GEN_ARCH := x86

View File

@@ -21,7 +21,8 @@ ifeq ($(filter-out $(SPECS),arm_v6),)
INC_DIR += $(VIRT_LINUX_INCLUDE_DIR)/spec/arm_v6
endif
ifeq ($(filter-out $(SPECS),arm_v7),)
INC_DIR += $(VIRT_LINUX_INCLUDE_DIR)/spec/arm_v7
INC_DIR += $(VIRT_LINUX_INCLUDE_DIR)/spec/arm_v7
RCU_TINY := yes
endif
ifeq ($(filter-out $(SPECS),arm_v8),)
INC_DIR += $(VIRT_LINUX_INCLUDE_DIR)/spec/arm_v8
@@ -30,13 +31,19 @@ endif
-include $(call select_from_repositories,lib/import/import-lx_emul_common.inc)
SRC_C += lx_emul/shadow/drivers/char/random.c
SRC_C += lx_emul/shadow/kernel/rcu/srcutree.c
SRC_C += lx_emul/shadow/mm/page_alloc.c
SRC_C += lx_emul/shadow/mm/vmalloc.c
SRC_C += lx_emul/virt/common_dummies.c
SRC_CC += lx_emul/virt/irq.cc
SRC_CC += lx_kit/memory_non_dma.cc
# RCU for UP
ifdef RCU_TINY
SRC_C += kernel/rcu/srcutiny.c
else
SRC_C += lx_emul/shadow/kernel/rcu/srcutree.c
endif
ifeq ($(filter-out $(SPECS),x86),)
SRC_C += lx_emul/virt/spec/x86/dummies_arch.c

View File

@@ -0,0 +1,58 @@
/*
* \brief Replaces kernel/rcu/tiny.c for non-SMP
* \author Sebastian Sumpf
* \date 2024-02-01
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/cache.h>
#include <linux/types.h>
#include <linux/time64.h> /* KTIME_MAX */
#include <linux/mm.h>
#include <linux/rcutiny.h>
#include <linux/rcupdate.h>
#include <linux/version.h>
void call_rcu(struct rcu_head * head,
rcu_callback_t func)
{
/*
* In case func is a small offset kvfree should be
* called directly, see 'rcu_reclaim_tiny'.
*/
enum { KVFREE_RCU_OFFSET = 4096, };
if (func < (rcu_callback_t)KVFREE_RCU_OFFSET) {
kvfree((void*)head - (unsigned long)func);
return;
}
func(head);
}
unsigned long get_state_synchronize_rcu(void)
{
lx_emul_trace_and_stop(__func__);
}
unsigned long start_poll_synchronize_rcu(void)
{
lx_emul_trace_and_stop(__func__);
}
bool poll_state_synchronize_rcu(unsigned long oldstate)
{
lx_emul_trace_and_stop(__func__);
}
void rcu_qs(void) { }

View File

@@ -124,10 +124,12 @@ void ignore_signals(struct task_struct * t)
lx_emul_trace(__func__);
}
#ifdef CONFIG_TREE_SRCU
#include <linux/srcu.h>
void synchronize_srcu(struct srcu_struct * ssp)
{
lx_emul_trace_and_stop(__func__);
}
#endif

View File

@@ -793,6 +793,8 @@ include/linux/rcu_sync.h
include/linux/rculist.h
include/linux/rculist_bl.h
include/linux/rcupdate.h
include/linux/rcupdate_wait.h
include/linux/rcutiny.h
include/linux/rcutree.h
include/linux/rcuwait.h
include/linux/reboot.h
@@ -844,9 +846,13 @@ include/linux/smp_types.h
include/linux/socket.h
include/linux/spinlock.h
include/linux/spinlock_api_smp.h
include/linux/spinlock_api_up.h
include/linux/spinlock_types.h
include/linux/spinlock_types_raw.h
include/linux/spinlock_types_up.h
include/linux/spinlock_up.h
include/linux/srcu.h
include/linux/srcutiny.h
include/linux/srcutree.h
include/linux/stackdepot.h
include/linux/stacktrace.h
@@ -908,6 +914,7 @@ include/linux/wait_bit.h
include/linux/workqueue.h
include/linux/writeback.h
include/linux/xarray.h
include/trace/events/rcu.h
include/uapi/asm-generic/Kbuild
include/uapi/asm-generic/bitsperlong.h
include/uapi/asm-generic/errno-base.h
@@ -1022,6 +1029,9 @@ include/video/edid.h
kernel/bounds.c
kernel/configs/tiny-base.config
kernel/configs/tiny.config
kernel/rcu/rcu.h
kernel/rcu/rcu_segcblist.h
kernel/rcu/srcutiny.c
kernel/time/timeconst.bc
lib/ctype.c
lib/gen_crc32table.c

View File

@@ -5,3 +5,7 @@
# do not generate thumb instructions on ARMv7 platforms
LX_DISABLE += THUMB2_KERNEL ARM_VIRT_EXT DEBUG_PREEMPT
# disable SMP because it will generate unsupported instruction on single core
# Cortex-A8 CPUs
LX_DISABLE += SMP