Deleted Added
full compact
sys_machdep.c (177091) sys_machdep.c (181775)
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 16 unchanged lines hidden (view full) ---

25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91
30 */
31
32#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 16 unchanged lines hidden (view full) ---

25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/i386/i386/sys_machdep.c 177091 2008-03-12 10:12:01Z jeff $");
33__FBSDID("$FreeBSD: head/sys/i386/i386/sys_machdep.c 181775 2008-08-15 20:51:31Z kmacy $");
34
35#include "opt_kstack_pages.h"
36#include "opt_mac.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/lock.h>
41#include <sys/malloc.h>

--- 11 unchanged lines hidden (view full) ---

53#include <machine/cpu.h>
54#include <machine/pcb.h>
55#include <machine/pcb_ext.h>
56#include <machine/proc.h>
57#include <machine/sysarch.h>
58
59#include <security/audit/audit.h>
60
34
35#include "opt_kstack_pages.h"
36#include "opt_mac.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/lock.h>
41#include <sys/malloc.h>

--- 11 unchanged lines hidden (view full) ---

53#include <machine/cpu.h>
54#include <machine/pcb.h>
55#include <machine/pcb_ext.h>
56#include <machine/proc.h>
57#include <machine/sysarch.h>
58
59#include <security/audit/audit.h>
60
61#ifdef XEN
62#include <machine/xen/xenfunc.h>
63
64void i386_reset_ldt(struct proc_ldt *pldt);
65
66void
67i386_reset_ldt(struct proc_ldt *pldt)
68{
69 xen_set_ldt((vm_offset_t)pldt->ldt_base, pldt->ldt_len);
70}
71#else
72#define i386_reset_ldt(x)
73#endif
74
61#include <vm/vm_kern.h> /* for kernel_map */
62
63#define MAX_LD 8192
64#define LD_PER_PAGE 512
65#define NEW_MAX_LD(num) ((num + LD_PER_PAGE) & ~(LD_PER_PAGE-1))
66#define SIZE_FROM_LARGEST_LD(num) (NEW_MAX_LD(num) << 3)
67#define NULL_LDT_BASE ((caddr_t)NULL)
68

--- 90 unchanged lines hidden (view full) ---

159 /*
160 * Construct a descriptor and store it in the pcb for
161 * the next context switch. Also store it in the gdt
162 * so that the load of tf_fs into %fs will activate it
163 * at return to userland.
164 */
165 sd.sd_lobase = base & 0xffffff;
166 sd.sd_hibase = (base >> 24) & 0xff;
75#include <vm/vm_kern.h> /* for kernel_map */
76
77#define MAX_LD 8192
78#define LD_PER_PAGE 512
79#define NEW_MAX_LD(num) ((num + LD_PER_PAGE) & ~(LD_PER_PAGE-1))
80#define SIZE_FROM_LARGEST_LD(num) (NEW_MAX_LD(num) << 3)
81#define NULL_LDT_BASE ((caddr_t)NULL)
82

--- 90 unchanged lines hidden (view full) ---

