Merge remote branch 'origin/master' into gdb
Conflicts: kernel/include/process.h
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <cpulocal.h>
|
||||
#include <march.h>
|
||||
#include <signal.h>
|
||||
#include <process.h>
|
||||
|
||||
#define LAPIC_ID 0x020
|
||||
#define LAPIC_TIMER 0x320
|
||||
@@ -438,6 +439,7 @@ void handle_interrupt(int vector, struct x86_regs *regs)
|
||||
}
|
||||
|
||||
check_signal(0, regs);
|
||||
check_need_resched();
|
||||
}
|
||||
|
||||
void gpe_handler(struct x86_regs *regs)
|
||||
@@ -447,6 +449,7 @@ void gpe_handler(struct x86_regs *regs)
|
||||
arch_show_interrupt_context(regs);
|
||||
set_signal(SIGILL, regs);
|
||||
check_signal(0, regs);
|
||||
check_need_resched();
|
||||
// panic("GPF");
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@
|
||||
#define PFL3_DIRTY ((pte_t)0x40)
|
||||
#define PFL3_SIZE ((pte_t)0x80) /* Used in 1G page */
|
||||
#define PFL3_GLOBAL ((pte_t)0x100)
|
||||
#define PFL3_IGNORED_11 ((pte_t)1 << 11)
|
||||
#define PFL3_FILEOFF PFL3_IGNORED_11
|
||||
|
||||
#define PFL2_PRESENT ((pte_t)0x01)
|
||||
#define PFL2_WRITABLE ((pte_t)0x02)
|
||||
@@ -88,6 +90,8 @@
|
||||
#define PFL2_DIRTY ((pte_t)0x40)
|
||||
#define PFL2_SIZE ((pte_t)0x80) /* Used in 2M page */
|
||||
#define PFL2_GLOBAL ((pte_t)0x100)
|
||||
#define PFL2_IGNORED_11 ((pte_t)1 << 11)
|
||||
#define PFL2_FILEOFF PFL2_IGNORED_11
|
||||
|
||||
#define PFL1_PRESENT ((pte_t)0x01)
|
||||
#define PFL1_WRITABLE ((pte_t)0x02)
|
||||
@@ -96,6 +100,8 @@
|
||||
#define PFL1_PCD ((pte_t)0x10)
|
||||
#define PFL1_ACCESSED ((pte_t)0x20)
|
||||
#define PFL1_DIRTY ((pte_t)0x40)
|
||||
#define PFL1_IGNORED_11 ((pte_t)1 << 11)
|
||||
#define PFL1_FILEOFF PFL1_IGNORED_11
|
||||
|
||||
/* We allow user programs to access all the memory */
|
||||
#define PFL4_KERN_ATTR (PFL4_PRESENT | PFL4_WRITABLE)
|
||||
@@ -108,6 +114,9 @@
|
||||
#define PFL3_PDIR_ATTR (PFL3_PRESENT | PFL3_WRITABLE | PFL3_USER)
|
||||
#define PFL2_PDIR_ATTR (PFL2_PRESENT | PFL2_WRITABLE | PFL2_USER)
|
||||
|
||||
#define PTE_NULL ((pte_t)0)
|
||||
typedef unsigned long pte_t;
|
||||
|
||||
/* For easy conversion, it is better to be the same as architecture's ones */
|
||||
enum ihk_mc_pt_attribute {
|
||||
PTATTR_ACTIVE = 0x01,
|
||||
@@ -115,14 +124,12 @@ enum ihk_mc_pt_attribute {
|
||||
PTATTR_USER = 0x04,
|
||||
PTATTR_DIRTY = 0x40,
|
||||
PTATTR_LARGEPAGE = 0x80,
|
||||
PTATTR_FILEOFF = PFL2_FILEOFF,
|
||||
PTATTR_NO_EXECUTE = 0x8000000000000000,
|
||||
PTATTR_UNCACHABLE = 0x10000,
|
||||
PTATTR_FOR_USER = 0x20000,
|
||||
};
|
||||
|
||||
#define PTE_NULL ((pte_t)0)
|
||||
typedef unsigned long pte_t;
|
||||
|
||||
static inline int pte_is_null(pte_t *ptep)
|
||||
{
|
||||
return (*ptep == PTE_NULL);
|
||||
@@ -138,11 +145,77 @@ static inline int pte_is_writable(pte_t *ptep)
|
||||
return !!(*ptep & PF_WRITABLE);
|
||||
}
|
||||
|
||||
static inline int pte_is_dirty(pte_t *ptep, size_t pgsize)
|
||||
{
|
||||
switch (pgsize) {
|
||||
case PTL1_SIZE: return !!(*ptep & PFL1_DIRTY);
|
||||
case PTL2_SIZE: return !!(*ptep & PFL2_DIRTY);
|
||||
case PTL3_SIZE: return !!(*ptep & PFL3_DIRTY);
|
||||
default:
|
||||
#if 0 /* XXX: workaround. cannot use panic() here */
|
||||
panic("pte_is_dirty");
|
||||
#else
|
||||
return !!(*ptep & PTATTR_DIRTY);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static inline int pte_is_fileoff(pte_t *ptep, size_t pgsize)
|
||||
{
|
||||
switch (pgsize) {
|
||||
case PTL1_SIZE: return !!(*ptep & PFL1_FILEOFF);
|
||||
case PTL2_SIZE: return !!(*ptep & PFL2_FILEOFF);
|
||||
case PTL3_SIZE: return !!(*ptep & PFL3_FILEOFF);
|
||||
default:
|
||||
#if 0 /* XXX: workaround. cannot use panic() here */
|
||||
panic("pte_is_fileoff");
|
||||
#else
|
||||
return !!(*ptep & PTATTR_FILEOFF);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static inline uintptr_t pte_get_phys(pte_t *ptep)
|
||||
{
|
||||
return (*ptep & PT_PHYSMASK);
|
||||
}
|
||||
|
||||
static inline off_t pte_get_off(pte_t *ptep, size_t pgsize)
|
||||
{
|
||||
return (off_t)(*ptep & PAGE_MASK);
|
||||
}
|
||||
|
||||
static inline void pte_make_fileoff(off_t off,
|
||||
enum ihk_mc_pt_attribute ptattr, size_t pgsize, pte_t *ptep)
|
||||
{
|
||||
uint64_t attr;
|
||||
|
||||
attr = ptattr & ~PAGE_MASK;
|
||||
|
||||
switch (pgsize) {
|
||||
case PTL1_SIZE: attr |= PFL1_FILEOFF; break;
|
||||
case PTL2_SIZE: attr |= PFL2_FILEOFF | PFL2_SIZE; break;
|
||||
case PTL3_SIZE: attr |= PFL3_FILEOFF | PFL3_SIZE; break;
|
||||
default:
|
||||
#if 0 /* XXX: workaround. cannot use panic() here */
|
||||
panic("pte_make_fileoff");
|
||||
#else
|
||||
attr |= PTATTR_FILEOFF;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
*ptep = (off & PAGE_MASK) | attr;
|
||||
}
|
||||
|
||||
#if 0 /* XXX: workaround. cannot use panic() here */
|
||||
static inline void pte_xchg(pte_t *ptep, pte_t *valp)
|
||||
{
|
||||
*valp = xchg(ptep, *valp);
|
||||
}
|
||||
#else
|
||||
#define pte_xchg(p,vp) do { *(vp) = xchg((p), *(vp)); } while (0)
|
||||
#endif
|
||||
|
||||
struct page_table;
|
||||
void set_pte(pte_t *ppte, unsigned long phys, enum ihk_mc_pt_attribute attr);
|
||||
pte_t *get_pte(struct page_table *pt, void *virt, enum ihk_mc_pt_attribute attr);
|
||||
|
||||
@@ -136,7 +136,7 @@ struct tss64 {
|
||||
} __attribute__((packed));
|
||||
|
||||
struct x86_regs {
|
||||
unsigned long r11, r10, r9, r8;
|
||||
unsigned long r15, r14, r13, r12, r11, r10, r9, r8;
|
||||
unsigned long rdi, rsi, rdx, rcx, rbx, rax, rbp;
|
||||
unsigned long error, rip, cs, rflags, rsp, ss;
|
||||
};
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
* 2012/02/11 bgerofi what kind of new features have been added
|
||||
*/
|
||||
|
||||
#ifndef __HEADER_X86_COMMON_SIGNAL_H
|
||||
#define __HEADER_X86_COMMON_SIGNAL_H
|
||||
|
||||
#define _NSIG 64
|
||||
#define _NSIG_BPW 64
|
||||
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
|
||||
@@ -149,3 +152,5 @@ typedef struct siginfo {
|
||||
#define SIGSYS 31
|
||||
#define SIGUNUSED 31
|
||||
#define SIGRTMIN 32
|
||||
|
||||
#endif /*__HEADER_X86_COMMON_SIGNAL_H*/
|
||||
|
||||
@@ -40,6 +40,7 @@ SYSCALL_DELEGATED(18, pwrite64)
|
||||
SYSCALL_DELEGATED(20, writev)
|
||||
SYSCALL_DELEGATED(21, access)
|
||||
SYSCALL_HANDLED(24, sched_yield)
|
||||
SYSCALL_HANDLED(25, mremap)
|
||||
SYSCALL_HANDLED(28, madvise)
|
||||
SYSCALL_HANDLED(34, pause)
|
||||
SYSCALL_HANDLED(39, getpid)
|
||||
@@ -75,6 +76,7 @@ SYSCALL_DELEGATED(201, time)
|
||||
SYSCALL_HANDLED(202, futex)
|
||||
SYSCALL_HANDLED(203, sched_setaffinity)
|
||||
SYSCALL_HANDLED(204, sched_getaffinity)
|
||||
SYSCALL_HANDLED(216, remap_file_pages)
|
||||
SYSCALL_DELEGATED(217, getdents64)
|
||||
SYSCALL_HANDLED(218, set_tid_address)
|
||||
SYSCALL_HANDLED(231, exit_group)
|
||||
@@ -87,5 +89,6 @@ SYSCALL_HANDLED(601, pmc_init)
|
||||
SYSCALL_HANDLED(602, pmc_start)
|
||||
SYSCALL_HANDLED(603, pmc_stop)
|
||||
SYSCALL_HANDLED(604, pmc_reset)
|
||||
SYSCALL_HANDLED(700, get_cpu_id)
|
||||
|
||||
/**** End of File ****/
|
||||
|
||||
@@ -35,8 +35,16 @@
|
||||
pushq %r8; \
|
||||
pushq %r9; \
|
||||
pushq %r10; \
|
||||
pushq %r11;
|
||||
pushq %r11; \
|
||||
pushq %r12; \
|
||||
pushq %r13; \
|
||||
pushq %r14; \
|
||||
pushq %r15;
|
||||
#define POP_ALL_REGS \
|
||||
popq %r15; \
|
||||
popq %r14; \
|
||||
popq %r13; \
|
||||
popq %r12; \
|
||||
popq %r11; \
|
||||
popq %r10; \
|
||||
popq %r9; \
|
||||
@@ -67,7 +75,7 @@ vector=vector+1
|
||||
|
||||
common_interrupt:
|
||||
PUSH_ALL_REGS
|
||||
movq 88(%rsp), %rdi
|
||||
movq 120(%rsp), %rdi
|
||||
movq %rsp, %rsi
|
||||
call handle_interrupt /* Enter C code */
|
||||
POP_ALL_REGS
|
||||
@@ -83,7 +91,7 @@ page_fault:
|
||||
cld
|
||||
PUSH_ALL_REGS
|
||||
movq %cr2, %rdi
|
||||
movq 88(%rsp),%rsi
|
||||
movq 120(%rsp),%rsi
|
||||
movq %rsp,%rdx
|
||||
movq __page_fault_handler_address(%rip), %rax
|
||||
andq %rax, %rax
|
||||
@@ -120,13 +128,13 @@ x86_syscall:
|
||||
movq %gs:24, %rcx
|
||||
movq %rcx, 32(%rsp)
|
||||
PUSH_ALL_REGS
|
||||
movq 72(%rsp), %rdi
|
||||
movq 104(%rsp), %rdi
|
||||
movw %ss, %ax
|
||||
movw %ax, %ds
|
||||
movq %rsp, %rsi
|
||||
callq *__x86_syscall_handler(%rip)
|
||||
1:
|
||||
movq %rax, 72(%rsp)
|
||||
movq %rax, 104(%rsp)
|
||||
POP_ALL_REGS
|
||||
#ifdef USE_SYSRET
|
||||
movq 8(%rsp), %rcx
|
||||
|
||||
@@ -219,7 +219,13 @@ static struct page_table *__alloc_new_pt(enum ihk_mc_ap_flag ap_flag)
|
||||
* but L2 and L1 do not!
|
||||
*/
|
||||
|
||||
static enum ihk_mc_pt_attribute attr_mask = PTATTR_WRITABLE | PTATTR_USER | PTATTR_ACTIVE;
|
||||
static enum ihk_mc_pt_attribute attr_mask
|
||||
= 0
|
||||
| PTATTR_FILEOFF
|
||||
| PTATTR_WRITABLE
|
||||
| PTATTR_USER
|
||||
| PTATTR_ACTIVE
|
||||
| 0;
|
||||
#define ATTR_MASK attr_mask
|
||||
|
||||
void enable_ptattr_no_execute(void)
|
||||
@@ -523,6 +529,7 @@ int ihk_mc_pt_print_pte(struct page_table *pt, void *virt)
|
||||
|
||||
if (!(pt->entry[l4idx] & PFL4_PRESENT)) {
|
||||
__kprintf("0x%lX l4idx not present! \n", (unsigned long)virt);
|
||||
__kprintf("l4 entry: 0x%lX\n", pt->entry[l4idx]);
|
||||
return -EFAULT;
|
||||
}
|
||||
pt = phys_to_virt(pt->entry[l4idx] & PAGE_MASK);
|
||||
@@ -530,6 +537,7 @@ int ihk_mc_pt_print_pte(struct page_table *pt, void *virt)
|
||||
__kprintf("l3 table: 0x%lX l3idx: %d \n", virt_to_phys(pt), l3idx);
|
||||
if (!(pt->entry[l3idx] & PFL3_PRESENT)) {
|
||||
__kprintf("0x%lX l3idx not present! \n", (unsigned long)virt);
|
||||
__kprintf("l3 entry: 0x%lX\n", pt->entry[l3idx]);
|
||||
return -EFAULT;
|
||||
}
|
||||
pt = phys_to_virt(pt->entry[l3idx] & PAGE_MASK);
|
||||
@@ -537,6 +545,7 @@ int ihk_mc_pt_print_pte(struct page_table *pt, void *virt)
|
||||
__kprintf("l2 table: 0x%lX l2idx: %d \n", virt_to_phys(pt), l2idx);
|
||||
if (!(pt->entry[l2idx] & PFL2_PRESENT)) {
|
||||
__kprintf("0x%lX l2idx not present! \n", (unsigned long)virt);
|
||||
__kprintf("l2 entry: 0x%lX\n", pt->entry[l2idx]);
|
||||
return -EFAULT;
|
||||
}
|
||||
if ((pt->entry[l2idx] & PFL2_SIZE)) {
|
||||
@@ -546,11 +555,12 @@ int ihk_mc_pt_print_pte(struct page_table *pt, void *virt)
|
||||
|
||||
__kprintf("l1 table: 0x%lX l1idx: %d \n", virt_to_phys(pt), l1idx);
|
||||
if (!(pt->entry[l1idx] & PFL1_PRESENT)) {
|
||||
__kprintf("0x%lX PTE (l1) not present! entry: 0x%lX\n",
|
||||
(unsigned long)virt, pt->entry[l1idx]);
|
||||
__kprintf("0x%lX l1idx not present! \n", (unsigned long)virt);
|
||||
__kprintf("l1 entry: 0x%lX\n", pt->entry[l1idx]);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
__kprintf("l1 entry: 0x%lX\n", pt->entry[l1idx]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -822,8 +832,16 @@ static int split_large_page(pte_t *ptep)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
phys = *ptep & PT_PHYSMASK;
|
||||
attr = *ptep & ~PFL2_SIZE;
|
||||
if (!(*ptep & PFL2_FILEOFF)) {
|
||||
phys = *ptep & PT_PHYSMASK;
|
||||
attr = *ptep & ~PT_PHYSMASK;
|
||||
attr &= ~PFL2_SIZE;
|
||||
}
|
||||
else {
|
||||
phys = *ptep & PAGE_MASK; /* file offset */
|
||||
attr = *ptep & ~PAGE_MASK;
|
||||
attr &= ~PFL2_SIZE;
|
||||
}
|
||||
|
||||
for (i = 0; i < PT_ENTRIES; ++i) {
|
||||
pt->entry[i] = (phys + (i * PTL1_SIZE)) | attr;
|
||||
@@ -833,6 +851,156 @@ static int split_large_page(pte_t *ptep)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct visit_pte_args {
|
||||
page_table_t pt;
|
||||
enum visit_pte_flag flags;
|
||||
int padding;
|
||||
pte_visitor_t *funcp;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static int visit_pte_l1(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
uintptr_t start, uintptr_t end)
|
||||
{
|
||||
struct visit_pte_args *args = arg0;
|
||||
|
||||
if ((*ptep == PTE_NULL) && (args->flags & VPTEF_SKIP_NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (*args->funcp)(args->arg, args->pt, ptep, (void *)base,
|
||||
PTL1_SIZE);
|
||||
}
|
||||
|
||||
static int visit_pte_l2(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
uintptr_t start, uintptr_t end)
|
||||
{
|
||||
int error;
|
||||
struct visit_pte_args *args = arg0;
|
||||
struct page_table *pt;
|
||||
|
||||
if ((*ptep == PTE_NULL) && (args->flags & VPTEF_SKIP_NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_LARGE_PAGES
|
||||
if (((*ptep == PTE_NULL) || (*ptep & PFL2_SIZE))
|
||||
&& (start <= base)
|
||||
&& (((base + PTL2_SIZE) <= end)
|
||||
|| (end == 0))) {
|
||||
error = (*args->funcp)(args->arg, args->pt, ptep,
|
||||
(void *)base, PTL2_SIZE);
|
||||
if (error != -E2BIG) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ptep & PFL2_SIZE) {
|
||||
ekprintf("visit_pte_l2:split large page\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
pt = __alloc_new_pt(IHK_MC_AP_NOWAIT);
|
||||
if (!pt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
*ptep = virt_to_phys(pt) | PFL2_PDIR_ATTR;
|
||||
}
|
||||
else {
|
||||
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
}
|
||||
|
||||
error = walk_pte_l1(pt, base, start, end, &visit_pte_l1, arg0);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int visit_pte_l3(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
uintptr_t start, uintptr_t end)
|
||||
{
|
||||
int error;
|
||||
struct visit_pte_args *args = arg0;
|
||||
struct page_table *pt;
|
||||
|
||||
if ((*ptep == PTE_NULL) && (args->flags & VPTEF_SKIP_NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_LARGE_PAGES
|
||||
if (((*ptep == PTE_NULL) || (*ptep & PFL3_SIZE))
|
||||
&& (start <= base)
|
||||
&& (((base + PTL3_SIZE) <= end)
|
||||
|| (end == 0))) {
|
||||
error = (*args->funcp)(args->arg, args->pt, ptep,
|
||||
(void *)base, PTL3_SIZE);
|
||||
if (error != -E2BIG) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ptep & PFL3_SIZE) {
|
||||
ekprintf("visit_pte_l3:split large page\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
pt = __alloc_new_pt(IHK_MC_AP_NOWAIT);
|
||||
if (!pt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
*ptep = virt_to_phys(pt) | PFL3_PDIR_ATTR;
|
||||
}
|
||||
else {
|
||||
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
}
|
||||
|
||||
error = walk_pte_l2(pt, base, start, end, &visit_pte_l2, arg0);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int visit_pte_l4(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
uintptr_t start, uintptr_t end)
|
||||
{
|
||||
int error;
|
||||
struct visit_pte_args *args = arg0;
|
||||
struct page_table *pt;
|
||||
|
||||
if ((*ptep == PTE_NULL) && (args->flags & VPTEF_SKIP_NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
pt = __alloc_new_pt(IHK_MC_AP_NOWAIT);
|
||||
if (!pt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
*ptep = virt_to_phys(pt) | PFL4_PDIR_ATTR;
|
||||
}
|
||||
else {
|
||||
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
}
|
||||
|
||||
error = walk_pte_l3(pt, base, start, end, &visit_pte_l3, arg0);
|
||||
return error;
|
||||
}
|
||||
|
||||
int visit_pte_range(page_table_t pt, void *start0, void *end0,
|
||||
enum visit_pte_flag flags, pte_visitor_t *funcp, void *arg)
|
||||
{
|
||||
const uintptr_t start = (uintptr_t)start0;
|
||||
const uintptr_t end = (uintptr_t)end0;
|
||||
struct visit_pte_args args;
|
||||
|
||||
args.pt = pt;
|
||||
args.flags = flags;
|
||||
args.funcp = funcp;
|
||||
args.arg = arg;
|
||||
|
||||
return walk_pte_l4(pt, 0, start, end, &visit_pte_l4, &args);
|
||||
}
|
||||
|
||||
struct clear_range_args {
|
||||
int free_physical;
|
||||
uint8_t padding[4];
|
||||
@@ -858,7 +1026,7 @@ static int clear_range_l1(void *args0, pte_t *ptep, uint64_t base,
|
||||
memobj_flush_page(args->memobj, phys, PTL1_SIZE);
|
||||
}
|
||||
|
||||
if (args->free_physical) {
|
||||
if (!(old & PFL1_FILEOFF) && args->free_physical) {
|
||||
page = phys_to_page(phys);
|
||||
if (page && page_unmap(page)) {
|
||||
ihk_mc_free_pages(phys_to_virt(phys), 1);
|
||||
@@ -904,7 +1072,7 @@ static int clear_range_l2(void *args0, pte_t *ptep, uint64_t base,
|
||||
memobj_flush_page(args->memobj, phys, PTL2_SIZE);
|
||||
}
|
||||
|
||||
if (args->free_physical) {
|
||||
if (!(old & PFL2_FILEOFF) && args->free_physical) {
|
||||
page = phys_to_page(phys);
|
||||
if (page && page_unmap(page)) {
|
||||
ihk_mc_free_pages(phys_to_virt(phys), PTL2_SIZE/PTL1_SIZE);
|
||||
@@ -998,7 +1166,7 @@ static int change_attr_range_l1(void *arg0, pte_t *ptep, uint64_t base,
|
||||
{
|
||||
struct change_attr_args *args = arg0;
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
if ((*ptep == PTE_NULL) || (*ptep & PFL1_FILEOFF)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@@ -1013,7 +1181,7 @@ static int change_attr_range_l2(void *arg0, pte_t *ptep, uint64_t base,
|
||||
int error;
|
||||
struct page_table *pt;
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
if ((*ptep == PTE_NULL) || (*ptep & PFL2_FILEOFF)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@@ -1032,7 +1200,9 @@ static int change_attr_range_l2(void *arg0, pte_t *ptep, uint64_t base,
|
||||
}
|
||||
|
||||
if (*ptep & PFL2_SIZE) {
|
||||
*ptep = (*ptep & ~args->clrpte) | args->setpte;
|
||||
if (!(*ptep & PFL2_FILEOFF)) {
|
||||
*ptep = (*ptep & ~args->clrpte) | args->setpte;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1045,7 +1215,7 @@ static int change_attr_range_l3(void *arg0, pte_t *ptep, uint64_t base,
|
||||
{
|
||||
struct page_table *pt;
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
if ((*ptep == PTE_NULL) || (*ptep & PFL3_FILEOFF)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@@ -1632,6 +1802,76 @@ enum ihk_mc_pt_attribute arch_vrflag_to_ptattr(unsigned long flag, uint64_t faul
|
||||
return attr;
|
||||
}
|
||||
|
||||
struct move_args {
|
||||
uintptr_t src;
|
||||
uintptr_t dest;
|
||||
};
|
||||
|
||||
static int move_one_page(void *arg0, page_table_t pt, pte_t *ptep, void *pgaddr, size_t pgsize)
|
||||
{
|
||||
int error;
|
||||
struct move_args *args = arg0;
|
||||
uintptr_t dest;
|
||||
pte_t apte;
|
||||
uintptr_t phys;
|
||||
enum ihk_mc_pt_attribute attr;
|
||||
|
||||
dkprintf("move_one_page(%p,%p,%p %#lx,%p,%#lx)\n",
|
||||
arg0, pt, ptep, *ptep, pgaddr, pgsize);
|
||||
if (pte_is_fileoff(ptep, pgsize)) {
|
||||
error = -ENOTSUPP;
|
||||
kprintf("move_one_page(%p,%p,%p %#lx,%p,%#lx):fileoff. %d\n",
|
||||
arg0, pt, ptep, *ptep, pgaddr, pgsize, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
dest = args->dest + ((uintptr_t)pgaddr - args->src);
|
||||
|
||||
apte = PTE_NULL;
|
||||
pte_xchg(ptep, &apte);
|
||||
|
||||
phys = apte & PT_PHYSMASK;
|
||||
attr = apte & ~PT_PHYSMASK;
|
||||
|
||||
error = ihk_mc_pt_set_range(pt, (void *)dest,
|
||||
(void *)(dest + pgsize), phys, attr);
|
||||
if (error) {
|
||||
kprintf("move_one_page(%p,%p,%p %#lx,%p,%#lx):"
|
||||
"set failed. %d\n",
|
||||
arg0, pt, ptep, *ptep, pgaddr, pgsize, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
dkprintf("move_one_page(%p,%p,%p %#lx,%p,%#lx):%d\n",
|
||||
arg0, pt, ptep, *ptep, pgaddr, pgsize, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
int move_pte_range(page_table_t pt, void *src, void *dest, size_t size)
|
||||
{
|
||||
int error;
|
||||
struct move_args args;
|
||||
|
||||
dkprintf("move_pte_range(%p,%p,%p,%#lx)\n", pt, src, dest, size);
|
||||
args.src = (uintptr_t)src;
|
||||
args.dest = (uintptr_t)dest;
|
||||
|
||||
error = visit_pte_range(pt, src, src+size, VPTEF_SKIP_NULL,
|
||||
&move_one_page, &args);
|
||||
flush_tlb(); /* XXX: TLB flush */
|
||||
if (error) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
dkprintf("move_pte_range(%p,%p,%p,%#lx):%d\n",
|
||||
pt, src, dest, size, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void load_page_table(struct page_table *pt)
|
||||
{
|
||||
unsigned long pt_addr;
|
||||
|
||||
@@ -288,14 +288,16 @@ check_signal(unsigned long rc, void *regs0)
|
||||
unsigned long
|
||||
do_kill(int pid, int tid, int sig)
|
||||
{
|
||||
struct cpu_local_var *v;
|
||||
struct process *p;
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct process *tproc = NULL;
|
||||
int i;
|
||||
__sigset_t mask;
|
||||
struct sig_pending *pending;
|
||||
struct list_head *head;
|
||||
int irqstate;
|
||||
int rc;
|
||||
unsigned long irqstate;
|
||||
|
||||
if(proc == NULL || proc->pid == 0){
|
||||
return -ESRCH;
|
||||
@@ -314,37 +316,52 @@ do_kill(int pid, int tid, int sig)
|
||||
}
|
||||
else{
|
||||
for(i = 0; i < num_processors; i++){
|
||||
if(get_cpu_local_var(i)->current &&
|
||||
get_cpu_local_var(i)->current->pid == pid){
|
||||
tproc = get_cpu_local_var(i)->current;
|
||||
break;
|
||||
v = get_cpu_local_var(i);
|
||||
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
||||
list_for_each_entry(p, &(v->runq), sched_list){
|
||||
if(p->pid == pid){
|
||||
tproc = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(pid == -1){
|
||||
for(i = 0; i < num_processors; i++)
|
||||
if(get_cpu_local_var(i)->current &&
|
||||
get_cpu_local_var(i)->current->pid > 0 &&
|
||||
get_cpu_local_var(i)->current->tid == tid){
|
||||
tproc = get_cpu_local_var(i)->current;
|
||||
break;
|
||||
for(i = 0; i < num_processors; i++){
|
||||
v = get_cpu_local_var(i);
|
||||
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
||||
list_for_each_entry(p, &(v->runq), sched_list){
|
||||
if(p->pid > 0 &&
|
||||
p->tid == tid){
|
||||
tproc = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(pid == 0)
|
||||
return -ESRCH;
|
||||
for(i = 0; i < num_processors; i++)
|
||||
if(get_cpu_local_var(i)->current &&
|
||||
get_cpu_local_var(i)->current->pid == pid &&
|
||||
get_cpu_local_var(i)->current->tid == tid){
|
||||
tproc = get_cpu_local_var(i)->current;
|
||||
break;
|
||||
for(i = 0; i < num_processors; i++){
|
||||
v = get_cpu_local_var(i);
|
||||
irqstate = ihk_mc_spinlock_lock(&(v->runq_lock));
|
||||
list_for_each_entry(p, &(v->runq), sched_list){
|
||||
if(p->pid == pid &&
|
||||
p->tid == tid){
|
||||
tproc = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
||||
}
|
||||
}
|
||||
|
||||
if(!tproc)
|
||||
if(!tproc){
|
||||
return -ESRCH;
|
||||
}
|
||||
if(sig == 0)
|
||||
return 0;
|
||||
|
||||
@@ -375,7 +392,7 @@ do_kill(int pid, int tid, int sig)
|
||||
}
|
||||
else{
|
||||
list_add_tail(&pending->list, head);
|
||||
proc->sigevent = 1;
|
||||
tproc->sigevent = 1;
|
||||
}
|
||||
}
|
||||
if(tid == -1){
|
||||
|
||||
Reference in New Issue
Block a user