diff options
author | Andi Kleen <ak@linux.intel.com> | 2010-10-06 22:43:40 +0200 |
---|---|---|
committer | Andi Kleen <ak@linux.intel.com> | 2010-10-06 22:43:40 +0200 |
commit | 9420cfcf310f985253c40c7c4a08d9b8c20f94ce (patch) | |
tree | 7b7041877c1da40ef089cdd40c3c04c26ac434cd | |
parent | e0ca7f239bbf7dd4afdb25309762a86b63a3aa31 (diff) | |
download | mce-test-9420cfcf310f985253c40c7c4a08d9b8c20f94ce.tar.gz |
tinjpage: Test for correct si_addr_lsb field in signals
Signed-off-by: Andi Kleen <ak@linux.intel.com>
-rw-r--r-- | tsrc/tinjpage.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/tsrc/tinjpage.c b/tsrc/tinjpage.c index fd98a4f..0f71530 100644 --- a/tsrc/tinjpage.c +++ b/tsrc/tinjpage.c @@ -83,11 +83,40 @@ void *xmalloc(size_t s) return p; } +static int ilog2(int n) +{ + int r = 0; + n--; + while (n) { + n >>= 1; + r++; + } + return r; +} + int recovercount; sigjmp_buf recover_ctx; sigjmp_buf early_recover_ctx; void *expected_addr; +/* Work around glibc not defining this yet */ +struct my_siginfo { + int si_signo; + int si_errno; + int si_code; + union { + struct { + void *_addr; /* faulting insn/memory ref. */ +#ifdef __ARCH_SI_TRAPNO + int _trapno; /* TRAP # which caused the signal */ +#endif + short _addr_lsb; /* LSB of the reported address */ + } _sigfault; + } _sifields; +}; +#undef si_addr_lsb +#define si_addr_lsb _sifields._sigfault._addr_lsb + void sighandler(int sig, siginfo_t *si, void *arg) { if (si->si_addr != expected_addr) { @@ -96,6 +125,12 @@ void sighandler(int sig, siginfo_t *si, void *arg) failure++; } + int lsb = ((struct my_siginfo *)si)->si_addr_lsb; + if (lsb != ilog2(sysconf(_SC_PAGE_SIZE))) { + printf("XXX: Unexpected addr lsb in siginfo %d\n", lsb); + failure++; + } + printf("\tsignal %d code %d addr %p\n", sig, si->si_code, si->si_addr); if (--recovercount == 0) { |