resolved merge conflicts with futex code
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
#BUILD_TARGET = builtin-mic attached-mic
|
||||
BUILD_TARGET ?= attached-mic
|
||||
SRC = $(CURDIR)
|
||||
|
||||
IHKBASE ?= $(SRC)/../../ihk/cokernel
|
||||
O ?= $(KBUILD_OUTPUT)
|
||||
V ?= $(VERBOSE)
|
||||
|
||||
KERNEL = kernel.img
|
||||
KERNELS = $(addsuffix /$(KERNEL),$(addprefix $(O)/,$(BUILD_TARGET)))
|
||||
|
||||
SUBCMD_OPTS = V='$(V)'
|
||||
|
||||
$(if $(O),,$(error Specify the compilation target directory))
|
||||
#$(if $(shell ls $(IHKBASE)/Makefile),,\
|
||||
# $(error IHK is not found in $(IHKBASE)))
|
||||
|
||||
.PHONY: all clean depend
|
||||
|
||||
all: $(KERNELS)
|
||||
|
||||
%/kernel.img: %/Makefile
|
||||
@echo 'Building for' $(dir $@)
|
||||
@make --no-print-directory -C $(dir $@) $(SUBCMD_OPTS)
|
||||
|
||||
%/Makefile: Makefile.build FORCE
|
||||
@mkdir -p $(dir $@)
|
||||
@echo 'SRC = $(SRC)' > $@
|
||||
@echo 'IHKBASE = $(IHKBASE)' >> $@
|
||||
@echo 'TARGET = $(notdir $(patsubst %/,%,$(dir $@)))' >> $@
|
||||
@echo 'TARGETDIR = $$(shell echo $$(TARGET) | sed "s/-/\//")' >> $@
|
||||
@cat Makefile.build >> $@
|
||||
@rm -f $(dir $@)/Makefile.dep
|
||||
|
||||
clean: $(addsuffix .clean,$(BUILD_TARGET))
|
||||
|
||||
%.clean: $(O)/%/Makefile
|
||||
@make --no-print-directory -C $(O)/$(basename $@) $(SUBCMD_OPTS) clean
|
||||
|
||||
FORCE:
|
||||
26
kernel/Makefile.build.mpiu → kernel/Makefile.build.dcfa
Executable file → Normal file
26
kernel/Makefile.build.mpiu → kernel/Makefile.build.dcfa
Executable file → Normal file
@@ -4,8 +4,14 @@ OBJS += process.o copy.o waitq.o futex.o timer.o
|
||||
DEPSRCS=$(wildcard $(SRC)/*.c)
|
||||
|
||||
CFLAGS += -I$(SRC)/include -mcmodel=kernel -D__KERNEL__
|
||||
CFLAGS += -DDCFA_KMOD -DKNC_MAP_MICPA -DCONFIG_$(CONFIG_V)
|
||||
CFLAGS += -DKNC_MAP_MICPA -DCONFIG_$(CONFIG_V) $(EXTRA_CFLAGS)
|
||||
|
||||
ifeq ("$(DCFA_V)", "k")
|
||||
CFLAGS += -DDCFA_RUN
|
||||
else
|
||||
CFLAGS += -DDCFA_KMOD
|
||||
endif
|
||||
|
||||
LDFLAGS += -e arch_start
|
||||
IHKOBJ = ihk/ihk.o
|
||||
|
||||
@@ -24,16 +30,28 @@ mkimage_cmd_base = [ -f $(SRC)/script/mkimage.$(TARGET) ] && CC=$(CC) LD=$(LD) L
|
||||
ld_kern_cmd = $(call echo_cmd,LDKERN,$@)$(ld_kern_cmd_base)
|
||||
mkimage_cmd = $(call echo_cmd,MKIMAGE,$@)$(mkimage_cmd_base)
|
||||
|
||||
all: depend kernel.img
|
||||
P_OBJ ?= ./a.out
|
||||
|
||||
all: kernel.img
|
||||
|
||||
kernel.img: $(OBJS) $(IHKOBJ) $(EXTRA_OBJS)
|
||||
$(ld_kern_cmd)
|
||||
$(mkimage_cmd)
|
||||
|
||||
clean:
|
||||
$(rm_cmd) $(OBJS) kernel.img kernel.img.elf Makefile.dep
|
||||
kobj: depend $(KERNEL_OBJ)
|
||||
|
||||
$(KERNEL_OBJ): $(OBJS) $(IHKOBJ)
|
||||
@echo ' ' [with] $^
|
||||
$(ld_cmd)
|
||||
|
||||
umod_clean:
|
||||
$(rm_cmd) $(OBJS) $(IHKOBJ) kernel.img kernel.img.elf Makefile.dep
|
||||
@$(submake) -C $(IHKBASE) $(SUBCMD_OPTS) clean
|
||||
|
||||
kmod_clean:
|
||||
$(rm_cmd) $(OBJS) $(IHKOBJ) $(KERNEL_OBJ) Makefile.dep
|
||||
@$(submake) -C $(IHKBASE) $(SUBCMD_OPTS) clean
|
||||
|
||||
depend: Makefile.dep
|
||||
|
||||
Makefile.dep:
|
||||
24
kernel/Makefile.build.dcfa.public
Normal file
24
kernel/Makefile.build.dcfa.public
Normal file
@@ -0,0 +1,24 @@
|
||||
IHKDIR=$(IHKBASE)/$(TARGETDIR)
|
||||
|
||||
LDFLAGS += -e arch_start
|
||||
|
||||
include $(SRC)/config/config.$(TARGET)
|
||||
include $(IHKBASE)/Makefile.common
|
||||
|
||||
ld_kern_cmd_base = $(LD) $(LDFLAGS) -o $@.elf $^
|
||||
mkimage_cmd_base = [ -f $(SRC)/script/mkimage.$(TARGET) ] && CC=$(CC) LD=$(LD) LDFLAGS="$(LDFLAGS_MKIMAGE)" OBJDUMP=$(OBJDUMP) OBJCOPY=$(OBJCOPY) sh $(SRC)/script/mkimage.$(TARGET) '$@.elf' '$@' '$(SRC)' || cp $@.elf $@
|
||||
|
||||
ld_kern_cmd = $(call echo_cmd,LDKERN,$@)$(ld_kern_cmd_base)
|
||||
mkimage_cmd = $(call echo_cmd,MKIMAGE,$@)$(mkimage_cmd_base)
|
||||
|
||||
P_OBJ ?= ./a.out
|
||||
|
||||
all: kernel_program.img
|
||||
|
||||
kernel_program.img: $(KERNEL_OBJ) $(P_OBJ)
|
||||
$(ld_kern_cmd)
|
||||
$(mkimage_cmd)
|
||||
|
||||
FORCE:
|
||||
|
||||
-include Makefile.dep
|
||||
102
kernel/Makefile.dcfa
Normal file
102
kernel/Makefile.dcfa
Normal file
@@ -0,0 +1,102 @@
|
||||
BUILD_TARGET ?= attached-mic
|
||||
SRC = $(CURDIR)
|
||||
IHKBASE ?= $(SRC)/../../ihk/cokernel
|
||||
INSTALL_KL_DIR ?= ./
|
||||
|
||||
O ?= $(KBUILD_OUTPUT)
|
||||
N ?= kernel_obj.o
|
||||
V ?= $(VERBOSE)
|
||||
|
||||
CONFIG_V ?= KNF
|
||||
DCFA_V ?= u
|
||||
|
||||
EXTRA_OBJS ?=
|
||||
|
||||
## compile items
|
||||
|
||||
KERNEL = kernel.img
|
||||
KERNELS = $(addsuffix /$(KERNEL),$(addprefix $(O)/,$(BUILD_TARGET)))
|
||||
|
||||
KERNEL_OBJ = $(addsuffix /$(N),$(addprefix $(O)/,$(BUILD_TARGET)))
|
||||
KERNEL_MAKEFILE = $(addsuffix /Makefile,$(addprefix $(O)/,$(BUILD_TARGET)))
|
||||
|
||||
## install items
|
||||
|
||||
ifeq ("$(DCFA_V)", "k")
|
||||
KERNEL_OBJ_PUB = $(INSTALL_KL_DIR)/$(N)
|
||||
KERNEL_MAKEFILE_PUB = $(INSTALL_KL_DIR)/Makefile
|
||||
else
|
||||
KERNELS_PUB = $(INSTALL_KL_DIR)/$(KERNEL)
|
||||
KERNEL_MAKEFILE_PUB = $(INSTALL_KL_DIR)/Makefile
|
||||
endif
|
||||
|
||||
SUBCMD_OPTS = V='$(V)'
|
||||
|
||||
$(if $(O),,$(error Specify the compilation target directory))
|
||||
#$(if $(shell ls $(IHKBASE)/Makefile),,\
|
||||
# $(error IHK is not found in $(IHKBASE)))
|
||||
|
||||
|
||||
.PHONY: kmod umod clean depend
|
||||
.SECONDARY: $(KERNEL_MAKEFILE) $(KERNEL_MAKEFILE_PUB)
|
||||
|
||||
kmod: $(KERNEL_OBJ)
|
||||
|
||||
umod: $(KERNELS)
|
||||
|
||||
umod_install:
|
||||
@echo install $(KERNELS_PUB)
|
||||
@rm -f $(KERNELS_PUB)
|
||||
@mkdir -p $(dir $(KERNELS_PUB))
|
||||
@cp $(KERNELS) $(KERNELS_PUB)
|
||||
|
||||
kmod_install: $(KERNEL_MAKEFILE_PUB)
|
||||
@echo install $(KERNEL_OBJ_PUB)
|
||||
@rm -f $(KERNEL_OBJ_PUB)
|
||||
@cp $(KERNEL_OBJ) $(KERNEL_OBJ_PUB)
|
||||
|
||||
%/kernel.img: %/Makefile
|
||||
@echo 'Building for' $(dir $@)
|
||||
@make --no-print-directory -C $(dir $@) $(SUBCMD_OPTS)
|
||||
|
||||
%/$(N): %/Makefile
|
||||
@echo 'Building for' $(dir $@)
|
||||
@make kobj --no-print-directory -C $(dir $@) $(SUBCMD_OPTS)
|
||||
|
||||
$(KERNEL_MAKEFILE): Makefile.build.dcfa
|
||||
rm -f $@
|
||||
@mkdir -p $(dir $@)
|
||||
@echo 'SRC = $(SRC)' > $@
|
||||
@echo 'IHKBASE = $(IHKBASE)' >> $@
|
||||
@echo 'TARGET = $(notdir $(patsubst %/,%,$(dir $@)))' >> $@
|
||||
@echo 'TARGETDIR = $$(shell echo $$(TARGET) | sed "s/-/\//")' >> $@
|
||||
@echo 'CONFIG_V = $(CONFIG_V)' >> $@
|
||||
@echo 'DCFA_V = $(DCFA_V)' >> $@
|
||||
@echo 'KERNEL_OBJ = $(KERNEL_OBJ)' >> $@
|
||||
@echo 'EXTRA_OBJS = $(EXTRA_OBJS)' >> $@
|
||||
@echo 'EXTRA_CFLAGS = $(EXTRA_CFLAGS)' >> $@
|
||||
@cat $^ >> $@
|
||||
# @rm -f $(dir $@)/Makefile.dep
|
||||
|
||||
$(KERNEL_MAKEFILE_PUB): Makefile.build.dcfa.public
|
||||
@echo install $@
|
||||
@rm -f $@
|
||||
@mkdir -p $(dir $@)
|
||||
@echo 'SRC = $(SRC)' > $@
|
||||
@echo 'IHKBASE = $(IHKBASE)' >> $@
|
||||
@echo 'TARGET = $(BUILD_TARGET)' >> $@
|
||||
@echo 'TARGETDIR = $$(shell echo $$(TARGET) | sed "s/-/\//")' >> $@
|
||||
@echo 'KERNEL_OBJ = $(KERNEL_OBJ_PUB)' >> $@
|
||||
@cat $^ >> $@
|
||||
|
||||
umod_clean: $(addsuffix .umod_clean,$(BUILD_TARGET))
|
||||
|
||||
kmod_clean: $(addsuffix .kmod_clean,$(BUILD_TARGET))
|
||||
|
||||
%.umod_clean: $(O)/%/Makefile
|
||||
@make --no-print-directory -C $(O)/$(basename $@) $(SUBCMD_OPTS) umod_clean
|
||||
|
||||
%.kmod_clean: $(O)/%/Makefile
|
||||
@make --no-print-directory -C $(O)/$(basename $@) $(SUBCMD_OPTS) kmod_clean
|
||||
|
||||
FORCE:
|
||||
@@ -1,47 +0,0 @@
|
||||
BUILD_TARGET ?= attached-mic
|
||||
SRC = $(CURDIR)
|
||||
|
||||
IHKBASE ?= $(SRC)/../../ihk/cokernel
|
||||
O ?= $(KBUILD_OUTPUT)
|
||||
V ?= $(VERBOSE)
|
||||
|
||||
CONFIG_V ?= KNF
|
||||
|
||||
EXTRA_OBJS ?=
|
||||
|
||||
KERNEL = kernel.img
|
||||
KERNELS = $(addsuffix /$(KERNEL),$(addprefix $(O)/,$(BUILD_TARGET)))
|
||||
|
||||
SUBCMD_OPTS = V='$(V)'
|
||||
|
||||
$(if $(O),,$(error Specify the compilation target directory))
|
||||
#$(if $(shell ls $(IHKBASE)/Makefile),,\
|
||||
# $(error IHK is not found in $(IHKBASE)))
|
||||
|
||||
|
||||
.PHONY: all clean depend
|
||||
|
||||
all: $(KERNELS)
|
||||
|
||||
%/kernel.img: %/Makefile
|
||||
@echo 'Building for' $(dir $@)
|
||||
@make --no-print-directory -C $(dir $@) $(SUBCMD_OPTS)
|
||||
|
||||
%/Makefile: Makefile.build.mpiu FORCE
|
||||
rm -f $@
|
||||
@mkdir -p $(dir $@)
|
||||
@echo 'SRC = $(SRC)' > $@
|
||||
@echo 'IHKBASE = $(IHKBASE)' >> $@
|
||||
@echo 'TARGET = $(notdir $(patsubst %/,%,$(dir $@)))' >> $@
|
||||
@echo 'TARGETDIR = $$(shell echo $$(TARGET) | sed "s/-/\//")' >> $@
|
||||
@echo 'CONFIG_V = $(CONFIG_V)' >> $@
|
||||
@echo 'EXTRA_OBJS = $(EXTRA_OBJS)' >> $@
|
||||
@cat Makefile.build.mpiu >> $@
|
||||
@rm -f $(dir $@)/Makefile.dep
|
||||
|
||||
clean: $(addsuffix .clean,$(BUILD_TARGET))
|
||||
|
||||
%.clean: $(O)/%/Makefile
|
||||
@make --no-print-directory -C $(O)/$(basename $@) $(SUBCMD_OPTS) clean
|
||||
|
||||
FORCE:
|
||||
@@ -19,7 +19,7 @@ void cpu_local_var_init(void)
|
||||
z = sizeof(struct cpu_local_var) * num_processors;
|
||||
z = (z + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
|
||||
clv = allocate_pages(z, 0);
|
||||
clv = allocate_pages(z, IHK_MC_AP_CRITICAL);
|
||||
memset(clv, 0, z * PAGE_SIZE);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,12 @@ void kputs(char *buf)
|
||||
|
||||
if (len + kmsg_buf.tail > kmsg_buf.len) {
|
||||
kmsg_buf.tail = 0;
|
||||
if(len > kmsg_buf.len) {
|
||||
len = kmsg_buf.len;
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(kmsg_buf.str + kmsg_buf.tail, buf, len);
|
||||
memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len);
|
||||
kmsg_buf.tail += len;
|
||||
|
||||
ihk_mc_spinlock_unlock(&kmsg_lock, flags);
|
||||
|
||||
138
kernel/host.c
138
kernel/host.c
@@ -33,7 +33,7 @@ void check_mapping_for_proc(struct process *proc, unsigned long addr)
|
||||
/*
|
||||
* Communication with host
|
||||
*/
|
||||
static void process_msg_prepare_process(unsigned long rphys)
|
||||
static int process_msg_prepare_process(unsigned long rphys)
|
||||
{
|
||||
unsigned long phys, sz, s, e, up;
|
||||
struct program_load_desc *p, *pn;
|
||||
@@ -46,24 +46,39 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
int argc, envc, args_envs_npages;
|
||||
char **env;
|
||||
int range_npages;
|
||||
void *up_v;
|
||||
|
||||
sz = sizeof(struct program_load_desc)
|
||||
+ sizeof(struct program_image_section) * 16;
|
||||
npages = (sz + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
npages = ((rphys + sz - 1) >> PAGE_SHIFT) - (rphys >> PAGE_SHIFT) + 1;
|
||||
|
||||
phys = ihk_mc_map_memory(NULL, rphys, sz);
|
||||
p = ihk_mc_map_virtual(phys, npages, PTATTR_WRITABLE);
|
||||
if((p = ihk_mc_map_virtual(phys, npages, PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
n = p->num_sections;
|
||||
dkprintf("# of sections: %d\n", n);
|
||||
|
||||
pn = ihk_mc_allocate(sizeof(struct program_load_desc)
|
||||
+ sizeof(struct program_image_section) * n, 0);
|
||||
if((pn = ihk_mc_allocate(sizeof(struct program_load_desc)
|
||||
+ sizeof(struct program_image_section) * n, IHK_MC_AP_NOWAIT)) == NULL){
|
||||
ihk_mc_unmap_virtual(p, npages, 0);
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy_long(pn, p, sizeof(struct program_load_desc)
|
||||
+ sizeof(struct program_image_section) * n);
|
||||
|
||||
proc = create_process(p->entry);
|
||||
proc->pid = 1024;
|
||||
if((proc = create_process(p->entry)) == NULL){
|
||||
ihk_mc_free(pn);
|
||||
ihk_mc_unmap_virtual(p, npages, 1);
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
return -ENOMEM;
|
||||
}
|
||||
proc->pid = pn->pid;
|
||||
proc->vm->region.user_start = pn->user_start;
|
||||
proc->vm->region.user_end = pn->user_end;
|
||||
|
||||
/* TODO: Clear it at the proper timing */
|
||||
cpu_local_var(scp).post_idx = 0;
|
||||
@@ -77,8 +92,14 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
#if 0
|
||||
if (range_npages <= 256) {
|
||||
#endif
|
||||
up = virt_to_phys(ihk_mc_alloc_pages(range_npages, 0));
|
||||
add_process_memory_range(proc, s, e, up, 0);
|
||||
if((up_v = ihk_mc_alloc_pages(range_npages, IHK_MC_AP_NOWAIT)) == NULL){
|
||||
goto err;
|
||||
}
|
||||
up = virt_to_phys(up_v);
|
||||
if(add_process_memory_range(proc, s, e, up, VR_NONE) != 0){
|
||||
ihk_mc_free_pages(up_v, range_npages);
|
||||
goto err;
|
||||
}
|
||||
|
||||
{
|
||||
void *_virt = (void *)s;
|
||||
@@ -108,7 +129,7 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
}
|
||||
else {
|
||||
up = 0;
|
||||
if (add_process_large_range(proc, s, e, 0, &up)) {
|
||||
if (add_process_large_range(proc, s, e, VR_NONE, &up)) {
|
||||
kprintf("ERROR: not enough memory\n");
|
||||
while (1) cpu_halt();
|
||||
}
|
||||
@@ -155,38 +176,62 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
/*
|
||||
Fix for the problem where brk grows to hit .bss section
|
||||
when using dynamically linked executables.
|
||||
Test code resides in /home/takagi/project/mpich/src/brk_icc_mic.
|
||||
This is because when using
|
||||
ld.so (i.e. using shared objects), mckernel/kernel/host.c sets "brk" to
|
||||
the end of .bss of ld.so (e.g. 0x21f000), and then ld.so places a
|
||||
main-program after this (e.g. 0x400000), so "brk" will hit .bss
|
||||
eventually.
|
||||
*/
|
||||
proc->vm->region.brk_start = proc->vm->region.brk_end =
|
||||
(USER_END / 4) & LARGE_PAGE_MASK;
|
||||
#else
|
||||
proc->vm->region.brk_start = proc->vm->region.brk_end =
|
||||
proc->vm->region.data_end;
|
||||
#endif
|
||||
proc->vm->region.map_start = proc->vm->region.map_end =
|
||||
(USER_END / 3) & LARGE_PAGE_MASK;
|
||||
|
||||
/* Map system call stuffs */
|
||||
addr = proc->vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
||||
e = addr + PAGE_SIZE * DOORBELL_PAGE_COUNT;
|
||||
add_process_memory_range(proc, addr, e,
|
||||
if(add_process_memory_range(proc, addr, e,
|
||||
cpu_local_var(scp).doorbell_pa,
|
||||
VR_REMOTE | VR_RESERVED);
|
||||
VR_REMOTE | VR_RESERVED) != 0){
|
||||
goto err;
|
||||
}
|
||||
addr = e;
|
||||
e = addr + PAGE_SIZE * REQUEST_PAGE_COUNT;
|
||||
add_process_memory_range(proc, addr, e,
|
||||
if(add_process_memory_range(proc, addr, e,
|
||||
cpu_local_var(scp).request_pa,
|
||||
VR_REMOTE | VR_RESERVED);
|
||||
VR_REMOTE | VR_RESERVED) != 0){
|
||||
goto err;
|
||||
}
|
||||
addr = e;
|
||||
e = addr + PAGE_SIZE * RESPONSE_PAGE_COUNT;
|
||||
add_process_memory_range(proc, addr, e,
|
||||
if(add_process_memory_range(proc, addr, e,
|
||||
cpu_local_var(scp).response_pa,
|
||||
VR_RESERVED);
|
||||
VR_RESERVED) != 0){
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Map, copy and update args and envs */
|
||||
addr = e;
|
||||
e = addr + PAGE_SIZE * ARGENV_PAGE_COUNT;
|
||||
|
||||
args_envs = ihk_mc_alloc_pages(ARGENV_PAGE_COUNT, 0);
|
||||
if((args_envs = ihk_mc_alloc_pages(ARGENV_PAGE_COUNT, IHK_MC_AP_NOWAIT)) == NULL){
|
||||
goto err;
|
||||
}
|
||||
args_envs_p = virt_to_phys(args_envs);
|
||||
|
||||
add_process_memory_range(proc, addr, e,
|
||||
args_envs_p,
|
||||
VR_RESERVED);
|
||||
if(add_process_memory_range(proc, addr, e, args_envs_p, VR_NONE) != 0){
|
||||
ihk_mc_free_pages(args_envs, ARGENV_PAGE_COUNT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
dkprintf("args_envs mapping\n");
|
||||
|
||||
@@ -197,8 +242,10 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
dkprintf("args_envs_npages: %d\n", args_envs_npages);
|
||||
args_envs_rp = ihk_mc_map_memory(NULL, (unsigned long)p->args, p->args_len);
|
||||
dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp);
|
||||
args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
||||
PTATTR_WRITABLE);
|
||||
if((args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
goto err;
|
||||
}
|
||||
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
|
||||
|
||||
dkprintf("args copy, nr: %d\n", *((int*)args_envs_r));
|
||||
@@ -216,8 +263,10 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
dkprintf("args_envs_npages: %d\n", args_envs_npages);
|
||||
args_envs_rp = ihk_mc_map_memory(NULL, (unsigned long)p->envs, p->envs_len);
|
||||
dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp);
|
||||
args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
||||
PTATTR_WRITABLE);
|
||||
if((args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
goto err;
|
||||
}
|
||||
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
|
||||
|
||||
dkprintf("envs copy, nr: %d\n", *((int*)args_envs_r));
|
||||
@@ -256,7 +305,10 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
dkprintf("env OK\n");
|
||||
|
||||
p->rprocess = (unsigned long)proc;
|
||||
init_process_stack(proc, pn, argc, argv, envc, env);
|
||||
p->rpgtable = virt_to_phys(proc->vm->page_table);
|
||||
if(init_process_stack(proc, pn, argc, argv, envc, env) != 0){
|
||||
goto err;
|
||||
}
|
||||
|
||||
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
||||
proc->vm->page_table);
|
||||
@@ -266,6 +318,14 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
ihk_mc_unmap_virtual(p, npages, 1);
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
flush_tlb();
|
||||
return 0;
|
||||
err:
|
||||
ihk_mc_free(pn);
|
||||
ihk_mc_unmap_virtual(p, npages, 1);
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
free_process_memory(proc);
|
||||
destroy_process(proc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void process_msg_init(struct ikc_scd_init_param *pcp)
|
||||
@@ -290,23 +350,32 @@ static void process_msg_init_acked(unsigned long pphys)
|
||||
lparam->request_rpa = param->request_page;
|
||||
lparam->request_pa = ihk_mc_map_memory(NULL, param->request_page,
|
||||
REQUEST_PAGE_COUNT * PAGE_SIZE);
|
||||
lparam->request_va = ihk_mc_map_virtual(lparam->request_pa,
|
||||
if((lparam->request_va = ihk_mc_map_virtual(lparam->request_pa,
|
||||
REQUEST_PAGE_COUNT,
|
||||
PTATTR_WRITABLE);
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
// TODO:
|
||||
panic("ENOMEM");
|
||||
}
|
||||
|
||||
lparam->doorbell_rpa = param->doorbell_page;
|
||||
lparam->doorbell_pa = ihk_mc_map_memory(NULL, param->doorbell_page,
|
||||
DOORBELL_PAGE_COUNT *
|
||||
PAGE_SIZE);
|
||||
lparam->doorbell_va = ihk_mc_map_virtual(lparam->doorbell_pa,
|
||||
if((lparam->doorbell_va = ihk_mc_map_virtual(lparam->doorbell_pa,
|
||||
DOORBELL_PAGE_COUNT,
|
||||
PTATTR_WRITABLE);
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
// TODO:
|
||||
panic("ENOMEM");
|
||||
}
|
||||
|
||||
lparam->post_rpa = param->post_page;
|
||||
lparam->post_pa = ihk_mc_map_memory(NULL, param->post_page,
|
||||
PAGE_SIZE);
|
||||
lparam->post_va = ihk_mc_map_virtual(lparam->post_pa, 1,
|
||||
PTATTR_WRITABLE);
|
||||
if((lparam->post_va = ihk_mc_map_virtual(lparam->post_pa, 1,
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
// TODO:
|
||||
panic("ENOMEM");
|
||||
}
|
||||
|
||||
lparam->post_fin = 1;
|
||||
|
||||
@@ -340,9 +409,10 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
return 0;
|
||||
|
||||
case SCD_MSG_PREPARE_PROCESS:
|
||||
process_msg_prepare_process(packet->arg);
|
||||
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
|
||||
if(process_msg_prepare_process(packet->arg) == 0)
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
|
||||
else
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_NACKED;
|
||||
pckt.ref = packet->ref;
|
||||
pckt.arg = packet->arg;
|
||||
syscall_channel_send(c, &pckt);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <ihk/atomic.h>
|
||||
#include <list.h>
|
||||
|
||||
#define VR_NONE 0x0
|
||||
#define VR_STACK 0x1
|
||||
#define VR_RESERVED 0x2
|
||||
#define VR_IO_NOCACHE 0x100
|
||||
@@ -40,6 +41,7 @@ struct vm_regions {
|
||||
unsigned long brk_start, brk_end;
|
||||
unsigned long map_start, map_end;
|
||||
unsigned long stack_start, stack_end;
|
||||
unsigned long user_start, user_end;
|
||||
};
|
||||
|
||||
struct process_vm;
|
||||
@@ -49,6 +51,7 @@ struct process {
|
||||
int status;
|
||||
int cpu_id;
|
||||
|
||||
ihk_atomic_t refcount;
|
||||
struct process_vm *vm;
|
||||
|
||||
ihk_mc_kernel_context_t ctx;
|
||||
@@ -72,6 +75,7 @@ struct process_vm {
|
||||
struct page_table *page_table;
|
||||
struct list_head vm_range_list;
|
||||
struct vm_regions region;
|
||||
struct process *owner_process; /* process that reside on the same page */
|
||||
|
||||
ihk_spinlock_t page_table_lock;
|
||||
ihk_spinlock_t memory_range_lock;
|
||||
@@ -87,18 +91,23 @@ struct process *create_process(unsigned long user_pc);
|
||||
struct process *clone_process(struct process *org,
|
||||
unsigned long pc, unsigned long sp);
|
||||
void destroy_process(struct process *proc);
|
||||
void hold_process(struct process *proc);
|
||||
void free_process(struct process *proc);
|
||||
void free_process_memory(struct process *proc);
|
||||
|
||||
int add_process_memory_range(struct process *process,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long phys, unsigned long flag);
|
||||
#if 0
|
||||
int add_process_large_range(struct process *process,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long flag, unsigned long *phys);
|
||||
unsigned long flag, unsigned long *phys,
|
||||
enum ihk_mc_ap_flag ap_flag);
|
||||
#endif
|
||||
int remove_process_region(struct process *proc,
|
||||
unsigned long start, unsigned long end);
|
||||
struct program_load_desc;
|
||||
void init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
int init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
int argc, char **argv,
|
||||
int envc, char **env);
|
||||
unsigned long extend_process_region(struct process *proc,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#define SCD_MSG_PREPARE_PROCESS 0x1
|
||||
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
||||
#define SCD_MSG_PREPARE_PROCESS_NACKED 0x7
|
||||
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
||||
|
||||
#define SCD_MSG_INIT_CHANNEL 0x5
|
||||
@@ -88,8 +89,12 @@ struct program_load_desc {
|
||||
int status;
|
||||
int cpu;
|
||||
int pid;
|
||||
int err;
|
||||
unsigned long entry;
|
||||
unsigned long user_start;
|
||||
unsigned long user_end;
|
||||
unsigned long rprocess;
|
||||
unsigned long rpgtable;
|
||||
unsigned long at_phdr;
|
||||
unsigned long at_phent;
|
||||
unsigned long at_phnum;
|
||||
|
||||
@@ -222,8 +222,10 @@ int main(void)
|
||||
|
||||
#ifdef DCFA_KMOD
|
||||
mc_cmd_client_init();
|
||||
#ifdef CMD_DCFA
|
||||
ibmic_cmd_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DCFA_RUN
|
||||
kputs("DCFA begin\n");
|
||||
|
||||
@@ -48,8 +48,12 @@ static int test_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
a = (unsigned long)packet->param1 << 12;
|
||||
|
||||
pp = ihk_mc_map_memory(NULL, a, 4 * 1024 * 1024);
|
||||
v = ihk_mc_map_virtual(pp, 4 * 1024,
|
||||
PTATTR_UNCACHABLE);
|
||||
if((v = ihk_mc_map_virtual(pp, 4 * 1024,
|
||||
PTATTR_UNCACHABLE)) == NULL){
|
||||
ihk_mc_unmap_memory(NULL, pp, 4 * 1024 * 1024);
|
||||
kprintf("Test msg : Not enough space\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
testmem(v, 4 * 1024 * 1024);
|
||||
|
||||
|
||||
29
kernel/mem.c
29
kernel/mem.c
@@ -44,10 +44,14 @@ static void reserve_pages(unsigned long start, unsigned long end, int type)
|
||||
|
||||
void *allocate_pages(int npages, enum ihk_mc_ap_flag flag)
|
||||
{
|
||||
unsigned long pa = ihk_pagealloc_alloc(pa_allocator, npages);
|
||||
/* all_pagealloc_alloc returns zero when error occured,
|
||||
and callee (in mcos/kernel/process.c) so propagate it */
|
||||
return pa ? phys_to_virt(pa) : 0;
|
||||
unsigned long pa = ihk_pagealloc_alloc(pa_allocator, npages);
|
||||
/* all_pagealloc_alloc returns zero when error occured,
|
||||
and callee (in mcos/kernel/process.c) so propagate it */
|
||||
if(pa)
|
||||
return phys_to_virt(pa);
|
||||
if(flag != IHK_MC_AP_NOWAIT)
|
||||
panic("Not enough space\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_pages(void *va, int npages)
|
||||
@@ -194,8 +198,15 @@ void *ihk_mc_map_virtual(unsigned long phys, int npages,
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < npages; i++) {
|
||||
ihk_mc_pt_set_page(NULL, (char *)p + (i << PAGE_SHIFT),
|
||||
phys + (i << PAGE_SHIFT), attr);
|
||||
if(ihk_mc_pt_set_page(NULL, (char *)p + (i << PAGE_SHIFT),
|
||||
phys + (i << PAGE_SHIFT), attr) != 0){
|
||||
int j;
|
||||
for(j = 0; j < i; j++){
|
||||
ihk_mc_pt_clear_page(NULL, (char *)p + (j << PAGE_SHIFT));
|
||||
}
|
||||
ihk_pagealloc_free(vmap_allocator, virt_to_phys(p), npages);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (char *)p + offset;
|
||||
}
|
||||
@@ -305,10 +316,12 @@ void *kmalloc(int size, enum ihk_mc_ap_flag flag)
|
||||
|
||||
while (1) {
|
||||
if (h == &v->free_list) {
|
||||
req_page = ((u + 1) * sizeof(*h) + PAGE_SIZE - 1)
|
||||
req_page = ((u + 2) * sizeof(*h) + PAGE_SIZE - 1)
|
||||
>> PAGE_SHIFT;
|
||||
|
||||
h = allocate_pages(req_page, 0);
|
||||
h = allocate_pages(req_page, flag);
|
||||
if(h == NULL)
|
||||
return NULL;
|
||||
prev->next = h;
|
||||
h->size = (req_page * PAGE_SIZE) / sizeof(*h) - 2;
|
||||
/* Guard entry */
|
||||
|
||||
@@ -12,7 +12,8 @@ static int arch_master_channel_packet_handler(struct ihk_ikc_channel_desc *,
|
||||
void ikc_master_init(void)
|
||||
{
|
||||
mchannel = kmalloc(sizeof(struct ihk_ikc_channel_desc) +
|
||||
sizeof(struct ihk_ikc_master_packet), 0);
|
||||
sizeof(struct ihk_ikc_master_packet),
|
||||
IHK_MC_AP_CRITICAL);
|
||||
|
||||
ihk_mc_ikc_init_first(mchannel, arch_master_channel_packet_handler);
|
||||
}
|
||||
|
||||
237
kernel/process.c
237
kernel/process.c
@@ -23,25 +23,36 @@
|
||||
|
||||
extern long do_arch_prctl(unsigned long code, unsigned long address);
|
||||
|
||||
void init_process_vm(struct process_vm *vm)
|
||||
static int init_process_vm(struct process *owner, struct process_vm *vm)
|
||||
{
|
||||
int i;
|
||||
void *pt = ihk_mc_pt_create(IHK_MC_AP_NOWAIT);
|
||||
|
||||
if(pt == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ihk_mc_spinlock_init(&vm->memory_range_lock);
|
||||
ihk_mc_spinlock_init(&vm->page_table_lock);
|
||||
|
||||
ihk_atomic_set(&vm->refcount, 1);
|
||||
INIT_LIST_HEAD(&vm->vm_range_list);
|
||||
vm->page_table = ihk_mc_pt_create();
|
||||
vm->page_table = pt;
|
||||
hold_process(owner);
|
||||
vm->owner_process = owner;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct process *create_process(unsigned long user_pc)
|
||||
{
|
||||
struct process *proc;
|
||||
|
||||
proc = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES, 0);
|
||||
proc = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES, IHK_MC_AP_NOWAIT);
|
||||
if (!proc)
|
||||
return NULL;
|
||||
|
||||
memset(proc, 0, sizeof(struct process));
|
||||
ihk_atomic_set(&proc->refcount, 2); /* one for exit, another for wait */
|
||||
|
||||
ihk_mc_init_user_process(&proc->ctx, &proc->uctx,
|
||||
((char *)proc) +
|
||||
@@ -49,7 +60,10 @@ struct process *create_process(unsigned long user_pc)
|
||||
|
||||
proc->vm = (struct process_vm *)(proc + 1);
|
||||
|
||||
init_process_vm(proc->vm);
|
||||
if(init_process_vm(proc, proc->vm) != 0){
|
||||
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_init(&proc->spin_sleep_lock);
|
||||
proc->spin_sleep = 0;
|
||||
@@ -62,9 +76,12 @@ struct process *clone_process(struct process *org, unsigned long pc,
|
||||
{
|
||||
struct process *proc;
|
||||
|
||||
proc = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES, 0);
|
||||
if((proc = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES, IHK_MC_AP_NOWAIT)) == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(proc, 0, KERNEL_STACK_NR_PAGES);
|
||||
memset(proc, 0, sizeof(struct process));
|
||||
ihk_atomic_set(&proc->refcount, 2); /* one for exit, another for wait */
|
||||
|
||||
/* NOTE: sp is the user mode stack! */
|
||||
ihk_mc_init_user_process(&proc->ctx, &proc->uctx,
|
||||
@@ -78,18 +95,21 @@ struct process *clone_process(struct process *org, unsigned long pc,
|
||||
ihk_atomic_inc(&org->vm->refcount);
|
||||
proc->vm = org->vm;
|
||||
|
||||
ihk_mc_spinlock_init(&proc->spin_sleep_lock);
|
||||
proc->spin_sleep = 0;
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
extern void __host_update_process_range(struct process *process,
|
||||
struct vm_range *range);
|
||||
|
||||
void update_process_page_table(struct process *process, struct vm_range *range,
|
||||
enum ihk_mc_pt_attribute flag)
|
||||
static int update_process_page_table(struct process *process,
|
||||
struct vm_range *range, enum ihk_mc_pt_attribute flag)
|
||||
{
|
||||
unsigned long p, pa = range->phys;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&process->vm->page_table_lock);
|
||||
unsigned long pp;
|
||||
unsigned long flags = ihk_mc_spinlock_lock(&process->vm->page_table_lock);
|
||||
p = range->start;
|
||||
while (p < range->end) {
|
||||
#ifdef USE_LARGE_PAGES
|
||||
@@ -101,8 +121,7 @@ void update_process_page_table(struct process *process, struct vm_range *range,
|
||||
|
||||
if (ihk_mc_pt_set_large_page(process->vm->page_table, (void *)p,
|
||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0) {
|
||||
kprintf("ERROR:setting large page for 0x%lX -> 0x%lX\n", p, pa);
|
||||
panic("");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dkprintf("large page set for 0x%lX -> 0x%lX\n", p, pa);
|
||||
@@ -112,8 +131,10 @@ void update_process_page_table(struct process *process, struct vm_range *range,
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
ihk_mc_pt_set_page(process->vm->page_table, (void *)p,
|
||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag);
|
||||
if(ihk_mc_pt_set_page(process->vm->page_table, (void *)p,
|
||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0){
|
||||
goto err;
|
||||
}
|
||||
|
||||
pa += PAGE_SIZE;
|
||||
p += PAGE_SIZE;
|
||||
@@ -121,9 +142,36 @@ void update_process_page_table(struct process *process, struct vm_range *range,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&process->vm->page_table_lock);
|
||||
ihk_mc_spinlock_unlock(&process->vm->page_table_lock, flags);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pp = range->start;
|
||||
pa = range->phys;
|
||||
while(pp < p){
|
||||
#ifdef USE_LARGE_PAGES
|
||||
if ((p & (LARGE_PAGE_SIZE - 1)) == 0 &&
|
||||
(pa & (LARGE_PAGE_SIZE - 1)) == 0 &&
|
||||
(range->end - p) >= LARGE_PAGE_SIZE) {
|
||||
ihk_mc_pt_clear_large_page(process->vm->page_table, (void *)pp);
|
||||
pa += LARGE_PAGE_SIZE;
|
||||
pp += LARGE_PAGE_SIZE;
|
||||
}
|
||||
else{
|
||||
#endif
|
||||
ihk_mc_pt_clear_page(process->vm->page_table, (void *)pp);
|
||||
pa += PAGE_SIZE;
|
||||
pp += PAGE_SIZE;
|
||||
#ifdef USE_LARGE_PAGES
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock(&process->vm->page_table_lock, flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int add_process_large_range(struct process *process,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long flag, unsigned long *phys)
|
||||
@@ -133,7 +181,15 @@ int add_process_large_range(struct process *process,
|
||||
int npages_allocated = 0;
|
||||
void *virt;
|
||||
|
||||
range = kmalloc(sizeof(struct vm_range), 0);
|
||||
if ((start < process->vm->region.user_start)
|
||||
|| (process->vm->region.user_end < end)) {
|
||||
kprintf("large range(%#lx - %#lx) is not in user avail(%#lx - %#lx)\n",
|
||||
start, end, process->vm->region.user_start,
|
||||
process->vm->region.user_end);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
range = kmalloc(sizeof(struct vm_range), ap_flag);
|
||||
if (!range) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -149,7 +205,7 @@ int add_process_large_range(struct process *process,
|
||||
npages_allocated += 64) {
|
||||
struct vm_range sub_range;
|
||||
|
||||
virt = ihk_mc_alloc_pages(64, 0);
|
||||
virt = ihk_mc_alloc_pages(64, IHK_MC_AP_NOWAIT);
|
||||
if (!virt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -179,15 +235,24 @@ int add_process_large_range(struct process *process,
|
||||
list_add_tail(&range->list, &process->vm->vm_range_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int add_process_memory_range(struct process *process,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long phys, unsigned long flag)
|
||||
{
|
||||
struct vm_range *range;
|
||||
int rc;
|
||||
|
||||
range = kmalloc(sizeof(struct vm_range), 0);
|
||||
if ((start < process->vm->region.user_start)
|
||||
|| (process->vm->region.user_end < end)) {
|
||||
kprintf("range(%#lx - %#lx) is not in user avail(%#lx - %#lx)\n",
|
||||
start, end, process->vm->region.user_start,
|
||||
process->vm->region.user_end);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
range = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
||||
if (!range) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -202,11 +267,15 @@ int add_process_memory_range(struct process *process,
|
||||
range->end - range->start, range->end - range->start);
|
||||
|
||||
if (flag & VR_REMOTE) {
|
||||
update_process_page_table(process, range, IHK_PTA_REMOTE);
|
||||
rc = update_process_page_table(process, range, IHK_PTA_REMOTE);
|
||||
} else if (flag & VR_IO_NOCACHE) {
|
||||
update_process_page_table(process, range, PTATTR_UNCACHABLE);
|
||||
rc = update_process_page_table(process, range, PTATTR_UNCACHABLE);
|
||||
} else {
|
||||
update_process_page_table(process, range, 0);
|
||||
rc = update_process_page_table(process, range, 0);
|
||||
}
|
||||
if(rc != 0){
|
||||
kfree(range);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if 0 // disable __host_update_process_range() in add_process_memory_range(), because it has no effect on the actual mapping on the MICs side.
|
||||
@@ -226,22 +295,28 @@ int add_process_memory_range(struct process *process,
|
||||
|
||||
|
||||
|
||||
void init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
int init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
int argc, char **argv,
|
||||
int envc, char **env)
|
||||
{
|
||||
int s_ind = 0;
|
||||
int arg_ind;
|
||||
char *stack = ihk_mc_alloc_pages(USER_STACK_NR_PAGES, 0);
|
||||
unsigned long *p = (unsigned long *)(stack +
|
||||
(USER_STACK_NR_PAGES * PAGE_SIZE));
|
||||
unsigned long size = USER_STACK_NR_PAGES * PAGE_SIZE;
|
||||
char *stack = ihk_mc_alloc_pages(USER_STACK_NR_PAGES, IHK_MC_AP_NOWAIT);
|
||||
unsigned long *p = (unsigned long *)(stack + size);
|
||||
unsigned long end = process->vm->region.user_end;
|
||||
unsigned long start = end - size;
|
||||
int rc;
|
||||
|
||||
memset(stack, 0, USER_STACK_NR_PAGES * PAGE_SIZE);
|
||||
if(stack == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
add_process_memory_range(process, USER_END -
|
||||
(USER_STACK_NR_PAGES * PAGE_SIZE),
|
||||
USER_END,
|
||||
virt_to_phys(stack), VR_STACK);
|
||||
memset(stack, 0, size);
|
||||
|
||||
if((rc = add_process_memory_range(process, start, end, virt_to_phys(stack), VR_STACK)) != 0){
|
||||
ihk_mc_free_pages(stack, USER_STACK_NR_PAGES);
|
||||
return rc;
|
||||
}
|
||||
|
||||
s_ind = -1;
|
||||
p[s_ind--] = 0; /* AT_NULL */
|
||||
@@ -267,10 +342,10 @@ void init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
p[s_ind] = argc;
|
||||
|
||||
ihk_mc_modify_user_context(process->uctx, IHK_UCR_STACK_POINTER,
|
||||
USER_END + sizeof(unsigned long) * s_ind);
|
||||
process->vm->region.stack_end = USER_END;
|
||||
process->vm->region.stack_start = USER_END -
|
||||
(USER_STACK_NR_PAGES * PAGE_SIZE);
|
||||
end + sizeof(unsigned long) * s_ind);
|
||||
process->vm->region.stack_end = end;
|
||||
process->vm->region.stack_start = start;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -280,6 +355,7 @@ unsigned long extend_process_region(struct process *proc,
|
||||
{
|
||||
unsigned long aligned_end, aligned_new_end;
|
||||
void *p;
|
||||
int rc;
|
||||
|
||||
if (!address || address < start || address >= USER_END) {
|
||||
return end;
|
||||
@@ -303,9 +379,15 @@ unsigned long extend_process_region(struct process *proc,
|
||||
aligned_end = (aligned_end + (LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
||||
/* Fill in the gap between old_aligned_end and aligned_end
|
||||
* with regular pages */
|
||||
p = allocate_pages((aligned_end - old_aligned_end) >> PAGE_SHIFT, 0);
|
||||
add_process_memory_range(proc, old_aligned_end, aligned_end,
|
||||
virt_to_phys(p), 0);
|
||||
if((p = allocate_pages((aligned_end - old_aligned_end) >> PAGE_SHIFT,
|
||||
IHK_MC_AP_NOWAIT)) == NULL){
|
||||
return end;
|
||||
}
|
||||
if((rc = add_process_memory_range(proc, old_aligned_end,
|
||||
aligned_end, virt_to_phys(p), VR_NONE)) != 0){
|
||||
free_pages(p, (aligned_end - old_aligned_end) >> PAGE_SHIFT);
|
||||
return end;
|
||||
}
|
||||
|
||||
dkprintf("filled in gap for LARGE_PAGE_SIZE aligned start: 0x%lX -> 0x%lX\n",
|
||||
old_aligned_end, aligned_end);
|
||||
@@ -316,17 +398,26 @@ unsigned long extend_process_region(struct process *proc,
|
||||
(LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
||||
address = aligned_new_end;
|
||||
|
||||
p = allocate_pages((aligned_new_end - aligned_end + LARGE_PAGE_SIZE)
|
||||
>> PAGE_SHIFT, 0);
|
||||
if((p = allocate_pages((aligned_new_end - aligned_end + LARGE_PAGE_SIZE) >> PAGE_SHIFT,
|
||||
IHK_MC_AP_NOWAIT)) == NULL){
|
||||
return end;
|
||||
}
|
||||
|
||||
p_aligned = ((unsigned long)p + (LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
||||
|
||||
if (p_aligned > (unsigned long)p) {
|
||||
free_pages(p, (p_aligned - (unsigned long)p) >> PAGE_SHIFT);
|
||||
}
|
||||
free_pages(
|
||||
(void *)(p_aligned + aligned_new_end - aligned_end),
|
||||
(LARGE_PAGE_SIZE - (p_aligned - (unsigned long)p)) >> PAGE_SHIFT);
|
||||
|
||||
add_process_memory_range(proc, aligned_end, aligned_new_end,
|
||||
virt_to_phys((void *)p_aligned), flag);
|
||||
if((rc = add_process_memory_range(proc, aligned_end,
|
||||
aligned_new_end, virt_to_phys((void *)p_aligned),
|
||||
flag)) != 0){
|
||||
free_pages(p, (aligned_new_end - aligned_end + LARGE_PAGE_SIZE) >> PAGE_SHIFT);
|
||||
return end;
|
||||
}
|
||||
|
||||
dkprintf("largePTE area: 0x%lX - 0x%lX (s: %lu) -> 0x%lX - \n",
|
||||
aligned_end, aligned_new_end,
|
||||
@@ -337,14 +428,17 @@ unsigned long extend_process_region(struct process *proc,
|
||||
}
|
||||
#endif
|
||||
|
||||
p = allocate_pages((aligned_new_end - aligned_end) >> PAGE_SHIFT, 0);
|
||||
p = allocate_pages((aligned_new_end - aligned_end) >> PAGE_SHIFT, IHK_MC_AP_NOWAIT);
|
||||
|
||||
if (!p) {
|
||||
return end;
|
||||
}
|
||||
|
||||
add_process_memory_range(proc, aligned_end, aligned_new_end,
|
||||
virt_to_phys(p), flag);
|
||||
if((rc = add_process_memory_range(proc, aligned_end, aligned_new_end,
|
||||
virt_to_phys(p), flag)) != 0){
|
||||
free_pages(p, (aligned_new_end - aligned_end) >> PAGE_SHIFT);
|
||||
return end;
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
@@ -372,12 +466,18 @@ extern void print_free_list(void);
|
||||
void free_process_memory(struct process *proc)
|
||||
{
|
||||
struct vm_range *range, *next;
|
||||
struct process_vm *vm = proc->vm;
|
||||
|
||||
if (!ihk_atomic_dec_and_test(&proc->vm->refcount)) {
|
||||
if (vm == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(range, next, &proc->vm->vm_range_list,
|
||||
proc->vm = NULL;
|
||||
if (!ihk_atomic_dec_and_test(&vm->refcount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(range, next, &vm->vm_range_list,
|
||||
list) {
|
||||
if (!(range->flag & VR_REMOTE) &&
|
||||
!(range->flag & VR_IO_NOCACHE) &&
|
||||
@@ -389,13 +489,33 @@ void free_process_memory(struct process *proc)
|
||||
list_del(&range->list);
|
||||
ihk_mc_free(range);
|
||||
}
|
||||
/* TODO: Free page tables */
|
||||
proc->status = PS_ZOMBIE;
|
||||
|
||||
ihk_mc_pt_destroy(vm->page_table);
|
||||
free_process(vm->owner_process);
|
||||
}
|
||||
|
||||
void hold_process(struct process *proc)
|
||||
{
|
||||
if (proc->status & (PS_ZOMBIE | PS_EXITED)) {
|
||||
panic("hold_process: already exited process");
|
||||
}
|
||||
|
||||
ihk_atomic_inc(&proc->refcount);
|
||||
return;
|
||||
}
|
||||
|
||||
void destroy_process(struct process *proc)
|
||||
{
|
||||
ihk_mc_free_pages(proc, 1);
|
||||
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
||||
}
|
||||
|
||||
void free_process(struct process *proc)
|
||||
{
|
||||
if (!ihk_atomic_dec_and_test(&proc->refcount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
destroy_process(proc);
|
||||
}
|
||||
|
||||
static void idle(void)
|
||||
@@ -443,6 +563,7 @@ void schedule(void)
|
||||
struct process *next, *prev, *proc, *tmp = NULL;
|
||||
int switch_ctx = 0;
|
||||
unsigned long irqstate;
|
||||
struct process *last;
|
||||
|
||||
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
||||
|
||||
@@ -455,10 +576,14 @@ void schedule(void)
|
||||
--v->runq_len;
|
||||
|
||||
/* Round-robin if not exited yet */
|
||||
if (prev->status != PS_EXITED) {
|
||||
if (!(prev->status & (PS_ZOMBIE | PS_EXITED))) {
|
||||
list_add_tail(&prev->sched_list, &(v->runq));
|
||||
++v->runq_len;
|
||||
}
|
||||
|
||||
if (!v->runq_len) {
|
||||
v->status = CPU_STATUS_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pick a new running process */
|
||||
@@ -479,7 +604,6 @@ void schedule(void)
|
||||
v->current = next;
|
||||
}
|
||||
|
||||
|
||||
if (switch_ctx) {
|
||||
dkprintf("[%d] schedule: %d => %d \n",
|
||||
ihk_mc_get_processor_id(),
|
||||
@@ -496,10 +620,15 @@ void schedule(void)
|
||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
||||
|
||||
if (prev) {
|
||||
ihk_mc_switch_context(&prev->ctx, &next->ctx);
|
||||
last = ihk_mc_switch_context(&prev->ctx, &next->ctx, prev);
|
||||
}
|
||||
else {
|
||||
ihk_mc_switch_context(NULL, &next->ctx);
|
||||
last = ihk_mc_switch_context(NULL, &next->ctx, prev);
|
||||
}
|
||||
|
||||
if ((last != NULL) && (last->status & (PS_ZOMBIE | PS_EXITED))) {
|
||||
free_process_memory(last);
|
||||
free_process(last);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -349,18 +349,24 @@ SYSCALL_DECLARE(lseek)
|
||||
SYSCALL_DECLARE(exit_group)
|
||||
{
|
||||
SYSCALL_HEADER;
|
||||
struct process *proc = cpu_local_var(current);
|
||||
|
||||
#ifdef DCFA_KMOD
|
||||
do_mod_exit((int)ihk_mc_syscall_arg0(ctx));
|
||||
#endif
|
||||
|
||||
do_syscall(&request, ctx);
|
||||
runq_del_proc(cpu_local_var(current), ihk_mc_get_processor_id());
|
||||
free_process_memory(cpu_local_var(current));
|
||||
/* XXX: send SIGKILL to all threads in this process */
|
||||
|
||||
do_syscall(&request, ctx);
|
||||
|
||||
#define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */
|
||||
proc->status = PS_ZOMBIE;
|
||||
if (IS_DETACHED_PROCESS(proc)) {
|
||||
/* release a reference for wait(2) */
|
||||
proc->status = PS_EXITED;
|
||||
free_process(proc);
|
||||
}
|
||||
|
||||
//cpu_local_var(next) = &cpu_local_var(idle);
|
||||
|
||||
cpu_local_var(current) = NULL;
|
||||
schedule();
|
||||
|
||||
return 0;
|
||||
@@ -371,6 +377,7 @@ SYSCALL_DECLARE(mmap)
|
||||
{
|
||||
struct vm_regions *region = &cpu_local_var(current)->vm->region;
|
||||
unsigned long lockr;
|
||||
void *va;
|
||||
|
||||
dkprintf("syscall.c,mmap,addr=%lx,len=%lx,prot=%lx,flags=%x,fd=%x,offset=%lx\n",
|
||||
ihk_mc_syscall_arg0(ctx), ihk_mc_syscall_arg1(ctx),
|
||||
@@ -415,15 +422,20 @@ SYSCALL_DECLARE(mmap)
|
||||
}
|
||||
|
||||
e = (e + (LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
||||
p = (unsigned long)ihk_mc_alloc_pages(
|
||||
(e - s + 2 * LARGE_PAGE_SIZE) >> PAGE_SHIFT, 0);
|
||||
if((p = (unsigned long)ihk_mc_alloc_pages(
|
||||
(e - s + 2 * LARGE_PAGE_SIZE) >> PAGE_SHIFT, IHK_MC_AP_NOWAIT)) == NULL){
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p_aligned = (p + LARGE_PAGE_SIZE + (LARGE_PAGE_SIZE - 1))
|
||||
& LARGE_PAGE_MASK;
|
||||
|
||||
// add range, mapping
|
||||
add_process_memory_range(cpu_local_var(current), s_orig, e,
|
||||
virt_to_phys((void *)(p_aligned - head_space)), 0);
|
||||
if(add_process_memory_range(cpu_local_var(current), s_orig, e,
|
||||
virt_to_phys((void *)(p_aligned - head_space)), VR_NONE) != 0){
|
||||
ihk_mc_free_pages(p, range_npages);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dkprintf("largePTE area: 0x%lX - 0x%lX (s: %lu) -> 0x%lX -\n",
|
||||
s_orig, e, (e - s_orig),
|
||||
@@ -432,10 +444,16 @@ SYSCALL_DECLARE(mmap)
|
||||
else {
|
||||
#endif
|
||||
// allocate physical address
|
||||
pa = virt_to_phys(ihk_mc_alloc_pages(range_npages, 0));
|
||||
if((va = ihk_mc_alloc_pages(range_npages, IHK_MC_AP_NOWAIT)) == NULL){
|
||||
return -ENOMEM;
|
||||
}
|
||||
pa = virt_to_phys(va);
|
||||
|
||||
// add page_table, add memory-range
|
||||
add_process_memory_range(cpu_local_var(current), s, e, pa, 0);
|
||||
if(add_process_memory_range(cpu_local_var(current), s, e, pa, VR_NONE) != 0){
|
||||
ihk_mc_free_pages(va, range_npages);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dkprintf("syscall.c,pa allocated=%lx\n", pa);
|
||||
#ifdef USE_LARGE_PAGES
|
||||
@@ -536,7 +554,7 @@ SYSCALL_DECLARE(mmap)
|
||||
dkprintf("syscall.c,!MAP_FIXED,!MAP_ANONYMOUS,MAP_PRIVATE\n");
|
||||
// lseek(mmap_fd, mmap_off, SEEK_SET);
|
||||
// read(mmap_fd, mmap_addr, mmap_len);
|
||||
SYSCALL_ARGS_6(MO, D, D, D, D, D);
|
||||
SYSCALL_ARGS_6(D, D, D, D, D, D);
|
||||
// overwriting request.args[0]
|
||||
unsigned long __phys;
|
||||
if (ihk_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, (void *)s, &__phys)) {
|
||||
@@ -925,26 +943,34 @@ SYSCALL_DECLARE(futex)
|
||||
|
||||
SYSCALL_DECLARE(exit)
|
||||
{
|
||||
struct process *proc = cpu_local_var(current);
|
||||
|
||||
#ifdef DCFA_KMOD
|
||||
do_mod_exit((int)ihk_mc_syscall_arg0(ctx));
|
||||
#endif
|
||||
|
||||
/* XXX: for if all threads issued the exit(2) rather than exit_group(2),
|
||||
* exit(2) also should delegate.
|
||||
*/
|
||||
/* If there is a clear_child_tid address set, clear it and wake it.
|
||||
* This unblocks any pthread_join() waiters. */
|
||||
if (cpu_local_var(current)->thread.clear_child_tid) {
|
||||
if (proc->thread.clear_child_tid) {
|
||||
|
||||
dkprintf("exit clear_child!\n");
|
||||
|
||||
*cpu_local_var(current)->thread.clear_child_tid = 0;
|
||||
*proc->thread.clear_child_tid = 0;
|
||||
barrier();
|
||||
futex((uint32_t *)cpu_local_var(current)->thread.clear_child_tid,
|
||||
futex((uint32_t *)proc->thread.clear_child_tid,
|
||||
FUTEX_WAKE, 1, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
runq_del_proc(cpu_local_var(current), cpu_local_var(current)->cpu_id);
|
||||
free_process_memory(cpu_local_var(current));
|
||||
proc->status = PS_ZOMBIE;
|
||||
if (IS_DETACHED_PROCESS(proc)) {
|
||||
/* release a reference for wait(2) */
|
||||
proc->status = PS_EXITED;
|
||||
free_process(proc);
|
||||
}
|
||||
|
||||
cpu_local_var(current) = NULL;
|
||||
schedule();
|
||||
|
||||
return 0;
|
||||
@@ -1018,7 +1044,7 @@ SYSCALL_DECLARE(sched_getaffinity)
|
||||
|
||||
CPU_ZERO_S(min_len, mask);
|
||||
for (cpu_id = 0; cpu_id < min_ncpus; ++cpu_id)
|
||||
CPU_SET_S(min_len, cpu_id, mask);
|
||||
CPU_SET_S(cpu_info->hw_ids[cpu_id], min_len, mask);
|
||||
|
||||
// dkprintf("sched_getaffinity returns full mask\n");
|
||||
|
||||
@@ -1033,18 +1059,31 @@ SYSCALL_DECLARE(noop)
|
||||
|
||||
#ifdef DCFA_KMOD
|
||||
|
||||
#ifdef CMD_DCFA
|
||||
extern int ibmic_cmd_syscall(char *uargs);
|
||||
extern int dcfampi_cmd_syscall(char *uargs);
|
||||
extern void ibmic_cmd_exit(int status);
|
||||
#endif
|
||||
|
||||
#ifdef CMD_DCFAMPI
|
||||
extern int dcfampi_cmd_syscall(char *uargs);
|
||||
#endif
|
||||
|
||||
static int (*mod_call_table[]) (char *) = {
|
||||
#ifdef CMD_DCFA
|
||||
[1] = ibmic_cmd_syscall,
|
||||
#endif
|
||||
#ifdef CMD_DCFAMPI
|
||||
[2] = dcfampi_cmd_syscall,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void (*mod_exit_table[]) (int) = {
|
||||
#ifdef CMD_DCFA
|
||||
[1] = ibmic_cmd_exit,
|
||||
#endif
|
||||
#ifdef CMD_DCFAMPI
|
||||
[2] = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
SYSCALL_DECLARE(mod_call) {
|
||||
@@ -1059,6 +1098,8 @@ SYSCALL_DECLARE(mod_call) {
|
||||
if(mod_call_table[mod_id])
|
||||
return mod_call_table[mod_id]((char*)uargs);
|
||||
|
||||
kprintf("ERROR! undefined mod_call id:%d\n", mod_id);
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
@@ -1239,6 +1280,14 @@ static int clone_init(void)
|
||||
|
||||
#endif
|
||||
|
||||
long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx)
|
||||
{
|
||||
SYSCALL_HEADER;
|
||||
dkprintf("syscall_generic_forwarding(%d)\n", n);
|
||||
SYSCALL_ARGS_6(D,D,D,D,D,D);
|
||||
SYSCALL_FOOTER;
|
||||
}
|
||||
|
||||
long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
{
|
||||
long l;
|
||||
@@ -1272,7 +1321,8 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
dkprintf("\n");
|
||||
|
||||
|
||||
if (syscall_table[num]) {
|
||||
if ((0 <= num) && (num < sizeof(syscall_table)/sizeof(syscall_table[0]))
|
||||
&& (syscall_table[num] != NULL)) {
|
||||
l = syscall_table[num](num, ctx);
|
||||
|
||||
dkprintf("SC(%d)[%3d] ret: %d\n",
|
||||
@@ -1283,8 +1333,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
ihk_mc_syscall_arg2(ctx), ihk_mc_syscall_arg3(ctx),
|
||||
ihk_mc_syscall_arg4(ctx), ihk_mc_syscall_pc(ctx),
|
||||
ihk_mc_syscall_sp(ctx));
|
||||
//while(1);
|
||||
l = -ENOSYS;
|
||||
l = syscall_generic_forwarding(num, ctx);
|
||||
}
|
||||
|
||||
return l;
|
||||
|
||||
Reference in New Issue
Block a user