c - WRMSR on x86_64 64bit RCX register value is wrongly set -
i want write pmc1 register, want set rcx 188.
the code use use wrmsr instruction attached @ end. problem pass eax , ecx value (64bit) macro, but %rcx register set eax value.
#define rtxen_write_msr(eax, ecx) __asm__ __volatile__(\ "movq %0, %%rax\n\t"\ "xorq %%rdx, %%rdx\n\t"\ "xorq %%rcx, %%rcx\n\t"\ "movq %1, %%rcx\n\t"\ "wrmsr"\ :\ :"r" (eax), "r" (ecx)\ :\ ) uint64_t eax = 0x14f2e uint64_t edx = 0x188 printk("eax:%#018lx, edx:%#018lx\n", eax, edx); rtxen_write_msr(eax, ecx);
when rtxen_write_msr(eax, ecx) executed, kernel panic! register information follows:
(xen) cpu: 1 (xen) rip: e008:[<ffff82c4c02166b1>] setread_perf_counter+0x251/0x4c0 (xen) rflags: 0000000000010046 context: hypervisor (xen) rax: 0000000000014f2e rbx: ffff8308558f7718 **rcx: 0000000000014f2e** (xen) rdx: 0000000000000000 rsi: 000000000000000a rdi: ffff82c4c0270640 (xen) rbp: 0000000000000001 rsp: ffff83086bec7cd8 r8: 0000000000000004 (xen) r9: 0000000000000004 r10: 0000000000000004 r11: 0000000000000400 (xen) r12: 0000000000014f2e r13: 0000000200000000 r14: ffff83086bec7dd8 (xen) r15: 00000000000000fb cr0: 000000008005003b cr4: 00000000001426f0 (xen) cr3: 000000008ce6a000 cr2: ffff880115ca32a0 (xen) ds: 002b es: 002b fs: 0000 gs: 0000 ss: e010 cs: e008
can me see what's wrong in code?
you know can have compiler pass arguments in right registers straight away?
asm volatile ( "wrmsr" : : "a" ((uint32_t)eax) , "c" ((uint32_t)ecx) , "d" ((uint32_t)0) );
the typecast uint32_t
ensures compiler use 32-bit register variants (eax
, ecx
, edx
).
you can find constrain modifiers intel registers here: http://gcc.gnu.org/onlinedocs/gcc/machine-constraints.html#machine-constraints
on side note: if using registers in asm need tell compiler doing so. need put registers use , compiler doen't know clobber registers list after third colon.
Comments
Post a Comment