Hi The patch is OK, but I found two other bugs when inspecting the code: - some of copy_from_user versions do multiple read operations from userspace before writing the registers to kernel space. If one of those subsequent reads fail, the function compute_size incorrectly assumes that all data up to the faulting address were copied to kernel space. - the function copy_in_user_fixup tries to guess if the fault address belongs to the source or destination range. However, the fault address is imprecise (the low 13 bits are always zero), and it may result in incorrect guess. I'll send patches for these bugs. I've seen a message "BUG: non-zero nr_ptes on freeing mm: 1" twice on sparc64, once on 4.4.13 and once on 4.4.16. I don't know how to reproduce it. Do you have an idea what could be causing this bug? Mikulas On Wed, 27 Jul 2016, David Miller wrote: > > On pre-Niagara systems, we fetch the fault address on data TLB > exceptions from the TLB_TAG_ACCESS register. But this register also > contains the context ID assosciated with the fault in the low 13 bits > of the register value. > > This propagates into current_thread_info()->fault_address and can > cause trouble later on. > > So clear the low 13-bits out of the TLB_TAG_ACCESS value in the cases > where it matters. > > Reported-by: Mikulas Patocka <mpatocka@xxxxxxxxxx> > Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> > --- > arch/sparc/kernel/dtlb_prot.S | 4 ++-- > arch/sparc/kernel/ktlb.S | 12 ++++++++++++ > arch/sparc/kernel/tsb.S | 12 ++++++++++-- > 3 files changed, 24 insertions(+), 4 deletions(-) > > diff --git a/arch/sparc/kernel/dtlb_prot.S b/arch/sparc/kernel/dtlb_prot.S > index d668ca14..4087a62 100644 > --- a/arch/sparc/kernel/dtlb_prot.S > +++ b/arch/sparc/kernel/dtlb_prot.S > @@ -25,13 +25,13 @@ > > /* PROT ** ICACHE line 2: More real fault processing */ > ldxa [%g4] ASI_DMMU, %g5 ! Put tagaccess in %g5 > + srlx %g5, PAGE_SHIFT, %g5 > + sllx %g5, PAGE_SHIFT, %g5 ! Clear context ID bits > bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup > mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 > ba,pt %xcc, sparc64_realfault_common ! Nope, normal fault > nop > nop > - nop > - nop > > /* PROT ** ICACHE line 3: Unused... */ > nop > diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S > index ef0d8e9..f22bec0 100644 > --- a/arch/sparc/kernel/ktlb.S > +++ b/arch/sparc/kernel/ktlb.S > @@ -20,6 +20,10 @@ kvmap_itlb: > mov TLB_TAG_ACCESS, %g4 > ldxa [%g4] ASI_IMMU, %g4 > > + /* The kernel executes in context zero, therefore we do not > + * need to clear the context ID bits out of %g4 here. > + */ > + > /* sun4v_itlb_miss branches here with the missing virtual > * address already loaded into %g4 > */ > @@ -128,6 +132,10 @@ kvmap_dtlb: > mov TLB_TAG_ACCESS, %g4 > ldxa [%g4] ASI_DMMU, %g4 > > + /* The kernel executes in context zero, therefore we do not > + * need to clear the context ID bits out of %g4 here. > + */ > + > /* sun4v_dtlb_miss branches here with the missing virtual > * address already loaded into %g4 > */ > @@ -251,6 +259,10 @@ kvmap_dtlb_longpath: > nop > .previous > > + /* The kernel executes in context zero, therefore we do not > + * need to clear the context ID bits out of %g5 here. > + */ > + > be,pt %xcc, sparc64_realfault_common > mov FAULT_CODE_DTLB, %g4 > ba,pt %xcc, winfix_trampoline > diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S > index be98685..d568c82 100644 > --- a/arch/sparc/kernel/tsb.S > +++ b/arch/sparc/kernel/tsb.S > @@ -29,13 +29,17 @@ > */ > tsb_miss_dtlb: > mov TLB_TAG_ACCESS, %g4 > + ldxa [%g4] ASI_DMMU, %g4 > + srlx %g4, PAGE_SHIFT, %g4 > ba,pt %xcc, tsb_miss_page_table_walk > - ldxa [%g4] ASI_DMMU, %g4 > + sllx %g4, PAGE_SHIFT, %g4 > > tsb_miss_itlb: > mov TLB_TAG_ACCESS, %g4 > + ldxa [%g4] ASI_IMMU, %g4 > + srlx %g4, PAGE_SHIFT, %g4 > ba,pt %xcc, tsb_miss_page_table_walk > - ldxa [%g4] ASI_IMMU, %g4 > + sllx %g4, PAGE_SHIFT, %g4 > > /* At this point we have: > * %g1 -- PAGE_SIZE TSB entry address > @@ -284,6 +288,10 @@ tsb_do_dtlb_fault: > nop > .previous > > + /* Clear context ID bits. */ > + srlx %g5, PAGE_SHIFT, %g5 > + sllx %g5, PAGE_SHIFT, %g5 > + > be,pt %xcc, sparc64_realfault_common > mov FAULT_CODE_DTLB, %g4 > ba,pt %xcc, winfix_trampoline > -- > 2.1.2.532.g19b5d50 > -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html