4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2012, Joyent, Inc. All rights reserverd.
25 */
26
27 /*
28 * To understand the present state of interrupt handling on i86pc, we must
29 * first consider the history of interrupt controllers and our way of handling
30 * interrupts.
31 *
32 * History of Interrupt Controllers on i86pc
33 * -----------------------------------------
34 *
35 * Intel 8259 and 8259A
36 *
37 * The first interrupt controller that attained widespread use on i86pc was
38 * the Intel 8259(A) Programmable Interrupt Controller that first saw use with
39 * the 8086. It took up to 8 interrupt sources and combined them into one
40 * output wire. Up to 8 8259s could be slaved together providing up to 64 IRQs.
41 * With the switch to the 8259A, level mode interrupts became possible. For a
42 * long time on i86pc the 8259A was the only way to handle interrupts and it
43 * had its own set of quirks. The 8259A and its corresponding interval timer
44 * the 8254 are programmed using outb and inb instructions.
454 #include <sys/disp.h>
455 #include <vm/seg_kp.h>
456 #include <sys/stack.h>
457 #include <sys/sysmacros.h>
458 #include <sys/cmn_err.h>
459 #include <sys/kstat.h>
460 #include <sys/smp_impldefs.h>
461 #include <sys/pool_pset.h>
462 #include <sys/zone.h>
463 #include <sys/bitmap.h>
464 #include <sys/archsystm.h>
465 #include <sys/machsystm.h>
466 #include <sys/ontrap.h>
467 #include <sys/x86_archext.h>
468 #include <sys/promif.h>
469 #include <vm/hat_i86.h>
470 #if defined(__xpv)
471 #include <sys/hypervisor.h>
472 #endif
473
474
475 #if defined(__xpv) && defined(DEBUG)
476
477 /*
478 * This panic message is intended as an aid to interrupt debugging.
479 *
480 * The associated assertion tests the condition of enabling
481 * events when events are already enabled. The implication
482 * being that whatever code the programmer thought was
483 * protected by having events disabled until the second
484 * enable happened really wasn't protected at all ..
485 */
486
487 int stistipanic = 1; /* controls the debug panic check */
488 const char *stistimsg = "stisti";
489 ulong_t laststi[NCPU];
490
491 /*
492 * This variable tracks the last place events were disabled on each cpu
493 * it assists in debugging when asserts that interrupts are enabled trip.
1456 /*
1457 * 1 or more of the selectors is bad.
1458 * Deliver a SIGSEGV.
1459 */
1460 proc_t *p = ttoproc(tp);
1461
1462 sti();
1463 mutex_enter(&p->p_lock);
1464 tp->t_lwp->lwp_cursig = SIGSEGV;
1465 mutex_exit(&p->p_lock);
1466 psig();
1467 tp->t_sig_check = 1;
1468 cli();
1469 }
1470 tp->t_lwp->lwp_pcb.pcb_rupdate = 0;
1471
1472 #endif /* __amd64 */
1473 return (1);
1474 }
1475
1476 /*
1477 * Here if we are returning to supervisor mode.
1478 * Check for a kernel preemption request.
1479 */
1480 if (CPU->cpu_kprunrun && (rp->r_ps & PS_IE)) {
1481
1482 /*
1483 * Do nothing if already in kpreempt
1484 */
1485 if (!tp->t_preempt_lk) {
1486 tp->t_preempt_lk = 1;
1487 sti();
1488 kpreempt(1); /* asynchronous kpreempt call */
1489 cli();
1490 tp->t_preempt_lk = 0;
1491 }
1492 }
1493
1494 /*
1495 * If we interrupted the mutex_exit() critical region we must
1496 * reset the PC back to the beginning to prevent missed wakeups
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2018 Joyent, Inc. All rights reserverd.
25 */
26
27 /*
28 * To understand the present state of interrupt handling on i86pc, we must
29 * first consider the history of interrupt controllers and our way of handling
30 * interrupts.
31 *
32 * History of Interrupt Controllers on i86pc
33 * -----------------------------------------
34 *
35 * Intel 8259 and 8259A
36 *
37 * The first interrupt controller that attained widespread use on i86pc was
38 * the Intel 8259(A) Programmable Interrupt Controller that first saw use with
39 * the 8086. It took up to 8 interrupt sources and combined them into one
40 * output wire. Up to 8 8259s could be slaved together providing up to 64 IRQs.
41 * With the switch to the 8259A, level mode interrupts became possible. For a
42 * long time on i86pc the 8259A was the only way to handle interrupts and it
43 * had its own set of quirks. The 8259A and its corresponding interval timer
44 * the 8254 are programmed using outb and inb instructions.
454 #include <sys/disp.h>
455 #include <vm/seg_kp.h>
456 #include <sys/stack.h>
457 #include <sys/sysmacros.h>
458 #include <sys/cmn_err.h>
459 #include <sys/kstat.h>
460 #include <sys/smp_impldefs.h>
461 #include <sys/pool_pset.h>
462 #include <sys/zone.h>
463 #include <sys/bitmap.h>
464 #include <sys/archsystm.h>
465 #include <sys/machsystm.h>
466 #include <sys/ontrap.h>
467 #include <sys/x86_archext.h>
468 #include <sys/promif.h>
469 #include <vm/hat_i86.h>
470 #if defined(__xpv)
471 #include <sys/hypervisor.h>
472 #endif
473
474 #if defined(__amd64) && !defined(__xpv)
475 /* If this fails, then the padding numbers in machcpuvar.h are wrong. */
476 CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_pad))
477 < MMU_PAGESIZE);
478 CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_kpti))
479 >= MMU_PAGESIZE);
480 CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_kpti_dbg))
481 < 2 * MMU_PAGESIZE);
482 CTASSERT((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_pad2))
483 < 2 * MMU_PAGESIZE);
484 CTASSERT(((sizeof (struct kpti_frame)) & 0xF) == 0);
485 CTASSERT(((offsetof(cpu_t, cpu_m) + offsetof(struct machcpu, mcpu_kpti_dbg))
486 & 0xF) == 0);
487 CTASSERT((offsetof(struct kpti_frame, kf_tr_rsp) & 0xF) == 0);
488 #endif
489
490 #if defined(__xpv) && defined(DEBUG)
491
492 /*
493 * This panic message is intended as an aid to interrupt debugging.
494 *
495 * The associated assertion tests the condition of enabling
496 * events when events are already enabled. The implication
497 * being that whatever code the programmer thought was
498 * protected by having events disabled until the second
499 * enable happened really wasn't protected at all ..
500 */
501
502 int stistipanic = 1; /* controls the debug panic check */
503 const char *stistimsg = "stisti";
504 ulong_t laststi[NCPU];
505
506 /*
507 * This variable tracks the last place events were disabled on each cpu
508 * it assists in debugging when asserts that interrupts are enabled trip.
1471 /*
1472 * 1 or more of the selectors is bad.
1473 * Deliver a SIGSEGV.
1474 */
1475 proc_t *p = ttoproc(tp);
1476
1477 sti();
1478 mutex_enter(&p->p_lock);
1479 tp->t_lwp->lwp_cursig = SIGSEGV;
1480 mutex_exit(&p->p_lock);
1481 psig();
1482 tp->t_sig_check = 1;
1483 cli();
1484 }
1485 tp->t_lwp->lwp_pcb.pcb_rupdate = 0;
1486
1487 #endif /* __amd64 */
1488 return (1);
1489 }
1490
1491 #if !defined(__xpv)
1492 /*
1493 * Assert that we're not trying to return into the syscall return
1494 * trampolines. Things will go baaaaad if we try to do that.
1495 *
1496 * Note that none of these run with interrupts on, so this should
1497 * never happen (even in the sysexit case the STI doesn't take effect
1498 * until after sysexit finishes).
1499 */
1500 extern void tr_sysc_ret_start();
1501 extern void tr_sysc_ret_end();
1502 ASSERT(!(rp->r_pc >= (uintptr_t)tr_sysc_ret_start &&
1503 rp->r_pc <= (uintptr_t)tr_sysc_ret_end));
1504 #endif
1505
1506 /*
1507 * Here if we are returning to supervisor mode.
1508 * Check for a kernel preemption request.
1509 */
1510 if (CPU->cpu_kprunrun && (rp->r_ps & PS_IE)) {
1511
1512 /*
1513 * Do nothing if already in kpreempt
1514 */
1515 if (!tp->t_preempt_lk) {
1516 tp->t_preempt_lk = 1;
1517 sti();
1518 kpreempt(1); /* asynchronous kpreempt call */
1519 cli();
1520 tp->t_preempt_lk = 0;
1521 }
1522 }
1523
1524 /*
1525 * If we interrupted the mutex_exit() critical region we must
1526 * reset the PC back to the beginning to prevent missed wakeups
|