Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 08/13] arm: Add support for multi memory regions
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510140441.24573-1-julien.grall@arm.com>

Currently, the RAM will always be contiguous and start 2GB. This patch
is giving the possibility to the user to specificy multiple RAM region
and

Note that at the moment it is not possible to place any RAM region below
2GB as the MMIO region is still static.

The implementation for multi memory regions is fairly straight-forward,
althought it the following points are worth to be mention:
    - The banks are sorted by base address, so it is easier to fetch the
    lowest bank later on and do sanity checking
    - If the user does not specify the address of the first bank, the
    old behavior is kept.

Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 arm/aarch32/include/kvm/kvm-arch.h |   2 +-
 arm/aarch64/include/kvm/kvm-arch.h |   4 +-
 arm/fdt.c                          |  17 +++--
 arm/include/arm-common/kvm-arch.h  |  20 ++++--
 arm/kvm.c                          | 125 ++++++++++++++++++++++++++++---------
 5 files changed, 125 insertions(+), 43 deletions(-)

diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
index cd31e72..2ee0cb1 100644
--- a/arm/aarch32/include/kvm/kvm-arch.h
+++ b/arm/aarch32/include/kvm/kvm-arch.h
@@ -3,7 +3,7 @@
 
 #define ARM_KERN_OFFSET(...)	0x8000
 
-#define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
+#define ARM_MAX_PHYS_SHIFT(...)	32
 
 #include "arm-common/kvm-arch.h"
 
diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index 1b3d0a5..53ac20f 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -5,9 +5,7 @@
 				0x8000				:	\
 				0x80000)
 
-#define ARM_MAX_MEMORY(cfg)	((cfg)->arch.aarch32_guest	?	\
-				ARM_LOMAP_MAX_MEMORY		:	\
-				ARM_HIMAP_MAX_MEMORY)
+#define ARM_MAX_PHYS_SHIFT(cfg)	((cfg)->arch.aarch32_guest ? 32 : 40)
 
 #include "arm-common/kvm-arch.h"
 
diff --git a/arm/fdt.c b/arm/fdt.c
index 6ac0b33..add9dea 100644
--- a/arm/fdt.c
+++ b/arm/fdt.c
@@ -114,10 +114,7 @@ static int setup_fdt(struct kvm *kvm)
 {
 	struct device_header *dev_hdr;
 	u8 staging_fdt[FDT_MAX_SIZE];
-	u64 mem_reg_prop[]	= {
-		cpu_to_fdt64(kvm->arch.memory_guest_start),
-		cpu_to_fdt64(kvm->ram[0].size),
-	};
+	fdt64_t mem_reg_prop[2 * MAX_RAM_BANKS];
 	struct psci_fns *fns;
 	void *fdt		= staging_fdt;
 	void *fdt_dest		= guest_flat_to_host(kvm,
@@ -126,6 +123,8 @@ static int setup_fdt(struct kvm *kvm)
 					void (*)(void *, u8, enum irq_type));
 	void (*generate_cpu_peripheral_fdt_nodes)(void *, struct kvm *)
 					= kvm->cpus[0]->generate_fdt_nodes;
+	unsigned int i;
+	const struct kvm_config *cfg = &kvm->cfg;
 
 	/* Create new tree without a reserve map */
 	_FDT(fdt_create(fdt, FDT_MAX_SIZE));
@@ -158,9 +157,17 @@ static int setup_fdt(struct kvm *kvm)
 	_FDT(fdt_end_node(fdt));
 
 	/* Memory */
+	for (i = 0; i < cfg->nr_ram; i++) {
+		fdt64_t *reg = &mem_reg_prop[i * 2];
+
+		reg[0] = cpu_to_fdt64(cfg->ram[i].base);
+		reg[1] = cpu_to_fdt64(cfg->ram[i].size);
+	}
+
 	_FDT(fdt_begin_node(fdt, "memory"));
 	_FDT(fdt_property_string(fdt, "device_type", "memory"));
-	_FDT(fdt_property(fdt, "reg", mem_reg_prop, sizeof(mem_reg_prop)));
+	_FDT(fdt_property(fdt, "reg", mem_reg_prop,
+			  2 * sizeof(fdt64_t) * cfg->nr_ram));
 	_FDT(fdt_end_node(fdt));
 
 	/* CPU and peripherals (interrupt controller, timers, etc) */
diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h
index b9d486d..884dda8 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -12,9 +12,6 @@
 #define ARM_AXI_AREA		_AC(0x0000000040000000, UL)
 #define ARM_MEMORY_AREA		_AC(0x0000000080000000, UL)
 
-#define ARM_LOMAP_MAX_MEMORY	((1ULL << 32) - ARM_MEMORY_AREA)
-#define ARM_HIMAP_MAX_MEMORY	((1ULL << 40) - ARM_MEMORY_AREA)
-
 #define ARM_GIC_DIST_BASE	(ARM_AXI_AREA - ARM_GIC_DIST_SIZE)
 #define ARM_GIC_CPUI_BASE	(ARM_GIC_DIST_BASE - ARM_GIC_CPUI_SIZE)
 #define ARM_GIC_SIZE		(ARM_GIC_DIST_SIZE + ARM_GIC_CPUI_SIZE)
@@ -34,6 +31,8 @@
 
 #define KVM_IOEVENTFD_HAS_PIO	0
 
+#define ARM_MAX_PHYS_ADDR(cfg)	(1UL << ARM_MAX_PHYS_SHIFT(cfg))
+
 /*
  * On a GICv3 there must be one redistributor per vCPU.
  * The value here is the size for one, we multiply this@runtime with
@@ -56,18 +55,27 @@ static inline bool arm_addr_in_ioport_region(u64 phys_addr)
 	return phys_addr >= KVM_IOPORT_AREA && phys_addr < limit;
 }
 
+#define MAX_RAM_BANKS	8
+
+#define ARCH_SUPPORT_CFG_RAM_BASE 1
+
+struct kvm_arch_ram_region
+{
+	void	*start;
+	u64	size;
+};
+
 struct kvm_arch {
 	/*
 	 * We may have to align the guest memory for virtio, so keep the
 	 * original pointers here for munmap.
 	 */
-	void	*ram_alloc_start;
-	u64	ram_alloc_size;
+	struct kvm_arch_ram_region ram_alloc[MAX_RAM_BANKS];
 
 	/*
 	 * Guest addresses for memory layout.
 	 */
-	u64	memory_guest_start;
+	unsigned int	nr_mem_banks;
 	u64	kern_guest_start;
 	u64	initrd_guest_start;
 	u64	initrd_size;
diff --git a/arm/kvm.c b/arm/kvm.c
index 34abe69..8a7c611 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -11,6 +11,8 @@
 #include <linux/kvm.h>
 #include <linux/sizes.h>
 
+#include <stdlib.h>
+
 struct kvm_ext kvm_req_ext[] = {
 	{ DEFINE_KVM_EXT(KVM_CAP_IRQCHIP) },
 	{ DEFINE_KVM_EXT(KVM_CAP_ONE_REG) },
@@ -24,14 +26,15 @@ bool kvm__arch_cpu_supports_vm(void)
 	return true;
 }
 
-static void kvm__init_ram(struct kvm *kvm)
+static void kvm__init_ram(struct kvm *kvm,
+			  const struct kvm_ram_config *ram_cfg,
+			  struct kvm_ram_region *ram,
+			  struct kvm_arch_ram_region *ram_alloc)
 {
 	int err;
-	u64 phys_start;
 	unsigned long alignment;
 	/* Convenience aliases */
 	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
-	struct kvm_ram_region *ram = &kvm->ram[0];
 
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
@@ -45,37 +48,42 @@ static void kvm__init_ram(struct kvm *kvm)
 		alignment = SZ_32M;
 	else
 		alignment = SZ_2M;
-	ram->size = kvm->cfg.ram[0].size;
-	kvm->arch.ram_alloc_size = ram->size + alignment;
-	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
-						kvm->arch.ram_alloc_size);
+	ram->size = ram_cfg->size;
+	ram_alloc->size = ram->size + alignment;
+	ram_alloc->start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
+						  ram_alloc->size);
 
-	if (kvm->arch.ram_alloc_start == MAP_FAILED)
+	if (ram_alloc->start == MAP_FAILED)
 		die("Failed to map %lld bytes for guest memory (%d)",
-		    kvm->arch.ram_alloc_size, errno);
-
-	ram->start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
-				   SZ_2M);
+		    ram_alloc->size, errno);
 
-	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
-		MADV_MERGEABLE);
+	ram->start = (void *)ALIGN((unsigned long)ram_alloc->start, SZ_2M);
 
-	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
-		MADV_HUGEPAGE);
+	madvise(ram_alloc->start, ram_alloc->size, MADV_MERGEABLE);
 
-	phys_start	= ARM_MEMORY_AREA;
+	madvise(ram_alloc->start, ram_alloc->size, MADV_HUGEPAGE);
 
-	err = kvm__register_mem(kvm, phys_start, ram->size, ram->start);
+	err = kvm__register_mem(kvm, ram_cfg->base, ram_cfg->size,
+				ram->start);
 	if (err)
 		die("Failed to register %lld bytes of memory at physical "
-		    "address 0x%llx [err %d]", ram->size, phys_start, err);
-
-	kvm->arch.memory_guest_start = phys_start;
+		    "address 0x%llx [err %d]",
+		    ram_cfg->size,
+		    ram_cfg->base,
+		    err);
+
+	pr_info("Registered memory bank 0x%llx-0x%llx\n",
+		ram_cfg->base,
+		ram_cfg->base + ram_cfg->size);
 }
 
 void kvm__arch_delete_ram(struct kvm *kvm)
 {
-	munmap(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size);
+	unsigned int i;
+
+	for (i = 0; i < kvm->nr_ram; i++)
+		munmap(kvm->arch.ram_alloc[i].start,
+		       kvm->arch.ram_alloc[i].size);
 }
 
 void kvm__arch_read_term(struct kvm *kvm)
@@ -88,27 +96,86 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 {
 }
 
+/* Only sort the bank by base address */
+static int cmp_bank(const void *p1, const void *p2)
+{
+	const struct kvm_ram_config *bank1 = p1;
+	const struct kvm_ram_config *bank2 = p2;
+
+	if (bank1->base < bank2->base)
+		return -1;
+	else if (bank1->base == bank2->base)
+		return 0;
+	else
+		return 1;
+}
+
 static void kvm__arch_sanitize_cfg(struct kvm_config *cfg)
 {
+	unsigned int i;
 	/* Convenience aliases */
 	struct kvm_ram_config *bank0 = &cfg->ram[0];
 
-	if (bank0->size > ARM_MAX_MEMORY(cfg)) {
-		bank0->size = ARM_MAX_MEMORY(cfg);
-		pr_warning("sanitize: Capping memory to %lluMB",
-			   bank0->size >> 20);
+	/*
+	 * The user may not have set an address for the first bank. (To keep the
+	 * command line backward compatible).
+	 */
+	if (bank0->base == INVALID_RAM_ADDR) {
+		/*
+		 * Impose the user to set address for the first bank when
+		 * multiple banks are specified.
+		 */
+		if (cfg->nr_ram > 1)
+			die("sanitize: Base address should be specified for all the banks\n");
+		bank0->base = ARM_MEMORY_AREA;
+		/*
+		 * Keep compatibility with old KVM command line behavior where
+		 * the memory is capped.
+		 */
+		if ((bank0->base + bank0->size) > ARM_MAX_PHYS_ADDR(cfg)) {
+			bank0->size = ARM_MAX_PHYS_ADDR(cfg) - bank0->base;
+			pr_warning("sanitize: Capping memory to %lluMB",
+				   bank0->size >> 20);
+		}
 	}
+
+	/* Sort banks by address to make easier later on. */
+	qsort(cfg->ram, cfg->nr_ram, sizeof(*cfg->ram), cmp_bank);
+
+	/* Check banks are not overlapping */
+	for (i = 1; i < cfg->nr_ram; i++) {
+		const struct kvm_ram_config *bank1 = &cfg->ram[i - 1];
+		const struct kvm_ram_config *bank2 = &cfg->ram[i];
+		unsigned long long end1 = bank1->base + bank1->size - 1;
+		unsigned long long end2 = bank2->base + bank2->size - 1;
+
+		if (!((end1 < bank2->base) || (bank1->base > end2)))
+			die("Memory bank 0x%llx-0x%llx overlapping with 0x%llx-0x%llx\n",
+			    bank1->base, end1, bank2->base, end2);
+	}
+
+	/* Check the memory is below the IPA size supported */
+	i = cfg->nr_ram - 1;
+	if ((cfg->ram[i].base + cfg->ram[i].size) > ARM_MAX_PHYS_ADDR(cfg))
+		die("Memory bank outside of the maximum IPA\n");
 }
 
 void kvm__arch_init(struct kvm *kvm)
 {
+	unsigned int i;
+	/* Convenience aliases */
+	struct kvm_config *cfg = &kvm->cfg;
+
 	kvm__arch_sanitize_cfg(&kvm->cfg);
 
 	/* Create the virtual GIC. */
 	if (gic__create(kvm, kvm->cfg.arch.irqchip))
 		die("Failed to create virtual GIC");
 
-	kvm__init_ram(kvm);
+	for (i = 0; i < cfg->nr_ram; i++)
+		kvm__init_ram(kvm, &cfg->ram[i], &kvm->ram[i],
+			      &kvm->arch.ram_alloc[i]);
+	kvm->nr_ram = cfg->nr_ram;
 }
 
 #define FDT_ALIGN	SZ_2M
@@ -125,6 +192,8 @@ bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
 	/*
 	 * Linux requires the initrd and dtb to be mapped inside lowmem,
 	 * so we can't just place them at the top of memory.
+	 *
+	 * Let's place it in the first memory bank.
 	 */
 	limit = ram0->start + min(ram0->size, (u64)SZ_256M) - 1;
 
@@ -133,7 +202,7 @@ bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
 	file_size = read_file(fd_kernel, pos, limit - pos);
 	if (file_size < 0) {
 		if (errno == ENOMEM)
-			die("kernel image too big to contain in guest memory.");
+			die("kernel image too big to contain in the first memory bank of the guest.");
 
 		die_perror("kernel read");
 	}
-- 
2.11.0

^ permalink raw reply related

* [RFC 07/13] Allow the user to specify where the RAM is placed in the memory
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510140441.24573-1-julien.grall@arm.com>

At the moment the user is only able to give the amount of memory used by
the guest. The placement of the RAM in the layout is left to the
software. It would be useful to give more freedom to the user where the
RAM regions will live in the memory layout and the size of them.

The command line to specify the size of the memory (-m/-mem) is now extended
in a compatible way to allow specifiying the base address: <size>[@<addr>].

The <addr> is mandatory if the option is specified multiple (i.e the
user request).

As not all the architecture will support multiple RAM region or even
specificying the address, it is left to the architecture to enable the
feature (see MAX_RAM_BANKS and ARCH_SUPPORT_CFG_RAM_BASE).

At the moment no-one is taking advantages of it, this will change in a
follow-up patch.

Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 arm/fdt.c                |  2 +-
 arm/kvm.c                | 33 +++++++++---------
 builtin-run.c            | 87 +++++++++++++++++++++++++++++++++++++++++++-----
 include/kvm/kvm-config.h | 16 ++++++++-
 include/kvm/kvm.h        | 21 ++++++++++--
 kvm.c                    |  4 +++
 mips/kvm.c               | 40 ++++++++++++----------
 powerpc/kvm.c            | 26 ++++++++-------
 x86/bios.c               |  8 +++--
 x86/kvm.c                | 47 +++++++++++++++-----------
 10 files changed, 204 insertions(+), 80 deletions(-)

diff --git a/arm/fdt.c b/arm/fdt.c
index 980015b..6ac0b33 100644
--- a/arm/fdt.c
+++ b/arm/fdt.c
@@ -116,7 +116,7 @@ static int setup_fdt(struct kvm *kvm)
 	u8 staging_fdt[FDT_MAX_SIZE];
 	u64 mem_reg_prop[]	= {
 		cpu_to_fdt64(kvm->arch.memory_guest_start),
-		cpu_to_fdt64(kvm->ram_size),
+		cpu_to_fdt64(kvm->ram[0].size),
 	};
 	struct psci_fns *fns;
 	void *fdt		= staging_fdt;
diff --git a/arm/kvm.c b/arm/kvm.c
index daa7425..34abe69 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -27,11 +27,11 @@ bool kvm__arch_cpu_supports_vm(void)
 static void kvm__init_ram(struct kvm *kvm)
 {
 	int err;
-	u64 phys_start, phys_size;
-	void *host_mem;
+	u64 phys_start;
 	unsigned long alignment;
 	/* Convenience aliases */
 	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
+	struct kvm_ram_region *ram = &kvm->ram[0];
 
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
@@ -45,8 +45,8 @@ static void kvm__init_ram(struct kvm *kvm)
 		alignment = SZ_32M;
 	else
 		alignment = SZ_2M;
-	kvm->ram_size = kvm->cfg.ram_size;
-	kvm->arch.ram_alloc_size = kvm->ram_size + alignment;
+	ram->size = kvm->cfg.ram[0].size;
+	kvm->arch.ram_alloc_size = ram->size + alignment;
 	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
 
@@ -54,8 +54,8 @@ static void kvm__init_ram(struct kvm *kvm)
 		die("Failed to map %lld bytes for guest memory (%d)",
 		    kvm->arch.ram_alloc_size, errno);
 
-	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
-					SZ_2M);
+	ram->start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
+				   SZ_2M);
 
 	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
 		MADV_MERGEABLE);
