Skip to content
Snippets Groups Projects
Commit a7ea5784 authored by Glauber Costa's avatar Glauber Costa
Browse files

implement wrmsr_safe

Unfortunately, the Xen hypervisor has a very nasty bug (seems to be fixed by a
2013 patch - which means that although it is fixed, a lot of hypervisors will
have it), that causes all of the x2apic msr writes to init related registers
(INIT, SIPI, etc) trigger a GPF. The way to work around this, is to implement a
form of "wrmsr_safe".
parent c6bc3478
No related branches found
No related tags found
No related merge requests found
......@@ -65,6 +65,11 @@ inline void wrmsr(msr index, u64 value)
wrmsr(static_cast<u32>(index), value);
}
inline void wrmsr_safe(msr index, u64 value)
{
wrmsr_safe(static_cast<u32>(index), value);
}
inline u64 rdmsr(msr index)
{
return rdmsr(static_cast<u32>(index));
......
......@@ -202,6 +202,27 @@ inline void wrmsr(u32 index, u64 data) {
asm volatile ("wrmsr" : : "c"(index), "a"(lo), "d"(hi));
}
inline bool wrmsr_safe(u32 index, u64 data) {
u32 lo = data, hi = data >> 32;
bool ret = true;
asm volatile ("1: \n\t"
"wrmsr\n\t"
"2: \n\t"
".pushsection .text.fixup, \"ax\" \n\t"
"3: \n\t"
"xor %[ret], %[ret]\n\t"
"jmp 2b \n\t"
".popsection \n\t"
".pushsection .fixup, \"a\" \n\t"
".quad 1b, 3b \n\t"
".popsection\n"
: [ret]"+r"(ret)
: "c"(index), "a"(lo), "d"(hi));
return ret;
}
inline void wrfsbase(u64 data)
{
asm volatile("wrfsbase %0" : : "r"(data));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment