Skip to content

Commit

Permalink
Merge tag 'powerpc-5.0-4' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman:
 "Just two fixes, both going to stable.

   - Our support for split pmd page table lock had a bug which could
     lead to a crash on mremap() when using the Radix MMU (Power9 only).

   - A fix for the PAPR SCM driver (nvdimm) we added last release, which
     had a bug where we might mis-handle a hypervisor response leading
     to us failing to attach the memory region.

  Thanks to: Aneesh Kumar K.V, Oliver O'Halloran"

* tag 'powerpc-5.0-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/papr_scm: Use the correct bind address
  powerpc/radix: Fix kernel crash with mremap()
  • Loading branch information
torvalds committed Feb 9, 2019
2 parents 6b2912c + 5a3840a commit 820828b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 16 deletions.
22 changes: 7 additions & 15 deletions arch/powerpc/include/asm/book3s/64/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -1258,21 +1258,13 @@ extern pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,

#define pmd_move_must_withdraw pmd_move_must_withdraw
struct spinlock;
static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
struct spinlock *old_pmd_ptl,
struct vm_area_struct *vma)
{
if (radix_enabled())
return false;
/*
* Archs like ppc64 use pgtable to store per pmd
* specific information. So when we switch the pmd,
* we should also withdraw and deposit the pgtable
*/
return true;
}


extern int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
struct spinlock *old_pmd_ptl,
struct vm_area_struct *vma);
/*
* Hash translation mode use the deposited table to store hash pte
* slot information.
*/
#define arch_needs_pgtable_deposit arch_needs_pgtable_deposit
static inline bool arch_needs_pgtable_deposit(void)
{
Expand Down
22 changes: 22 additions & 0 deletions arch/powerpc/mm/pgtable-book3s64.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,3 +400,25 @@ void arch_report_meminfo(struct seq_file *m)
atomic_long_read(&direct_pages_count[MMU_PAGE_1G]) << 20);
}
#endif /* CONFIG_PROC_FS */

/*
* For hash translation mode, we use the deposited table to store hash slot
* information and they are stored at PTRS_PER_PMD offset from related pmd
* location. Hence a pmd move requires deposit and withdraw.
*
* For radix translation with split pmd ptl, we store the deposited table in the
* pmd page. Hence if we have different pmd page we need to withdraw during pmd
* move.
*
* With hash we use deposited table always irrespective of anon or not.
* With radix we use deposited table only for anonymous mapping.
*/
int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
struct spinlock *old_pmd_ptl,
struct vm_area_struct *vma)
{
if (radix_enabled())
return (new_pmd_ptl != old_pmd_ptl) && vma_is_anonymous(vma);

return true;
}
5 changes: 4 additions & 1 deletion arch/powerpc/platforms/pseries/papr_scm.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
{
unsigned long ret[PLPAR_HCALL_BUFSIZE];
uint64_t rc, token;
uint64_t saved = 0;

/*
* When the hypervisor cannot map all the requested memory in a single
Expand All @@ -56,6 +57,8 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0,
p->blocks, BIND_ANY_ADDR, token);
token = ret[0];
if (!saved)
saved = ret[1];
cond_resched();
} while (rc == H_BUSY);

Expand All @@ -64,7 +67,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
return -ENXIO;
}

p->bound_addr = ret[1];
p->bound_addr = saved;

dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res);

Expand Down

0 comments on commit 820828b

Please sign in to comment.