|
@@ -80,7 +80,14 @@ static inline void do_trace_read_msr(unsigned int msr, u64 val, int failed) {}
|
|
|
static inline void do_trace_rdpmc(unsigned int msr, u64 val, int failed) {}
|
|
|
#endif
|
|
|
|
|
|
-static inline unsigned long long native_read_msr(unsigned int msr)
|
|
|
+/*
|
|
|
+ * __rdmsr() and __wrmsr() are the two primitives which are the bare minimum MSR
|
|
|
+ * accessors and should not have any tracing or other functionality piggybacking
|
|
|
+ * on them - those are *purely* for accessing MSRs and nothing more. So don't even
|
|
|
+ * think of extending them - you will be slapped with a stinking trout or a frozen
|
|
|
+ * shark will reach you, wherever you are! You've been warned.
|
|
|
+ */
|
|
|
+static inline unsigned long long notrace __rdmsr(unsigned int msr)
|
|
|
{
|
|
|
DECLARE_ARGS(val, low, high);
|
|
|
|
|
@@ -88,11 +95,30 @@ static inline unsigned long long native_read_msr(unsigned int msr)
|
|
|
"2:\n"
|
|
|
_ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_unsafe)
|
|
|
: EAX_EDX_RET(val, low, high) : "c" (msr));
|
|
|
- if (msr_tracepoint_active(__tracepoint_read_msr))
|
|
|
- do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
|
|
|
+
|
|
|
return EAX_EDX_VAL(val, low, high);
|
|
|
}
|
|
|
|
|
|
+static inline void notrace __wrmsr(unsigned int msr, u32 low, u32 high)
|
|
|
+{
|
|
|
+ asm volatile("1: wrmsr\n"
|
|
|
+ "2:\n"
|
|
|
+ _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_unsafe)
|
|
|
+ : : "c" (msr), "a"(low), "d" (high) : "memory");
|
|
|
+}
|
|
|
+
|
|
|
+static inline unsigned long long native_read_msr(unsigned int msr)
|
|
|
+{
|
|
|
+ unsigned long long val;
|
|
|
+
|
|
|
+ val = __rdmsr(msr);
|
|
|
+
|
|
|
+ if (msr_tracepoint_active(__tracepoint_read_msr))
|
|
|
+ do_trace_read_msr(msr, val, 0);
|
|
|
+
|
|
|
+ return val;
|
|
|
+}
|
|
|
+
|
|
|
static inline unsigned long long native_read_msr_safe(unsigned int msr,
|
|
|
int *err)
|
|
|
{
|
|
@@ -114,31 +140,16 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
|
|
|
return EAX_EDX_VAL(val, low, high);
|
|
|
}
|
|
|
|
|
|
-/* Can be uninlined because referenced by paravirt */
|
|
|
-static inline void notrace
|
|
|
-__native_write_msr_notrace(unsigned int msr, u32 low, u32 high)
|
|
|
-{
|
|
|
- asm volatile("1: wrmsr\n"
|
|
|
- "2:\n"
|
|
|
- _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_unsafe)
|
|
|
- : : "c" (msr), "a"(low), "d" (high) : "memory");
|
|
|
-}
|
|
|
-
|
|
|
/* Can be uninlined because referenced by paravirt */
|
|
|
static inline void notrace
|
|
|
native_write_msr(unsigned int msr, u32 low, u32 high)
|
|
|
{
|
|
|
- __native_write_msr_notrace(msr, low, high);
|
|
|
+ __wrmsr(msr, low, high);
|
|
|
+
|
|
|
if (msr_tracepoint_active(__tracepoint_write_msr))
|
|
|
do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
|
|
|
}
|
|
|
|
|
|
-static inline void
|
|
|
-wrmsr_notrace(unsigned int msr, u32 low, u32 high)
|
|
|
-{
|
|
|
- __native_write_msr_notrace(msr, low, high);
|
|
|
-}
|
|
|
-
|
|
|
/* Can be uninlined because referenced by paravirt */
|
|
|
static inline int notrace
|
|
|
native_write_msr_safe(unsigned int msr, u32 low, u32 high)
|