lx_emul: consolidate SMP + NO_HZ_IDLE

* Move common SMP and NO_HZ_IDLE variables and functions into
  generic lx_emul shadow implementations, and integrate them
  into the common lx_emul import rules
* Enable SMP and NO_HZ_IDLE within virt_linux kernel configuration
* Adapt pc drivers and wireguard accordingly
* Use original Linux softirq implementation in wireguard
* Remove erroneous softirq shadow implementation

Ref genodelabs/genode#4540
Ref genodelabs/genode#4562
This commit is contained in:
Stefan Kalkowski 2022-07-21 11:13:02 +02:00 committed by Christian Helmuth
parent 48eacb6f79
commit 89f9e7a3ee
41 changed files with 403 additions and 2644 deletions

View File

@ -9,4 +9,4 @@ LX_GEN_DIR := $(LIB_CACHE_DIR)/virt_linux_generated
-include $(call select_from_repositories,lib/import/import-lx_emul_common.inc)
SRC_CC += lx_kit/memory_non_dma.cc
SRC_CC += lx_kit/memory_non_dma.cc

View File

@ -18,17 +18,29 @@ SRC_CC += lx_emul/task.cc
SRC_CC += lx_emul/time.cc
SRC_C += lx_emul/clocksource.c
SRC_C += lx_emul/start.c
SRC_C += lx_emul/shadow/fs/exec.c
SRC_C += lx_emul/shadow/kernel/cpu.c
SRC_C += lx_emul/shadow/kernel/exit.c
SRC_C += lx_emul/shadow/kernel/fork.c
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
SRC_C += lx_emul/shadow/kernel/sched/isolation.c
SRC_C += lx_emul/shadow/kernel/sched/loadavg.c
SRC_C += lx_emul/shadow/kernel/sched/sched.c
SRC_C += lx_emul/shadow/kernel/smp.c
SRC_C += lx_emul/shadow/kernel/stop_machine.c
SRC_C += lx_emul/shadow/lib/cpumask.c
SRC_C += lx_emul/shadow/mm/percpu.c
SRC_C += lx_emul/shadow/mm/slab_common.c
SRC_C += lx_emul/shadow/mm/slub.c
SRC_C += lx_emul/shadow/mm/vmstat.c
SRC_C += lx_emul/start.c
SRC_C += lx_emul/virt_to_page.c
SRC_CC += lx_kit/console.cc
@ -44,6 +56,9 @@ LX_ARCH := x86
GEN_ARCH := x86
SPEC_ARCH := x86_32
SRC_C += lx_emul/shadow/arch/x86/kernel/irq.c
SRC_C += lx_emul/shadow/arch/x86/kernel/setup_percpu.c
# temporarily add the following include path for x86 platform_session wrapper
INC_DIR += $(DDE_LINUX_DIR)/src/include/spec/x86/lx_kit
endif
@ -53,6 +68,9 @@ LX_ARCH := x86
GEN_ARCH := x86
SPEC_ARCH := x86_64
SRC_C += lx_emul/shadow/arch/x86/kernel/irq.c
SRC_C += lx_emul/shadow/arch/x86/kernel/setup_percpu.c
# temporarily add the following include path for x86 platform_session wrapper
INC_DIR += $(DDE_LINUX_DIR)/src/include/spec/x86/lx_kit
endif

View File

@ -6,12 +6,10 @@ PRG_DIR := $(REP_DIR)/src/app/wireguard/spec/arm_64
GEN_PRG_DIR := $(PRG_DIR)/../..
SRC_C += arch/arm64/kernel/smp.c
SRC_C += kernel/smp.c
SRC_C += arch/arm64/kernel/cpufeature.c
vpath arch/arm64/kernel/cpufeature.c $(GEN_PRG_DIR)/lx_emul/shadow
vpath arch/arm64/kernel/smp.c $(REP_DIR)/src/lib/lx_emul/shadow
vpath kernel/smp.c $(REP_DIR)/src/lib/lx_emul/shadow
SRC_S += arch/arm64/crypto/poly1305-core.S

View File

@ -17,12 +17,10 @@ SRC_C += dummies_arch.c
SRC_C += lx_emul.c
SRC_C += wireguard.c
SRC_C += genode_c_api_arch.c
SRC_C += softirq.c
vpath wireguard.c $(GEN_PRG_DIR)/genode_c_api
vpath %.c $(PRG_DIR)
vpath %.c $(GEN_PRG_DIR)
vpath softirq.c $(REP_DIR)/src/lib/lx_emul/shadow/kernel
INC_DIR += $(PRG_DIR)
INC_DIR += $(GEN_PRG_DIR)

