sys_machdep.c (8bd57f8fc21608b654349b3894e488ac1f78f2ed) | sys_machdep.c (1acf256d96ab7ec881c40f4eeeef2e064c7e7d20) |
---|---|
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 --- 226 unchanged lines hidden (view full) --- 235done: 236 error = copyout(&ua, args, sizeof(struct i386_ioperm_args)); 237 return (error); 238} 239 240/* 241 * Update the GDT entry pointing to the LDT to point to the LDT of the 242 * current process. | 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 --- 226 unchanged lines hidden (view full) --- 235done: 236 error = copyout(&ua, args, sizeof(struct i386_ioperm_args)); 237 return (error); 238} 239 240/* 241 * Update the GDT entry pointing to the LDT to point to the LDT of the 242 * current process. |
243 * 244 * This must be called with sched_lock held. Unfortunately, we can't use a 245 * mtx_assert() here because cpu_switch() calls this function after changing 246 * curproc but before sched_lock's owner is updated in mi_switch(). |
|
243 */ 244void 245set_user_ldt(struct pcb *pcb) 246{ 247 struct pcb_ldt *pcb_ldt; 248 | 247 */ 248void 249set_user_ldt(struct pcb *pcb) 250{ 251 struct pcb_ldt *pcb_ldt; 252 |
249 if (pcb != PCPU_GET(curpcb)) 250 return; 251 252 mtx_lock_spin(&sched_lock); | |
253 pcb_ldt = pcb->pcb_ldt; 254#ifdef SMP 255 gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pcb_ldt->ldt_sd; 256#else 257 gdt[GUSERLDT_SEL].sd = pcb_ldt->ldt_sd; 258#endif 259 lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); 260 PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL)); | 253 pcb_ldt = pcb->pcb_ldt; 254#ifdef SMP 255 gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pcb_ldt->ldt_sd; 256#else 257 gdt[GUSERLDT_SEL].sd = pcb_ldt->ldt_sd; 258#endif 259 lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); 260 PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL)); |
261} 262 263void 264set_user_ldt_rv(struct pcb *pcb) 265{ 266 267 if (pcb != PCPU_GET(curpcb)) 268 return; 269 270 mtx_lock_spin(&sched_lock); 271 set_user_ldt(pcb); |
|
261 mtx_unlock_spin(&sched_lock); 262} 263 264/* 265 * Must be called with either sched_lock free or held but not recursed. 266 * If it does not return NULL, it will return with it owned. 267 */ 268struct pcb_ldt * --- 148 unchanged lines hidden (view full) --- 417 old_ldt_len = pcb_ldt->ldt_len; 418 pcb_ldt->ldt_sd = new_ldt->ldt_sd; 419 pcb_ldt->ldt_base = new_ldt->ldt_base; 420 pcb_ldt->ldt_len = new_ldt->ldt_len; 421 mtx_unlock_spin(&sched_lock); 422 kmem_free(kernel_map, (vm_offset_t)old_ldt_base, 423 old_ldt_len * sizeof(union descriptor)); 424 FREE(new_ldt, M_SUBPROC); | 272 mtx_unlock_spin(&sched_lock); 273} 274 275/* 276 * Must be called with either sched_lock free or held but not recursed. 277 * If it does not return NULL, it will return with it owned. 278 */ 279struct pcb_ldt * --- 148 unchanged lines hidden (view full) --- 428 old_ldt_len = pcb_ldt->ldt_len; 429 pcb_ldt->ldt_sd = new_ldt->ldt_sd; 430 pcb_ldt->ldt_base = new_ldt->ldt_base; 431 pcb_ldt->ldt_len = new_ldt->ldt_len; 432 mtx_unlock_spin(&sched_lock); 433 kmem_free(kernel_map, (vm_offset_t)old_ldt_base, 434 old_ldt_len * sizeof(union descriptor)); 435 FREE(new_ldt, M_SUBPROC); |
436#ifndef SMP 437 mtx_lock_spin(&sched_lock); 438#endif |
|
425 } else { 426 pcb->pcb_ldt = pcb_ldt = new_ldt; | 439 } else { 440 pcb->pcb_ldt = pcb_ldt = new_ldt; |
441#ifdef SMP |
|
427 mtx_unlock_spin(&sched_lock); | 442 mtx_unlock_spin(&sched_lock); |
443#endif |
|
428 } 429#ifdef SMP 430 /* signal other cpus to reload ldt */ | 444 } 445#ifdef SMP 446 /* signal other cpus to reload ldt */ |
431 smp_rendezvous(NULL, (void (*)(void *))set_user_ldt, NULL, pcb); | 447 smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, NULL, pcb); |
432#else 433 set_user_ldt(pcb); | 448#else 449 set_user_ldt(pcb); |
450 mtx_unlock_spin(&sched_lock); |
|
434#endif 435 } 436 437 /* Check descriptors for access violations */ 438 for (i = 0, n = uap->start; i < uap->num; i++, n++) { 439 union descriptor desc, *dp; 440 dp = &uap->descs[i]; 441 error = copyin(dp, &desc, sizeof(union descriptor)); --- 72 unchanged lines hidden --- | 451#endif 452 } 453 454 /* Check descriptors for access violations */ 455 for (i = 0, n = uap->start; i < uap->num; i++, n++) { 456 union descriptor desc, *dp; 457 dp = &uap->descs[i]; 458 error = copyin(dp, &desc, sizeof(union descriptor)); --- 72 unchanged lines hidden --- |