Introduction of write-combined memory type mappings.
Introduction of VR_WRITE_COMBINED, PTATTR_WRITE_COMBINED and modification to the memobj's get_page() interface so that Linux communicates back mapping flags (such as write-combined).
This commit is contained in:
@ -32,6 +32,8 @@
|
||||
#include <pager.h>
|
||||
#include <string.h>
|
||||
#include <syscall.h>
|
||||
#include <process.h>
|
||||
|
||||
|
||||
#define dkprintf(...) do { if (0) kprintf(__VA_ARGS__); } while (0)
|
||||
#define ekprintf(...) kprintf(__VA_ARGS__)
|
||||
@ -192,7 +194,7 @@ static void devobj_release(struct memobj *memobj)
|
||||
return;
|
||||
}
|
||||
|
||||
static int devobj_get_page(struct memobj *memobj, off_t off, int p2align, uintptr_t *physp)
|
||||
static int devobj_get_page(struct memobj *memobj, off_t off, int p2align, uintptr_t *physp, unsigned long *flag)
|
||||
{
|
||||
const off_t pgoff = off >> PAGE_SHIFT;
|
||||
struct devobj *obj = to_devobj(memobj);
|
||||
@ -232,6 +234,14 @@ kprintf("ix: %ld\n", ix);
|
||||
/* convert remote physical into local physical */
|
||||
kprintf("devobj_get_page(%p %lx,%lx,%d):PFN_PRESENT before %#lx\n", memobj, obj->handle, off, p2align, pfn);
|
||||
attr = pfn & ~PFN_PFN;
|
||||
|
||||
/* 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.. */
|
||||
if ((pfn & PFL1_PWT) && !(pfn & PFL1_PCD)) {
|
||||
*flag |= VR_WRITE_COMBINED;
|
||||
}
|
||||
|
||||
pfn = ihk_mc_map_memory(NULL, (pfn & PFN_PFN), PAGE_SIZE);
|
||||
pfn &= PFN_PFN;
|
||||
pfn |= attr;
|
||||
|
||||
@ -385,7 +385,7 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
static int fileobj_get_page(struct memobj *memobj, off_t off, int p2align, uintptr_t *physp)
|
||||
static int fileobj_get_page(struct memobj *memobj, off_t off, int p2align, uintptr_t *physp, unsigned long *pflag)
|
||||
{
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct fileobj *obj = to_fileobj(memobj);
|
||||
|
||||
@ -34,7 +34,7 @@ struct memobj {
|
||||
|
||||
typedef void memobj_release_func_t(struct memobj *obj);
|
||||
typedef void memobj_ref_func_t(struct memobj *obj);
|
||||
typedef int memobj_get_page_func_t(struct memobj *obj, off_t off, int p2align, uintptr_t *physp);
|
||||
typedef int memobj_get_page_func_t(struct memobj *obj, off_t off, int p2align, uintptr_t *physp, unsigned long *flag);
|
||||
typedef uintptr_t memobj_copy_page_func_t(struct memobj *obj, uintptr_t orgphys, int p2align);
|
||||
typedef int memobj_flush_page_func_t(struct memobj *obj, uintptr_t phys, size_t pgsize);
|
||||
typedef int memobj_invalidate_page_func_t(struct memobj *obj, uintptr_t phys, size_t pgsize);
|
||||
@ -63,10 +63,10 @@ static inline void memobj_ref(struct memobj *obj)
|
||||
}
|
||||
|
||||
static inline int memobj_get_page(struct memobj *obj, off_t off,
|
||||
int p2align, uintptr_t *physp)
|
||||
int p2align, uintptr_t *physp, unsigned long *pflag)
|
||||
{
|
||||
if (obj->ops->get_page) {
|
||||
return (*obj->ops->get_page)(obj, off, p2align, physp);
|
||||
return (*obj->ops->get_page)(obj, off, p2align, physp, pflag);
|
||||
}
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#define VR_RESERVED 0x2
|
||||
#define VR_IO_NOCACHE 0x100
|
||||
#define VR_REMOTE 0x200
|
||||
#define VR_WRITE_COMBINED 0x400
|
||||
#define VR_DEMAND_PAGING 0x1000
|
||||
#define VR_PRIVATE 0x2000
|
||||
#define VR_LOCKED 0x4000
|
||||
|
||||
@ -881,8 +881,8 @@ enum ihk_mc_pt_attribute common_vrflag_to_ptattr(unsigned long flag, uint64_t fa
|
||||
attr |= PTATTR_NO_EXECUTE;
|
||||
}
|
||||
|
||||
if ((flag & VR_MEMTYPE_MASK) == VR_MEMTYPE_UC) {
|
||||
attr |= PTATTR_UNCACHABLE;
|
||||
if (flag & VR_WRITE_COMBINED) {
|
||||
attr |= PTATTR_WRITE_COMBINED;
|
||||
}
|
||||
|
||||
return attr;
|
||||
@ -1376,6 +1376,7 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
enum ihk_mc_pt_attribute attr;
|
||||
uintptr_t phys;
|
||||
struct page *page = NULL;
|
||||
unsigned long memobj_flag = 0;
|
||||
|
||||
dkprintf("page_fault_process_memory_range(%p,%lx-%lx %lx,%lx,%lx)\n", vm, range->start, range->end, range->flag, fault_addr, reason);
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
@ -1402,7 +1403,6 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
pgsize = PAGE_SIZE;
|
||||
p2align = PAGE_P2ALIGN;
|
||||
}
|
||||
attr = arch_vrflag_to_ptattr(range->flag, reason, ptep);
|
||||
pgaddr = (void *)(fault_addr & ~(pgsize - 1));
|
||||
if (!ptep || pte_is_null(ptep) || pte_is_fileoff(ptep, pgsize)) {
|
||||
if (range->memobj) {
|
||||
@ -1414,7 +1414,8 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
else {
|
||||
off = pte_get_off(ptep, pgsize);
|
||||
}
|
||||
error = memobj_get_page(range->memobj, off, p2align, &phys);
|
||||
error = memobj_get_page(range->memobj, off, p2align,
|
||||
&phys, &memobj_flag);
|
||||
if (error) {
|
||||
if (error != -ERESTART) {
|
||||
}
|
||||
@ -1440,7 +1441,16 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
else {
|
||||
phys = pte_get_phys(ptep);
|
||||
}
|
||||
|
||||
page = phys_to_page(phys);
|
||||
|
||||
/* If Linux requested VR_WRITE_COMBINED, but the range is NOCACHE mapped,
|
||||
* make sure we use VR_WRITE_COMBINED */
|
||||
attr = arch_vrflag_to_ptattr(
|
||||
(((memobj_flag & VR_WRITE_COMBINED) && (range->flag & VR_IO_NOCACHE)) ?
|
||||
range->flag & ~(VR_IO_NOCACHE) : range->flag)
|
||||
| memobj_flag, reason, ptep);
|
||||
|
||||
/*****/
|
||||
if (((range->flag & VR_PRIVATE)
|
||||
|| ((reason & PF_PATCH)
|
||||
|
||||
@ -203,7 +203,7 @@ static void shmobj_ref(struct memobj *memobj)
|
||||
}
|
||||
|
||||
static int shmobj_get_page(struct memobj *memobj, off_t off, int p2align,
|
||||
uintptr_t *physp)
|
||||
uintptr_t *physp, unsigned long *pflag)
|
||||
{
|
||||
struct shmobj *obj = to_shmobj(memobj);
|
||||
int error;
|
||||
|
||||
@ -165,7 +165,7 @@ out:
|
||||
}
|
||||
|
||||
static int zeroobj_get_page(struct memobj *memobj, off_t off, int p2align,
|
||||
uintptr_t *physp)
|
||||
uintptr_t *physp, unsigned long *pflag)
|
||||
{
|
||||
int error;
|
||||
struct zeroobj *obj = to_zeroobj(memobj);
|
||||
|
||||
Reference in New Issue
Block a user