ensure that DTrace memory access faults are non-fatal.
Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
typedef unsigned long dtrace_icookie_t;
-#define DTRACE_CPUFLAG_ISSET(flag) \
- (cpu_core[smp_processor_id()].cpuc_dtrace_flags & (flag))
-
-#define DTRACE_CPUFLAG_SET(flag) \
- (cpu_core[smp_processor_id()].cpuc_dtrace_flags |= (flag))
-
-#define DTRACE_CPUFLAG_CLEAR(flag) \
- (cpu_core[smp_processor_id()].cpuc_dtrace_flags &= ~(flag))
-
-#define CPU_DTRACE_NOFAULT 0x0001
-#define CPU_DTRACE_DROP 0x0002
-#define CPU_DTRACE_BADADDR 0x0004
-#define CPU_DTRACE_BADALIGN 0x0008
-#define CPU_DTRACE_DIVZERO 0x0010
-#define CPU_DTRACE_ILLOP 0x0020
-#define CPU_DTRACE_NOSCRATCH 0x0040
-#define CPU_DTRACE_KPRIV 0x0080
-#define CPU_DTRACE_UPRIV 0x0100
-#define CPU_DTRACE_TUPOFLOW 0x0200
-#define CPU_DTRACE_ENTRY 0x0800
-#define CPU_DTRACE_BADSTACK 0x1000
-
-#define CPU_DTRACE_FAULT (CPU_DTRACE_BADADDR | CPU_DTRACE_BADALIGN | \
- CPU_DTRACE_DIVZERO | CPU_DTRACE_ILLOP | \
- CPU_DTRACE_NOSCRATCH | CPU_DTRACE_KPRIV | \
- CPU_DTRACE_UPRIV | CPU_DTRACE_TUPOFLOW | \
- CPU_DTRACE_BADSTACK)
-#define CPU_DTRACE_ERROR (CPU_DTRACE_FAULT | CPU_DTRACE_DROP)
-
-#define CPUC_SIZE (sizeof (uint16_t) + sizeof(uint8_t) + \
- sizeof(uintptr_t) + sizeof(struct mutex))
-#define CPUC_PADSIZE (192 - CPUC_SIZE)
-
-typedef struct cpu_core {
- uint16_t cpuc_dtrace_flags;
- uint8_t cpuc_dcpc_intr_state;
- uint8_t cpuc_pad[CPUC_PADSIZE];
- uintptr_t cpuc_dtrace_illval;
- struct mutex cpuc_pid_lock;
-
- uintptr_t cpu_dtrace_caller;
- ktime_t cpu_dtrace_chillmark;
- ktime_t cpu_dtrace_chilled;
-} cpu_core_t;
-
-extern cpu_core_t cpu_core[];
-extern struct mutex cpu_lock;
+extern struct mutex cpu_lock;
extern void dtrace_sync(void);
extern void dtrace_toxic_ranges(void (*)(uintptr_t, uintptr_t));
*/
#include <linux/delay.h>
+#include <linux/dtrace_cpu.h>
#include <linux/dtrace_ioctl.h>
#include <linux/fs.h>
#include <linux/jiffies.h>
if (kaddr - taddr < tsize) {
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
- cpu_core[smp_processor_id()].cpuc_dtrace_illval = kaddr;
+ this_cpu_core->cpuc_dtrace_illval = kaddr;
return 1;
}
if (taddr - kaddr < size) {
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
- cpu_core[smp_processor_id()].cpuc_dtrace_illval = taddr;
+ this_cpu_core->cpuc_dtrace_illval = kaddr;
return 1;
}
}
* Use is subject to license terms.
*/
+#include <linux/dtrace_cpu.h>
#include <linux/hardirq.h>
#include <linux/in6.h>
#include <linux/inet.h>
size_t size = bits / NBBY; \
uint##bits##_t rval; \
int i; \
- int cpu = smp_processor_id(); \
volatile uint16_t *flags = (volatile uint16_t *) \
- &cpu_core[cpu].cpuc_dtrace_flags; \
+ &this_cpu_core->cpuc_dtrace_flags; \
\
/* \
* Deviation from the OpenSolaris code... Protect \
*/ \
if (addr == 0) { \
*flags |= CPU_DTRACE_BADADDR; \
- cpu_core[cpu].cpuc_dtrace_illval = addr; \
+ this_cpu_core->cpuc_dtrace_illval = addr; \
return 0; \
} \
\
\
if (addr + size <= dtrace_toxrange[i].dtt_base) \
continue; \
- \
+ \
/* \
* This address falls within a toxic region. \
*/ \
*flags |= CPU_DTRACE_BADADDR; \
- cpu_core[cpu].cpuc_dtrace_illval = addr; \
+ this_cpu_core->cpuc_dtrace_illval = addr; \
return 0; \
} \
\
dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
dtrace_vstate_t *vstate)
{
- int cpu = smp_processor_id();
- volatile uintptr_t *illval = &cpu_core[cpu].cpuc_dtrace_illval;
+ volatile uintptr_t *illval = &this_cpu_core->cpuc_dtrace_illval;
/*
* If we hold the privilege to read from kernel memory, then
{
volatile uint16_t *flags;
- flags = (volatile uint16_t *)&cpu_core[
- smp_processor_id()].cpuc_dtrace_flags;
+ flags = (volatile uint16_t *)&this_cpu_core->cpuc_dtrace_flags;
if (s1 == s2)
return 0;
dtrace_key_t *tupregs, int nargs,
dtrace_mstate_t *mstate, dtrace_state_t *state)
{
- volatile uint16_t *flags = &cpu_core[
- smp_processor_id()
- ].cpuc_dtrace_flags;
- volatile uintptr_t *illval = &cpu_core[
- smp_processor_id()
- ].cpuc_dtrace_illval;
+ volatile uint16_t *flags = &this_cpu_core->cpuc_dtrace_flags;
+ volatile uintptr_t *illval = &this_cpu_core->cpuc_dtrace_illval;
dtrace_vstate_t *vstate = &state->dts_vstate;
union {
rval = 1;
break;
}
+
+ if (p == p->real_parent)
+ break;
}
DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
const char *strtab = difo->dtdo_strtab;
const uint64_t *inttab = difo->dtdo_inttab;
- int cpu = smp_processor_id();
uint64_t rval = 0;
dtrace_statvar_t *svar;
dtrace_dstate_t *dstate = &vstate->dtvs_dynvars;
dtrace_difv_t *v;
- volatile uint16_t *flags = &cpu_core[cpu].cpuc_dtrace_flags;
- volatile uintptr_t *illval = &cpu_core[cpu].cpuc_dtrace_illval;
+ volatile uint16_t *flags = &this_cpu_core->cpuc_dtrace_flags;
+ volatile uintptr_t *illval = &this_cpu_core->cpuc_dtrace_illval;
dtrace_key_t tupregs[DIF_DTR_NREGS + 2];
/* +2 for thread and id */
* Use is subject to license terms.
*/
+#include <linux/dtrace_cpu.h>
+
#include "dtrace.h"
static uint32_t dtrace_helptrace_next = 0;
{
uint32_t size, next, nnext, i;
dtrace_helptrace_t *ent;
- uint16_t flags = cpu_core[
- smp_processor_id()
- ].cpuc_dtrace_flags;
+ uint16_t flags = this_cpu_core->cpuc_dtrace_flags;
if (!dtrace_helptrace_enabled)
return;
? mstate->dtms_fltoffs
: -1;
ent->dtht_fault = DTRACE_FLAGS2FLT(flags);
- ent->dtht_illval = cpu_core[smp_processor_id()].cpuc_dtrace_illval;
+ ent->dtht_illval = this_cpu_core->cpuc_dtrace_illval;
for (i = 0; i < vstate->dtvs_nlocals; i++) {
dtrace_statvar_t *svar;
uint64_t dtrace_helper(int which, dtrace_mstate_t *mstate,
dtrace_state_t *state, uint64_t arg0, uint64_t arg1)
{
- uint16_t *flags = &cpu_core[
- smp_processor_id()
- ].cpuc_dtrace_flags;
+ uint16_t *flags = &this_cpu_core->cpuc_dtrace_flags;
uint64_t sarg0 = mstate->dtms_arg[0];
uint64_t sarg1 = mstate->dtms_arg[1];
uint64_t rval = 0;
* Use is subject to license terms.
*/
+#include <linux/dtrace_cpu.h>
#include <linux/hardirq.h>
#include <linux/smp.h>
#include <asm/stacktrace.h>
uintptr_t _userlimit = 0x00007fffffffffffLL;
uintptr_t kernelbase = 0xffff880000000000LL;
-cpu_core_t cpu_core[NR_CPUS];
-EXPORT_SYMBOL(cpu_core);
EXPORT_SYMBOL(dtrace_getfp);
DEFINE_MUTEX(cpu_lock);
#else
if (kaddr < kernelbase || kaddr + size < kaddr) {
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
- cpu_core[smp_processor_id()].cpuc_dtrace_illval = kaddr;
+ this_cpu_core->cpuc_dtrace_illval = kaddr;
return 0;
}
#endif
if (uaddr + size >= kernelbase || uaddr + size < uaddr) {
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
- cpu_core[smp_processor_id()].cpuc_dtrace_illval = uaddr;
+ this_cpu_core->cpuc_dtrace_illval = uaddr;
return 0;
}
\
if ((uintptr_t)uaddr > _userlimit) { \
DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); \
- cpu_core[smp_processor_id()].cpuc_dtrace_illval = \
- (uintptr_t)uaddr; \
+ this_cpu_core->cpuc_dtrace_illval = (uintptr_t)uaddr; \
return 0; \
} \
\
* Use is subject to license terms.
*/
+#include <linux/dtrace_cpu.h>
+
#include "dtrace.h"
/*
* Use is subject to license terms.
*/
+#include <linux/dtrace_cpu.h>
#include <linux/hardirq.h>
#include <linux/idr.h>
#include <linux/module.h>
{
ktime_t now;
volatile uint16_t *flags;
- cpu_core_t *cpu = &cpu_core[smp_processor_id()];
+ cpu_core_t *cpu = this_cpu_core;
if (dtrace_destructive_disallow)
return;
char *str = (char *)&pcs[nframes];
int size, offs = 0, i, j;
uintptr_t old = mstate->dtms_scratch_ptr, saved;
- uint16_t *flags = &cpu_core[
- smp_processor_id()
- ].cpuc_dtrace_flags;
+ uint16_t *flags = &this_cpu_core->cpuc_dtrace_flags;
char *sym;
/*
mstate.dtms_arg[3] = arg3;
mstate.dtms_arg[4] = arg4;
- flags = (volatile uint16_t *)&cpu_core[cpuid].cpuc_dtrace_flags;
+ flags = (volatile uint16_t *)&this_cpu_core->cpuc_dtrace_flags;
for (ecb = probe->dtpr_ecb; ecb != NULL; ecb = ecb->dte_next) {
dtrace_predicate_t *pred = ecb->dte_predicate;
? mstate.dtms_fltoffs
: -1,
DTRACE_FLAGS2FLT(*flags),
- cpu_core[cpuid].cpuc_dtrace_illval);
+ this_cpu_core->cpuc_dtrace_illval);
continue;
}
* Use is subject to license terms.
*/
+#include <linux/dtrace_cpu.h>
+
#include "dtrace.h"
void dtrace_panic(const char *fmt, ...)
* Use is subject to license terms.
*/
+#include <linux/dtrace_cpu.h>
#include <linux/smp.h>
#include <asm/cmpxchg.h>
return;
if (which > state->dts_nspeculations) {
- cpu_core[cpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
+ per_cpu_core(cpu)->cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
return;
}
return;
if (which > state->dts_nspeculations) {
- cpu_core[cpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
+ per_cpu_core(cpu)->cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
return;
}
* atomically transitioned into the ACTIVEMANY state.
*/
dtrace_buffer_t *dtrace_speculation_buffer(dtrace_state_t *state,
- processorid_t cpuid,
+ processorid_t cpu,
dtrace_specid_t which)
{
dtrace_speculation_t *spec;
return NULL;
if (which > state->dts_nspeculations) {
- cpu_core[cpuid].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
+ per_cpu_core(cpu)->cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
return NULL;
}
spec = &state->dts_speculations[which - 1];
- buf = &spec->dtsp_buffer[cpuid];
+ buf = &spec->dtsp_buffer[cpu];
do {
curr = spec->dtsp_state;
* Use is subject to license terms.
*/
+#include <linux/dtrace_cpu.h>
#include <linux/vmalloc.h>
#include "dtrace.h"
if (s1 == s2 || limit == 0)
return 0;
- flags = (volatile uint16_t *)
- &cpu_core[smp_processor_id()].cpuc_dtrace_flags;
+ flags = (volatile uint16_t *)&this_cpu_core->cpuc_dtrace_flags;
do {
if (s1 == NULL)