dtracy: catch page faults
This commit is contained in:
parent
6f30420136
commit
cc066d8130
|
@ -511,6 +511,17 @@ TEXT _wrmsrinst(SB), $0
|
||||||
MOVL BP, AX /* BP set to -1 if traped */
|
MOVL BP, AX /* BP set to -1 if traped */
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
/* fault-proof memcpy */
|
||||||
|
TEXT peek(SB), $0
|
||||||
|
MOVL $0, AX /* AX set to -1 if traped */
|
||||||
|
MOVL src+0(FP), SI
|
||||||
|
MOVL dst+4(FP), DI
|
||||||
|
MOVL cnt+8(FP), CX
|
||||||
|
CLD
|
||||||
|
TEXT _peekinst(SB), $0
|
||||||
|
REP; MOVSB
|
||||||
|
RET
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to determine the CPU type which requires fiddling with EFLAGS.
|
* 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
|
* If the Id bit can be toggled then the CPUID instruction can be used
|
||||||
|
|
|
@ -450,6 +450,7 @@ trap(Ureg* ureg)
|
||||||
extern void _forkretiret(void);
|
extern void _forkretiret(void);
|
||||||
extern void _rdmsrinst(void);
|
extern void _rdmsrinst(void);
|
||||||
extern void _wrmsrinst(void);
|
extern void _wrmsrinst(void);
|
||||||
|
extern void _peekinst(void);
|
||||||
|
|
||||||
extern void load_fs(ulong);
|
extern void load_fs(ulong);
|
||||||
extern void load_gs(ulong);
|
extern void load_gs(ulong);
|
||||||
|
@ -478,6 +479,12 @@ trap(Ureg* ureg)
|
||||||
ureg->pc += 2;
|
ureg->pc += 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if(pc == _peekinst){
|
||||||
|
if(vno == VectorGPF){
|
||||||
|
ureg->ax = -1;
|
||||||
|
ureg->pc += 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,6 +719,14 @@ fault386(Ureg* ureg, void*)
|
||||||
if(!user){
|
if(!user){
|
||||||
if(vmapsync(addr))
|
if(vmapsync(addr))
|
||||||
return;
|
return;
|
||||||
|
{
|
||||||
|
extern void _peekinst(void);
|
||||||
|
if((void(*)(void))ureg->pc == _peekinst){
|
||||||
|
ureg->ax = -1;
|
||||||
|
ureg->pc += 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(addr >= USTKTOP)
|
if(addr >= USTKTOP)
|
||||||
panic("kernel fault: bad address pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
|
panic("kernel fault: bad address pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
|
||||||
if(up == nil)
|
if(up == nil)
|
||||||
|
|
|
@ -449,6 +449,18 @@ TEXT _wrmsrinst(SB), $0
|
||||||
MOVQ BP, AX /* BP set to -1 if traped */
|
MOVQ BP, AX /* BP set to -1 if traped */
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
/* fault-proof memcpy */
|
||||||
|
TEXT peek(SB), 1, $-4
|
||||||
|
MOVQ $0, AX
|
||||||
|
MOVQ RARG, SI
|
||||||
|
MOVQ dst+8(FP), DI
|
||||||
|
MOVL cnt+16(FP), CX
|
||||||
|
CLD
|
||||||
|
TEXT _peekinst(SB), $0
|
||||||
|
REP; MOVSB
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
TEXT invlpg(SB), 1, $-4
|
TEXT invlpg(SB), 1, $-4
|
||||||
INVLPG (RARG)
|
INVLPG (RARG)
|
||||||
RET
|
RET
|
||||||
|
|
|
@ -440,6 +440,7 @@ trap(Ureg *ureg)
|
||||||
|
|
||||||
extern void _rdmsrinst(void);
|
extern void _rdmsrinst(void);
|
||||||
extern void _wrmsrinst(void);
|
extern void _wrmsrinst(void);
|
||||||
|
extern void _peekinst(void);
|
||||||
|
|
||||||
pc = (void*)ureg->pc;
|
pc = (void*)ureg->pc;
|
||||||
if(pc == _rdmsrinst || pc == _wrmsrinst){
|
if(pc == _rdmsrinst || pc == _wrmsrinst){
|
||||||
|
@ -448,6 +449,12 @@ trap(Ureg *ureg)
|
||||||
ureg->pc += 2;
|
ureg->pc += 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if(pc == _peekinst){
|
||||||
|
if(vno == VectorGPF){
|
||||||
|
ureg->ax = -1;
|
||||||
|
ureg->pc += 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,6 +679,15 @@ faultamd64(Ureg* ureg, void*)
|
||||||
read = !(ureg->error & 2);
|
read = !(ureg->error & 2);
|
||||||
user = userureg(ureg);
|
user = userureg(ureg);
|
||||||
if(!user){
|
if(!user){
|
||||||
|
{
|
||||||
|
extern void _peekinst(void);
|
||||||
|
|
||||||
|
if((void(*)(void))ureg->pc == _peekinst){
|
||||||
|
ureg->ax = -1;
|
||||||
|
ureg->pc += 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(addr >= USTKTOP)
|
if(addr >= USTKTOP)
|
||||||
panic("kernel fault: bad address pc=%#p addr=%#p", ureg->pc, addr);
|
panic("kernel fault: bad address pc=%#p addr=%#p", ureg->pc, addr);
|
||||||
if(up == nil)
|
if(up == nil)
|
||||||
|
|
|
@ -518,10 +518,16 @@ dtgetvar(int v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int peek(char *, char *, int);
|
||||||
|
|
||||||
int
|
int
|
||||||
dtpeek(uvlong addr, void *buf, int len)
|
dtpeek(uvlong addr, void *buf, int len)
|
||||||
{
|
{
|
||||||
if((uintptr)addr != addr || up == nil || !okaddr((uintptr) addr, len, 0)) return -1;
|
uintptr a;
|
||||||
memmove(buf, (void *) addr, len);
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue