]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/commpage/commpage.c
xnu-3789.1.32.tar.gz
[apple/xnu.git] / osfmk / i386 / commpage / commpage.c
index 35ee69cdff499b992468149a2782e69c721bea73..6dae085679e3d1ecd2364c0aea225697bf3d0c14 100644 (file)
 #include <kern/page_decrypt.h>
 #include <kern/processor.h>
 
+#include <sys/kdebug.h>
+
+#if CONFIG_ATM
+#include <atm/atm_internal.h>
+#endif
+
 /* the lists of commpage routines are in commpage_asm.s  */
 extern commpage_descriptor*    commpage_32_routines[];
 extern commpage_descriptor*    commpage_64_routines[];
@@ -120,10 +126,24 @@ commpage_allocate(
        if (submap == NULL)
                panic("commpage submap is null");
 
-       if ((kr = vm_map(kernel_map,&kernel_addr,area_used,0,VM_FLAGS_ANYWHERE,NULL,0,FALSE,VM_PROT_ALL,VM_PROT_ALL,VM_INHERIT_NONE)))
+       if ((kr = vm_map(kernel_map,
+                        &kernel_addr,
+                        area_used,
+                        0,
+                        VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_OSFMK),
+                        NULL,
+                        0,
+                        FALSE,
+                        VM_PROT_ALL,
+                        VM_PROT_ALL,
+                        VM_INHERIT_NONE)))
                panic("cannot allocate commpage %d", kr);
 
-       if ((kr = vm_map_wire(kernel_map,kernel_addr,kernel_addr+area_used,VM_PROT_DEFAULT,FALSE)))
+       if ((kr = vm_map_wire(kernel_map,
+                             kernel_addr,
+                             kernel_addr+area_used,
+                             VM_PROT_DEFAULT|VM_PROT_MEMORY_TAG_MAKE(VM_KERN_MEMORY_OSFMK),
+                             FALSE)))
                panic("cannot wire commpage: %d", kr);
 
        /* 
@@ -136,7 +156,7 @@ commpage_allocate(
         */
        if (!(kr = vm_map_lookup_entry( kernel_map, vm_map_trunc_page(kernel_addr, VM_MAP_PAGE_MASK(kernel_map)), &entry) || entry->is_sub_map))
                panic("cannot find commpage entry %d", kr);
-       entry->object.vm_object->copy_strategy = MEMORY_OBJECT_COPY_NONE;
+       VME_OBJECT(entry)->copy_strategy = MEMORY_OBJECT_COPY_NONE;
 
        if ((kr = mach_make_memory_entry( kernel_map,           // target map
                                    &size,              // size 
@@ -281,15 +301,65 @@ commpage_init_cpu_capabilities( void )
                                        CPUID_LEAF7_FEATURE_HLE);
        setif(bits, kHasAVX2_0,  cpuid_leaf7_features() &
                                        CPUID_LEAF7_FEATURE_AVX2);
+       setif(bits, kHasRDSEED,  cpuid_features() &
+                                       CPUID_LEAF7_FEATURE_RDSEED);
+       setif(bits, kHasADX,     cpuid_features() &
+                                       CPUID_LEAF7_FEATURE_ADX);
        
+       setif(bits, kHasMPX,     cpuid_leaf7_features() &
+                                       CPUID_LEAF7_FEATURE_MPX);
+       setif(bits, kHasSGX,     cpuid_leaf7_features() &
+                                       CPUID_LEAF7_FEATURE_SGX);
        uint64_t misc_enable = rdmsr64(MSR_IA32_MISC_ENABLE);
        setif(bits, kHasENFSTRG, (misc_enable & 1ULL) &&
                                 (cpuid_leaf7_features() &
-                                       CPUID_LEAF7_FEATURE_ENFSTRG));
+                                       CPUID_LEAF7_FEATURE_ERMS));
        
        _cpu_capabilities = bits;               // set kernel version for use by drivers etc
 }
 
