Message ID | 1504910713-7094-28-git-send-email-linuxram@us.ibm.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | powerpc: Free up RPAGE_RSV bits | expand |
On Fri, 8 Sep 2017 15:45:07 -0700 Ram Pai <linuxram@us.ibm.com> wrote: > This patch provides the implementation for > arch_vma_access_permitted(). Returns true if the > requested access is allowed by pkey associated with the > vma. > > Signed-off-by: Ram Pai <linuxram@us.ibm.com> > --- > arch/powerpc/include/asm/mmu_context.h | 5 +++- > arch/powerpc/mm/pkeys.c | 43 ++++++++++++++++++++++++++++++++ > 2 files changed, 47 insertions(+), 1 deletions(-) > > diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h > index 04e9221..9a56355 100644 > --- a/arch/powerpc/include/asm/mmu_context.h > +++ b/arch/powerpc/include/asm/mmu_context.h > @@ -135,6 +135,10 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, > { > } > > +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS > +bool arch_vma_access_permitted(struct vm_area_struct *vma, > + bool write, bool execute, bool foreign); > +#else /* CONFIG_PPC64_MEMORY_PROTECTION_KEYS */ > static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, > bool write, bool execute, bool foreign) > { > @@ -142,7 +146,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, > return true; > } > > -#ifndef CONFIG_PPC64_MEMORY_PROTECTION_KEYS > #define pkey_initialize() > #define pkey_mm_init(mm) > > diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c > index 24589d9..21c3b42 100644 > --- a/arch/powerpc/mm/pkeys.c > +++ b/arch/powerpc/mm/pkeys.c > @@ -320,3 +320,46 @@ bool arch_pte_access_permitted(u64 pte, bool write, bool execute) > return pkey_access_permitted(pte_to_pkey_bits(pte), > write, execute); > } > + > +/* > + * We only want to enforce protection keys on the current process > + * because we effectively have no access to AMR/IAMR for other > + * processes or any way to tell *which * AMR/IAMR in a threaded > + * process we could use. > + * > + * So do not enforce things if the VMA is not from the current > + * mm, or if we are in a kernel thread. > + */ > +static inline bool vma_is_foreign(struct vm_area_struct *vma) > +{ > + if (!current->mm) > + return true; > + /* > + * if the VMA is from another process, then AMR/IAMR has no > + * relevance and should not be enforced. > + */ > + if (current->mm != vma->vm_mm) > + return true; > + > + return false; > +} > + > +bool arch_vma_access_permitted(struct vm_area_struct *vma, > + bool write, bool execute, bool foreign) > +{ > + int pkey; > + > + if (!pkey_inited) > + return true; > + > + /* allow access if the VMA is not one from this process */ > + if (foreign || vma_is_foreign(vma)) > + return true; > + > + pkey = vma_pkey(vma); > + > + if (!pkey) > + return true; > + > + return pkey_access_permitted(pkey, write, execute); > +} Again, I think this is GUP, I don't really understand the top level use case of enforcing permissions for GUP in a thread context. Balbir Singh.
Ram Pai <linuxram@us.ibm.com> writes: > diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c > index 24589d9..21c3b42 100644 > --- a/arch/powerpc/mm/pkeys.c > +++ b/arch/powerpc/mm/pkeys.c > @@ -320,3 +320,46 @@ bool arch_pte_access_permitted(u64 pte, bool write, bool execute) > return pkey_access_permitted(pte_to_pkey_bits(pte), > write, execute); > } > + > +/* > + * We only want to enforce protection keys on the current process > + * because we effectively have no access to AMR/IAMR for other > + * processes or any way to tell *which * AMR/IAMR in a threaded > + * process we could use. This comment doesn't match the code, or at least is confusing to me. A "threaded process" is two tasks that have the same mm. ie. where current->mm == vma->mm. And in that case we *do* enforce protection, based on the AMR/IAMR of the current thread. > + * So do not enforce things if the VMA is not from the current > + * mm, or if we are in a kernel thread. > + */ > +static inline bool vma_is_foreign(struct vm_area_struct *vma) > +{ > + if (!current->mm) > + return true; > + /* > + * if the VMA is from another process, then AMR/IAMR has no > + * relevance and should not be enforced. > + */ > + if (current->mm != vma->vm_mm) > + return true; ie. threaded processes end up here, because they *do* share an mm. > + > + return false; > +} > + > +bool arch_vma_access_permitted(struct vm_area_struct *vma, > + bool write, bool execute, bool foreign) > +{ > + int pkey; > + > + if (!pkey_inited) > + return true; > + > + /* allow access if the VMA is not one from this process */ > + if (foreign || vma_is_foreign(vma)) > + return true; > + > + pkey = vma_pkey(vma); > + > + if (!pkey) > + return true; I think I'd prefer if we didn't special case key 0, instead just let it go through to pkey_access_permitted(). > + > + return pkey_access_permitted(pkey, write, execute); > +} cheers
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 04e9221..9a56355 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -135,6 +135,10 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, { } +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS +bool arch_vma_access_permitted(struct vm_area_struct *vma, + bool write, bool execute, bool foreign); +#else /* CONFIG_PPC64_MEMORY_PROTECTION_KEYS */ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { @@ -142,7 +146,6 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, return true; } -#ifndef CONFIG_PPC64_MEMORY_PROTECTION_KEYS #define pkey_initialize() #define pkey_mm_init(mm) diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c index 24589d9..21c3b42 100644 --- a/arch/powerpc/mm/pkeys.c +++ b/arch/powerpc/mm/pkeys.c @@ -320,3 +320,46 @@ bool arch_pte_access_permitted(u64 pte, bool write, bool execute) return pkey_access_permitted(pte_to_pkey_bits(pte), write, execute); } + +/* + * We only want to enforce protection keys on the current process + * because we effectively have no access to AMR/IAMR for other + * processes or any way to tell *which * AMR/IAMR in a threaded + * process we could use. + * + * So do not enforce things if the VMA is not from the current + * mm, or if we are in a kernel thread. + */ +static inline bool vma_is_foreign(struct vm_area_struct *vma) +{ + if (!current->mm) + return true; + /* + * if the VMA is from another process, then AMR/IAMR has no + * relevance and should not be enforced. + */ + if (current->mm != vma->vm_mm) + return true; + + return false; +} + +bool arch_vma_access_permitted(struct vm_area_struct *vma, + bool write, bool execute, bool foreign) +{ + int pkey; + + if (!pkey_inited) + return true; + + /* allow access if the VMA is not one from this process */ + if (foreign || vma_is_foreign(vma)) + return true; + + pkey = vma_pkey(vma); + + if (!pkey) + return true; + + return pkey_access_permitted(pkey, write, execute); +}
This patch provides the implementation for arch_vma_access_permitted(). Returns true if the requested access is allowed by pkey associated with the vma. Signed-off-by: Ram Pai <linuxram@us.ibm.com> --- arch/powerpc/include/asm/mmu_context.h | 5 +++- arch/powerpc/mm/pkeys.c | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletions(-)