Kernel updates since December 2009

This commit is contained in:
Bahadir Balban
2010-03-25 01:12:40 +02:00
parent 16818191b3
commit 74b5963fcb
487 changed files with 22477 additions and 3857 deletions

View File

@@ -18,6 +18,7 @@ from config.lib import *
config = configuration_retrieve()
arch = config.arch
gcc_arch_flag = config.gcc_arch_flag
LIBL4_RELDIR = 'conts/libl4'
KERNEL_INCLUDE = join(PROJROOT, 'include')
@@ -48,25 +49,27 @@ LIBPOSIX_INCLUDE_SERVER = join(LIBPOSIX_DIR, 'include')
LIBPOSIX_INCLUDE_USERSPACE = join(LIBPOSIX_DIR, 'include/posix')
LIBPOSIX_LIBPATH = join(BUILDDIR, LIBPOSIX_RELDIR)
env = Environment(CC = config.user_toolchain + 'gcc',
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', \
'-std=gnu99', '-Wall', '-Werror'],
LINKFLAGS = ['-nostdlib'],
ASFLAGS = ['-D__ASSEMBLY__'],
PROGSUFFIX = '.elf',
ENV = {'PATH' : os.environ['PATH']},
LIBS = ['gcc', 'libl4', 'c-userspace','libdev-userspace', \
'libmm', 'libmc', 'libmalloc', 'gcc'],
CPPPATH = ['include', LIBDEV_INCLUDE, LIBC_INCLUDE, KERNEL_INCLUDE,
LIBL4_INCLUDE, LIBMEM_INCLUDE],
LIBPATH = [LIBDEV_LIBPATH, LIBC_LIBPATH, LIBL4_LIBPATH,
LIBMEM_LIBPATH, LIBPOSIX_LIBPATH],
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
env = Environment(CC = config.toolchain + 'gcc',
AR = config.toolchain + 'ar',
RANLIB = config.toolchain + 'ranlib',
CCFLAGS = ['-g','-nostdinc', '-nostdlib', '-ffreestanding',
'-march=' + gcc_arch_flag, '-std=gnu99', '-Wall', '-Werror'],
LINKFLAGS = ['-nostdlib'],
ASFLAGS = ['-D__ASSEMBLY__'],
PROGSUFFIX = '.elf',
ENV = {'PATH' : os.environ['PATH']},
LIBS = ['libl4', 'libdev-userspace', 'gcc', 'c-userspace', \
'gcc', 'libmm', 'libmc', 'libmalloc'],
CPPPATH = ['include', LIBDEV_INCLUDE, LIBC_INCLUDE, KERNEL_INCLUDE,
LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBPOSIX_INCLUDE_USERSPACE],
LIBPATH = [LIBDEV_LIBPATH, LIBC_LIBPATH, LIBL4_LIBPATH,
LIBMEM_LIBPATH, LIBPOSIX_LIBPATH],
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
contid = ARGUMENTS.get('cont', '0')
libposix_env = env.Clone()
libposix_env.Replace(CPPPATH = [LIBPOSIX_INCLUDE_USERSPACE, 'include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE])
libposix_env.Replace(CPPPATH = [LIBPOSIX_INCLUDE_USERSPACE, 'include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBC_INCLUDE])
libposix = SConscript('libposix/SConscript', \
exports = { 'config' : config, 'env' : libposix_env, 'contid' : contid}, duplicate = 0, \
variant_dir = join(BUILDDIR, 'conts' + '/posix' + '/libposix'))
@@ -83,7 +86,7 @@ rootfs = SConscript('rootfs/SConscript', \
# No libposix reference because it conflicts with the compiler C library + the cluncky libc we have.
test0_env = env.Clone()
test0_env.Replace(CPPPATH = ['include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE])
test0_env.Replace(CPPPATH = ['include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBC_INCLUDE, LIBPOSIX_INCLUDE_USERSPACE])
test0 = SConscript('test0/SConscript', \
exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid, 'previmage' : rootfs }, duplicate = 0, \
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/test0'))

View File

@@ -97,8 +97,8 @@ def relocate_bootdesc(target, source, env):
images = source[1:]
mm0 = images[0]
start, end = image_lma_start_end(mm0.path)
print config.user_toolchain + "objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path
os.system(config.user_toolchain + "objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path)
print config.toolchain + "objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path
os.system(config.toolchain + "objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path)
shutil.copyfile(bootdesc_raw.path, target[0].path)
bootdesc_c = e.Command('bootdesc.c', images, generate_bootdesc)

View File

@@ -12,7 +12,7 @@ from configure import *
config = configuration_retrieve()
builddir = ARGUMENTS.get('builddir', 'build/conts/posix')
env = Environment(CC = config.user_toolchain + 'gcc',
env = Environment(CC = config.toolchain + 'gcc',
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
LINKFLAGS = ['-nostdlib','-Tlinker.lds'],
ASFLAGS = ['-D__ASSEMBLY__'],

View File

@@ -8,7 +8,8 @@ Import('env')
e = env.Clone()
e.Append(CPPPATH = ['include', 'include/posix'])
e.Replace(CCFLAGS = ['-g', '-nostdlib', '-Wall', '-Werror', '-ffreestanding', '-std=gnu99'])
e.Replace(CCFLAGS = ['-g','-nostdinc', '-nostdlib', '-Wall', '-Werror', '-ffreestanding', '-std=gnu99'],
CPPFLAGS = ' -include l4lib/macros.h ')
objects = e.StaticObject(Glob('*.c'))
libposix = e.StaticLibrary('posix', objects)

View File

@@ -16,7 +16,7 @@ kernel_headers = join(project_root, "include")
l4lib_headers = join(project_root, "tasks/libl4/include")
config_h = join(project_root, "include/l4/config.h")
env = Environment(CC = config.user_toolchain + 'gcc',
env = Environment(CC = config.toolchain + 'gcc',
CCFLAGS = ['-g', '-std=gnu99', '-nostdlib', '-ffreestanding'],
LINKFLAGS = ['-nostdlib'],
CPPPATH = ['#include'],

View File

@@ -11,8 +11,7 @@
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <libposix.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/utcb.h>
#include <l4/macros.h>

View File

@@ -6,8 +6,6 @@
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/utcb.h>
#include <l4/macros.h>

View File

@@ -10,8 +10,6 @@
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/utcb.h>
#include <fcntl.h>

View File

@@ -1,6 +1,6 @@
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
#include L4LIB_INC_ARCH(syscalls.h)
#include <l4lib/ipcdefs.h>
#include <unistd.h>
#include <l4/macros.h>

View File

@@ -6,8 +6,6 @@
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/utcb.h>
#include <l4/macros.h>

View File

@@ -1,6 +1,4 @@
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <sys/types.h>
#include <unistd.h>
#include <libposix.h>

View File

@@ -1,6 +1,12 @@
#ifndef __LIBPOSIX_H__
#define __LIBPOSIX_H__
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include <l4lib/types.h>
#include <l4lib/ipcdefs.h>
/* Abort debugging conditions */
// #define LIBPOSIX_ERROR_MESSAGES
#if defined (LIBPOSIX_ERROR_MESSAGES)

View File

@@ -33,7 +33,7 @@
#endif
/* The kernel sources contain a file with all the needed information. */
#include <linux/limits.h>
//#include <linux/limits.h>
/* Have to remove NR_OPEN? */
#ifdef __undef_NR_OPEN

View File

@@ -23,9 +23,9 @@
#ifndef _UCLIBC_PTHREAD_H
#define _UCLIBC_PTHREAD_H
#ifndef _PTHREAD_H
# error "Always include <pthread.h> rather than <bits/uClibc_pthread.h>"
#endif
//#ifndef _PTHREAD_H
//# error "Always include <pthread.h> rather than <bits/uClibc_pthread.h>"
//#endif
#if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc)
/* Threading functions internal to uClibc. Make these thread functions

View File

@@ -8,11 +8,11 @@
#define __LIBPOSIX_SHPAGE_H__
#include <l4/macros.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/utcb.h>
#include INC_GLUE(memory.h)
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
extern void *shared_page;

View File

@@ -328,16 +328,16 @@ extern int sprintf (char *__restrict __s,
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern int vfprintf (FILE *__restrict __s, __const char *__restrict __format,
__gnuc_va_list __arg);
//extern int vfprintf (FILE *__restrict __s, __const char *__restrict __format,
// __gnuc_va_list __arg);
/* Write formatted output to stdout from argument list ARG.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern int vprintf (__const char *__restrict __format, __gnuc_va_list __arg);
//extern int vprintf (__const char *__restrict __format, __gnuc_va_list __arg);
/* Write formatted output to S from argument list ARG. */
extern int vsprintf (char *__restrict __s, __const char *__restrict __format,
__gnuc_va_list __arg) __THROW;
//extern int vsprintf (char *__restrict __s, __const char *__restrict __format,
// __gnuc_va_list __arg) __THROW;
__END_NAMESPACE_STD
#if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
@@ -347,18 +347,18 @@ extern int snprintf (char *__restrict __s, size_t __maxlen,
__const char *__restrict __format, ...)
__THROW __attribute__ ((__format__ (__printf__, 3, 4)));
extern int vsnprintf (char *__restrict __s, size_t __maxlen,
__const char *__restrict __format, __gnuc_va_list __arg)
__THROW __attribute__ ((__format__ (__printf__, 3, 0)));
//extern int vsnprintf (char *__restrict __s, size_t __maxlen,
// __const char *__restrict __format, __gnuc_va_list __arg)
// __THROW __attribute__ ((__format__ (__printf__, 3, 0)));
__END_NAMESPACE_C99
#endif
#ifdef __USE_GNU
/* Write formatted output to a string dynamically allocated with `malloc'.
Store the address of the string in *PTR. */
extern int vasprintf (char **__restrict __ptr, __const char *__restrict __f,
__gnuc_va_list __arg)
__THROW __attribute__ ((__format__ (__printf__, 2, 0)));
//extern int vasprintf (char **__restrict __ptr, __const char *__restrict __f,
// __gnuc_va_list __arg)
// __THROW __attribute__ ((__format__ (__printf__, 2, 0)));
#if 0 /* uClibc: disabled */
extern int __asprintf (char **__restrict __ptr,
__const char *__restrict __fmt, ...)
@@ -374,8 +374,8 @@ extern int asprintf (char **__restrict __ptr,
cancellation point. But due to similarity with an POSIX interface
or due to the implementation they are cancellation points and
therefore not marked with __THROW. */
extern int vdprintf (int __fd, __const char *__restrict __fmt,
__gnuc_va_list __arg)
//extern int vdprintf (int __fd, __const char *__restrict __fmt,
// __gnuc_va_list __arg)
__attribute__ ((__format__ (__printf__, 2, 0)));
extern int dprintf (int __fd, __const char *__restrict __fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
@@ -405,21 +405,21 @@ __BEGIN_NAMESPACE_C99
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format,
__gnuc_va_list __arg)
__attribute__ ((__format__ (__scanf__, 2, 0)));
//extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format,
// __gnuc_va_list __arg)
// __attribute__ ((__format__ (__scanf__, 2, 0)));
/* Read formatted input from stdin into argument list ARG.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern int vscanf (__const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__format__ (__scanf__, 1, 0)));
//extern int vscanf (__const char *__restrict __format, __gnuc_va_list __arg)
// __attribute__ ((__format__ (__scanf__, 1, 0)));
/* Read formatted input from S into argument list ARG. */
extern int vsscanf (__const char *__restrict __s,
__const char *__restrict __format, __gnuc_va_list __arg)
__THROW __attribute__ ((__format__ (__scanf__, 2, 0)));
//extern int vsscanf (__const char *__restrict __s,
// __const char *__restrict __format, __gnuc_va_list __arg)
// __THROW __attribute__ ((__format__ (__scanf__, 2, 0)));
__END_NAMESPACE_C99
#endif /* Use ISO C9x. */

View File

@@ -7,8 +7,6 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <libposix.h>

View File

@@ -11,8 +11,6 @@
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/utcb.h>
#include <fcntl.h>

View File

@@ -8,8 +8,6 @@
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <libposix.h>

View File

@@ -11,8 +11,6 @@
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/utcb.h>
#include <fcntl.h>

View File

@@ -9,8 +9,6 @@
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/os/posix/readdir.h>
#include <l4/macros.h>

View File

@@ -8,8 +8,6 @@
#include <stdio.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4/macros.h>
#include <libposix.h>

View File

@@ -4,17 +4,15 @@
* Copyright (C) 2007-2009 Bahadir Balban
*/
#include <l4lib/kip.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/arch/utcb.h>
#include <l4lib/ipcdefs.h>
#include <l4/macros.h>
#include INC_GLUE(memlayout.h)
#include <stdio.h>
#include <shpage.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <shpage.h>
#include <libposix.h>
#include INC_GLUE(memlayout.h)
#if 0

View File

@@ -11,8 +11,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <l4lib/os/posix/kstat.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/utcb.h>
#include <fcntl.h>

View File

@@ -1,5 +1,4 @@
#include <l4lib/arch/syscalls.h>
#include <sys/time.h>
#include <errno.h>
#include <libposix.h>

View File

@@ -7,8 +7,6 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <libposix.h>

View File

@@ -4,22 +4,13 @@ Import('config', 'env', 'contid')
import os, sys
arch = config.arch
subarch = config.subarch
sys.path.append('../../../../')
from config.lib import *
container = next((c for c in config.containers if int(c.id) == int(contid)), None)
def create_symlinks(arch):
arch_path = "include/arch"
arch_path2 ="src/arch"
if os.path.exists(arch_path):
os.system("rm %s" % (arch_path))
os.system("ln -s %s %s" % ("arch-" + arch, arch_path))
if os.path.exists(arch_path2):
os.system("rm %s" % (arch_path2))
os.system("ln -s %s %s" % ("arch-" + arch, arch_path2))
def generate_container_h(target, source, env):
base_value_dict = {}
with open(source[0].path, 'r') as ch_in:
@@ -52,13 +43,15 @@ def generate_vma_lma_lds(target, source, env):
lma_lds = Command('include/linker.lds', 'include/linker.lds.in', generate_vma_lma_lds)
container_h = Command('include/container.h', 'include/container.h.in', generate_container_h)
src = [Glob('*.c') + Glob('mm/*.c') + Glob('lib/*.c') + Glob('fs/*.c') + Glob('fs/memfs/*.c') + Glob('lib/elf/*.c') + Glob('mm/arch/*.[Sc]')]
src = [Glob('*.c') + Glob('mm/*.c') + Glob('lib/*.c') + Glob('fs/*.c') + \
Glob('fs/memfs/*.c') + Glob('lib/elf/*.c') + Glob('mm/arch/' + arch + '/*.[Sc]') +
Glob('mm/arch/' + arch + '/' + subarch + '/*.[Sc]')]
e = env.Clone()
e.Append(LINKFLAGS = ['-T' + lma_lds[0].path, '-u_start'])
e.Append(LIBS = 'posix')
e.Append(CPPFLAGS = ' -include ' + container_h[0].path)
e.Append(CPPFLAGS = ' -include ' + container_h[0].path + ' -include macros.h -include l4lib/macros.h ')
objs = e.Object(src)
mm0 = e.Program('mm0.elf', objs)
Depends(objs, container_h)

View File

@@ -30,7 +30,7 @@ LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
join(LIBC_DIR, 'include/arch' + '/' + arch)]
env = Environment(CC = config.user_toolchain + 'gcc',
env = Environment(CC = config.toolchain + 'gcc',
# We don't use -nostdinc because sometimes we need standard headers,
# such as stdarg.h e.g. for variable args, as in printk().
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', \
@@ -41,7 +41,7 @@ env = Environment(CC = config.user_toolchain + 'gcc',
PROGSUFFIX = '.elf', # The suffix to use for final executable
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
LIBS = ['gcc', 'libl4', 'libc', 'libmm', 'libmc'],
CPPPATH = ["#include", LIBC_INCLUDE, KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE],
CPPPATH = ["#include", LIBC_INCLUDE, KERNEL_INCLUDE, LIBL4_INCLUDE],
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h -D__KERNEL__')

View File

@@ -5,7 +5,7 @@
#include <l4/macros.h>
#include <bootdesc.h>
#include <memfs/memfs.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
void *vfs_rootdev_open(void)
{

View File

@@ -1 +0,0 @@
arch-arm

View File

@@ -0,0 +1,44 @@
/*
* Debug/performance measurements for mm0
*
* Copyright (C) 2010 B Labs Ltd.
*/
#ifndef __ARCH_DEBUG_H__
#define __ARCH_DEBUG_H__
#if !defined(CONFIG_DEBUG_PERFMON_USER)
#include <l4lib/types.h>
/* Common empty definitions for all arches */
static inline u32 perfmon_read_cyccnt() { return 0; }
static inline void perfmon_reset_start_cyccnt() { }
static inline u32 perfmon_read_reset_start_cyccnt() { return 0; }
#define debug_record_cycles(str)
#else /* End of CONFIG_DEBUG_PERFMON_USER */
/* Architecture specific perfmon cycle counting */
#include L4LIB_INC_SUBARCH(perfmon.h)
extern u64 perfmon_total_cycles;
extern u64 current_cycles;
/*
* This is for Cortex-A9 running at 400Mhz. 25 / 100000 is
* a rewriting of 2.5 nanosec / 1,000,000
*/
#define debug_record_cycles(str) \
{ \
current_cycles = perfmon_read_cyccnt(); \
perfmon_total_cycles += current_cycles; \
printf("%s: took %llu milliseconds\n", str, \
current_cycles * 64 * 25 / 100000); \
perfmon_reset_start_cyccnt(); \
}
#endif /* End of !CONFIG_DEBUG_PERFMON_USER */
#endif /* __ARCH_DEBUG_H__ */

View File

@@ -0,0 +1,15 @@
#ifndef __INITTASK_ARCH_MM_H__
#define __INITTASK_ARCH_MM_H__
#include <l4/macros.h>
#include <l4/types.h>
#include INC_GLUE(memory.h)
#include INC_ARCH(exception.h)
#include <vm_area.h>
struct fault_data;
void set_generic_fault_params(struct fault_data *fault);
void arch_print_fault_params(struct fault_data *fault);
void fault_handle_error(struct fault_data *fault);
#endif /* __INITTASK_ARCH_MM_H__ */

View File

@@ -6,7 +6,7 @@
#ifndef __MM0_CAPABILITY_H__
#define __MM0_CAPABILITY_H__
#include <l4lib/capability.h>
#include <l4lib/lib/cap.h>
#include <task.h>
extern struct cap_list capability_list;

View File

@@ -0,0 +1,9 @@
#ifndef __MM0_MACROS_H__
#define __MM0_MACROS_H__
#define __INC_ARCH(x) <arch/__ARCH__/x>
#define __INC_SUBARCH(x) <arch/__ARCH__/__SUBARCH__/x>
#define __INC_PLAT(x) <platform/__PLATFORM__/x>
#define __INC_GLUE(x) <glue/__ARCH__/x>
#endif /* __MM0_MACROS_H__ */

View File

@@ -21,15 +21,11 @@ struct container_memory_regions {
};
extern struct container_memory_regions cont_mem_regions;
#define PAGER_MMAP_SEGMENT SZ_4MB
#define PAGER_MMAP_START (page_align_up(__stack))
#define PAGER_MMAP_END (PAGER_MMAP_START + PAGER_MMAP_SEGMENT)
void init_mm_descriptors(struct page_bitmap *page_map,
struct bootdesc *bootdesc, struct membank *membank);
void init_physmem(void);
int pager_address_pool_init(void);
int pager_address_pool_init();
void *pager_new_address(int npages);
int pager_delete_address(void *virt_addr, int npages);
void *pager_map_pages(struct vm_file *f, unsigned long page_offset, unsigned long npages);
@@ -38,6 +34,7 @@ void *pager_map_page(struct vm_file *f, unsigned long page_offset);
void pager_unmap_page(void *addr);
void *pager_map_file_range(struct vm_file *f, unsigned long byte_offset,
unsigned long size);
void *pager_validate_map_user_range2(struct tcb *user, void *userptr,
unsigned long size, unsigned int vm_flags);

View File

@@ -10,8 +10,8 @@
#include <l4/types.h>
#include INC_GLUE(memlayout.h)
#include <l4/lib/list.h>
#include <l4lib/arch/types.h>
#include <l4lib/arch/syscalls.h>
#include L4LIB_INC_ARCH(types.h)
#include L4LIB_INC_ARCH(syscalls.h)
#include <l4lib/utcb.h>
#include <lib/addr.h>
#include <l4/api/kip.h>

View File

@@ -5,10 +5,8 @@
int pager_validate_user_range(struct tcb *user, void *userptr, unsigned long size,
unsigned int vm_flags);
void *pager_validate_map_user_range(struct tcb *user, void *userptr,
unsigned long size, unsigned int vm_flags);
void pager_unmap_user_range(void *mapped_ptr, unsigned long size);
void *pager_get_user_page(struct tcb *user, void *userptr,
unsigned long size, unsigned int vm_flags);
int copy_user_args(struct tcb *task, struct args_struct *args,
void *argv_user, int args_max);
int copy_user_buf(struct tcb *task, void *buf, char *user, int maxlength,

View File

@@ -11,9 +11,10 @@
#include <l4/config.h>
#include <l4/types.h>
#include <task.h>
#include <arch/mm.h>
#include <lib/spinlock.h>
#include <physmem.h>
#include <linker.h>
#include __INC_ARCH(mm.h)
// #define DEBUG_FAULT_HANDLING
#ifdef DEBUG_FAULT_HANDLING
@@ -22,6 +23,14 @@
#define dprintf(...)
#endif
/* Some task segment marks for mm0 */
#define PAGER_MMAP_SEGMENT SZ_1MB
#define PAGER_MMAP_START (page_align_up(__stack))
#define PAGER_MMAP_END (PAGER_MMAP_START + PAGER_MMAP_SEGMENT)
#define PAGER_EXT_VIRTUAL_START PAGER_MMAP_END
#define PAGER_EXT_VIRTUAL_END (unsigned long)(PAGER_MMAP_END + SZ_2MB)
#define PAGER_VIRTUAL_START PAGER_EXT_VIRTUAL_END
/* Protection flags */
#define VM_NONE (1 << 0)
#define VM_READ (1 << 1)
@@ -75,6 +84,10 @@ extern struct page *page_array;
sizeof(struct page)) + \
membank[0].start)
/* Multiple conversions together */
#define virt_to_page(x) (phys_to_page(virt_to_phys(x)))
#define page_to_virt(x) (phys_to_virt((void *)page_to_phys(x)))
/* Fault data specific to this task + ptr to kernel's data */
struct fault_data {
fault_kdata_t *kdata; /* Generic data forged by the kernel */
@@ -226,9 +239,12 @@ void vm_object_print(struct vm_object *vmo);
void vm_print_objects(struct link *vmo_list);
void vm_print_files(struct link *file_list);
/* Used for pre-faulting a page from mm0 */
/* Buggy version. Used for pre-faulting a page from mm0 */
struct page *task_prefault_page(struct tcb *task, unsigned long address,
unsigned int vmflags);
/* New version */
struct page *task_prefault_smart(struct tcb *task, unsigned long address,
unsigned int vmflags);
struct page *page_init(struct page *page);
struct page *find_page(struct vm_object *vmo, unsigned long page_offset);
void *pager_map_page(struct vm_file *f, unsigned long page_offset);

View File

@@ -5,9 +5,9 @@
*/
#include <stdio.h>
#include <init.h>
#include <l4lib/arch/utcb.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(utcb.h)
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include <l4lib/kip.h>
#include <l4lib/utcb.h>
#include <l4lib/ipcdefs.h>

View File

@@ -1 +0,0 @@
arch-arm

View File

@@ -0,0 +1,94 @@
/*
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 2004 National ICT Australia
*
* All rights reserved.
*
* Developed by: Embedded, Real-time and Operating Systems Program (ERTOS)
* National ICT Australia
* http://www.ertos.nicta.com.au
*
* Permission is granted by National ICT Australia, free of charge, to
* any person obtaining a copy of this software and any associated
* documentation files (the "Software") to deal with the Software without
* restriction, including (without limitation) the rights to use, copy,
* modify, adapt, merge, publish, distribute, communicate to the public,
* sublicense, and/or sell, lend or rent out copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimers.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of National ICT Australia, nor the names of its
* contributors, may be used to endorse or promote products derived
* from this Software without specific prior written permission.
*
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
* ERRORS, WHETHER OR NOT DISCOVERABLE.
*
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
* DAMAGES OR OTHER LIABILITY.
*
* If applicable legislation implies representations, warranties, or
* conditions, or imposes obligations or liability on National ICT
* Australia or one of its contributors in respect of the Software that
* cannot be wholly or partly excluded, restricted or modified, the
* liability of National ICT Australia or the contributor is limited, to
* the full extent permitted by the applicable legislation, at its
* option, to:
* a. in the case of goods, any one or more of the following:
* i. the replacement of the goods or the supply of equivalent goods;
* ii. the repair of the goods;
* iii. the payment of the cost of replacing the goods or of acquiring
* equivalent goods;
* iv. the payment of the cost of having the goods repaired; or
* b. in the case of services:
* i. the supplying of the services again; or
* ii. the payment of the cost of having the services supplied again.
*
* The construction, validity and performance of this licence is governed
* by the laws in force in New South Wales, Australia.
*/
#ifdef __thumb__
#define bl blx
#endif
.section .text.head
.code 32
.global _start;
.align;
_start:
ldr sp, =__stack
bl platform_init
bl __container_init
1:
b 1b

View File

@@ -0,0 +1,11 @@
/*
* Perfmon globals
*/
#if defined(CONFIG_DEBUG_PERFMON_USER)
u64 perfmon_total_cycles;
u64 current_cycles;
#endif

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2007 Bahadir Balban
*/
#include <task.h>
#include <vm_area.h>
#include <l4lib/exregs.h>
#include __INC_ARCH(mm.h)
#if defined(DEBUG_FAULT_HANDLING)
void arch_print_fault_params(struct fault_data *fault)
{
printf("%s: Handling %s fault (%s abort) from %d. fault @ 0x%x, generic pte flags: 0x%x\n",
__TASKNAME__, (fault->reason & VM_READ) ? "read" :
(fault->reason & VM_WRITE) ? "write" : "exec",
is_prefetch_abort(fault->kdata->fsr) ? "prefetch" : "data",
fault->task->tid, fault->address, fault->pte_flags);
}
#else
void arch_print_fault_params(struct fault_data *fault) { }
#endif
void fault_handle_error(struct fault_data *fault)
{
struct task_ids ids;
/* Suspend the task */
ids.tid = fault->task->tid;
BUG_ON(l4_thread_control(THREAD_SUSPEND, &ids) < 0);
BUG();
}

View File

@@ -0,0 +1,65 @@
/*
* ARMv5 specific functions
*
* Copyright (C) 2008 - 2010 B Labs Ltd.
*/
#include <task.h>
#include <vm_area.h>
#include <l4lib/exregs.h>
#include __INC_ARCH(mm.h)
/* Extracts generic protection flags from architecture-specific pte */
unsigned int vm_prot_flags(pte_t pte)
{
unsigned int vm_prot_flags = 0;
unsigned int rw_flags = __MAP_USR_RW & PTE_PROT_MASK;
unsigned int ro_flags = __MAP_USR_RO & PTE_PROT_MASK;
/* Clear non-protection flags */
pte &= PTE_PROT_MASK;
if (pte == ro_flags)
vm_prot_flags = VM_READ | VM_EXEC;
else if (pte == rw_flags)
vm_prot_flags = VM_READ | VM_WRITE | VM_EXEC;
else
vm_prot_flags = VM_NONE;
return vm_prot_flags;
}
/*
* PTE STATES:
* PTE type field: 00 (Translation fault)
* PTE type field correct, AP bits: None (Read or Write access fault)
* PTE type field correct, AP bits: RO (Write access fault)
*/
/*
* Extracts arch-specific fault parameters
* and puts them into generic format
*/
void set_generic_fault_params(struct fault_data *fault)
{
unsigned int prot_flags = vm_prot_flags(fault->kdata->pte);
fault->reason = 0;
fault->pte_flags = prot_flags;
if (is_prefetch_abort(fault->kdata->fsr)) {
fault->reason |= VM_READ;
fault->address = fault->kdata->faulty_pc;
} else {
fault->address = fault->kdata->far;
/* Always assume read fault first */
if (prot_flags & VM_NONE)
fault->reason |= VM_READ;
else if (prot_flags & VM_READ)
fault->reason |= VM_WRITE;
else
BUG();
}
arch_print_fault_params(fault);
}

View File

@@ -0,0 +1,65 @@
/*
* ARMv5 specific functions
*
* Copyright (C) 2008 - 2010 B Labs Ltd.
*/
#include <task.h>
#include <vm_area.h>
#include <l4lib/exregs.h>
#include __INC_ARCH(mm.h)
/* Extracts generic protection flags from architecture-specific pte */
unsigned int vm_prot_flags(pte_t pte)
{
unsigned int vm_prot_flags = 0;
unsigned int rw_flags = __MAP_USR_RW & PTE_PROT_MASK;
unsigned int ro_flags = __MAP_USR_RO & PTE_PROT_MASK;
/* Clear non-protection flags */
pte &= PTE_PROT_MASK;
if (pte == ro_flags)
vm_prot_flags = VM_READ | VM_EXEC;
else if (pte == rw_flags)
vm_prot_flags = VM_READ | VM_WRITE | VM_EXEC;
else
vm_prot_flags = VM_NONE;
return vm_prot_flags;
}
/*
* PTE STATES:
* PTE type field: 00 (Translation fault)
* PTE type field correct, AP bits: None (Read or Write access fault)
* PTE type field correct, AP bits: RO (Write access fault)
*/
/*
* Extracts arch-specific fault parameters
* and puts them into generic format
*/
void set_generic_fault_params(struct fault_data *fault)
{
unsigned int prot_flags = vm_prot_flags(fault->kdata->pte);
fault->reason = 0;
fault->pte_flags = prot_flags;
if (is_prefetch_abort(fault->kdata->fsr)) {
fault->reason |= VM_READ;
fault->address = fault->kdata->faulty_pc;
} else {
fault->address = fault->kdata->far;
/* Always assume read fault first */
if (prot_flags & VM_NONE)
fault->reason |= VM_READ;
else if (prot_flags & VM_READ)
fault->reason |= VM_WRITE;
else
BUG();
}
arch_print_fault_params(fault);
}

View File

@@ -0,0 +1,77 @@
/*
* ARMv7 specific functions
*
* Copyright (C) 2008 - 2010 B Labs Ltd.
*/
#include <task.h>
#include <vm_area.h>
#include <l4lib/exregs.h>
#include __INC_ARCH(mm.h)
#include INC_SUBARCH(mm.h)
#include INC_SUBARCH(exception.h)
/* Get simplified access permissions */
int pte_get_access_simple(pte_t pte)
{
/* Place AP[2] and AP[1] in [1:0] positions and return */
return (((pte >> PTE_AP2_BIT) & 1) << 1)
| ((pte >> PTE_AP1_BIT) & 1);
}
int is_translation_fault(u32 fsr)
{
return (fsr & FSR_FS_MASK) == ABORT_TRANSLATION_PAGE;
}
unsigned int vm_prot_flags(pte_t pte, u32 fsr)
{
unsigned int pte_prot_flags = 0;
/* Translation fault means no permissions */
if (is_translation_fault(fsr))
return VM_NONE;
/* Check simplified permission bits */
switch (pte_get_access_simple(pte)) {
case AP_SIMPLE_USER_RW_KERN_RW:
pte_prot_flags |= VM_WRITE;
case AP_SIMPLE_USER_RO_KERN_RO:
pte_prot_flags |= VM_READ;
/* Also, check exec never bit */
if (!(pte & (1 << PTE_XN_BIT)))
pte_prot_flags |= VM_EXEC;
break;
case AP_SIMPLE_USER_NONE_KERN_RW:
case AP_SIMPLE_USER_NONE_KERN_RO:
default:
pte_prot_flags = VM_NONE;
break;
}
return pte_prot_flags;
}
void set_generic_fault_params(struct fault_data *fault)
{
fault->pte_flags = vm_prot_flags(fault->kdata->pte, fault->kdata->fsr);
fault->reason = 0;
/*
* Prefetch fault denotes exec fault.
*/
if (is_prefetch_abort(fault->kdata->fsr)) {
fault->reason |= VM_EXEC;
fault->address = fault->kdata->faulty_pc;
} else {
fault->address = fault->kdata->far;
/* Write-not-read bit determines fault */
if (fault->kdata->fsr & (1 << DFSR_WNR_BIT))
fault->reason |= VM_WRITE;
else
fault->reason |= VM_READ;
}
arch_print_fault_params(fault);
}

View File

@@ -8,8 +8,7 @@
#include <bootm.h>
#include <init.h>
#include <linker.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
extern unsigned long pager_offset;

View File

@@ -7,12 +7,11 @@
#include <init.h>
#include <memory.h>
#include <capability.h>
#include <l4lib/capability/cap_print.h>
#include <l4/api/errno.h>
#include <l4/lib/list.h>
#include <l4lib/arch/syscalls.h>
#include L4LIB_INC_ARCH(syscalls.h)
#include <l4/generic/cap-types.h> /* TODO: Move this to API */
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
#include <malloc/malloc.h>
#include <user.h>
@@ -504,15 +503,14 @@ int sys_request_cap(struct tcb *task, struct capability *__cap_userptr)
struct capability *cap;
int ret;
if (!(cap = pager_validate_map_user_range(task, __cap_userptr,
sizeof(*__cap_userptr),
VM_READ | VM_WRITE)))
if (!(cap = pager_get_user_page(task, __cap_userptr,
sizeof(*__cap_userptr),
VM_READ | VM_WRITE)))
return -EFAULT;
/* Only support IPC requests for now */
if (cap_type(cap) != CAP_TYPE_IPC) {
ret = -EPERM;
goto out;
}
/* Validate rest of the fields */
@@ -560,7 +558,6 @@ int sys_request_cap(struct tcb *task, struct capability *__cap_userptr)
}
out:
pager_unmap_user_range(cap, sizeof(*cap));
return ret;
}

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
#include <l4lib/ipcdefs.h>
#include <l4lib/exregs.h>
#include <l4/api/errno.h>
@@ -111,6 +111,7 @@ int sys_clone(struct tcb *parent,
if (!child_stack)
return -EINVAL;
BUG_ON((unsigned long)child_stack < 0x10000);
if (clone_flags & CLONE_VM) {
flags |= TCB_SHARED_VM;

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <l4lib/arch/syslib.h>
#include <l4lib/arch/syscalls.h>
#include L4LIB_INC_ARCH(syslib.h)
#include L4LIB_INC_ARCH(syscalls.h)
#include <l4lib/ipcdefs.h>
#include <l4lib/types.h>
#include <l4/macros.h>

View File

@@ -11,12 +11,12 @@
#include <utcb.h>
#include <vm_area.h>
#include <syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/exregs.h>
#include <l4lib/ipcdefs.h>
#include <malloc/malloc.h>
#include <l4/api/space.h>
#include L4LIB_INC_ARCH(syslib.h)
#include L4LIB_INC_ARCH(syscalls.h)
/* Closes all file descriptors of a task */

View File

@@ -1,17 +1,12 @@
/*
* Page fault handling.
*
* Copyright (C) 2007, 2008 Bahadir Balban
* Copyright (C) 2007, 2008-2010 Bahadir Bilgehan Balban
*/
#include <vm_area.h>
#include <task.h>
#include <mm/alloc_page.h>
#include <malloc/malloc.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include INC_GLUE(memory.h)
#include INC_SUBARCH(mm.h)
#include <arch/mm.h>
#include <l4/generic/space.h>
#include <l4/api/errno.h>
#include <string.h>
@@ -20,6 +15,12 @@
#include <file.h>
#include <test.h>
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include INC_GLUE(memory.h)
#include INC_SUBARCH(mm.h)
#include __INC_ARCH(mm.h)
#include __INC_ARCH(debug.h)
/* Given a page and the vma it is in, returns that page's virtual address */
unsigned long vma_page_to_virtual(struct vm_area *vma, struct page *page)
@@ -245,28 +246,16 @@ struct vm_obj_link *vma_create_shadow(void)
/* Allocates a new page, copies the original onto it and returns. */
struct page *copy_to_new_page(struct page *orig)
{
void *new_vaddr, *vaddr, *paddr;
struct page *new;
void *paddr = alloc_page(1);
BUG_ON(!(paddr = alloc_page(1)));
new = phys_to_page(paddr);
/* Map the new and orig page to self */
new_vaddr = l4_map_helper(paddr, 1);
vaddr = l4_map_helper((void *)page_to_phys(orig), 1);
BUG_ON(!paddr);
/* Copy the page into new page */
memcpy(new_vaddr, vaddr, PAGE_SIZE);
memcpy(phys_to_virt(paddr), page_to_virt(orig), PAGE_SIZE);
/* Unmap both pages from current task. */
l4_unmap_helper(vaddr, 1);
l4_unmap_helper(new_vaddr, 1);
return new;
return phys_to_page(paddr);
}
/* Copy all mapped object link stack from vma to new vma */
int vma_copy_links(struct vm_area *new_vma, struct vm_area *vma)
{
@@ -649,96 +638,140 @@ struct page *copy_on_write(struct fault_data *fault)
* FIXME: Add VM_DIRTY bit for every page that has write-faulted.
*/
struct page *__do_page_fault(struct fault_data *fault)
/* Handle read faults */
struct page *page_read_fault(struct fault_data *fault)
{
unsigned int reason = fault->reason;
unsigned int vma_flags = fault->vma->flags;
unsigned int pte_flags = fault->pte_flags;
struct vm_area *vma = fault->vma;
struct vm_obj_link *vmo_link;
unsigned long file_offset;
struct page *page;
struct page *page = 0;
/* Handle read */
if ((reason & VM_READ) && (pte_flags & VM_NONE)) {
file_offset = fault_to_file_offset(fault);
file_offset = fault_to_file_offset(fault);
/* Get the first object, either original file or a shadow */
if (!(vmo_link = vma_next_link(&vma->vm_obj_list, &vma->vm_obj_list))) {
printf("%s:%s: No vm object in vma!\n",
__TASKNAME__, __FUNCTION__);
/* Get the first object, either original file or a shadow */
if (!(vmo_link = vma_next_link(&vma->vm_obj_list, &vma->vm_obj_list))) {
printf("%s:%s: No vm object in vma!\n",
__TASKNAME__, __FUNCTION__);
BUG();
}
/* Traverse the list of read-only vm objects and search for the page */
while (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
file_offset))) {
if (!(vmo_link = vma_next_link(&vmo_link->list,
&vma->vm_obj_list))) {
printf("%s:%s: Traversed all shadows and the original "
"file's vm_object, but could not find the "
"faulty page in this vma.\n",__TASKNAME__,
__FUNCTION__);
BUG();
}
}
BUG_ON(!page);
/* Traverse the list of read-only vm objects and search for the page */
while (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
file_offset))) {
if (!(vmo_link = vma_next_link(&vmo_link->list,
&vma->vm_obj_list))) {
printf("%s:%s: Traversed all shadows and the original "
"file's vm_object, but could not find the "
"faulty page in this vma.\n",__TASKNAME__,
__FUNCTION__);
return page;
}
struct page *page_write_fault(struct fault_data *fault)
{
unsigned int vma_flags = fault->vma->flags;
struct vm_area *vma = fault->vma;
struct vm_obj_link *vmo_link;
unsigned long file_offset;
struct page *page = 0;
/* Copy-on-write. All private vmas are always COW */
if (vma_flags & VMA_PRIVATE) {
BUG_ON(IS_ERR(page = copy_on_write(fault)));
/*
* This handles shared pages that are both anon and non-anon.
*/
} else if ((vma_flags & VMA_SHARED)) {
file_offset = fault_to_file_offset(fault);
/* Don't traverse, just take the first object */
BUG_ON(!(vmo_link = vma_next_link(&vma->vm_obj_list,
&vma->vm_obj_list)));
/* Get the page from its pager */
if (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
file_offset))) {
/*
* Writable page does not exist,
* if it is anonymous, it needs to be COW'ed,
* otherwise the file must have paged-in this
* page, so its a bug.
*/
if (vma_flags & VMA_ANONYMOUS) {
BUG_ON(IS_ERR(page = copy_on_write(fault)));
return page;
} else {
printf("%s: Could not obtain faulty "
"page from regular file.\n",
__TASKNAME__);
BUG();
}
}
BUG_ON(!page);
}
/* Handle write */
if ((reason & VM_WRITE) && (pte_flags & VM_READ)) {
/* Copy-on-write. All private vmas are always COW */
if (vma_flags & VMA_PRIVATE) {
BUG_ON(IS_ERR(page = copy_on_write(fault)));
/*
* This handles shared pages that are both anon and non-anon.
* Page and object are now dirty. Currently it's
* only relevant for file-backed shared objects.
*/
} else if ((vma_flags & VMA_SHARED)) {
file_offset = fault_to_file_offset(fault);
page->flags |= VM_DIRTY;
page->owner->flags |= VM_DIRTY;
} else
BUG();
/* Don't traverse, just take the first object */
BUG_ON(!(vmo_link = vma_next_link(&vma->vm_obj_list,
&vma->vm_obj_list)));
return page;
}
/* Get the page from its pager */
if (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
file_offset))) {
/*
* Writable page does not exist,
* if it is anonymous, it needs to be COW'ed,
* otherwise the file must have paged-in this
* page, so its a bug.
*/
if (vma_flags & VMA_ANONYMOUS) {
BUG_ON(IS_ERR(page = copy_on_write(fault)));
goto out_success;
} else {
printf("%s: Could not obtain faulty "
"page from regular file.\n",
__TASKNAME__);
BUG();
}
}
struct page *__do_page_fault(struct fault_data *fault)
{
unsigned int reason = fault->reason;
unsigned int pte_flags = fault->pte_flags;
unsigned int map_flags = 0;
struct page *page = 0;
/*
* Page and object are now dirty. Currently it's
* only relevant for file-backed shared objects.
*/
page->flags |= VM_DIRTY;
page->owner->flags |= VM_DIRTY;
} else
BUG();
if ((reason & VM_READ) && (pte_flags & VM_NONE)) {
page = page_read_fault(fault);
map_flags = MAP_USR_RO;
} else if ((reason & VM_WRITE) && (pte_flags & VM_NONE)) {
page = page_read_fault(fault);
page = page_write_fault(fault);
map_flags = MAP_USR_RW;
} else if ((reason & VM_EXEC) && (pte_flags & VM_NONE)) {
page = page_read_fault(fault);
map_flags = MAP_USR_RX;
} else if ((reason & VM_EXEC) && (pte_flags & VM_READ)) {
/* Retrieve already paged in file */
page = page_read_fault(fault);
if (pte_flags & VM_WRITE)
map_flags = MAP_USR_RWX;
else
map_flags = MAP_USR_RX;
} else if ((reason & VM_WRITE) && (pte_flags & VM_READ)) {
page = page_write_fault(fault);
if (pte_flags & VM_EXEC)
map_flags = MAP_USR_RWX;
else
map_flags = MAP_USR_RW;
} else {
printf("mm0: Unhandled page fault.\n");
BUG();
}
out_success:
BUG_ON(!page);
/* Map the new page to faulty task */
l4_map((void *)page_to_phys(page),
(void *)page_align(fault->address), 1,
(reason & VM_READ) ? MAP_USR_RO_FLAGS : MAP_USR_RW_FLAGS,
fault->task->tid);
dprintf("%s: Mapped 0x%x as writable to tid %d.\n", __TASKNAME__,
page_align(fault->address), fault->task->tid);
map_flags, fault->task->tid);
// vm_object_print(page->owner);
return page;
@@ -796,7 +829,7 @@ int vm_freeze_shadows(struct tcb *task)
/* Map the page as read-only */
l4_map((void *)page_to_phys(p),
(void *)virtual, 1,
MAP_USR_RO_FLAGS, task->tid);
MAP_USR_RO, task->tid);
}
}
@@ -860,11 +893,6 @@ struct page *do_page_fault(struct fault_data *fault)
fault_handle_error(fault);
}
if ((reason & VM_EXEC) && (vma_flags & VM_EXEC)) {
printf("Exec faults unsupported yet.\n");
fault_handle_error(fault);
}
/* Handle legitimate faults */
return __do_page_fault(fault);
}
@@ -890,20 +918,145 @@ struct page *page_fault_handler(struct tcb *sender, fault_kdata_t *fkdata)
return do_page_fault(&fault);
}
int vm_compare_prot_flags(unsigned int current, unsigned int needed)
static inline unsigned int pte_to_map_flags(unsigned int pte_flags)
{
current &= VM_PROT_MASK;
needed &= VM_PROT_MASK;
unsigned int map_flags;
if (needed & VM_READ)
if (current & (VM_READ | VM_WRITE))
return 1;
switch(pte_flags) {
case VM_READ:
map_flags = MAP_USR_RO;
break;
case (VM_READ | VM_WRITE):
map_flags = MAP_USR_RW;
break;
case (VM_READ | VM_WRITE | VM_EXEC):
map_flags = MAP_USR_RWX;
break;
case (VM_READ | VM_EXEC):
map_flags = MAP_USR_RX;
break;
default:
BUG();
}
if (needed & VM_WRITE &&
(current & VM_WRITE))
return 1;
return map_flags;
}
return 0;
/*
* Prefaults a page of a task. The catch is that the page may already
* have been faulted with even more progress than the desired
* flags would progress in the fault (e.g. read-faulting a
* copy-on-write'd page).
*
* This function detects whether progress is necessary or not by
* inspecting the vma's vm_object chain state.
*
* Generally both read-fault and write-fault paths are repeatable, in
* the sense that an already faulted page may be safely re-faulted again
* and again, be it a read-only or copy-on-write'd page.
*
* The retrieval of the same page in a repetitive fashion is safe,
* but while it also seems to appear safe, it is unnecessary to downgrade
* or change mapping permissions of a page. E.g. make a copy-on-write'd
* page read-only by doing a blind read-fault on it.
*
* Hence this function checks whether a fault is necessary and simply
* returns if it isn't.
*
* FIXME: Escalate any page fault errors like a civilized function!
*/
struct page *task_prefault_smart(struct tcb *task, unsigned long address,
unsigned int wanted_flags)
{
struct vm_obj_link *vmo_link;
unsigned long file_offset;
unsigned int vma_flags, pte_flags;
struct vm_area *vma;
struct page *page;
int err;
struct fault_data fault = {
.task = task,
.address = address,
};
/* Find the vma */
if (!(fault.vma = find_vma(fault.address,
&fault.task->vm_area_head->list))) {
dprintf("%s: Invalid: No vma for given address. %d\n",
__FUNCTION__, -EINVAL);
return PTR_ERR(-EINVAL);
}
/* Read fault, repetitive safe */
if (wanted_flags & VM_READ)
if (IS_ERR(page = page_read_fault(&fault)))
return page;
/* Write fault, repetitive safe */
if (wanted_flags & VM_WRITE)
if (IS_ERR(page = page_write_fault(&fault)))
return page;
/*
* If we came this far, it means we have more
* permissions than VM_NONE.
*
* Now we _must_ find out what those page
* protection flags were, and do this without
* needing to inspect any ptes.
*
* We don't want to downgrade a RW page to RO again.
*/
file_offset = fault_to_file_offset(&fault);
vma_flags = fault.vma->flags;
vma = fault.vma;
/* Get the topmost vm_object */
if (!(vmo_link = vma_next_link(&vma->vm_obj_list,
&vma->vm_obj_list))) {
printf("%s:%s: No vm object in vma!\n",
__TASKNAME__, __FUNCTION__);
BUG();
}
/* Traverse the list of vm objects and search for the page */
while (IS_ERR(page = vmo_link->obj->pager->ops.page_in(vmo_link->obj,
file_offset))) {
if (!(vmo_link = vma_next_link(&vmo_link->list,
&vma->vm_obj_list))) {
printf("%s:%s: Traversed all shadows and the original "
"file's vm_object, but could not find the "
"faulty page in this vma.\n",__TASKNAME__,
__FUNCTION__);
BUG();
}
}
/* Use flags for the vm_object containing the page */
if (vmo_link->obj->flags & VM_WRITE)
pte_flags = VM_WRITE | VM_READ;
else
pte_flags = VM_READ;
/*
* Now check vma flags for adding the VM_EXEC
* The real pte may not have this flag yet, but
* it is allowed to have it and it doesn't harm.
*/
if (vma_flags & VM_EXEC)
pte_flags |= VM_EXEC;
/* Map the page to task using these flags */
if ((err = l4_map((void *)page_to_phys(page),
(void *)page_align(fault.address), 1,
pte_to_map_flags(pte_flags),
fault.task->tid)) < 0) {
printf("l4_map() failed. err=%d\n", err);
BUG();
}
return page;
}
/*
@@ -914,6 +1067,16 @@ int vm_compare_prot_flags(unsigned int current, unsigned int needed)
struct page *task_prefault_page(struct tcb *task, unsigned long address,
unsigned int vmflags)
{
struct page *ret;
perfmon_reset_start_cyccnt();
ret = task_prefault_smart(task, address, vmflags);
debug_record_cycles("task_prefault_smart");
return ret;
#if 0
struct page *p;
struct fault_data fault = {
.task = task,
@@ -949,6 +1112,23 @@ struct page *task_prefault_page(struct tcb *task, unsigned long address,
BUG_ON(vmflags & ~(VM_READ | VM_WRITE));
return p;
#endif
}
int vm_compare_prot_flags(unsigned int current, unsigned int needed)
{
current &= VM_PROT_MASK;
needed &= VM_PROT_MASK;
if (needed & VM_READ)
if (current & (VM_READ | VM_WRITE))
return 1;
if (needed & VM_WRITE &&
(current & VM_WRITE))
return 1;
return 0;
}

View File

@@ -10,8 +10,8 @@
#include <l4/macros.h>
#include <l4/api/errno.h>
#include <l4lib/types.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include <l4lib/ipcdefs.h>
#include <l4/api/kip.h>
#include <posix/sys/types.h>
@@ -43,8 +43,8 @@ int page_copy(struct page *dst, struct page *src,
BUG_ON(dst_offset + size > PAGE_SIZE);
BUG_ON(src_offset + size > PAGE_SIZE);
dstvaddr = l4_map_helper((void *)page_to_phys(dst), 1);
srcvaddr = l4_map_helper((void *)page_to_phys(src), 1);
dstvaddr = page_to_virt(dst);
srcvaddr = page_to_virt(src);
/*
printf("%s: Copying from page with offset %lx to page with offset %lx\n"
"src copy offset: 0x%lx, dst copy offset: 0x%lx, copy size: %lx\n",
@@ -56,9 +56,6 @@ int page_copy(struct page *dst, struct page *src,
memcpy(dstvaddr + dst_offset, srcvaddr + src_offset, size);
l4_unmap_helper(dstvaddr, 1);
l4_unmap_helper(srcvaddr, 1);
return 0;
}
@@ -552,16 +549,16 @@ int copy_cache_pages(struct vm_file *vmfile, struct tcb *task, void *buf,
copysize = min(copysize, PAGE_SIZE - page_offset(task_offset));
if (read)
page_copy(task_prefault_page(task, task_offset,
VM_READ | VM_WRITE),
page_copy(task_prefault_smart(task, task_offset,
VM_READ | VM_WRITE),
file_page,
page_offset(task_offset),
page_offset(file_offset),
copysize);
else
page_copy(file_page,
task_prefault_page(task, task_offset,
VM_READ),
task_prefault_smart(task, task_offset,
VM_READ),
page_offset(file_offset),
page_offset(task_offset),
copysize);

View File

@@ -3,8 +3,9 @@
*
* Copyright (C) 2007 - 2009 Bahadir Balban
*/
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include __INC_ARCH(debug.h)
#include <l4lib/utcb.h>
#include <l4lib/exregs.h>
#include <l4/lib/list.h>
@@ -229,6 +230,8 @@ void init_physmem_secondary(struct membank *membank)
{
struct page_bitmap *pmap = initdata.page_map;
int npages = pmap->pfn_end - pmap->pfn_start;
void *virtual_start;
int err;
/*
* Allocation marks for the struct
@@ -253,17 +256,6 @@ void init_physmem_secondary(struct membank *membank)
*/
pg_npages = __pfn(page_align_up((sizeof(struct page) * npages)));
/* These are relative pfn offsets
* to the start of the memory bank
*
* FIXME:
* 1.) These values were only right
* when membank started from pfn 0.
*
* 2.) Use set_page_map to set page map
* below instead of manually.
*/
pg_spfn = __pfn(membank[0].free);
pg_epfn = pg_spfn + pg_npages;
@@ -311,7 +303,34 @@ void init_physmem_secondary(struct membank *membank)
/* Test that page/phys macros work */
BUG_ON(phys_to_page(page_to_phys(&page_array[5]))
!= &page_array[5])
!= &page_array[5]);
/* Now map all physical pages to virtual correspondents */
virtual_start = (void *)PAGER_VIRTUAL_START;
if ((err = l4_map((void *)membank[0].start,
virtual_start,
__pfn(membank[0].end - membank[0].start),
MAP_USR_RW, self_tid())) < 0) {
printk("FATAL: Could not map all physical pages to "
"virtual. err=%d\n", err);
BUG();
}
#if 0
printf("Virtual offset: %p\n", virtual_start);
printf("Physical page offset: 0x%lx\n", membank[0].start);
printf("page address: 0x%lx\n", (unsigned long)&page_array[5]);
printf("page_to_virt: %p\n", page_to_virt(&page_array[5]));
printf("virt_to_phys, virtual_start: %p\n", virt_to_phys(virtual_start));
printf("page_to_virt_to_phys: %p\n", virt_to_phys(page_to_virt(&page_array[5])));
printf("page_to_phys: 0x%lx\n", page_to_phys(&page_array[5]));
#endif
/* Now test that virt/phys macros work */
BUG_ON(virt_to_phys(page_to_virt(&page_array[5]))
!= (void *)page_to_phys(&page_array[5]));
BUG_ON(virt_to_page(page_to_virt(&page_array[5]))
!= &page_array[5]);
}
@@ -354,6 +373,7 @@ void init_physmem_primary()
physmem.numpages = physmem.end - physmem.start;
}
void init_physmem(void)
{
init_physmem_primary();
@@ -377,6 +397,9 @@ void copy_init_process(void)
void *mapped;
int err;
/* Measure performance, if enabled */
perfmon_reset_start_cyccnt();
if ((fd = sys_open(self, "/test0", O_TRUNC |
O_RDWR | O_CREAT, 0)) < 0) {
printf("FATAL: Could not open file "
@@ -384,6 +407,8 @@ void copy_init_process(void)
BUG();
}
debug_record_cycles("sys_open");
init_img = bootdesc_get_image_byname("test0");
img_size = page_align_up(init_img->phys_end) -
page_align(init_img->phys_start);
@@ -407,6 +432,8 @@ void copy_init_process(void)
BUG();
}
debug_record_cycles("Until after do_mmap");
/* Prefault it */
if ((err = task_prefault_range(self, (unsigned long)mapped,
img_size, VM_READ | VM_WRITE))
@@ -415,26 +442,38 @@ void copy_init_process(void)
BUG();
}
/* Copy the raw image to anon region */
memcpy(mapped, init_img_start, img_size);
debug_record_cycles("memcpy image");
/* Write it to real file from anon region */
sys_write(find_task(self_tid()), fd, mapped, img_size);
debug_record_cycles("sys_write");
/* Close file */
sys_close(find_task(self_tid()), fd);
debug_record_cycles("sys_close");
/* Unmap anon region */
do_munmap(self, (unsigned long)mapped, __pfn(img_size));
/* Unmap raw virtual range for image memory */
l4_unmap_helper(init_img_start,__pfn(img_size));
debug_record_cycles("Final do_munmap/l4_unmap");
}
void start_init_process(void)
{
/* Copy raw test0 elf image from memory to memfs first */
copy_init_process();
init_execve("/test0");

View File

@@ -10,7 +10,7 @@
#include <l4/types.h>
#include <l4/api/errno.h>
#include <l4/generic/space.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
#include INC_GLUE(memory.h)
#include INC_SUBARCH(mm.h)
#include <memory.h>
@@ -30,6 +30,8 @@ struct address_pool pager_vaddr_pool;
/* Bitmap size to represent an address pool of 256 MB. */
#define ADDRESS_POOL_256MB 2048
unsigned long free_virtual_address_start;
/* Same as a regular id pool except that its bitmap size is fixed */
static struct pager_virtual_address_id_pool {
int nwords;
@@ -60,8 +62,8 @@ int pager_address_pool_init(void)
address_pool_init_with_idpool(&pager_vaddr_pool,
(struct id_pool *)
&pager_virtual_address_id_pool,
PAGER_MMAP_END,
__pfn_to_addr(cont_mem_regions.pager->end));
PAGER_EXT_VIRTUAL_START,
PAGER_EXT_VIRTUAL_END);
return 0;
}
@@ -126,7 +128,7 @@ void *pager_map_pages(struct vm_file *f, unsigned long page_offset, unsigned lon
/* Map pages contiguously one by one */
for (unsigned long pfn = page_offset; pfn < page_offset + npages; pfn++) {
BUG_ON(!(p = find_page(&f->vm_obj, pfn)))
l4_map((void *)page_to_phys(p), addr, 1, MAP_USR_RW_FLAGS, self_tid());
l4_map((void *)page_to_phys(p), addr, 1, MAP_USR_RW, self_tid());
addr += PAGE_SIZE;
}
@@ -192,7 +194,7 @@ void *pager_validate_map_user_range2(struct tcb *user, void *userptr,
}
l4_map((void *)page_to_phys(p),
virt, 1, MAP_USR_RW_FLAGS, self_tid());
virt, 1, MAP_USR_RW, self_tid());
virt += PAGE_SIZE;
}
@@ -207,3 +209,25 @@ void *pager_validate_map_user_range2(struct tcb *user, void *userptr,
}
/*
* Find the page's offset from membank physical start,
* simply add the same offset to virtual start
*/
void *phys_to_virt(void *p)
{
unsigned long paddr = (unsigned long)p;
return (void *)(paddr - membank[0].start + PAGER_VIRTUAL_START);
}
/*
* Find the page's offset from virtual start, add it to membank
* physical start offset
*/
void *virt_to_phys(void *v)
{
unsigned long vaddr = (unsigned long)v;
return (void *)(vaddr - PAGER_VIRTUAL_START + membank[0].start);
}

View File

@@ -8,8 +8,8 @@
#include <malloc/malloc.h>
#include INC_API(errno.h)
#include <posix/sys/types.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include <memory.h>
#include <task.h>
#include <mmap.h>
@@ -401,17 +401,15 @@ void *sys_mmap(struct tcb *task, struct sys_mmap_args *args)
struct sys_mmap_args *mapped_args;
void *ret;
if (!(mapped_args = pager_validate_map_user_range(task, args,
sizeof(*args),
VM_READ | VM_WRITE)))
if (!(mapped_args = pager_get_user_page(task, args,
sizeof(*args),
VM_READ | VM_WRITE)))
return PTR_ERR(-EINVAL);
ret = __sys_mmap(task, mapped_args->start, mapped_args->length,
mapped_args->prot, mapped_args->flags, mapped_args->fd,
mapped_args->offset);
pager_unmap_user_range(mapped_args, sizeof(*args));
return ret;
}

View File

@@ -7,7 +7,7 @@
#include <file.h>
#include <l4/api/errno.h>
#include <l4/lib/math.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
#include <vm_area.h>
#include <malloc/malloc.h>

View File

@@ -3,8 +3,8 @@
*/
#include <l4/macros.h>
#include <l4/lib/list.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include <malloc/malloc.h>
#include <mm/alloc_page.h>
#include <vm_area.h>
@@ -66,7 +66,7 @@ int file_page_out(struct vm_object *vm_obj, unsigned long page_offset)
{
struct vm_file *f = vm_object_to_file(vm_obj);
struct page *page;
void *vaddr, *paddr;
void *paddr;
int err;
/* Check first if the file has such a page at all */
@@ -86,46 +86,26 @@ int file_page_out(struct vm_object *vm_obj, unsigned long page_offset)
return 0;
paddr = (void *)page_to_phys(page);
vaddr = l4_new_virtual(1);
/* FIXME:
* Are we sure that pages need
* to be mapped to self one-by-one?
*
* This needs fixing.
*/
/* Map the page to self */
l4_map(paddr, vaddr, 1, MAP_USR_RW_FLAGS, self_tid());
//printf("%s/%s: Writing to vnode %lu, at pgoff 0x%lu, %d pages, buf at %p\n",
// __TASKNAME__, __FUNCTION__, f->vnode->vnum, page_offset, 1, vaddr);
/* Syscall to vfs to write page back to file. */
if ((err = vfs_write(f->vnode, page_offset, 1, vaddr)) < 0)
goto out_err;
/* Unmap it from self */
l4_unmap(vaddr, 1, self_tid());
l4_del_virtual(vaddr, 1);
if ((err = vfs_write(f->vnode, page_offset, 1,
phys_to_virt(paddr))) < 0)
return err;
/* Clear dirty flag */
page->flags &= ~VM_DIRTY;
return 0;
out_err:
l4_unmap(vaddr, 1, self_tid());
l4_del_virtual(vaddr, 1);
return err;
}
struct page *file_page_in(struct vm_object *vm_obj, unsigned long page_offset)
{
struct vm_file *f = vm_object_to_file(vm_obj);
struct page *page;
void *vaddr, *paddr;
void *paddr;
int err;
/* Check first if the file has such a page at all */
@@ -140,24 +120,19 @@ struct page *file_page_in(struct vm_object *vm_obj, unsigned long page_offset)
if (!(page = find_page(vm_obj, page_offset))) {
/* Allocate a new page */
paddr = alloc_page(1);
vaddr = l4_new_virtual(1);
page = phys_to_page(paddr);
/* Map the page to vfs task */
l4_map(paddr, vaddr, 1, MAP_USR_RW_FLAGS, self_tid());
/* Syscall to vfs to read into the page. */
/* Call to vfs to read into the page. */
if ((err = vfs_read(f->vnode, page_offset,
1, vaddr)) < 0)
goto out_err;
1, phys_to_virt(paddr))) < 0) {
free_page(paddr);
return PTR_ERR(err);
}
// printf("%s/%s: Reading into vnode %lu, at pgoff 0x%lu, %d pages, buf at %p\n",
// __TASKNAME__, __FUNCTION__, f->vnode->vnum, page_offset, 1, vaddr);
/* Unmap it from vfs */
l4_unmap(vaddr, 1, self_tid());
l4_del_virtual(vaddr, 1);
/* Update vm object details */
vm_obj->npages++;
@@ -174,12 +149,6 @@ struct page *file_page_in(struct vm_object *vm_obj, unsigned long page_offset)
}
return page;
out_err:
l4_unmap(vaddr, 1, self_tid());
l4_del_virtual(vaddr, 1);
free_page(paddr);
return PTR_ERR(err);
}
/*
@@ -392,9 +361,13 @@ int init_devzero(void)
/* Allocate and initialise the zero page */
zphys = alloc_page(1);
zpage = phys_to_page(zphys);
zvirt = l4_map_helper(zphys, 1);
zvirt = (void *)phys_to_virt(zphys);
memset(zvirt, 0, PAGE_SIZE);
l4_unmap_helper(zvirt, 1);
/*
* FIXME:
* Flush the dcache if virtual data cache
*/
/* Allocate and initialise devzero file */
devzero = vm_file_create();

View File

@@ -13,7 +13,7 @@
#include <l4/api/errno.h>
#include INC_GLUE(memory.h)
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
#include <stdio.h>
#include <init.h>
#include <physmem.h>

View File

@@ -11,8 +11,8 @@
#include <vm_area.h>
#include <globals.h>
#include <malloc/malloc.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include <lib/idpool.h>
#include <lib/addr.h>
#include <lib/spinlock.h>

View File

@@ -12,10 +12,10 @@
#include <l4/api/kip.h>
#include <l4/api/errno.h>
#include INC_GLUE(memory.h)
#include L4LIB_INC_ARCH(syscalls.h)
#include L4LIB_INC_ARCH(syslib.h)
#include L4LIB_INC_ARCH(utcb.h)
#include <l4lib/arch/syscalls.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/arch/utcb.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/exregs.h>
@@ -358,9 +358,7 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids,
}
/* Create the thread structures and address space as the pager */
if ((err = l4_thread_control(THREAD_CREATE |
TC_AS_PAGER |
ctrl_flags, ids)) < 0) {
if ((err = l4_thread_control(THREAD_CREATE | ctrl_flags, ids)) < 0) {
printf("l4_thread_control failed with %d.\n", err);
return PTR_ERR(err);
}
@@ -464,6 +462,7 @@ int task_copy_args_to_user(char *user_stack,
/* Set beginning of envp */
envp_start = (char **)user_stack;
/* Forward by number of envp ptrs */
user_stack += sizeof(int) * env->argc;
@@ -509,6 +508,7 @@ int task_prefault_range(struct tcb *task, unsigned long start,
{
struct page *p;
for (unsigned long i = start; i < start + size; i += PAGE_SIZE)
if (IS_ERR(p = task_prefault_page(task, i, vm_flags)))
return (int)p;

View File

@@ -53,6 +53,7 @@ int vm_object_test_shadow_count(struct vm_object *vmo)
* Add checking that total open file descriptors are
* equal to total opener count of all files
*/
#if defined (DEBUG_FAULT_HANDLING)
int mm0_test_global_vm_integrity(void)
{
struct tcb *task;
@@ -123,6 +124,8 @@ int mm0_test_global_vm_integrity(void)
}
return 0;
}
#else /* End of DEBUG_FAULT_HANDLING */
int mm0_test_global_vm_integrity(void) { return 0; }
#endif /* End of !DEBUG_FAULT_HANDLING */

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Bahadir Balban
*/
#include <l4lib/arch/syslib.h>
#include L4LIB_INC_ARCH(syslib.h)
#include <vm_area.h>
#include <task.h>
#include <user.h>
@@ -46,8 +46,8 @@ int pager_validate_user_range(struct tcb *user, void *userptr, unsigned long siz
* FIXME: There's no logic here to make non-contiguous physical pages
* to get mapped virtually contiguous.
*/
void *pager_validate_map_user_range(struct tcb *user, void *userptr,
unsigned long size, unsigned int vm_flags)
void *pager_get_user_page(struct tcb *user, void *userptr,
unsigned long size, unsigned int vm_flags)
{
unsigned long start = page_align(userptr);
unsigned long end = page_align_up(userptr + size);
@@ -58,26 +58,17 @@ void *pager_validate_map_user_range(struct tcb *user, void *userptr,
return 0;
/* Map first page and calculate the mapped address of pointer */
mapped = l4_map_helper((void *)page_to_phys(task_prefault_page(user, start,
vm_flags)), 1);
mapped = page_to_virt(task_prefault_page(user, start, vm_flags));
mapped = (void *)(((unsigned long)mapped) |
((unsigned long)(PAGE_MASK & (unsigned long)userptr)));
/* Map the rest of the pages, if any */
for (unsigned long i = start + PAGE_SIZE; i < end; i += PAGE_SIZE)
l4_map_helper((void *)
page_to_phys(task_prefault_page(user, start + i,
vm_flags)), 1);
BUG();
return mapped;
}
void pager_unmap_user_range(void *mapped_ptr, unsigned long size)
{
l4_unmap_helper((void *)page_align(mapped_ptr),
__pfn(page_align_up(size)));
}
/*
* Copy from one buffer to another. Stop if maxlength or
* a page boundary is hit.
@@ -164,28 +155,23 @@ int copy_from_user(struct tcb *task, void *buf, char *user, int size)
int count = size;
void *mapped = 0;
if (!(mapped = pager_validate_map_user_range(task, user,
TILL_PAGE_ENDS(user),
VM_READ)))
if (!(mapped = pager_get_user_page(task, user, TILL_PAGE_ENDS(user),
VM_READ)))
return -EINVAL;
while ((ret = memcpy_page(buf + copied, mapped, count, 0)) < 0) {
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
copied += TILL_PAGE_ENDS(mapped);
count -= TILL_PAGE_ENDS(mapped);
if (!(mapped =
pager_validate_map_user_range(task, user + copied,
TILL_PAGE_ENDS(user + copied),
VM_READ)))
pager_get_user_page(task, user + copied,
TILL_PAGE_ENDS(user + copied),
VM_READ)))
return -EINVAL;
}
/* Note copied is always in bytes */
total = copied + ret;
/* Unmap the final page */
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
return total;
}
@@ -196,28 +182,23 @@ int copy_to_user(struct tcb *task, char *user, void *buf, int size)
void *mapped = 0;
/* Map the user page */
if (!(mapped = pager_validate_map_user_range(task, user,
TILL_PAGE_ENDS(user),
VM_READ)))
if (!(mapped = pager_get_user_page(task, user,
TILL_PAGE_ENDS(user),
VM_READ | VM_WRITE)))
return -EINVAL;
while ((ret = memcpy_page(mapped, buf + copied, count, 1)) < 0) {
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
copied += TILL_PAGE_ENDS(mapped);
count -= TILL_PAGE_ENDS(mapped);
if (!(mapped =
pager_validate_map_user_range(task, user + copied,
TILL_PAGE_ENDS(user + copied),
VM_READ)))
if (!(mapped = pager_get_user_page(task, user + copied,
TILL_PAGE_ENDS(user + copied),
VM_READ | VM_WRITE)))
return -EINVAL;
}
/* Note copied is always in bytes */
total = copied + ret;
/* Unmap the final page */
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
return total;
}
@@ -243,9 +224,8 @@ int copy_user_buf(struct tcb *task, void *buf, char *user, int maxlength,
return -EINVAL;
/* Map the first page the user buffer is in */
if (!(mapped = pager_validate_map_user_range(task, user,
TILL_PAGE_ENDS(user),
VM_READ)))
if (!(mapped = pager_get_user_page(task, user, TILL_PAGE_ENDS(user),
VM_READ)))
return -EINVAL;
while ((ret = copy_func(buf + copied, mapped, count)) < 0) {
@@ -257,13 +237,12 @@ int copy_user_buf(struct tcb *task, void *buf, char *user, int maxlength,
* because we know we hit a page boundary and we increase
* by the page boundary bytes
*/
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
copied += TILL_PAGE_ENDS(mapped);
count -= TILL_PAGE_ENDS(mapped);
if (!(mapped =
pager_validate_map_user_range(task, user + copied,
TILL_PAGE_ENDS(user + copied),
VM_READ)))
pager_get_user_page(task, user + copied,
TILL_PAGE_ENDS(user + copied),
VM_READ)))
return -EINVAL;
}
}
@@ -271,9 +250,6 @@ int copy_user_buf(struct tcb *task, void *buf, char *user, int maxlength,
/* Note copied is always in bytes */
total = (copied / elem_size) + ret;
/* Unmap the final page */
pager_unmap_user_range(mapped, TILL_PAGE_ENDS(mapped));
return total;
}

View File

@@ -3,9 +3,10 @@
*
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
*/
#include <l4lib/arch/utcb.h>
#include <l4/macros.h>
#include INC_GLUE(memlayout.h)
#include L4LIB_INC_ARCH(utcb.h)
#include <mmap.h>
#include <utcb.h>
#include <malloc/malloc.h>

View File

@@ -12,7 +12,7 @@ linkoutput_file_suffix = "-linkinfo.txt"
linkoutput_file = image_name + linkoutput_file_suffix
def generate_bootdesc():
command = config.user_toolchain + objdump + " -t " + image_name + " > " + linkoutput_file
command = config.toolchain + objdump + " -t " + image_name + " > " + linkoutput_file
print command
os.system(command)
f = open(linkoutput_file, "r")

View File

@@ -69,7 +69,7 @@ test_exec_env = environment.Clone()
test_exec_env.Append(LIBS = ['posix', 'c-userspace'])
test_exec_env.Append(LINKFLAGS = '-T' + test_exec_lds[0].path)
test_exec_env.Append(CPPFLAGS = ' -D__USERSPACE__')
test_exec_env.Append(CPPFLAGS = ' -D__USERSPACE__ -include l4lib/macros.h ')
test_exec_env.Replace(PROGSUFFIX = '')
test_exec_src = Glob('src/test_exec/*.[cS]')
test_exec_objs = test_exec_env.Object(test_exec_src)
@@ -81,7 +81,7 @@ AlwaysBuild(test_exec_lds)
env.Append(LIBS = ['posix', 'c-userspace'])
env.Append(LINKFLAGS = '-T' + lma_lds[0].path)
env.Append(CPPFLAGS = ' -D__USERSPACE__')
env.Append(CPPFLAGS = ' -D__USERSPACE__ -include l4lib/macros.h ')
env.Replace(PROGSUFFIX = '')
objs = env.Object(src + test_exec_asm)
test0 = env.Program('test0', objs)

View File

@@ -58,7 +58,7 @@ def get_physical_base(source, target, env):
prev_image + " >> " + physical_base_ld_script))
# The kernel build environment
env = Environment(CC = config.user_toolchain + 'gcc',
env = Environment(CC = config.toolchain + 'gcc',
# We don't use -nostdinc because sometimes we need standard headers,
# such as stdarg.h e.g. for variable args, as in printk().
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
@@ -74,7 +74,7 @@ env = Environment(CC = config.user_toolchain + 'gcc',
test_exec_ld_script = "include/test_exec_linker.lds"
# The kernel build environment:
test_exec_env = Environment(CC = config.user_toolchain + 'gcc',
test_exec_env = Environment(CC = config.toolchain + 'gcc',
# We don't use -nostdinc because sometimes we need standard headers,
# such as stdarg.h e.g. for variable args, as in printk().
CCFLAGS = ['-O3', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],

View File

@@ -2,7 +2,7 @@
#define __TEST0_CAP_H__
#include <l4lib/capability.h>
#include <l4lib/lib/cap.h>
#include <l4/generic/cap-types.h>
#include <l4/api/capability.h>

View File

@@ -3,6 +3,8 @@
#define __TASKNAME__ "test0"
#include L4LIB_INC_ARCH(syslib.h)
// #define TEST_VERBOSE_PRINT
#if defined (TEST_VERBOSE_PRINT)
#define test_printf(...) printf(__VA_ARGS__)

View File

@@ -6,7 +6,6 @@
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/kip.h>
#include <l4lib/utcb.h>
#include <l4lib/ipcdefs.h>
@@ -15,6 +14,7 @@
#include <sys/types.h>
#include <atoi.h>
#include <stdlib.h>
#include L4LIB_INC_ARCH(syslib.h)
void wait_pager(l4id_t partner)
{
@@ -50,10 +50,10 @@ int main(int argc, char *argv[])
shmtest();
forktest();
fileio();
forktest();
clonetest();
undeftest();

View File

@@ -1,6 +1,6 @@
#include <capability.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include L4LIB_INC_ARCH(syslib.h)
int cap_request_pager(struct capability *cap)
{

View File

@@ -26,14 +26,16 @@ int clonetest(void)
void *child_stack;
/* Parent loops and calls clone() to clone new threads. Children don't come back from the clone() call */
for (int i = 0; i < 4; i++) {
for (int i = 0; i < 20; i++) {
if ((child_stack = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, 0, 0)) == MAP_FAILED) {
test_printf("MMAP failed.\n");
goto out_err;
} else {
test_printf("Mapped area starting at %p\n", child_stack);
}
((int *)child_stack)[-1] = 5; /* Test mapped area */
// printf("mmap returned child stack: %p\n", child_stack);
// ((int *)child_stack)[-1] = 5; /* Test mapped area */
test_printf("Cloning...\n");

View File

@@ -12,8 +12,6 @@
#include <alloca.h>
#include <l4lib/ipcdefs.h>
#define PAGE_SIZE 0x1000
extern char _start_test_exec[];
extern char _end_test_exec[];

View File

@@ -3,7 +3,6 @@
*
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
*/
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <errno.h>
#include <sys/mman.h>

View File

@@ -15,8 +15,6 @@
#include <tests.h>
#include <errno.h>
#define PAGE_SIZE 0x1000
int mmaptest(void)
{
int fd;

View File

@@ -3,7 +3,6 @@
*
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
*/
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/mutex.h>
#include <errno.h>

View File

@@ -5,7 +5,6 @@
*/
#include <stdio.h>
#include <string.h>
#include <l4lib/arch/syslib.h>
#include <l4lib/kip.h>
#include <l4lib/utcb.h>
#include <l4lib/ipcdefs.h>