From 3d1357108ae40c6bf76ac127f3ff36c0f0885b1e Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Tue, 27 Jun 2017 01:57:22 +0000 Subject: [PATCH] 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 --- sys/powerpc/booke/pmap.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 6b7003dea82..c8b0634087a 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -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"); }