]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: support building on UEK4
authorKris Van Hees <kris.van.hees@oracle.com>
Tue, 10 Feb 2015 17:18:39 +0000 (12:18 -0500)
committerKris Van Hees <kris.van.hees@oracle.com>
Mon, 20 Apr 2015 08:05:20 +0000 (04:05 -0400)
Support building DTrace modules on UEK4.  Various things changed at
the kernel level between UEK3 and UEK4 that require adjustments in the
building of the DTrace modules.

- ARCH no longer reflects the difference between x86 and x86_64.  So,
  we now use UTS_MACHINE to drive the architecture-specific portions
  of DTrace during the building process.

- The trick used to implement a direct call probe in dt_test_probe()
  required updating to avoid compiler warnings/errors.  It is a little
  bit less "ugly" now :)

- The uid and gid used in the task structure now uses kuid_t and kgid_t
  as datatypes, which are no longer numeric values but rather a struct.

- The API for the IDR facility in the Linux kernel changed.

- The flush_delayed_work_sync() function has been removed.  Source code
  has been updated to use flush_delayed_work().

- The mechanism to enforce turning preemption on and off has been
  updated.

Orabug: 20456825

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Acked-by: Nick Alcock <nick.alcock@oracle.com>
15 files changed:
dtrace/Kbuild
dtrace/dt_test_dev.c
dtrace/dtrace_dev.c
dtrace/dtrace_dif.c
dtrace/dtrace_ecb.c
dtrace/dtrace_match.c
dtrace/dtrace_priv.c
dtrace/dtrace_probe.c
dtrace/dtrace_ptofapi.c
dtrace/dtrace_state.c
dtrace/dtrace_util.c
dtrace/fasttrap_dev.c
dtrace/include/dtrace/dtrace_impl.h
dtrace/include/dtrace/dtrace_impl_defines.h
dtrace/include/uapi/linux/dtrace/stability.h

index a567bb8c9b69c97e03cde12722a80a5eae432481..ae8f15b81d9f8f856cc29c48970ef9b93dacd942 100644 (file)
@@ -25,7 +25,7 @@
 # Use is subject to license terms.
 
 EXTRA_CFLAGS                   := -I$(src)/include -I$(src)/include/uapi \
-                                  -I$(src)/include/$(ARCH)
+                                  -I$(src)/include/$(UTS_MACHINE)
 
 obj-$(CONFIG_DT_CORE)          += dtrace.o
 obj-$(CONFIG_DT_FASTTRAP)      += fasttrap.o
@@ -36,7 +36,8 @@ obj-$(CONFIG_DT_DT_TEST)      += dt_test.o
 obj-$(CONFIG_DT_DT_PERF)       += dt_perf.o
 
 dtrace-y                       := dtrace_mod.o dtrace_dev.o \
-                                  dtrace_asm_$(ARCH).o dtrace_isa_$(ARCH).o \
+                                  dtrace_asm_$(UTS_MACHINE).o \
+                                  dtrace_isa_$(UTS_MACHINE).o \
                                   dtrace_actdesc.o dtrace_anon.o \
                                   dtrace_buffer.o dtrace_dif.o dtrace_dof.o \
                                   dtrace_ecb.o dtrace_enable.o \
@@ -47,7 +48,7 @@ dtrace-y                      := dtrace_mod.o dtrace_dev.o \
                                   dtrace_spec.o dtrace_state.o dtrace_util.o
 fasttrap-y                     := fasttrap_mod.o fasttrap_dev.o
 profile-y                      := profile_mod.o profile_dev.o
-sdt-y                          := sdt_mod.o sdt_dev.o sdt_$(ARCH).o
+sdt-y                          := sdt_mod.o sdt_dev.o sdt_$(UTS_MACHINE).o
 systrace-y                     := systrace_mod.o systrace_dev.o
 dt_test-y                      := dt_test_mod.o dt_test_dev.o
 dt_perf-y                      := dt_perf_mod.o dt_perf_dev.o
index 33cec8e396b7647df0b62d2cbabc9cc23f532aa6..9292da8e34cd6df236de1a04793cd9fdfb28b25a 100644 (file)
@@ -62,6 +62,12 @@ void dt_test_destroy(void *arg, dtrace_id_t id, void *parg)
 {
 }
 
+void probe_p(dtrace_id_t pid, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2,
+             uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6,
+             uintptr_t arg7, uintptr_t arg8, uintptr_t arg9)
+{
+}
+
 /*
  * Direct calling into dtrace_probe() when passing more than 5 parameters to
  * the probe requires a stub function.  Otherwise we may not be able to get
@@ -77,7 +83,7 @@ void dt_test_probe(uintptr_t arg0, uintptr_t arg1, uintptr_t arg2,
         * Not at all...
         * But we're doing it anyway...
         */
-       void (*probe_fn)() = (void *)&dtrace_probe;
+       typeof(probe_p) *probe_fn = (void *)&dtrace_probe;
 
        probe_fn(pid, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
                 arg9);
index b41abc23287ff83f44ac10f002d0be151d855f1c..c7be698ad500fd208edfac5f650e36aba4f4ad4f 100644 (file)
@@ -101,7 +101,7 @@ static int dtrace_open(struct inode *inode, struct file *file)
 {
        dtrace_state_t  *state;
        uint32_t        priv;
-       uid_t           uid;
+       kuid_t          uid;
 
        dtrace_cred2priv(file->f_cred, &priv, &uid);
        if (priv == DTRACE_PRIV_NONE)
@@ -495,7 +495,7 @@ static long dtrace_ioctl(struct file *file,
                dtrace_probedesc_t      desc;
                dtrace_probekey_t       pkey;
                uint32_t                priv;
-               uid_t                   uid;
+               kuid_t                  uid;
 
                dt_dbg_ioctl("IOCTL %s (cmd %#x), argp %p\n",
                             cmd == DTRACEIOC_PROBES ? "PROBES"
index b759f5c14d6ed7965e19487bea8e344be0e2f40a..5d6468e8d9ddddccc87035297d1019ae8a3c5126 100644 (file)
@@ -2286,7 +2286,7 @@ static uint64_t dtrace_dif_variable(dtrace_mstate_t *mstate,
                 * Additionally, it is safe to dereference one's own process
                 * credential, since this is never NULL after process birth.
                 */
-               return (uint64_t)current->real_cred->uid;
+               return (uint64_t)from_kuid(NULL, current_real_cred()->uid);
 
        case DIF_VAR_GID:
                if (!dtrace_priv_proc(state))
@@ -2299,7 +2299,7 @@ static uint64_t dtrace_dif_variable(dtrace_mstate_t *mstate,
                 * Additionally, it is safe to dereference one's own process
                 * credential, since this is never NULL after process birth.
                 */
-               return (uint64_t)current->real_cred->gid;
+               return (uint64_t)from_kgid(NULL, current_real_cred()->gid);
 
        case DIF_VAR_ERRNO: {
                int64_t arg0;
index c7ad8c976a100b8d11d08ed37856274904b4aa4e..6eaaa3c47becb6ee6cdb98bdb5963d238f3828f5 100644 (file)
@@ -42,7 +42,6 @@ static dtrace_action_t *dtrace_ecb_aggregation_create(dtrace_ecb_t *ecb,
        dtrace_recdesc_t        *frec;
        dtrace_aggid_t          aggid;
        dtrace_state_t          *state = ecb->dte_state;
-       int                     err;
 
        agg = kzalloc(sizeof(dtrace_aggregation_t), GFP_KERNEL);
        if (agg == NULL)
@@ -141,14 +140,14 @@ success:
         * Get an ID for the aggregation (add it to the idr).
         */
        mutex_unlock(&dtrace_lock);
-again:
-       idr_pre_get(&state->dts_agg_idr, __GFP_NOFAIL);
+
+       idr_preload(GFP_KERNEL);
        mutex_lock(&dtrace_lock);
 
-       err = idr_get_new(&state->dts_agg_idr, agg, &aggid);
-       if (err == -EAGAIN) {
-               mutex_unlock(&dtrace_lock);
-               goto again;
+       aggid = idr_alloc_cyclic(&state->dts_agg_idr, agg, 0, 0, GFP_NOWAIT);
+       idr_preload_end();
+       if (aggid < 0) {
+               /* FIXME: need to handle this */
        }
 
        state->dts_naggs++;
index 75666a5430d95428f54e293441488a8a7c41f899..7efd7f48abaddc810793dc2b3dc65c1cf3c5ea11 100644 (file)
@@ -31,7 +31,7 @@ dtrace_hash_t *dtrace_bymod;
 dtrace_hash_t  *dtrace_byfunc;
 dtrace_hash_t  *dtrace_byname;
 
-int dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid)
+int dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, kuid_t uid)
 {
        if (priv != DTRACE_PRIV_ALL) {
                uint32_t        ppriv =
@@ -46,7 +46,7 @@ int dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid)
                        return 0;
 
                if (((ppriv & ~match) & DTRACE_PRIV_OWNER) != 0 &&
-                   uid != prp->dtpr_provider->dtpv_priv.dtpp_uid)
+                   !uid_eq(uid, prp->dtpr_provider->dtpv_priv.dtpp_uid))
                        return 0;
        }
 
@@ -54,7 +54,7 @@ int dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid)
 }
 
 int dtrace_match_probe(const dtrace_probe_t *prp, const dtrace_probekey_t *pkp,
-                      uint32_t priv, uid_t uid)
+                      uint32_t priv, kuid_t uid)
 {
        dtrace_provider_t       *pvp = prp->dtpr_provider;
        int                     rv;
@@ -204,7 +204,7 @@ int dtrace_match_nonzero(const char *s, const char *p, int depth)
 struct probe_match {
        const dtrace_probekey_t *pkp;
        uint32_t                priv;
-       uid_t                   uid;
+       kuid_t                  uid;
        int                     (*matched)(dtrace_probe_t *, void *);
        void                    *arg;
        int                     nmatched;
@@ -229,7 +229,7 @@ static int dtrace_match_one(int id, void *p, void *data)
        return 0;
 }
 
-int dtrace_match(const dtrace_probekey_t *pkp, uint32_t priv, uid_t uid,
+int dtrace_match(const dtrace_probekey_t *pkp, uint32_t priv, kuid_t uid,
                 int (*matched)(dtrace_probe_t *, void *), void *arg)
 {
        dtrace_probe_t  template, *probe;
index a19b08e2fa9520cee5bb78fcf75d1eff1ab8db64..79930a57eb3d74535ad0ed2b8fddc76fe7fcd542 100644 (file)
@@ -45,12 +45,12 @@ int dtrace_priv_proc_common_user(dtrace_state_t *state)
        ASSERT(s_cr != NULL);
 
        if ((cr = current_cred()) != NULL &&
-           s_cr->euid == cr->euid &&
-           s_cr->euid == cr->uid &&
-           s_cr->euid == cr->suid &&
-           s_cr->egid == cr->egid &&
-           s_cr->egid == cr->gid &&
-           s_cr->egid == cr->sgid)
+           uid_eq(s_cr->euid, cr->euid) &&
+           uid_eq(s_cr->euid, cr->uid) &&
+           uid_eq(s_cr->euid, cr->suid) &&
+           gid_eq(s_cr->egid, cr->egid) &&
+           gid_eq(s_cr->egid, cr->gid) &&
+           gid_eq(s_cr->egid, cr->sgid))
                return 1;
 
        return 0;
index 0437ba21810c261181ab9f21e5610d9f5b76fe6c..35ab7f1d82b135ee8b0f8942f9fde168e7f1bbb5 100644 (file)
@@ -59,12 +59,11 @@ dtrace_id_t dtrace_probe_create(dtrace_provider_id_t prov, const char *mod,
        dtrace_probe_t          *probe;
        dtrace_provider_t       *provider = (dtrace_provider_t *)prov;
        dtrace_id_t             id;
-       int                     err;
 
        probe = kmem_cache_alloc(dtrace_probe_cachep, __GFP_NOFAIL);
 
        /*
-        * The idr_pre_get() function should be called without holding locks.
+        * The ir_preload() function should be called without holding locks.
         * When the provider is the DTrace core itself, dtrace_lock will be
         * held when we enter this function.
         */
@@ -73,14 +72,13 @@ dtrace_id_t dtrace_probe_create(dtrace_provider_id_t prov, const char *mod,
                mutex_unlock(&dtrace_lock);
        }
 
-again:
-       idr_pre_get(&dtrace_probe_idr, __GFP_NOFAIL);
+       idr_preload(GFP_KERNEL);
 
        mutex_lock(&dtrace_lock);
-       err = idr_get_new(&dtrace_probe_idr, probe, &id);
-       if (err == -EAGAIN) {
-               mutex_unlock(&dtrace_lock);
-               goto again;
+       id = idr_alloc_cyclic(&dtrace_probe_idr, probe, 0, 0, GFP_NOWAIT);
+       idr_preload_end();
+       if (id < 0) {
+               /* FIXME: Need to handle failure */
        }
 
        probe->dtpr_id = id;
@@ -113,7 +111,7 @@ int dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab)
 {
        dtrace_probekey_t       pkey;
        uint32_t                priv;
-       uid_t                   uid;
+       kuid_t                  uid;
 
        dtrace_ecb_create_cache = NULL;
 
@@ -729,12 +727,12 @@ void dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
                                ASSERT(s_cr != NULL);
 
                                if ((cr = current_cred()) == NULL ||
-                                   s_cr->euid != cr->euid ||
-                                   s_cr->euid != cr->uid ||
-                                   s_cr->euid != cr->suid ||
-                                   s_cr->egid != cr->egid ||
-                                   s_cr->egid != cr->gid ||
-                                   s_cr->egid != cr->sgid)
+                                   !uid_eq(s_cr->euid, cr->euid) ||
+                                   !uid_eq(s_cr->euid, cr->uid) ||
+                                   !uid_eq(s_cr->euid, cr->suid) ||
+                                   !gid_eq(s_cr->egid, cr->egid) ||
+                                   !gid_eq(s_cr->egid, cr->gid) ||
+                                   !gid_eq(s_cr->egid, cr->sgid))
                                        continue;
                        }
                }
@@ -1282,7 +1280,6 @@ EXPORT_SYMBOL(dtrace_probe);
 int dtrace_probe_init(void)
 {
        dtrace_id_t     id;
-       int             err;
 
        dtrace_probe_cachep = KMEM_CACHE(dtrace_probe, SLAB_HWCACHE_ALIGN);
        if (dtrace_probe_cachep == NULL)
@@ -1295,30 +1292,27 @@ int dtrace_probe_init(void)
         * being the very first entry.  This is used in functionality that runs
         * through the list of probes.
         *
-        * We need to drop our locks when calling idr_pre_get(), so we try to
+        * We need to drop our locks when calling idr_preload(), so we try to
         * get them back right after.
         */
-again:
        mutex_unlock(&dtrace_lock);
        mutex_unlock(&dtrace_provider_lock);
        mutex_unlock(&cpu_lock);
 
-       idr_pre_get(&dtrace_probe_idr, __GFP_NOFAIL);
+       idr_preload(GFP_KERNEL);
 
        mutex_lock(&cpu_lock);
        mutex_lock(&dtrace_provider_lock);
        mutex_lock(&dtrace_lock);
 
-       err = idr_get_new(&dtrace_probe_idr, NULL, &id);
-       if (err == -EAGAIN)
-               goto again;
+       id = idr_alloc_cyclic(&dtrace_probe_idr, NULL, 0, 0, GFP_NOWAIT);
+       idr_preload_end();
 
        return id == 0 ? 0 : -EAGAIN;
 }
 
 void dtrace_probe_exit(void)
 {
-       idr_remove_all(&dtrace_probe_idr);
        idr_destroy(&dtrace_probe_idr);
        kmem_cache_destroy(dtrace_probe_cachep);
 }
@@ -1358,7 +1352,7 @@ dtrace_id_t dtrace_probe_lookup(dtrace_provider_id_t prid, const char *mod,
        pkey.dtpk_id = DTRACE_IDNONE;
 
        mutex_lock(&dtrace_lock);
-       match = dtrace_match(&pkey, DTRACE_PRIV_ALL, 0,
+       match = dtrace_match(&pkey, DTRACE_PRIV_ALL, make_kuid(NULL, 0),
                             dtrace_probe_lookup_match, &id);
        mutex_unlock(&dtrace_lock);
 
index 15964f858da54de8edd3feb2967e13427f05e2b8..3933a65165dd7266ff7b335a4398f752bdeb0a04 100644 (file)
@@ -203,7 +203,8 @@ int dtrace_register(const char *name, const dtrace_pattr_t *pap, uint32_t priv,
        provider->dtpv_priv.dtpp_flags = priv;
 
        if (cr != NULL) {
-               provider->dtpv_priv.dtpp_uid = get_cred(cr)->uid;
+               provider->dtpv_priv.dtpp_uid =
+                       make_kuid(NULL, from_kuid(NULL, get_cred(cr)->uid));
                put_cred(cr);
        }
 
index 15910c118ad190faad205426a728391f106b69af..837879dd7cdd8ec8b43080a3a9be4bc2bc063160 100644 (file)
@@ -339,7 +339,6 @@ dtrace_state_t *dtrace_state_create(struct file *file)
 #ifdef FIXME
        const cred_t    *cr = file->f_cred;
 #endif
-       int             err;
        dtrace_aggid_t  aggid;
 
        ASSERT(MUTEX_HELD(&cpu_lock));
@@ -373,18 +372,16 @@ dtrace_state_t *dtrace_state_create(struct file *file)
         * Create a first entry in the aggregation IDR, so that ID 0 is used as
         * that gets used as meaning 'none'.
         */
-again:
        mutex_unlock(&dtrace_lock);
        mutex_unlock(&cpu_lock);
 
-       idr_pre_get(&state->dts_agg_idr, __GFP_NOFAIL);
+       idr_preload(GFP_KERNEL);
 
        mutex_lock(&cpu_lock);
        mutex_lock(&dtrace_lock);
 
-       err = idr_get_new(&state->dts_agg_idr, NULL, &aggid);
-       if (err == -EAGAIN)
-               goto again;
+       aggid = idr_alloc_cyclic(&state->dts_agg_idr, NULL, 0, 0, GFP_NOWAIT);
+       idr_preload_end();
 
        ASSERT(aggid == 0);
 
@@ -1075,7 +1072,6 @@ void dtrace_state_destroy(dtrace_state_t *state)
         * If there were aggregations allocated, they should have been cleaned
         * up by now, so we can get rid of the idr.
         */
-       idr_remove_all(&state->dts_agg_idr);
        idr_destroy(&state->dts_agg_idr);
 
        vfree(state->dts_buffer);
index 40cdc2c769cf3917aba41f5de61808470d2cd685..e558c6321fa1d6df692a954580cfd33ead98f347 100644 (file)
@@ -130,7 +130,7 @@ int dtrace_badname(const char *s)
        return 0;
 }
 
-void dtrace_cred2priv(const cred_t *cr, uint32_t *privp, uid_t *uidp)
+void dtrace_cred2priv(const cred_t *cr, uint32_t *privp, kuid_t *uidp)
 {
 #ifdef FIXME
 /*
index 2b3bef83fafc17960f60975c6316f164da3629b2..c46ee71e1c72b9d2f0625f7dda0f13deb5ec86f1 100644 (file)
@@ -1671,7 +1671,7 @@ void fasttrap_dev_exit(void)
 
                if (tmp != CLEANUP_NONE) {
                        mutex_unlock(&fasttrap_cleanup_mtx);
-                       flush_delayed_work_sync(&fasttrap_cleanup);
+                       flush_delayed_work(&fasttrap_cleanup);
                        mutex_lock(&fasttrap_cleanup_mtx);
                }
        }
index 23f5d446caeada89df0ab5b322ace765dd693716..8f816a663f0fbf86e2cb14968fa021670cbae06f 100644 (file)
@@ -483,14 +483,14 @@ extern dtrace_hash_t              *dtrace_bymod;
 extern dtrace_hash_t           *dtrace_byfunc;
 extern dtrace_hash_t           *dtrace_byname;
 
-extern int dtrace_match_priv(const dtrace_probe_t *, uint32_t, uid_t);
+extern int dtrace_match_priv(const dtrace_probe_t *, uint32_t, kuid_t);
 extern int dtrace_match_probe(const dtrace_probe_t *,
-                             const dtrace_probekey_t *, uint32_t, uid_t);
+                             const dtrace_probekey_t *, uint32_t, kuid_t);
 extern int dtrace_match_glob(const char *, const char *, int);
 extern int dtrace_match_string(const char *, const char *, int);
 extern int dtrace_match_nul(const char *, const char *, int);
 extern int dtrace_match_nonzero(const char *, const char *, int);
-extern int dtrace_match(const dtrace_probekey_t *, uint32_t, uid_t,
+extern int dtrace_match(const dtrace_probekey_t *, uint32_t, kuid_t,
                        int (*matched)(dtrace_probe_t *, void *), void *);
 extern void dtrace_probekey(const dtrace_probedesc_t *, dtrace_probekey_t *);
 
@@ -850,7 +850,7 @@ extern int dtrace_strncmp(char *, char *, size_t);
 extern size_t dtrace_strlen(const char *, size_t);
 extern int dtrace_badattr(const dtrace_attribute_t *);
 extern int dtrace_badname(const char *);
-extern void dtrace_cred2priv(const cred_t *, uint32_t *, uid_t *);
+extern void dtrace_cred2priv(const cred_t *, uint32_t *, kuid_t *);
 
 typedef void for_each_module_fn(void *, struct module *);
 extern void dtrace_for_each_module(for_each_module_fn *fn, void *arg);
index e17f185ff340ec6fd892115b47953ae918e174d1..737dd50fb8c35ef11afde97c848bb3840978375b 100644 (file)
@@ -192,13 +192,13 @@ typedef enum dtrace_speculation_state {
 #define MUTEX_HELD(lock)       mutex_owned(lock)
 
 #ifdef CONFIG_PREEMPT_VOLUNTARY
-# define dtrace_is_preemptive()        (!(preempt_count() & PREEMPT_ACTIVE))
+# define dtrace_is_preemptive()        (preempt_count() > 0)
 # define dtrace_preempt_off()  do {                                          \
-                                       add_preempt_count(PREEMPT_ACTIVE);    \
+                                       preempt_count_inc();                  \
                                        barrier();                            \
                                } while (0)
 # define dtrace_preempt_on()   do {                                          \
-                                       sub_preempt_count(PREEMPT_ACTIVE);    \
+                                       preempt_count_dec();                  \
                                        barrier();                            \
                                } while (0)
 #endif
index 9b9eb142dcc8ec0c1fddb9920b8135f9eb8bf2d7..7427f1ee3e5a3e767c5a591f4f01f0d56f62c81b 100644 (file)
@@ -32,6 +32,7 @@
  * Use is subject to license terms.
  */
 
+#include <linux/uidgid.h>
 #include <linux/dtrace/universal.h>
 #include <linux/dtrace/stability_defines.h>
 
@@ -44,7 +45,7 @@
 
 typedef struct dtrace_ppriv {
        uint32_t dtpp_flags;                    /* privilege flags */
-       uid_t dtpp_uid;                         /* user ID */
+       kuid_t dtpp_uid;                        /* user ID */
 } dtrace_ppriv_t;
 
 typedef struct dtrace_attribute {