Print this page
104 Bring back lx brand


 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)