]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_kpc.c
xnu-6153.121.1.tar.gz
[apple/xnu.git] / bsd / kern / kern_kpc.c
index 9cf0ab817712c4c2ee150d01d9c38b5027e6d342..5e23e548e7b724df96e1a659c4c244a135d758d6 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 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 <kern/debug.h>
+#include <kern/kalloc.h>
 #include <sys/param.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -35,6 +36,7 @@
 #include <kern/assert.h>
 
 #include <kern/kpc.h>
+#include <sys/ktrace.h>
 
 #include <pexpert/pexpert.h>
 #include <kperf/kperf.h>
 #define REQ_CONFIG               (9)
 #define REQ_PERIOD              (10)
 #define REQ_ACTIONID            (11)
-#define REQ_FORCE_ALL_CTRS      (12)
-#define REQ_DISABLE_WHITELIST   (13)
+#define REQ_SW_INC              (14)
+#define REQ_PMU_VERSION         (15)
 
 /* Type-munging casts */
 typedef int (*getint_t)(void);
 typedef int (*setint_t)(int);
 
-/* safety */
 static int kpc_initted = 0;
 
-/* locking and buffer for large data requests */
-static lck_grp_attr_t *sysctl_buffer_lckgrp_attr = NULL;
-static lck_grp_t      *sysctl_buffer_lckgrp = NULL;
-static lck_mtx_t       sysctl_buffer_lock;
-static void           *sysctl_buffer = NULL;
+static lck_grp_attr_t *sysctl_lckgrp_attr = NULL;
+static lck_grp_t *sysctl_lckgrp = NULL;
+static lck_mtx_t sysctl_lock;
 
-typedef int (*setget_func_t)(int);
+/*
+ * Another element is needed to hold the CPU number when getting counter values.
+ */
+#define KPC_MAX_BUF_LEN (KPC_MAX_COUNTERS_COPIED + 1)
 
-/* init our stuff */
-extern void kpc_thread_init(void); /* osfmk/kern/kpc_thread.c */
-extern void kpc_arch_init(void);
+typedef int (*setget_func_t)(int);
 
 void
 kpc_init(void)
 {
-       sysctl_buffer_lckgrp_attr = lck_grp_attr_alloc_init();
-        sysctl_buffer_lckgrp = lck_grp_alloc_init("kpc", 
-                                                  sysctl_buffer_lckgrp_attr);
-       lck_mtx_init(&sysctl_buffer_lock, sysctl_buffer_lckgrp, LCK_ATTR_NULL);
+       sysctl_lckgrp_attr = lck_grp_attr_alloc_init();
+       sysctl_lckgrp = lck_grp_alloc_init("kpc", sysctl_lckgrp_attr);
+       lck_mtx_init(&sysctl_lock, sysctl_lckgrp, LCK_ATTR_NULL);
 
        kpc_arch_init();
+       kpc_common_init();
        kpc_thread_init();
 
        kpc_initted = 1;
 }
 
