Skip to content

Commit 820828b

Browse files
committed
Merge tag 'powerpc-5.0-4' of git://git.kernel.org/pub/scm/linux/kernel/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()
2 parents 6b2912c + 5a3840a commit 820828b

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

arch/powerpc/include/asm/book3s/64/pgtable.h

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,21 +1258,13 @@ extern pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
12581258

12591259
#define pmd_move_must_withdraw pmd_move_must_withdraw
12601260
struct spinlock;
1261-
static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
1262-
struct spinlock *old_pmd_ptl,
1263-
struct vm_area_struct *vma)
1264-
{
1265-
if (radix_enabled())
1266-
return false;
1267-
/*
1268-
* Archs like ppc64 use pgtable to store per pmd
1269-
* specific information. So when we switch the pmd,
1270-
* we should also withdraw and deposit the pgtable
1271-
*/
1272-
return true;
1273-
}
1274-
1275-
1261+
extern int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
1262+
struct spinlock *old_pmd_ptl,
1263+
struct vm_area_struct *vma);
1264+
/*
1265+
* Hash translation mode use the deposited table to store hash pte
1266+
* slot information.
1267+
*/
12761268
#define arch_needs_pgtable_deposit arch_needs_pgtable_deposit
12771269
static inline bool arch_needs_pgtable_deposit(void)
12781270
{

arch/powerpc/mm/pgtable-book3s64.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,3 +400,25 @@ void arch_report_meminfo(struct seq_file *m)
400400
atomic_long_read(&direct_pages_count[MMU_PAGE_1G]) << 20);
401401
}
402402
#endif /* CONFIG_PROC_FS */
403+
404+
/*
405+
* For hash translation mode, we use the deposited table to store hash slot
406+
* information and they are stored at PTRS_PER_PMD offset from related pmd
407+
* location. Hence a pmd move requires deposit and withdraw.
408+
*
409+
* For radix translation with split pmd ptl, we store the deposited table in the
410+
* pmd page. Hence if we have different pmd page we need to withdraw during pmd
411+
* move.
412+
*
413+
* With hash we use deposited table always irrespective of anon or not.
414+
* With radix we use deposited table only for anonymous mapping.
415+
*/
416+
int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
417+
struct spinlock *old_pmd_ptl,
418+
struct vm_area_struct *vma)
419+
{
420+
if (radix_enabled())
421+
return (new_pmd_ptl != old_pmd_ptl) && vma_is_anonymous(vma);
422+
423+
return true;
424+
}

arch/powerpc/platforms/pseries/papr_scm.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
4343
{
4444
unsigned long ret[PLPAR_HCALL_BUFSIZE];
4545
uint64_t rc, token;
46+
uint64_t saved = 0;
4647

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

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

67-
p->bound_addr = ret[1];
70+
p->bound_addr = saved;
6871

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

0 commit comments

Comments
 (0)