* [PATCH v2 09/12] ppc64/kexec_file: setup backup region for kdump kernel
From: Hari Bathini @ 2020-07-02 19:56 UTC (permalink / raw)
To: Michael Ellerman, Andrew Morton
Cc: kernel test robot, Pingfan Liu, Kexec-ml, Petr Tesarik,
Mahesh J Salgaonkar, Mimi Zohar, lkml, linuxppc-dev, Sourabh Jain,
Vivek Goyal, Dave Young, Thiago Jung Bauermann, Eric Biederman
In-Reply-To: <159371956443.21555.18251597651350106920.stgit@hbathini.in.ibm.com>
Though kdump kernel boots from loaded address, the first 64K bytes
of it is copied down to real 0. So, setup a backup region to copy
the first 64K bytes of crashed kernel, in purgatory, before booting
into kdump kernel. Also, update reserve map with backup region and
crashed kernel's memory to avoid kdump kernel from accidentially
using that memory.
Reported-by: kernel test robot <lkp@intel.com>
[lkp: In v1, purgatory() declaration was missing]
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
---
Changes in v2:
* Check if backup region is available before branching out. This is
to keep `kexec -l -s` flow as before as much as possible. This would
eventually change with more testing and addition of sha256 digest
verification support.
* Fixed missing prototype for purgatory() as reported by lkp.
lkp report for reference:
- https://lore.kernel.org/patchwork/patch/1264423/
arch/powerpc/include/asm/crashdump-ppc64.h | 5 +
arch/powerpc/include/asm/kexec.h | 7 ++
arch/powerpc/include/asm/purgatory.h | 11 +++
arch/powerpc/kexec/elf_64.c | 9 +++
arch/powerpc/kexec/file_load_64.c | 95 ++++++++++++++++++++++++++++
arch/powerpc/purgatory/Makefile | 28 ++++++++
arch/powerpc/purgatory/purgatory_64.c | 36 +++++++++++
arch/powerpc/purgatory/trampoline_64.S | 28 +++++++-
8 files changed, 211 insertions(+), 8 deletions(-)
create mode 100644 arch/powerpc/include/asm/purgatory.h
create mode 100644 arch/powerpc/purgatory/purgatory_64.c
diff --git a/arch/powerpc/include/asm/crashdump-ppc64.h b/arch/powerpc/include/asm/crashdump-ppc64.h
index 90deb46..fcc5fce 100644
--- a/arch/powerpc/include/asm/crashdump-ppc64.h
+++ b/arch/powerpc/include/asm/crashdump-ppc64.h
@@ -2,6 +2,11 @@
#ifndef _ASM_POWERPC_CRASHDUMP_PPC64_H
#define _ASM_POWERPC_CRASHDUMP_PPC64_H
+/* Backup region - first 64K bytes of System RAM. */
+#define BACKUP_SRC_START 0
+#define BACKUP_SRC_END 0xffff
+#define BACKUP_SRC_SIZE (BACKUP_SRC_END - BACKUP_SRC_START + 1)
+
/* min & max addresses for kdump load segments */
#define KDUMP_BUF_MIN (crashk_res.start)
#define KDUMP_BUF_MAX ((crashk_res.end < ppc64_rma_size) ? \
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index e78cd0a..037cf2b 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -109,6 +109,9 @@ extern const struct kexec_file_ops kexec_elf64_ops;
struct kimage_arch {
struct crash_mem *exclude_ranges;
+ unsigned long backup_start;
+ void *backup_buf;
+
#ifdef CONFIG_IMA_KEXEC
phys_addr_t ima_buffer_addr;
size_t ima_buffer_size;
@@ -124,6 +127,10 @@ int setup_new_fdt(const struct kimage *image, void *fdt,
int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size);
#ifdef CONFIG_PPC64
+struct kexec_buf;
+
+int load_crashdump_segments_ppc64(struct kimage *image,
+ struct kexec_buf *kbuf);
int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
const void *fdt, unsigned long kernel_load_addr,
unsigned long fdt_load_addr);
diff --git a/arch/powerpc/include/asm/purgatory.h b/arch/powerpc/include/asm/purgatory.h
new file mode 100644
index 0000000..076d150
--- /dev/null
+++ b/arch/powerpc/include/asm/purgatory.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASM_POWERPC_PURGATORY_H
+#define _ASM_POWERPC_PURGATORY_H
+
+#ifndef __ASSEMBLY__
+#include <linux/purgatory.h>
+
+void purgatory(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_PURGATORY_H */
diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c
index c695f94..4838b42 100644
--- a/arch/powerpc/kexec/elf_64.c
+++ b/arch/powerpc/kexec/elf_64.c
@@ -67,6 +67,15 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
pr_debug("Loaded purgatory at 0x%lx\n", pbuf.mem);
+ /* Setup additional segments needed for panic kernel */
+ if (image->type == KEXEC_TYPE_CRASH) {
+ ret = load_crashdump_segments_ppc64(image, &kbuf);
+ if (ret) {
+ pr_err("Failed to load kdump kernel segments\n");
+ goto out;
+ }
+ }
+
if (initrd != NULL) {
kbuf.buffer = initrd;
kbuf.bufsz = kbuf.memsz = initrd_len;
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index f06dcf1..f91530e 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -20,6 +20,7 @@
#include <linux/of_device.h>
#include <linux/memblock.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <asm/types.h>
#include <asm/drmem.h>
#include <asm/kexec_ranges.h>
@@ -858,6 +859,69 @@ static int kexec_do_relocs_ppc64(unsigned long my_r2, const Elf_Sym *sym,
}
/**
+ * load_backup_segment - Initialize backup segment of crashing kernel.
+ * @image: Kexec image.
+ * @kbuf: Buffer contents and memory parameters.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+static int load_backup_segment(struct kimage *image, struct kexec_buf *kbuf)
+{
+ void *buf;
+ int ret;
+
+ /* Setup a segment for backup region */
+ buf = vzalloc(BACKUP_SRC_SIZE);
+ if (!buf)
+ return -ENOMEM;
+
+ /*
+ * A source buffer has no meaning for backup region as data will
+ * be copied from backup source, after crash, in the purgatory.
+ * But as load segment code doesn't recognize such segments,
+ * setup a dummy source buffer to keep it happy for now.
+ */
+ kbuf->buffer = buf;
+ kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
+ kbuf->bufsz = kbuf->memsz = BACKUP_SRC_SIZE;
+ kbuf->top_down = false;
+
+ ret = kexec_add_buffer(kbuf);
+ if (ret) {
+ vfree(buf);
+ return ret;
+ }
+
+ image->arch.backup_buf = buf;
+ image->arch.backup_start = kbuf->mem;
+ return 0;
+}
+
+/**
+ * load_crashdump_segments_ppc64 - Initialize the additional segements needed
+ * to load kdump kernel.
+ * @image: Kexec image.
+ * @kbuf: Buffer contents and memory parameters.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+int load_crashdump_segments_ppc64(struct kimage *image,
+ struct kexec_buf *kbuf)
+{
+ int ret;
+
+ /* Load backup segment - first 64K bytes of the crashing kernel */
+ ret = load_backup_segment(image, kbuf);
+ if (ret) {
+ pr_err("Failed to load backup segment\n");
+ return ret;
+ }
+ pr_debug("Loaded the backup region at 0x%lx\n", kbuf->mem);
+
+ return 0;
+}
+
+/**
* setup_purgatory_ppc64 - initialize PPC64 specific purgatory's global
* variables and call setup_purgatory() to initialize
* common global variable.
@@ -898,6 +962,14 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
goto out;
}
+ /* Tell purgatory where to look for backup region */
+ ret = kexec_purgatory_get_set_symbol(image, "backup_start",
+ &image->arch.backup_start,
+ sizeof(image->arch.backup_start),
+ false);
+ if (ret)
+ goto out;
+
/* Setup the stack top */
stack_buf = kexec_purgatory_get_symbol_addr(image, "stack_buf");
if (!stack_buf)
@@ -966,7 +1038,7 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
/*
* Restrict memory usage for kdump kernel by setting up
- * usable memory ranges.
+ * usable memory ranges and memory reserve map.
*/
if (image->type == KEXEC_TYPE_CRASH) {
ret = get_usable_memory_ranges(&umem);
@@ -978,6 +1050,24 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
pr_err("Error setting up usable-memory property for kdump kernel\n");
goto out;
}
+
+ ret = fdt_add_mem_rsv(fdt, BACKUP_SRC_START + BACKUP_SRC_SIZE,
+ crashk_res.start - BACKUP_SRC_SIZE);
+ if (ret) {
+ pr_err("Error reserving crash memory: %s\n",
+ fdt_strerror(ret));
+ goto out;
+ }
+ }
+
+ if (image->arch.backup_start) {
+ ret = fdt_add_mem_rsv(fdt, image->arch.backup_start,
+ BACKUP_SRC_SIZE);
+ if (ret) {
+ pr_err("Error reserving memory for backup: %s\n",
+ fdt_strerror(ret));
+ goto out;
+ }
}
ret = setup_new_fdt(image, fdt, initrd_load_addr, initrd_len,
@@ -1188,5 +1278,8 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
kfree(image->arch.exclude_ranges);
image->arch.exclude_ranges = NULL;
+ vfree(image->arch.backup_buf);
+ image->arch.backup_buf = NULL;
+
return kexec_image_post_load_cleanup_default(image);
}
diff --git a/arch/powerpc/purgatory/Makefile b/arch/powerpc/purgatory/Makefile
index 348f5958..a494413 100644
--- a/arch/powerpc/purgatory/Makefile
+++ b/arch/powerpc/purgatory/Makefile
@@ -2,13 +2,37 @@
KASAN_SANITIZE := n
-targets += trampoline_$(BITS).o purgatory.ro kexec-purgatory.c
+purgatory-y := purgatory_$(BITS).o trampoline_$(BITS).o
+
+targets += $(purgatory-y)
+PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined
+targets += purgatory.ro
+
+PURGATORY_CFLAGS_REMOVE :=
+
+# Default KBUILD_CFLAGS can have -pg option set when FUNCTION_TRACE is
+# enabled leaving some undefined symbols like _mcount in purgatory.
+ifdef CONFIG_FUNCTION_TRACER
+PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_FTRACE)
+endif
+
+ifdef CONFIG_STACKPROTECTOR
+PURGATORY_CFLAGS_REMOVE += -fstack-protector
+endif
-$(obj)/purgatory.ro: $(obj)/trampoline_$(BITS).o FORCE
+ifdef CONFIG_STACKPROTECTOR_STRONG
+PURGATORY_CFLAGS_REMOVE += -fstack-protector-strong
+endif
+
+CFLAGS_REMOVE_purgatory_$(BITS).o += $(PURGATORY_CFLAGS_REMOVE)
+
+$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
$(call if_changed,ld)
+targets += kexec-purgatory.c
+
quiet_cmd_bin2c = BIN2C $@
cmd_bin2c = $(objtree)/scripts/bin2c kexec_purgatory < $< > $@
diff --git a/arch/powerpc/purgatory/purgatory_64.c b/arch/powerpc/purgatory/purgatory_64.c
new file mode 100644
index 0000000..1eca74c
--- /dev/null
+++ b/arch/powerpc/purgatory/purgatory_64.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * purgatory: Runs between two kernels
+ *
+ * Copyright 2020, Hari Bathini, IBM Corporation.
+ */
+
+#include <asm/purgatory.h>
+#include <asm/crashdump-ppc64.h>
+
+extern unsigned long backup_start;
+
+static void *__memcpy(void *dest, const void *src, unsigned long n)
+{
+ unsigned long i;
+ unsigned char *d;
+ const unsigned char *s;
+
+ d = dest;
+ s = src;
+ for (i = 0; i < n; i++)
+ d[i] = s[i];
+
+ return dest;
+}
+
+void purgatory(void)
+{
+ void *dest, *src;
+
+ src = (void *)BACKUP_SRC_START;
+ if (backup_start) {
+ dest = (void *)backup_start;
+ __memcpy(dest, src, BACKUP_SRC_SIZE);
+ }
+}
diff --git a/arch/powerpc/purgatory/trampoline_64.S b/arch/powerpc/purgatory/trampoline_64.S
index 83e93b7..ef808d3 100644
--- a/arch/powerpc/purgatory/trampoline_64.S
+++ b/arch/powerpc/purgatory/trampoline_64.S
@@ -44,11 +44,6 @@ master:
mr %r17,%r3 /* save cpu id to r17 */
mr %r15,%r4 /* save physical address in reg15 */
- or %r3,%r3,%r3 /* ok now to high priority, lets boot */
- lis %r6,0x1
- mtctr %r6 /* delay a bit for slaves to catch up */
- bdnz . /* before we overwrite 0-100 again */
-
bl 0f /* Work out where we're running */
0: mflr %r18
@@ -56,6 +51,24 @@ master:
ld %r1,(stack - 0b)(%r18) /* setup stack */
+ /* Branch out to copy backup region, if required. */
+ ld %r12,(backup_start - 0b)(%r18)
+ cmpdi %cr0,%r12,0
+ beq 80f
+
+ subi %r1,%r1,112
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+ bl purgatory
+#else
+ bl .purgatory
+#endif
+ nop
+80:
+ or %r3,%r3,%r3 /* ok now to high priority, lets boot */
+ lis %r6,0x1
+ mtctr %r6 /* delay a bit for slaves to catch up */
+ bdnz . /* before we overwrite 0-100 again */
+
/* load device-tree address */
ld %r3, (dt_offset - 0b)(%r18)
mr %r16,%r3 /* save dt address in reg16 */
@@ -112,6 +125,11 @@ dt_offset:
.8byte 0x0
.size dt_offset, . - dt_offset
+ .balign 8
+ .globl backup_start
+backup_start:
+ .8byte 0x0
+ .size backup_start, . - backup_start
.balign 8
.globl my_toc
^ permalink raw reply related
* [PATCH v2 10/12] ppc64/kexec_file: prepare elfcore header for crashing kernel
From: Hari Bathini @ 2020-07-02 19:56 UTC (permalink / raw)
To: Michael Ellerman, Andrew Morton
Cc: Pingfan Liu, Kexec-ml, Petr Tesarik, Mahesh J Salgaonkar,
Sourabh Jain, lkml, linuxppc-dev, Mimi Zohar, Vivek Goyal,
Dave Young, Thiago Jung Bauermann, Eric Biederman
In-Reply-To: <159371956443.21555.18251597651350106920.stgit@hbathini.in.ibm.com>
Prepare elf headers for the crashing kernel's core file using
crash_prepare_elf64_headers() and pass on this info to kdump
kernel by updating its command line with elfcorehdr parameter.
Also, add elfcorehdr location to reserve map to avoid it from
being stomped on while booting.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
---
Changes in v2:
* Tried merging adjacent memory ranges on hitting maximum ranges limit
to reduce reallocations for memory ranges and also, minimize PT_LOAD
segments for elfcore.
* Updated add_rtas_mem_range() & add_opal_mem_range() callsites based on
the new prototype for these functions.
arch/powerpc/include/asm/kexec.h | 6 +
arch/powerpc/kexec/elf_64.c | 12 ++
arch/powerpc/kexec/file_load.c | 49 ++++++++++
arch/powerpc/kexec/file_load_64.c | 181 +++++++++++++++++++++++++++++++++++++
4 files changed, 248 insertions(+)
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 037cf2b..8b0a6d6 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -112,12 +112,18 @@ struct kimage_arch {
unsigned long backup_start;
void *backup_buf;
+ unsigned long elfcorehdr_addr;
+ unsigned long elf_headers_sz;
+ void *elf_headers;
+
#ifdef CONFIG_IMA_KEXEC
phys_addr_t ima_buffer_addr;
size_t ima_buffer_size;
#endif
};
+char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
+ unsigned long cmdline_len);
int setup_purgatory(struct kimage *image, const void *slave_code,
const void *fdt, unsigned long kernel_load_addr,
unsigned long fdt_load_addr);
diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c
index 4838b42..40a028c 100644
--- a/arch/powerpc/kexec/elf_64.c
+++ b/arch/powerpc/kexec/elf_64.c
@@ -36,6 +36,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
void *fdt;
const void *slave_code;
struct elfhdr ehdr;
+ char *modified_cmdline = NULL;
struct kexec_elf_info elf_info;
struct kexec_buf kbuf = { .image = image, .buf_min = 0,
.buf_max = ppc64_rma_size };
@@ -74,6 +75,16 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
pr_err("Failed to load kdump kernel segments\n");
goto out;
}
+
+ /* Setup cmdline for kdump kernel case */
+ modified_cmdline = setup_kdump_cmdline(image, cmdline,
+ cmdline_len);
+ if (!modified_cmdline) {
+ pr_err("Setting up cmdline for kdump kernel failed\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ cmdline = modified_cmdline;
}
if (initrd != NULL) {
@@ -130,6 +141,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
pr_err("Error setting up the purgatory.\n");
out:
+ kfree(modified_cmdline);
kexec_free_elf_info(&elf_info);
/* Make kimage_file_post_load_cleanup free the fdt buffer for us. */
diff --git a/arch/powerpc/kexec/file_load.c b/arch/powerpc/kexec/file_load.c
index 99a2c4d..2e74992 100644
--- a/arch/powerpc/kexec/file_load.c
+++ b/arch/powerpc/kexec/file_load.c
@@ -17,11 +17,46 @@
#include <linux/slab.h>
#include <linux/kexec.h>
#include <linux/libfdt.h>
+#include <asm/setup.h>
#include <asm/ima.h>
#define SLAVE_CODE_SIZE 256 /* First 0x100 bytes */
/**
+ * setup_kdump_cmdline - Prepend "elfcorehdr=<addr> " to command line
+ * of kdump kernel for exporting the core.
+ * @image: Kexec image
+ * @cmdline: Command line parameters to update.
+ * @cmdline_len: Length of the cmdline parameters.
+ *
+ * kdump segment must be setup before calling this function.
+ *
+ * Returns new cmdline buffer for kdump kernel on success, NULL otherwise.
+ */
+char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
+ unsigned long cmdline_len)
+{
+ int elfcorehdr_strlen;
+ char *cmdline_ptr;
+
+ cmdline_ptr = kzalloc(COMMAND_LINE_SIZE, GFP_KERNEL);
+ if (!cmdline_ptr)
+ return NULL;
+
+ elfcorehdr_strlen = sprintf(cmdline_ptr, "elfcorehdr=0x%lx ",
+ image->arch.elfcorehdr_addr);
+
+ if (elfcorehdr_strlen + cmdline_len > COMMAND_LINE_SIZE) {
+ pr_err("Appending elfcorehdr=<addr> exceeds cmdline size\n");
+ kfree(cmdline_ptr);
+ return NULL;
+ }
+
+ memcpy(cmdline_ptr + elfcorehdr_strlen, cmdline, cmdline_len);
+ return cmdline_ptr;
+}
+
+/**
* setup_purgatory - initialize the purgatory's global variables
* @image: kexec image.
* @slave_code: Slave code for the purgatory.
@@ -215,6 +250,20 @@ int setup_new_fdt(const struct kimage *image, void *fdt,
}
}
+ if (image->type == KEXEC_TYPE_CRASH) {
+ /*
+ * Avoid elfcorehdr from being stomped on in kdump kernel by
+ * setting up memory reserve map.
+ */
+ ret = fdt_add_mem_rsv(fdt, image->arch.elfcorehdr_addr,
+ image->arch.elf_headers_sz);
+ if (ret) {
+ pr_err("Error reserving elfcorehdr memory: %s\n",
+ fdt_strerror(ret));
+ goto err;
+ }
+ }
+
ret = setup_ima_buffer(image, fdt, chosen_node);
if (ret) {
pr_err("Error setting up the new device tree.\n");
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index f91530e..6f895fa 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -122,6 +122,77 @@ static int get_usable_memory_ranges(struct crash_mem **mem_ranges)
}
/**
+ * get_crash_memory_ranges - Get crash memory ranges. This list includes
+ * first/crashing kernel's memory regions that
+ * would be exported via an elfcore.
+ * @mem_ranges: Range list to add the memory ranges to.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+static int get_crash_memory_ranges(struct crash_mem **mem_ranges)
+{
+ struct memblock_region *reg;
+ struct crash_mem *tmem;
+ int ret;
+
+ for_each_memblock(memory, reg) {
+ u64 base, size;
+
+ base = (u64)reg->base;
+ size = (u64)reg->size;
+
+ /* Skip backup memory region, which needs a separate entry */
+ if (base == BACKUP_SRC_START) {
+ if (size > BACKUP_SRC_SIZE) {
+ base = BACKUP_SRC_END + 1;
+ size -= BACKUP_SRC_SIZE;
+ } else
+ continue;
+ }
+
+ ret = add_mem_range(mem_ranges, base, size);
+ if (ret)
+ goto out;
+
+ /* Try merging adjacent ranges before reallocation attempt */
+ if ((*mem_ranges)->nr_ranges == (*mem_ranges)->max_nr_ranges)
+ sort_memory_ranges(*mem_ranges, true);
+ }
+
+ /* Reallocate memory ranges if there is no space to split ranges */
+ tmem = *mem_ranges;
+ if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) {
+ tmem = realloc_mem_ranges(mem_ranges);
+ if (!tmem)
+ goto out;
+ }
+
+ /* Exclude crashkernel region */
+ ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end);
+ if (ret)
+ goto out;
+
+ ret = add_rtas_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_opal_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ /* create a separate program header for the backup region */
+ ret = add_mem_range(mem_ranges, BACKUP_SRC_START, BACKUP_SRC_SIZE);
+ if (ret)
+ goto out;
+
+ sort_memory_ranges(*mem_ranges, false);
+out:
+ if (ret)
+ pr_err("Failed to setup crash memory ranges\n");
+ return ret;
+}
+
+/**
* __locate_mem_hole_top_down - Looks top down for a large enough memory hole
* in the memory regions between buf_min & buf_max
* for the buffer. If found, sets kbuf->mem.
@@ -898,6 +969,103 @@ static int load_backup_segment(struct kimage *image, struct kexec_buf *kbuf)
}
/**
+ * update_backup_region_phdr - Update backup region's offset for the core to
+ * export the region appropriately.
+ * @image: Kexec image.
+ * @ehdr: ELF core header.
+ *
+ * Assumes an exclusive program header is setup for the backup region
+ * in the ELF headers
+ *
+ * Returns nothing.
+ */
+static void update_backup_region_phdr(struct kimage *image, Elf64_Ehdr *ehdr)
+{
+ Elf64_Phdr *phdr;
+ unsigned int i;
+
+ phdr = (Elf64_Phdr *)(ehdr + 1);
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ if (phdr->p_paddr == BACKUP_SRC_START) {
+ phdr->p_offset = image->arch.backup_start;
+ pr_debug("Backup region offset updated to 0x%lx\n",
+ image->arch.backup_start);
+ return;
+ }
+ }
+}
+
+/**
+ * prepare_elf_headers - Prepare headers for the elfcore to be exported as
+ * /proc/vmcore by the kdump kernel.
+ * @image: Kexec image.
+ * @cmem: Crash memory ranges to be exported via elfcore.
+ * @addr: Vmalloc'd memory allocated by crash_prepare_elf64_headers
+ * to prepare the elf headers.
+ * @sz: Size of the vmalloc'd memory allocated.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+static int prepare_elf_headers(struct kimage *image, struct crash_mem *cmem,
+ void **addr, unsigned long *sz)
+{
+ int ret;
+
+ ret = crash_prepare_elf64_headers(cmem, false, addr, sz);
+
+ /* Fix the offset for backup region in the ELF header */
+ if (!ret)
+ update_backup_region_phdr(image, *addr);
+
+ return ret;
+}
+
+/**
+ * load_elfcorehdr_segment - Setup crash memory ranges and initialize elfcorehdr
+ * segment needed to load kdump kernel.
+ * @image: Kexec image.
+ * @kbuf: Buffer contents and memory parameters.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf)
+{
+ struct crash_mem *cmem = NULL;
+ unsigned long headers_sz;
+ void *headers = NULL;
+ int ret;
+
+ ret = get_crash_memory_ranges(&cmem);
+ if (ret)
+ goto out;
+
+ /* Setup elfcorehdr segment */
+ ret = prepare_elf_headers(image, cmem, &headers, &headers_sz);
+ if (ret) {
+ pr_err("Failed to prepare elf headers for the core\n");
+ goto out;
+ }
+
+ kbuf->buffer = headers;
+ kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
+ kbuf->bufsz = kbuf->memsz = headers_sz;
+ kbuf->top_down = false;
+
+ ret = kexec_add_buffer(kbuf);
+ if (ret) {
+ vfree(headers);
+ goto out;
+ }
+
+ image->arch.elfcorehdr_addr = kbuf->mem;
+ image->arch.elf_headers_sz = headers_sz;
+ image->arch.elf_headers = headers;
+out:
+ kfree(cmem);
+ return ret;
+}
+
+/**
* load_crashdump_segments_ppc64 - Initialize the additional segements needed
* to load kdump kernel.
* @image: Kexec image.
@@ -918,6 +1086,15 @@ int load_crashdump_segments_ppc64(struct kimage *image,
}
pr_debug("Loaded the backup region at 0x%lx\n", kbuf->mem);
+ /* Load elfcorehdr segment - to export crashing kernel's vmcore */
+ ret = load_elfcorehdr_segment(image, kbuf);
+ if (ret) {
+ pr_err("Failed to load elfcorehdr segment\n");
+ return ret;
+ }
+ pr_debug("Loaded elf core header at 0x%lx, bufsz=0x%lx memsz=0x%lx\n",
+ image->arch.elfcorehdr_addr, kbuf->bufsz, kbuf->memsz);
+
return 0;
}
@@ -1281,5 +1458,9 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
vfree(image->arch.backup_buf);
image->arch.backup_buf = NULL;
+ vfree(image->arch.elf_headers);
+ image->arch.elf_headers = NULL;
+ image->arch.elf_headers_sz = 0;
+
return kexec_image_post_load_cleanup_default(image);
}
^ permalink raw reply related
* [PATCH v2 11/12] ppc64/kexec_file: add appropriate regions for memory reserve map
From: Hari Bathini @ 2020-07-02 19:56 UTC (permalink / raw)
To: Michael Ellerman, Andrew Morton
Cc: Pingfan Liu, Kexec-ml, Petr Tesarik, Mahesh J Salgaonkar,
Sourabh Jain, lkml, linuxppc-dev, Mimi Zohar, Vivek Goyal,
Dave Young, Thiago Jung Bauermann, Eric Biederman
In-Reply-To: <159371956443.21555.18251597651350106920.stgit@hbathini.in.ibm.com>
While initrd, elfcorehdr and backup regions are already added to the
reserve map, there are a few missing regions that need to be added to
the memory reserve map. Add them here. And now that all the changes
to load panic kernel are in place, claim likewise.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
---
Changes in v2:
* Updated add_rtas_mem_range() & add_opal_mem_range() callsites based on
the new prototype for these functions.
arch/powerpc/kexec/file_load_64.c | 58 ++++++++++++++++++++++++++++++++++---
1 file changed, 53 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index 6f895fa..d3b29e0 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -193,6 +193,34 @@ static int get_crash_memory_ranges(struct crash_mem **mem_ranges)
}
/**
+ * get_reserved_memory_ranges - Get reserve memory ranges. This list includes
+ * memory regions that should be added to the
+ * memory reserve map to ensure the region is
+ * protected from any mischeif.
+ * @mem_ranges: Range list to add the memory ranges to.
+ *
+ * Returns 0 on success, negative errno on error.
+ */
+static int get_reserved_memory_ranges(struct crash_mem **mem_ranges)
+{
+ int ret;
+
+ ret = add_rtas_mem_range(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_tce_mem_ranges(mem_ranges);
+ if (ret)
+ goto out;
+
+ ret = add_reserved_ranges(mem_ranges);
+out:
+ if (ret)
+ pr_err("Failed to setup reserved memory ranges\n");
+ return ret;
+}
+
+/**
* __locate_mem_hole_top_down - Looks top down for a large enough memory hole
* in the memory regions between buf_min & buf_max
* for the buffer. If found, sets kbuf->mem.
@@ -1200,8 +1228,8 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
unsigned long initrd_load_addr,
unsigned long initrd_len, const char *cmdline)
{
- struct crash_mem *umem = NULL;
- int chosen_node, ret;
+ struct crash_mem *umem = NULL, *rmem = NULL;
+ int i, nr_ranges, chosen_node, ret;
/* Remove memory reservation for the current device tree. */
ret = delete_fdt_mem_rsv(fdt, __pa(initial_boot_params),
@@ -1247,6 +1275,25 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
}
}
+ /* Update memory reserve map */
+ ret = get_reserved_memory_ranges(&rmem);
+ if (ret)
+ goto out;
+
+ nr_ranges = rmem ? rmem->nr_ranges : 0;
+ for (i = 0; i < nr_ranges; i++) {
+ u64 base, size;
+
+ base = rmem->ranges[i].start;
+ size = rmem->ranges[i].end - base + 1;
+ ret = fdt_add_mem_rsv(fdt, base, size);
+ if (ret) {
+ pr_err("Error updating memory reserve map: %s\n",
+ fdt_strerror(ret));
+ goto out;
+ }
+ }
+
ret = setup_new_fdt(image, fdt, initrd_load_addr, initrd_len,
cmdline, &chosen_node);
if (ret)
@@ -1257,6 +1304,7 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
pr_err("Failed to update device-tree with linux,booted-from-kexec\n");
out:
kfree(umem);
+ kfree(rmem);
return ret;
}
@@ -1434,10 +1482,10 @@ int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
/* Get exclude memory ranges needed for setting up kdump segments */
ret = get_exclude_memory_ranges(&(image->arch.exclude_ranges));
- if (ret)
+ if (ret) {
pr_err("Failed to setup exclude memory ranges for buffer lookup\n");
- /* Return this until all changes for panic kernel are in */
- return -EOPNOTSUPP;
+ return ret;
+ }
}
return kexec_image_probe_default(image, buf, buf_len);
^ permalink raw reply related
* [PATCH v2 12/12] ppc64/kexec_file: fix kexec load failure with lack of memory hole
From: Hari Bathini @ 2020-07-02 19:57 UTC (permalink / raw)
To: Michael Ellerman, Andrew Morton
Cc: Pingfan Liu, Kexec-ml, Petr Tesarik, Mahesh J Salgaonkar,
Sourabh Jain, lkml, linuxppc-dev, Mimi Zohar, Vivek Goyal,
Dave Young, Thiago Jung Bauermann, Eric Biederman
In-Reply-To: <159371956443.21555.18251597651350106920.stgit@hbathini.in.ibm.com>
The kexec purgatory has to run in real mode. Only the first memory
block maybe accessible in real mode. And, unlike the case with panic
kernel, no memory is set aside for regular kexec load. Another thing
to note is, the memory for crashkernel is reserved at an offset of
128MB. So, when crashkernel memory is reserved, the memory ranges to
load kexec segments shrink further as the generic code only looks for
memblock free memory ranges and in all likelihood only a tiny bit of
memory from 0 to 128MB would be available to load kexec segments.
With kdump being used by default in general, kexec file load is likely
to fail almost always. This can be fixed by changing the memory hole
lookup logic for regular kexec to use the same method as kdump. This
would mean that most kexec segments will overlap with crashkernel
memory region. That should still be ok as the pages, whose destination
address isn't available while loading, are placed in an intermediate
location till a flush to the actual destination address happens during
kexec boot sequence.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
---
Changes in v2:
* New patch to fix locating memory hole for kexec_file_load (kexec -s -l)
when memory is reserved for crashkernel.
arch/powerpc/kexec/file_load_64.c | 33 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 19 deletions(-)
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index d3b29e0..746c16f 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -1326,13 +1326,6 @@ int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf)
u64 buf_min, buf_max;
int ret;
- /*
- * Use the generic kexec_locate_mem_hole for regular
- * kexec_file_load syscall
- */
- if (kbuf->image->type != KEXEC_TYPE_CRASH)
- return kexec_locate_mem_hole(kbuf);
-
/* Look up the exclude ranges list while locating the memory hole */
emem = &(kbuf->image->arch.exclude_ranges);
if (!(*emem) || ((*emem)->nr_ranges == 0)) {
@@ -1340,11 +1333,15 @@ int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf)
return 0;
}
+ buf_min = kbuf->buf_min;
+ buf_max = kbuf->buf_max;
/* Segments for kdump kernel should be within crashkernel region */
- buf_min = (kbuf->buf_min < crashk_res.start ?
- crashk_res.start : kbuf->buf_min);
- buf_max = (kbuf->buf_max > crashk_res.end ?
- crashk_res.end : kbuf->buf_max);
+ if (kbuf->image->type == KEXEC_TYPE_CRASH) {
+ buf_min = (buf_min < crashk_res.start ?
+ crashk_res.start : buf_min);
+ buf_max = (buf_max > crashk_res.end ?
+ crashk_res.end : buf_max);
+ }
if (buf_min > buf_max) {
pr_err("Invalid buffer min and/or max values\n");
@@ -1477,15 +1474,13 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
unsigned long buf_len)
{
- if (image->type == KEXEC_TYPE_CRASH) {
- int ret;
+ int ret;
- /* Get exclude memory ranges needed for setting up kdump segments */
- ret = get_exclude_memory_ranges(&(image->arch.exclude_ranges));
- if (ret) {
- pr_err("Failed to setup exclude memory ranges for buffer lookup\n");
- return ret;
- }
+ /* Get exclude memory ranges needed for setting up kexec segments */
+ ret = get_exclude_memory_ranges(&(image->arch.exclude_ranges));
+ if (ret) {
+ pr_err("Failed to setup exclude memory ranges for buffer lookup\n");
+ return ret;
}
return kexec_image_probe_default(image, buf, buf_len);
^ permalink raw reply related
* Re: [PATCH 6/8] powerpc/pseries: implement paravirt qspinlocks for SPLPAR
From: Waiman Long @ 2020-07-02 21:01 UTC (permalink / raw)
To: Nicholas Piggin
Cc: linux-arch, Peter Zijlstra, Will Deacon, Boqun Feng, linux-kernel,
kvm-ppc, virtualization, Ingo Molnar, linuxppc-dev
In-Reply-To: <20200702074839.1057733-7-npiggin@gmail.com>
On 7/2/20 3:48 AM, Nicholas Piggin wrote:
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> arch/powerpc/include/asm/paravirt.h | 23 ++++++++
> arch/powerpc/include/asm/qspinlock.h | 55 +++++++++++++++++++
> arch/powerpc/include/asm/qspinlock_paravirt.h | 5 ++
> arch/powerpc/platforms/pseries/Kconfig | 5 ++
> arch/powerpc/platforms/pseries/setup.c | 6 +-
> include/asm-generic/qspinlock.h | 2 +
> 6 files changed, 95 insertions(+), 1 deletion(-)
> create mode 100644 arch/powerpc/include/asm/qspinlock_paravirt.h
>
> diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h
> index 7a8546660a63..5fae9dfa6fe9 100644
> --- a/arch/powerpc/include/asm/paravirt.h
> +++ b/arch/powerpc/include/asm/paravirt.h
> @@ -29,6 +29,16 @@ static inline void yield_to_preempted(int cpu, u32 yield_count)
> {
> plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(cpu), yield_count);
> }
> +
> +static inline void prod_cpu(int cpu)
> +{
> + plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
> +}
> +
> +static inline void yield_to_any(void)
> +{
> + plpar_hcall_norets(H_CONFER, -1, 0);
> +}
> #else
> static inline bool is_shared_processor(void)
> {
> @@ -45,6 +55,19 @@ static inline void yield_to_preempted(int cpu, u32 yield_count)
> {
> ___bad_yield_to_preempted(); /* This would be a bug */
> }
> +
> +extern void ___bad_yield_to_any(void);
> +static inline void yield_to_any(void)
> +{
> + ___bad_yield_to_any(); /* This would be a bug */
> +}
> +
> +extern void ___bad_prod_cpu(void);
> +static inline void prod_cpu(int cpu)
> +{
> + ___bad_prod_cpu(); /* This would be a bug */
> +}
> +
> #endif
>
> #define vcpu_is_preempted vcpu_is_preempted
> diff --git a/arch/powerpc/include/asm/qspinlock.h b/arch/powerpc/include/asm/qspinlock.h
> index f84da77b6bb7..997a9a32df77 100644
> --- a/arch/powerpc/include/asm/qspinlock.h
> +++ b/arch/powerpc/include/asm/qspinlock.h
> @@ -3,9 +3,36 @@
> #define _ASM_POWERPC_QSPINLOCK_H
>
> #include <asm-generic/qspinlock_types.h>
> +#include <asm/paravirt.h>
>
> #define _Q_PENDING_LOOPS (1 << 9) /* not tuned */
>
> +#ifdef CONFIG_PARAVIRT_SPINLOCKS
> +extern void native_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val);
> +extern void __pv_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val);
> +
> +static __always_inline void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
> +{
> + if (!is_shared_processor())
> + native_queued_spin_lock_slowpath(lock, val);
> + else
> + __pv_queued_spin_lock_slowpath(lock, val);
> +}
You may need to match the use of __pv_queued_spin_lock_slowpath() with
the corresponding __pv_queued_spin_unlock(), e.g.
#define queued_spin_unlock queued_spin_unlock
static inline queued_spin_unlock(struct qspinlock *lock)
{
if (!is_shared_processor())
smp_store_release(&lock->locked, 0);
else
__pv_queued_spin_unlock(lock);
}
Otherwise, pv_kick() will never be called.
Cheers,
Longman
^ permalink raw reply
* Re: [PATCH] MAINTAINERS: Add Shengjiu to reviewer list of sound/soc/fsl
From: Fabio Estevam @ 2020-07-02 21:46 UTC (permalink / raw)
To: Nicolin Chen
Cc: Linux-ALSA, Mark Brown, linux-kernel, Timur Tabi, Xiubo Li,
linuxppc-dev, S.j. Wang
In-Reply-To: <20200702193102.25282-1-nicoleotsuka@gmail.com>
On Thu, Jul 2, 2020 at 4:31 PM Nicolin Chen <nicoleotsuka@gmail.com> wrote:
>
> Add Shengjiu who's actively working on the latest fsl/nxp audio drivers.
>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
> Cc: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Fabio Estevam <festevam@gmail.com>
^ permalink raw reply
* Re: [PATCH 0/8] mm: cleanup usage of <asm/pgalloc.h>
From: Mike Rapoport @ 2020-07-02 21:46 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-ia64, linux-sh, Peter Zijlstra, linux-kernel, Max Filippov,
Satheesh Rajendran, linux-csky, sparclinux, linux-riscv,
linux-arch, Stephen Rothwell, linux-hexagon, Joerg Roedel,
Mike Rapoport, Abdul Haleem, linux-snps-arc, linux-xtensa,
Arnd Bergmann, linux-s390, linux-um, Steven Rostedt, linux-m68k,
openrisc, Andy Lutomirski, Stafford Horne, linux-arm-kernel,
linux-parisc, linux-mm, linux-mips, linux-alpha, linuxppc-dev
In-Reply-To: <20200627143453.31835-1-rppt@kernel.org>
Gentle ping.
On Sat, Jun 27, 2020 at 05:34:45PM +0300, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
>
> Hi,
>
> Most architectures have very similar versions of pXd_alloc_one() and
> pXd_free_one() for intermediate levels of page table.
> These patches add generic versions of these functions in
> <asm-generic/pgalloc.h> and enable use of the generic functions where
> appropriate.
>
> In addition, functions declared and defined in <asm/pgalloc.h> headers
> are used mostly by core mm and early mm initialization in arch and there is
> no actual reason to have the <asm/pgalloc.h> included all over the place.
> The first patch in this series removes unneeded includes of <asm/pgalloc.h>
>
> In the end it didn't work out as neatly as I hoped and moving
> pXd_alloc_track() definitions to <asm-generic/pgalloc.h> would require
> unnecessary changes to arches that have custom page table allocations, so
> I've decided to move lib/ioremap.c to mm/ and make pgalloc-track.h local to
> mm/.
>
> Joerg Roedel (1):
> mm: move p?d_alloc_track to separate header file
>
> Mike Rapoport (7):
> mm: remove unneeded includes of <asm/pgalloc.h>
> opeinrisc: switch to generic version of pte allocation
> xtensa: switch to generic version of pte allocation
> asm-generic: pgalloc: provide generic pmd_alloc_one() and pmd_free_one()
> asm-generic: pgalloc: provide generic pud_alloc_one() and pud_free_one()
> asm-generic: pgalloc: provide generic pgd_free()
> mm: move lib/ioremap.c to mm/
>
> arch/alpha/include/asm/pgalloc.h | 21 +----
> arch/alpha/include/asm/tlbflush.h | 1 -
> arch/alpha/kernel/core_irongate.c | 1 -
> arch/alpha/kernel/core_marvel.c | 1 -
> arch/alpha/kernel/core_titan.c | 1 -
> arch/alpha/kernel/machvec_impl.h | 2 -
> arch/alpha/kernel/smp.c | 1 -
> arch/alpha/mm/numa.c | 1 -
> arch/arc/mm/fault.c | 1 -
> arch/arc/mm/init.c | 1 -
> arch/arm/include/asm/pgalloc.h | 12 +--
> arch/arm/include/asm/tlb.h | 1 -
> arch/arm/kernel/machine_kexec.c | 1 -
> arch/arm/kernel/smp.c | 1 -
> arch/arm/kernel/suspend.c | 1 -
> arch/arm/mach-omap2/omap-mpuss-lowpower.c | 1 -
> arch/arm/mm/hugetlbpage.c | 1 -
> arch/arm/mm/mmu.c | 1 +
> arch/arm64/include/asm/pgalloc.h | 39 +---------
> arch/arm64/kernel/smp.c | 1 -
> arch/arm64/mm/hugetlbpage.c | 1 -
> arch/arm64/mm/ioremap.c | 1 -
> arch/arm64/mm/mmu.c | 1 +
> arch/csky/include/asm/pgalloc.h | 7 +-
> arch/csky/kernel/smp.c | 1 -
> arch/hexagon/include/asm/pgalloc.h | 7 +-
> arch/ia64/include/asm/pgalloc.h | 24 ------
> arch/ia64/include/asm/tlb.h | 1 -
> arch/ia64/kernel/process.c | 1 -
> arch/ia64/kernel/smp.c | 1 -
> arch/ia64/kernel/smpboot.c | 1 -
> arch/ia64/mm/contig.c | 1 -
> arch/ia64/mm/discontig.c | 1 -
> arch/ia64/mm/hugetlbpage.c | 1 -
> arch/ia64/mm/tlb.c | 1 -
> arch/m68k/include/asm/mmu_context.h | 2 +-
> arch/m68k/include/asm/sun3_pgalloc.h | 7 +-
> arch/m68k/kernel/dma.c | 2 +-
> arch/m68k/kernel/traps.c | 3 +-
> arch/m68k/mm/cache.c | 2 +-
> arch/m68k/mm/fault.c | 1 -
> arch/m68k/mm/kmap.c | 2 +-
> arch/m68k/mm/mcfmmu.c | 1 +
> arch/m68k/mm/memory.c | 1 -
> arch/m68k/sun3x/dvma.c | 2 +-
> arch/microblaze/include/asm/pgalloc.h | 6 --
> arch/microblaze/include/asm/tlbflush.h | 1 -
> arch/microblaze/kernel/process.c | 1 -
> arch/microblaze/kernel/signal.c | 1 -
> arch/mips/include/asm/pgalloc.h | 19 +----
> arch/mips/sgi-ip32/ip32-memory.c | 1 -
> arch/nds32/mm/mm-nds32.c | 2 +
> arch/nios2/include/asm/pgalloc.h | 7 +-
> arch/openrisc/include/asm/pgalloc.h | 33 +-------
> arch/openrisc/include/asm/tlbflush.h | 1 -
> arch/openrisc/kernel/or32_ksyms.c | 1 -
> arch/parisc/include/asm/mmu_context.h | 1 -
> arch/parisc/include/asm/pgalloc.h | 12 +--
> arch/parisc/kernel/cache.c | 1 -
> arch/parisc/kernel/pci-dma.c | 1 -
> arch/parisc/kernel/process.c | 1 -
> arch/parisc/kernel/signal.c | 1 -
> arch/parisc/kernel/smp.c | 1 -
> arch/parisc/mm/hugetlbpage.c | 1 -
> arch/parisc/mm/ioremap.c | 2 +-
> arch/powerpc/include/asm/tlb.h | 1 -
> arch/powerpc/mm/book3s64/hash_hugetlbpage.c | 1 -
> arch/powerpc/mm/book3s64/hash_pgtable.c | 1 -
> arch/powerpc/mm/book3s64/hash_tlb.c | 1 -
> arch/powerpc/mm/book3s64/radix_hugetlbpage.c | 1 -
> arch/powerpc/mm/init_32.c | 1 -
> arch/powerpc/mm/kasan/8xx.c | 1 -
> arch/powerpc/mm/kasan/book3s_32.c | 1 -
> arch/powerpc/mm/mem.c | 1 -
> arch/powerpc/mm/nohash/40x.c | 1 -
> arch/powerpc/mm/nohash/8xx.c | 1 -
> arch/powerpc/mm/nohash/fsl_booke.c | 1 -
> arch/powerpc/mm/nohash/kaslr_booke.c | 1 -
> arch/powerpc/mm/pgtable.c | 1 -
> arch/powerpc/mm/pgtable_64.c | 1 -
> arch/powerpc/mm/ptdump/hashpagetable.c | 2 +-
> arch/powerpc/mm/ptdump/ptdump.c | 1 -
> arch/powerpc/platforms/pseries/cmm.c | 1 -
> arch/riscv/include/asm/pgalloc.h | 18 +----
> arch/riscv/mm/fault.c | 1 -
> arch/s390/include/asm/tlb.h | 1 -
> arch/s390/include/asm/tlbflush.h | 1 -
> arch/s390/kernel/machine_kexec.c | 1 -
> arch/s390/kernel/ptrace.c | 1 -
> arch/s390/kvm/diag.c | 1 -
> arch/s390/kvm/priv.c | 1 -
> arch/s390/kvm/pv.c | 1 -
> arch/s390/mm/cmm.c | 1 -
> arch/s390/mm/mmap.c | 1 -
> arch/s390/mm/pgtable.c | 1 -
> arch/sh/include/asm/pgalloc.h | 4 +
> arch/sh/kernel/idle.c | 1 -
> arch/sh/kernel/machine_kexec.c | 1 -
> arch/sh/mm/cache-sh3.c | 1 -
> arch/sh/mm/cache-sh7705.c | 1 -
> arch/sh/mm/hugetlbpage.c | 1 -
> arch/sh/mm/init.c | 1 +
> arch/sh/mm/ioremap_fixed.c | 1 -
> arch/sh/mm/tlb-sh3.c | 1 -
> arch/sparc/include/asm/ide.h | 1 -
> arch/sparc/include/asm/tlb_64.h | 1 -
> arch/sparc/kernel/leon_smp.c | 1 -
> arch/sparc/kernel/process_32.c | 1 -
> arch/sparc/kernel/signal_32.c | 1 -
> arch/sparc/kernel/smp_32.c | 1 -
> arch/sparc/kernel/smp_64.c | 1 +
> arch/sparc/kernel/sun4m_irq.c | 1 -
> arch/sparc/mm/highmem.c | 1 -
> arch/sparc/mm/io-unit.c | 1 -
> arch/sparc/mm/iommu.c | 1 -
> arch/sparc/mm/tlb.c | 1 -
> arch/um/include/asm/pgalloc.h | 9 +--
> arch/um/include/asm/pgtable-3level.h | 3 -
> arch/um/kernel/mem.c | 17 -----
> arch/x86/ia32/ia32_aout.c | 1 -
> arch/x86/include/asm/mmu_context.h | 1 -
> arch/x86/include/asm/pgalloc.h | 42 +---------
> arch/x86/kernel/alternative.c | 1 +
> arch/x86/kernel/apic/apic.c | 1 -
> arch/x86/kernel/mpparse.c | 1 -
> arch/x86/kernel/traps.c | 1 -
> arch/x86/mm/fault.c | 1 -
> arch/x86/mm/hugetlbpage.c | 1 -
> arch/x86/mm/kaslr.c | 1 -
> arch/x86/mm/pgtable_32.c | 1 -
> arch/x86/mm/pti.c | 1 -
> arch/x86/platform/uv/bios_uv.c | 1 +
> arch/xtensa/include/asm/pgalloc.h | 40 ++++------
> arch/xtensa/kernel/xtensa_ksyms.c | 1 -
> arch/xtensa/mm/cache.c | 1 -
> arch/xtensa/mm/fault.c | 1 -
> drivers/block/xen-blkback/common.h | 1 -
> drivers/iommu/ipmmu-vmsa.c | 1 -
> drivers/xen/balloon.c | 1 -
> drivers/xen/privcmd.c | 1 -
> fs/binfmt_elf_fdpic.c | 1 -
> include/asm-generic/pgalloc.h | 80 ++++++++++++++++++++
> include/asm-generic/tlb.h | 1 -
> include/linux/mm.h | 45 -----------
> lib/Makefile | 1 -
> mm/Makefile | 2 +-
> mm/hugetlb.c | 1 +
> {lib => mm}/ioremap.c | 2 +
> mm/pgalloc-track.h | 51 +++++++++++++
> mm/sparse.c | 1 -
> mm/vmalloc.c | 1 +
> 151 files changed, 194 insertions(+), 451 deletions(-)
> rename {lib => mm}/ioremap.c (99%)
> create mode 100644 mm/pgalloc-track.h
>
> --
> 2.26.2
>
--
Sincerely yours,
Mike.
^ permalink raw reply
* [PATCH 0/2] ASoC: fsl-asoc-card: add support for generic codecs
From: Arnaud Ferraris @ 2020-07-02 14:11 UTC (permalink / raw)
Cc: devicetree, alsa-devel, linuxppc-dev, Timur Tabi, Xiubo Li,
linux-kernel, Takashi Iwai, Liam Girdwood, Rob Herring,
Jaroslav Kysela, Nicolin Chen, Mark Brown, kernel, Fabio Estevam
fsl-asoc-card currently only works with AC97 or a selection of codecs,
although the hardware is capable of more.
Supporting generic codecs when acting as I2S slave (codec is master)
would be useful, especially when using Bluetooth audio, as these are
generally simple I2S devices not controlled by the sound subsystem.
This will allow using simple/dummy codecs along with ASRC.
Arnaud Ferraris (2):
dt-bindings: sound: fsl-asoc-card: add new compatible for I2S slave
ASoC: fsl-asoc-card: add support for generic I2S slave use-case
Documentation/devicetree/bindings/sound/fsl-asoc-card.txt | 23 ++++++++++++++++++++++-
sound/soc/fsl/fsl-asoc-card.c | 46 +++++++++++++++++++++++++++++++++++-----------
2 files changed, 57 insertions(+), 12 deletions(-)
^ permalink raw reply
* [PATCH 1/2] dt-bindings: sound: fsl-asoc-card: add new compatible for I2S slave
From: Arnaud Ferraris @ 2020-07-02 14:11 UTC (permalink / raw)
Cc: devicetree, alsa-devel, linuxppc-dev, Timur Tabi, Xiubo Li,
linux-kernel, Takashi Iwai, Liam Girdwood, Rob Herring,
Jaroslav Kysela, Nicolin Chen, Mark Brown, kernel, Fabio Estevam
In-Reply-To: <20200702141114.232688-1-arnaud.ferraris@collabora.com>
fsl-asoc-card currently doesn't support generic codecs with the SoC
acting as I2S slave.
This commit adds a new `fsl,imx-audio-i2s-slave` for this use-case, as
well as the following mandatory properties:
- `audio-codec-dai-name` for specifying the codec DAI to be used
- `audio-slot-width`
Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
---
.../bindings/sound/fsl-asoc-card.txt | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index 133d7e14a4d0..694a138df462 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -22,6 +22,8 @@ Note: The card is initially designed for those sound cards who use AC'97, I2S
The compatible list for this generic sound card currently:
"fsl,imx-audio-ac97"
+ "fsl,imx-audio-i2s-slave"
+
"fsl,imx-audio-cs42888"
"fsl,imx-audio-cs427x"
@@ -75,7 +77,13 @@ Optional unless SSI is selected as a CPU DAI:
- mux-ext-port : The external port of the i.MX audio muxer
-Example:
+Optional unless compatible is "fsl,imx-audio-i2s-slave":
+
+ - audio-codec-dai-name: The name of the DAI provided by the codec
+
+ - audio-slot-width : The audio sample format
+
+Examples:
sound-cs42888 {
compatible = "fsl,imx-audio-cs42888";
model = "cs42888-audio";
@@ -96,3 +104,16 @@ sound-cs42888 {
"AIN2L", "Line In Jack",
"AIN2R", "Line In Jack";
};
+
+sound-bluetooth {
+ compatible = "fsl,imx-audio-i2s-slave";
+ audio-cpu = <&ssi1>;
+ audio-codec = <&codec_bluetooth>;
+ audio-codec-dai-name = "bt-sco-pcm-wb";
+ audio-slot-width = <16>;
+ audio-routing =
+ "RX", "Mic Jack",
+ "Headphone Jack", "TX";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+};
--
2.27.0
^ permalink raw reply related
* [PATCH 2/2] ASoC: fsl-asoc-card: add support for generic I2S slave use-case
From: Arnaud Ferraris @ 2020-07-02 14:11 UTC (permalink / raw)
Cc: devicetree, alsa-devel, linuxppc-dev, Timur Tabi, Xiubo Li,
linux-kernel, Takashi Iwai, Liam Girdwood, Rob Herring,
Jaroslav Kysela, Nicolin Chen, Mark Brown, kernel, Fabio Estevam
In-Reply-To: <20200702141114.232688-1-arnaud.ferraris@collabora.com>
This commit implements support for generic codecs with the SoC acting as
I2S slave, by implementing the new `fsl,imx-audio-i2s-slave` compatible
and related properties.
This is particularly useful when using a Bluetooth controller acting as
I2S master, but other simple or dummy codecs might benefit from it too.
Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
---
sound/soc/fsl/fsl-asoc-card.c | 46 ++++++++++++++++++++++++++---------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 57ea1b072326..6076b963c873 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -166,12 +166,15 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
return 0;
/* Specific configurations of DAIs starts from here */
- ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), cpu_priv->sysclk_id[tx],
- cpu_priv->sysclk_freq[tx],
- cpu_priv->sysclk_dir[tx]);
- if (ret && ret != -ENOTSUPP) {
- dev_err(dev, "failed to set sysclk for cpu dai\n");
- return ret;
+ if (cpu_priv->sysclk_freq[tx] > 0) {
+ ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0),
+ cpu_priv->sysclk_id[tx],
+ cpu_priv->sysclk_freq[tx],
+ cpu_priv->sysclk_dir[tx]);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(dev, "failed to set sysclk for cpu dai\n");
+ return ret;
+ }
}
if (cpu_priv->slot_width) {
@@ -475,11 +478,14 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
return 0;
}
- ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
- codec_priv->mclk_freq, SND_SOC_CLOCK_IN);
- if (ret && ret != -ENOTSUPP) {
- dev_err(dev, "failed to set sysclk in %s\n", __func__);
- return ret;
+ if (codec_priv->mclk_freq > 0) {
+ ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
+ codec_priv->mclk_freq,
+ SND_SOC_CLOCK_IN);
+ if (ret && ret != -ENOTSUPP) {
+ dev_err(dev, "failed to set sysclk in %s\n", __func__);
+ return ret;
+ }
}
return 0;
@@ -620,6 +626,23 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
priv->cpu_priv.slot_width = 32;
priv->card.dapm_routes = audio_map_tx;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
+ } else if (of_device_is_compatible(np, "fsl,imx-audio-i2s-slave")) {
+ ret = of_property_read_string(np, "audio-codec-dai-name",
+ &codec_dai_name);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get codec DAI name\n");
+ ret = -EINVAL;
+ goto asrc_fail;
+ }
+ ret = of_property_read_u32(np, "audio-slot-width",
+ &priv->cpu_priv.slot_width);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get slot width\n");
+ ret = -EINVAL;
+ goto asrc_fail;
+ }
+ priv->card.set_bias_level = NULL;
+ priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
} else {
dev_err(&pdev->dev, "unknown Device Tree compatible\n");
ret = -EINVAL;
@@ -763,6 +786,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
static const struct of_device_id fsl_asoc_card_dt_ids[] = {
{ .compatible = "fsl,imx-audio-ac97", },
+ { .compatible = "fsl,imx-audio-i2s-slave", },
{ .compatible = "fsl,imx-audio-cs42888", },
{ .compatible = "fsl,imx-audio-cs427x", },
{ .compatible = "fsl,imx-audio-sgtl5000", },
--
2.27.0
^ permalink raw reply related
* [PATCH 0/4] ASoC: fsl_asrc: allow selecting arbitrary clocks
From: Arnaud Ferraris @ 2020-07-02 14:22 UTC (permalink / raw)
Cc: devicetree, alsa-devel, linuxppc-dev, Timur Tabi, Xiubo Li,
linux-kernel, Takashi Iwai, Liam Girdwood, Rob Herring,
Jaroslav Kysela, Nicolin Chen, Mark Brown, kernel, Fabio Estevam
The current ASRC driver hardcodes the input and output clocks used for
sample rate conversions. In order to allow greater flexibility and to
cover more use cases, it would be preferable to select the clocks using
device-tree properties.
This series also fix register configuration and clock assignment so
conversion can be conducted effectively in both directions with a good
quality.
Arnaud Ferraris (4):
dt-bindings: sound: fsl,asrc: add properties to select in/out clocks
ASoC: fsl_asrc: allow using arbitrary input and output clocks
ASoC: fsl_asrc: always use ratio for conversion
ASoC: fsl_asrc: swap input and output clocks in capture mode
Documentation/devicetree/bindings/sound/fsl,asrc.txt | 8 ++++++++
sound/soc/fsl/fsl_asrc.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
sound/soc/fsl/fsl_asrc_common.h | 3 +++
3 files changed, 75 insertions(+), 5 deletions(-)
^ permalink raw reply
* [PATCH 1/4] dt-bindings: sound: fsl, asrc: add properties to select in/out clocks
From: Arnaud Ferraris @ 2020-07-02 14:22 UTC (permalink / raw)
Cc: alsa-devel, devicetree, Arnaud Ferraris, linuxppc-dev, Timur Tabi,
Xiubo Li, linux-kernel, Takashi Iwai, Liam Girdwood, Rob Herring,
Jaroslav Kysela, Nicolin Chen, Mark Brown, kernel, Fabio Estevam
In-Reply-To: <20200702142235.235869-1-arnaud.ferraris@collabora.com>
The ASRC peripheral accepts a wide range of input and output clocks, but
no mechanism exists at the moment to define those as they are currently
hardcoded in the driver.
This commit adds new properties allowing selection of arbitrary input
and output clocks.
Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
---
Documentation/devicetree/bindings/sound/fsl,asrc.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
index 998b4c8a7f78..e26ce9bad617 100644
--- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
@@ -55,6 +55,12 @@ Optional properties:
Ends, which can replace the fsl,asrc-width.
The value is 2 (S16_LE), or 6 (S24_LE).
+ - fsl,asrc-input-clock : Input clock ID, defaults to INCLK_NONE
+ (see enum asrc_inclk in fsl_asrc.h)
+
+ - fsl,asrc-output-clock : Output clock ID, defaults to OUTCLK_ASRCK1_CLK
+ (see enum asrc_outclk in fsl_asrc.h)
+
Example:
asrc: asrc@2034000 {
@@ -77,4 +83,6 @@ asrc: asrc@2034000 {
"txa", "txb", "txc";
fsl,asrc-rate = <48000>;
fsl,asrc-width = <16>;
+ fsl,asrc-input-clock = <0x3>;
+ fsl,asrc-output-clock = <0xf>;
};
--
2.27.0
^ permalink raw reply related
* [PATCH 2/4] ASoC: fsl_asrc: allow using arbitrary input and output clocks
From: Arnaud Ferraris @ 2020-07-02 14:22 UTC (permalink / raw)
Cc: alsa-devel, devicetree, Arnaud Ferraris, linuxppc-dev, Timur Tabi,
Xiubo Li, linux-kernel, Takashi Iwai, Liam Girdwood, Rob Herring,
Jaroslav Kysela, Nicolin Chen, Mark Brown, kernel, Fabio Estevam
In-Reply-To: <20200702142235.235869-1-arnaud.ferraris@collabora.com>
fsl_asrc currently uses hardcoded input and output clocks, preventing
its use for anything other than S/PDIF output.
This patch adds the ability to select any clock as input or output (by
using new DT properties), making it possible to use this peripheral in a
more advanced way.
Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
---
sound/soc/fsl/fsl_asrc.c | 18 ++++++++++++++++--
sound/soc/fsl/fsl_asrc_common.h | 3 +++
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 95f6a9617b0b..75df220e4b51 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -605,8 +605,8 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
config.pair = pair->index;
config.channel_num = channels;
- config.inclk = INCLK_NONE;
- config.outclk = OUTCLK_ASRCK1_CLK;
+ config.inclk = asrc->inclk;
+ config.outclk = asrc->outclk;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
config.input_format = params_format(params);
@@ -1067,6 +1067,20 @@ static int fsl_asrc_probe(struct platform_device *pdev)
asrc->channel_avail = 10;
+ ret = of_property_read_u32(np, "fsl,asrc-input-clock",
+ &asrc->inclk);
+ if (ret) {
+ dev_info(&pdev->dev, "no input clock specified, using none\n");
+ asrc->inclk = INCLK_NONE;
+ }
+
+ ret = of_property_read_u32(np, "fsl,asrc-output-clock",
+ &asrc->outclk);
+ if (ret) {
+ dev_info(&pdev->dev, "no output clock specified, using default\n");
+ asrc->outclk = OUTCLK_ASRCK1_CLK;
+ }
+
ret = of_property_read_u32(np, "fsl,asrc-rate",
&asrc->asrc_rate);
if (ret) {
diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h
index 7e1c13ca37f1..1468878fbaca 100644
--- a/sound/soc/fsl/fsl_asrc_common.h
+++ b/sound/soc/fsl/fsl_asrc_common.h
@@ -89,6 +89,9 @@ struct fsl_asrc {
struct fsl_asrc_pair *pair[PAIR_CTX_NUM];
unsigned int channel_avail;
+ enum asrc_inclk inclk;
+ enum asrc_outclk outclk;
+
int asrc_rate;
snd_pcm_format_t asrc_format;
bool use_edma;
--
2.27.0
^ permalink raw reply related
* [PATCH 3/4] ASoC: fsl_asrc: always use ratio for conversion
From: Arnaud Ferraris @ 2020-07-02 14:22 UTC (permalink / raw)
Cc: alsa-devel, devicetree, Arnaud Ferraris, linuxppc-dev, Timur Tabi,
Xiubo Li, linux-kernel, Takashi Iwai, Liam Girdwood, Rob Herring,
Jaroslav Kysela, Nicolin Chen, Mark Brown, kernel, Fabio Estevam
In-Reply-To: <20200702142235.235869-1-arnaud.ferraris@collabora.com>
Even when not in "Ideal Ratio" mode, ASRC can use an internally measured
ratio, which greatly improves the conversion quality.
This patch ensures we always use at least the internal ratio.
Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
---
sound/soc/fsl/fsl_asrc.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 75df220e4b51..65e7307a3df0 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -451,7 +451,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
regmap_update_bits(asrc->regmap, REG_ASRCTR,
ASRCTR_ATSi_MASK(index), ASRCTR_ATS(index));
regmap_update_bits(asrc->regmap, REG_ASRCTR,
- ASRCTR_USRi_MASK(index), 0);
+ ASRCTR_USRi_MASK(index), ASRCTR_USR(index));
/* Set the input and output clock sources */
regmap_update_bits(asrc->regmap, REG_ASRCSR,
@@ -493,8 +493,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
/* Enable Ideal Ratio mode */
regmap_update_bits(asrc->regmap, REG_ASRCTR,
- ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
- ASRCTR_IDR(index) | ASRCTR_USR(index));
+ ASRCTR_IDRi_MASK(index), ASRCTR_IDR(index));
fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
--
2.27.0
^ permalink raw reply related
* [PATCH 4/4] ASoC: fsl_asrc: swap input and output clocks in capture mode
From: Arnaud Ferraris @ 2020-07-02 14:22 UTC (permalink / raw)
Cc: alsa-devel, devicetree, Arnaud Ferraris, linuxppc-dev, Timur Tabi,
Xiubo Li, linux-kernel, Takashi Iwai, Liam Girdwood, Rob Herring,
Jaroslav Kysela, Nicolin Chen, Mark Brown, kernel, Fabio Estevam
In-Reply-To: <20200702142235.235869-1-arnaud.ferraris@collabora.com>
The input clock is the reference clock we need to convert the stream to,
which therefore has to be the clock of the origin stream/device.
When the stream is bi-directional and we want ASRC to act on both
directions, we need to swap the input and output clocks between the
playback and capture streams.
As some of the clocks have different ID's depending on whether they are
used as input or output, this requires adding a new function to find the
output clock ID corresponding to a given input clock.
Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
---
sound/soc/fsl/fsl_asrc.c | 50 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 65e7307a3df0..5aeab1fbcdd9 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -506,6 +506,50 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
}
+/**
+ * Select the output clock corresponding to a given input clock (and vice-versa)
+ *
+ * If we want to setup a capture channel, the input and output clocks have to
+ * be swapped.
+ * However, even if most of the clocks have the same index when used as input
+ * or output, some of them (ESAI, SSI* and SPDIF) are different:
+ * - the TX output clock has the index of the corresponding RX input clock
+ * - the RX output clock has the index of the corresponding TX input clock
+ *
+ * This function makes sure that we use the proper clock index when swapping
+ * the input and output clocks.
+ */
+static enum asrc_outclk fsl_asrc_get_capture_clock(enum asrc_inclk inclk)
+{
+ enum asrc_outclk outclk;
+
+ switch (inclk) {
+ case INCLK_ESAI_RX:
+ case INCLK_SSI1_RX:
+ case INCLK_SSI2_RX:
+ case INCLK_SPDIF_RX:
+ outclk = inclk + 0x8;
+ break;
+ case INCLK_SSI3_RX:
+ outclk = OUTCLK_SSI3_RX;
+ break;
+ case INCLK_ESAI_TX:
+ case INCLK_SSI1_TX:
+ case INCLK_SSI2_TX:
+ case INCLK_SPDIF_TX:
+ outclk = inclk - 0x8;
+ break;
+ case INCLK_SSI3_TX:
+ outclk = OUTCLK_SSI3_TX;
+ break;
+ default:
+ outclk = inclk;
+ break;
+ }
+
+ return outclk;
+}
+
/**
* Start the assigned ASRC pair
*
@@ -604,15 +648,17 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
config.pair = pair->index;
config.channel_num = channels;
- config.inclk = asrc->inclk;
- config.outclk = asrc->outclk;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ config.inclk = asrc->inclk;
+ config.outclk = asrc->outclk;
config.input_format = params_format(params);
config.output_format = asrc->asrc_format;
config.input_sample_rate = rate;
config.output_sample_rate = asrc->asrc_rate;
} else {
+ config.inclk = fsl_asrc_get_capture_clock(asrc->outclk);
+ config.outclk = fsl_asrc_get_capture_clock(asrc->inclk);
config.input_format = asrc->asrc_format;
config.output_format = params_format(params);
config.input_sample_rate = asrc->asrc_rate;
--
2.27.0
^ permalink raw reply related
* Re: [PATCH 09/20] bcache: stop setting ->queuedata
From: Coly Li @ 2020-07-02 14:47 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe
Cc: linux-bcache, linux-xtensa, linux-nvdimm, linux-s390, dm-devel,
linux-nvme, linux-kernel, linux-raid, linux-m68k, linuxppc-dev,
drbd-dev
In-Reply-To: <20200701085947.3354405-10-hch@lst.de>
On 2020/7/1 16:59, Christoph Hellwig wrote:
> Nothing in bcache actually uses the ->queuedata field.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Coly Li <colyli@suse.de>
> ---
> drivers/md/bcache/super.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
> index 2014016f9a60d3..21aa168113d30b 100644
> --- a/drivers/md/bcache/super.c
> +++ b/drivers/md/bcache/super.c
> @@ -876,7 +876,6 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
> return -ENOMEM;
>
> d->disk->queue = q;
> - q->queuedata = d;
> q->backing_dev_info->congested_data = d;
> q->limits.max_hw_sectors = UINT_MAX;
> q->limits.max_sectors = UINT_MAX;
>
^ permalink raw reply
* Re: [PATCH 16/20] block: move ->make_request_fn to struct block_device_operations
From: Coly Li @ 2020-07-02 14:48 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe
Cc: linux-bcache, linux-xtensa, linux-nvdimm, linux-s390, dm-devel,
linux-nvme, linux-kernel, linux-raid, linux-m68k, linuxppc-dev,
drbd-dev
In-Reply-To: <20200701085947.3354405-17-hch@lst.de>
On 2020/7/1 16:59, Christoph Hellwig wrote:
> The make_request_fn is a little weird in that it sits directly in
> struct request_queue instead of an operation vector. Replace it with
> a block_device_operations method called submit_bio (which describes much
> better what it does). Also remove the request_queue argument to it, as
> the queue can be derived pretty trivially from the bio.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
For the bcache part,
Acked-by: Coly Li <colyli@suse.de>
> ---
> Documentation/block/biodoc.rst | 2 +-
> .../block/writeback_cache_control.rst | 2 +-
> arch/m68k/emu/nfblock.c | 5 +-
> arch/xtensa/platforms/iss/simdisk.c | 5 +-
> block/blk-cgroup.c | 2 +-
> block/blk-core.c | 53 +++++++------------
> block/blk-mq.c | 10 ++--
> block/blk.h | 2 -
> drivers/block/brd.c | 5 +-
> drivers/block/drbd/drbd_int.h | 2 +-
> drivers/block/drbd/drbd_main.c | 9 ++--
> drivers/block/drbd/drbd_req.c | 2 +-
> drivers/block/null_blk_main.c | 17 ++++--
> drivers/block/pktcdvd.c | 11 ++--
> drivers/block/ps3vram.c | 15 +++---
> drivers/block/rsxx/dev.c | 7 ++-
> drivers/block/umem.c | 5 +-
> drivers/block/zram/zram_drv.c | 11 ++--
> drivers/lightnvm/core.c | 8 +--
> drivers/lightnvm/pblk-init.c | 12 +++--
> drivers/md/bcache/request.c | 4 +-
> drivers/md/bcache/request.h | 4 +-
> drivers/md/bcache/super.c | 23 +++++---
> drivers/md/dm.c | 23 ++++----
> drivers/md/md.c | 5 +-
> drivers/nvdimm/blk.c | 5 +-
> drivers/nvdimm/btt.c | 5 +-
> drivers/nvdimm/pmem.c | 5 +-
> drivers/nvme/host/core.c | 1 +
> drivers/nvme/host/multipath.c | 5 +-
> drivers/nvme/host/nvme.h | 1 +
> drivers/s390/block/dcssblk.c | 9 ++--
> drivers/s390/block/xpram.c | 6 +--
> include/linux/blk-mq.h | 2 +-
> include/linux/blkdev.h | 7 +--
> include/linux/lightnvm.h | 3 +-
> 36 files changed, 153 insertions(+), 140 deletions(-)
>
[snipped]
> diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
> index 7acf024e99f351..fc5702b10074d6 100644
> --- a/drivers/md/bcache/request.c
> +++ b/drivers/md/bcache/request.c
> @@ -1158,7 +1158,7 @@ static void quit_max_writeback_rate(struct cache_set *c,
>
> /* Cached devices - read & write stuff */
>
> -blk_qc_t cached_dev_make_request(struct request_queue *q, struct bio *bio)
> +blk_qc_t cached_dev_submit_bio(struct bio *bio)
> {
> struct search *s;
> struct bcache_device *d = bio->bi_disk->private_data;
> @@ -1291,7 +1291,7 @@ static void flash_dev_nodata(struct closure *cl)
> continue_at(cl, search_free, NULL);
> }
>
> -blk_qc_t flash_dev_make_request(struct request_queue *q, struct bio *bio)
> +blk_qc_t flash_dev_submit_bio(struct bio *bio)
> {
> struct search *s;
> struct closure *cl;
> diff --git a/drivers/md/bcache/request.h b/drivers/md/bcache/request.h
> index bb005c93dd7218..82b38366a95deb 100644
> --- a/drivers/md/bcache/request.h
> +++ b/drivers/md/bcache/request.h
> @@ -37,10 +37,10 @@ unsigned int bch_get_congested(const struct cache_set *c);
> void bch_data_insert(struct closure *cl);
>
> void bch_cached_dev_request_init(struct cached_dev *dc);
> -blk_qc_t cached_dev_make_request(struct request_queue *q, struct bio *bio);
> +blk_qc_t cached_dev_submit_bio(struct bio *bio);
>
> void bch_flash_dev_request_init(struct bcache_device *d);
> -blk_qc_t flash_dev_make_request(struct request_queue *q, struct bio *bio);
> +blk_qc_t flash_dev_submit_bio(struct bio *bio);
>
> extern struct kmem_cache *bch_search_cache;
>
> diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
> index 21aa168113d30b..de13f6e916966d 100644
> --- a/drivers/md/bcache/super.c
> +++ b/drivers/md/bcache/super.c
> @@ -680,7 +680,16 @@ static int ioctl_dev(struct block_device *b, fmode_t mode,
> return d->ioctl(d, mode, cmd, arg);
> }
>
> -static const struct block_device_operations bcache_ops = {
> +static const struct block_device_operations bcache_cached_ops = {
> + .submit_bio = cached_dev_submit_bio,
> + .open = open_dev,
> + .release = release_dev,
> + .ioctl = ioctl_dev,
> + .owner = THIS_MODULE,
> +};
> +
> +static const struct block_device_operations bcache_flash_ops = {
> + .submit_bio = flash_dev_submit_bio,
> .open = open_dev,
> .release = release_dev,
> .ioctl = ioctl_dev,
> @@ -820,8 +829,8 @@ static void bcache_device_free(struct bcache_device *d)
> }
>
> static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
> - sector_t sectors, make_request_fn make_request_fn,
> - struct block_device *cached_bdev)
> + sector_t sectors, struct block_device *cached_bdev,
> + const struct block_device_operations *ops)
> {
> struct request_queue *q;
> const size_t max_stripes = min_t(size_t, INT_MAX,
> @@ -868,10 +877,10 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
>
> d->disk->major = bcache_major;
> d->disk->first_minor = idx_to_first_minor(idx);
> - d->disk->fops = &bcache_ops;
> + d->disk->fops = ops;
> d->disk->private_data = d;
>
> - q = blk_alloc_queue(make_request_fn, NUMA_NO_NODE);
> + q = blk_alloc_queue(NUMA_NO_NODE);
> if (!q)
> return -ENOMEM;
>
> @@ -1355,7 +1364,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
>
> ret = bcache_device_init(&dc->disk, block_size,
> dc->bdev->bd_part->nr_sects - dc->sb.data_offset,
> - cached_dev_make_request, dc->bdev);
> + dc->bdev, &bcache_cached_ops);
> if (ret)
> return ret;
>
> @@ -1468,7 +1477,7 @@ static int flash_dev_run(struct cache_set *c, struct uuid_entry *u)
> kobject_init(&d->kobj, &bch_flash_dev_ktype);
>
> if (bcache_device_init(d, block_bytes(c), u->sectors,
> - flash_dev_make_request, NULL))
> + NULL, &bcache_flash_ops))
> goto err;
>
> bcache_device_attach(d, c, u - c->uuids);
^ permalink raw reply
* Re: [PATCH 17/20] block: rename generic_make_request to submit_bio_noacct
From: Coly Li @ 2020-07-02 14:51 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe
Cc: linux-bcache, linux-xtensa, linux-nvdimm, linux-s390, dm-devel,
linux-nvme, linux-kernel, linux-raid, linux-m68k, linuxppc-dev,
drbd-dev
In-Reply-To: <20200701085947.3354405-18-hch@lst.de>
On 2020/7/1 16:59, Christoph Hellwig wrote:
> generic_make_request has always been very confusingly misnamed, so rename
> it to submit_bio_noacct to make it clear that it is submit_bio minus
> accounting and a few checks.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
I will miss generic_make_request(). Anyway, if it is decided, for bcache
part,
Acked-by: Coly Li <colyli@suse.de>
> ---
> Documentation/block/biodoc.rst | 2 +-
> .../fault-injection/fault-injection.rst | 2 +-
> Documentation/trace/ftrace.rst | 4 +--
> block/bio.c | 14 ++++----
> block/blk-core.c | 32 +++++++++----------
> block/blk-crypto-fallback.c | 2 +-
> block/blk-crypto.c | 2 +-
> block/blk-merge.c | 2 +-
> block/blk-throttle.c | 4 +--
> block/bounce.c | 2 +-
> drivers/block/drbd/drbd_int.h | 6 ++--
> drivers/block/drbd/drbd_main.c | 2 +-
> drivers/block/drbd/drbd_receiver.c | 2 +-
> drivers/block/drbd/drbd_req.c | 2 +-
> drivers/block/drbd/drbd_worker.c | 2 +-
> drivers/block/pktcdvd.c | 2 +-
> drivers/lightnvm/pblk-read.c | 2 +-
> drivers/md/bcache/bcache.h | 2 +-
> drivers/md/bcache/btree.c | 2 +-
> drivers/md/bcache/request.c | 7 ++--
> drivers/md/dm-cache-target.c | 6 ++--
> drivers/md/dm-clone-target.c | 10 +++---
> drivers/md/dm-crypt.c | 6 ++--
> drivers/md/dm-delay.c | 2 +-
> drivers/md/dm-era-target.c | 2 +-
> drivers/md/dm-integrity.c | 4 +--
> drivers/md/dm-mpath.c | 2 +-
> drivers/md/dm-raid1.c | 2 +-
> drivers/md/dm-snap-persistent.c | 2 +-
> drivers/md/dm-snap.c | 6 ++--
> drivers/md/dm-thin.c | 4 +--
> drivers/md/dm-verity-target.c | 2 +-
> drivers/md/dm-writecache.c | 2 +-
> drivers/md/dm-zoned-target.c | 2 +-
> drivers/md/dm.c | 10 +++---
> drivers/md/md-faulty.c | 4 +--
> drivers/md/md-linear.c | 4 +--
> drivers/md/md-multipath.c | 4 +--
> drivers/md/raid0.c | 8 ++---
> drivers/md/raid1.c | 14 ++++----
> drivers/md/raid10.c | 28 ++++++++--------
> drivers/md/raid5.c | 10 +++---
> drivers/nvme/host/multipath.c | 2 +-
> include/linux/blkdev.h | 2 +-
> 44 files changed, 115 insertions(+), 118 deletions(-)
>
[snipped]
> diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c
> index 140927ebf41e9a..c28537a489bc10 100644
> --- a/drivers/lightnvm/pblk-read.c
> +++ b/drivers/lightnvm/pblk-read.c
> @@ -320,7 +320,7 @@ void pblk_submit_read(struct pblk *pblk, struct bio *bio)
> split_bio = bio_split(bio, nr_secs * NR_PHY_IN_LOG, GFP_KERNEL,
> &pblk_bio_set);
> bio_chain(split_bio, bio);
> - generic_make_request(bio);
> + submit_bio_noacct(bio);
>
> /* New bio contains first N sectors of the previous one, so
> * we can continue to use existing rqd, but we need to shrink
> diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
> index 221e0191b6870f..3c708e8b5e2d34 100644
> --- a/drivers/md/bcache/bcache.h
> +++ b/drivers/md/bcache/bcache.h
> @@ -929,7 +929,7 @@ static inline void closure_bio_submit(struct cache_set *c,
> bio_endio(bio);
> return;
> }
> - generic_make_request(bio);
> + submit_bio_noacct(bio);
> }
>
> /*
> diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
> index 6548a601edf0e4..d5c51e33204679 100644
> --- a/drivers/md/bcache/btree.c
> +++ b/drivers/md/bcache/btree.c
> @@ -959,7 +959,7 @@ static struct btree *mca_alloc(struct cache_set *c, struct btree_op *op,
> * bch_btree_node_get - find a btree node in the cache and lock it, reading it
> * in from disk if necessary.
> *
> - * If IO is necessary and running under generic_make_request, returns -EAGAIN.
> + * If IO is necessary and running under submit_bio_noacct, returns -EAGAIN.
> *
> * The btree node will have either a read or a write lock held, depending on
> * level and op->lock.
> diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
> index fc5702b10074d6..dd012ebface012 100644
> --- a/drivers/md/bcache/request.c
> +++ b/drivers/md/bcache/request.c
> @@ -1115,7 +1115,7 @@ static void detached_dev_do_request(struct bcache_device *d, struct bio *bio)
> !blk_queue_discard(bdev_get_queue(dc->bdev)))
> bio->bi_end_io(bio);
> else
> - generic_make_request(bio);
> + submit_bio_noacct(bio);
> }
>
> static void quit_max_writeback_rate(struct cache_set *c,
> @@ -1197,7 +1197,7 @@ blk_qc_t cached_dev_submit_bio(struct bio *bio)
> if (!bio->bi_iter.bi_size) {
> /*
> * can't call bch_journal_meta from under
> - * generic_make_request
> + * submit_bio_noacct
> */
> continue_at_nobarrier(&s->cl,
> cached_dev_nodata,
> @@ -1311,8 +1311,7 @@ blk_qc_t flash_dev_submit_bio(struct bio *bio)
>
> if (!bio->bi_iter.bi_size) {
> /*
> - * can't call bch_journal_meta from under
> - * generic_make_request
> + * can't call bch_journal_meta from under submit_bio_noacct
> */
> continue_at_nobarrier(&s->cl,
> flash_dev_nodata,
>
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: sound: fsl-asoc-card: add new compatible for I2S slave
From: Arnaud Ferraris @ 2020-07-02 15:28 UTC (permalink / raw)
To: Mark Brown
Cc: devicetree, alsa-devel, linuxppc-dev, Timur Tabi, Xiubo Li,
linux-kernel, Takashi Iwai, Liam Girdwood, Jaroslav Kysela,
Nicolin Chen, Rob Herring, kernel, Fabio Estevam
In-Reply-To: <20200702143145.GG4483@sirena.org.uk>
Hi Mark,
Le 02/07/2020 à 16:31, Mark Brown a écrit :
> On Thu, Jul 02, 2020 at 04:11:14PM +0200, Arnaud Ferraris wrote:
>> fsl-asoc-card currently doesn't support generic codecs with the SoC
>> acting as I2S slave.
>>
>> This commit adds a new `fsl,imx-audio-i2s-slave` for this use-case, as
>> well as the following mandatory properties:
>
> Why require that the CODEC be clock master here - why not make this
> configurable, reusing the properties from the generic and audio graph
> cards?
This is partly because I'm not sure how to do it (yet), but mostly
because I don't have the hardware to test this (the 2 CODECs present on
my only i.MX6 board are both clock master)
Regards,
Arnaud
^ permalink raw reply
* [PATCH] powerpc/powernv: machine check handler for POWER10
From: Nicholas Piggin @ 2020-07-02 23:33 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/mce.h | 1 +
arch/powerpc/kernel/dt_cpu_ftrs.c | 10 ++++
arch/powerpc/kernel/mce.c | 1 +
arch/powerpc/kernel/mce_power.c | 84 +++++++++++++++++++++++++++++++
4 files changed, 96 insertions(+)
diff --git a/arch/powerpc/include/asm/mce.h b/arch/powerpc/include/asm/mce.h
index 376a395daf32..30b5b03fb11d 100644
--- a/arch/powerpc/include/asm/mce.h
+++ b/arch/powerpc/include/asm/mce.h
@@ -86,6 +86,7 @@ enum MCE_TlbErrorType {
enum MCE_UserErrorType {
MCE_USER_ERROR_INDETERMINATE = 0,
MCE_USER_ERROR_TLBIE = 1,
+ MCE_USER_ERROR_SCV = 2,
};
enum MCE_RaErrorType {
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index 3a409517c031..12cec6919a1a 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -67,6 +67,7 @@ struct dt_cpu_feature {
extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
extern long __machine_check_early_realmode_p9(struct pt_regs *regs);
+extern long __machine_check_early_realmode_p10(struct pt_regs *regs);
static int hv_mode;
@@ -450,6 +451,14 @@ static int __init feat_enable_pmu_power9(struct dt_cpu_feature *f)
return 1;
}
+static int __init feat_enable_mce_power10(struct dt_cpu_feature *f)
+{
+ cur_cpu_spec->platform = "power10";
+ cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p10;
+
+ return 1;
+}
+
static int __init feat_enable_tm(struct dt_cpu_feature *f)
{
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
@@ -638,6 +647,7 @@ static struct dt_cpu_feature_match __initdata
{"group-start-register", feat_enable, 0},
{"pc-relative-addressing", feat_enable, 0},
{"machine-check-power9", feat_enable_mce_power9, 0},
+ {"machine-check-power10", feat_enable_mce_power10, 0},
{"performance-monitor-power9", feat_enable_pmu_power9, 0},
{"event-based-branch-v3", feat_enable, 0},
{"random-number-generator", feat_enable, 0},
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
index fd90c0eda229..4f96f3c24797 100644
--- a/arch/powerpc/kernel/mce.c
+++ b/arch/powerpc/kernel/mce.c
@@ -370,6 +370,7 @@ void machine_check_print_event_info(struct machine_check_event *evt,
static const char *mc_user_types[] = {
"Indeterminate",
"tlbie(l) invalid",
+ "scv invalid",
};
static const char *mc_ra_types[] = {
"Indeterminate",
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index c3b522bff9b4..b7e173754a2e 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -243,6 +243,45 @@ static const struct mce_ierror_table mce_p9_ierror_table[] = {
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
{ 0, 0, 0, 0, 0, 0, 0 } };
+static const struct mce_ierror_table mce_p10_ierror_table[] = {
+{ 0x00000000081c0000, 0x0000000000040000, true,
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000000081c0000, 0x0000000000080000, true,
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000000081c0000, 0x00000000000c0000, true,
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
+{ 0x00000000081c0000, 0x0000000000100000, true,
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
+{ 0x00000000081c0000, 0x0000000000140000, true,
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
+{ 0x00000000081c0000, 0x0000000000180000, true,
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000000081c0000, 0x00000000001c0000, true,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH_FOREIGN, MCE_ECLASS_SOFTWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000000081c0000, 0x0000000008080000, true,
+ MCE_ERROR_TYPE_USER,MCE_USER_ERROR_SCV, MCE_ECLASS_SOFTWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
+{ 0x00000000081c0000, 0x00000000080c0000, true,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH, MCE_ECLASS_SOFTWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000000081c0000, 0x0000000008100000, true,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_SOFTWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000000081c0000, 0x0000000008140000, false,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_STORE, MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_FATAL, false }, /* ASYNC is fatal */
+{ 0x00000000081c0000, 0x00000000081c0000, true, MCE_ECLASS_HARDWARE,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0, 0, 0, 0, 0, 0, 0 } };
+
struct mce_derror_table {
unsigned long dsisr_value;
bool dar_valid; /* dar is a valid indicator of faulting address */
@@ -361,6 +400,46 @@ static const struct mce_derror_table mce_p9_derror_table[] = {
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
{ 0, false, 0, 0, 0, 0, 0 } };
+static const struct mce_derror_table mce_p10_derror_table[] = {
+{ 0x00008000, false,
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00004000, true,
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
+ MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000800, true,
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
+{ 0x00000400, true,
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
+{ 0x00000200, false,
+ MCE_ERROR_TYPE_USER, MCE_USER_ERROR_TLBIE, MCE_ECLASS_SOFTWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
+{ 0x00000080, true,
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, /* Before PARITY */
+ MCE_ECLASS_SOFT_INDETERMINATE,
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
+{ 0x00000100, true,
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000040, true,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD, MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000020, false,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
+ MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000010, false,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN,
+ MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0x00000008, false,
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD_STORE_FOREIGN, MCE_ECLASS_HARDWARE,
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
+{ 0, false, 0, 0, 0, 0, 0 } };
+
static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
uint64_t *phys_addr)
{
@@ -657,3 +736,8 @@ long __machine_check_early_realmode_p9(struct pt_regs *regs)
return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table);
}
+
+long __machine_check_early_realmode_p10(struct pt_regs *regs)
+{
+ return mce_handle_error(regs, mce_p10_derror_table, mce_p10_ierror_table);
+}
--
2.23.0
^ permalink raw reply related
* Re: [PATCH v2 4/4] mm/vmalloc: Hugepage vmalloc mappings
From: Nicholas Piggin @ 2020-07-03 0:15 UTC (permalink / raw)
To: linux-mm, Zefan Li
Cc: linux-arch, Will Deacon, Catalin Marinas, x86, linux-kernel,
Ingo Molnar, Borislav, Petkov, H. Peter Anvin, Thomas, Gleixner,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <d148f86c-b27b-63fb-31d2-35b8f52ec540@huawei.com>
Excerpts from Zefan Li's message of July 1, 2020 5:10 pm:
>> static void *__vmalloc_node(unsigned long size, unsigned long align,
>> - gfp_t gfp_mask, pgprot_t prot,
>> - int node, const void *caller);
>> + gfp_t gfp_mask, pgprot_t prot, unsigned long vm_flags,
>> + int node, const void *caller);
>> static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
>> - pgprot_t prot, int node)
>> + pgprot_t prot, unsigned int page_shift,
>> + int node)
>> {
>> struct page **pages;
>> + unsigned long addr = (unsigned long)area->addr;
>> + unsigned long size = get_vm_area_size(area);
>> + unsigned int page_order = page_shift - PAGE_SHIFT;
>> unsigned int nr_pages, array_size, i;
>> const gfp_t nested_gfp = (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO;
>> const gfp_t alloc_mask = gfp_mask | __GFP_NOWARN;
>> const gfp_t highmem_mask = (gfp_mask & (GFP_DMA | GFP_DMA32)) ?
>> - 0 :
>> - __GFP_HIGHMEM;
>> + 0 : __GFP_HIGHMEM;
>>
>> - nr_pages = get_vm_area_size(area) >> PAGE_SHIFT;
>> + nr_pages = size >> page_shift;
>
> while try out this patchset, we encountered a BUG_ON in account_kernel_stack()
> in kernel/fork.c.
>
> BUG_ON(vm->nr_pages != THREAD_SIZE / PAGE_SIZE);
>
> which obviously should be updated accordingly.
Thanks for finding that. We may have to change this around a bit so
nr_pages still appears to be in PAGE_SIZE units for anybody looking.
Thanks,
Nick
^ permalink raw reply
* Re: [PATCH 6/8] powerpc/pseries: implement paravirt qspinlocks for SPLPAR
From: Waiman Long @ 2020-07-03 0:36 UTC (permalink / raw)
To: Nicholas Piggin
Cc: kbuild-all, kernel test robot, Peter Zijlstra, linuxppc-dev,
Boqun Feng, linux-kernel, virtualization, Ingo Molnar,
Will Deacon
In-Reply-To: <202007030059.nT5quxzB%lkp@intel.com>
On 7/2/20 12:15 PM, kernel test robot wrote:
> Hi Nicholas,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on powerpc/next]
> [also build test ERROR on tip/locking/core v5.8-rc3 next-20200702]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-queued-spinlocks-and-rwlocks/20200702-155158
> base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
> config: powerpc-allyesconfig (attached as .config)
> compiler: powerpc64-linux-gcc (GCC) 9.3.0
> reproduce (this is a W=1 build):
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
> kernel/locking/lock_events.c:61:16: warning: no previous prototype for 'lockevent_read' [-Wmissing-prototypes]
> 61 | ssize_t __weak lockevent_read(struct file *file, char __user *user_buf,
> | ^~~~~~~~~~~~~~
> kernel/locking/lock_events.c: In function 'skip_lockevent':
>>> kernel/locking/lock_events.c:126:12: error: implicit declaration of function 'pv_is_native_spin_unlock' [-Werror=implicit-function-declaration]
> 126 | pv_on = !pv_is_native_spin_unlock();
> | ^~~~~~~~~~~~~~~~~~~~~~~~
> cc1: some warnings being treated as errors
>
> vim +/pv_is_native_spin_unlock +126 kernel/locking/lock_events.c
I think you will need to add the following into
arch/powerpc/include/asm/qspinlock_paravirt.h:
static inline pv_is_native_spin_unlock(void)
{
return !is_shared_processor();
}
Cheers,
Longman
^ permalink raw reply
* [Bug 208181] BUG: KASAN: stack-out-of-bounds in strcmp+0x58/0xd8
From: bugzilla-daemon @ 2020-07-03 1:12 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-208181-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=208181
--- Comment #14 from Erhard F. (erhard_f@mailbox.org) ---
Ah, I've overlooked that...
To set CONFIG_DATA_SHIFT=25 I needed to set ADVANCED_OPTIONS=y,
DATA_SHIFT_BOOL=y first.
But with CONFIG_DATA_SHIFT=25 this kernel won't boot at all. OpenFirmware shows
for a brief moment that the kernel gets loaded and then I get dropped back to
OF console.
OpenFirmware tells me:
Invalid memory access at %SRR0: a0000000 %SRR1: 00000000
--
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* [PATCH v2 0/3] remove PROT_SAO support and disable
From: Nicholas Piggin @ 2020-07-03 1:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-mm, kvm-ppc, Nicholas Piggin, linux-api
It was suggested that I post this to a wider audience on account of
the change to supported userspace features in patch 2 particularly.
Thanks,
Nick
Nicholas Piggin (3):
powerpc: remove stale calc_vm_prot_bits comment
powerpc/64s: remove PROT_SAO support
powerpc/64s/hash: disable subpage_prot syscall by default
arch/powerpc/Kconfig | 7 +++-
arch/powerpc/configs/powernv_defconfig | 1 -
arch/powerpc/configs/pseries_defconfig | 1 -
arch/powerpc/include/asm/book3s/64/pgtable.h | 8 ++--
arch/powerpc/include/asm/cputable.h | 10 ++---
arch/powerpc/include/asm/kvm_book3s_64.h | 5 ++-
arch/powerpc/include/asm/mman.h | 30 ++-----------
arch/powerpc/include/asm/nohash/64/pgtable.h | 2 -
arch/powerpc/include/uapi/asm/mman.h | 2 +-
arch/powerpc/kernel/dt_cpu_ftrs.c | 2 +-
arch/powerpc/mm/book3s64/hash_utils.c | 2 -
include/linux/mm.h | 2 -
include/trace/events/mmflags.h | 2 -
mm/ksm.c | 4 --
tools/testing/selftests/powerpc/mm/.gitignore | 1 -
tools/testing/selftests/powerpc/mm/Makefile | 4 +-
tools/testing/selftests/powerpc/mm/prot_sao.c | 42 -------------------
17 files changed, 25 insertions(+), 100 deletions(-)
delete mode 100644 tools/testing/selftests/powerpc/mm/prot_sao.c
--
2.23.0
^ permalink raw reply
* [PATCH v2 1/3] powerpc: remove stale calc_vm_prot_bits comment
From: Nicholas Piggin @ 2020-07-03 1:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-mm, kvm-ppc, Nicholas Piggin, linux-api
In-Reply-To: <20200703011958.1166620-1-npiggin@gmail.com>
This comment is wrong, we wouldn't use calc_vm_prot_bits here because
we are being called by calc_vm_prot_bits to modify its behaviour.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/mman.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/arch/powerpc/include/asm/mman.h b/arch/powerpc/include/asm/mman.h
index d610c2e07b28..4ba303ea27f5 100644
--- a/arch/powerpc/include/asm/mman.h
+++ b/arch/powerpc/include/asm/mman.h
@@ -13,10 +13,6 @@
#include <linux/pkeys.h>
#include <asm/cpu_has_feature.h>
-/*
- * This file is included by linux/mman.h, so we can't use cacl_vm_prot_bits()
- * here. How important is the optimization?
- */
static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
unsigned long pkey)
{
--
2.23.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox