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