@@ -64,13 +64,11 @@ static void kvm__init_ram(struct kvm *kvm)
 		MADV_HUGEPAGE);
 
 	phys_start	= ARM_MEMORY_AREA;
-	phys_size	= kvm->ram_size;
-	host_mem	= kvm->ram_start;
 
-	err = kvm__register_mem(kvm, phys_start, phys_size, host_mem);
+	err = kvm__register_mem(kvm, phys_start, ram->size, ram->start);
 	if (err)
 		die("Failed to register %lld bytes of memory at physical "
-		    "address 0x%llx [err %d]", phys_size, phys_start, err);
+		    "address 0x%llx [err %d]", ram->size, phys_start, err);
 
 	kvm->arch.memory_guest_start = phys_start;
 }
@@ -92,10 +90,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 
 static void kvm__arch_sanitize_cfg(struct kvm_config *cfg)
 {
-	if (cfg->ram_size > ARM_MAX_MEMORY(cfg)) {
-		cfg->ram_size = ARM_MAX_MEMORY(cfg);
+	/* Convenience aliases */
+	struct kvm_ram_config *bank0 = &cfg->ram[0];
+
+	if (bank0->size > ARM_MAX_MEMORY(cfg)) {
+		bank0->size = ARM_MAX_MEMORY(cfg);
 		pr_warning("sanitize: Capping memory to %lluMB",
-			   cfg->ram_size >> 20);
+			   bank0->size >> 20);
 	}
 }
 
@@ -118,14 +119,16 @@ bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
 	void *pos, *kernel_end, *limit;
 	unsigned long guest_addr;
 	ssize_t file_size;
+	/* Convenience aliases */
+	struct kvm_ram_region *ram0 = &kvm->ram[0];
 
 	/*
 	 * Linux requires the initrd and dtb to be mapped inside lowmem,
 	 * so we can't just place them at the top of memory.
 	 */
-	limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1;
+	limit = ram0->start + min(ram0->size, (u64)SZ_256M) - 1;
 
-	pos = kvm->ram_start + ARM_KERN_OFFSET(kvm);
+	pos = ram0->start + ARM_KERN_OFFSET(kvm);
 	kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos);
 	file_size = read_file(fd_kernel, pos, limit - pos);
 	if (file_size < 0) {
diff --git a/builtin-run.c b/builtin-run.c
index b56aea7..5415d70 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -87,6 +87,63 @@ void kvm_run_set_wrapper_sandbox(void)
 	kvm_run_wrapper = KVM_RUN_SANDBOX;
 }
 
+static int mem_parser(const struct option *opt, const char *arg, int unset)
+{
+	struct kvm_config *cfg = opt->value;
+	const char *p = arg;
+	char *next;
+	u64 size, addr;
+	int base;
+
+	/* parse out size */
+	size = strtoll(p, &next, 10);
+
+	if (next == p)
+		die("mem: no size specified.\n");
+
+	if (*next != '@' && *next != '\0')
+		die("mem: unexpected chars after size.\n");
+
+	if (*next == '\0')
+		p = next;
+	else
+		p = next + 1;
+
+	/* parse out guest addr */
+	base = 10;
+	if (strcasestr(p, "0x"))
+		base = 16;
+	addr = strtoll(p, &next, base);
+	if (next == p && addr == 0) {
+		/*
+		 * To keep backward compatibility, the <addr> is not
+		 * mandatory for the first bank.
+		 */
+		if (cfg->nr_ram > 0)
+			die("mem: <addr> must be specified\n");
+		addr = INVALID_RAM_ADDR;
+	}
+
+	if ( cfg->nr_ram == MAX_RAM_BANKS )
+		die("mem: Too many banks\n");
+
+	/*
+	 * Allow the architecture to tell whether it is possible to configure
+	 * the RAM base address.
+	 */
+#ifndef ARCH_SUPPORT_CFG_RAM_BASE
+	if (addr == INVALID_RAM_ADDR)
+		die("mem: specifying <addr> is not allowed\n");
+#endif
+
+	cfg->ram[cfg->nr_ram].base = addr;
+	cfg->ram[cfg->nr_ram].size = size;
+
+	cfg->nr_ram++;
+
+	return 0;
+}
+
 #ifndef OPT_ARCH_RUN
 #define OPT_ARCH_RUN(...)
 #endif
@@ -97,8 +154,11 @@ void kvm_run_set_wrapper_sandbox(void)
 	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
 			"A name for the guest"),			\
 	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
-	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
-		" size in MiB."),					\
+	OPT_CALLBACK('m', "mem", cfg,					\
+		     "<size>[@<addr>]",					\
+		     "Virtual machine memory region, size in MiB."	\
+		     "<addr> must be specified in case of multiple regions", \
+		     mem_parser, NULL),					\
 	OPT_CALLBACK('\0', "shmem", NULL,				\
 		     "[pci:]<addr>:<size>[:handle=<handle>][:create]",	\
 		     "Share host shmem with guest via pci device",	\
@@ -455,6 +515,8 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 	unsigned int nr_online_cpus;
 	struct kvm *kvm = kvm__new();
 	bool video;
+	u64 total_ram = 0;
+	unsigned int i;
 
 	if (IS_ERR(kvm))
 		return kvm;
@@ -521,16 +583,23 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 	if (kvm->cfg.nrcpus == 0)
 		kvm->cfg.nrcpus = nr_online_cpus;
 
-	if (!kvm->cfg.ram_size)
-		kvm->cfg.ram_size = get_ram_size(kvm->cfg.nrcpus);
+	/* Deal with user not specifiying memory */
+	if (kvm->cfg.nr_ram == 0 && !kvm->cfg.ram[0].size) {
+		kvm->cfg.ram[0].size = get_ram_size(kvm->cfg.nrcpus);
+		kvm->cfg.nr_ram = 1;
+	}
+
+	for (i = 0; i < kvm->cfg.nr_ram; i++) {
+		total_ram += kvm->cfg.ram[i].size;
+		/* The user input is in MB, but the internal deals with bytes */
+		kvm->cfg.ram[i].size <<= MB_SHIFT;
+	}
 
-	if (kvm->cfg.ram_size > host_ram_size())
+	if (total_ram > host_ram_size())
 		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
-			(unsigned long long)kvm->cfg.ram_size,
+			(unsigned long long)total_ram,
 			(unsigned long long)host_ram_size());
 
-	kvm->cfg.ram_size <<= MB_SHIFT;
-
 	if (!kvm->cfg.dev)
 		kvm->cfg.dev = DEFAULT_KVM_DEV;
 
@@ -636,7 +705,7 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 
 	printf("  # %s run -k %s -m %Lu -c %d --name %s\n", KVM_BINARY_NAME,
 		kvm->cfg.kernel_filename,
-		(unsigned long long)kvm->cfg.ram_size / 1024 / 1024,
+		(unsigned long long)kvm->cfg.ram[0].size / 1024 / 1024,
 		kvm->cfg.nrcpus, kvm->cfg.guest_name);
 
 	if (init_list__init(kvm) < 0)
diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h
index 386fa8c..9e5caf1 100644
--- a/include/kvm/kvm-config.h
+++ b/include/kvm/kvm-config.h
@@ -17,10 +17,24 @@
 #define MIN_RAM_SIZE_MB		(64ULL)
 #define MIN_RAM_SIZE_BYTE	(MIN_RAM_SIZE_MB << MB_SHIFT)
 
