add arm64 support

- add arm64 dependent codes with GICv3 and SVE support
- fix bugs based on architecture separation requests
This commit is contained in:
Takayuki Okamoto
2017-09-05 15:06:27 +09:00
parent 704096b139
commit 9989f41fd3
192 changed files with 26941 additions and 34 deletions

View File

@@ -1,3 +1,4 @@
# Makefile.build.in COPYRIGHT FUJITSU LIMITED 2015-2016
VPATH=@abs_srcdir@
SRC=$(VPATH)
IHKDIR=$(IHKBASE)/$(TARGETDIR)
@@ -6,22 +7,30 @@ OBJS += process.o copy.o waitq.o futex.o timer.o plist.o fileobj.o shmobj.o
OBJS += zeroobj.o procfs.o devobj.o sysfs.o xpmem.o profile.o freeze.o
OBJS += rbtree.o
OBJS += pager.o
# POSTK_DEBUG_ARCH_DEP_18 coredump arch separation.
# OBJS added gencore.o
OBJS += gencore.o
DEPSRCS=$(wildcard $(SRC)/*.c)
CFLAGS += -I$(SRC)/include -I@abs_builddir@/../ -I@abs_builddir@/include -D__KERNEL__ -g -fno-omit-frame-pointer -fno-inline -fno-inline-small-functions
LDFLAGS += -e arch_start
IHKOBJ = ihk/ihk.o
# POSTK_DEBUG_ARCH_DEP_24
default: all
include $(SRC)/config/config.$(TARGET)
include @abs_builddir@/../../ihk/cokernel/Makefile.common
# CFLAGS += -I$(SRC)/../arch/$(IHKARCH)/kernel/include -I$(SRC)/../lib/include
SUBCMD_OPTS = TARGET=$(TARGET) O=$(CURDIR)/ihk CC=$(CC) LD=$(LD) SRC=$(SRC)
OBJDUMP ?= objdump
OBJCOPY ?= objcopy
# POSTK_DEBUG_ARCH_DEP_26
#SUBCMD_OPTS = TARGET=$(TARGET) O=$(CURDIR)/ihk CC=$(CC) LD=$(LD) SRC=$(SRC)
SUBCMD_OPTS = TARGET=$(TARGET) O=$(CURDIR)/ihk CC=$(CC) LD=$(LD) OBJCOPY=$(OBJCOPY) SRC=$(SRC)
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 $@

View File

@@ -1,3 +1,4 @@
/* ap.c COPYRIGHT FUJITSU LIMITED 2015 */
/**
* \file ap.c
* Licence details are found in the file LICENSE.

View File

@@ -0,0 +1,39 @@
CC = ${CROSS_COMPILE}gcc
LD = ${CROSS_COMPILE}ld
OBJDUMP = ${CROSS_COMPILE}objdump
OBJCOPY = ${CROSS_COMPILE}objcopy
# ARM64_MEMORY_LAYOUT
# ----+-----------+-----------------------
# # | page size | virtual memory space
# ----+-----------+-----------------------
# 1 | 4KB | 39bit [linux-linaro-tracking, upstream kernel]
# 2 | 4KB | 48bit
# 3 | 64KB | 42bit [CentOS]
# 4 | 64KB | 48bit
# ----+-----------+-----------------------
HOST_DIR=@KDIR@
HOST_CONFIG=$(HOST_DIR)/.config
HOST_KERNEL_CONFIG_ARM64_64K_PAGES=$(shell grep -E "^CONFIG_ARM64_64K_PAGES=y" $(HOST_CONFIG) | sed 's|CONFIG_ARM64_64K_PAGES=||g')
HOST_KERNEL_CONFIG_ARM64_VA_BITS=$(shell grep -E "^CONFIG_ARM64_VA_BITS=" $(HOST_CONFIG) | sed 's|CONFIG_ARM64_VA_BITS=||g')
ifeq ($(HOST_KERNEL_CONFIG_ARM64_64K_PAGES), y)
ifeq ($(HOST_KERNEL_CONFIG_ARM64_VA_BITS), 42)
$(info PAGE_SIZE:64KB VA_BITS:42 PGTABLE_LEVELS:2)
ARM64_MEMORY_LAYOUT=3
else
$(info PAGE_SIZE:64KB VA_BITS:48, PGTABLE_LEVELS:3)
ARM64_MEMORY_LAYOUT=4
endif
else
ifeq ($(HOST_KERNEL_CONFIG_ARM64_VA_BITS), 39)
$(info PAGE_SIZE:4KB VA_BITS:39 PGTABLE_LEVELS:3)
ARM64_MEMORY_LAYOUT=1
else
$(info PAGE_SIZE:4KB VA_BITS:48 PGTABLE_LEVELS:4)
ARM64_MEMORY_LAYOUT=2
endif
endif
$(info linker script:smp-arm64_type$(ARM64_MEMORY_LAYOUT).lds)
LDFLAGS += -T $(SRC)/config/smp-arm64_type$(ARM64_MEMORY_LAYOUT).lds

View File

@@ -0,0 +1,50 @@
PHDRS
{
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(7);
}
SECTIONS
{
. = 0xffffffffff800000; /* KERNEL_START */
_head = .;
.text : {
*(.text);
} : text
. = ALIGN(0x1000);
.data : {
*(.data)
*(.data.*)
} :data
.rodata : {
*(.rodata .rodata.*)
} :data
.vdso : ALIGN(0x1000) {
vdso_page = .;
. = vdso_page + 0x0000;
*(.vdso.data)
. = vdso_page + 0x1000;
*(.vdso.text)
. = ALIGN(0x1000);
} : data = 0xf4
.bss : {
*(.bss .bss.*)
}
. = ALIGN(0x1000);
idmap_page_table = .;
. += 0x1000; /* PAGE_SIZE */
swapper_page_table = .;
. += 0x1000; /* PAGE_SIZE */
idmap_pg_dir = .;
. += 0x3000; /* IDMAP_DIR_SIZE */
swapper_pg_dir = .;
. += 0x2000; /* SWAPPER_DIR_SIZE */
_end = .;
}

View File

@@ -0,0 +1,50 @@
PHDRS
{
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(7);
}
SECTIONS
{
. = 0xffffffffff800000; /* KERNEL_START */
_head = .;
.text : {
*(.text);
} : text
. = ALIGN(0x1000);
.data : {
*(.data)
*(.data.*)
} :data
.rodata : {
*(.rodata .rodata.*)
} :data
.vdso : ALIGN(0x1000) {
vdso_page = .;
. = vdso_page + 0x0000;
*(.vdso.data)
. = vdso_page + 0x1000;
*(.vdso.text)
. = ALIGN(0x1000);
} : data = 0xf4
.bss : {
*(.bss .bss.*)
}
. = ALIGN(0x1000);
idmap_page_table = .;
. += 0x1000; /* PAGE_SIZE */
swapper_page_table = .;
. += 0x1000; /* PAGE_SIZE */
idmap_pg_dir = .;
. += 0x3000; /* IDMAP_DIR_SIZE */
swapper_pg_dir = .;
. += 0x3000; /* SWAPPER_DIR_SIZE */
_end = .;
}

View File

@@ -0,0 +1,50 @@
PHDRS
{
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(7);
}
SECTIONS
{
. = 0xffffffffe0000000; /* KERNEL_START */
_head = .;
.text : {
*(.text);
} : text
. = ALIGN(0x10000);
.data : {
*(.data)
*(.data.*)
} :data
.rodata : {
*(.rodata .rodata.*)
} :data
.vdso : ALIGN(0x10000) {
vdso_page = .;
. = vdso_page + 0x00000;
*(.vdso.data)
. = vdso_page + 0x10000;
*(.vdso.text)
. = ALIGN(0x10000);
} : data = 0xf4
.bss : {
*(.bss .bss.*)
}
. = ALIGN(0x10000);
idmap_page_table = .;
. += 0x10000; /* PAGE_SIZE */
swapper_page_table = .;
. += 0x10000; /* PAGE_SIZE */
idmap_pg_dir = .;
. += 0x30000; /* IDMAP_DIR_SIZE */
swapper_pg_dir = .;
. += 0x20000; /* SWAPPER_DIR_SIZE */
_end = .;
}

View File

@@ -0,0 +1,50 @@
PHDRS
{
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(7);
}
SECTIONS
{
. = 0xffffffffe0000000; /* KERNEL_START */
_head = .;
.text : {
*(.text);
} : text
. = ALIGN(0x10000);
.data : {
*(.data)
*(.data.*)
} :data
.rodata : {
*(.rodata .rodata.*)
} :data
.vdso : ALIGN(0x10000) {
vdso_page = .;
. = vdso_page + 0x00000;
*(.vdso.data)
. = vdso_page + 0x10000;
*(.vdso.text)
. = ALIGN(0x10000);
} : data = 0xf4
.bss : {
*(.bss .bss.*)
}
. = ALIGN(0x10000);
idmap_page_table = .;
. += 0x10000; /* PAGE_SIZE */
swapper_page_table = .;
. += 0x10000; /* PAGE_SIZE */
idmap_pg_dir = .;
. += 0x30000; /* IDMAP_DIR_SIZE */
swapper_pg_dir = .;
. += 0x30000; /* SWAPPER_DIR_SIZE */
_end = .;
}

