lkml.org 
[lkml]   [2022]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 149/201] x86/msr: Remove .fixup usage
    Date
    From: Peter Zijlstra <peterz@infradead.org>

    [ Upstream commit d52a7344bdfa9c3442d3f86fb3501d9343726c76 ]

    Rework the MSR accessors to remove .fixup usage. Add two new extable
    types (to the 4 already existing msr ones) using the new register
    infrastructure to record which register should get the error value.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
    Link: https://lore.kernel.org/r/20211110101325.364084212@infradead.org
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/x86/include/asm/extable_fixup_types.h | 23 +++++-----
    arch/x86/include/asm/msr.h | 26 ++++-------
    arch/x86/mm/extable.c | 51 ++++++++++++----------
    3 files changed, 47 insertions(+), 53 deletions(-)

    diff --git a/arch/x86/include/asm/extable_fixup_types.h b/arch/x86/include/asm/extable_fixup_types.h
    index 944f8329022a..9d597fe1017d 100644
    --- a/arch/x86/include/asm/extable_fixup_types.h
    +++ b/arch/x86/include/asm/extable_fixup_types.h
    @@ -32,17 +32,16 @@
    #define EX_TYPE_COPY 4
    #define EX_TYPE_CLEAR_FS 5
    #define EX_TYPE_FPU_RESTORE 6
    -#define EX_TYPE_WRMSR 7
    -#define EX_TYPE_RDMSR 8
    -#define EX_TYPE_BPF 9
    -
    -#define EX_TYPE_WRMSR_IN_MCE 10
    -#define EX_TYPE_RDMSR_IN_MCE 11
    -
    -#define EX_TYPE_DEFAULT_MCE_SAFE 12
    -#define EX_TYPE_FAULT_MCE_SAFE 13
    -
    -#define EX_TYPE_POP_ZERO 14
    -#define EX_TYPE_IMM_REG 15 /* reg := (long)imm */
    +#define EX_TYPE_BPF 7
    +#define EX_TYPE_WRMSR 8
    +#define EX_TYPE_RDMSR 9
    +#define EX_TYPE_WRMSR_SAFE 10 /* reg := -EIO */
    +#define EX_TYPE_RDMSR_SAFE 11 /* reg := -EIO */
    +#define EX_TYPE_WRMSR_IN_MCE 12
    +#define EX_TYPE_RDMSR_IN_MCE 13
    +#define EX_TYPE_DEFAULT_MCE_SAFE 14
    +#define EX_TYPE_FAULT_MCE_SAFE 15
    +#define EX_TYPE_POP_ZERO 16
    +#define EX_TYPE_IMM_REG 17 /* reg := (long)imm */

    #endif
    diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
    index 6b52182e178a..d42e6c6b47b1 100644
    --- a/arch/x86/include/asm/msr.h
    +++ b/arch/x86/include/asm/msr.h
    @@ -137,17 +137,11 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
    {
    DECLARE_ARGS(val, low, high);

    - asm volatile("2: rdmsr ; xor %[err],%[err]\n"
    - "1:\n\t"
    - ".section .fixup,\"ax\"\n\t"
    - "3: mov %[fault],%[err]\n\t"
    - "xorl %%eax, %%eax\n\t"
    - "xorl %%edx, %%edx\n\t"
    - "jmp 1b\n\t"
    - ".previous\n\t"
    - _ASM_EXTABLE(2b, 3b)
    + asm volatile("1: rdmsr ; xor %[err],%[err]\n"
    + "2:\n\t"
    + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_RDMSR_SAFE, %[err])
    : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
    - : "c" (msr), [fault] "i" (-EIO));
    + : "c" (msr));
    if (tracepoint_enabled(read_msr))
    do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
    return EAX_EDX_VAL(val, low, high);
    @@ -169,15 +163,11 @@ native_write_msr_safe(unsigned int msr, u32 low, u32 high)
    {
    int err;

    - asm volatile("2: wrmsr ; xor %[err],%[err]\n"
    - "1:\n\t"
    - ".section .fixup,\"ax\"\n\t"
    - "3: mov %[fault],%[err] ; jmp 1b\n\t"
    - ".previous\n\t"
    - _ASM_EXTABLE(2b, 3b)
    + asm volatile("1: wrmsr ; xor %[err],%[err]\n"
    + "2:\n\t"
    + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_WRMSR_SAFE, %[err])
    : [err] "=a" (err)
    - : "c" (msr), "0" (low), "d" (high),
    - [fault] "i" (-EIO)
    + : "c" (msr), "0" (low), "d" (high)
    : "memory");
    if (tracepoint_enabled(write_msr))
    do_trace_write_msr(msr, ((u64)high << 32 | low), err);
    diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
    index 251732113624..1c558f8e8c07 100644
    --- a/arch/x86/mm/extable.c
    +++ b/arch/x86/mm/extable.c
    @@ -83,28 +83,29 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup,
    return ex_handler_fault(fixup, regs, trapnr);
    }

    -static bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
    - struct pt_regs *regs)
    +static bool ex_handler_msr(const struct exception_table_entry *fixup,
    + struct pt_regs *regs, bool wrmsr, bool safe, int reg)
    {
    - if (pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
    + if (!safe && wrmsr &&
    + pr_warn_once("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))
    + show_stack_regs(regs);
    +
    + if (!safe && !wrmsr &&
    + pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
    (unsigned int)regs->cx, regs->ip, (void *)regs->ip))
    show_stack_regs(regs);

    - /* Pretend that the read succeeded and returned 0. */
    - regs->ax = 0;
    - regs->dx = 0;
    - return ex_handler_default(fixup, regs);
    -}
    + if (!wrmsr) {
    + /* Pretend that the read succeeded and returned 0. */
    + regs->ax = 0;
    + regs->dx = 0;
    + }

    -static bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
    - struct pt_regs *regs)
    -{
    - if (pr_warn_once("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))
    - show_stack_regs(regs);
    + if (safe)
    + *pt_regs_nr(regs, reg) = -EIO;

    - /* Pretend that the write succeeded. */
    return ex_handler_default(fixup, regs);
    }

    @@ -186,18 +187,22 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
    return ex_handler_clear_fs(e, regs);
    case EX_TYPE_FPU_RESTORE:
    return ex_handler_fprestore(e, regs);
    - case EX_TYPE_RDMSR:
    - return ex_handler_rdmsr_unsafe(e, regs);
    - case EX_TYPE_WRMSR:
    - return ex_handler_wrmsr_unsafe(e, regs);
    case EX_TYPE_BPF:
    return ex_handler_bpf(e, regs);
    - case EX_TYPE_RDMSR_IN_MCE:
    - ex_handler_msr_mce(regs, false);
    - break;
    + case EX_TYPE_WRMSR:
    + return ex_handler_msr(e, regs, true, false, reg);
    + case EX_TYPE_RDMSR:
    + return ex_handler_msr(e, regs, false, false, reg);
    + case EX_TYPE_WRMSR_SAFE:
    + return ex_handler_msr(e, regs, true, true, reg);
    + case EX_TYPE_RDMSR_SAFE:
    + return ex_handler_msr(e, regs, false, true, reg);
    case EX_TYPE_WRMSR_IN_MCE:
    ex_handler_msr_mce(regs, true);
    break;
    + case EX_TYPE_RDMSR_IN_MCE:
    + ex_handler_msr_mce(regs, false);
    + break;
    case EX_TYPE_POP_ZERO:
    return ex_handler_pop_zero(e, regs);
    case EX_TYPE_IMM_REG:
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-07-27 19:19    [W:4.061 / U:0.264 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site