Skip to content

Commit

Permalink
Merge tag 'x86_core_for_v5.19_rc1' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/tip/tip

Pull core x86 updates from Borislav Petkov:

 - Remove all the code around GS switching on 32-bit now that it is not
   needed anymore

 - Other misc improvements

* tag 'x86_core_for_v5.19_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  bug: Use normal relative pointers in 'struct bug_entry'
  x86/nmi: Make register_nmi_handler() more robust
  x86/asm: Merge load_gs_index()
  x86/32: Remove lazy GS macros
  ELF: Remove elf_core_copy_kernel_regs()
  x86/32: Simplify ELF_CORE_COPY_REGS
  • Loading branch information
torvalds committed May 24, 2022
2 parents a13dc4d + 69505e3 commit de8ac81
Show file tree
Hide file tree
Showing 23 changed files with 61 additions and 88 deletions.
4 changes: 2 additions & 2 deletions arch/arm64/include/asm/asm-bug.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
14472: .string file; \
.popsection; \
\
.long 14472b - 14470b; \
.long 14472b - .; \
.short line;
#else
#define _BUGVERBOSE_LOCATION(file, line)
Expand All @@ -25,7 +25,7 @@
#define __BUG_ENTRY(flags) \
.pushsection __bug_table,"aw"; \
.align 2; \
14470: .long 14471f - 14470b; \
14470: .long 14471f - .; \
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
.short flags; \
.popsection; \
Expand Down
14 changes: 8 additions & 6 deletions arch/powerpc/include/asm/bug.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
#ifdef CONFIG_DEBUG_BUGVERBOSE
.macro __EMIT_BUG_ENTRY addr,file,line,flags
.section __bug_table,"aw"
5001: .4byte \addr - 5001b, 5002f - 5001b
5001: .4byte \addr - .
.4byte 5002f - .
.short \line, \flags
.org 5001b+BUG_ENTRY_SIZE
.previous
Expand All @@ -24,7 +25,7 @@
#else
.macro __EMIT_BUG_ENTRY addr,file,line,flags
.section __bug_table,"aw"
5001: .4byte \addr - 5001b
5001: .4byte \addr - .
.short \flags
.org 5001b+BUG_ENTRY_SIZE
.previous
Expand All @@ -49,15 +50,16 @@
#ifdef CONFIG_DEBUG_BUGVERBOSE
#define _EMIT_BUG_ENTRY \
".section __bug_table,\"aw\"\n" \
"2:\t.4byte 1b - 2b, %0 - 2b\n" \
"\t.short %1, %2\n" \
"2: .4byte 1b - .\n" \
" .4byte %0 - .\n" \
" .short %1, %2\n" \
".org 2b+%3\n" \
".previous\n"
#else
#define _EMIT_BUG_ENTRY \
".section __bug_table,\"aw\"\n" \
"2:\t.4byte 1b - 2b\n" \
"\t.short %2\n" \
"2: .4byte 1b - .\n" \
" .short %2\n" \
".org 2b+%3\n" \
".previous\n"
#endif
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/fadump.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ u32 *__init fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs)
* FIXME: How do i get PID? Do I really need it?
* prstatus.pr_pid = ????
*/
elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
elf_core_copy_regs(&prstatus.pr_reg, regs);
buf = append_elf_note(buf, CRASH_CORE_NOTE_NAME, NT_PRSTATUS,
&prstatus, sizeof(prstatus));
return buf;
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/powernv/opal-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static void __init fill_prstatus(struct elf_prstatus *prstatus, int pir,
struct pt_regs *regs)
{
memset(prstatus, 0, sizeof(struct elf_prstatus));
elf_core_copy_kernel_regs(&(prstatus->pr_reg), regs);
elf_core_copy_regs(&(prstatus->pr_reg), regs);

/*
* Overload PID with PIR value.
Expand Down
4 changes: 2 additions & 2 deletions arch/riscv/include/asm/bug.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
typedef u32 bug_insn_t;

#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
#define __BUG_ENTRY_ADDR RISCV_INT " 1b - 2b"
#define __BUG_ENTRY_FILE RISCV_INT " %0 - 2b"
#define __BUG_ENTRY_ADDR RISCV_INT " 1b - ."
#define __BUG_ENTRY_FILE RISCV_INT " %0 - ."
#else
#define __BUG_ENTRY_ADDR RISCV_PTR " 1b"
#define __BUG_ENTRY_FILE RISCV_PTR " %0"
Expand Down
5 changes: 3 additions & 2 deletions arch/s390/include/asm/bug.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"1: .asciz \""__FILE__"\"\n" \
".previous\n" \
".section __bug_table,\"awM\",@progbits,%2\n" \
"2: .long 0b-2b,1b-2b\n" \
"2: .long 0b-.\n" \
" .long 1b-.\n" \
" .short %0,%1\n" \
" .org 2b+%2\n" \
".previous\n" \
Expand All @@ -30,7 +31,7 @@
asm_inline volatile( \
"0: mc 0,0\n" \
".section __bug_table,\"awM\",@progbits,%1\n" \
"1: .long 0b-1b\n" \
"1: .long 0b-.\n" \
" .short %0\n" \
" .org 1b+%1\n" \
".previous\n" \
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/bug.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#ifdef CONFIG_X86_32
# define __BUG_REL(val) ".long " __stringify(val)
#else
# define __BUG_REL(val) ".long " __stringify(val) " - 2b"
# define __BUG_REL(val) ".long " __stringify(val) " - ."
#endif

#ifdef CONFIG_DEBUG_BUGVERBOSE
Expand Down
15 changes: 2 additions & 13 deletions arch/x86/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ extern unsigned int vdso32_enabled;
* now struct_user_regs, they are different)
*/

#define ELF_CORE_COPY_REGS_COMMON(pr_reg, regs) \
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
do { \
pr_reg[0] = regs->bx; \
pr_reg[1] = regs->cx; \
Expand All @@ -128,6 +128,7 @@ do { \
pr_reg[7] = regs->ds; \
pr_reg[8] = regs->es; \
pr_reg[9] = regs->fs; \
savesegment(gs, pr_reg[10]); \
pr_reg[11] = regs->orig_ax; \
pr_reg[12] = regs->ip; \
pr_reg[13] = regs->cs; \
Expand All @@ -136,18 +137,6 @@ do { \
pr_reg[16] = regs->ss; \
} while (0);

#define ELF_CORE_COPY_REGS(pr_reg, regs) \
do { \
ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
pr_reg[10] = get_user_gs(regs); \
} while (0);

#define ELF_CORE_COPY_KERNEL_REGS(pr_reg, regs) \
do { \
ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
savesegment(gs, pr_reg[10]); \
} while (0);

#define ELF_PLATFORM (utsname()->machine)
#define set_personality_64bit() do { } while (0)

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/include/asm/mmu_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ do { \
#ifdef CONFIG_X86_32
#define deactivate_mm(tsk, mm) \
do { \
lazy_load_gs(0); \
loadsegment(gs, 0); \
} while (0)
#else
#define deactivate_mm(tsk, mm) \
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/nmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct nmiaction {
#define register_nmi_handler(t, fn, fg, n, init...) \
({ \
static struct nmiaction init fn##_na = { \
.list = LIST_HEAD_INIT(fn##_na.list), \
.handler = (fn), \
.name = (n), \
.flags = (fg), \
Expand Down
12 changes: 0 additions & 12 deletions arch/x86/include/asm/segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,18 +350,6 @@ static inline void __loadsegment_fs(unsigned short value)
#define savesegment(seg, value) \
asm("mov %%" #seg ",%0":"=r" (value) : : "memory")

/*
* x86-32 user GS accessors. This is ugly and could do with some cleaning up.
*/
#ifdef CONFIG_X86_32
# define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; })
# define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v))
# define task_user_gs(tsk) ((tsk)->thread.gs)
# define lazy_save_gs(v) savesegment(gs, (v))
# define lazy_load_gs(v) loadsegment(gs, (v))
# define load_gs_index(v) loadsegment(gs, (v))
#endif /* X86_32 */

#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */

Expand Down
7 changes: 4 additions & 3 deletions arch/x86/include/asm/special_insns.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,15 @@ static inline void wbinvd(void)
native_wbinvd();
}

#ifdef CONFIG_X86_64

static inline void load_gs_index(unsigned int selector)
{
#ifdef CONFIG_X86_64
native_load_gs_index(selector);
}

#else
loadsegment(gs, selector);
#endif
}

#endif /* CONFIG_PARAVIRT_XXL */

Expand Down
12 changes: 8 additions & 4 deletions arch/x86/kernel/nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action)
struct nmi_desc *desc = nmi_to_desc(type);
unsigned long flags;

if (!action->handler)
if (WARN_ON_ONCE(!action->handler || !list_empty(&action->list)))
return -EINVAL;

raw_spin_lock_irqsave(&desc->lock, flags);
Expand All @@ -177,7 +177,7 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action)
list_add_rcu(&action->list, &desc->head);
else
list_add_tail_rcu(&action->list, &desc->head);

raw_spin_unlock_irqrestore(&desc->lock, flags);
return 0;
}
Expand All @@ -186,7 +186,7 @@ EXPORT_SYMBOL(__register_nmi_handler);
void unregister_nmi_handler(unsigned int type, const char *name)
{
struct nmi_desc *desc = nmi_to_desc(type);
struct nmiaction *n;
struct nmiaction *n, *found = NULL;
unsigned long flags;

raw_spin_lock_irqsave(&desc->lock, flags);
Expand All @@ -200,12 +200,16 @@ void unregister_nmi_handler(unsigned int type, const char *name)
WARN(in_nmi(),
"Trying to free NMI (%s) from NMI context!\n", n->name);
list_del_rcu(&n->list);
found = n;
break;
}
}

raw_spin_unlock_irqrestore(&desc->lock, flags);
synchronize_rcu();
if (found) {
synchronize_rcu();
INIT_LIST_HEAD(&found->list);
}
}
EXPORT_SYMBOL_GPL(unregister_nmi_handler);

Expand Down
5 changes: 1 addition & 4 deletions arch/x86/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
savesegment(ds, p->thread.ds);
#else
p->thread.sp0 = (unsigned long) (childregs + 1);
savesegment(gs, p->thread.gs);
/*
* Clear all status flags including IF and set fixed bit. 64bit
* does not have this initialization as the frame does not contain
Expand Down Expand Up @@ -192,10 +193,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
if (sp)
childregs->sp = sp;

#ifdef CONFIG_X86_32
task_user_gs(p) = get_user_gs(current_pt_regs());
#endif

if (unlikely(p->flags & PF_IO_WORKER)) {
/*
* An IO thread is a user space thread, but it doesn't
Expand Down
11 changes: 4 additions & 7 deletions arch/x86/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
unsigned long d0, d1, d2, d3, d6, d7;
unsigned short gs;

if (user_mode(regs))
gs = get_user_gs(regs);
else
savesegment(gs, gs);
savesegment(gs, gs);

show_ip(regs, log_lvl);

Expand Down Expand Up @@ -114,7 +111,7 @@ void release_thread(struct task_struct *dead_task)
void
start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
{
set_user_gs(regs, 0);
loadsegment(gs, 0);
regs->fs = 0;
regs->ds = __USER_DS;
regs->es = __USER_DS;
Expand Down Expand Up @@ -177,7 +174,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
* used %fs or %gs (it does not today), or if the kernel is
* running inside of a hypervisor layer.
*/
lazy_save_gs(prev->gs);
savesegment(gs, prev->gs);

/*
* Load the per-thread Thread-Local Storage descriptor.
Expand Down Expand Up @@ -208,7 +205,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
* Restore %gs if needed (which is common)
*/
if (prev->gs | next->gs)
lazy_load_gs(next->gs);
loadsegment(gs, next->gs);

this_cpu_write(current_task, next_p);

Expand Down
6 changes: 3 additions & 3 deletions arch/x86/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ static u16 get_segment_reg(struct task_struct *task, unsigned long offset)
retval = *pt_regs_access(task_pt_regs(task), offset);
else {
if (task == current)
retval = get_user_gs(task_pt_regs(task));
savesegment(gs, retval);
else
retval = task_user_gs(task);
retval = task->thread.gs;
}
return retval;
}
Expand Down Expand Up @@ -210,7 +210,7 @@ static int set_segment_reg(struct task_struct *task,
break;

case offsetof(struct user_regs_struct, gs):
task_user_gs(task) = value;
task->thread.gs = value;
}

return 0;
Expand Down
8 changes: 5 additions & 3 deletions arch/x86/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static bool restore_sigcontext(struct pt_regs *regs,
return false;

#ifdef CONFIG_X86_32
set_user_gs(regs, sc.gs);
loadsegment(gs, sc.gs);
regs->fs = sc.fs;
regs->es = sc.es;
regs->ds = sc.ds;
Expand Down Expand Up @@ -146,8 +146,10 @@ __unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
struct pt_regs *regs, unsigned long mask)
{
#ifdef CONFIG_X86_32
unsafe_put_user(get_user_gs(regs),
(unsigned int __user *)&sc->gs, Efault);
unsigned int gs;
savesegment(gs, gs);

unsafe_put_user(gs, (unsigned int __user *)&sc->gs, Efault);
unsafe_put_user(regs->fs, (unsigned int __user *)&sc->fs, Efault);
unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault);
unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault);
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/vm86_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval)

