* sparc64 MM regression... @ 2018-03-15 19:28 ` David Miller 0 siblings, 0 replies; 4+ messages in thread From: David Miller @ 2018-03-15 19:28 UTC (permalink / raw) To: nitin.m.gupta; +Cc: sparclinux, linux-kernel So I bisected a userspace corruption regression down to commit: commit a8e654f01cb725d0bfd741ebca1bf4c9337969cc Author: Nitin Gupta <nitin.m.gupta@oracle.com> Date: Wed Jan 31 16:18:09 2018 -0800 sparc64: update pmdp_invalidate() to return old pmd value The transformation is basically from a set_pte_at() call into an atomic cmpxchg64() loop to set the pmd. The problem is that set_pmd_at() does more than just assign the pmd entry. It also does some accounting and also queues up a batch TLB flush entry. So the side effect of this change is that the TLB is never flushed for these changed PMDs, and thus the userland memory corruption I was seeing. ^ permalink raw reply [flat|nested] 4+ messages in thread
* sparc64 MM regression... @ 2018-03-15 19:28 ` David Miller 0 siblings, 0 replies; 4+ messages in thread From: David Miller @ 2018-03-15 19:28 UTC (permalink / raw) To: nitin.m.gupta; +Cc: sparclinux, linux-kernel So I bisected a userspace corruption regression down to commit: commit a8e654f01cb725d0bfd741ebca1bf4c9337969cc Author: Nitin Gupta <nitin.m.gupta@oracle.com> Date: Wed Jan 31 16:18:09 2018 -0800 sparc64: update pmdp_invalidate() to return old pmd value The transformation is basically from a set_pte_at() call into an atomic cmpxchg64() loop to set the pmd. The problem is that set_pmd_at() does more than just assign the pmd entry. It also does some accounting and also queues up a batch TLB flush entry. So the side effect of this change is that the TLB is never flushed for these changed PMDs, and thus the userland memory corruption I was seeing. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: sparc64 MM regression... 2018-03-15 19:28 ` David Miller @ 2018-03-15 20:00 ` David Miller -1 siblings, 0 replies; 4+ messages in thread From: David Miller @ 2018-03-15 20:00 UTC (permalink / raw) To: nitin.m.gupta; +Cc: sparclinux, linux-kernel From: David Miller <davem@davemloft.net> Date: Thu, 15 Mar 2018 15:28:15 -0400 (EDT) > > So I bisected a userspace corruption regression down to commit: > > commit a8e654f01cb725d0bfd741ebca1bf4c9337969cc > Author: Nitin Gupta <nitin.m.gupta@oracle.com> > Date: Wed Jan 31 16:18:09 2018 -0800 > > sparc64: update pmdp_invalidate() to return old pmd value > > The transformation is basically from a set_pte_at() call into > an atomic cmpxchg64() loop to set the pmd. > > The problem is that set_pmd_at() does more than just assign > the pmd entry. > > It also does some accounting and also queues up a batch TLB > flush entry. > > So the side effect of this change is that the TLB is never > flushed for these changed PMDs, and thus the userland memory > corruption I was seeing. This seems to do the trick: diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index 847ddff..b5cfab7 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c @@ -163,13 +163,10 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, pte_unmap(pte); } -void set_pmd_at(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, pmd_t pmd) -{ - pmd_t orig = *pmdp; - - *pmdp = pmd; +static void __set_pmd_acct(struct mm_struct *mm, unsigned long addr, + pmd_t orig, pmd_t pmd) +{ if (mm == &init_mm) return; @@ -219,6 +216,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, } } +void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd) +{ + pmd_t orig = *pmdp; + + *pmdp = pmd; + __set_pmd_acct(mm, addr, orig, pmd); +} + static inline pmd_t pmdp_establish(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp, pmd_t pmd) { @@ -227,6 +233,7 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, do { old = *pmdp; } while (cmpxchg64(&pmdp->pmd, old.pmd, pmd.pmd) != old.pmd); + __set_pmd_acct(vma->vm_mm, address, old, pmd); return old; } ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: sparc64 MM regression... @ 2018-03-15 20:00 ` David Miller 0 siblings, 0 replies; 4+ messages in thread From: David Miller @ 2018-03-15 20:00 UTC (permalink / raw) To: nitin.m.gupta; +Cc: sparclinux, linux-kernel From: David Miller <davem@davemloft.net> Date: Thu, 15 Mar 2018 15:28:15 -0400 (EDT) > > So I bisected a userspace corruption regression down to commit: > > commit a8e654f01cb725d0bfd741ebca1bf4c9337969cc > Author: Nitin Gupta <nitin.m.gupta@oracle.com> > Date: Wed Jan 31 16:18:09 2018 -0800 > > sparc64: update pmdp_invalidate() to return old pmd value > > The transformation is basically from a set_pte_at() call into > an atomic cmpxchg64() loop to set the pmd. > > The problem is that set_pmd_at() does more than just assign > the pmd entry. > > It also does some accounting and also queues up a batch TLB > flush entry. > > So the side effect of this change is that the TLB is never > flushed for these changed PMDs, and thus the userland memory > corruption I was seeing. This seems to do the trick: diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index 847ddff..b5cfab7 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c @@ -163,13 +163,10 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, pte_unmap(pte); } -void set_pmd_at(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, pmd_t pmd) -{ - pmd_t orig = *pmdp; - - *pmdp = pmd; +static void __set_pmd_acct(struct mm_struct *mm, unsigned long addr, + pmd_t orig, pmd_t pmd) +{ if (mm = &init_mm) return; @@ -219,6 +216,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, } } +void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd) +{ + pmd_t orig = *pmdp; + + *pmdp = pmd; + __set_pmd_acct(mm, addr, orig, pmd); +} + static inline pmd_t pmdp_establish(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp, pmd_t pmd) { @@ -227,6 +233,7 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, do { old = *pmdp; } while (cmpxchg64(&pmdp->pmd, old.pmd, pmd.pmd) != old.pmd); + __set_pmd_acct(vma->vm_mm, address, old, pmd); return old; } ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-03-15 20:00 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-03-15 19:28 sparc64 MM regression David Miller 2018-03-15 19:28 ` David Miller 2018-03-15 20:00 ` David Miller 2018-03-15 20:00 ` David Miller
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.