Author: jhibbits
Date: Tue Jun 27 01:57:22 2017
New Revision: 320392
URL: https://svnweb.freebsd.org/changeset/base/320392

Log:
  Disable interrupts when updating the TLB
  
  Without disabling interrupts it's possible for another thread to preempt
  and update the registers post-read (tlb1_read_entry) or pre-write
  (tlb1_write_entry), and confuse the kernel with mixed register states.
  
  MFC after:    2 weeks

Modified:
  head/sys/powerpc/booke/pmap.c

Modified: head/sys/powerpc/booke/pmap.c
==============================================================================
--- head/sys/powerpc/booke/pmap.c       Tue Jun 27 01:29:10 2017        
(r320391)
+++ head/sys/powerpc/booke/pmap.c       Tue Jun 27 01:57:22 2017        
(r320392)
@@ -3812,10 +3812,14 @@ tlb0_print_tlbentries(void)
 void
 tlb1_read_entry(tlb_entry_t *entry, unsigned int slot)
 {
+       register_t msr;
        uint32_t mas0;
 
        KASSERT((entry != NULL), ("%s(): Entry is NULL!", __func__));
 
+       msr = mfmsr();
+       mtmsr(msr & ~PSL_EE);
+
        mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(slot);
        mtspr(SPR_MAS0, mas0);
        __asm __volatile("isync; tlbre");
@@ -3835,6 +3839,7 @@ tlb1_read_entry(tlb_entry_t *entry, unsigned int slot)
                entry->mas7 = 0;
                break;
        }
+       mtmsr(msr);
 
        entry->virt = entry->mas2 & MAS2_EPN_MASK;
        entry->phys = ((vm_paddr_t)(entry->mas7 & MAS7_RPN) << 32) |
@@ -3850,6 +3855,7 @@ tlb1_read_entry(tlb_entry_t *entry, unsigned int slot)
 static void
 tlb1_write_entry(tlb_entry_t *e, unsigned int idx)
 {
+       register_t msr;
        uint32_t mas0;
 
        //debugf("tlb1_write_entry: s\n");
@@ -3858,6 +3864,9 @@ tlb1_write_entry(tlb_entry_t *e, unsigned int idx)
        mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(idx);
        //debugf("tlb1_write_entry: mas0 = 0x%08x\n", mas0);
 
+       msr = mfmsr();
+       mtmsr(msr & ~PSL_EE);
+
        mtspr(SPR_MAS0, mas0);
        __asm __volatile("isync");
        mtspr(SPR_MAS1, e->mas1);
@@ -3882,6 +3891,7 @@ tlb1_write_entry(tlb_entry_t *e, unsigned int idx)
        }
 
        __asm __volatile("tlbwe; isync; msync");
+       mtmsr(msr);
 
        //debugf("tlb1_write_entry: e\n");
 }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to