When doing rfork(0), i.e. separating curproc VM from any other user of

the same vmspace, decrement the reference count of the shared LDT instead
of a newly-made copy. Code factually removed LDT from the process that
did rfork(0).

Introduce user_ldt_deref() function that does decrement of refcount for
the struct proc_ldt, and call it in the rfork(0) case on the shared LDT.

Reviewed by:	jhb
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2008-09-12 09:53:29 +00:00
parent cb1d78d09a
commit 9719da13e7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=182961
3 changed files with 14 additions and 5 deletions

View file

@ -526,6 +526,14 @@ user_ldt_free(struct thread *td)
}
mdp->md_ldt = NULL;
user_ldt_deref(pldt);
}
void
user_ldt_deref(struct proc_ldt *pldt)
{
mtx_assert(&dt_lock, MA_OWNED);
if (--pldt->ldt_refcnt == 0) {
mtx_unlock_spin(&dt_lock);
kmem_free(kernel_map, (vm_offset_t)pldt->ldt_base,

View file

@ -158,17 +158,17 @@ cpu_fork(td1, p2, td2, flags)
if ((flags & RFMEM) == 0) {
/* unshare user LDT */
struct mdproc *mdp1 = &p1->p_md;
struct proc_ldt *pldt;
struct proc_ldt *pldt, *pldt1;
mtx_lock_spin(&dt_lock);
if ((pldt = mdp1->md_ldt) != NULL &&
pldt->ldt_refcnt > 1) {
pldt = user_ldt_alloc(mdp1, pldt->ldt_len);
if ((pldt1 = mdp1->md_ldt) != NULL &&
pldt1->ldt_refcnt > 1) {
pldt = user_ldt_alloc(mdp1, pldt1->ldt_len);
if (pldt == NULL)
panic("could not copy LDT");
mdp1->md_ldt = pldt;
set_user_ldt(mdp1);
user_ldt_free(td1);
user_ldt_deref(pldt1);
} else
mtx_unlock_spin(&dt_lock);
}

View file

@ -71,6 +71,7 @@ struct mdproc {
void set_user_ldt(struct mdproc *);
struct proc_ldt *user_ldt_alloc(struct mdproc *, int);
void user_ldt_free(struct thread *);
void user_ldt_deref(struct proc_ldt *pldt);
extern struct mtx dt_lock;