Skip to content

Commit

Permalink
Merge tag 'pstore-v4.19-rc4' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/kees/linux

Pull pstore fix from Kees Cook:
 "This fixes a 6 year old pstore bug that everyone just got lucky in
  avoiding, likely due only using page-aligned persistent ram regions:

   - Handle page-vs-byte offset handling between iomap and vmap (Bin Yang)"

* tag 'pstore-v4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  pstore: Fix incorrect persistent ram buffer mapping
  • Loading branch information
Linus Torvalds committed Sep 14, 2018
2 parents 4624d6e + 831b624 commit 145ea6f
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions fs/pstore/ram_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,12 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size,
vaddr = vmap(pages, page_count, VM_MAP, prot);
kfree(pages);

return vaddr;
/*
* Since vmap() uses page granularity, we must add the offset
* into the page here, to get the byte granularity address
* into the mapping to represent the actual "start" location.
*/
return vaddr + offset_in_page(start);
}

static void *persistent_ram_iomap(phys_addr_t start, size_t size,
Expand All @@ -448,6 +453,11 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size,
else
va = ioremap_wc(start, size);

/*
* Since request_mem_region() and ioremap() are byte-granularity
* there is no need handle anything special like we do when the
* vmap() case in persistent_ram_vmap() above.
*/
return va;
}

Expand All @@ -468,7 +478,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;
Expand Down Expand Up @@ -515,7 +525,8 @@ void persistent_ram_free(struct persistent_ram_zone *prz)

if (prz->vaddr) {
if (pfn_valid(prz->paddr >> PAGE_SHIFT)) {
vunmap(prz->vaddr);
/* We must vunmap() at page-granularity. */
vunmap(prz->vaddr - offset_in_page(prz->paddr));
} else {
iounmap(prz->vaddr);
release_mem_region(prz->paddr, prz->size);
Expand Down

0 comments on commit 145ea6f

Please sign in to comment.