introduction of mckernel_procfs_file_operations; fix /proc/self path resolution;
implementation of /proc/self/pagemap (LTP mmap12)
This commit is contained in:
committed by
Balazs Gerofi bgerofi@riken.jp
parent
815d907ca4
commit
d4ba4dc8b3
@ -117,6 +117,25 @@
|
||||
#define PTE_NULL ((pte_t)0)
|
||||
typedef unsigned long pte_t;
|
||||
|
||||
/*
|
||||
* pagemap kernel ABI bits
|
||||
*/
|
||||
#define PM_ENTRY_BYTES sizeof(uint64_t)
|
||||
#define PM_STATUS_BITS 3
|
||||
#define PM_STATUS_OFFSET (64 - PM_STATUS_BITS)
|
||||
#define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET)
|
||||
#define PM_STATUS(nr) (((nr) << PM_STATUS_OFFSET) & PM_STATUS_MASK)
|
||||
#define PM_PSHIFT_BITS 6
|
||||
#define PM_PSHIFT_OFFSET (PM_STATUS_OFFSET - PM_PSHIFT_BITS)
|
||||
#define PM_PSHIFT_MASK (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET)
|
||||
#define PM_PSHIFT(x) (((uint64_t) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK)
|
||||
#define PM_PFRAME_MASK ((1LL << PM_PSHIFT_OFFSET) - 1)
|
||||
#define PM_PFRAME(x) ((x) & PM_PFRAME_MASK)
|
||||
|
||||
#define PM_PRESENT PM_STATUS(4LL)
|
||||
#define PM_SWAP PM_STATUS(2LL)
|
||||
|
||||
|
||||
/* For easy conversion, it is better to be the same as architecture's ones */
|
||||
enum ihk_mc_pt_attribute {
|
||||
PTATTR_ACTIVE = 0x01,
|
||||
|
||||
@ -494,6 +494,50 @@ static int __clear_pt_page(struct page_table *pt, void *virt, int largepage)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t ihk_mc_pt_virt_to_pagemap(struct page_table *pt, unsigned long virt)
|
||||
{
|
||||
int l4idx, l3idx, l2idx, l1idx;
|
||||
unsigned long v = (unsigned long)virt;
|
||||
uint64_t ret = 0;
|
||||
|
||||
if (!pt) {
|
||||
pt = init_pt;
|
||||
}
|
||||
|
||||
GET_VIRT_INDICES(v, l4idx, l3idx, l2idx, l1idx);
|
||||
|
||||
if (!(pt->entry[l4idx] & PFL4_PRESENT)) {
|
||||
return ret;
|
||||
}
|
||||
pt = phys_to_virt(pt->entry[l4idx] & PAGE_MASK);
|
||||
|
||||
if (!(pt->entry[l3idx] & PFL3_PRESENT)) {
|
||||
return ret;
|
||||
}
|
||||
pt = phys_to_virt(pt->entry[l3idx] & PAGE_MASK);
|
||||
|
||||
if (!(pt->entry[l2idx] & PFL2_PRESENT)) {
|
||||
return ret;
|
||||
}
|
||||
if ((pt->entry[l2idx] & PFL2_SIZE)) {
|
||||
|
||||
ret = PM_PFRAME(((pt->entry[l2idx] & LARGE_PAGE_MASK) +
|
||||
(v & (LARGE_PAGE_SIZE - 1))) >> PAGE_SHIFT);
|
||||
ret |= PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT;
|
||||
return ret;
|
||||
}
|
||||
pt = phys_to_virt(pt->entry[l2idx] & PAGE_MASK);
|
||||
|
||||
if (!(pt->entry[l1idx] & PFL1_PRESENT)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = PM_PFRAME((pt->entry[l1idx] & PT_PHYSMASK) >> PAGE_SHIFT);
|
||||
ret |= PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ihk_mc_pt_virt_to_phys(struct page_table *pt,
|
||||
void *virt, unsigned long *phys)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user