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 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27 /*
28 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
29 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
30 */
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/vmparam.h>
35 #include <sys/systm.h>
36 #include <sys/signal.h>
37 #include <sys/stack.h>
38 #include <sys/regset.h>
39 #include <sys/privregs.h>
40 #include <sys/frame.h>
41 #include <sys/proc.h>
42 #include <sys/psw.h>
43 #include <sys/siginfo.h>
44 #include <sys/cpuvar.h>
45 #include <sys/asm_linkage.h>
46 #include <sys/kmem.h>
47 #include <sys/errno.h>
48 #include <sys/bootconf.h>
558 dmc->gregs[REG_RBP] = (greg_t)(uint32_t)smc->gregs[EBP];
559 dmc->gregs[REG_RBX] = (greg_t)(uint32_t)smc->gregs[EBX];
560 dmc->gregs[REG_RDX] = (greg_t)(uint32_t)smc->gregs[EDX];
561 dmc->gregs[REG_RCX] = (greg_t)(uint32_t)smc->gregs[ECX];
562 dmc->gregs[REG_RAX] = (greg_t)(uint32_t)smc->gregs[EAX];
563 dmc->gregs[REG_TRAPNO] = (greg_t)(uint32_t)smc->gregs[TRAPNO];
564 dmc->gregs[REG_ERR] = (greg_t)(uint32_t)smc->gregs[ERR];
565 dmc->gregs[REG_RIP] = (greg_t)(uint32_t)smc->gregs[EIP];
566 dmc->gregs[REG_CS] = (greg_t)(uint32_t)smc->gregs[CS];
567 dmc->gregs[REG_RFL] = (greg_t)(uint32_t)smc->gregs[EFL];
568 dmc->gregs[REG_RSP] = (greg_t)(uint32_t)smc->gregs[UESP];
569 dmc->gregs[REG_SS] = (greg_t)(uint32_t)smc->gregs[SS];
570
571 /*
572 * A valid fpregs is only copied in if uc.uc_flags has UC_FPU set
573 * otherwise there is no guarantee that anything in fpregs is valid.
574 */
575 if (src->uc_flags & UC_FPU)
576 fpregset_32ton(&src->uc_mcontext.fpregs,
577 &dst->uc_mcontext.fpregs);
578 }
579
580 #endif /* _SYSCALL32_IMPL */
581
582 /*
583 * Return the user-level PC.
584 * If in a system call, return the address of the syscall trap.
585 */
586 greg_t
587 getuserpc()
588 {
589 greg_t upc = lwptoregs(ttolwp(curthread))->r_pc;
590 uint32_t insn;
591
592 if (curthread->t_sysnum == 0)
593 return (upc);
594
595 /*
596 * We might've gotten here from sysenter (0xf 0x34),
597 * syscall (0xf 0x5) or lcall (0x9a 0 0 0 0 0x27 0).
612 *
613 * Since struct regs stores each 16-bit segment register as a 32-bit greg_t, we
614 * also explicitly zero the top 16 bits since they may be coming from the
615 * user's address space via setcontext(2) or /proc.
616 *
617 * Note about null selector. When running on the hypervisor if we allow a
618 * process to set its %cs to null selector with RPL of 0 the hypervisor will
619 * crash the domain. If running on bare metal we would get a #gp fault and
620 * be able to kill the process and continue on. Therefore we make sure to
621 * force RPL to SEL_UPL even for null selector when setting %cs.
622 */
623
624 #if defined(IS_CS) || defined(IS_NOT_CS)
625 #error "IS_CS and IS_NOT_CS already defined"
626 #endif
627
628 #define IS_CS 1
629 #define IS_NOT_CS 0
630
631 /*ARGSUSED*/
632 static greg_t
633 fix_segreg(greg_t sr, int iscs, model_t datamodel)
634 {
635 switch (sr &= 0xffff) {
636
637 case 0:
638 if (iscs == IS_CS)
639 return (0 | SEL_UPL);
640 else
641 return (0);
642
643 #if defined(__amd64)
644 /*
645 * If lwp attempts to switch data model then force their
646 * code selector to be null selector.
647 */
648 case U32CS_SEL:
649 if (datamodel == DATAMODEL_NATIVE)
650 return (0 | SEL_UPL);
651 else
652 return (sr);
653
654 case UCS_SEL:
655 if (datamodel == DATAMODEL_ILP32)
656 return (0 | SEL_UPL);
657 #elif defined(__i386)
658 case UCS_SEL:
659 #endif
660 /*FALLTHROUGH*/
661 case UDS_SEL:
662 case LWPFS_SEL:
663 case LWPGS_SEL:
664 case SEL_UPL:
665 return (sr);
666 default:
667 break;
668 }
669
670 /*
671 * Force it into the LDT in ring 3 for 32-bit processes, which by
672 * default do not have an LDT, so that any attempt to use an invalid
673 * selector will reference the (non-existant) LDT, and cause a #gp
674 * fault for the process.
675 *
676 * 64-bit processes get the null gdt selector since they
677 * are not allowed to have a private LDT.
678 */
679 #if defined(__amd64)
680 if (datamodel == DATAMODEL_ILP32) {
681 return (sr | SEL_TI_LDT | SEL_UPL);
682 } else {
683 if (iscs == IS_CS)
684 return (0 | SEL_UPL);
685 else
686 return (0);
687 }
688
689 #elif defined(__i386)
|
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 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27 /*
28 * Copyright 2015 Joyent, Inc.
29 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
30 */
31
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/vmparam.h>
35 #include <sys/systm.h>
36 #include <sys/signal.h>
37 #include <sys/stack.h>
38 #include <sys/regset.h>
39 #include <sys/privregs.h>
40 #include <sys/frame.h>
41 #include <sys/proc.h>
42 #include <sys/psw.h>
43 #include <sys/siginfo.h>
44 #include <sys/cpuvar.h>
45 #include <sys/asm_linkage.h>
46 #include <sys/kmem.h>
47 #include <sys/errno.h>
48 #include <sys/bootconf.h>
558 dmc->gregs[REG_RBP] = (greg_t)(uint32_t)smc->gregs[EBP];
559 dmc->gregs[REG_RBX] = (greg_t)(uint32_t)smc->gregs[EBX];
560 dmc->gregs[REG_RDX] = (greg_t)(uint32_t)smc->gregs[EDX];
561 dmc->gregs[REG_RCX] = (greg_t)(uint32_t)smc->gregs[ECX];
562 dmc->gregs[REG_RAX] = (greg_t)(uint32_t)smc->gregs[EAX];
563 dmc->gregs[REG_TRAPNO] = (greg_t)(uint32_t)smc->gregs[TRAPNO];
564 dmc->gregs[REG_ERR] = (greg_t)(uint32_t)smc->gregs[ERR];
565 dmc->gregs[REG_RIP] = (greg_t)(uint32_t)smc->gregs[EIP];
566 dmc->gregs[REG_CS] = (greg_t)(uint32_t)smc->gregs[CS];
567 dmc->gregs[REG_RFL] = (greg_t)(uint32_t)smc->gregs[EFL];
568 dmc->gregs[REG_RSP] = (greg_t)(uint32_t)smc->gregs[UESP];
569 dmc->gregs[REG_SS] = (greg_t)(uint32_t)smc->gregs[SS];
570
571 /*
572 * A valid fpregs is only copied in if uc.uc_flags has UC_FPU set
573 * otherwise there is no guarantee that anything in fpregs is valid.
574 */
575 if (src->uc_flags & UC_FPU)
576 fpregset_32ton(&src->uc_mcontext.fpregs,
577 &dst->uc_mcontext.fpregs);
578
579 /*
580 * Copy the brand-private data:
581 */
582 dst->uc_brand_data[0] = (void *)(uintptr_t)src->uc_brand_data[0];
583 dst->uc_brand_data[1] = (void *)(uintptr_t)src->uc_brand_data[1];
584 dst->uc_brand_data[2] = (void *)(uintptr_t)src->uc_brand_data[2];
585 }
586
587 #endif /* _SYSCALL32_IMPL */
588
589 /*
590 * Return the user-level PC.
591 * If in a system call, return the address of the syscall trap.
592 */
593 greg_t
594 getuserpc()
595 {
596 greg_t upc = lwptoregs(ttolwp(curthread))->r_pc;
597 uint32_t insn;
598
599 if (curthread->t_sysnum == 0)
600 return (upc);
601
602 /*
603 * We might've gotten here from sysenter (0xf 0x34),
604 * syscall (0xf 0x5) or lcall (0x9a 0 0 0 0 0x27 0).
619 *
620 * Since struct regs stores each 16-bit segment register as a 32-bit greg_t, we
621 * also explicitly zero the top 16 bits since they may be coming from the
622 * user's address space via setcontext(2) or /proc.
623 *
624 * Note about null selector. When running on the hypervisor if we allow a
625 * process to set its %cs to null selector with RPL of 0 the hypervisor will
626 * crash the domain. If running on bare metal we would get a #gp fault and
627 * be able to kill the process and continue on. Therefore we make sure to
628 * force RPL to SEL_UPL even for null selector when setting %cs.
629 */
630
631 #if defined(IS_CS) || defined(IS_NOT_CS)
632 #error "IS_CS and IS_NOT_CS already defined"
633 #endif
634
635 #define IS_CS 1
636 #define IS_NOT_CS 0
637
638 /*ARGSUSED*/
639 greg_t
640 fix_segreg(greg_t sr, int iscs, model_t datamodel)
641 {
642 kthread_t *t = curthread;
643
644 switch (sr &= 0xffff) {
645
646 case 0:
647 if (iscs == IS_CS)
648 return (0 | SEL_UPL);
649 else
650 return (0);
651
652 #if defined(__amd64)
653 /*
654 * If lwp attempts to switch data model then force their
655 * code selector to be null selector.
656 */
657 case U32CS_SEL:
658 if (datamodel == DATAMODEL_NATIVE)
659 return (0 | SEL_UPL);
660 else
661 return (sr);
662
663 case UCS_SEL:
664 if (datamodel == DATAMODEL_ILP32)
665 return (0 | SEL_UPL);
666 #elif defined(__i386)
667 case UCS_SEL:
668 #endif
669 /*FALLTHROUGH*/
670 case UDS_SEL:
671 case LWPFS_SEL:
672 case LWPGS_SEL:
673 case SEL_UPL:
674 return (sr);
675 default:
676 break;
677 }
678
679 /*
680 * Allow this process's brand to do any necessary segment register
681 * manipulation.
682 */
683 if (PROC_IS_BRANDED(t->t_procp) && BRMOP(t->t_procp)->b_fixsegreg) {
684 greg_t bsr = BRMOP(t->t_procp)->b_fixsegreg(sr, datamodel);
685
686 if (bsr == 0 && iscs == IS_CS)
687 return (0 | SEL_UPL);
688 else
689 return (bsr);
690 }
691
692 /*
693 * Force it into the LDT in ring 3 for 32-bit processes, which by
694 * default do not have an LDT, so that any attempt to use an invalid
695 * selector will reference the (non-existant) LDT, and cause a #gp
696 * fault for the process.
697 *
698 * 64-bit processes get the null gdt selector since they
699 * are not allowed to have a private LDT.
700 */
701 #if defined(__amd64)
702 if (datamodel == DATAMODEL_ILP32) {
703 return (sr | SEL_TI_LDT | SEL_UPL);
704 } else {
705 if (iscs == IS_CS)
706 return (0 | SEL_UPL);
707 else
708 return (0);
709 }
710
711 #elif defined(__i386)
|