diff options
author | Marius Strobl <marius@FreeBSD.org> | 2011-01-02 15:01:03 +0000 |
---|---|---|
committer | Marius Strobl <marius@FreeBSD.org> | 2011-01-02 15:01:03 +0000 |
commit | f8d0071f71a52b4547c6ed008e9e17b17f40206c (patch) | |
tree | 581aa9596109d578ecbb9c06dae1fb62ca6c9561 /sys/sparc64 | |
parent | 3e73ff1e94fff6ae15eda4319266e8e7d2891cc7 (diff) | |
download | src-f8d0071f71a52b4547c6ed008e9e17b17f40206c.tar.gz src-f8d0071f71a52b4547c6ed008e9e17b17f40206c.zip |
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.
MFC after: 3 days
Notes
Notes:
svn path=/head/; revision=216891
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/sparc64/tlb.c | 12 |
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); } |