173 /*
174 * Construct a descriptor and store it in the pcb for
175 * the next context switch. Also store it in the gdt
176 * so that the load of tf_fs into %fs will activate it
177 * at return to userland.
178 */
179 sd.sd_lobase = base & 0xffffff;
180 sd.sd_hibase = (base >> 24) & 0xff;
181#ifdef XEN
182 /* need to do nosegneg like Linux */
183 sd.sd_lolimit = (HYPERVISOR_VIRT_START >> 12) & 0xffff;
184#else
167 sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */
185 sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */
186#endif
168 sd.sd_hilimit = 0xf;
169 sd.sd_type = SDT_MEMRWA;
170 sd.sd_dpl = SEL_UPL;
171 sd.sd_p = 1;
172 sd.sd_xx = 0;
173 sd.sd_def32 = 1;
174 sd.sd_gran = 1;
175 critical_enter();
176 td->td_pcb->pcb_fsd = sd;
187 sd.sd_hilimit = 0xf;
188 sd.sd_type = SDT_MEMRWA;
189 sd.sd_dpl = SEL_UPL;
190 sd.sd_p = 1;
191 sd.sd_xx = 0;
192 sd.sd_def32 = 1;
193 sd.sd_gran = 1;
194 critical_enter();
195 td->td_pcb->pcb_fsd = sd;
196#ifdef XEN
197 HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[0]),
198 *(uint64_t *)&sd);
199#else
177 PCPU_GET(fsgs_gdt)[0] = sd;
200 PCPU_GET(fsgs_gdt)[0] = sd;
201#endif
178 critical_exit();
179 td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
180 }
181 break;
182 case I386_GET_GSBASE:
183 sdp = &td->td_pcb->pcb_gsd;
184 base = sdp->sd_hibase << 24 | sdp->sd_lobase;
185 error = copyout(&base, uap->parms, sizeof(base));
186 break;
187 case I386_SET_GSBASE:
188 error = copyin(uap->parms, &base, sizeof(base));
189 if (!error) {
190 /*
191 * Construct a descriptor and store it in the pcb for
192 * the next context switch. Also store it in the gdt
193 * because we have to do a load_gs() right now.
194 */
195 sd.sd_lobase = base & 0xffffff;
196 sd.sd_hibase = (base >> 24) & 0xff;
202 critical_exit();
203 td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
204 }
205 break;
206 case I386_GET_GSBASE:
207 sdp = &td->td_pcb->pcb_gsd;
208 base = sdp->sd_hibase << 24 | sdp->sd_lobase;
209 error = copyout(&base, uap->parms, sizeof(base));
210 break;
211 case I386_SET_GSBASE:
212 error = copyin(uap->parms, &base, sizeof(base));
213 if (!error) {
214 /*
215 * Construct a descriptor and store it in the pcb for
216 * the next context switch. Also store it in the gdt
217 * because we have to do a load_gs() right now.
218 */
219 sd.sd_lobase = base & 0xffffff;
220 sd.sd_hibase = (base >> 24) & 0xff;
221
222#ifdef XEN
223 /* need to do nosegneg like Linux */
224 sd.sd_lolimit = (HYPERVISOR_VIRT_START >> 12) & 0xffff;
225#else
197 sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */
226 sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */
227#endif
198 sd.sd_hilimit = 0xf;
199 sd.sd_type = SDT_MEMRWA;
200 sd.sd_dpl = SEL_UPL;
201 sd.sd_p = 1;
202 sd.sd_xx = 0;
203 sd.sd_def32 = 1;
204 sd.sd_gran = 1;
205 critical_enter();
206 td->td_pcb->pcb_gsd = sd;
228 sd.sd_hilimit = 0xf;
229 sd.sd_type = SDT_MEMRWA;
230 sd.sd_dpl = SEL_UPL;
231 sd.sd_p = 1;
232 sd.sd_xx = 0;
233 sd.sd_def32 = 1;
234 sd.sd_gran = 1;
235 critical_enter();
236 td->td_pcb->pcb_gsd = sd;
237#ifdef XEN
238 HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[1]),
239 *(uint64_t *)&sd);
240#else
207 PCPU_GET(fsgs_gdt)[1] = sd;
241 PCPU_GET(fsgs_gdt)[1] = sd;
242#endif
208 critical_exit();
209 load_gs(GSEL(GUGS_SEL, SEL_UPL));
210 }
211 break;
212 default:
213 error = EINVAL;
214 break;
215 }

--- 139 unchanged lines hidden (view full) ---

355
356 dtlocked = 0;
357 if (!mtx_owned(&dt_lock)) {
358 mtx_lock_spin(&dt_lock);
359 dtlocked = 1;
360 }
361
362 pldt = mdp->md_ldt;
243 critical_exit();
244 load_gs(GSEL(GUGS_SEL, SEL_UPL));
245 }
246 break;
247 default:
248 error = EINVAL;
249 break;
250 }

