Re: [PATCH RFC PKS/PMEM 51/58] kernel: Utilize new kmap_thread()
ira.we...@intel.com writes: > From: Ira Weiny > > This kmap() call is localized to a single thread. To avoid the over > head of global PKRS updates use the new kmap_thread() call. Acked-by: "Eric W. Biederman" > > Cc: Eric Biederman > Signed-off-by: Ira Weiny > --- > kernel/kexec_core.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c > index c19c0dad1ebe..272a9920c0d6 100644 > --- a/kernel/kexec_core.c > +++ b/kernel/kexec_core.c > @@ -815,7 +815,7 @@ static int kimage_load_normal_segment(struct kimage > *image, > if (result < 0) > goto out; > > - ptr = kmap(page); > + ptr = kmap_thread(page); > /* Start with a clear page */ > clear_page(ptr); > ptr += maddr & ~PAGE_MASK; > @@ -828,7 +828,7 @@ static int kimage_load_normal_segment(struct kimage > *image, > memcpy(ptr, kbuf, uchunk); > else > result = copy_from_user(ptr, buf, uchunk); > - kunmap(page); > + kunmap_thread(page); > if (result) { > result = -EFAULT; > goto out; > @@ -879,7 +879,7 @@ static int kimage_load_crash_segment(struct kimage *image, > goto out; > } > arch_kexec_post_alloc_pages(page_address(page), 1, 0); > - ptr = kmap(page); > + ptr = kmap_thread(page); > ptr += maddr & ~PAGE_MASK; > mchunk = min_t(size_t, mbytes, > PAGE_SIZE - (maddr & ~PAGE_MASK)); > @@ -895,7 +895,7 @@ static int kimage_load_crash_segment(struct kimage *image, > else > result = copy_from_user(ptr, buf, uchunk); > kexec_flush_icache_page(page); > - kunmap(page); > + kunmap_thread(page); > arch_kexec_pre_free_pages(page_address(page), 1); > if (result) { > result = -EFAULT; ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH RFC PKS/PMEM 57/58] nvdimm/pmem: Stray access protection for pmem->virt_addr
On 10/9/20 12:50 PM, ira.we...@intel.com wrote: From: Ira Weiny The pmem driver uses a cached virtual address to access its memory directly. Because the nvdimm driver is well aware of the special protections it has mapped memory with, we call dev_access_[en|dis]able() around the direct pmem->virt_addr (pmem_addr) usage instead of the unnecessary overhead of trying to get a page to kmap. Signed-off-by: Ira Weiny --- drivers/nvdimm/pmem.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index fab29b514372..e4dc1ae990fc 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -148,7 +148,9 @@ static blk_status_t pmem_do_read(struct pmem_device *pmem, if (unlikely(is_bad_pmem(>bb, sector, len))) return BLK_STS_IOERR; + dev_access_enable(false); rc = read_pmem(page, page_off, pmem_addr, len); + dev_access_disable(false); Hi Ira! The APIs should be tweaked to use a symbol (GLOBAL, PER_THREAD), instead of true/false. Try reading the above and you'll see that it sounds like it's doing the opposite of what it is ("enable_this(false)" sounds like a clumsy API design to *disable*, right?). And there is no hint about the scope. And it *could* be so much more readable like this: dev_access_enable(DEV_ACCESS_THIS_THREAD); thanks, -- John Hubbard NVIDIA ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH RFC PKS/PMEM 22/58] fs/f2fs: Utilize new kmap_thread()
On Fri, 2020-10-09 at 14:34 -0700, Eric Biggers wrote: > On Fri, Oct 09, 2020 at 12:49:57PM -0700, ira.we...@intel.com wrote: > > From: Ira Weiny > > > > The kmap() calls in this FS are localized to a single thread. To > > avoid the over head of global PKRS updates use the new > > kmap_thread() call. > > > > Cc: Jaegeuk Kim > > Cc: Chao Yu > > Signed-off-by: Ira Weiny > > --- > > fs/f2fs/f2fs.h | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > > index d9e52a7f3702..ff72a45a577e 100644 > > --- a/fs/f2fs/f2fs.h > > +++ b/fs/f2fs/f2fs.h > > @@ -2410,12 +2410,12 @@ static inline struct page > > *f2fs_pagecache_get_page( > > > > static inline void f2fs_copy_page(struct page *src, struct page > > *dst) > > { > > - char *src_kaddr = kmap(src); > > - char *dst_kaddr = kmap(dst); > > + char *src_kaddr = kmap_thread(src); > > + char *dst_kaddr = kmap_thread(dst); > > > > memcpy(dst_kaddr, src_kaddr, PAGE_SIZE); > > - kunmap(dst); > > - kunmap(src); > > + kunmap_thread(dst); > > + kunmap_thread(src); > > } > > Wouldn't it make more sense to switch cases like this to > kmap_atomic()? > The pages are only mapped to do a memcpy(), then they're immediately > unmapped. On a VIPT/VIVT architecture, this is horrendously wasteful. You're taking something that was mapped at colour c_src mapping it to a new address src_kaddr, which is likely a different colour and necessitates flushing the original c_src, then you copy it to dst_kaddr, which is also likely a different colour from c_dst, so dst_kaddr has to be flushed on kunmap and c_dst has to be invalidated on kmap. What we should have is an architectural primitive for doing this, something like kmemcopy_arch(dst, src). PIPT architectures can implement it as the above (possibly losing kmap if they don't need it) but VIPT/VIVT architectures can set up a correctly coloured mapping so they can simply copy from c_src to c_dst without any need to flush and the data arrives cache hot at c_dst. James ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH RFC PKS/PMEM 48/58] drivers/md: Utilize new kmap_thread()
On 2020/10/10 03:50, ira.we...@intel.com wrote: > From: Ira Weiny > > These kmap() calls are localized to a single thread. To avoid the over > head of global PKRS updates use the new kmap_thread() call. > Hi Ira, There were a number of options considered. 1) Attempt to change all the thread local kmap() calls to kmap_atomic() 2) Introduce a flags parameter to kmap() to indicate if the mapping should be global or not 3) Change ~20-30 call sites to 'kmap_global()' to indicate that they require a global mapping of the pages 4) Change ~209 call sites to 'kmap_thread()' to indicate that the mapping is to be used within that thread of execution only I copied the above information from patch 00/58 to this message. The idea behind kmap_thread() is fine to me, but as you said the new api is very easy to be missed in new code (even for me). I would like to be supportive to option 2) introduce a flag to kmap(), then we won't forget the new thread-localized kmap method, and people won't ask why a _thread() function is called but no kthread created. Thanks. Coly Li > Cc: Coly Li (maintainer:BCACHE (BLOCK LAYER CACHE)) > Cc: Kent Overstreet (maintainer:BCACHE (BLOCK > LAYER CACHE)) > Signed-off-by: Ira Weiny > --- > drivers/md/bcache/request.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c > index c7cadaafa947..a4571f6d09dd 100644 > --- a/drivers/md/bcache/request.c > +++ b/drivers/md/bcache/request.c > @@ -44,10 +44,10 @@ static void bio_csum(struct bio *bio, struct bkey *k) > uint64_t csum = 0; > > bio_for_each_segment(bv, bio, iter) { > - void *d = kmap(bv.bv_page) + bv.bv_offset; > + void *d = kmap_thread(bv.bv_page) + bv.bv_offset; > > csum = bch_crc64_update(csum, d, bv.bv_len); > - kunmap(bv.bv_page); > + kunmap_thread(bv.bv_page); > } > > k->ptr[KEY_PTRS(k)] = csum & (~0ULL >> 1); > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH RFC PKS/PMEM 22/58] fs/f2fs: Utilize new kmap_thread()
On Sat, Oct 10, 2020 at 01:39:54AM +0100, Matthew Wilcox wrote: > On Fri, Oct 09, 2020 at 02:34:34PM -0700, Eric Biggers wrote: > > On Fri, Oct 09, 2020 at 12:49:57PM -0700, ira.we...@intel.com wrote: > > > The kmap() calls in this FS are localized to a single thread. To avoid > > > the over head of global PKRS updates use the new kmap_thread() call. > > > > > > @@ -2410,12 +2410,12 @@ static inline struct page > > > *f2fs_pagecache_get_page( > > > > > > static inline void f2fs_copy_page(struct page *src, struct page *dst) > > > { > > > - char *src_kaddr = kmap(src); > > > - char *dst_kaddr = kmap(dst); > > > + char *src_kaddr = kmap_thread(src); > > > + char *dst_kaddr = kmap_thread(dst); > > > > > > memcpy(dst_kaddr, src_kaddr, PAGE_SIZE); > > > - kunmap(dst); > > > - kunmap(src); > > > + kunmap_thread(dst); > > > + kunmap_thread(src); > > > } > > > > Wouldn't it make more sense to switch cases like this to kmap_atomic()? > > The pages are only mapped to do a memcpy(), then they're immediately > > unmapped. > > Maybe you missed the earlier thread from Thomas trying to do something > similar for rather different reasons ... > > https://lore.kernel.org/lkml/20200919091751.06...@linutronix.de/ I did miss it. I'm not subscribed to any of the mailing lists it was sent to. Anyway, it shouldn't matter. Patchsets should be standalone, and not require reading random prior threads on linux-kernel to understand. And I still don't really understand. After this patchset, there is still code nearly identical to the above (doing a temporary mapping just for a memcpy) that would still be using kmap_atomic(). Is the idea that later, such code will be converted to use kmap_thread() instead? If not, why use one over the other? - Eric ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[staging:staging-testing] BUILD SUCCESS 41f0666f0f60997dea10e716df728f330525052e
db1xxx_defconfig powerpc mpc866_ads_defconfig i386 alldefconfig arm spear13xx_defconfig ia64 allmodconfig ia64defconfig ia64 allyesconfig m68kdefconfig m68k allyesconfig nios2 defconfig arc allyesconfig nds32 allnoconfig c6x allyesconfig nds32 defconfig nios2allyesconfig cskydefconfig alpha defconfig alphaallyesconfig xtensa allyesconfig h8300allyesconfig arc defconfig sh allmodconfig parisc defconfig s390 allyesconfig parisc allyesconfig s390defconfig i386 allyesconfig sparcallyesconfig sparc defconfig i386defconfig mips allyesconfig mips allmodconfig powerpc allyesconfig powerpc allmodconfig powerpc allnoconfig i386 randconfig-a006-20201009 i386 randconfig-a005-20201009 i386 randconfig-a001-20201009 i386 randconfig-a004-20201009 i386 randconfig-a002-20201009 i386 randconfig-a003-20201009 x86_64 randconfig-a012-20201009 x86_64 randconfig-a015-20201009 x86_64 randconfig-a013-20201009 x86_64 randconfig-a014-20201009 x86_64 randconfig-a011-20201009 x86_64 randconfig-a016-20201009 i386 randconfig-a015-20201009 i386 randconfig-a013-20201009 i386 randconfig-a014-20201009 i386 randconfig-a016-20201009 i386 randconfig-a011-20201009 i386 randconfig-a012-20201009 riscvnommu_virt_defconfig riscv rv32_defconfig riscvallyesconfig riscv allnoconfig riscv defconfig riscvallmodconfig x86_64 rhel x86_64 allyesconfig x86_64rhel-7.6-kselftests x86_64 defconfig x86_64 rhel-8.3 x86_64 kexec clang tested configs: x86_64 randconfig-a004-20201009 x86_64 randconfig-a003-20201009 x86_64 randconfig-a005-20201009 x86_64 randconfig-a001-20201009 x86_64 randconfig-a002-20201009 x86_64 randconfig-a006-20201009 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH RFC PKS/PMEM 22/58] fs/f2fs: Utilize new kmap_thread()
On Fri, Oct 09, 2020 at 02:34:34PM -0700, Eric Biggers wrote: > On Fri, Oct 09, 2020 at 12:49:57PM -0700, ira.we...@intel.com wrote: > > The kmap() calls in this FS are localized to a single thread. To avoid > > the over head of global PKRS updates use the new kmap_thread() call. > > > > @@ -2410,12 +2410,12 @@ static inline struct page *f2fs_pagecache_get_page( > > > > static inline void f2fs_copy_page(struct page *src, struct page *dst) > > { > > - char *src_kaddr = kmap(src); > > - char *dst_kaddr = kmap(dst); > > + char *src_kaddr = kmap_thread(src); > > + char *dst_kaddr = kmap_thread(dst); > > > > memcpy(dst_kaddr, src_kaddr, PAGE_SIZE); > > - kunmap(dst); > > - kunmap(src); > > + kunmap_thread(dst); > > + kunmap_thread(src); > > } > > Wouldn't it make more sense to switch cases like this to kmap_atomic()? > The pages are only mapped to do a memcpy(), then they're immediately unmapped. Maybe you missed the earlier thread from Thomas trying to do something similar for rather different reasons ... https://lore.kernel.org/lkml/20200919091751.06...@linutronix.de/ ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] Fixed coding style issues raised by checkpatch.
This patch fixes the following: - Made sure alignment matched open parenthesis. Signed-off-by: Tabot Kevin --- drivers/staging/greybus/audio_module.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index c52c4f3..a243d60 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -175,8 +175,8 @@ static int gbaudio_codec_request_handler(struct gb_operation *op) } static int gb_audio_add_mgmt_connection(struct gbaudio_module_info *gbmodule, - struct greybus_descriptor_cport *cport_desc, - struct gb_bundle *bundle) + struct greybus_descriptor_cport *cport_desc, + struct gb_bundle *bundle) { struct gb_connection *connection; @@ -199,8 +199,8 @@ static int gb_audio_add_mgmt_connection(struct gbaudio_module_info *gbmodule, } static int gb_audio_add_data_connection(struct gbaudio_module_info *gbmodule, - struct greybus_descriptor_cport *cport_desc, - struct gb_bundle *bundle) + struct greybus_descriptor_cport *cport_desc, + struct gb_bundle *bundle) { struct gb_connection *connection; struct gbaudio_data_connection *dai; -- 2.7.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH RFC PKS/PMEM 09/58] drivers/gpu: Utilize new kmap_thread()
On Fri, Oct 09, 2020 at 12:49:44PM -0700, ira.we...@intel.com wrote: > From: Ira Weiny > > These kmap() calls in the gpu stack are localized to a single thread. > To avoid the over head of global PKRS updates use the new kmap_thread() > call. > > Cc: David Airlie > Cc: Daniel Vetter > Cc: Patrik Jakobsson > Signed-off-by: Ira Weiny I'm guessing the entire pile goes in through some other tree. If so: Acked-by: Daniel Vetter If you want this to land through maintainer trees, then we need a per-driver split (since aside from amdgpu and radeon they're all different subtrees). btw the two kmap calls in drm you highlight in the cover letter should also be convertible to kmap_thread. We only hold vmalloc mappings for a longer time (or it'd be quite a driver bug). So if you want maybe throw those two as two additional patches on top, and we can do some careful review & testing for them. -Daniel > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 12 ++-- > drivers/gpu/drm/gma500/gma_display.c | 4 ++-- > drivers/gpu/drm/gma500/mmu.c | 10 +- > drivers/gpu/drm/i915/gem/i915_gem_shmem.c| 4 ++-- > .../gpu/drm/i915/gem/selftests/i915_gem_context.c| 4 ++-- > drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c | 8 > drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c | 4 ++-- > drivers/gpu/drm/i915/gt/intel_gtt.c | 4 ++-- > drivers/gpu/drm/i915/gt/shmem_utils.c| 4 ++-- > drivers/gpu/drm/i915/i915_gem.c | 8 > drivers/gpu/drm/i915/i915_gpu_error.c| 4 ++-- > drivers/gpu/drm/i915/selftests/i915_perf.c | 4 ++-- > drivers/gpu/drm/radeon/radeon_ttm.c | 4 ++-- > 13 files changed, 37 insertions(+), 37 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > index 978bae731398..bd564bccb7a3 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > @@ -2437,11 +2437,11 @@ static ssize_t amdgpu_ttm_gtt_read(struct file *f, > char __user *buf, > > page = adev->gart.pages[p]; > if (page) { > - ptr = kmap(page); > + ptr = kmap_thread(page); > ptr += off; > > r = copy_to_user(buf, ptr, cur_size); > - kunmap(adev->gart.pages[p]); > + kunmap_thread(adev->gart.pages[p]); > } else > r = clear_user(buf, cur_size); > > @@ -2507,9 +2507,9 @@ static ssize_t amdgpu_iomem_read(struct file *f, char > __user *buf, > if (p->mapping != adev->mman.bdev.dev_mapping) > return -EPERM; > > - ptr = kmap(p); > + ptr = kmap_thread(p); > r = copy_to_user(buf, ptr + off, bytes); > - kunmap(p); > + kunmap_thread(p); > if (r) > return -EFAULT; > > @@ -2558,9 +2558,9 @@ static ssize_t amdgpu_iomem_write(struct file *f, const > char __user *buf, > if (p->mapping != adev->mman.bdev.dev_mapping) > return -EPERM; > > - ptr = kmap(p); > + ptr = kmap_thread(p); > r = copy_from_user(ptr + off, buf, bytes); > - kunmap(p); > + kunmap_thread(p); > if (r) > return -EFAULT; > > diff --git a/drivers/gpu/drm/gma500/gma_display.c > b/drivers/gpu/drm/gma500/gma_display.c > index 3df6d6e850f5..35f4e55c941f 100644 > --- a/drivers/gpu/drm/gma500/gma_display.c > +++ b/drivers/gpu/drm/gma500/gma_display.c > @@ -400,9 +400,9 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc, > /* Copy the cursor to cursor mem */ > tmp_dst = dev_priv->vram_addr + cursor_gt->offset; > for (i = 0; i < cursor_pages; i++) { > - tmp_src = kmap(gt->pages[i]); > + tmp_src = kmap_thread(gt->pages[i]); > memcpy(tmp_dst, tmp_src, PAGE_SIZE); > - kunmap(gt->pages[i]); > + kunmap_thread(gt->pages[i]); > tmp_dst += PAGE_SIZE; > } > > diff --git a/drivers/gpu/drm/gma500/mmu.c b/drivers/gpu/drm/gma500/mmu.c > index 505044c9a673..fba7a3a461fd 100644 > --- a/drivers/gpu/drm/gma500/mmu.c > +++ b/drivers/gpu/drm/gma500/mmu.c > @@ -192,20 +192,20 @@ struct psb_mmu_pd *psb_mmu_alloc_pd(struct > psb_mmu_driver *driver, > pd->invalid_pte = 0; > } > > - v = kmap(pd->dummy_pt); > + v = kmap_thread(pd->dummy_pt); > for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) > v[i] = pd->invalid_pte; > > - kunmap(pd->dummy_pt); > + kunmap_thread(pd->dummy_pt); > > - v = kmap(pd->p); > +
Re: [PATCH RFC PKS/PMEM 22/58] fs/f2fs: Utilize new kmap_thread()
On Fri, Oct 09, 2020 at 12:49:57PM -0700, ira.we...@intel.com wrote: > From: Ira Weiny > > The kmap() calls in this FS are localized to a single thread. To avoid > the over head of global PKRS updates use the new kmap_thread() call. > > Cc: Jaegeuk Kim > Cc: Chao Yu > Signed-off-by: Ira Weiny > --- > fs/f2fs/f2fs.h | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index d9e52a7f3702..ff72a45a577e 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -2410,12 +2410,12 @@ static inline struct page *f2fs_pagecache_get_page( > > static inline void f2fs_copy_page(struct page *src, struct page *dst) > { > - char *src_kaddr = kmap(src); > - char *dst_kaddr = kmap(dst); > + char *src_kaddr = kmap_thread(src); > + char *dst_kaddr = kmap_thread(dst); > > memcpy(dst_kaddr, src_kaddr, PAGE_SIZE); > - kunmap(dst); > - kunmap(src); > + kunmap_thread(dst); > + kunmap_thread(src); > } Wouldn't it make more sense to switch cases like this to kmap_atomic()? The pages are only mapped to do a memcpy(), then they're immediately unmapped. - Eric ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Gruß,
Gruß, Mit warmem Herzen biete ich Ihnen meine Freundschaft und meine Grüße im Namen unseres Herrn an, und ich hoffe, dass dieser Brief Sie rechtzeitig trifft. Ich schlage mit meinem freien Verstand vor und als eine Person der Integrität von Gott weiß ich, dass dies Die Botschaft wird Ihnen als Überraschung erscheinen, die wir kaum kennen, aber die Gnade Gottes hat mich zu Ihnen geleitet, und ich wünsche, dass Sie diese Botschaft lesen und im Namen des Herrn gesegnet werden. Ich habe einen Gehirntumor; Ich leide im Moment schrecklich. Mein Arzt hat mir gerade mitgeteilt, dass meine Tage wegen meiner Gesundheit gezählt sind und daher zum sicheren Tod verurteilt sind. Derzeit habe ich alle meine Ersparnisse für meine medizinische Versorgung aufgebraucht. Aber ich habe einige Mittel für mein Wohltätigkeitsprojekt; Diese Gelder werden bei einer der Banken hier in Cote D'Ivoire Westafrika hinterlegt. Mein Familienstand ist so, dass ich ledig bin, weil ich meinen Ehemann über 9 Jahre verloren habe und leider kein Kind zusammen hatte, für das ich mein Vermächtnis nicht hinterlassen kann. Um mein Geld freizugeben, möchte ich daher eine Spende machen, damit mein Geld nicht streng besteuert wird. Dazu wäre ich so anmutig und um den Armen zu helfen, das Erbe in Höhe von vier Millionen Euro (4.000.000,00 Millionen Euro) zu geben, damit Sie in meinem Gedächtnis eine wohltätige Grundlage schaffen können, damit die Gnade Gottes mit mir ist bis zu meinem letzten Zuhause, damit ich einen ehrenvollen Platz beim Herrn, unserem Vater, erhalten kann. Ich habe keine Angst, denn bevor ich Sie kontaktierte, habe ich mehrere Nächte lang darum gebetet, dass der Herr mir den Kontakt einer vertrauenswürdigen Person gibt, der ich diese Angelegenheit anvertrauen kann, und ich glaube, dass meine Kontakte zu Ihnen göttlich sind. Wisse, dass du 30% des Geldes für dich behalten kannst und der Rest wird verwendet, um eine gemeinnützige Stiftung in meinem Gedächtnis und einen Verband im Kampf gegen Krebs zu schaffen und auch Waisenhäuser zu bauen. Ich zähle auf Ihren guten Willen und insbesondere auf die ordnungsgemäße Verwendung dieser Mittel. Ich bezweifle nicht, dass ich Ihnen sehr vertraue, dass Gott mich zu Ihnen führen kann. Meine E-Mail vernitha.mayn...@yahoo.com In Erwartung Ihrer prompten Antwort erhalten Sie meine herzlichen und brüderlichen Grüße. Dein, Frau Vernitha Maynard ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v3 00/11] Introduce Simple atomic counters
On Fri, Oct 09, 2020 at 09:37:46PM +0200, Peter Zijlstra wrote: > On Fri, Oct 09, 2020 at 09:55:55AM -0600, Shuah Khan wrote: > > Simple atomic counters api provides interfaces for simple atomic counters > > that just count, and don't guard resource lifetimes. The interfaces are > > built on top of atomic_t api, providing a smaller subset of atomic_t > > interfaces necessary to support simple counters. > > To what actual purpose?!? AFACIT its pointless wrappery, it gets us > nothing. It's not pointless. There is value is separating types for behavioral constraint to avoid flaws. atomic_t provides a native operation. We gained refcount_t for the "must not wrap" type, and this gets us the other side of that behavioral type, which is "wrapping is expected". Separating the atomic_t uses allows for a clearer path to being able to reason about code flow, whether it be a human or a static analyzer. The counter wrappers add nothing to the image size, and only serve to confine the API to one that cannot be used for lifetime management. Once conversions are done, we have a clean line between refcounting and statistical atomics, which means we have a much lower chance of introducing new flaws (and maybe we'll fix flaws during the conversion, which we've certainly seen before when doing this stricter type/language changes). I don't see why this is an objectionable goal. -- Kees Cook ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 57/58] nvdimm/pmem: Stray access protection for pmem->virt_addr
From: Ira Weiny The pmem driver uses a cached virtual address to access its memory directly. Because the nvdimm driver is well aware of the special protections it has mapped memory with, we call dev_access_[en|dis]able() around the direct pmem->virt_addr (pmem_addr) usage instead of the unnecessary overhead of trying to get a page to kmap. Signed-off-by: Ira Weiny --- drivers/nvdimm/pmem.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index fab29b514372..e4dc1ae990fc 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -148,7 +148,9 @@ static blk_status_t pmem_do_read(struct pmem_device *pmem, if (unlikely(is_bad_pmem(>bb, sector, len))) return BLK_STS_IOERR; + dev_access_enable(false); rc = read_pmem(page, page_off, pmem_addr, len); + dev_access_disable(false); flush_dcache_page(page); return rc; } @@ -180,11 +182,13 @@ static blk_status_t pmem_do_write(struct pmem_device *pmem, * after clear poison. */ flush_dcache_page(page); + dev_access_enable(false); write_pmem(pmem_addr, page, page_off, len); if (unlikely(bad_pmem)) { rc = pmem_clear_poison(pmem, pmem_off, len); write_pmem(pmem_addr, page, page_off, len); } + dev_access_disable(false); return rc; } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 43/58] drivers/mmc: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Ulf Hansson Cc: Sascha Sommer Signed-off-by: Ira Weiny --- drivers/mmc/host/mmc_spi.c| 4 ++-- drivers/mmc/host/sdricoh_cs.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 18a850f37ddc..ab28e7103b8d 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -918,7 +918,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, } /* allow pio too; we don't allow highmem */ - kmap_addr = kmap(sg_page(sg)); + kmap_addr = kmap_thread(sg_page(sg)); if (direction == DMA_TO_DEVICE) t->tx_buf = kmap_addr + sg->offset; else @@ -950,7 +950,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, /* discard mappings */ if (direction == DMA_FROM_DEVICE) flush_kernel_dcache_page(sg_page(sg)); - kunmap(sg_page(sg)); + kunmap_thread(sg_page(sg)); if (dma_dev) dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir); diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index 76a8cd3a186f..7806bc69c4f1 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -312,11 +312,11 @@ static void sdricoh_request(struct mmc_host *mmc, struct mmc_request *mrq) int result; page = sg_page(data->sg); - buf = kmap(page) + data->sg->offset + (len * i); + buf = kmap_thread(page) + data->sg->offset + (len * i); result = sdricoh_blockio(host, data->flags & MMC_DATA_READ, buf, len); - kunmap(page); + kunmap_thread(page); flush_dcache_page(page); if (result) { dev_err(dev, "sdricoh_request: cmd %i " -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 42/58] drivers/scsi: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Signed-off-by: Ira Weiny --- drivers/scsi/ipr.c | 8 drivers/scsi/pmcraid.c | 8 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b0aa58d117cc..a5a0b8feb661 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3923,9 +3923,9 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, buffer += bsize_elem) { struct page *page = sg_page(sg); - kaddr = kmap(page); + kaddr = kmap_thread(page); memcpy(kaddr, buffer, bsize_elem); - kunmap(page); + kunmap_thread(page); sg->length = bsize_elem; @@ -3938,9 +3938,9 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, if (len % bsize_elem) { struct page *page = sg_page(sg); - kaddr = kmap(page); + kaddr = kmap_thread(page); memcpy(kaddr, buffer, len % bsize_elem); - kunmap(page); + kunmap_thread(page); sg->length = len % bsize_elem; } diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index aa9ae2ae8579..4b05ba4b8a11 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -3269,13 +3269,13 @@ static int pmcraid_copy_sglist( for (i = 0; i < (len / bsize_elem); i++, sg = sg_next(sg), buffer += bsize_elem) { struct page *page = sg_page(sg); - kaddr = kmap(page); + kaddr = kmap_thread(page); if (direction == DMA_TO_DEVICE) rc = copy_from_user(kaddr, buffer, bsize_elem); else rc = copy_to_user(buffer, kaddr, bsize_elem); - kunmap(page); + kunmap_thread(page); if (rc) { pmcraid_err("failed to copy user data into sg list\n"); @@ -3288,14 +3288,14 @@ static int pmcraid_copy_sglist( if (len % bsize_elem) { struct page *page = sg_page(sg); - kaddr = kmap(page); + kaddr = kmap_thread(page); if (direction == DMA_TO_DEVICE) rc = copy_from_user(kaddr, buffer, len % bsize_elem); else rc = copy_to_user(buffer, kaddr, len % bsize_elem); - kunmap(page); + kunmap_thread(page); sg->length = len % bsize_elem; } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 51/58] kernel: Utilize new kmap_thread()
From: Ira Weiny This kmap() call is localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Eric Biederman Signed-off-by: Ira Weiny --- kernel/kexec_core.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index c19c0dad1ebe..272a9920c0d6 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -815,7 +815,7 @@ static int kimage_load_normal_segment(struct kimage *image, if (result < 0) goto out; - ptr = kmap(page); + ptr = kmap_thread(page); /* Start with a clear page */ clear_page(ptr); ptr += maddr & ~PAGE_MASK; @@ -828,7 +828,7 @@ static int kimage_load_normal_segment(struct kimage *image, memcpy(ptr, kbuf, uchunk); else result = copy_from_user(ptr, buf, uchunk); - kunmap(page); + kunmap_thread(page); if (result) { result = -EFAULT; goto out; @@ -879,7 +879,7 @@ static int kimage_load_crash_segment(struct kimage *image, goto out; } arch_kexec_post_alloc_pages(page_address(page), 1, 0); - ptr = kmap(page); + ptr = kmap_thread(page); ptr += maddr & ~PAGE_MASK; mchunk = min_t(size_t, mbytes, PAGE_SIZE - (maddr & ~PAGE_MASK)); @@ -895,7 +895,7 @@ static int kimage_load_crash_segment(struct kimage *image, else result = copy_from_user(ptr, buf, uchunk); kexec_flush_icache_page(page); - kunmap(page); + kunmap_thread(page); arch_kexec_pre_free_pages(page_address(page), 1); if (result) { result = -EFAULT; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 50/58] drivers/android: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Greg Kroah-Hartman Signed-off-by: Ira Weiny --- drivers/android/binder_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 69609696a843..5f50856caad7 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -1118,9 +1118,9 @@ binder_alloc_copy_user_to_buffer(struct binder_alloc *alloc, page = binder_alloc_get_page(alloc, buffer, buffer_offset, ); size = min_t(size_t, bytes, PAGE_SIZE - pgoff); - kptr = kmap(page) + pgoff; + kptr = kmap_thread(page) + pgoff; ret = copy_from_user(kptr, from, size); - kunmap(page); + kunmap_thread(page); if (ret) return bytes - size + ret; bytes -= size; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 37/58] fs/ext2: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS update use the new kmap_thread() call instead. Cc: Jan Kara Signed-off-by: Ira Weiny --- fs/ext2/dir.c | 2 +- fs/ext2/ext2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index f3194bf20733..abe97ba458c8 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -196,7 +196,7 @@ static struct page * ext2_get_page(struct inode *dir, unsigned long n, struct address_space *mapping = dir->i_mapping; struct page *page = read_mapping_page(mapping, n, NULL); if (!IS_ERR(page)) { - kmap(page); + kmap_thread(page); if (unlikely(!PageChecked(page))) { if (PageError(page) || !ext2_check_page(page, quiet)) goto fail; diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 021ec8b42ac3..9bcb6714c255 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -749,7 +749,7 @@ extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **); extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int); static inline void ext2_put_page(struct page *page) { - kunmap(page); + kunmap_thread(page); put_page(page); } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 47/58] drivers/mtd: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Miquel Raynal Cc: Richard Weinberger Cc: Vignesh Raghavendra Signed-off-by: Ira Weiny --- drivers/mtd/mtd_blkdevs.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 0c05f77f9b21..4b18998273fa 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -88,14 +88,14 @@ static blk_status_t do_blktrans_request(struct mtd_blktrans_ops *tr, return BLK_STS_IOERR; return BLK_STS_OK; case REQ_OP_READ: - buf = kmap(bio_page(req->bio)) + bio_offset(req->bio); + buf = kmap_thread(bio_page(req->bio)) + bio_offset(req->bio); for (; nsect > 0; nsect--, block++, buf += tr->blksize) { if (tr->readsect(dev, block, buf)) { - kunmap(bio_page(req->bio)); + kunmap_thread(bio_page(req->bio)); return BLK_STS_IOERR; } } - kunmap(bio_page(req->bio)); + kunmap_thread(bio_page(req->bio)); rq_flush_dcache_pages(req); return BLK_STS_OK; case REQ_OP_WRITE: @@ -103,14 +103,14 @@ static blk_status_t do_blktrans_request(struct mtd_blktrans_ops *tr, return BLK_STS_IOERR; rq_flush_dcache_pages(req); - buf = kmap(bio_page(req->bio)) + bio_offset(req->bio); + buf = kmap_thread(bio_page(req->bio)) + bio_offset(req->bio); for (; nsect > 0; nsect--, block++, buf += tr->blksize) { if (tr->writesect(dev, block, buf)) { - kunmap(bio_page(req->bio)); + kunmap_thread(bio_page(req->bio)); return BLK_STS_IOERR; } } - kunmap(bio_page(req->bio)); + kunmap_thread(bio_page(req->bio)); return BLK_STS_OK; default: return BLK_STS_IOERR; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 54/58] powerpc: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Ira Weiny --- arch/powerpc/mm/mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 42e25874f5a8..6ef557b8dda6 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -573,9 +573,9 @@ void flush_icache_user_page(struct vm_area_struct *vma, struct page *page, { unsigned long maddr; - maddr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); + maddr = (unsigned long) kmap_thread(page) + (addr & ~PAGE_MASK); flush_icache_range(maddr, maddr + len); - kunmap(page); + kunmap_thread(page); } /* -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 56/58] dax: Stray access protection for dax_direct_access()
From: Ira Weiny dax_direct_access() is a special case of accessing pmem via a page offset and without a struct page. Because the dax driver is well aware of the special protections it has mapped memory with, call dev_access_[en|dis]able() directly instead of the unnecessary overhead of trying to get a page to kmap. Similar to kmap, we leverage existing functions, dax_read_[un]lock(), because they are already required to surround the use of the memory returned from dax_direct_access(). Signed-off-by: Ira Weiny --- drivers/dax/super.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dax/super.c b/drivers/dax/super.c index e84070b55463..0ddb3ee73e36 100644 --- a/drivers/dax/super.c +++ b/drivers/dax/super.c @@ -30,6 +30,7 @@ static DEFINE_SPINLOCK(dax_host_lock); int dax_read_lock(void) { + dev_access_enable(false); return srcu_read_lock(_srcu); } EXPORT_SYMBOL_GPL(dax_read_lock); @@ -37,6 +38,7 @@ EXPORT_SYMBOL_GPL(dax_read_lock); void dax_read_unlock(int id) { srcu_read_unlock(_srcu, id); + dev_access_disable(false); } EXPORT_SYMBOL_GPL(dax_read_unlock); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 58/58] [dax|pmem]: Enable stray access protection
From: Ira Weiny Protecting against stray writes is particularly important for PMEM because, unlike writes to anonymous memory, writes to PMEM persists across a reboot. Thus data corruption could result in permanent loss of data. While stray writes are more serious than reads, protection is also enabled for reads. This helps to detect bugs in code which would incorrectly access device memory and prevents a more serious machine checks should those bug reads from a poison page. Enable stray access protection by setting the flag in pgmap which requests it. There is no option presented to the user. If Zone Device Access Protection not be supported this flag will have no affect. Signed-off-by: Ira Weiny --- drivers/dax/device.c | 2 ++ drivers/nvdimm/pmem.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/dax/device.c b/drivers/dax/device.c index 1e89513f3c59..e6fb35b4f0fb 100644 --- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@ -430,6 +430,8 @@ int dev_dax_probe(struct device *dev) } dev_dax->pgmap.type = MEMORY_DEVICE_GENERIC; + dev_dax->pgmap.flags |= PGMAP_PROT_ENABLED; + addr = devm_memremap_pages(dev, _dax->pgmap); if (IS_ERR(addr)) return PTR_ERR(addr); diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index e4dc1ae990fc..9fcd8338e23f 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -426,6 +426,8 @@ static int pmem_attach_disk(struct device *dev, return -EBUSY; } + pmem->pgmap.flags |= PGMAP_PROT_ENABLED; + q = blk_alloc_queue(dev_to_node(dev)); if (!q) return -ENOMEM; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 38/58] fs/isofs: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Signed-off-by: Ira Weiny --- fs/isofs/compress.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c index bc12ac7e2312..ddd3fd99d2e1 100644 --- a/fs/isofs/compress.c +++ b/fs/isofs/compress.c @@ -344,7 +344,7 @@ static int zisofs_readpage(struct file *file, struct page *page) pages[i] = grab_cache_page_nowait(mapping, index); if (pages[i]) { ClearPageError(pages[i]); - kmap(pages[i]); + kmap_thread(pages[i]); } } @@ -356,7 +356,7 @@ static int zisofs_readpage(struct file *file, struct page *page) flush_dcache_page(pages[i]); if (i == full_page && err) SetPageError(pages[i]); - kunmap(pages[i]); + kunmap_thread(pages[i]); unlock_page(pages[i]); if (i != full_page) put_page(pages[i]); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 45/58] drivers/firmware: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Ard Biesheuvel Signed-off-by: Ira Weiny --- drivers/firmware/efi/capsule-loader.c | 6 +++--- drivers/firmware/efi/capsule.c| 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c index 4dde8edd53b6..aa2e0b5940fd 100644 --- a/drivers/firmware/efi/capsule-loader.c +++ b/drivers/firmware/efi/capsule-loader.c @@ -197,7 +197,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, page = cap_info->pages[cap_info->index - 1]; } - kbuff = kmap(page); + kbuff = kmap_thread(page); kbuff += PAGE_SIZE - cap_info->page_bytes_remain; /* Copy capsule binary data from user space to kernel space buffer */ @@ -217,7 +217,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, } cap_info->count += write_byte; - kunmap(page); + kunmap_thread(page); /* Submit the full binary to efi_capsule_update() API */ if (cap_info->header.headersize > 0 && @@ -236,7 +236,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, return write_byte; fail_unmap: - kunmap(page); + kunmap_thread(page); failed: efi_free_all_buff_pages(cap_info); return ret; diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c index 598b7800d14e..edb7797b0e4f 100644 --- a/drivers/firmware/efi/capsule.c +++ b/drivers/firmware/efi/capsule.c @@ -244,7 +244,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages) for (i = 0; i < sg_count; i++) { efi_capsule_block_desc_t *sglist; - sglist = kmap(sg_pages[i]); + sglist = kmap_thread(sg_pages[i]); for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) { u64 sz = min_t(u64, imagesize, @@ -265,7 +265,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages) else sglist[j].data = page_to_phys(sg_pages[i + 1]); - kunmap(sg_pages[i]); + kunmap_thread(sg_pages[i]); } mutex_lock(_mutex); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 33/58] fs/cramfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Nicolas Pitre Signed-off-by: Ira Weiny --- fs/cramfs/inode.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 912308600d39..003c014a42ed 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -247,8 +247,8 @@ static void *cramfs_blkdev_read(struct super_block *sb, unsigned int offset, struct page *page = pages[i]; if (page) { - memcpy(data, kmap(page), PAGE_SIZE); - kunmap(page); + memcpy(data, kmap_thread(page), PAGE_SIZE); + kunmap_thread(page); put_page(page); } else memset(data, 0, PAGE_SIZE); @@ -826,7 +826,7 @@ static int cramfs_readpage(struct file *file, struct page *page) maxblock = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT; bytes_filled = 0; - pgdata = kmap(page); + pgdata = kmap_thread(page); if (page->index < maxblock) { struct super_block *sb = inode->i_sb; @@ -914,13 +914,13 @@ static int cramfs_readpage(struct file *file, struct page *page) memset(pgdata + bytes_filled, 0, PAGE_SIZE - bytes_filled); flush_dcache_page(page); - kunmap(page); + kunmap_thread(page); SetPageUptodate(page); unlock_page(page); return 0; err: - kunmap(page); + kunmap_thread(page); ClearPageUptodate(page); SetPageError(page); unlock_page(page); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 31/58] fs/vboxsf: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Hans de Goede Signed-off-by: Ira Weiny --- fs/vboxsf/file.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/vboxsf/file.c b/fs/vboxsf/file.c index c4ab5996d97a..d9c7e6b7b4cc 100644 --- a/fs/vboxsf/file.c +++ b/fs/vboxsf/file.c @@ -216,7 +216,7 @@ static int vboxsf_readpage(struct file *file, struct page *page) u8 *buf; int err; - buf = kmap(page); + buf = kmap_thread(page); err = vboxsf_read(sf_handle->root, sf_handle->handle, off, , buf); if (err == 0) { @@ -227,7 +227,7 @@ static int vboxsf_readpage(struct file *file, struct page *page) SetPageError(page); } - kunmap(page); + kunmap_thread(page); unlock_page(page); return err; } @@ -268,10 +268,10 @@ static int vboxsf_writepage(struct page *page, struct writeback_control *wbc) if (!sf_handle) return -EBADF; - buf = kmap(page); + buf = kmap_thread(page); err = vboxsf_write(sf_handle->root, sf_handle->handle, off, , buf); - kunmap(page); + kunmap_thread(page); kref_put(_handle->refcount, vboxsf_handle_release); @@ -302,10 +302,10 @@ static int vboxsf_write_end(struct file *file, struct address_space *mapping, if (!PageUptodate(page) && copied < len) zero_user(page, from + copied, len - copied); - buf = kmap(page); + buf = kmap_thread(page); err = vboxsf_write(sf_handle->root, sf_handle->handle, pos, , buf + from); - kunmap(page); + kunmap_thread(page); if (err) { nwritten = 0; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 52/58] mm: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Signed-off-by: Ira Weiny --- mm/memory.c | 8 mm/swapfile.c| 4 ++-- mm/userfaultfd.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index fcfc4ca36eba..75a054882d7a 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4945,7 +4945,7 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, if (bytes > PAGE_SIZE-offset) bytes = PAGE_SIZE-offset; - maddr = kmap(page); + maddr = kmap_thread(page); if (write) { copy_to_user_page(vma, page, addr, maddr + offset, buf, bytes); @@ -4954,7 +4954,7 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, copy_from_user_page(vma, page, addr, buf, maddr + offset, bytes); } - kunmap(page); + kunmap_thread(page); put_page(page); } len -= bytes; @@ -5216,14 +5216,14 @@ long copy_huge_page_from_user(struct page *dst_page, for (i = 0; i < pages_per_huge_page; i++) { if (allow_pagefault) - page_kaddr = kmap(dst_page + i); + page_kaddr = kmap_thread(dst_page + i); else page_kaddr = kmap_atomic(dst_page + i); rc = copy_from_user(page_kaddr, (const void __user *)(src + i * PAGE_SIZE), PAGE_SIZE); if (allow_pagefault) - kunmap(dst_page + i); + kunmap_thread(dst_page + i); else kunmap_atomic(page_kaddr); diff --git a/mm/swapfile.c b/mm/swapfile.c index debc94155f74..e3296ff95648 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -3219,7 +3219,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) error = PTR_ERR(page); goto bad_swap_unlock_inode; } - swap_header = kmap(page); + swap_header = kmap_thread(page); maxpages = read_swap_header(p, swap_header, inode); if (unlikely(!maxpages)) { @@ -3395,7 +3395,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) filp_close(swap_file, NULL); out: if (page && !IS_ERR(page)) { - kunmap(page); + kunmap_thread(page); put_page(page); } if (name) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 9a3d451402d7..4d38c881bb2d 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -586,11 +586,11 @@ static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm, mmap_read_unlock(dst_mm); BUG_ON(!page); - page_kaddr = kmap(page); + page_kaddr = kmap_thread(page); err = copy_from_user(page_kaddr, (const void __user *) src_addr, PAGE_SIZE); - kunmap(page); + kunmap_thread(page); if (unlikely(err)) { err = -EFAULT; goto out; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 55/58] samples: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Kirti Wankhede Signed-off-by: Ira Weiny --- samples/vfio-mdev/mbochs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 3cc5e5921682..6d95422c0b46 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -479,12 +479,12 @@ static ssize_t mdev_access(struct mdev_device *mdev, char *buf, size_t count, pos -= MBOCHS_MMIO_BAR_OFFSET; poff = pos & ~PAGE_MASK; pg = __mbochs_get_page(mdev_state, pos >> PAGE_SHIFT); - map = kmap(pg); + map = kmap_thread(pg); if (is_write) memcpy(map + poff, buf, count); else memcpy(buf, map + poff, count); - kunmap(pg); + kunmap_thread(pg); put_page(pg); } else { -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 34/58] fs/erofs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Gao Xiang Cc: Chao Yu Signed-off-by: Ira Weiny --- fs/erofs/super.c | 4 ++-- fs/erofs/xattr.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/erofs/super.c b/fs/erofs/super.c index ddaa516c008a..41696b60f1b3 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -139,7 +139,7 @@ static int erofs_read_superblock(struct super_block *sb) sbi = EROFS_SB(sb); - data = kmap(page); + data = kmap_thread(page); dsb = (struct erofs_super_block *)(data + EROFS_SUPER_OFFSET); ret = -EINVAL; @@ -189,7 +189,7 @@ static int erofs_read_superblock(struct super_block *sb) } ret = 0; out: - kunmap(page); + kunmap_thread(page); put_page(page); return ret; } diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c index c8c381eadcd6..1771baa99d77 100644 --- a/fs/erofs/xattr.c +++ b/fs/erofs/xattr.c @@ -20,7 +20,7 @@ static inline void xattr_iter_end(struct xattr_iter *it, bool atomic) { /* the only user of kunmap() is 'init_inode_xattrs' */ if (!atomic) - kunmap(it->page); + kunmap_thread(it->page); else kunmap_atomic(it->kaddr); @@ -96,7 +96,7 @@ static int init_inode_xattrs(struct inode *inode) } /* read in shared xattr array (non-atomic, see kmalloc below) */ - it.kaddr = kmap(it.page); + it.kaddr = kmap_thread(it.page); atomic_map = false; ih = (struct erofs_xattr_ibody_header *)(it.kaddr + it.ofs); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 53/58] lib: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Alexander Viro Cc: "Jérôme Glisse" Cc: Martin KaFai Lau Cc: Song Liu Cc: Yonghong Song Cc: Andrii Nakryiko Cc: John Fastabend Cc: KP Singh Signed-off-by: Ira Weiny --- lib/iov_iter.c | 12 ++-- lib/test_bpf.c | 4 ++-- lib/test_hmm.c | 8 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 5e40786c8f12..1d47f957cf95 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -208,7 +208,7 @@ static size_t copy_page_to_iter_iovec(struct page *page, size_t offset, size_t b } /* Too bad - revert to non-atomic kmap */ - kaddr = kmap(page); + kaddr = kmap_thread(page); from = kaddr + offset; left = copyout(buf, from, copy); copy -= left; @@ -225,7 +225,7 @@ static size_t copy_page_to_iter_iovec(struct page *page, size_t offset, size_t b from += copy; bytes -= copy; } - kunmap(page); + kunmap_thread(page); done: if (skip == iov->iov_len) { @@ -292,7 +292,7 @@ static size_t copy_page_from_iter_iovec(struct page *page, size_t offset, size_t } /* Too bad - revert to non-atomic kmap */ - kaddr = kmap(page); + kaddr = kmap_thread(page); to = kaddr + offset; left = copyin(to, buf, copy); copy -= left; @@ -309,7 +309,7 @@ static size_t copy_page_from_iter_iovec(struct page *page, size_t offset, size_t to += copy; bytes -= copy; } - kunmap(page); + kunmap_thread(page); done: if (skip == iov->iov_len) { @@ -1742,10 +1742,10 @@ int iov_iter_for_each_range(struct iov_iter *i, size_t bytes, return 0; iterate_all_kinds(i, bytes, v, -EINVAL, ({ - w.iov_base = kmap(v.bv_page) + v.bv_offset; + w.iov_base = kmap_thread(v.bv_page) + v.bv_offset; w.iov_len = v.bv_len; err = f(, context); - kunmap(v.bv_page); + kunmap_thread(v.bv_page); err;}), ({ w = v; err = f(, context);}) diff --git a/lib/test_bpf.c b/lib/test_bpf.c index ca7d635bccd9..441f822f56ba 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -6506,11 +6506,11 @@ static void *generate_test_data(struct bpf_test *test, int sub) if (!page) goto err_kfree_skb; - ptr = kmap(page); + ptr = kmap_thread(page); if (!ptr) goto err_free_page; memcpy(ptr, test->frag_data, MAX_DATA); - kunmap(page); + kunmap_thread(page); skb_add_rx_frag(skb, 0, page, 0, MAX_DATA, MAX_DATA); } diff --git a/lib/test_hmm.c b/lib/test_hmm.c index e7dc3de355b7..e40d26f97f45 100644 --- a/lib/test_hmm.c +++ b/lib/test_hmm.c @@ -329,9 +329,9 @@ static int dmirror_do_read(struct dmirror *dmirror, unsigned long start, if (!page) return -ENOENT; - tmp = kmap(page); + tmp = kmap_thread(page); memcpy(ptr, tmp, PAGE_SIZE); - kunmap(page); + kunmap_thread(page); ptr += PAGE_SIZE; bounce->cpages++; @@ -398,9 +398,9 @@ static int dmirror_do_write(struct dmirror *dmirror, unsigned long start, if (!page || xa_pointer_tag(entry) != DPT_XA_TAG_WRITE) return -ENOENT; - tmp = kmap(page); + tmp = kmap_thread(page); memcpy(tmp, ptr, PAGE_SIZE); - kunmap(page); + kunmap_thread(page); ptr += PAGE_SIZE; bounce->cpages++; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 27/58] fs/ubifs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Richard Weinberger Signed-off-by: Ira Weiny --- fs/ubifs/file.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index b77d1637bbbc..a3537447a885 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -111,7 +111,7 @@ static int do_readpage(struct page *page) ubifs_assert(c, !PageChecked(page)); ubifs_assert(c, !PagePrivate(page)); - addr = kmap(page); + addr = kmap_thread(page); block = page->index << UBIFS_BLOCKS_PER_PAGE_SHIFT; beyond = (i_size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT; @@ -174,7 +174,7 @@ static int do_readpage(struct page *page) SetPageUptodate(page); ClearPageError(page); flush_dcache_page(page); - kunmap(page); + kunmap_thread(page); return 0; error: @@ -182,7 +182,7 @@ static int do_readpage(struct page *page) ClearPageUptodate(page); SetPageError(page); flush_dcache_page(page); - kunmap(page); + kunmap_thread(page); return err; } @@ -616,7 +616,7 @@ static int populate_page(struct ubifs_info *c, struct page *page, dbg_gen("ino %lu, pg %lu, i_size %lld, flags %#lx", inode->i_ino, page->index, i_size, page->flags); - addr = zaddr = kmap(page); + addr = zaddr = kmap_thread(page); end_index = (i_size - 1) >> PAGE_SHIFT; if (!i_size || page->index > end_index) { @@ -692,7 +692,7 @@ static int populate_page(struct ubifs_info *c, struct page *page, SetPageUptodate(page); ClearPageError(page); flush_dcache_page(page); - kunmap(page); + kunmap_thread(page); *n = nn; return 0; @@ -700,7 +700,7 @@ static int populate_page(struct ubifs_info *c, struct page *page, ClearPageUptodate(page); SetPageError(page); flush_dcache_page(page); - kunmap(page); + kunmap_thread(page); ubifs_err(c, "bad data node (block %u, inode %lu)", page_block, inode->i_ino); return -EINVAL; @@ -918,7 +918,7 @@ static int do_writepage(struct page *page, int len) /* Update radix tree tags */ set_page_writeback(page); - addr = kmap(page); + addr = kmap_thread(page); block = page->index << UBIFS_BLOCKS_PER_PAGE_SHIFT; i = 0; while (len) { @@ -950,7 +950,7 @@ static int do_writepage(struct page *page, int len) ClearPagePrivate(page); ClearPageChecked(page); - kunmap(page); + kunmap_thread(page); unlock_page(page); end_page_writeback(page); return err; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 46/58] drives/staging: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Greg Kroah-Hartman Signed-off-by: Ira Weiny --- drivers/staging/rts5208/rtsx_transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index 0027bcf638ad..f747cc23951b 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -92,13 +92,13 @@ unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, while (sglen > 0) { unsigned int plen = min(sglen, (unsigned int) PAGE_SIZE - poff); - unsigned char *ptr = kmap(page); + unsigned char *ptr = kmap_thread(page); if (dir == TO_XFER_BUF) memcpy(ptr + poff, buffer + cnt, plen); else memcpy(buffer + cnt, ptr + poff, plen); - kunmap(page); + kunmap_thread(page); /* Start at the beginning of the next page */ poff = 0; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 49/58] drivers/misc: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Greg Kroah-Hartman Signed-off-by: Ira Weiny --- drivers/misc/vmw_vmci/vmci_queue_pair.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c index 8531ae781195..f308abb8ad03 100644 --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -343,7 +343,7 @@ static int qp_memcpy_to_queue_iter(struct vmci_queue *queue, size_t to_copy; if (kernel_if->host) - va = kmap(kernel_if->u.h.page[page_index]); + va = kmap_thread(kernel_if->u.h.page[page_index]); else va = kernel_if->u.g.vas[page_index + 1]; /* Skip header. */ @@ -357,12 +357,12 @@ static int qp_memcpy_to_queue_iter(struct vmci_queue *queue, if (!copy_from_iter_full((u8 *)va + page_offset, to_copy, from)) { if (kernel_if->host) - kunmap(kernel_if->u.h.page[page_index]); + kunmap_thread(kernel_if->u.h.page[page_index]); return VMCI_ERROR_INVALID_ARGS; } bytes_copied += to_copy; if (kernel_if->host) - kunmap(kernel_if->u.h.page[page_index]); + kunmap_thread(kernel_if->u.h.page[page_index]); } return VMCI_SUCCESS; @@ -391,7 +391,7 @@ static int qp_memcpy_from_queue_iter(struct iov_iter *to, int err; if (kernel_if->host) - va = kmap(kernel_if->u.h.page[page_index]); + va = kmap_thread(kernel_if->u.h.page[page_index]); else va = kernel_if->u.g.vas[page_index + 1]; /* Skip header. */ @@ -405,12 +405,12 @@ static int qp_memcpy_from_queue_iter(struct iov_iter *to, err = copy_to_iter((u8 *)va + page_offset, to_copy, to); if (err != to_copy) { if (kernel_if->host) - kunmap(kernel_if->u.h.page[page_index]); + kunmap_thread(kernel_if->u.h.page[page_index]); return VMCI_ERROR_INVALID_ARGS; } bytes_copied += to_copy; if (kernel_if->host) - kunmap(kernel_if->u.h.page[page_index]); + kunmap_thread(kernel_if->u.h.page[page_index]); } return VMCI_SUCCESS; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 48/58] drivers/md: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Coly Li (maintainer:BCACHE (BLOCK LAYER CACHE)) Cc: Kent Overstreet (maintainer:BCACHE (BLOCK LAYER CACHE)) Signed-off-by: Ira Weiny --- drivers/md/bcache/request.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index c7cadaafa947..a4571f6d09dd 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -44,10 +44,10 @@ static void bio_csum(struct bio *bio, struct bkey *k) uint64_t csum = 0; bio_for_each_segment(bv, bio, iter) { - void *d = kmap(bv.bv_page) + bv.bv_offset; + void *d = kmap_thread(bv.bv_page) + bv.bv_offset; csum = bch_crc64_update(csum, d, bv.bv_len); - kunmap(bv.bv_page); + kunmap_thread(bv.bv_page); } k->ptr[KEY_PTRS(k)] = csum & (~0ULL >> 1); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 30/58] fs/romfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Signed-off-by: Ira Weiny --- fs/romfs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/romfs/super.c b/fs/romfs/super.c index e582d001f792..9050074c6755 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c @@ -107,7 +107,7 @@ static int romfs_readpage(struct file *file, struct page *page) void *buf; int ret; - buf = kmap(page); + buf = kmap_thread(page); if (!buf) return -ENOMEM; @@ -136,7 +136,7 @@ static int romfs_readpage(struct file *file, struct page *page) SetPageUptodate(page); flush_dcache_page(page); - kunmap(page); + kunmap_thread(page); unlock_page(page); return ret; } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 44/58] drivers/xen: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Stefano Stabellini Signed-off-by: Ira Weiny --- drivers/xen/gntalloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c index 3fa40c723e8e..3b78e055feff 100644 --- a/drivers/xen/gntalloc.c +++ b/drivers/xen/gntalloc.c @@ -184,9 +184,9 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op, static void __del_gref(struct gntalloc_gref *gref) { if (gref->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { - uint8_t *tmp = kmap(gref->page); + uint8_t *tmp = kmap_thread(gref->page); tmp[gref->notify.pgoff] = 0; - kunmap(gref->page); + kunmap_thread(gref->page); } if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { notify_remote_via_evtchn(gref->notify.event); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 41/58] drivers/target: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls in this driver are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Signed-off-by: Ira Weiny --- drivers/target/target_core_iblock.c| 4 ++-- drivers/target/target_core_rd.c| 4 ++-- drivers/target/target_core_transport.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 1c181d31f4c8..df7b1568edb3 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -415,7 +415,7 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) unsigned char *buf, *not_zero; int ret; - buf = kmap(sg_page(sg)) + sg->offset; + buf = kmap_thread(sg_page(sg)) + sg->offset; if (!buf) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; /* @@ -423,7 +423,7 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) * incoming WRITE_SAME payload does not contain zeros. */ not_zero = memchr_inv(buf, 0x00, cmd->data_length); - kunmap(sg_page(sg)); + kunmap_thread(sg_page(sg)); if (not_zero) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 408bd975170b..dbbdd39c5bf9 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -159,9 +159,9 @@ static int rd_allocate_sgl_table(struct rd_dev *rd_dev, struct rd_dev_sg_table * sg_assign_page([j], pg); sg[j].length = PAGE_SIZE; - p = kmap(pg); + p = kmap_thread(pg); memset(p, init_payload, PAGE_SIZE); - kunmap(pg); + kunmap_thread(pg); } page_offset += sg_per_table; diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ff26ab0a5f60..8d0bae5a92e5 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1692,11 +1692,11 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess unsigned char *buf = NULL; if (sgl) - buf = kmap(sg_page(sgl)) + sgl->offset; + buf = kmap_thread(sg_page(sgl)) + sgl->offset; if (buf) { memset(buf, 0, sgl->length); - kunmap(sg_page(sgl)); + kunmap_thread(sg_page(sgl)); } } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 36/58] fs/ext2: Use ext2_put_page
From: Ira Weiny There are 3 places in namei.c where the equivalent of ext2_put_page() is open coded. We want to use k[un]map_thread() instead of k[un]map() in ext2_[get|put]_page(). Move ext2_put_page() to ext2.h and use it in namei.c in prep for converting the k[un]map() code. Cc: Jan Kara Signed-off-by: Ira Weiny --- fs/ext2/dir.c | 6 -- fs/ext2/ext2.h | 8 fs/ext2/namei.c | 15 +-- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 70355ab6740e..f3194bf20733 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -66,12 +66,6 @@ static inline unsigned ext2_chunk_size(struct inode *inode) return inode->i_sb->s_blocksize; } -static inline void ext2_put_page(struct page *page) -{ - kunmap(page); - put_page(page); -} - /* * Return the offset into page `page_nr' of the last valid * byte in that page, plus one. diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 5136b7289e8d..021ec8b42ac3 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -16,6 +16,8 @@ #include #include #include +#include +#include /* XXX Here for now... not interested in restructing headers JUST now */ @@ -745,6 +747,12 @@ extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *); extern int ext2_empty_dir (struct inode *); extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **); extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int); +static inline void ext2_put_page(struct page *page) +{ + kunmap(page); + put_page(page); +} + /* ialloc.c */ extern struct inode * ext2_new_inode (struct inode *, umode_t, const struct qstr *); diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 5bf2c145643b..ea980f1e2e99 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -389,23 +389,18 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, if (dir_de) { if (old_dir != new_dir) ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0); - else { - kunmap(dir_page); - put_page(dir_page); - } + else + ext2_put_page(dir_page); inode_dec_link_count(old_dir); } return 0; out_dir: - if (dir_de) { - kunmap(dir_page); - put_page(dir_page); - } + if (dir_de) + ext2_put_page(dir_page); out_old: - kunmap(old_page); - put_page(old_page); + ext2_put_page(old_page); out: return err; } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 29/58] fs/ntfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Anton Altaparmakov Signed-off-by: Ira Weiny --- fs/ntfs/aops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index bb0a43860ad2..11633d732809 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -1099,7 +1099,7 @@ static int ntfs_write_mst_block(struct page *page, if (!nr_bhs) goto done; /* Map the page so we can access its contents. */ - kaddr = kmap(page); + kaddr = kmap_thread(page); /* Clear the page uptodate flag whilst the mst fixups are applied. */ BUG_ON(!PageUptodate(page)); ClearPageUptodate(page); @@ -1276,7 +1276,7 @@ static int ntfs_write_mst_block(struct page *page, iput(VFS_I(base_tni)); } SetPageUptodate(page); - kunmap(page); + kunmap_thread(page); done: if (unlikely(err && err != -ENOMEM)) { /* -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 40/58] net: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls in these drivers are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Alexey Kuznetsov Cc: Hideaki YOSHIFUJI Cc: Trond Myklebust Cc: Anna Schumaker Cc: Boris Pismenny Cc: Aviad Yehezkel Cc: John Fastabend Cc: Daniel Borkmann Signed-off-by: Ira Weiny --- net/ceph/messenger.c | 4 ++-- net/core/datagram.c | 4 ++-- net/core/sock.c | 8 net/ipv4/ip_output.c | 4 ++-- net/sunrpc/cache.c | 4 ++-- net/sunrpc/xdr.c | 8 net/tls/tls_device.c | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index d4d7a0e52491..0c49b8e333da 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1535,10 +1535,10 @@ static u32 ceph_crc32c_page(u32 crc, struct page *page, { char *kaddr; - kaddr = kmap(page); + kaddr = kmap_thread(page); BUG_ON(kaddr == NULL); crc = crc32c(crc, kaddr + page_offset, length); - kunmap(page); + kunmap_thread(page); return crc; } diff --git a/net/core/datagram.c b/net/core/datagram.c index 639745d4f3b9..cbd0a343074a 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -441,14 +441,14 @@ static int __skb_datagram_iter(const struct sk_buff *skb, int offset, end = start + skb_frag_size(frag); if ((copy = end - offset) > 0) { struct page *page = skb_frag_page(frag); - u8 *vaddr = kmap(page); + u8 *vaddr = kmap_thread(page); if (copy > len) copy = len; n = INDIRECT_CALL_1(cb, simple_copy_to_iter, vaddr + skb_frag_off(frag) + offset - start, copy, data, to); - kunmap(page); + kunmap_thread(page); offset += n; if (n != copy) goto short_copy; diff --git a/net/core/sock.c b/net/core/sock.c index 6c5c6b18eff4..9b46a75cd8c1 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2846,11 +2846,11 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, siz ssize_t res; struct msghdr msg = {.msg_flags = flags}; struct kvec iov; - char *kaddr = kmap(page); + char *kaddr = kmap_thread(page); iov.iov_base = kaddr + offset; iov.iov_len = size; res = kernel_sendmsg(sock, , , 1, size); - kunmap(page); + kunmap_thread(page); return res; } EXPORT_SYMBOL(sock_no_sendpage); @@ -2861,12 +2861,12 @@ ssize_t sock_no_sendpage_locked(struct sock *sk, struct page *page, ssize_t res; struct msghdr msg = {.msg_flags = flags}; struct kvec iov; - char *kaddr = kmap(page); + char *kaddr = kmap_thread(page); iov.iov_base = kaddr + offset; iov.iov_len = size; res = kernel_sendmsg_locked(sk, , , 1, size); - kunmap(page); + kunmap_thread(page); return res; } EXPORT_SYMBOL(sock_no_sendpage_locked); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index e6f2ada9e7d5..05304fb251a4 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -949,9 +949,9 @@ csum_page(struct page *page, int offset, int copy) { char *kaddr; __wsum csum; - kaddr = kmap(page); + kaddr = kmap_thread(page); csum = csum_partial(kaddr + offset, copy, 0); - kunmap(page); + kunmap_thread(page); return csum; } diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index baef5ee43dbb..88193f2a8e6f 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -935,9 +935,9 @@ static ssize_t cache_downcall(struct address_space *mapping, if (!page) goto out_slow; - kaddr = kmap(page); + kaddr = kmap_thread(page); ret = cache_do_downcall(kaddr, buf, count, cd); - kunmap(page); + kunmap_thread(page); unlock_page(page); put_page(page); return ret; diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index be11d672b5b9..00afbb48fb0a 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -1353,7 +1353,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base, base &= ~PAGE_MASK; avail_page = min_t(unsigned int, PAGE_SIZE - base, avail_here); - c = kmap(*ppages) + base; + c = kmap_thread(*ppages) + base; while (avail_here) { avail_here -= avail_page; @@ -1429,9 +1429,9 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base, } }
[PATCH RFC PKS/PMEM 24/58] fs/freevxfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Christoph Hellwig Signed-off-by: Ira Weiny --- fs/freevxfs/vxfs_immed.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c index bfc780c682fb..9c42fec4cd85 100644 --- a/fs/freevxfs/vxfs_immed.c +++ b/fs/freevxfs/vxfs_immed.c @@ -69,9 +69,9 @@ vxfs_immed_readpage(struct file *fp, struct page *pp) u_int64_t offset = (u_int64_t)pp->index << PAGE_SHIFT; caddr_t kaddr; - kaddr = kmap(pp); + kaddr = kmap_thread(pp); memcpy(kaddr, vip->vii_immed.vi_immed + offset, PAGE_SIZE); - kunmap(pp); + kunmap_thread(pp); flush_dcache_page(pp); SetPageUptodate(pp); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 39/58] fs/jffs2: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Signed-off-by: Ira Weiny --- fs/jffs2/file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 3e6d54f9b011..14dd2b18cc16 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -287,13 +287,13 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, /* In 2.4, it was already kmapped by generic_file_write(). Doesn't hurt to do it again. The alternative is ifdefs, which are ugly. */ - kmap(pg); + kmap_thread(pg); ret = jffs2_write_inode_range(c, f, ri, page_address(pg) + aligned_start, (pg->index << PAGE_SHIFT) + aligned_start, end - aligned_start, ); - kunmap(pg); + kunmap_thread(pg); if (ret) { /* There was an error writing. */ -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 28/58] fs/cachefiles: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: David Howells Signed-off-by: Ira Weiny --- fs/cachefiles/rdwr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 3080cda9e824..2468e5c067ba 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -936,9 +936,9 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) } } - data = kmap(page); + data = kmap_thread(page); ret = kernel_write(file, data, len, ); - kunmap(page); + kunmap_thread(page); fput(file); if (ret != len) goto error_eio; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 26/58] fs/zonefs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Damien Le Moal Cc: Naohiro Aota Signed-off-by: Ira Weiny --- fs/zonefs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 8ec7c8f109d7..2fd6c86beee1 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -1297,7 +1297,7 @@ static int zonefs_read_super(struct super_block *sb) if (ret) goto free_page; - super = kmap(page); + super = kmap_thread(page); ret = -EINVAL; if (le32_to_cpu(super->s_magic) != ZONEFS_MAGIC) @@ -1349,7 +1349,7 @@ static int zonefs_read_super(struct super_block *sb) ret = 0; unmap: - kunmap(page); + kunmap_thread(page); free_page: __free_page(page); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 35/58] fs: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Alexander Viro Cc: Jens Axboe Signed-off-by: Ira Weiny --- fs/aio.c | 4 ++-- fs/binfmt_elf.c | 4 ++-- fs/binfmt_elf_fdpic.c | 4 ++-- fs/exec.c | 10 +- fs/io_uring.c | 4 ++-- fs/splice.c | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index d5ec30385566..27f95996d25f 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1223,10 +1223,10 @@ static long aio_read_events_ring(struct kioctx *ctx, avail = min(avail, nr - ret); avail = min_t(long, avail, AIO_EVENTS_PER_PAGE - pos); - ev = kmap(page); + ev = kmap_thread(page); copy_ret = copy_to_user(event + ret, ev + pos, sizeof(*ev) * avail); - kunmap(page); + kunmap_thread(page); if (unlikely(copy_ret)) { ret = -EFAULT; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 13d053982dd7..1a332ef1ae03 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -2430,9 +2430,9 @@ static int elf_core_dump(struct coredump_params *cprm) page = get_dump_page(addr); if (page) { - void *kaddr = kmap(page); + void *kaddr = kmap_thread(page); stop = !dump_emit(cprm, kaddr, PAGE_SIZE); - kunmap(page); + kunmap_thread(page); put_page(page); } else stop = !dump_skip(cprm, PAGE_SIZE); diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 50f845702b92..8fbe188e0fdd 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -1542,9 +1542,9 @@ static bool elf_fdpic_dump_segments(struct coredump_params *cprm) bool res; struct page *page = get_dump_page(addr); if (page) { - void *kaddr = kmap(page); + void *kaddr = kmap_thread(page); res = dump_emit(cprm, kaddr, PAGE_SIZE); - kunmap(page); + kunmap_thread(page); put_page(page); } else { res = dump_skip(cprm, PAGE_SIZE); diff --git a/fs/exec.c b/fs/exec.c index a91003e28eaa..3948b8511e3a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -575,11 +575,11 @@ static int copy_strings(int argc, struct user_arg_ptr argv, if (kmapped_page) { flush_kernel_dcache_page(kmapped_page); - kunmap(kmapped_page); + kunmap_thread(kmapped_page); put_arg_page(kmapped_page); } kmapped_page = page; - kaddr = kmap(kmapped_page); + kaddr = kmap_thread(kmapped_page); kpos = pos & PAGE_MASK; flush_arg_page(bprm, kpos, kmapped_page); } @@ -593,7 +593,7 @@ static int copy_strings(int argc, struct user_arg_ptr argv, out: if (kmapped_page) { flush_kernel_dcache_page(kmapped_page); - kunmap(kmapped_page); + kunmap_thread(kmapped_page); put_arg_page(kmapped_page); } return ret; @@ -871,11 +871,11 @@ int transfer_args_to_stack(struct linux_binprm *bprm, for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0; - char *src = kmap(bprm->page[index]) + offset; + char *src = kmap_thread(bprm->page[index]) + offset; sp -= PAGE_SIZE - offset; if (copy_to_user((void *) sp, src, PAGE_SIZE - offset) != 0) ret = -EFAULT; - kunmap(bprm->page[index]); + kunmap_thread(bprm->page[index]); if (ret) goto out; } diff --git a/fs/io_uring.c b/fs/io_uring.c index aae0ef2ec34d..f59bb079822d 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2903,7 +2903,7 @@ static ssize_t loop_rw_iter(int rw, struct file *file, struct kiocb *kiocb, iovec = iov_iter_iovec(iter); } else { /* fixed buffers import bvec */ - iovec.iov_base =
[PATCH RFC PKS/PMEM 32/58] fs/hostfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Jeff Dike Cc: Richard Weinberger Cc: Anton Ivanov Signed-off-by: Ira Weiny --- fs/hostfs/hostfs_kern.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index c070c0d8e3e9..608efd0f83cb 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -409,7 +409,7 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc) if (page->index >= end_index) count = inode->i_size & (PAGE_SIZE-1); - buffer = kmap(page); + buffer = kmap_thread(page); err = write_file(HOSTFS_I(inode)->fd, , buffer, count); if (err != count) { @@ -425,7 +425,7 @@ static int hostfs_writepage(struct page *page, struct writeback_control *wbc) err = 0; out: - kunmap(page); + kunmap_thread(page); unlock_page(page); return err; @@ -437,7 +437,7 @@ static int hostfs_readpage(struct file *file, struct page *page) loff_t start = page_offset(page); int bytes_read, ret = 0; - buffer = kmap(page); + buffer = kmap_thread(page); bytes_read = read_file(FILE_HOSTFS_I(file)->fd, , buffer, PAGE_SIZE); if (bytes_read < 0) { @@ -454,7 +454,7 @@ static int hostfs_readpage(struct file *file, struct page *page) out: flush_dcache_page(page); - kunmap(page); + kunmap_thread(page); unlock_page(page); return ret; } @@ -480,9 +480,9 @@ static int hostfs_write_end(struct file *file, struct address_space *mapping, unsigned from = pos & (PAGE_SIZE - 1); int err; - buffer = kmap(page); + buffer = kmap_thread(page); err = write_file(FILE_HOSTFS_I(file)->fd, , buffer + from, copied); - kunmap(page); + kunmap_thread(page); if (!PageUptodate(page) && err == PAGE_SIZE) SetPageUptodate(page); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 18/58] fs/hfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Signed-off-by: Ira Weiny --- fs/hfs/bnode.c | 14 +++--- fs/hfs/btree.c | 20 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index b63a4df7327b..8b4d02576405 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -23,8 +23,8 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf, off += node->page_offset; page = node->page[0]; - memcpy(buf, kmap(page) + off, len); - kunmap(page); + memcpy(buf, kmap_thread(page) + off, len); + kunmap_thread(page); } u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off) @@ -108,9 +108,9 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, src_page = src_node->page[0]; dst_page = dst_node->page[0]; - memcpy(kmap(dst_page) + dst, kmap(src_page) + src, len); - kunmap(src_page); - kunmap(dst_page); + memcpy(kmap_thread(dst_page) + dst, kmap_thread(src_page) + src, len); + kunmap_thread(src_page); + kunmap_thread(dst_page); set_page_dirty(dst_page); } @@ -125,9 +125,9 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) src += node->page_offset; dst += node->page_offset; page = node->page[0]; - ptr = kmap(page); + ptr = kmap_thread(page); memmove(ptr + dst, ptr + src, len); - kunmap(page); + kunmap_thread(page); set_page_dirty(page); } diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 19017d296173..bd4a6d35e361 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c @@ -80,7 +80,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke goto free_inode; /* Load the header */ - head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc)); + head = (struct hfs_btree_header_rec *)(kmap_thread(page) + sizeof(struct hfs_bnode_desc)); tree->root = be32_to_cpu(head->root); tree->leaf_count = be32_to_cpu(head->leaf_count); tree->leaf_head = be32_to_cpu(head->leaf_head); @@ -119,7 +119,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke tree->node_size_shift = ffs(size) - 1; tree->pages_per_bnode = (tree->node_size + PAGE_SIZE - 1) >> PAGE_SHIFT; - kunmap(page); + kunmap_thread(page); put_page(page); return tree; @@ -268,7 +268,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) off += node->page_offset; pagep = node->page + (off >> PAGE_SHIFT); - data = kmap(*pagep); + data = kmap_thread(*pagep); off &= ~PAGE_MASK; idx = 0; @@ -281,7 +281,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) idx += i; data[off] |= m; set_page_dirty(*pagep); - kunmap(*pagep); + kunmap_thread(*pagep); tree->free_nodes--; mark_inode_dirty(tree->inode); hfs_bnode_put(node); @@ -290,14 +290,14 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) } } if (++off >= PAGE_SIZE) { - kunmap(*pagep); - data = kmap(*++pagep); + kunmap_thread(*pagep); + data = kmap_thread(*++pagep); off = 0; } idx += 8; len--; } - kunmap(*pagep); + kunmap_thread(*pagep); nidx = node->next; if (!nidx) { printk(KERN_DEBUG "create new bmap node...\n"); @@ -313,7 +313,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) off = off16; off += node->page_offset; pagep = node->page + (off >> PAGE_SHIFT); - data = kmap(*pagep); + data = kmap_thread(*pagep); off &= ~PAGE_MASK; } } @@ -360,7 +360,7 @@ void hfs_bmap_free(struct hfs_bnode *node) } off += node->page_offset + nidx / 8; page = node->page[off >> PAGE_SHIFT]; - data = kmap(page); + data = kmap_thread(page); off &= ~PAGE_MASK; m = 1 << (~nidx & 7); byte = data[off]; @@ -373,7 +373,7 @@ void hfs_bmap_free(struct hfs_bnode *node) }
[PATCH RFC PKS/PMEM 16/58] fs/gfs2: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Bob Peterson Cc: Andreas Gruenbacher Signed-off-by: Ira Weiny --- fs/gfs2/bmap.c | 4 ++-- fs/gfs2/ops_fstype.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 0f69fbd4af66..375af4528411 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -67,7 +67,7 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, } if (!PageUptodate(page)) { - void *kaddr = kmap(page); + void *kaddr = kmap_thread(page); u64 dsize = i_size_read(inode); if (dsize > gfs2_max_stuffed_size(ip)) @@ -75,7 +75,7 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize); memset(kaddr + dsize, 0, PAGE_SIZE - dsize); - kunmap(page); + kunmap_thread(page); SetPageUptodate(page); } diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 6d18d2c91add..a5d20d9b504a 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -263,9 +263,9 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector, int silent) __free_page(page); return -EIO; } - p = kmap(page); + p = kmap_thread(page); gfs2_sb_in(sdp, p); - kunmap(page); + kunmap_thread(page); __free_page(page); return gfs2_check_sb(sdp, silent); } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 25/58] fs/reiserfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Jan Kara Cc: "Theodore Ts'o" Cc: Randy Dunlap Cc: Alex Shi Signed-off-by: Ira Weiny --- fs/reiserfs/journal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index e98f99338f8f..be8f56261e8c 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -4194,11 +4194,11 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, int flags) SB_ONDISK_JOURNAL_SIZE(sb))); set_buffer_uptodate(tmp_bh); page = cn->bh->b_page; - addr = kmap(page); + addr = kmap_thread(page); memcpy(tmp_bh->b_data, addr + offset_in_page(cn->bh->b_data), cn->bh->b_size); - kunmap(page); + kunmap_thread(page); mark_buffer_dirty(tmp_bh); jindex++; set_buffer_journal_dirty(cn->bh); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 03/58] memremap: Add zone device access protection
From: Ira Weiny Device managed memory exposes itself to the kernel direct map which allows stray pointers to access these device memories. Stray pointers to normal memory may result in a crash or other undesirable behavior which, while unfortunate, are usually recoverable with a reboot. Stray access, specifically stray writes, to areas such as non-volatile memory are permanent in nature and thus are more likely to result in permanent user data loss vs stray access to other memory areas. Furthermore, we protect against reads which can help with speculative reads to poison areas as well. But this is a secondary reason. Set up an infrastructure for extra device access protection. Then implement the new protection using the new Protection Keys Supervisor (PKS) on architectures which support it. To enable this extra protection devices specify a flag in the pgmap to indicate that these areas wish to use additional protection. Kernel code which intends to access this memory can do so automatically through the use of the kmap infrastructure calling into dev_access_[enable|disable]() described here. The kmap infrastructure is implemented in a follow on patch. In addition, users can directly enable/disable the access through dev_access_[enable|disable]() if they have a priori knowledge of the type of pages they are accessing. All calls to enable/disable protection flow through dev_access_[enable|disable]() and are nestable by the use of a per task reference count. This reference count does 2 things. 1) Allows a thread to nest calls to disable protection such that the first call to re-enable protection does not 'break' the last access of the pmem device memory. 2) Provides faster performance by avoiding lots of MSR writes. For example, looping over a sequence of pmem pages. In addition, we must ensure the reference count is preserved through an exception so we add the count to irqentry_state_t and save/restore the reference count while giving exceptions their own count should they use a kmap call. The following shows how this works through an exception: ... // ref == 0 dev_access_enable() // ref += 1 ==> disable protection irq() // enable protection // ref = 0 _handler() dev_access_enable() // ref += 1 ==> disable protection dev_access_disable() // ref -= 1 ==> enable protection // WARN_ON(ref != 0) // disable protection do_pmem_thing() // all good here dev_access_disable() // ref -= 1 ==> 0 ==> enable protection ... Nested exceptions operate the same way with each exception storing the interrupted exception state all the way down. The pkey value is never free'ed as this optimizes the implementation to be either on or off using a static branch conditional in the fast paths. Cc: Juri Lelli Cc: Vincent Guittot Cc: Dietmar Eggemann Cc: Steven Rostedt Cc: Ben Segall Cc: Mel Gorman Signed-off-by: Ira Weiny --- arch/x86/entry/common.c | 21 + include/linux/entry-common.h | 3 ++ include/linux/memremap.h | 1 + include/linux/mm.h | 43 + include/linux/sched.h| 3 ++ init/init_task.c | 3 ++ kernel/fork.c| 3 ++ mm/Kconfig | 13 ++ mm/memremap.c| 90 9 files changed, 180 insertions(+) diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 86ad32e0095e..3680724c1a4d 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -264,12 +264,27 @@ noinstr void idtentry_exit_nmi(struct pt_regs *regs, irqentry_state_t *irq_state * * NOTE That the thread saved PKRS must be preserved separately to ensure * global overrides do not 'stick' on a thread. + * + * Furthermore, Zone Device Access Protection maintains access in a re-entrant + * manner through a reference count which also needs to be maintained should + * exception handlers use those interfaces for memory access. Here we start + * off the exception handler ref count to 0 and ensure it is 0 when the + * exception is done. Then restore it for the interrupted task. */ noinstr void irq_save_pkrs(irqentry_state_t *state) { if (!cpu_feature_enabled(X86_FEATURE_PKS)) return; +#ifdef CONFIG_ZONE_DEVICE_ACCESS_PROTECTION + /* +* Save the ref count of the current running process and set it to 0 +* for any irq users to properly track re-entrance +*/ + state->pkrs_ref = current->dev_page_access_ref; + current->dev_page_access_ref = 0; +#endif + /* * The thread_pkrs must be maintained separately to prevent global * overrides from 'sticking' on a thread. @@ -286,6 +301,12 @@
[PATCH RFC PKS/PMEM 14/58] fs/cifs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Steve French Signed-off-by: Ira Weiny --- fs/cifs/cifsencrypt.c | 6 +++--- fs/cifs/file.c| 16 fs/cifs/smb2ops.c | 8 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 9daa256f69d4..2f8232d01a56 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -82,17 +82,17 @@ int __cifs_calc_signature(struct smb_rqst *rqst, rqst_page_get_length(rqst, i, , ); - kaddr = (char *) kmap(rqst->rq_pages[i]) + offset; + kaddr = (char *) kmap_thread(rqst->rq_pages[i]) + offset; rc = crypto_shash_update(shash, kaddr, len); if (rc) { cifs_dbg(VFS, "%s: Could not update with payload\n", __func__); - kunmap(rqst->rq_pages[i]); + kunmap_thread(rqst->rq_pages[i]); return rc; } - kunmap(rqst->rq_pages[i]); + kunmap_thread(rqst->rq_pages[i]); } rc = crypto_shash_final(shash, signature); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index be46fab4c96d..6db2caab8852 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2145,17 +2145,17 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) inode = page->mapping->host; offset += (loff_t)from; - write_data = kmap(page); + write_data = kmap_thread(page); write_data += from; if ((to > PAGE_SIZE) || (from > to)) { - kunmap(page); + kunmap_thread(page); return -EIO; } /* racing with truncate? */ if (offset > mapping->host->i_size) { - kunmap(page); + kunmap_thread(page); return 0; /* don't care */ } @@ -2183,7 +2183,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) rc = -EIO; } - kunmap(page); + kunmap_thread(page); return rc; } @@ -2559,10 +2559,10 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, known which we might as well leverage */ /* BB check if anything else missing out of ppw such as updating last write time */ - page_data = kmap(page); + page_data = kmap_thread(page); rc = cifs_write(cfile, pid, page_data + offset, copied, ); /* if (rc < 0) should we set writebehind rc? */ - kunmap(page); + kunmap_thread(page); free_xid(xid); } else { @@ -4511,7 +4511,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, if (rc == 0) goto read_complete; - read_data = kmap(page); + read_data = kmap_thread(page); /* for reads over a certain size could initiate async read ahead */ rc = cifs_read(file, read_data, PAGE_SIZE, poffset); @@ -4540,7 +4540,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, rc = 0; io_error: - kunmap(page); + kunmap_thread(page); unlock_page(page); read_complete: diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 32f90dc82c84..a3e7ebab38b6 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4068,12 +4068,12 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst, rqst_page_get_length(_rq[i], j, , ); - dst = (char *) kmap(new_rq[i].rq_pages[j]) + offset; - src = (char *) kmap(old_rq[i - 1].rq_pages[j]) + offset; + dst = (char *) kmap_thread(new_rq[i].rq_pages[j]) + offset; + src = (char *) kmap_thread(old_rq[i - 1].rq_pages[j]) + offset; memcpy(dst, src, len); - kunmap(new_rq[i].rq_pages[j]); - kunmap(old_rq[i - 1].rq_pages[j]); + kunmap_thread(new_rq[i].rq_pages[j]); + kunmap_thread(old_rq[i - 1].rq_pages[j]); } } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 19/58] fs/hfsplus: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Signed-off-by: Ira Weiny --- fs/hfsplus/bitmap.c | 20 - fs/hfsplus/bnode.c | 102 ++-- fs/hfsplus/btree.c | 18 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index cebce0cfe340..9ec7c1559a0c 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c @@ -39,7 +39,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, start = size; goto out; } - pptr = kmap(page); + pptr = kmap_thread(page); curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; i = offset % 32; offset &= ~(PAGE_CACHE_BITS - 1); @@ -74,7 +74,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, } curr++; } - kunmap(page); + kunmap_thread(page); offset += PAGE_CACHE_BITS; if (offset >= size) break; @@ -84,7 +84,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, start = size; goto out; } - curr = pptr = kmap(page); + curr = pptr = kmap_thread(page); if ((size ^ offset) / PAGE_CACHE_BITS) end = pptr + PAGE_CACHE_BITS / 32; else @@ -127,7 +127,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, len -= 32; } set_page_dirty(page); - kunmap(page); + kunmap_thread(page); offset += PAGE_CACHE_BITS; page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); @@ -135,7 +135,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, start = size; goto out; } - pptr = kmap(page); + pptr = kmap_thread(page); curr = pptr; end = pptr + PAGE_CACHE_BITS / 32; } @@ -151,7 +151,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, done: *curr = cpu_to_be32(n); set_page_dirty(page); - kunmap(page); + kunmap_thread(page); *max = offset + (curr - pptr) * 32 + i - start; sbi->free_blocks -= *max; hfsplus_mark_mdb_dirty(sb); @@ -185,7 +185,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) page = read_mapping_page(mapping, pnr, NULL); if (IS_ERR(page)) goto kaboom; - pptr = kmap(page); + pptr = kmap_thread(page); curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; end = pptr + PAGE_CACHE_BITS / 32; len = count; @@ -215,11 +215,11 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) if (!count) break; set_page_dirty(page); - kunmap(page); + kunmap_thread(page); page = read_mapping_page(mapping, ++pnr, NULL); if (IS_ERR(page)) goto kaboom; - pptr = kmap(page); + pptr = kmap_thread(page); curr = pptr; end = pptr + PAGE_CACHE_BITS / 32; } @@ -231,7 +231,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) } out: set_page_dirty(page); - kunmap(page); + kunmap_thread(page); sbi->free_blocks += len; hfsplus_mark_mdb_dirty(sb); mutex_unlock(>alloc_mutex); diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 177fae4e6581..62757d92fbbd 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -29,14 +29,14 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) off &= ~PAGE_MASK; l = min_t(int, len, PAGE_SIZE - off); - memcpy(buf, kmap(*pagep) + off, l); - kunmap(*pagep); + memcpy(buf, kmap_thread(*pagep) + off, l); + kunmap_thread(*pagep); while ((len -= l) != 0) { buf += l; l = min_t(int, len, PAGE_SIZE); - memcpy(buf, kmap(*++pagep), l); - kunmap(*pagep); + memcpy(buf, kmap_thread(*++pagep), l); + kunmap_thread(*pagep); } } @@ -82,16 +82,16 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len) off &= ~PAGE_MASK; l = min_t(int, len, PAGE_SIZE - off); - memcpy(kmap(*pagep) + off, buf, l); + memcpy(kmap_thread(*pagep) + off, buf, l); set_page_dirty(*pagep); - kunmap(*pagep); +
[PATCH RFC PKS/PMEM 22/58] fs/f2fs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Jaegeuk Kim Cc: Chao Yu Signed-off-by: Ira Weiny --- fs/f2fs/f2fs.h | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d9e52a7f3702..ff72a45a577e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2410,12 +2410,12 @@ static inline struct page *f2fs_pagecache_get_page( static inline void f2fs_copy_page(struct page *src, struct page *dst) { - char *src_kaddr = kmap(src); - char *dst_kaddr = kmap(dst); + char *src_kaddr = kmap_thread(src); + char *dst_kaddr = kmap_thread(dst); memcpy(dst_kaddr, src_kaddr, PAGE_SIZE); - kunmap(dst); - kunmap(src); + kunmap_thread(dst); + kunmap_thread(src); } static inline void f2fs_put_page(struct page *page, int unlock) -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 15/58] fs/ecryptfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Herbert Xu Cc: Eric Biggers Cc: Aditya Pakki Signed-off-by: Ira Weiny --- fs/ecryptfs/crypto.c | 8 fs/ecryptfs/read_write.c | 8 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 0681540c48d9..e73e00994bee 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -469,10 +469,10 @@ int ecryptfs_encrypt_page(struct page *page) } lower_offset = lower_offset_for_page(crypt_stat, page); - enc_extent_virt = kmap(enc_extent_page); + enc_extent_virt = kmap_thread(enc_extent_page); rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, lower_offset, PAGE_SIZE); - kunmap(enc_extent_page); + kunmap_thread(enc_extent_page); if (rc < 0) { ecryptfs_printk(KERN_ERR, "Error attempting to write lower page; rc = [%d]\n", @@ -518,10 +518,10 @@ int ecryptfs_decrypt_page(struct page *page) BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)); lower_offset = lower_offset_for_page(crypt_stat, page); - page_virt = kmap(page); + page_virt = kmap_thread(page); rc = ecryptfs_read_lower(page_virt, lower_offset, PAGE_SIZE, ecryptfs_inode); - kunmap(page); + kunmap_thread(page); if (rc < 0) { ecryptfs_printk(KERN_ERR, "Error attempting to read lower page; rc = [%d]\n", diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 0438997ac9d8..5eca4330c0c0 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c @@ -64,11 +64,11 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, offset = loff_t)page_for_lower->index) << PAGE_SHIFT) + offset_in_page); - virt = kmap(page_for_lower); + virt = kmap_thread(page_for_lower); rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size); if (rc > 0) rc = 0; - kunmap(page_for_lower); + kunmap_thread(page_for_lower); return rc; } @@ -251,11 +251,11 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, int rc; offset = loff_t)page_index) << PAGE_SHIFT) + offset_in_page); - virt = kmap(page_for_ecryptfs); + virt = kmap_thread(page_for_ecryptfs); rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); if (rc > 0) rc = 0; - kunmap(page_for_ecryptfs); + kunmap_thread(page_for_ecryptfs); flush_dcache_page(page_for_ecryptfs); return rc; } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 06/58] kmap: Introduce k[un]map_thread debugging
From: Ira Weiny Most kmap() callers use the map within a single thread and have no need for the protection domain to be enabled globally. To differentiate these kmap users, new k[un]map_thread() calls were introduced which are thread local. To aid in debugging the new use of kmap_thread(), add a reference count, a check on that count, and tracing to ID where mapping errors occur. Cc: Juri Lelli Cc: Vincent Guittot Cc: Dietmar Eggemann Cc: Steven Rostedt Cc: Ben Segall Cc: Mel Gorman Signed-off-by: Ira Weiny --- include/linux/highmem.h| 5 +++ include/linux/sched.h | 5 +++ include/trace/events/kmap_thread.h | 56 ++ init/init_task.c | 3 ++ kernel/fork.c | 15 lib/Kconfig.debug | 8 + mm/debug.c | 23 7 files changed, 115 insertions(+) create mode 100644 include/trace/events/kmap_thread.h diff --git a/include/linux/highmem.h b/include/linux/highmem.h index ef7813544719..22d1c000802e 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -247,6 +247,10 @@ static inline void kunmap(struct page *page) __kunmap(page, true); } +#ifdef CONFIG_DEBUG_KMAP_THREAD +void *kmap_thread(struct page *page); +void kunmap_thread(struct page *page); +#else static inline void *kmap_thread(struct page *page) { return __kmap(page, false); @@ -255,6 +259,7 @@ static inline void kunmap_thread(struct page *page) { __kunmap(page, false); } +#endif /* * Prevent people trying to call kunmap_atomic() as if it were kunmap() diff --git a/include/linux/sched.h b/include/linux/sched.h index 25d97ab6c757..4627ea4a49e6 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1318,6 +1318,11 @@ struct task_struct { #ifdef CONFIG_ZONE_DEVICE_ACCESS_PROTECTION unsigned intdev_page_access_ref; #endif + +#ifdef CONFIG_DEBUG_KMAP_THREAD + unsigned intkmap_thread_cnt; +#endif + /* * New fields for task_struct should be added above here, so that * they are included in the randomized portion of task_struct. diff --git a/include/trace/events/kmap_thread.h b/include/trace/events/kmap_thread.h new file mode 100644 index ..e7143cfe0daf --- /dev/null +++ b/include/trace/events/kmap_thread.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ + +/* + * Copyright (c) 2020 Intel Corporation. All rights reserved. + * + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kmap_thread + +#if !defined(_TRACE_KMAP_THREAD_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KMAP_THREAD_H + +#include + +DECLARE_EVENT_CLASS(kmap_thread_template, + TP_PROTO(struct task_struct *tsk, struct page *page, +void *caller_addr, int cnt), + TP_ARGS(tsk, page, caller_addr, cnt), + + TP_STRUCT__entry( + __field(int, pid) + __field(struct page *, page) + __field(void *, caller_addr) + __field(int, cnt) + ), + + TP_fast_assign( + __entry->pid = tsk->pid; + __entry->page = page; + __entry->caller_addr = caller_addr; + __entry->cnt = cnt; + ), + + TP_printk("PID %d; (%d) %pS %p", + __entry->pid, + __entry->cnt, + __entry->caller_addr, + __entry->page + ) +); + +DEFINE_EVENT(kmap_thread_template, kmap_thread, + TP_PROTO(struct task_struct *tsk, struct page *page, +void *caller_addr, int cnt), + TP_ARGS(tsk, page, caller_addr, cnt)); + +DEFINE_EVENT(kmap_thread_template, kunmap_thread, + TP_PROTO(struct task_struct *tsk, struct page *page, +void *caller_addr, int cnt), + TP_ARGS(tsk, page, caller_addr, cnt)); + + +#endif /* _TRACE_KMAP_THREAD_H */ + +#include diff --git a/init/init_task.c b/init/init_task.c index 9b39f25de59b..19f09965eb34 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -212,6 +212,9 @@ struct task_struct init_task #ifdef CONFIG_ZONE_DEVICE_ACCESS_PROTECTION .dev_page_access_ref = 0, #endif +#ifdef CONFIG_DEBUG_KMAP_THREAD + .kmap_thread_cnt = 0, +#endif }; EXPORT_SYMBOL(init_task); diff --git a/kernel/fork.c b/kernel/fork.c index b6a3ee328a89..2c66e49b7614 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -722,6 +722,17 @@ static inline void put_signal_struct(struct signal_struct *sig) free_signal_struct(sig); } +#ifdef CONFIG_DEBUG_KMAP_THREAD +static void check_outstanding_kmap_thread(struct task_struct *tsk) +{ + if (tsk->kmap_thread_cnt) + pr_warn(KERN_ERR "WARNING: PID %d; Failed to kunmap_thread() [cnt %d]\n", + tsk->pid, tsk->kmap_thread_cnt); +} +#else +static void check_outstanding_kmap_thread(struct task_struct *tsk) { } +#endif +
[PATCH RFC PKS/PMEM 21/58] fs/nfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Trond Myklebust Cc: Anna Schumaker Signed-off-by: Ira Weiny --- fs/nfs/dir.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index cb52db9a0cfb..fee321acccb4 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -213,7 +213,7 @@ int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int le static int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page) { - struct nfs_cache_array *array = kmap(page); + struct nfs_cache_array *array = kmap_thread(page); struct nfs_cache_array_entry *cache_entry; int ret; @@ -235,7 +235,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page) if (entry->eof != 0) array->eof_index = array->size; out: - kunmap(page); + kunmap_thread(page); return ret; } @@ -347,7 +347,7 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) struct nfs_cache_array *array; int status; - array = kmap(desc->page); + array = kmap_thread(desc->page); if (*desc->dir_cookie == 0) status = nfs_readdir_search_for_pos(array, desc); @@ -359,7 +359,7 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) desc->current_index += array->size; desc->page_index++; } - kunmap(desc->page); + kunmap_thread(desc->page); return status; } @@ -602,10 +602,10 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en out_nopages: if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) { - array = kmap(page); + array = kmap_thread(page); array->eof_index = array->size; status = 0; - kunmap(page); + kunmap_thread(page); } put_page(scratch); @@ -669,7 +669,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, goto out; } - array = kmap(page); + array = kmap_thread(page); status = nfs_readdir_alloc_pages(pages, array_size); if (status < 0) @@ -691,7 +691,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, nfs_readdir_free_pages(pages, array_size); out_release_array: - kunmap(page); + kunmap_thread(page); nfs4_label_free(entry.label); out: nfs_free_fattr(entry.fattr); @@ -803,7 +803,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc) struct nfs_cache_array *array = NULL; struct nfs_open_dir_context *ctx = file->private_data; - array = kmap(desc->page); + array = kmap_thread(desc->page); for (i = desc->cache_entry_index; i < array->size; i++) { struct nfs_cache_array_entry *ent; @@ -827,7 +827,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc) if (array->eof_index >= 0) desc->eof = true; - kunmap(desc->page); + kunmap_thread(desc->page); dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", (unsigned long long)*desc->dir_cookie, res); return res; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 05/58] kmap: Introduce k[un]map_thread
From: Ira Weiny To correctly support the semantics of kmap() with Kernel protection keys (PKS), kmap() may be required to set the protections on multiple processors (globally). Enabling PKS globally can be very expensive depending on the requested operation. Furthermore, enabling a domain globally reduces the protection afforded by PKS. Most kmap() (Aprox 209 of 229) callers use the map within a single thread and have no need for the protection domain to be enabled globally. However, the remaining callers do not follow this pattern and, as best I can tell, expect the mapping to be 'global' and available to any thread who may access the mapping.[1] We don't anticipate global mappings to pmem, however in general there is a danger in changing the semantics of kmap(). Effectively, this would cause an unresolved page fault with little to no information about why the failure occurred. To resolve this a number of options were considered. 1) Attempt to change all the thread local kmap() calls to kmap_atomic()[2] 2) Introduce a flags parameter to kmap() to indicate if the mapping should be global or not 3) Change ~20 call sites to 'kmap_global()' to indicate that they require a global enablement of the pages. 4) Change ~209 call sites to 'kmap_thread()' to indicate that the mapping is to be used within that thread of execution only Option 1 is simply not feasible. Option 2 would require all of the call sites of kmap() to change. Option 3 seems like a good minimal change but there is a danger that new code may miss the semantic change of kmap() and not get the behavior the developer intended. Therefore, #4 was chosen. Subsequent patches will convert most ~90% of the kmap callers to this new call leaving about 10% of the existing kmap callers to enable PKS globally. Cc: Randy Dunlap Signed-off-by: Ira Weiny --- include/linux/highmem.h | 34 ++ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 2a9806e3b8d2..ef7813544719 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -60,7 +60,7 @@ static inline void kmap_flush_tlb(unsigned long addr) { } #endif void *kmap_high(struct page *page); -static inline void *kmap(struct page *page) +static inline void *__kmap(struct page *page, bool global) { void *addr; @@ -74,20 +74,20 @@ static inline void *kmap(struct page *page) * Even non-highmem pages may have additional access protections which * need to be checked and potentially enabled. */ - dev_page_enable_access(page, true); + dev_page_enable_access(page, global); return addr; } void kunmap_high(struct page *page); -static inline void kunmap(struct page *page) +static inline void __kunmap(struct page *page, bool global) { might_sleep(); /* * Even non-highmem pages may have additional access protections which * need to be checked and potentially disabled. */ - dev_page_disable_access(page, true); + dev_page_disable_access(page, global); if (!PageHighMem(page)) return; kunmap_high(page); @@ -160,10 +160,10 @@ static inline struct page *kmap_to_page(void *addr) static inline unsigned long totalhigh_pages(void) { return 0UL; } -static inline void *kmap(struct page *page) +static inline void *__kmap(struct page *page, bool global) { might_sleep(); - dev_page_enable_access(page, true); + dev_page_enable_access(page, global); return page_address(page); } @@ -171,9 +171,9 @@ static inline void kunmap_high(struct page *page) { } -static inline void kunmap(struct page *page) +static inline void __kunmap(struct page *page, bool global) { - dev_page_disable_access(page, true); + dev_page_disable_access(page, global); #ifdef ARCH_HAS_FLUSH_ON_KUNMAP kunmap_flush_on_unmap(page_address(page)); #endif @@ -238,6 +238,24 @@ static inline void kmap_atomic_idx_pop(void) #endif +static inline void *kmap(struct page *page) +{ + return __kmap(page, true); +} +static inline void kunmap(struct page *page) +{ + __kunmap(page, true); +} + +static inline void *kmap_thread(struct page *page) +{ + return __kmap(page, false); +} +static inline void kunmap_thread(struct page *page) +{ + __kunmap(page, false); +} + /* * Prevent people trying to call kunmap_atomic() as if it were kunmap() * kunmap_atomic() should get the return value of kmap_atomic, not the page. -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 13/58] fs/btrfs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Chris Mason Cc: Josef Bacik Cc: David Sterba Signed-off-by: Ira Weiny --- fs/btrfs/check-integrity.c | 4 ++-- fs/btrfs/compression.c | 4 ++-- fs/btrfs/inode.c | 16 fs/btrfs/lzo.c | 24 fs/btrfs/raid56.c | 34 +- fs/btrfs/reflink.c | 8 fs/btrfs/send.c| 4 ++-- fs/btrfs/zlib.c| 32 fs/btrfs/zstd.c| 20 ++-- 9 files changed, 73 insertions(+), 73 deletions(-) diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 81a8c87a5afb..9e5a02512ab5 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c @@ -2706,7 +2706,7 @@ static void __btrfsic_submit_bio(struct bio *bio) bio_for_each_segment(bvec, bio, iter) { BUG_ON(bvec.bv_len != PAGE_SIZE); - mapped_datav[i] = kmap(bvec.bv_page); + mapped_datav[i] = kmap_thread(bvec.bv_page); i++; if (dev_state->state->print_mask & @@ -2720,7 +2720,7 @@ static void __btrfsic_submit_bio(struct bio *bio) bio, _is_patched, bio->bi_opf); bio_for_each_segment(bvec, bio, iter) - kunmap(bvec.bv_page); + kunmap_thread(bvec.bv_page); kfree(mapped_datav); } else if (NULL != dev_state && (bio->bi_opf & REQ_PREFLUSH)) { if (dev_state->state->print_mask & diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 1ab56a734e70..5944fb36d68a 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -1626,7 +1626,7 @@ static void heuristic_collect_sample(struct inode *inode, u64 start, u64 end, curr_sample_pos = 0; while (index < index_end) { page = find_get_page(inode->i_mapping, index); - in_data = kmap(page); + in_data = kmap_thread(page); /* Handle case where the start is not aligned to PAGE_SIZE */ i = start % PAGE_SIZE; while (i < PAGE_SIZE - SAMPLING_READ_SIZE) { @@ -1639,7 +1639,7 @@ static void heuristic_collect_sample(struct inode *inode, u64 start, u64 end, start += SAMPLING_INTERVAL; curr_sample_pos += SAMPLING_READ_SIZE; } - kunmap(page); + kunmap_thread(page); put_page(page); index++; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9570458aa847..9710a52c6c42 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4603,7 +4603,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, if (offset != blocksize) { if (!len) len = blocksize - offset; - kaddr = kmap(page); + kaddr = kmap_thread(page); if (front) memset(kaddr + (block_start - page_offset(page)), 0, offset); @@ -4611,7 +4611,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, memset(kaddr + (block_start - page_offset(page)) + offset, 0, len); flush_dcache_page(page); - kunmap(page); + kunmap_thread(page); } ClearPageChecked(page); set_page_dirty(page); @@ -6509,9 +6509,9 @@ static noinline int uncompress_inline(struct btrfs_path *path, */ if (max_size + pg_offset < PAGE_SIZE) { - char *map = kmap(page); + char *map = kmap_thread(page); memset(map + pg_offset + max_size, 0, PAGE_SIZE - max_size - pg_offset); - kunmap(page); + kunmap_thread(page); } kfree(tmp); return ret; @@ -6704,7 +6704,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, goto out; } } else { - map = kmap(page); + map = kmap_thread(page); read_extent_buffer(leaf, map + pg_offset, ptr, copy_size); if (pg_offset + copy_size < PAGE_SIZE) { @@ -6712,7 +6712,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, PAGE_SIZE - pg_offset - copy_size);
[PATCH RFC PKS/PMEM 12/58] fs/afs: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: David Howells Signed-off-by: Ira Weiny --- fs/afs/dir.c | 16 fs/afs/dir_edit.c | 16 fs/afs/mntpt.c| 4 ++-- fs/afs/write.c| 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 1d2e61e0ab04..5d01cdb590de 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -127,14 +127,14 @@ static bool afs_dir_check_page(struct afs_vnode *dvnode, struct page *page, qty /= sizeof(union afs_xdr_dir_block); /* check them */ - dbuf = kmap(page); + dbuf = kmap_thread(page); for (tmp = 0; tmp < qty; tmp++) { if (dbuf->blocks[tmp].hdr.magic != AFS_DIR_MAGIC) { printk("kAFS: %s(%lx): bad magic %d/%d is %04hx\n", __func__, dvnode->vfs_inode.i_ino, tmp, qty, ntohs(dbuf->blocks[tmp].hdr.magic)); trace_afs_dir_check_failed(dvnode, off, i_size); - kunmap(page); + kunmap_thread(page); trace_afs_file_error(dvnode, -EIO, afs_file_error_dir_bad_magic); goto error; } @@ -146,7 +146,7 @@ static bool afs_dir_check_page(struct afs_vnode *dvnode, struct page *page, ((u8 *)>blocks[tmp])[AFS_DIR_BLOCK_SIZE - 1] = 0; } - kunmap(page); + kunmap_thread(page); checked: afs_stat_v(dvnode, n_read_dir); @@ -177,13 +177,13 @@ static bool afs_dir_check_pages(struct afs_vnode *dvnode, struct afs_read *req) req->pos, req->index, req->nr_pages, req->offset); for (i = 0; i < req->nr_pages; i++) { - dbuf = kmap(req->pages[i]); + dbuf = kmap_thread(req->pages[i]); for (j = 0; j < qty; j++) { union afs_xdr_dir_block *block = >blocks[j]; pr_warn("[%02x] %32phN\n", i * qty + j, block); } - kunmap(req->pages[i]); + kunmap_thread(req->pages[i]); } return false; } @@ -481,7 +481,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, limit = blkoff & ~(PAGE_SIZE - 1); - dbuf = kmap(page); + dbuf = kmap_thread(page); /* deal with the individual blocks stashed on this page */ do { @@ -489,7 +489,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, sizeof(union afs_xdr_dir_block)]; ret = afs_dir_iterate_block(dvnode, ctx, dblock, blkoff); if (ret != 1) { - kunmap(page); + kunmap_thread(page); goto out; } @@ -497,7 +497,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, } while (ctx->pos < dir->i_size && blkoff < limit); - kunmap(page); + kunmap_thread(page); ret = 0; } diff --git a/fs/afs/dir_edit.c b/fs/afs/dir_edit.c index b108528bf010..35ed6828e205 100644 --- a/fs/afs/dir_edit.c +++ b/fs/afs/dir_edit.c @@ -218,7 +218,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, need_slots = round_up(12 + name->len + 1 + 4, AFS_DIR_DIRENT_SIZE); need_slots /= AFS_DIR_DIRENT_SIZE; - meta_page = kmap(page0); + meta_page = kmap_thread(page0); meta = _page->blocks[0]; if (i_size == 0) goto new_directory; @@ -247,7 +247,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, set_page_private(page, 1); SetPagePrivate(page); } - dir_page = kmap(page); + dir_page = kmap_thread(page); } /* Abandon the edit if we got a callback break. */ @@ -284,7 +284,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, if (page != page0) { unlock_page(page); - kunmap(page); + kunmap_thread(page); put_page(page); } } @@ -323,7 +323,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, afs_set_contig_bits(block, slot, need_slots); if (page != page0) { unlock_page(page); - kunmap(page); + kunmap_thread(page); put_page(page); } @@ -337,7 +337,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, out_unmap: unlock_page(page0); - kunmap(page0); +
[PATCH RFC PKS/PMEM 08/58] drivers/firmware_loader: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this driver are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Luis Chamberlain Signed-off-by: Ira Weiny --- drivers/base/firmware_loader/fallback.c | 4 ++-- drivers/base/firmware_loader/main.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index 283ca2de76d4..22dea9ba7a37 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -322,14 +322,14 @@ static void firmware_rw(struct fw_priv *fw_priv, char *buffer, int page_ofs = offset & (PAGE_SIZE-1); int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); - page_data = kmap(fw_priv->pages[page_nr]); + page_data = kmap_thread(fw_priv->pages[page_nr]); if (read) memcpy(buffer, page_data + page_ofs, page_cnt); else memcpy(page_data + page_ofs, buffer, page_cnt); - kunmap(fw_priv->pages[page_nr]); + kunmap_thread(fw_priv->pages[page_nr]); buffer += page_cnt; offset += page_cnt; count -= page_cnt; diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 63b9714a0154..cc884c9f8742 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -409,11 +409,11 @@ static int fw_decompress_xz_pages(struct device *dev, struct fw_priv *fw_priv, /* decompress onto the new allocated page */ page = fw_priv->pages[fw_priv->nr_pages - 1]; - xz_buf.out = kmap(page); + xz_buf.out = kmap_thread(page); xz_buf.out_pos = 0; xz_buf.out_size = PAGE_SIZE; xz_ret = xz_dec_run(xz_dec, _buf); - kunmap(page); + kunmap_thread(page); fw_priv->size += xz_buf.out_pos; /* partial decompression means either end or error */ if (xz_buf.out_pos != PAGE_SIZE) -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 09/58] drivers/gpu: Utilize new kmap_thread()
From: Ira Weiny These kmap() calls in the gpu stack are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: David Airlie Cc: Daniel Vetter Cc: Patrik Jakobsson Signed-off-by: Ira Weiny --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 12 ++-- drivers/gpu/drm/gma500/gma_display.c | 4 ++-- drivers/gpu/drm/gma500/mmu.c | 10 +- drivers/gpu/drm/i915/gem/i915_gem_shmem.c| 4 ++-- .../gpu/drm/i915/gem/selftests/i915_gem_context.c| 4 ++-- drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c | 8 drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c | 4 ++-- drivers/gpu/drm/i915/gt/intel_gtt.c | 4 ++-- drivers/gpu/drm/i915/gt/shmem_utils.c| 4 ++-- drivers/gpu/drm/i915/i915_gem.c | 8 drivers/gpu/drm/i915/i915_gpu_error.c| 4 ++-- drivers/gpu/drm/i915/selftests/i915_perf.c | 4 ++-- drivers/gpu/drm/radeon/radeon_ttm.c | 4 ++-- 13 files changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 978bae731398..bd564bccb7a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -2437,11 +2437,11 @@ static ssize_t amdgpu_ttm_gtt_read(struct file *f, char __user *buf, page = adev->gart.pages[p]; if (page) { - ptr = kmap(page); + ptr = kmap_thread(page); ptr += off; r = copy_to_user(buf, ptr, cur_size); - kunmap(adev->gart.pages[p]); + kunmap_thread(adev->gart.pages[p]); } else r = clear_user(buf, cur_size); @@ -2507,9 +2507,9 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf, if (p->mapping != adev->mman.bdev.dev_mapping) return -EPERM; - ptr = kmap(p); + ptr = kmap_thread(p); r = copy_to_user(buf, ptr + off, bytes); - kunmap(p); + kunmap_thread(p); if (r) return -EFAULT; @@ -2558,9 +2558,9 @@ static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf, if (p->mapping != adev->mman.bdev.dev_mapping) return -EPERM; - ptr = kmap(p); + ptr = kmap_thread(p); r = copy_from_user(ptr + off, buf, bytes); - kunmap(p); + kunmap_thread(p); if (r) return -EFAULT; diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index 3df6d6e850f5..35f4e55c941f 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -400,9 +400,9 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc, /* Copy the cursor to cursor mem */ tmp_dst = dev_priv->vram_addr + cursor_gt->offset; for (i = 0; i < cursor_pages; i++) { - tmp_src = kmap(gt->pages[i]); + tmp_src = kmap_thread(gt->pages[i]); memcpy(tmp_dst, tmp_src, PAGE_SIZE); - kunmap(gt->pages[i]); + kunmap_thread(gt->pages[i]); tmp_dst += PAGE_SIZE; } diff --git a/drivers/gpu/drm/gma500/mmu.c b/drivers/gpu/drm/gma500/mmu.c index 505044c9a673..fba7a3a461fd 100644 --- a/drivers/gpu/drm/gma500/mmu.c +++ b/drivers/gpu/drm/gma500/mmu.c @@ -192,20 +192,20 @@ struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, pd->invalid_pte = 0; } - v = kmap(pd->dummy_pt); + v = kmap_thread(pd->dummy_pt); for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) v[i] = pd->invalid_pte; - kunmap(pd->dummy_pt); + kunmap_thread(pd->dummy_pt); - v = kmap(pd->p); + v = kmap_thread(pd->p); for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) v[i] = pd->invalid_pde; - kunmap(pd->p); + kunmap_thread(pd->p); clear_page(kmap(pd->dummy_page)); - kunmap(pd->dummy_page); + kunmap_thread(pd->dummy_page); pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024); if (!pd->tables) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 38113d3c0138..274424795fb7 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -566,9 +566,9 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *dev_priv, if (err < 0)
[PATCH RFC PKS/PMEM 20/58] fs/jffs2: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: David Woodhouse Cc: Richard Weinberger Signed-off-by: Ira Weiny --- fs/jffs2/file.c | 4 ++-- fs/jffs2/gc.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index f8fb89b10227..3e6d54f9b011 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -88,7 +88,7 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) BUG_ON(!PageLocked(pg)); - pg_buf = kmap(pg); + pg_buf = kmap_thread(pg); /* FIXME: Can kmap fail? */ ret = jffs2_read_inode_range(c, f, pg_buf, pg->index << PAGE_SHIFT, @@ -103,7 +103,7 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) } flush_dcache_page(pg); - kunmap(pg); + kunmap_thread(pg); jffs2_dbg(2, "readpage finished\n"); return ret; diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 373b3b7c9f44..a7259783ab84 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c @@ -1335,7 +1335,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era return PTR_ERR(page); } - pg_ptr = kmap(page); + pg_ptr = kmap_thread(page); mutex_lock(>sem); offset = start; @@ -1400,7 +1400,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era } } - kunmap(page); + kunmap_thread(page); put_page(page); return ret; } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 23/58] fs/fuse: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Miklos Szeredi Signed-off-by: Ira Weiny --- fs/fuse/readdir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index 90e3f01bd796..953ffe6f56e3 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -536,9 +536,9 @@ static int fuse_readdir_cached(struct file *file, struct dir_context *ctx) * Contents of the page are now protected against changing by holding * the page lock. */ - addr = kmap(page); + addr = kmap_thread(page); res = fuse_parse_cache(ff, addr, size, ctx); - kunmap(page); + kunmap_thread(page); unlock_page(page); put_page(page); -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 11/58] drivers/net: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in these drivers are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Jesse Brandeburg Signed-off-by: Ira Weiny --- drivers/net/ethernet/intel/igb/igb_ethtool.c | 4 ++-- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 6e8231c1ddf0..ac9189752012 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -1794,14 +1794,14 @@ static int igb_check_lbtest_frame(struct igb_rx_buffer *rx_buffer, frame_size >>= 1; - data = kmap(rx_buffer->page); + data = kmap_thread(rx_buffer->page); if (data[3] != 0xFF || data[frame_size + 10] != 0xBE || data[frame_size + 12] != 0xAF) match = false; - kunmap(rx_buffer->page); + kunmap_thread(rx_buffer->page); return match; } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 71ec908266a6..7d469425f8b4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -1963,14 +1963,14 @@ static bool ixgbe_check_lbtest_frame(struct ixgbe_rx_buffer *rx_buffer, frame_size >>= 1; - data = kmap(rx_buffer->page) + rx_buffer->page_offset; + data = kmap_thread(rx_buffer->page) + rx_buffer->page_offset; if (data[3] != 0xFF || data[frame_size + 10] != 0xBE || data[frame_size + 12] != 0xAF) match = false; - kunmap(rx_buffer->page); + kunmap_thread(rx_buffer->page); return match; } -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 17/58] fs/nilfs2: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this FS are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Ryusuke Konishi Signed-off-by: Ira Weiny --- fs/nilfs2/alloc.c | 34 +- fs/nilfs2/cpfile.c | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index adf3bb0a8048..2aa4c34094ef 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c @@ -524,7 +524,7 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode, ret = nilfs_palloc_get_desc_block(inode, group, 1, _bh); if (ret < 0) return ret; - desc_kaddr = kmap(desc_bh->b_page); + desc_kaddr = kmap_thread(desc_bh->b_page); desc = nilfs_palloc_block_get_group_desc( inode, group, desc_bh, desc_kaddr); n = nilfs_palloc_rest_groups_in_desc_block(inode, group, @@ -536,7 +536,7 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode, inode, group, 1, _bh); if (ret < 0) goto out_desc; - bitmap_kaddr = kmap(bitmap_bh->b_page); + bitmap_kaddr = kmap_thread(bitmap_bh->b_page); bitmap = bitmap_kaddr + bh_offset(bitmap_bh); pos = nilfs_palloc_find_available_slot( bitmap, group_offset, @@ -547,21 +547,21 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode, desc, lock, -1); req->pr_entry_nr = entries_per_group * group + pos; - kunmap(desc_bh->b_page); - kunmap(bitmap_bh->b_page); + kunmap_thread(desc_bh->b_page); + kunmap_thread(bitmap_bh->b_page); req->pr_desc_bh = desc_bh; req->pr_bitmap_bh = bitmap_bh; return 0; } - kunmap(bitmap_bh->b_page); + kunmap_thread(bitmap_bh->b_page); brelse(bitmap_bh); } group_offset = 0; } - kunmap(desc_bh->b_page); + kunmap_thread(desc_bh->b_page); brelse(desc_bh); } @@ -569,7 +569,7 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode, return -ENOSPC; out_desc: - kunmap(desc_bh->b_page); + kunmap_thread(desc_bh->b_page); brelse(desc_bh); return ret; } @@ -605,10 +605,10 @@ void nilfs_palloc_commit_free_entry(struct inode *inode, spinlock_t *lock; group = nilfs_palloc_group(inode, req->pr_entry_nr, _offset); - desc_kaddr = kmap(req->pr_desc_bh->b_page); + desc_kaddr = kmap_thread(req->pr_desc_bh->b_page); desc = nilfs_palloc_block_get_group_desc(inode, group, req->pr_desc_bh, desc_kaddr); - bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page); + bitmap_kaddr = kmap_thread(req->pr_bitmap_bh->b_page); bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh); lock = nilfs_mdt_bgl_lock(inode, group); @@ -620,8 +620,8 @@ void nilfs_palloc_commit_free_entry(struct inode *inode, else nilfs_palloc_group_desc_add_entries(desc, lock, 1); - kunmap(req->pr_bitmap_bh->b_page); - kunmap(req->pr_desc_bh->b_page); + kunmap_thread(req->pr_bitmap_bh->b_page); + kunmap_thread(req->pr_desc_bh->b_page); mark_buffer_dirty(req->pr_desc_bh); mark_buffer_dirty(req->pr_bitmap_bh); @@ -646,10 +646,10 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode, spinlock_t *lock; group = nilfs_palloc_group(inode, req->pr_entry_nr, _offset); - desc_kaddr = kmap(req->pr_desc_bh->b_page); + desc_kaddr = kmap_thread(req->pr_desc_bh->b_page); desc = nilfs_palloc_block_get_group_desc(inode, group, req->pr_desc_bh, desc_kaddr); - bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page); + bitmap_kaddr = kmap_thread(req->pr_bitmap_bh->b_page); bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh); lock = nilfs_mdt_bgl_lock(inode, group); @@ -661,8 +661,8 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode, else nilfs_palloc_group_desc_add_entries(desc, lock, 1); -
[PATCH RFC PKS/PMEM 02/58] x86/pks/test: Add testing for global option
From: Ira Weiny Now that PKS can be enabled globaly (for all threads) add a test which spawns a thread and tests the same PKS functionality. The test enables/disables PKS in 1 thread while attempting to access the page in another thread. We use the same test array as in the 'local' PKS testing. Signed-off-by: Ira Weiny --- arch/x86/mm/fault.c | 4 ++ lib/pks/pks_test.c | 128 +--- 2 files changed, 124 insertions(+), 8 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 4b4ff9efa298..4c74f52fbc23 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1108,6 +1108,10 @@ static int spurious_kernel_fault_check(unsigned long error_code, pte_t *pte, if (global_pkey_is_enabled(pte, is_write, irq_state)) return 1; + /* +* NOTE: This must be after the global_pkey_is_enabled() call +* to allow the fixup code to be tested. +*/ if (handle_pks_testing(error_code, irq_state)) return 1; diff --git a/lib/pks/pks_test.c b/lib/pks/pks_test.c index 286c8b8457da..dfddccbe4cb6 100644 --- a/lib/pks/pks_test.c +++ b/lib/pks/pks_test.c @@ -154,7 +154,8 @@ static void check_exception(irqentry_state_t *irq_state) } /* Check the exception state */ - if (!check_pkrs(test_armed_key, PKEY_DISABLE_ACCESS)) { + if (!check_pkrs(test_armed_key, + PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)) { pr_err(" FAIL: PKRS cache and MSR\n"); test_exception_ctx->pass = false; } @@ -308,24 +309,29 @@ static int test_it(struct pks_test_ctx *ctx, struct pks_access_test *test, void return ret; } -static int run_access_test(struct pks_test_ctx *ctx, - struct pks_access_test *test, - void *ptr) +static void set_protection(int pkey, enum pks_access_mode mode, bool global) { - switch (test->mode) { + switch (mode) { case PKS_TEST_NO_ACCESS: - pks_mknoaccess(ctx->pkey, false); + pks_mknoaccess(pkey, global); break; case PKS_TEST_RDWR: - pks_mkrdwr(ctx->pkey, false); + pks_mkrdwr(pkey, global); break; case PKS_TEST_RDONLY: - pks_mkread(ctx->pkey, false); + pks_mkread(pkey, global); break; default: pr_err("BUG in test invalid mode\n"); break; } +} + +static int run_access_test(struct pks_test_ctx *ctx, + struct pks_access_test *test, + void *ptr) +{ + set_protection(ctx->pkey, test->mode, false); return test_it(ctx, test, ptr); } @@ -516,6 +522,110 @@ static void run_exception_test(void) pass ? "PASS" : "FAIL"); } +struct shared_data { + struct mutex lock; + struct pks_test_ctx *ctx; + void *kmap_addr; + struct pks_access_test *test; +}; + +static int thread_main(void *d) +{ + struct shared_data *data = d; + struct pks_test_ctx *ctx = data->ctx; + + while (!kthread_should_stop()) { + mutex_lock(>lock); + /* +* wait for the main thread to hand us the page +* We should be spinning so hopefully we will not have gotten +* the global value from a schedule in. +*/ + if (data->kmap_addr) { + if (test_it(ctx, data->test, data->kmap_addr)) + ctx->pass = false; + data->kmap_addr = NULL; + } + mutex_unlock(>lock); + } + + return 0; +} + +static void run_thread_access_test(struct shared_data *data, + struct pks_test_ctx *ctx, + struct pks_access_test *test, + void *ptr) +{ + set_protection(ctx->pkey, test->mode, true); + + pr_info("checking... mode %s; write %s\n", + get_mode_str(test->mode), test->write ? "TRUE" : "FALSE"); + + mutex_lock(>lock); + data->test = test; + data->kmap_addr = ptr; + mutex_unlock(>lock); + + while (data->kmap_addr) { + msleep(10); + } +} + +static void run_global_test(void) +{ + struct task_struct *other_task; + struct pks_test_ctx *ctx; + struct shared_data data; + bool pass = true; + void *ptr; + int i; + + pr_info(" * BEGIN: global pkey checking\n"); + + /* Set up context, data pgae, and thread */ + ctx = alloc_ctx("global pkey test"); + if
[PATCH RFC PKS/PMEM 10/58] drivers/rdma: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in these drivers are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Mike Marciniszyn Cc: Dennis Dalessandro Cc: Doug Ledford Cc: Jason Gunthorpe Cc: Faisal Latif Cc: Shiraz Saleem Cc: Bernard Metzler Signed-off-by: Ira Weiny --- drivers/infiniband/hw/hfi1/sdma.c | 4 ++-- drivers/infiniband/hw/i40iw/i40iw_cm.c | 10 +- drivers/infiniband/sw/siw/siw_qp_tx.c | 14 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index 04575c9afd61..09d206e3229a 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -3130,7 +3130,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx, } if (type == SDMA_MAP_PAGE) { - kvaddr = kmap(page); + kvaddr = kmap_thread(page); kvaddr += offset; } else if (WARN_ON(!kvaddr)) { __sdma_txclean(dd, tx); @@ -3140,7 +3140,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx, memcpy(tx->coalesce_buf + tx->coalesce_idx, kvaddr, len); tx->coalesce_idx += len; if (type == SDMA_MAP_PAGE) - kunmap(page); + kunmap_thread(page); /* If there is more data, return */ if (tx->tlen - tx->coalesce_idx) diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index a3b95805c154..122d7a5642a1 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -3721,7 +3721,7 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) ibmr->device = iwpd->ibpd.device; iwqp->lsmm_mr = ibmr; if (iwqp->page) - iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page); + iwqp->sc_qp.qp_uk.sq_base = kmap_thread(iwqp->page); dev->iw_priv_qp_ops->qp_send_lsmm(>sc_qp, iwqp->ietf_mem.va, (accept.size + conn_param->private_data_len), @@ -3729,12 +3729,12 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) } else { if (iwqp->page) - iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page); + iwqp->sc_qp.qp_uk.sq_base = kmap_thread(iwqp->page); dev->iw_priv_qp_ops->qp_send_lsmm(>sc_qp, NULL, 0, 0); } if (iwqp->page) - kunmap(iwqp->page); + kunmap_thread(iwqp->page); iwqp->cm_id = cm_id; cm_node->cm_id = cm_id; @@ -4102,10 +4102,10 @@ static void i40iw_cm_event_connected(struct i40iw_cm_event *event) i40iw_cm_init_tsa_conn(iwqp, cm_node); read0 = (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO); if (iwqp->page) - iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page); + iwqp->sc_qp.qp_uk.sq_base = kmap_thread(iwqp->page); dev->iw_priv_qp_ops->qp_send_rtt(>sc_qp, read0); if (iwqp->page) - kunmap(iwqp->page); + kunmap_thread(iwqp->page); memset(, 0, sizeof(attr)); attr.qp_state = IB_QPS_RTS; diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c index d19d8325588b..4ed37c328d02 100644 --- a/drivers/infiniband/sw/siw/siw_qp_tx.c +++ b/drivers/infiniband/sw/siw/siw_qp_tx.c @@ -76,7 +76,7 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr) if (unlikely(!p)) return -EFAULT; - buffer = kmap(p); + buffer = kmap_thread(p); if (likely(PAGE_SIZE - off >= bytes)) { memcpy(paddr, buffer + off, bytes); @@ -84,7 +84,7 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr) unsigned long part = bytes - (PAGE_SIZE - off); memcpy(paddr, buffer + off, part); - kunmap(p); + kunmap_thread(p); if (!mem->is_pbl) p = siw_get_upage(mem->umem, @@ -96,10 +96,10 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr) if (unlikely(!p)) return -EFAULT; - buffer = kmap(p); + buffer = kmap_thread(p); memcpy(paddr + part, buffer,
[PATCH RFC PKS/PMEM 04/58] kmap: Add stray access protection for device pages
From: Ira Weiny Device managed pages may have additional protections. These protections need to be removed prior to valid use by kernel users. Check for special treatment of device managed pages in kmap and take action if needed. We use kmap as an interface for generic kernel code because under normal circumstances it would be a bug for general kernel code to not use kmap prior to accessing kernel memory. Therefore, this should allow any valid kernel users to seamlessly use these pages without issues. Because of the critical nature of kmap it must be pointed out that the over head on regular DRAM is carefully implemented to be as fast as possible. Furthermore the underlying MSR write required on device pages when protected is better than a normal MSR write. Specifically, WRMSR(MSR_IA32_PKRS) is not serializing but still maintains ordering properties similar to WRPKRU. The current SDM section on PKRS needs updating but should be the same as that of WRPKRU. So to quote from the WRPKRU text: WRPKRU will never execute speculatively. Memory accesses affected by PKRU register will not execute (even speculatively) until all prior executions of WRPKRU have completed execution and updated the PKRU register. Still this will make accessing pmem more expensive from the kernel but the overhead is minimized and many pmem users access this memory through user page mappings which are not affected at all. Cc: Randy Dunlap Signed-off-by: Ira Weiny --- include/linux/highmem.h | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 14e6202ce47f..2a9806e3b8d2 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -31,6 +32,20 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size) #include +static inline void dev_page_enable_access(struct page *page, bool global) +{ + if (!page_is_access_protected(page)) + return; + dev_access_enable(global); +} + +static inline void dev_page_disable_access(struct page *page, bool global) +{ + if (!page_is_access_protected(page)) + return; + dev_access_disable(global); +} + #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. +*/ + dev_page_enable_access(page, true); 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. +*/ + dev_page_disable_access(page, true); 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(); + dev_page_enable_access(page, false); 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(); + dev_page_enable_access(page, true); return page_address(page); } @@ -146,6 +173,7 @@ static inline void kunmap_high(struct page *page) static inline void kunmap(struct page *page) { + dev_page_disable_access(page, true); #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(); + dev_page_enable_access(page, false); 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); \ + dev_page_disable_access(kmap_to_page(addr), false); \ + kunmap_atomic_high(addr); \ pagefault_enable(); \ preempt_enable(); \ } while (0) --
[PATCH RFC PKS/PMEM 00/58] PMEM: Introduce stray write protection for PMEM
From: Ira Weiny Should a stray write in the kernel occur persistent memory is affected more than regular memory. A write to the wrong area of memory could result in latent data corruption which will will persist after a reboot. PKS provides a nice way to restrict access to persistent memory kernel mappings, while providing fast access when needed. Since the last RFC[1] this patch set has grown quite a bit. It now depends on the core patches submitted separately. https://lore.kernel.org/lkml/20201009194258.3207172-1-ira.we...@intel.com/ And contained in the git tree here: https://github.com/weiny2/linux-kernel/tree/pks-rfc-v3 However, functionally there is only 1 major change from the last RFC. Specifically, kmap() is most often used within a single thread in a 'map/do something/unmap' pattern. In fact this is the pattern used in ~90% of the callers of kmap(). This pattern works very well for the pmem use case and the testing which was done. However, there were another ~20-30 kmap users which do not follow this pattern. Some of them seem to expect the mapping to be 'global' while others require a detailed audit to be sure.[2][3] While we don't anticipate global mappings to pmem there is a danger in changing the semantics of kmap(). Effectively, this would cause an unresolved page fault with little to no information about why. There were a number of options considered. 1) Attempt to change all the thread local kmap() calls to kmap_atomic() 2) Introduce a flags parameter to kmap() to indicate if the mapping should be global or not 3) Change ~20-30 call sites to 'kmap_global()' to indicate that they require a global mapping of the pages 4) Change ~209 call sites to 'kmap_thread()' to indicate that the mapping is to be used within that thread of execution only Option 1 is simply not feasible kmap_atomic() is not the same semantic as kmap() within a single tread. Option 2 would require all of the call sites of kmap() to change. Option 3 seems like a good minimal change but there is a danger that new code may miss the semantic change of kmap() and not get the behavior intended for future users. Therefore, option #4 was chosen. To handle the global PKRS state in the most efficient manner possible. We lazily override the thread specific PKRS key value only when needed because we anticipate PKS to not be needed will not be needed most of the time. And even when it is used 90% of the time it is a thread local call. [1] https://lore.kernel.org/lkml/20200717072056.73134-1-ira.we...@intel.com/ [2] The following list of callers continue calling kmap() (utilizing the global PKRS). It would be nice if more of them could be converted to kmap_thread() drivers/firewire/net.c: ptr = kmap(dev->broadcast_rcv_buffer.pages[u]); drivers/gpu/drm/i915/gem/i915_gem_pages.c: return kmap(sg_page(sgt->sgl)); drivers/gpu/drm/ttm/ttm_bo_util.c: map->virtual = kmap(map->page); drivers/infiniband/hw/qib/qib_user_sdma.c: mpage = kmap(page); drivers/misc/vmw_vmci/vmci_host.c: context->notify = kmap(context->notify_page) + (uva & (PAGE_SIZE - 1)); drivers/misc/xilinx_sdfec.c:addr = kmap(pages[i]); drivers/mmc/host/usdhi6rol0.c: host->pg.mapped = kmap(host->pg.page); drivers/mmc/host/usdhi6rol0.c: host->pg.mapped = kmap(host->pg.page); drivers/mmc/host/usdhi6rol0.c: host->pg.mapped = kmap(host->pg.page); drivers/nvme/target/tcp.c: iov->iov_base = kmap(sg_page(sg)) + sg->offset + sg_offset; drivers/scsi/libiscsi_tcp.c:segment->sg_mapped = kmap(sg_page(sg)); drivers/target/iscsi/iscsi_target.c:iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off; drivers/target/target_core_transport.c: return kmap(sg_page(sg)) + sg->offset; fs/btrfs/check-integrity.c: block_ctx->datav[i] = kmap(block_ctx->pagev[i]); fs/ceph/dir.c: cache_ctl->dentries = kmap(cache_ctl->page); fs/ceph/inode.c:ctl->dentries = kmap(ctl->page); fs/erofs/zpvec.h: kmap_atomic(ctor->curr) : kmap(ctor->curr); lib/scatterlist.c: miter->addr = kmap(miter->page) + miter->__offset; net/ceph/pagelist.c:pl->mapped_tail = kmap(page); net/ceph/pagelist.c:pl->mapped_tail = kmap(page); virt/kvm/kvm_main.c:hva = kmap(page); [3] The following appear to follow the same pattern as ext2 which was converted after some code audit. So I _think_ they too could be converted to k[un]map_thread(). fs/freevxfs/vxfs_subr.c|75| kmap(pp); fs/jfs/jfs_metapage.c|102| kmap(page); fs/jfs/jfs_metapage.c|156| kmap(page); fs/minix/dir.c|72| kmap(page); fs/nilfs2/dir.c|195| kmap(page); fs/nilfs2/ifile.h|24| void *kaddr =
[PATCH RFC PKS/PMEM 07/58] drivers/drbd: Utilize new kmap_thread()
From: Ira Weiny The kmap() calls in this driver are localized to a single thread. To avoid the over head of global PKRS updates use the new kmap_thread() call. Cc: Jens Axboe Signed-off-by: Ira Weiny --- drivers/block/drbd/drbd_main.c | 4 ++-- drivers/block/drbd/drbd_receiver.c | 12 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 573dbf6f0c31..f0d0c6b0745e 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1532,9 +1532,9 @@ static int _drbd_no_send_page(struct drbd_peer_device *peer_device, struct page int err; socket = peer_device->connection->data.socket; - addr = kmap(page) + offset; + addr = kmap_thread(page) + offset; err = drbd_send_all(peer_device->connection, socket, addr, size, msg_flags); - kunmap(page); + kunmap_thread(page); if (!err) peer_device->device->send_cnt += size >> 9; return err; diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 422363daa618..4704bc0564e2 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1951,13 +1951,13 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector, page = peer_req->pages; page_chain_for_each(page) { unsigned len = min_t(int, ds, PAGE_SIZE); - data = kmap(page); + data = kmap_thread(page); err = drbd_recv_all_warn(peer_device->connection, data, len); if (drbd_insert_fault(device, DRBD_FAULT_RECEIVE)) { drbd_err(device, "Fault injection: Corrupting data on receive\n"); data[0] = data[0] ^ (unsigned long)-1; } - kunmap(page); + kunmap_thread(page); if (err) { drbd_free_peer_req(device, peer_req); return NULL; @@ -1992,7 +1992,7 @@ static int drbd_drain_block(struct drbd_peer_device *peer_device, int data_size) page = drbd_alloc_pages(peer_device, 1, 1); - data = kmap(page); + data = kmap_thread(page); while (data_size) { unsigned int len = min_t(int, data_size, PAGE_SIZE); @@ -2001,7 +2001,7 @@ static int drbd_drain_block(struct drbd_peer_device *peer_device, int data_size) break; data_size -= len; } - kunmap(page); + kunmap_thread(page); drbd_free_pages(peer_device->device, page, 0); return err; } @@ -2033,10 +2033,10 @@ static int recv_dless_read(struct drbd_peer_device *peer_device, struct drbd_req D_ASSERT(peer_device->device, sector == bio->bi_iter.bi_sector); bio_for_each_segment(bvec, bio, iter) { - void *mapped = kmap(bvec.bv_page) + bvec.bv_offset; + void *mapped = kmap_thread(bvec.bv_page) + bvec.bv_offset; expect = min_t(int, data_size, bvec.bv_len); err = drbd_recv_all_warn(peer_device->connection, mapped, expect); - kunmap(bvec.bv_page); + kunmap_thread(bvec.bv_page); if (err) return err; data_size -= expect; -- 2.28.0.rc0.12.gb6a658bd00c9 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC PKS/PMEM 01/58] x86/pks: Add a global pkrs option
From: Ira Weiny Some users, such as kmap(), sometimes requires PKS to be global. However, updating all CPUs, and worse yet all threads is expensive. Introduce a global PKRS state which is checked at critical times to allow the state to enable access when global PKS is required. To accomplish this with minimal locking; the code is carefully designed with the following key concepts. 1) Borrow the idea of lazy TLB invalidations from the fault handler code. When enabling PKS access we anticipate that other threads are not yet running. However, if they are we catch the fault and clean up the MSR value. 2) When disabling PKS access we force all MSR values across all CPU's. This is required to block access as soon as possible.[1] However, it is key that we never attempt to update the per-task PKS values directly. See next point. 3) Per-task PKS values never get updated with global PKS values. This is key to prevent locking requirements and a nearly intractable problem of trying to update every task in the system. Here are a few key points. 3a) The MSR value can be updated with the global PKS value if that global value happened to change while the task was running. 3b) If the task was sleeping while the global PKS was updated then the global value is added in when task's are scheduled. 3c) If the global PKS value restricts access the MSR is updated as soon as possible[1] and the thread value is not updated which ensures the thread does not retain the elevated privileges after a context switch. 4) Follow on patches must be careful to preserve the separation of the thread PKRS value and the MSR value. 5) Access Disable on any individual pkey is turned into (Access Disable | Write Disable) to facilitate faster integration of the global value into the thread local MSR through a simple '&' operation. Doing otherwise would result in complicated individual bit manipulation for each pkey. [1] There is a race condition which is ignored which is required for performance issues. This potentially allows access to a thread until the end of it's time slice. After the context switch the global value will be restored. Signed-off-by: Ira Weiny --- Documentation/core-api/protection-keys.rst | 11 +- arch/x86/entry/common.c| 7 + arch/x86/include/asm/pkeys.h | 6 +- arch/x86/include/asm/pkeys_common.h| 8 +- arch/x86/kernel/process.c | 74 +++- arch/x86/mm/fault.c| 189 - arch/x86/mm/pkeys.c| 88 -- include/linux/pkeys.h | 6 +- lib/pks/pks_test.c | 16 +- 9 files changed, 329 insertions(+), 76 deletions(-) diff --git a/Documentation/core-api/protection-keys.rst b/Documentation/core-api/protection-keys.rst index c60366921d60..9e8a98653e13 100644 --- a/Documentation/core-api/protection-keys.rst +++ b/Documentation/core-api/protection-keys.rst @@ -121,9 +121,9 @@ mapping adds that mapping to the protection domain. int pks_key_alloc(const char * const pkey_user); #define PAGE_KERNEL_PKEY(pkey) #define _PAGE_KEY(pkey) -void pks_mknoaccess(int pkey); -void pks_mkread(int pkey); -void pks_mkrdwr(int pkey); +void pks_mknoaccess(int pkey, bool global); +void pks_mkread(int pkey, bool global); +void pks_mkrdwr(int pkey, bool global); void pks_key_free(int pkey); pks_key_alloc() allocates keys dynamically to allow better use of the limited @@ -141,7 +141,10 @@ _PAGE_KEY(). The pks_mk*() family of calls allows kernel users the ability to change the protections for the domain identified by the pkey specified. 3 states are available pks_mknoaccess(), pks_mkread(), and pks_mkrdwr() which set the access -to none, read, and read/write respectively. +to none, read, and read/write respectively. 'global' specifies that the +protection should be set across all threads (logical CPU's) not just the +current running thread/CPU. This increases the overhead of PKS and lessens the +protection so it should be used sparingly. Finally, pks_key_free() allows a user to return the key to the allocator for use by others. diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 324a8fd5ac10..86ad32e0095e 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -261,12 +261,19 @@ noinstr void idtentry_exit_nmi(struct pt_regs *regs, irqentry_state_t *irq_state * current running value and set the default PKRS value for the duration of the * exception. Thus preventing exception handlers from having the elevated * access of the interrupted task. + * + * NOTE That the thread saved PKRS must be preserved separately to ensure + * global overrides do not 'stick' on a thread. */ noinstr void irq_save_pkrs(irqentry_state_t *state) { if
Re: [PATCH v3 00/11] Introduce Simple atomic counters
On Fri, Oct 09, 2020 at 09:55:55AM -0600, Shuah Khan wrote: > This patch series is a result of discussion at the refcount_t BOF > the Linux Plumbers Conference. In this discussion, we identified > a need for looking closely and investigating atomic_t usages in > the kernel when it is used strictly as a counter without it > controlling object lifetimes and state changes. > > There are a number of atomic_t usages in the kernel where atomic_t api > is used strictly for counting and not for managing object lifetime. In > some cases, atomic_t might not even be needed. Then the right patch is to not user atomic_t in those cases. > The purpose of these counters is to clearly differentiate atomic_t > counters from atomic_t usages that guard object lifetimes, hence prone > to overflow and underflow errors. It allows tools that scan for underflow > and overflow on atomic_t usages to detect overflow and underflows to scan > just the cases that are prone to errors. Guarding lifetimes is what we got refcount_t for. > Simple atomic counters api provides interfaces for simple atomic counters > that just count, and don't guard resource lifetimes. The interfaces are > built on top of atomic_t api, providing a smaller subset of atomic_t > interfaces necessary to support simple counters. To what actual purpose?!? AFACIT its pointless wrappery, it gets us nothing. > Counter wraps around to INT_MIN when it overflows and should not be used > to guard resource lifetimes, device usage and open counts that control > state changes, and pm states. Overflowing to INT_MIN is consistent with > the atomic_t api, which it is built on top of. > > Using counter_atomic* to guard lifetimes could lead to use-after free > when it overflows and undefined behavior when used to manage state > changes and device usage/open states. > > This patch series introduces Simple atomic counters. Counter atomic ops > leverage atomic_t and provide a sub-set of atomic_t ops. Thanks for Cc'ing the atomic maintainers :/ NAK. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v3 00/11] Introduce Simple atomic counters
On 10/9/20 12:03 PM, Kees Cook wrote: On Fri, Oct 09, 2020 at 09:55:55AM -0600, Shuah Khan wrote: Note: Would like to get this into Linux 5.10-rc1 so we can continue updating drivers that can be updated to use this API. If this all looks good, Kees, would you like to take this through your tree or would you like to take this through mine. I'd mentioned this in the v2, but yes, please take via your trees. :) Sorry. I missed that. I will get take this through my trees. I'm glad to see this landing! Thanks for reviews and brainstorming ideas. It has been lot of fun doing this work. thanks, -- Shuah ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 3/8] staging: wfx: standardize the error when vif does not exist
Jerome Pouiller writes: > From: Jérôme Pouiller > > Smatch complains: > >drivers/staging/wfx/hif_rx.c:177 hif_scan_complete_indication() warn: > potential NULL parameter dereference 'wvif' >drivers/staging/wfx/data_tx.c:576 wfx_flush() warn: potential NULL > parameter dereference 'wvif' > > Indeed, if the vif id returned by the device does not exist anymore, > wdev_to_wvif() could return NULL. > > In add, the error is not handled uniformly in the code, sometime a > WARN() is displayed but code continue, sometime a dev_warn() is > displayed, sometime it is just not tested, ... > > This patch standardize that. > > Reported-by: Dan Carpenter > Signed-off-by: Jérôme Pouiller > --- > drivers/staging/wfx/data_tx.c | 5 - > drivers/staging/wfx/hif_rx.c | 34 -- > drivers/staging/wfx/sta.c | 4 > 3 files changed, 32 insertions(+), 11 deletions(-) > > diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c > index b4d5dd3d2d23..8db0be08daf8 100644 > --- a/drivers/staging/wfx/data_tx.c > +++ b/drivers/staging/wfx/data_tx.c > @@ -431,7 +431,10 @@ static void wfx_skb_dtor(struct wfx_vif *wvif, struct > sk_buff *skb) > sizeof(struct hif_req_tx) + > req->fc_offset; > > - WARN_ON(!wvif); > + if (!wvif) { > + pr_warn("%s: vif associated with the skb does not exist > anymore\n", __func__); > + return; > + } I'm not really a fan of using function names in warning or error messages as it clutters the log. In debug messages I think they are ok. -- https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/8] staging: wfx: check memory allocation
Jerome Pouiller writes: > From: Jérôme Pouiller > > Smatch complains: > >main.c:228 wfx_send_pdata_pds() warn: potential NULL parameter dereference > 'tmp_buf' >227 tmp_buf = kmemdup(pds->data, pds->size, GFP_KERNEL); >228 ret = wfx_send_pds(wdev, tmp_buf, pds->size); > ^^^ >229 kfree(tmp_buf); > > Reported-by: Dan Carpenter > Signed-off-by: Jérôme Pouiller > --- > drivers/staging/wfx/main.c | 8 +++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c > index df11c091e094..a8dc2c033410 100644 > --- a/drivers/staging/wfx/main.c > +++ b/drivers/staging/wfx/main.c > @@ -222,12 +222,18 @@ static int wfx_send_pdata_pds(struct wfx_dev *wdev) > if (ret) { > dev_err(wdev->dev, "can't load PDS file %s\n", > wdev->pdata.file_pds); > - return ret; > + goto err1; > } > tmp_buf = kmemdup(pds->data, pds->size, GFP_KERNEL); > + if (!tmp_buf) { > + ret = -ENOMEM; > + goto err2; > + } > ret = wfx_send_pds(wdev, tmp_buf, pds->size); > kfree(tmp_buf); > +err2: > release_firmware(pds); > +err1: > return ret; > } A minor style issue but using more descriptive error labels make the code more readable and maintainable, especially in a bigger function. For example, err2 could be called err_release_firmware. And actually err1 could be removed and the goto replaced with just "return ret;". Then err2 could be renamed to a simple err. -- https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v3 00/11] Introduce Simple atomic counters
On Fri, Oct 09, 2020 at 09:55:55AM -0600, Shuah Khan wrote: > Note: Would like to get this into Linux 5.10-rc1 so we can continue > updating drivers that can be updated to use this API. If this all looks > good, Kees, would you like to take this through your tree or would you > like to take this through mine. I'd mentioned this in the v2, but yes, please take via your trees. :) I'm glad to see this landing! -- Kees Cook ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/8] staging: wfx: fix issues reported by Smatch
From: Jérôme Pouiller Fix the issues reported by Dan using Smatch[1]. [1] https://lore.kernel.org/lkml/20201008131320.GA1042@kadam/ Jérôme Pouiller (8): staging: wfx: improve error handling of hif_join() staging: wfx: check memory allocation staging: wfx: standardize the error when vif does not exist staging: wfx: wfx_init_common() returns NULL on error staging: wfx: increase robustness of hif_generic_confirm() staging: wfx: gpiod_get_value() can return an error staging: wfx: drop unicode characters from strings staging: wfx: improve robustness of wfx_get_hw_rate() drivers/staging/wfx/bh.c | 2 +- drivers/staging/wfx/data_tx.c | 9 ++- drivers/staging/wfx/hif_rx.c | 44 +++ drivers/staging/wfx/hif_tx.c | 4 +++- drivers/staging/wfx/main.c| 10 ++-- drivers/staging/wfx/sta.c | 4 6 files changed, 53 insertions(+), 20 deletions(-) -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 8/8] staging: wfx: improve robustness of wfx_get_hw_rate()
From: Jérôme Pouiller Smatch complains: data_tx.c:37 wfx_get_hw_rate() warn: constraint '(struct ieee80211_supported_band)->bitrates' overflow 'band->bitrates' 0 <= abs_rl '0-127' user_rl '' required = '(struct ieee80211_supported_band)->n_bitrates' 23 struct ieee80211_supported_band *band; 24 25 if (rate->idx < 0) 26 return -1; 27 if (rate->flags & IEEE80211_TX_RC_MCS) { 28 if (rate->idx > 7) { 29 WARN(1, "wrong rate->idx value: %d", rate->idx); 30 return -1; 31 } 32 return rate->idx + 14; 33 } 34 // WFx only support 2GHz, else band information should be retrieved 35 // from ieee80211_tx_info 36 band = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]; 37 return band->bitrates[rate->idx].hw_value; Add a simple check to make Smatch happy. Reported-by: Dan Carpenter Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index 8db0be08daf8..41f6a604a697 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -31,6 +31,10 @@ static int wfx_get_hw_rate(struct wfx_dev *wdev, } return rate->idx + 14; } + if (rate->idx >= band->n_bitrates) { + WARN(1, "wrong rate->idx value: %d", rate->idx); + return -1; + } // WFx only support 2GHz, else band information should be retrieved // from ieee80211_tx_info band = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]; -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 7/8] staging: wfx: drop unicode characters from strings
From: Jérôme Pouiller Smatch complains: hif_rx.c:235 hif_generic_indication() warn: format string contains non-ascii character '\xc2' hif_rx.c:235 hif_generic_indication() warn: format string contains non-ascii character '\xb0' 234 if (!wfx_api_older_than(wdev, 1, 4)) 235 dev_info(wdev->dev, "Rx test ongoing. Temperature: %d°C\n", ^ 236 body->data.rx_stats.current_temp); So, replace the unicode character. Reported-by: Dan Carpenter Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index f99921e76059..56a5f891447b 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -246,7 +246,7 @@ static int hif_generic_indication(struct wfx_dev *wdev, mutex_lock(>rx_stats_lock); // Older firmware send a generic indication beside RxStats if (!wfx_api_older_than(wdev, 1, 4)) - dev_info(wdev->dev, "Rx test ongoing. Temperature: %d°C\n", + dev_info(wdev->dev, "Rx test ongoing. Temperature: %d degrees C\n", body->data.rx_stats.current_temp); memcpy(>rx_stats, >data.rx_stats, sizeof(wdev->rx_stats)); -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 3/8] staging: wfx: standardize the error when vif does not exist
From: Jérôme Pouiller Smatch complains: drivers/staging/wfx/hif_rx.c:177 hif_scan_complete_indication() warn: potential NULL parameter dereference 'wvif' drivers/staging/wfx/data_tx.c:576 wfx_flush() warn: potential NULL parameter dereference 'wvif' Indeed, if the vif id returned by the device does not exist anymore, wdev_to_wvif() could return NULL. In add, the error is not handled uniformly in the code, sometime a WARN() is displayed but code continue, sometime a dev_warn() is displayed, sometime it is just not tested, ... This patch standardize that. Reported-by: Dan Carpenter Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/data_tx.c | 5 - drivers/staging/wfx/hif_rx.c | 34 -- drivers/staging/wfx/sta.c | 4 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c index b4d5dd3d2d23..8db0be08daf8 100644 --- a/drivers/staging/wfx/data_tx.c +++ b/drivers/staging/wfx/data_tx.c @@ -431,7 +431,10 @@ static void wfx_skb_dtor(struct wfx_vif *wvif, struct sk_buff *skb) sizeof(struct hif_req_tx) + req->fc_offset; - WARN_ON(!wvif); + if (!wvif) { + pr_warn("%s: vif associated with the skb does not exist anymore\n", __func__); + return; + } wfx_tx_policy_put(wvif, req->retry_policy_index); skb_pull(skb, offset); ieee80211_tx_status_irqsafe(wvif->wdev->hw, skb); diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index d6dfab094b03..ca09467cba05 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -110,9 +110,9 @@ static int hif_receive_indication(struct wfx_dev *wdev, const struct hif_ind_rx *body = buf; if (!wvif) { - dev_warn(wdev->dev, "ignore rx data for non-existent vif %d\n", -hif->interface); - return 0; + dev_warn(wdev->dev, "%s: ignore rx data for non-existent vif %d\n", +__func__, hif->interface); + return -EIO; } skb_pull(skb, sizeof(struct hif_msg) + sizeof(struct hif_ind_rx)); wfx_rx_cb(wvif, body, skb); @@ -128,8 +128,8 @@ static int hif_event_indication(struct wfx_dev *wdev, int type = le32_to_cpu(body->event_id); if (!wvif) { - dev_warn(wdev->dev, "received event for non-existent vif\n"); - return 0; + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; } switch (type) { @@ -161,7 +161,10 @@ static int hif_pm_mode_complete_indication(struct wfx_dev *wdev, { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); - WARN_ON(!wvif); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } complete(>set_pm_mode_complete); return 0; @@ -173,7 +176,11 @@ static int hif_scan_complete_indication(struct wfx_dev *wdev, { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); - WARN_ON(!wvif); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } + wfx_scan_complete(wvif); return 0; @@ -185,7 +192,10 @@ static int hif_join_complete_indication(struct wfx_dev *wdev, { struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); - WARN_ON(!wvif); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } dev_warn(wdev->dev, "unattended JoinCompleteInd\n"); return 0; @@ -195,11 +205,15 @@ static int hif_suspend_resume_indication(struct wfx_dev *wdev, const struct hif_msg *hif, const void *buf) { - struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); const struct hif_ind_suspend_resume_tx *body = buf; + struct wfx_vif *wvif; if (body->bc_mc_only) { - WARN_ON(!wvif); + wvif = wdev_to_wvif(wdev, hif->interface); + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } if (body->resume) wfx_suspend_resume_mc(wvif, STA_NOTIFY_AWAKE); else diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index a246f0d1d6e9..2320a81eae0b 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -619,6 +619,10 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
[PATCH 5/8] staging: wfx: increase robustness of hif_generic_confirm()
From: Jérôme Pouiller Smatch complains: drivers/staging/wfx/hif_rx.c:26 hif_generic_confirm() warn: negative user subtract: 0-u16max - 4 20 static int hif_generic_confirm(struct wfx_dev *wdev, 21 const struct hif_msg *hif, const void *buf) 22 { 23 // All confirm messages start with status 24 int status = le32_to_cpup((__le32 *)buf); 25 int cmd = hif->id; 26 int len = le16_to_cpu(hif->len) - 4; // drop header ^ 27 28 WARN(!mutex_is_locked(>hif_cmd.lock), "data locking error"); In fact, rx_helper() already make the necessary checks on the value of hif->len. Never mind, add an explicit check to make Smatch happy. Reported-by: Dan Carpenter Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index ca09467cba05..2d4265257112 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -40,10 +40,10 @@ static int hif_generic_confirm(struct wfx_dev *wdev, } if (wdev->hif_cmd.buf_recv) { - if (wdev->hif_cmd.len_recv >= len) + if (wdev->hif_cmd.len_recv >= len && len > 0) memcpy(wdev->hif_cmd.buf_recv, buf, len); else - status = -ENOMEM; + status = -EIO; } wdev->hif_cmd.ret = status; -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 6/8] staging: wfx: gpiod_get_value() can return an error
From: Jérôme Pouiller Smatch complains: hif_rx.c:98 hif_wakeup_indication() warn: 'gpiod_get_value(wdev->pdata.gpio_wakeup)' returns positive and negative bh.c:24 device_wakeup() warn: 'gpiod_get_value_cansleep(wdev->pdata.gpio_wakeup)' returns positive and negative Reported-by: Dan Carpenter Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/bh.c | 2 +- drivers/staging/wfx/hif_rx.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c index 586b769c0446..2ffa587aefaa 100644 --- a/drivers/staging/wfx/bh.c +++ b/drivers/staging/wfx/bh.c @@ -21,7 +21,7 @@ static void device_wakeup(struct wfx_dev *wdev) if (!wdev->pdata.gpio_wakeup) return; - if (gpiod_get_value_cansleep(wdev->pdata.gpio_wakeup)) + if (gpiod_get_value_cansleep(wdev->pdata.gpio_wakeup) >= 0) return; if (wfx_api_older_than(wdev, 1, 4)) { diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 2d4265257112..f99921e76059 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -94,8 +94,8 @@ static int hif_startup_indication(struct wfx_dev *wdev, static int hif_wakeup_indication(struct wfx_dev *wdev, const struct hif_msg *hif, const void *buf) { - if (!wdev->pdata.gpio_wakeup - || !gpiod_get_value(wdev->pdata.gpio_wakeup)) { + if (!wdev->pdata.gpio_wakeup || + gpiod_get_value(wdev->pdata.gpio_wakeup) == 0) { dev_warn(wdev->dev, "unexpected wake-up indication\n"); return -EIO; } -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/8] staging: wfx: improve error handling of hif_join()
From: Jérôme Pouiller Smatch complains: hif_tx.c:319 hif_join() error: we previously assumed 'channel' could be null (see line 315) 311 if (!hif) 312 return -ENOMEM; 313 body->infrastructure_bss_mode = !conf->ibss_joined; 314 body->short_preamble = conf->use_short_preamble; 315 if (channel && channel->flags & IEEE80211_CHAN_NO_IR) ^^^ 316 body->probe_for_join = 0; 317 else 318 body->probe_for_join = 1; 319 body->channel_number = channel->hw_value; ^ 320 body->beacon_interval = cpu_to_le32(conf->beacon_int); 321 body->basic_rate_set = Indeed, channel can't be NULL (else I would have seen plenty of Ooops this past year). This patch explicitly claims this restriction. Reported-by: Dan Carpenter Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/hif_tx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c index e61cc2486761..63b437261eb7 100644 --- a/drivers/staging/wfx/hif_tx.c +++ b/drivers/staging/wfx/hif_tx.c @@ -308,11 +308,13 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, WARN_ON(!conf->basic_rates); WARN_ON(sizeof(body->ssid) < ssidlen); WARN(!conf->ibss_joined && !ssidlen, "joining an unknown BSS"); + if (WARN_ON(!channel)) + return -EINVAL; if (!hif) return -ENOMEM; body->infrastructure_bss_mode = !conf->ibss_joined; body->short_preamble = conf->use_short_preamble; - if (channel && channel->flags & IEEE80211_CHAN_NO_IR) + if (channel->flags & IEEE80211_CHAN_NO_IR) body->probe_for_join = 0; else body->probe_for_join = 1; -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/8] staging: wfx: check memory allocation
From: Jérôme Pouiller Smatch complains: main.c:228 wfx_send_pdata_pds() warn: potential NULL parameter dereference 'tmp_buf' 227 tmp_buf = kmemdup(pds->data, pds->size, GFP_KERNEL); 228 ret = wfx_send_pds(wdev, tmp_buf, pds->size); ^^^ 229 kfree(tmp_buf); Reported-by: Dan Carpenter Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index df11c091e094..a8dc2c033410 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -222,12 +222,18 @@ static int wfx_send_pdata_pds(struct wfx_dev *wdev) if (ret) { dev_err(wdev->dev, "can't load PDS file %s\n", wdev->pdata.file_pds); - return ret; + goto err1; } tmp_buf = kmemdup(pds->data, pds->size, GFP_KERNEL); + if (!tmp_buf) { + ret = -ENOMEM; + goto err2; + } ret = wfx_send_pds(wdev, tmp_buf, pds->size); kfree(tmp_buf); +err2: release_firmware(pds); +err1: return ret; } -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 4/8] staging: wfx: wfx_init_common() returns NULL on error
From: Jérôme Pouiller Smatch complains: bus_spi.c:228 wfx_spi_probe() warn: 'bus->core' could be an error pointer bus_sdio.c:221 wfx_sdio_probe() warn: 'bus->core' could be an error pointer bus->core contains the result of wfx_init_common(). With this patch, wfx_init_common() returns a valid pointer or NULL. Reported-by: Dan Carpenter Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index a8dc2c033410..e7bc1988124a 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -309,7 +309,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, wdev->pdata.gpio_wakeup = devm_gpiod_get_optional(dev, "wakeup", GPIOD_OUT_LOW); if (IS_ERR(wdev->pdata.gpio_wakeup)) - return ERR_CAST(wdev->pdata.gpio_wakeup); + return NULL; if (wdev->pdata.gpio_wakeup) gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup"); -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Greetings to you,
Attention; I am a CHRISTIAN ARTWELL working with BANQUE POPULAIRE S.A TOGO as their SECRETARIAT GENERAL FOREIGN REMITTANCE DEPT, an account officer to late Engineer George, May I inform you that an amount of $9.6 million also (150 kg of Gold) with our bank will be moved on your name as the beneficiary I need your help to receive this money and you will get 50% of the money while I get 50% You will receive this amount through a bank wire transfer. for more details Your quick response will be highly appreciated. CHRISTIAN ARTWELL ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: comedi: check validity of wMaxPacketSize of usb endpoints found
On 09/10/20 9:46 pm, Anant Thazhemadam wrote: > While finding usb endpoints in vmk80xx_find_usb_endpoints(), check if > wMaxPacketSize = 0 for the endpoints found. > > Some devices have isochronous endpoints that have wMaxPacketSize = 0 > (as required by the USB-2 spec). > However, since this doesn't apply here, wMaxPacketSize = 0 can be > considered to be invalid. > > Reported-by: syzbot+009f546aa1370056b...@syzkaller.appspotmail.com > Tested-by: syzbot+009f546aa1370056b...@syzkaller.appspotmail.com > Signed-off-by: Anant Thazhemadam > --- > The error (as detected by syzbot) is generated in > vmk80xx_write_packet() (which is called in vmk80xx_reset_device()) when > it tries to assign devpriv->usb_tx_buf[0] = cmd. > > This NULL pointer dereference issue arises because > size = usb_endpoint_maxp(devpriv->ep_tx) = 0. > > This can be traced back to vmk80xx_find_usb_endpoints(), where the usb > endpoints are found, and assigned accordingly. > (For some more insight, in vmk80xx_find_usb_endpoints(), > if one of intf->cur_altsetting->iface_desc->endpoints' desc value = 0, > and consequently this endpoint is assigned to devpriv->ep_tx, > this issue gets triggered.) > > Checking if the wMaxPacketSize of an endpoint is invalid and returning > an error value accordingly, seems to fix the error. > > We could also alternatively perform this checking (if the size is 0 or not) > in vmk80xx_reset_device() itself, but it only seemed like covering up the > issue > at that place, rather than fixing it, so I wasn't sure that was any better. > > However, if I'm not wrong, this might end up causing the probe to fail, and > I'm > not sure if that's the right thing to do in cases like this, and if it isn't > I'd > like some input on what exactly is the required course of action in cases > like this. > > drivers/staging/comedi/drivers/vmk80xx.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/staging/comedi/drivers/vmk80xx.c > b/drivers/staging/comedi/drivers/vmk80xx.c > index 65dc6c51037e..cb0a965d3c37 100644 > --- a/drivers/staging/comedi/drivers/vmk80xx.c > +++ b/drivers/staging/comedi/drivers/vmk80xx.c > @@ -667,6 +667,9 @@ static int vmk80xx_find_usb_endpoints(struct > comedi_device *dev) > if (!devpriv->ep_rx || !devpriv->ep_tx) > return -ENODEV; > > + if(!usb_endpoint_maxp(devpriv->ep_rx) || > !usb_endpoint_maxp(devpriv->ep_tx)) > + return -EINVAL; > + > return 0; > } > The patch in this mail has a coding style issue (that I thought I had fixed), and was sent out by mistake. Please ignore this mail. Apologies. Thanks, Anant ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: comedi: check validity of wMaxPacketSize of usb endpoints found
While finding usb endpoints in vmk80xx_find_usb_endpoints(), check if wMaxPacketSize = 0 for the endpoints found. Some devices have isochronous endpoints that have wMaxPacketSize = 0 (as required by the USB-2 spec). However, since this doesn't apply here, wMaxPacketSize = 0 can be considered to be invalid. Reported-by: syzbot+009f546aa1370056b...@syzkaller.appspotmail.com Tested-by: syzbot+009f546aa1370056b...@syzkaller.appspotmail.com Signed-off-by: Anant Thazhemadam --- The error (as detected by syzbot) is generated in vmk80xx_write_packet() (which is called in vmk80xx_reset_device()) when it tries to assign devpriv->usb_tx_buf[0] = cmd. This NULL pointer dereference issue arises because size = usb_endpoint_maxp(devpriv->ep_tx) = 0. This can be traced back to vmk80xx_find_usb_endpoints(), where the usb endpoints are found, and assigned accordingly. (For some more insight, in vmk80xx_find_usb_endpoints(), if one of intf->cur_altsetting->iface_desc->endpoints' desc value = 0, and consequently this endpoint is assigned to devpriv->ep_tx, this issue gets triggered.) Checking if the wMaxPacketSize of an endpoint is invalid and returning an error value accordingly, seems to fix the error. We could also alternatively perform this checking (if the size is 0 or not) in vmk80xx_reset_device() itself, but it only seemed like covering up the issue at that place, rather than fixing it, so I wasn't sure that was any better. However, if I'm not wrong, this might end up causing the probe to fail, and I'm not sure if that's the right thing to do in cases like this, and if it isn't I'd like some input on what exactly is the required course of action in cases like this. drivers/staging/comedi/drivers/vmk80xx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 65dc6c51037e..cb0a965d3c37 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -667,6 +667,9 @@ static int vmk80xx_find_usb_endpoints(struct comedi_device *dev) if (!devpriv->ep_rx || !devpriv->ep_tx) return -ENODEV; + if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx)) + return -EINVAL; + return 0; } -- 2.25.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: comedi: check validity of wMaxPacketSize of usb endpoints found
While finding usb endpoints in vmk80xx_find_usb_endpoints(), check if wMaxPacketSize = 0 for the endpoints found. Some devices have isochronous endpoints that have wMaxPacketSize = 0 (as required by the USB-2 spec). However, since this doesn't apply here, wMaxPacketSize = 0 can be considered to be invalid. Reported-by: syzbot+009f546aa1370056b...@syzkaller.appspotmail.com Tested-by: syzbot+009f546aa1370056b...@syzkaller.appspotmail.com Signed-off-by: Anant Thazhemadam --- The error (as detected by syzbot) is generated in vmk80xx_write_packet() (which is called in vmk80xx_reset_device()) when it tries to assign devpriv->usb_tx_buf[0] = cmd. This NULL pointer dereference issue arises because size = usb_endpoint_maxp(devpriv->ep_tx) = 0. This can be traced back to vmk80xx_find_usb_endpoints(), where the usb endpoints are found, and assigned accordingly. (For some more insight, in vmk80xx_find_usb_endpoints(), if one of intf->cur_altsetting->iface_desc->endpoints' desc value = 0, and consequently this endpoint is assigned to devpriv->ep_tx, this issue gets triggered.) Checking if the wMaxPacketSize of an endpoint is invalid and returning an error value accordingly, seems to fix the error. We could also alternatively perform this checking (if the size is 0 or not) in vmk80xx_reset_device() itself, but it only seemed like covering up the issue at that place, rather than fixing it, so I wasn't sure that was any better. However, if I'm not wrong, this might end up causing the probe to fail, and I'm not sure if that's the right thing to do in cases like this, and if it isn't I'd like some input on what exactly is the required course of action in cases like this. drivers/staging/comedi/drivers/vmk80xx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 65dc6c51037e..cb0a965d3c37 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -667,6 +667,9 @@ static int vmk80xx_find_usb_endpoints(struct comedi_device *dev) if (!devpriv->ep_rx || !devpriv->ep_tx) return -ENODEV; + if(!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx)) + return -EINVAL; + return 0; } -- 2.25.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 00/11] Introduce Simple atomic counters
This patch series is a result of discussion at the refcount_t BOF the Linux Plumbers Conference. In this discussion, we identified a need for looking closely and investigating atomic_t usages in the kernel when it is used strictly as a counter without it controlling object lifetimes and state changes. There are a number of atomic_t usages in the kernel where atomic_t api is used strictly for counting and not for managing object lifetime. In some cases, atomic_t might not even be needed. The purpose of these counters is to clearly differentiate atomic_t counters from atomic_t usages that guard object lifetimes, hence prone to overflow and underflow errors. It allows tools that scan for underflow and overflow on atomic_t usages to detect overflow and underflows to scan just the cases that are prone to errors. Simple atomic counters api provides interfaces for simple atomic counters that just count, and don't guard resource lifetimes. The interfaces are built on top of atomic_t api, providing a smaller subset of atomic_t interfaces necessary to support simple counters. Counter wraps around to INT_MIN when it overflows and should not be used to guard resource lifetimes, device usage and open counts that control state changes, and pm states. Overflowing to INT_MIN is consistent with the atomic_t api, which it is built on top of. Using counter_atomic* to guard lifetimes could lead to use-after free when it overflows and undefined behavior when used to manage state changes and device usage/open states. This patch series introduces Simple atomic counters. Counter atomic ops leverage atomic_t and provide a sub-set of atomic_t ops. In addition this patch series converts a few drivers to use the new api. The following criteria is used for select variables for conversion: 1. Variable doesn't guard object lifetimes, manage state changes e.g: device usage counts, device open counts, and pm states. 2. Variable is used for stats and counters. 3. The conversion doesn't change the overflow behavior. Note: Would like to get this into Linux 5.10-rc1 so we can continue updating drivers that can be updated to use this API. If this all looks good, Kees, would you like to take this through your tree or would you like to take this through mine. Changes since Patch v2: -- Thanks for reviews and reviewed-by, and Acked-by tags. Updated the patches with the tags. -- Minor changes to address Greg's comment to remove default from Kconfig -- Added Copyrights to new files Updates to address comments on v2 from Kees Cook -- Updated Patch 1/11 to make clear that the counter wraps around to INT_MIN and that this behavior is consistent with the atomic_t api, on which this counter built api built on top of. -- Other patch change logs updated with the correct wrap around behavior. -- Patch 1/11 is updated to add tests with constants for overflow and underflow. -- Patch 8/11 - added inits for the stat counters -- Patch 10/11 - fixes the vmci_num_guest_devices != 0 to >0 which is safer than checking for !=0. Changes since Patch v1 -- Thanks for reviews and reviewed-by, and Acked-by tags. Updated the patches with the tags. -- Addressed Kees's and Joel's comments: 1. Removed dec_return interfaces 2. Removed counter_simple interfaces to be added later with changes to drivers that use them (if any). Changes since RFC: -- Thanks for reviews and reviewed-by, and Acked-by tags. Updated the patches with the tags. -- Addressed Kees's comments: 1. Non-atomic counters renamed to counter_simple32 and counter_simple64 to clearly indicate size. 2. Added warning for counter_simple* usage and it should be used only when there is no need for atomicity. 3. Renamed counter_atomic to counter_atomic32 to clearly indicate size. 4. Renamed counter_atomic_long to counter_atomic64 and it now uses atomic64_t ops and indicates size. 5. Test updated for the API renames. 6. Added helper functions for test results printing 7. Verified that the test module compiles in kunit env. and test module can be loaded to run the test. 8. Updated Documentation to reflect the intent to make the API restricted so it can never be used to guard object lifetimes and state management. I left _return ops for now, inc_return is necessary for now as per the discussion we had on this topic. -- Updated driver patches with API name changes. -- We discussed if binder counters can be non-atomic. For now I left them the same as the RFC patch - using counter_atomic32 -- Unrelated to this patch series: The patch series review uncovered improvements could be made to test_async_driver_probe and vmw_vmci/vmci_guest. I will track these for fixing later. Shuah Khan (11): counters: Introduce counter_atomic* counters selftests:lib:test_counters: add new test for counters drivers/base: convert deferred_trigger_count and probe_count to counter_atomic32
[PATCH v3 07/11] drivers/android/binder: convert stats, transaction_log to counter_atomic32
counter_atomic* is introduced to be used when a variable is used as a simple counter and doesn't guard object lifetimes. This clearly differentiates atomic_t usages that guard object lifetimes. counter_atomic* variables wrap around to INT_MIN when it overflows and should not be used to guard resource lifetimes, device usage and open counts that control state changes, and pm states. stats tracks per-process binder statistics. Unsure if there is a chance of this overflowing, other than stats getting reset to 0. Convert it to use counter_atomic. binder_transaction_log:cur is used to keep track of the current log entry location. Overflow is handled in the code. Since it is used as a counter, convert it to use counter_atomic32. This conversion doesn't change the overflow wrap around behavior. Reviewed-by: Joel Fernandes (Google) Reviewed-by: Kees Cook Reviewed-by: Christian Brauner Signed-off-by: Shuah Khan --- drivers/android/binder.c | 41 --- drivers/android/binder_internal.h | 3 ++- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index f936530a19b0..52175cd6a62b 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -172,22 +173,22 @@ enum binder_stat_types { }; struct binder_stats { - atomic_t br[_IOC_NR(BR_FAILED_REPLY) + 1]; - atomic_t bc[_IOC_NR(BC_REPLY_SG) + 1]; - atomic_t obj_created[BINDER_STAT_COUNT]; - atomic_t obj_deleted[BINDER_STAT_COUNT]; + struct counter_atomic32 br[_IOC_NR(BR_FAILED_REPLY) + 1]; + struct counter_atomic32 bc[_IOC_NR(BC_REPLY_SG) + 1]; + struct counter_atomic32 obj_created[BINDER_STAT_COUNT]; + struct counter_atomic32 obj_deleted[BINDER_STAT_COUNT]; }; static struct binder_stats binder_stats; static inline void binder_stats_deleted(enum binder_stat_types type) { - atomic_inc(_stats.obj_deleted[type]); + counter_atomic32_inc(_stats.obj_deleted[type]); } static inline void binder_stats_created(enum binder_stat_types type) { - atomic_inc(_stats.obj_created[type]); + counter_atomic32_inc(_stats.obj_created[type]); } struct binder_transaction_log binder_transaction_log; @@ -197,7 +198,7 @@ static struct binder_transaction_log_entry *binder_transaction_log_add( struct binder_transaction_log *log) { struct binder_transaction_log_entry *e; - unsigned int cur = atomic_inc_return(>cur); + unsigned int cur = counter_atomic32_inc_return(>cur); if (cur >= ARRAY_SIZE(log->entry)) log->full = true; @@ -3615,9 +3616,9 @@ static int binder_thread_write(struct binder_proc *proc, ptr += sizeof(uint32_t); trace_binder_command(cmd); if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { - atomic_inc(_stats.bc[_IOC_NR(cmd)]); - atomic_inc(>stats.bc[_IOC_NR(cmd)]); - atomic_inc(>stats.bc[_IOC_NR(cmd)]); + counter_atomic32_inc(_stats.bc[_IOC_NR(cmd)]); + counter_atomic32_inc(>stats.bc[_IOC_NR(cmd)]); + counter_atomic32_inc(>stats.bc[_IOC_NR(cmd)]); } switch (cmd) { case BC_INCREFS: @@ -4047,9 +4048,9 @@ static void binder_stat_br(struct binder_proc *proc, { trace_binder_return(cmd); if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) { - atomic_inc(_stats.br[_IOC_NR(cmd)]); - atomic_inc(>stats.br[_IOC_NR(cmd)]); - atomic_inc(>stats.br[_IOC_NR(cmd)]); + counter_atomic32_inc(_stats.br[_IOC_NR(cmd)]); + counter_atomic32_inc(>stats.br[_IOC_NR(cmd)]); + counter_atomic32_inc(>stats.br[_IOC_NR(cmd)]); } } @@ -5841,7 +5842,7 @@ static void print_binder_stats(struct seq_file *m, const char *prefix, BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != ARRAY_SIZE(binder_command_strings)); for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { - int temp = atomic_read(>bc[i]); + int temp = counter_atomic32_read(>bc[i]); if (temp) seq_printf(m, "%s%s: %d\n", prefix, @@ -5851,7 +5852,7 @@ static void print_binder_stats(struct seq_file *m, const char *prefix, BUILD_BUG_ON(ARRAY_SIZE(stats->br) != ARRAY_SIZE(binder_return_strings)); for (i = 0; i < ARRAY_SIZE(stats->br); i++) { - int temp = atomic_read(>br[i]); + int temp = counter_atomic32_read(>br[i]); if (temp) seq_printf(m, "%s%s: %d\n", prefix, @@ -5863,8 +5864,8 @@ static void print_binder_stats(struct seq_file *m, const char *prefix,
Re: [PATCH] staging: octeon: repair "fixed-link" support
Hi Alexander, I love your patch! Yet something to improve: [auto build test ERROR on staging/staging-testing] url: https://github.com/0day-ci/linux/commits/Alexander-A-Sverdlin/staging-octeon-repair-fixed-link-support/20201009-174828 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 76c3bdd67d27289b9e407113821eab2a70bbcca6 config: arm64-randconfig-r033-20201009 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 4cfc4025cc1433ca5ef1c526053fc9c4bfe64109) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/0day-ci/linux/commit/99d271d0a7dda48d064e12957a8846907220bf44 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Alexander-A-Sverdlin/staging-octeon-repair-fixed-link-support/20201009-174828 git checkout 99d271d0a7dda48d064e12957a8846907220bf44 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): >> drivers/staging/octeon/ethernet.c:897:5: error: use of undeclared identifier >> 'r' r = of_phy_register_fixed_link(priv->of_node); ^ drivers/staging/octeon/ethernet.c:898:9: error: use of undeclared identifier 'r' if (r) { ^ drivers/staging/octeon/ethernet.c:898:9: error: use of undeclared identifier 'r' drivers/staging/octeon/ethernet.c:898:9: error: use of undeclared identifier 'r' >> drivers/staging/octeon/ethernet.c:900:27: error: no member named 'ipd_port' >> in 'struct octeon_ethernet' interface, priv->ipd_port); ^ 5 errors generated. vim +/r +897 drivers/staging/octeon/ethernet.c 692 693 pip = pdev->dev.of_node; 694 if (!pip) { 695 pr_err("Error: No 'pip' in /aliases\n"); 696 return -EINVAL; 697 } 698 699 cvm_oct_configure_common_hw(); 700 701 cvmx_helper_initialize_packet_io_global(); 702 703 if (receive_group_order) { 704 if (receive_group_order > 4) 705 receive_group_order = 4; 706 pow_receive_groups = (1 << (1 << receive_group_order)) - 1; 707 } else { 708 pow_receive_groups = BIT(pow_receive_group); 709 } 710 711 /* Change the input group for all ports before input is enabled */ 712 num_interfaces = cvmx_helper_get_number_of_interfaces(); 713 for (interface = 0; interface < num_interfaces; interface++) { 714 int num_ports = cvmx_helper_ports_on_interface(interface); 715 int port; 716 717 for (port = cvmx_helper_get_ipd_port(interface, 0); 718 port < cvmx_helper_get_ipd_port(interface, num_ports); 719 port++) { 720 union cvmx_pip_prt_tagx pip_prt_tagx; 721 722 pip_prt_tagx.u64 = 723 cvmx_read_csr(CVMX_PIP_PRT_TAGX(port)); 724 725 if (receive_group_order) { 726 int tag_mask; 727 728 /* We support only 16 groups at the moment, so 729 * always disable the two additional "hidden" 730 * tag_mask bits on CN68XX. 731 */ 732 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) 733 pip_prt_tagx.u64 |= 0x3ull << 44; 734 735 tag_mask = ~((1 << receive_group_order) - 1); 736 pip_prt_tagx.s.grptagbase = 0; 737 pip_prt_tagx.s.grptagmask = tag_mask; 738 pip_prt_tagx.s.grptag = 1; 739 pip_prt_tagx.s.tag_mode = 0; 740 pip_prt_tagx.s.inc_prt_flag = 1; 741 pip_prt_tagx.
Re: [PATCH] staging: octeon: repair "fixed-link" support
On Fri, Oct 09, 2020 at 11:47:39AM +0200, Alexander A Sverdlin wrote: > From: Alexander Sverdlin > > The PHYs must be registered once in device probe function, not in device > open callback because it's only possible to register them once. > > Fixes: a25e278020 ("staging: octeon: support fixed-link phys") > Signed-off-by: Alexander Sverdlin Looks like it breaks the build, please fix up and test your patches when sending them out next time. thanks, greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 07/11] drivers/android/binder: convert stats, transaction_log to counter_atomic32
On Tue, Oct 06, 2020 at 02:44:38PM -0600, Shuah Khan wrote: > counter_atomic* is introduced to be used when a variable is used as > a simple counter and doesn't guard object lifetimes. This clearly > differentiates atomic_t usages that guard object lifetimes. > > counter_atomic* variables will wrap around to 0 when it overflows and > should not be used to guard resource lifetimes, device usage and > open counts that control state changes, and pm states. > > stats tracks per-process binder statistics. Unsure if there is a chance > of this overflowing, other than stats getting reset to 0. Convert it to > use counter_atomic. > > binder_transaction_log:cur is used to keep track of the current log entry > location. Overflow is handled in the code. Since it is used as a > counter, convert it to use counter_atomic32. > > This conversion doesn't change the overflow wrap around behavior. > > Signed-off-by: Shuah Khan > Reviewed-by: Joel Fernandes (Google) > Reviewed-by: Kees Cook > --- Thanks! Reviewed-by: Christian Brauner ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] stating: octeon: Drop on uncorrectable alignment or FCS error
On Fri, Oct 09, 2020 at 11:46:05AM +0200, Alexander A Sverdlin wrote: > --- a/drivers/staging/octeon/ethernet-rx.c > +++ b/drivers/staging/octeon/ethernet-rx.c > @@ -69,14 +69,16 @@ static inline int cvm_oct_check_rcv_error(struct cvmx_wqe > *work) > else > port = work->word1.cn38xx.ipprt; > > - if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64)) { > + if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64)) > /* >* Ignore length errors on min size packets. Some >* equipment incorrectly pads packets to 64+4FCS >* instead of 60+4FCS. Note these packets still get >* counted as frame errors. >*/ > - } else if (work->word2.snoip.err_code == 5 || > + return 0; > + > + if (work->word2.snoip.err_code == 5 || > work->word2.snoip.err_code == 7) { This line is indented to match the old code and it no longer matches. (Please update the whitespace). > /* >* We received a packet with either an alignment error regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/2] Fix new warnings at linux-next
There are some file renames at linux-next that are causing some new documentation warnings. Address them. Mauro Carvalho Chehab (2): MAINTAINERS: fix broken doc refs due to yaml conversion crypto: sun8x-ce*: update entries to its documentation Documentation/devicetree/bindings/clock/hi6220-clock.txt | 2 +- MAINTAINERS | 9 - drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c| 2 +- drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c| 2 +- drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c| 2 +- .../devicetree/bindings/net/wireless/silabs,wfx.yaml | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) -- 2.26.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/2] MAINTAINERS: fix broken doc refs due to yaml conversion
Several *.txt files got converted to yaml. Update their references at MAINTAINERS file accordingly. Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/clock/hi6220-clock.txt | 2 +- MAINTAINERS | 9 - .../devicetree/bindings/net/wireless/silabs,wfx.yaml | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/hi6220-clock.txt b/Documentation/devicetree/bindings/clock/hi6220-clock.txt index ef3deb7b86ea..17ac4a3dd26a 100644 --- a/Documentation/devicetree/bindings/clock/hi6220-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi6220-clock.txt @@ -4,7 +4,7 @@ Clock control registers reside in different Hi6220 system controllers, please refer the following document to know more about the binding rules for these system controllers: -Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +Documentation/devicetree/bindings/arm/hisilicon/hisilicon.yaml Required Properties: diff --git a/MAINTAINERS b/MAINTAINERS index d55f55d89509..7b1183aaafe5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -978,7 +978,7 @@ M: Michael Hennerich L: linux-...@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt +F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml F: drivers/iio/adc/ad7768-1.c ANALOG DEVICES INC AD7780 DRIVER @@ -3867,7 +3867,7 @@ M:Roger Quadros L: linux-...@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git -F: Documentation/devicetree/bindings/usb/cdns-usb3.txt +F: Documentation/devicetree/bindings/usb/cdns,usb3.yaml F: drivers/usb/cdns3/ CADET FM/AM RADIO RECEIVER DRIVER @@ -7918,7 +7918,7 @@ HISILICON LPC BUS DRIVER M: john.ga...@huawei.com S: Maintained W: http://www.hisilicon.com -F: Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt +F: Documentation/devicetree/bindings/arm/hisilicon/low-pin-count.yaml F: drivers/bus/hisi_lpc.c HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) @@ -14911,7 +14911,6 @@ RENESAS ETHERNET DRIVERS R: Sergei Shtylyov L: net...@vger.kernel.org L: linux-renesas-...@vger.kernel.org -F: Documentation/devicetree/bindings/net/renesas,*.txt F: Documentation/devicetree/bindings/net/renesas,*.yaml F: drivers/net/ethernet/renesas/ F: include/linux/sh_eth.h @@ -18107,7 +18106,7 @@ M: Yu Chen M: Binghui Wang L: linux-...@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt +F: Documentation/devicetree/bindings/phy/hisilicon,hi3660-usb3.yaml F: drivers/phy/hisilicon/phy-hi3660-usb3.c USB ISP116X DRIVER diff --git a/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml b/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml index 43b5630c0407..510edd12ed19 100644 --- a/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml +++ b/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml @@ -24,7 +24,7 @@ description: In addition, it is recommended to declare a mmc-pwrseq on SDIO host above WFx. Without it, you may encounter issues with warm boot. The mmc-pwrseq should be compatible with mmc-pwrseq-simple. Please consult -Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt for more +Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml for more information. For SPI':' -- 2.26.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: octeon: repair "fixed-link" support
Hi Alexander, I love your patch! Yet something to improve: [auto build test ERROR on staging/staging-testing] url: https://github.com/0day-ci/linux/commits/Alexander-A-Sverdlin/staging-octeon-repair-fixed-link-support/20201009-174828 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 76c3bdd67d27289b9e407113821eab2a70bbcca6 config: x86_64-allyesconfig (attached as .config) compiler: gcc-9 (Debian 9.3.0-15) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/99d271d0a7dda48d064e12957a8846907220bf44 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Alexander-A-Sverdlin/staging-octeon-repair-fixed-link-support/20201009-174828 git checkout 99d271d0a7dda48d064e12957a8846907220bf44 # save the attached .config to linux build tree make W=1 ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): drivers/staging/octeon/ethernet.c: In function 'cvm_oct_probe': >> drivers/staging/octeon/ethernet.c:897:5: error: 'r' undeclared (first use in >> this function); did you mean 'rq'? 897 | r = of_phy_register_fixed_link(priv->of_node); | ^ | rq drivers/staging/octeon/ethernet.c:897:5: note: each undeclared identifier is reported only once for each function it appears in >> drivers/staging/octeon/ethernet.c:900:25: error: 'struct octeon_ethernet' >> has no member named 'ipd_port' 900 | interface, priv->ipd_port); | ^~ vim +897 drivers/staging/octeon/ethernet.c 692 693 pip = pdev->dev.of_node; 694 if (!pip) { 695 pr_err("Error: No 'pip' in /aliases\n"); 696 return -EINVAL; 697 } 698 699 cvm_oct_configure_common_hw(); 700 701 cvmx_helper_initialize_packet_io_global(); 702 703 if (receive_group_order) { 704 if (receive_group_order > 4) 705 receive_group_order = 4; 706 pow_receive_groups = (1 << (1 << receive_group_order)) - 1; 707 } else { 708 pow_receive_groups = BIT(pow_receive_group); 709 } 710 711 /* Change the input group for all ports before input is enabled */ 712 num_interfaces = cvmx_helper_get_number_of_interfaces(); 713 for (interface = 0; interface < num_interfaces; interface++) { 714 int num_ports = cvmx_helper_ports_on_interface(interface); 715 int port; 716 717 for (port = cvmx_helper_get_ipd_port(interface, 0); 718 port < cvmx_helper_get_ipd_port(interface, num_ports); 719 port++) { 720 union cvmx_pip_prt_tagx pip_prt_tagx; 721 722 pip_prt_tagx.u64 = 723 cvmx_read_csr(CVMX_PIP_PRT_TAGX(port)); 724 725 if (receive_group_order) { 726 int tag_mask; 727 728 /* We support only 16 groups at the moment, so 729 * always disable the two additional "hidden" 730 * tag_mask bits on CN68XX. 731 */ 732 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) 733 pip_prt_tagx.u64 |= 0x3ull << 44; 734 735 tag_mask = ~((1 << receive_group_order) - 1); 736 pip_prt_tagx.s.grptagbase = 0; 737 pip_prt_tagx.s.grptagmask = tag_mask; 738 pip_prt_tagx.s.grptag = 1; 739 pip_prt_tagx.s.tag_mode = 0; 740 pip_prt_tagx.s.inc_prt_flag = 1; 741 pip_prt_tagx.s.ip6_dprt_flag= 1; 742 pip_prt_tagx.s.ip4_dprt_flag= 1; 743 pip_prt_tagx.s.ip6_sprt_flag= 1; 744 pip_prt_tagx.s.ip4_sprt_flag= 1; 745 pip_prt_tagx.s.ip6_dst_flag = 1; 746 pip_prt_tagx.s.ip4_dst_flag = 1; 747 pip_prt_tagx.s.ip6_src_flag = 1; 748 pip_prt_tagx.s.ip4_src_flag = 1; 749
Re: [PATCH] staging: octeon: Drop on uncorrectable alignment or FCS error
Hello Greg, On 10/01/2020 13:48, Greg Kroah-Hartman wrote: > On Wed, Jan 08, 2020 at 05:10:42PM +0100, Alexander X Sverdlin wrote: >> From: Alexander Sverdlin >> >> Currently in case of alignment or FCS error if the packet cannot be >> corrected it's still not dropped. Report the error properly and drop the >> packet while making the code around a little bit more readable. >> >> Fixes: 80ff0fd3ab ("Staging: Add octeon-ethernet driver files.") >> Signed-off-by: Alexander Sverdlin >> --- >> drivers/staging/octeon/ethernet-rx.c | 18 +- >> 1 file changed, 9 insertions(+), 9 deletions(-) > > This driver is now deleted from the tree, sorry. Now that the driver is restored, would you please consider this patch again? -- Best regards, Alexander Sverdlin. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] stating: octeon: Drop on uncorrectable alignment or FCS error
From: Alexander Sverdlin Currently in case of alignment or FCS error if the packet cannot be corrected it's still not dropped. Report the error properly and drop the packet while making the code around a little bit more readable. Signed-off-by: Alexander Sverdlin Fixes: 80ff0fd3ab ("Staging: Add octeon-ethernet driver files.") Change-Id: Ie1fadcc57cb5e221cf3e83c169b53a5533b8edff --- drivers/staging/octeon/ethernet-rx.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index 2c16230..b22f7be 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -69,14 +69,16 @@ static inline int cvm_oct_check_rcv_error(struct cvmx_wqe *work) else port = work->word1.cn38xx.ipprt; - if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64)) { + if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64)) /* * Ignore length errors on min size packets. Some * equipment incorrectly pads packets to 64+4FCS * instead of 60+4FCS. Note these packets still get * counted as frame errors. */ - } else if (work->word2.snoip.err_code == 5 || + return 0; + + if (work->word2.snoip.err_code == 5 || work->word2.snoip.err_code == 7) { /* * We received a packet with either an alignment error @@ -125,14 +127,12 @@ static inline int cvm_oct_check_rcv_error(struct cvmx_wqe *work) return 1; } } - } else { - printk_ratelimited("Port %d receive error code %d, packet dropped\n", - port, work->word2.snoip.err_code); - cvm_oct_free_work(work); - return 1; } - return 0; + printk_ratelimited("Port %d receive error code %d, packet dropped\n", + port, work->word2.snoip.err_code); + cvm_oct_free_work(work); + return 1; } static void copy_segments_to_skb(struct cvmx_wqe *work, struct sk_buff *skb) -- 2.10.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel