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.in COPYRIGHT FUJITSU LIMITED 2016
KDIR ?= @KDIR@
ARCH ?= @ARCH@
src = @abs_srcdir@
@ -7,12 +8,18 @@ IHK_BASE=$(src)/../../../../ihk
obj-m += mcctrl.o
ccflags-y := -I$(IHK_BASE)/linux/include -I$(IHK_BASE)/linux/include/ihk/arch/$(ARCH) -I$(IHK_BASE)/ikc/include -I$(IHK_BASE)/ikc/include/ikc/arch/$(ARCH) -I$(IHK_BASE)/include -I$(IHK_BASE)/include/arch/$(ARCH) -I$(src)/../../include -mcmodel=kernel -mno-red-zone -DMCEXEC_PATH=\"$(BINDIR)/mcexec\" -I@abs_builddir@
# POSTK_DEBUG_ARCH_DEP_1, arch depend "-mcmodel"
# POSTK_DEBUG_ARCH_DEP_83, arch depend translate_rva_to_rpa() move
#ccflags-y := -I$(IHK_BASE)/linux/include -I$(IHK_BASE)/linux/include/ihk/arch/$(ARCH) -I$(IHK_BASE)/ikc/include -I$(IHK_BASE)/ikc/include/ikc/arch/$(ARCH) -I$(IHK_BASE)/include -I$(IHK_BASE)/include/arch/$(ARCH) -I$(src)/../../include -mcmodel=kernel -mno-red-zone -DMCEXEC_PATH=\"$(BINDIR)/mcexec\" -I@abs_builddir@
ccflags-y := -I$(IHK_BASE)/linux/include -I$(IHK_BASE)/linux/include/ihk/arch/$(ARCH) -I$(IHK_BASE)/ikc/include -I$(IHK_BASE)/ikc/include/ikc/arch/$(ARCH) -I$(IHK_BASE)/include -I$(IHK_BASE)/include/arch/$(ARCH) -I$(src)/../../include -I$(src)/arch/$(ARCH)/include -DMCEXEC_PATH=\"$(BINDIR)/mcexec\" -I@abs_builddir@
mcctrl-y := driver.o control.o ikc.o syscall.o procfs.o binfmt_mcexec.o
mcctrl-y += sysfs.o sysfs_files.o arch/$(ARCH)/archdeps.o
KBUILD_EXTRA_SYMBOLS = @abs_builddir@/../../../../ihk/linux/core/Module.symvers
EXTRA_CFLAGS += $(foreach i, $(shell seq 1 100), $(addprefix -DPOSTK_DEBUG_ARCH_DEP_, $(i)))
EXTRA_CFLAGS += $(foreach i, $(shell seq 1 100), $(addprefix -DPOSTK_DEBUG_TEMP_FIX_, $(i)))
.PHONY: clean install modules

View File

@ -0,0 +1,2 @@
# Makefile.in COPYRIGHT FUJITSU LIMITED 2016
# dummy file

View File