View File

@@ -1,3 +1,4 @@
/* devobj.c COPYRIGHT FUJITSU LIMITED 2015-2017 */
/**
* \file devobj.c
* License details are found in the file LICENSE.
@@ -87,7 +88,12 @@ int devobj_create(int fd, size_t len, off_t off, struct memobj **objp, int *maxp
int error;
struct devobj *obj = NULL;
const size_t npages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
#ifdef POSTK_DEBUG_TEMP_FIX_36
const size_t uintptr_per_page = (PAGE_SIZE / sizeof(uintptr_t));
const size_t pfn_npages = (npages + uintptr_per_page - 1) / uintptr_per_page;
#else
const size_t pfn_npages = (npages / (PAGE_SIZE / sizeof(uintptr_t))) + 1;
#endif /*POSTK_DEBUG_TEMP_FIX_36*/
dkprintf("%s: fd: %d, len: %lu, off: %lu \n", __FUNCTION__, fd, len, off);
@@ -168,8 +174,10 @@ static void devobj_release(struct memobj *memobj)
struct devobj *obj = to_devobj(memobj);
struct devobj *free_obj = NULL;
uintptr_t handle;
#ifndef POSTK_DEBUG_TEMP_FIX_36
const size_t pfn_npages =
(obj->npages / (PAGE_SIZE / sizeof(uintptr_t))) + 1;
#endif /*!POSTK_DEBUG_TEMP_FIX_36*/
dkprintf("devobj_release(%p %lx)\n", obj, obj->handle);
@@ -201,7 +209,13 @@ static void devobj_release(struct memobj *memobj)
if (obj->pfn_table) {
// Don't call memory_stat_rss_sub() because devobj related pages don't reside in main memory
#ifdef POSTK_DEBUG_TEMP_FIX_36
const size_t uintptr_per_page = (PAGE_SIZE / sizeof(uintptr_t));
const size_t pfn_npages = (obj->npages + uintptr_per_page - 1) / uintptr_per_page;
ihk_mc_free_pages(obj->pfn_table, pfn_npages);
#else
ihk_mc_free_pages(obj->pfn_table, pfn_npages);
#endif /*POSTK_DEBUG_TEMP_FIX_36*/
}
kfree(free_obj);
}
@@ -258,7 +272,11 @@ static int devobj_get_page(struct memobj *memobj, off_t off, int p2align, uintpt
/* TODO: do an arch dependent PTE to mapping flag conversion
* instead of this inline check, also, we rely on having the
* same PAT config as Linux here.. */
#ifdef POSTK_DEBUG_ARCH_DEP_12
if (pfn_is_write_combined(pfn)) {
#else /* POSTK_DEBUG_ARCH_DEP_12 */
if ((pfn & PFL1_PWT) && !(pfn & PFL1_PCD)) {
#endif /* POSTK_DEBUG_ARCH_DEP_12 */
*flag |= VR_WRITE_COMBINED;
}

View File

@@ -1,3 +1,4 @@
/* fileobj.c COPYRIGHT FUJITSU LIMITED 2015-2017 */
/**
* \file fileobj.c
* License details are found in the file LICENSE.

499
kernel/gencore.c Normal file
View File

@@ -0,0 +1,499 @@
/* gencore.c COPYRIGHT FUJITSU LIMITED 2015-2016 */
#ifdef POSTK_DEBUG_ARCH_DEP_18 /* coredump arch separation. */
#include <ihk/debug.h>
#include <kmalloc.h>
#include <cls.h>
#include <list.h>
#include <process.h>
#include <string.h>
#include <elfcore.h>
#define align32(x) ((((x) + 3) / 4) * 4)
#define alignpage(x) ((((x) + (PAGE_SIZE) - 1) / (PAGE_SIZE)) * (PAGE_SIZE))
//#define DEBUG_PRINT_GENCORE
#ifdef DEBUG_PRINT_GENCORE
#define dkprintf(...) kprintf(__VA_ARGS__)
#define ekprintf(...) kprintf(__VA_ARGS__)
#else
#define dkprintf(...) do { if (0) kprintf(__VA_ARGS__); } while (0)
#define ekprintf(...) kprintf(__VA_ARGS__)
#endif
/*
* Generate a core file image, which consists of many chunks.
* Returns an allocated table, an etnry of which is a pair of the address
* of a chunk and its length.
*/
/**
* \brief Fill the elf header.
*
* \param eh An Elf64_Ehdr structure.
* \param segs Number of segments of the core file.
*/
void fill_elf_header(Elf64_Ehdr *eh, int segs)
{
eh->e_ident[EI_MAG0] = 0x7f;
eh->e_ident[EI_MAG1] = 'E';
eh->e_ident[EI_MAG2] = 'L';
eh->e_ident[EI_MAG3] = 'F';
eh->e_ident[EI_CLASS] = ELF_CLASS;
eh->e_ident[EI_DATA] = ELF_DATA;
eh->e_ident[EI_VERSION] = El_VERSION;
eh->e_ident[EI_OSABI] = ELF_OSABI;
eh->e_ident[EI_ABIVERSION] = ELF_ABIVERSION;
eh->e_type = ET_CORE;
eh->e_machine = ELF_ARCH;
eh->e_version = EV_CURRENT;
eh->e_entry = 0; /* Do we really need this? */
eh->e_phoff = 64; /* fixed */
eh->e_shoff = 0; /* no section header */
eh->e_flags = 0;
eh->e_ehsize = 64; /* fixed */
eh->e_phentsize = 56; /* fixed */
eh->e_phnum = segs;
eh->e_shentsize = 0;
eh->e_shnum = 0;
eh->e_shstrndx = 0;
}
/**
* \brief Return the size of the prstatus entry of the NOTE segment.
*
*/
int get_prstatus_size(void)
{
return sizeof(struct note) + align32(sizeof("CORE"))
+ align32(sizeof(struct elf_prstatus64));
}
/**
* \brief Return the size of the prpsinfo entry of the NOTE segment.
*
*/
int get_prpsinfo_size(void)
{
return sizeof(struct note) + align32(sizeof("CORE"))
+ align32(sizeof(struct elf_prpsinfo64));
}
/**
* \brief Fill a prstatus structure.
*
* \param head A pointer to a note structure.
* \param proc A pointer to the current process structure.
* \param regs0 A pointer to a ihk_mc_user_context_t structure.
*/
void fill_prstatus(struct note *head, struct thread *thread, void *regs0)
{
void *name;
struct elf_prstatus64 *prstatus;
head->namesz = sizeof("CORE");
head->descsz = sizeof(struct elf_prstatus64);
head->type = NT_PRSTATUS;
name = (void *) (head + 1);
memcpy(name, "CORE", sizeof("CORE"));
prstatus = (struct elf_prstatus64 *)(name + align32(sizeof("CORE")));
arch_fill_prstatus(prstatus, thread, regs0);
}
/**
* \brief Fill a prpsinfo structure.
*
* \param head A pointer to a note structure.
* \param proc A pointer to the current process structure.
* \param regs A pointer to a ihk_mc_user_context_t structure.
*/
void fill_prpsinfo(struct note *head, struct thread *thread, void *regs)
{
void *name;
struct elf_prpsinfo64 *prpsinfo;
head->namesz = sizeof("CORE");
head->descsz = sizeof(struct elf_prpsinfo64);
head->type = NT_PRPSINFO;
name = (void *) (head + 1);
memcpy(name, "CORE", sizeof("CORE"));
prpsinfo = (struct elf_prpsinfo64 *)(name + align32(sizeof("CORE")));
prpsinfo->pr_state = thread->status;
prpsinfo->pr_pid = thread->proc->pid;
/*
We leave most of the fields unfilled.
char pr_sname;
char pr_zomb;
char pr_nice;
a8_uint64_t pr_flag;
unsigned int pr_uid;
unsigned int pr_gid;
int pr_ppid, pr_pgrp, pr_sid;
char pr_fname[16];
char pr_psargs[ELF_PRARGSZ];
*/
}
/**
* \brief Return the size of the AUXV entry of the NOTE segment.
*
*/
int get_auxv_size(void)
{
return sizeof(struct note) + align32(sizeof("CORE"))
+ sizeof(unsigned long) * AUXV_LEN;
}
/**
* \brief Fill an AUXV structure.
*
* \param head A pointer to a note structure.
* \param proc A pointer to the current process structure.
* \param regs A pointer to a ihk_mc_user_context_t structure.
*/
void fill_auxv(struct note *head, struct thread *thread, void *regs)
{
void *name;
void *auxv;
head->namesz = sizeof("CORE");
head->descsz = sizeof(unsigned long) * AUXV_LEN;
head->type = NT_AUXV;
name = (void *) (head + 1);
memcpy(name, "CORE", sizeof("CORE"));
auxv = name + align32(sizeof("CORE"));
memcpy(auxv, thread->proc->saved_auxv, sizeof(unsigned long) * AUXV_LEN);
}
/**
* \brief Return the size of the whole NOTE segment.
*
*/
int get_note_size(void)
{
return get_prstatus_size() + get_prpsinfo_size()
+ get_auxv_size();
}
/**
* \brief Fill the NOTE segment.
*
* \param head A pointer to a note structure.
* \param proc A pointer to the current process structure.
* \param regs A pointer to a ihk_mc_user_context_t structure.
*/
void fill_note(void *note, struct thread *thread, void *regs)
{
fill_prstatus(note, thread, regs);
note += get_prstatus_size();
fill_prpsinfo(note, thread, regs);
note += get_prpsinfo_size();
fill_auxv(note, thread, regs);
}
/**
* \brief Generate an image of the core file.
*
* \param proc A pointer to the current process structure.
* \param regs A pointer to a ihk_mc_user_context_t structure.
* \param coretable(out) An array of core chunks.
* \param chunks(out) Number of the entires of coretable.
*
* A core chunk is represented by a pair of a physical
* address of memory region and its size. If there are
* no corresponding physical address for a VM area
* (an unallocated demand-paging page, e.g.), the address
* should be zero.
*/
int gencore(struct thread *thread, void *regs,
struct coretable **coretable, int *chunks)
{
struct coretable *ct = NULL;
#ifdef POSTK_DEBUG_TEMP_FIX_39
Elf64_Ehdr *eh = NULL;
#else
Elf64_Ehdr eh;
#endif /*POSTK_DEBUG_TEMP_FIX_39*/
Elf64_Phdr *ph = NULL;
void *note = NULL;
struct vm_range *range;
struct process_vm *vm = thread->vm;
int segs = 1; /* the first one is for NOTE */
int notesize, phsize, alignednotesize;
unsigned int offset = 0;
int i;
*chunks = 3; /* Elf header , header table and NOTE segment */
if (vm == NULL) {
dkprintf("no vm found.\n");
return -1;
}
list_for_each_entry(range, &vm->vm_range_list, list) {
dkprintf("start:%lx end:%lx flag:%lx objoff:%lx\n",
range->start, range->end, range->flag, range->objoff);
/* We omit reserved areas because they are only for
mckernel's internal use. */
if (range->flag & VR_RESERVED)
continue;
/* We need a chunk for each page for a demand paging area.
This can be optimized for spacial complexity but we would
lose simplicity instead. */
if (range->flag & VR_DEMAND_PAGING) {
unsigned long p, phys;
int prevzero = 0;
for (p = range->start; p < range->end; p += PAGE_SIZE) {
if (ihk_mc_pt_virt_to_phys(thread->vm->address_space->page_table,
(void *)p, &phys) != 0) {
prevzero = 1;
} else {
if (prevzero == 1)
(*chunks)++;
(*chunks)++;
prevzero = 0;
}
}
if (prevzero == 1)
(*chunks)++;
} else {
(*chunks)++;
}
segs++;
}
dkprintf("we have %d segs and %d chunks.\n\n", segs, *chunks);
{
struct vm_regions region = thread->vm->region;
dkprintf("text: %lx-%lx\n", region.text_start, region.text_end);
dkprintf("data: %lx-%lx\n", region.data_start, region.data_end);
dkprintf("brk: %lx-%lx\n", region.brk_start, region.brk_end);
dkprintf("map: %lx-%lx\n", region.map_start, region.map_end);
dkprintf("stack: %lx-%lx\n", region.stack_start, region.stack_end);
dkprintf("user: %lx-%lx\n\n", region.user_start, region.user_end);
}
dkprintf("now generate a core file image\n");
#ifdef POSTK_DEBUG_TEMP_FIX_39
eh = kmalloc(sizeof(*eh), IHK_MC_AP_NOWAIT);
if (eh == NULL) {
dkprintf("could not alloc a elf header table.\n");
goto fail;
}
#ifdef POSTK_DEBUG_TEMP_FIX_63 /* Add core table and elf header initialization */
memset(eh, 0, sizeof(*eh));
#endif /* POSTK_DEBUG_TEMP_FIX_63 */
offset += sizeof(*eh);
fill_elf_header(eh, segs);
#else
offset += sizeof(eh);
fill_elf_header(&eh, segs);
#endif /* POSTK_DEBUG_TEMP_FIX_39 */
/* program header table */
phsize = sizeof(Elf64_Phdr) * segs;
ph = kmalloc(phsize, IHK_MC_AP_NOWAIT);
if (ph == NULL) {
dkprintf("could not alloc a program header table.\n");
goto fail;
}
memset(ph, 0, phsize);
offset += phsize;
/* NOTE segment
* To align the next segment page-sized, we prepare a padded
* region for our NOTE segment.
*/
notesize = get_note_size();
alignednotesize = alignpage(notesize + offset) - offset;
note = kmalloc(alignednotesize, IHK_MC_AP_NOWAIT);
if (note == NULL) {
dkprintf("could not alloc NOTE for core.\n");
goto fail;
}
memset(note, 0, alignednotesize);
fill_note(note, thread, regs);
/* prgram header for NOTE segment is exceptional */
ph[0].p_type = PT_NOTE;
ph[0].p_flags = 0;
ph[0].p_offset = offset;
ph[0].p_vaddr = 0;
ph[0].p_paddr = 0;
ph[0].p_filesz = notesize;
ph[0].p_memsz = notesize;
ph[0].p_align = 0;
offset += alignednotesize;
/* program header for each memory chunk */
i = 1;
list_for_each_entry(range, &vm->vm_range_list, list) {
unsigned long flag = range->flag;
unsigned long size = range->end - range->start;
if (range->flag & VR_RESERVED)
continue;
ph[i].p_type = PT_LOAD;
ph[i].p_flags = ((flag & VR_PROT_READ) ? PF_R : 0)
| ((flag & VR_PROT_WRITE) ? PF_W : 0)
| ((flag & VR_PROT_EXEC) ? PF_X : 0);
ph[i].p_offset = offset;
ph[i].p_vaddr = range->start;
ph[i].p_paddr = 0;
ph[i].p_filesz = size;
ph[i].p_memsz = size;
ph[i].p_align = PAGE_SIZE;
i++;
offset += size;
}
/* coretable to send to host */
ct = kmalloc(sizeof(struct coretable) * (*chunks), IHK_MC_AP_NOWAIT);
if (!ct) {
dkprintf("could not alloc a coretable.\n");
goto fail;
}
#ifdef POSTK_DEBUG_TEMP_FIX_63 /* Add core table and elf header initialization */
memset(ct, 0, sizeof(*ct));
#endif /* POSTK_DEBUG_TEMP_FIX_63 */
#ifdef POSTK_DEBUG_TEMP_FIX_39
ct[0].addr = virt_to_phys(eh); /* ELF header */
ct[0].len = 64;
dkprintf("coretable[0]: %lx@%lx(%lx)\n", ct[0].len, ct[0].addr, eh);
#else
ct[0].addr = virt_to_phys(&eh); /* ELF header */
ct[0].len = 64;
dkprintf("coretable[0]: %lx@%lx(%lx)\n", ct[0].len, ct[0].addr, &eh);
#endif /* POSTK_DEBUG_TEMP_FIX_39 */
ct[1].addr = virt_to_phys(ph); /* program header table */
ct[1].len = phsize;
dkprintf("coretable[1]: %lx@%lx(%lx)\n", ct[1].len, ct[1].addr, ph);
ct[2].addr = virt_to_phys(note); /* NOTE segment */
ct[2].len = alignednotesize;
dkprintf("coretable[2]: %lx@%lx(%lx)\n", ct[2].len, ct[2].addr, note);
i = 3; /* memory segments */
list_for_each_entry(range, &vm->vm_range_list, list) {
unsigned long phys;
if (range->flag & VR_RESERVED)
continue;
if (range->flag & VR_DEMAND_PAGING) {
/* Just an ad hoc kluge. */
unsigned long p, start, phys;
int prevzero = 0;
unsigned long size = 0;
for (start = p = range->start;
p < range->end; p += PAGE_SIZE) {
if (ihk_mc_pt_virt_to_phys(thread->vm->address_space->page_table,
(void *)p, &phys) != 0) {
if (prevzero == 0) {
/* We begin a new chunk */
size = PAGE_SIZE;
start = p;
} else {
/* We extend the previous chunk */
size += PAGE_SIZE;
}
prevzero = 1;
} else {
if (prevzero == 1) {
/* Flush out an empty chunk */
ct[i].addr = 0;
ct[i].len = size;
dkprintf("coretable[%d]: %lx@%lx(%lx)\n", i,
ct[i].len, ct[i].addr, start);
i++;
}
ct[i].addr = phys;
ct[i].len = PAGE_SIZE;
dkprintf("coretable[%d]: %lx@%lx(%lx)\n", i,
ct[i].len, ct[i].addr, p);
i++;
prevzero = 0;
}
}
if (prevzero == 1) {
/* An empty chunk */
ct[i].addr = 0;
ct[i].len = size;
dkprintf("coretable[%d]: %lx@%lx(%lx)\n", i,
ct[i].len, ct[i].addr, start);
i++;
}
} else {
if ((thread->vm->region.user_start <= range->start) &&
(range->end <= thread->vm->region.user_end)) {
if (ihk_mc_pt_virt_to_phys(thread->vm->address_space->page_table,
(void *)range->start, &phys) != 0) {
dkprintf("could not convert user virtual address %lx"
"to physical address", range->start);
goto fail;
}
} else {
phys = virt_to_phys((void *)range->start);
}
ct[i].addr = phys;
ct[i].len = range->end - range->start;
dkprintf("coretable[%d]: %lx@%lx(%lx)\n", i,
ct[i].len, ct[i].addr, range->start);
i++;
}
}
*coretable = ct;
return 0;
fail:
if (ct)
kfree(ct);
if (ph)
kfree(ph);
if (note)
kfree(note);
return -1;
}
/**
* \brief Free all the allocated spaces for an image of the core file.
*
* \param coretable An array of core chunks.
*/
void freecore(struct coretable **coretable)
{
struct coretable *ct = *coretable;
kfree(phys_to_virt(ct[2].addr)); /* NOTE segment */
kfree(phys_to_virt(ct[1].addr)); /* ph */
#ifdef POSTK_DEBUG_TEMP_FIX_39
kfree(phys_to_virt(ct[0].addr)); /* eh */
#endif /*POSTK_DEBUG_TEMP_FIX_39*/
kfree(*coretable);
}
#endif /* POSTK_DEBUG_ARCH_DEP_18 */

View File

@@ -1,3 +1,4 @@
/* host.c COPYRIGHT FUJITSU LIMITED 2015-2016 */
/**
* \file host.c
* License details are found in the file LICENSE.

View File

@@ -1,3 +1,4 @@
/* auxvec.h COPYRIGHT FUJITSU LIMITED 2015-2016 */
#ifndef _LINUX_AUXVEC_H
#define _LINUX_AUXVEC_H

119
kernel/include/elfcore.h Normal file
View File

@@ -0,0 +1,119 @@
/* elfcore.h COPYRIGHT FUJITSU LIMITED 2015-2016 */
#ifdef POSTK_DEBUG_ARCH_DEP_18 /* coredump arch separation. */
#ifndef __HEADER_ELFCORE_H
#define __HEADER_ELFCORE_H
/*
* Structures and definitions for ELF core file.
* Extracted from
* System V Application Binary Interface - DRAFT - 10 June 2013,
* http://www.sco.com/developers/gabi/latest/contents.html
*/
#include <ihk/types.h>
typedef uint16_t Elf64_Half;
typedef uint32_t Elf64_Word;
typedef uint64_t Elf64_Xword;
typedef uint64_t Elf64_Addr;
typedef uint64_t Elf64_Off;
#define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;
/* e_ident table defined. */
/* offset */
#define EI_MAG0 0
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_OSABI 7
#define EI_ABIVERSION 8
#define EI_PAD 9
/* EI_MAG */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
/* EI_CLASS */
#define ELFCLASS64 2 /* 64-bit object */
/* EI_DATA */
#define ELFDATA2LSB 1 /* LSB */
#define ELFDATA2MSB 2 /* MSB */
/* EI_VERSION */
#define El_VERSION 1 /* defined to be the same as EV CURRENT */
#define EV_CURRENT 1 /* Current version */
/* EI_OSABI */
#define ELFOSABI_NONE 0 /* unspecied */
/* EI_ABIVERSION */
#define El_ABIVERSION_NONE 0 /* unspecied */
/* e_type defined */
#define ET_CORE 4 /* Core file */
typedef struct {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
} Elf64_Phdr;
#define PT_LOAD 1
#define PT_NOTE 4
#define PF_X 1 /* executable bit */
#define PF_W 2 /* writable bit */
#define PF_R 4 /* readable bit */
struct note {
Elf64_Word namesz;
Elf64_Word descsz;
Elf64_Word type;
/* name char[namesz] and desc[descsz] */
};
#define NT_PRSTATUS 1
#ifdef POSTK_DEBUG_ARCH_DEP_18 /* coredump arch separation. */
#define NT_PRFPREG 2
#else /* POSTK_DEBUG_ARCH_DEP_18 */
#define NT_PRFRPREG 2
#endif /* POSTK_DEBUG_ARCH_DEP_18 */
#define NT_PRPSINFO 3
#define NT_AUXV 6
#include "elfcoregpl.h"
/* functions */
struct thread;
extern void arch_fill_prstatus(struct elf_prstatus64 *prstatus, struct thread *thread, void *regs0);
#endif /* __HEADER_ELFCORE_H */
#endif /* POSTK_DEBUG_ARCH_DEP_18 */

View File

@@ -0,0 +1,67 @@
/* elfcoregpl.h COPYRIGHT FUJITSU LIMITED 2015-2016 */
#ifdef POSTK_DEBUG_ARCH_DEP_18 /* coredump arch separation. */
#ifndef __HEADER_ELFCOREGPL_H
#define __HEADER_ELFCOREGPL_H
#include <ihk/types.h>
/* From /usr/include/linux/elfcore.h of Linux */
#define ELF_PRARGSZ (80)
/* From /usr/include/linux/elfcore.h fro Linux */
struct elf_siginfo
{
int si_signo;
int si_code;
int si_errno;
};
/* From bfd/hosts/x86-64linux.h of gdb. */
typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
typedef a8_uint64_t elf_greg64_t;
#include <elf.h>
struct prstatus64_timeval
{
a8_uint64_t tv_sec;
a8_uint64_t tv_usec;
};
struct elf_prstatus64
{
struct elf_siginfo pr_info;
short int pr_cursig;
a8_uint64_t pr_sigpend;
a8_uint64_t pr_sighold;
pid_t pr_pid;
pid_t pr_ppid;
pid_t pr_pgrp;
pid_t pr_sid;
struct prstatus64_timeval pr_utime;
struct prstatus64_timeval pr_stime;
struct prstatus64_timeval pr_cutime;
struct prstatus64_timeval pr_cstime;
elf_gregset64_t pr_reg;
int pr_fpvalid;
};
struct elf_prpsinfo64
{
char pr_state;
char pr_sname;
char pr_zomb;
char pr_nice;
a8_uint64_t pr_flag;
unsigned int pr_uid;
unsigned int pr_gid;
int pr_pid, pr_ppid, pr_pgrp, pr_sid;
char pr_fname[16];
char pr_psargs[ELF_PRARGSZ];
};
#endif /* __HEADER_ELFCOREGPL_H */
#endif /* POSTK_DEBUG_ARCH_DEP_18 */

View File

@@ -1,3 +1,4 @@
/* futex.h COPYRIGHT FUJITSU LIMITED 2015-2016 */
/**
* \file futex.h
* Licence details are found in the file LICENSE.
@@ -116,6 +117,8 @@
#include <arch/system.h>
#endif
#ifdef POSTK_DEBUG_ARCH_DEP_8 /* arch depend hide */
#else
static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
@@ -180,6 +183,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
return ret;
}
#endif /* arch depend hide */
#endif // __KERNEL__
#endif // _ASM_X86_FUTEX_H

View File

@@ -38,6 +38,17 @@ extern void __chk_io_ptr(void __iomem *);
#ifdef __KERNEL__
#ifdef POSTK_DEBUG_ARCH_DEP_72
#if __GNUC__ > 5
#error no compiler-gcc.h file for this gcc version
#elif __GNUC__ == 5
# include <lwk/compiler-gcc4.h>
#elif __GNUC__ == 4
# include <lwk/compiler-gcc4.h>
#else
# error Sorry, your compiler is too old/not recognized.
#endif
#else /* POSTK_DEBUG_ARCH_DEP_72 */
#if __GNUC__ > 4
#error no compiler-gcc.h file for this gcc version
#elif __GNUC__ == 4
@@ -45,6 +56,7 @@ extern void __chk_io_ptr(void __iomem *);
#else
# error Sorry, your compiler is too old/not recognized.
#endif
#endif /* POSTK_DEBUG_ARCH_DEP_72 */
/*
* Generic compiler-dependent macros required for kernel

View File

@@ -1,3 +1,4 @@
/* memobj.h COPYRIGHT FUJITSU LIMITED 2015-2016 */
/**
* \file memobj.h
* License details are found in the file LICENSE.
@@ -19,6 +20,8 @@
#include <errno.h>
#include <list.h>
#ifdef POSTK_DEBUG_ARCH_DEP_18 /* coredump arch separation. */
#else /* POSTK_DEBUG_ARCH_DEP_18 */
/* begin types.h */
typedef int32_t key_t;
typedef uint32_t uid_t;
@@ -26,6 +29,7 @@ typedef uint32_t gid_t;
typedef int64_t time_t;
typedef int32_t pid_t;
/* end types.h */
#endif /* POSTK_DEBUG_ARCH_DEP_18 */
enum {
/* for memobj.flags */

View File

@@ -9,6 +9,7 @@
/*
* HISTORY
*/
/* process.h COPYRIGHT FUJITSU LIMITED 2015-2017 */
#ifndef HEADER_PROCESS_H
#define HEADER_PROCESS_H
@@ -66,6 +67,10 @@
#define PS_TRACED 0x40 /* Set to "not running" by a ptrace related event */
#define PS_STOPPING 0x80
#define PS_TRACING 0x100
#ifdef POSTK_DEBUG_TEMP_FIX_41 /* early to wait4() wakeup for ptrace, fix. */
#define PS_DELAY_STOPPED 0x200
#define PS_DELAY_TRACED 0x400
#endif /* POSTK_DEBUG_TEMP_FIX_41 */
#define PS_NORMAL (PS_INTERRUPTIBLE | PS_UNINTERRUPTIBLE)
@@ -135,6 +140,10 @@
#define WEXITED 0x00000004
#define WCONTINUED 0x00000008
#define WNOWAIT 0x01000000 /* Don't reap, just poll status. */
#ifdef POSTK_DEBUG_ARCH_DEP_44 /* wait() add support __WALL */
#define __WALL 0x40000000 /* Wait on all children, regardless of type */
#endif /* POSTK_DEBUG_ARCH_DEP_44 */
#define __WCLONE 0x80000000
/* idtype */

View File

@@ -9,6 +9,7 @@
/*
* HISTORY
*/
/* syscall.h COPYRIGHT FUJITSU LIMITED 2015-2016 */
#ifndef __HEADER_SYSCALL_H
#define __HEADER_SYSCALL_H
@@ -346,13 +347,25 @@ enum {
#undef SYSCALL_DELEGATED
#define __NR_coredump 999 /* pseudo syscall for coredump */
#ifdef POSTK_DEBUG_TEMP_FIX_61 /* Core table size and lseek return value to loff_t */
struct coretable { /* table entry for a core chunk */
off_t len; /* length of the chunk */
unsigned long addr; /* physical addr of the chunk */
};
#else /* POSTK_DEBUG_TEMP_FIX_61 */
struct coretable { /* table entry for a core chunk */
int len; /* length of the chunk */
unsigned long addr; /* physical addr of the chunk */
};
#endif /* POSTK_DEBUG_TEMP_FIX_61 */
#ifdef POSTK_DEBUG_TEMP_FIX_1
void create_proc_procfs_files(int pid, int tid, int cpuid);
void delete_proc_procfs_files(int pid, int tid);
#else /* POSTK_DEBUG_TEMP_FIX_1 */
void create_proc_procfs_files(int pid, int cpuid);
void delete_proc_procfs_files(int pid);
#endif /* POSTK_DEBUG_TEMP_FIX_1 */
void create_os_procfs_files(void);
void delete_os_procfs_files(void);
@@ -452,6 +465,7 @@ int arch_setup_vdso(void);
int arch_cpu_read_write_register(struct ihk_os_cpu_register *desc,
enum mcctrl_os_cpu_operation op);
#ifndef POSTK_DEBUG_ARCH_DEP_52
#define VDSO_MAXPAGES 2
struct vdso {
long busy;
@@ -468,6 +482,7 @@ struct vdso {
void *pvti_virt;
long pvti_phys;
};
#endif /*POSTK_DEBUG_ARCH_DEP_52*/
struct cpu_mapping {
int cpu_number;

View File

@@ -1,3 +1,4 @@
/* xpmem.h COPYRIGHT FUJITSU LIMITED 2017 */
/**
* \file xpmem.h
* License details are found in the file LICENSE.
@@ -16,7 +17,11 @@
#define XPMEM_DEV_PATH "/dev/xpmem"
#if defined(POSTK_DEBUG_ARCH_DEP_46) || defined(POSTK_DEBUG_ARCH_DEP_62)
extern int xpmem_open(int, const char*, int, ihk_mc_user_context_t *ctx);
#else /* POSTK_DEBUG_ARCH_DEP_46 || POSTK_DEBUG_ARCH_DEP_62 */
extern int xpmem_open(ihk_mc_user_context_t *ctx);
#endif /* POSTK_DEBUG_ARCH_DEP_46 || POSTK_DEBUG_ARCH_DEP_62 */
extern int xpmem_remove_process_memory_range(struct process_vm *vm,
struct vm_range *vmr);
extern int xpmem_fault_process_memory_range(struct process_vm *vm,

View File

@@ -244,10 +244,34 @@ static void time_init(void)
return;
}
#ifdef POSTK_DEBUG_TEMP_FIX_73 /* NULL access for *monitor fix */
void monitor_init(void)
#else /* POSTK_DEBUG_TEMP_FIX_73 */
static void monitor_init()
#endif /* POSTK_DEBUG_TEMP_FIX_73 */
{
int z;
unsigned long phys;
#ifdef POSTK_DEBUG_TEMP_FIX_73 /* NULL access for *monitor fix */
const struct ihk_mc_cpu_info *cpu_info = ihk_mc_get_cpu_info();
if (!cpu_info) {
panic("PANIC: in monitor_init() ihk_mc_cpu_info is NULL.");
return;
}
z = sizeof(struct ihk_os_monitor) +
sizeof(struct ihk_os_cpu_monitor) * (cpu_info->ncpus - 1);
z = (z + PAGE_SIZE -1) >> PAGE_SHIFT;
monitor = ihk_mc_alloc_pages(z, IHK_MC_AP_CRITICAL);
memset(monitor, 0, z * PAGE_SIZE);
monitor->num_processors = (cpu_info->ncpus - 1);
monitor->ns_per_tsc = ihk_mc_get_ns_per_tsc();
phys = virt_to_phys(monitor);
ihk_set_monitor(phys, sizeof(struct ihk_os_monitor) +
sizeof(struct ihk_os_cpu_monitor) * (cpu_info->ncpus - 1));
return;
#else /* POSTK_DEBUG_TEMP_FIX_73 */
z = sizeof(struct ihk_os_monitor) +
sizeof(struct ihk_os_cpu_monitor) * num_processors;
@@ -259,6 +283,7 @@ static void monitor_init()
phys = virt_to_phys(monitor);
ihk_set_monitor(phys, sizeof(struct ihk_os_monitor) +
sizeof(struct ihk_os_cpu_monitor) * num_processors);
#endif /* POSTK_DEBUG_TEMP_FIX_73 */
}
int nmi_mode;
@@ -282,7 +307,9 @@ static void rest_init(void)
//pc_test();
ap_init();
#ifndef POSTK_DEBUG_TEMP_FIX_73 /* NULL access for *monitor fix */
monitor_init();
#endif /* !POSTK_DEBUG_TEMP_FIX_73 */
cpu_local_var_init();
nmi_init();
time_init();

View File

@@ -1,3 +1,4 @@
/* listeners.c COPYRIGHT FUJITSU LIMITED 2015 */
/**
* \file listeners.c
* License details are found in the file LICENSE.

View File

@@ -1,3 +1,4 @@
/* mem.c COPYRIGHT FUJITSU LIMITED 2015-2017 */
/**
* \file mem.c
* License details are found in the file LICENSE.
@@ -867,6 +868,12 @@ void coredump(struct thread *thread, void *regs)
struct coretable *coretable;
int chunks;
#ifdef POSTK_DEBUG_ARCH_DEP_67 /* use limit corefile size. (temporarily fix.) */
if (thread->proc->rlimit[MCK_RLIMIT_CORE].rlim_cur == 0) {
return;
}
#endif /* POSTK_DEBUG_ARCH_DEP_67 */
ret = gencore(thread, regs, &coretable, &chunks);
if (ret != 0) {
dkprintf("could not generate a core file image\n");
@@ -885,6 +892,7 @@ void coredump(struct thread *thread, void *regs)
freecore(&coretable);
}
#ifndef POSTK_DEBUG_ARCH_DEP_8
void remote_flush_tlb_cpumask(struct process_vm *vm,
unsigned long addr, int cpu_id)
{
@@ -941,8 +949,14 @@ void remote_flush_tlb_array_cpumask(struct process_vm *vm,
dkprintf("remote_flush_tlb_cpumask: flush_ind: %d, addr: 0x%lX, interrupting cpu: %d\n",
flush_ind, addr, cpu);
#ifdef POSTK_DEBUG_ARCH_DEP_8 /* arch depend hide */
/* TODO(pka_idke) Interim support */
ihk_mc_interrupt_cpu(cpu,
ihk_mc_get_vector(flush_ind + IHK_TLB_FLUSH_IRQ_VECTOR_START));
#else /* POSTK_DEBUG_ARCH_DEP_8 */
ihk_mc_interrupt_cpu(get_x86_cpu_local_variable(cpu)->apic_id,
flush_ind + IHK_TLB_FLUSH_IRQ_VECTOR_START);
#endif /* POSTK_DEBUG_ARCH_DEP_8 */
}
#ifdef DEBUG_IC_TLB
@@ -979,6 +993,7 @@ void remote_flush_tlb_array_cpumask(struct process_vm *vm,
ihk_mc_spinlock_unlock_noirq(&flush_entry->lock);
}
#endif /* POSTK_DEBUG_ARCH_DEP_8 */
void tlb_flush_handler(int vector)
{
@@ -1545,11 +1560,18 @@ void ihk_mc_unmap_virtual(void *va, int npages, int free_physical)
for (i = 0; i < npages; i++) {
ihk_mc_pt_clear_page(NULL, (char *)va + (i << PAGE_SHIFT));
}
#ifdef POSTK_DEBUG_TEMP_FIX_42 /* add unmap virtual tlb flush. */
flush_tlb();
#endif /* POSTK_DEBUG_TEMP_FIX_42 */
#ifdef POSTK_DEBUG_TEMP_FIX_51 /* ihk_mc_unmap_virtual() free_physical disabled */
ihk_pagealloc_free(vmap_allocator, (unsigned long)va, npages);
#else /* POSTK_DEBUG_TEMP_FIX_51 */
if (free_physical) {
ihk_pagealloc_free(vmap_allocator, (unsigned long)va, npages);
flush_tlb_single((unsigned long)va);
}
#endif /* POSTK_DEBUG_TEMP_FIX_51 */
}
#ifdef ATTACHED_MIC
@@ -1604,8 +1626,14 @@ void ihk_mc_clean_micpa(void){
}
#endif
#ifdef POSTK_DEBUG_TEMP_FIX_73 /* NULL access for *monitor fix */
extern void monitor_init(void);
#endif /* POSTK_DEBUG_TEMP_FIX_73 */
void mem_init(void)
{
#ifdef POSTK_DEBUG_TEMP_FIX_73 /* NULL access for *monitor fix */
monitor_init();
#endif /* !POSTK_DEBUG_TEMP_FIX_73 */
/* Initialize NUMA information and memory allocator bitmaps */
numa_init();
@@ -1944,10 +1972,17 @@ static void ___kmalloc_insert_chunk(struct list_head *free_list,
if (next_chunk) {
list_add_tail(&chunk->list, &next_chunk->list);
}
#ifdef POSTK_DEBUG_TEMP_FIX_46 /* kmalloc free_list consolidate bug fix. */
/* Add tail */
else {
list_add_tail(&chunk->list, free_list);
}
#else /* POSTK_DEBUG_TEMP_FIX_46 */
/* Add after the head */
else {
list_add(&chunk->list, free_list);
}
#endif /* POSTK_DEBUG_TEMP_FIX_46 */
return;
}
@@ -2128,3 +2163,81 @@ void ___kmalloc_print_free_list(struct list_head *list)
kprintf_unlock(irqflags);
}
#ifdef POSTK_DEBUG_ARCH_DEP_27
int search_free_space(struct thread *thread, size_t len, intptr_t hint,
int pgshift, intptr_t *addrp)
{
struct vm_regions *region = &thread->vm->region;
intptr_t addr;
int error;
struct vm_range *range;
size_t pgsize = (size_t)1 << pgshift;
dkprintf("search_free_space(%lx,%lx,%d,%p)\n", len, hint, pgshift, addrp);
addr = hint;
for (;;) {
addr = (addr + pgsize - 1) & ~(pgsize - 1);
if ((region->user_end <= addr)
|| ((region->user_end - len) < addr)) {
ekprintf("search_free_space(%lx,%lx,%p):"
"no space. %lx %lx\n",
len, hint, addrp, addr,
region->user_end);
error = -ENOMEM;
goto out;
}
range = lookup_process_memory_range(thread->vm, addr, addr+len);
if (range == NULL) {
break;
}
addr = range->end;
}
error = 0;
*addrp = addr;
out:
dkprintf("search_free_space(%lx,%lx,%d,%p): %d %lx\n",
len, hint, pgshift, addrp, error, addr);
return error;
}
#endif /* POSTK_DEBUG_ARCH_DEP_27 */
#ifdef POSTK_DEBUG_TEMP_FIX_52 /* supports NUMA for memory area determination */
#ifdef IHK_RBTREE_ALLOCATOR
int is_mckernel_memory(unsigned long phys)
{
int i;
for (i = 0; i < ihk_mc_get_nr_memory_chunks(); ++i) {
unsigned long start, end;
int numa_id;
ihk_mc_get_memory_chunk(i, &start, &end, &numa_id);
if (start <= phys && phys < end) {
return 1;
}
}
return 0;
}
#else /* IHK_RBTREE_ALLOCATOR */
int is_mckernel_memory(unsigned long phys)
{
int i;
for (i = 0; i < ihk_mc_get_nr_numa_nodes(); ++i) {
struct ihk_page_allocator_desc *pa_allocator;
list_for_each_entry(pa_allocator,
&memory_nodes[i].allocators, list) {
if (pa_allocator->start <= phys && phys < pa_allocator->end) {
return 1;
}
}
}
return 0;
}
#endif /* IHK_RBTREE_ALLOCATOR */
#endif /* POSTK_DEBUG_TEMP_FIX_52 */

View File

@@ -1,3 +1,4 @@
/* process.c COPYRIGHT FUJITSU LIMITED 2015-2017 */
/**
* \file process.c
* License details are found in the file LICENSE.
@@ -29,6 +30,9 @@
#include <page.h>
#include <cpulocal.h>
#include <auxvec.h>
#ifdef POSTK_DEBUG_ARCH_DEP_65
#include <hwcap.h>
#endif /* POSTK_DEBUG_ARCH_DEP_65 */
#include <timer.h>
#include <mman.h>
#include <xpmem.h>
@@ -45,6 +49,9 @@
#define ekprintf(...) kprintf(__VA_ARGS__)
#endif
#ifdef POSTK_DEBUG_ARCH_DEP_22
extern struct thread *arch_switch_context(struct thread *prev, struct thread *next);
#endif /* POSTK_DEBUG_ARCH_DEP_22 */
extern long alloc_debugreg(struct thread *proc);
extern void save_debugreg(unsigned long *debugreg);
extern void restore_debugreg(unsigned long *debugreg);
@@ -66,8 +73,10 @@ int ptrace_detach(int pid, int data);
extern unsigned long do_kill(struct thread *, int pid, int tid, int sig, struct siginfo *info, int ptracecont);
extern void procfs_create_thread(struct thread *);
extern void procfs_delete_thread(struct thread *);
#ifndef POSTK_DEBUG_ARCH_DEP_22
extern void perf_start(struct mc_perf_event *event);
extern void perf_reset(struct mc_perf_event *event);
#endif /* !POSTK_DEBUG_ARCH_DEP_22 */
struct list_head resource_set_list;
mcs_rwlock_lock_t resource_set_lock;
@@ -95,8 +104,18 @@ init_process(struct process *proc, struct process *parent)
proc->mpol_threshold = parent->mpol_threshold;
memcpy(proc->rlimit, parent->rlimit,
sizeof(struct rlimit) * MCK_RLIM_MAX);
#ifdef POSTK_DEBUG_TEMP_FIX_69 /* Fix problem not to inherit parent cpu_set. */
memcpy(&proc->cpu_set, &parent->cpu_set,
sizeof(proc->cpu_set));
#endif /* POSTK_DEBUG_TEMP_FIX_69 */
}
#ifdef POSTK_DEBUG_ARCH_DEP_63 /* struct process member initialize add */
INIT_LIST_HEAD(&proc->hash_list);
INIT_LIST_HEAD(&proc->siblings_list);
INIT_LIST_HEAD(&proc->ptraced_siblings_list);
mcs_rwlock_init(&proc->update_lock);
#endif /* POSTK_DEBUG_ARCH_DEP_63 */
INIT_LIST_HEAD(&proc->threads_list);
INIT_LIST_HEAD(&proc->children_list);
INIT_LIST_HEAD(&proc->ptraced_children_list);
@@ -370,6 +389,9 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
/* NOTE: sp is the user mode stack! */
ihk_mc_init_user_process(&thread->ctx, &thread->uctx, ((char *)thread) +
KERNEL_STACK_NR_PAGES * PAGE_SIZE, pc, sp);
#ifdef POSTK_DEBUG_ARCH_DEP_23 /* add arch dep. clone_process() function */
arch_clone_thread(org, pc, sp, thread);
#endif /* POSTK_DEBUG_ARCH_DEP_23 */
memcpy(thread->uctx, org->uctx, sizeof(*org->uctx));
ihk_mc_modify_user_context(thread->uctx, IHK_UCR_STACK_POINTER, sp);
@@ -1793,8 +1815,30 @@ retry:
}
dkprintf("%s: cow,copying virt:%lx<-%lx,phys:%lx<-%lx,pgsize=%lu\n",
__FUNCTION__, virt, phys_to_virt(phys), virt_to_phys(virt), phys, pgsize);
#ifdef POSTK_DEBUG_TEMP_FIX_14
if (page) {
// McKernel memory space
memcpy(virt, phys_to_virt(phys), pgsize);
} else {
// Host Kernel memory space
const enum ihk_mc_pt_attribute attr = 0;
const int remove_vmap_allocator_entry = 1;
void* vmap;
vmap = ihk_mc_map_virtual(phys, npages, attr);
if (!vmap) {
error = -ENOMEM;
kprintf("page_fault_process_memory_range(%p,%lx-%lx %lx,%lx,%lx):cannot virtual mapping. %d\n", vm, range->start, range->end, range->flag, fault_addr, reason, error);
ihk_mc_free_pages(virt, npages);
goto out;
}
memcpy(virt, vmap, pgsize);
ihk_mc_unmap_virtual(vmap, npages, remove_vmap_allocator_entry);
}
#else /*POSTK_DEBUG_TEMP_FIX_14*/
memcpy(virt, phys_to_virt(phys), pgsize);
#endif /*POSTK_DEBUG_TEMP_FIX_14*/
/* Call rusage_memory_stat_add() because remote page fault may create a page not pointed-to by PTE */
if(rusage_memory_stat_add(range, phys, pgsize, pgsize)) {
dkprintf("%lx+,%s: remote page fault + cow, calling memory_stat_rss_add(),pgsize=%ld\n",
@@ -1810,6 +1854,16 @@ retry:
page = phys_to_page(phys);
}
}
#ifdef POSTK_DEBUG_ARCH_DEP_21
else if (!(range->flag & VR_PRIVATE)) { /*VR_SHARED*/
if (!(attr & PTATTR_DIRTY)) {
if (!(range->flag & VR_STACK)) {
attr &= ~PTATTR_WRITABLE;
}
}
}
#endif /*POSTK_DEBUG_ARCH_DEP_21*/
/*****/
if (ptep) {
if(rusage_memory_stat_add(range, phys, pgsize, pgsize)) {
@@ -2031,8 +2085,12 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
/* Create stack range */
end = STACK_TOP(&thread->vm->region) & LARGE_PAGE_MASK;
#ifdef POSTK_DEBUG_ARCH_DEP_80 /* user stack prepage size fix */
minsz = LARGE_PAGE_SIZE;
#else /* POSTK_DEBUG_ARCH_DEP_80 */
minsz = (proc->rlimit[MCK_RLIMIT_STACK].rlim_cur
+ LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK;
#endif /* POSTK_DEBUG_ARCH_DEP_80 */
size = (proc->rlimit[MCK_RLIMIT_STACK].rlim_max
+ LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK;
dkprintf("%s: rlim_max: %lu, rlim_cur: %lu\n",
@@ -2099,6 +2157,12 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
p = (unsigned long *)(stack + minsz);
s_ind = -1;
#ifdef POSTK_DEBUG_ARCH_DEP_15 /* userstack 16byte align */
if(!((envc + argc) % 2)){
p[s_ind--] = 0;
}
#endif /* POSTK_DEBUG_ARCH_DEP_15 */
/* "random" 16 bytes on the very top */
p[s_ind--] = 0x010101011;
p[s_ind--] = 0x010101011;
@@ -2109,6 +2173,10 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
AUXV_LEN in include/process.h. */
p[s_ind--] = 0; /* AT_NULL */
p[s_ind--] = 0;
#ifdef POSTK_DEBUG_ARCH_DEP_65
p[s_ind--] = arch_get_hwcap(); /* AT_HWCAP */
p[s_ind--] = AT_HWCAP;
#endif /* POSTK_DEBUG_ARCH_DEP_65 */
p[s_ind--] = pn->at_entry; /* AT_ENTRY */
p[s_ind--] = AT_ENTRY;
p[s_ind--] = pn->at_phnum; /* AT_PHNUM */
@@ -2117,7 +2185,11 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
p[s_ind--] = AT_PHENT;
p[s_ind--] = pn->at_phdr; /* AT_PHDR */
p[s_ind--] = AT_PHDR;
#ifdef POSTK_DEBUG_ARCH_DEP_50
p[s_ind--] = PAGE_SIZE; /* AT_PAGESZ */
#else
p[s_ind--] = 4096; /* AT_PAGESZ */
#endif /* POSTK_DEBUG_ARCH_DEP_50 */
p[s_ind--] = AT_PAGESZ;
p[s_ind--] = pn->at_clktck; /* AT_CLKTCK */
p[s_ind--] = AT_CLKTCK;
@@ -2163,12 +2235,31 @@ unsigned long extend_process_region(struct process_vm *vm,
void *p;
int rc;
#ifdef POSTK_DEBUG_TEMP_FIX_68 /* fix heap_extension p2align/shift */
size_t align_size;
unsigned long align_mask;
int align_p2align;
int align_shift;
if (vm->proc->heap_extension > PAGE_SIZE) {
align_size = LARGE_PAGE_SIZE;
align_mask = LARGE_PAGE_MASK;
align_p2align = LARGE_PAGE_P2ALIGN;
align_shift = LARGE_PAGE_SHIFT;
} else {
align_size = PAGE_SIZE;
align_mask = PAGE_MASK;
align_p2align = PAGE_P2ALIGN;
align_shift = PAGE_SHIFT;
}
#else /* POSTK_DEBUG_TEMP_FIX_68 */
size_t align_size = vm->proc->heap_extension > PAGE_SIZE ?
LARGE_PAGE_SIZE : PAGE_SIZE;
unsigned long align_mask = vm->proc->heap_extension > PAGE_SIZE ?
LARGE_PAGE_MASK : PAGE_MASK;
unsigned long align_p2align = vm->proc->heap_extension > PAGE_SHIFT ?
LARGE_PAGE_P2ALIGN : PAGE_P2ALIGN;
#endif /* POSTK_DEBUG_TEMP_FIX_68 */
new_end_allocated = (address + (PAGE_SIZE - 1)) & PAGE_MASK;
if ((new_end_allocated - end_allocated) < vm->proc->heap_extension) {
@@ -2190,12 +2281,21 @@ unsigned long extend_process_region(struct process_vm *vm,
}
}
#ifdef POSTK_DEBUG_TEMP_FIX_68 /* fix heap_extension p2align/shift */
if ((rc = add_process_memory_range(vm, end_allocated, new_end_allocated,
(p == 0 ? 0 : virt_to_phys(p)), flag, NULL, 0,
align_shift, NULL)) != 0) {
ihk_mc_free_pages_user(p, (new_end_allocated - end_allocated) >> PAGE_SHIFT);
return end_allocated;
}
#else /* POSTK_DEBUG_TEMP_FIX_68 */
if ((rc = add_process_memory_range(vm, end_allocated, new_end_allocated,
(p == 0 ? 0 : virt_to_phys(p)), flag, NULL, 0,
align_p2align, NULL)) != 0) {
ihk_mc_free_pages_user(p, (new_end_allocated - end_allocated) >> PAGE_SHIFT);
return end_allocated;
}
#endif /* POSTK_DEBUG_TEMP_FIX_68 */
// memory_stat_rss_add() is called in add_process_memory_range()
dkprintf("%s: new_end_allocated: 0x%lx, align_size: %lu, align_mask: %lx\n",
@@ -2857,6 +2957,9 @@ static void do_migrate(void)
__FUNCTION__, req->thread->tid, old_cpu_id, cpu_id);
v->flags |= CPU_FLAG_NEED_RESCHED;
#ifdef POSTK_DEBUG_TEMP_FIX_57 /* migration wakeup IPI target fix. */
ihk_mc_interrupt_cpu(cpu_id, ihk_mc_get_vector(IHK_GV_IKC));
#endif /* POSTK_DEBUG_TEMP_FIX_57 */
waitq_wakeup(&req->wq);
double_rq_unlock(cur_v, v, irqstate);
continue;
@@ -2931,6 +3034,12 @@ void spin_sleep_or_schedule(void)
}
ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate);
#ifdef POSTK_DEBUG_TEMP_FIX_56 /* in futex_wait() signal handring fix. */
if (hassigpending(cpu_local_var(current))) {
woken = 1;
}
#endif /* POSTK_DEBUG_TEMP_FIX_56 */
if (woken) {
return;
}
@@ -3027,9 +3136,15 @@ redo:
}
/* Take care of floating point registers except for idle process */
#ifdef POSTK_DEBUG_ARCH_DEP_66 /* Fixed not to save fp_regs when the process ends */
if (prev && (prev != &cpu_local_var(idle) && prev->status != PS_EXITED)) {
save_fp_regs(prev);
}
#else /* POSTK_DEBUG_ARCH_DEP_66 */
if (prev && prev != &cpu_local_var(idle)) {
save_fp_regs(prev);
}
#endif /* POSTK_DEBUG_ARCH_DEP_66 */
if (next != &cpu_local_var(idle)) {
restore_fp_regs(next);
@@ -3039,6 +3154,9 @@ redo:
next->vm->address_space->page_table)
ihk_mc_load_page_table(next->vm->address_space->page_table);
#ifdef POSTK_DEBUG_ARCH_DEP_22
last = arch_switch_context(prev, next);
#else
dkprintf("[%d] schedule: tlsblock_base: 0x%lX\n",
ihk_mc_get_processor_id(), next->tlsblock_base);
@@ -3073,6 +3191,7 @@ redo:
else {
last = ihk_mc_switch_context(NULL, &next->ctx, prev);
}
#endif /* POSTK_DEBUG_ARCH_DEP_22 */
/*
* We must hold the lock throughout the context switch, otherwise
@@ -3166,16 +3285,25 @@ int __sched_wakeup_thread(struct thread *thread,
status = -EINVAL;
}
#ifdef POSTK_DEBUG_TEMP_FIX_55 /* runq_locked flag apply for unlock */
if (!runq_locked) {
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
}
#else /* POSTK_DEBUG_TEMP_FIX_55 */
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
#endif /* POSTK_DEBUG_TEMP_FIX_55 */
if (!status && (thread->cpu_id != ihk_mc_get_processor_id())) {
dkprintf("%s: issuing IPI, thread->cpu_id=%d\n",
__FUNCTION__, thread->cpu_id);
#ifdef POSTK_DEBUG_ARCH_DEP_8 /* arch depend hide */
ihk_mc_interrupt_cpu(thread->cpu_id,
ihk_mc_get_vector(IHK_GV_IKC));
#else /* POSTK_DEBUG_ARCH_DEP_8 */
ihk_mc_interrupt_cpu(
get_x86_cpu_local_variable(thread->cpu_id)->apic_id,
0xd1);
#endif /* POSTK_DEBUG_ARCH_DEP_8 */
}
return status;
@@ -3229,9 +3357,15 @@ void sched_request_migrate(int cpu_id, struct thread *thread)
v->status = CPU_STATUS_RUNNING;
ihk_mc_spinlock_unlock(&v->runq_lock, irqstate);
#ifdef POSTK_DEBUG_ARCH_DEP_8 /* arch depend hide */
if (cpu_id != ihk_mc_get_processor_id())
ihk_mc_interrupt_cpu(/* Kick scheduler */
thread->cpu_id, ihk_mc_get_vector(IHK_GV_IKC));
#else /* POSTK_DEBUG_ARCH_DEP_8 */
if (cpu_id != ihk_mc_get_processor_id())
ihk_mc_interrupt_cpu(/* Kick scheduler */
get_x86_cpu_local_variable(cpu_id)->apic_id, 0xd1);
#endif /* POSTK_DEBUG_ARCH_DEP_8 */
dkprintf("%s: tid: %d -> cpu: %d\n",
__FUNCTION__, thread->tid, cpu_id);
@@ -3268,9 +3402,15 @@ void runq_add_thread(struct thread *thread, int cpu_id)
rusage_num_threads_inc();
/* Kick scheduler */
#ifdef POSTK_DEBUG_ARCH_DEP_8 /* arch depend hide */
if (cpu_id != ihk_mc_get_processor_id())
ihk_mc_interrupt_cpu(
thread->cpu_id, ihk_mc_get_vector(IHK_GV_IKC));
#else /* POSTK_DEBUG_ARCH_DEP_8 */
if (cpu_id != ihk_mc_get_processor_id())
ihk_mc_interrupt_cpu(
get_x86_cpu_local_variable(cpu_id)->apic_id, 0xd1);
#endif /* POSTK_DEBUG_ARCH_DEP_8 */
}
/* NOTE: shouldn't remove a running process! */

View File

@@ -9,6 +9,7 @@
/*
* HISTORY:
*/
/* procfs.c COPYRIGHT FUJITSU LIMITED 2015-2017 */
#include <types.h>
#include <kmsg.h>
@@ -231,6 +232,12 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
eof = 1;
goto end;
}
#ifdef POSTK_DEBUG_ARCH_DEP_42 /* /proc/cpuinfo support added. */
else if (!strcmp(p, "cpuinfo")) { /* "/proc/cpuinfo" */
ans = ihk_mc_show_cpuinfo(buf, count, offset, &eof);
goto end;
}
#endif /* POSTK_DEBUG_ARCH_DEP_42 */
else {
kprintf("unsupported procfs entry: %s\n", p);
goto end;
@@ -285,8 +292,12 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
goto end;
}
#ifdef POSTK_DEBUG_TEMP_FIX_52 /* NUMA support(memory area determination) */
if (!is_mckernel_memory(pa)) {
#else
if (pa < ihk_mc_get_memory_address(IHK_MC_GMA_MAP_START, 0) ||
pa >= ihk_mc_get_memory_address(IHK_MC_GMA_MAP_END, 0)) {
#endif /* POSTK_DEBUG_TEMP_FIX_52 */
ans = -EIO;
goto end;
}
@@ -308,16 +319,34 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
*/
if (strcmp(p, "maps") == 0) {
struct vm_range *range;
#ifdef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
int left = PAGE_SIZE * 2;
#else /* POSTK_DEBUG_TEMP_FIX_47 */
int left = r->count - 1; /* extra 1 for terminating NULL */
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
int written = 0;
char *_buf = buf;
#ifdef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
int len = 0;
char *tmp = NULL;
_buf = tmp = kmalloc(left, IHK_MC_AP_CRITICAL);
if (!tmp) {
kprintf("%s: error allocating /proc/self/maps buffer\n",
__FUNCTION__);
ans = 0;
goto end;
}
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
#ifndef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
/* Starting from the middle of a proc file is not supported for maps */
if (offset > 0) {
ans = 0;
eof = 1;
goto end;
}
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
@@ -347,17 +376,42 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
_buf += written_now;
written += written_now;
#ifdef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
if (left == 0) {
kprintf("%s(): WARNING: buffer too small to fill proc/maps\n",
__FUNCTION__);
break;
}
#else /* POSTK_DEBUG_TEMP_FIX_47 */
if (left == 1) {
kprintf("%s(): WARNING: buffer too small to fill proc/maps\n",
__FUNCTION__);
break;
}
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
}
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
#ifdef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
len = strlen(tmp);
if (r->offset < len) {
if (r->offset + r->count < len) {
ans = r->count;
} else {
eof = 1;
ans = len;
}
strncpy(buf, tmp + r->offset, ans);
} else if (r->offset == len) {
ans = 0;
eof = 1;
}
kfree(tmp);
#else /* POSTK_DEBUG_TEMP_FIX_47 */
ans = written + 1;
eof = 1;
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
goto end;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,4 @@
/* xpmem.c COPYRIGHT FUJITSU LIMITED 2017 */
/**
* \file xpmem.c
* License details are found in the file LICENSE.
@@ -34,6 +35,19 @@
struct xpmem_partition *xpmem_my_part = NULL; /* pointer to this partition */
#if defined(POSTK_DEBUG_ARCH_DEP_46) || defined(POSTK_DEBUG_ARCH_DEP_62)
int xpmem_open(int num, const char *pathname,
int flags, ihk_mc_user_context_t *ctx)
{
int ret;
struct thread *thread = cpu_local_var(current);
struct process *proc = thread->proc;
int fd;
struct mckfd *mckfd;
long irqstate;
XPMEM_DEBUG("call: syscall_num=%d, pathname=%s, flags=%d", num, pathname, flags);
#else /* POSTK_DEBUG_ARCH_DEP_46 || POSTK_DEBUG_ARCH_DEP_62 */
int xpmem_open(
ihk_mc_user_context_t *ctx)
{
@@ -48,6 +62,7 @@ int xpmem_open(
long irqstate;
XPMEM_DEBUG("call: pathname=%s, flags=%d", pathname, flags);
#endif /* POSTK_DEBUG_ARCH_DEP_46 || POSTK_DEBUG_ARCH_DEP_62 */
if (!xpmem_my_part) {
ret = xpmem_init();
@@ -56,6 +71,13 @@ int xpmem_open(
}
}
#ifdef POSTK_DEBUG_ARCH_DEP_62 /* Absorb the difference between open and openat args. */
fd = syscall_generic_forwarding(num, ctx);
if(fd < 0){
XPMEM_DEBUG("syscall_num=%d error: fd=%d", num, fd);
return fd;
}
#else /* POSTK_DEBUG_ARCH_DEP_62 */
request.number = __NR_open;
request.args[0] = (unsigned long)pathname;
request.args[1] = flags;
@@ -64,6 +86,7 @@ int xpmem_open(
XPMEM_DEBUG("__NR_open error: fd=%d", fd);
return fd;
}
#endif /* POSTK_DEBUG_ARCH_DEP_62 */
ret = __xpmem_open();
if (ret) {