add arm64 support
- add arm64 dependent codes with GICv3 and SVE support - fix bugs based on architecture separation requests
This commit is contained in:
@@ -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 $@
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* ap.c COPYRIGHT FUJITSU LIMITED 2015 */
|
||||
/**
|
||||
* \file ap.c
|
||||
* Licence details are found in the file LICENSE.
|
||||
|
||||
39
kernel/config/config.smp-arm64.in
Normal file
39
kernel/config/config.smp-arm64.in
Normal 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
|
||||
50
kernel/config/smp-arm64_type1.lds
Normal file
50
kernel/config/smp-arm64_type1.lds
Normal 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 = .;
|
||||
}
|
||||
50
kernel/config/smp-arm64_type2.lds
Normal file
50
kernel/config/smp-arm64_type2.lds
Normal 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 = .;
|
||||
}
|
||||
50
kernel/config/smp-arm64_type3.lds
Normal file
50
kernel/config/smp-arm64_type3.lds
Normal 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 = .;
|
||||
}
|
||||
50
kernel/config/smp-arm64_type4.lds
Normal file
50
kernel/config/smp-arm64_type4.lds
Normal 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 = .;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
499
kernel/gencore.c
Normal 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 */
|
||||
@@ -1,3 +1,4 @@
|
||||
/* host.c COPYRIGHT FUJITSU LIMITED 2015-2016 */
|
||||
/**
|
||||
* \file host.c
|
||||
* License details are found in the file LICENSE.
|
||||
|
||||
@@ -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
119
kernel/include/elfcore.h
Normal 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 */
|
||||
67
kernel/include/elfcoregpl.h
Normal file
67
kernel/include/elfcoregpl.h
Normal 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 */
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* listeners.c COPYRIGHT FUJITSU LIMITED 2015 */
|
||||
/**
|
||||
* \file listeners.c
|
||||
* License details are found in the file LICENSE.
|
||||
|
||||
113
kernel/mem.c
113
kernel/mem.c
@@ -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 */
|
||||
|
||||
140
kernel/process.c
140
kernel/process.c
@@ -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! */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
470
kernel/syscall.c
470
kernel/syscall.c
File diff suppressed because it is too large
Load Diff
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user