+#define INVALID_RAM_ADDR	(~0ULL)
+
+/* By default the user is only able to speficy one RAM bank */
+#ifndef MAX_RAM_BANKS
+#define MAX_RAM_BANKS	1
+#endif
+
+struct kvm_ram_config
+{
+	u64 base;
+	u64 size;
+};
+
 struct kvm_config {
 	struct kvm_config_arch arch;
 	struct disk_image_params disk_image[MAX_DISK_IMAGES];
-	u64 ram_size;
+	struct kvm_ram_config ram[MAX_RAM_BANKS];
+	u8 nr_ram;
 	u8  image_count;
 	u8 num_net_devices;
 	bool virtio_rng;
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 6ac5c66..4e21446 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -46,6 +46,11 @@ struct kvm_mem_bank {
 	u64			size;
 };
 
+struct kvm_ram_region {
+	void			*start;
+	u64			size;
+};
+
 struct kvm {
 	struct kvm_arch		arch;
 	struct kvm_config	cfg;
@@ -57,8 +62,8 @@ struct kvm {
 	struct kvm_cpu		**cpus;
 
 	u32			mem_slots;	/* for KVM_SET_USER_MEMORY_REGION */
-	u64			ram_size;
-	void			*ram_start;
+	struct kvm_ram_region	ram[MAX_RAM_BANKS];
+	u32			nr_ram;
 	u64			ram_pagesize;
 	struct list_head	mem_banks;
 
@@ -125,7 +130,17 @@ extern const char *kvm_exit_reasons[];
 
 static inline bool host_ptr_in_ram(struct kvm *kvm, void *p)
 {
-	return kvm->ram_start <= p && p < (kvm->ram_start + kvm->ram_size);
+	unsigned int i;
+
+	for (i = 0; i < kvm->nr_ram; i++ )
+	{
+		struct kvm_ram_region *ram = &kvm->ram[i];
+
+		if (ram->start <= p && p < (ram->start + ram->size))
+			return true;
+	}
+
+	return false;
 }
 
 bool kvm__supports_extension(struct kvm *kvm, unsigned int extension);
diff --git a/kvm.c b/kvm.c
index e13d8f2..9c2cb2f 100644
--- a/kvm.c
+++ b/kvm.c
@@ -151,6 +151,7 @@ static int kvm__check_extensions(struct kvm *kvm)
 
 struct kvm *kvm__new(void)
 {
+	unsigned int i;
 	struct kvm *kvm = calloc(1, sizeof(*kvm));
 	if (!kvm)
 		return ERR_PTR(-ENOMEM);
@@ -158,6 +159,9 @@ struct kvm *kvm__new(void)
 	kvm->sys_fd = -1;
 	kvm->vm_fd = -1;
 
+	for ( i = 0; i < MAX_RAM_BANKS; i++)
+		kvm->cfg.ram[i].base = INVALID_RAM_ADDR;
+
 	return kvm;
 }
 
diff --git a/mips/kvm.c b/mips/kvm.c
index 61bf104..17e7ca5 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -21,26 +21,28 @@ static void kvm__init_ram(struct kvm *kvm)
 {
 	u64	phys_start, phys_size;
 	void	*host_mem;
+	/* Convenience aliases */
+	const struct kvm_ram_region *ram = &kvm->ram[0];
 
-	if (kvm->ram_size <= KVM_MMIO_START) {
+	if (ram->size <= KVM_MMIO_START) {
 		/* one region for all memory */
 		phys_start = 0;
-		phys_size  = kvm->ram_size;
-		host_mem   = kvm->ram_start;
+		phys_size  = ram->size;
+		host_mem   = ram->start;
 
 		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
 	} else {
 		/* one region for memory that fits below MMIO range */
 		phys_start = 0;
 		phys_size  = KVM_MMIO_START;
-		host_mem   = kvm->ram_start;
+		host_mem   = ram->start;
 
 		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
 
 		/* one region for rest of memory */
 		phys_start = KVM_MMIO_START + KVM_MMIO_SIZE;
-		phys_size  = kvm->ram_size - KVM_MMIO_START;
-		host_mem   = kvm->ram_start + KVM_MMIO_START;
+		phys_size  = ram->size - KVM_MMIO_START;
+		host_mem   = ram->start + KVM_MMIO_START;
 
 		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
 	}
@@ -48,7 +50,7 @@ static void kvm__init_ram(struct kvm *kvm)
 
 void kvm__arch_delete_ram(struct kvm *kvm)
 {
-	munmap(kvm->ram_start, kvm->ram_size);
+	munmap(kvm->ram[0].start, kvm->ram[0].size);
 }
 
 void kvm__arch_set_cmdline(char *cmdline, bool video)
@@ -61,16 +63,18 @@ void kvm__arch_init(struct kvm *kvm)
 {
 	int ret;
 	/* Convenience aliases */
-	u64 ram_size = kvm->cfg.ram_size;
+	u64 ram_size = kvm->cfg.ram[0].size;
 	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
+	struct kvm_ram_region *ram = &kvm->ram[0];
 
-	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
-	kvm->ram_size = ram_size;
+	kvm->nr_ram = 1;
+	ram->start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
+	ram->size = ram_size;
 
-	if (kvm->ram_start == MAP_FAILED)
+	if (ram->start == MAP_FAILED)
 		die("out of memory");
 
-	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
+	madvise(ram->start, ram->size, MADV_MERGEABLE);
 
 	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
 	if (ret < 0)
@@ -124,20 +128,22 @@ int kvm__arch_setup_firmware(struct kvm *kvm)
 
 static void kvm__mips_install_cmdline(struct kvm *kvm)
 {
-	char *p = kvm->ram_start;
 	u64 cmdline_offset = 0x2000;
 	u64 argv_start = 0x3000;
 	u64 argv_offset = argv_start;
 	u64 argc = 0;
+	/* Convenience aliases */
+	struct kvm_ram_region *ram = &kvm->ram[0];
 
+	char *p = ram->start;
 
-	if ((u64) kvm->ram_size <= KVM_MMIO_START)
+	if ((u64) ram->size <= KVM_MMIO_START)
 		sprintf(p + cmdline_offset, "mem=0x%llx@0 ",
-			(unsigned long long)kvm->ram_size);
+			(unsigned long long)ram->size);
 	else
 		sprintf(p + cmdline_offset, "mem=0x%llx at 0 mem=0x%llx at 0x%llx ",
 			(unsigned long long)KVM_MMIO_START,
-			(unsigned long long)kvm->ram_size - KVM_MMIO_START,
+			(unsigned long long)ram->size - KVM_MMIO_START,
 			(unsigned long long)(KVM_MMIO_START + KVM_MMIO_SIZE));
 
 	strcat(p + cmdline_offset, kvm->cfg.real_cmdline); /* maximum size is 2K */
@@ -181,7 +187,7 @@ static bool load_flat_binary(struct kvm *kvm, int fd_kernel)
 	p = k_start = guest_flat_to_host(kvm, KERNEL_LOAD_ADDR);
 
 	kernel_size = read_file(fd_kernel, p,
-				kvm->cfg.ram_size - KERNEL_LOAD_ADDR);
+				kvm->cfg.ram[0].size - KERNEL_LOAD_ADDR);
 	if (kernel_size == -1) {
 		if (errno == ENOMEM)
 			die("kernel too big for guest memory");
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index 2c8dbb7..2800ee7 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -66,8 +66,8 @@ static void kvm__init_ram(struct kvm *kvm)
 	void	*host_mem;
 
 	phys_start = 0;
-	phys_size  = kvm->ram_size;
-	host_mem   = kvm->ram_start;
+	phys_size  = kvm->ram[0].size;
+	host_mem   = kvm->ram[0].start;
 
 	/*
 	 * We put MMIO at PPC_MMIO_START, high up.  Make sure that this doesn't
@@ -93,26 +93,28 @@ void kvm__arch_init(struct kvm *kvm)
 	int cap_ppc_rma;
 	unsigned long hpt;
 	/* Convenience aliases */
-	u64 ram_size = kvm->cfg.ram_size;
+	u64 ram_size = kvm->cfg.ram[0].size;
 	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
+	struct kvm_ram_region *ram = &kvm->ram[0];
 
-	kvm->ram_size		= ram_size;
+	kvm->nr_ram		= 1;
+	ram->size		= ram_size;
 
 	/* Map "default" hugetblfs path to the standard 16M mount point */
 	if (hugetlbfs_path && !strcmp(hugetlbfs_path, "default"))
 		hugetlbfs_path = HUGETLBFS_PATH;
 
-	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, kvm->ram_size);
+	ram->start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram->size);
 
-	if (kvm->ram_start == MAP_FAILED)
+	if (ram->start == MAP_FAILED)
 		die("Couldn't map %lld bytes for RAM (%d)\n",
-		    kvm->ram_size, errno);
+		    ram->size, errno);
 
 	/* FDT goes at top of memory, RTAS just below */
-	kvm->arch.fdt_gra = kvm->ram_size - FDT_MAX_SIZE;
+	kvm->arch.fdt_gra = ram->size - FDT_MAX_SIZE;
 	/* FIXME: Not all PPC systems have RTAS */
 	kvm->arch.rtas_gra = kvm->arch.fdt_gra - RTAS_MAX_SIZE;
-	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
+	madvise(ram->start, ram->size, MADV_MERGEABLE);
 
 	/* FIXME:  SPAPR-PR specific; allocate a guest HPT. */
 	if (posix_memalign((void **)&hpt, (1<<HPT_ORDER), (1<<HPT_ORDER)))
@@ -145,7 +147,7 @@ void kvm__arch_init(struct kvm *kvm)
 
 void kvm__arch_delete_ram(struct kvm *kvm)
 {
-	munmap(kvm->ram_start, kvm->ram_size);
+	munmap(kvm->ram[0].start, kvm->ram[0].size);
 }
 
 void kvm__irq_trigger(struct kvm *kvm, int irq)
@@ -186,7 +188,7 @@ bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
 		p = guest_flat_to_host(kvm, INITRD_LOAD_ADDR);
 
 		filesize = read_file(fd_initrd, p,
-			       (kvm->ram_start + kvm->ram_size) - p);
+			       (kvm->ram[0].start + kvm->ram[0].size) - p);
 		if (filesize < 0) {
 			if (errno == ENOMEM)
 				die("initrd too big to contain in guest RAM.\n");
@@ -283,7 +285,7 @@ static void generate_segment_page_sizes(struct kvm_ppc_smmu_info *info, struct f
  */
 static int setup_fdt(struct kvm *kvm)
 {
-	uint64_t 	mem_reg_property[] = { 0, cpu_to_be64(kvm->ram_size) };
+	uint64_t 	mem_reg_property[] = { 0, cpu_to_be64(kvm->ram[0].size) };
 	int 		smp_cpus = kvm->nrcpus;
 	uint32_t	int_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
 	char 		hypertas_prop_kvm[] = "hcall-pft\0hcall-term\0"
diff --git a/x86/bios.c b/x86/bios.c
index 5ac9e24..2efd771 100644
--- a/x86/bios.c
+++ b/x86/bios.c
@@ -59,6 +59,8 @@ static void e820_setup(struct kvm *kvm)
 	struct e820map *e820;
 	struct e820entry *mem_map;
 	unsigned int i = 0;
+	/* Convenience aliases */
+	const struct kvm_ram_region *ram = &kvm->ram[0];
 
 	e820		= guest_flat_to_host(kvm, E820_MAP_START);
 	mem_map		= e820->map;
@@ -78,10 +80,10 @@ static void e820_setup(struct kvm *kvm)
 		.size		= MB_BIOS_END - MB_BIOS_BEGIN,
 		.type		= E820_RESERVED,
 	};
-	if (kvm->ram_size < KVM_32BIT_GAP_START) {
+	if (ram->size < KVM_32BIT_GAP_START) {
 		mem_map[i++]	= (struct e820entry) {
 			.addr		= BZ_KERNEL_START,
-			.size		= kvm->ram_size - BZ_KERNEL_START,
+			.size		= ram->size - BZ_KERNEL_START,
 			.type		= E820_RAM,
 		};
 	} else {
@@ -92,7 +94,7 @@ static void e820_setup(struct kvm *kvm)
 		};
 		mem_map[i++]	= (struct e820entry) {
 			.addr		= KVM_32BIT_MAX_MEM_SIZE,
-			.size		= kvm->ram_size - KVM_32BIT_MAX_MEM_SIZE,
+			.size		= ram->size - KVM_32BIT_MAX_MEM_SIZE,
 			.type		= E820_RAM,
 		};
 	}
diff --git a/x86/kvm.c b/x86/kvm.c
index 03b0277..8faa166 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -90,13 +90,15 @@ static void kvm__init_ram(struct kvm *kvm)
 {
 	u64	phys_start, phys_size;
 	void	*host_mem;
+	/* Convenience aliases */
+	const struct kvm_ram_region *ram = &kvm->ram[0];
 
-	if (kvm->ram_size < KVM_32BIT_GAP_START) {
+	if (ram->size < KVM_32BIT_GAP_START) {
 		/* Use a single block of RAM for 32bit RAM */
 
 		phys_start = 0;
-		phys_size  = kvm->ram_size;
-		host_mem   = kvm->ram_start;
+		phys_size  = ram->size;
+		host_mem   = ram->start;
 
 		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
 	} else {
@@ -104,15 +106,15 @@ static void kvm__init_ram(struct kvm *kvm)
 
 		phys_start = 0;
 		phys_size  = KVM_32BIT_GAP_START;
-		host_mem   = kvm->ram_start;
+		host_mem   = ram->start;
 
 		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
 
 		/* Second RAM range from 4GB to the end of RAM: */
 
 		phys_start = KVM_32BIT_MAX_MEM_SIZE;
-		phys_size  = kvm->ram_size - phys_start;
-		host_mem   = kvm->ram_start + phys_start;
+		phys_size  = ram->size - phys_start;
+		host_mem   = ram->start + phys_start;
 
 		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
 	}
@@ -135,8 +137,9 @@ void kvm__arch_init(struct kvm *kvm)
 	struct kvm_pit_config pit_config = { .flags = 0, };
 	int ret;
 	/* Convenience aliases */
-	u64 ram_size = kvm->cfg.ram_size;
+	u64 ram_size = kvm->cfg.ram[0].size;
 	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
+	struct kvm_ram_region *ram = &kvm->ram[0];
 
 	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);
 	if (ret < 0)
@@ -146,23 +149,29 @@ void kvm__arch_init(struct kvm *kvm)
 	if (ret < 0)
 		die_perror("KVM_CREATE_PIT2 ioctl");
 
+	kvm->nr_ram = 1;
 	if (ram_size < KVM_32BIT_GAP_START) {
-		kvm->ram_size = ram_size;
-		kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
+		ram->size = ram_size;
+		ram->start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
+						    ram_size);
 	} else {
-		kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size + KVM_32BIT_GAP_SIZE);
-		kvm->ram_size = ram_size + KVM_32BIT_GAP_SIZE;
-		if (kvm->ram_start != MAP_FAILED)
+		ram->start = mmap_anon_or_hugetlbfs(kvm,
+						    hugetlbfs_path,
+						    ram_size + KVM_32BIT_GAP_SIZE);
+		ram->size = ram_size + KVM_32BIT_GAP_SIZE;
+		if (ram->start != MAP_FAILED)
 			/*
 			 * We mprotect the gap (see kvm__init_ram() for details) PROT_NONE so that
 			 * if we accidently write to it, we will know.
 			 */
-			mprotect(kvm->ram_start + KVM_32BIT_GAP_START, KVM_32BIT_GAP_SIZE, PROT_NONE);
+			mprotect(ram->start + KVM_32BIT_GAP_START,
+				 KVM_32BIT_GAP_SIZE, PROT_NONE);
 	}
-	if (kvm->ram_start == MAP_FAILED)
+	if (ram->start == MAP_FAILED)
 		die("out of memory");
 
-	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
+	madvise(ram->start, ram->size,
+		MADV_MERGEABLE);
 
 	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
 	if (ret < 0)
@@ -173,7 +182,7 @@ void kvm__arch_init(struct kvm *kvm)
 
 void kvm__arch_delete_ram(struct kvm *kvm)
 {
-	munmap(kvm->ram_start, kvm->ram_size);
+	munmap(kvm->ram[0].start, kvm->ram[0].size);
 }
 
 void kvm__irq_line(struct kvm *kvm, int irq, int level)
@@ -221,7 +230,7 @@ static bool load_flat_binary(struct kvm *kvm, int fd_kernel)
 
 	p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
 
-	if (read_file(fd_kernel, p, kvm->cfg.ram_size) < 0)
+	if (read_file(fd_kernel, p, kvm->cfg.ram[0].size) < 0)
 		die_perror("read");
 
 	kvm->arch.boot_selector	= BOOT_LOADER_SELECTOR;
@@ -270,7 +279,7 @@ static bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd,
 	/* read actual kernel image (vmlinux.bin) to BZ_KERNEL_START */
 	p = guest_flat_to_host(kvm, BZ_KERNEL_START);
 	file_size = read_file(fd_kernel, p,
-			      kvm->cfg.ram_size - BZ_KERNEL_START);
+			      kvm->cfg.ram[0].size - BZ_KERNEL_START);
 	if (file_size < 0)
 		die_perror("kernel read");
 
@@ -316,7 +325,7 @@ static bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd,
 		for (;;) {
 			if (addr < BZ_KERNEL_START)
 				die("Not enough memory for initrd");
-			else if (addr < (kvm->ram_size - initrd_stat.st_size))
+			else if (addr < (kvm->ram[0].size - initrd_stat.st_size))
 				break;
 			addr -= 0x100000;
 		}
-- 
2.11.0

^ permalink raw reply related

* [RFC 06/13] arm: Move anything related to RAM initialization in kvm__init_ram
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510140441.24573-1-julien.grall@arm.com>

---
 arm/kvm.c | 68 +++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/arm/kvm.c b/arm/kvm.c
index 71aad9d..daa7425 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -29,6 +29,39 @@ static void kvm__init_ram(struct kvm *kvm)
 	int err;
 	u64 phys_start, phys_size;
 	void *host_mem;
+	unsigned long alignment;
+	/* Convenience aliases */
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
+
+	/*
+	 * Allocate guest memory. We must align our buffer to 64K to
+	 * correlate with the maximum guest page size for virtio-mmio.
+	 * If using THP, then our minimal alignment becomes 2M.
+	 * 2M trumps 64K, so let's go with that.
+	 * If we are running with 16K page size, align the memory to
+	 * 32M, so that we can make use of the THP.
+	 */
+	if (sysconf(_SC_PAGESIZE) == SZ_16K)
+		alignment = SZ_32M;
+	else
+		alignment = SZ_2M;
+	kvm->ram_size = kvm->cfg.ram_size;
+	kvm->arch.ram_alloc_size = kvm->ram_size + alignment;
+	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
+						kvm->arch.ram_alloc_size);
+
+	if (kvm->arch.ram_alloc_start == MAP_FAILED)
+		die("Failed to map %lld bytes for guest memory (%d)",
+		    kvm->arch.ram_alloc_size, errno);
+
+	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
+					SZ_2M);
+
+	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
+		MADV_MERGEABLE);
+
+	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
+		MADV_HUGEPAGE);
 
 	phys_start	= ARM_MEMORY_AREA;
 	phys_size	= kvm->ram_size;
