Merge tag 'v4.12-rc5' into ras/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -409,8 +409,13 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
|
||||
memcpy(insnbuf, replacement, a->replacementlen);
|
||||
insnbuf_sz = a->replacementlen;
|
||||
|
||||
/* 0xe8 is a relative jump; fix the offset. */
|
||||
if (*insnbuf == 0xe8 && a->replacementlen == 5) {
|
||||
/*
|
||||
* 0xe8 is a relative jump; fix the offset.
|
||||
*
|
||||
* Instruction length is checked before the opcode to avoid
|
||||
* accessing uninitialized bytes for zero-length replacements.
|
||||
*/
|
||||
if (a->replacementlen == 5 && *insnbuf == 0xe8) {
|
||||
*(s32 *)(insnbuf + 1) += replacement - instr;
|
||||
DPRINTK("Fix CALL offset: 0x%x, CALL 0x%lx",
|
||||
*(s32 *)(insnbuf + 1),
|
||||
|
@@ -255,6 +255,7 @@ static void init_cyrix(struct cpuinfo_x86 *c)
|
||||
break;
|
||||
|
||||
case 4: /* MediaGX/GXm or Geode GXM/GXLV/GX1 */
|
||||
case 11: /* GX1 with inverted Device ID */
|
||||
#ifdef CONFIG_PCI
|
||||
{
|
||||
u32 vendor, device;
|
||||
|
@@ -320,7 +320,7 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
|
||||
}
|
||||
|
||||
static enum ucode_state
|
||||
load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size);
|
||||
load_microcode_amd(bool save, u8 family, const u8 *data, size_t size);
|
||||
|
||||
int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
|
||||
{
|
||||
@@ -338,8 +338,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
|
||||
if (!desc.mc)
|
||||
return -EINVAL;
|
||||
|
||||
ret = load_microcode_amd(smp_processor_id(), x86_family(cpuid_1_eax),
|
||||
desc.data, desc.size);
|
||||
ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size);
|
||||
if (ret != UCODE_OK)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -675,7 +674,7 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
|
||||
}
|
||||
|
||||
static enum ucode_state
|
||||
load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size)
|
||||
load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
|
||||
{
|
||||
enum ucode_state ret;
|
||||
|
||||
@@ -689,8 +688,8 @@ load_microcode_amd(int cpu, u8 family, const u8 *data, size_t size)
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/* save BSP's matching patch for early load */
|
||||
if (cpu_data(cpu).cpu_index == boot_cpu_data.cpu_index) {
|
||||
struct ucode_patch *p = find_patch(cpu);
|
||||
if (save) {
|
||||
struct ucode_patch *p = find_patch(0);
|
||||
if (p) {
|
||||
memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
|
||||
memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
|
||||
@@ -722,11 +721,12 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
|
||||
{
|
||||
char fw_name[36] = "amd-ucode/microcode_amd.bin";
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
bool bsp = c->cpu_index == boot_cpu_data.cpu_index;
|
||||
enum ucode_state ret = UCODE_NFOUND;
|
||||
const struct firmware *fw;
|
||||
|
||||
/* reload ucode container only on the boot cpu */
|
||||
if (!refresh_fw || c->cpu_index != boot_cpu_data.cpu_index)
|
||||
if (!refresh_fw || !bsp)
|
||||
return UCODE_OK;
|
||||
|
||||
if (c->x86 >= 0x15)
|
||||
@@ -743,7 +743,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device,
|
||||
goto fw_release;
|
||||
}
|
||||
|
||||
ret = load_microcode_amd(cpu, c->x86, fw->data, fw->size);
|
||||
ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size);
|
||||
|
||||
fw_release:
|
||||
release_firmware(fw);
|
||||
|
@@ -619,6 +619,9 @@ int __init save_microcode_in_initrd_intel(void)
|
||||
|
||||
show_saved_mc();
|
||||
|
||||
/* initrd is going away, clear patch ptr. */
|
||||
intel_ucode_patch = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -689,8 +689,12 @@ static inline void *alloc_tramp(unsigned long size)
|
||||
{
|
||||
return module_alloc(size);
|
||||
}
|
||||
static inline void tramp_free(void *tramp)
|
||||
static inline void tramp_free(void *tramp, int size)
|
||||
{
|
||||
int npages = PAGE_ALIGN(size) >> PAGE_SHIFT;
|
||||
|
||||
set_memory_nx((unsigned long)tramp, npages);
|
||||
set_memory_rw((unsigned long)tramp, npages);
|
||||
module_memfree(tramp);
|
||||
}
|
||||
#else
|
||||
@@ -699,7 +703,7 @@ static inline void *alloc_tramp(unsigned long size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline void tramp_free(void *tramp) { }
|
||||
static inline void tramp_free(void *tramp, int size) { }
|
||||
#endif
|
||||
|
||||
/* Defined as markers to the end of the ftrace default trampolines */
|
||||
@@ -771,7 +775,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
|
||||
/* Copy ftrace_caller onto the trampoline memory */
|
||||
ret = probe_kernel_read(trampoline, (void *)start_offset, size);
|
||||
if (WARN_ON(ret < 0)) {
|
||||
tramp_free(trampoline);
|
||||
tramp_free(trampoline, *tramp_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -797,7 +801,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
|
||||
|
||||
/* Are we pointing to the reference? */
|
||||
if (WARN_ON(memcmp(op_ptr.op, op_ref, 3) != 0)) {
|
||||
tramp_free(trampoline);
|
||||
tramp_free(trampoline, *tramp_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -839,7 +843,7 @@ void arch_ftrace_update_trampoline(struct ftrace_ops *ops)
|
||||
unsigned long offset;
|
||||
unsigned long ip;
|
||||
unsigned int size;
|
||||
int ret;
|
||||
int ret, npages;
|
||||
|
||||
if (ops->trampoline) {
|
||||
/*
|
||||
@@ -848,11 +852,14 @@ void arch_ftrace_update_trampoline(struct ftrace_ops *ops)
|
||||
*/
|
||||
if (!(ops->flags & FTRACE_OPS_FL_ALLOC_TRAMP))
|
||||
return;
|
||||
npages = PAGE_ALIGN(ops->trampoline_size) >> PAGE_SHIFT;
|
||||
set_memory_rw(ops->trampoline, npages);
|
||||
} else {
|
||||
ops->trampoline = create_trampoline(ops, &size);
|
||||
if (!ops->trampoline)
|
||||
return;
|
||||
ops->trampoline_size = size;
|
||||
npages = PAGE_ALIGN(size) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
offset = calc_trampoline_call_offset(ops->flags & FTRACE_OPS_FL_SAVE_REGS);
|
||||
@@ -863,6 +870,7 @@ void arch_ftrace_update_trampoline(struct ftrace_ops *ops)
|
||||
/* Do a safe modify in case the trampoline is executing */
|
||||
new = ftrace_call_replace(ip, (unsigned long)func);
|
||||
ret = update_ftrace_func(ip, new);
|
||||
set_memory_ro(ops->trampoline, npages);
|
||||
|
||||
/* The update should never fail */
|
||||
WARN_ON(ret);
|
||||
@@ -939,7 +947,7 @@ void arch_ftrace_trampoline_free(struct ftrace_ops *ops)
|
||||
if (!ops || !(ops->flags & FTRACE_OPS_FL_ALLOC_TRAMP))
|
||||
return;
|
||||
|
||||
tramp_free((void *)ops->trampoline);
|
||||
tramp_free((void *)ops->trampoline, ops->trampoline_size);
|
||||
ops->trampoline = 0;
|
||||
}
|
||||
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/frame.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/moduleloader.h>
|
||||
|
||||
#include <asm/text-patching.h>
|
||||
#include <asm/cacheflush.h>
|
||||
@@ -417,6 +418,14 @@ static void prepare_boost(struct kprobe *p, struct insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Recover page to RW mode before releasing it */
|
||||
void free_insn_page(void *page)
|
||||
{
|
||||
set_memory_nx((unsigned long)page & PAGE_MASK, 1);
|
||||
set_memory_rw((unsigned long)page & PAGE_MASK, 1);
|
||||
module_memfree(page);
|
||||
}
|
||||
|
||||
static int arch_copy_kprobe(struct kprobe *p)
|
||||
{
|
||||
struct insn insn;
|
||||
|
@@ -161,8 +161,8 @@ void kvm_async_pf_task_wait(u32 token)
|
||||
*/
|
||||
rcu_irq_exit();
|
||||
native_safe_halt();
|
||||
rcu_irq_enter();
|
||||
local_irq_disable();
|
||||
rcu_irq_enter();
|
||||
}
|
||||
}
|
||||
if (!n.halted)
|
||||
|
@@ -78,7 +78,7 @@ void __show_regs(struct pt_regs *regs, int all)
|
||||
|
||||
printk(KERN_DEFAULT "EIP: %pS\n", (void *)regs->ip);
|
||||
printk(KERN_DEFAULT "EFLAGS: %08lx CPU: %d\n", regs->flags,
|
||||
smp_processor_id());
|
||||
raw_smp_processor_id());
|
||||
|
||||
printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
|
||||
regs->ax, regs->bx, regs->cx, regs->dx);
|
||||
|
@@ -980,8 +980,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
*/
|
||||
x86_configure_nx();
|
||||
|
||||
simple_udelay_calibration();
|
||||
|
||||
parse_early_param();
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
@@ -1041,6 +1039,8 @@ void __init setup_arch(char **cmdline_p)
|
||||
*/
|
||||
init_hypervisor_platform();
|
||||
|
||||
simple_udelay_calibration();
|
||||
|
||||
x86_init.resources.probe_roms();
|
||||
|
||||
/* after parse_early_param, so could debug it */
|
||||
|
@@ -104,6 +104,11 @@ static inline unsigned long *last_frame(struct unwind_state *state)
|
||||
return (unsigned long *)task_pt_regs(state->task) - 2;
|
||||
}
|
||||
|
||||
static bool is_last_frame(struct unwind_state *state)
|
||||
{
|
||||
return state->bp == last_frame(state);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
#define GCC_REALIGN_WORDS 3
|
||||
#else
|
||||
@@ -115,16 +120,15 @@ static inline unsigned long *last_aligned_frame(struct unwind_state *state)
|
||||
return last_frame(state) - GCC_REALIGN_WORDS;
|
||||
}
|
||||
|
||||
static bool is_last_task_frame(struct unwind_state *state)
|
||||
static bool is_last_aligned_frame(struct unwind_state *state)
|
||||
{
|
||||
unsigned long *last_bp = last_frame(state);
|
||||
unsigned long *aligned_bp = last_aligned_frame(state);
|
||||
|
||||
/*
|
||||
* We have to check for the last task frame at two different locations
|
||||
* because gcc can occasionally decide to realign the stack pointer and
|
||||
* change the offset of the stack frame in the prologue of a function
|
||||
* called by head/entry code. Examples:
|
||||
* GCC can occasionally decide to realign the stack pointer and change
|
||||
* the offset of the stack frame in the prologue of a function called
|
||||
* by head/entry code. Examples:
|
||||
*
|
||||
* <start_secondary>:
|
||||
* push %edi
|
||||
@@ -141,11 +145,38 @@ static bool is_last_task_frame(struct unwind_state *state)
|
||||
* push %rbp
|
||||
* mov %rsp,%rbp
|
||||
*
|
||||
* Note that after aligning the stack, it pushes a duplicate copy of
|
||||
* the return address before pushing the frame pointer.
|
||||
* After aligning the stack, it pushes a duplicate copy of the return
|
||||
* address before pushing the frame pointer.
|
||||
*/
|
||||
return (state->bp == last_bp ||
|
||||
(state->bp == aligned_bp && *(aligned_bp+1) == *(last_bp+1)));
|
||||
return (state->bp == aligned_bp && *(aligned_bp + 1) == *(last_bp + 1));
|
||||
}
|
||||
|
||||
static bool is_last_ftrace_frame(struct unwind_state *state)
|
||||
{
|
||||
unsigned long *last_bp = last_frame(state);
|
||||
unsigned long *last_ftrace_bp = last_bp - 3;
|
||||
|
||||
/*
|
||||
* When unwinding from an ftrace handler of a function called by entry
|
||||
* code, the stack layout of the last frame is:
|
||||
*
|
||||
* bp
|
||||
* parent ret addr
|
||||
* bp
|
||||
* function ret addr
|
||||
* parent ret addr
|
||||
* pt_regs
|
||||
* -----------------
|
||||
*/
|
||||
return (state->bp == last_ftrace_bp &&
|
||||
*state->bp == *(state->bp + 2) &&
|
||||
*(state->bp + 1) == *(state->bp + 4));
|
||||
}
|
||||
|
||||
static bool is_last_task_frame(struct unwind_state *state)
|
||||
{
|
||||
return is_last_frame(state) || is_last_aligned_frame(state) ||
|
||||
is_last_ftrace_frame(state);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user