@ -0,0 +1,316 @@
/* archdeps.c COPYRIGHT FUJITSU LIMITED 2016 */
#include <linux/version.h>
#include <linux/mm_types.h>
#include <asm/vdso.h>
#include "../../../config.h"
#include "../../mcctrl.h"
#ifdef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */
//#define SC_DEBUG
#ifdef SC_DEBUG
#define dprintk(...) printk(__VA_ARGS__)
#else
#define dprintk(...)
#endif
#endif /* POSTK_DEBUG_ARCH_DEP_83 */
#define D(fmt, ...) printk("%s(%d) " fmt, __func__, __LINE__, ##__VA_ARGS__)
#ifdef MCCTRL_KSYM_vdso_start
# if MCCTRL_KSYM_vdso_start
void *vdso_start = (void *)MCCTRL_KSYM_vdso_start;
# endif
#else
# error missing address of vdso_start.
#endif
#ifdef MCCTRL_KSYM_vdso_end
# if MCCTRL_KSYM_vdso_end
void *vdso_end = (void *)MCCTRL_KSYM_vdso_end;
# endif
#else
# error missing address of vdso_end.
#endif
#ifdef MCCTRL_KSYM_vdso_spec
# if MCCTRL_KSYM_vdso_spec
static struct vm_special_mapping (*vdso_spec)[2] = (void*)MCCTRL_KSYM_vdso_spec;
# endif
#else
# error missing address of vdso_spec.
#endif
#ifdef POSTK_DEBUG_ARCH_DEP_52
#define VDSO_MAXPAGES 1
struct vdso {
long busy;
int vdso_npages;
int padding;
long vdso_physlist[VDSO_MAXPAGES];
long vvar_phys;
long lbase;
long offset_sigtramp;
};
#endif /*POSTK_DEBUG_ARCH_DEP_52*/
unsigned long
reserve_user_space_common(struct mcctrl_usrdata *usrdata, unsigned long start, unsigned long end);
int
reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp, unsigned long *endp)
{
struct vm_area_struct *vma;
unsigned long start = 0L;
unsigned long end;
if (mutex_lock_killable(&usrdata->reserve_lock) < 0) {
return -1;
}
#define DESIRED_USER_END TASK_UNMAPPED_BASE
end = DESIRED_USER_END;
down_write(&current->mm->mmap_sem);
vma = find_vma(current->mm, 0);
if (vma->vm_start < end) {
printk("mcctrl:user space overlap.\n");
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
up_write(&current->mm->mmap_sem);
#endif
start = reserve_user_space_common(usrdata, start, end);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
up_write(&current->mm->mmap_sem);
#endif
mutex_unlock(&usrdata->reserve_lock);
if (IS_ERR_VALUE(start)) {
return start;
}
*startp = start;
*endp = end;
return 0;
}
void get_vdso_info(ihk_os_t os, long vdso_rpa)
{
ihk_device_t dev = ihk_os_to_dev(os);
struct vm_special_mapping* vvar_map;
struct vm_special_mapping* vdso_map;
int nr_vdso_page;
long vdso_pa;
struct vdso *vdso;
vdso_pa = ihk_device_map_memory(dev, vdso_rpa, sizeof(*vdso));
vdso = ihk_device_map_virtual(dev, vdso_pa, sizeof(*vdso), NULL, 0);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)
vvar_map = &(*vdso_spec)[0];
vdso_map = &(*vdso_spec)[1];
nr_vdso_page = ((vdso_end - vdso_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
/* VDSO pages */
//D("nr_vdso_page:%d\n", nr_vdso_page);
vdso->vdso_npages = 1; //vdso page is supposed to be one
if (vdso->vdso_npages != nr_vdso_page) {
vdso->vdso_npages = 0;
goto out;
}
//D("vdso->vdso_physlist[0]:0x#lx\n", vdso->vdso_physlist[0]);
vdso->vdso_physlist[0] = page_to_phys(*vdso_map->pages);
/* VVAR page */
//D("vdso->vvar_phys:0x#lx\n", vdso->vvar_phys);
vdso->vvar_phys = page_to_phys(*vvar_map->pages);
/* offsets */
vdso->lbase = VDSO_LBASE;
vdso->offset_sigtramp = vdso_offset_sigtramp;
#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)*/
out:
wmb();
vdso->busy = 0;
ihk_device_unmap_virtual(dev, vdso, sizeof(*vdso));
ihk_device_unmap_memory(dev, vdso_pa, sizeof(*vdso));
return;
} /* get_vdso_info() */
void *
get_user_sp(void)
{
/* TODO; skeleton for UTI */
return NULL;
}
void
set_user_sp(void *usp)
{
/* TODO; skeleton for UTI */
}
/* TODO; skeleton for UTI */
struct trans_uctx {
volatile int cond;
int fregsize;
unsigned long rax;
unsigned long rbx;
unsigned long rcx;
unsigned long rdx;
unsigned long rsi;
unsigned long rdi;
unsigned long rbp;
unsigned long r8;
unsigned long r9;
unsigned long r10;
unsigned long r11;
unsigned long r12;
unsigned long r13;
unsigned long r14;
unsigned long r15;
unsigned long rflags;
unsigned long rip;
unsigned long rsp;
unsigned long fs;
};
void
restore_fs(unsigned long fs)
{
/* TODO; skeleton for UTI */
}
void
save_fs_ctx(void *ctx)
{
/* TODO; skeleton for UTI */
}
unsigned long
get_fs_ctx(void *ctx)
{
/* TODO; skeleton for UTI */
return 0;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0)
# define IHK_MC_PGTABLE_LEVELS CONFIG_ARM64_PGTABLE_LEVELS
#else
# define IHK_MC_PGTABLE_LEVELS CONFIG_PGTABLE_LEVELS
#endif
typedef unsigned long translation_table_t;
struct page_table {
translation_table_t* tt;
translation_table_t* tt_pa;
int asid;
};
#ifdef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */
int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
unsigned long *rpap, unsigned long *pgsizep)
{
unsigned long rpa;
int i;
int ix;
unsigned long phys;
unsigned long *pt;
int error;
unsigned long pgsize;
struct page_table* tbl;
struct property {
int idx_bits;
int block; /*block support flag*/
int pgshift;
} properties[3][4] = {
{ /* 4KB */
{.idx_bits = 47 - 39 + 1, .block = 0, .pgshift = 39}, /*zero*/
{.idx_bits = 38 - 30 + 1, .block = 1, .pgshift = 30}, /*first*/
{.idx_bits = 29 - 21 + 1, .block = 1, .pgshift = 21}, /*second*/
{.idx_bits = 20 - 12 + 1, .block = 0, .pgshift = 12}, /*third*/
},
{ /* 16KB */
{.idx_bits = 47 - 47 + 1, .block = 0, .pgshift = 47}, /*zero*/
{.idx_bits = 46 - 36 + 1, .block = 0, .pgshift = 36}, /*first*/
{.idx_bits = 35 - 25 + 1, .block = 1, .pgshift = 25}, /*second*/
{.idx_bits = 24 - 14 + 1, .block = 0, .pgshift = 14}, /*third*/
},
{ /* 64KB */
{0}, /*zero*/
{.idx_bits = 47 - 42 + 1, .block = 0, .pgshift = 42}, /*first*/
{.idx_bits = 41 - 29 + 1, .block = 1, .pgshift = 29}, /*second*/
{.idx_bits = 28 - 16 + 1, .block = 0, .pgshift = 16}, /*third*/
},
};
const struct property* prop =
(PAGE_SIZE == (1UL << 12)) ? &(properties[0][0]) :
(PAGE_SIZE == (1UL << 14)) ? &(properties[1][0]) :
(PAGE_SIZE == (1UL << 16)) ? &(properties[2][0]) : NULL;
// page table to translation_table.
phys = ihk_device_map_memory(ihk_os_to_dev(os), rpt, PAGE_SIZE);
tbl = ihk_device_map_virtual(ihk_os_to_dev(os), phys, PAGE_SIZE, NULL, 0);
rpa = (unsigned long)tbl->tt_pa;
/* i = 0:zero, 1:first, 2:second, 3:third */
for (i = 4 - IHK_MC_PGTABLE_LEVELS; i < 4; ++i) {
ix = (rva >> prop[i].pgshift) & ((1 << prop[i].idx_bits) - 1);
phys = ihk_device_map_memory(ihk_os_to_dev(os), rpa, PAGE_SIZE);
pt = ihk_device_map_virtual(ihk_os_to_dev(os), phys, PAGE_SIZE, NULL, 0);
dprintk("rpa %#lx offsh %d ix %#x phys %#lx pt %p pt[ix] %#lx\n",
rpa, prop[i].pgshift, ix, phys, pt, pt[ix]);
#define PG_DESC_VALID 0x1
if (!(pt[ix] & PG_DESC_VALID)) {
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
error = -EFAULT;
dprintk("Remote PTE is not present for 0x%lx (rpt: %lx) ?\n", rva, rpt);
goto out;
}
#define PG_DESC_TYEP_MASK 0x3
#define PG_DESC_BLOCK 0x1
if (prop[i].block && (pt[ix]&PG_DESC_TYEP_MASK) == PG_DESC_BLOCK) {
/* D_Block */
pgsize = 1UL << prop[i].pgshift;
rpa = (pt[ix] & ((1UL << 47) - 1)) & ~(pgsize - 1);
rpa |= rva & (pgsize - 1);
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
error = 0;
goto found;
}
/* D_Table */
rpa = (pt[ix] & ((1UL << 47) - 1)) & ~(PAGE_SIZE - 1);
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
}
/* D_Page */
pgsize = PAGE_SIZE;
rpa |= rva & (pgsize - 1);
found:
error = 0;
*rpap = rpa;
*pgsizep = pgsize;
out:
dprintk("translate_rva_to_rpa: %d rva %#lx --> rpa %#lx (%lx)\n",
error, rva, rpa, pgsize);
return error;
}
#endif /* POSTK_DEBUG_ARCH_DEP_83 */
#ifdef POSTK_DEBUG_ARCH_DEP_12
#define PFN_WRITE_COMBINED PTE_ATTRINDX(MT_NORMAL_NC)
static inline bool pte_is_write_combined(pte_t pte)
{
return ((pte_val(pte) & PTE_ATTRINDX_MASK) == PFN_WRITE_COMBINED);
}
#endif /* POSTK_DEBUG_ARCH_DEP_12 */

View File

@ -0,0 +1,18 @@
/* archdeps.h COPYRIGHT FUJITSU LIMITED 2017 */
#ifdef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */
#ifndef __HEADER_MCCTRL_ARM64_ARCHDEPS_H
#define __HEADER_MCCTRL_ARM64_ARCHDEPS_H
extern int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
unsigned long *rpap, unsigned long *pgsizep);
#ifdef POSTK_DEBUG_ARCH_DEP_12
#define PFN_WRITE_COMBINED PTE_ATTRINDX(MT_NORMAL_NC)
static inline bool pte_is_write_combined(pte_t pte)
{
return ((pte_val(pte) & PTE_ATTRINDX_MASK) == PFN_WRITE_COMBINED);
}
#endif /* POSTK_DEBUG_ARCH_DEP_12 */
#endif /* __HEADER_MCCTRL_ARM64_ARCHDEPS_H */
#endif /* POSTK_DEBUG_ARCH_DEP_83 */

View File

