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

Commit 460b48a0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull powerpc fixes from Michael Ellerman:
 "A minor fix to our IMC PMU code to print a less confusing error
  message when the driver can't initialise properly.

  A fix for a bug where a user requesting an unsupported branch sampling
  filter can corrupt PMU state, preventing the PMU from counting
  properly.

  And finally a fix for a bug in our support for kexec_file_load(),
  which prevented loading a kernel and initramfs. Most versions of kexec
  don't yet use kexec_file_load().

  Thanks to: Anju T Sudhakar, Dave Young, Madhavan Srinivasan, Ravi
  Bangoria, Thiago Jung Bauermann"

* tag 'powerpc-5.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/kexec: Fix loading of kernel + initramfs with kexec_file_load()
  powerpc/perf: Fix MMCRA corruption by bhrb_filter
  powerpc/powernv: Return for invalid IMC domain
parents b44a1dd3 8b909e35
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -547,6 +547,7 @@ static int elf_exec_load(struct kimage *image, struct elfhdr *ehdr,
		kbuf.memsz = phdr->p_memsz;
		kbuf.memsz = phdr->p_memsz;
		kbuf.buf_align = phdr->p_align;
		kbuf.buf_align = phdr->p_align;
		kbuf.buf_min = phdr->p_paddr + base;
		kbuf.buf_min = phdr->p_paddr + base;
		kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
		ret = kexec_add_buffer(&kbuf);
		ret = kexec_add_buffer(&kbuf);
		if (ret)
		if (ret)
			goto out;
			goto out;
@@ -581,7 +582,8 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
	struct kexec_buf kbuf = { .image = image, .buf_min = 0,
	struct kexec_buf kbuf = { .image = image, .buf_min = 0,
				  .buf_max = ppc64_rma_size };
				  .buf_max = ppc64_rma_size };
	struct kexec_buf pbuf = { .image = image, .buf_min = 0,
	struct kexec_buf pbuf = { .image = image, .buf_min = 0,
				  .buf_max = ppc64_rma_size, .top_down = true };
				  .buf_max = ppc64_rma_size, .top_down = true,
				  .mem = KEXEC_BUF_MEM_UNKNOWN };


	ret = build_elf_exec_info(kernel_buf, kernel_len, &ehdr, &elf_info);
	ret = build_elf_exec_info(kernel_buf, kernel_len, &ehdr, &elf_info);
	if (ret)
	if (ret)
@@ -606,6 +608,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
		kbuf.bufsz = kbuf.memsz = initrd_len;
		kbuf.bufsz = kbuf.memsz = initrd_len;
		kbuf.buf_align = PAGE_SIZE;
		kbuf.buf_align = PAGE_SIZE;
		kbuf.top_down = false;
		kbuf.top_down = false;
		kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
		ret = kexec_add_buffer(&kbuf);
		ret = kexec_add_buffer(&kbuf);
		if (ret)
		if (ret)
			goto out;
			goto out;
@@ -638,6 +641,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
	kbuf.bufsz = kbuf.memsz = fdt_size;
	kbuf.bufsz = kbuf.memsz = fdt_size;
	kbuf.buf_align = PAGE_SIZE;
	kbuf.buf_align = PAGE_SIZE;
	kbuf.top_down = true;
	kbuf.top_down = true;
	kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
	ret = kexec_add_buffer(&kbuf);
	ret = kexec_add_buffer(&kbuf);
	if (ret)
	if (ret)
		goto out;
		goto out;
+4 −2
Original line number Original line Diff line number Diff line
@@ -1846,6 +1846,7 @@ static int power_pmu_event_init(struct perf_event *event)
	int n;
	int n;
	int err;
	int err;
	struct cpu_hw_events *cpuhw;
	struct cpu_hw_events *cpuhw;
	u64 bhrb_filter;


	if (!ppmu)
	if (!ppmu)
		return -ENOENT;
		return -ENOENT;
@@ -1951,13 +1952,14 @@ static int power_pmu_event_init(struct perf_event *event)
	err = power_check_constraints(cpuhw, events, cflags, n + 1);
	err = power_check_constraints(cpuhw, events, cflags, n + 1);


	if (has_branch_stack(event)) {
	if (has_branch_stack(event)) {
		cpuhw->bhrb_filter = ppmu->bhrb_filter_map(
		bhrb_filter = ppmu->bhrb_filter_map(
					event->attr.branch_sample_type);
					event->attr.branch_sample_type);


		if (cpuhw->bhrb_filter == -1) {
		if (bhrb_filter == -1) {
			put_cpu_var(cpu_hw_events);
			put_cpu_var(cpu_hw_events);
			return -EOPNOTSUPP;
			return -EOPNOTSUPP;
		}
		}
		cpuhw->bhrb_filter = bhrb_filter;
	}
	}


	put_cpu_var(cpu_hw_events);
	put_cpu_var(cpu_hw_events);
+3 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ enum {
#define	POWER8_MMCRA_IFM1		0x0000000040000000UL
#define	POWER8_MMCRA_IFM1		0x0000000040000000UL
#define	POWER8_MMCRA_IFM2		0x0000000080000000UL
#define	POWER8_MMCRA_IFM2		0x0000000080000000UL
#define	POWER8_MMCRA_IFM3		0x00000000C0000000UL
#define	POWER8_MMCRA_IFM3		0x00000000C0000000UL
#define	POWER8_MMCRA_BHRB_MASK		0x00000000C0000000UL


/*
/*
 * Raw event encoding for PowerISA v2.07 (Power8):
 * Raw event encoding for PowerISA v2.07 (Power8):
@@ -239,6 +240,8 @@ static u64 power8_bhrb_filter_map(u64 branch_sample_type)


static void power8_config_bhrb(u64 pmu_bhrb_filter)
static void power8_config_bhrb(u64 pmu_bhrb_filter)
{
{
	pmu_bhrb_filter &= POWER8_MMCRA_BHRB_MASK;

	/* Enable BHRB filter in PMU */
	/* Enable BHRB filter in PMU */
	mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
	mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -88,6 +88,7 @@ enum {
#define POWER9_MMCRA_IFM1		0x0000000040000000UL
#define POWER9_MMCRA_IFM1		0x0000000040000000UL
#define POWER9_MMCRA_IFM2		0x0000000080000000UL
#define POWER9_MMCRA_IFM2		0x0000000080000000UL
#define POWER9_MMCRA_IFM3		0x00000000C0000000UL
#define POWER9_MMCRA_IFM3		0x00000000C0000000UL
#define POWER9_MMCRA_BHRB_MASK		0x00000000C0000000UL


/* Nasty Power9 specific hack */
/* Nasty Power9 specific hack */
#define PVR_POWER9_CUMULUS		0x00002000
#define PVR_POWER9_CUMULUS		0x00002000
@@ -296,6 +297,8 @@ static u64 power9_bhrb_filter_map(u64 branch_sample_type)


static void power9_config_bhrb(u64 pmu_bhrb_filter)
static void power9_config_bhrb(u64 pmu_bhrb_filter)
{
{
	pmu_bhrb_filter &= POWER9_MMCRA_BHRB_MASK;

	/* Enable BHRB filter in PMU */
	/* Enable BHRB filter in PMU */
	mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
	mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
}
}
+4 −0
Original line number Original line Diff line number Diff line
@@ -157,6 +157,10 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain)
	struct imc_pmu *pmu_ptr;
	struct imc_pmu *pmu_ptr;
	u32 offset;
	u32 offset;


	/* Return for unknown domain */
	if (domain < 0)
		return -EINVAL;

	/* memory for pmu */
	/* memory for pmu */
	pmu_ptr = kzalloc(sizeof(*pmu_ptr), GFP_KERNEL);
	pmu_ptr = kzalloc(sizeof(*pmu_ptr), GFP_KERNEL);
	if (!pmu_ptr)
	if (!pmu_ptr)