View File

@ -46,45 +46,43 @@ LX_ABS_DIR := $(addsuffix /$(LX_REL_DIR),$(PORT_DIR))
# ingredients needed for creating a Linux build directory / generated headers
LX_FILES += Kbuild \
Makefile \
arch/arm64/Makefile \
arch/arm64/boot/dts \
arch/arm64/configs \
arch/arm64/crypto/poly1305-armv8.pl \
arch/arm64/include \
arch/arm64/kernel/asm-offsets.c \
arch/arm64/kernel/vdso/Makefile \
arch/arm64/kernel/vdso/gen_vdso_offsets.sh \
arch/arm64/kernel/vdso/note.S \
arch/arm64/kernel/vdso/sigreturn.S \
arch/arm64/kernel/vdso/vdso.lds.S \
arch/arm64/kernel/vdso/vgettimeofday.c \
arch/arm64/tools/Makefile \
arch/arm64/tools/cpucaps \
arch/arm64/tools/gen-cpucaps.awk \
arch/x86/Makefile \
arch/x86/Makefile_32.cpu \
arch/x86/configs \
arch/x86/entry/syscalls/Makefile \
arch/x86/entry/syscalls/syscall_32.tbl \
arch/x86/entry/syscalls/syscall_64.tbl \
arch/x86/include/asm/Kbuild \
arch/x86/include/asm/atomic64_32.h \
arch/x86/include/asm/cmpxchg_32.h \
arch/x86/include/asm/string.h \
arch/x86/include/asm/string_32.h \
arch/x86/include/asm/string_64.h \
arch/x86/include/uapi/asm/Kbuild \
arch/x86/include/uapi/asm/posix_types.h \
arch/x86/include/uapi/asm/posix_types_32.h \
arch/x86/include/uapi/asm/posix_types_64.h \
arch/x86/include \
arch/x86/kernel/asm-offsets.c \
arch/x86/kernel/asm-offsets_64.c \
arch/x86/tools/Makefile \
arch/x86/tools/relocs.c \
arch/x86/tools/relocs.h \
arch/x86/tools/relocs_32.c \
arch/x86/tools/relocs_64.c \
arch/x86/tools/relocs_common.c \
arch/arm64/Makefile \
arch/arm64/configs \
arch/arm64/boot/dts \
arch/arm64/include/asm/Kbuild \
arch/arm64/include/uapi/asm/Kbuild \
arch/arm64/tools/Makefile \
arch/arm64/tools/gen-cpucaps.awk \
arch/arm64/tools/cpucaps \
include/asm-generic/bitops/fls64.h \
include/asm-generic/Kbuild \
include/linux/compiler-version.h \
include/linux/kbuild.h \
include/linux/license.h \
include/uapi/Kbuild \
include/uapi/asm-generic/Kbuild \
include \
kernel/bounds.c \
kernel/configs/tiny-base.config \
kernel/configs/tiny.config \
kernel/time/timeconst.bc \
lib/vdso/Makefile \
lib/vdso/gettimeofday.c \
scripts/Kbuild.include \
scripts/Makefile \
scripts/Makefile.asm-generic \
@ -93,8 +91,8 @@ LX_FILES += Kbuild \
scripts/Makefile.extrawarn \
scripts/Makefile.host \
scripts/Makefile.lib \
scripts/asn1_compiler.c \
scripts/as-version.sh \
scripts/asn1_compiler.c \
scripts/atomic/check-atomics.sh \
scripts/basic/Makefile \
scripts/basic/fixdep.c \
@ -125,23 +123,6 @@ LX_FILES += $(addprefix scripts/kconfig/,$(LX_SCRIPTS_KCONFIG_FILES)) \
LX_FILES += $(shell cd $(LX_ABS_DIR); find -name "Kconfig*" -printf "%P\n")
# needed for generated/asm-offsets.h
LX_FILES += arch/x86/kernel/asm-offsets.c \
arch/x86/kernel/asm-offsets_64.c \
kernel/bounds.c \
kernel/time/timeconst.bc \
arch/arm64/kernel/vdso/vgettimeofday.c \
arch/arm64/kernel/vdso/note.S \
arch/arm64/kernel/vdso/vdso.lds.S \
arch/arm64/kernel/asm-offsets.c \
arch/arm64/kernel/vdso/Makefile \
lib/vdso/Makefile \
arch/arm64/kernel/vdso/sigreturn.S \
lib/vdso/gettimeofday.c \
include/vdso/datapage.h \
arch/arm64/kernel/vdso/gen_vdso_offsets.sh \
arch/arm64/crypto/poly1305-armv8.pl \
# add content listed in the repository's source.list or dep.list files
LX_FILE_LISTS := $(shell find -H $(REP_DIR) -name dep.list -or -name source.list)
LX_FILES += $(shell cat $(LX_FILE_LISTS))

