Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7a36a6e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:
 "A landry list of fixes:

   - fix reboot breakage on some PCID-enabled system

   - fix crashes/hangs on some PCID-enabled systems

   - fix microcode loading on certain older CPUs

   - various unwinder fixes

   - extend an APIC quirk to more hardware systems and disable APIC
     related warning on virtualized systems

   - various Hyper-V fixes

   - a macro definition robustness fix

   - remove jprobes IRQ disabling

   - various mem-encryption fixes"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/microcode: Do the family check first
  x86/mm: Flush more aggressively in lazy TLB mode
  x86/apic: Update TSC_DEADLINE quirk with additional SKX stepping
  x86/apic: Silence "FW_BUG TSC_DEADLINE disabled due to Errata" on hypervisors
  x86/mm: Disable various instrumentations of mm/mem_encrypt.c and mm/tlb.c
  x86/hyperv: Fix hypercalls with extended CPU ranges for TLB flushing
  x86/hyperv: Don't use percpu areas for pcpu_flush/pcpu_flush_ex structures
  x86/hyperv: Clear vCPU banks between calls to avoid flushing unneeded vCPUs
  x86/unwind: Disable unwinder warnings on 32-bit
  x86/unwind: Align stack pointer in unwinder dump
  x86/unwind: Use MSB for frame pointer encoding on 32-bit
  x86/unwind: Fix dereference of untrusted pointer
  x86/alternatives: Fix alt_max_short macro to really be a max()
  x86/mm/64: Fix reboot interaction with CR4.PCIDE
  kprobes/x86: Remove IRQ disabling from jprobe handlers
  kprobes/x86: Set up frame pointer in kprobe trampoline
parents a339b351 1f161f67
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -176,7 +176,7 @@
/*
/*
 * This is a sneaky trick to help the unwinder find pt_regs on the stack.  The
 * This is a sneaky trick to help the unwinder find pt_regs on the stack.  The
 * frame pointer is replaced with an encoded pointer to pt_regs.  The encoding
 * frame pointer is replaced with an encoded pointer to pt_regs.  The encoding
 * is just setting the LSB, which makes it an invalid stack address and is also
 * is just clearing the MSB, which makes it an invalid stack address and is also
 * a signal to the unwinder that it's a pt_regs pointer in disguise.
 * a signal to the unwinder that it's a pt_regs pointer in disguise.
 *
 *
 * NOTE: This macro must be used *after* SAVE_ALL because it corrupts the
 * NOTE: This macro must be used *after* SAVE_ALL because it corrupts the
@@ -185,7 +185,7 @@
.macro ENCODE_FRAME_POINTER
.macro ENCODE_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
	mov %esp, %ebp
	mov %esp, %ebp
	orl $0x1, %ebp
	andl $0x7fffffff, %ebp
#endif
#endif
.endm
.endm


+5 −0
Original line number Original line Diff line number Diff line
@@ -85,6 +85,8 @@ EXPORT_SYMBOL_GPL(hyperv_cs);
u32 *hv_vp_index;
u32 *hv_vp_index;
EXPORT_SYMBOL_GPL(hv_vp_index);
EXPORT_SYMBOL_GPL(hv_vp_index);


u32 hv_max_vp_index;

static int hv_cpu_init(unsigned int cpu)
static int hv_cpu_init(unsigned int cpu)
{
{
	u64 msr_vp_index;
	u64 msr_vp_index;
@@ -93,6 +95,9 @@ static int hv_cpu_init(unsigned int cpu)


	hv_vp_index[smp_processor_id()] = msr_vp_index;
	hv_vp_index[smp_processor_id()] = msr_vp_index;


	if (msr_vp_index > hv_max_vp_index)
		hv_max_vp_index = msr_vp_index;

	return 0;
	return 0;
}
}


+43 −14
Original line number Original line Diff line number Diff line
@@ -36,9 +36,9 @@ struct hv_flush_pcpu_ex {
/* Each gva in gva_list encodes up to 4096 pages to flush */
/* Each gva in gva_list encodes up to 4096 pages to flush */
#define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
#define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)


static struct hv_flush_pcpu __percpu *pcpu_flush;
static struct hv_flush_pcpu __percpu **pcpu_flush;


static struct hv_flush_pcpu_ex __percpu *pcpu_flush_ex;
static struct hv_flush_pcpu_ex __percpu **pcpu_flush_ex;


/*
/*
 * Fills in gva_list starting from offset. Returns the number of items added.
 * Fills in gva_list starting from offset. Returns the number of items added.
@@ -76,6 +76,18 @@ static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
{
{
	int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
	int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;


	/* valid_bank_mask can represent up to 64 banks */
	if (hv_max_vp_index / 64 >= 64)
		return 0;

	/*
	 * Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex
	 * structs are not cleared between calls, we risk flushing unneeded
	 * vCPUs otherwise.
	 */
	for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
		flush->hv_vp_set.bank_contents[vcpu_bank] = 0;

	/*
	/*
	 * Some banks may end up being empty but this is acceptable.
	 * Some banks may end up being empty but this is acceptable.
	 */
	 */