@@ -68,43 +101,8 @@ static void kvm__arch_sanitize_cfg(struct kvm_config *cfg)
 
 void kvm__arch_init(struct kvm *kvm)
 {
-	unsigned long alignment;
-
-	/* Convenience aliases */
-	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
-
 	kvm__arch_sanitize_cfg(&kvm->cfg);
 
-	/*
-	 * Allocate guest memory. We must align our buffer to 64K to
-	 * correlate with the maximum guest page size for virtio-mmio.
-	 * If using THP, then our minimal alignment becomes 2M.
-	 * 2M trumps 64K, so let's go with that.
-	 * If we are running with 16K page size, align the memory to
-	 * 32M, so that we can make use of the THP.
-	 */
-	if (sysconf(_SC_PAGESIZE) == SZ_16K)
-		alignment = SZ_32M;
-	else
-		alignment = SZ_2M;
-	kvm->ram_size = kvm->cfg.ram_size;
-	kvm->arch.ram_alloc_size = kvm->ram_size + alignment;
-	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
-						kvm->arch.ram_alloc_size);
-
-	if (kvm->arch.ram_alloc_start == MAP_FAILED)
-		die("Failed to map %lld bytes for guest memory (%d)",
-		    kvm->arch.ram_alloc_size, errno);
-
-	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
-					alignment);
-
-	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
-		MADV_MERGEABLE);
-
-	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
-		MADV_HUGEPAGE);
-
 	/* Create the virtual GIC. */
 	if (gic__create(kvm, kvm->cfg.arch.irqchip))
 		die("Failed to create virtual GIC");
-- 
2.11.0

^ permalink raw reply related

* [RFC 05/13] kvm__arch_sanitize_cfg
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510140441.24573-1-julien.grall@arm.com>

---
 arm/aarch64/include/kvm/kvm-arch.h |  2 +-
 arm/kvm.c                          | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index 9de623a..1b3d0a5 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -5,7 +5,7 @@
 				0x8000				:	\
 				0x80000)
 
-#define ARM_MAX_MEMORY(kvm)	((kvm)->cfg.arch.aarch32_guest	?	\
+#define ARM_MAX_MEMORY(cfg)	((cfg)->arch.aarch32_guest	?	\
 				ARM_LOMAP_MAX_MEMORY		:	\
 				ARM_HIMAP_MAX_MEMORY)
 
diff --git a/arm/kvm.c b/arm/kvm.c
index 619390a..71aad9d 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -57,6 +57,15 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 {
 }
 
+static void kvm__arch_sanitize_cfg(struct kvm_config *cfg)
+{
+	if (cfg->ram_size > ARM_MAX_MEMORY(cfg)) {
+		cfg->ram_size = ARM_MAX_MEMORY(cfg);
+		pr_warning("sanitize: Capping memory to %lluMB",
+			   cfg->ram_size >> 20);
+	}
+}
+
 void kvm__arch_init(struct kvm *kvm)
 {
 	unsigned long alignment;
@@ -64,6 +73,8 @@ void kvm__arch_init(struct kvm *kvm)
 	/* Convenience aliases */
 	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
 
+	kvm__arch_sanitize_cfg(&kvm->cfg);
+
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
 	 * correlate with the maximum guest page size for virtio-mmio.
@@ -76,7 +87,7 @@ void kvm__arch_init(struct kvm *kvm)
 		alignment = SZ_32M;
 	else
 		alignment = SZ_2M;
-	kvm->ram_size = min(kvm->cfg.ram_size, (u64)ARM_MAX_MEMORY(kvm));
+	kvm->ram_size = kvm->cfg.ram_size;
 	kvm->arch.ram_alloc_size = kvm->ram_size + alignment;
 	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
-- 
2.11.0

^ permalink raw reply related

* [RFC 04/13] Fold kvm__init_ram call in kvm__arch_init
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510140441.24573-1-julien.grall@arm.com>

The slipt between kvm__init_ram and kvm__arch_init for setting up the
RAM can be quite subttle. By moving the former call in the later, it
will be possible to make the RAM initialization easier on Arm with multi
RAM banks support.

Note that it is necessary to move the call to kvm__arch_init after the
initialization of the list kvm->mem_banks because kvm__init_ram is
relying on it.

Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 arm/kvm.c         | 4 +++-
 include/kvm/kvm.h | 1 -
 kvm.c             | 4 +---
 mips/kvm.c        | 4 +++-
 powerpc/kvm.c     | 4 +++-
 x86/kvm.c         | 4 +++-
 6 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/arm/kvm.c b/arm/kvm.c
index 7424887..619390a 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -24,7 +24,7 @@ bool kvm__arch_cpu_supports_vm(void)
 	return true;
 }
 
-void kvm__init_ram(struct kvm *kvm)
+static void kvm__init_ram(struct kvm *kvm)
 {
 	int err;
 	u64 phys_start, phys_size;
@@ -97,6 +97,8 @@ void kvm__arch_init(struct kvm *kvm)
 	/* Create the virtual GIC. */
 	if (gic__create(kvm, kvm->cfg.arch.irqchip))
 		die("Failed to create virtual GIC");
+
+	kvm__init_ram(kvm);
 }
 
 #define FDT_ALIGN	SZ_2M
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 95bab40..6ac5c66 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -79,7 +79,6 @@ int kvm__init(struct kvm *kvm);
 struct kvm *kvm__new(void);
 int kvm__recommended_cpus(struct kvm *kvm);
 int kvm__max_cpus(struct kvm *kvm);
-void kvm__init_ram(struct kvm *kvm);
 int kvm__exit(struct kvm *kvm);
 bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename);
 bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
diff --git a/kvm.c b/kvm.c
index 98b3cb8..e13d8f2 100644
--- a/kvm.c
+++ b/kvm.c
@@ -317,10 +317,8 @@ int kvm__init(struct kvm *kvm)
 		goto err_vm_fd;
 	}
 
-	kvm__arch_init(kvm);
-
 	INIT_LIST_HEAD(&kvm->mem_banks);
-	kvm__init_ram(kvm);
+	kvm__arch_init(kvm);
 
 	if (!kvm->cfg.firmware_filename) {
 		if (!kvm__load_kernel(kvm, kvm->cfg.kernel_filename,
diff --git a/mips/kvm.c b/mips/kvm.c
index cdb0007..61bf104 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -17,7 +17,7 @@ void kvm__arch_read_term(struct kvm *kvm)
 	virtio_console__inject_interrupt(kvm);
 }
 
-void kvm__init_ram(struct kvm *kvm)
+static void kvm__init_ram(struct kvm *kvm)
 {
 	u64	phys_start, phys_size;
 	void	*host_mem;
@@ -75,6 +75,8 @@ void kvm__arch_init(struct kvm *kvm)
 	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
 	if (ret < 0)
 		die_perror("KVM_CREATE_IRQCHIP ioctl");
+
+	kvm__init_ram(kvm);
 }
 
 void kvm__irq_line(struct kvm *kvm, int irq, int level)
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index 0f2dab3..2c8dbb7 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -60,7 +60,7 @@ bool kvm__arch_cpu_supports_vm(void)
 	return true;
 }
 
-void kvm__init_ram(struct kvm *kvm)
+static void kvm__init_ram(struct kvm *kvm)
 {
 	u64	phys_start, phys_size;
 	void	*host_mem;
@@ -139,6 +139,8 @@ void kvm__arch_init(struct kvm *kvm)
 			 SPAPR_PCI_MEM_WIN_SIZE,
 			 SPAPR_PCI_IO_WIN_ADDR,
 			 SPAPR_PCI_IO_WIN_SIZE);
+
+	kvm__init_ram(kvm);
 }
 
 void kvm__arch_delete_ram(struct kvm *kvm)
diff --git a/x86/kvm.c b/x86/kvm.c
index 453922f..03b0277 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -86,7 +86,7 @@ bool kvm__arch_cpu_supports_vm(void)
  * a gap between 0xe0000000 and 0x100000000 in the guest virtual mem space.
  */
 
-void kvm__init_ram(struct kvm *kvm)
+static void kvm__init_ram(struct kvm *kvm)
 {
 	u64	phys_start, phys_size;
 	void	*host_mem;
@@ -167,6 +167,8 @@ void kvm__arch_init(struct kvm *kvm)
 	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
 	if (ret < 0)
 		die_perror("KVM_CREATE_IRQCHIP ioctl");
+
+	kvm__init_ram(kvm);
 }
 
 void kvm__arch_delete_ram(struct kvm *kvm)
-- 
2.11.0

^ permalink raw reply related

* [RFC 03/13] virtio/scsi: Allow to use multiple banks
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510140441.24573-1-julien.grall@arm.com>

At the moment, virtio scsi only register a bank starting at 0. On some
architectures this may not be true and the guest may have multiple
memory region.

Register all the memory regions to vhost by browsing kvm->mem_banks. The
code is based on the virtio_net__vhost_init implementation.

Signed-off-by: Julien Grall <julien.grall@arm.com>

---

This code was not tested as I don't have any setup with scsi.
---
 virtio/scsi.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/virtio/scsi.c b/virtio/scsi.c
index 58d2353..ee58e5f 100644
--- a/virtio/scsi.c
+++ b/virtio/scsi.c
@@ -182,24 +182,29 @@ static struct virtio_ops scsi_dev_virtio_ops = {
 
 static void virtio_scsi_vhost_init(struct kvm *kvm, struct scsi_dev *sdev)
 {
+	struct kvm_mem_bank *bank;
 	struct vhost_memory *mem;
 	u64 features;
-	int r;
+	int r, i;
 
 	sdev->vhost_fd = open("/dev/vhost-scsi", O_RDWR);
 	if (sdev->vhost_fd < 0)
 		die_perror("Failed openning vhost-scsi device");
 
-	mem = calloc(1, sizeof(*mem) + sizeof(struct vhost_memory_region));
+	mem = calloc(1, sizeof(*mem) + kvm->mem_slots * sizeof(struct vhost_memory_region));
 	if (mem == NULL)
 		die("Failed allocating memory for vhost memory map");
 
-	mem->nregions = 1;
-	mem->regions[0] = (struct vhost_memory_region) {
-		.guest_phys_addr	= 0,
-		.memory_size		= kvm->ram_size,
-		.userspace_addr		= (unsigned long)kvm->ram_start,
-	};
+	i = 0;
+	list_for_each_entry(bank, &kvm->mem_banks, list) {
+		mem->regions[0] = (struct vhost_memory_region) {
+			.guest_phys_addr	= bank->guest_phys_addr,
+			.memory_size		= bank->size,
+			.userspace_addr		= (unsigned long)bank->host_addr,
+		};
+
+	}
+	mem->nregions = i;
 
 	r = ioctl(sdev->vhost_fd, VHOST_SET_OWNER);
 	if (r != 0)
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 1/2] PCI: kirin: Add MSI support
From: Bjorn Helgaas @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525854012-24228-2-git-send-email-chenyao11@huawei.com>

[+cc Tejun, Wolfram]

On Wed, May 09, 2018 at 04:20:11PM +0800, Yao Chen wrote:
> Add support for MSI.
> ...

> @@ -448,6 +467,26 @@ static int kirin_pcie_host_init(struct pcie_port *pp)
>  static int __init kirin_add_pcie_port(struct dw_pcie *pci,
>  				      struct platform_device *pdev)
>  {
> +	int ret;
> +
> +	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> +		pci->pp.msi_irq = platform_get_irq(pdev, 0);
> +		if (!pci->pp.msi_irq) {

I think this test is incorrect.  platform_get_irq() returns a negative
errno value when it fails.  Most calls test "irq < 0" to check for failure.

There's a lot of duplicated code like this, so maybe we should consider
putting that check into devm_request_irq(), similar to what
devm_ioremap_resource() does, so the driver code could look like this:

  pci->pp.msi_irq = platform_get_irq(pdev, 0);
  ret = devm_request_irq(&pdev->dev, pci->pp.msi_irq, ...);
  if (ret) {
    dev_err(&pdev->dev, "failed to request MSI IRQ\n");
    return ret;
  }

The basic devm_ioremap_resource() motivation is here: 72f8c0bfa0de ("lib:
devres: add convenience function to remap a resource") and the same
considerations seem to apply here.

But that's more than you need to do for *this* series.  So for now, I would
simply fix the test to check for "irq < 0" and update the messages as I
mention below.

> +			dev_err(&pdev->dev, "failed to get msi irq[%d]\n",
> +				pci->pp.msi_irq);
> +			return -ENODEV;
> +		}
> +		ret = devm_request_irq(&pdev->dev, pci->pp.msi_irq,
> +				       kirin_pcie_msi_irq_handler,
> +				       IRQF_SHARED | IRQF_NO_THREAD,
> +				       "kirin_pcie_msi", &pci->pp);
> +		if (ret) {
> +			dev_err(&pdev->dev, "failed to request msi irq[%d]\n",

s/msi irq/MSI IRQ/ in both dev_err() messages above.  This is because the
message is English text (not code), and the convention is that non-words
like these initialisms written in all caps.

I would style the first one as "failed to get MSI IRQ (%d)" because the %d
there is a return code, probably -ENXIO.

The second one should be "failed to request MSI IRQ %d" because here the %d
is the actual IRQ.

> +				pci->pp.msi_irq);
> +			return ret;
> +		}
> +	}
> +
>  	pci->pp.ops = &kirin_pcie_host_ops;
>  
>  	return dw_pcie_host_init(&pci->pp);
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [RFC 02/13] kvm__arch_init: Don't pass hugetlbfs_path and ram_size in parameter
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510140441.24573-1-julien.grall@arm.com>

The structure KVM already contains a pointer to the configuration. Both
hugetlbfs_path and ram_size are part of the configuration, so is it not
necessary to path them again in parameter.

Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 arm/kvm.c         | 7 +++++--
 include/kvm/kvm.h | 2 +-
 kvm.c             | 2 +-
 mips/kvm.c        | 5 ++++-
 powerpc/kvm.c     | 5 ++++-
 x86/kvm.c         | 5 ++++-
 6 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/arm/kvm.c b/arm/kvm.c
index c4ab5c0..7424887 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -57,10 +57,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 {
 }
 
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	unsigned long alignment;
 
+	/* Convenience aliases */
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
+
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
 	 * correlate with the maximum guest page size for virtio-mmio.
@@ -73,7 +76,7 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 		alignment = SZ_32M;
 	else
 		alignment = SZ_2M;
-	kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm));
+	kvm->ram_size = min(kvm->cfg.ram_size, (u64)ARM_MAX_MEMORY(kvm));
 	kvm->arch.ram_alloc_size = kvm->ram_size + alignment;
 	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 90463b8..95bab40 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -104,7 +104,7 @@ int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
 void kvm__remove_socket(const char *name);
 
 void kvm__arch_set_cmdline(char *cmdline, bool video);
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size);
+void kvm__arch_init(struct kvm *kvm);
 void kvm__arch_delete_ram(struct kvm *kvm);
 int kvm__arch_setup_firmware(struct kvm *kvm);
 int kvm__arch_free_firmware(struct kvm *kvm);
