Commit d05cfbd9 authored by Peng Liu's avatar Peng Liu Committed by Zheng Zengkai
Browse files

arm64: Add support for memmap kernel parameters

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NYPZ


CVE: NA

-------------------------------------------------

Add support for memmap kernel parameters for ARM64. The three below
modes are supported:

memmap=exactmap
Enable setting of an exact memory map, as specified by the user.

memmap=nn[KMG]@ss[KMG]
Force usage of a specific region of memory.

memmap=nn[KMG]$ss[KMG]
Region of memory to be reserved is from ss to ss+nn, the region must
be in the range of existed memory, otherwise will be ignored.

If users set memmap=exactmap before memmap=nn[KMG]@ss[KMG], they will
get the exact memory specified by memmap=nn[KMG]@ss[KMG]. For example,
on one machine with 4GB memory, "memmap=exactmap memmap=1G@1G" will
make kernel use the memory from 1GB to 2GB only.

Signed-off-by: default avatarPeng Liu <liupeng256@huawei.com>
Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 8c34e5f6
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -2794,8 +2794,8 @@
			option.
			See Documentation/admin-guide/mm/memory-hotplug.rst.

	memmap=exactmap	[KNL,X86] Enable setting of an exact
			E820 memory map, as specified by the user.
	memmap=exactmap	[KNL,X86,ARM64] Enable setting of an exact
			E820 and ARM64 memory map, as specified by the user.
			Such memmap=exactmap lines can be constructed based on
			BIOS output or other requirements. See the memmap=nn@ss
			option description.
@@ -2806,7 +2806,8 @@
			If @ss[KMG] is omitted, it is equivalent to mem=nn[KMG],
			which limits max address to nn[KMG].
			Multiple different regions can be specified,
			comma delimited.
			comma delimited, example as follows is not supported to
			ARM64.
			Example:
				memmap=100M@2G,100M#3G,1G!1024G

@@ -2817,6 +2818,8 @@
	memmap=nn[KMG]$ss[KMG]
			[KNL,ACPI] Mark specific memory as reserved.
			Region of memory to be reserved is from ss to ss+nn.
			For ARM64, reserved memory must be in the range of
			existed memory.
			Example: Exclude memory from 0x18690000-0x1869ffff
			         memmap=64K$0x18690000
			         or
+59 −0
Original line number Diff line number Diff line
@@ -404,6 +404,65 @@ static int __init reserve_park_mem(void)
}
#endif

static int need_remove_real_memblock __initdata;

static int __init parse_memmap_one(char *p)
{
	char *oldp;
	u64 start_at, mem_size;

	if (!p)
		return -EINVAL;

	if (!strncmp(p, "exactmap", 8)) {
		need_remove_real_memblock = 1;
		return -EINVAL;
	}

	oldp = p;
	mem_size = memparse(p, &p);
	if (p == oldp)
		return -EINVAL;

	if (!mem_size)
		return -EINVAL;

	if (*p == '@') {
		start_at = memparse(p + 1, &p);
		/*
		 * use the exactmap defined by nn[KMG]@ss[KMG], remove
		 * memblock populated by DT etc.
		 */
		if (need_remove_real_memblock) {
			need_remove_real_memblock = 0;
			memblock_remove(0, ULLONG_MAX);
		}
		memblock_add(start_at, mem_size);
	} else if (*p == '$') {
		start_at = memparse(p + 1, &p);
		memblock_reserve(start_at, mem_size);
	} else
		pr_info("Unrecognized memmap option, please check the parameter.\n");

	return *p == '\0' ? 0 : -EINVAL;
}

static int __init parse_memmap_opt(char *str)
{
	while (str) {
		char *k = strchr(str, ',');

		if (k)
			*k++ = 0;

		parse_memmap_one(str);
		str = k;
	}

	return 0;
}
early_param("memmap", parse_memmap_opt);

void __init arm64_memblock_init(void)
{
	const s64 linear_region_size = BIT(vabits_actual - 1);