From f4e0230dde250f0c043f6129ed967effb795f3bb Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Thu, 6 Dec 2012 11:23:26 +0100 Subject: [PATCH] L4lx: mask all VCPU IRQs when doing ipc (fix #553) Open VCPU interrupts while the VCPU is in an IPC operation can badly influence its state. That's why this commit fixes a whole bunch of places, where IRQs weren't masked by now. --- ports-foc/patches/l4lx_genode.patch | 506 ++++++++++--------- ports-foc/src/drivers/genode_serial.c | 4 + ports-foc/src/lib/l4lx/genode_block.cc | 25 +- ports-foc/src/lib/l4lx/genode_framebuffer.cc | 2 + ports-foc/src/lib/l4lx/genode_input.cc | 14 +- ports-foc/src/lib/l4lx/include/linux.h | 19 +- ports-foc/src/lib/l4lx/l4_log.cc | 6 + ports-foc/src/lib/l4lx/l4lx_irq.cc | 20 +- ports-foc/src/lib/l4lx/l4lx_task.cc | 4 + ports-foc/src/lib/l4lx/l4lx_thread.cc | 22 +- 10 files changed, 360 insertions(+), 262 deletions(-) diff --git a/ports-foc/patches/l4lx_genode.patch b/ports-foc/patches/l4lx_genode.patch index 1c223210b7..021bc0bab1 100644 --- a/ports-foc/patches/l4lx_genode.patch +++ b/ports-foc/patches/l4lx_genode.patch @@ -1,3 +1,170 @@ +Index: arch/l4/boot/Makefile +=================================================================== +--- arch/l4/boot/Makefile (revision 25) ++++ arch/l4/boot/Makefile (working copy) +@@ -10,7 +10,7 @@ + $(call if_changed,objcopy) + @echo ' Kernel: $@ is ready' + +-lImage: $(obj)/Image vmlinuz$(VMLINUZ_SUFFIX) l4linux$(VMLINUZ_SUFFIX) ++lImage: $(obj)/Image + + vmlinuz$(VMLINUZ_SUFFIX): ldrImage FORCE + $(call if_changed,gzip) +@@ -21,8 +21,8 @@ + + objects-y := ldr.o res.o image.o + +-include $(L4OBJ)/l4defs.mk.inc +- ++#include $(L4OBJ)/l4defs.mk.inc ++KBUILD_CFLAGS_i386 = -m32 + KBUILD_CFLAGS := $(filter-out -mregparm=3,$(KBUILD_CFLAGS)) \ + $(L4INC) -I$(L4OBJ)/include/uclibc \ + -Wall -fno-strict-aliasing -O2 -pipe \ +Index: arch/l4/lib/pte.c +=================================================================== +--- arch/l4/lib/pte.c (revision 25) ++++ arch/l4/lib/pte.c (working copy) +@@ -18,7 +18,10 @@ + #include + #include + #include ++#include + ++extern void l4lx_memory_map_physical_page(unsigned long address); ++ + static void l4x_flush_page(struct mm_struct *mm, + unsigned long address, + unsigned long vaddr, +@@ -77,7 +80,7 @@ + if (mm && !l4_is_invalid_cap(mm->context.task)) { + L4XV_V(f); + if (!mm->context.task) +- l4x_printf("%s: Ups, task == 0\n", __func__); ++ LOG_printf("%s: Ups, task == 0\n", __func__); + /* Direct flush in the child, use virtual address in the + * child address space */ + L4XV_L(f); +@@ -93,10 +96,11 @@ + tag = l4_task_unmap(L4RE_THIS_TASK_CAP, + l4_fpage(address & PAGE_MASK, size, flush_rights), + L4_FP_OTHER_SPACES); ++ l4lx_memory_map_physical_page(address); + L4XV_U(f); + } + if (l4_error(tag)) +- l4x_printf("l4_task_unmap error %ld\n", l4_error(tag)); ++ LOG_printf("l4_task_unmap error %ld\n", l4_error(tag)); + } + + #ifdef ARCH_arm +Index: arch/l4/Makefile +=================================================================== +--- arch/l4/Makefile (revision 25) ++++ arch/l4/Makefile (working copy) +@@ -163,6 +163,14 @@ + KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) + KBUILD_CFLAGS += $(call cc-option,-mno-avx,) + ++# ++# Prevent the gcc from linking Linux functions into compiler-generated ++# Genode stuff. ++# ++KBUILD_CFLAGS += -Dmemmove=lx_memmove -Dmemset=lx_memset -Dmemcpy=lx_memcpy ++KBUILD_CFLAGS += -Dstrlen=lx_strlen -Dabort=lx_abort ++ ++ + endif + + ifeq ($(BASEARCH),arm) +@@ -243,6 +251,8 @@ + + endif + ++# Genode compiler is build without Linux defines. ++KBUILD_CFLAGS +=-D__linux__ -Dlinux + + # ----------------------------------------------- + +@@ -265,14 +275,15 @@ + L4LX_E_L-$(CONFIG_L4_TCG_STPM) += stpm-client + L4LX_E_L-$(CONFIG_L4_FERRET) += ferret + +-L4INC = -I$(L4OBJ)/include/$(L4_MK_ARCH)/$(L4_MK_API) \ +- -I$(L4OBJ)/include/$(L4_MK_ARCH) \ +- -I$(L4OBJ)/include/$(L4_MK_API) \ +- -I$(L4OBJ)/include ++#L4INC = -I$(L4OBJ)/include/$(L4_MK_ARCH)/$(L4_MK_API) \ ++# -I$(L4OBJ)/include/$(L4_MK_ARCH) \ ++# -I$(L4OBJ)/include/$(L4_MK_API) \ ++# -I$(L4OBJ)/include + + head-y := arch/l4/kernel/head.o + +-libs-y += arch/l4/lib/arch-$(BASEARCH)/ \ ++libs-y += arch/l4/lib/arch-$(BASEARCH)/ ++#\ + arch/l4/l4lxlib/generic/ \ + arch/l4/l4lxlib/$(BASEENV)/ + +@@ -291,7 +302,7 @@ + + core-y += arch/l4/ + +--include $(L4OBJ)/l4defs.mk.inc ++#-include $(L4OBJ)/l4defs.mk.inc + + L4_REQUIRED_MODS := libc_be_minimal_log_io \ + libc_minimal libc_minimal_l4re \ +@@ -307,15 +318,17 @@ + $(error Aborting.) + endif + +-libs-y += -Bstatic $(L4_LIBDIRS) -ll4sys -ll4sys-direct -lgcc-l4 ++libs-y += -Bstatic $(L4_LIBDIRS) ++#-ll4sys -ll4sys-direct -lgcc-l4 ++libs-y += $(GENODE_LIBS) + export L4INC L4_REQUIRED_MODS + +-LDFLAGS_vmlinux = \ +- --defsym __L4_KIP_ADDR__=$(L4_BID_KIP_ADDR) \ ++LDFLAGS_vmlinux = -nostdlib ++# --defsym __L4_KIP_ADDR__=$(L4_BID_KIP_ADDR) \ + --defsym __l4sys_invoke_direct=$(L4_BID_KIP_ADDR)+$(L4_BID_KIP_OFFS_SYS_INVOKE) \ + --defsym __l4sys_debugger_direct=$(L4_BID_KIP_ADDR)+$(L4_BID_KIP_OFFS_SYS_DEBUGGER) + +-KBUILD_CPPFLAGS += -Iarch/l4/include/asm/l4-arch \ ++KBUILD_CPPFLAGS += $(GENODE_INCLUDES) -Iarch/l4/include/asm/l4-arch \ + -Iarch/$(LINSRCARCH)/include/generated \ + $(if $(PLATFORMNAME),-I$(src)/arch/l4/include/asm/mach-$(LINSRCARCH)/$(PLATFORMNAME)) \ + $(if $(PLATFORMNAME),-I$(src)/arch/l4/include/asm/plat-$(LINSRCARCH)/$(PLATFORMNAME)) \ +@@ -337,6 +350,8 @@ + KBUILD_CPPFLAGS += -DTEXT_OFFSET=0x01000000 + endif + ++drivers-y += arch/l4/drivers/ ++ + all: lImage + + boot := arch/l4/boot +@@ -345,11 +360,11 @@ + $(Q)$(MAKE) $(build)=$(boot) $@ + + check_for_l4defs: +- $(Q)if [ ! -e $(L4OBJ)/l4defs.mk.inc ]; then \ +- echo "No $(L4OBJ)/l4defs.mk.inc available."; \ +- echo "Did you run 'make' in $(L4OBJ) to a successful end?"; \ +- exit 1; \ +- fi ++# $(Q)if [ ! -e $(L4OBJ)/l4defs.mk.inc ]; then \ ++# echo "No $(L4OBJ)/l4defs.mk.inc available."; \ ++# echo "Did you run 'make' in $(L4OBJ) to a successful end?"; \ ++# exit 1; \ ++# fi + + server: + $(Q)$(MAKE) $(build)=arch/l4/server Index: arch/l4/Kconfig =================================================================== --- arch/l4/Kconfig (revision 25) @@ -45,6 +212,42 @@ Index: arch/l4/kernel/dispatch.c } } } +Index: arch/l4/kernel/arch-arm/traps.c +=================================================================== +--- arch/l4/kernel/arch-arm/traps.c (revision 25) ++++ arch/l4/kernel/arch-arm/traps.c (working copy) +@@ -68,6 +68,7 @@ + dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); + } + ++#if 0 + #ifndef CONFIG_ARM_UNWIND + /* + * Stack pointers should always be within the kernels view of +@@ -83,6 +84,7 @@ + return 0; + } + #endif ++#endif + + /* + * Dump out the contents of some memory nicely... +@@ -172,6 +174,7 @@ + #else + static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) + { ++#if 0 + unsigned int fp, mode; + int ok = 1; + +@@ -203,6 +206,7 @@ + + if (ok) + c_backtrace(fp, mode); ++#endif + } + #endif + Index: arch/l4/kernel/arch-arm/vmlinux.lds.S =================================================================== --- arch/l4/kernel/arch-arm/vmlinux.lds.S (revision 25) @@ -182,42 +385,6 @@ Index: arch/l4/kernel/arch-arm/vmlinux.lds.S _end = .; STABS_DEBUG -Index: arch/l4/kernel/arch-arm/traps.c -=================================================================== ---- arch/l4/kernel/arch-arm/traps.c (revision 25) -+++ arch/l4/kernel/arch-arm/traps.c (working copy) -@@ -68,6 +68,7 @@ - dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); - } - -+#if 0 - #ifndef CONFIG_ARM_UNWIND - /* - * Stack pointers should always be within the kernels view of -@@ -83,6 +84,7 @@ - return 0; - } - #endif -+#endif - - /* - * Dump out the contents of some memory nicely... -@@ -172,6 +174,7 @@ - #else - static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) - { -+#if 0 - unsigned int fp, mode; - int ok = 1; - -@@ -203,6 +206,7 @@ - - if (ok) - c_backtrace(fp, mode); -+#endif - } - #endif - Index: arch/l4/kernel/arch-x86/x86_init.c =================================================================== --- arch/l4/kernel/arch-x86/x86_init.c (revision 25) @@ -433,6 +600,18 @@ Index: arch/l4/kernel/arch-x86/vmlinux.lds.S _end = .; STABS_DEBUG +Index: arch/l4/kernel/arch-x86/dispatch.c +=================================================================== +--- arch/l4/kernel/arch-x86/dispatch.c (revision 25) ++++ arch/l4/kernel/arch-x86/dispatch.c (working copy) +@@ -749,6 +749,7 @@ + + TBUF_LOG_EXCP(fiasco_tbuf_log_3val("except ", TBUF_TID(t->user_thread_id), t->trap_nr, t->error_code)); + ++ fiasco_tbuf_log_3val("except ", t->trap_nr, regs->ip, 0); + if (l4x_deliver_signal(r_trapno(t, v), r_err(t, v))) + return 0; /* handled signal, reply */ + Index: arch/l4/kernel/timer.c =================================================================== --- arch/l4/kernel/timer.c (revision 25) @@ -499,16 +678,15 @@ Index: arch/l4/kernel/main.c =================================================================== --- arch/l4/kernel/main.c (revision 25) +++ arch/l4/kernel/main.c (working copy) -@@ -280,7 +280,7 @@ - } - #endif +@@ -209,6 +209,7 @@ + static void *l4x_main_memory_start; + static void *l4x_isa_dma_memory_start; + unsigned long l4x_vmalloc_memory_start; ++unsigned long l4x_vmalloc_memory_size; + l4_kernel_info_t *l4lx_kinfo; + l4_cap_idx_t l4x_user_gate[NR_CPUS]; --#ifndef CONFIG_L4_SERIAL -+#if 0 //ndef CONFIG_L4_SERIAL - if (strstr(cmdline, "console=ttyLv")) { - LOG_printf("Console output set to ttyLvx but driver not compiled in.\n"); - enter_kdebug("L4 serial driver not enabled"); -@@ -381,6 +381,26 @@ +@@ -381,6 +382,28 @@ } @@ -520,6 +698,8 @@ Index: arch/l4/kernel/main.c +int l4x_nr_irqs(void) { return NR_IRQS; } +void l4x_migrate_lock(unsigned long *flags) { spin_lock_irqsave(&migrate_lock, *flags); } +void l4x_migrate_unlock(unsigned long flags) { spin_unlock_irqrestore(&migrate_lock, flags);} ++unsigned l4x_smp_processor_id() { return smp_processor_id(); } ++ + +unsigned l4x_target_cpu(const struct cpumask *dest) +{ @@ -535,7 +715,7 @@ Index: arch/l4/kernel/main.c unsigned long l4x_virt_to_phys(volatile void * address) { int i; -@@ -405,10 +425,10 @@ +@@ -405,10 +428,10 @@ /* Debugging check: don't miss a translation, can give nasty * DMA problems */ @@ -549,7 +729,7 @@ Index: arch/l4/kernel/main.c return __pa(address); } -@@ -439,7 +459,7 @@ +@@ -439,7 +462,7 @@ /* Debugging check: don't miss a translation, can give nasty * DMA problems */ @@ -558,7 +738,7 @@ Index: arch/l4/kernel/main.c __func__, address); l4x_virt_to_phys_show(); WARN_ON(1); -@@ -558,7 +578,7 @@ +@@ -558,7 +581,7 @@ r = l4re_ns_query_srv(entry->cap, n + 1, *cap); if (r) { @@ -567,7 +747,7 @@ Index: arch/l4/kernel/main.c name, l4sys_errtostr(r), r); L4XV_U(f); return -ENOENT; -@@ -742,6 +762,7 @@ +@@ -742,6 +765,7 @@ = sizeof(at_exit_functions) / sizeof(at_exit_functions[0]); static int __current_exititem; @@ -575,7 +755,7 @@ Index: arch/l4/kernel/main.c static struct cxa_atexit_item *__next_atexit(void) { if (__current_exititem >= at_exit_nr_of_functions) { -@@ -750,21 +771,10 @@ +@@ -750,21 +774,10 @@ } return &at_exit_functions[__current_exititem++]; } @@ -599,7 +779,7 @@ Index: arch/l4/kernel/main.c void __cxa_finalize(void *dso_handle) { const int verbose = 0; -@@ -819,10 +829,20 @@ +@@ -819,10 +832,20 @@ } static int l4x_forward_pf(l4_umword_t addr, l4_umword_t pc, int extra_write) { @@ -620,7 +800,7 @@ Index: arch/l4/kernel/main.c do { l4_msg_regs_t *mr = l4_utcb_mr_u(u); mr->mr[0] = addr | (extra_write ? 2 : 0); -@@ -844,6 +864,7 @@ +@@ -844,6 +867,7 @@ // unresolvable page fault, we're supposed to trigger an // exception return 0; @@ -628,16 +808,39 @@ Index: arch/l4/kernel/main.c return 1; } -@@ -1283,7 +1304,7 @@ +@@ -1283,15 +1307,17 @@ 0, "Main memory"); /* Reserve some part of the virtual address space for vmalloc */ - l4x_vmalloc_memory_start = (unsigned long)l4x_main_memory_start; +- if (l4re_rm_reserve_area(&l4x_vmalloc_memory_start, + l4x_vmalloc_memory_start = (unsigned long)l4x_main_memory_start + l4x_mainmem_size; - if (l4re_rm_reserve_area(&l4x_vmalloc_memory_start, #ifdef CONFIG_X86_32 - __VMALLOC_RESERVE, -@@ -1416,6 +1437,10 @@ +- __VMALLOC_RESERVE, ++ l4x_vmalloc_memory_size = __VMALLOC_RESERVE; + #elif defined(CONFIG_X86_64) +- VMALLOC_END - VMALLOC_START + 1, ++ l4x_vmalloc_memory_size = VMALLOC_END - VMALLOC_START + 1; + #else +- VMALLOC_SIZE << 20, ++ l4x_vmalloc_memory_size = VMALLOC_SIZE << 20; + #endif ++ ++ if (l4re_rm_reserve_area(&l4x_vmalloc_memory_start, ++ l4x_vmalloc_memory_size, + L4RE_RM_SEARCH_ADDR, PGDIR_SHIFT)) { + LOG_printf("%s: Error reserving vmalloc memory area!\n", __func__); + l4x_exit_l4linux(); +@@ -1305,7 +1331,7 @@ + + #ifdef ARCH_x86 + // fixmap area +- l4x_fixmap_space_start = (unsigned long)l4x_main_memory_start; ++ l4x_fixmap_space_start = (unsigned long)l4x_vmalloc_memory_start + l4x_vmalloc_memory_size; + if (l4re_rm_reserve_area(&l4x_fixmap_space_start, + __end_of_fixed_addresses * PAGE_SIZE, + L4RE_RM_SEARCH_ADDR, PAGE_SHIFT) < 0) { +@@ -1416,6 +1442,10 @@ static void l4x_create_ugate(l4_cap_idx_t forthread, unsigned cpu) { @@ -648,7 +851,7 @@ Index: arch/l4/kernel/main.c l4_msgtag_t r; l4x_user_gate[cpu] = l4x_cap_alloc_noctx(); -@@ -1436,6 +1461,7 @@ +@@ -1436,6 +1466,7 @@ l4_debugger_set_object_name(l4x_user_gate[cpu], n); #endif } @@ -656,7 +859,7 @@ Index: arch/l4/kernel/main.c } #ifdef CONFIG_HOTPLUG_CPU -@@ -1641,11 +1667,15 @@ +@@ -1641,11 +1672,15 @@ l4x_exit_l4linux(); } @@ -672,7 +875,7 @@ Index: arch/l4/kernel/main.c #ifdef CONFIG_L4_DEBUG_REGISTER_NAMES l4_debugger_set_object_name(c, s); -@@ -1906,8 +1936,12 @@ +@@ -1906,8 +1941,12 @@ static int l4x_cpu_virt_phys_map_init(const char *boot_command_line) { @@ -685,7 +888,7 @@ Index: arch/l4/kernel/main.c unsigned i; #ifdef CONFIG_SMP -@@ -1923,9 +1957,10 @@ +@@ -1923,9 +1962,10 @@ } } @@ -697,7 +900,7 @@ Index: arch/l4/kernel/main.c if ((p = strstr(boot_command_line, "l4x_cpus_map="))) { // l4x_cpus_map=0,1,2,3,4,... // the list specifies the physical CPU for each -@@ -1947,10 +1982,12 @@ +@@ -1947,10 +1987,12 @@ LOG_printf("ERROR: Error parsing l4x_cpus_map option\n"); return 1; } @@ -710,7 +913,7 @@ Index: arch/l4/kernel/main.c l4x_cpu_physmap[l4x_nr_cpus].phys_id = pcpu; for (i = 0; i < l4x_nr_cpus; ++i) overbooking |= -@@ -1974,12 +2011,16 @@ +@@ -1974,12 +2016,16 @@ l4x_nr_cpus = v; } @@ -727,7 +930,7 @@ Index: arch/l4/kernel/main.c if (l4_error(l4_scheduler_info(l4re_env()->scheduler, &max_cpus, &cs)) == L4_EOK) { -@@ -1989,6 +2030,8 @@ +@@ -1989,6 +2035,8 @@ l4x_cpu_physmap[0].phys_id = p; } #endif @@ -736,7 +939,7 @@ Index: arch/l4/kernel/main.c LOG_printf("CPU mapping (l:p)[%d]: ", l4x_nr_cpus); for (i = 0; i < l4x_nr_cpus; i++) -@@ -2034,6 +2077,7 @@ +@@ -2034,6 +2082,7 @@ printk("panic: going to sleep forever, bye\n"); L4XV_L(f); LOG_printf("panic: going to sleep forever, bye\n"); @@ -744,7 +947,7 @@ Index: arch/l4/kernel/main.c l4_sleep_forever(); return 0; } -@@ -2302,7 +2346,7 @@ +@@ -2302,7 +2351,7 @@ LOG_printf("Device scan done.\n"); } @@ -753,7 +956,7 @@ Index: arch/l4/kernel/main.c { l4lx_thread_t main_id; struct l4lx_thread_start_info_t si; -@@ -2414,10 +2458,13 @@ +@@ -2414,10 +2463,13 @@ l4x_start_thread_id = l4re_env()->main_thread; @@ -767,7 +970,7 @@ Index: arch/l4/kernel/main.c #ifndef CONFIG_L4_VCPU #ifdef CONFIG_L4_TAMED -@@ -3223,6 +3270,10 @@ +@@ -3223,6 +3275,10 @@ /* Not resolvable: Ooops */ LOG_printf("Non-resolvable page fault at %lx, ip %lx.\n", pfa, ip); // will trigger an oops in caller @@ -778,7 +981,7 @@ Index: arch/l4/kernel/main.c return 0; } -@@ -3419,7 +3470,9 @@ +@@ -3419,7 +3475,9 @@ void exit(int code) { __cxa_finalize(0); @@ -822,173 +1025,6 @@ Index: arch/l4/include/asm/l4lxapi/thread.h /** * \brief Create a thread. * \ingroup thread -Index: arch/l4/boot/Makefile -=================================================================== ---- arch/l4/boot/Makefile (revision 25) -+++ arch/l4/boot/Makefile (working copy) -@@ -10,7 +10,7 @@ - $(call if_changed,objcopy) - @echo ' Kernel: $@ is ready' - --lImage: $(obj)/Image vmlinuz$(VMLINUZ_SUFFIX) l4linux$(VMLINUZ_SUFFIX) -+lImage: $(obj)/Image - - vmlinuz$(VMLINUZ_SUFFIX): ldrImage FORCE - $(call if_changed,gzip) -@@ -21,8 +21,8 @@ - - objects-y := ldr.o res.o image.o - --include $(L4OBJ)/l4defs.mk.inc -- -+#include $(L4OBJ)/l4defs.mk.inc -+KBUILD_CFLAGS_i386 = -m32 - KBUILD_CFLAGS := $(filter-out -mregparm=3,$(KBUILD_CFLAGS)) \ - $(L4INC) -I$(L4OBJ)/include/uclibc \ - -Wall -fno-strict-aliasing -O2 -pipe \ -Index: arch/l4/lib/pte.c -=================================================================== ---- arch/l4/lib/pte.c (revision 25) -+++ arch/l4/lib/pte.c (working copy) -@@ -18,7 +18,10 @@ - #include - #include - #include -+#include - -+extern void l4lx_memory_map_physical_page(unsigned long address); -+ - static void l4x_flush_page(struct mm_struct *mm, - unsigned long address, - unsigned long vaddr, -@@ -77,7 +80,7 @@ - if (mm && !l4_is_invalid_cap(mm->context.task)) { - L4XV_V(f); - if (!mm->context.task) -- l4x_printf("%s: Ups, task == 0\n", __func__); -+ LOG_printf("%s: Ups, task == 0\n", __func__); - /* Direct flush in the child, use virtual address in the - * child address space */ - L4XV_L(f); -@@ -93,10 +96,11 @@ - tag = l4_task_unmap(L4RE_THIS_TASK_CAP, - l4_fpage(address & PAGE_MASK, size, flush_rights), - L4_FP_OTHER_SPACES); -+ l4lx_memory_map_physical_page(address); - L4XV_U(f); - } - if (l4_error(tag)) -- l4x_printf("l4_task_unmap error %ld\n", l4_error(tag)); -+ LOG_printf("l4_task_unmap error %ld\n", l4_error(tag)); - } - - #ifdef ARCH_arm -Index: arch/l4/Makefile -=================================================================== ---- arch/l4/Makefile (revision 25) -+++ arch/l4/Makefile (working copy) -@@ -163,6 +163,14 @@ - KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) - KBUILD_CFLAGS += $(call cc-option,-mno-avx,) - -+# -+# Prevent the gcc from linking Linux functions into compiler-generated -+# Genode stuff. -+# -+KBUILD_CFLAGS += -Dmemmove=lx_memmove -Dmemset=lx_memset -Dmemcpy=lx_memcpy -+KBUILD_CFLAGS += -Dstrlen=lx_strlen -Dabort=lx_abort -+ -+ - endif - - ifeq ($(BASEARCH),arm) -@@ -243,6 +251,8 @@ - - endif - -+# Genode compiler is build without Linux defines. -+KBUILD_CFLAGS +=-D__linux__ -Dlinux - - # ----------------------------------------------- - -@@ -265,14 +275,15 @@ - L4LX_E_L-$(CONFIG_L4_TCG_STPM) += stpm-client - L4LX_E_L-$(CONFIG_L4_FERRET) += ferret - --L4INC = -I$(L4OBJ)/include/$(L4_MK_ARCH)/$(L4_MK_API) \ -- -I$(L4OBJ)/include/$(L4_MK_ARCH) \ -- -I$(L4OBJ)/include/$(L4_MK_API) \ -- -I$(L4OBJ)/include -+#L4INC = -I$(L4OBJ)/include/$(L4_MK_ARCH)/$(L4_MK_API) \ -+# -I$(L4OBJ)/include/$(L4_MK_ARCH) \ -+# -I$(L4OBJ)/include/$(L4_MK_API) \ -+# -I$(L4OBJ)/include - - head-y := arch/l4/kernel/head.o - --libs-y += arch/l4/lib/arch-$(BASEARCH)/ \ -+libs-y += arch/l4/lib/arch-$(BASEARCH)/ -+#\ - arch/l4/l4lxlib/generic/ \ - arch/l4/l4lxlib/$(BASEENV)/ - -@@ -291,7 +302,7 @@ - - core-y += arch/l4/ - ---include $(L4OBJ)/l4defs.mk.inc -+#-include $(L4OBJ)/l4defs.mk.inc - - L4_REQUIRED_MODS := libc_be_minimal_log_io \ - libc_minimal libc_minimal_l4re \ -@@ -307,15 +318,17 @@ - $(error Aborting.) - endif - --libs-y += -Bstatic $(L4_LIBDIRS) -ll4sys -ll4sys-direct -lgcc-l4 -+libs-y += -Bstatic $(L4_LIBDIRS) -+#-ll4sys -ll4sys-direct -lgcc-l4 -+libs-y += $(GENODE_LIBS) - export L4INC L4_REQUIRED_MODS - --LDFLAGS_vmlinux = \ -- --defsym __L4_KIP_ADDR__=$(L4_BID_KIP_ADDR) \ -+LDFLAGS_vmlinux = -nostdlib -+# --defsym __L4_KIP_ADDR__=$(L4_BID_KIP_ADDR) \ - --defsym __l4sys_invoke_direct=$(L4_BID_KIP_ADDR)+$(L4_BID_KIP_OFFS_SYS_INVOKE) \ - --defsym __l4sys_debugger_direct=$(L4_BID_KIP_ADDR)+$(L4_BID_KIP_OFFS_SYS_DEBUGGER) - --KBUILD_CPPFLAGS += -Iarch/l4/include/asm/l4-arch \ -+KBUILD_CPPFLAGS += $(GENODE_INCLUDES) -Iarch/l4/include/asm/l4-arch \ - -Iarch/$(LINSRCARCH)/include/generated \ - $(if $(PLATFORMNAME),-I$(src)/arch/l4/include/asm/mach-$(LINSRCARCH)/$(PLATFORMNAME)) \ - $(if $(PLATFORMNAME),-I$(src)/arch/l4/include/asm/plat-$(LINSRCARCH)/$(PLATFORMNAME)) \ -@@ -337,6 +350,8 @@ - KBUILD_CPPFLAGS += -DTEXT_OFFSET=0x01000000 - endif - -+drivers-y += arch/l4/drivers/ -+ - all: lImage - - boot := arch/l4/boot -@@ -345,11 +360,11 @@ - $(Q)$(MAKE) $(build)=$(boot) $@ - - check_for_l4defs: -- $(Q)if [ ! -e $(L4OBJ)/l4defs.mk.inc ]; then \ -- echo "No $(L4OBJ)/l4defs.mk.inc available."; \ -- echo "Did you run 'make' in $(L4OBJ) to a successful end?"; \ -- exit 1; \ -- fi -+# $(Q)if [ ! -e $(L4OBJ)/l4defs.mk.inc ]; then \ -+# echo "No $(L4OBJ)/l4defs.mk.inc available."; \ -+# echo "Did you run 'make' in $(L4OBJ) to a successful end?"; \ -+# exit 1; \ -+# fi - - server: - $(Q)$(MAKE) $(build)=arch/l4/server Index: arch/x86/lib/memcpy_32.c =================================================================== --- arch/x86/lib/memcpy_32.c (revision 25) diff --git a/ports-foc/src/drivers/genode_serial.c b/ports-foc/src/drivers/genode_serial.c index 0adacd4f97..71ba57dd08 100644 --- a/ports-foc/src/drivers/genode_serial.c +++ b/ports-foc/src/drivers/genode_serial.c @@ -322,9 +322,13 @@ static int __init genode_serial_init(void) static void __exit genode_serial_exit(void) { unsigned i; + unsigned long flags; + for (i = 0; i < genode_reg.nr; i++) { uart_remove_one_port(&genode_reg, &genode_serial_port[i].port); + local_irq_save(flags); genode_terminal_stop(i); + local_irq_restore(flags); } if (genode_reg.nr) uart_unregister_driver(&genode_reg); diff --git a/ports-foc/src/lib/l4lx/genode_block.cc b/ports-foc/src/lib/l4lx/genode_block.cc index 2a9d9c65f4..2f5aba45bd 100644 --- a/ports-foc/src/lib/l4lx/genode_block.cc +++ b/ports-foc/src/lib/l4lx/genode_block.cc @@ -189,6 +189,8 @@ extern "C" { { using namespace Genode; + Linux::Irq_guard guard; + static unsigned count = 0; if (count == 0) { try { @@ -242,6 +244,8 @@ extern "C" { void genode_block_register_callback(FASTCALL void (*func)(void*, short, void*, unsigned long)) { + Linux::Irq_guard guard; + static Signal_thread thread(devices); if (!end_request) { end_request = func; @@ -258,6 +262,9 @@ extern "C" { PWRN("Invalid index!"); return; } + + Linux::Irq_guard guard; + *cnt = devices[idx]->block_count(); *sz = devices[idx]->block_size(); *queue_sz = devices[idx]->session()->tx()->bulk_buffer_size(); @@ -268,13 +275,13 @@ extern "C" { void* genode_block_request(unsigned idx, unsigned long sz, void *req, unsigned long *offset) { - Linux::Irq_guard guard; - if (idx >= genode_block_count()) { PWRN("Invalid index!"); return 0; } + Linux::Irq_guard guard; + try { Block::Connection *session = devices[idx]->session(); Block::Packet_descriptor p = session->tx()->alloc_packet(sz); @@ -290,12 +297,13 @@ extern "C" { void genode_block_submit(unsigned idx, unsigned long queue_offset, unsigned long size, unsigned long disc_offset, int write) { - Linux::Irq_guard guard; - if (idx >= genode_block_count()) { PWRN("Invalid index!"); return; } + + Linux::Irq_guard guard; + Genode::size_t sector = disc_offset / devices[idx]->block_size(); Genode::size_t sector_cnt = size / devices[idx]->block_size(); Block::Packet_descriptor p(Block::Packet_descriptor(queue_offset, size), @@ -313,6 +321,9 @@ extern "C" { return; } + unsigned long flags; + l4x_irq_save(&flags); + Block::Connection *session = devices[idx]->session(); void *req; while (session->tx()->ack_avail()) { @@ -320,9 +331,13 @@ extern "C" { void *addr = session->tx()->packet_content(packet); bool write = packet.operation() == Block::Packet_descriptor::WRITE; devices[idx]->cache()->remove(session->tx()->packet_content(packet), &req); - if (req && end_request) + if (req && end_request) { + l4x_irq_restore(flags); end_request(req, write, addr, packet.size()); + l4x_irq_save(&flags); + } session->tx()->release_packet(packet); } + l4x_irq_restore(flags); } } // extern "C" diff --git a/ports-foc/src/lib/l4lx/genode_framebuffer.cc b/ports-foc/src/lib/l4lx/genode_framebuffer.cc index f12c3d6a28..c6ac6d1a05 100644 --- a/ports-foc/src/lib/l4lx/genode_framebuffer.cc +++ b/ports-foc/src/lib/l4lx/genode_framebuffer.cc @@ -41,6 +41,8 @@ extern "C" { int genode_screen_count() { + Linux::Irq_guard guard; + return framebuffer() ? 1 : 0; } diff --git a/ports-foc/src/lib/l4lx/genode_input.cc b/ports-foc/src/lib/l4lx/genode_input.cc index 2f71860357..870a8d07b8 100644 --- a/ports-foc/src/lib/l4lx/genode_input.cc +++ b/ports-foc/src/lib/l4lx/genode_input.cc @@ -141,18 +141,18 @@ extern "C" { if (!genode_input_event) return; - if ( mouse && keyboard && input()) { - int num = 0; - { - Linux::Irq_guard guard; + unsigned long flags; + l4x_irq_save(&flags); - num = input()->flush(); - } + if ( mouse && keyboard && input()) { + int num = input()->flush(); + l4x_irq_restore(flags); for (int i = 0; i < num; i++) { Input::Event ev = buffer()[i]; handle_event(mouse, keyboard, &ev); } - } + } else + l4x_irq_restore(flags); } } //extern "C" diff --git a/ports-foc/src/lib/l4lx/include/linux.h b/ports-foc/src/lib/l4lx/include/linux.h index 9fe7f09ec8..cb69a0b677 100644 --- a/ports-foc/src/lib/l4lx/include/linux.h +++ b/ports-foc/src/lib/l4lx/include/linux.h @@ -15,8 +15,10 @@ #define _L4LX__LINUX_H_ #include +#include #include +#include #ifdef __cplusplus extern "C" { @@ -29,6 +31,7 @@ FASTCALL void l4x_migrate_unlock(unsigned long flags); FASTCALL unsigned long l4x_hz(); FASTCALL int l4x_nr_irqs(void); +FASTCALL unsigned l4x_smp_processor_id(); FASTCALL unsigned l4x_cpu_physmap_get_id(unsigned); FASTCALL unsigned l4x_target_cpu(const struct cpumask*); FASTCALL void l4x_cpumask_copy(struct irq_data*, const struct cpumask*); @@ -53,11 +56,23 @@ namespace Linux { private: unsigned long _flags; + bool _vcpu; public: - Irq_guard() : _flags(0) { l4x_irq_save(&_flags); } - ~Irq_guard() { l4x_irq_restore(_flags); } + Irq_guard() + : _flags(0), + _vcpu(dynamic_cast(Genode::Thread_base::myself())) + { + if (_vcpu) + l4x_irq_save(&_flags); + } + + ~Irq_guard() + { + if (_vcpu) + l4x_irq_restore(_flags); + } }; } #endif /* _L4LX__LINUX_H_ */ diff --git a/ports-foc/src/lib/l4lx/l4_log.cc b/ports-foc/src/lib/l4lx/l4_log.cc index a02e2f4d65..db7a940972 100644 --- a/ports-foc/src/lib/l4lx/l4_log.cc +++ b/ports-foc/src/lib/l4lx/l4_log.cc @@ -14,6 +14,8 @@ /* Genode includes */ #include +#include + namespace Fiasco { #include #include @@ -25,6 +27,8 @@ extern "C" { void LOG_printf(const char *format, ...) { + Linux::Irq_guard guard; + va_list list; va_start(list, format); Genode::vprintf(format, list); @@ -33,6 +37,8 @@ extern "C" { void LOG_vprintf(const char *format, va_list list) { + Linux::Irq_guard guard; + Genode::vprintf(format, list); } diff --git a/ports-foc/src/lib/l4lx/l4lx_irq.cc b/ports-foc/src/lib/l4lx/l4lx_irq.cc index 835bf05b6a..b32e12ce56 100644 --- a/ports-foc/src/lib/l4lx/l4lx_irq.cc +++ b/ports-foc/src/lib/l4lx/l4lx_irq.cc @@ -65,6 +65,7 @@ unsigned int l4lx_irq_dev_startup(struct irq_data *data) /* First test whether a capability has been registered with * this IRQ number */ p->irq_cap = l4x_have_irqcap(irq); + p->cpu = l4x_smp_processor_id(); if (l4_is_invalid_cap(p->irq_cap)) { PERR("Invalid irq cap!"); return 0; @@ -166,23 +167,18 @@ int l4lx_irq_dev_set_affinity(struct irq_data *data, unsigned long flags = 0; l4x_migrate_lock(&flags); - { - Linux::Irq_guard guard; - if (l4_error(l4_irq_detach(p->irq_cap))) - PWRN("%02d: Unable to detach from IRQ\n", data->irq); - } + if (l4_error(l4_irq_detach(p->irq_cap))) + PWRN("%02d: Unable to detach from IRQ\n", data->irq); l4x_cpumask_copy(data, dest); p->cpu = target_cpu; + PDBG("switched irq %d to cpu %d", data->irq, target_cpu); - { - Linux::Irq_guard guard; - l4_msgtag_t ret = l4_irq_attach(p->irq_cap, data->irq << 2, - l4x_cpu_thread_get_cap(p->cpu)); - if (l4_error(ret)) - PWRN("Attach to irq %lx failed with error %ld!", p->irq_cap, l4_error(ret)); - } + l4_msgtag_t ret = l4_irq_attach(p->irq_cap, data->irq << 2, + l4x_cpu_thread_get_cap(p->cpu)); + if (l4_error(ret)) + PWRN("Attach to irq %lx failed with error %ld!", p->irq_cap, l4_error(ret)); if (p->enabled) l4_irq_unmask(p->irq_cap); diff --git a/ports-foc/src/lib/l4lx/l4lx_task.cc b/ports-foc/src/lib/l4lx/l4lx_task.cc index 07cd48ccbd..4df2dfb53f 100644 --- a/ports-foc/src/lib/l4lx/l4lx_task.cc +++ b/ports-foc/src/lib/l4lx/l4lx_task.cc @@ -65,6 +65,8 @@ l4_cap_idx_t l4lx_task_number_allocate(void) */ int l4lx_task_number_free(l4_cap_idx_t task) { + Linux::Irq_guard guard; + Genode::Cap_index* idx = Genode::cap_idx_alloc()->kcap_to_idx(task); Genode::cap_idx_alloc()->free(idx, 1); return 0; @@ -85,6 +87,8 @@ int l4lx_task_number_free(l4_cap_idx_t task) int l4lx_task_get_new_task(l4_cap_idx_t parent_id, l4_cap_idx_t *id) { + Linux::Irq_guard guard; + *id = Genode::cap_idx_alloc()->alloc_range(1)->kcap(); return 0; } diff --git a/ports-foc/src/lib/l4lx/l4lx_thread.cc b/ports-foc/src/lib/l4lx/l4lx_thread.cc index bc0a625cd7..7e3ef8c4d9 100644 --- a/ports-foc/src/lib/l4lx/l4lx_thread.cc +++ b/ports-foc/src/lib/l4lx/l4lx_thread.cc @@ -19,6 +19,10 @@ #include #include +namespace Fiasco { +#include +} + using namespace Fiasco; enum { @@ -86,7 +90,9 @@ extern "C" { void l4lx_thread_name_set(l4_cap_idx_t thread, const char *name) { - PWRN("%s: Not implemented yet!", __func__); + Linux::Irq_guard guard; + + Fiasco::l4_debugger_set_object_name(thread, name); } @@ -94,6 +100,8 @@ void l4lx_thread_init(void) { } void l4lx_thread_alloc_irq(l4_cap_idx_t c) { + Linux::Irq_guard guard; + Genode::Native_capability cap = L4lx::vcpu_connection()->alloc_irq(); l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, l4_obj_fpage(cap.dst(), 0, L4_FPAGE_RWX), c | L4_ITEM_MAP); @@ -110,6 +118,8 @@ l4lx_thread_t l4lx_thread_create(L4_CV void (*thread_func)(void *data), { using namespace L4lx; + Linux::Irq_guard guard; + if (DEBUG) PDBG("func=%p cpu=%x stack=%p data=%p data_size=%x prio=%d name=%s", thread_func, cpu_nr, stack_pointer, stack_data, @@ -146,6 +156,8 @@ l4lx_thread_t l4lx_thread_create(L4_CV void (*thread_func)(void *data), int l4lx_thread_start(struct l4lx_thread_start_info_t *startinfo) { + Linux::Irq_guard guard; + if (DEBUG) PDBG("ip=%lx sp=%lx", startinfo->ip, startinfo->sp); L4lx::Vcpu *vc = (L4lx::Vcpu*) startinfo->l4cap; @@ -156,6 +168,8 @@ int l4lx_thread_start(struct l4lx_thread_start_info_t *startinfo) void l4lx_thread_pager_change(l4_cap_idx_t thread, l4_cap_idx_t pager) { + Linux::Irq_guard guard; + if (DEBUG) PDBG("Change pager of %lx to %lx", thread, pager); @@ -169,18 +183,24 @@ void l4lx_thread_pager_change(l4_cap_idx_t thread, l4_cap_idx_t pager) void l4lx_thread_set_kernel_pager(l4_cap_idx_t thread) { + Linux::Irq_guard guard; + PWRN("%s: Not implemented yet!", __func__); } void l4lx_thread_shutdown(l4lx_thread_t u, void *v) { + Linux::Irq_guard guard; + PWRN("%s: Not implemented yet!", __func__); } int l4lx_thread_equal(l4_cap_idx_t t1, l4_cap_idx_t t2) { + Linux::Irq_guard guard; + PWRN("%s: Not implemented yet!", __func__); return 0; }