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()
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user