> > I believe that this is a bug in amd64 pmap. Fictitious pages are not > promoted, in particular, the pv_table array does not span over the > dynamically registered fictitious ranges. As result, pa_to_pvh() returns > garbage and pvh must not be accessed in the case of 'small_mappings' in > several pmap functions. It is typically not accessed, except in case > when we have to drop and reacquire pv lock, to avoid LOR with pmap. Cool. Thanks for explaining that. -M > i386 does not have the issue, due to pvh_global_lock. > > Below is the supposed fix (not tested). > > diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c > index 7a93e76..e514b07 100644 > --- a/sys/amd64/amd64/pmap.c > +++ b/sys/amd64/amd64/pmap.c > _at__at_ -3947,12 +3947,14 _at__at_ small_mappings: > while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { > pmap = PV_PMAP(pv); > if (!PMAP_TRYLOCK(pmap)) { > - pvh_gen = pvh->pv_gen; > + if ((m->flags & PG_FICTITIOUS) == 0) > + pvh_gen = pvh->pv_gen; > md_gen = m->md.pv_gen; > rw_wunlock(lock); > PMAP_LOCK(pmap); > rw_wlock(lock); > - if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { > + if (((m->flags & PG_FICTITIOUS) == 0 && > + pvh_gen != pvh->pv_gen) || md_gen != m->md.pv_gen) { > rw_wunlock(lock); > PMAP_UNLOCK(pmap); > goto retry; > _at__at_ -5775,13 +5777,14 _at__at_ small_mappings: > TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { > pmap = PV_PMAP(pv); > if (!PMAP_TRYLOCK(pmap)) { > - pvh_gen = pvh->pv_gen; > + if ((m->flags & PG_FICTITIOUS) == 0) > + pvh_gen = pvh->pv_gen; > md_gen = m->md.pv_gen; > rw_wunlock(lock); > PMAP_LOCK(pmap); > rw_wlock(lock); > - if (pvh_gen != pvh->pv_gen || > - md_gen != m->md.pv_gen) { > + if (((m->flags & PG_FICTITIOUS) == 0 && > + pvh_gen != pvh->pv_gen) || md_gen != m->md.pv_gen) { > PMAP_UNLOCK(pmap); > rw_wunlock(lock); > goto retry_pv_loop; > _at__at_ -5985,12 +5988,14 _at__at_ small_mappings: > pvf = pv; > pmap = PV_PMAP(pv); > if (!PMAP_TRYLOCK(pmap)) { > - pvh_gen = pvh->pv_gen; > + if ((m->flags & PG_FICTITIOUS) == 0) > + pvh_gen = pvh->pv_gen; > md_gen = m->md.pv_gen; > rw_wunlock(lock); > PMAP_LOCK(pmap); > rw_wlock(lock); > - if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { > + if (((m->flags & PG_FICTITIOUS) == 0 && > + pvh_gen != pvh->pv_gen) || md_gen != m->md.pv_gen) { > PMAP_UNLOCK(pmap); > goto retry; > } > _at__at_ -6248,11 +6253,13 _at__at_ small_mappings: > pmap = PV_PMAP(pv); > if (!PMAP_TRYLOCK(pmap)) { > md_gen = m->md.pv_gen; > - pvh_gen = pvh->pv_gen; > + if ((m->flags & PG_FICTITIOUS) == 0) > + pvh_gen = pvh->pv_gen; > rw_wunlock(lock); > PMAP_LOCK(pmap); > rw_wlock(lock); > - if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { > + if (((m->flags & PG_FICTITIOUS) == 0 && > + pvh_gen != pvh->pv_gen) || md_gen != m->md.pv_gen) { > PMAP_UNLOCK(pmap); > goto restart; > } >Received on Sat Jun 04 2016 - 15:51:13 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:05 UTC