linux - Why a segfault instead of privilege instruction error? -
i trying execute privileged instruction rdmsr
in user mode, , expect kind of privilege error, segfault instead. have checked asm
, loading 0x186
ecx
, supposed perfevtsel0
, based on manual, page 1171.
what cause of segfault, , how can modify code below fix it?
i want resolve before hacking kernel module, because don't want segfault blow kernel.
update: running on intel(r) xeon(r) cpu x3470
.
#define _gnu_source #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include <sched.h> #include <assert.h> uint64_t read_msr(int ecx) { unsigned int a, d; __asm __volatile("rdmsr" : "=a"(a), "=d"(d) : "c"(ecx)); return ((uint64_t)a) | (((uint64_t)d) << 32); } int main(int ac, char **av) { uint64_t start, end; cpu_set_t cpuset; unsigned int c = 0x186; int = 0; cpu_zero(&cpuset); cpu_set(i, &cpuset); assert(sched_setaffinity(0, sizeof(cpuset), &cpuset) == 0); printf("%lu\n", read_msr(c)); return 0; }
the question try answer: why above code cause sigsegv
instead of sigill
, though code has no memory error, illegal instruction (a privileged instruction called non-privileged user pace)?
i expect sigill
si_code
ill_prvopc
instead of segfault, too. question 3 years old , today, stumbled upon same behavior. disappointed :-(
what cause of segfault
the cause seems linux kernel code decides send sigsegv
. here responsible function: http://elixir.free-electrons.com/linux/v4.9/source/arch/x86/kernel/traps.c#l487 have @ last line of function.
in your follow question, got list of other assembly instructions propagated sigsegv
userspace though general protection faults. found question because triggered behavior cli
.
and how can modify code below fix it?
as of linux kernel 4.9, i'm not aware of reliable way distinguish between memory error (what expect sigsegv
) , privileged instruction error userspace.
there may hacky , unportable way distibguish these cases. when privileged instruction causes sigsegv
, siginfo_t
si_code
set value illegal according man 2 sigaction
. documented values segv_maperr
, segv_accerr
, segv_pkuerr
, si_kernel
(0x80) on system. in strace, see sigsegv {si_signo=sigsegv, si_code=si_kernel, si_addr=0}
. responsible kernel code here.
it possible grep dmesg
this string.
please, never ever use 2 methods distinguish between gpf , memory error on production system.
specific solution code: don't run rdmsr
user space. answer unsatisfying if looking generic way figure out why program received sigsegv
.
Comments
Post a Comment