Print this page

        

@@ -413,10 +413,17 @@
          */
         if (src->uc_flags & UC_FPU)
                 fpregset_32ton(&src->uc_mcontext.fpregs,
                     &dst->uc_mcontext.fpregs);
 
+        /*
+         * Copy the brand-private data:
+         */
+        dst->uc_brand_data[0] = (void *)(uintptr_t)src->uc_brand_data[0];
+        dst->uc_brand_data[1] = (void *)(uintptr_t)src->uc_brand_data[1];
+        dst->uc_brand_data[2] = (void *)(uintptr_t)src->uc_brand_data[2];
+
         if (src->uc_flags & UC_XSAVE) {
                 dst->uc_xsave = (long)(uint32_t)src->uc_xsave;
         } else {
                 dst->uc_xsave = 0;
         }

@@ -472,13 +479,15 @@
 
 #define IS_CS           1
 #define IS_NOT_CS       0
 
 /*ARGSUSED*/
-static greg_t
+greg_t
 fix_segreg(greg_t sr, int iscs, model_t datamodel)
 {
+        kthread_t *t = curthread;
+
         switch (sr &= 0xffff) {
 
         case 0:
                 if (iscs == IS_CS)
                         return (0 | SEL_UPL);

@@ -506,10 +515,23 @@
                 return (sr);
         default:
                 break;
         }
 
+        /*
+         * Allow this process's brand to do any necessary segment register
+         * manipulation.
+         */
+        if (PROC_IS_BRANDED(t->t_procp) && BRMOP(t->t_procp)->b_fixsegreg) {
+                greg_t bsr = BRMOP(t->t_procp)->b_fixsegreg(sr, datamodel);
+
+                if (bsr == 0 && iscs == IS_CS)
+                        return (0 | SEL_UPL);
+                else
+                        return (bsr);
+        }
+
         /*
          * Force it into the LDT in ring 3 for 32-bit processes, which by
          * default do not have an LDT, so that any attempt to use an invalid
          * selector will reference the (non-existant) LDT, and cause a #gp
          * fault for the process.