]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/bsd_i386_native.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / osfmk / i386 / bsd_i386_native.c
index 13a7cb0aaf254ed48bd5f7299d3c91687300abeb..e117ddda986c6b6d3d1a0b3313f2a03aef950ca9 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2010-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
-#include <mach_rt.h>
 #include <mach_debug.h>
 #include <mach_ldebug.h>
 
@@ -34,7 +33,6 @@
 #include <mach/thread_status.h>
 #include <mach/vm_param.h>
 
-#include <kern/counters.h>
 #include <kern/cpu_data.h>
 #include <kern/mach_param.h>
 #include <kern/task.h>
  */
 kern_return_t
 machine_thread_dup(
-    thread_t           parent,
-    thread_t           child
-)
+       thread_t            parent,
+       thread_t            child,
+       __unused boolean_t  is_corpse
+       )
 {
-       
-       pcb_t           parent_pcb = THREAD_TO_PCB(parent);
-       pcb_t           child_pcb = THREAD_TO_PCB(child);
+       pcb_t           parent_pcb = THREAD_TO_PCB(parent);
+       pcb_t           child_pcb = THREAD_TO_PCB(child);
 
        /*
         * Copy over the x86_saved_state registers
         */
-       if (cpu_mode_is64bit()) {
-               if (thread_is_64bit(parent))
-                       bcopy(USER_REGS64(parent), USER_REGS64(child), sizeof(x86_saved_state64_t));
-               else
-                       bcopy(USER_REGS32(parent), USER_REGS32(child), sizeof(x86_saved_state_compat32_t));
-       } else
+       if (thread_is_64bit_addr(parent)) {
+               bcopy(USER_REGS64(parent), USER_REGS64(child), sizeof(x86_saved_state64_t));
+       } else {
                bcopy(USER_REGS32(parent), USER_REGS32(child), sizeof(x86_saved_state32_t));
+       }
 
        /*
         * Check to see if parent is using floating point
@@ -100,26 +96,27 @@ machine_thread_dup(
         */
        fpu_dup_fxstate(parent, child);
 
-#ifdef MACH_BSD
+#ifdef  MACH_BSD
        /*
         * Copy the parent's cthread id and USER_CTHREAD descriptor, if 32-bit.
         */
        child_pcb->cthread_self = parent_pcb->cthread_self;
-       if (!thread_is_64bit(parent))
+       if (!thread_is_64bit_addr(parent)) {
                child_pcb->cthread_desc = parent_pcb->cthread_desc;
+       }
 
        /*
         * FIXME - should a user specified LDT, TSS and V86 info
         * be duplicated as well?? - probably not.
         */
        // duplicate any use LDT entry that was set I think this is appropriate.
-        if (parent_pcb->uldt_selector!= 0) {
-               child_pcb->uldt_selector = parent_pcb->uldt_selector;
+       if (parent_pcb->uldt_selector != 0) {
+               child_pcb->uldt_selector = parent_pcb->uldt_selector;
                child_pcb->uldt_desc = parent_pcb->uldt_desc;
        }
 #endif
 
-       return (KERN_SUCCESS);
+       return KERN_SUCCESS;
 }
 
 void thread_set_parent(thread_t parent, int pid);
@@ -129,8 +126,8 @@ thread_set_parent(thread_t parent, int pid)
 {
        pal_register_cache_state(parent, DIRTY);
 
-       if (thread_is_64bit(parent)) {
-               x86_saved_state64_t     *iss64;
+       if (thread_is_64bit_addr(parent)) {
+               x86_saved_state64_t     *iss64;
 
                iss64 = USER_REGS64(parent);
 
@@ -138,7 +135,7 @@ thread_set_parent(thread_t parent, int pid)
                iss64->rdx = 0;
                iss64->isf.rflags &= ~EFL_CF;
        } else {
-               x86_saved_state32_t     *iss32;
+               x86_saved_state32_t     *iss32;
 
                iss32 = USER_REGS32(parent);
 
@@ -153,67 +150,31 @@ thread_set_parent(thread_t parent, int pid)
  * current thread to the given thread ID; fast version for 32-bit processes
  *
  * Parameters:    self                    Thread ID to set
- *                
+ *
  * Returns:        0                      Success
  *                !0                      Not success
  */
 kern_return_t
 thread_fast_set_cthread_self(uint32_t self)
 {
-       thread_t thread = current_thread();
-       pcb_t pcb = THREAD_TO_PCB(thread);
-       struct real_descriptor desc = {
-               .limit_low = 1,
-               .limit_high = 0,
-               .base_low = self & 0xffff,
-               .base_med = (self >> 16) & 0xff,
-               .base_high = (self >> 24) & 0xff,
-               .access = ACC_P|ACC_PL_U|ACC_DATA_W,
-               .granularity = SZ_32|SZ_G,
-       };
-
-       current_thread()->machine.cthread_self = (uint64_t) self;       /* preserve old func too */
-
-       /* assign descriptor */
-       mp_disable_preemption();
-       pcb->cthread_desc = desc;
-       *ldt_desc_p(USER_CTHREAD) = desc;
-       saved_state32(pcb->iss)->gs = USER_CTHREAD;
-       mp_enable_preemption();
-
-       return (USER_CTHREAD);
+       machine_thread_set_tsd_base(current_thread(), self);
+       return USER_CTHREAD; /* N.B.: not a kern_return_t! */
 }
 
 /*
  * thread_fast_set_cthread_self64: Sets the machine kernel thread ID of the
- * current thread to the given thread ID; fast version for 64-bit processes 
+ * current thread to the given thread ID; fast version for 64-bit processes
  *
  * Parameters:    self                    Thread ID
- *                
+ *
  * Returns:        0                      Success
  *                !0                      Not success
  */
 kern_return_t
 thread_fast_set_cthread_self64(uint64_t self)
 {
-       pcb_t pcb = THREAD_TO_PCB(current_thread());
-       cpu_data_t              *cdp;
-
-       /* check for canonical address, set 0 otherwise  */
-       if (!IS_USERADDR64_CANONICAL(self))
-               self = 0ULL;
-
-       pcb->cthread_self = self;
-       mp_disable_preemption();
-       cdp = current_cpu_datap();
-#if defined(__x86_64__)
-       if ((cdp->cpu_uber.cu_user_gs_base != pcb->cthread_self) ||
-           (pcb->cthread_self != rdmsr64(MSR_IA32_KERNEL_GS_BASE)))
-               wrmsr64(MSR_IA32_KERNEL_GS_BASE, self);
-#endif
-       cdp->cpu_uber.cu_user_gs_base = self;
-       mp_enable_preemption();
-       return (USER_CTHREAD); /* N.B.: not a kern_return_t! */
+       machine_thread_set_tsd_base(current_thread(), self);
+       return USER_CTHREAD; /* N.B.: not a kern_return_t! */
 }
 
 /*
@@ -250,11 +211,12 @@ thread_set_user_ldt(uint32_t address, uint32_t size, uint32_t flags)
        pcb_t pcb;
        struct fake_descriptor temp;
 
-       if (flags != 0)
-               return -1;              // flags not supported
-       if (size > 0xFFFFF)
-               return -1;              // size too big, 1 meg is the limit
-
+       if (flags != 0) {
+               return -1;              // flags not supported
+       }
+       if (size > 0xFFFFF) {
+               return -1;              // size too big, 1 meg is the limit
+       }
        mp_disable_preemption();
 
        // create a "fake" descriptor so we can use fix_desc()
@@ -265,14 +227,14 @@ thread_set_user_ldt(uint32_t address, uint32_t size, uint32_t flags)
        temp.offset = address;
        temp.lim_or_seg = size;
        temp.size_or_wdct = SZ_32;
-       temp.access = ACC_P|ACC_PL_U|ACC_DATA_W;
+       temp.access = ACC_P | ACC_PL_U | ACC_DATA_W;
 
        // turn this into a real descriptor
-       fix_desc(&temp,1);
+       fix_desc(&temp, 1);
 
        // set up our data in the pcb
        pcb->uldt_desc = *(struct real_descriptor*)&temp;
-       pcb->uldt_selector = USER_SETTABLE;             // set the selector value
+       pcb->uldt_selector = USER_SETTABLE;             // set the selector value
 
        // now set it up in the current table...
        *ldt_desc_p(USER_SETTABLE) = *(struct real_descriptor*)&temp;