| 504 | } |
| 505 | |
| 506 | struct proc_ldt * |
| 507 | user_ldt_alloc(struct proc *p, int force) |
| 508 | { |
| 509 | struct proc_ldt *pldt, *new_ldt; |
| 510 | struct mdproc *mdp; |
| 511 | struct soft_segment_descriptor sldt; |
| 512 | vm_offset_t sva; |
| 513 | vm_size_t sz; |
| 514 | |
| 515 | mtx_assert(&dt_lock, MA_OWNED); |
| 516 | mdp = &p->p_md; |
| 517 | if (!force && mdp->md_ldt != NULL) |
| 518 | return (mdp->md_ldt); |
| 519 | mtx_unlock(&dt_lock); |
| 520 | new_ldt = malloc(sizeof(struct proc_ldt), M_SUBPROC, M_WAITOK); |
| 521 | sz = max_ldt_segment * sizeof(struct user_segment_descriptor); |
| 522 | sva = kmem_malloc(sz, M_WAITOK | M_ZERO); |
| 523 | new_ldt->ldt_base = (caddr_t)sva; |
| 524 | pmap_pti_add_kva(sva, sva + sz, false); |
| 525 | new_ldt->ldt_refcnt = 1; |
| 526 | sldt.ssd_base = sva; |
| 527 | sldt.ssd_limit = sz - 1; |
| 528 | sldt.ssd_type = SDT_SYSLDT; |
| 529 | sldt.ssd_dpl = SEL_KPL; |
| 530 | sldt.ssd_p = 1; |
| 531 | sldt.ssd_long = 0; |
| 532 | sldt.ssd_def32 = 0; |
| 533 | sldt.ssd_gran = 0; |
| 534 | mtx_lock(&dt_lock); |
| 535 | pldt = mdp->md_ldt; |
| 536 | if (pldt != NULL && !force) { |
| 537 | pmap_pti_remove_kva(sva, sva + sz); |
| 538 | kmem_free(sva, sz); |
| 539 | free(new_ldt, M_SUBPROC); |
| 540 | return (pldt); |
| 541 | } |
| 542 | |
| 543 | if (pldt != NULL) { |
| 544 | bcopy(pldt->ldt_base, new_ldt->ldt_base, max_ldt_segment * |
| 545 | sizeof(struct user_segment_descriptor)); |
| 546 | user_ldt_derefl(pldt); |
| 547 | } |
| 548 | critical_enter(); |
| 549 | ssdtosyssd(&sldt, &p->p_md.md_ldt_sd); |
| 550 | atomic_thread_fence_rel(); |
| 551 | mdp->md_ldt = new_ldt; |
| 552 | critical_exit(); |
| 553 | smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, NULL, |
| 554 | p->p_vmspace); |
| 555 | |
| 556 | return (mdp->md_ldt); |
| 557 | } |
| 558 | |
| 559 | void |
| 560 | user_ldt_free(struct thread *td) |
no test coverage detected