View File

@ -0,0 +1,40 @@
crypto/internal.h
drivers/net/wireguard/allowedips.h
drivers/net/wireguard/cookie.h
drivers/net/wireguard/device.h
drivers/net/wireguard/messages.h
drivers/net/wireguard/netlink.h
drivers/net/wireguard/noise.h
drivers/net/wireguard/peer.h
drivers/net/wireguard/peerlookup.h
drivers/net/wireguard/queueing.h
drivers/net/wireguard/ratelimiter.h
drivers/net/wireguard/selftest/allowedips.c
drivers/net/wireguard/selftest/counter.c
drivers/net/wireguard/selftest/ratelimiter.c
drivers/net/wireguard/socket.h
drivers/net/wireguard/timers.h
drivers/net/wireguard/version.h
kernel/irq/debug.h
kernel/irq/internals.h
kernel/irq/settings.h
kernel/locking/lock_events.h
kernel/locking/lock_events_list.h
kernel/locking/mutex.h
kernel/sched/autogroup.h
kernel/sched/cpudeadline.h
kernel/sched/cpupri.h
kernel/sched/features.h
kernel/sched/sched.h
kernel/sched/stats.h
kernel/smpboot.h
kernel/time/ntp_internal.h
kernel/time/tick-internal.h
kernel/time/tick-sched.h
kernel/time/timekeeping.h
kernel/time/timekeeping_internal.h
kernel/workqueue_internal.h
lib/kstrtox.h
mm/internal.h
mm/slab.h
net/core/datagram.h

View File

@ -285,8 +285,9 @@ __wsum csum_partial(const void * buff,int len,__wsum sum)
}
#include <linux//wait_bit.h>
void __init wait_bit_init(void)
#include <linux/rcutree.h>
void kvfree(const void * addr)
{
lx_emul_trace(__func__);
lx_emul_trace_and_stop(__func__);
}

View File

@ -220,10 +220,6 @@ _genode_wg_set_device(struct genl_info *info)
}
void genode_wg_arch_net_dev_init(struct net_device *net_dev,
int *pcpu_refcnt);
static void
_genode_wg_config_add_dev(genode_wg_u16_t listen_port,
const genode_wg_u8_t * const priv_key)
@ -237,10 +233,8 @@ _genode_wg_config_add_dev(genode_wg_u16_t listen_port,
/* prepare environment for the execution of 'wg_set_device' */
_genode_wg_net_dev.public_data.rtnl_link_ops = _genode_wg_rtnl_link_ops;
_genode_wg_net_dev.public_data.pcpu_refcnt = &_genode_wg_net_dev.pcpu_refcnt;
_genode_wg_net_dev.pcpu_refcnt = 0;
genode_wg_arch_net_dev_init(
genode_wg_net_device(), &_genode_wg_net_dev.pcpu_refcnt);
_genode_wg_sk_buff.sk = &_genode_wg_sock;
_genode_wg_sock.sk_user_data = &_genode_wg_net_dev.private_data;

View File

@ -276,26 +276,6 @@ struct rtable * ip_route_output_flow(struct net * net,struct flowi4 * flp4,const
}
#include <linux/sched.h>
int __cond_resched(void)
{
if (should_resched(0)) {
schedule();
return 1;
}
return 0;
}
#include <linux/rcupdate.h>
void call_rcu(struct rcu_head * head,rcu_callback_t func)
{
func(head);
}
#include <linux/slab.h>
void kfree_sensitive(const void * p)
@ -383,3 +363,9 @@ bool __do_once_start(bool * done,unsigned long * flags)
{
return !*done;
}
#ifdef CONFIG_X86_64
DEFINE_PER_CPU(void *, hardirq_stack_ptr);
#endif
DEFINE_PER_CPU(bool, hardirq_stack_inuse);

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,6 @@ bool cpu_have_feature(unsigned int num)
u64 vabits_actual;
void rcu_read_unlock_strict(void)
{
lx_emul_trace(__func__);
}
unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n)
{
lx_emul_trace_and_stop(__func__);
@ -82,32 +77,9 @@ void __init generic_sched_clock_init(void)
lx_emul_trace(__func__);
}
#include <linux/sched.h>
void do_set_cpus_allowed(struct task_struct * p,const struct cpumask * new_mask)
{
lx_emul_trace(__func__);
}
#include <linux/of.h>
void __init of_core_init(void)
{
lx_emul_trace(__func__);
}
#include <linux/stop_machine.h>
int stop_machine(cpu_stop_fn_t fn,void * data,const struct cpumask * cpus)
{
return (*fn)(data);
}
#include <linux/rcutree.h>
void kvfree(const void * addr)
{
lx_emul_trace_and_stop(__func__);
}

