--- arch/x86_64/mm/pat.c | 26 ++++++++++++++++++++++++++ include/asm-x86_64/pat.h | 2 ++ 2 files changed, 28 insertions(+) Index: linux/arch/x86_64/mm/pat.c =================================================================== --- linux.orig/arch/x86_64/mm/pat.c +++ linux/arch/x86_64/mm/pat.c @@ -226,3 +226,29 @@ int free_mattr(u64 start, u64 end, unsig return err; } +static struct vm_operations_struct mattr_vmops = { + .close = free_mattr_vma, +}; + +/* Note that if there is already a vm_ops caller has to ensure + free_mattr_vma is called in its close functin. */ +int reserve_mattr_vma(struct vm_area_struct *vma) +{ + u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT; + int err; + err = reserve_mattr(addr, addr + vma->vm_end - vma->vm_start, + pgprot_nonstd(vma->vm_page_prot), NULL); + if (err) + return err; + if (!vma->vm_ops) + vma->vm_ops = &mattr_vmops; + return 0; +} + +void free_mattr_vma(struct vm_area_struct *vma) +{ + u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT; + free_mattr(addr, addr + vma->vm_end - vma->vm_start, + pgprot_nonstd(vma->vm_page_prot)); +} + Index: linux/include/asm-x86_64/pat.h =================================================================== --- linux.orig/include/asm-x86_64/pat.h +++ linux/include/asm-x86_64/pat.h @@ -7,6 +7,8 @@ int reserve_mattr(u64 start, u64 end, unsigned long attr, unsigned long *fattr); int free_mattr(u64 start, u64 end, unsigned long attr); +int reserve_mattr_vma(struct vm_area_struct *vma); +void free_mattr_vma(struct vm_area_struct *vma); #endif