611 * user's address space via setcontext(2) or /proc.
612 *
613 * Note about null selector. When running on the hypervisor if we allow a
614 * process to set its %cs to null selector with RPL of 0 the hypervisor will
615 * crash the domain. If running on bare metal we would get a #gp fault and
616 * be able to kill the process and continue on. Therefore we make sure to
617 * force RPL to SEL_UPL even for null selector when setting %cs.
618 */
619
620 #if defined(IS_CS) || defined(IS_NOT_CS)
621 #error "IS_CS and IS_NOT_CS already defined"
622 #endif
623
624 #define IS_CS 1
625 #define IS_NOT_CS 0
626
627 /*ARGSUSED*/
628 static greg_t
629 fix_segreg(greg_t sr, int iscs, model_t datamodel)
630 {
631 switch (sr &= 0xffff) {
632
633 case 0:
634 if (iscs == IS_CS)
635 return (0 | SEL_UPL);
636 else
637 return (0);
638
639 #if defined(__amd64)
640 /*
641 * If lwp attempts to switch data model then force their
642 * code selector to be null selector.
643 */
644 case U32CS_SEL:
645 if (datamodel == DATAMODEL_NATIVE)
646 return (0 | SEL_UPL);
647 else
648 return (sr);
649
650 case UCS_SEL:
651 if (datamodel == DATAMODEL_ILP32)
652 return (0 | SEL_UPL);
653 #elif defined(__i386)
654 case UCS_SEL:
655 #endif
656 /*FALLTHROUGH*/
657 case UDS_SEL:
658 case LWPFS_SEL:
659 case LWPGS_SEL:
660 case SEL_UPL:
661 return (sr);
662 default:
663 break;
664 }
665
666 /*
667 * Force it into the LDT in ring 3 for 32-bit processes, which by
668 * default do not have an LDT, so that any attempt to use an invalid
669 * selector will reference the (non-existant) LDT, and cause a #gp
670 * fault for the process.
671 *
672 * 64-bit processes get the null gdt selector since they
673 * are not allowed to have a private LDT.
674 */
675 #if defined(__amd64)
676 if (datamodel == DATAMODEL_ILP32) {
677 return (sr | SEL_TI_LDT | SEL_UPL);
678 } else {
679 if (iscs == IS_CS)
680 return (0 | SEL_UPL);
681 else
682 return (0);
683 }
684
685 #elif defined(__i386)
|
611 * user's address space via setcontext(2) or /proc.
612 *
613 * Note about null selector. When running on the hypervisor if we allow a
614 * process to set its %cs to null selector with RPL of 0 the hypervisor will
615 * crash the domain. If running on bare metal we would get a #gp fault and
616 * be able to kill the process and continue on. Therefore we make sure to
617 * force RPL to SEL_UPL even for null selector when setting %cs.
618 */
619
620 #if defined(IS_CS) || defined(IS_NOT_CS)
621 #error "IS_CS and IS_NOT_CS already defined"
622 #endif
623
624 #define IS_CS 1
625 #define IS_NOT_CS 0
626
627 /*ARGSUSED*/
628 static greg_t
629 fix_segreg(greg_t sr, int iscs, model_t datamodel)
630 {
631 kthread_t *t = curthread;
632
633 switch (sr &= 0xffff) {
634
635 case 0:
636 if (iscs == IS_CS)
637 return (0 | SEL_UPL);
638 else
639 return (0);
640
641 #if defined(__amd64)
642 /*
643 * If lwp attempts to switch data model then force their
644 * code selector to be null selector.
645 */
646 case U32CS_SEL:
647 if (datamodel == DATAMODEL_NATIVE)
648 return (0 | SEL_UPL);
649 else
650 return (sr);
651
652 case UCS_SEL:
653 if (datamodel == DATAMODEL_ILP32)
654 return (0 | SEL_UPL);
655 #elif defined(__i386)
656 case UCS_SEL:
657 #endif
658 /*FALLTHROUGH*/
659 case UDS_SEL:
660 case LWPFS_SEL:
661 case LWPGS_SEL:
662 case SEL_UPL:
663 return (sr);
664 default:
665 break;
666 }
667
668 /*
669 * Allow this process's brand to do any necessary segment register
670 * manipulation.
671 */
672 if (PROC_IS_BRANDED(t->t_procp) && BRMOP(t->t_procp)->b_fixsegreg) {
673 greg_t bsr = BRMOP(t->t_procp)->b_fixsegreg(sr, datamodel);
674
675 if (bsr == 0 && iscs == IS_CS)
676 return (0 | SEL_UPL);
677 else
678 return (bsr);
679 }
680
681 /*
682 * Force it into the LDT in ring 3 for 32-bit processes, which by
683 * default do not have an LDT, so that any attempt to use an invalid
684 * selector will reference the (non-existant) LDT, and cause a #gp
685 * fault for the process.
686 *
687 * 64-bit processes get the null gdt selector since they
688 * are not allowed to have a private LDT.
689 */
690 #if defined(__amd64)
691 if (datamodel == DATAMODEL_ILP32) {
692 return (sr | SEL_TI_LDT | SEL_UPL);
693 } else {
694 if (iscs == IS_CS)
695 return (0 | SEL_UPL);
696 else
697 return (0);
698 }
699
700 #elif defined(__i386)
|