diff --git a/kvm.c b/kvm.c
index f8f2fdc..98b3cb8 100644
--- a/kvm.c
+++ b/kvm.c
@@ -317,7 +317,7 @@ int kvm__init(struct kvm *kvm)
 		goto err_vm_fd;
 	}
 
-	kvm__arch_init(kvm, kvm->cfg.hugetlbfs_path, kvm->cfg.ram_size);
+	kvm__arch_init(kvm);
 
 	INIT_LIST_HEAD(&kvm->mem_banks);
 	kvm__init_ram(kvm);
diff --git a/mips/kvm.c b/mips/kvm.c
index 24bd650..cdb0007 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -57,9 +57,12 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	int ret;
+	/* Convenience aliases */
+	u64 ram_size = kvm->cfg.ram_size;
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
 
 	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
 	kvm->ram_size = ram_size;
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index c738c1d..0f2dab3 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -88,10 +88,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	int cap_ppc_rma;
 	unsigned long hpt;
+	/* Convenience aliases */
+	u64 ram_size = kvm->cfg.ram_size;
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
 
 	kvm->ram_size		= ram_size;
 
diff --git a/x86/kvm.c b/x86/kvm.c
index d8751e9..453922f 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -130,10 +130,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	struct kvm_pit_config pit_config = { .flags = 0, };
 	int ret;
+	/* Convenience aliases */
+	u64 ram_size = kvm->cfg.ram_size;
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
 
 	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);
 	if (ret < 0)
-- 
2.11.0

^ permalink raw reply related

* [RFC 01/13] arm: Allow use of hugepage with 16K pagesize host
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510140441.24573-1-julien.grall@arm.com>

From: Suzuki K Poulose <suzuki.poulose@arm.com>

With 16K pagesize, the hugepage size is 32M. Align the guest
memory to the hugepagesize for 16K.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Andre Przywara <andre.przywara@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 arm/kvm.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arm/kvm.c b/arm/kvm.c
index 2ab436e..c4ab5c0 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -59,14 +59,22 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 
 void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 {
+	unsigned long alignment;
+
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
 	 * correlate with the maximum guest page size for virtio-mmio.
 	 * If using THP, then our minimal alignment becomes 2M.
 	 * 2M trumps 64K, so let's go with that.
+	 * If we are running with 16K page size, align the memory to
+	 * 32M, so that we can make use of the THP.
 	 */
+	if (sysconf(_SC_PAGESIZE) == SZ_16K)
+		alignment = SZ_32M;
+	else
+		alignment = SZ_2M;
 	kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm));
-	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
+	kvm->arch.ram_alloc_size = kvm->ram_size + alignment;
 	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
 
@@ -75,7 +83,7 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 		    kvm->arch.ram_alloc_size, errno);
 
 	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
-					SZ_2M);
+					alignment);
 
 	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
 		MADV_MERGEABLE);
-- 
2.11.0

^ permalink raw reply related

* [RFC 00/13] arm: Allow the user specifying where the RAM is place in the memory
From: Julien Grall @ 2018-05-10 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

At the moment, a user is only able to specify the amount of RAM used by the
guest. Where the RAM will live is left to the software and hardcoded.

It could be useful for testing purpose to move the RAM in different place.
This series adds the possibility for the user to specify multiple RAM region.

The option -m/--mem is extended to specify the address using the following
format: <size>@<addr>. The option needs to be repeated as many times as the
number of RAM region in the guest layout.

For instance, if you want 512MB at 3GB and 512MB 4GB it would look like:
    -m 512 at 0xc0000000 -m 512 at 0x100000000

Note that the memory layout is not yet fully configurable by the user, so the
MMIO region is still living below 2GB. This means RAM cannot live in the
region 0-2GB. This could be changed in the future.

This new version also integrates work from Suzuki to allow the user specifying
the IPA size for the guest. This was previously sent separately on kvmarm [1].

Cheers,

[1] https://lkml.org/lkml/2018/3/27/437

Julien Grall (7):
  kvm__arch_init: Don't pass hugetlbfs_path and ram_size in parameter
  virtio/scsi: Allow to use multiple banks
  Fold kvm__init_ram call in kvm__arch_init
  kvm__arch_sanitize_cfg
  arm: Move anything related to RAM initialization in kvm__init_ram
  Allow the user to specify where the RAM is placed in the memory
  arm: Add support for multi memory regions

Suzuki K Poulose (6):
  arm: Allow use of hugepage with 16K pagesize host
  virtio: Handle aborts using invalid PFN
  kvmtool: Allow backends to run checks on the KVM device fd
  kvmtool: arm64: Add support for guest physical address size
  kvmtool: arm64: Switch memory layout
  kvmtool: arm/arm64: Add support for creating VM with PA size

 arm/aarch32/include/kvm/kvm-arch.h        |   3 +-
 arm/aarch64/include/kvm/kvm-arch.h        |  15 ++-
 arm/aarch64/include/kvm/kvm-config-arch.h |   5 +-
 arm/fdt.c                                 |  17 ++-
 arm/include/arm-common/kvm-arch.h         |  32 ++++--
 arm/include/arm-common/kvm-config-arch.h  |   1 +
 arm/kvm.c                                 | 183 +++++++++++++++++++++++++-----
 builtin-run.c                             |  87 ++++++++++++--
 include/kvm/kvm-config.h                  |  16 ++-
 include/kvm/kvm.h                         |  28 ++++-
 kvm.c                                     |  10 +-
 mips/kvm.c                                |  47 +++++---
 powerpc/kvm.c                             |  33 +++---
 virtio/mmio.c                             |  14 ++-
 virtio/pci.c                              |  10 +-
 virtio/scsi.c                             |  21 ++--
 x86/bios.c                                |   8 +-
 x86/kvm.c                                 |  54 +++++----
 18 files changed, 443 insertions(+), 141 deletions(-)

-- 
2.11.0

^ permalink raw reply

* [PATCH v2 21/27] coresight: Convert driver messages to dev_dbg
From: Suzuki K Poulose @ 2018-05-10 13:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <adf2465b-dd2c-dc0f-51ca-da7f1a8836ba@arm.com>

