]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Fix a race between _pmap_unwire_ptp() and MipsDoTLBMiss().
authormarkj <markj@FreeBSD.org>
Fri, 24 Apr 2020 21:21:23 +0000 (21:21 +0000)
committermarkj <markj@FreeBSD.org>
Fri, 24 Apr 2020 21:21:23 +0000 (21:21 +0000)
commit4ed79ccedd7e9735acb1dce2d3a8cd27d50a3941
tree5eabab3f137fc15a3f78084811c542e0cf829bbe
parent890e35e73a9634129a09527b07e8e8dbc85fd366
Fix a race between _pmap_unwire_ptp() and MipsDoTLBMiss().

MipsDoTLBMiss() will load a segmap entry or pde, check that it isn't
zero, and then chase that pointer to a physical page. If that page has
been freed in the interim, it will read garbage and go on to populate
the TLB with it.

This can happen because pmap_unwire_ptp zeros out the pde and
vm_page_free_zero()s the ptp (or, recursively, zeros out the segmap
entry and vm_page_free_zero()s the pdp) without interlocking against
MipsDoTLBMiss(). The pmap is locked, and pvh_global_lock may or may not
be held, but this is not enough. Solve this issue by inserting TLB
shootdowns within _pmap_unwire_ptp(); as MipsDoTLBMiss() runs with IRQs
deferred, the IPIs involved in TLB shootdown are sufficient to ensure
that MipsDoTLBMiss() sees either a zero segmap entry / pde or a non-zero
entry and the pointed-to page still not freed.

Submitted by: Nathaniel Filardo <nwf20@cl.cam.ac.uk>
Reviewed by: kib
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D24491
sys/mips/mips/pmap.c