commit c291a380d610060240c76fc3cadfce6450abfdc8 Author: Wolfgang Mauerer Date: Fri Dec 11 10:59:00 2009 +0100 Add support for sharing kernel/userland data between Xenomai and Linux A new structure (struct xnshared) is introduced. It allows us to share generic data between user and kernel of Linux and Xenomai; a bitmap of feature flags located at the beginning of the structure identifies which data are shared. The structure is allocated in the global semaphore heap, and xnsysinfo.xnshared_offset identifies the offset of the structure within the heap. Currently, no shared features are yet supported - the patch only introduces the necessary ABI changes. When the need arises to share data between said entities, the structure must be accordingly extended, and a new feature bit must be added to the flags. Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h index 483b99f..8f1ddc6 100644 --- a/include/asm-generic/syscall.h +++ b/include/asm-generic/syscall.h @@ -53,6 +53,7 @@ typedef struct xnsysinfo { unsigned long long cpufreq; /* CPU frequency */ unsigned long tickval; /* Tick duration (ns) */ + unsigned long xnvdso_off; /* Offset of xnvdso in the sem heap */ } xnsysinfo_t; #define SIGSHADOW SIGWINCH diff --git a/include/nucleus/xnvdso.h b/include/nucleus/xnvdso.h new file mode 100644 index 0000000..cc2ec20 --- /dev/null +++ b/include/nucleus/xnvdso.h @@ -0,0 +1,36 @@ +#ifndef XNVDSO_H +#define XNVDSO_H + +/* + * Data shared between Xenomai kernel/userland and the Linux kernel/userland + * on the global semaphore heap. The features element indicates which data are + * shared. Notice that struct xnvdso may only grow, but never shrink. + */ +struct xnvdso { + unsigned long long features; + + /* Embed domain specific structures that describe the + * shared data here */ +}; + +/* + * For each shared feature, add a flag below. For now, the set is still + * empty. + */ +/* +#define XNVDSO_FEAT_A 0x0000000000000001 +#define XNVDSO_FEAT_B 0x0000000000000002 +#define XNVDSO_FEAT_C 0x0000000000000004 +#define XNVDSO_FEATURES (XNVDSO_FEAT_A | XNVDSO_FEAT_B | XVDSO_FEAT_C) +*/ + +#define XNVDSO_FEATURES 0x0000000000000000 + +extern struct xnvdso *xnvdso; + +static inline int xnvdso_test_feature(unsigned long long feature) +{ + return testbits(xnvdso->features, feature); +} + +#endif diff --git a/ksrc/nucleus/module.c b/ksrc/nucleus/module.c index 5404182..40ee9a6 100644 --- a/ksrc/nucleus/module.c +++ b/ksrc/nucleus/module.c @@ -34,6 +34,7 @@ #include #endif /* CONFIG_XENO_OPT_PIPE */ #include +#include #include MODULE_DESCRIPTION("Xenomai nucleus"); @@ -51,6 +52,9 @@ u_long xnmod_sysheap_size; int xeno_nucleus_status = -EINVAL; +struct xnvdso *xnvdso; +EXPORT_SYMBOL_GPL(xnvdso); + struct xnsys_ppd __xnsys_global_ppd; EXPORT_SYMBOL_GPL(__xnsys_global_ppd); @@ -82,6 +86,21 @@ void xnmod_alloc_glinks(xnqueue_t *freehq) } EXPORT_SYMBOL_GPL(xnmod_alloc_glinks); +/* + * We re-use the global semaphore heap to provide a multi-purpose shared + * memory area between Xenomai and Linux - for both kernel and userland + */ +void __init xnheap_init_shared(void) +{ + xnvdso = (struct xnvdso *)xnheap_alloc(&__xnsys_global_ppd.sem_heap, + sizeof(*xnvdso)); + + if (!xnvdso) + xnpod_fatal("Xenomai: cannot allocate memory for xnvdso!\n"); + + xnvdso->features = XNVDSO_FEATURES; +} + int __init __xeno_sys_init(void) { int ret; @@ -106,6 +125,8 @@ int __init __xeno_sys_init(void) goto cleanup_arch; xnheap_set_label(&__xnsys_global_ppd.sem_heap, "global sem heap"); + + xnheap_init_shared(); #endif #ifdef __KERNEL__ diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c index 0c94a60..d8bced3 100644 --- a/ksrc/nucleus/shadow.c +++ b/ksrc/nucleus/shadow.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -1746,6 +1747,9 @@ static int xnshadow_sys_info(struct pt_regs *regs) info.cpufreq = xnarch_get_cpu_freq(); + info.xnvdso_off = + xnheap_mapped_offset(&xnsys_ppd_get(1)->sem_heap, xnvdso); + return __xn_safe_copy_to_user((void __user *)infarg, &info, sizeof(info)); }