Message ID | 20200717072056.73134-14-ira.weiny@intel.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | PKS: Add Protection Keys Supervisor (PKS) support | expand |
On Fri, Jul 17, 2020 at 12:20:52AM -0700, ira.weiny@intel.com wrote: > @@ -31,6 +32,20 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size) > > #include <asm/kmap_types.h> > > +static inline void enable_access(struct page *page) > +{ > + if (!page_is_access_protected(page)) > + return; > + dev_access_enable(); > +} > + > +static inline void disable_access(struct page *page) > +{ > + if (!page_is_access_protected(page)) > + return; > + dev_access_disable(); > +} These are some very generic names, do we want them to be a little more specific?
On Fri, Jul 17, 2020 at 11:21:39AM +0200, Peter Zijlstra wrote: > On Fri, Jul 17, 2020 at 12:20:52AM -0700, ira.weiny@intel.com wrote: > > @@ -31,6 +32,20 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size) > > > > #include <asm/kmap_types.h> > > > > +static inline void enable_access(struct page *page) > > +{ > > + if (!page_is_access_protected(page)) > > + return; > > + dev_access_enable(); > > +} > > + > > +static inline void disable_access(struct page *page) > > +{ > > + if (!page_is_access_protected(page)) > > + return; > > + dev_access_disable(); > > +} > > These are some very generic names, do we want them to be a little more > specific? I had them named kmap_* but Dave (I think it was Dave) thought they did not really apply strictly to kmap_*. They are static to this file which I thought may be sufficient to 'uniqify' them? I'm ok to change them but that is how I arrived at this name. Ira
On Sat, Jul 18, 2020 at 09:13:19PM -0700, Ira Weiny wrote: > On Fri, Jul 17, 2020 at 11:21:39AM +0200, Peter Zijlstra wrote: > > On Fri, Jul 17, 2020 at 12:20:52AM -0700, ira.weiny@intel.com wrote: > > > @@ -31,6 +32,20 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size) > > > > > > #include <asm/kmap_types.h> > > > > > > +static inline void enable_access(struct page *page) > > > +{ > > > + if (!page_is_access_protected(page)) > > > + return; > > > + dev_access_enable(); > > > +} > > > + > > > +static inline void disable_access(struct page *page) > > > +{ > > > + if (!page_is_access_protected(page)) > > > + return; > > > + dev_access_disable(); > > > +} > > > > These are some very generic names, do we want them to be a little more > > specific? > > I had them named kmap_* but Dave (I think it was Dave) thought they did not > really apply strictly to kmap_*. > > They are static to this file which I thought may be sufficient to 'uniqify' > them? They're static to a .h, which means they're all over the place ;-)
On Mon, Jul 20, 2020 at 11:17:40AM +0200, Peter Zijlstra wrote: > On Sat, Jul 18, 2020 at 09:13:19PM -0700, Ira Weiny wrote: > > On Fri, Jul 17, 2020 at 11:21:39AM +0200, Peter Zijlstra wrote: > > > On Fri, Jul 17, 2020 at 12:20:52AM -0700, ira.weiny@intel.com wrote: > > > > @@ -31,6 +32,20 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size) > > > > > > > > #include <asm/kmap_types.h> > > > > > > > > +static inline void enable_access(struct page *page) > > > > +{ > > > > + if (!page_is_access_protected(page)) > > > > + return; > > > > + dev_access_enable(); > > > > +} > > > > + > > > > +static inline void disable_access(struct page *page) > > > > +{ > > > > + if (!page_is_access_protected(page)) > > > > + return; > > > > + dev_access_disable(); > > > > +} > > > > > > These are some very generic names, do we want them to be a little more > > > specific? > > > > I had them named kmap_* but Dave (I think it was Dave) thought they did not > > really apply strictly to kmap_*. > > > > They are static to this file which I thought may be sufficient to 'uniqify' > > them? > > They're static to a .h, which means they're all over the place ;-) I've thought about it a bit. I think I agree with both you and Dave. How about: dev_page_{en,dis}able_access() ?? I've made that change for now. Thanks, Ira
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index d6e82e3de027..7f809d8d5a94 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -8,6 +8,7 @@ #include <linux/mm.h> #include <linux/uaccess.h> #include <linux/hardirq.h> +#include <linux/memremap.h> #include <asm/cacheflush.h> @@ -31,6 +32,20 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size) #include <asm/kmap_types.h> +static inline void enable_access(struct page *page) +{ + if (!page_is_access_protected(page)) + return; + dev_access_enable(); +} + +static inline void disable_access(struct page *page) +{ + if (!page_is_access_protected(page)) + return; + dev_access_disable(); +} + #ifdef CONFIG_HIGHMEM extern void *kmap_atomic_high_prot(struct page *page, pgprot_t prot); extern void kunmap_atomic_high(void *kvaddr); @@ -55,6 +70,11 @@ static inline void *kmap(struct page *page) else addr = kmap_high(page); kmap_flush_tlb((unsigned long)addr); + /* + * Even non-highmem pages may have additional access protections which + * need to be checked and potentially enabled. + */ + enable_access(page); return addr; } @@ -63,6 +83,11 @@ void kunmap_high(struct page *page); static inline void kunmap(struct page *page) { might_sleep(); + /* + * Even non-highmem pages may have additional access protections which + * need to be checked and potentially disabled. + */ + disable_access(page); if (!PageHighMem(page)) return; kunmap_high(page); @@ -85,6 +110,7 @@ static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot) { preempt_disable(); pagefault_disable(); + enable_access(page); if (!PageHighMem(page)) return page_address(page); return kmap_atomic_high_prot(page, prot); @@ -137,6 +163,7 @@ static inline unsigned long totalhigh_pages(void) { return 0UL; } static inline void *kmap(struct page *page) { might_sleep(); + enable_access(page); return page_address(page); } @@ -146,6 +173,7 @@ static inline void kunmap_high(struct page *page) static inline void kunmap(struct page *page) { + disable_access(page); #ifdef ARCH_HAS_FLUSH_ON_KUNMAP kunmap_flush_on_unmap(page_address(page)); #endif @@ -155,6 +183,7 @@ static inline void *kmap_atomic(struct page *page) { preempt_disable(); pagefault_disable(); + enable_access(page); return page_address(page); } #define kmap_atomic_prot(page, prot) kmap_atomic(page) @@ -216,7 +245,8 @@ static inline void kmap_atomic_idx_pop(void) #define kunmap_atomic(addr) \ do { \ BUILD_BUG_ON(__same_type((addr), struct page *)); \ - kunmap_atomic_high(addr); \ + disable_access(kmap_to_page(addr)); \ + kunmap_atomic_high(addr); \ pagefault_enable(); \ preempt_enable(); \ } while (0)