View File

@ -1,7 +1,7 @@
/*
* \brief Dummy definitions of Linux Kernel functions
* \author Automatically generated file - do no edit
* \date 2022-05-04
* \date 2022-07-21
*/
#include <lx_emul.h>
@ -141,6 +141,11 @@ void flush_dcache_page(struct page * page)
}
#include <linux/interrupt.h>
bool force_irqthreads;
#include <linux/netdevice.h>
void free_netdev(struct net_device * dev)
@ -498,25 +503,17 @@ int printk_deferred(const char * fmt,...)
}
#include <asm-generic/qrwlock.h>
#include <linux/rcutree.h>
void queued_read_lock_slowpath(struct qrwlock * lock)
void rcu_irq_enter_irqson(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <asm-generic/qspinlock.h>
#include <linux/rcutree.h>
void queued_spin_lock_slowpath(struct qspinlock * lock,u32 val)
{
lx_emul_trace_and_stop(__func__);
}
#include <asm-generic/qrwlock.h>
void queued_write_lock_slowpath(struct qrwlock * lock)
void rcu_irq_exit_irqson(void)
{
lx_emul_trace_and_stop(__func__);
}

View File

@ -1,13 +1,6 @@
#include <linux/netdevice.h>
void genode_wg_arch_net_dev_init(struct net_device *net_dev,
int *pcpu_refcnt)
{
net_dev->pcpu_refcnt = pcpu_refcnt;
}
void finalize_system_capabilities(void);

View File

@ -7,7 +7,6 @@ arch/arm64/lib/strlen.S
crypto/skcipher.c
crypto/api.c
lib/hweight.c
lib/cpumask.c
crypto/algapi.c
crypto/memneq.c
crypto/scatterwalk.c
@ -33,13 +32,19 @@ kernel/sched/clock.c
kernel/sched/completion.c
kernel/sched/swait.c
kernel/sched/wait.c
kernel/sched/wait_bit.c
kernel/smpboot.c
kernel/softirq.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/hrtimer.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/tick-broadcast-hrtimer.c
kernel/time/tick-common.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/time.c
kernel/time/timeconv.c
kernel/time/timecounter.c

File diff suppressed because it is too large Load Diff

View File

@ -24,3 +24,4 @@ void clocksource_arch_init(struct clocksource * cs)
struct cpuinfo_x86 boot_cpu_data __read_mostly;

View File

@ -1,7 +1,7 @@
/*
* \brief Dummy definitions of Linux Kernel functions
* \author Automatically generated file - do no edit
* \date 2022-01-25
* \date 2022-07-19
*/
#include <lx_emul.h>
@ -39,22 +39,6 @@ int __ipv6_addr_type(const struct in6_addr * addr)
}
#include <linux/irqdomain.h>
struct irq_domain * __irq_domain_add(struct fwnode_handle * fwnode,int size,irq_hw_number_t hwirq_max,int direct_max,const struct irq_domain_ops * ops,void * host_data)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/irqdomain.h>
struct irq_desc * __irq_resolve_mapping(struct irq_domain * domain,irq_hw_number_t hwirq,unsigned int * irq)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/mm.h>
void __put_page(struct page * page)
@ -118,21 +102,6 @@ void ack_bad_irq(unsigned int irq)
}
extern int cpu_has_xfeatures(u64 xfeatures_needed,const char ** feature_name);
int cpu_has_xfeatures(u64 xfeatures_needed,const char ** feature_name)
{
lx_emul_trace_and_stop(__func__);
}
#include <crypto/internal/skcipher.h>
int crypto_register_skciphers(struct skcipher_alg * algs,int count)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/netdevice.h>
struct net_device * dev_get_by_index(struct net * net,int ifindex)
@ -157,6 +126,11 @@ asmlinkage __visible void dump_stack(void)
}
#include <linux/interrupt.h>
bool force_irqthreads;
#include <linux/netdevice.h>
void free_netdev(struct net_device * dev)
@ -307,9 +281,9 @@ int ipv6_chk_addr(struct net * net,const struct in6_addr * addr,const struct net
}
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
void irq_domain_free_irqs_common(struct irq_domain * domain,unsigned int virq,unsigned int nr_irqs)
int irq_can_set_affinity(unsigned int irq)
{
lx_emul_trace_and_stop(__func__);
}
@ -322,9 +296,9 @@ bool irq_fpu_usable(void)
}
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
void irq_set_default_host(struct irq_domain * domain)
int irq_set_affinity(unsigned int irq,const struct cpumask * cpumask)
{
lx_emul_trace_and_stop(__func__);
}
@ -381,17 +355,20 @@ int kstrtoll(const char * s,unsigned int base,long long * res)
}
#include <linux/rcutiny.h>
#include <linux/preempt.h>
void kvfree(const void * addr)
void migrate_disable(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/delay.h>
#include <linux/preempt.h>
unsigned long lpj_fine;
void migrate_enable(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/netdevice.h>
@ -410,6 +387,14 @@ void page_frag_free(void * addr)
}
#include <linux/percpu_counter.h>
void percpu_counter_add_batch(struct percpu_counter * fbc,s64 amount,s32 batch)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/printk.h>
int printk_deferred(const char * fmt,...)
@ -466,17 +451,9 @@ void skb_set_owner_w(struct sk_buff * skb,struct sock * sk)
}
#include <crypto/internal/skcipher.h>
#include <linux/smp.h>
int skcipher_walk_done(struct skcipher_walk * walk,int err)
{
lx_emul_trace_and_stop(__func__);
}
#include <crypto/internal/skcipher.h>
int skcipher_walk_virt(struct skcipher_walk * walk,struct skcipher_request * req,bool atomic)
int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait)
{
lx_emul_trace_and_stop(__func__);
}
@ -570,3 +547,4 @@ void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task)
{
lx_emul_trace_and_stop(__func__);
}