@@ -83,11 +95,6 @@ static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
		vcpu = hv_cpu_number_to_vp_number(cpu);
		vcpu = hv_cpu_number_to_vp_number(cpu);
		vcpu_bank = vcpu / 64;
		vcpu_bank = vcpu / 64;
		vcpu_offset = vcpu % 64;
		vcpu_offset = vcpu % 64;

		/* valid_bank_mask can represent up to 64 banks */
		if (vcpu_bank >= 64)
			return 0;

		__set_bit(vcpu_offset, (unsigned long *)
		__set_bit(vcpu_offset, (unsigned long *)
			  &flush->hv_vp_set.bank_contents[vcpu_bank]);
			  &flush->hv_vp_set.bank_contents[vcpu_bank]);
		if (vcpu_bank >= nr_bank)
		if (vcpu_bank >= nr_bank)
@@ -102,6 +109,7 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
				    const struct flush_tlb_info *info)
				    const struct flush_tlb_info *info)
{
{
	int cpu, vcpu, gva_n, max_gvas;
	int cpu, vcpu, gva_n, max_gvas;
	struct hv_flush_pcpu **flush_pcpu;
	struct hv_flush_pcpu *flush;
	struct hv_flush_pcpu *flush;
	u64 status = U64_MAX;
	u64 status = U64_MAX;
	unsigned long flags;
	unsigned long flags;
@@ -116,7 +124,17 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,


	local_irq_save(flags);
	local_irq_save(flags);


	flush = this_cpu_ptr(pcpu_flush);
	flush_pcpu = this_cpu_ptr(pcpu_flush);

	if (unlikely(!*flush_pcpu))
		*flush_pcpu = page_address(alloc_page(GFP_ATOMIC));

	flush = *flush_pcpu;

	if (unlikely(!flush)) {
		local_irq_restore(flags);
		goto do_native;
	}


	if (info->mm) {
	if (info->mm) {
		flush->address_space = virt_to_phys(info->mm->pgd);
		flush->address_space = virt_to_phys(info->mm->pgd);
@@ -173,6 +191,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
				       const struct flush_tlb_info *info)
				       const struct flush_tlb_info *info)
{
{
	int nr_bank = 0, max_gvas, gva_n;
	int nr_bank = 0, max_gvas, gva_n;
	struct hv_flush_pcpu_ex **flush_pcpu;
	struct hv_flush_pcpu_ex *flush;
	struct hv_flush_pcpu_ex *flush;
	u64 status = U64_MAX;
	u64 status = U64_MAX;
	unsigned long flags;
	unsigned long flags;
@@ -187,7 +206,17 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,


	local_irq_save(flags);
	local_irq_save(flags);


	flush = this_cpu_ptr(pcpu_flush_ex);
	flush_pcpu = this_cpu_ptr(pcpu_flush_ex);

	if (unlikely(!*flush_pcpu))
		*flush_pcpu = page_address(alloc_page(GFP_ATOMIC));

	flush = *flush_pcpu;

	if (unlikely(!flush)) {
		local_irq_restore(flags);
		goto do_native;
	}


	if (info->mm) {
	if (info->mm) {
		flush->address_space = virt_to_phys(info->mm->pgd);
		flush->address_space = virt_to_phys(info->mm->pgd);
@@ -222,18 +251,18 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
		flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
		flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY;
		status = hv_do_rep_hypercall(
		status = hv_do_rep_hypercall(
			HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
			HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
			0, nr_bank + 2, flush, NULL);
			0, nr_bank, flush, NULL);
	} else if (info->end &&
	} else if (info->end &&
		   ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
		   ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) {
		status = hv_do_rep_hypercall(
		status = hv_do_rep_hypercall(
			HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
			HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX,
			0, nr_bank + 2, flush, NULL);
			0, nr_bank, flush, NULL);
	} else {
	} else {
		gva_n = fill_gva_list(flush->gva_list, nr_bank,
		gva_n = fill_gva_list(flush->gva_list, nr_bank,
				      info->start, info->end);
				      info->start, info->end);
		status = hv_do_rep_hypercall(
		status = hv_do_rep_hypercall(
			HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX,
			HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX,
			gva_n, nr_bank + 2, flush, NULL);
			gva_n, nr_bank, flush, NULL);
	}
	}


	local_irq_restore(flags);
	local_irq_restore(flags);
@@ -266,7 +295,7 @@ void hyper_alloc_mmu(void)
		return;
		return;


	if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
	if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
		pcpu_flush = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
		pcpu_flush = alloc_percpu(struct hv_flush_pcpu *);
	else
	else
		pcpu_flush_ex = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
		pcpu_flush_ex = alloc_percpu(struct hv_flush_pcpu_ex *);
}
}
+3 −1
Original line number Original line Diff line number Diff line
@@ -62,8 +62,10 @@
#define new_len2		145f-144f
#define new_len2		145f-144f


/*
/*
 * max without conditionals. Idea adapted from:
 * gas compatible max based on the idea from:
 * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
 * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
 *
 * The additional "-" is needed because gas uses a "true" value of -1.
 */
 */
#define alt_max_short(a, b)	((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
#define alt_max_short(a, b)	((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))


+3 −3
Original line number Original line Diff line number Diff line
@@ -103,12 +103,12 @@ static inline int alternatives_text_reserved(void *start, void *end)
	alt_end_marker ":\n"
	alt_end_marker ":\n"


/*
/*
 * max without conditionals. Idea adapted from:
 * gas compatible max based on the idea from:
 * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
 * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
 *
 *
 * The additional "-" is needed because gas works with s32s.
 * The additional "-" is needed because gas uses a "true" value of -1.
 */
 */
#define alt_max_short(a, b)	"((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") - (" b ")))))"
#define alt_max_short(a, b)	"((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))"


/*
/*
 * Pad the second replacement alternative with additional NOPs if it is
 * Pad the second replacement alternative with additional NOPs if it is
Loading