+static uint64_t *
+kpc_get_bigarray(uint32_t *size_out)
+{
+       static uint64_t *bigarray = NULL;
+
+       LCK_MTX_ASSERT(&sysctl_lock, LCK_MTX_ASSERT_OWNED);
+
+       uint32_t size = kpc_get_counterbuf_size() + sizeof(uint64_t);
+       *size_out = size;
+
+       if (bigarray) {
+               return bigarray;
+       }
+
+       /*
+        * Another element is needed to hold the CPU number when getting counter
+        * values.
+        */
+       bigarray = kalloc_tag(size, VM_KERN_MEMORY_DIAG);
+       assert(bigarray != NULL);
+       return bigarray;
+}
+
 /* abstract sysctl handlers */
 static int
 sysctl_get_int( struct sysctl_oid *oidp, struct sysctl_req *req,
-                uint32_t value )
+    uint32_t value )
 {
        int error = 0;
-    
+
        /* copy out the old value */
        error = sysctl_handle_int(oidp, &value, 0, req);
-    
+
+       return error;
+}
+
+static int
+sysctl_set_int( struct sysctl_req *req, int (*set_func)(int))
+{
+       int error = 0;
+       int value = 0;
+
+       error = SYSCTL_IN( req, &value, sizeof(value));
+       if (error) {
+               return error;
+       }
+
+       error = set_func( value );
+
        return error;
 }
 
 static int
 sysctl_getset_int( struct sysctl_oid *oidp, struct sysctl_req *req,
-                   int (*get_func)(void), int (*set_func)(int) )
+    int (*get_func)(void), int (*set_func)(int))
 {
        int error = 0;
        uint32_t value = 0;
-    
+
        /* get the old value and process it */
        value = get_func();
 
        /* copy out the old value, get the new value */
        error = sysctl_handle_int(oidp, &value, 0, req);
-       if (error || !req->newptr)
-               return (error);
+       if (error || !req->newptr) {
+               return error;
+       }
 
        /* if that worked, and we're writing... */
        error = set_func( value );
@@ -121,97 +161,89 @@ sysctl_getset_int( struct sysctl_oid *oidp, struct sysctl_req *req,
        return error;
 }
 
+
 static int
 sysctl_setget_int( struct sysctl_req *req,
-                   int (*setget_func)(int) )
+    int (*setget_func)(int))
 {
        int error = 0;
        int value = 0;
-    
-       error = SYSCTL_IN( req, &value, sizeof(value) );
-       if( error )
+
+       error = SYSCTL_IN( req, &value, sizeof(value));
+       if (error) {
                return error;
-       
+       }
+
        value = setget_func(value);
 
-       error = SYSCTL_OUT( req, &value, sizeof(value) );
+       error = SYSCTL_OUT( req, &value, sizeof(value));
 
        return error;
 }
 
 static int
-kpc_sysctl_acquire_buffer(void)
-{
-       if( sysctl_buffer == NULL )
-               sysctl_buffer = kpc_counterbuf_alloc();
-
-       if( !sysctl_buffer )
-       {
-               return ENOMEM;
-       }
-
-       return 0;
-}
-
-static int 
 sysctl_kpc_get_counters(uint32_t counters,
-                      uint32_t *size, void *buf)
+    uint32_t *size, void *buf)
 {
        uint64_t *ctr_buf = (uint64_t*)buf;
        int curcpu;
        uint32_t count;
 
        count = kpc_get_cpu_counters(counters & KPC_ALL_CPUS,
-                                    counters,
-                                    &curcpu, &ctr_buf[1]);
-       if (!count)
+           counters,
+           &curcpu, &ctr_buf[1]);
+       if (!count) {
                return EINVAL;
+       }
 
        ctr_buf[0] = curcpu;
 
-       *size = (count+1) * sizeof(uint64_t);
+       *size = (count + 1) * sizeof(uint64_t);
 
        return 0;
 }
 
-static int 
+static int
 sysctl_kpc_get_shadow_counters(uint32_t counters,
-                      uint32_t *size, void *buf)
+    uint32_t *size, void *buf)
 {
        uint64_t *ctr_buf = (uint64_t*)buf;
        int curcpu;
        uint32_t count;
 
        count = kpc_get_shadow_counters(counters & KPC_ALL_CPUS,
-                                       counters,
-                                       &curcpu, &ctr_buf[1]);
+           counters,
+           &curcpu, &ctr_buf[1]);
 
-       if (!count)
+       if (!count) {
                return EINVAL;
+       }
 
        ctr_buf[0] = curcpu;
 
-       *size = (count+1) * sizeof(uint64_t);
+       *size = (count + 1) * sizeof(uint64_t);
 
        return 0;
 }
 
-static int 
+static int
 sysctl_kpc_get_thread_counters(uint32_t tid,
-                             uint32_t *size, void *buf)
+    uint32_t *size, void *buf)
 {
        uint32_t count = *size / sizeof(uint64_t);
        int r;
 
-       if( tid != 0 )
+       if (tid != 0) {
                return EINVAL;
+       }
 
        r = kpc_get_curthread_counters(&count, buf);
-       if( !r )
+       if (!r) {
                *size = count * sizeof(uint64_t);
+       }
 
        return r;
-}   
+}
 
 static int
 sysctl_kpc_get_config(uint32_t classes, void* buf)
@@ -222,6 +254,10 @@ sysctl_kpc_get_config(uint32_t classes, void* buf)
 static int
 sysctl_kpc_set_config(uint32_t classes, void* buf)
 {
+       /* userspace cannot reconfigure the power class */
+       if (classes & KPC_CLASS_POWER_MASK) {
+               return EPERM;
+       }
        return kpc_set_config( classes, buf);
 }
 
@@ -234,6 +270,10 @@ sysctl_kpc_get_period(uint32_t classes, void* buf)
 static int
 sysctl_kpc_set_period(uint32_t classes, void* buf)
 {
+       /* userspace cannot reconfigure the power class */
+       if (classes & KPC_CLASS_POWER_MASK) {
+               return EPERM;
+       }
        return kpc_set_period( classes, buf);
 }
 
@@ -251,35 +291,23 @@ sysctl_kpc_set_actionid(uint32_t classes, void* buf)
 
 
 static int
-sysctl_get_bigarray( struct sysctl_req *req, 
-                     int (*get_fn)(uint32_t, uint32_t*, void*) )
+sysctl_get_bigarray(struct sysctl_req *req,
+    int (*get_fn)(uint32_t, uint32_t*, void*))
 {
-       int error = 0;
-       uint32_t bufsize = KPC_MAX_COUNTERS * sizeof(uint64_t); /* XXX? */
+       uint32_t bufsize = 0;
+       uint64_t *buf = kpc_get_bigarray(&bufsize);
        uint32_t arg = 0;
 
        /* get the argument */
-       error = SYSCTL_IN( req, &arg, sizeof(arg) );
-       if(error)
-       {
-               printf( "kpc: no arg?\n" );
+       int error = SYSCTL_IN(req, &arg, sizeof(arg));
+       if (error) {
                return error;
        }
 
-       /* get the wired buffer */
-       error = kpc_sysctl_acquire_buffer();
-       if (error)
-               return error;
-
-       /* atomically get the array into the wired buffer. We have a double
-        * copy, but this is better than page faulting / interrupting during
-        * a copy.
-        */
-       error = get_fn( arg, &bufsize, sysctl_buffer );
-
-       /* do the copy out */
-       if( !error )
-               error = SYSCTL_OUT( req, sysctl_buffer, bufsize );
+       error = get_fn(arg, &bufsize, buf);
+       if (!error) {
+               error = SYSCTL_OUT(req, buf, bufsize);
+       }
 
        return error;
 }
@@ -304,79 +332,54 @@ sysctl_actionid_size( uint32_t classes )
 }
 
 static int