+/* initialize the approx_time_supported flag and set the approx time to 0.
+ * Called during initial commpage population.
+ */
+static void
+commpage_mach_approximate_time_init(void)
+{
+       char *cp = commPagePtr32;
+       uint8_t supported;
+
+#ifdef CONFIG_MACH_APPROXIMATE_TIME
+       supported = 1;
+#else
+       supported = 0;
+#endif
+       if ( cp ) {
+               cp += (_COMM_PAGE_APPROX_TIME_SUPPORTED - _COMM_PAGE32_BASE_ADDRESS);
+               *(boolean_t *)cp = supported;
+       }
+       
+       cp = commPagePtr64;
+       if ( cp ) {
+               cp += (_COMM_PAGE_APPROX_TIME_SUPPORTED - _COMM_PAGE32_START_ADDRESS);
+               *(boolean_t *)cp = supported;
+       }
+       commpage_update_mach_approximate_time(0);
+}
+
+static void
+commpage_mach_continuous_time_init(void)
+{
+       commpage_update_mach_continuous_time(0);
+}
+
+static void
+commpage_boottime_init(void)
+{
+       clock_sec_t secs;
+       clock_usec_t microsecs;
+       clock_get_boottime_microtime(&secs, &microsecs);
+       commpage_update_boottime(secs * USEC_PER_SEC + microsecs);
+}
+
 uint64_t
 _get_cpu_capabilities(void)
 {
@@ -430,7 +500,14 @@ commpage_populate( void )
        simple_lock_init(&commpage_active_cpus_lock, 0);
 
        commpage_update_active_cpus();
+       commpage_mach_approximate_time_init();
+       commpage_mach_continuous_time_init();
+       commpage_boottime_init();
        rtc_nanotime_init_commpage();
+       commpage_update_kdebug_state();
+#if CONFIG_ATM
+       commpage_update_atm_diagnostic_config(atm_get_diagnostic_config());
+#endif
 }
 
 /* Fill in the common routines during kernel initialization. 
@@ -662,6 +739,132 @@ commpage_update_active_cpus(void)
        simple_unlock(&commpage_active_cpus_lock);
 }
 
+/*
+ * Update the commpage with current kdebug state. This currently has bits for
+ * global trace state, and typefilter enablement. It is likely additional state
+ * will be tracked in the future.
+ *
+ * INVARIANT: This value will always be 0 if global tracing is disabled. This
+ * allows simple guard tests of "if (*_COMM_PAGE_KDEBUG_ENABLE) { ... }"
+ */
+void
+commpage_update_kdebug_state(void)
+{
+       volatile uint32_t *saved_data_ptr;
+       char *cp;
+
+       cp = commPagePtr32;
+       if (cp) {
+               cp += (_COMM_PAGE_KDEBUG_ENABLE - _COMM_PAGE32_BASE_ADDRESS);
+               saved_data_ptr = (volatile uint32_t *)cp;
+               *saved_data_ptr = kdebug_commpage_state();
+       }
+
+       cp = commPagePtr64;
+       if (cp) {
+               cp += (_COMM_PAGE_KDEBUG_ENABLE - _COMM_PAGE32_START_ADDRESS);
+               saved_data_ptr = (volatile uint32_t *)cp;
+               *saved_data_ptr = kdebug_commpage_state();
+       }
+}
+
+/* Ditto for atm_diagnostic_config */
+void
+commpage_update_atm_diagnostic_config(uint32_t diagnostic_config)
+{
+       volatile uint32_t *saved_data_ptr;
+       char *cp;
+
+       cp = commPagePtr32;
+       if (cp) {
+               cp += (_COMM_PAGE_ATM_DIAGNOSTIC_CONFIG - _COMM_PAGE32_BASE_ADDRESS);
+               saved_data_ptr = (volatile uint32_t *)cp;
+               *saved_data_ptr = diagnostic_config;
+       }
+
+       cp = commPagePtr64;
+       if ( cp ) {
+               cp += (_COMM_PAGE_ATM_DIAGNOSTIC_CONFIG - _COMM_PAGE32_START_ADDRESS);
+               saved_data_ptr = (volatile uint32_t *)cp;
+               *saved_data_ptr = diagnostic_config;
+       }
+}
+
+/*
+ * update the commpage data for last known value of mach_absolute_time()
+ */
+
+void
+commpage_update_mach_approximate_time(uint64_t abstime)
+{
+#ifdef CONFIG_MACH_APPROXIMATE_TIME
+       uint64_t saved_data;
+       char *cp;
+       
+       cp = commPagePtr32;
+       if ( cp ) {
+               cp += (_COMM_PAGE_APPROX_TIME - _COMM_PAGE32_BASE_ADDRESS);
+               saved_data = *(uint64_t *)cp;
+               if (saved_data < abstime) {
+                       /* ignoring the success/fail return value assuming that
+                        * if the value has been updated since we last read it,
+                        * "someone" has a newer timestamp than us and ours is
+                        * now invalid. */
+                       OSCompareAndSwap64(saved_data, abstime, (uint64_t *)cp);
+               }
+       }
+       cp = commPagePtr64;
+       if ( cp ) {
+               cp += (_COMM_PAGE_APPROX_TIME - _COMM_PAGE32_START_ADDRESS);
+               saved_data = *(uint64_t *)cp;
+               if (saved_data < abstime) {
+                       /* ignoring the success/fail return value assuming that
+                        * if the value has been updated since we last read it,
+                        * "someone" has a newer timestamp than us and ours is
+                        * now invalid. */
+                       OSCompareAndSwap64(saved_data, abstime, (uint64_t *)cp);
+               }
+       }
+#else
+#pragma unused (abstime)
+#endif
+}
+
+void
+commpage_update_mach_continuous_time(uint64_t sleeptime)
+{
+       char *cp;
+       cp = commPagePtr32;
+       if (cp) {
+               cp += (_COMM_PAGE_CONT_TIMEBASE - _COMM_PAGE32_START_ADDRESS);
+               *(uint64_t *)cp = sleeptime;
+       }
+       
+       cp = commPagePtr64;
+       if (cp) {
+               cp += (_COMM_PAGE_CONT_TIMEBASE - _COMM_PAGE32_START_ADDRESS);
+               *(uint64_t *)cp = sleeptime;
+       }
+}
+
+void
+commpage_update_boottime(uint64_t boottime)
+{
+       char *cp;
+       cp = commPagePtr32;
+       if (cp) {
+               cp += (_COMM_PAGE_BOOTTIME_USEC - _COMM_PAGE32_START_ADDRESS);
+               *(uint64_t *)cp = boottime;
+       }
+
+       cp = commPagePtr64;
+       if (cp) {
+               cp += (_COMM_PAGE_BOOTTIME_USEC - _COMM_PAGE32_START_ADDRESS);
+               *(uint64_t *)cp = boottime;
+       }
+}
+
+
 extern user32_addr_t commpage_text32_location;
 extern user64_addr_t commpage_text64_location;