resolved merge conflicts with futex code
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
TARGET = @TARGET@
|
TARGET = @TARGET@
|
||||||
|
SBINDIR = @SBINDIR@
|
||||||
|
|
||||||
all::
|
all::
|
||||||
@(cd executer/kernel; make modules)
|
@(cd executer/kernel; make modules)
|
||||||
@ -25,6 +26,10 @@ install::
|
|||||||
exit 1 \
|
exit 1 \
|
||||||
;; \
|
;; \
|
||||||
esac
|
esac
|
||||||
|
if [ "$(TARGET)" = attached-mic ]; then \
|
||||||
|
mkdir -p -m 755 $(SBINDIR); \
|
||||||
|
install -m 755 boot-attached-mic.sh $(SBINDIR)/boot.sh; \
|
||||||
|
fi
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
@(cd executer/kernel; make clean)
|
@(cd executer/kernel; make clean)
|
||||||
|
|||||||
@ -4,8 +4,14 @@
|
|||||||
(X86_CPU_LOCAL_OFFSET_TSS + X86_TSS_OFFSET_SP0)
|
(X86_CPU_LOCAL_OFFSET_TSS + X86_TSS_OFFSET_SP0)
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
.globl ihk_mc_switch_context
|
.globl ihk_mc_switch_context
|
||||||
ihk_mc_switch_context:
|
ihk_mc_switch_context:
|
||||||
|
/*
|
||||||
|
* rdi - ihk_mc_kernel_context_t *old_ctx
|
||||||
|
* rsi - ihk_mc_kernel_context_t *new_ctx
|
||||||
|
* rdx - void *prev
|
||||||
|
*/
|
||||||
pushfq
|
pushfq
|
||||||
popq %rax
|
popq %rax
|
||||||
testq %rdi, %rdi
|
testq %rdi, %rdi
|
||||||
@ -35,4 +41,5 @@ ihk_mc_switch_context:
|
|||||||
popfq
|
popfq
|
||||||
movq 8(%rsi), %rbp
|
movq 8(%rsi), %rbp
|
||||||
movq 24(%rsi), %rsi
|
movq 24(%rsi), %rsi
|
||||||
|
movq %rdx,%rax
|
||||||
retq
|
retq
|
||||||
|
|||||||
@ -44,7 +44,7 @@ void *get_x86_this_cpu_kstack(void);
|
|||||||
void init_processors_local(int max_id);
|
void init_processors_local(int max_id);
|
||||||
void assign_processor_id(void);
|
void assign_processor_id(void);
|
||||||
void arch_delay(int);
|
void arch_delay(int);
|
||||||
void x86_set_warm_reset(void);
|
void x86_set_warm_reset(unsigned long ip, char *first_page_va);
|
||||||
void x86_init_perfctr(void);
|
void x86_init_perfctr(void);
|
||||||
|
|
||||||
extern int kprintf(const char *format, ...);
|
extern int kprintf(const char *format, ...);
|
||||||
@ -393,12 +393,7 @@ static void outb(uint8_t v, uint16_t port)
|
|||||||
|
|
||||||
static void set_warm_reset_vector(unsigned long ip)
|
static void set_warm_reset_vector(unsigned long ip)
|
||||||
{
|
{
|
||||||
/* Write CMOS */
|
x86_set_warm_reset(ip, first_page_va);
|
||||||
x86_set_warm_reset();
|
|
||||||
|
|
||||||
/* Set vector */
|
|
||||||
*(unsigned short *)(first_page_va + 0x469) = (ip >> 4);
|
|
||||||
*(unsigned short *)(first_page_va + 0x467) = ip & 0xf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wait_icr_idle(void)
|
static void wait_icr_idle(void)
|
||||||
|
|||||||
@ -42,6 +42,12 @@
|
|||||||
|
|
||||||
#define PT_ENTRIES 512
|
#define PT_ENTRIES 512
|
||||||
|
|
||||||
|
/* mask of the physical address of the entry to the page table */
|
||||||
|
#define PT_PHYSMASK (((1UL << 52) - 1) & PAGE_MASK)
|
||||||
|
|
||||||
|
#define PF_PRESENT 0x01 /* entry is valid */
|
||||||
|
#define PF_SIZE 0x80 /* entry points large page */
|
||||||
|
|
||||||
#define PFL4_PRESENT 0x01
|
#define PFL4_PRESENT 0x01
|
||||||
#define PFL4_WRITABLE 0x02
|
#define PFL4_WRITABLE 0x02
|
||||||
#define PFL4_USER 0x04
|
#define PFL4_USER 0x04
|
||||||
@ -85,6 +91,7 @@ enum ihk_mc_pt_attribute {
|
|||||||
PTATTR_USER = 0x04,
|
PTATTR_USER = 0x04,
|
||||||
PTATTR_LARGEPAGE = 0x80,
|
PTATTR_LARGEPAGE = 0x80,
|
||||||
PTATTR_UNCACHABLE = 0x10000,
|
PTATTR_UNCACHABLE = 0x10000,
|
||||||
|
PTATTR_FOR_USER = 0x20000,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef unsigned long pte_t;
|
typedef unsigned long pte_t;
|
||||||
|
|||||||
@ -11,7 +11,7 @@ struct x86_cpu_local_variables *locals;
|
|||||||
void init_processors_local(int max_id)
|
void init_processors_local(int max_id)
|
||||||
{
|
{
|
||||||
/* Is contiguous allocating adequate?? */
|
/* Is contiguous allocating adequate?? */
|
||||||
locals = ihk_mc_alloc_pages(max_id, 0);
|
locals = ihk_mc_alloc_pages(max_id, IHK_MC_AP_CRITICAL);
|
||||||
memset(locals, 0, PAGE_SIZE * max_id);
|
memset(locals, 0, PAGE_SIZE * max_id);
|
||||||
|
|
||||||
kprintf("locals = %p\n", locals);
|
kprintf("locals = %p\n", locals);
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
static char *last_page;
|
static char *last_page;
|
||||||
extern char _head[], _end[];
|
extern char _head[], _end[];
|
||||||
|
|
||||||
struct ihk_mc_pa_ops *pa_ops;
|
static struct ihk_mc_pa_ops *pa_ops;
|
||||||
|
|
||||||
extern unsigned long x86_kernel_phys_base;
|
extern unsigned long x86_kernel_phys_base;
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ static unsigned long setup_l3(struct page_table *pt,
|
|||||||
pt->entry[i] = 0;
|
pt->entry[i] = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pt_phys = setup_l2(arch_alloc_page(0), phys, start, end);
|
pt_phys = setup_l2(arch_alloc_page(IHK_MC_AP_CRITICAL), phys, start, end);
|
||||||
|
|
||||||
pt->entry[i] = pt_phys | PFL3_KERN_ATTR;
|
pt->entry[i] = pt_phys | PFL3_KERN_ATTR;
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ static void init_normal_area(struct page_table *pt)
|
|||||||
|
|
||||||
for (phys = (map_start & ~(PTL4_SIZE - 1)); phys < map_end;
|
for (phys = (map_start & ~(PTL4_SIZE - 1)); phys < map_end;
|
||||||
phys += PTL4_SIZE) {
|
phys += PTL4_SIZE) {
|
||||||
pt_phys = setup_l3(arch_alloc_page(0), phys,
|
pt_phys = setup_l3(arch_alloc_page(IHK_MC_AP_CRITICAL), phys,
|
||||||
map_start, map_end);
|
map_start, map_end);
|
||||||
|
|
||||||
pt->entry[ident_index++] = pt_phys | PFL4_KERN_ATTR;
|
pt->entry[ident_index++] = pt_phys | PFL4_KERN_ATTR;
|
||||||
@ -165,10 +165,11 @@ static void init_normal_area(struct page_table *pt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct page_table *__alloc_new_pt(void)
|
static struct page_table *__alloc_new_pt(enum ihk_mc_ap_flag ap_flag)
|
||||||
{
|
{
|
||||||
struct page_table *newpt = arch_alloc_page(0);
|
struct page_table *newpt = arch_alloc_page(ap_flag);
|
||||||
|
|
||||||
|
if(newpt)
|
||||||
memset(newpt, 0, sizeof(struct page_table));
|
memset(newpt, 0, sizeof(struct page_table));
|
||||||
|
|
||||||
return newpt;
|
return newpt;
|
||||||
@ -200,7 +201,7 @@ static unsigned long attr_to_l2attr(enum ihk_mc_pt_attribute attr)
|
|||||||
static unsigned long attr_to_l1attr(enum ihk_mc_pt_attribute attr)
|
static unsigned long attr_to_l1attr(enum ihk_mc_pt_attribute attr)
|
||||||
{
|
{
|
||||||
if (attr & PTATTR_UNCACHABLE) {
|
if (attr & PTATTR_UNCACHABLE) {
|
||||||
return (attr & ATTR_MASK) | PFL1_PWT | PFL1_PWT;
|
return (attr & ATTR_MASK) | PFL1_PCD | PFL1_PWT;
|
||||||
} else {
|
} else {
|
||||||
return (attr & ATTR_MASK);
|
return (attr & ATTR_MASK);
|
||||||
}
|
}
|
||||||
@ -224,6 +225,7 @@ void set_pte(pte_t *ppte, unsigned long phys, int attr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* get_pte()
|
* get_pte()
|
||||||
*
|
*
|
||||||
@ -231,7 +233,7 @@ void set_pte(pte_t *ppte, unsigned long phys, int attr)
|
|||||||
* and returns a pointer to the PTE corresponding to the
|
* and returns a pointer to the PTE corresponding to the
|
||||||
* virtual address.
|
* virtual address.
|
||||||
*/
|
*/
|
||||||
pte_t *get_pte(struct page_table *pt, void *virt, int attr)
|
pte_t *get_pte(struct page_table *pt, void *virt, int attr, enum ihk_mc_ap_flag ap_flag)
|
||||||
{
|
{
|
||||||
int l4idx, l3idx, l2idx, l1idx;
|
int l4idx, l3idx, l2idx, l1idx;
|
||||||
unsigned long v = (unsigned long)virt;
|
unsigned long v = (unsigned long)virt;
|
||||||
@ -247,7 +249,8 @@ pte_t *get_pte(struct page_table *pt, void *virt, int attr)
|
|||||||
if (pt->entry[l4idx] & PFL4_PRESENT) {
|
if (pt->entry[l4idx] & PFL4_PRESENT) {
|
||||||
pt = phys_to_virt(pt->entry[l4idx] & PAGE_MASK);
|
pt = phys_to_virt(pt->entry[l4idx] & PAGE_MASK);
|
||||||
} else {
|
} else {
|
||||||
newpt = __alloc_new_pt();
|
if((newpt = __alloc_new_pt(ap_flag)) == NULL)
|
||||||
|
return NULL;
|
||||||
pt->entry[l4idx] = virt_to_phys(newpt) | attr_to_l4attr(attr);
|
pt->entry[l4idx] = virt_to_phys(newpt) | attr_to_l4attr(attr);
|
||||||
pt = newpt;
|
pt = newpt;
|
||||||
}
|
}
|
||||||
@ -255,7 +258,8 @@ pte_t *get_pte(struct page_table *pt, void *virt, int attr)
|
|||||||
if (pt->entry[l3idx] & PFL3_PRESENT) {
|
if (pt->entry[l3idx] & PFL3_PRESENT) {
|
||||||
pt = phys_to_virt(pt->entry[l3idx] & PAGE_MASK);
|
pt = phys_to_virt(pt->entry[l3idx] & PAGE_MASK);
|
||||||
} else {
|
} else {
|
||||||
newpt = __alloc_new_pt();
|
if((newpt = __alloc_new_pt(ap_flag)) == NULL)
|
||||||
|
return NULL;
|
||||||
pt->entry[l3idx] = virt_to_phys(newpt) | attr_to_l3attr(attr);
|
pt->entry[l3idx] = virt_to_phys(newpt) | attr_to_l3attr(attr);
|
||||||
pt = newpt;
|
pt = newpt;
|
||||||
}
|
}
|
||||||
@ -273,7 +277,8 @@ pte_t *get_pte(struct page_table *pt, void *virt, int attr)
|
|||||||
if (pt->entry[l2idx] & PFL2_PRESENT) {
|
if (pt->entry[l2idx] & PFL2_PRESENT) {
|
||||||
pt = phys_to_virt(pt->entry[l2idx] & PAGE_MASK);
|
pt = phys_to_virt(pt->entry[l2idx] & PAGE_MASK);
|
||||||
} else {
|
} else {
|
||||||
newpt = __alloc_new_pt();
|
if((newpt = __alloc_new_pt(ap_flag)) == NULL)
|
||||||
|
return NULL;
|
||||||
pt->entry[l2idx] = virt_to_phys(newpt) | attr_to_l2attr(attr)
|
pt->entry[l2idx] = virt_to_phys(newpt) | attr_to_l2attr(attr)
|
||||||
| PFL2_PRESENT;
|
| PFL2_PRESENT;
|
||||||
pt = newpt;
|
pt = newpt;
|
||||||
@ -281,6 +286,7 @@ pte_t *get_pte(struct page_table *pt, void *virt, int attr)
|
|||||||
|
|
||||||
return &(pt->entry[l1idx]);
|
return &(pt->entry[l1idx]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __set_pt_page(struct page_table *pt, void *virt, unsigned long phys,
|
static int __set_pt_page(struct page_table *pt, void *virt, unsigned long phys,
|
||||||
int attr)
|
int attr)
|
||||||
@ -288,6 +294,10 @@ static int __set_pt_page(struct page_table *pt, void *virt, unsigned long phys,
|
|||||||
int l4idx, l3idx, l2idx, l1idx;
|
int l4idx, l3idx, l2idx, l1idx;
|
||||||
unsigned long v = (unsigned long)virt;
|
unsigned long v = (unsigned long)virt;
|
||||||
struct page_table *newpt;
|
struct page_table *newpt;
|
||||||
|
enum ihk_mc_ap_flag ap_flag;
|
||||||
|
|
||||||
|
ap_flag = (attr & (PTATTR_USER | PTATTR_FOR_USER)) ?
|
||||||
|
IHK_MC_AP_NOWAIT: IHK_MC_AP_CRITICAL;
|
||||||
|
|
||||||
if (!pt) {
|
if (!pt) {
|
||||||
pt = init_pt;
|
pt = init_pt;
|
||||||
@ -304,7 +314,8 @@ static int __set_pt_page(struct page_table *pt, void *virt, unsigned long phys,
|
|||||||
if (pt->entry[l4idx] & PFL4_PRESENT) {
|
if (pt->entry[l4idx] & PFL4_PRESENT) {
|
||||||
pt = phys_to_virt(pt->entry[l4idx] & PAGE_MASK);
|
pt = phys_to_virt(pt->entry[l4idx] & PAGE_MASK);
|
||||||
} else {
|
} else {
|
||||||
newpt = __alloc_new_pt();
|
if((newpt = __alloc_new_pt(ap_flag)) == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
pt->entry[l4idx] = virt_to_phys(newpt) | attr_to_l4attr(attr);
|
pt->entry[l4idx] = virt_to_phys(newpt) | attr_to_l4attr(attr);
|
||||||
pt = newpt;
|
pt = newpt;
|
||||||
}
|
}
|
||||||
@ -312,7 +323,8 @@ static int __set_pt_page(struct page_table *pt, void *virt, unsigned long phys,
|
|||||||
if (pt->entry[l3idx] & PFL3_PRESENT) {
|
if (pt->entry[l3idx] & PFL3_PRESENT) {
|
||||||
pt = phys_to_virt(pt->entry[l3idx] & PAGE_MASK);
|
pt = phys_to_virt(pt->entry[l3idx] & PAGE_MASK);
|
||||||
} else {
|
} else {
|
||||||
newpt = __alloc_new_pt();
|
if((newpt = __alloc_new_pt(ap_flag)) == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
pt->entry[l3idx] = virt_to_phys(newpt) | attr_to_l3attr(attr);
|
pt->entry[l3idx] = virt_to_phys(newpt) | attr_to_l3attr(attr);
|
||||||
pt = newpt;
|
pt = newpt;
|
||||||
}
|
}
|
||||||
@ -334,7 +346,8 @@ static int __set_pt_page(struct page_table *pt, void *virt, unsigned long phys,
|
|||||||
if (pt->entry[l2idx] & PFL2_PRESENT) {
|
if (pt->entry[l2idx] & PFL2_PRESENT) {
|
||||||
pt = phys_to_virt(pt->entry[l2idx] & PAGE_MASK);
|
pt = phys_to_virt(pt->entry[l2idx] & PAGE_MASK);
|
||||||
} else {
|
} else {
|
||||||
newpt = __alloc_new_pt();
|
if((newpt = __alloc_new_pt(ap_flag)) == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
pt->entry[l2idx] = virt_to_phys(newpt) | attr_to_l2attr(attr)
|
pt->entry[l2idx] = virt_to_phys(newpt) | attr_to_l2attr(attr)
|
||||||
| PFL2_PRESENT;
|
| PFL2_PRESENT;
|
||||||
pt = newpt;
|
pt = newpt;
|
||||||
@ -523,7 +536,7 @@ int ihk_mc_pt_prepare_map(page_table_t p, void *virt, unsigned long size,
|
|||||||
if (pt->entry[l4idx] & PFL4_PRESENT) {
|
if (pt->entry[l4idx] & PFL4_PRESENT) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
newpt = __alloc_new_pt();
|
newpt = __alloc_new_pt(IHK_MC_AP_CRITICAL);
|
||||||
if (!newpt) {
|
if (!newpt) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
@ -544,9 +557,12 @@ int ihk_mc_pt_prepare_map(page_table_t p, void *virt, unsigned long size,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct page_table *ihk_mc_pt_create(void)
|
struct page_table *ihk_mc_pt_create(enum ihk_mc_ap_flag ap_flag)
|
||||||
{
|
{
|
||||||
struct page_table *pt = ihk_mc_alloc_pages(1, 0);
|
struct page_table *pt = ihk_mc_alloc_pages(1, ap_flag);
|
||||||
|
|
||||||
|
if(pt == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
memset(pt->entry, 0, PAGE_SIZE);
|
memset(pt->entry, 0, PAGE_SIZE);
|
||||||
/* Copy the kernel space */
|
/* Copy the kernel space */
|
||||||
@ -556,11 +572,60 @@ struct page_table *ihk_mc_pt_create(void)
|
|||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void destroy_page_table(int level, struct page_table *pt)
|
||||||
|
{
|
||||||
|
int ix;
|
||||||
|
unsigned long entry;
|
||||||
|
struct page_table *lower;
|
||||||
|
|
||||||
|
if ((level < 1) || (4 < level)) {
|
||||||
|
panic("destroy_page_table: level is out of range");
|
||||||
|
}
|
||||||
|
if (pt == NULL) {
|
||||||
|
panic("destroy_page_table: pt is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level > 1) {
|
||||||
|
for (ix = 0; ix < PT_ENTRIES; ++ix) {
|
||||||
|
entry = pt->entry[ix];
|
||||||
|
if (!(entry & PF_PRESENT)) {
|
||||||
|
/* entry is not valid */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (entry & PF_SIZE) {
|
||||||
|
/* not a page table */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lower = (struct page_table *)phys_to_virt(entry & PT_PHYSMASK);
|
||||||
|
destroy_page_table(level-1, lower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_free_page(pt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ihk_mc_pt_destroy(struct page_table *pt)
|
||||||
|
{
|
||||||
|
const int level = 4; /* PML4 */
|
||||||
|
|
||||||
|
/* clear shared entry */
|
||||||
|
memset(pt->entry + PT_ENTRIES / 2, 0, sizeof(pt->entry[0]) * PT_ENTRIES / 2);
|
||||||
|
|
||||||
|
destroy_page_table(level, pt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int ihk_mc_pt_clear_page(page_table_t pt, void *virt)
|
int ihk_mc_pt_clear_page(page_table_t pt, void *virt)
|
||||||
{
|
{
|
||||||
return __clear_pt_page(pt, virt, 0);
|
return __clear_pt_page(pt, virt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ihk_mc_pt_clear_large_page(page_table_t pt, void *virt)
|
||||||
|
{
|
||||||
|
return __clear_pt_page(pt, virt, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void load_page_table(struct page_table *pt)
|
void load_page_table(struct page_table *pt)
|
||||||
{
|
{
|
||||||
unsigned long pt_addr;
|
unsigned long pt_addr;
|
||||||
@ -632,7 +697,9 @@ void *map_fixed_area(unsigned long phys, unsigned long size, int uncachable)
|
|||||||
kprintf("map_fixed: %lx => %p (%d pages)\n", paligned, v, npages);
|
kprintf("map_fixed: %lx => %p (%d pages)\n", paligned, v, npages);
|
||||||
|
|
||||||
for (i = 0; i < npages; i++) {
|
for (i = 0; i < npages; i++) {
|
||||||
__set_pt_page(init_pt, (void *)fixed_virt, paligned, flag);
|
if(__set_pt_page(init_pt, (void *)fixed_virt, paligned, flag)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
fixed_virt += PAGE_SIZE;
|
fixed_virt += PAGE_SIZE;
|
||||||
paligned += PAGE_SIZE;
|
paligned += PAGE_SIZE;
|
||||||
@ -650,7 +717,7 @@ void init_low_area(struct page_table *pt)
|
|||||||
|
|
||||||
void init_page_table(void)
|
void init_page_table(void)
|
||||||
{
|
{
|
||||||
init_pt = arch_alloc_page(0);
|
init_pt = arch_alloc_page(IHK_MC_AP_CRITICAL);
|
||||||
|
|
||||||
memset(init_pt, 0, sizeof(PAGE_SIZE));
|
memset(init_pt, 0, sizeof(PAGE_SIZE));
|
||||||
|
|
||||||
@ -682,7 +749,7 @@ void ihk_mc_reserve_arch_pages(unsigned long start, unsigned long end,
|
|||||||
|
|
||||||
void ihk_mc_set_page_allocator(struct ihk_mc_pa_ops *ops)
|
void ihk_mc_set_page_allocator(struct ihk_mc_pa_ops *ops)
|
||||||
{
|
{
|
||||||
last_page = NULL;
|
last_page = (void *)-1;
|
||||||
pa_ops = ops;
|
pa_ops = ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,8 @@ int ihk_mc_ikc_init_first_local(struct ihk_ikc_channel_desc *channel,
|
|||||||
memset(channel, 0, sizeof(struct ihk_ikc_channel_desc));
|
memset(channel, 0, sizeof(struct ihk_ikc_channel_desc));
|
||||||
|
|
||||||
/* Place both sides in this side */
|
/* Place both sides in this side */
|
||||||
rq = arch_alloc_page(0);
|
rq = arch_alloc_page(IHK_MC_AP_CRITICAL);
|
||||||
wq = arch_alloc_page(0);
|
wq = arch_alloc_page(IHK_MC_AP_CRITICAL);
|
||||||
|
|
||||||
ihk_ikc_init_queue(rq, 0, 0, PAGE_SIZE, MASTER_IKCQ_PKTSIZE);
|
ihk_ikc_init_queue(rq, 0, 0, PAGE_SIZE, MASTER_IKCQ_PKTSIZE);
|
||||||
ihk_ikc_init_queue(wq, 0, 0, PAGE_SIZE, MASTER_IKCQ_PKTSIZE);
|
ihk_ikc_init_queue(wq, 0, 0, PAGE_SIZE, MASTER_IKCQ_PKTSIZE);
|
||||||
|
|||||||
98
boot-attached-mic.sh.in
Executable file
98
boot-attached-mic.sh.in
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
prefix="@prefix@"
|
||||||
|
BINDIR="@BINDIR@"
|
||||||
|
SBINDIR="@SBINDIR@"
|
||||||
|
KMODDIR="@KMODDIR@"
|
||||||
|
KERNDIR="@KERNDIR@"
|
||||||
|
|
||||||
|
if ! lspci | grep 'Co-processor.*Intel Corporation' > /dev/null 2>&1; then
|
||||||
|
echo No Intel co-processor found. >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "removing kernel modules..." >&2
|
||||||
|
modules_were_loaded="0"
|
||||||
|
|
||||||
|
if [ "`service mpss status 2> /dev/null`" != "mpss is stopped" ]; then
|
||||||
|
modules_were_loaded="1"
|
||||||
|
sudo service mpss stop
|
||||||
|
fi
|
||||||
|
if lsmod | awk 'BEGIN{rc=1}$1 == "mic"{rc=0}END{exit(rc)}'; then
|
||||||
|
modules_were_loaded="1"
|
||||||
|
sudo service mpss unload
|
||||||
|
fi
|
||||||
|
|
||||||
|
for mod_name in mcctrl ihk_mic ihk; do
|
||||||
|
if lsmod | awk 'BEGIN{rc=1}$1 == "'"$mod_name"'"{rc=0}END{exit(rc)}'; then
|
||||||
|
modules_were_loaded="1"
|
||||||
|
echo "rmmod $mod_name" >&2
|
||||||
|
if rmmod $mod_name; then
|
||||||
|
echo "$mod_name removed succesfully" >&2
|
||||||
|
sleep 1
|
||||||
|
else
|
||||||
|
echo "ERROR: couldn't remove $mod_name" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "removing kernel modules done" >&2
|
||||||
|
|
||||||
|
if [ "$1" == "-u" ]; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
wait_time=50
|
||||||
|
|
||||||
|
if [ "$modules_were_loaded" == "1" ]; then
|
||||||
|
echo "waiting for ${wait_time} seconds: " >&2
|
||||||
|
while [ "$wait_time" != 0 ]; do
|
||||||
|
echo -n "$wait_time " >&2
|
||||||
|
sleep 1
|
||||||
|
let wait_time=(${wait_time}-1)
|
||||||
|
done
|
||||||
|
echo "" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" == "-w" ]; then
|
||||||
|
shift 1
|
||||||
|
echo "press enter to continue" >&2
|
||||||
|
read enter_press
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
for mod_path in "$KMODDIR/ihk.ko" "$KMODDIR/ihk_mic.ko" "$KMODDIR/mcctrl.ko"; do
|
||||||
|
if insmod $mod_path; then
|
||||||
|
sleep 3
|
||||||
|
echo "$mod_path inserted succesfully" >&2
|
||||||
|
else
|
||||||
|
echo "ERROR: couldn't insert $mod_path" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$mod_path" == "$KMODDIR/ihk_mic.ko" ]; then
|
||||||
|
echo "creating OS device" >&2
|
||||||
|
sleep 2
|
||||||
|
"$SBINDIR/ihktest" 0 create
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$mod_path" == "$KMODDIR/mcctrl.ko" ]; then
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
echo "setting kernel parameter to: \"$1\"" >&2
|
||||||
|
"$SBINDIR/ihkostest" 0 kargs "$1"
|
||||||
|
sleep 2
|
||||||
|
else
|
||||||
|
echo "setting kernel parameter to: \"hidos\"" >&2
|
||||||
|
"$SBINDIR/ihkostest" 0 kargs "hidos"
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
echo "using kernel image: $KERNDIR/mckernel.img" >&2
|
||||||
|
"$SBINDIR/ihkostest" 0 load "$KERNDIR/mckernel.img"
|
||||||
|
sleep 2
|
||||||
|
echo "booting OS 0" >&2
|
||||||
|
"$SBINDIR/ihkostest" 0 boot
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
13
configure.ac
13
configure.ac
@ -28,6 +28,8 @@ if test "X$WITH_TARGET" = Xyes -o "X$WITH_TARGET" = Xno; then
|
|||||||
WITH_TARGET=attached-mic
|
WITH_TARGET=attached-mic
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
|
||||||
|
|
||||||
case $WITH_TARGET in
|
case $WITH_TARGET in
|
||||||
attached-mic)
|
attached-mic)
|
||||||
ARCH=`uname -m`
|
ARCH=`uname -m`
|
||||||
@ -38,6 +40,9 @@ case $WITH_TARGET in
|
|||||||
if test "X$BINDIR" = X; then
|
if test "X$BINDIR" = X; then
|
||||||
BINDIR="$prefix/bin"
|
BINDIR="$prefix/bin"
|
||||||
fi
|
fi
|
||||||
|
if test "X$SBINDIR" = X; then
|
||||||
|
SBINDIR="$prefix/sbin"
|
||||||
|
fi
|
||||||
if test "X$KMODDIR" = X; then
|
if test "X$KMODDIR" = X; then
|
||||||
KMODDIR="$prefix/kmod"
|
KMODDIR="$prefix/kmod"
|
||||||
fi
|
fi
|
||||||
@ -55,6 +60,9 @@ case $WITH_TARGET in
|
|||||||
if test "X$BINDIR" = X; then
|
if test "X$BINDIR" = X; then
|
||||||
BINDIR="$prefix/attached/bin"
|
BINDIR="$prefix/attached/bin"
|
||||||
fi
|
fi
|
||||||
|
if test "X$SBINDIR" = X; then
|
||||||
|
SBINDIR="$prefix/attached/sbin"
|
||||||
|
fi
|
||||||
if test "X$KMODDIR" = X; then
|
if test "X$KMODDIR" = X; then
|
||||||
KMODDIR="$prefix/attached/kmod"
|
KMODDIR="$prefix/attached/kmod"
|
||||||
fi
|
fi
|
||||||
@ -69,6 +77,9 @@ case $WITH_TARGET in
|
|||||||
if test "X$BINDIR" = X; then
|
if test "X$BINDIR" = X; then
|
||||||
BINDIR="$prefix/bin"
|
BINDIR="$prefix/bin"
|
||||||
fi
|
fi
|
||||||
|
if test "X$SBINDIR" = X; then
|
||||||
|
SBINDIR="$prefix/sbin"
|
||||||
|
fi
|
||||||
if test "X$KMODDIR" = X; then
|
if test "X$KMODDIR" = X; then
|
||||||
KMODDIR="$prefix/kmod"
|
KMODDIR="$prefix/kmod"
|
||||||
fi
|
fi
|
||||||
@ -87,6 +98,7 @@ AC_SUBST(ARCH)
|
|||||||
AC_SUBST(KDIR)
|
AC_SUBST(KDIR)
|
||||||
AC_SUBST(TARGET)
|
AC_SUBST(TARGET)
|
||||||
AC_SUBST(BINDIR)
|
AC_SUBST(BINDIR)
|
||||||
|
AC_SUBST(SBINDIR)
|
||||||
AC_SUBST(KMODDIR)
|
AC_SUBST(KMODDIR)
|
||||||
AC_SUBST(KERNDIR)
|
AC_SUBST(KERNDIR)
|
||||||
|
|
||||||
@ -95,6 +107,7 @@ AC_CONFIG_FILES([
|
|||||||
executer/user/Makefile
|
executer/user/Makefile
|
||||||
executer/kernel/Makefile
|
executer/kernel/Makefile
|
||||||
kernel/Makefile
|
kernel/Makefile
|
||||||
|
boot-attached-mic.sh
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|||||||
@ -30,8 +30,12 @@ struct program_load_desc {
|
|||||||
int status;
|
int status;
|
||||||
int cpu;
|
int cpu;
|
||||||
int pid;
|
int pid;
|
||||||
|
int err;
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
|
unsigned long user_start;
|
||||||
|
unsigned long user_end;
|
||||||
unsigned long rprocess;
|
unsigned long rprocess;
|
||||||
|
unsigned long rpgtable;
|
||||||
unsigned long at_phdr;
|
unsigned long at_phdr;
|
||||||
unsigned long at_phent;
|
unsigned long at_phent;
|
||||||
unsigned long at_phnum;
|
unsigned long at_phnum;
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
KDIR ?= /lib/modules/`uname -r `/build
|
|
||||||
|
|
||||||
obj-m += mcctrl.o
|
|
||||||
|
|
||||||
mcctrl-objs := driver.o control.o ikc.o syscall.o
|
|
||||||
|
|
||||||
IHK_BASE=$(src)/../../../ihk
|
|
||||||
EXTRA_CFLAGS = -I$(IHK_BASE)/linux/include -I$(IHK_BASE)/ikc/include -I$(IHK_BASE)/include -I$(src)/../include
|
|
||||||
KBUILD_EXTRA_SYMBOLS = $(IHK_BASE)/linux/core/Module.symvers
|
|
||||||
|
|
||||||
.PHONY: clean install
|
|
||||||
|
|
||||||
modules:
|
|
||||||
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) .*.cmd *.mod.c *.o *.ko* Module.symvers modules.order -r .tmp*
|
|
||||||
|
|
||||||
install:
|
|
||||||
@ -50,6 +50,11 @@ static long mcexec_prepare_image(ihk_os_t os,
|
|||||||
|
|
||||||
pdesc->pid = task_tgid_vnr(current);
|
pdesc->pid = task_tgid_vnr(current);
|
||||||
|
|
||||||
|
if (reserve_user_space(usrdata, &pdesc->user_start, &pdesc->user_end)) {
|
||||||
|
kfree(pdesc);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
args = kmalloc(pdesc->args_len, GFP_KERNEL);
|
args = kmalloc(pdesc->args_len, GFP_KERNEL);
|
||||||
if (copy_from_user(args, pdesc->args, pdesc->args_len)) {
|
if (copy_from_user(args, pdesc->args, pdesc->args_len)) {
|
||||||
kfree(args);
|
kfree(args);
|
||||||
@ -82,6 +87,12 @@ static long mcexec_prepare_image(ihk_os_t os,
|
|||||||
|
|
||||||
wait_event_interruptible(usrdata->wq_prepare, pdesc->status);
|
wait_event_interruptible(usrdata->wq_prepare, pdesc->status);
|
||||||
|
|
||||||
|
if(pdesc->err == -1){
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto free_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
usrdata->rpgtable = pdesc->rpgtable;
|
||||||
if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) +
|
if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) +
|
||||||
sizeof(struct program_image_section) * desc.num_sections)) {
|
sizeof(struct program_image_section) * desc.num_sections)) {
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
@ -224,6 +235,7 @@ int mcexec_wait_syscall(ihk_os_t os, struct syscall_wait_desc *__user req)
|
|||||||
unsigned long s, w, d;
|
unsigned long s, w, d;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//printk("mcexec_wait_syscall swd=%p req=%p size=%d\n", &swd, req, sizeof(swd.cpu));
|
||||||
if (copy_from_user(&swd, req, sizeof(swd.cpu))) {
|
if (copy_from_user(&swd, req, sizeof(swd.cpu))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
@ -510,11 +522,12 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mcexec_prepare_ack(ihk_os_t os, unsigned long arg)
|
void mcexec_prepare_ack(ihk_os_t os, unsigned long arg, int err)
|
||||||
{
|
{
|
||||||
struct program_load_desc *desc = phys_to_virt(arg);
|
struct program_load_desc *desc = phys_to_virt(arg);
|
||||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||||
|
|
||||||
|
desc->err = err;
|
||||||
desc->status = 1;
|
desc->status = 1;
|
||||||
|
|
||||||
wake_up_all(&usrdata->wq_prepare);
|
wake_up_all(&usrdata->wq_prepare);
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
//struct mcctrl_channel *channels;
|
//struct mcctrl_channel *channels;
|
||||||
|
|
||||||
void mcexec_prepare_ack(ihk_os_t os, unsigned long arg);
|
void mcexec_prepare_ack(ihk_os_t os, unsigned long arg, int err);
|
||||||
static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys);
|
static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys);
|
||||||
int mcexec_syscall(struct mcctrl_channel *c, unsigned long arg);
|
int mcexec_syscall(struct mcctrl_channel *c, unsigned long arg);
|
||||||
|
|
||||||
@ -31,7 +31,11 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SCD_MSG_PREPARE_PROCESS_ACKED:
|
case SCD_MSG_PREPARE_PROCESS_ACKED:
|
||||||
mcexec_prepare_ack(__os, pisp->arg);
|
mcexec_prepare_ack(__os, pisp->arg, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCD_MSG_PREPARE_PROCESS_NACKED:
|
||||||
|
mcexec_prepare_ack(__os, pisp->arg, -1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCD_MSG_SYSCALL_ONESIDE:
|
case SCD_MSG_SYSCALL_ONESIDE:
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#define SCD_MSG_PREPARE_PROCESS 0x1
|
#define SCD_MSG_PREPARE_PROCESS 0x1
|
||||||
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
||||||
|
#define SCD_MSG_PREPARE_PROCESS_NACKED 0x7
|
||||||
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
||||||
|
|
||||||
#define SCD_MSG_INIT_CHANNEL 0x5
|
#define SCD_MSG_INIT_CHANNEL 0x5
|
||||||
@ -77,9 +78,13 @@ struct mcctrl_usrdata {
|
|||||||
int mcctrl_dma_abort;
|
int mcctrl_dma_abort;
|
||||||
unsigned long last_thread_exec;
|
unsigned long last_thread_exec;
|
||||||
wait_queue_head_t wq_prepare;
|
wait_queue_head_t wq_prepare;
|
||||||
|
unsigned long rpgtable; /* per process, not per OS */
|
||||||
};
|
};
|
||||||
|
|
||||||
int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp);
|
int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp);
|
||||||
int mcctrl_ikc_send_msg(ihk_os_t os, int cpu, int msg, int ref, unsigned long arg);
|
int mcctrl_ikc_send_msg(ihk_os_t os, int cpu, int msg, int ref, unsigned long arg);
|
||||||
int mcctrl_ikc_is_valid_thread(ihk_os_t os, int cpu);
|
int mcctrl_ikc_is_valid_thread(ihk_os_t os, int cpu);
|
||||||
|
int reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp,
|
||||||
|
unsigned long *endp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -5,6 +5,9 @@
|
|||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
|
#include <linux/anon_inodes.h>
|
||||||
|
#include <linux/mman.h>
|
||||||
|
#include <linux/file.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/delay.h>
|
#include <asm/delay.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@ -13,6 +16,13 @@
|
|||||||
#define ALIGN_WAIT_BUF(z) (((z + 63) >> 6) << 6)
|
#define ALIGN_WAIT_BUF(z) (((z + 63) >> 6) << 6)
|
||||||
|
|
||||||
//#define SC_DEBUG
|
//#define SC_DEBUG
|
||||||
|
|
||||||
|
#ifdef SC_DEBUG
|
||||||
|
#define dprintk(...) printk(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define dprintk(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SC_DEBUG
|
#ifdef SC_DEBUG
|
||||||
//static struct ihk_dma_request last_request;
|
//static struct ihk_dma_request last_request;
|
||||||
|
|
||||||
@ -26,6 +36,129 @@ static void print_dma_lastreq(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1 /* x86 depend, host OS side */
|
||||||
|
unsigned long translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva)
|
||||||
|
{
|
||||||
|
unsigned long rpa;
|
||||||
|
int offsh;
|
||||||
|
int i;
|
||||||
|
int ix;
|
||||||
|
unsigned long phys;
|
||||||
|
unsigned long *pt;
|
||||||
|
|
||||||
|
rpa = rpt;
|
||||||
|
offsh = 39;
|
||||||
|
/* i = 0: PML4, 1: PDPT, 2: PDT, 3: PT */
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
ix = (rva >> offsh) & 0x1FF;
|
||||||
|
phys = ihk_device_map_memory(ihk_os_to_dev(os), rpa, PAGE_SIZE);
|
||||||
|
pt = ihk_device_map_virtual(ihk_os_to_dev(os), phys, PAGE_SIZE, NULL, 0);
|
||||||
|
dprintk("rpa %#lx offsh %d ix %#x phys %#lx pt %p pt[ix] %#lx\n",
|
||||||
|
rpa, offsh, ix, phys, pt, pt[ix]);
|
||||||
|
|
||||||
|
#define PTE_P 0x001
|
||||||
|
if (!(pt[ix] & PTE_P)) {
|
||||||
|
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
|
||||||
|
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PTE_PS 0x080
|
||||||
|
if (pt[ix] & PTE_PS) {
|
||||||
|
rpa = pt[ix] & ((1UL << 52) - 1) & ~((1UL << offsh) - 1);
|
||||||
|
rpa |= rva & ((1UL << offsh) - 1);
|
||||||
|
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
|
||||||
|
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpa = pt[ix] & ((1UL << 52) - 1) & ~((1UL << 12) - 1);
|
||||||
|
offsh -= 9;
|
||||||
|
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
|
||||||
|
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
|
||||||
|
}
|
||||||
|
rpa |= rva & ((1UL << 12) - 1);
|
||||||
|
out:
|
||||||
|
dprintk("translate_rva_to_rpa: rva %#lx --> rpa %#lx\n", rva, rpa);
|
||||||
|
return rpa;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||||
|
{
|
||||||
|
struct mcctrl_usrdata * usrdata = vma->vm_file->private_data;
|
||||||
|
ihk_device_t dev = ihk_os_to_dev(usrdata->os);
|
||||||
|
unsigned long rpa;
|
||||||
|
unsigned long phys;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
dprintk("mcctrl:page fault:flags %#x pgoff %#lx va %p page %p\n",
|
||||||
|
vmf->flags, vmf->pgoff, vmf->virtual_address, vmf->page);
|
||||||
|
|
||||||
|
rpa = translate_rva_to_rpa(usrdata->os, usrdata->rpgtable,
|
||||||
|
(unsigned long)vmf->virtual_address);
|
||||||
|
|
||||||
|
phys = ihk_device_map_memory(dev, rpa, PAGE_SIZE);
|
||||||
|
error = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, phys>>PAGE_SHIFT);
|
||||||
|
ihk_device_unmap_memory(dev, phys, PAGE_SIZE);
|
||||||
|
if (error) {
|
||||||
|
printk("mcctrl:page fault:flags %#x pgoff %#lx va %p page %p\n",
|
||||||
|
vmf->flags, vmf->pgoff, vmf->virtual_address, vmf->page);
|
||||||
|
return VM_FAULT_SIGBUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VM_FAULT_NOPAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct vm_operations_struct rus_vmops = {
|
||||||
|
.fault = &rus_vm_fault,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rus_mmap(struct file *file, struct vm_area_struct *vma)
|
||||||
|
{
|
||||||
|
vma->vm_flags |= VM_IO | VM_RESERVED | VM_DONTEXPAND | VM_PFNMAP;
|
||||||
|
vma->vm_ops = &rus_vmops;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct file_operations rus_fops = {
|
||||||
|
.mmap = &rus_mmap,
|
||||||
|
};
|
||||||
|
|
||||||
|
int reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp, unsigned long *endp)
|
||||||
|
{
|
||||||
|
struct file *file;
|
||||||
|
struct vm_area_struct *vma;
|
||||||
|
unsigned long start;
|
||||||
|
unsigned long end;
|
||||||
|
|
||||||
|
file = anon_inode_getfile("[mckernel]", &rus_fops, usrdata, O_RDWR);
|
||||||
|
if (IS_ERR(file)) {
|
||||||
|
return PTR_ERR(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DESIRED_USER_END 0x800000000000
|
||||||
|
#define GAP_FOR_MCEXEC 0x008000000000UL
|
||||||
|
end = DESIRED_USER_END;
|
||||||
|
down_write(¤t->mm->mmap_sem);
|
||||||
|
vma = find_vma(current->mm, 0);
|
||||||
|
if (vma) {
|
||||||
|
end = (vma->vm_start - GAP_FOR_MCEXEC) & ~(GAP_FOR_MCEXEC - 1);
|
||||||
|
}
|
||||||
|
start = do_mmap_pgoff(file, 0, end,
|
||||||
|
PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, 0);
|
||||||
|
up_write(¤t->mm->mmap_sem);
|
||||||
|
fput(file);
|
||||||
|
if (IS_ERR_VALUE(start)) {
|
||||||
|
printk("mcctrl:user space reservation failed.\n");
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
*startp = start;
|
||||||
|
*endp = end;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//unsigned long last_thread_exec = 0;
|
//unsigned long last_thread_exec = 0;
|
||||||
|
|
||||||
#ifndef DO_USER_MODE
|
#ifndef DO_USER_MODE
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
#CC=/usr/linux-k1om-4.7/bin/x86_64-k1om-linux-gcc
|
|
||||||
CC=gcc
|
|
||||||
CFLAGS=-Wall -O
|
|
||||||
TARGET=mcexec
|
|
||||||
|
|
||||||
all: $(TARGET)
|
|
||||||
|
|
||||||
mcexec: mcexec.c
|
|
||||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -pthread -o $@ $^ $(EXTRA_OBJS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) $(TARGET) *.o
|
|
||||||
|
|
||||||
.PHONY: all clean
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,12 +1,12 @@
|
|||||||
CC=@CC@
|
CC=@CC@
|
||||||
BINDIR=@BINDIR@
|
BINDIR=@BINDIR@
|
||||||
CFLAGS=-Wall -O
|
CFLAGS=-Wall -O -fPIE -pie
|
||||||
TARGET=mcexec
|
TARGET=mcexec
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
mcexec: mcexec.c
|
mcexec: mcexec.c
|
||||||
$(CC) $(CFLAGS) -pthread -o $@ $^
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -pthread -o $@ $^ $(EXTRA_OBJS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(TARGET) *.o
|
$(RM) $(TARGET) *.o
|
||||||
|
|||||||
@ -46,6 +46,16 @@ extern int mc_cmd_server_init();
|
|||||||
extern void mc_cmd_server_exit();
|
extern void mc_cmd_server_exit();
|
||||||
extern void mc_cmd_handle(int fd, int cpu, unsigned long args[6]);
|
extern void mc_cmd_handle(int fd, int cpu, unsigned long args[6]);
|
||||||
|
|
||||||
|
#ifdef CMD_DCFA
|
||||||
|
extern void ibmic_cmd_server_exit();
|
||||||
|
extern int ibmic_cmd_server_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CMD_DCFAMPI
|
||||||
|
extern void dcfampi_cmd_server_exit();
|
||||||
|
extern int dcfampi_cmd_server_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
int __glob_argc = -1;
|
int __glob_argc = -1;
|
||||||
char **__glob_argv = 0;
|
char **__glob_argv = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -435,6 +445,20 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "Error: cmd server init failed\n");
|
fprintf(stderr, "Error: cmd server init failed\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CMD_DCFA
|
||||||
|
if(ibmic_cmd_server_init()){
|
||||||
|
fprintf(stderr, "Error: Failed to initialize ibmic_cmd_server.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CMD_DCFAMPI
|
||||||
|
if(dcfampi_cmd_server_init()){
|
||||||
|
fprintf(stderr, "Error: Failed to initialize dcfampi_cmd_server.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
__dprint("mccmd server initialized\n");
|
__dprint("mccmd server initialized\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -500,12 +524,32 @@ void do_syscall_load(int fd, int cpu, unsigned long dest, unsigned long src,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
do_generic_syscall(
|
||||||
|
struct syscall_wait_desc *w)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
__dprintf("do_generic_syscall(%ld)\n", w->sr.number);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
ret = syscall(w->sr.number, w->sr.args[0], w->sr.args[1], w->sr.args[2],
|
||||||
|
w->sr.args[3], w->sr.args[4], w->sr.args[5]);
|
||||||
|
if (errno != 0) {
|
||||||
|
ret = -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
__dprintf("do_generic_syscall(%ld):%ld (%#lx)\n", w->sr.number, ret, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#define SET_ERR(ret) if (ret == -1) ret = -errno
|
#define SET_ERR(ret) if (ret == -1) ret = -errno
|
||||||
|
|
||||||
int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
||||||
{
|
{
|
||||||
struct syscall_wait_desc w;
|
struct syscall_wait_desc w;
|
||||||
int ret;
|
long ret;
|
||||||
|
char *fn;
|
||||||
|
|
||||||
w.cpu = cpu;
|
w.cpu = cpu;
|
||||||
|
|
||||||
@ -530,7 +574,17 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
|||||||
|
|
||||||
__dprintf("open: %s\n", dma_buf);
|
__dprintf("open: %s\n", dma_buf);
|
||||||
|
|
||||||
ret = open((char *)dma_buf, w.sr.args[1], w.sr.args[2]);
|
fn = (char *)dma_buf;
|
||||||
|
if(!strcmp(fn, "/proc/meminfo")){
|
||||||
|
fn = "/admin/fs/attached/files/proc/meminfo";
|
||||||
|
}
|
||||||
|
else if(!strcmp(fn, "/proc/cpuinfo")){
|
||||||
|
fn = "/admin/fs/attached/files/proc/cpuinfo";
|
||||||
|
}
|
||||||
|
else if(!strcmp(fn, "/sys/devices/system/cpu/online")){
|
||||||
|
fn = "/admin/fs/attached/files/sys/devices/system/cpu/online";
|
||||||
|
}
|
||||||
|
ret = open(fn, w.sr.args[1], w.sr.args[2]);
|
||||||
SET_ERR(ret);
|
SET_ERR(ret);
|
||||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
@ -694,6 +748,13 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
|||||||
w.sr.args[0], cpu);
|
w.sr.args[0], cpu);
|
||||||
|
|
||||||
#ifdef USE_SYSCALL_MOD_CALL
|
#ifdef USE_SYSCALL_MOD_CALL
|
||||||
|
#ifdef CMD_DCFA
|
||||||
|
ibmic_cmd_server_exit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CMD_DCFAMPI
|
||||||
|
dcfampi_cmd_server_exit();
|
||||||
|
#endif
|
||||||
mc_cmd_server_exit();
|
mc_cmd_server_exit();
|
||||||
__dprint("mccmd server exited\n");
|
__dprint("mccmd server exited\n");
|
||||||
#endif
|
#endif
|
||||||
@ -805,7 +866,8 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
__dprintf("Unhandled system calls: %ld\n", w.sr.number);
|
ret = do_generic_syscall(&w);
|
||||||
|
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,7 +4,13 @@ OBJS += process.o copy.o waitq.o futex.o timer.o
|
|||||||
DEPSRCS=$(wildcard $(SRC)/*.c)
|
DEPSRCS=$(wildcard $(SRC)/*.c)
|
||||||
|
|
||||||
CFLAGS += -I$(SRC)/include -mcmodel=kernel -D__KERNEL__
|
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
|
LDFLAGS += -e arch_start
|
||||||
IHKOBJ = ihk/ihk.o
|
IHKOBJ = ihk/ihk.o
|
||||||
@ -24,14 +30,26 @@ mkimage_cmd_base = [ -f $(SRC)/script/mkimage.$(TARGET) ] && CC=$(CC) LD=$(LD) L
|
|||||||
ld_kern_cmd = $(call echo_cmd,LDKERN,$@)$(ld_kern_cmd_base)
|
ld_kern_cmd = $(call echo_cmd,LDKERN,$@)$(ld_kern_cmd_base)
|
||||||
mkimage_cmd = $(call echo_cmd,MKIMAGE,$@)$(mkimage_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)
|
kernel.img: $(OBJS) $(IHKOBJ) $(EXTRA_OBJS)
|
||||||
$(ld_kern_cmd)
|
$(ld_kern_cmd)
|
||||||
$(mkimage_cmd)
|
$(mkimage_cmd)
|
||||||
|
|
||||||
clean:
|
kobj: depend $(KERNEL_OBJ)
|
||||||
$(rm_cmd) $(OBJS) kernel.img kernel.img.elf Makefile.dep
|
|
||||||
|
$(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
|
@$(submake) -C $(IHKBASE) $(SUBCMD_OPTS) clean
|
||||||
|
|
||||||
depend: Makefile.dep
|
depend: 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 = sizeof(struct cpu_local_var) * num_processors;
|
||||||
z = (z + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
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);
|
memset(clv, 0, z * PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,9 +20,12 @@ void kputs(char *buf)
|
|||||||
|
|
||||||
if (len + kmsg_buf.tail > kmsg_buf.len) {
|
if (len + kmsg_buf.tail > kmsg_buf.len) {
|
||||||
kmsg_buf.tail = 0;
|
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;
|
kmsg_buf.tail += len;
|
||||||
|
|
||||||
ihk_mc_spinlock_unlock(&kmsg_lock, flags);
|
ihk_mc_spinlock_unlock(&kmsg_lock, flags);
|
||||||
|
|||||||
136
kernel/host.c
136
kernel/host.c
@ -33,7 +33,7 @@ void check_mapping_for_proc(struct process *proc, unsigned long addr)
|
|||||||
/*
|
/*
|
||||||
* Communication with host
|
* 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;
|
unsigned long phys, sz, s, e, up;
|
||||||
struct program_load_desc *p, *pn;
|
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;
|
int argc, envc, args_envs_npages;
|
||||||
char **env;
|
char **env;
|
||||||
int range_npages;
|
int range_npages;
|
||||||
|
void *up_v;
|
||||||
|
|
||||||
sz = sizeof(struct program_load_desc)
|
sz = sizeof(struct program_load_desc)
|
||||||
+ sizeof(struct program_image_section) * 16;
|
+ 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);
|
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;
|
n = p->num_sections;
|
||||||
dkprintf("# of sections: %d\n", n);
|
dkprintf("# of sections: %d\n", n);
|
||||||
|
|
||||||
pn = ihk_mc_allocate(sizeof(struct program_load_desc)
|
if((pn = ihk_mc_allocate(sizeof(struct program_load_desc)
|
||||||
+ sizeof(struct program_image_section) * n, 0);
|
+ 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)
|
memcpy_long(pn, p, sizeof(struct program_load_desc)
|
||||||
+ sizeof(struct program_image_section) * n);
|
+ sizeof(struct program_image_section) * n);
|
||||||
|
|
||||||
proc = create_process(p->entry);
|
if((proc = create_process(p->entry)) == NULL){
|
||||||
proc->pid = 1024;
|
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 */
|
/* TODO: Clear it at the proper timing */
|
||||||
cpu_local_var(scp).post_idx = 0;
|
cpu_local_var(scp).post_idx = 0;
|
||||||
@ -77,8 +92,14 @@ static void process_msg_prepare_process(unsigned long rphys)
|
|||||||
#if 0
|
#if 0
|
||||||
if (range_npages <= 256) {
|
if (range_npages <= 256) {
|
||||||
#endif
|
#endif
|
||||||
up = virt_to_phys(ihk_mc_alloc_pages(range_npages, 0));
|
if((up_v = ihk_mc_alloc_pages(range_npages, IHK_MC_AP_NOWAIT)) == NULL){
|
||||||
add_process_memory_range(proc, s, e, up, 0);
|
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;
|
void *_virt = (void *)s;
|
||||||
@ -108,7 +129,7 @@ static void process_msg_prepare_process(unsigned long rphys)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
up = 0;
|
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");
|
kprintf("ERROR: not enough memory\n");
|
||||||
while (1) cpu_halt();
|
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.brk_start = proc->vm->region.brk_end =
|
||||||
proc->vm->region.data_end;
|
proc->vm->region.data_end;
|
||||||
|
#endif
|
||||||
proc->vm->region.map_start = proc->vm->region.map_end =
|
proc->vm->region.map_start = proc->vm->region.map_end =
|
||||||
(USER_END / 3) & LARGE_PAGE_MASK;
|
(USER_END / 3) & LARGE_PAGE_MASK;
|
||||||
|
|
||||||
/* Map system call stuffs */
|
/* Map system call stuffs */
|
||||||
addr = proc->vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
addr = proc->vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
||||||
e = addr + PAGE_SIZE * DOORBELL_PAGE_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,
|
cpu_local_var(scp).doorbell_pa,
|
||||||
VR_REMOTE | VR_RESERVED);
|
VR_REMOTE | VR_RESERVED) != 0){
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
addr = e;
|
addr = e;
|
||||||
e = addr + PAGE_SIZE * REQUEST_PAGE_COUNT;
|
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,
|
cpu_local_var(scp).request_pa,
|
||||||
VR_REMOTE | VR_RESERVED);
|
VR_REMOTE | VR_RESERVED) != 0){
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
addr = e;
|
addr = e;
|
||||||
e = addr + PAGE_SIZE * RESPONSE_PAGE_COUNT;
|
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,
|
cpu_local_var(scp).response_pa,
|
||||||
VR_RESERVED);
|
VR_RESERVED) != 0){
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Map, copy and update args and envs */
|
/* Map, copy and update args and envs */
|
||||||
addr = e;
|
addr = e;
|
||||||
e = addr + PAGE_SIZE * ARGENV_PAGE_COUNT;
|
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);
|
args_envs_p = virt_to_phys(args_envs);
|
||||||
|
|
||||||
add_process_memory_range(proc, addr, e,
|
if(add_process_memory_range(proc, addr, e, args_envs_p, VR_NONE) != 0){
|
||||||
args_envs_p,
|
ihk_mc_free_pages(args_envs, ARGENV_PAGE_COUNT);
|
||||||
VR_RESERVED);
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
dkprintf("args_envs mapping\n");
|
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);
|
dkprintf("args_envs_npages: %d\n", args_envs_npages);
|
||||||
args_envs_rp = ihk_mc_map_memory(NULL, (unsigned long)p->args, p->args_len);
|
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);
|
dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp);
|
||||||
args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
if((args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
||||||
PTATTR_WRITABLE);
|
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
|
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
|
||||||
|
|
||||||
dkprintf("args copy, nr: %d\n", *((int*)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);
|
dkprintf("args_envs_npages: %d\n", args_envs_npages);
|
||||||
args_envs_rp = ihk_mc_map_memory(NULL, (unsigned long)p->envs, p->envs_len);
|
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);
|
dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp);
|
||||||
args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
if((args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
||||||
PTATTR_WRITABLE);
|
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
|
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
|
||||||
|
|
||||||
dkprintf("envs copy, nr: %d\n", *((int*)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");
|
dkprintf("env OK\n");
|
||||||
|
|
||||||
p->rprocess = (unsigned long)proc;
|
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,
|
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
||||||
proc->vm->page_table);
|
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_virtual(p, npages, 1);
|
||||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||||
flush_tlb();
|
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)
|
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_rpa = param->request_page;
|
||||||
lparam->request_pa = ihk_mc_map_memory(NULL, param->request_page,
|
lparam->request_pa = ihk_mc_map_memory(NULL, param->request_page,
|
||||||
REQUEST_PAGE_COUNT * PAGE_SIZE);
|
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,
|
REQUEST_PAGE_COUNT,
|
||||||
PTATTR_WRITABLE);
|
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||||
|
// TODO:
|
||||||
|
panic("ENOMEM");
|
||||||
|
}
|
||||||
|
|
||||||
lparam->doorbell_rpa = param->doorbell_page;
|
lparam->doorbell_rpa = param->doorbell_page;
|
||||||
lparam->doorbell_pa = ihk_mc_map_memory(NULL, param->doorbell_page,
|
lparam->doorbell_pa = ihk_mc_map_memory(NULL, param->doorbell_page,
|
||||||
DOORBELL_PAGE_COUNT *
|
DOORBELL_PAGE_COUNT *
|
||||||
PAGE_SIZE);
|
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,
|
DOORBELL_PAGE_COUNT,
|
||||||
PTATTR_WRITABLE);
|
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||||
|
// TODO:
|
||||||
|
panic("ENOMEM");
|
||||||
|
}
|
||||||
|
|
||||||
lparam->post_rpa = param->post_page;
|
lparam->post_rpa = param->post_page;
|
||||||
lparam->post_pa = ihk_mc_map_memory(NULL, param->post_page,
|
lparam->post_pa = ihk_mc_map_memory(NULL, param->post_page,
|
||||||
PAGE_SIZE);
|
PAGE_SIZE);
|
||||||
lparam->post_va = ihk_mc_map_virtual(lparam->post_pa, 1,
|
if((lparam->post_va = ihk_mc_map_virtual(lparam->post_pa, 1,
|
||||||
PTATTR_WRITABLE);
|
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||||
|
// TODO:
|
||||||
|
panic("ENOMEM");
|
||||||
|
}
|
||||||
|
|
||||||
lparam->post_fin = 1;
|
lparam->post_fin = 1;
|
||||||
|
|
||||||
@ -340,9 +409,10 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SCD_MSG_PREPARE_PROCESS:
|
case SCD_MSG_PREPARE_PROCESS:
|
||||||
process_msg_prepare_process(packet->arg);
|
if(process_msg_prepare_process(packet->arg) == 0)
|
||||||
|
|
||||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
|
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
|
||||||
|
else
|
||||||
|
pckt.msg = SCD_MSG_PREPARE_PROCESS_NACKED;
|
||||||
pckt.ref = packet->ref;
|
pckt.ref = packet->ref;
|
||||||
pckt.arg = packet->arg;
|
pckt.arg = packet->arg;
|
||||||
syscall_channel_send(c, &pckt);
|
syscall_channel_send(c, &pckt);
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <ihk/atomic.h>
|
#include <ihk/atomic.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
|
|
||||||
|
#define VR_NONE 0x0
|
||||||
#define VR_STACK 0x1
|
#define VR_STACK 0x1
|
||||||
#define VR_RESERVED 0x2
|
#define VR_RESERVED 0x2
|
||||||
#define VR_IO_NOCACHE 0x100
|
#define VR_IO_NOCACHE 0x100
|
||||||
@ -40,6 +41,7 @@ struct vm_regions {
|
|||||||
unsigned long brk_start, brk_end;
|
unsigned long brk_start, brk_end;
|
||||||
unsigned long map_start, map_end;
|
unsigned long map_start, map_end;
|
||||||
unsigned long stack_start, stack_end;
|
unsigned long stack_start, stack_end;
|
||||||
|
unsigned long user_start, user_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct process_vm;
|
struct process_vm;
|
||||||
@ -49,6 +51,7 @@ struct process {
|
|||||||
int status;
|
int status;
|
||||||
int cpu_id;
|
int cpu_id;
|
||||||
|
|
||||||
|
ihk_atomic_t refcount;
|
||||||
struct process_vm *vm;
|
struct process_vm *vm;
|
||||||
|
|
||||||
ihk_mc_kernel_context_t ctx;
|
ihk_mc_kernel_context_t ctx;
|
||||||
@ -72,6 +75,7 @@ struct process_vm {
|
|||||||
struct page_table *page_table;
|
struct page_table *page_table;
|
||||||
struct list_head vm_range_list;
|
struct list_head vm_range_list;
|
||||||
struct vm_regions region;
|
struct vm_regions region;
|
||||||
|
struct process *owner_process; /* process that reside on the same page */
|
||||||
|
|
||||||
ihk_spinlock_t page_table_lock;
|
ihk_spinlock_t page_table_lock;
|
||||||
ihk_spinlock_t memory_range_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,
|
struct process *clone_process(struct process *org,
|
||||||
unsigned long pc, unsigned long sp);
|
unsigned long pc, unsigned long sp);
|
||||||
void destroy_process(struct process *proc);
|
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);
|
void free_process_memory(struct process *proc);
|
||||||
|
|
||||||
int add_process_memory_range(struct process *process,
|
int add_process_memory_range(struct process *process,
|
||||||
unsigned long start, unsigned long end,
|
unsigned long start, unsigned long end,
|
||||||
unsigned long phys, unsigned long flag);
|
unsigned long phys, unsigned long flag);
|
||||||
|
#if 0
|
||||||
int add_process_large_range(struct process *process,
|
int add_process_large_range(struct process *process,
|
||||||
unsigned long start, unsigned long end,
|
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,
|
int remove_process_region(struct process *proc,
|
||||||
unsigned long start, unsigned long end);
|
unsigned long start, unsigned long end);
|
||||||
struct program_load_desc;
|
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 argc, char **argv,
|
||||||
int envc, char **env);
|
int envc, char **env);
|
||||||
unsigned long extend_process_region(struct process *proc,
|
unsigned long extend_process_region(struct process *proc,
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#define SCD_MSG_PREPARE_PROCESS 0x1
|
#define SCD_MSG_PREPARE_PROCESS 0x1
|
||||||
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
||||||
|
#define SCD_MSG_PREPARE_PROCESS_NACKED 0x7
|
||||||
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
||||||
|
|
||||||
#define SCD_MSG_INIT_CHANNEL 0x5
|
#define SCD_MSG_INIT_CHANNEL 0x5
|
||||||
@ -88,8 +89,12 @@ struct program_load_desc {
|
|||||||
int status;
|
int status;
|
||||||
int cpu;
|
int cpu;
|
||||||
int pid;
|
int pid;
|
||||||
|
int err;
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
|
unsigned long user_start;
|
||||||
|
unsigned long user_end;
|
||||||
unsigned long rprocess;
|
unsigned long rprocess;
|
||||||
|
unsigned long rpgtable;
|
||||||
unsigned long at_phdr;
|
unsigned long at_phdr;
|
||||||
unsigned long at_phent;
|
unsigned long at_phent;
|
||||||
unsigned long at_phnum;
|
unsigned long at_phnum;
|
||||||
|
|||||||
@ -222,8 +222,10 @@ int main(void)
|
|||||||
|
|
||||||
#ifdef DCFA_KMOD
|
#ifdef DCFA_KMOD
|
||||||
mc_cmd_client_init();
|
mc_cmd_client_init();
|
||||||
|
#ifdef CMD_DCFA
|
||||||
ibmic_cmd_init();
|
ibmic_cmd_init();
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DCFA_RUN
|
#ifdef DCFA_RUN
|
||||||
kputs("DCFA begin\n");
|
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;
|
a = (unsigned long)packet->param1 << 12;
|
||||||
|
|
||||||
pp = ihk_mc_map_memory(NULL, a, 4 * 1024 * 1024);
|
pp = ihk_mc_map_memory(NULL, a, 4 * 1024 * 1024);
|
||||||
v = ihk_mc_map_virtual(pp, 4 * 1024,
|
if((v = ihk_mc_map_virtual(pp, 4 * 1024,
|
||||||
PTATTR_UNCACHABLE);
|
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);
|
testmem(v, 4 * 1024 * 1024);
|
||||||
|
|
||||||
|
|||||||
23
kernel/mem.c
23
kernel/mem.c
@ -47,7 +47,11 @@ void *allocate_pages(int npages, enum ihk_mc_ap_flag flag)
|
|||||||
unsigned long pa = ihk_pagealloc_alloc(pa_allocator, npages);
|
unsigned long pa = ihk_pagealloc_alloc(pa_allocator, npages);
|
||||||
/* all_pagealloc_alloc returns zero when error occured,
|
/* all_pagealloc_alloc returns zero when error occured,
|
||||||
and callee (in mcos/kernel/process.c) so propagate it */
|
and callee (in mcos/kernel/process.c) so propagate it */
|
||||||
return pa ? phys_to_virt(pa) : 0;
|
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)
|
void free_pages(void *va, int npages)
|
||||||
@ -194,8 +198,15 @@ void *ihk_mc_map_virtual(unsigned long phys, int npages,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < npages; i++) {
|
for (i = 0; i < npages; i++) {
|
||||||
ihk_mc_pt_set_page(NULL, (char *)p + (i << PAGE_SHIFT),
|
if(ihk_mc_pt_set_page(NULL, (char *)p + (i << PAGE_SHIFT),
|
||||||
phys + (i << PAGE_SHIFT), attr);
|
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;
|
return (char *)p + offset;
|
||||||
}
|
}
|
||||||
@ -305,10 +316,12 @@ void *kmalloc(int size, enum ihk_mc_ap_flag flag)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (h == &v->free_list) {
|
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;
|
>> PAGE_SHIFT;
|
||||||
|
|
||||||
h = allocate_pages(req_page, 0);
|
h = allocate_pages(req_page, flag);
|
||||||
|
if(h == NULL)
|
||||||
|
return NULL;
|
||||||
prev->next = h;
|
prev->next = h;
|
||||||
h->size = (req_page * PAGE_SIZE) / sizeof(*h) - 2;
|
h->size = (req_page * PAGE_SIZE) / sizeof(*h) - 2;
|
||||||
/* Guard entry */
|
/* Guard entry */
|
||||||
|
|||||||
@ -12,7 +12,8 @@ static int arch_master_channel_packet_handler(struct ihk_ikc_channel_desc *,
|
|||||||
void ikc_master_init(void)
|
void ikc_master_init(void)
|
||||||
{
|
{
|
||||||
mchannel = kmalloc(sizeof(struct ihk_ikc_channel_desc) +
|
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);
|
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);
|
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->memory_range_lock);
|
||||||
ihk_mc_spinlock_init(&vm->page_table_lock);
|
ihk_mc_spinlock_init(&vm->page_table_lock);
|
||||||
|
|
||||||
ihk_atomic_set(&vm->refcount, 1);
|
ihk_atomic_set(&vm->refcount, 1);
|
||||||
INIT_LIST_HEAD(&vm->vm_range_list);
|
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 *create_process(unsigned long user_pc)
|
||||||
{
|
{
|
||||||
struct process *proc;
|
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)
|
if (!proc)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset(proc, 0, sizeof(struct process));
|
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,
|
ihk_mc_init_user_process(&proc->ctx, &proc->uctx,
|
||||||
((char *)proc) +
|
((char *)proc) +
|
||||||
@ -49,7 +60,10 @@ struct process *create_process(unsigned long user_pc)
|
|||||||
|
|
||||||
proc->vm = (struct process_vm *)(proc + 1);
|
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);
|
ihk_mc_spinlock_init(&proc->spin_sleep_lock);
|
||||||
proc->spin_sleep = 0;
|
proc->spin_sleep = 0;
|
||||||
@ -62,9 +76,12 @@ struct process *clone_process(struct process *org, unsigned long pc,
|
|||||||
{
|
{
|
||||||
struct process *proc;
|
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! */
|
/* NOTE: sp is the user mode stack! */
|
||||||
ihk_mc_init_user_process(&proc->ctx, &proc->uctx,
|
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);
|
ihk_atomic_inc(&org->vm->refcount);
|
||||||
proc->vm = org->vm;
|
proc->vm = org->vm;
|
||||||
|
|
||||||
|
ihk_mc_spinlock_init(&proc->spin_sleep_lock);
|
||||||
|
proc->spin_sleep = 0;
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void __host_update_process_range(struct process *process,
|
extern void __host_update_process_range(struct process *process,
|
||||||
struct vm_range *range);
|
struct vm_range *range);
|
||||||
|
|
||||||
void update_process_page_table(struct process *process, struct vm_range *range,
|
static int update_process_page_table(struct process *process,
|
||||||
enum ihk_mc_pt_attribute flag)
|
struct vm_range *range, enum ihk_mc_pt_attribute flag)
|
||||||
{
|
{
|
||||||
unsigned long p, pa = range->phys;
|
unsigned long p, pa = range->phys;
|
||||||
|
unsigned long pp;
|
||||||
ihk_mc_spinlock_lock_noirq(&process->vm->page_table_lock);
|
unsigned long flags = ihk_mc_spinlock_lock(&process->vm->page_table_lock);
|
||||||
p = range->start;
|
p = range->start;
|
||||||
while (p < range->end) {
|
while (p < range->end) {
|
||||||
#ifdef USE_LARGE_PAGES
|
#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,
|
if (ihk_mc_pt_set_large_page(process->vm->page_table, (void *)p,
|
||||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0) {
|
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0) {
|
||||||
kprintf("ERROR:setting large page for 0x%lX -> 0x%lX\n", p, pa);
|
goto err;
|
||||||
panic("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dkprintf("large page set for 0x%lX -> 0x%lX\n", p, pa);
|
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 {
|
else {
|
||||||
#endif
|
#endif
|
||||||
ihk_mc_pt_set_page(process->vm->page_table, (void *)p,
|
if(ihk_mc_pt_set_page(process->vm->page_table, (void *)p,
|
||||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag);
|
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0){
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
pa += PAGE_SIZE;
|
pa += PAGE_SIZE;
|
||||||
p += PAGE_SIZE;
|
p += PAGE_SIZE;
|
||||||
@ -121,9 +142,36 @@ void update_process_page_table(struct process *process, struct vm_range *range,
|
|||||||
}
|
}
|
||||||
#endif
|
#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,
|
int add_process_large_range(struct process *process,
|
||||||
unsigned long start, unsigned long end,
|
unsigned long start, unsigned long end,
|
||||||
unsigned long flag, unsigned long *phys)
|
unsigned long flag, unsigned long *phys)
|
||||||
@ -133,7 +181,15 @@ int add_process_large_range(struct process *process,
|
|||||||
int npages_allocated = 0;
|
int npages_allocated = 0;
|
||||||
void *virt;
|
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) {
|
if (!range) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -149,7 +205,7 @@ int add_process_large_range(struct process *process,
|
|||||||
npages_allocated += 64) {
|
npages_allocated += 64) {
|
||||||
struct vm_range sub_range;
|
struct vm_range sub_range;
|
||||||
|
|
||||||
virt = ihk_mc_alloc_pages(64, 0);
|
virt = ihk_mc_alloc_pages(64, IHK_MC_AP_NOWAIT);
|
||||||
if (!virt) {
|
if (!virt) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -179,15 +235,24 @@ int add_process_large_range(struct process *process,
|
|||||||
list_add_tail(&range->list, &process->vm->vm_range_list);
|
list_add_tail(&range->list, &process->vm->vm_range_list);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int add_process_memory_range(struct process *process,
|
int add_process_memory_range(struct process *process,
|
||||||
unsigned long start, unsigned long end,
|
unsigned long start, unsigned long end,
|
||||||
unsigned long phys, unsigned long flag)
|
unsigned long phys, unsigned long flag)
|
||||||
{
|
{
|
||||||
struct vm_range *range;
|
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) {
|
if (!range) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -202,11 +267,15 @@ int add_process_memory_range(struct process *process,
|
|||||||
range->end - range->start, range->end - range->start);
|
range->end - range->start, range->end - range->start);
|
||||||
|
|
||||||
if (flag & VR_REMOTE) {
|
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) {
|
} else if (flag & VR_IO_NOCACHE) {
|
||||||
update_process_page_table(process, range, PTATTR_UNCACHABLE);
|
rc = update_process_page_table(process, range, PTATTR_UNCACHABLE);
|
||||||
} else {
|
} 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.
|
#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 argc, char **argv,
|
||||||
int envc, char **env)
|
int envc, char **env)
|
||||||
{
|
{
|
||||||
int s_ind = 0;
|
int s_ind = 0;
|
||||||
int arg_ind;
|
int arg_ind;
|
||||||
char *stack = ihk_mc_alloc_pages(USER_STACK_NR_PAGES, 0);
|
unsigned long size = USER_STACK_NR_PAGES * PAGE_SIZE;
|
||||||
unsigned long *p = (unsigned long *)(stack +
|
char *stack = ihk_mc_alloc_pages(USER_STACK_NR_PAGES, IHK_MC_AP_NOWAIT);
|
||||||
(USER_STACK_NR_PAGES * PAGE_SIZE));
|
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 -
|
memset(stack, 0, size);
|
||||||
(USER_STACK_NR_PAGES * PAGE_SIZE),
|
|
||||||
USER_END,
|
if((rc = add_process_memory_range(process, start, end, virt_to_phys(stack), VR_STACK)) != 0){
|
||||||
virt_to_phys(stack), VR_STACK);
|
ihk_mc_free_pages(stack, USER_STACK_NR_PAGES);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
s_ind = -1;
|
s_ind = -1;
|
||||||
p[s_ind--] = 0; /* AT_NULL */
|
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;
|
p[s_ind] = argc;
|
||||||
|
|
||||||
ihk_mc_modify_user_context(process->uctx, IHK_UCR_STACK_POINTER,
|
ihk_mc_modify_user_context(process->uctx, IHK_UCR_STACK_POINTER,
|
||||||
USER_END + sizeof(unsigned long) * s_ind);
|
end + sizeof(unsigned long) * s_ind);
|
||||||
process->vm->region.stack_end = USER_END;
|
process->vm->region.stack_end = end;
|
||||||
process->vm->region.stack_start = USER_END -
|
process->vm->region.stack_start = start;
|
||||||
(USER_STACK_NR_PAGES * PAGE_SIZE);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -280,6 +355,7 @@ unsigned long extend_process_region(struct process *proc,
|
|||||||
{
|
{
|
||||||
unsigned long aligned_end, aligned_new_end;
|
unsigned long aligned_end, aligned_new_end;
|
||||||
void *p;
|
void *p;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (!address || address < start || address >= USER_END) {
|
if (!address || address < start || address >= USER_END) {
|
||||||
return 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;
|
aligned_end = (aligned_end + (LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
||||||
/* Fill in the gap between old_aligned_end and aligned_end
|
/* Fill in the gap between old_aligned_end and aligned_end
|
||||||
* with regular pages */
|
* with regular pages */
|
||||||
p = allocate_pages((aligned_end - old_aligned_end) >> PAGE_SHIFT, 0);
|
if((p = allocate_pages((aligned_end - old_aligned_end) >> PAGE_SHIFT,
|
||||||
add_process_memory_range(proc, old_aligned_end, aligned_end,
|
IHK_MC_AP_NOWAIT)) == NULL){
|
||||||
virt_to_phys(p), 0);
|
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",
|
dkprintf("filled in gap for LARGE_PAGE_SIZE aligned start: 0x%lX -> 0x%lX\n",
|
||||||
old_aligned_end, aligned_end);
|
old_aligned_end, aligned_end);
|
||||||
@ -316,17 +398,26 @@ unsigned long extend_process_region(struct process *proc,
|
|||||||
(LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
(LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
||||||
address = aligned_new_end;
|
address = aligned_new_end;
|
||||||
|
|
||||||
p = allocate_pages((aligned_new_end - aligned_end + LARGE_PAGE_SIZE)
|
if((p = allocate_pages((aligned_new_end - aligned_end + LARGE_PAGE_SIZE) >> PAGE_SHIFT,
|
||||||
>> PAGE_SHIFT, 0);
|
IHK_MC_AP_NOWAIT)) == NULL){
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
p_aligned = ((unsigned long)p + (LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
p_aligned = ((unsigned long)p + (LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
||||||
|
|
||||||
if (p_aligned > (unsigned long)p) {
|
if (p_aligned > (unsigned long)p) {
|
||||||
free_pages(p, (p_aligned - (unsigned long)p) >> PAGE_SHIFT);
|
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,
|
if((rc = add_process_memory_range(proc, aligned_end,
|
||||||
virt_to_phys((void *)p_aligned), flag);
|
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",
|
dkprintf("largePTE area: 0x%lX - 0x%lX (s: %lu) -> 0x%lX - \n",
|
||||||
aligned_end, aligned_new_end,
|
aligned_end, aligned_new_end,
|
||||||
@ -337,14 +428,17 @@ unsigned long extend_process_region(struct process *proc,
|
|||||||
}
|
}
|
||||||
#endif
|
#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) {
|
if (!p) {
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_process_memory_range(proc, aligned_end, aligned_new_end,
|
if((rc = add_process_memory_range(proc, aligned_end, aligned_new_end,
|
||||||
virt_to_phys(p), flag);
|
virt_to_phys(p), flag)) != 0){
|
||||||
|
free_pages(p, (aligned_new_end - aligned_end) >> PAGE_SHIFT);
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
@ -372,12 +466,18 @@ extern void print_free_list(void);
|
|||||||
void free_process_memory(struct process *proc)
|
void free_process_memory(struct process *proc)
|
||||||
{
|
{
|
||||||
struct vm_range *range, *next;
|
struct vm_range *range, *next;
|
||||||
|
struct process_vm *vm = proc->vm;
|
||||||
|
|
||||||
if (!ihk_atomic_dec_and_test(&proc->vm->refcount)) {
|
if (vm == NULL) {
|
||||||
return;
|
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) {
|
list) {
|
||||||
if (!(range->flag & VR_REMOTE) &&
|
if (!(range->flag & VR_REMOTE) &&
|
||||||
!(range->flag & VR_IO_NOCACHE) &&
|
!(range->flag & VR_IO_NOCACHE) &&
|
||||||
@ -389,13 +489,33 @@ void free_process_memory(struct process *proc)
|
|||||||
list_del(&range->list);
|
list_del(&range->list);
|
||||||
ihk_mc_free(range);
|
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)
|
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)
|
static void idle(void)
|
||||||
@ -443,6 +563,7 @@ void schedule(void)
|
|||||||
struct process *next, *prev, *proc, *tmp = NULL;
|
struct process *next, *prev, *proc, *tmp = NULL;
|
||||||
int switch_ctx = 0;
|
int switch_ctx = 0;
|
||||||
unsigned long irqstate;
|
unsigned long irqstate;
|
||||||
|
struct process *last;
|
||||||
|
|
||||||
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
||||||
|
|
||||||
@ -455,10 +576,14 @@ void schedule(void)
|
|||||||
--v->runq_len;
|
--v->runq_len;
|
||||||
|
|
||||||
/* Round-robin if not exited yet */
|
/* 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));
|
list_add_tail(&prev->sched_list, &(v->runq));
|
||||||
++v->runq_len;
|
++v->runq_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!v->runq_len) {
|
||||||
|
v->status = CPU_STATUS_IDLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pick a new running process */
|
/* Pick a new running process */
|
||||||
@ -479,7 +604,6 @@ void schedule(void)
|
|||||||
v->current = next;
|
v->current = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (switch_ctx) {
|
if (switch_ctx) {
|
||||||
dkprintf("[%d] schedule: %d => %d \n",
|
dkprintf("[%d] schedule: %d => %d \n",
|
||||||
ihk_mc_get_processor_id(),
|
ihk_mc_get_processor_id(),
|
||||||
@ -496,10 +620,15 @@ void schedule(void)
|
|||||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
ihk_mc_switch_context(&prev->ctx, &next->ctx);
|
last = ihk_mc_switch_context(&prev->ctx, &next->ctx, prev);
|
||||||
}
|
}
|
||||||
else {
|
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 {
|
else {
|
||||||
|
|||||||
@ -349,18 +349,24 @@ SYSCALL_DECLARE(lseek)
|
|||||||
SYSCALL_DECLARE(exit_group)
|
SYSCALL_DECLARE(exit_group)
|
||||||
{
|
{
|
||||||
SYSCALL_HEADER;
|
SYSCALL_HEADER;
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
|
|
||||||
#ifdef DCFA_KMOD
|
#ifdef DCFA_KMOD
|
||||||
do_mod_exit((int)ihk_mc_syscall_arg0(ctx));
|
do_mod_exit((int)ihk_mc_syscall_arg0(ctx));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* XXX: send SIGKILL to all threads in this process */
|
||||||
|
|
||||||
do_syscall(&request, ctx);
|
do_syscall(&request, ctx);
|
||||||
runq_del_proc(cpu_local_var(current), ihk_mc_get_processor_id());
|
|
||||||
free_process_memory(cpu_local_var(current));
|
|
||||||
|
|
||||||
//cpu_local_var(next) = &cpu_local_var(idle);
|
#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(current) = NULL;
|
|
||||||
schedule();
|
schedule();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -371,6 +377,7 @@ SYSCALL_DECLARE(mmap)
|
|||||||
{
|
{
|
||||||
struct vm_regions *region = &cpu_local_var(current)->vm->region;
|
struct vm_regions *region = &cpu_local_var(current)->vm->region;
|
||||||
unsigned long lockr;
|
unsigned long lockr;
|
||||||
|
void *va;
|
||||||
|
|
||||||
dkprintf("syscall.c,mmap,addr=%lx,len=%lx,prot=%lx,flags=%x,fd=%x,offset=%lx\n",
|
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),
|
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;
|
e = (e + (LARGE_PAGE_SIZE - 1)) & LARGE_PAGE_MASK;
|
||||||
p = (unsigned long)ihk_mc_alloc_pages(
|
if((p = (unsigned long)ihk_mc_alloc_pages(
|
||||||
(e - s + 2 * LARGE_PAGE_SIZE) >> PAGE_SHIFT, 0);
|
(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))
|
p_aligned = (p + LARGE_PAGE_SIZE + (LARGE_PAGE_SIZE - 1))
|
||||||
& LARGE_PAGE_MASK;
|
& LARGE_PAGE_MASK;
|
||||||
|
|
||||||
// add range, mapping
|
// add range, mapping
|
||||||
add_process_memory_range(cpu_local_var(current), s_orig, e,
|
if(add_process_memory_range(cpu_local_var(current), s_orig, e,
|
||||||
virt_to_phys((void *)(p_aligned - head_space)), 0);
|
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",
|
dkprintf("largePTE area: 0x%lX - 0x%lX (s: %lu) -> 0x%lX -\n",
|
||||||
s_orig, e, (e - s_orig),
|
s_orig, e, (e - s_orig),
|
||||||
@ -432,10 +444,16 @@ SYSCALL_DECLARE(mmap)
|
|||||||
else {
|
else {
|
||||||
#endif
|
#endif
|
||||||
// allocate physical address
|
// 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 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);
|
dkprintf("syscall.c,pa allocated=%lx\n", pa);
|
||||||
#ifdef USE_LARGE_PAGES
|
#ifdef USE_LARGE_PAGES
|
||||||
@ -536,7 +554,7 @@ SYSCALL_DECLARE(mmap)
|
|||||||
dkprintf("syscall.c,!MAP_FIXED,!MAP_ANONYMOUS,MAP_PRIVATE\n");
|
dkprintf("syscall.c,!MAP_FIXED,!MAP_ANONYMOUS,MAP_PRIVATE\n");
|
||||||
// lseek(mmap_fd, mmap_off, SEEK_SET);
|
// lseek(mmap_fd, mmap_off, SEEK_SET);
|
||||||
// read(mmap_fd, mmap_addr, mmap_len);
|
// 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]
|
// overwriting request.args[0]
|
||||||
unsigned long __phys;
|
unsigned long __phys;
|
||||||
if (ihk_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, (void *)s, &__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)
|
SYSCALL_DECLARE(exit)
|
||||||
{
|
{
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
|
|
||||||
#ifdef DCFA_KMOD
|
#ifdef DCFA_KMOD
|
||||||
do_mod_exit((int)ihk_mc_syscall_arg0(ctx));
|
do_mod_exit((int)ihk_mc_syscall_arg0(ctx));
|
||||||
#endif
|
#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.
|
/* If there is a clear_child_tid address set, clear it and wake it.
|
||||||
* This unblocks any pthread_join() waiters. */
|
* 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");
|
dkprintf("exit clear_child!\n");
|
||||||
|
|
||||||
*cpu_local_var(current)->thread.clear_child_tid = 0;
|
*proc->thread.clear_child_tid = 0;
|
||||||
barrier();
|
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);
|
FUTEX_WAKE, 1, 0, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
runq_del_proc(cpu_local_var(current), cpu_local_var(current)->cpu_id);
|
proc->status = PS_ZOMBIE;
|
||||||
free_process_memory(cpu_local_var(current));
|
if (IS_DETACHED_PROCESS(proc)) {
|
||||||
|
/* release a reference for wait(2) */
|
||||||
|
proc->status = PS_EXITED;
|
||||||
|
free_process(proc);
|
||||||
|
}
|
||||||
|
|
||||||
cpu_local_var(current) = NULL;
|
|
||||||
schedule();
|
schedule();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1018,7 +1044,7 @@ SYSCALL_DECLARE(sched_getaffinity)
|
|||||||
|
|
||||||
CPU_ZERO_S(min_len, mask);
|
CPU_ZERO_S(min_len, mask);
|
||||||
for (cpu_id = 0; cpu_id < min_ncpus; ++cpu_id)
|
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");
|
// dkprintf("sched_getaffinity returns full mask\n");
|
||||||
|
|
||||||
@ -1033,18 +1059,31 @@ SYSCALL_DECLARE(noop)
|
|||||||
|
|
||||||
#ifdef DCFA_KMOD
|
#ifdef DCFA_KMOD
|
||||||
|
|
||||||
|
#ifdef CMD_DCFA
|
||||||
extern int ibmic_cmd_syscall(char *uargs);
|
extern int ibmic_cmd_syscall(char *uargs);
|
||||||
extern int dcfampi_cmd_syscall(char *uargs);
|
|
||||||
extern void ibmic_cmd_exit(int status);
|
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 *) = {
|
static int (*mod_call_table[]) (char *) = {
|
||||||
|
#ifdef CMD_DCFA
|
||||||
[1] = ibmic_cmd_syscall,
|
[1] = ibmic_cmd_syscall,
|
||||||
|
#endif
|
||||||
|
#ifdef CMD_DCFAMPI
|
||||||
[2] = dcfampi_cmd_syscall,
|
[2] = dcfampi_cmd_syscall,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void (*mod_exit_table[]) (int) = {
|
static void (*mod_exit_table[]) (int) = {
|
||||||
|
#ifdef CMD_DCFA
|
||||||
[1] = ibmic_cmd_exit,
|
[1] = ibmic_cmd_exit,
|
||||||
|
#endif
|
||||||
|
#ifdef CMD_DCFAMPI
|
||||||
[2] = NULL,
|
[2] = NULL,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
SYSCALL_DECLARE(mod_call) {
|
SYSCALL_DECLARE(mod_call) {
|
||||||
@ -1059,6 +1098,8 @@ SYSCALL_DECLARE(mod_call) {
|
|||||||
if(mod_call_table[mod_id])
|
if(mod_call_table[mod_id])
|
||||||
return mod_call_table[mod_id]((char*)uargs);
|
return mod_call_table[mod_id]((char*)uargs);
|
||||||
|
|
||||||
|
kprintf("ERROR! undefined mod_call id:%d\n", mod_id);
|
||||||
|
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1239,6 +1280,14 @@ static int clone_init(void)
|
|||||||
|
|
||||||
#endif
|
#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 syscall(int num, ihk_mc_user_context_t *ctx)
|
||||||
{
|
{
|
||||||
long l;
|
long l;
|
||||||
@ -1272,7 +1321,8 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
|||||||
dkprintf("\n");
|
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);
|
l = syscall_table[num](num, ctx);
|
||||||
|
|
||||||
dkprintf("SC(%d)[%3d] ret: %d\n",
|
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_arg2(ctx), ihk_mc_syscall_arg3(ctx),
|
||||||
ihk_mc_syscall_arg4(ctx), ihk_mc_syscall_pc(ctx),
|
ihk_mc_syscall_arg4(ctx), ihk_mc_syscall_pc(ctx),
|
||||||
ihk_mc_syscall_sp(ctx));
|
ihk_mc_syscall_sp(ctx));
|
||||||
//while(1);
|
l = syscall_generic_forwarding(num, ctx);
|
||||||
l = -ENOSYS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
|
|||||||
@ -50,8 +50,11 @@ void ihk_mc_init_ap(void);
|
|||||||
void ihk_mc_init_context(ihk_mc_kernel_context_t *new_ctx,
|
void ihk_mc_init_context(ihk_mc_kernel_context_t *new_ctx,
|
||||||
void *stack_pointer,
|
void *stack_pointer,
|
||||||
void (*next_function)(void));
|
void (*next_function)(void));
|
||||||
void ihk_mc_switch_context(ihk_mc_kernel_context_t *old_ctx,
|
|
||||||
ihk_mc_kernel_context_t *new_ctx);
|
/* returns the 'prev' argument of the call that caused the switch to the context returned. */
|
||||||
|
void *ihk_mc_switch_context(ihk_mc_kernel_context_t *old_ctx,
|
||||||
|
ihk_mc_kernel_context_t *new_ctx,
|
||||||
|
void *prev);
|
||||||
int ihk_mc_interrupt_cpu(int cpu, int vector);
|
int ihk_mc_interrupt_cpu(int cpu, int vector);
|
||||||
|
|
||||||
void ihk_mc_init_user_process(ihk_mc_kernel_context_t *ctx,
|
void ihk_mc_init_user_process(ihk_mc_kernel_context_t *ctx,
|
||||||
|
|||||||
@ -22,6 +22,9 @@ enum ihk_mc_ma_type {
|
|||||||
|
|
||||||
enum ihk_mc_ap_flag {
|
enum ihk_mc_ap_flag {
|
||||||
IHK_MC_AP_FLAG,
|
IHK_MC_AP_FLAG,
|
||||||
|
IHK_MC_AP_CRITICAL, /* panic on no memory space */
|
||||||
|
IHK_MC_AP_NOWAIT, /* error return on no memory space */
|
||||||
|
IHK_MC_AP_WAIT /* wait on no memory space */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ihk_mc_pt_prepare_flag {
|
enum ihk_mc_pt_prepare_flag {
|
||||||
@ -88,10 +91,13 @@ int ihk_mc_pt_set_large_page(page_table_t pt, void *virt,
|
|||||||
int ihk_mc_pt_change_page(page_table_t pt, void *virt,
|
int ihk_mc_pt_change_page(page_table_t pt, void *virt,
|
||||||
enum ihk_mc_pt_attribute);
|
enum ihk_mc_pt_attribute);
|
||||||
int ihk_mc_pt_clear_page(page_table_t pt, void *virt);
|
int ihk_mc_pt_clear_page(page_table_t pt, void *virt);
|
||||||
|
int ihk_mc_pt_clear_large_page(page_table_t pt, void *virt);
|
||||||
int ihk_mc_pt_prepare_map(page_table_t pt, void *virt, unsigned long size,
|
int ihk_mc_pt_prepare_map(page_table_t pt, void *virt, unsigned long size,
|
||||||
enum ihk_mc_pt_prepare_flag);
|
enum ihk_mc_pt_prepare_flag);
|
||||||
|
|
||||||
struct page_table *ihk_mc_pt_create(void);
|
struct page_table *ihk_mc_pt_create(enum ihk_mc_ap_flag ap_flag);
|
||||||
|
/* XXX: proper use of struct page_table and page_table_t is unknown */
|
||||||
|
void ihk_mc_pt_destroy(struct page_table *pt);
|
||||||
void ihk_mc_load_page_table(struct page_table *pt);
|
void ihk_mc_load_page_table(struct page_table *pt);
|
||||||
int ihk_mc_pt_virt_to_phys(struct page_table *pt,
|
int ihk_mc_pt_virt_to_phys(struct page_table *pt,
|
||||||
void *virt, unsigned long *phys);
|
void *virt, unsigned long *phys);
|
||||||
|
|||||||
@ -44,17 +44,17 @@ void *__ihk_pagealloc_init(unsigned long start, unsigned long size,
|
|||||||
desc = initial;
|
desc = initial;
|
||||||
*pdescsize = descsize;
|
*pdescsize = descsize;
|
||||||
} else {
|
} else {
|
||||||
desc = (void *)allocate_pages(descsize, 0);
|
desc = (void *)allocate_pages(descsize, IHK_MC_AP_CRITICAL);
|
||||||
}
|
}
|
||||||
flag = descsize;
|
|
||||||
memset(desc, 0, descsize * PAGE_SIZE);
|
|
||||||
|
|
||||||
if (!desc) {
|
if (!desc) {
|
||||||
kprintf("IHK: failed to allocate page-allocator-desc "\
|
kprintf("IHK: failed to allocate page-allocator-desc "\
|
||||||
"(%lx, %lx, %lx)\n", start, size, unit);
|
"(%lx, %lx, %lx)\n", start, size, unit);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flag = descsize;
|
||||||
|
memset(desc, 0, descsize * PAGE_SIZE);
|
||||||
|
|
||||||
desc->start = start;
|
desc->start = start;
|
||||||
desc->last = 0;
|
desc->last = 0;
|
||||||
desc->count = mapaligned >> 3;
|
desc->count = mapaligned >> 3;
|
||||||
@ -88,10 +88,21 @@ void ihk_pagealloc_destroy(void *__desc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long __ihk_pagealloc_large(struct ihk_page_allocator_desc *desc,
|
static unsigned long __ihk_pagealloc_large(struct ihk_page_allocator_desc *desc,
|
||||||
int nblocks)
|
int npages)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int i, j, mi;
|
unsigned int i, j, mi;
|
||||||
|
int nblocks;
|
||||||
|
int nfrags;
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
nblocks = (npages / 64);
|
||||||
|
mask = -1;
|
||||||
|
nfrags = (npages % 64);
|
||||||
|
if (nfrags > 0) {
|
||||||
|
++nblocks;
|
||||||
|
mask = (1UL << nfrags) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
flags = ihk_mc_spinlock_lock(&desc->lock);
|
flags = ihk_mc_spinlock_lock(&desc->lock);
|
||||||
for (i = 0, mi = desc->last; i < desc->count; i++, mi++) {
|
for (i = 0, mi = desc->last; i < desc->count; i++, mi++) {
|
||||||
@ -101,15 +112,16 @@ static unsigned long __ihk_pagealloc_large(struct ihk_page_allocator_desc *desc,
|
|||||||
if (mi + nblocks >= desc->count) {
|
if (mi + nblocks >= desc->count) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (j = mi; j < mi + nblocks; j++) {
|
for (j = mi; j < mi + nblocks - 1; j++) {
|
||||||
if (desc->map[j]) {
|
if (desc->map[j]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j == mi + nblocks) {
|
if ((j == (mi + nblocks - 1)) && !(desc->map[j] & mask)) {
|
||||||
for (j = mi; j < mi + nblocks; j++) {
|
for (j = mi; j < mi + nblocks - 1; j++) {
|
||||||
desc->map[j] = (unsigned long)-1;
|
desc->map[j] = (unsigned long)-1;
|
||||||
}
|
}
|
||||||
|
desc->map[j] |= mask;
|
||||||
ihk_mc_spinlock_unlock(&desc->lock, flags);
|
ihk_mc_spinlock_unlock(&desc->lock, flags);
|
||||||
return ADDRESS(desc, mi, 0);
|
return ADDRESS(desc, mi, 0);
|
||||||
}
|
}
|
||||||
@ -126,10 +138,8 @@ unsigned long ihk_pagealloc_alloc(void *__desc, int npages)
|
|||||||
int j;
|
int j;
|
||||||
unsigned long v, mask, flags;
|
unsigned long v, mask, flags;
|
||||||
|
|
||||||
/* If requested page is more than the half of the element,
|
|
||||||
* we allocate the whole element (ulong) */
|
|
||||||
if (npages >= 32) {
|
if (npages >= 32) {
|
||||||
return __ihk_pagealloc_large(desc, (npages + 63) >> 6);
|
return __ihk_pagealloc_large(desc, npages);
|
||||||
}
|
}
|
||||||
|
|
||||||
mask = (1UL << npages) - 1;
|
mask = (1UL << npages) - 1;
|
||||||
@ -191,9 +201,6 @@ void ihk_pagealloc_free(void *__desc, unsigned long address, int npages)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/* XXX: Parameter check */
|
/* XXX: Parameter check */
|
||||||
if (npages >= 32) {
|
|
||||||
npages = (npages + 63) & ~63;
|
|
||||||
}
|
|
||||||
flags = ihk_mc_spinlock_lock(&desc->lock);
|
flags = ihk_mc_spinlock_lock(&desc->lock);
|
||||||
mi = (address - desc->start) >> desc->shift;
|
mi = (address - desc->start) >> desc->shift;
|
||||||
for (i = 0; i < npages; i++, mi++) {
|
for (i = 0; i < npages; i++, mi++) {
|
||||||
|
|||||||
104
make.sh
104
make.sh
@ -1,104 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
MOPT=
|
|
||||||
OPT=
|
|
||||||
ihkdir=`pwd`/../ihk
|
|
||||||
installdir=
|
|
||||||
kerneldir=
|
|
||||||
target=
|
|
||||||
cleanflag=
|
|
||||||
while [ "X$1" != X ]; do
|
|
||||||
case "$1" in
|
|
||||||
clean)
|
|
||||||
cleanflag=1
|
|
||||||
;;
|
|
||||||
installdir=*)
|
|
||||||
installdir="`echo $1 | sed 's/^installdir=//'`"
|
|
||||||
;;
|
|
||||||
ihkdir=*)
|
|
||||||
ihkdir="`echo $1 | sed 's/^ihkdir=//'`"
|
|
||||||
;;
|
|
||||||
kerneldir=*)
|
|
||||||
kerneldir="`echo $1 | sed 's/^kerneldir=//'`"
|
|
||||||
;;
|
|
||||||
target=*)
|
|
||||||
target="`echo $1 | sed 's/^target=//'`"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "unknown option $1" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "X$cleanflag" != X ]; then
|
|
||||||
(cd executer/kernel; make clean)
|
|
||||||
(cd executer/user; make clean)
|
|
||||||
rm -rf kernel/build
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "X$target" = X ]; then
|
|
||||||
if [ -f $ihkdir/target ]; then
|
|
||||||
target="`cat $ihkdir/target`"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ "X$target" = X ]; then
|
|
||||||
target=attached-mic
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "X$kerneldir" = X ]; then
|
|
||||||
if [ -f $ihkdir/kerneldir ]; then
|
|
||||||
kerneldir="`cat $ihkdir/kerneldir`"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "X$kerneldir" != X ]; then
|
|
||||||
MOPT="KDIR=$kerneldir"
|
|
||||||
fi
|
|
||||||
if [ "X$target" = "Xbuiltin-mic" ]; then
|
|
||||||
MOPT="$MOPT ARCH=k1om"
|
|
||||||
OPT="CC=x86_64-k1om-linux-gcc"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "X$installdir" != X ]; then
|
|
||||||
mkdir -p "$installdir"
|
|
||||||
fi
|
|
||||||
(cd executer/kernel; make $MOPT)
|
|
||||||
if [ -f executer/kernel/mcctrl.ko ]; then
|
|
||||||
if [ "X$installdir" != X ]; then
|
|
||||||
cp executer/kernel/mcctrl.ko "$installdir"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "executer/kernel/mcctrl.ko could not be built" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$target" in
|
|
||||||
attached-mic | builtin-x86 | builtin-mic)
|
|
||||||
(cd kernel; mkdir -p build; make O=`pwd`/build BUILD_TARGET=$target)
|
|
||||||
krn=kernel/build/$target/kernel.img
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "unknown target $target" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
if [ -f $krn ]; then
|
|
||||||
if [ "X$installdir" != X ]; then
|
|
||||||
cp $krn "$installdir"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "$krn could not be built" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
(cd executer/user; make $OPT)
|
|
||||||
if [ -f executer/user/mcexec ]; then
|
|
||||||
if [ "X$installdir" != X ]; then
|
|
||||||
cp executer/user/mcexec "$installdir"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "executer/user/mcexec could not be built" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user