aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2011-01-05 13:40:40 +0000
committerMarius Strobl <marius@FreeBSD.org>2011-01-05 13:40:40 +0000
commit7b5131a8b3eea51dcc3e987c4d12eccef77aef72 (patch)
tree989cb6ad0b5430afa561ca1ec919c9d1f7fa90c9
parent9ea71eb8bff0f29578d68f0dd1b8b9b273055ca2 (diff)
downloadsrc-7b5131a8b3eea51dcc3e987c4d12eccef77aef72.tar.gz
src-7b5131a8b3eea51dcc3e987c4d12eccef77aef72.zip
MFC: r216891
Extend the section in which interrupts are disabled in the TLB demap functions, otherwise if we get preempted after checking whether a certain pmap is active on the current CPU but before disabling interrupts we might operate on an outdated state as the pmap might have been deactivated in the meantime. As the same issue may arises when the TLB demap function is interrupted by a TLB demap IPI, just entering a critical section before the check isn't sufficient so we have to fully disable interrupts instead. Approved by: re (kib)
Notes
Notes: svn path=/releng/7.4/; revision=217007
-rw-r--r--sys/sparc64/sparc64/tlb.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/sys/sparc64/sparc64/tlb.c b/sys/sparc64/sparc64/tlb.c
index 9bd90a1dd475..313d32967eb6 100644
--- a/sys/sparc64/sparc64/tlb.c
+++ b/sys/sparc64/sparc64/tlb.c
@@ -80,15 +80,15 @@ tlb_context_demap(struct pmap *pm)
*/
PMAP_STATS_INC(tlb_ncontext_demap);
cookie = ipi_tlb_context_demap(pm);
+ s = intr_disable();
if (pm->pm_active & PCPU_GET(cpumask)) {
KASSERT(pm->pm_context[curcpu] != -1,
("tlb_context_demap: inactive pmap?"));
- s = intr_disable();
stxa(TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, ASI_DMMU_DEMAP, 0);
stxa(TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, ASI_IMMU_DEMAP, 0);
flush(KERNBASE);
- intr_restore(s);
}
+ intr_restore(s);
ipi_wait(cookie);
}
@@ -101,6 +101,7 @@ tlb_page_demap(struct pmap *pm, vm_offset_t va)
PMAP_STATS_INC(tlb_npage_demap);
cookie = ipi_tlb_page_demap(pm, va);
+ s = intr_disable();
if (pm->pm_active & PCPU_GET(cpumask)) {
KASSERT(pm->pm_context[curcpu] != -1,
("tlb_page_demap: inactive pmap?"));
@@ -109,12 +110,11 @@ tlb_page_demap(struct pmap *pm, vm_offset_t va)
else
flags = TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE;
- s = intr_disable();
stxa(TLB_DEMAP_VA(va) | flags, ASI_DMMU_DEMAP, 0);
stxa(TLB_DEMAP_VA(va) | flags, ASI_IMMU_DEMAP, 0);
flush(KERNBASE);
- intr_restore(s);
}
+ intr_restore(s);
ipi_wait(cookie);
}
@@ -128,6 +128,7 @@ tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
PMAP_STATS_INC(tlb_nrange_demap);
cookie = ipi_tlb_range_demap(pm, start, end);
+ s = intr_disable();
if (pm->pm_active & PCPU_GET(cpumask)) {
KASSERT(pm->pm_context[curcpu] != -1,
("tlb_range_demap: inactive pmap?"));
@@ -136,13 +137,12 @@ tlb_range_demap(struct pmap *pm, vm_offset_t start, vm_offset_t end)
else
flags = TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE;
- s = intr_disable();
for (va = start; va < end; va += PAGE_SIZE) {
stxa(TLB_DEMAP_VA(va) | flags, ASI_DMMU_DEMAP, 0);
stxa(TLB_DEMAP_VA(va) | flags, ASI_IMMU_DEMAP, 0);
flush(KERNBASE);
}
- intr_restore(s);
}
+ intr_restore(s);
ipi_wait(cookie);
}