-sysctl_getset_bigarray( struct sysctl_req *req, 
-                        int (*size_fn)(uint32_t arg),
-                        int (*get_fn)(uint32_t, void*),
-                        int (*set_fn)(uint32_t, void*) )
+sysctl_getset_bigarray(struct sysctl_req *req, int (*size_fn)(uint32_t arg),
+    int (*get_fn)(uint32_t, void*), int (*set_fn)(uint32_t, void*))
 {
        int error = 0;
-       uint32_t bufsize = KPC_MAX_COUNTERS * sizeof(uint64_t); /* XXX? */
-       uint32_t regsize = 0;
        uint64_t arg;
 
+       uint32_t bufsize = 0;
+       uint64_t *buf = kpc_get_bigarray(&bufsize);
+
        /* get the config word */
-       error = SYSCTL_IN( req, &arg, sizeof(arg) );
-       if(error)
-       {
-               printf( "kpc: no arg?\n" );
+       error = SYSCTL_IN(req, &arg, sizeof(arg));
+       if (error) {
                return error;
        }
 
-       /* Work out size of registers */
-       regsize = size_fn((uint32_t)arg);
-
-       /* Ignore NULL requests */
-       if(regsize == 0)
+       /* Determine the size of registers to modify. */
+       uint32_t regsize = size_fn((uint32_t)arg);
+       if (regsize == 0 || regsize > bufsize) {
                return EINVAL;
+       }
 
-       /* ensure not too big */
-       if( regsize > bufsize )
-               return EINVAL;
-
-       /* get the wired buffer */
-       error = kpc_sysctl_acquire_buffer();
-       if (error)
-               return error;
-
-       // if writing...
-       if(req->newptr)
-       {
-               // copy in the rest in -- sysctl remembers we did one already
-               error = SYSCTL_IN( req, sysctl_buffer, 
-                                  regsize );
-
-               // if SYSCTL_IN fails it means we are only doing a read
-               if(!error) {
-                       // set it
-                       error = set_fn( (uint32_t)arg, sysctl_buffer );
-                       if( error )
-                               goto fail;
+       /* if writing */
+       if (req->newptr) {
+               /* copy the rest -- SYSCTL_IN knows the copyin should be shifted */
+               error = SYSCTL_IN(req, buf, regsize);
+
+               /* SYSCTL_IN failure means only need to read */
+               if (!error) {
+                       error = set_fn((uint32_t)arg, buf);
+                       if (error) {
+                               return error;
+                       }
                }
        }
 
-       // if reading
-       if(req->oldptr)
-       {
-               // read it
-               error = get_fn( (uint32_t)arg, sysctl_buffer );
-               if( error )
-                       goto fail;
+       /* if reading */
+       if (req->oldptr) {
+               error = get_fn((uint32_t)arg, buf);
+               if (error) {
+                       return error;
+               }
 
-               // copy out the full set
-               error = SYSCTL_OUT( req, sysctl_buffer, regsize );
+               error = SYSCTL_OUT(req, buf, regsize);
        }
-   
-fail:
+
        return error;
 }
 
-
-
-/*
- * #define SYSCTL_HANDLER_ARGS (struct sysctl_oid *oidp,         \
- *                                void *arg1, int arg2,                 \
- *                              struct sysctl_req *req )
- */
 static int
 kpc_sysctl SYSCTL_HANDLER_ARGS
 {
@@ -384,12 +387,19 @@ kpc_sysctl SYSCTL_HANDLER_ARGS
 
        // __unused struct sysctl_oid *unused_oidp = oidp;
        (void)arg2;
-    
-       if( !kpc_initted )
+
+       if (!kpc_initted) {
                panic("kpc_init not called");
+       }
+
+       if (!kpc_supported) {
+               return ENOTSUP;
+       }
+
+       ktrace_lock();
 
        // Most sysctls require an access check, but a few are public.
-       switch( (uintptr_t) arg1 ) {
+       switch ((uintptr_t) arg1) {
        case REQ_CLASSES:
        case REQ_CONFIG_COUNT:
        case REQ_COUNTER_COUNT:
@@ -399,41 +409,42 @@ kpc_sysctl SYSCTL_HANDLER_ARGS
        default:
                // Require kperf access to read or write anything else.
                // This is either root or the blessed pid.
-               ret = kperf_access_check();
-               if (ret) {
+               if ((ret = ktrace_read_check())) {
+                       ktrace_unlock();
                        return ret;
                }
                break;
        }
 
-       lck_mtx_lock(&sysctl_buffer_lock);
+       ktrace_unlock();
+
+       lck_mtx_lock(&sysctl_lock);
 
        /* which request */
-       switch( (uintptr_t) arg1 )
-       {
+       switch ((uintptr_t) arg1) {
        case REQ_CLASSES:
                ret = sysctl_get_int( oidp, req,
-                                      kpc_get_classes() );
+                   kpc_get_classes());
                break;
        case REQ_COUNTING:
                ret = sysctl_getset_int( oidp, req,
-                                         (getint_t)kpc_get_running,
-                                         (setint_t)kpc_set_running );
+                   (getint_t)kpc_get_running,
+                   (setint_t)kpc_set_running );
                break;
        case REQ_THREAD_COUNTING:
                ret = sysctl_getset_int( oidp, req,
-                                         (getint_t)kpc_get_thread_counting,
-                                         (setint_t)kpc_set_thread_counting );
+                   (getint_t)kpc_get_thread_counting,
+                   (setint_t)kpc_set_thread_counting );
                break;
 
        case REQ_CONFIG_COUNT:
                ret = sysctl_setget_int( req,
-                                         (setget_func_t)kpc_get_config_count );
+                   (setget_func_t)kpc_get_config_count );
                break;
 
        case REQ_COUNTER_COUNT:
                ret = sysctl_setget_int( req,
-                                         (setget_func_t)kpc_get_counter_count );
+                   (setget_func_t)kpc_get_counter_count );
                break;
 
 
@@ -451,23 +462,32 @@ kpc_sysctl SYSCTL_HANDLER_ARGS
 
        case REQ_CONFIG:
                ret = sysctl_getset_bigarray( req,
-                                              sysctl_config_size,
-                                              sysctl_kpc_get_config,
-                                              sysctl_kpc_set_config );
+                   sysctl_config_size,
+                   sysctl_kpc_get_config,
+                   sysctl_kpc_set_config );
                break;
 
        case REQ_PERIOD:
                ret = sysctl_getset_bigarray( req,
-                                              sysctl_counter_size,
-                                              sysctl_kpc_get_period,
-                                              sysctl_kpc_set_period );
+                   sysctl_counter_size,
+                   sysctl_kpc_get_period,
+                   sysctl_kpc_set_period );
                break;
 
        case REQ_ACTIONID:
                ret = sysctl_getset_bigarray( req,
-                                              sysctl_actionid_size,
-                                              sysctl_kpc_get_actionid,
-                                              sysctl_kpc_set_actionid );
+                   sysctl_actionid_size,
+                   sysctl_kpc_get_actionid,
+                   sysctl_kpc_set_actionid );
+               break;
+
+
+       case REQ_SW_INC:
+               ret = sysctl_set_int( req, (setget_func_t)kpc_set_sw_inc );
+               break;
+
+       case REQ_PMU_VERSION:
+               ret = sysctl_get_int(oidp, req, kpc_get_pmu_version());
                break;
 
        default:
@@ -475,8 +495,8 @@ kpc_sysctl SYSCTL_HANDLER_ARGS
                break;
        }
 
