* [PATCH] pstore: fix incorrect persistent ram buffer mapping @ 2018-09-12 3:36 Bin Yang 2018-09-12 17:44 ` Kees Cook 0 siblings, 1 reply; 4+ messages in thread From: Bin Yang @ 2018-09-12 3:36 UTC (permalink / raw) To: keescook, anton, ccross, tony.luck, linux-kernel, bin.yang persistent_ram_vmap() returns the page start vaddr. persistent_ram_iomap() supports non-page-aligned mapping. persistent_ram_buffer_map() always adds offset-in-page to the vaddr returned from these two functions, which causes incorrect mapping of non-page-aligned persistent ram buffer. Signed-off-by: Bin Yang <bin.yang@intel.com> --- fs/pstore/ram_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 951a14e..7c05fdd 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -429,7 +429,7 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size, vaddr = vmap(pages, page_count, VM_MAP, prot); kfree(pages); - return vaddr; + return vaddr + offset_in_page(start); } static void *persistent_ram_iomap(phys_addr_t start, size_t size, @@ -468,7 +468,7 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, return -ENOMEM; } - prz->buffer = prz->vaddr + offset_in_page(start); + prz->buffer = prz->vaddr; prz->buffer_size = size - sizeof(struct persistent_ram_buffer); return 0; @@ -515,7 +515,7 @@ void persistent_ram_free(struct persistent_ram_zone *prz) if (prz->vaddr) { if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { - vunmap(prz->vaddr); + vunmap(prz->vaddr - offset_in_page(prz->paddr)); } else { iounmap(prz->vaddr); release_mem_region(prz->paddr, prz->size); -- 2.7.4 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] pstore: fix incorrect persistent ram buffer mapping 2018-09-12 3:36 [PATCH] pstore: fix incorrect persistent ram buffer mapping Bin Yang @ 2018-09-12 17:44 ` Kees Cook 2018-09-13 1:21 ` Yang, Bin 0 siblings, 1 reply; 4+ messages in thread From: Kees Cook @ 2018-09-12 17:44 UTC (permalink / raw) To: Bin Yang; +Cc: Anton Vorontsov, Colin Cross, Tony Luck, LKML On Tue, Sep 11, 2018 at 8:36 PM, Bin Yang <bin.yang@intel.com> wrote: > persistent_ram_vmap() returns the page start vaddr. > persistent_ram_iomap() supports non-page-aligned mapping. Oh, yes, good catch. This should probably be explicitly mentioned in comments for these functions. > persistent_ram_buffer_map() always adds offset-in-page to the vaddr > returned from these two functions, which causes incorrect mapping of > non-page-aligned persistent ram buffer. How did you find this problem, and/or how was the problem manifesting? > Signed-off-by: Bin Yang <bin.yang@intel.com> > --- > fs/pstore/ram_core.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c > index 951a14e..7c05fdd 100644 > --- a/fs/pstore/ram_core.c > +++ b/fs/pstore/ram_core.c > @@ -429,7 +429,7 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size, > vaddr = vmap(pages, page_count, VM_MAP, prot); > kfree(pages); > > - return vaddr; > + return vaddr + offset_in_page(start); > } > > static void *persistent_ram_iomap(phys_addr_t start, size_t size, > @@ -468,7 +468,7 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, > return -ENOMEM; > } > > - prz->buffer = prz->vaddr + offset_in_page(start); > + prz->buffer = prz->vaddr; > prz->buffer_size = size - sizeof(struct persistent_ram_buffer); > > return 0; > @@ -515,7 +515,7 @@ void persistent_ram_free(struct persistent_ram_zone *prz) > > if (prz->vaddr) { > if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { > - vunmap(prz->vaddr); > + vunmap(prz->vaddr - offset_in_page(prz->paddr)); > } else { > iounmap(prz->vaddr); > release_mem_region(prz->paddr, prz->size); > -- > 2.7.4 > Regardless, yes, this patch looks correct. Thanks! I'll add it to my tree. -Kees -- Kees Cook Pixel Security ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] pstore: fix incorrect persistent ram buffer mapping 2018-09-12 17:44 ` Kees Cook @ 2018-09-13 1:21 ` Yang, Bin 2018-09-13 4:25 ` Kees Cook 0 siblings, 1 reply; 4+ messages in thread From: Yang, Bin @ 2018-09-13 1:21 UTC (permalink / raw) To: keescook; +Cc: ccross, Luck, Tony, linux-kernel, anton On Wed, 2018-09-12 at 10:44 -0700, Kees Cook wrote: > On Tue, Sep 11, 2018 at 8:36 PM, Bin Yang <bin.yang@intel.com> wrote: > > persistent_ram_vmap() returns the page start vaddr. > > persistent_ram_iomap() supports non-page-aligned mapping. > > Oh, yes, good catch. This should probably be explicitly mentioned in > comments for these functions. > > > persistent_ram_buffer_map() always adds offset-in-page to the vaddr > > returned from these two functions, which causes incorrect mapping of > > non-page-aligned persistent ram buffer. > > How did you find this problem, and/or how was the problem manifesting? By default, ftrace_size is 4096 and max_ftrace_cnt is nr_cpu_ids. The zone_sz in ramoops_init_przs() is 4096/nr_cpu_ids which might not be page aligned. If the offset-in-page > 2048, the vaddr will be in next page. If the next page is not mapped, it will cause kernel panic. I just wanted to enable this driver on my board and did not change the default value of ftrace_size. It resulted kernel panic as below: [ 0.074231] BUG: unable to handle kernel paging request at ffffa19e0081b000 [ 0.074498] IP: persistent_ram_new+0x1f8/0x39f [ 0.074651] PGD 272eb7067 P4D 272eb7067 PUD 272eb8067 PMD 2721da067 PTE 0 [ 0.074886] Oops: 0000 [#1] PREEMPT SMP NOPTI [ 0.075000] Modules linked in: [ 0.075000] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G U 4.14.67-94.pk414-sos #4 [ 0.075000] task: ffff96ae32f76040 task.stack: ffff96ae32f78000 [ 0.075000] RIP: 0010:persistent_ram_new+0x1f8/0x39f [ 0.075000] RSP: 0000:ffff96ae32f7bc00 EFLAGS: 00010246 [ 0.075000] RAX: ffffa19e0081a800 RBX: 0000000000040e43 RCX: ffffffffb38a7380 [ 0.075000] RDX: 0000000080000001 RSI: 0000000000000100 RDI: 00000000ffffffff [ 0.075000] RBP: ffff96ae32f7bc40 R08: ffff96ae32e7b0b0 R09: 0000000000000000 [ 0.075000] R10: 0000000000000000 R11: ffff96ae321dd900 R12: 00000000000003f4 [ 0.075000] R13: ffff96ae321ddf00 R14: ffffa19e0081b000 R15: 0000000000000000 [ 0.075000] FS: 0000000000000000(0000) GS:ffff96ae3fc00000(0000) knlGS:0000000000000000 [ 0.075000] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.075000] CR2: ffffa19e0081b000 CR3: 0000000038814000 CR4: 00000000003406f0 [ 0.075000] Call Trace: [ 0.075000] ramoops_init_przs.part.10.constprop.15+0x105/0x260 [ 0.075000] ramoops_probe+0x232/0x3a0 [ 0.075000] platform_drv_probe+0x3e/0xa0 [ 0.075000] driver_probe_device+0x2cd/0x400 [ 0.075000] __driver_attach+0xe4/0x110 [ 0.075000] ? driver_probe_device+0x400/0x400 [ 0.075000] bus_for_each_dev+0x70/0xa0 [ 0.075000] driver_attach+0x1e/0x20 [ 0.075000] bus_add_driver+0x159/0x230 [ 0.075000] ? do_early_param+0x95/0x95 [ 0.075000] driver_register+0x70/0xc0 [ 0.075000] ? init_pstore_fs+0x4d/0x4d [ 0.075000] __platform_driver_register+0x36/0x40 [ 0.075000] ramoops_init+0x12f/0x131 [ 0.075000] do_one_initcall+0x4d/0x12c [ 0.075000] ? do_early_param+0x95/0x95 [ 0.075000] kernel_init_freeable+0x19b/0x222 [ 0.075000] ? rest_init+0xbb/0xbb [ 0.075000] kernel_init+0xe/0xfc [ 0.075000] ret_from_fork+0x3a/0x50 [ 0.075000] Code: 4c 89 f2 49 c7 45 60 00 00 00 00 49 8d 7d 58 e8 af f6 ff ff 85 c0 89 c3 0f 8f 96 02 00 00 0f 85 ab 02 00 00 4d 8b 75 18 8b 5d cc <41> 8b 16 81 f3 44 42 47 43 39 d3 0f [ 0.075000] RIP: persistent_ram_new+0x1f8/0x39f RSP: ffff96ae32f7bc00 [ 0.075000] CR2: ffffa19e0081b000 [ 0.075000] ---[ end trace a92ad58b000ab3fe ]--- [ 0.075000] Kernel panic - not syncing: Fatal exception [ 0.075000] reboot: panic mode set: p,w [ 0.075000] Rebooting in 10 seconds.. > > > Signed-off-by: Bin Yang <bin.yang@intel.com> > > --- > > fs/pstore/ram_core.c | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c > > index 951a14e..7c05fdd 100644 > > --- a/fs/pstore/ram_core.c > > +++ b/fs/pstore/ram_core.c > > @@ -429,7 +429,7 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size, > > vaddr = vmap(pages, page_count, VM_MAP, prot); > > kfree(pages); > > > > - return vaddr; > > + return vaddr + offset_in_page(start); > > } > > > > static void *persistent_ram_iomap(phys_addr_t start, size_t size, > > @@ -468,7 +468,7 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, > > return -ENOMEM; > > } > > > > - prz->buffer = prz->vaddr + offset_in_page(start); > > + prz->buffer = prz->vaddr; > > prz->buffer_size = size - sizeof(struct persistent_ram_buffer); > > > > return 0; > > @@ -515,7 +515,7 @@ void persistent_ram_free(struct persistent_ram_zone *prz) > > > > if (prz->vaddr) { > > if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { > > - vunmap(prz->vaddr); > > + vunmap(prz->vaddr - offset_in_page(prz->paddr)); > > } else { > > iounmap(prz->vaddr); > > release_mem_region(prz->paddr, prz->size); > > -- > > 2.7.4 > > > > Regardless, yes, this patch looks correct. Thanks! I'll add it to my tree. thanks > > -Kees > ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] pstore: fix incorrect persistent ram buffer mapping 2018-09-13 1:21 ` Yang, Bin @ 2018-09-13 4:25 ` Kees Cook 0 siblings, 0 replies; 4+ messages in thread From: Kees Cook @ 2018-09-13 4:25 UTC (permalink / raw) To: Yang, Bin; +Cc: ccross, Luck, Tony, linux-kernel, anton On Wed, Sep 12, 2018 at 6:21 PM, Yang, Bin <bin.yang@intel.com> wrote: > On Wed, 2018-09-12 at 10:44 -0700, Kees Cook wrote: >> On Tue, Sep 11, 2018 at 8:36 PM, Bin Yang <bin.yang@intel.com> wrote: >> > persistent_ram_vmap() returns the page start vaddr. >> > persistent_ram_iomap() supports non-page-aligned mapping. >> >> Oh, yes, good catch. This should probably be explicitly mentioned in >> comments for these functions. >> >> > persistent_ram_buffer_map() always adds offset-in-page to the vaddr >> > returned from these two functions, which causes incorrect mapping of >> > non-page-aligned persistent ram buffer. >> >> How did you find this problem, and/or how was the problem manifesting? > > By default, ftrace_size is 4096 and max_ftrace_cnt is nr_cpu_ids. The > zone_sz in ramoops_init_przs() is 4096/nr_cpu_ids which might not be > page aligned. If the offset-in-page > 2048, the vaddr will be in next > page. If the next page is not mapped, it will cause kernel panic. > > I just wanted to enable this driver on my board and did not change the > default value of ftrace_size. It resulted kernel panic as below: > > > [ 0.074231] BUG: unable to handle kernel paging request at > ffffa19e0081b000 Perfect, thanks! I've updated your commit log to include these details now. Should be in linux-next shortly. -Kees -- Kees Cook Pixel Security ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-09-13 4:25 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-09-12 3:36 [PATCH] pstore: fix incorrect persistent ram buffer mapping Bin Yang 2018-09-12 17:44 ` Kees Cook 2018-09-13 1:21 ` Yang, Bin 2018-09-13 4:25 ` Kees Cook
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).