On 02/05/18 14:52, Robin Murphy wrote:
> On 02/05/18 04:55, Kim Phillips wrote:
>> On Tue, 1 May 2018 10:10:51 +0100
>> Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>>
>>> Convert component enable/disable messages from dev_info to dev_dbg.
>>> This is required to prevent LOCKDEP splats when operating in perf
>>> mode where we could be called with locks held to enable a coresight
>>
>> Can we see the splats?? Doesn't lockdep turn itself off if it starts
>> triggering too many splats?
> 
> Without some very careful and robust reasoning for why the condition being reported by lockdep could not actually occur in practice, "avoiding the splats" is far, far less important than "avoiding the potential deadlock that they are reporting".
> 
>>> path. If someone wants to really see the messages, they can always
>>> enable it at runtime via dynamic_debug.
>>
>> Won't the splats still occur when the messages are enabled with
>> dynamic_debug?
>>
>> So in effect this patch only tries to mitigate the splats, all the
>> while making things harder for regular users that now have to recompile
>> their kernels, in exchange for a very small convenience for kernel
>> developers that happen to see a splat or two with DEBUG_LOCKDEP set?
> 
> FWIW, if "regular users" means people running distro kernels, then chances are that they probably have DYNAMIC_DEBUG set already (100% of my local sample of 2 - Ubuntu x86_64 and Arch aarch64 - certainly do). Either way, though, this particular log spam really does only look vaguely useful to people debugging the coresight stack itself, so anyone going out of their way to turn it on has surely already gone beyond regular use (even if they're just reproducing an issue with additional logging at the request of kernel developers, rather than debugging it themselves).
> 
> Reducing the scope for possible deadlock from the general case to just debugging scenarios is certainly not a bad thing, but as you say I think we need a closer look at the underlying issue to know whether even dev_dbg() is wise.



Sorry for the delay, here is how it looks like on 4.17. In the original
version where I added this change was, slightly different, which had to
do with triggering prints from a perf-context, which could be holding
other locks/semaphores (CPU hotplug). I should have captured the log for
the commit description. I will see if I can get a better splat with the
older version.

Anyways, the following splat is only triggered when you enable printing
stuff from a perf call path. As people have already observed here, the
prints are too invasive and only helpful for the debug. We cannot move
the prints out of the path as there is no safer place outside, either.
Both sysfs mode and perf mode uses the same code path. But with perf,
you might be holding some additional semaphores/locks which is triggering
the splat. Below, stack #1 is from the perf context.



[ 1207.472310] ======================================================
[ 1207.478434] WARNING: possible circular locking dependency detected
[ 1207.484563] 4.17.0-rc3-00027-g9b9372f #73 Not tainted
[ 1207.489568] ------------------------------------------------------
[ 1207.495694] bash/2334 is trying to acquire lock:
[ 1207.500272] 000000004a592304 (&mm->mmap_sem){++++}, at: __might_fault+0x3c/0x88
[ 1207.507555]
[ 1207.507555] but task is already holding lock:
[ 1207.513339] 0000000008ac668a (&sb->s_type->i_mutex_key#3){++++}, at: iterate_dir+0x68/0x1a8
[ 1207.521652]
[ 1207.521652] which lock already depends on the new lock.
[ 1207.521652]
[ 1207.529761]
[ 1207.529761] the existing dependency chain (in reverse order) is:
[ 1207.537177]
[ 1207.537177] -> #5 (&sb->s_type->i_mutex_key#3){++++}:
[ 1207.543686]        down_write+0x48/0xa0
[ 1207.547496]        start_creating+0x54/0x118
[ 1207.551734]        debugfs_create_dir+0x14/0x110
[ 1207.556319]        opp_debug_register+0x78/0x110
[ 1207.560903]        _add_opp_dev+0x54/0x98
[ 1207.564884]        dev_pm_opp_get_opp_table+0x94/0x178
[ 1207.569982]        dev_pm_opp_add+0x20/0x68
[ 1207.574138]        scpi_dvfs_add_opps_to_device+0x80/0x108
[ 1207.579581]        scpi_cpufreq_init+0x50/0x2c0
[ 1207.584076]        cpufreq_online+0xc4/0x6e0
[ 1207.588313]        cpufreq_add_dev+0xa8/0xb8
[ 1207.592551]        subsys_interface_register+0xa4/0xf8
[ 1207.597649]        cpufreq_register_driver+0x17c/0x258
[ 1207.602747]        scpi_cpufreq_probe+0x30/0x70
[ 1207.607244]        platform_drv_probe+0x58/0xc0
[ 1207.611740]        driver_probe_device+0x2d4/0x478
[ 1207.616493]        __device_attach_driver+0xac/0x158
[ 1207.621418]        bus_for_each_drv+0x70/0xc8
[ 1207.625740]        __device_attach+0xdc/0x160
[ 1207.630063]        device_initial_probe+0x10/0x18
[ 1207.634729]        bus_probe_device+0x94/0xa0
[ 1207.639055]        device_add+0x308/0x5e8
[ 1207.643035]        platform_device_add+0x110/0x298
[ 1207.647789]        platform_device_register_full+0x10c/0x130
[ 1207.653404]        scpi_clocks_probe+0xe4/0x160
[ 1207.657901]        platform_drv_probe+0x58/0xc0
[ 1207.662396]        driver_probe_device+0x2d4/0x478
[ 1207.667149]        __device_attach_driver+0xac/0x158
[ 1207.672073]        bus_for_each_drv+0x70/0xc8
[ 1207.676397]        __device_attach+0xdc/0x160
[ 1207.680714]        device_initial_probe+0x10/0x18
[ 1207.685371]        bus_probe_device+0x94/0xa0
[ 1207.689685]        device_add+0x308/0x5e8
[ 1207.693654]        of_device_add+0x44/0x60
[ 1207.697709]        of_platform_device_create_pdata+0x80/0xe0
[ 1207.703311]        of_platform_bus_create+0x170/0x458
[ 1207.708313]        of_platform_populate+0x7c/0x130
[ 1207.713055]        devm_of_platform_populate+0x50/0xb0
[ 1207.718144]        scpi_probe+0x3c0/0x480
[ 1207.722113]        platform_drv_probe+0x58/0xc0
[ 1207.726598]        driver_probe_device+0x2d4/0x478
[ 1207.731341]        __device_attach_driver+0xac/0x158
[ 1207.736255]        bus_for_each_drv+0x70/0xc8
[ 1207.740568]        __device_attach+0xdc/0x160
[ 1207.744881]        device_initial_probe+0x10/0x18
[ 1207.749537]        bus_probe_device+0x94/0xa0
[ 1207.753851]        deferred_probe_work_func+0x58/0x180
[ 1207.758938]        process_one_work+0x228/0x410
[ 1207.763422]        worker_thread+0x25c/0x460
[ 1207.767651]        kthread+0x100/0x130
[ 1207.771363]        ret_from_fork+0x10/0x18
[ 1207.775415]
[ 1207.775415] -> #4 (opp_table_lock){+.+.}:
[ 1207.780864]        __mutex_lock+0x8c/0x8e8
[ 1207.784921]        mutex_lock_nested+0x1c/0x28
[ 1207.789321]        dev_pm_opp_get_opp_table+0x28/0x178
[ 1207.794409]        dev_pm_opp_add+0x20/0x68
[ 1207.798552]        scpi_dvfs_add_opps_to_device+0x80/0x108
[ 1207.803983]        scpi_cpufreq_init+0x50/0x2c0
[ 1207.808468]        cpufreq_online+0xc4/0x6e0
[ 1207.812695]        cpufreq_add_dev+0xa8/0xb8
[ 1207.816922]        subsys_interface_register+0xa4/0xf8
[ 1207.822009]        cpufreq_register_driver+0x17c/0x258
[ 1207.827097]        scpi_cpufreq_probe+0x30/0x70
[ 1207.831583]        platform_drv_probe+0x58/0xc0
[ 1207.836069]        driver_probe_device+0x2d4/0x478
[ 1207.840812]        __device_attach_driver+0xac/0x158
[ 1207.845726]        bus_for_each_drv+0x70/0xc8
[ 1207.850038]        __device_attach+0xdc/0x160
[ 1207.854351]        device_initial_probe+0x10/0x18
[ 1207.859009]        bus_probe_device+0x94/0xa0
[ 1207.863323]        device_add+0x308/0x5e8
[ 1207.867293]        platform_device_add+0x110/0x298
[ 1207.872036]        platform_device_register_full+0x10c/0x130
[ 1207.877639]        scpi_clocks_probe+0xe4/0x160
[ 1207.882125]        platform_drv_probe+0x58/0xc0
[ 1207.886610]        driver_probe_device+0x2d4/0x478
[ 1207.891353]        __device_attach_driver+0xac/0x158
[ 1207.896268]        bus_for_each_drv+0x70/0xc8
[ 1207.900581]        __device_attach+0xdc/0x160
[ 1207.904893]        device_initial_probe+0x10/0x18
[ 1207.909550]        bus_probe_device+0x94/0xa0
[ 1207.913865]        device_add+0x308/0x5e8
[ 1207.917833]        of_device_add+0x44/0x60
[ 1207.921888]        of_platform_device_create_pdata+0x80/0xe0
[ 1207.927490]        of_platform_bus_create+0x170/0x458
[ 1207.932491]        of_platform_populate+0x7c/0x130
[ 1207.937234]        devm_of_platform_populate+0x50/0xb0
[ 1207.942322]        scpi_probe+0x3c0/0x480
[ 1207.946292]        platform_drv_probe+0x58/0xc0
[ 1207.950777]        driver_probe_device+0x2d4/0x478
[ 1207.955520]        __device_attach_driver+0xac/0x158
[ 1207.960434]        bus_for_each_drv+0x70/0xc8
[ 1207.964747]        __device_attach+0xdc/0x160
[ 1207.969059]        device_initial_probe+0x10/0x18
[ 1207.973716]        bus_probe_device+0x94/0xa0
[ 1207.978029]        deferred_probe_work_func+0x58/0x180
[ 1207.983115]        process_one_work+0x228/0x410
[ 1207.987600]        worker_thread+0x25c/0x460
[ 1207.991827]        kthread+0x100/0x130
[ 1207.995538]        ret_from_fork+0x10/0x18
[ 1207.999590]
[ 1207.999590] -> #3 (subsys mutex#9){+.+.}:
[ 1208.005041]        __mutex_lock+0x8c/0x8e8
[ 1208.009098]        mutex_lock_nested+0x1c/0x28
[ 1208.013497]        subsys_interface_register+0x54/0xf8
[ 1208.018584]        cpufreq_register_driver+0x17c/0x258
[ 1208.023672]        scpi_cpufreq_probe+0x30/0x70
[ 1208.028157]        platform_drv_probe+0x58/0xc0
[ 1208.032643]        driver_probe_device+0x2d4/0x478
[ 1208.037386]        __device_attach_driver+0xac/0x158
[ 1208.042300]        bus_for_each_drv+0x70/0xc8
[ 1208.046613]        __device_attach+0xdc/0x160
[ 1208.050926]        device_initial_probe+0x10/0x18
[ 1208.055583]        bus_probe_device+0x94/0xa0
[ 1208.059897]        device_add+0x308/0x5e8
[ 1208.063867]        platform_device_add+0x110/0x298
[ 1208.068610]        platform_device_register_full+0x10c/0x130
[ 1208.074214]        scpi_clocks_probe+0xe4/0x160
[ 1208.078699]        platform_drv_probe+0x58/0xc0
[ 1208.083184]        driver_probe_device+0x2d4/0x478
[ 1208.087928]        __device_attach_driver+0xac/0x158
[ 1208.092842]        bus_for_each_drv+0x70/0xc8
[ 1208.097155]        __device_attach+0xdc/0x160
[ 1208.101468]        device_initial_probe+0x10/0x18
[ 1208.106124]        bus_probe_device+0x94/0xa0
[ 1208.110439]        device_add+0x308/0x5e8
[ 1208.114407]        of_device_add+0x44/0x60
[ 1208.118462]        of_platform_device_create_pdata+0x80/0xe0
[ 1208.124064]        of_platform_bus_create+0x170/0x458
[ 1208.129065]        of_platform_populate+0x7c/0x130
[ 1208.133808]        devm_of_platform_populate+0x50/0xb0
[ 1208.138896]        scpi_probe+0x3c0/0x480
[ 1208.142866]        platform_drv_probe+0x58/0xc0
[ 1208.147351]        driver_probe_device+0x2d4/0x478
[ 1208.152095]        __device_attach_driver+0xac/0x158
[ 1208.157009]        bus_for_each_drv+0x70/0xc8
[ 1208.161322]        __device_attach+0xdc/0x160
[ 1208.165635]        device_initial_probe+0x10/0x18
[ 1208.170292]        bus_probe_device+0x94/0xa0
[ 1208.174605]        deferred_probe_work_func+0x58/0x180
[ 1208.179691]        process_one_work+0x228/0x410
[ 1208.184176]        worker_thread+0x25c/0x460
[ 1208.188403]        kthread+0x100/0x130
[ 1208.192114]        ret_from_fork+0x10/0x18
[ 1208.196166]
[ 1208.196166] -> #2 (cpu_hotplug_lock.rw_sem){++++}:
[ 1208.202389]        cpus_read_lock+0x4c/0xc0
[ 1208.206531]        etm_setup_aux+0x50/0x230
[ 1208.210675]        rb_alloc_aux+0x20c/0x2e0
[ 1208.214816]        perf_mmap+0x3fc/0x670
[ 1208.218699]        mmap_region+0x38c/0x5a0
[ 1208.222754]        do_mmap+0x320/0x410
[ 1208.226466]        vm_mmap_pgoff+0xe4/0x110
[ 1208.230608]        ksys_mmap_pgoff+0xc0/0x230
[ 1208.234923]        sys_mmap+0x18/0x28
[ 1208.238548]        el0_svc_naked+0x30/0x34
[ 1208.242600]
[ 1208.242600] -> #1 (&event->mmap_mutex){+.+.}:
[ 1208.248392]        __mutex_lock+0x8c/0x8e8
[ 1208.252448]        mutex_lock_nested+0x1c/0x28
[ 1208.256848]        perf_mmap+0x150/0x670
[ 1208.260731]        mmap_region+0x38c/0x5a0
[ 1208.264786]        do_mmap+0x320/0x410
[ 1208.268497]        vm_mmap_pgoff+0xe4/0x110
[ 1208.272638]        ksys_mmap_pgoff+0xc0/0x230
[ 1208.276952]        sys_mmap+0x18/0x28
[ 1208.280577]        el0_svc_naked+0x30/0x34
[ 1208.284629]
[ 1208.284629] -> #0 (&mm->mmap_sem){++++}:
[ 1208.289991]        lock_acquire+0x44/0x60
[ 1208.293961]        __might_fault+0x60/0x88
[ 1208.298017]        filldir64+0xd0/0x340
[ 1208.301815]        dcache_readdir+0x110/0x178
[ 1208.306128]        iterate_dir+0x9c/0x1a8
[ 1208.310097]        ksys_getdents64+0x8c/0x178
[ 1208.314411]        sys_getdents64+0xc/0x18
[ 1208.318465]        el0_svc_naked+0x30/0x34
[ 1208.322518]
[ 1208.322518] other info that might help us debug this:
[ 1208.322518]
[ 1208.330443] Chain exists of:
[ 1208.330443]   &mm->mmap_sem --> opp_table_lock --> &sb->s_type->i_mutex_key#3
[ 1208.330443]
[ 1208.341831]  Possible unsafe locking scenario:
[ 1208.341831]
[ 1208.347691]        CPU0                    CPU1
[ 1208.352172]        ----                    ----
[ 1208.356653]   lock(&sb->s_type->i_mutex_key#3);
[ 1208.361145]                                lock(opp_table_lock);
[ 1208.367094]                                lock(&sb->s_type->i_mutex_key#3);
[ 1208.374079]   lock(&mm->mmap_sem);
[ 1208.377449]
[ 1208.377449]  *** DEADLOCK ***
[ 1208.377449]
[ 1208.383312] 1 lock held by bash/2334:
[ 1208.386934]  #0: 0000000008ac668a (&sb->s_type->i_mutex_key#3){++++}, at: iterate_dir+0x68/0x1a8
[ 1208.395653]
[ 1208.395653] stack backtrace:
[ 1208.399970] CPU: 4 PID: 2334 Comm: bash Not tainted 4.17.0-rc3-00027-g9b9372f #73
[ 1208.407378] Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Jul 28 2017
[ 1208.418053] Call trace:
[ 1208.420475]  dump_backtrace+0x0/0x1d0
[ 1208.424100]  show_stack+0x14/0x20
[ 1208.427382]  dump_stack+0xb8/0xf4
[ 1208.430665]  print_circular_bug.isra.20+0x1d4/0x2e0
[ 1208.435494]  __lock_acquire+0x14c8/0x19c0
[ 1208.439463]  lock_acquire+0x44/0x60
[ 1208.442917]  __might_fault+0x60/0x88
[ 1208.446456]  filldir64+0xd0/0x340
[ 1208.449736]  dcache_readdir+0x110/0x178
[ 1208.453533]  iterate_dir+0x9c/0x1a8
[ 1208.456986]  ksys_getdents64+0x8c/0x178
[ 1208.460783]  sys_getdents64+0xc/0x18
[ 1208.464321]  el0_svc_naked+0x30/0x34
[ 1397.521749] replicator_disable:86: coresight-dynamic-replicator 20120000.replicator: REPLICATOR disabled
[ 1397.531166] tmc_disable_etr_sink:1833: coresight-tmc 20070000.etr: TMC-ETR disabled
[ 1397.539439] replicator_disable:86: coresight-dynamic-replicator 20120000.replicator: REPLICATOR disabled
[ 1397.548850] tmc_disable_etr_sink:1833: coresight-tmc 20070000.etr: TMC-ETR disabled
[ 1397.557650] replicator_disable:86: coresight-dynamic-replicator 20120000.replicator: REPLICATOR disabled
[ 1397.567060] tmc_disable_etr_sink:1833: coresight-tmc 20070000.etr: TMC-ETR disabled
[ 1397.575416] replicator_disable:86: coresight-dynamic-replicator 20120000.replicator: REPLICATOR disabled
[ 1397.584820] tmc_disable_etr_sink:1833: coresight-tmc 20070000.etr: TMC-ETR disabled
[ 1397.593708] replicator_disable:86: coresight-dynamic-replicator 20120000.replicator: REPLICATOR disabled
[ 1397.603104] tmc_disable_etr_sink:1833: coresight-tmc 20070000.etr: TMC-ETR disabled



Cheers
Suzuki

^ permalink raw reply

* [PATCH] Kirin-PCIe: Add kirin pcie msi feature.
From: Bjorn Helgaas @ 2018-05-10 13:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180509045151.GA24899@dragon>

On Wed, May 09, 2018 at 12:51:53PM +0800, Shawn Guo wrote:
> Hi Bjorn,
> 
> On Tue, May 08, 2018 at 07:56:58AM -0500, Bjorn Helgaas wrote:
> ...
> > > +			return ret;
> > > +		}
> > > +	}
> > > +
> > > +	pci->pp.root_bus_nr = -1;
> > 
> > Setting root_bus_nr looks like an unrelated change that should be in a
> > separate patch.
> > 
> > But I'm not sure why you need to set root_bus_nr at all, since
> > dw_pcie_host_init() always sets it.
> > 
> > Some other callers of dw_pcie_host_init() do set it:
> > 
> >   exynos_add_pcie_port()
> >   imx6_add_pcie_port()
> >   armada8k_add_pcie_port()
> >   artpec6_add_pcie_port()
> >   dw_plat_add_pcie_port()
> >   histb_pcie_probe()
> >   qcom_pcie_probe()
> >   spear13xx_add_pcie_port()
> > 
> > But I don't see *why* any of these need to set it.  If they don't need to
> > set it, they shouldn't.
> 
> Mostly it's a blind copy of unnecessary code.  I tested histb driver
> by dropping the line, and did not see anything broken.  I will cook up
> a series to remove the code from all above drivers, and copy
> corresponding driver owner to comment.

Thanks, Shawn, I really appreciate that!

> > And it would be nice if histb and qcom followed the structure and naming
> > conventions of the other drivers, i.e., they should have
> > histb_add_pcie_port() and qcom_add_pcie_port().
> 
> I can create a patch for histb driver, but will leave qcom one to
> Stanimir to decide.

Sounds good, thanks again!

^ permalink raw reply

* [PATCH] ARM: keystone: fix platform_domain_notifier array overrun
From: Russell King @ 2018-05-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

platform_domain_notifier contains a variable sized array, which the
pm_clk_notify() notifier treats as a NULL terminated array:

     for (con_id = clknb->con_ids; *con_id; con_id++)
             pm_clk_add(dev, *con_id);

Omitting the initialiser for con_ids means that the array is zero
sized, and there is no NULL terminator.  This leads to pm_clk_notify()
overrunning into what ever structure follows, which may not be NULL.
This leads to an oops:

Unable to handle kernel NULL pointer dereference at virtual address 0000008c
pgd = c0003000
[0000008c] *pgd=80000800004003c, *pmd=00000000c
Internal error: Oops: 206 [#1] PREEMPT SMP ARM
Modules linked in:c
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.16.0+ #9
Hardware name: Keystone
PC is at strlen+0x0/0x34
LR is at kstrdup+0x18/0x54
pc : [<c0623340>]    lr : [<c0111d6c>]    psr: 20000013
sp : eec73dc0  ip : eed780c0  fp : 00000001
r10: 00000000  r9 : 00000000  r8 : eed71e10
r7 : 0000008c  r6 : 0000008c  r5 : 014000c0  r4 : c03a6ff4
r3 : c09445d0  r2 : 00000000  r1 : 014000c0  r0 : 0000008c
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 30c5387d  Table: 00003000  DAC: fffffffd
Process swapper/0 (pid: 1, stack limit = 0xeec72210)
Stack: (0xeec73dc0 to 0xeec74000)
...
[<c0623340>] (strlen) from [<c0111d6c>] (kstrdup+0x18/0x54)
[<c0111d6c>] (kstrdup) from [<c03a6ff4>] (__pm_clk_add+0x58/0x120)
[<c03a6ff4>] (__pm_clk_add) from [<c03a731c>] (pm_clk_notify+0x64/0xa8)
[<c03a731c>] (pm_clk_notify) from [<c004614c>] (notifier_call_chain+0x44/0x84)
[<c004614c>] (notifier_call_chain) from [<c0046320>] (__blocking_notifier_call_chain+0x48/0x60)
[<c0046320>] (__blocking_notifier_call_chain) from [<c0046350>] (blocking_notifier_call_chain+0x18/0x20)
[<c0046350>] (blocking_notifier_call_chain) from [<c0390234>] (device_add+0x36c/0x534)
[<c0390234>] (device_add) from [<c047fc00>] (of_platform_device_create_pdata+0x70/0xa4)
[<c047fc00>] (of_platform_device_create_pdata) from [<c047fea0>] (of_platform_bus_create+0xf0/0x1ec)
[<c047fea0>] (of_platform_bus_create) from [<c047fff8>] (of_platform_populate+0x5c/0xac)
[<c047fff8>] (of_platform_populate) from [<c08b1f04>] (of_platform_default_populate_init+0x8c/0xa8)
[<c08b1f04>] (of_platform_default_populate_init) from [<c000a78c>] (do_one_initcall+0x3c/0x164)
[<c000a78c>] (do_one_initcall) from [<c087bd9c>] (kernel_init_freeable+0x10c/0x1d0)
[<c087bd9c>] (kernel_init_freeable) from [<c0628db0>] (kernel_init+0x8/0xf0)
[<c0628db0>] (kernel_init) from [<c00090d8>] (ret_from_fork+0x14/0x3c)
Exception stack(0xeec73fb0 to 0xeec73ff8)
3fa0:                                     00000000 00000000 00000000 00000000
3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
Code: e3520000 1afffff7 e12fff1e c0801730 (e5d02000)
---[ end trace cafa8f148e262e80 ]---

Fix this by adding the necessary initialiser.

Fixes: fc20ffe1213b ("ARM: keystone: add PM domain support for clock management")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
This looks to be a latent bug that's been present since the above
commit - whether it's a problem depends on the data structure that
the linker places after platform_domain_notifier - if the first word
of the following structure is NULL, then the bug will be hidden.  If
it's a pointer to a string, or something that reasonably looks like a
string, the bug will be hidden.  If it's a value that points at an
invalid memory address, then an oops similar to the above will result.

 arch/arm/mach-keystone/pm_domain.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c
index fe57e2692629..abca83d22ff3 100644
--- a/arch/arm/mach-keystone/pm_domain.c
+++ b/arch/arm/mach-keystone/pm_domain.c
@@ -29,6 +29,7 @@ static struct dev_pm_domain keystone_pm_domain = {
 
 static struct pm_clk_notifier_block platform_domain_notifier = {
 	.pm_domain = &keystone_pm_domain,
+	.con_ids = { NULL },
 };
 
 static const struct of_device_id of_keystone_table[] = {
-- 
2.7.4

^ permalink raw reply related

* [PATCH]irqchip/irq-gic-v3:Avoid a waste of LPI resource
From: Zhang, Lei @ 2018-05-10 13:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <78df845d-0788-3cbd-e435-5a3a8221fdc8@redhat.com>

Hi Mark, Marc

> -----Original Message-----
> From: linux-arm-kernel
> [mailto:linux-arm-kernel-bounces at lists.infradead.org] On Behalf Of
> Mark Langsdorf
> Sent: Wednesday, May 09, 2018 11:32 PM
> To: linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH]irqchip/irq-gic-v3:Avoid a waste of LPI resource
> 
 
> Marc's suggestion of implementing a glue layer, and then changing the
> glue layer interface to pass the allocation requirements up to this
> driver is the best solution that can be supported for server products.

Thanks for your comments.
?
I'm considering implementing a glue layer. But the management of 
whole LPI resource is implemented by core ITS driver (irq-gic-v3-its.c),
So I think core ITS driver also need to be modified.
?
Below is my idea for core ITS driver. 
Would you give me comments?
?
Add an interface that can specify the number of LPIs allocation requirements on Core ITS driver.
My idea is extend its_msi_prepare function by adding two argument.

SYNOPSIS
its_msi_prepare(struct irq_domain *domain, struct device *dev,int nvec,
 msi_alloc_info_t *info,int request_nr_lpis, int request_lpis_align)
?
Argument "request_nr_lpis" means request LPIs total number for device. 
Argument "request_lpis_align" means request of LPIs alignment. 0 means do not specify alignment.

For PCI, PCI glue layer specifies, request_nr_lpis = 32, request_lpis_align = 32.
For our device, the glue layer specifies, request_nr_lpis = 1, request_lpis_align = 0.
(We have lots of device but each device only need a single LPI on our original bus. )
?

For expanding two arguments, core ITS driver maybe need to discard chunk mechanism 
and use bitmap to manage LPI resource directly.
?
Example:
 (1) Non PCI glue layer requires ?request_nr_lpis? = 1, ?request_lpis_align? = 0.
?
    Bitmap will become  ...0000000000000000001
?
 (2) PCI glue layer requires ?request_nr_lpis? = 32, ?request_lpis_align? = 32.
?
    Bitmap will become  ...000FFFFFFFF00000001
?
?
 (3) Non PCI glue layer requires ?request_nr_lpis? = 1, ?request_lpis_align? = 0.
?
    Bitmap will become  ...000FFFFFFFF00000003
?
I think it may be easy to implement by using bitmap_find_next_zero_area, because it has ?align_mask? argument.

Regards,
Lei Zhang
--
Lei Zhang  e-mail: zhang.lei at jp.fujitsu.com FUJITSU LIMITED

^ permalink raw reply

* [PATCH] ARM: dts: socfpga: Fix NAND controller node compatible
From: Marek Vasut @ 2018-05-10 12:52 UTC (permalink / raw)
  To: linux-arm-kernel

The compatible string for the Denali NAND controller is incorrect,
fix it by replacing it with one matching the DT bindings and the
driver.

Signed-off-by: Marek Vasut <marex@denx.de>
Fixes: d837a80d19 ("ARM: dts: socfpga: add nand controller nodes")
Cc: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Cc: Dinh Nguyen <dinguyen@kernel.org>
---
 arch/arm/boot/dts/socfpga.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 7e24dc8e82d4..d697f5062624 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -744,7 +744,7 @@
 		nand0: nand at ff900000 {
 			#address-cells = <0x1>;
 			#size-cells = <0x1>;
-			compatible = "denali,denali-nand-dt";
+			compatible = "altr,socfpga-denali-nand";
 			reg = <0xff900000 0x100000>,
 			      <0xffb80000 0x10000>;
 			reg-names = "nand_data", "denali_reg";
-- 
2.16.2

^ permalink raw reply related

* [PATCH v1 3/5] arm64: dts: rockchip: Add gpio-syscon10 to rk3328
From: Robin Murphy @ 2018-05-10 12:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525943800-14095-4-git-send-email-djw@t-chip.com.cn>

On 10/05/18 10:16, djw at t-chip.com.cn wrote:
> From: Levin Du <djw@t-chip.com.cn>
> 
> Adding a new gpio controller named "gpio-syscon10" to rk3328, providing
> access to the pins defined in the syscon GRF_SOC_CON10.

This is the GPIO_MUTE pin, right? The public TRM is rather vague, but 
cross-referencing against the datasheet and schematics implies that it's 
the "gpiomut_*" part of the GRF bit names which is most significant.

It might be worth using a more descriptive name here, since "syscon10" 
is pretty much meaningless at the board level.

Robin.

> Boards using these special pins to control regulators or LEDs, can now
> utilize existing drivers like gpio-regulator and leds-gpio.
> 
> Signed-off-by: Levin Du <djw@t-chip.com.cn>
> 
> ---
> 
> Changes in v1:
> - Split from V0 and add to rk3328.dtsi for general use.
> 
>   arch/arm64/boot/dts/rockchip/rk3328.dtsi | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> index b8e9da1..73a822d 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> @@ -309,6 +309,12 @@
>   			mode-loader = <BOOT_BL_DOWNLOAD>;
>   		};
>   
> +		gpio_syscon10: gpio-syscon10 {
> +			compatible = "rockchip,gpio-syscon";
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio,syscon-dev = <0 0x0428 0>;
> +		};
>   	};
>   
>   	uart0: serial at ff110000 {
> 

^ permalink raw reply

* [PATCH] arm64: msm8916: fix gic_irq_domain_translate warnings
From: Vinod Koul @ 2018-05-10 12:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHLCerOZ3_A7PvD6i53WXLJXVPmUWcNakvA2gcwFYMT9f1iR0A@mail.gmail.com>

On 10-05-18, 12:03, Amit Kucheria wrote:
> On Wed, Apr 18, 2018 at 7:34 PM,  <srinivas.kandagatla@linaro.org> wrote:
> > From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> >
> > Remove the usage of IRQ_TYPE_NONE to fix loud warnings from
> > patch (83a86fbb5b56b "irqchip/gic: Loudly complain about
> > the use of IRQ_TYPE_NONE").
> >
> > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> 
> Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
> Tested-by: Amit Kucheria <amit.kucheria@linaro.org>

Tested-by: Vinod Koul <vkoul@kernel.org>

-- 
~Vinod

^ permalink raw reply

* [PATCH v2 3/3] rtc: stm32: add stm32mp1 rtc support
From: kbuild test robot @ 2018-05-10 11:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525880770-22263-4-git-send-email-amelie.delaunay@st.com>

Hi Amelie,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on abelloni/rtc-next]
[also build test WARNING on next-20180510]
[cannot apply to v4.17-rc4]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Amelie-Delaunay/Introduce-STM32MP1-RTC/20180510-054013
base:   https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next

smatch warnings:
drivers/rtc/rtc-stm32.c:827 stm32_rtc_probe() warn: always true condition '(regs.verr != ~0) => (0-u16max != (-1))'

vim +827 drivers/rtc/rtc-stm32.c

   694	
   695	static int stm32_rtc_probe(struct platform_device *pdev)
   696	{
   697		struct stm32_rtc *rtc;
   698		struct stm32_rtc_registers regs;
   699		struct resource *res;
   700		int ret;
   701	
   702		rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
   703		if (!rtc)
   704			return -ENOMEM;
   705	
   706		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   707		rtc->base = devm_ioremap_resource(&pdev->dev, res);
   708		if (IS_ERR(rtc->base))
   709			return PTR_ERR(rtc->base);
   710	
   711		rtc->data = (struct stm32_rtc_data *)
   712			    of_device_get_match_data(&pdev->dev);
   713		regs = rtc->data->regs;
   714	
   715		if (rtc->data->need_dbp) {
   716			rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
   717								   "st,syscfg");
   718			if (IS_ERR(rtc->dbp)) {
   719				dev_err(&pdev->dev, "no st,syscfg\n");
   720				return PTR_ERR(rtc->dbp);
   721			}
   722	
   723			ret = of_property_read_u32_index(pdev->dev.of_node, "st,syscfg",
   724							 1, &rtc->dbp_reg);
   725			if (ret) {
   726				dev_err(&pdev->dev, "can't read DBP register offset\n");
   727				return ret;
   728			}
   729	
   730			ret = of_property_read_u32_index(pdev->dev.of_node, "st,syscfg",
   731							 2, &rtc->dbp_mask);
   732			if (ret) {
   733				dev_err(&pdev->dev, "can't read DBP register mask\n");
   734				return ret;
   735			}
   736		}
   737	
   738		if (!rtc->data->has_pclk) {
   739			rtc->pclk = NULL;
   740			rtc->rtc_ck = devm_clk_get(&pdev->dev, NULL);
   741		} else {
   742			rtc->pclk = devm_clk_get(&pdev->dev, "pclk");
   743			if (IS_ERR(rtc->pclk)) {
   744				dev_err(&pdev->dev, "no pclk clock");
   745				return PTR_ERR(rtc->pclk);
   746			}
   747			rtc->rtc_ck = devm_clk_get(&pdev->dev, "rtc_ck");
   748		}
   749		if (IS_ERR(rtc->rtc_ck)) {
   750			dev_err(&pdev->dev, "no rtc_ck clock");
   751			return PTR_ERR(rtc->rtc_ck);
   752		}
   753	
   754		if (rtc->data->has_pclk) {
   755			ret = clk_prepare_enable(rtc->pclk);
   756			if (ret)
   757				return ret;
   758		}
   759	
   760		ret = clk_prepare_enable(rtc->rtc_ck);
   761		if (ret)
   762			goto err;
   763	
   764		if (rtc->data->need_dbp)
   765			regmap_update_bits(rtc->dbp, rtc->dbp_reg,
   766					   rtc->dbp_mask, rtc->dbp_mask);
   767	
   768		/*
   769		 * After a system reset, RTC_ISR.INITS flag can be read to check if
   770		 * the calendar has been initialized or not. INITS flag is reset by a
   771		 * power-on reset (no vbat, no power-supply). It is not reset if
   772		 * rtc_ck parent clock has changed (so RTC prescalers need to be
   773		 * changed). That's why we cannot rely on this flag to know if RTC
   774		 * init has to be done.
   775		 */
   776		ret = stm32_rtc_init(pdev, rtc);
   777		if (ret)
   778			goto err;
   779	
   780		rtc->irq_alarm = platform_get_irq(pdev, 0);
   781		if (rtc->irq_alarm <= 0) {
   782			dev_err(&pdev->dev, "no alarm irq\n");
   783			ret = rtc->irq_alarm;
   784			goto err;
   785		}
   786	
   787		ret = device_init_wakeup(&pdev->dev, true);
   788		if (rtc->data->has_wakeirq) {
   789			rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
   790			if (rtc->wakeirq_alarm <= 0)
   791				ret = rtc->wakeirq_alarm;
   792			else
   793				ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
   794								    rtc->wakeirq_alarm);
   795		}
   796		if (ret)
   797			dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
   798	
   799		platform_set_drvdata(pdev, rtc);
   800	
   801		rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
   802							&stm32_rtc_ops, THIS_MODULE);
   803		if (IS_ERR(rtc->rtc_dev)) {
   804			ret = PTR_ERR(rtc->rtc_dev);
   805			dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
   806				ret);
   807			goto err;
   808		}
   809	
   810		/* Handle RTC alarm interrupts */
   811		ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_alarm, NULL,
   812						stm32_rtc_alarm_irq, IRQF_ONESHOT,
   813						pdev->name, rtc);
   814		if (ret) {
   815			dev_err(&pdev->dev, "IRQ%d (alarm interrupt) already claimed\n",
   816				rtc->irq_alarm);
   817			goto err;
   818		}
   819	
   820		/*
   821		 * If INITS flag is reset (calendar year field set to 0x00), calendar
   822		 * must be initialized
   823		 */
   824		if (!(readl_relaxed(rtc->base + regs.isr) & STM32_RTC_ISR_INITS))
   825			dev_warn(&pdev->dev, "Date/Time must be initialized\n");
   826	
 > 827		if (regs.verr != UNDEF_REG) {
   828			u32 ver = readl_relaxed(rtc->base + regs.verr);
   829	
   830			dev_info(&pdev->dev, "registered rev:%d.%d\n",
   831				 (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
   832				 (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
   833		}
   834	
   835		return 0;
   836	err:
   837		if (rtc->data->has_pclk)
   838			clk_disable_unprepare(rtc->pclk);
   839		clk_disable_unprepare(rtc->rtc_ck);
   840	
   841		if (rtc->data->need_dbp)
   842			regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
   843	
   844		dev_pm_clear_wake_irq(&pdev->dev);
   845		device_init_wakeup(&pdev->dev, false);
   846	
   847		return ret;
   848	}
   849	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply

* [PATCH v2] tty: implement led triggers
From: Robin Murphy @ 2018-05-10 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510111434.GC6977@amd>

On 10/05/18 12:14, Pavel Machek wrote:
> Hi!
> 
>>>>> @@ -499,6 +500,7 @@ static void flush_to_ldisc(struct work_struct *work)
>>>>>   		struct tty_buffer *head = buf->head;
>>>>>   		struct tty_buffer *next;
>>>>>   		int count;
>>>>> +		unsigned long delay = 50 /* ms */;
>>>>
>>>> Comment after the semicolon?
>>>
>>> Given that this comment is about the 50 and not the delay member, I
>>> prefer it before the ;.
>>
>> Hmm. I personally find it hard to read and can only find about 30
>> instances of this comment style (for assignments) in the kernel. And
>> arguably the comment applies equally well to the delay variable in this
>> case too.
> 
> It is not too traditional, but I believe it makes sense....
> 
> (and yes, I wish we had kernel in Rust, so we could have real units
> attached to our variables...)

Well, the variable itself could always be named "delay_ms" if it's 
really that important.

Robin.

^ permalink raw reply

* [PATCH v3 1/3] leds: triggers: provide led_trigger_register_format()
From: Pavel Machek @ 2018-05-10 11:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180510112101.GD6977@amd>

On Thu 2018-05-10 13:21:01, Pavel Machek wrote:
> Hi!
> 
> > This allows one to simplify drivers that provide a trigger with a
> > non-constant name (e.g. one trigger per device with the trigger name
> > depending on the device's name).
> > 
> > Internally the memory the name member of struct led_trigger points to
> > now always allocated dynamically instead of just taken from the caller.
> > 
> > The function led_trigger_rename_static() must be changed accordingly and
> > was renamed to led_trigger_rename() for consistency, with the only user
> > adapted.
> 
> Well, I'm not sure if we want to have _that_ many trigger. Trigger
> interface is going to become.. "interesting".
> 
> We have 4K limit on total number of triggers. We use rather strange
> interface to select trigger.
> 
> > @@ -115,13 +115,13 @@ static int can_led_notifier(struct notifier_block *nb, unsigned long msg,
> >  
> >  	if (msg == NETDEV_CHANGENAME) {
> >  		snprintf(name, sizeof(name), "%s-tx", netdev->name);
> > -		led_trigger_rename_static(name, priv->tx_led_trig);
> > +		led_trigger_rename(priv->tx_led_trig, name);
> >  
> >  		snprintf(name, sizeof(name), "%s-rx", netdev->name);
> > -		led_trigger_rename_static(name, priv->rx_led_trig);
> > +		led_trigger_rename(priv->rx_led_trig, name);
> >  
> >  		snprintf(name, sizeof(name), "%s-rxtx", netdev->name);
> > -		led_trigger_rename_static(name, priv->rxtx_led_trig);
> > +		led_trigger_rename(priv->rxtx_led_trig, name);
> >  	}
> >  
> 
> I know this is not your fault, but if you have a space or "[]" in
> netdev names, confusing things will happen.

Hmm. If we are doing this we really should check trigger names for
forbidden characters. At least "[] " should be forbidden.
								Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180510/b72fc1a4/attachment.sig>

^ permalink raw reply

* [PATCH v3 1/3] leds: triggers: provide led_trigger_register_format()
From: Pavel Machek @ 2018-05-10 11:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180508100543.12559-2-u.kleine-koenig@pengutronix.de>

Hi!

> This allows one to simplify drivers that provide a trigger with a
> non-constant name (e.g. one trigger per device with the trigger name
> depending on the device's name).
> 
> Internally the memory the name member of struct led_trigger points to
> now always allocated dynamically instead of just taken from the caller.
> 
> The function led_trigger_rename_static() must be changed accordingly and
> was renamed to led_trigger_rename() for consistency, with the only user
> adapted.

Well, I'm not sure if we want to have _that_ many trigger. Trigger
interface is going to become.. "interesting".

We have 4K limit on total number of triggers. We use rather strange
interface to select trigger.

> @@ -115,13 +115,13 @@ static int can_led_notifier(struct notifier_block *nb, unsigned long msg,
>  
>  	if (msg == NETDEV_CHANGENAME) {
>  		snprintf(name, sizeof(name), "%s-tx", netdev->name);
> -		led_trigger_rename_static(name, priv->tx_led_trig);
> +		led_trigger_rename(priv->tx_led_trig, name);
>  
>  		snprintf(name, sizeof(name), "%s-rx", netdev->name);
> -		led_trigger_rename_static(name, priv->rx_led_trig);
> +		led_trigger_rename(priv->rx_led_trig, name);
>  
>  		snprintf(name, sizeof(name), "%s-rxtx", netdev->name);
> -		led_trigger_rename_static(name, priv->rxtx_led_trig);
> +		led_trigger_rename(priv->rxtx_led_trig, name);
>  	}
>  

I know this is not your fault, but if you have a space or "[]" in
netdev names, confusing things will happen.

I believe we should have triggers "net-rx, net-tx" and it should have
parameter "which device it acts on". 
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180510/4e84c1e3/attachment.sig>

^ permalink raw reply

* [PATCH v2] tty: implement led triggers
From: Pavel Machek @ 2018-05-10 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180507092710.GQ2285@localhost>

Hi!

> > > > @@ -499,6 +500,7 @@ static void flush_to_ldisc(struct work_struct *work)
> > > >  		struct tty_buffer *head = buf->head;
> > > >  		struct tty_buffer *next;
> > > >  		int count;
> > > > +		unsigned long delay = 50 /* ms */;
> > > 
> > > Comment after the semicolon?
> > 
> > Given that this comment is about the 50 and not the delay member, I
> > prefer it before the ;.
> 
> Hmm. I personally find it hard to read and can only find about 30
> instances of this comment style (for assignments) in the kernel. And
> arguably the comment applies equally well to the delay variable in this
> case too.

It is not too traditional, but I believe it makes sense....

(and yes, I wish we had kernel in Rust, so we could have real units
attached to our variables...)

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180510/fe3e817a/attachment.sig>

^ permalink raw reply

* [PATCHv2] ARM64: KVM: use lm_alias() for kvm_ksym_ref()
From: Mark Rutland @ 2018-05-10 11:13 UTC (permalink / raw)
  To: linux-arm-kernel

For historical reasons, we open-code lm_alias() in kvm_ksym_ref().

Let's use lm_alias() to avoid duplication and make things clearer.

As we have to pull this from <linux/mm.h> (which is not safe for
inclusion in assembly), we may as well move the kvm_ksym_ref()
definition into the existing !__ASSEMBLY__ block.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Christoffer Dall <christoffer.dall@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: kvmarm at lists.cs.columbia.edu
---
 arch/arm64/include/asm/kvm_asm.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Since v1 [1]:
* Rebase to v4.17-rc4
* Fix typo in commit message

Mark.

[1] https://lkml.kernel.org/r/20180406151909.57197-1-mark.rutland at arm.com

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index f6648a3e4152..a9ceeec5a76f 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -33,16 +33,19 @@
 #define KVM_ARM64_DEBUG_DIRTY_SHIFT	0
 #define KVM_ARM64_DEBUG_DIRTY		(1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
 
+#ifndef __ASSEMBLY__
+
+#include <linux/mm.h>
+
 /* Translate a kernel address of @sym into its equivalent linear mapping */
 #define kvm_ksym_ref(sym)						\
 	({								\
 		void *val = &sym;					\
 		if (!is_kernel_in_hyp_mode())				\
-			val = phys_to_virt((u64)&sym - kimage_voffset);	\
+			val = lm_alias(&sym);				\
 		val;							\
 	 })
 
-#ifndef __ASSEMBLY__
 struct kvm;
 struct kvm_vcpu;
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH] ARM: dts: vexpress: Replace '_' with '-' in node names
From: Sudeep Holla @ 2018-05-10 10:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL_Jsq+VNuvbxgFTFVouJF-_yMS90u0fd8jaXnYtKwogOP5rww@mail.gmail.com>



On 09/05/18 22:14, Rob Herring wrote:
> On Wed, May 9, 2018 at 11:48 AM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>> The latest DTC throws warnings for character '_' in the node names.
>>
>> Warning (node_name_chars_strict): /sysreg at 10000/sys_led: Character '_' not recommended in node name
>> Warning (node_name_chars_strict): /sysreg at 10000/sys_mci: Character '_' not recommended in node name
>> Warning (node_name_chars_strict): /sysreg at 10000/sys_flash: Character '_' not recommended in node name
>>
>> The general recommendation is to use character '-' for all the node names.
>> This patch fixes the warnings following the recommendation.
>>
>> Cc: Liviu Dudau <liviu.dudau@arm.com>
>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
>> ---
>>  arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
>> index 7b8ff5b3b912..58e73131ecef 100644
>> --- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
>> +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
>> @@ -77,19 +77,19 @@
>>                                         compatible = "arm,vexpress-sysreg";
>>                                         reg = <0x010000 0x1000>;
>>
>> -                                       v2m_led_gpios: sys_led {
>> +                                       v2m_led_gpios: sys-led {
> 
> Except this is a gpio-controller so it should have 'gpio' for its node
> name. (I have a dtc check written for that, but there are too many
> false positives.)
> 

True, sorry I didn't look at it in detail.

> But then you have 3 of them and no addressing, so you need to add reg
> property (with the register's offset and size) and unit-address.
> 

Indeed. I had a look at the history but couldn't gather much. All I
could get is that this is one of those weird mix of all functionality on
ARM Ltd platforms which fits no subsystem. Me and Lorenzo has similar
issue on TC2 platform. Pawel seem to have plumed this system control
registers block into MFD and GPIO long back.

> I'm surprised Linus W accepted these a GPIO when they are not really
> general purpose, but then lots of things slip in.
> 

I assume all these happened in early days of DT.

I will drop this for now. I will take a look if these nodes can be made
better to align with standard gpio controller nodes.

-- 
Regards,
Sudeep

^ permalink raw reply

* [PATCH v5 9/9] ARM: dts: at91: sama5d2: Add resistive touch device
From: Eugen Hristev @ 2018-05-10 10:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525949114-29263-1-git-send-email-eugen.hristev@microchip.com>

Add generic resistive touch device which is connected to ADC block
inside the SAMA5D2 SoC

Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
Changes in v5:
 - renamed touchscreen-threshold-pressure to touchscreen-min-pressure

 arch/arm/boot/dts/sama5d2.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index f06ba99..a44f325 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -1442,6 +1442,16 @@
 				status = "disabled";
 			};
 
+			resistive_touch: resistive-touch {
+				compatible = "resistive-adc-touch";
+				io-channels = <&adc AT91_SAMA5D2_ADC_X_CHANNEL>,
+					      <&adc AT91_SAMA5D2_ADC_Y_CHANNEL>,
+					      <&adc AT91_SAMA5D2_ADC_P_CHANNEL>;
+				io-channel-names = "x", "y", "pressure";
+				touchscreen-min-pressure = <50000>;
+				status = "disabled";
+			};
+
 			pioA: pinctrl at fc038000 {
 				compatible = "atmel,sama5d2-pinctrl";
 				reg = <0xfc038000 0x600>;
-- 
2.7.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox