- Remove all the code around GS switching on 32-bit now that it is not
needed anymore - Other misc improvements -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmKLp74ACgkQEsHwGGHe VUpqrhAAgNdNw/vNTTzeOH5ZSNxyIoTQapmrSNev0cXRW4tV2hxuYSa2wPZPJZXx aYhnFxwL7rVy0er7jG/5KaOyzHmrh6PcmqgFdPVo8+yVrfcsPIUqg/4L5peFZh7T ETV2pvFIiB4njkL/pR3mU5uAtTjyO89tD/LclKmc4ndv19vI8maj+k/dCDOnNnEz m4wJMXYWh4bG47/izU5TcTYU7ttTLEiVQ/mC5kEuj7PQeUR0kXKvvLo4rX+lOI2v dQRHgHg/qoNM7uVLd7vV/YdMWwcHchmKG5Y7+a/ogdlwR7a/X9e+lklFSeuxNvyH 8dOHIyzcb6lKTijpqhisZ3o9150ax3Q5FlSWuE3F/9Rcuc1T5eY82kTW2RTOTdV9 xsjob4y+hlpsUfuImupxJLHn685xsYAdqyiG/SPkcnJL++tNBlWiGHX9NqXF5cgw bq4/94Aouxevl0OBxnFBeoQOJvOnf60OY3LHcYR78yEEJyi4iWsC0/TEmD+9IE+r EpC1wz9bHCYbSwZ+yv8u2tNPd/rKxdspPL/6SxT9a+WAVrOZbQAN3VmlOIon6W9O bW5ye6suqBbl/Q1FACVU1xxSNjLTJUTFsB1X3QKGm8E+Kr7/zD1ZtT0WQNvyLMfT p/I4VRcdIxV3eDiYqeTfJ3sTS7IjKHSaZVBnpkZvRh869mMdqCg= =CfX1 -----END PGP SIGNATURE----- Merge tag 'x86_core_for_v5.19_rc1' of git://git.kernel.org/pub/scm/linux/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
This commit is contained in:
commit
de8ac81747
|
@ -14,7 +14,7 @@
|
||||||
14472: .string file; \
|
14472: .string file; \
|
||||||
.popsection; \
|
.popsection; \
|
||||||
\
|
\
|
||||||
.long 14472b - 14470b; \
|
.long 14472b - .; \
|
||||||
.short line;
|
.short line;
|
||||||
#else
|
#else
|
||||||
#define _BUGVERBOSE_LOCATION(file, line)
|
#define _BUGVERBOSE_LOCATION(file, line)
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
#define __BUG_ENTRY(flags) \
|
#define __BUG_ENTRY(flags) \
|
||||||
.pushsection __bug_table,"aw"; \
|
.pushsection __bug_table,"aw"; \
|
||||||
.align 2; \
|
.align 2; \
|
||||||
14470: .long 14471f - 14470b; \
|
14470: .long 14471f - .; \
|
||||||
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
|
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
|
||||||
.short flags; \
|
.short flags; \
|
||||||
.popsection; \
|
.popsection; \
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||||
.macro __EMIT_BUG_ENTRY addr,file,line,flags
|
.macro __EMIT_BUG_ENTRY addr,file,line,flags
|
||||||
.section __bug_table,"aw"
|
.section __bug_table,"aw"
|
||||||
5001: .4byte \addr - 5001b, 5002f - 5001b
|
5001: .4byte \addr - .
|
||||||
|
.4byte 5002f - .
|
||||||
.short \line, \flags
|
.short \line, \flags
|
||||||
.org 5001b+BUG_ENTRY_SIZE
|
.org 5001b+BUG_ENTRY_SIZE
|
||||||
.previous
|
.previous
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
#else
|
#else
|
||||||
.macro __EMIT_BUG_ENTRY addr,file,line,flags
|
.macro __EMIT_BUG_ENTRY addr,file,line,flags
|
||||||
.section __bug_table,"aw"
|
.section __bug_table,"aw"
|
||||||
5001: .4byte \addr - 5001b
|
5001: .4byte \addr - .
|
||||||
.short \flags
|
.short \flags
|
||||||
.org 5001b+BUG_ENTRY_SIZE
|
.org 5001b+BUG_ENTRY_SIZE
|
||||||
.previous
|
.previous
|
||||||
|
@ -49,15 +50,16 @@
|
||||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||||
#define _EMIT_BUG_ENTRY \
|
#define _EMIT_BUG_ENTRY \
|
||||||
".section __bug_table,\"aw\"\n" \
|
".section __bug_table,\"aw\"\n" \
|
||||||
"2:\t.4byte 1b - 2b, %0 - 2b\n" \
|
"2: .4byte 1b - .\n" \
|
||||||
"\t.short %1, %2\n" \
|
" .4byte %0 - .\n" \
|
||||||
|
" .short %1, %2\n" \
|
||||||
".org 2b+%3\n" \
|
".org 2b+%3\n" \
|
||||||
".previous\n"
|
".previous\n"
|
||||||
#else
|
#else
|
||||||
#define _EMIT_BUG_ENTRY \
|
#define _EMIT_BUG_ENTRY \
|
||||||
".section __bug_table,\"aw\"\n" \
|
".section __bug_table,\"aw\"\n" \
|
||||||
"2:\t.4byte 1b - 2b\n" \
|
"2: .4byte 1b - .\n" \
|
||||||
"\t.short %2\n" \
|
" .short %2\n" \
|
||||||
".org 2b+%3\n" \
|
".org 2b+%3\n" \
|
||||||
".previous\n"
|
".previous\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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?
|
* FIXME: How do i get PID? Do I really need it?
|
||||||
* prstatus.pr_pid = ????
|
* 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,
|
buf = append_elf_note(buf, CRASH_CORE_NOTE_NAME, NT_PRSTATUS,
|
||||||
&prstatus, sizeof(prstatus));
|
&prstatus, sizeof(prstatus));
|
||||||
return buf;
|
return buf;
|
||||||
|
|
|
@ -112,7 +112,7 @@ static void __init fill_prstatus(struct elf_prstatus *prstatus, int pir,
|
||||||
struct pt_regs *regs)
|
struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
memset(prstatus, 0, sizeof(struct elf_prstatus));
|
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.
|
* Overload PID with PIR value.
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
typedef u32 bug_insn_t;
|
typedef u32 bug_insn_t;
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
||||||
#define __BUG_ENTRY_ADDR RISCV_INT " 1b - 2b"
|
#define __BUG_ENTRY_ADDR RISCV_INT " 1b - ."
|
||||||
#define __BUG_ENTRY_FILE RISCV_INT " %0 - 2b"
|
#define __BUG_ENTRY_FILE RISCV_INT " %0 - ."
|
||||||
#else
|
#else
|
||||||
#define __BUG_ENTRY_ADDR RISCV_PTR " 1b"
|
#define __BUG_ENTRY_ADDR RISCV_PTR " 1b"
|
||||||
#define __BUG_ENTRY_FILE RISCV_PTR " %0"
|
#define __BUG_ENTRY_FILE RISCV_PTR " %0"
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"1: .asciz \""__FILE__"\"\n" \
|
"1: .asciz \""__FILE__"\"\n" \
|
||||||
".previous\n" \
|
".previous\n" \
|
||||||
".section __bug_table,\"awM\",@progbits,%2\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" \
|
" .short %0,%1\n" \
|
||||||
" .org 2b+%2\n" \
|
" .org 2b+%2\n" \
|
||||||
".previous\n" \
|
".previous\n" \
|
||||||
|
@ -30,7 +31,7 @@
|
||||||
asm_inline volatile( \
|
asm_inline volatile( \
|
||||||
"0: mc 0,0\n" \
|
"0: mc 0,0\n" \
|
||||||
".section __bug_table,\"awM\",@progbits,%1\n" \
|
".section __bug_table,\"awM\",@progbits,%1\n" \
|
||||||
"1: .long 0b-1b\n" \
|
"1: .long 0b-.\n" \
|
||||||
" .short %0\n" \
|
" .short %0\n" \
|
||||||
" .org 1b+%1\n" \
|
" .org 1b+%1\n" \
|
||||||
".previous\n" \
|
".previous\n" \
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
# define __BUG_REL(val) ".long " __stringify(val)
|
# define __BUG_REL(val) ".long " __stringify(val)
|
||||||
#else
|
#else
|
||||||
# define __BUG_REL(val) ".long " __stringify(val) " - 2b"
|
# define __BUG_REL(val) ".long " __stringify(val) " - ."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||||
|
|
|
@ -116,7 +116,7 @@ extern unsigned int vdso32_enabled;
|
||||||
* now struct_user_regs, they are different)
|
* 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 { \
|
do { \
|
||||||
pr_reg[0] = regs->bx; \
|
pr_reg[0] = regs->bx; \
|
||||||
pr_reg[1] = regs->cx; \
|
pr_reg[1] = regs->cx; \
|
||||||
|
@ -128,6 +128,7 @@ do { \
|
||||||
pr_reg[7] = regs->ds; \
|
pr_reg[7] = regs->ds; \
|
||||||
pr_reg[8] = regs->es; \
|
pr_reg[8] = regs->es; \
|
||||||
pr_reg[9] = regs->fs; \
|
pr_reg[9] = regs->fs; \
|
||||||
|
savesegment(gs, pr_reg[10]); \
|
||||||
pr_reg[11] = regs->orig_ax; \
|
pr_reg[11] = regs->orig_ax; \
|
||||||
pr_reg[12] = regs->ip; \
|
pr_reg[12] = regs->ip; \
|
||||||
pr_reg[13] = regs->cs; \
|
pr_reg[13] = regs->cs; \
|
||||||
|
@ -136,18 +137,6 @@ do { \
|
||||||
pr_reg[16] = regs->ss; \
|
pr_reg[16] = regs->ss; \
|
||||||
} while (0);
|
} 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 ELF_PLATFORM (utsname()->machine)
|
||||||
#define set_personality_64bit() do { } while (0)
|
#define set_personality_64bit() do { } while (0)
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ do { \
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
#define deactivate_mm(tsk, mm) \
|
#define deactivate_mm(tsk, mm) \
|
||||||
do { \
|
do { \
|
||||||
lazy_load_gs(0); \
|
loadsegment(gs, 0); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define deactivate_mm(tsk, mm) \
|
#define deactivate_mm(tsk, mm) \
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct nmiaction {
|
||||||
#define register_nmi_handler(t, fn, fg, n, init...) \
|
#define register_nmi_handler(t, fn, fg, n, init...) \
|
||||||
({ \
|
({ \
|
||||||
static struct nmiaction init fn##_na = { \
|
static struct nmiaction init fn##_na = { \
|
||||||
|
.list = LIST_HEAD_INIT(fn##_na.list), \
|
||||||
.handler = (fn), \
|
.handler = (fn), \
|
||||||
.name = (n), \
|
.name = (n), \
|
||||||
.flags = (fg), \
|
.flags = (fg), \
|
||||||
|
|
|
@ -350,18 +350,6 @@ static inline void __loadsegment_fs(unsigned short value)
|
||||||
#define savesegment(seg, value) \
|
#define savesegment(seg, value) \
|
||||||
asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
|
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 /* !__ASSEMBLY__ */
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
|
|
@ -184,14 +184,15 @@ static inline void wbinvd(void)
|
||||||
native_wbinvd();
|
native_wbinvd();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
|
|
||||||
static inline void load_gs_index(unsigned int selector)
|
static inline void load_gs_index(unsigned int selector)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
native_load_gs_index(selector);
|
native_load_gs_index(selector);
|
||||||
}
|
#else
|
||||||
|
loadsegment(gs, selector);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PARAVIRT_XXL */
|
#endif /* CONFIG_PARAVIRT_XXL */
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action)
|
||||||
struct nmi_desc *desc = nmi_to_desc(type);
|
struct nmi_desc *desc = nmi_to_desc(type);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!action->handler)
|
if (WARN_ON_ONCE(!action->handler || !list_empty(&action->list)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||||
|
@ -177,7 +177,7 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action)
|
||||||
list_add_rcu(&action->list, &desc->head);
|
list_add_rcu(&action->list, &desc->head);
|
||||||
else
|
else
|
||||||
list_add_tail_rcu(&action->list, &desc->head);
|
list_add_tail_rcu(&action->list, &desc->head);
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ EXPORT_SYMBOL(__register_nmi_handler);
|
||||||
void unregister_nmi_handler(unsigned int type, const char *name)
|
void unregister_nmi_handler(unsigned int type, const char *name)
|
||||||
{
|
{
|
||||||
struct nmi_desc *desc = nmi_to_desc(type);
|
struct nmi_desc *desc = nmi_to_desc(type);
|
||||||
struct nmiaction *n;
|
struct nmiaction *n, *found = NULL;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&desc->lock, flags);
|
raw_spin_lock_irqsave(&desc->lock, flags);
|
||||||
|
@ -200,12 +200,16 @@ void unregister_nmi_handler(unsigned int type, const char *name)
|
||||||
WARN(in_nmi(),
|
WARN(in_nmi(),
|
||||||
"Trying to free NMI (%s) from NMI context!\n", n->name);
|
"Trying to free NMI (%s) from NMI context!\n", n->name);
|
||||||
list_del_rcu(&n->list);
|
list_del_rcu(&n->list);
|
||||||
|
found = n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
||||||
synchronize_rcu();
|
if (found) {
|
||||||
|
synchronize_rcu();
|
||||||
|
INIT_LIST_HEAD(&found->list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(unregister_nmi_handler);
|
EXPORT_SYMBOL_GPL(unregister_nmi_handler);
|
||||||
|
|
||||||
|
|
|
@ -161,6 +161,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
|
||||||
savesegment(ds, p->thread.ds);
|
savesegment(ds, p->thread.ds);
|
||||||
#else
|
#else
|
||||||
p->thread.sp0 = (unsigned long) (childregs + 1);
|
p->thread.sp0 = (unsigned long) (childregs + 1);
|
||||||
|
savesegment(gs, p->thread.gs);
|
||||||
/*
|
/*
|
||||||
* Clear all status flags including IF and set fixed bit. 64bit
|
* Clear all status flags including IF and set fixed bit. 64bit
|
||||||
* does not have this initialization as the frame does not contain
|
* does not have this initialization as the frame does not contain
|
||||||
|
@ -192,10 +193,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
|
||||||
if (sp)
|
if (sp)
|
||||||
childregs->sp = 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)) {
|
if (unlikely(p->flags & PF_IO_WORKER)) {
|
||||||
/*
|
/*
|
||||||
* An IO thread is a user space thread, but it doesn't
|
* An IO thread is a user space thread, but it doesn't
|
||||||
|
|
|
@ -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 long d0, d1, d2, d3, d6, d7;
|
||||||
unsigned short gs;
|
unsigned short gs;
|
||||||
|
|
||||||
if (user_mode(regs))
|
savesegment(gs, gs);
|
||||||
gs = get_user_gs(regs);
|
|
||||||
else
|
|
||||||
savesegment(gs, gs);
|
|
||||||
|
|
||||||
show_ip(regs, log_lvl);
|
show_ip(regs, log_lvl);
|
||||||
|
|
||||||
|
@ -114,7 +111,7 @@ void release_thread(struct task_struct *dead_task)
|
||||||
void
|
void
|
||||||
start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
|
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->fs = 0;
|
||||||
regs->ds = __USER_DS;
|
regs->ds = __USER_DS;
|
||||||
regs->es = __USER_DS;
|
regs->es = __USER_DS;
|
||||||
|
@ -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
|
* used %fs or %gs (it does not today), or if the kernel is
|
||||||
* running inside of a hypervisor layer.
|
* running inside of a hypervisor layer.
|
||||||
*/
|
*/
|
||||||
lazy_save_gs(prev->gs);
|
savesegment(gs, prev->gs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the per-thread Thread-Local Storage descriptor.
|
* Load the per-thread Thread-Local Storage descriptor.
|
||||||
|
@ -208,7 +205,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
||||||
* Restore %gs if needed (which is common)
|
* Restore %gs if needed (which is common)
|
||||||
*/
|
*/
|
||||||
if (prev->gs | next->gs)
|
if (prev->gs | next->gs)
|
||||||
lazy_load_gs(next->gs);
|
loadsegment(gs, next->gs);
|
||||||
|
|
||||||
this_cpu_write(current_task, next_p);
|
this_cpu_write(current_task, next_p);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
retval = *pt_regs_access(task_pt_regs(task), offset);
|
||||||
else {
|
else {
|
||||||
if (task == current)
|
if (task == current)
|
||||||
retval = get_user_gs(task_pt_regs(task));
|
savesegment(gs, retval);
|
||||||
else
|
else
|
||||||
retval = task_user_gs(task);
|
retval = task->thread.gs;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ static int set_segment_reg(struct task_struct *task,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case offsetof(struct user_regs_struct, gs):
|
case offsetof(struct user_regs_struct, gs):
|
||||||
task_user_gs(task) = value;
|
task->thread.gs = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -93,7 +93,7 @@ static bool restore_sigcontext(struct pt_regs *regs,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
set_user_gs(regs, sc.gs);
|
loadsegment(gs, sc.gs);
|
||||||
regs->fs = sc.fs;
|
regs->fs = sc.fs;
|
||||||
regs->es = sc.es;
|
regs->es = sc.es;
|
||||||
regs->ds = sc.ds;
|
regs->ds = sc.ds;
|
||||||
|
@ -146,8 +146,10 @@ __unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
|
||||||
struct pt_regs *regs, unsigned long mask)
|
struct pt_regs *regs, unsigned long mask)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
unsafe_put_user(get_user_gs(regs),
|
unsigned int gs;
|
||||||
(unsigned int __user *)&sc->gs, Efault);
|
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->fs, (unsigned int __user *)&sc->fs, Efault);
|
||||||
unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault);
|
unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault);
|
||||||
unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault);
|
unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault);
|
||||||
|
|
|
@ -151,7 +151,7 @@ exit_vm86:
|
||||||
|
|
||||||
memcpy(®s->pt, &vm86->regs32, sizeof(struct pt_regs));
|
memcpy(®s->pt, &vm86->regs32, sizeof(struct pt_regs));
|
||||||
|
|
||||||
lazy_load_gs(vm86->regs32.gs);
|
loadsegment(gs, vm86->regs32.gs);
|
||||||
|
|
||||||
regs->pt.ax = retval;
|
regs->pt.ax = retval;
|
||||||
return;
|
return;
|
||||||
|
@ -325,7 +325,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
|
||||||
* Save old state
|
* Save old state
|
||||||
*/
|
*/
|
||||||
vm86->saved_sp0 = tsk->thread.sp0;
|
vm86->saved_sp0 = tsk->thread.sp0;
|
||||||
lazy_save_gs(vm86->regs32.gs);
|
savesegment(gs, vm86->regs32.gs);
|
||||||
|
|
||||||
/* make room for real-mode segments */
|
/* make room for real-mode segments */
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
|
|
|
@ -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)
|
static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
unsigned short sel;
|
unsigned short sel;
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
switch (seg_reg_idx) {
|
switch (seg_reg_idx) {
|
||||||
case INAT_SEG_REG_IGNORE:
|
case INAT_SEG_REG_IGNORE:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -402,7 +402,8 @@ static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
|
||||||
case INAT_SEG_REG_FS:
|
case INAT_SEG_REG_FS:
|
||||||
return (unsigned short)(regs->fs & 0xffff);
|
return (unsigned short)(regs->fs & 0xffff);
|
||||||
case INAT_SEG_REG_GS:
|
case INAT_SEG_REG_GS:
|
||||||
return get_user_gs(regs);
|
savesegment(gs, sel);
|
||||||
|
return sel;
|
||||||
case INAT_SEG_REG_IGNORE:
|
case INAT_SEG_REG_IGNORE:
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -153,7 +153,7 @@ static long pm_address(u_char FPU_modrm, u_char segment,
|
||||||
switch (segment) {
|
switch (segment) {
|
||||||
case PREFIX_GS_ - 1:
|
case PREFIX_GS_ - 1:
|
||||||
/* user gs handling can be lazy, use special accessors */
|
/* user gs handling can be lazy, use special accessors */
|
||||||
addr->selector = get_user_gs(FPU_info->regs);
|
savesegment(gs, addr->selector);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
addr->selector = PM_REG_(segment);
|
addr->selector = PM_REG_(segment);
|
||||||
|
|
|
@ -84,15 +84,6 @@ static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *re
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void elf_core_copy_kernel_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
#ifdef ELF_CORE_COPY_KERNEL_REGS
|
|
||||||
ELF_CORE_COPY_KERNEL_REGS((*elfregs), regs);
|
|
||||||
#else
|
|
||||||
elf_core_copy_regs(elfregs, regs);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
|
static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
|
||||||
{
|
{
|
||||||
#if defined (ELF_CORE_COPY_TASK_REGS)
|
#if defined (ELF_CORE_COPY_TASK_REGS)
|
||||||
|
|
|
@ -1078,7 +1078,7 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
|
||||||
return;
|
return;
|
||||||
memset(&prstatus, 0, sizeof(prstatus));
|
memset(&prstatus, 0, sizeof(prstatus));
|
||||||
prstatus.common.pr_pid = current->pid;
|
prstatus.common.pr_pid = current->pid;
|
||||||
elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
|
elf_core_copy_regs(&prstatus.pr_reg, regs);
|
||||||
buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
|
buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
|
||||||
&prstatus, sizeof(prstatus));
|
&prstatus, sizeof(prstatus));
|
||||||
final_note(buf);
|
final_note(buf);
|
||||||
|
|
15
lib/bug.c
15
lib/bug.c
|
@ -6,8 +6,7 @@
|
||||||
|
|
||||||
CONFIG_BUG - emit BUG traps. Nothing happens without this.
|
CONFIG_BUG - emit BUG traps. Nothing happens without this.
|
||||||
CONFIG_GENERIC_BUG - enable this code.
|
CONFIG_GENERIC_BUG - enable this code.
|
||||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS - use 32-bit pointers relative to
|
CONFIG_GENERIC_BUG_RELATIVE_POINTERS - use 32-bit relative pointers for bug_addr and file
|
||||||
the containing struct bug_entry for bug_addr and file.
|
|
||||||
CONFIG_DEBUG_BUGVERBOSE - emit full file+line information for each BUG
|
CONFIG_DEBUG_BUGVERBOSE - emit full file+line information for each BUG
|
||||||
|
|
||||||
CONFIG_BUG and CONFIG_DEBUG_BUGVERBOSE are potentially user-settable
|
CONFIG_BUG and CONFIG_DEBUG_BUGVERBOSE are potentially user-settable
|
||||||
|
@ -53,10 +52,10 @@ extern struct bug_entry __start___bug_table[], __stop___bug_table[];
|
||||||
|
|
||||||
static inline unsigned long bug_addr(const struct bug_entry *bug)
|
static inline unsigned long bug_addr(const struct bug_entry *bug)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
||||||
return bug->bug_addr;
|
return (unsigned long)&bug->bug_addr_disp + bug->bug_addr_disp;
|
||||||
#else
|
#else
|
||||||
return (unsigned long)bug + bug->bug_addr_disp;
|
return bug->bug_addr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,10 +130,10 @@ void bug_get_file_line(struct bug_entry *bug, const char **file,
|
||||||
unsigned int *line)
|
unsigned int *line)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||||
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
||||||
*file = bug->file;
|
*file = (const char *)&bug->file_disp + bug->file_disp;
|
||||||
#else
|
#else
|
||||||
*file = (const char *)bug + bug->file_disp;
|
*file = bug->file;
|
||||||
#endif
|
#endif
|
||||||
*line = bug->line;
|
*line = bug->line;
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue