summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Musolino <alex@musolino.id.au>2018-12-12 12:51:29 +1030
committerAlex Musolino <alex@musolino.id.au>2018-12-12 12:51:29 +1030
commit9b194f23b2a544fab666e40f4f574c8fceb7601f (patch)
tree59b1b2b1829c0d776c21d8618611d3ae38fc7e9b
parentb836802fe6c1327bc1947a560741f26aac6a7711 (diff)
parent4c68cfa41226de2501c677e80e9e6932d1e39236 (diff)
merge
-rw-r--r--lib/theo5
-rw-r--r--sys/games/lib/fortunes1
-rw-r--r--sys/include/dtracy.h7
-rw-r--r--sys/src/9/pc/l.s11
-rw-r--r--sys/src/9/pc/mkfile1
-rw-r--r--sys/src/9/pc/pc4
-rw-r--r--sys/src/9/pc/trap.c13
-rw-r--r--sys/src/9/pc64/l.s12
-rw-r--r--sys/src/9/pc64/mkfile1
-rw-r--r--sys/src/9/pc64/pc644
-rw-r--r--sys/src/9/pc64/trap.c14
-rw-r--r--sys/src/9/port/devdtracy.c73
-rw-r--r--sys/src/9/port/dtracysys.c2
-rw-r--r--sys/src/9/port/dtracytimer.c56
-rwxr-xr-xsys/src/9/port/mkdevc13
-rw-r--r--sys/src/cmd/dtracy/act.c33
-rw-r--r--sys/src/cmd/sshfs.c2
-rw-r--r--sys/src/libdtracy/prog.c53
18 files changed, 242 insertions, 63 deletions
diff --git a/lib/theo b/lib/theo
index 8c1cf546a..1a4b71a26 100644
--- a/lib/theo
+++ b/lib/theo
@@ -905,3 +905,8 @@ No.
No.
Not going to explain further.
Get your shit together
+oh my, the moral outrage
+Let it go, and consider leaving for good.
+Do you have evidence?
+Diffs are welcome.
+Please don't do that.
diff --git a/sys/games/lib/fortunes b/sys/games/lib/fortunes
index adb2e9ff5..e5d2e27a2 100644
--- a/sys/games/lib/fortunes
+++ b/sys/games/lib/fortunes
@@ -5248,3 +5248,4 @@ I've been looking into running Plan 9 in JSLinux -- Skip Tavakkolian
i have been looking for an excuse to install 9front.
I'm beginning to wonder if anyone is left that isn't part of 9front? -- Steve Stallion
Having a public mailing list is an invitation for discussion amongst likeminded individuals, not elitist fuckery. -- Steve Stallion, talking about 9fans
+[9fans] ..... UNSUBSCRIBE_HELP NEEDED
diff --git a/sys/include/dtracy.h b/sys/include/dtracy.h
index 3e2ff81f1..cd8d577b3 100644
--- a/sys/include/dtracy.h
+++ b/sys/include/dtracy.h
@@ -41,6 +41,8 @@ struct DTName {
/*
we assign all pairs (probe,action-group) (called an enabling or DTEnab) a unique ID called EPID.
we could also use probe IDs and action group IDs but using a single 32-bit ID for both is more flexible/efficient.
+
+ epid == -1 indicates a fault record (see below)
*/
struct DTEnab {
u32int epid;
@@ -235,6 +237,10 @@ struct DTTrigInfo {
DTChan *ch;
};
+/* fault records are used to note when a probe had to be aborted (e.g. because of a page fault) */
+enum {
+ DTFILL = 1, /* illegal address */
+};
void dtinit(int);
void dtsync(void);
@@ -269,6 +275,7 @@ int dtcread(DTChan *, void *, int);
int dtcaggread(DTChan *, void *, int);
void dtcreset(DTChan *);
void dtcrun(DTChan *, int);
+int dtcfault(DTTrigInfo *, int, char *, ...);
/* aggbuf functions */
int dtaunpackid(DTAgg *);
diff --git a/sys/src/9/pc/l.s b/sys/src/9/pc/l.s
index 217088ecb..5f40295ef 100644
--- a/sys/src/9/pc/l.s
+++ b/sys/src/9/pc/l.s
@@ -511,6 +511,17 @@ TEXT _wrmsrinst(SB), $0
MOVL BP, AX /* BP set to -1 if traped */
RET
+/* fault-proof memcpy */
+TEXT peek(SB), $0
+ MOVL src+0(FP), SI
+ MOVL dst+4(FP), DI
+ MOVL cnt+8(FP), CX
+ CLD
+TEXT _peekinst(SB), $0
+ REP; MOVSB
+ MOVL CX, AX
+ RET
+
/*
* Try to determine the CPU type which requires fiddling with EFLAGS.
* If the Id bit can be toggled then the CPUID instruction can be used
diff --git a/sys/src/9/pc/mkfile b/sys/src/9/pc/mkfile
index ee05c3a29..6b43feddc 100644
--- a/sys/src/9/pc/mkfile
+++ b/sys/src/9/pc/mkfile
@@ -67,6 +67,7 @@ LIB=\
/$objtype/lib/libmp.a\
/$objtype/lib/libfis.a\
/$objtype/lib/libaml.a\
+ /$objtype/lib/libdtracy.a\
ETHER=`{echo devether.c ether*.c | sed 's/\.c/.'$O'/g'}
AUDIO=`{echo devaudio.c audio*.c | sed 's/\.c/.'$O'/g'}
diff --git a/sys/src/9/pc/pc b/sys/src/9/pc/pc
index ffdb41a4a..86c5c8b1e 100644
--- a/sys/src/9/pc/pc
+++ b/sys/src/9/pc/pc
@@ -18,6 +18,7 @@ dev
cap
kprof
fs
+ dtracy
ether netif
bridge netif log
@@ -137,6 +138,9 @@ misc
vgatvp3026 =cur
vgavesa
vgavmware +cur
+
+ dtracysys
+ dtracytimer
ip
tcp
diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c
index b76afaff2..0d74f0a98 100644
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -450,6 +450,7 @@ trap(Ureg* ureg)
extern void _forkretiret(void);
extern void _rdmsrinst(void);
extern void _wrmsrinst(void);
+ extern void _peekinst(void);
extern void load_fs(ulong);
extern void load_gs(ulong);
@@ -478,6 +479,11 @@ trap(Ureg* ureg)
ureg->pc += 2;
return;
}
+ } else if(pc == _peekinst){
+ if(vno == VectorGPF){
+ ureg->pc += 2;
+ return;
+ }
}
}
@@ -712,6 +718,13 @@ fault386(Ureg* ureg, void*)
if(!user){
if(vmapsync(addr))
return;
+ {
+ extern void _peekinst(void);
+ if((void(*)(void))ureg->pc == _peekinst){
+ ureg->pc += 2;
+ return;
+ }
+ }
if(addr >= USTKTOP)
panic("kernel fault: bad address pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
if(up == nil)
diff --git a/sys/src/9/pc64/l.s b/sys/src/9/pc64/l.s
index 7143d3b69..c00a24fc7 100644
--- a/sys/src/9/pc64/l.s
+++ b/sys/src/9/pc64/l.s
@@ -449,6 +449,18 @@ TEXT _wrmsrinst(SB), $0
MOVQ BP, AX /* BP set to -1 if traped */
RET
+/* fault-proof memcpy */
+TEXT peek(SB), 1, $-4
+ MOVQ RARG, SI
+ MOVQ dst+8(FP), DI
+ MOVL cnt+16(FP), CX
+ CLD
+TEXT _peekinst(SB), $0
+ REP; MOVSB
+ MOVL CX, AX
+ RET
+
+
TEXT invlpg(SB), 1, $-4
INVLPG (RARG)
RET
diff --git a/sys/src/9/pc64/mkfile b/sys/src/9/pc64/mkfile
index 51204dcee..fc0b5af09 100644
--- a/sys/src/9/pc64/mkfile
+++ b/sys/src/9/pc64/mkfile
@@ -65,6 +65,7 @@ LIB=\
/$objtype/lib/libc.a\
/$objtype/lib/libfis.a\
/$objtype/lib/libaml.a\
+ /$objtype/lib/libdtracy.a\
ETHER=`{cd ../pc; echo devether.c ether*.c | sed 's/\.c/.'$O'/g'}
AUDIO=`{cd ../pc; echo devaudio.c audio*.c | sed 's/\.c/.'$O'/g'}
diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64
index ca464f96b..e3ce365d9 100644
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -41,6 +41,7 @@ dev
segment
vmx
+ dtracy
link
# devpccard
@@ -136,6 +137,9 @@ misc
vgavesa
# vgavmware +cur
+ dtracysys
+ dtracytimer
+
ip
tcp
udp
diff --git a/sys/src/9/pc64/trap.c b/sys/src/9/pc64/trap.c
index 1944f43bd..23c1e9b69 100644
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -440,6 +440,7 @@ trap(Ureg *ureg)
extern void _rdmsrinst(void);
extern void _wrmsrinst(void);
+ extern void _peekinst(void);
pc = (void*)ureg->pc;
if(pc == _rdmsrinst || pc == _wrmsrinst){
@@ -448,6 +449,11 @@ trap(Ureg *ureg)
ureg->pc += 2;
return;
}
+ } else if(pc == _peekinst){
+ if(vno == VectorGPF){
+ ureg->pc += 2;
+ return;
+ }
}
}
@@ -672,6 +678,14 @@ faultamd64(Ureg* ureg, void*)
read = !(ureg->error & 2);
user = userureg(ureg);
if(!user){
+ {
+ extern void _peekinst(void);
+
+ if((void(*)(void))ureg->pc == _peekinst){
+ ureg->pc += 2;
+ return;
+ }
+ }
if(addr >= USTKTOP)
panic("kernel fault: bad address pc=%#p addr=%#p", ureg->pc, addr);
if(up == nil)
diff --git a/sys/src/9/port/devdtracy.c b/sys/src/9/port/devdtracy.c
index 82d2d0a27..4bd47ca0e 100644
--- a/sys/src/9/port/devdtracy.c
+++ b/sys/src/9/port/devdtracy.c
@@ -125,9 +125,13 @@ dtkfree(DTKChan *p)
dtktab[idx] = nil;
}
+static int dtracyen;
+
static void
dtracyinit(void)
{
+ dtracyen = getconf("*dtracy") != nil;
+ if(!dtracyen) return;
machlocks = smalloc(sizeof(Lock) * conf.nmach);
dtinit(conf.nmach);
}
@@ -135,6 +139,8 @@ dtracyinit(void)
static Chan*
dtracyattach(char *spec)
{
+ if(!dtracyen)
+ error("*dtracy= not set");
return devattach(L'Δ', spec);
}
@@ -512,67 +518,16 @@ dtgetvar(int v)
}
}
+int peek(char *, char *, int);
+
int
dtpeek(uvlong addr, void *buf, int len)
{
- if((uintptr)addr != addr || up == nil || !okaddr((uintptr) addr, len, 0)) return -1;
- memmove(buf, (void *) addr, len);
- return 0;
-}
-
-static DTProbe *timerprobe;
-
-static void
-dtracytimer(void *)
-{
- DTTrigInfo info;
-
- memset(&info, 0, sizeof(info));
- for(;;){
- tsleep(&up->sleep, return0, nil, 1000);
- dtptrigger(timerprobe, m->machno, &info);
- }
-}
-
-static void
-timerprovide(DTProvider *prov, DTName)
-{
- static int provided;
-
- if(provided) return;
- provided = 1;
- timerprobe = dtpnew((DTName){"timer", "", "1s"}, prov, nil);
-}
-
-static int
-timerenable(DTProbe *)
-{
- static int gotkproc;
+ uintptr a;
- if(!gotkproc){
- kproc("dtracytimer", dtracytimer, nil);
- gotkproc=1;
- }
- return 0;
+ a = addr;
+ if(len == 0) return 0;
+ if(a != addr || a > -(uintptr)len || len < 0) return -1;
+ if(up == nil || up->privatemem || a >= KZERO) return -1;
+ return peek((void *)a, buf, len) > 0 ? -1 : 0;
}
-
-static void
-timerdisable(DTProbe *)
-{
-}
-
-DTProvider dtracyprov_timer = {
- .name = "timer",
- .provide = timerprovide,
- .enable = timerenable,
- .disable = timerdisable,
-};
-
-extern DTProvider dtracyprov_sys;
-
-DTProvider *dtproviders[] = {
- &dtracyprov_timer,
- &dtracyprov_sys,
- nil,
-};
-
diff --git a/sys/src/9/port/dtracysys.c b/sys/src/9/port/dtracysys.c
index c9e0f4e5a..859dd9f84 100644
--- a/sys/src/9/port/dtracysys.c
+++ b/sys/src/9/port/dtracysys.c
@@ -260,7 +260,7 @@ sysdisable(DTProbe *p)
z = systab[i], systab[i] = wraptab[i], wraptab[i] = z;
}
-DTProvider dtracyprov_sys = {
+DTProvider dtracysysprov = {
.name = "sys",
.provide = sysprovide,
.enable = sysenable,
diff --git a/sys/src/9/port/dtracytimer.c b/sys/src/9/port/dtracytimer.c
new file mode 100644
index 000000000..cb3b636f6
--- /dev/null
+++ b/sys/src/9/port/dtracytimer.c
@@ -0,0 +1,56 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+#include <dtracy.h>
+
+static DTProbe *timerprobe;
+
+static void
+dtracytimer(void *)
+{
+ DTTrigInfo info;
+
+ memset(&info, 0, sizeof(info));
+ for(;;){
+ tsleep(&up->sleep, return0, nil, 1000);
+ dtptrigger(timerprobe, m->machno, &info);
+ }
+}
+
+static void
+timerprovide(DTProvider *prov, DTName)
+{
+ static int provided;
+
+ if(provided) return;
+ provided = 1;
+ timerprobe = dtpnew((DTName){"timer", "", "1s"}, prov, nil);
+}
+
+static int
+timerenable(DTProbe *)
+{
+ static int gotkproc;
+
+ if(!gotkproc){
+ kproc("dtracytimer", dtracytimer, nil);
+ gotkproc=1;
+ }
+ return 0;
+}
+
+static void
+timerdisable(DTProbe *)
+{
+}
+
+DTProvider dtracytimerprov = {
+ .name = "timer",
+ .provide = timerprovide,
+ .enable = timerenable,
+ .disable = timerdisable,
+};
diff --git a/sys/src/9/port/mkdevc b/sys/src/9/port/mkdevc
index 283c69a27..8e87636d8 100755
--- a/sys/src/9/port/mkdevc
+++ b/sys/src/9/port/mkdevc
@@ -58,7 +58,8 @@ collect && section == "misc"{
if($i ~ "[+=]cur")
vgacur[nvgacur++] = $1;
}
- }
+ }else if($1 ~ "^dtracy.*")
+ dtracyprov[ndtracyprov++] = $1;
}
collect && section == "port"{
@@ -190,6 +191,16 @@ END{
printf "%s\n", port[i];
printf "\n";
}
+
+ if(ndtracyprov){
+ printf "#include <dtracy.h>\n";
+ for(i = 0; i < ndtracyprov; i++)
+ printf "extern DTProvider %sprov;\n", dtracyprov[i]
+ printf "DTProvider *dtproviders[] = {\n"
+ for(i = 0; i < ndtracyprov; i++)
+ printf "\t&%sprov,\n", dtracyprov[i]
+ printf "\tnil,\n};\n\n"
+ }
printf "char* conffile = \"%s/%s\";\n", pwd, ARGV[1];
printf "ulong kerndate = KERNDATE;\n";
diff --git a/sys/src/cmd/dtracy/act.c b/sys/src/cmd/dtracy/act.c
index 063be6cb9..3412382c3 100644
--- a/sys/src/cmd/dtracy/act.c
+++ b/sys/src/cmd/dtracy/act.c
@@ -462,6 +462,34 @@ parseclause(Clause *cl, uchar *p, uchar *e, Enab *en, Biobuf *bp)
return 0;
}
+uchar *
+parsefault(uchar *p0, uchar *e)
+{
+ uchar *p;
+ u32int epid;
+ u8int type, dummy;
+ u16int n;
+ Enab *en;
+
+ p = unpack(p0, e, "csci", &type, &n, &dummy, &epid);
+ if(p == nil) return nil;
+ en = epidlookup(epid);
+ switch(type){
+ case DTFILL: {
+ u32int pid;
+ u64int addr;
+
+ p = unpack(p, e, "iv", &pid, &addr);
+ if(p == nil) return nil;
+ fprint(2, "dtracy: illegal access: probe=%s, pid=%d, addr=%#llx\n", en != nil ? en->probe : nil, pid, addr);
+ break;
+ }
+ default:
+ fprint(2, "dtracy: unknown fault type %#.2ux\n", type);
+ }
+ return p0 + n - 12;
+}
+
int
parsebuf(uchar *p, int n, Biobuf *bp)
{
@@ -474,6 +502,11 @@ parsebuf(uchar *p, int n, Biobuf *bp)
while(p < e){
p = unpack(p, e, "iv", &epid, &ts);
if(p == nil) goto err;
+ if(epid == (u32int)-1){
+ p = parsefault(p, e);
+ if(p == nil) goto err;
+ continue;
+ }
en = epidlookup(epid);
if(en == nil) goto err;
if(parseclause(en->cl, p - 12, p + en->reclen - 12, en, bp) < 0) return -1;
diff --git a/sys/src/cmd/sshfs.c b/sys/src/cmd/sshfs.c
index f85c72dae..d0c21ec74 100644
--- a/sys/src/cmd/sshfs.c
+++ b/sys/src/cmd/sshfs.c
@@ -1414,4 +1414,6 @@ threadmain(int argc, char **argv)
passwdparse(gidtab, readfile(gidfile));
threadpostmountsrv(&sshfssrv, svc, mtpt, MCREATE | mflag);
+
+ exits(nil);
}
diff --git a/sys/src/libdtracy/prog.c b/sys/src/libdtracy/prog.c
index f0637acad..402638f13 100644
--- a/sys/src/libdtracy/prog.c
+++ b/sys/src/libdtracy/prog.c
@@ -230,6 +230,55 @@ dtpeekstr(uvlong addr, u8int *v, int len)
#define PUT4(c) *bp++ = c; *bp++ = c >> 8; *bp++ = c >> 16; *bp++ = c >> 24;
#define PUT8(c) PUT4(c); PUT4(c>>32);
+int
+dtcfault(DTTrigInfo *info, int type, char *fmt, ...)
+{
+ DTBuf *b;
+ va_list va;
+ int n;
+ char *s;
+ u8int *bp;
+ u32int l;
+ uvlong q;
+
+ b = info->ch->wrbufs[info->machno];
+ n = 20;
+ va_start(va, fmt);
+ for(s = fmt; *s != 0; s++)
+ switch(*s){
+ case 'i': n += 4; break;
+ case 'p': n += 8; break;
+ default:
+ assert(0);
+ }
+ va_end(va);
+ if(b->wr + n > DTBUFSZ)
+ return -1;
+ bp = &b->data[b->wr];
+ PUT4(-1);
+ PUT8(info->ts);
+ PUT1(type);
+ PUT2(n);
+ PUT1(0);
+ PUT4(info->epid);
+ va_start(va, fmt);
+ for(s = fmt; *s != 0; s++)
+ switch(*s){
+ case 'i':
+ l = va_arg(va, int);
+ PUT4(l);
+ break;
+ case 'p':
+ q = (uintptr) va_arg(va, void *);
+ PUT8(q);
+ break;
+ }
+ va_end(va);
+ assert(bp - b->data - b->wr == n);
+ b->wr = bp - b->data;
+ return 0;
+}
+
static int
dtgexec(DTActGr *g, DTTrigInfo *info)
{
@@ -265,8 +314,8 @@ dtgexec(DTActGr *g, DTTrigInfo *info)
break;
case ACTTRACESTR:
if(dtpeekstr(v, bp, g->acts[i].size) < 0){
- snprint(info->ch->errstr, sizeof(info->ch->errstr), "fault @ %#llux", v);
- return -1;
+ dtcfault(info, DTFILL, "ip", dtgetvar(DTV_PID), v);
+ return 0;
}
bp += g->acts[i].size;
break;