Print this page




 398         dmc->gregs[REG_RBX] = (greg_t)(uint32_t)smc->gregs[EBX];
 399         dmc->gregs[REG_RDX] = (greg_t)(uint32_t)smc->gregs[EDX];
 400         dmc->gregs[REG_RCX] = (greg_t)(uint32_t)smc->gregs[ECX];
 401         dmc->gregs[REG_RAX] = (greg_t)(uint32_t)smc->gregs[EAX];
 402         dmc->gregs[REG_TRAPNO] = (greg_t)(uint32_t)smc->gregs[TRAPNO];
 403         dmc->gregs[REG_ERR] = (greg_t)(uint32_t)smc->gregs[ERR];
 404         dmc->gregs[REG_RIP] = (greg_t)(uint32_t)smc->gregs[EIP];
 405         dmc->gregs[REG_CS] = (greg_t)(uint32_t)smc->gregs[CS];
 406         dmc->gregs[REG_RFL] = (greg_t)(uint32_t)smc->gregs[EFL];
 407         dmc->gregs[REG_RSP] = (greg_t)(uint32_t)smc->gregs[UESP];
 408         dmc->gregs[REG_SS] = (greg_t)(uint32_t)smc->gregs[SS];
 409 
 410         /*
 411          * A valid fpregs is only copied in if uc.uc_flags has UC_FPU set
 412          * otherwise there is no guarantee that anything in fpregs is valid.
 413          */
 414         if (src->uc_flags & UC_FPU)
 415                 fpregset_32ton(&src->uc_mcontext.fpregs,
 416                     &dst->uc_mcontext.fpregs);
 417 







 418         if (src->uc_flags & UC_XSAVE) {
 419                 dst->uc_xsave = (long)(uint32_t)src->uc_xsave;
 420         } else {
 421                 dst->uc_xsave = 0;
 422         }
 423 }
 424 
 425 #endif  /* _SYSCALL32_IMPL */
 426 
 427 /*
 428  * Return the user-level PC.
 429  * If in a system call, return the address of the syscall trap.
 430  */
 431 greg_t
 432 getuserpc(void)
 433 {
 434         greg_t upc = lwptoregs(ttolwp(curthread))->r_pc;
 435         uint32_t insn;
 436 
 437         if (curthread->t_sysnum == 0)


 457  *
 458  * Since struct regs stores each 16-bit segment register as a 32-bit greg_t, we
 459  * also explicitly zero the top 16 bits since they may be coming from the
 460  * user's address space via setcontext(2) or /proc.
 461  *
 462  * Note about null selector. When running on the hypervisor if we allow a
 463  * process to set its %cs to null selector with RPL of 0 the hypervisor will
 464  * crash the domain. If running on bare metal we would get a #gp fault and
 465  * be able to kill the process and continue on. Therefore we make sure to
 466  * force RPL to SEL_UPL even for null selector when setting %cs.
 467  */
 468 
 469 #if defined(IS_CS) || defined(IS_NOT_CS)
 470 #error  "IS_CS and IS_NOT_CS already defined"
 471 #endif
 472 
 473 #define IS_CS           1
 474 #define IS_NOT_CS       0
 475 
 476 /*ARGSUSED*/
 477 static greg_t
 478 fix_segreg(greg_t sr, int iscs, model_t datamodel)
 479 {


 480         switch (sr &= 0xffff) {
 481 
 482         case 0:
 483                 if (iscs == IS_CS)
 484                         return (0 | SEL_UPL);
 485                 else
 486                         return (0);
 487 
 488         /*
 489          * If lwp attempts to switch data model then force their
 490          * code selector to be null selector.
 491          */
 492         case U32CS_SEL:
 493                 if (datamodel == DATAMODEL_NATIVE)
 494                         return (0 | SEL_UPL);
 495                 else
 496                         return (sr);
 497 
 498         case UCS_SEL:
 499                 if (datamodel == DATAMODEL_ILP32)
 500                         return (0 | SEL_UPL);
 501         /*FALLTHROUGH*/
 502         case UDS_SEL:
 503         case LWPFS_SEL:
 504         case LWPGS_SEL:
 505         case SEL_UPL:
 506                 return (sr);
 507         default:
 508                 break;
 509         }
 510 













 511         /*
 512          * Force it into the LDT in ring 3 for 32-bit processes, which by
 513          * default do not have an LDT, so that any attempt to use an invalid
 514          * selector will reference the (non-existant) LDT, and cause a #gp
 515          * fault for the process.
 516          *
 517          * 64-bit processes get the null gdt selector since they
 518          * are not allowed to have a private LDT.
 519          */
 520         if (datamodel == DATAMODEL_ILP32) {
 521                 return (sr | SEL_TI_LDT | SEL_UPL);
 522         } else {
 523                 if (iscs == IS_CS)
 524                         return (0 | SEL_UPL);
 525                 else
 526                         return (0);
 527         }
 528 
 529 }
 530 




 398         dmc->gregs[REG_RBX] = (greg_t)(uint32_t)smc->gregs[EBX];
 399         dmc->gregs[REG_RDX] = (greg_t)(uint32_t)smc->gregs[EDX];
 400         dmc->gregs[REG_RCX] = (greg_t)(uint32_t)smc->gregs[ECX];
 401         dmc->gregs[REG_RAX] = (greg_t)(uint32_t)smc->gregs[EAX];
 402         dmc->gregs[REG_TRAPNO] = (greg_t)(uint32_t)smc->gregs[TRAPNO];
 403         dmc->gregs[REG_ERR] = (greg_t)(uint32_t)smc->gregs[ERR];
 404         dmc->gregs[REG_RIP] = (greg_t)(uint32_t)smc->gregs[EIP];
 405         dmc->gregs[REG_CS] = (greg_t)(uint32_t)smc->gregs[CS];
 406         dmc->gregs[REG_RFL] = (greg_t)(uint32_t)smc->gregs[EFL];
 407         dmc->gregs[REG_RSP] = (greg_t)(uint32_t)smc->gregs[UESP];
 408         dmc->gregs[REG_SS] = (greg_t)(uint32_t)smc->gregs[SS];
 409 
 410         /*
 411          * A valid fpregs is only copied in if uc.uc_flags has UC_FPU set
 412          * otherwise there is no guarantee that anything in fpregs is valid.
 413          */
 414         if (src->uc_flags & UC_FPU)
 415                 fpregset_32ton(&src->uc_mcontext.fpregs,
 416                     &dst->uc_mcontext.fpregs);
 417 
 418         /*
 419          * Copy the brand-private data:
 420          */
 421         dst->uc_brand_data[0] = (void *)(uintptr_t)src->uc_brand_data[0];
 422         dst->uc_brand_data[1] = (void *)(uintptr_t)src->uc_brand_data[1];
 423         dst->uc_brand_data[2] = (void *)(uintptr_t)src->uc_brand_data[2];
 424 
 425         if (src->uc_flags & UC_XSAVE) {
 426                 dst->uc_xsave = (long)(uint32_t)src->uc_xsave;
 427         } else {
 428                 dst->uc_xsave = 0;
 429         }
 430 }
 431 
 432 #endif  /* _SYSCALL32_IMPL */
 433 
 434 /*
 435  * Return the user-level PC.
 436  * If in a system call, return the address of the syscall trap.
 437  */
 438 greg_t
 439 getuserpc(void)
 440 {
 441         greg_t upc = lwptoregs(ttolwp(curthread))->r_pc;
 442         uint32_t insn;
 443 
 444         if (curthread->t_sysnum == 0)


 464  *
 465  * Since struct regs stores each 16-bit segment register as a 32-bit greg_t, we
 466  * also explicitly zero the top 16 bits since they may be coming from the
 467  * user's address space via setcontext(2) or /proc.
 468  *
 469  * Note about null selector. When running on the hypervisor if we allow a
 470  * process to set its %cs to null selector with RPL of 0 the hypervisor will
 471  * crash the domain. If running on bare metal we would get a #gp fault and
 472  * be able to kill the process and continue on. Therefore we make sure to
 473  * force RPL to SEL_UPL even for null selector when setting %cs.
 474  */
 475 
 476 #if defined(IS_CS) || defined(IS_NOT_CS)
 477 #error  "IS_CS and IS_NOT_CS already defined"
 478 #endif
 479 
 480 #define IS_CS           1
 481 #define IS_NOT_CS       0
 482 
 483 /*ARGSUSED*/
 484 greg_t
 485 fix_segreg(greg_t sr, int iscs, model_t datamodel)
 486 {
 487         kthread_t *t = curthread;
 488 
 489         switch (sr &= 0xffff) {
 490 
 491         case 0:
 492                 if (iscs == IS_CS)
 493                         return (0 | SEL_UPL);
 494                 else
 495                         return (0);
 496 
 497         /*
 498          * If lwp attempts to switch data model then force their
 499          * code selector to be null selector.
 500          */
 501         case U32CS_SEL:
 502                 if (datamodel == DATAMODEL_NATIVE)
 503                         return (0 | SEL_UPL);
 504                 else
 505                         return (sr);
 506 
 507         case UCS_SEL:
 508                 if (datamodel == DATAMODEL_ILP32)
 509                         return (0 | SEL_UPL);
 510         /*FALLTHROUGH*/
 511         case UDS_SEL:
 512         case LWPFS_SEL:
 513         case LWPGS_SEL:
 514         case SEL_UPL:
 515                 return (sr);
 516         default:
 517                 break;
 518         }
 519 
 520         /*
 521          * Allow this process's brand to do any necessary segment register
 522          * manipulation.
 523          */
 524         if (PROC_IS_BRANDED(t->t_procp) && BRMOP(t->t_procp)->b_fixsegreg) {
 525                 greg_t bsr = BRMOP(t->t_procp)->b_fixsegreg(sr, datamodel);
 526 
 527                 if (bsr == 0 && iscs == IS_CS)
 528                         return (0 | SEL_UPL);
 529                 else
 530                         return (bsr);
 531         }
 532 
 533         /*
 534          * Force it into the LDT in ring 3 for 32-bit processes, which by
 535          * default do not have an LDT, so that any attempt to use an invalid
 536          * selector will reference the (non-existant) LDT, and cause a #gp
 537          * fault for the process.
 538          *
 539          * 64-bit processes get the null gdt selector since they
 540          * are not allowed to have a private LDT.
 541          */
 542         if (datamodel == DATAMODEL_ILP32) {
 543                 return (sr | SEL_TI_LDT | SEL_UPL);
 544         } else {
 545                 if (iscs == IS_CS)
 546                         return (0 | SEL_UPL);
 547                 else
 548                         return (0);
 549         }
 550 
 551 }
 552