View File

@ -1,11 +1,6 @@
#include <linux/netdevice.h>
void genode_wg_arch_net_dev_init(struct net_device *net_dev,
int *pcpu_refcnt)
{
}
void genode_wg_arch_lx_user_init(void)
{
}

View File

@ -27,12 +27,16 @@ drivers/net/wireguard/socket.c
drivers/net/wireguard/timers.c
kernel/kthread.c
kernel/locking/mutex.c
kernel/locking/osq_lock.c
kernel/locking/rwsem.c
kernel/notifier.c
kernel/sched/clock.c
kernel/sched/completion.c
kernel/sched/swait.c
kernel/sched/wait.c
kernel/sched/wait_bit.c
kernel/smpboot.c
kernel/softirq.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/hrtimer.c
@ -40,6 +44,8 @@ kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/time.c
kernel/time/timeconv.c
kernel/time/timecounter.c

View File

@ -0,0 +1,18 @@
/*
* \brief Replaces arch/x86/kernel/irq.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/irq.h>
#include <asm/hardirq.h>
DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
EXPORT_PER_CPU_SYMBOL(irq_stat);

View File

@ -0,0 +1,25 @@
/*
* \brief Replaces arch/x86/kernel/setup_percpu.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <asm/processor.h>
#include <asm/cpu.h>
int cpu_number = 0;
DEFINE_PER_CPU_READ_MOSTLY(unsigned long, this_cpu_off) = 0;
EXPORT_PER_CPU_SYMBOL(this_cpu_off);
unsigned long __per_cpu_offset[NR_CPUS] = { 0UL };

View File

@ -16,6 +16,7 @@
#include <linux/cpu.h>
#include <linux/cpumask.h>
atomic_t __num_online_cpus = ATOMIC_INIT(1);
struct cpumask __cpu_online_mask = { .bits[0] = 1 };
struct cpumask __cpu_possible_mask = { .bits[0] = 1 };
struct cpumask __cpu_present_mask = { .bits[0] = 1 };

View File

@ -0,0 +1,20 @@
/*
* \brief Replaces kernel/irq_work.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/irq_work.h>
bool irq_work_needs_cpu(void)
{
return false;
}

View File

@ -11,15 +11,23 @@
* version 2.
*/
#include <linux/cache.h>
#include <linux/types.h>
#include <linux/time64.h> /* KTIME_MAX */
#include <linux/mm.h>
#include <linux/rcutree.h>
#include <linux/rcupdate.h>
extern void __rcu_read_lock(void);
#ifdef CONFIG_PREEMPT_RCU
void __rcu_read_lock(void) { }
extern void __rcu_read_unlock(void);
void __rcu_read_unlock(void) { }
#endif
extern void rcu_read_unlock_strict(void);
void rcu_read_unlock_strict(void) { }
int rcu_needs_cpu(u64 basemono, u64 *nextevt)
{
@ -27,3 +35,29 @@ int rcu_needs_cpu(u64 basemono, u64 *nextevt)
*nextevt = KTIME_MAX;
return 0;
}
noinstr void rcu_irq_enter(void) { }
void noinstr rcu_irq_exit(void) { }
void rcu_softirq_qs(void) { }
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);
}