-       lck_mtx_unlock(&sysctl_buffer_lock);
+       lck_mtx_unlock(&sysctl_lock);
+
        return ret;
 }
 
@@ -484,69 +504,81 @@ kpc_sysctl SYSCTL_HANDLER_ARGS
 /***  sysctl definitions  ***/
 
 /* root kperf node */
-SYSCTL_NODE(, OID_AUTO, kpc, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
-            "kpc");
+SYSCTL_NODE(, OID_AUTO, kpc, CTLFLAG_RW | CTLFLAG_LOCKED, 0,
+    "kpc");
 
 /* values */
 SYSCTL_PROC(_kpc, OID_AUTO, classes,
-            CTLTYPE_INT|CTLFLAG_RD|CTLFLAG_ANYBODY,
-            (void*)REQ_CLASSES, 
-            sizeof(int), kpc_sysctl, "I", "Available classes");
+    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_CLASSES,
+    sizeof(int), kpc_sysctl, "I", "Available classes");
 
 SYSCTL_PROC(_kpc, OID_AUTO, counting,
-            CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
-            (void*)REQ_COUNTING, 
-            sizeof(int), kpc_sysctl, "I", "PMCs counting");
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_COUNTING,
+    sizeof(int), kpc_sysctl, "I", "PMCs counting");
 
 SYSCTL_PROC(_kpc, OID_AUTO, thread_counting,
-            CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
-            (void*)REQ_THREAD_COUNTING, 
-            sizeof(int), kpc_sysctl, "I", "Thread accumulation");
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_THREAD_COUNTING,
+    sizeof(int), kpc_sysctl, "I", "Thread accumulation");
+
+SYSCTL_PROC(_kpc, OID_AUTO, pmu_version,
+    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void *)REQ_PMU_VERSION,
+    sizeof(int), kpc_sysctl, "I", "PMU version for hardware");
 
 /* faux values */
 SYSCTL_PROC(_kpc, OID_AUTO, config_count,
-            CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
-            (void*)REQ_CONFIG_COUNT, 
-            sizeof(int), kpc_sysctl, "S", "Config count");
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_CONFIG_COUNT,
+    sizeof(int), kpc_sysctl, "S", "Config count");
 
 SYSCTL_PROC(_kpc, OID_AUTO, counter_count,
-            CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
-            (void*)REQ_COUNTER_COUNT, 
-            sizeof(int), kpc_sysctl, "S", "Counter count");
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_COUNTER_COUNT,
+    sizeof(int), kpc_sysctl, "S", "Counter count");
+
+SYSCTL_PROC(_kpc, OID_AUTO, sw_inc,
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_SW_INC,
+    sizeof(int), kpc_sysctl, "S", "Software increment");
 
 /* arrays */
 SYSCTL_PROC(_kpc, OID_AUTO, thread_counters,
-            CTLFLAG_RD|CTLFLAG_WR|CTLFLAG_ANYBODY,
-            (void*)REQ_THREAD_COUNTERS, 
-            sizeof(uint64_t), kpc_sysctl, 
-            "QU", "Current thread counters");
+    CTLFLAG_RD | CTLFLAG_WR | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_THREAD_COUNTERS,
+    sizeof(uint64_t), kpc_sysctl,
+    "QU", "Current thread counters");
 
 SYSCTL_PROC(_kpc, OID_AUTO, counters,
-            CTLFLAG_RD|CTLFLAG_WR|CTLFLAG_ANYBODY,
-            (void*)REQ_COUNTERS, 
-            sizeof(uint64_t), kpc_sysctl, 
-            "QU", "Current counters");
+    CTLFLAG_RD | CTLFLAG_WR | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_COUNTERS,
+    sizeof(uint64_t), kpc_sysctl,
+    "QU", "Current counters");
 
 SYSCTL_PROC(_kpc, OID_AUTO, shadow_counters,
-            CTLFLAG_RD|CTLFLAG_WR|CTLFLAG_ANYBODY,
-            (void*)REQ_SHADOW_COUNTERS, 
-            sizeof(uint64_t), kpc_sysctl, 
-            "QU", "Current shadow counters");
+    CTLFLAG_RD | CTLFLAG_WR | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_SHADOW_COUNTERS,
+    sizeof(uint64_t), kpc_sysctl,
+    "QU", "Current shadow counters");
 
 SYSCTL_PROC(_kpc, OID_AUTO, config,
-            CTLFLAG_RD|CTLFLAG_WR|CTLFLAG_ANYBODY,
-            (void*)REQ_CONFIG, 
-            sizeof(uint64_t), kpc_sysctl, 
-            "QU", "Set counter configs");
+    CTLFLAG_RD | CTLFLAG_WR | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_CONFIG,
+    sizeof(uint64_t), kpc_sysctl,
+    "QU", "Set counter configs");
 
 SYSCTL_PROC(_kpc, OID_AUTO, period,
-            CTLFLAG_RD|CTLFLAG_WR|CTLFLAG_ANYBODY,
-            (void*)REQ_PERIOD, 
-            sizeof(uint64_t), kpc_sysctl, 
-            "QU", "Set counter periods");
+    CTLFLAG_RD | CTLFLAG_WR | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_PERIOD,
+    sizeof(uint64_t), kpc_sysctl,
+    "QU", "Set counter periods");
 
 SYSCTL_PROC(_kpc, OID_AUTO, actionid,
-            CTLFLAG_RD|CTLFLAG_WR|CTLFLAG_ANYBODY,
-            (void*)REQ_ACTIONID, 
-            sizeof(uint32_t), kpc_sysctl, 
-            "QU", "Set counter actionids");
+    CTLFLAG_RD | CTLFLAG_WR | CTLFLAG_ANYBODY | CTLFLAG_MASKED | CTLFLAG_LOCKED,
+    (void*)REQ_ACTIONID,
+    sizeof(uint32_t), kpc_sysctl,
+    "QU", "Set counter actionids");
+
+