Date: Sun, 26 Nov 2017 20:30:02 +0000 (UTC) From: Justin Hibbits <jhibbits@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r326236 - head/sys/powerpc/booke Message-ID: <201711262030.vAQKU2sT025183@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhibbits Date: Sun Nov 26 20:30:02 2017 New Revision: 326236 URL: https://svnweb.freebsd.org/changeset/base/326236 Log: Synchronize TLB1 mappings when created This allows modules creating mappings to be loaded post-boot, after SMP has started. Without this, the TLB1 mappings can become unsynchronized and lead to kernel page faults when accessed on the alternate CPUs. MFC after: 3 weeks Modified: head/sys/powerpc/booke/pmap.c Modified: head/sys/powerpc/booke/pmap.c ============================================================================== --- head/sys/powerpc/booke/pmap.c Sun Nov 26 19:17:55 2017 (r326235) +++ head/sys/powerpc/booke/pmap.c Sun Nov 26 20:30:02 2017 (r326236) @@ -3872,31 +3872,27 @@ tlb1_read_entry(tlb_entry_t *entry, unsigned int slot) tsize2size((entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT); } -/* - * Write given entry to TLB1 hardware. - */ +struct tlbwrite_args { + tlb_entry_t *e; + unsigned int idx; +}; + static void -tlb1_write_entry(tlb_entry_t *e, unsigned int idx) +tlb1_write_entry_int(void *arg) { - register_t msr; + struct tlbwrite_args *args = arg; uint32_t mas0; - //debugf("tlb1_write_entry: s\n"); - /* Select entry */ - mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(idx); - //debugf("tlb1_write_entry: mas0 = 0x%08x\n", mas0); + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(args->idx); - msr = mfmsr(); - __asm __volatile("wrteei 0"); - mtspr(SPR_MAS0, mas0); __asm __volatile("isync"); - mtspr(SPR_MAS1, e->mas1); + mtspr(SPR_MAS1, args->e->mas1); __asm __volatile("isync"); - mtspr(SPR_MAS2, e->mas2); + mtspr(SPR_MAS2, args->e->mas2); __asm __volatile("isync"); - mtspr(SPR_MAS3, e->mas3); + mtspr(SPR_MAS3, args->e->mas3); __asm __volatile("isync"); switch ((mfpvr() >> 16) & 0xFFFF) { case FSL_E500mc: @@ -3906,7 +3902,7 @@ tlb1_write_entry(tlb_entry_t *e, unsigned int idx) __asm __volatile("isync"); /* FALLTHROUGH */ case FSL_E500v2: - mtspr(SPR_MAS7, e->mas7); + mtspr(SPR_MAS7, args->e->mas7); __asm __volatile("isync"); break; default: @@ -3914,9 +3910,42 @@ tlb1_write_entry(tlb_entry_t *e, unsigned int idx) } __asm __volatile("tlbwe; isync; msync"); - mtmsr(msr); - //debugf("tlb1_write_entry: e\n"); +} + +static void +tlb1_write_entry_sync(void *arg) +{ + /* Empty synchronization point for smp_rendezvous(). */ +} + +/* + * Write given entry to TLB1 hardware. + */ +static void +tlb1_write_entry(tlb_entry_t *e, unsigned int idx) +{ + struct tlbwrite_args args; + + args.e = e; + args.idx = idx; + +#ifdef SMP + if ((e->mas2 & _TLB_ENTRY_SHARED) && smp_started) { + mb(); + smp_rendezvous(tlb1_write_entry_sync, + tlb1_write_entry_int, + tlb1_write_entry_sync, &args); + } else +#endif + { + register_t msr; + + msr = mfmsr(); + __asm __volatile("wrteei 0"); + tlb1_write_entry_int(&args); + mtmsr(msr); + } } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201711262030.vAQKU2sT025183>