summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2005-09-03 19:43:15 +0000
committermarcel <marcel@FreeBSD.org>2005-09-03 19:43:15 +0000
commit516e4da61f61ff79186706603c0f53e3362bab9f (patch)
tree0c1b6ba6abd80abbd31a29bee977619d44a3bd28 /sys/ia64
parent39788de49ed8c451980050349cf26ad80c4f6eb1 (diff)
downloadFreeBSD-src-516e4da61f61ff79186706603c0f53e3362bab9f.zip
FreeBSD-src-516e4da61f61ff79186706603c0f53e3362bab9f.tar.gz
Fix collision chain termination checks. The result of IA64_PHYS_TO_RR7
is never 0, so one cannot test for a NULL pointer after a physical address is translated into a virtual pointer with said macro. Instead, keep the physical address around and test it against 0. Note that this obviously implies that a PTE can never be allocated at physical address 0. This isn't exactly guaranteed, but hasn't been a problem so far. We test the physical address against 0 for as long as the ia64 port exists...
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/pmap.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c
index ce0df9f..b7293c1 100644
--- a/sys/ia64/ia64/pmap.c
+++ b/sys/ia64/ia64/pmap.c
@@ -827,20 +827,22 @@ pmap_remove_vhpt(vm_offset_t va)
struct ia64_lpte *pte;
struct ia64_lpte *lpte;
struct ia64_lpte *vhpte;
- uint64_t tag;
+ uint64_t chain, tag;
tag = ia64_ttag(va);
vhpte = (struct ia64_lpte *)ia64_thash(va);
bckt = (struct ia64_bucket *)vhpte->chain;
- mtx_lock_spin(&bckt->mutex);
lpte = NULL;
- pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(bckt->chain);
- while (pte != NULL && pte->tag != tag) {
+ mtx_lock_spin(&bckt->mutex);
+ chain = bckt->chain;
+ pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(chain);
+ while (chain != 0 && pte->tag != tag) {
lpte = pte;
- pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(pte->chain);
+ chain = pte->chain;
+ pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(chain);
}
- if (pte == NULL) {
+ if (chain == 0) {
mtx_unlock_spin(&bckt->mutex);
return (ENOENT);
}
@@ -866,21 +868,21 @@ pmap_find_vhpt(vm_offset_t va)
{
struct ia64_bucket *bckt;
struct ia64_lpte *pte;
- uint64_t tag;
+ uint64_t chain, tag;
tag = ia64_ttag(va);
pte = (struct ia64_lpte *)ia64_thash(va);
bckt = (struct ia64_bucket *)pte->chain;
- if (bckt->chain == 0)
- return (NULL);
-
- pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(bckt->chain);
- while (pte->tag != tag) {
- if (pte->chain == 0)
- return (NULL);
- pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(pte->chain);
+
+ mtx_lock_spin(&bckt->mutex);
+ chain = bckt->chain;
+ pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(chain);
+ while (chain != 0 && pte->tag != tag) {
+ chain = pte->chain;
+ pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(chain);
}
- return (pte);
+ mtx_unlock_spin(&bckt->mutex);
+ return ((chain != 0) ? pte : NULL);
}
/*
OpenPOWER on IntegriCloud