Page MenuHomeFreeBSD

riscv: Fix another race in pmap_pinit()
ClosedPublic

Authored by markj on Feb 14 2022, 3:06 PM.
Tags
None
Referenced Files
Unknown Object (File)
Feb 13 2024, 8:44 PM
Unknown Object (File)
Dec 23 2023, 12:44 AM
Unknown Object (File)
Dec 18 2023, 1:39 PM
Unknown Object (File)
Dec 4 2023, 5:33 PM
Unknown Object (File)
Nov 28 2023, 10:31 AM
Unknown Object (File)
Nov 27 2023, 7:55 AM
Unknown Object (File)
Nov 25 2023, 3:01 AM
Unknown Object (File)
Nov 23 2023, 5:48 PM

Details

Summary

Commit c862d5f2a789 ("riscv: Fix a race in pmap_pinit()") did not really
fix the race. Alan writes,

Suppose that N entries in the L1 tables are in use, and we are in the
middle of the memcpy().  Specifically, we have read the zero-filled
(N+1)st entry from the kernel L1 table.  Then, we are preempted.  Now,
another core/thread does pmap_growkernel(), which fills the (N+1)st
entry.  Finally, we return to the original core/thread, and overwrite
the valid entry with the zero that we earlier read.

Try to fix the race properly, by copying kernel L1 entries while holding
the allpmaps lock. To avoid doing unnecessary work while holding this
global lock, copy only the entries that we expect to be valid. We could
go further: since kernel map L1 entries are never invalidated since DMAP
L1 entries are currently never demoted, we could just count the number
of valid entries with the lock held and copy them after dropping the
lock. That seems a bit fragile to me, though: if the second assumption
stops being true, then we'll have a subtle bug and will have to go back
to copying under the lock. Also note that in (soon to be added) SV48
mode, there is no need for the allpmaps list at all.

Reported by: alc, jrtc27

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 44436
Build 41324: arc lint + arc unit

Event Timeline

markj requested review of this revision.Feb 14 2022, 3:06 PM
jrtc27 added inline comments.
sys/riscv/riscv/pmap.c
1241

The switch from memcpy seems like a separate change?..

sys/riscv/riscv/pmap.c
1241

Yes, I'm effectively making two changes here: fixing the race, and trying to reduce the amount of work done under the allpmaps lock. I can commit the changes separately; for review purposes it seemed reasonable to squash the two.

arichardson added inline comments.
sys/riscv/riscv/pmap.c
1241

Should be allowed now and avoids an extra line at the start?

markj marked an inline comment as done.

Shrink i's scope.

This revision is now accepted and ready to land.Feb 15 2022, 8:07 AM
This revision was automatically updated to reflect the committed changes.