[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH v2 19/34] x86/extable: Add support for immediate form MSR instructions



Signed-off-by: Xin Li (Intel) <xin@xxxxxxxxx>
---
 arch/x86/include/asm/msr.h | 18 ++++++++++++++++++
 arch/x86/mm/extable.c      | 39 +++++++++++++++++++++++++++++++++-----
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index c955339be9c9..8f7a67b1c61c 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -78,6 +78,24 @@ static inline void do_trace_rdpmc(u32 msr, u64 val, int 
failed) {}
 extern u64 xen_read_pmc(int counter);
 #endif
 
+/*
+ * Called only from an MSR fault handler, the instruction pointer points to
+ * the MSR access instruction that caused the fault.
+ */
+static __always_inline bool is_msr_imm_insn(void *ip)
+{
+       /*
+        * A full decoder for immediate form MSR instructions appears excessive.
+        */
+#ifdef CONFIG_X86_64
+       const u8 msr_imm_insn_prefix[] = { 0xc4, 0xe7 };
+
+       return !memcmp(ip, msr_imm_insn_prefix, sizeof(msr_imm_insn_prefix));
+#else
+       return false;
+#endif
+}
+
 /*
  * __rdmsr() and __wrmsr() are the two primitives which are the bare minimum 
MSR
  * accessors and should not have any tracing or other functionality 
piggybacking
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index bf8dab18be97..f1743babafc8 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -167,23 +167,52 @@ static bool ex_handler_uaccess(const struct 
exception_table_entry *fixup,
 static bool ex_handler_msr(const struct exception_table_entry *fixup,
                           struct pt_regs *regs, bool wrmsr, bool safe, int reg)
 {
+       bool imm_insn = is_msr_imm_insn((void *)regs->ip);
+       u32 msr;
+
+       if (imm_insn)
+               /*
+                * The 32-bit immediate specifying a MSR is encoded into
+                * byte 5 ~ 8 of an immediate form MSR instruction.
+                */
+               msr = *(u32 *)(regs->ip + 5);
+       else
+               msr = (u32)regs->cx;
+
        if (__ONCE_LITE_IF(!safe && wrmsr)) {
-               pr_warn("unchecked MSR access error: WRMSR to 0x%x (tried to 
write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
-                       (unsigned int)regs->cx, (unsigned int)regs->dx,
-                       (unsigned int)regs->ax,  regs->ip, (void *)regs->ip);
+               /*
+                * To maintain consistency with existing RDMSR and WRMSR(NS) 
instructions,
+                * the register operand for immediate form MSR instructions is 
ALWAYS
+                * encoded as RAX in <asm/msr.h> for reading or writing the MSR 
value.
+                */
+               u64 msr_val = regs->ax;
+
+               if (!imm_insn) {
+                       /*
+                        * On processors that support the Intel 64 
architecture, the
+                        * high-order 32 bits of each of RAX and RDX are 
ignored.
+                        */
+                       msr_val &= 0xffffffff;
+                       msr_val |= (u64)regs->dx << 32;
+               }
+
+               pr_warn("unchecked MSR access error: WRMSR to 0x%x (tried to 
write 0x%016llx) at rIP: 0x%lx (%pS)\n",
+                       msr, msr_val, regs->ip, (void *)regs->ip);
                show_stack_regs(regs);
        }
 
        if (__ONCE_LITE_IF(!safe && !wrmsr)) {
                pr_warn("unchecked MSR access error: RDMSR from 0x%x at rIP: 
0x%lx (%pS)\n",
-                       (unsigned int)regs->cx, regs->ip, (void *)regs->ip);
+                       msr, regs->ip, (void *)regs->ip);
                show_stack_regs(regs);
        }
 
        if (!wrmsr) {
                /* Pretend that the read succeeded and returned 0. */
                regs->ax = 0;
-               regs->dx = 0;
+
+               if (!imm_insn)
+                       regs->dx = 0;
        }
 
        if (safe)
-- 
2.49.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.