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 --- |