View File

@ -22,6 +22,7 @@
#include <linux/sched/stat.h>
#include <linux/sched/nohz.h>
#include <linux/version.h>
#include <linux/kernel_stat.h>
#include <lx_emul/debug.h>
#include <lx_emul/task.h>
@ -44,6 +45,10 @@ typedef unsigned int wait_task_inactive_match_state_t;
#endif
DEFINE_PER_CPU(struct kernel_stat, kstat);
EXPORT_PER_CPU_SYMBOL(kstat);
void set_user_nice(struct task_struct * p, long nice)
{
p->static_prio = NICE_TO_PRIO(nice);
@ -183,7 +188,6 @@ int wake_up_state(struct task_struct * p, unsigned int state)
#ifdef CONFIG_SMP
unsigned long wait_task_inactive(struct task_struct * p,
wait_task_inactive_match_state_t match_state)
{
@ -206,15 +210,20 @@ int set_cpus_allowed_ptr(struct task_struct * p,
}
#ifdef CONFIG_NO_HZ_COMMON
void do_set_cpus_allowed(struct task_struct * p,
const struct cpumask * new_mask) { }
#ifdef CONFIG_NO_HZ_COMMON
int get_nohz_timer_target(void)
{
return 0;
}
#endif
#endif
void wake_up_nohz_cpu(int cpu) { }
#endif /* CONFIG_NO_HZ_COMMON */
#endif /* CONFIG_SMP */
static bool __wake_q_add(struct wake_q_head *head, struct task_struct *task)
@ -253,3 +262,9 @@ void wake_up_q(struct wake_q_head *head)
put_task_struct(task);
}
}
int idle_cpu(int cpu)
{
return 1;
}

View File

@ -0,0 +1,17 @@
/*
* \brief Replaces kernel/sched/cputime.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/sched.h>
void account_idle_ticks(unsigned long ticks) { }

View File

@ -0,0 +1,17 @@
/*
* \brief Replaces kernel/sched/fair.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <../kernel/sched/sched.h>
#include <linux/sched/nohz.h>
void nohz_balance_enter_idle(int cpu) { }

View File

@ -0,0 +1,30 @@
/*
* \brief Replaces kernel/sched/isolation.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/sched/isolation.h>
#ifdef CONFIG_CPU_ISOLATION
const struct cpumask * housekeeping_cpumask(enum hk_flags flags)
{
static struct cpumask dummy;
return &dummy;
}
bool housekeeping_enabled(enum hk_flags flags)
{
return false;
}
#endif

View File

@ -0,0 +1,20 @@
/*
* \brief Replaces kernel/sched/loadavg.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/sched.h>
void calc_load_nohz_start(void) { }
void calc_load_nohz_stop(void) { }

View File

@ -1,84 +0,0 @@
/*
* \brief Replaces kernel/softirq.c
* \author Stefan Kalkowski
* \date 2021-03-16
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/interrupt.h>
#include <linux/bottom_half.h>
#include <linux/tick.h>
#define CREATE_TRACE_POINTS
#include <trace/events/irq.h>
#include <lx_emul/debug.h>
irq_cpustat_t irq_stat;
int __init __weak arch_probe_nr_irqs(void)
{
return 0;
}
int __init __weak arch_early_irq_init(void)
{
return 0;
}
unsigned int __weak arch_dynirq_lower_bound(unsigned int from)
{
return from;
}
static struct softirq_action actions[NR_SOFTIRQS];
void open_softirq(int nr, void (* action)(struct softirq_action *))
{
if (nr >= NR_SOFTIRQS) {
printk("Error: %s nr=%d exceeds softirq limit\n", __func__, nr);
return;
}
actions[nr].action = action;
}
inline void raise_softirq_irqoff(unsigned int nr)
{
if (nr >= NR_SOFTIRQS || !actions[nr].action)
return;
actions[nr].action(&actions[nr]);
}
void raise_softirq(unsigned int nr)
{
raise_softirq_irqoff(nr);
}
void __local_bh_enable_ip(unsigned long ip,unsigned int cnt)
{
/*
* Called by write_unlock_bh, which reverts preempt_cnt by the
* value SOFTIRQ_LOCK_OFFSET.
*/
__preempt_count_sub(cnt);
}
void __init softirq_init(void) {}
void irq_enter(void) {}
void irq_exit(void) {}