memcpy(&regs->pt, &vm86->regs32, sizeof(struct pt_regs));

lazy_load_gs(vm86->regs32.gs);
loadsegment(gs, vm86->regs32.gs);

regs->pt.ax = retval;
return;
Expand Down Expand Up @@ -325,7 +325,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
* Save old state
*/
vm86->saved_sp0 = tsk->thread.sp0;
lazy_save_gs(vm86->regs32.gs);
savesegment(gs, vm86->regs32.gs);

/* make room for real-mode segments */
preempt_disable();
Expand Down
5 changes: 3 additions & 2 deletions arch/x86/lib/insn-eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,9 @@ static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)
*/
static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
{
#ifdef CONFIG_X86_64
unsigned short sel;

#ifdef CONFIG_X86_64
switch (seg_reg_idx) {
case INAT_SEG_REG_IGNORE:
return 0;
Expand Down Expand Up @@ -402,7 +402,8 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
case INAT_SEG_REG_FS:
return (unsigned short)(regs->fs & 0xffff);
case INAT_SEG_REG_GS:
return get_user_gs(regs);
savesegment(gs, sel);
return sel;
case INAT_SEG_REG_IGNORE:
default:
return -EINVAL;
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/math-emu/get_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ static long pm_address(u_char FPU_modrm, u_char segment,
switch (segment) {
case PREFIX_GS_ - 1:
/* user gs handling can be lazy, use special accessors */
addr->selector = get_user_gs(FPU_info->regs);
savesegment(gs, addr->selector);
break;
default:
addr->selector = PM_REG_(segment);
Expand Down
Loading

0 comments on commit de8ac81

Please sign in to comment.