Set md_ldt (pointer to the LDT) after md_ldt_sd (system segment
descriptor for the LDT) is populated. md_ldt is used by context-switch code as indicator that LDT segment register shall be loaded with GUSERLDT segment instead of 0, so context switch at the wrong time may cause attempt to load non-populated descriptor. Use store with the barrier to prevent other CPUs from seeing updated md_ldt but not seeing updated md_ldt_sd. Multithreaded process may context-switch to another thread of the process on another CPU and read md_ldt. MFC after: 1 week
This commit is contained in:
parent
5f9f9bd940
commit
293409233b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=201890
@ -420,13 +420,14 @@ user_ldt_alloc(struct proc *p, int force)
|
||||
return (pldt);
|
||||
}
|
||||
|
||||
mdp->md_ldt = new_ldt;
|
||||
if (pldt != NULL) {
|
||||
bcopy(pldt->ldt_base, new_ldt->ldt_base, max_ldt_segment *
|
||||
sizeof(struct user_segment_descriptor));
|
||||
user_ldt_derefl(pldt);
|
||||
}
|
||||
ssdtosyssd(&sldt, &p->p_md.md_ldt_sd);
|
||||
atomic_store_rel_ptr((volatile uintptr_t *)&mdp->md_ldt,
|
||||
(uintptr_t)new_ldt);
|
||||
if (p == curproc)
|
||||
set_user_ldt(mdp);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user