]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/dev/i386/sysctl.c
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / bsd / dev / i386 / sysctl.c
index 567c5817e636c6da6808805218f22f892fbfd1c3..944df9f64644d47edb99442221052850604d591b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -40,6 +40,7 @@
 #include <libkern/libkern.h>
 #include <i386/lapic.h>
 #include <i386/mp.h>
+#include <kern/kalloc.h>
 
 
 static int
@@ -177,7 +178,7 @@ cpu_leaf7_features SYSCTL_HANDLER_ARGS
        if (leaf7_extfeatures != 0) {
                strlcat(buf, " ", sizeof(buf));
                cpuid_get_leaf7_extfeature_names(leaf7_extfeatures, buf + strlen(buf),
-                   sizeof(buf) - strlen(buf));
+                   (unsigned int)(sizeof(buf) - strlen(buf)));
        }
 
        return SYSCTL_OUT(req, buf, strlen(buf) + 1);
@@ -247,19 +248,26 @@ cpu_flex_ratio_max SYSCTL_HANDLER_ARGS
 static int
 cpu_ucode_update SYSCTL_HANDLER_ARGS
 {
-       __unused struct sysctl_oid *unused_oidp = oidp;
-       __unused void *unused_arg1 = arg1;
-       __unused int unused_arg2 = arg2;
+#pragma unused(oidp, arg1, arg2)
        uint64_t addr;
        int error;
 
+       /* Can't update microcode from within a VM. */
+
+       if (cpuid_features() & CPUID_FEATURE_VMM) {
+               return ENODEV;
+       }
+
+       if (req->newptr == USER_ADDR_NULL) {
+               return EINVAL;
+       }
+
        error = SYSCTL_IN(req, &addr, sizeof(addr));
        if (error) {
                return error;
        }
 
-       int ret = ucode_interface(addr);
-       return ret;
+       return ucode_interface(addr);
 }
 
 extern uint64_t panic_restart_timeout;
@@ -271,12 +279,16 @@ panic_set_restart_timeout(__unused struct sysctl_oid *oidp, __unused void *arg1,
 
        if (panic_restart_timeout) {
                absolutetime_to_nanoseconds(panic_restart_timeout, &nstime);
-               old_value = nstime / NSEC_PER_SEC;
+               old_value = (int)MIN(nstime / NSEC_PER_SEC, INT_MAX);
        }
 
-       error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
+       error = sysctl_io_number(req, old_value, sizeof(old_value), &new_value, &changed);
        if (error == 0 && changed) {
-               nanoseconds_to_absolutetime(((uint64_t)new_value) * NSEC_PER_SEC, &panic_restart_timeout);
+               if (new_value >= 0) {
+                       nanoseconds_to_absolutetime(((uint64_t)new_value) * NSEC_PER_SEC, &panic_restart_timeout);
+               } else {
+                       error = EDOM;
+               }
        }
        return error;
 }
@@ -304,6 +316,26 @@ misc_interrupt_latency_max(__unused struct sysctl_oid *oidp, __unused void *arg1
 }
 
 #if DEVELOPMENT || DEBUG
+/*
+ * Populates a string with each CPU's tsc synch delta.
+ */
+static int
+x86_cpu_tsc_deltas(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
+{
+       int err;
+       uint32_t ncpus = ml_wait_max_cpus();
+       uint32_t buflen = (2 /* hex digits */ * sizeof(uint64_t) + 3 /* for "0x" + " " */) * ncpus + 1;
+       char *buf = kalloc(buflen);
+
+       cpu_data_tsc_sync_deltas_string(buf, buflen, 0, ncpus - 1);
+
+       err = sysctl_io_string(req, buf, buflen, 0, 0);
+
+       kfree(buf, buflen);
+
+       return err;
+}
+
 /*
  * Triggers a machine-check exception - for a suitably configured kernel only.
  */
@@ -813,6 +845,11 @@ SYSCTL_QUAD(_machdep_tsc, OID_AUTO, at_boot,
     CTLFLAG_RD | CTLFLAG_LOCKED, &tsc_at_boot, "");
 SYSCTL_QUAD(_machdep_tsc, OID_AUTO, rebase_abs_time,
     CTLFLAG_RD | CTLFLAG_LOCKED, &tsc_rebase_abs_time, "");
+#if DEVELOPMENT || DEBUG
+SYSCTL_PROC(_machdep_tsc, OID_AUTO, synch_deltas,
+    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
+    0, 0, x86_cpu_tsc_deltas, "A", "TSC synch deltas");
+#endif
 
 SYSCTL_NODE(_machdep_tsc, OID_AUTO, nanotime,
     CTLFLAG_RD | CTLFLAG_LOCKED, NULL, "TSC to ns conversion");
@@ -839,6 +876,10 @@ SYSCTL_NODE(_machdep, OID_AUTO, misc, CTLFLAG_RW | CTLFLAG_LOCKED, 0,
 extern uint32_t mp_interrupt_watchdog_events;
 SYSCTL_UINT(_machdep_misc, OID_AUTO, interrupt_watchdog_events,
     CTLFLAG_RW | CTLFLAG_LOCKED, &mp_interrupt_watchdog_events, 0, "");
+
+extern int insnstream_force_cacheline_mismatch;
+SYSCTL_INT(_machdep_misc, OID_AUTO, insnstream_force_clmismatch,
+    CTLFLAG_RW | CTLFLAG_LOCKED, &insnstream_force_cacheline_mismatch, 0, "");
 #endif
 
 
@@ -852,6 +893,11 @@ SYSCTL_PROC(_machdep_misc, OID_AUTO, interrupt_latency_max,
     0, 0,
     misc_interrupt_latency_max, "A", "Maximum Interrupt latency");
 
+extern boolean_t is_x2apic;
+SYSCTL_INT(_machdep, OID_AUTO, x2apic_enabled,
+    CTLFLAG_KERN | CTLFLAG_RD | CTLFLAG_LOCKED,
+    &is_x2apic, 0, "");
+
 #if DEVELOPMENT || DEBUG
 SYSCTL_PROC(_machdep_misc, OID_AUTO, machine_check_panic,
     CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
@@ -960,7 +1006,7 @@ misc_nmis(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int ar
 {
        int new = 0, old = 0, changed = 0, error;
 
-       old = NMI_count;
+       old = (int)MIN(NMI_count, INT_MAX);
 
        error = sysctl_io_number(req, old, sizeof(int), &new, &changed);
        if (error == 0 && changed) {