@ -1,7 +1,18 @@
/* archdeps.c COPYRIGHT FUJITSU LIMITED 2016 */
#include <linux/version.h>
#include "../../../config.h"
#include "../../mcctrl.h"
#ifdef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */
//#define SC_DEBUG
#ifdef SC_DEBUG
#define dprintk(...) printk(__VA_ARGS__)
#else
#define dprintk(...)
#endif
#endif /* POSTK_DEBUG_ARCH_DEP_83 */
#ifdef MCCTRL_KSYM_vdso_image_64
#if MCCTRL_KSYM_vdso_image_64
struct vdso_image *vdso_image = (void *)MCCTRL_KSYM_vdso_image_64;
@ -54,6 +65,25 @@ void **hv_clockp
= NULL;
#endif
#ifdef POSTK_DEBUG_ARCH_DEP_52
#define VDSO_MAXPAGES 2
struct vdso {
long busy;
int vdso_npages;
char vvar_is_global;
char hpet_is_global;
char pvti_is_global;
char padding;
long vdso_physlist[VDSO_MAXPAGES];
void *vvar_virt;
long vvar_phys;
void *hpet_virt;
long hpet_phys;
void *pvti_virt;
long pvti_phys;
};
#endif /*POSTK_DEBUG_ARCH_DEP_52*/
unsigned long
reserve_user_space_common(struct mcctrl_usrdata *usrdata, unsigned long start, unsigned long end);
@ -258,3 +288,76 @@ get_fs_ctx(void *ctx)
return tctx->fs;
}
#ifdef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */
int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
unsigned long *rpap, unsigned long *pgsizep)
{
unsigned long rpa;
int offsh;
int i;
int ix;
unsigned long phys;
unsigned long *pt;
int error;
unsigned long pgsize;
rpa = rpt;
offsh = 39;
pgsize = 0;
/* i = 0: PML4, 1: PDPT, 2: PDT, 3: PT */
for (i = 0; i < 4; ++i) {
ix = (rva >> offsh) & 0x1FF;
phys = ihk_device_map_memory(ihk_os_to_dev(os), rpa, PAGE_SIZE);
pt = ihk_device_map_virtual(ihk_os_to_dev(os), phys, PAGE_SIZE, NULL, 0);
dprintk("rpa %#lx offsh %d ix %#x phys %#lx pt %p pt[ix] %#lx\n",
rpa, offsh, ix, phys, pt, pt[ix]);
#define PTE_P 0x001
if (!(pt[ix] & PTE_P)) {
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
error = -EFAULT;
dprintk("Remote PTE is not present for 0x%lx (rpt: %lx) ?\n", rva, rpt);
goto out;
}
#define PTE_PS 0x080
if (pt[ix] & PTE_PS) {
pgsize = 1UL << offsh;
rpa = pt[ix] & ((1UL << 52) - 1) & ~(pgsize - 1);
rpa |= rva & (pgsize - 1);
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
error = 0;
goto found;
}
rpa = pt[ix] & ((1UL << 52) - 1) & ~((1UL << 12) - 1);
offsh -= 9;
ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE);
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
}
pgsize = 1UL << 12;
rpa |= rva & (pgsize - 1);
found:
error = 0;
*rpap = rpa;
*pgsizep = pgsize;
out:
dprintk("translate_rva_to_rpa: %d rva %#lx --> rpa %#lx (%lx)\n",
error, rva, rpa, pgsize);
return error;
}
#endif /* POSTK_DEBUG_ARCH_DEP_83 */
#ifdef POSTK_DEBUG_ARCH_DEP_12
#define PFN_WRITE_COMBINED _PAGE_PWT
static inline bool pte_is_write_combined(pte_t pte)
{
return ((pte_flags(pte) & _PAGE_PWT) && !(pte_flags(pte) & _PAGE_PCD));
}
#endif /* POSTK_DEBUG_ARCH_DEP_12 */

View File

@ -0,0 +1,18 @@
/* archdeps.h COPYRIGHT FUJITSU LIMITED 2017 */
#ifdef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */
#ifndef __HEADER_MCCTRL_X86_64_ARCHDEPS_H
#define __HEADER_MCCTRL_X86_64_ARCHDEPS_H
extern int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
unsigned long *rpap, unsigned long *pgsizep);
#ifdef POSTK_DEBUG_ARCH_DEP_12
#define PFN_WRITE_COMBINED _PAGE_PWT
static inline bool pte_is_write_combined(pte_t pte)
{
return ((pte_flags(pte) & _PAGE_PWT) && !(pte_flags(pte) & _PAGE_PCD));
}
#endif /* POSTK_DEBUG_ARCH_DEP_12 */
#endif /* __HEADER_MCCTRL_X86_64_ARCHDEPS_H */
#endif /* POSTK_DEBUG_ARCH_DEP_83 */

View File

