summaryrefslogtreecommitdiff
path: root/sys/arch/arm64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/arm64')
-rw-r--r--sys/arch/arm64/arm64/pmap.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/sys/arch/arm64/arm64/pmap.c b/sys/arch/arm64/arm64/pmap.c
index af2294bead1..df734710e98 100644
--- a/sys/arch/arm64/arm64/pmap.c
+++ b/sys/arch/arm64/arm64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.55 2018/08/15 20:18:31 kettenis Exp $ */
+/* $OpenBSD: pmap.c,v 1.56 2018/08/16 15:36:04 patrick Exp $ */
/*
* Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com>
*
@@ -2174,20 +2174,27 @@ uint32_t pmap_asid[NUM_ASID / 32];
void
pmap_allocate_asid(pmap_t pm)
{
+ uint32_t bits;
int asid, bit;
- do {
- asid = arc4random() & (NUM_ASID - 2);
- bit = (asid & (32 - 1));
- } while (asid == 0 || (pmap_asid[asid / 32] & (3U << bit)));
+ for (;;) {
+ do {
+ asid = arc4random() & (NUM_ASID - 2);
+ bit = (asid & (32 - 1));
+ bits = pmap_asid[asid / 32];
+ } while (asid == 0 || (bits & (3U << bit)));
- atomic_setbits_int(&pmap_asid[asid / 32], 3U << bit);
+ if (atomic_cas_uint(&pmap_asid[asid / 32], bits,
+ bits | (3U << bit)) == bits)
+ break;
+ }
pm->pm_asid = asid;
}
void
pmap_free_asid(pmap_t pm)
{
+ uint32_t bits;
int bit;
KASSERT(pm != curcpu()->ci_curpm);
@@ -2195,7 +2202,12 @@ pmap_free_asid(pmap_t pm)
cpu_tlb_flush_asid_all((uint64_t)(pm->pm_asid | ASID_USER) << 48);
bit = (pm->pm_asid & (32 - 1));
- atomic_clearbits_int(&pmap_asid[pm->pm_asid / 32], 3U << bit);
+ for (;;) {
+ bits = pmap_asid[pm->pm_asid / 32];
+ if (atomic_cas_uint(&pmap_asid[pm->pm_asid / 32], bits,
+ bits & ~(3U << bit)) == bits)
+ break;
+ }
}
void