Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
caprevoke: Handle a race between revokers
Suppose a CAPSTORE page is mapped into multiple address spaces, so is subject to parallel revocation. Suppose two revokers race to scan the page. Suppose further that neither mapping has CDBM set (e.g., because a third mapping which had set CAPSTORE has been destroyed). The revokers are initially serialized by the page's object's write lock. However, the following race is possible: T1: - calls pmap_caploadgen_update(), which busies the page and returns PMAP_CAPLOADGEN_SCAN_RW_XBUSIED - drops VM object lock and calls vm_cheri_revoke_visit_rw() to scan the page T2: - calls pmap_caploadgen_update(), observes that PGA_CAPSTORE is set T1: - finds no capabilities in the page, calls pmap_caploadgen_update() again - observes that no mappings has CDBM set, clears PGA_CAPSTORE and returns - unbusies the page T2: - acquires the page busy lock - calls vm_cheri_revoke_visit_rw(), finds no capabilities - calls pmap_caploadgen_update(), which panics because PGA_CAPSTORE has already been cleared Handle the race by permitting CAPSTORE to be clear in pmap_caploadgen_update(). In this case, simply update the LCLG and move on.
- Loading branch information