@ -122,6 +122,23 @@ static int load_elf(struct linux_binprm *bprm
for(i = 0, st = 0; mode != 2;){
if(st == 0){
off = p & ~PAGE_MASK;
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
rc = get_user_pages_remote(current, bprm->mm,
bprm->p, 1, FOLL_FORCE, &page, NULL, NULL);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)
rc = get_user_pages_remote(current, bprm->mm,
bprm->p, 1, FOLL_FORCE, &page, NULL);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
rc = get_user_pages_remote(current, bprm->mm,
bprm->p, 1, 0, 1,
&page, NULL);
#else
rc = get_user_pages(current, bprm->mm,
bprm->p, 1, 0, 1,
&page, NULL);
#endif
#else /* POSTK_DEBUG_ARCH_DEP_41 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
rc = get_user_pages_remote(current, bprm->mm,
bprm->p, 1, 0, 1,
@ -131,6 +148,7 @@ static int load_elf(struct linux_binprm *bprm
bprm->p, 1, 0, 1,
&page, NULL);
#endif
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
if(rc <= 0) {
kfree(pbuf);
return -EFAULT;

View File

@ -1,3 +1,4 @@
/* control.c COPYRIGHT FUJITSU LIMITED 2016-2017 */
/**
* \file executer/kernel/control.c
* License details are found in the file LICENSE.
@ -337,6 +338,11 @@ struct mcos_handler_info *new_mcos_handler_info(ihk_os_t os, struct file *file)
struct mcos_handler_info *info;
info = kmalloc(sizeof(struct mcos_handler_info), GFP_KERNEL);
#ifdef POSTK_DEBUG_TEMP_FIX_64 /* host process is SIGKILLed fix. */
if (info == NULL) {
return NULL;
}
#endif /* POSTK_DEBUG_TEMP_FIX_64 */
memset(info, '\0', sizeof(struct mcos_handler_info));
info->ud = ihk_host_os_get_usrdata(os);
info->file = file;
@ -403,6 +409,11 @@ static long mcexec_newprocess(ihk_os_t os,
return -EFAULT;
}
info = new_mcos_handler_info(os, file);
#ifdef POSTK_DEBUG_TEMP_FIX_64 /* host process is SIGKILLed fix. */
if (info == NULL) {
return -ENOMEM;
}
#endif /* POSTK_DEBUG_TEMP_FIX_64 */
info->pid = desc.pid;
ihk_os_register_release_handler(file, release_handler, info);
ihk_os_set_mcos_private_data(file, info);
@ -433,6 +444,12 @@ static long mcexec_start_image(ihk_os_t os,
}
info = new_mcos_handler_info(os, file);
#ifdef POSTK_DEBUG_TEMP_FIX_64 /* host process is SIGKILLed fix. */
if (info == NULL) {
kfree(desc);
return -ENOMEM;
}
#endif /* POSTK_DEBUG_TEMP_FIX_64 */
info->pid = desc->pid;
info->cpu = desc->cpu;
ihk_os_register_release_handler(file, release_handler, info);
@ -540,7 +557,11 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
struct mcctrl_usrdata *udp = ihk_host_os_get_usrdata(os);
struct mcctrl_part_exec *pe;
struct get_cpu_set_arg req;
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
struct mcctrl_cpu_topology *cpu_top, *cpu_top_i;
#else /* POSTK_DEBUG_ARCH_DEP_40 */
struct cpu_topology *cpu_top, *cpu_top_i;
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
struct cache_topology *cache_top;
int cpu, cpus_assigned, cpus_to_assign, cpu_prev;
int ret = 0;
@ -610,6 +631,13 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
pli_next = NULL;
/* Add ourself to the list in order of start time */
list_for_each_entry(pli_iter, &pe->pli_list, list) {
#ifdef POSTK_DEBUG_ARCH_DEP_74 /* Fix HOST-Linux version dependent code (task_struct.start_time) */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
if (pli_iter->task->start_time > current->start_time) {
pli_next = pli_iter;
break;
}
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) */
if ((pli_iter->task->start_time.tv_sec >
current->start_time.tv_sec) ||
((pli_iter->task->start_time.tv_sec ==
@ -619,6 +647,18 @@ static long mcexec_get_cpuset(ihk_os_t os, unsigned long arg)
pli_next = pli_iter;
break;
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) */
#else /* POSTK_DEBUG_ARCH_DEP_74 */
if ((pli_iter->task->start_time.tv_sec >
current->start_time.tv_sec) ||
((pli_iter->task->start_time.tv_sec ==
current->start_time.tv_sec) &&
((pli_iter->task->start_time.tv_nsec >
current->start_time.tv_nsec)))) {
pli_next = pli_iter;
break;
}
#endif /* POSTK_DEBUG_ARCH_DEP_74 */
}
/* Add in front of next */
@ -1297,7 +1337,18 @@ retry_alloc:
ret = -EINVAL;;
goto put_ppd_out;
}
#ifdef POSTK_DEBUG_ARCH_DEP_46 /* user area direct access fix. */
if (copy_to_user(&req->cpu, &packet->ref, sizeof(req->cpu))) {
if (mcctrl_delete_per_thread_data(ppd, current) < 0) {
kprintf("%s: error deleting per-thread data\n", __FUNCTION__);
}
ret = -EINVAL;
goto put_ppd_out;
}
#else /* POSTK_DEBUG_ARCH_DEP_46 */
req->cpu = packet->ref;
#endif /* POSTK_DEBUG_ARCH_DEP_46 */
ret = 0;
goto put_ppd_out;
@ -1497,6 +1548,42 @@ mcexec_getcred(unsigned long phys)
{
int *virt = phys_to_virt(phys);
#ifdef POSTK_DEBUG_TEMP_FIX_45 /* setfsgid()/setfsuid() mismatch fix. */
int ret = -EINVAL;
if (virt[0] == 0 || virt[0] == task_pid_vnr(current)) {
virt[0] = GUIDVAL(current_uid());
virt[1] = GUIDVAL(current_euid());
virt[2] = GUIDVAL(current_suid());
virt[3] = GUIDVAL(current_fsuid());
virt[4] = GUIDVAL(current_gid());
virt[5] = GUIDVAL(current_egid());
virt[6] = GUIDVAL(current_sgid());
virt[7] = GUIDVAL(current_fsgid());
ret = 0;
} else {
const struct task_struct *task_p =
pid_task(find_get_pid(virt[0]), PIDTYPE_PID);
if (task_p) {
const struct cred *t_cred = __task_cred(task_p);
rcu_read_lock();
virt[0] = GUIDVAL(t_cred->uid);
virt[1] = GUIDVAL(t_cred->euid);
virt[2] = GUIDVAL(t_cred->suid);
virt[3] = GUIDVAL(t_cred->fsuid);
virt[4] = GUIDVAL(t_cred->gid);
virt[5] = GUIDVAL(t_cred->egid);
virt[6] = GUIDVAL(t_cred->sgid);
virt[7] = GUIDVAL(t_cred->fsgid);
rcu_read_unlock();
ret = 0;
}
}
return ret;
#else /* POSTK_DEBUG_TEMP_FIX_45 */
virt[0] = GUIDVAL(current_uid());
virt[1] = GUIDVAL(current_euid());
virt[2] = GUIDVAL(current_suid());
@ -1506,6 +1593,7 @@ mcexec_getcred(unsigned long phys)
virt[6] = GUIDVAL(current_sgid());
virt[7] = GUIDVAL(current_fsgid());
return 0;
#endif /* POSTK_DEBUG_TEMP_FIX_45 */
}
int
@ -2416,8 +2504,13 @@ mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *arg)
cpumask_t *cpuset;
struct mcctrl_usrdata *ud = ihk_host_os_get_usrdata(os);
ihk_device_t dev = ihk_os_to_dev(os);
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
struct mcctrl_cpu_topology *cpu_topo;
struct mcctrl_cpu_topology *target_cpu = NULL;
#else /* POSTK_DEBUG_ARCH_DEP_40 */
struct cpu_topology *cpu_topo;
struct cpu_topology *target_cpu = NULL;
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
struct node_topology *node_topo;
struct ihk_cache_topology *lcache_topo;
struct ihk_node_topology *lnode_topo;
@ -2486,8 +2579,18 @@ mcexec_uti_attr(ihk_os_t os, struct uti_attr_desc __user *arg)
continue;
if(IS_ERR(lnode_topo))
continue;
#ifdef POSTK_DEBUG_ARCH_DEP_54 /* cpu_isset() linux version depend fix. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
if (cpumask_test_cpu(target_cpu->saved->cpu_number,
&lnode_topo->cpumap)) {
#else
if (cpu_isset(target_cpu->saved->cpu_number,
lnode_topo->cpumap)) {
#endif
#else /* POSTK_DEBUG_ARCH_DEP_54 */
if (cpu_isset(target_cpu->saved->cpu_number,
lnode_topo->cpumap)) {
#endif /* POSTK_DEBUG_ARCH_DEP_54 */
if (kattr->attr.flags &
UTI_FLAG_SAME_NUMA_DOMAIN) {
cpumask_or(wkmask, wkmask,

View File

@ -1,3 +1,4 @@
/* driver.c COPYRIGHT FUJITSU LIMITED 2016 */
/**
* \file executer/kernel/driver.c
* License details are found in the file LICENSE.
@ -174,6 +175,9 @@ int mcctrl_os_shutdown_notifier(int os_index)
destroy_ikc_channels(os[os_index]);
procfs_exit(os_index);
}
#ifdef POSTK_DEBUG_TEMP_FIX_35 /* in shutdown phase, rus_page_hash_put_pages() call added. */
rus_page_hash_put_pages();
#endif /* POSTK_DEBUG_TEMP_FIX_35 */
os[os_index] = NULL;

View File

@ -1,3 +1,4 @@
// mcctrl.h COPYRIGHT FUJITSU LIMITED 2016-2017
/**
* \file mcctrl.h
* License details are found in the file LICENSE.
@ -106,10 +107,17 @@
#define __NR_coredump 999
#ifdef POSTK_DEBUG_TEMP_FIX_61 /* Core table size and lseek return value to loff_t */
struct coretable {
loff_t len;
unsigned long addr;
};
#else /* POSTK_DEBUG_TEMP_FIX_61 */
struct coretable {
int len;
unsigned long addr;
};
#endif /* POSTK_DEBUG_TEMP_FIX_61 */
enum mcctrl_os_cpu_operation {
MCCTRL_OS_CPU_READ_REGISTER,
@ -263,7 +271,11 @@ struct cache_topology {
struct list_head chain;
};
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
struct mcctrl_cpu_topology {
#else /* POSTK_DEBUG_ARCH_DEP_40 */
struct cpu_topology {
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
//struct mcctrl_usrdata *udp;
struct ihk_cpu_topology *saved;
int mckernel_cpu_id;
@ -367,8 +379,31 @@ int mcctrl_add_per_thread_data(struct mcctrl_per_proc_data* ppd,
struct task_struct *task, void *data);
int mcctrl_delete_per_thread_data(struct mcctrl_per_proc_data* ppd,
struct task_struct *task);
#ifdef POSTK_DEBUG_ARCH_DEP_56 /* Strange how to use inline declaration fix. */
static inline struct mcctrl_per_thread_data *mcctrl_get_per_thread_data(
struct mcctrl_per_proc_data *ppd, struct task_struct *task)
{
struct mcctrl_per_thread_data *ptd_iter, *ptd = NULL;
int hash = (((uint64_t)task >> 4) & MCCTRL_PER_THREAD_DATA_HASH_MASK);
unsigned long flags;
/* Check if data for this thread exists and return it */
read_lock_irqsave(&ppd->per_thread_data_hash_lock[hash], flags);
list_for_each_entry(ptd_iter, &ppd->per_thread_data_hash[hash], hash) {
if (ptd_iter->task == task) {
ptd = ptd_iter;
break;
}
}
read_unlock_irqrestore(&ppd->per_thread_data_hash_lock[hash], flags);
return ptd ? ptd->data : NULL;
}
#else /* POSTK_DEBUG_ARCH_DEP_56 */
inline struct mcctrl_per_thread_data *mcctrl_get_per_thread_data(
struct mcctrl_per_proc_data *ppd, struct task_struct *task);
#endif /* POSTK_DEBUG_ARCH_DEP_56 */
void __return_syscall(ihk_os_t os, struct ikc_scd_packet *packet,
long ret, int stid);
@ -409,6 +444,7 @@ void reply_get_cpu_mapping(long req_pa);
void free_topology_info(ihk_os_t os);
/* archdep.c */
#ifndef POSTK_DEBUG_ARCH_DEP_52
#define VDSO_MAXPAGES 2
struct vdso {
long busy;
@ -425,6 +461,7 @@ struct vdso {
void *pvti_virt;
long pvti_phys;
};
#endif /*POSTK_DEBUG_ARCH_DEP_52*/
int reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp,
unsigned long *endp);

View File

@ -9,6 +9,7 @@
/*
* HISTORY:
*/
/* procfs.c COPYRIGHT FUJITSU LIMITED 2016-2017 */
#include <linux/slab.h>
#include <linux/string.h>
@ -508,6 +509,215 @@ procfs_exit(int osnum)
* This function conforms to the 2) way of fs/proc/generic.c
* from linux-2.6.39.4.
*/
#ifdef POSTK_DEBUG_TEMP_FIX_43 /* Fixed an issue that failed pread / pwrite of size larger than 4MB */
static ssize_t __mckernel_procfs_read_write(
struct file *file,
char __user *buf, size_t nbytes,
loff_t *ppos, int read_write)
{
struct inode * inode = file->f_inode;
char *kern_buffer = NULL;
int order = 0;
volatile struct procfs_read *r = NULL;
struct ikc_scd_packet isp;
int ret, osnum, pid, retw;
unsigned long pbuf;
size_t count = nbytes;
size_t copy_size = 0;
size_t copied = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
struct proc_dir_entry *dp = PDE(inode);
struct procfs_list_entry *e = dp->data;
#else
struct procfs_list_entry *e = PDE_DATA(inode);
#endif
loff_t offset = *ppos;
char pathbuf[PROCFS_NAME_MAX];
char *path, *p;
ihk_os_t os = NULL;
struct mcctrl_usrdata *udp = NULL;
struct mcctrl_per_proc_data *ppd = NULL;
if (count <= 0 || offset < 0) {
return 0;
}
path = getpath(e, pathbuf, PROCFS_NAME_MAX);
dprintk("%s: invoked for %s, offset: %lu, count: %lu\n",
__FUNCTION__, path,
(unsigned long)offset, count);
/* Verify OS number */
ret = sscanf(path, "mcos%d/", &osnum);
if (ret != 1) {
printk("%s: error: couldn't determine OS number\n", __FUNCTION__);
return -EINVAL;
}
if (osnum != e->osnum) {
printk("%s: error: OS numbers don't match\n", __FUNCTION__);
return -EINVAL;
}
/* Is this request for a specific process? */
p = strchr(path, '/') + 1;
ret = sscanf(p, "%d/", &pid);
if (ret != 1) {
pid = -1;
}
os = osnum_to_os(osnum);
if (!os) {
printk("%s: error: no IHK OS data found for OS %d\n",
__FUNCTION__, osnum);
return -EINVAL;
}
udp = ihk_host_os_get_usrdata(os);
if (!udp) {
printk("%s: error: no MCCTRL data found for OS %d\n",
__FUNCTION__, osnum);
return -EINVAL;
}
if (pid > 0) {
ppd = mcctrl_get_per_proc_data(udp, pid);
if (unlikely(!ppd)) {
printk("%s: error: no per-process structure for PID %d",
__FUNCTION__, pid);
return -EINVAL;
}
}
/* NOTE: we need physically contigous memory to pass through IKC */
for (order = get_order(count); order >= 0; order--) {
kern_buffer = (char *)__get_free_pages(GFP_KERNEL, order);
if (kern_buffer) {
break;
}
}
if (!kern_buffer) {
printk("%s: ERROR: allocating kernel buffer\n", __FUNCTION__);
ret = -ENOMEM;
goto out;
}
copy_size = PAGE_SIZE * (1 << order);
pbuf = virt_to_phys(kern_buffer);
r = kmalloc(sizeof(struct procfs_read), GFP_KERNEL);
if (r == NULL) {
ret = -ENOMEM;
goto out;
}
while (count > 0) {
int this_len = min_t(ssize_t, count, copy_size);
r->pbuf = pbuf;
r->eof = 0;
r->ret = -EIO; /* default */
r->status = 0;
r->offset = offset;
r->count = this_len;
r->readwrite = read_write;
strncpy((char *)r->fname, path, PROCFS_NAME_MAX);
isp.msg = SCD_MSG_PROCFS_REQUEST;
isp.ref = 0;
isp.arg = virt_to_phys(r);
isp.pid = pid;
ret = mcctrl_ikc_send(osnum_to_os(e->osnum),
(pid > 0) ? ppd->ikc_target_cpu : 0, &isp);
if (ret < 0) {
goto out; /* error */
}
/* Wait for a reply. */
ret = -EIO; /* default exit code */
dprintk("%s: waiting for reply\n", __FUNCTION__);
retry_wait:
/* Wait for the status field of the procfs_read structure,
* wait on per-process or OS specific data depending on
* who the request is for.
*/
if (pid > 0) {
retw = wait_event_interruptible_timeout(ppd->wq_procfs,
r->status != 0, HZ);
}
else {
retw = wait_event_interruptible_timeout(udp->wq_procfs,
r->status != 0, HZ);
}
/* Timeout? */
if (retw == 0 && r->status == 0) {
printk("%s: error: timeout (1 sec)\n", __FUNCTION__);
goto out;
}
/* Interrupted? */
else if (retw == -ERESTARTSYS) {
ret = -ERESTART;
goto out;
}
/* Were we woken up by a reply to another procfs request? */
else if (r->status == 0) {
/* TODO: r->status is not set atomically, we could be woken
* up with status == 0 and it could change to 1 while in this
* code, we could potentially miss the wake_up()...
*/
printk("%s: stale wake-up, retrying\n", __FUNCTION__);
goto retry_wait;
}
/* Wake up and check the result. */
dprintk("%s: woke up. ret: %d, eof: %d\n",
__FUNCTION__, r->ret, r->eof);
if (r->ret > 0) {
if (read_write == 0) {
if (copy_to_user(buf, kern_buffer, r->ret)) {
printk("%s: ERROR: copy_to_user failed.\n", __FUNCTION__);
ret = -EFAULT;
goto out;
}
}
buf += r->ret;
offset += r->ret;
copied += r->ret;
count -= r->ret;
}
else {
if (!copied) {
/* Transmit error from McKernel */
copied = r->ret;
}
break;
}
if (r->eof != 0) {
break;
}
}
*ppos = offset;
ret = copied;
out:
if (ppd)
mcctrl_put_per_proc_data(ppd);
if (kern_buffer)
free_pages((uintptr_t)kern_buffer, order);
if (r)
kfree((void *)r);
return ret;
}
#else /* POSTK_DEBUG_TEMP_FIX_43 */
static ssize_t __mckernel_procfs_read_write(
struct file *file,
char __user *buf, size_t nbytes,
@ -693,6 +903,7 @@ out:
return ret;
}
#endif /* POSTK_DEBUG_TEMP_FIX_43 */
static ssize_t mckernel_procfs_read(struct file *file,
char __user *buf, size_t nbytes, loff_t *ppos)
@ -832,7 +1043,11 @@ static const struct procfs_entry pid_entry_stuff[] = {
static const struct procfs_entry base_entry_stuff[] = {
// PROC_REG("cmdline", S_IRUGO, NULL),
#ifdef POSTK_DEBUG_ARCH_DEP_42 /* /proc/cpuinfo support added. */
PROC_REG("cpuinfo", S_IRUGO, NULL),
#else /* POSTK_DEBUG_ARCH_DEP_42 */
// PROC_REG("cpuinfo", S_IRUGO, NULL),
#endif /* POSTK_DEBUG_ARCH_DEP_42 */
// PROC_REG("meminfo", S_IRUGO, NULL),
// PROC_REG("pagetypeinfo",S_IRUGO, NULL),
// PROC_REG("softirq", S_IRUGO, NULL),

View File

@ -1,3 +1,4 @@
/* syscall.c COPYRIGHT FUJITSU LIMITED 2016-2017 */
/**
* \file executer/kernel/syscall.c
* License details are found in the file LICENSE.
@ -48,6 +49,9 @@
#include "../../../config.h"
#include "mcctrl.h"
#include <linux/version.h>
#ifdef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */
#include <archdeps.h>
#endif /* POSTK_DEBUG_ARCH_DEP_83 */
#define ALIGN_WAIT_BUF(z) (((z + 63) >> 6) << 6)
@ -157,6 +161,7 @@ out:
return ret;
}
#ifndef POSTK_DEBUG_ARCH_DEP_56 /* Strange how to use inline declaration fix. */
struct mcctrl_per_thread_data *mcctrl_get_per_thread_data(struct mcctrl_per_proc_data *ppd, struct task_struct *task)
{
struct mcctrl_per_thread_data *ptd_iter, *ptd = NULL;
@ -176,7 +181,9 @@ struct mcctrl_per_thread_data *mcctrl_get_per_thread_data(struct mcctrl_per_proc
read_unlock_irqrestore(&ppd->per_thread_data_hash_lock[hash], flags);
return ptd ? ptd->data : NULL;
}
#endif /* !POSTK_DEBUG_ARCH_DEP_56 */
#ifndef POSTK_DEBUG_ARCH_DEP_83 /* arch depend translate_rva_to_rpa() move */
#if 1 /* x86 depend, host OS side */
int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
unsigned long *rpap, unsigned long *pgsizep)
@ -240,6 +247,7 @@ out:
return error;
}
#endif
#endif /* !POSTK_DEBUG_ARCH_DEP_83 */
static int __notify_syscall_requester(ihk_os_t os, struct ikc_scd_packet *packet,
struct syscall_response *res)
@ -764,8 +772,18 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
struct ikc_scd_packet *packet;
int ret = 0;
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
dprintk("mcctrl:page fault:flags %#x pgoff %#lx va %#lx page %p\n",
vmf->flags, vmf->pgoff, vmf->address, vmf->page);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
dprintk("mcctrl:page fault:flags %#x pgoff %#lx va %p page %p\n",
vmf->flags, vmf->pgoff, vmf->virtual_address, vmf->page);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
dprintk("mcctrl:page fault:flags %#x pgoff %#lx va %p page %p\n",
vmf->flags, vmf->pgoff, vmf->virtual_address, vmf->page);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
/* Look up per-process structure */
ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(current));
@ -788,16 +806,41 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
for (try = 1; ; ++try) {
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
error = translate_rva_to_rpa(usrdata->os, ppd->rpgtable,
vmf->address, &rpa, &pgsize);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
error = translate_rva_to_rpa(usrdata->os, ppd->rpgtable,
(unsigned long)vmf->virtual_address,
&rpa, &pgsize);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
error = translate_rva_to_rpa(usrdata->os, ppd->rpgtable,
(unsigned long)vmf->virtual_address,
&rpa, &pgsize);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
#define NTRIES 2
if (!error || (try >= NTRIES)) {
if (error) {
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
printk("%s: error translating 0x%#lx "
"(req: TID: %u, syscall: %lu)\n",
__FUNCTION__, vmf->address,
packet->req.rtid, packet->req.number);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
printk("%s: error translating 0x%p "
"(req: TID: %u, syscall: %lu)\n",
__FUNCTION__, vmf->virtual_address,
packet->req.rtid, packet->req.number);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
printk("%s: error translating 0x%p "
"(req: TID: %u, syscall: %lu)\n",
__FUNCTION__, vmf->virtual_address,
packet->req.rtid, packet->req.number);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
}
break;
@ -808,12 +851,34 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
#define PF_WRITE 0x02
reason |= PF_WRITE;
}
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
error = remote_page_fault(usrdata, (void *)vmf->address, reason);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
error = remote_page_fault(usrdata, vmf->virtual_address, reason);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
error = remote_page_fault(usrdata, vmf->virtual_address, reason);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
if (error) {
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
printk("%s: error forwarding PF for 0x%#lx "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->address,
packet->req.rtid, packet->req.number);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
printk("%s: error forwarding PF for 0x%p "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->virtual_address,
packet->req.rtid, packet->req.number);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
printk("%s: error forwarding PF for 0x%p "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->virtual_address,
packet->req.rtid, packet->req.number);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
break;
}
}
@ -822,7 +887,15 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
goto put_and_out;
}
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
rva = vmf->address & ~(pgsize - 1);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
rva = (unsigned long)vmf->virtual_address & ~(pgsize - 1);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
rva = (unsigned long)vmf->virtual_address & ~(pgsize - 1);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
rpa = rpa & ~(pgsize - 1);
phys = ihk_device_map_memory(dev, rpa, pgsize);
@ -841,26 +914,66 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
page = pfn_to_page(pfn+pix);
if ((error = rus_page_hash_insert(page)) < 0) {
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
printk("%s: error adding page to RUS hash for 0x%#lx "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->address,
packet->req.rtid, packet->req.number);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
printk("%s: error adding page to RUS hash for 0x%p "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->virtual_address,
packet->req.rtid, packet->req.number);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
printk("%s: error adding page to RUS hash for 0x%p "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->virtual_address,
packet->req.rtid, packet->req.number);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
}
error = vm_insert_page(vma, rva+(pix*PAGE_SIZE), page);
if (error) {
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
printk("%s: error inserting mapping for 0x%#lx "
"(req: TID: %d, syscall: %lu) error: %d, "
"vm_start: 0x%lx, vm_end: 0x%lx\n",
__FUNCTION__, vmf->address,
packet->req.rtid, packet->req.number, error,
vma->vm_start, vma->vm_end);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
printk("%s: error inserting mapping for 0x%p "
"(req: TID: %d, syscall: %lu) error: %d, "
"vm_start: 0x%lx, vm_end: 0x%lx\n",
__FUNCTION__, vmf->virtual_address,
packet->req.rtid, packet->req.number, error,
vma->vm_start, vma->vm_end);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
printk("%s: error inserting mapping for 0x%p "
"(req: TID: %d, syscall: %lu) error: %d, "
"vm_start: 0x%lx, vm_end: 0x%lx\n",
__FUNCTION__, vmf->virtual_address,
packet->req.rtid, packet->req.number, error,
vma->vm_start, vma->vm_end);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
}
}
else
error = vm_insert_pfn(vma, rva+(pix*PAGE_SIZE), pfn+pix);
if (error) {
#ifdef POSTK_DEBUG_TEMP_FIX_11 /* rus_vm_fault() multi-thread fix */
if (error == -EBUSY) {
error = 0;
} else {
break;
}
#else /* POSTK_DEBUG_TEMP_FIX_11 */
break;
#endif /* POSTK_DEBUG_TEMP_FIX_11 */
}
}
#else
@ -868,10 +981,24 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
#endif
ihk_device_unmap_memory(dev, phys, pgsize);
if (error) {
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* HOST-Linux version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
printk("%s: remote PF failed for 0x%#lx, pgoff: %lu "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->address, vmf->pgoff,
packet->req.rtid, packet->req.number);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
printk("%s: remote PF failed for 0x%p, pgoff: %lu "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->virtual_address, vmf->pgoff,
packet->req.rtid, packet->req.number);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
#else /* POSTK_DEBUG_ARCH_DEP_41 */
printk("%s: remote PF failed for 0x%p, pgoff: %lu "
"(req: TID: %d, syscall: %lu)\n",
__FUNCTION__, vmf->virtual_address, vmf->pgoff,
packet->req.rtid, packet->req.number);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
ret = VM_FAULT_SIGBUS;
goto put_and_out;
}
@ -1322,12 +1449,17 @@ static int pager_req_read(ihk_os_t os, uintptr_t handle, off_t off, size_t size,
pos = off;
ss = vfs_read(file, buf, size, &pos);
if ((ss != size) && (ss > 0)) {
#ifdef POSTK_DEBUG_TEMP_FIX_12 /* clear_user() used by kernel area, fix */
memset(buf + ss, 0, size - ss);
ss = size;
#else /* POSTK_DEBUG_TEMP_FIX_12 */
if (clear_user(buf+ss, size-ss) == 0) {
ss = size;
}
else {
ss = -EFAULT;
}
#endif /* POSTK_DEBUG_TEMP_FIX_12 */
}
set_fs(fs);
if (ss < 0) {
@ -1604,10 +1736,16 @@ retry:
pfn |= PFN_VALID | PFN_PRESENT;
/* Check if mapping is write-combined */
#ifdef POSTK_DEBUG_ARCH_DEP_12
if (pte_is_write_combined(*pte)) {
pfn |= PFN_WRITE_COMBINED;
}
#else /* POSTK_DEBUG_ARCH_DEP_12 */
if ((pte_flags(*pte) & _PAGE_PWT) &&
!(pte_flags(*pte) & _PAGE_PCD)) {
pfn |= _PAGE_PWT;
}
#endif /* POSTK_DEBUG_ARCH_DEP_12 */
}
pte_unmap(pte);
}
@ -1631,7 +1769,11 @@ retry:
goto out_release;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0)
fault = handle_mm_fault(vma, va, flags);
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0) */
fault = handle_mm_fault(current->mm, vma, va, flags);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0) */
if (fault != 0) {
printk("%s: error: faulting %lx at off: %lu\n",
__FUNCTION__, va, off);
@ -1972,7 +2114,13 @@ static int clear_pte_range(uintptr_t start, uintptr_t len)
static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) {
struct file *file;
struct coretable *coretable;
#ifdef POSTK_DEBUG_TEMP_FIX_61 /* Core table size and lseek return value to loff_t */
int i, tablesize, error = 0;
loff_t size;
ssize_t ret;
#else /* POSTK_DEBUG_TEMP_FIX_61 */
int ret, i, tablesize, size, error = 0;
#endif /* POSTK_DEBUG_TEMP_FIX_61 */
mm_segment_t oldfs = get_fs();
unsigned long phys, tablephys, rphys;
ihk_device_t dev = ihk_os_to_dev(os);
@ -1994,8 +2142,20 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) {
* dump routine of the Linux kernel in linux/fs/exec.c.
* So we have a legitimate reason to do this.
*/
#ifdef POSTK_DEBUG_TEMP_FIX_59 /* corefile open flag add O_TRUNC */
file = filp_open("core", O_CREAT | O_RDWR | O_LARGEFILE | O_TRUNC, 0600);
#else /* POSTK_DEBUG_TEMP_FIX_59 */
file = filp_open("core", O_CREAT | O_RDWR | O_LARGEFILE, 0600);
#endif /* POSTK_DEBUG_TEMP_FIX_59 */
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* use writehandler version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)
if (IS_ERR(file) || !file->f_op) {
#else
if (IS_ERR(file) || !file->f_op || !file->f_op->write) {
#endif
#else /* POSTK_DEBUG_ARCH_DEP_41 */
if (IS_ERR(file) || !file->f_op || !file->f_op->write) {
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
dprintk("cannot open core file\n");
error = PTR_ERR(file);
goto fail;
@ -2014,9 +2174,22 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) {
phys = ihk_device_map_memory(dev, rphys, size);
dprintk("physical %lx, ", phys);
pt = ihk_device_map_virtual(dev, phys, size, NULL, 0);
#ifdef POSTK_DEBUG_TEMP_FIX_38
if (pt == NULL) {
pt = phys_to_virt(phys);
}
#endif /*POSTK_DEBUG_TEMP_FIX_38*/
dprintk("virtual %p\n", pt);
if (pt != NULL) {
#ifdef POSTK_DEBUG_ARCH_DEP_41 /* use writehandler version switch add */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)
ret = __kernel_write(file, pt, size, &file->f_pos);
#else
ret = file->f_op->write(file, pt, size, &file->f_pos);
#endif
#else /* POSTK_DEBUG_ARCH_DEP_41 */
ret = file->f_op->write(file, pt, size, &file->f_pos);
#endif /* POSTK_DEBUG_ARCH_DEP_41 */
} else {
dprintk("cannot map physical memory(%lx) to virtual memory.\n",
phys);
@ -2027,7 +2200,11 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) {
ihk_device_unmap_virtual(dev, pt, size);
ihk_device_unmap_memory(dev, phys, size);
if (ret != size) {
#ifdef POSTK_DEBUG_TEMP_FIX_61 /* Core table size and lseek return value to loff_t */
dprintk("core file write failed(%ld).\n", ret);
#else /* POSTK_DEBUG_TEMP_FIX_61 */
dprintk("core file write failed(%d).\n", ret);
#endif /* POSTK_DEBUG_TEMP_FIX_61 */
error = PTR_ERR(file);
break;
}
@ -2040,7 +2217,11 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) {
}
ret = file->f_op->llseek(file, size, SEEK_CUR);
if (ret < 0) {
#ifdef POSTK_DEBUG_TEMP_FIX_61 /* Core table size and lseek return value to loff_t */
dprintk("core file seek failed(%ld).\n", ret);
#else /* POSTK_DEBUG_TEMP_FIX_61 */
dprintk("core file seek failed(%d).\n", ret);
#endif /* POSTK_DEBUG_TEMP_FIX_61 */
error = PTR_ERR(file);
break;
}
@ -2110,7 +2291,11 @@ int __do_in_kernel_syscall(ihk_os_t os, struct ikc_scd_packet *packet)
case __NR_coredump:
error = writecore(os, sc->args[1], sc->args[0]);
#ifdef POSTK_DEBUG_TEMP_FIX_62 /* Fix to notify McKernel that core file generation failed */
ret = error;
#else /* POSTK_DEBUG_TEMP_FIX_62 */
ret = 0;
#endif /* POSTK_DEBUG_TEMP_FIX_62 */
break;
case __NR_sched_setparam: {

View File

@ -1,3 +1,4 @@
// sysfs_files.c COPYRIGHT FUJITSU LIMITED 2016
/**
* \file sysfs_files.c
* License details are found in the file LICENSE.
@ -151,8 +152,13 @@ static void free_node_topology(struct mcctrl_usrdata *udp)
return;
} /* free_node_topology() */
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
static void free_cpu_topology_one(struct mcctrl_usrdata *udp,
struct mcctrl_cpu_topology *cpu)
#else /* POSTK_DEBUG_ARCH_DEP_40 */
static void free_cpu_topology_one(struct mcctrl_usrdata *udp,
struct cpu_topology *cpu)
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
{
struct cache_topology *cache;
struct cache_topology *next;
@ -168,8 +174,13 @@ static void free_cpu_topology_one(struct mcctrl_usrdata *udp,
static void free_cpu_topology(struct mcctrl_usrdata *udp)
{
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
struct mcctrl_cpu_topology *cpu;
struct mcctrl_cpu_topology *next;
#else /* POSTK_DEBUG_ARCH_DEP_40 */
struct cpu_topology *cpu;
struct cpu_topology *next;
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
list_for_each_entry_safe(cpu, next, &udp->cpu_topology_list, chain) {
list_del(&cpu->chain);
@ -299,8 +310,13 @@ static int translate_cpumap(struct mcctrl_usrdata *udp,
return error;
} /* translate_cpumap() */
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
static struct cache_topology *get_cache_topology(struct mcctrl_usrdata *udp,
struct mcctrl_cpu_topology *cpu_topo, struct ihk_cache_topology *saved)
#else /* POSTK_DEBUG_ARCH_DEP_40 */
static struct cache_topology *get_cache_topology(struct mcctrl_usrdata *udp,
struct cpu_topology *cpu_topo, struct ihk_cache_topology *saved)
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
{
int error;
struct cache_topology *topo = NULL;
@ -334,12 +350,21 @@ out:
return (error)? ERR_PTR(error): topo;
} /* get_cache_topology() */
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
static struct mcctrl_cpu_topology *get_one_cpu_topology(struct mcctrl_usrdata *udp,
int index)
#else /* POSTK_DEBUG_ARCH_DEP_40 */
static struct cpu_topology *get_one_cpu_topology(struct mcctrl_usrdata *udp,
int index)
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
{
int error;
ihk_device_t dev = ihk_os_to_dev(udp->os);
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
struct mcctrl_cpu_topology *topology = NULL;
#else /* POSTK_DEBUG_ARCH_DEP_40 */
struct cpu_topology *topology = NULL;
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
struct cache_topology *cache;
struct ihk_cache_topology *saved_cache;
@ -357,7 +382,11 @@ static struct cpu_topology *get_one_cpu_topology(struct mcctrl_usrdata *udp,
topology->saved = ihk_device_get_cpu_topology(dev,
mckernel_cpu_2_hw_id(udp, index));
#ifdef POSTK_DEBUG_TEMP_FIX_21 /* IS_ERR() through return NULL */
if (!topology->saved) {
#else /* POSTK_DEBUG_TEMP_FIX_21 */
if (IS_ERR(topology->saved)) {
#endif /* POSTK_DEBUG_TEMP_FIX_21 */
error = PTR_ERR(topology->saved);
eprintk("mcctrl:get_one_cpu_topology:"
"ihk_device_get_cpu_topology failed. %d\n",
@ -413,7 +442,11 @@ static int get_cpu_topology(struct mcctrl_usrdata *udp)
{
int error;
int index;
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
struct mcctrl_cpu_topology *topology;
#else /* POSTK_DEBUG_ARCH_DEP_40 */
struct cpu_topology *topology;
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
dprintk("get_cpu_topology(%p)\n", udp);
for (index = 0; index < udp->cpu_info->n_cpus; ++index) {
@ -435,8 +468,13 @@ out:
return error;
} /* get_cpu_topology() */
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
static void setup_cpu_sysfs_cache_files(struct mcctrl_usrdata *udp,
struct mcctrl_cpu_topology *cpu, struct cache_topology *cache)
#else /* POSTK_DEBUG_ARCH_DEP_40 */
static void setup_cpu_sysfs_cache_files(struct mcctrl_usrdata *udp,
struct cpu_topology *cpu, struct cache_topology *cache)
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
{
char *prefix = "/sys/devices/system/cpu";
int cpu_number = cpu->mckernel_cpu_id;
@ -488,8 +526,13 @@ static void setup_cpu_sysfs_cache_files(struct mcctrl_usrdata *udp,
return;
} /* setup_cpu_sysfs_cache_files() */
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
static void setup_cpu_sysfs_files(struct mcctrl_usrdata *udp,
struct mcctrl_cpu_topology *cpu)
#else /* POSTK_DEBUG_ARCH_DEP_40 */
static void setup_cpu_sysfs_files(struct mcctrl_usrdata *udp,
struct cpu_topology *cpu)
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
{
char *prefix = "/sys/devices/system/cpu";
int cpu_number = cpu->mckernel_cpu_id;
@ -566,7 +609,11 @@ static void setup_cpus_sysfs_files_node_link(struct mcctrl_usrdata *udp)
static void setup_cpus_sysfs_files(struct mcctrl_usrdata *udp)
{
int error;
#ifdef POSTK_DEBUG_ARCH_DEP_40 /* cpu_topology name change */
struct mcctrl_cpu_topology *cpu;
#else /* POSTK_DEBUG_ARCH_DEP_40 */
struct cpu_topology *cpu;
#endif /* POSTK_DEBUG_ARCH_DEP_40 */
error = get_cpu_topology(udp);
if (error) {
@ -904,21 +951,30 @@ out:
return error;
} /* read_link() */
#ifdef POSTK_DEBUG_TEMP_FIX_22 /* iterate_dir() deadlock */
static int setup_one_pci(struct mcctrl_usrdata *udp, const char *name)
{
#else /* POSTK_DEBUG_TEMP_FIX_22 */
static int setup_one_pci(void *arg0, const char *name, int namlen,
loff_t offset, u64 ino, unsigned d_type)
{
struct mcctrl_usrdata *udp = arg0;
#endif /* POSTK_DEBUG_TEMP_FIX_22 */
int error;
char *buf = NULL;
long node;
struct sysfsm_bitmap_param param;
#ifdef POSTK_DEBUG_TEMP_FIX_22 /* iterate_dir() deadlock */
dprintk("setup_one_pci(%p,%s)\n", udp, name);
#else /* POSTK_DEBUG_TEMP_FIX_22 */
dprintk("setup_one_pci(%p,%s,%d,%#lx,%#lx,%d)\n",
arg0, name, namlen, (long)offset, (long)ino, d_type);
if (namlen != 12) {
error = 0;
goto out;
}
#endif /* POSTK_DEBUG_TEMP_FIX_22 */
buf = (void *)__get_free_pages(GFP_KERNEL, 0);
if (!buf) {
@ -970,12 +1026,65 @@ static int setup_one_pci(void *arg0, const char *name, int namlen,
error = 0;
out:
free_pages((long)buf, 0);
#ifdef POSTK_DEBUG_TEMP_FIX_22 /* iterate_dir() deadlock */
dprintk("setup_one_pci(%p,%s): %d\n", udp, name, error);
#else /* POSTK_DEBUG_TEMP_FIX_22 */
dprintk("setup_one_pci(%p,%s,%d,%#lx,%#lx,%d): %d\n",
arg0, name, namlen, (long)offset, (long)ino, d_type,
error);
#endif /* POSTK_DEBUG_TEMP_FIX_22 */
return error;
} /* setup_one_pci() */
#ifdef POSTK_DEBUG_TEMP_FIX_22 /* iterate_dir() deadlock */
LIST_HEAD(pci_file_name_list);
struct pci_file_name {
char *name;
struct list_head chain;
};
static int pci_file_name_gen(void *buf, const char *name, int namlen,
loff_t offset, u64 ino, unsigned d_type)
{
struct pci_file_name *p;
int error = -1;
dprintk("pci_file_name_gen(%p,%s,%d,%#lx,%#lx,%d)\n",
buf, name, namlen, (long)offset, (long)ino, d_type);
/* check namlen, name exmple, "0000:00:00.0" 12 chars */
/* otherstring, return function */
if (namlen != 12) {
error = 0;
goto out;
}
p = kmalloc(sizeof(*p), GFP_KERNEL);
if (!p) {
error = -ENOMEM;
eprintk("mcctrl:pci_file_name_gen:kmalloc failed. %d\n", error);
goto out;
}
p->name = kmalloc(sizeof(namlen + 1), GFP_KERNEL);
if (!p->name) {
error = -ENOMEM;
eprintk("mcctrl:pci_file_name_gen:kmalloc failed. %d\n", error);
kfree(p);
goto out;
}
memset(p->name, '\0', namlen + 1);
memcpy(p->name, name, namlen);
list_add(&p->chain, &pci_file_name_list);
error = 0;
out:
dprintk("pci_file_name_gen(%p,%s,%d,%#lx,%#lx,%d): %d\n",
buf, name, namlen, (long)offset, (long)ino, d_type, error);
return error;
}
#endif /* POSTK_DEBUG_TEMP_FIX_22 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
typedef int (*mcctrl_filldir_t)(void *buf, const char *name, int namlen,
loff_t offset, u64 ino, unsigned d_type);
@ -1019,6 +1128,11 @@ static int setup_pci_files(struct mcctrl_usrdata *udp)
int error;
int er;
struct file *fp = NULL;
#ifdef POSTK_DEBUG_TEMP_FIX_22 /* iterate_dir() deadlock */
int ret = 0;
struct pci_file_name *cur;
struct pci_file_name *next;
#endif /* POSTK_DEBUG_TEMP_FIX_22 */
dprintk("setup_pci_files(%p)\n", udp);
fp = filp_open("/sys/bus/pci/devices", O_DIRECTORY, 0);
@ -1028,13 +1142,28 @@ static int setup_pci_files(struct mcctrl_usrdata *udp)
goto out;
}
#ifdef POSTK_DEBUG_TEMP_FIX_22 /* iterate_dir() deadlock */
error = mcctrl_vfs_readdir(fp, &pci_file_name_gen, udp);
#else /* POSTK_DEBUG_TEMP_FIX_22 */
error = mcctrl_vfs_readdir(fp, &setup_one_pci, udp);
#endif /* POSTK_DEBUG_TEMP_FIX_22 */
if (error) {
eprintk("mcctrl:setup_pci_files:"
"mcctrl_vfs_readdir failed. %d\n", error);
goto out;
}
#ifdef POSTK_DEBUG_TEMP_FIX_22 /* iterate_dir() deadlock */
list_for_each_entry_safe(cur, next, &pci_file_name_list, chain) {
if (!ret) {
ret = setup_one_pci(udp, cur->name);
}
list_del(&cur->chain);
kfree(cur->name);
kfree(cur);
}
#endif /* POSTK_DEBUG_TEMP_FIX_22 */
error = 0;
out:
if (!IS_ERR_OR_NULL(fp)) {