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
This commit is contained in:
parent
b436609213
commit
3d1357108a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=320392
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user