--- 139 unchanged lines hidden (view full) ---

390
391 dtlocked = 0;
392 if (!mtx_owned(&dt_lock)) {
393 mtx_lock_spin(&dt_lock);
394 dtlocked = 1;
395 }
396
397 pldt = mdp->md_ldt;
398#ifdef XEN
399 i386_reset_ldt(pldt);
400 PCPU_SET(currentldt, (int)pldt);
401#else
363#ifdef SMP
364 gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pldt->ldt_sd;
365#else
366 gdt[GUSERLDT_SEL].sd = pldt->ldt_sd;
367#endif
368 lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
369 PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL));
402#ifdef SMP
403 gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pldt->ldt_sd;
404#else
405 gdt[GUSERLDT_SEL].sd = pldt->ldt_sd;
406#endif
407 lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
408 PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL));
409#endif /* XEN */
370 if (dtlocked)
371 mtx_unlock_spin(&dt_lock);
372}
373
374#ifdef SMP
375static void
376set_user_ldt_rv(struct vmspace *vmsp)
377{
378 struct thread *td;
379
380 td = curthread;
381 if (vmsp != td->td_proc->p_vmspace)
382 return;
383
384 set_user_ldt(&td->td_proc->p_md);
385}
386#endif
387
410 if (dtlocked)
411 mtx_unlock_spin(&dt_lock);
412}
413
414#ifdef SMP
415static void
416set_user_ldt_rv(struct vmspace *vmsp)
417{
418 struct thread *td;
419
420 td = curthread;
421 if (vmsp != td->td_proc->p_vmspace)
422 return;
423
424 set_user_ldt(&td->td_proc->p_md);
425}
426#endif
427
428#ifdef XEN
429
430/*
431 * dt_lock must be held. Returns with dt_lock held.
432 */
433struct proc_ldt *
434user_ldt_alloc(struct mdproc *mdp, int len)
435{
436 struct proc_ldt *pldt, *new_ldt;
437
438 mtx_assert(&dt_lock, MA_OWNED);
439 mtx_unlock_spin(&dt_lock);
440 MALLOC(new_ldt, struct proc_ldt *, sizeof(struct proc_ldt),
441 M_SUBPROC, M_WAITOK);
442
443 new_ldt->ldt_len = len = NEW_MAX_LD(len);
444 new_ldt->ldt_base = (caddr_t)kmem_alloc(kernel_map,
445 round_page(len * sizeof(union descriptor)));
446 if (new_ldt->ldt_base == NULL) {
447 FREE(new_ldt, M_SUBPROC);
448 return NULL;
449 }
450 new_ldt->ldt_refcnt = 1;
451 new_ldt->ldt_active = 0;
452
453 if ((pldt = mdp->md_ldt)) {
454 if (len > pldt->ldt_len)
455 len = pldt->ldt_len;
456 bcopy(pldt->ldt_base, new_ldt->ldt_base,
457 len * sizeof(union descriptor));
458 } else {
459 bcopy(ldt, new_ldt->ldt_base, PAGE_SIZE);
460 }
461 pmap_map_readonly(kernel_pmap, (vm_offset_t)new_ldt->ldt_base,
462 new_ldt->ldt_len*sizeof(union descriptor));
463 return new_ldt;
464}
465#else
388/*
389 * dt_lock must be held. Returns with dt_lock held.
390 */
391struct proc_ldt *
392user_ldt_alloc(struct mdproc *mdp, int len)
393{
394 struct proc_ldt *pldt, *new_ldt;
395

--- 22 unchanged lines hidden (view full) ---

418 len = pldt->ldt_len;
419 bcopy(pldt->ldt_base, new_ldt->ldt_base,
420 len * sizeof(union descriptor));
421 } else
422 bcopy(ldt, new_ldt->ldt_base, sizeof(ldt));
423
424 return (new_ldt);
425}
466/*
467 * dt_lock must be held. Returns with dt_lock held.
468 */
469struct proc_ldt *
470user_ldt_alloc(struct mdproc *mdp, int len)
471{
472 struct proc_ldt *pldt, *new_ldt;
473

--- 22 unchanged lines hidden (view full) ---

496 len = pldt->ldt_len;
497 bcopy(pldt->ldt_base, new_ldt->ldt_base,
498 len * sizeof(union descriptor));
499 } else
500 bcopy(ldt, new_ldt->ldt_base, sizeof(ldt));
501
502 return (new_ldt);
503}
504#endif /* !XEN */
426
427/*
428 * Must be called with dt_lock held. Returns with dt_lock unheld.
429 */
430void
431user_ldt_free(struct thread *td)
432{
433 struct mdproc *mdp = &td->td_proc->p_md;

--- 228 unchanged lines hidden (view full) ---

662 descs);
663 }
664 mtx_unlock_spin(&dt_lock);
665 }
666 if (error == 0)
667 td->td_retval[0] = uap->start;
668 return (error);
669}
505
506/*
507 * Must be called with dt_lock held. Returns with dt_lock unheld.
508 */
509void
510user_ldt_free(struct thread *td)
511{
512 struct mdproc *mdp = &td->td_proc->p_md;

--- 228 unchanged lines hidden (view full) ---

741 descs);
742 }
743 mtx_unlock_spin(&dt_lock);
744 }
745 if (error == 0)
746 td->td_retval[0] = uap->start;
747 return (error);
748}
749#ifdef XEN
750static int
751i386_set_ldt_data(struct thread *td, int start, int num,
752 union descriptor *descs)
753{
754 struct mdproc *mdp = &td->td_proc->p_md;
755 struct proc_ldt *pldt = mdp->md_ldt;
670
756
757 mtx_assert(&dt_lock, MA_OWNED);
758
759 /* Fill in range */
760 bcopy(descs,
761 &((union descriptor *)(pldt->ldt_base))[start],
762 num * sizeof(union descriptor));
763 return (0);
764}
765#else
671static int
672i386_set_ldt_data(struct thread *td, int start, int num,
673 union descriptor *descs)
674{
675 struct mdproc *mdp = &td->td_proc->p_md;
676 struct proc_ldt *pldt = mdp->md_ldt;
677
678 mtx_assert(&dt_lock, MA_OWNED);
679
680 /* Fill in range */
681 bcopy(descs,
682 &((union descriptor *)(pldt->ldt_base))[start],
683 num * sizeof(union descriptor));
684 return (0);
685}
766static int
767i386_set_ldt_data(struct thread *td, int start, int num,
768 union descriptor *descs)
769{
770 struct mdproc *mdp = &td->td_proc->p_md;
771 struct proc_ldt *pldt = mdp->md_ldt;
772
773 mtx_assert(&dt_lock, MA_OWNED);
774
775 /* Fill in range */
776 bcopy(descs,
777 &((union descriptor *)(pldt->ldt_base))[start],
778 num * sizeof(union descriptor));
779 return (0);
780}
781#endif /* !XEN */
686
687static int
688i386_ldt_grow(struct thread *td, int len)
689{
690 struct mdproc *mdp = &td->td_proc->p_md;
691 struct proc_ldt *new_ldt, *pldt;
692 caddr_t old_ldt_base = NULL_LDT_BASE;
693 int old_ldt_len = 0;

--- 64 unchanged lines hidden ---
782
783static int
784i386_ldt_grow(struct thread *td, int len)
785{
786 struct mdproc *mdp = &td->td_proc->p_md;
787 struct proc_ldt *new_ldt, *pldt;
788 caddr_t old_ldt_base = NULL_LDT_BASE;
789 int old_ldt_len = 0;

--- 64 unchanged lines hidden ---