View File

@ -0,0 +1,30 @@
/*
* \brief Replaces lib/cpumask.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/cpumask.h>
#include <lx_emul/debug.h>
unsigned int cpumask_next(int n,const struct cpumask * srcp)
{
return n + 1;
}
int cpumask_next_and(int n,
const struct cpumask * src1p,
const struct cpumask * src2p)
{
return n + 1;
}

View File

@ -0,0 +1,18 @@
/*
* \brief Replaces mm/vmstat.c
* \author Stefan Kalkowski
* \date 2022-07-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/mm.h>
#include <linux/vmstat.h>
void quiet_vmstat(void) { }

View File

@ -3,7 +3,10 @@
#
# kernel fundamentals
LX_ENABLE += TTY SERIAL_EARLYCON SERIAL_OF_PLATFORM PRINTK HAS_IOMEM
LX_ENABLE += TTY SERIAL_EARLYCON SERIAL_OF_PLATFORM PRINTK HAS_IOMEM SMP
# support disabling ticking during idle
LX_ENABLE += NO_HZ_IDLE
# initrd support
LX_ENABLE += BINFMT_ELF BLK_DEV_INITRD

View File

@ -21,10 +21,6 @@ SRC_CC += lx_emul/irq.cc
SRC_CC += lx_emul/random.cc
SRC_C += lx_emul/shadow/kernel/dma/mapping.c
SRC_C += lx_emul/shadow/kernel/irq/spurious.c
SRC_C += lx_emul/shadow/kernel/locking/spinlock.c
SRC_C += lx_emul/shadow/kernel/rcu/tree.c
SRC_C += lx_emul/shadow/kernel/sched/sched.c
SRC_C += lx_emul/shadow/kernel/stop_machine.c
SRC_C += lx_emul/shadow/lib/devres.c
SRC_C += lx_emul/shadow/lib/smp_processor_id.c
SRC_C += lx_emul/shadow/mm/memblock.c
@ -51,7 +47,6 @@ SRC_C += lx_emul/vmalloc.c
SRC_C += lx_emul/delay.c
SRC_C += lx_emul/shadow/fs/libfs.c
SRC_C += lx_emul/shadow/kernel/rcu/tiny.c
SRC_C += lx_emul/shadow/lib/logic_iomem.c
SRC_C += lx_emul/shadow/drivers/char/random.c

View File

@ -528,30 +528,6 @@ void intel_dsb_commit(const struct intel_crtc_state *crtc_state)
}
void calc_load_nohz_start(void)
{
lx_emul_trace(__func__);
}
void calc_load_nohz_stop(void)
{
lx_emul_trace(__func__);
}
void account_idle_ticks(unsigned long ticks)
{
lx_emul_trace(__func__);
}
bool irq_work_needs_cpu(void)
{
return false;
}
#include <asm/smp.h>
struct smp_ops smp_ops = { };

View File

@ -84,30 +84,6 @@ int __printk_ratelimit(const char * func)
}
void calc_load_nohz_start(void)
{
lx_emul_trace(__func__);
}
void calc_load_nohz_stop(void)
{
lx_emul_trace(__func__);
}
void account_idle_ticks(unsigned long ticks)
{
lx_emul_trace(__func__);
}
bool irq_work_needs_cpu(void)
{
return false;
}
#include <linux/prandom.h>
u32 prandom_u32(void)

View File

@ -43,11 +43,6 @@ const struct trace_print_flags vmaflag_names[] = { {0,NULL}};
const struct trace_print_flags pageflag_names[] = { {0,NULL}};
#include <linux/kernel_stat.h>
struct kernel_stat kstat;
#include <asm/processor.h>
/*
@ -371,13 +366,6 @@ bool pat_enabled(void)
}
#include <linux/cpumask.h>
atomic_t __num_online_cpus = ATOMIC_INIT(1);
unsigned long __per_cpu_offset[NR_CPUS] = { 0UL };
struct srcu_struct;
extern int __srcu_read_lock(struct srcu_struct * ssp);
int __srcu_read_lock(struct srcu_struct * ssp)
@ -402,78 +390,6 @@ void cpu_hotplug_enable(void)
}
#include <linux/cpumask.h>
unsigned int cpumask_next(int n,const struct cpumask * srcp)
{
lx_emul_trace(__func__);
return n + 1;
}
#include <linux/cpumask.h>
int cpumask_next_and(int n,const struct cpumask * src1p,const struct cpumask * src2p)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/sched.h>
void do_set_cpus_allowed(struct task_struct * p,const struct cpumask * new_mask)
{
lx_emul_trace(__func__);
}
#include <linux/sched/isolation.h>
const struct cpumask * housekeeping_cpumask(enum hk_flags flags)
{
static struct cpumask ret;
lx_emul_trace(__func__);
return &ret;
}
#include <linux/sched/isolation.h>
bool housekeeping_enabled(enum hk_flags flags)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/cpumask.h>
unsigned int nr_cpu_ids = 1;
#include <linux/rcutree.h>
noinstr void rcu_irq_enter(void)
{
lx_emul_trace(__func__);
}
#include <linux/rcutree.h>
void noinstr rcu_irq_exit(void)
{
lx_emul_trace(__func__);
}
#include <linux/rcutree.h>
void rcu_softirq_qs(void)
{
lx_emul_trace(__func__);
}
extern void synchronize_srcu(struct srcu_struct * ssp);
void synchronize_srcu(struct srcu_struct * ssp)
{
@ -481,64 +397,15 @@ void synchronize_srcu(struct srcu_struct * ssp)
}
int cpu_number = 0;
#ifdef CONFIG_X86_64
DEFINE_PER_CPU(void *, hardirq_stack_ptr);
#endif
DEFINE_PER_CPU(bool, hardirq_stack_inuse);
#include <linux/interrupt.h>
DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
EXPORT_PER_CPU_SYMBOL(irq_stat);
extern void rcu_read_unlock_strict(void);
void rcu_read_unlock_strict(void)
{
lx_emul_trace(__func__);
}
DEFINE_PER_CPU_READ_MOSTLY(unsigned long, this_cpu_off) = 0;
EXPORT_PER_CPU_SYMBOL(this_cpu_off);
#include <asm/processor.h>
DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
EXPORT_PER_CPU_SYMBOL(cpu_info);
#include <linux/sched/nohz.h>
void wake_up_nohz_cpu(int cpu)
{
lx_emul_trace(__func__);
}
#include <linux/sched/nohz.h>
void nohz_balance_enter_idle(int cpu)
{
lx_emul_trace(__func__);
}
#include <linux/vmstat.h>
void quiet_vmstat(void)
{
lx_emul_trace(__func__);
}
extern int idle_cpu(int cpu);
int idle_cpu(int cpu)
{
lx_emul_trace(__func__);
return 1;
}

View File

@ -17,6 +17,7 @@ arch/x86/include/asm/cmpxchg.h
arch/x86/include/asm/compat.h
arch/x86/include/asm/cpu_entry_area.h
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/cpu.h
arch/x86/include/asm/cpumask.h
arch/x86/include/asm/delay.h
arch/x86/include/asm/desc.h
@ -239,6 +240,7 @@ include/linux/atomic.h
include/linux/audit.h
include/linux/auxvec.h
include/linux/backing-dev-defs.h
include/linux/bcd.h
include/linux/binfmts.h
include/linux/bio.h
include/linux/bit_spinlock.h

View File

@ -1,31 +0,0 @@
/*
* \brief Replaces kernel/rcu/tiny.c
* \author Josef Soentgen
* \date 2022-04-05
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/mm.h>
#include <linux/rcupdate.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);
}

View File

@ -296,30 +296,6 @@ int net_ratelimit(void)
}
void calc_load_nohz_start(void)
{
lx_emul_trace(__func__);
}
void calc_load_nohz_stop(void)
{
lx_emul_trace(__func__);
}
void account_idle_ticks(unsigned long ticks)
{
lx_emul_trace(__func__);
}
bool irq_work_needs_cpu(void)
{
return false;
}
#include <asm/smp.h>
struct smp_ops smp_ops = { };

View File

@ -29,31 +29,6 @@
#include <linux/timekeeper_internal.h>
void calc_load_nohz_start(void)
{
lx_emul_trace(__func__);
}
void calc_load_nohz_stop(void)
{
lx_emul_trace(__func__);
}
void account_idle_ticks(unsigned long ticks)
{
lx_emul_trace(__func__);
}
bool irq_work_needs_cpu(void)
{
return false;
}
int ___ratelimit(struct ratelimit_state * rs, const char * func)
{
/*