mirror of
https://github.com/opnsense/src.git
synced 2026-06-10 09:11:07 -04:00
Split the per-process Local Descriptor Table out of the PCB and into
struct mdproc. Submitted by: Andrew R. Reiter <arr@watson.org> Silence on: -current
This commit is contained in:
parent
7ce26133ea
commit
24db04598b
17 changed files with 215 additions and 172 deletions
|
|
@ -246,7 +246,8 @@ sw1b:
|
|||
/* XXX FIXME: we should be restoring the local APIC TPR */
|
||||
#endif /* SMP */
|
||||
|
||||
cmpl $0, PCB_USERLDT(%edx) /* if there is one */
|
||||
movl TD_PROC(%ecx), %eax /* load struct proc from CURTHREAD */
|
||||
cmpl $0, P_MD+MD_LDT(%eax) /* see if md_ldt == 0 */
|
||||
jnz 1f /* then use it */
|
||||
movl _default_ldt,%eax /* We will use the default */
|
||||
cmpl PCPU(CURRENTLDT),%eax /* check to see if already loaded */
|
||||
|
|
@ -255,9 +256,11 @@ sw1b:
|
|||
movl %eax,PCPU(CURRENTLDT) /* store what we have */
|
||||
jmp 2f
|
||||
|
||||
1: pushl %edx /* call a non-trusting routine */
|
||||
call set_user_ldt /* to check and load the ldt */
|
||||
popl %edx
|
||||
1: pushl %edx /* save edx */
|
||||
pushl P_MD+MD_LDT(%eax) /* passing p_md -> set_user_ldt */
|
||||
call set_user_ldt /* check and load the ldt */
|
||||
popl %eax /* get p_md off stack */
|
||||
popl %edx /* restore edx */
|
||||
2:
|
||||
|
||||
/* This must be done after loading the user LDT. */
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/proc.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <nfs/nfsproto.h>
|
||||
|
|
@ -76,6 +77,7 @@
|
|||
#include <machine/sigframe.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/vm86.h>
|
||||
#include <machine/proc.h>
|
||||
|
||||
ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
|
||||
ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
|
||||
|
|
@ -92,6 +94,9 @@ ASSYM(TD_KSE, offsetof(struct thread, td_kse));
|
|||
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
|
||||
ASSYM(TD_INTR_NESTING_LEVEL, offsetof(struct thread, td_intr_nesting_level));
|
||||
|
||||
ASSYM(P_MD, offsetof(struct proc, p_md));
|
||||
ASSYM(MD_LDT, offsetof(struct mdproc, md_ldt));
|
||||
|
||||
ASSYM(KE_FLAGS, offsetof(struct kse, ke_flags));
|
||||
|
||||
ASSYM(KEF_ASTPENDING, KEF_ASTPENDING);
|
||||
|
|
@ -126,7 +131,6 @@ ASSYM(PCB_EBX, offsetof(struct pcb, pcb_ebx));
|
|||
ASSYM(PCB_EIP, offsetof(struct pcb, pcb_eip));
|
||||
ASSYM(TSS_ESP0, offsetof(struct i386tss, tss_esp0));
|
||||
|
||||
ASSYM(PCB_USERLDT, offsetof(struct pcb, pcb_ldt));
|
||||
ASSYM(PCB_GS, offsetof(struct pcb, pcb_gs));
|
||||
ASSYM(PCB_DR0, offsetof(struct pcb, pcb_dr0));
|
||||
ASSYM(PCB_DR1, offsetof(struct pcb, pcb_dr1));
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@
|
|||
#include <machine/md_var.h>
|
||||
#include <machine/pc/bios.h>
|
||||
#include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
|
||||
#include <machine/proc.h>
|
||||
#include <machine/globals.h>
|
||||
#ifdef PERFMON
|
||||
#include <machine/perfmon.h>
|
||||
|
|
@ -880,8 +881,8 @@ setregs(td, entry, stack, ps_strings)
|
|||
struct trapframe *regs = td->td_frame;
|
||||
struct pcb *pcb = td->td_pcb;
|
||||
|
||||
if (pcb->pcb_ldt)
|
||||
user_ldt_free(pcb);
|
||||
if (td->td_proc->p_md.md_ldt)
|
||||
user_ldt_free(td);
|
||||
|
||||
bzero((char *)regs, sizeof(struct trapframe));
|
||||
regs->tf_eip = entry;
|
||||
|
|
|
|||
|
|
@ -246,7 +246,8 @@ sw1b:
|
|||
/* XXX FIXME: we should be restoring the local APIC TPR */
|
||||
#endif /* SMP */
|
||||
|
||||
cmpl $0, PCB_USERLDT(%edx) /* if there is one */
|
||||
movl TD_PROC(%ecx), %eax /* load struct proc from CURTHREAD */
|
||||
cmpl $0, P_MD+MD_LDT(%eax) /* see if md_ldt == 0 */
|
||||
jnz 1f /* then use it */
|
||||
movl _default_ldt,%eax /* We will use the default */
|
||||
cmpl PCPU(CURRENTLDT),%eax /* check to see if already loaded */
|
||||
|
|
@ -255,9 +256,11 @@ sw1b:
|
|||
movl %eax,PCPU(CURRENTLDT) /* store what we have */
|
||||
jmp 2f
|
||||
|
||||
1: pushl %edx /* call a non-trusting routine */
|
||||
call set_user_ldt /* to check and load the ldt */
|
||||
popl %edx
|
||||
1: pushl %edx /* save edx */
|
||||
pushl P_MD+MD_LDT(%eax) /* passing p_md -> set_user_ldt */
|
||||
call set_user_ldt /* check and load the ldt */
|
||||
popl %eax /* get p_md off stack */
|
||||
popl %edx /* restore edx */
|
||||
2:
|
||||
|
||||
/* This must be done after loading the user LDT. */
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pcb_ext.h> /* pcb.h included by sys/user.h */
|
||||
#include <machine/proc.h>
|
||||
#include <machine/sysarch.h>
|
||||
|
||||
#include <vm/vm_kern.h> /* for kernel_map */
|
||||
|
|
@ -70,7 +71,7 @@ static int i386_set_ldt __P((struct thread *, char *));
|
|||
static int i386_get_ioperm __P((struct thread *, char *));
|
||||
static int i386_set_ioperm __P((struct thread *, char *));
|
||||
#ifdef SMP
|
||||
static void set_user_ldt_rv __P((struct pcb *));
|
||||
static void set_user_ldt_rv __P((struct thread *));
|
||||
#endif
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
|
|
@ -256,15 +257,15 @@ done:
|
|||
* curproc but before sched_lock's owner is updated in mi_switch().
|
||||
*/
|
||||
void
|
||||
set_user_ldt(struct pcb *pcb)
|
||||
set_user_ldt(struct mdproc *mdp)
|
||||
{
|
||||
struct pcb_ldt *pcb_ldt;
|
||||
struct proc_ldt *pldt;
|
||||
|
||||
pcb_ldt = pcb->pcb_ldt;
|
||||
pldt = mdp->md_ldt;
|
||||
#ifdef SMP
|
||||
gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
|
||||
gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pldt->ldt_sd;
|
||||
#else
|
||||
gdt[GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
|
||||
gdt[GUSERLDT_SEL].sd = pldt->ldt_sd;
|
||||
#endif
|
||||
lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
|
||||
PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL));
|
||||
|
|
@ -272,14 +273,14 @@ set_user_ldt(struct pcb *pcb)
|
|||
|
||||
#ifdef SMP
|
||||
static void
|
||||
set_user_ldt_rv(struct pcb *pcb)
|
||||
set_user_ldt_rv(struct thread *td)
|
||||
{
|
||||
|
||||
if (pcb != PCPU_GET(curpcb))
|
||||
if (td != PCPU_GET(curthread))
|
||||
return;
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
set_user_ldt(pcb);
|
||||
set_user_ldt(&td->td_proc->p_md);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -288,15 +289,15 @@ set_user_ldt_rv(struct pcb *pcb)
|
|||
* Must be called with either sched_lock free or held but not recursed.
|
||||
* If it does not return NULL, it will return with it owned.
|
||||
*/
|
||||
struct pcb_ldt *
|
||||
user_ldt_alloc(struct pcb *pcb, int len)
|
||||
struct proc_ldt *
|
||||
user_ldt_alloc(struct mdproc *mdp, int len)
|
||||
{
|
||||
struct pcb_ldt *pcb_ldt, *new_ldt;
|
||||
struct proc_ldt *pldt, *new_ldt;
|
||||
|
||||
if (mtx_owned(&sched_lock))
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
mtx_assert(&sched_lock, MA_NOTOWNED);
|
||||
MALLOC(new_ldt, struct pcb_ldt *, sizeof(struct pcb_ldt),
|
||||
MALLOC(new_ldt, struct proc_ldt *, sizeof(struct proc_ldt),
|
||||
M_SUBPROC, M_WAITOK);
|
||||
|
||||
new_ldt->ldt_len = len = NEW_MAX_LD(len);
|
||||
|
|
@ -314,11 +315,11 @@ user_ldt_alloc(struct pcb *pcb, int len)
|
|||
gdt_segs[GUSERLDT_SEL].ssd_limit = len * sizeof(union descriptor) - 1;
|
||||
ssdtosd(&gdt_segs[GUSERLDT_SEL], &new_ldt->ldt_sd);
|
||||
|
||||
if ((pcb_ldt = pcb->pcb_ldt)) {
|
||||
if (len > pcb_ldt->ldt_len)
|
||||
len = pcb_ldt->ldt_len;
|
||||
bcopy(pcb_ldt->ldt_base, new_ldt->ldt_base,
|
||||
len * sizeof(union descriptor));
|
||||
if ((pldt = mdp->md_ldt)) {
|
||||
if (len > pldt->ldt_len)
|
||||
len = pldt->ldt_len;
|
||||
bcopy(pldt->ldt_base, new_ldt->ldt_base,
|
||||
len * sizeof(union descriptor));
|
||||
} else {
|
||||
bcopy(ldt, new_ldt->ldt_base, sizeof(ldt));
|
||||
}
|
||||
|
|
@ -327,30 +328,31 @@ user_ldt_alloc(struct pcb *pcb, int len)
|
|||
|
||||
/*
|
||||
* Must be called either with sched_lock free or held but not recursed.
|
||||
* If pcb->pcb_ldt is not NULL, it will return with sched_lock released.
|
||||
* If md_ldt is not NULL, it will return with sched_lock released.
|
||||
*/
|
||||
void
|
||||
user_ldt_free(struct pcb *pcb)
|
||||
user_ldt_free(struct thread *td)
|
||||
{
|
||||
struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
|
||||
struct mdproc *mdp = &td->td_proc->p_md;
|
||||
struct proc_ldt *pldt = mdp->md_ldt;
|
||||
|
||||
if (pcb_ldt == NULL)
|
||||
if (pldt == NULL)
|
||||
return;
|
||||
|
||||
if (!mtx_owned(&sched_lock))
|
||||
mtx_lock_spin(&sched_lock);
|
||||
mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED);
|
||||
if (pcb == PCPU_GET(curpcb)) {
|
||||
if (td == PCPU_GET(curthread)) {
|
||||
lldt(_default_ldt);
|
||||
PCPU_SET(currentldt, _default_ldt);
|
||||
}
|
||||
|
||||
pcb->pcb_ldt = NULL;
|
||||
if (--pcb_ldt->ldt_refcnt == 0) {
|
||||
mdp->md_ldt = NULL;
|
||||
if (--pldt->ldt_refcnt == 0) {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
kmem_free(kernel_map, (vm_offset_t)pcb_ldt->ldt_base,
|
||||
pcb_ldt->ldt_len * sizeof(union descriptor));
|
||||
FREE(pcb_ldt, M_SUBPROC);
|
||||
kmem_free(kernel_map, (vm_offset_t)pldt->ldt_base,
|
||||
pldt->ldt_len * sizeof(union descriptor));
|
||||
FREE(pldt, M_SUBPROC);
|
||||
} else
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
|
|
@ -361,8 +363,7 @@ i386_get_ldt(td, args)
|
|||
char *args;
|
||||
{
|
||||
int error = 0;
|
||||
struct pcb *pcb = td->td_pcb;
|
||||
struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
|
||||
struct proc_ldt *pldt = td->td_proc->p_md.md_ldt;
|
||||
int nldt, num;
|
||||
union descriptor *lp;
|
||||
struct i386_ldt_args ua, *uap = &ua;
|
||||
|
|
@ -379,10 +380,10 @@ i386_get_ldt(td, args)
|
|||
if ((uap->start < 0) || (uap->num <= 0))
|
||||
return(EINVAL);
|
||||
|
||||
if (pcb_ldt) {
|
||||
nldt = pcb_ldt->ldt_len;
|
||||
if (pldt) {
|
||||
nldt = pldt->ldt_len;
|
||||
num = min(uap->num, nldt);
|
||||
lp = &((union descriptor *)(pcb_ldt->ldt_base))[uap->start];
|
||||
lp = &((union descriptor *)(pldt->ldt_base))[uap->start];
|
||||
} else {
|
||||
nldt = sizeof(ldt)/sizeof(ldt[0]);
|
||||
num = min(uap->num, nldt);
|
||||
|
|
@ -405,8 +406,8 @@ i386_set_ldt(td, args)
|
|||
{
|
||||
int error = 0, i, n;
|
||||
int largest_ld;
|
||||
struct pcb *pcb = td->td_pcb;
|
||||
struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
|
||||
struct mdproc *mdp = &td->td_proc->p_md;
|
||||
struct proc_ldt *pldt = mdp->md_ldt;
|
||||
struct i386_ldt_args ua, *uap = &ua;
|
||||
caddr_t old_ldt_base;
|
||||
int old_ldt_len;
|
||||
|
|
@ -431,16 +432,16 @@ i386_set_ldt(td, args)
|
|||
return(EINVAL);
|
||||
|
||||
/* allocate user ldt */
|
||||
if (!pcb_ldt || largest_ld >= pcb_ldt->ldt_len) {
|
||||
struct pcb_ldt *new_ldt = user_ldt_alloc(pcb, largest_ld);
|
||||
if (!pldt || largest_ld >= pldt->ldt_len) {
|
||||
struct proc_ldt *new_ldt = user_ldt_alloc(mdp, largest_ld);
|
||||
if (new_ldt == NULL)
|
||||
return ENOMEM;
|
||||
if (pcb_ldt) {
|
||||
old_ldt_base = pcb_ldt->ldt_base;
|
||||
old_ldt_len = pcb_ldt->ldt_len;
|
||||
pcb_ldt->ldt_sd = new_ldt->ldt_sd;
|
||||
pcb_ldt->ldt_base = new_ldt->ldt_base;
|
||||
pcb_ldt->ldt_len = new_ldt->ldt_len;
|
||||
if (pldt) {
|
||||
old_ldt_base = pldt->ldt_base;
|
||||
old_ldt_len = pldt->ldt_len;
|
||||
pldt->ldt_sd = new_ldt->ldt_sd;
|
||||
pldt->ldt_base = new_ldt->ldt_base;
|
||||
pldt->ldt_len = new_ldt->ldt_len;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
kmem_free(kernel_map, (vm_offset_t)old_ldt_base,
|
||||
old_ldt_len * sizeof(union descriptor));
|
||||
|
|
@ -449,16 +450,17 @@ i386_set_ldt(td, args)
|
|||
mtx_lock_spin(&sched_lock);
|
||||
#endif
|
||||
} else {
|
||||
pcb->pcb_ldt = pcb_ldt = new_ldt;
|
||||
mdp->md_ldt = pldt = new_ldt;
|
||||
#ifdef SMP
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
#endif
|
||||
}
|
||||
#ifdef SMP
|
||||
/* signal other cpus to reload ldt */
|
||||
smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, NULL, pcb);
|
||||
smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv,
|
||||
NULL, td);
|
||||
#else
|
||||
set_user_ldt(pcb);
|
||||
set_user_ldt(mdp);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -532,7 +534,7 @@ i386_set_ldt(td, args)
|
|||
/* Fill in range */
|
||||
savecrit = critical_enter();
|
||||
error = copyin(uap->descs,
|
||||
&((union descriptor *)(pcb_ldt->ldt_base))[uap->start],
|
||||
&((union descriptor *)(pldt->ldt_base))[uap->start],
|
||||
uap->num * sizeof(union descriptor));
|
||||
if (!error)
|
||||
td->td_retval[0] = uap->start;
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ cpu_fork(td1, p2, flags)
|
|||
register struct proc *p1;
|
||||
struct thread *td2;
|
||||
struct pcb *pcb2;
|
||||
struct mdproc *mdp2;
|
||||
#ifdef DEV_NPX
|
||||
int savecrit;
|
||||
#endif
|
||||
|
|
@ -134,15 +135,15 @@ cpu_fork(td1, p2, flags)
|
|||
if ((flags & RFPROC) == 0) {
|
||||
if ((flags & RFMEM) == 0) {
|
||||
/* unshare user LDT */
|
||||
struct pcb *pcb1 = td1->td_pcb;
|
||||
struct pcb_ldt *pcb_ldt = pcb1->pcb_ldt;
|
||||
if (pcb_ldt && pcb_ldt->ldt_refcnt > 1) {
|
||||
pcb_ldt = user_ldt_alloc(pcb1,pcb_ldt->ldt_len);
|
||||
if (pcb_ldt == NULL)
|
||||
struct mdproc *mdp1 = &td1->td_proc->p_md;
|
||||
struct proc_ldt *pldt = mdp1->md_ldt;
|
||||
if (pldt && pldt->ldt_refcnt > 1) {
|
||||
pldt = user_ldt_alloc(mdp1, pldt->ldt_len);
|
||||
if (pldt == NULL)
|
||||
panic("could not copy LDT");
|
||||
pcb1->pcb_ldt = pcb_ldt;
|
||||
set_user_ldt(pcb1);
|
||||
user_ldt_free(pcb1);
|
||||
mdp1->md_ldt = pldt;
|
||||
set_user_ldt(mdp1);
|
||||
user_ldt_free(td1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -162,9 +163,13 @@ cpu_fork(td1, p2, flags)
|
|||
pcb2 = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
td2->td_pcb = pcb2;
|
||||
|
||||
/* Copy p1's pcb. */
|
||||
/* Copy p1's pcb */
|
||||
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
|
||||
|
||||
/* Point mdproc and then copy over td1's contents */
|
||||
mdp2 = &td2->td_proc->p_md;
|
||||
bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
|
||||
|
||||
/*
|
||||
* Create a new fresh stack for the new process.
|
||||
* Copy the trap frame for the return to user mode as if from a
|
||||
|
|
@ -191,7 +196,6 @@ cpu_fork(td1, p2, flags)
|
|||
pcb2->pcb_eip = (int)fork_trampoline;
|
||||
/*-
|
||||
* pcb2->pcb_dr*: cloned above.
|
||||
* pcb2->pcb_ldt: duplicated below, if necessary.
|
||||
* pcb2->pcb_savefpu: cloned above.
|
||||
* pcb2->pcb_flags: cloned above.
|
||||
* pcb2->pcb_onfault: cloned above (always NULL here?).
|
||||
|
|
@ -206,13 +210,13 @@ cpu_fork(td1, p2, flags)
|
|||
|
||||
/* Copy the LDT, if necessary. */
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if (pcb2->pcb_ldt != 0) {
|
||||
if (mdp2->md_ldt != 0) {
|
||||
if (flags & RFMEM) {
|
||||
pcb2->pcb_ldt->ldt_refcnt++;
|
||||
mdp2->md_ldt->ldt_refcnt++;
|
||||
} else {
|
||||
pcb2->pcb_ldt = user_ldt_alloc(pcb2,
|
||||
pcb2->pcb_ldt->ldt_len);
|
||||
if (pcb2->pcb_ldt == NULL)
|
||||
mdp2->md_ldt = user_ldt_alloc(mdp2,
|
||||
mdp2->md_ldt->ldt_len);
|
||||
if (mdp2->md_ldt == NULL)
|
||||
panic("could not copy LDT");
|
||||
}
|
||||
}
|
||||
|
|
@ -254,7 +258,7 @@ cpu_exit(td)
|
|||
register struct thread *td;
|
||||
{
|
||||
struct pcb *pcb = td->td_pcb;
|
||||
|
||||
struct mdproc *mdp = &td->td_proc->p_md;
|
||||
#ifdef DEV_NPX
|
||||
npxexit(td);
|
||||
#endif
|
||||
|
|
@ -267,8 +271,8 @@ cpu_exit(td)
|
|||
ctob(IOPAGES + 1));
|
||||
pcb->pcb_ext = 0;
|
||||
}
|
||||
if (pcb->pcb_ldt)
|
||||
user_ldt_free(pcb);
|
||||
if (mdp->md_ldt)
|
||||
user_ldt_free(td);
|
||||
if (pcb->pcb_flags & PCB_DBREGS) {
|
||||
/*
|
||||
* disable all hardware breakpoints
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ struct pcb {
|
|||
int pcb_dr6;
|
||||
int pcb_dr7;
|
||||
|
||||
struct pcb_ldt *pcb_ldt; /* per process (user) LDT */
|
||||
union savefpu pcb_save;
|
||||
u_char pcb_flags;
|
||||
#define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */
|
||||
|
|
|
|||
|
|
@ -43,20 +43,9 @@ struct pcb_ext {
|
|||
struct vm86_kernel ext_vm86; /* vm86 area */
|
||||
};
|
||||
|
||||
struct pcb_ldt {
|
||||
caddr_t ldt_base;
|
||||
int ldt_len;
|
||||
int ldt_refcnt;
|
||||
u_long ldt_active;
|
||||
struct segment_descriptor ldt_sd;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
int i386_extend_pcb __P((struct thread *));
|
||||
void set_user_ldt __P((struct pcb *));
|
||||
struct pcb_ldt *user_ldt_alloc __P((struct pcb *, int));
|
||||
void user_ldt_free __P((struct pcb *));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,15 @@
|
|||
#define _MACHINE_PROC_H_
|
||||
|
||||
#include <machine/globals.h>
|
||||
#include <machine/segments.h>
|
||||
|
||||
struct proc_ldt {
|
||||
caddr_t ldt_base;
|
||||
int ldt_len;
|
||||
int ldt_refcnt;
|
||||
u_long ldt_active;
|
||||
struct segment_descriptor ldt_sd;
|
||||
};
|
||||
|
||||
/*
|
||||
* Machine-dependent part of the proc structure for i386.
|
||||
|
|
@ -46,6 +55,15 @@ struct mdthread {
|
|||
};
|
||||
|
||||
struct mdproc {
|
||||
struct proc_ldt *md_ldt; /* per-process ldt */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
void set_user_ldt __P((struct mdproc *));
|
||||
struct proc_ldt *user_ldt_alloc __P((struct mdproc *, int));
|
||||
void user_ldt_free __P((struct thread *));
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_PROC_H_ */
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/proc.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <nfs/nfsproto.h>
|
||||
|
|
@ -76,6 +77,7 @@
|
|||
#include <machine/sigframe.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/vm86.h>
|
||||
#include <machine/proc.h>
|
||||
|
||||
ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
|
||||
ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
|
||||
|
|
@ -92,6 +94,9 @@ ASSYM(TD_KSE, offsetof(struct thread, td_kse));
|
|||
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
|
||||
ASSYM(TD_INTR_NESTING_LEVEL, offsetof(struct thread, td_intr_nesting_level));
|
||||
|
||||
ASSYM(P_MD, offsetof(struct proc, p_md));
|
||||
ASSYM(MD_LDT, offsetof(struct mdproc, md_ldt));
|
||||
|
||||
ASSYM(KE_FLAGS, offsetof(struct kse, ke_flags));
|
||||
|
||||
ASSYM(KEF_ASTPENDING, KEF_ASTPENDING);
|
||||
|
|
@ -126,7 +131,6 @@ ASSYM(PCB_EBX, offsetof(struct pcb, pcb_ebx));
|
|||
ASSYM(PCB_EIP, offsetof(struct pcb, pcb_eip));
|
||||
ASSYM(TSS_ESP0, offsetof(struct i386tss, tss_esp0));
|
||||
|
||||
ASSYM(PCB_USERLDT, offsetof(struct pcb, pcb_ldt));
|
||||
ASSYM(PCB_GS, offsetof(struct pcb, pcb_gs));
|
||||
ASSYM(PCB_DR0, offsetof(struct pcb, pcb_dr0));
|
||||
ASSYM(PCB_DR1, offsetof(struct pcb, pcb_dr1));
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@
|
|||
#include <machine/md_var.h>
|
||||
#include <machine/pc/bios.h>
|
||||
#include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
|
||||
#include <machine/proc.h>
|
||||
#include <machine/globals.h>
|
||||
#ifdef PERFMON
|
||||
#include <machine/perfmon.h>
|
||||
|
|
@ -880,8 +881,8 @@ setregs(td, entry, stack, ps_strings)
|
|||
struct trapframe *regs = td->td_frame;
|
||||
struct pcb *pcb = td->td_pcb;
|
||||
|
||||
if (pcb->pcb_ldt)
|
||||
user_ldt_free(pcb);
|
||||
if (td->td_proc->p_md.md_ldt)
|
||||
user_ldt_free(td);
|
||||
|
||||
bzero((char *)regs, sizeof(struct trapframe));
|
||||
regs->tf_eip = entry;
|
||||
|
|
|
|||
|
|
@ -246,7 +246,8 @@ sw1b:
|
|||
/* XXX FIXME: we should be restoring the local APIC TPR */
|
||||
#endif /* SMP */
|
||||
|
||||
cmpl $0, PCB_USERLDT(%edx) /* if there is one */
|
||||
movl TD_PROC(%ecx), %eax /* load struct proc from CURTHREAD */
|
||||
cmpl $0, P_MD+MD_LDT(%eax) /* see if md_ldt == 0 */
|
||||
jnz 1f /* then use it */
|
||||
movl _default_ldt,%eax /* We will use the default */
|
||||
cmpl PCPU(CURRENTLDT),%eax /* check to see if already loaded */
|
||||
|
|
@ -255,9 +256,11 @@ sw1b:
|
|||
movl %eax,PCPU(CURRENTLDT) /* store what we have */
|
||||
jmp 2f
|
||||
|
||||
1: pushl %edx /* call a non-trusting routine */
|
||||
call set_user_ldt /* to check and load the ldt */
|
||||
popl %edx
|
||||
1: pushl %edx /* save edx */
|
||||
pushl P_MD+MD_LDT(%eax) /* passing p_md -> set_user_ldt */
|
||||
call set_user_ldt /* check and load the ldt */
|
||||
popl %eax /* get p_md off stack */
|
||||
popl %edx /* restore edx */
|
||||
2:
|
||||
|
||||
/* This must be done after loading the user LDT. */
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pcb_ext.h> /* pcb.h included by sys/user.h */
|
||||
#include <machine/proc.h>
|
||||
#include <machine/sysarch.h>
|
||||
|
||||
#include <vm/vm_kern.h> /* for kernel_map */
|
||||
|
|
@ -70,7 +71,7 @@ static int i386_set_ldt __P((struct thread *, char *));
|
|||
static int i386_get_ioperm __P((struct thread *, char *));
|
||||
static int i386_set_ioperm __P((struct thread *, char *));
|
||||
#ifdef SMP
|
||||
static void set_user_ldt_rv __P((struct pcb *));
|
||||
static void set_user_ldt_rv __P((struct thread *));
|
||||
#endif
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
|
|
@ -256,15 +257,15 @@ done:
|
|||
* curproc but before sched_lock's owner is updated in mi_switch().
|
||||
*/
|
||||
void
|
||||
set_user_ldt(struct pcb *pcb)
|
||||
set_user_ldt(struct mdproc *mdp)
|
||||
{
|
||||
struct pcb_ldt *pcb_ldt;
|
||||
struct proc_ldt *pldt;
|
||||
|
||||
pcb_ldt = pcb->pcb_ldt;
|
||||
pldt = mdp->md_ldt;
|
||||
#ifdef SMP
|
||||
gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
|
||||
gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pldt->ldt_sd;
|
||||
#else
|
||||
gdt[GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
|
||||
gdt[GUSERLDT_SEL].sd = pldt->ldt_sd;
|
||||
#endif
|
||||
lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
|
||||
PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL));
|
||||
|
|
@ -272,14 +273,14 @@ set_user_ldt(struct pcb *pcb)
|
|||
|
||||
#ifdef SMP
|
||||
static void
|
||||
set_user_ldt_rv(struct pcb *pcb)
|
||||
set_user_ldt_rv(struct thread *td)
|
||||
{
|
||||
|
||||
if (pcb != PCPU_GET(curpcb))
|
||||
if (td != PCPU_GET(curthread))
|
||||
return;
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
set_user_ldt(pcb);
|
||||
set_user_ldt(&td->td_proc->p_md);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -288,15 +289,15 @@ set_user_ldt_rv(struct pcb *pcb)
|
|||
* Must be called with either sched_lock free or held but not recursed.
|
||||
* If it does not return NULL, it will return with it owned.
|
||||
*/
|
||||
struct pcb_ldt *
|
||||
user_ldt_alloc(struct pcb *pcb, int len)
|
||||
struct proc_ldt *
|
||||
user_ldt_alloc(struct mdproc *mdp, int len)
|
||||
{
|
||||
struct pcb_ldt *pcb_ldt, *new_ldt;
|
||||
struct proc_ldt *pldt, *new_ldt;
|
||||
|
||||
if (mtx_owned(&sched_lock))
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
mtx_assert(&sched_lock, MA_NOTOWNED);
|
||||
MALLOC(new_ldt, struct pcb_ldt *, sizeof(struct pcb_ldt),
|
||||
MALLOC(new_ldt, struct proc_ldt *, sizeof(struct proc_ldt),
|
||||
M_SUBPROC, M_WAITOK);
|
||||
|
||||
new_ldt->ldt_len = len = NEW_MAX_LD(len);
|
||||
|
|
@ -314,11 +315,11 @@ user_ldt_alloc(struct pcb *pcb, int len)
|
|||
gdt_segs[GUSERLDT_SEL].ssd_limit = len * sizeof(union descriptor) - 1;
|
||||
ssdtosd(&gdt_segs[GUSERLDT_SEL], &new_ldt->ldt_sd);
|
||||
|
||||
if ((pcb_ldt = pcb->pcb_ldt)) {
|
||||
if (len > pcb_ldt->ldt_len)
|
||||
len = pcb_ldt->ldt_len;
|
||||
bcopy(pcb_ldt->ldt_base, new_ldt->ldt_base,
|
||||
len * sizeof(union descriptor));
|
||||
if ((pldt = mdp->md_ldt)) {
|
||||
if (len > pldt->ldt_len)
|
||||
len = pldt->ldt_len;
|
||||
bcopy(pldt->ldt_base, new_ldt->ldt_base,
|
||||
len * sizeof(union descriptor));
|
||||
} else {
|
||||
bcopy(ldt, new_ldt->ldt_base, sizeof(ldt));
|
||||
}
|
||||
|
|
@ -327,30 +328,31 @@ user_ldt_alloc(struct pcb *pcb, int len)
|
|||
|
||||
/*
|
||||
* Must be called either with sched_lock free or held but not recursed.
|
||||
* If pcb->pcb_ldt is not NULL, it will return with sched_lock released.
|
||||
* If md_ldt is not NULL, it will return with sched_lock released.
|
||||
*/
|
||||
void
|
||||
user_ldt_free(struct pcb *pcb)
|
||||
user_ldt_free(struct thread *td)
|
||||
{
|
||||
struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
|
||||
struct mdproc *mdp = &td->td_proc->p_md;
|
||||
struct proc_ldt *pldt = mdp->md_ldt;
|
||||
|
||||
if (pcb_ldt == NULL)
|
||||
if (pldt == NULL)
|
||||
return;
|
||||
|
||||
if (!mtx_owned(&sched_lock))
|
||||
mtx_lock_spin(&sched_lock);
|
||||
mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED);
|
||||
if (pcb == PCPU_GET(curpcb)) {
|
||||
if (td == PCPU_GET(curthread)) {
|
||||
lldt(_default_ldt);
|
||||
PCPU_SET(currentldt, _default_ldt);
|
||||
}
|
||||
|
||||
pcb->pcb_ldt = NULL;
|
||||
if (--pcb_ldt->ldt_refcnt == 0) {
|
||||
mdp->md_ldt = NULL;
|
||||
if (--pldt->ldt_refcnt == 0) {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
kmem_free(kernel_map, (vm_offset_t)pcb_ldt->ldt_base,
|
||||
pcb_ldt->ldt_len * sizeof(union descriptor));
|
||||
FREE(pcb_ldt, M_SUBPROC);
|
||||
kmem_free(kernel_map, (vm_offset_t)pldt->ldt_base,
|
||||
pldt->ldt_len * sizeof(union descriptor));
|
||||
FREE(pldt, M_SUBPROC);
|
||||
} else
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
|
|
@ -361,8 +363,7 @@ i386_get_ldt(td, args)
|
|||
char *args;
|
||||
{
|
||||
int error = 0;
|
||||
struct pcb *pcb = td->td_pcb;
|
||||
struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
|
||||
struct proc_ldt *pldt = td->td_proc->p_md.md_ldt;
|
||||
int nldt, num;
|
||||
union descriptor *lp;
|
||||
struct i386_ldt_args ua, *uap = &ua;
|
||||
|
|
@ -379,10 +380,10 @@ i386_get_ldt(td, args)
|
|||
if ((uap->start < 0) || (uap->num <= 0))
|
||||
return(EINVAL);
|
||||
|
||||
if (pcb_ldt) {
|
||||
nldt = pcb_ldt->ldt_len;
|
||||
if (pldt) {
|
||||
nldt = pldt->ldt_len;
|
||||
num = min(uap->num, nldt);
|
||||
lp = &((union descriptor *)(pcb_ldt->ldt_base))[uap->start];
|
||||
lp = &((union descriptor *)(pldt->ldt_base))[uap->start];
|
||||
} else {
|
||||
nldt = sizeof(ldt)/sizeof(ldt[0]);
|
||||
num = min(uap->num, nldt);
|
||||
|
|
@ -405,8 +406,8 @@ i386_set_ldt(td, args)
|
|||
{
|
||||
int error = 0, i, n;
|
||||
int largest_ld;
|
||||
struct pcb *pcb = td->td_pcb;
|
||||
struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
|
||||
struct mdproc *mdp = &td->td_proc->p_md;
|
||||
struct proc_ldt *pldt = mdp->md_ldt;
|
||||
struct i386_ldt_args ua, *uap = &ua;
|
||||
caddr_t old_ldt_base;
|
||||
int old_ldt_len;
|
||||
|
|
@ -431,16 +432,16 @@ i386_set_ldt(td, args)
|
|||
return(EINVAL);
|
||||
|
||||
/* allocate user ldt */
|
||||
if (!pcb_ldt || largest_ld >= pcb_ldt->ldt_len) {
|
||||
struct pcb_ldt *new_ldt = user_ldt_alloc(pcb, largest_ld);
|
||||
if (!pldt || largest_ld >= pldt->ldt_len) {
|
||||
struct proc_ldt *new_ldt = user_ldt_alloc(mdp, largest_ld);
|
||||
if (new_ldt == NULL)
|
||||
return ENOMEM;
|
||||
if (pcb_ldt) {
|
||||
old_ldt_base = pcb_ldt->ldt_base;
|
||||
old_ldt_len = pcb_ldt->ldt_len;
|
||||
pcb_ldt->ldt_sd = new_ldt->ldt_sd;
|
||||
pcb_ldt->ldt_base = new_ldt->ldt_base;
|
||||
pcb_ldt->ldt_len = new_ldt->ldt_len;
|
||||
if (pldt) {
|
||||
old_ldt_base = pldt->ldt_base;
|
||||
old_ldt_len = pldt->ldt_len;
|
||||
pldt->ldt_sd = new_ldt->ldt_sd;
|
||||
pldt->ldt_base = new_ldt->ldt_base;
|
||||
pldt->ldt_len = new_ldt->ldt_len;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
kmem_free(kernel_map, (vm_offset_t)old_ldt_base,
|
||||
old_ldt_len * sizeof(union descriptor));
|
||||
|
|
@ -449,16 +450,17 @@ i386_set_ldt(td, args)
|
|||
mtx_lock_spin(&sched_lock);
|
||||
#endif
|
||||
} else {
|
||||
pcb->pcb_ldt = pcb_ldt = new_ldt;
|
||||
mdp->md_ldt = pldt = new_ldt;
|
||||
#ifdef SMP
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
#endif
|
||||
}
|
||||
#ifdef SMP
|
||||
/* signal other cpus to reload ldt */
|
||||
smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, NULL, pcb);
|
||||
smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv,
|
||||
NULL, td);
|
||||
#else
|
||||
set_user_ldt(pcb);
|
||||
set_user_ldt(mdp);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -532,7 +534,7 @@ i386_set_ldt(td, args)
|
|||
/* Fill in range */
|
||||
savecrit = critical_enter();
|
||||
error = copyin(uap->descs,
|
||||
&((union descriptor *)(pcb_ldt->ldt_base))[uap->start],
|
||||
&((union descriptor *)(pldt->ldt_base))[uap->start],
|
||||
uap->num * sizeof(union descriptor));
|
||||
if (!error)
|
||||
td->td_retval[0] = uap->start;
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ cpu_fork(td1, p2, flags)
|
|||
register struct proc *p1;
|
||||
struct thread *td2;
|
||||
struct pcb *pcb2;
|
||||
struct mdproc *mdp2;
|
||||
#ifdef DEV_NPX
|
||||
int savecrit;
|
||||
#endif
|
||||
|
|
@ -134,15 +135,15 @@ cpu_fork(td1, p2, flags)
|
|||
if ((flags & RFPROC) == 0) {
|
||||
if ((flags & RFMEM) == 0) {
|
||||
/* unshare user LDT */
|
||||
struct pcb *pcb1 = td1->td_pcb;
|
||||
struct pcb_ldt *pcb_ldt = pcb1->pcb_ldt;
|
||||
if (pcb_ldt && pcb_ldt->ldt_refcnt > 1) {
|
||||
pcb_ldt = user_ldt_alloc(pcb1,pcb_ldt->ldt_len);
|
||||
if (pcb_ldt == NULL)
|
||||
struct mdproc *mdp1 = &td1->td_proc->p_md;
|
||||
struct proc_ldt *pldt = mdp1->md_ldt;
|
||||
if (pldt && pldt->ldt_refcnt > 1) {
|
||||
pldt = user_ldt_alloc(mdp1, pldt->ldt_len);
|
||||
if (pldt == NULL)
|
||||
panic("could not copy LDT");
|
||||
pcb1->pcb_ldt = pcb_ldt;
|
||||
set_user_ldt(pcb1);
|
||||
user_ldt_free(pcb1);
|
||||
mdp1->md_ldt = pldt;
|
||||
set_user_ldt(mdp1);
|
||||
user_ldt_free(td1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -162,9 +163,13 @@ cpu_fork(td1, p2, flags)
|
|||
pcb2 = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
td2->td_pcb = pcb2;
|
||||
|
||||
/* Copy p1's pcb. */
|
||||
/* Copy p1's pcb */
|
||||
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
|
||||
|
||||
/* Point mdproc and then copy over td1's contents */
|
||||
mdp2 = &td2->td_proc->p_md;
|
||||
bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
|
||||
|
||||
/*
|
||||
* Create a new fresh stack for the new process.
|
||||
* Copy the trap frame for the return to user mode as if from a
|
||||
|
|
@ -191,7 +196,6 @@ cpu_fork(td1, p2, flags)
|
|||
pcb2->pcb_eip = (int)fork_trampoline;
|
||||
/*-
|
||||
* pcb2->pcb_dr*: cloned above.
|
||||
* pcb2->pcb_ldt: duplicated below, if necessary.
|
||||
* pcb2->pcb_savefpu: cloned above.
|
||||
* pcb2->pcb_flags: cloned above.
|
||||
* pcb2->pcb_onfault: cloned above (always NULL here?).
|
||||
|
|
@ -206,13 +210,13 @@ cpu_fork(td1, p2, flags)
|
|||
|
||||
/* Copy the LDT, if necessary. */
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if (pcb2->pcb_ldt != 0) {
|
||||
if (mdp2->md_ldt != 0) {
|
||||
if (flags & RFMEM) {
|
||||
pcb2->pcb_ldt->ldt_refcnt++;
|
||||
mdp2->md_ldt->ldt_refcnt++;
|
||||
} else {
|
||||
pcb2->pcb_ldt = user_ldt_alloc(pcb2,
|
||||
pcb2->pcb_ldt->ldt_len);
|
||||
if (pcb2->pcb_ldt == NULL)
|
||||
mdp2->md_ldt = user_ldt_alloc(mdp2,
|
||||
mdp2->md_ldt->ldt_len);
|
||||
if (mdp2->md_ldt == NULL)
|
||||
panic("could not copy LDT");
|
||||
}
|
||||
}
|
||||
|
|
@ -254,7 +258,7 @@ cpu_exit(td)
|
|||
register struct thread *td;
|
||||
{
|
||||
struct pcb *pcb = td->td_pcb;
|
||||
|
||||
struct mdproc *mdp = &td->td_proc->p_md;
|
||||
#ifdef DEV_NPX
|
||||
npxexit(td);
|
||||
#endif
|
||||
|
|
@ -267,8 +271,8 @@ cpu_exit(td)
|
|||
ctob(IOPAGES + 1));
|
||||
pcb->pcb_ext = 0;
|
||||
}
|
||||
if (pcb->pcb_ldt)
|
||||
user_ldt_free(pcb);
|
||||
if (mdp->md_ldt)
|
||||
user_ldt_free(td);
|
||||
if (pcb->pcb_flags & PCB_DBREGS) {
|
||||
/*
|
||||
* disable all hardware breakpoints
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ struct pcb {
|
|||
int pcb_dr6;
|
||||
int pcb_dr7;
|
||||
|
||||
struct pcb_ldt *pcb_ldt; /* per process (user) LDT */
|
||||
union savefpu pcb_save;
|
||||
u_char pcb_flags;
|
||||
#define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */
|
||||
|
|
|
|||
|
|
@ -43,20 +43,9 @@ struct pcb_ext {
|
|||
struct vm86_kernel ext_vm86; /* vm86 area */
|
||||
};
|
||||
|
||||
struct pcb_ldt {
|
||||
caddr_t ldt_base;
|
||||
int ldt_len;
|
||||
int ldt_refcnt;
|
||||
u_long ldt_active;
|
||||
struct segment_descriptor ldt_sd;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
int i386_extend_pcb __P((struct thread *));
|
||||
void set_user_ldt __P((struct pcb *));
|
||||
struct pcb_ldt *user_ldt_alloc __P((struct pcb *, int));
|
||||
void user_ldt_free __P((struct pcb *));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,15 @@
|
|||
#define _MACHINE_PROC_H_
|
||||
|
||||
#include <machine/globals.h>
|
||||
#include <machine/segments.h>
|
||||
|
||||
struct proc_ldt {
|
||||
caddr_t ldt_base;
|
||||
int ldt_len;
|
||||
int ldt_refcnt;
|
||||
u_long ldt_active;
|
||||
struct segment_descriptor ldt_sd;
|
||||
};
|
||||
|
||||
/*
|
||||
* Machine-dependent part of the proc structure for i386.
|
||||
|
|
@ -46,6 +55,15 @@ struct mdthread {
|
|||
};
|
||||
|
||||
struct mdproc {
|
||||
struct proc_ldt *md_ldt; /* per-process ldt */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
void set_user_ldt __P((struct mdproc *));
|
||||
struct proc_ldt *user_ldt_alloc __P((struct mdproc *, int));
|
||||
void user_ldt_free __P((struct thread *));
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_PROC_H_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue