On Thursday, 2020-07-16 at 16:52:49 +03, Jarkko Sakkinen wrote: > From: Sean Christopherson <sean.j.christopherson@xxxxxxxxx> > > Add vm_ops()->mprotect() for additional constraints for a VMA. > > Intel Software Guard eXtensions (SGX) will use this callback to add two > constraints: > > 1. Verify that the address range does not have holes: each page address > must be filled with an enclave page. > 2. Verify that VMA permissions won't surpass the permissions of any enclave > page within the address range. Enclave cryptographically sealed > permissions for each page address that set the upper limit for possible > VMA permissions. Not respecting this can cause #GP's to be emitted. > > Cc: linux-mm@xxxxxxxxx > Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> > Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> > Acked-by: Jethro Beekman <jethro@xxxxxxxxxxxx> > Signed-off-by: Sean Christopherson <sean.j.christopherson@xxxxxxxxx> > Co-developed-by: Jarkko Sakkinen <jarkko.sakkinen@xxxxxxxxxxxxxxx> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@xxxxxxxxxxxxxxx> Reviewed-by: Darren Kenny <darren.kenny@xxxxxxxxxx> > --- > include/linux/mm.h | 3 +++ > mm/mprotect.c | 5 ++++- > 2 files changed, 7 insertions(+), 1 deletion(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index dc7b87310c10..458e8cb99aaf 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -542,6 +542,9 @@ struct vm_operations_struct { > void (*close)(struct vm_area_struct * area); > int (*split)(struct vm_area_struct * area, unsigned long addr); > int (*mremap)(struct vm_area_struct * area); > + int (*mprotect)(struct vm_area_struct *vma, > + struct vm_area_struct **pprev, unsigned long start, > + unsigned long end, unsigned long newflags); > vm_fault_t (*fault)(struct vm_fault *vmf); > vm_fault_t (*huge_fault)(struct vm_fault *vmf, > enum page_entry_size pe_size); > diff --git a/mm/mprotect.c b/mm/mprotect.c > index ce8b8a5eacbb..f170f3da8a4f 100644 > --- a/mm/mprotect.c > +++ b/mm/mprotect.c > @@ -610,7 +610,10 @@ static int do_mprotect_pkey(unsigned long start, size_t len, > tmp = vma->vm_end; > if (tmp > end) > tmp = end; > - error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); > + if (vma->vm_ops && vma->vm_ops->mprotect) > + error = vma->vm_ops->mprotect(vma, &prev, nstart, tmp, newflags); > + else > + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); > if (error) > goto out; > nstart = tmp; > -- > 2.25.1