2022-05-31 10:04:11 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
|
|
|
*
|
|
|
|
* Derived from MIPS:
|
|
|
|
* Copyright (C) 1995 Linus Torvalds
|
|
|
|
* Copyright (C) 1995 Waldorf Electronics
|
|
|
|
* Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 Ralf Baechle
|
|
|
|
* Copyright (C) 1996 Stoned Elipot
|
|
|
|
* Copyright (C) 1999 Silicon Graphics, Inc.
|
|
|
|
* Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki
|
|
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/acpi.h>
|
2023-06-13 23:39:28 +00:00
|
|
|
#include <linux/cpu.h>
|
2022-05-31 10:04:11 +00:00
|
|
|
#include <linux/dmi.h>
|
|
|
|
#include <linux/efi.h>
|
|
|
|
#include <linux/export.h>
|
|
|
|
#include <linux/memblock.h>
|
|
|
|
#include <linux/initrd.h>
|
|
|
|
#include <linux/ioport.h>
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
#include <linux/kexec.h>
|
|
|
|
#include <linux/crash_dump.h>
|
2022-05-31 10:04:11 +00:00
|
|
|
#include <linux/root_dev.h>
|
|
|
|
#include <linux/console.h>
|
|
|
|
#include <linux/pfn.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/sizes.h>
|
|
|
|
#include <linux/device.h>
|
|
|
|
#include <linux/dma-map-ops.h>
|
2022-12-10 14:40:05 +00:00
|
|
|
#include <linux/libfdt.h>
|
|
|
|
#include <linux/of_fdt.h>
|
|
|
|
#include <linux/of_address.h>
|
2022-12-10 14:40:15 +00:00
|
|
|
#include <linux/suspend.h>
|
2022-05-31 10:04:11 +00:00
|
|
|
#include <linux/swiotlb.h>
|
|
|
|
|
|
|
|
#include <asm/addrspace.h>
|
2022-12-10 14:39:59 +00:00
|
|
|
#include <asm/alternative.h>
|
2022-05-31 10:04:11 +00:00
|
|
|
#include <asm/bootinfo.h>
|
|
|
|
#include <asm/cache.h>
|
|
|
|
#include <asm/cpu.h>
|
|
|
|
#include <asm/dma.h>
|
|
|
|
#include <asm/efi.h>
|
|
|
|
#include <asm/loongson.h>
|
2022-05-31 10:04:12 +00:00
|
|
|
#include <asm/numa.h>
|
2022-05-31 10:04:11 +00:00
|
|
|
#include <asm/pgalloc.h>
|
|
|
|
#include <asm/sections.h>
|
|
|
|
#include <asm/setup.h>
|
|
|
|
#include <asm/time.h>
|
|
|
|
|
|
|
|
#define SMBIOS_BIOSSIZE_OFFSET 0x09
|
|
|
|
#define SMBIOS_BIOSEXTERN_OFFSET 0x13
|
|
|
|
#define SMBIOS_FREQLOW_OFFSET 0x16
|
|
|
|
#define SMBIOS_FREQHIGH_OFFSET 0x17
|
|
|
|
#define SMBIOS_FREQLOW_MASK 0xFF
|
|
|
|
#define SMBIOS_CORE_PACKAGE_OFFSET 0x23
|
|
|
|
#define LOONGSON_EFI_ENABLE (1 << 3)
|
|
|
|
|
efi/loongarch: libstub: remove dependency on flattened DT
LoongArch does not use FDT or DT natively [yet], and the only reason it
currently uses it is so that it can reuse the existing EFI stub code.
Overloading the DT with data passed between the EFI stub and the core
kernel has been a source of problems: there is the overlap between
information provided by EFI which DT can also provide (initrd base/size,
command line, memory descriptions), requiring us to reason about which
is which and what to prioritize. It has also resulted in ABI leaks,
i.e., internal ABI being promoted to external ABI inadvertently because
the bootloader can set the EFI stub's DT properties as well (e.g.,
"kaslr-seed"). This has become especially problematic with boot
environments that want to pretend that EFI boot is being done (to access
ACPI and SMBIOS tables, for instance) but have no ability to execute the
EFI stub, and so the environment that the EFI stub creates is emulated
[poorly, in some cases].
Another downside of treating DT like this is that the DT binary that the
kernel receives is different from the one created by the firmware, which
is undesirable in the context of secure and measured boot.
Given that LoongArch support in Linux is brand new, we can avoid these
pitfalls, and treat the DT strictly as a hardware description, and use a
separate handover method between the EFI stub and the kernel. Now that
initrd loading and passing the EFI memory map have been refactored into
pure EFI routines that use EFI configuration tables, the only thing we
need to pass directly is the kernel command line (even if we could pass
this via a config table as well, it is used extremely early, so passing
it directly is preferred in this case.)
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Huacai Chen <chenhuacai@loongson.cn>
2022-09-16 17:48:53 +00:00
|
|
|
unsigned long fw_arg0, fw_arg1, fw_arg2;
|
2022-05-31 10:04:11 +00:00
|
|
|
DEFINE_PER_CPU(unsigned long, kernelsp);
|
|
|
|
struct cpuinfo_loongarch cpu_data[NR_CPUS] __read_mostly;
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(cpu_data);
|
|
|
|
|
|
|
|
struct loongson_board_info b_info;
|
|
|
|
static const char dmi_empty_string[] = " ";
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Setup information
|
|
|
|
*
|
|
|
|
* These are initialized so they are in the .data section
|
|
|
|
*/
|
2022-12-10 14:40:05 +00:00
|
|
|
char init_command_line[COMMAND_LINE_SIZE] __initdata;
|
2022-05-31 10:04:11 +00:00
|
|
|
|
|
|
|
static int num_standard_resources;
|
|
|
|
static struct resource *standard_resources;
|
|
|
|
|
|
|
|
static struct resource code_resource = { .name = "Kernel code", };
|
|
|
|
static struct resource data_resource = { .name = "Kernel data", };
|
|
|
|
static struct resource bss_resource = { .name = "Kernel bss", };
|
|
|
|
|
|
|
|
const char *get_system_type(void)
|
|
|
|
{
|
|
|
|
return "generic-loongson-machine";
|
|
|
|
}
|
|
|
|
|
2023-06-13 23:39:28 +00:00
|
|
|
void __init arch_cpu_finalize_init(void)
|
2022-12-10 14:39:59 +00:00
|
|
|
{
|
|
|
|
alternative_instructions();
|
|
|
|
}
|
|
|
|
|
2022-05-31 10:04:11 +00:00
|
|
|
static const char *dmi_string_parse(const struct dmi_header *dm, u8 s)
|
|
|
|
{
|
|
|
|
const u8 *bp = ((u8 *) dm) + dm->length;
|
|
|
|
|
|
|
|
if (s) {
|
|
|
|
s--;
|
|
|
|
while (s > 0 && *bp) {
|
|
|
|
bp += strlen(bp) + 1;
|
|
|
|
s--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*bp != 0) {
|
|
|
|
size_t len = strlen(bp)+1;
|
|
|
|
size_t cmp_len = len > 8 ? 8 : len;
|
|
|
|
|
|
|
|
if (!memcmp(bp, dmi_empty_string, cmp_len))
|
|
|
|
return dmi_empty_string;
|
|
|
|
|
|
|
|
return bp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __init parse_cpu_table(const struct dmi_header *dm)
|
|
|
|
{
|
|
|
|
long freq_temp = 0;
|
|
|
|
char *dmi_data = (char *)dm;
|
|
|
|
|
|
|
|
freq_temp = ((*(dmi_data + SMBIOS_FREQHIGH_OFFSET) << 8) +
|
|
|
|
((*(dmi_data + SMBIOS_FREQLOW_OFFSET)) & SMBIOS_FREQLOW_MASK));
|
|
|
|
cpu_clock_freq = freq_temp * 1000000;
|
|
|
|
|
|
|
|
loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]);
|
|
|
|
loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_CORE_PACKAGE_OFFSET);
|
|
|
|
|
|
|
|
pr_info("CpuClock = %llu\n", cpu_clock_freq);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __init parse_bios_table(const struct dmi_header *dm)
|
|
|
|
{
|
|
|
|
char *dmi_data = (char *)dm;
|
|
|
|
|
2022-07-21 09:53:01 +00:00
|
|
|
b_info.bios_size = (*(dmi_data + SMBIOS_BIOSSIZE_OFFSET) + 1) << 6;
|
2022-05-31 10:04:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void __init find_tokens(const struct dmi_header *dm, void *dummy)
|
|
|
|
{
|
|
|
|
switch (dm->type) {
|
|
|
|
case 0x0: /* Extern BIOS */
|
|
|
|
parse_bios_table(dm);
|
|
|
|
break;
|
|
|
|
case 0x4: /* Calling interface */
|
|
|
|
parse_cpu_table(dm);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static void __init smbios_parse(void)
|
|
|
|
{
|
|
|
|
b_info.bios_vendor = (void *)dmi_get_system_info(DMI_BIOS_VENDOR);
|
|
|
|
b_info.bios_version = (void *)dmi_get_system_info(DMI_BIOS_VERSION);
|
|
|
|
b_info.bios_release_date = (void *)dmi_get_system_info(DMI_BIOS_DATE);
|
|
|
|
b_info.board_vendor = (void *)dmi_get_system_info(DMI_BOARD_VENDOR);
|
|
|
|
b_info.board_name = (void *)dmi_get_system_info(DMI_BOARD_NAME);
|
|
|
|
dmi_walk(find_tokens, NULL);
|
|
|
|
}
|
|
|
|
|
2023-04-18 11:38:58 +00:00
|
|
|
#ifdef CONFIG_ARCH_WRITECOMBINE
|
2023-10-18 00:42:52 +00:00
|
|
|
bool wc_enabled = true;
|
2023-04-18 11:38:58 +00:00
|
|
|
#else
|
2023-10-18 00:42:52 +00:00
|
|
|
bool wc_enabled = false;
|
2023-04-18 11:38:58 +00:00
|
|
|
#endif
|
|
|
|
|
2023-10-18 00:42:52 +00:00
|
|
|
EXPORT_SYMBOL(wc_enabled);
|
2023-04-18 11:38:58 +00:00
|
|
|
|
|
|
|
static int __init setup_writecombine(char *p)
|
|
|
|
{
|
|
|
|
if (!strcmp(p, "on"))
|
2023-10-18 00:42:52 +00:00
|
|
|
wc_enabled = true;
|
2023-04-18 11:38:58 +00:00
|
|
|
else if (!strcmp(p, "off"))
|
2023-10-18 00:42:52 +00:00
|
|
|
wc_enabled = false;
|
2023-04-18 11:38:58 +00:00
|
|
|
else
|
|
|
|
pr_warn("Unknown writecombine setting \"%s\".\n", p);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
early_param("writecombine", setup_writecombine);
|
|
|
|
|
2022-05-31 10:04:11 +00:00
|
|
|
static int usermem __initdata;
|
|
|
|
|
|
|
|
static int __init early_parse_mem(char *p)
|
|
|
|
{
|
|
|
|
phys_addr_t start, size;
|
|
|
|
|
|
|
|
if (!p) {
|
|
|
|
pr_err("mem parameter is empty, do nothing\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If a user specifies memory size, we
|
|
|
|
* blow away any automatically generated
|
|
|
|
* size.
|
|
|
|
*/
|
|
|
|
if (usermem == 0) {
|
|
|
|
usermem = 1;
|
|
|
|
memblock_remove(memblock_start_of_DRAM(),
|
|
|
|
memblock_end_of_DRAM() - memblock_start_of_DRAM());
|
|
|
|
}
|
|
|
|
start = 0;
|
|
|
|
size = memparse(p, &p);
|
|
|
|
if (*p == '@')
|
|
|
|
start = memparse(p + 1, &p);
|
|
|
|
else {
|
|
|
|
pr_err("Invalid format!\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2022-05-31 10:04:12 +00:00
|
|
|
if (!IS_ENABLED(CONFIG_NUMA))
|
|
|
|
memblock_add(start, size);
|
|
|
|
else
|
|
|
|
memblock_add_node(start, size, pa_to_nid(start), MEMBLOCK_NONE);
|
2022-05-31 10:04:11 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
early_param("mem", early_parse_mem);
|
|
|
|
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
static void __init arch_reserve_vmcore(void)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_PROC_VMCORE
|
|
|
|
u64 i;
|
|
|
|
phys_addr_t start, end;
|
|
|
|
|
|
|
|
if (!is_kdump_kernel())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!elfcorehdr_size) {
|
|
|
|
for_each_mem_range(i, &start, &end) {
|
|
|
|
if (elfcorehdr_addr >= start && elfcorehdr_addr < end) {
|
|
|
|
/*
|
|
|
|
* Reserve from the elf core header to the end of
|
|
|
|
* the memory segment, that should all be kdump
|
|
|
|
* reserved memory.
|
|
|
|
*/
|
|
|
|
elfcorehdr_size = end - elfcorehdr_addr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) {
|
|
|
|
pr_warn("elfcorehdr is overlapped\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
|
|
|
|
|
|
|
|
pr_info("Reserving %llu KiB of memory at 0x%llx for elfcorehdr\n",
|
|
|
|
elfcorehdr_size >> 10, elfcorehdr_addr);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
LoongArch: Use generic interface to support crashkernel=X,[high,low]
LoongArch already supports two crashkernel regions in kexec-tools, so we
can directly use the common interface to support crashkernel=X,[high,low]
after commit 0ab97169aa0517079b ("crash_core: add generic function to do
reservation").
With the help of newly changed function parse_crashkernel() and generic
reserve_crashkernel_generic(), crashkernel reservation can be simplified
by steps:
1) Add a new header file <asm/crash_core.h>, then define CRASH_ALIGN,
CRASH_ADDR_LOW_MAX and CRASH_ADDR_HIGH_MAX and in <asm/crash_core.h>;
2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
reserve_crashkernel_generic();
3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
arch/loongarch/Kconfig.
One can reserve the crash kernel from high memory above DMA zone range
by explicitly passing "crashkernel=X,high"; or reserve a memory range
below 4G with "crashkernel=X,low". Besides, there are few rules need to
take notice:
1) "crashkernel=X,[high,low]" will be ignored if "crashkernel=size" is
specified.
2) "crashkernel=X,low" is valid only when "crashkernel=X,high" is passed
and there is enough memory to be allocated under 4G.
3) When allocating crashkernel above 4G and no "crashkernel=X,low" is
specified, a 128M low memory will be allocated automatically for
swiotlb bounce buffer.
See Documentation/admin-guide/kernel-parameters.txt for more information.
Following test cases have been performed as expected:
1) crashkernel=256M //low=256M
2) crashkernel=1G //low=1G
3) crashkernel=4G //high=4G, low=128M(default)
4) crashkernel=4G crashkernel=256M,high //high=4G, low=128M(default), high is ignored
5) crashkernel=4G crashkernel=256M,low //high=4G, low=128M(default), low is ignored
6) crashkernel=4G,high //high=4G, low=128M(default)
7) crashkernel=256M,low //low=0M, invalid
8) crashkernel=4G,high crashkernel=256M,low //high=4G, low=256M
9) crashkernel=4G,high crashkernel=4G,low //high=0M, low=0M, invalid
10) crashkernel=512M@2560M //low=512M
11) crashkernel=1G,high crashkernel=0M,low //high=1G, low=0M
Recommended usage in general:
1) In the case of small memory: crashkernel=512M
2) In the case of large memory: crashkernel=1024M,high crashkernel=128M,low
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2024-01-17 04:43:08 +00:00
|
|
|
static void __init arch_reserve_crashkernel(void)
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
{
|
|
|
|
int ret;
|
LoongArch: Use generic interface to support crashkernel=X,[high,low]
LoongArch already supports two crashkernel regions in kexec-tools, so we
can directly use the common interface to support crashkernel=X,[high,low]
after commit 0ab97169aa0517079b ("crash_core: add generic function to do
reservation").
With the help of newly changed function parse_crashkernel() and generic
reserve_crashkernel_generic(), crashkernel reservation can be simplified
by steps:
1) Add a new header file <asm/crash_core.h>, then define CRASH_ALIGN,
CRASH_ADDR_LOW_MAX and CRASH_ADDR_HIGH_MAX and in <asm/crash_core.h>;
2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
reserve_crashkernel_generic();
3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
arch/loongarch/Kconfig.
One can reserve the crash kernel from high memory above DMA zone range
by explicitly passing "crashkernel=X,high"; or reserve a memory range
below 4G with "crashkernel=X,low". Besides, there are few rules need to
take notice:
1) "crashkernel=X,[high,low]" will be ignored if "crashkernel=size" is
specified.
2) "crashkernel=X,low" is valid only when "crashkernel=X,high" is passed
and there is enough memory to be allocated under 4G.
3) When allocating crashkernel above 4G and no "crashkernel=X,low" is
specified, a 128M low memory will be allocated automatically for
swiotlb bounce buffer.
See Documentation/admin-guide/kernel-parameters.txt for more information.
Following test cases have been performed as expected:
1) crashkernel=256M //low=256M
2) crashkernel=1G //low=1G
3) crashkernel=4G //high=4G, low=128M(default)
4) crashkernel=4G crashkernel=256M,high //high=4G, low=128M(default), high is ignored
5) crashkernel=4G crashkernel=256M,low //high=4G, low=128M(default), low is ignored
6) crashkernel=4G,high //high=4G, low=128M(default)
7) crashkernel=256M,low //low=0M, invalid
8) crashkernel=4G,high crashkernel=256M,low //high=4G, low=256M
9) crashkernel=4G,high crashkernel=4G,low //high=0M, low=0M, invalid
10) crashkernel=512M@2560M //low=512M
11) crashkernel=1G,high crashkernel=0M,low //high=1G, low=0M
Recommended usage in general:
1) In the case of small memory: crashkernel=512M
2) In the case of large memory: crashkernel=1024M,high crashkernel=128M,low
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2024-01-17 04:43:08 +00:00
|
|
|
unsigned long long low_size = 0;
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
unsigned long long crash_base, crash_size;
|
LoongArch: Use generic interface to support crashkernel=X,[high,low]
LoongArch already supports two crashkernel regions in kexec-tools, so we
can directly use the common interface to support crashkernel=X,[high,low]
after commit 0ab97169aa0517079b ("crash_core: add generic function to do
reservation").
With the help of newly changed function parse_crashkernel() and generic
reserve_crashkernel_generic(), crashkernel reservation can be simplified
by steps:
1) Add a new header file <asm/crash_core.h>, then define CRASH_ALIGN,
CRASH_ADDR_LOW_MAX and CRASH_ADDR_HIGH_MAX and in <asm/crash_core.h>;
2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
reserve_crashkernel_generic();
3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
arch/loongarch/Kconfig.
One can reserve the crash kernel from high memory above DMA zone range
by explicitly passing "crashkernel=X,high"; or reserve a memory range
below 4G with "crashkernel=X,low". Besides, there are few rules need to
take notice:
1) "crashkernel=X,[high,low]" will be ignored if "crashkernel=size" is
specified.
2) "crashkernel=X,low" is valid only when "crashkernel=X,high" is passed
and there is enough memory to be allocated under 4G.
3) When allocating crashkernel above 4G and no "crashkernel=X,low" is
specified, a 128M low memory will be allocated automatically for
swiotlb bounce buffer.
See Documentation/admin-guide/kernel-parameters.txt for more information.
Following test cases have been performed as expected:
1) crashkernel=256M //low=256M
2) crashkernel=1G //low=1G
3) crashkernel=4G //high=4G, low=128M(default)
4) crashkernel=4G crashkernel=256M,high //high=4G, low=128M(default), high is ignored
5) crashkernel=4G crashkernel=256M,low //high=4G, low=128M(default), low is ignored
6) crashkernel=4G,high //high=4G, low=128M(default)
7) crashkernel=256M,low //low=0M, invalid
8) crashkernel=4G,high crashkernel=256M,low //high=4G, low=256M
9) crashkernel=4G,high crashkernel=4G,low //high=0M, low=0M, invalid
10) crashkernel=512M@2560M //low=512M
11) crashkernel=1G,high crashkernel=0M,low //high=1G, low=0M
Recommended usage in general:
1) In the case of small memory: crashkernel=512M
2) In the case of large memory: crashkernel=1024M,high crashkernel=128M,low
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2024-01-17 04:43:08 +00:00
|
|
|
char *cmdline = boot_command_line;
|
|
|
|
bool high = false;
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
|
LoongArch: Use generic interface to support crashkernel=X,[high,low]
LoongArch already supports two crashkernel regions in kexec-tools, so we
can directly use the common interface to support crashkernel=X,[high,low]
after commit 0ab97169aa0517079b ("crash_core: add generic function to do
reservation").
With the help of newly changed function parse_crashkernel() and generic
reserve_crashkernel_generic(), crashkernel reservation can be simplified
by steps:
1) Add a new header file <asm/crash_core.h>, then define CRASH_ALIGN,
CRASH_ADDR_LOW_MAX and CRASH_ADDR_HIGH_MAX and in <asm/crash_core.h>;
2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
reserve_crashkernel_generic();
3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
arch/loongarch/Kconfig.
One can reserve the crash kernel from high memory above DMA zone range
by explicitly passing "crashkernel=X,high"; or reserve a memory range
below 4G with "crashkernel=X,low". Besides, there are few rules need to
take notice:
1) "crashkernel=X,[high,low]" will be ignored if "crashkernel=size" is
specified.
2) "crashkernel=X,low" is valid only when "crashkernel=X,high" is passed
and there is enough memory to be allocated under 4G.
3) When allocating crashkernel above 4G and no "crashkernel=X,low" is
specified, a 128M low memory will be allocated automatically for
swiotlb bounce buffer.
See Documentation/admin-guide/kernel-parameters.txt for more information.
Following test cases have been performed as expected:
1) crashkernel=256M //low=256M
2) crashkernel=1G //low=1G
3) crashkernel=4G //high=4G, low=128M(default)
4) crashkernel=4G crashkernel=256M,high //high=4G, low=128M(default), high is ignored
5) crashkernel=4G crashkernel=256M,low //high=4G, low=128M(default), low is ignored
6) crashkernel=4G,high //high=4G, low=128M(default)
7) crashkernel=256M,low //low=0M, invalid
8) crashkernel=4G,high crashkernel=256M,low //high=4G, low=256M
9) crashkernel=4G,high crashkernel=4G,low //high=0M, low=0M, invalid
10) crashkernel=512M@2560M //low=512M
11) crashkernel=1G,high crashkernel=0M,low //high=1G, low=0M
Recommended usage in general:
1) In the case of small memory: crashkernel=512M
2) In the case of large memory: crashkernel=1024M,high crashkernel=128M,low
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2024-01-17 04:43:08 +00:00
|
|
|
if (!IS_ENABLED(CONFIG_KEXEC_CORE))
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
return;
|
|
|
|
|
LoongArch: Use generic interface to support crashkernel=X,[high,low]
LoongArch already supports two crashkernel regions in kexec-tools, so we
can directly use the common interface to support crashkernel=X,[high,low]
after commit 0ab97169aa0517079b ("crash_core: add generic function to do
reservation").
With the help of newly changed function parse_crashkernel() and generic
reserve_crashkernel_generic(), crashkernel reservation can be simplified
by steps:
1) Add a new header file <asm/crash_core.h>, then define CRASH_ALIGN,
CRASH_ADDR_LOW_MAX and CRASH_ADDR_HIGH_MAX and in <asm/crash_core.h>;
2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
reserve_crashkernel_generic();
3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
arch/loongarch/Kconfig.
One can reserve the crash kernel from high memory above DMA zone range
by explicitly passing "crashkernel=X,high"; or reserve a memory range
below 4G with "crashkernel=X,low". Besides, there are few rules need to
take notice:
1) "crashkernel=X,[high,low]" will be ignored if "crashkernel=size" is
specified.
2) "crashkernel=X,low" is valid only when "crashkernel=X,high" is passed
and there is enough memory to be allocated under 4G.
3) When allocating crashkernel above 4G and no "crashkernel=X,low" is
specified, a 128M low memory will be allocated automatically for
swiotlb bounce buffer.
See Documentation/admin-guide/kernel-parameters.txt for more information.
Following test cases have been performed as expected:
1) crashkernel=256M //low=256M
2) crashkernel=1G //low=1G
3) crashkernel=4G //high=4G, low=128M(default)
4) crashkernel=4G crashkernel=256M,high //high=4G, low=128M(default), high is ignored
5) crashkernel=4G crashkernel=256M,low //high=4G, low=128M(default), low is ignored
6) crashkernel=4G,high //high=4G, low=128M(default)
7) crashkernel=256M,low //low=0M, invalid
8) crashkernel=4G,high crashkernel=256M,low //high=4G, low=256M
9) crashkernel=4G,high crashkernel=4G,low //high=0M, low=0M, invalid
10) crashkernel=512M@2560M //low=512M
11) crashkernel=1G,high crashkernel=0M,low //high=1G, low=0M
Recommended usage in general:
1) In the case of small memory: crashkernel=512M
2) In the case of large memory: crashkernel=1024M,high crashkernel=128M,low
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2024-01-17 04:43:08 +00:00
|
|
|
ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
|
|
|
|
&crash_size, &crash_base, &low_size, &high);
|
|
|
|
if (ret)
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
return;
|
|
|
|
|
LoongArch: Use generic interface to support crashkernel=X,[high,low]
LoongArch already supports two crashkernel regions in kexec-tools, so we
can directly use the common interface to support crashkernel=X,[high,low]
after commit 0ab97169aa0517079b ("crash_core: add generic function to do
reservation").
With the help of newly changed function parse_crashkernel() and generic
reserve_crashkernel_generic(), crashkernel reservation can be simplified
by steps:
1) Add a new header file <asm/crash_core.h>, then define CRASH_ALIGN,
CRASH_ADDR_LOW_MAX and CRASH_ADDR_HIGH_MAX and in <asm/crash_core.h>;
2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
reserve_crashkernel_generic();
3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
arch/loongarch/Kconfig.
One can reserve the crash kernel from high memory above DMA zone range
by explicitly passing "crashkernel=X,high"; or reserve a memory range
below 4G with "crashkernel=X,low". Besides, there are few rules need to
take notice:
1) "crashkernel=X,[high,low]" will be ignored if "crashkernel=size" is
specified.
2) "crashkernel=X,low" is valid only when "crashkernel=X,high" is passed
and there is enough memory to be allocated under 4G.
3) When allocating crashkernel above 4G and no "crashkernel=X,low" is
specified, a 128M low memory will be allocated automatically for
swiotlb bounce buffer.
See Documentation/admin-guide/kernel-parameters.txt for more information.
Following test cases have been performed as expected:
1) crashkernel=256M //low=256M
2) crashkernel=1G //low=1G
3) crashkernel=4G //high=4G, low=128M(default)
4) crashkernel=4G crashkernel=256M,high //high=4G, low=128M(default), high is ignored
5) crashkernel=4G crashkernel=256M,low //high=4G, low=128M(default), low is ignored
6) crashkernel=4G,high //high=4G, low=128M(default)
7) crashkernel=256M,low //low=0M, invalid
8) crashkernel=4G,high crashkernel=256M,low //high=4G, low=256M
9) crashkernel=4G,high crashkernel=4G,low //high=0M, low=0M, invalid
10) crashkernel=512M@2560M //low=512M
11) crashkernel=1G,high crashkernel=0M,low //high=1G, low=0M
Recommended usage in general:
1) In the case of small memory: crashkernel=512M
2) In the case of large memory: crashkernel=1024M,high crashkernel=128M,low
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2024-01-17 04:43:08 +00:00
|
|
|
reserve_crashkernel_generic(cmdline, crash_size, crash_base, low_size, high);
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
}
|
|
|
|
|
2022-12-10 14:40:05 +00:00
|
|
|
static void __init fdt_setup(void)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_OF_EARLY_FLATTREE
|
|
|
|
void *fdt_pointer;
|
|
|
|
|
|
|
|
/* ACPI-based systems do not require parsing fdt */
|
|
|
|
if (acpi_os_get_root_pointer())
|
|
|
|
return;
|
|
|
|
|
2024-01-17 04:43:00 +00:00
|
|
|
/* Prefer to use built-in dtb, checking its legality first. */
|
|
|
|
if (!fdt_check_header(__dtb_start))
|
|
|
|
fdt_pointer = __dtb_start;
|
|
|
|
else
|
|
|
|
fdt_pointer = efi_fdt_pointer(); /* Fallback to firmware dtb */
|
|
|
|
|
2022-12-10 14:40:05 +00:00
|
|
|
if (!fdt_pointer || fdt_check_header(fdt_pointer))
|
|
|
|
return;
|
|
|
|
|
|
|
|
early_init_dt_scan(fdt_pointer);
|
|
|
|
early_init_fdt_reserve_self();
|
|
|
|
|
|
|
|
max_low_pfn = PFN_PHYS(memblock_end_of_DRAM());
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __init bootcmdline_init(char **cmdline_p)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* If CONFIG_CMDLINE_FORCE is enabled then initializing the command line
|
|
|
|
* is trivial - we simply use the built-in command line unconditionally &
|
|
|
|
* unmodified.
|
|
|
|
*/
|
|
|
|
if (IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
|
|
|
|
strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_OF_FLATTREE
|
|
|
|
/*
|
|
|
|
* If CONFIG_CMDLINE_BOOTLOADER is enabled and we are in FDT-based system,
|
|
|
|
* the boot_command_line will be overwritten by early_init_dt_scan_chosen().
|
|
|
|
* So we need to append init_command_line (the original copy of boot_command_line)
|
|
|
|
* to boot_command_line.
|
|
|
|
*/
|
|
|
|
if (initial_boot_params) {
|
|
|
|
if (boot_command_line[0])
|
|
|
|
strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
|
|
|
|
|
2024-01-17 04:43:00 +00:00
|
|
|
if (!strstr(boot_command_line, init_command_line))
|
|
|
|
strlcat(boot_command_line, init_command_line, COMMAND_LINE_SIZE);
|
|
|
|
|
2023-07-28 02:30:42 +00:00
|
|
|
goto out;
|
2022-12-10 14:40:05 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-07-28 02:30:42 +00:00
|
|
|
/*
|
|
|
|
* Append built-in command line to the bootloader command line if
|
|
|
|
* CONFIG_CMDLINE_EXTEND is enabled.
|
|
|
|
*/
|
|
|
|
if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) && CONFIG_CMDLINE[0]) {
|
|
|
|
strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
|
|
|
|
strlcat(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use built-in command line if the bootloader command line is empty.
|
|
|
|
*/
|
|
|
|
if (IS_ENABLED(CONFIG_CMDLINE_BOOTLOADER) && !boot_command_line[0])
|
|
|
|
strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
|
|
|
|
|
2022-12-10 14:40:05 +00:00
|
|
|
out:
|
|
|
|
*cmdline_p = boot_command_line;
|
|
|
|
}
|
|
|
|
|
2022-05-31 10:04:11 +00:00
|
|
|
void __init platform_init(void)
|
|
|
|
{
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
arch_reserve_vmcore();
|
LoongArch: Use generic interface to support crashkernel=X,[high,low]
LoongArch already supports two crashkernel regions in kexec-tools, so we
can directly use the common interface to support crashkernel=X,[high,low]
after commit 0ab97169aa0517079b ("crash_core: add generic function to do
reservation").
With the help of newly changed function parse_crashkernel() and generic
reserve_crashkernel_generic(), crashkernel reservation can be simplified
by steps:
1) Add a new header file <asm/crash_core.h>, then define CRASH_ALIGN,
CRASH_ADDR_LOW_MAX and CRASH_ADDR_HIGH_MAX and in <asm/crash_core.h>;
2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
reserve_crashkernel_generic();
3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
arch/loongarch/Kconfig.
One can reserve the crash kernel from high memory above DMA zone range
by explicitly passing "crashkernel=X,high"; or reserve a memory range
below 4G with "crashkernel=X,low". Besides, there are few rules need to
take notice:
1) "crashkernel=X,[high,low]" will be ignored if "crashkernel=size" is
specified.
2) "crashkernel=X,low" is valid only when "crashkernel=X,high" is passed
and there is enough memory to be allocated under 4G.
3) When allocating crashkernel above 4G and no "crashkernel=X,low" is
specified, a 128M low memory will be allocated automatically for
swiotlb bounce buffer.
See Documentation/admin-guide/kernel-parameters.txt for more information.
Following test cases have been performed as expected:
1) crashkernel=256M //low=256M
2) crashkernel=1G //low=1G
3) crashkernel=4G //high=4G, low=128M(default)
4) crashkernel=4G crashkernel=256M,high //high=4G, low=128M(default), high is ignored
5) crashkernel=4G crashkernel=256M,low //high=4G, low=128M(default), low is ignored
6) crashkernel=4G,high //high=4G, low=128M(default)
7) crashkernel=256M,low //low=0M, invalid
8) crashkernel=4G,high crashkernel=256M,low //high=4G, low=256M
9) crashkernel=4G,high crashkernel=4G,low //high=0M, low=0M, invalid
10) crashkernel=512M@2560M //low=512M
11) crashkernel=1G,high crashkernel=0M,low //high=1G, low=0M
Recommended usage in general:
1) In the case of small memory: crashkernel=512M
2) In the case of large memory: crashkernel=1024M,high crashkernel=128M,low
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2024-01-17 04:43:08 +00:00
|
|
|
arch_reserve_crashkernel();
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
|
2022-05-31 10:04:11 +00:00
|
|
|
#ifdef CONFIG_ACPI_TABLE_UPGRADE
|
|
|
|
acpi_table_upgrade();
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_ACPI
|
|
|
|
acpi_gbl_use_default_register_widths = false;
|
|
|
|
acpi_boot_table_init();
|
|
|
|
#endif
|
2024-02-23 06:36:31 +00:00
|
|
|
|
|
|
|
early_init_fdt_scan_reserved_mem();
|
2022-12-10 14:40:05 +00:00
|
|
|
unflatten_and_copy_device_tree();
|
2022-05-31 10:04:11 +00:00
|
|
|
|
2022-05-31 10:04:12 +00:00
|
|
|
#ifdef CONFIG_NUMA
|
|
|
|
init_numa_memory();
|
|
|
|
#endif
|
2022-05-31 10:04:11 +00:00
|
|
|
dmi_setup();
|
|
|
|
smbios_parse();
|
|
|
|
pr_info("The BIOS Version: %s\n", b_info.bios_version);
|
|
|
|
|
|
|
|
efi_runtime_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __init check_kernel_sections_mem(void)
|
|
|
|
{
|
|
|
|
phys_addr_t start = __pa_symbol(&_text);
|
|
|
|
phys_addr_t size = __pa_symbol(&_end) - start;
|
|
|
|
|
|
|
|
if (!memblock_is_region_memory(start, size)) {
|
|
|
|
pr_info("Kernel sections are not in the memory maps\n");
|
|
|
|
memblock_add(start, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* arch_mem_init - initialize memory management subsystem
|
|
|
|
*/
|
|
|
|
static void __init arch_mem_init(char **cmdline_p)
|
|
|
|
{
|
|
|
|
if (usermem)
|
|
|
|
pr_info("User-defined physical RAM map overwrite\n");
|
|
|
|
|
|
|
|
check_kernel_sections_mem();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In order to reduce the possibility of kernel panic when failed to
|
|
|
|
* get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate
|
2023-04-19 04:07:27 +00:00
|
|
|
* low memory as small as possible before swiotlb_init(), so make
|
|
|
|
* sparse_init() using top-down allocation.
|
2022-05-31 10:04:11 +00:00
|
|
|
*/
|
|
|
|
memblock_set_bottom_up(false);
|
|
|
|
sparse_init();
|
|
|
|
memblock_set_bottom_up(true);
|
|
|
|
|
LoongArch: Use acpi_arch_dma_setup() and remove ARCH_HAS_PHYS_TO_DMA
Use _DMA defined in ACPI spec for translation between
DMA address and CPU address, and implement acpi_arch_dma_setup
for initializing dev->dma_range_map, where acpi_dma_get_range
is called for parsing _DMA.
e.g.
If we have two dma ranges:
cpu address dma address size offset
0x200080000000 0x2080000000 0x400000000 0x1fe000000000
0x400080000000 0x4080000000 0x400000000 0x3fc000000000
_DMA for pci devices should be declared in host bridge as
flowing:
Name (_DMA, ResourceTemplate() {
QWordMemory (ResourceProducer,
PosDecode,
MinFixed,
MaxFixed,
NonCacheable,
ReadWrite,
0x0,
0x4080000000,
0x447fffffff,
0x3fc000000000,
0x400000000,
,
,
)
QWordMemory (ResourceProducer,
PosDecode,
MinFixed,
MaxFixed,
NonCacheable,
ReadWrite,
0x0,
0x2080000000,
0x247fffffff,
0x1fe000000000,
0x400000000,
,
,
)
})
Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2022-09-11 09:06:35 +00:00
|
|
|
swiotlb_init(true, SWIOTLB_VERBOSE);
|
2022-05-31 10:04:11 +00:00
|
|
|
|
|
|
|
dma_contiguous_reserve(PFN_PHYS(max_low_pfn));
|
|
|
|
|
2022-12-10 14:40:15 +00:00
|
|
|
/* Reserve for hibernation. */
|
|
|
|
register_nosave_region(PFN_DOWN(__pa_symbol(&__nosave_begin)),
|
|
|
|
PFN_UP(__pa_symbol(&__nosave_end)));
|
|
|
|
|
2022-05-31 10:04:11 +00:00
|
|
|
memblock_dump_all();
|
|
|
|
|
|
|
|
early_memtest(PFN_PHYS(ARCH_PFN_OFFSET), PFN_PHYS(max_low_pfn));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __init resource_init(void)
|
|
|
|
{
|
|
|
|
long i = 0;
|
|
|
|
size_t res_size;
|
|
|
|
struct resource *res;
|
|
|
|
struct memblock_region *region;
|
|
|
|
|
|
|
|
code_resource.start = __pa_symbol(&_text);
|
|
|
|
code_resource.end = __pa_symbol(&_etext) - 1;
|
|
|
|
data_resource.start = __pa_symbol(&_etext);
|
|
|
|
data_resource.end = __pa_symbol(&_edata) - 1;
|
|
|
|
bss_resource.start = __pa_symbol(&__bss_start);
|
|
|
|
bss_resource.end = __pa_symbol(&__bss_stop) - 1;
|
|
|
|
|
|
|
|
num_standard_resources = memblock.memory.cnt;
|
|
|
|
res_size = num_standard_resources * sizeof(*standard_resources);
|
|
|
|
standard_resources = memblock_alloc(res_size, SMP_CACHE_BYTES);
|
|
|
|
|
|
|
|
for_each_mem_region(region) {
|
|
|
|
res = &standard_resources[i++];
|
|
|
|
if (!memblock_is_nomap(region)) {
|
|
|
|
res->name = "System RAM";
|
|
|
|
res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
|
|
|
|
res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
|
|
|
|
res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
|
|
|
|
} else {
|
|
|
|
res->name = "Reserved";
|
|
|
|
res->flags = IORESOURCE_MEM;
|
|
|
|
res->start = __pfn_to_phys(memblock_region_reserved_base_pfn(region));
|
|
|
|
res->end = __pfn_to_phys(memblock_region_reserved_end_pfn(region)) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
request_resource(&iomem_resource, res);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We don't know which RAM region contains kernel data,
|
|
|
|
* so we try it repeatedly and let the resource manager
|
|
|
|
* test it.
|
|
|
|
*/
|
|
|
|
request_resource(res, &code_resource);
|
|
|
|
request_resource(res, &data_resource);
|
|
|
|
request_resource(res, &bss_resource);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-10 14:40:05 +00:00
|
|
|
static int __init add_legacy_isa_io(struct fwnode_handle *fwnode,
|
|
|
|
resource_size_t hw_start, resource_size_t size)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
unsigned long vaddr;
|
|
|
|
struct logic_pio_hwaddr *range;
|
|
|
|
|
|
|
|
range = kzalloc(sizeof(*range), GFP_ATOMIC);
|
|
|
|
if (!range)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
range->fwnode = fwnode;
|
|
|
|
range->size = size = round_up(size, PAGE_SIZE);
|
|
|
|
range->hw_start = hw_start;
|
|
|
|
range->flags = LOGIC_PIO_CPU_MMIO;
|
|
|
|
|
|
|
|
ret = logic_pio_register_range(range);
|
|
|
|
if (ret) {
|
|
|
|
kfree(range);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Legacy ISA must placed at the start of PCI_IOBASE */
|
|
|
|
if (range->io_start != 0) {
|
|
|
|
logic_pio_unregister_range(range);
|
|
|
|
kfree(range);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
vaddr = (unsigned long)(PCI_IOBASE + range->io_start);
|
2024-03-08 17:12:54 +00:00
|
|
|
vmap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
|
2022-12-10 14:40:05 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __init int arch_reserve_pio_range(void)
|
|
|
|
{
|
|
|
|
struct device_node *np;
|
|
|
|
|
|
|
|
for_each_node_by_name(np, "isa") {
|
|
|
|
struct of_range range;
|
|
|
|
struct of_range_parser parser;
|
|
|
|
|
|
|
|
pr_info("ISA Bridge: %pOF\n", np);
|
|
|
|
|
|
|
|
if (of_range_parser_init(&parser, np)) {
|
|
|
|
pr_info("Failed to parse resources.\n");
|
|
|
|
of_node_put(np);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for_each_of_range(&parser, &range) {
|
|
|
|
switch (range.flags & IORESOURCE_TYPE_BITS) {
|
|
|
|
case IORESOURCE_IO:
|
|
|
|
pr_info(" IO 0x%016llx..0x%016llx -> 0x%016llx\n",
|
|
|
|
range.cpu_addr,
|
|
|
|
range.cpu_addr + range.size - 1,
|
|
|
|
range.bus_addr);
|
|
|
|
if (add_legacy_isa_io(&np->fwnode, range.cpu_addr, range.size))
|
|
|
|
pr_warn("Failed to reserve legacy IO in Logic PIO\n");
|
|
|
|
break;
|
|
|
|
case IORESOURCE_MEM:
|
|
|
|
pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx\n",
|
|
|
|
range.cpu_addr,
|
|
|
|
range.cpu_addr + range.size - 1,
|
|
|
|
range.bus_addr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
arch_initcall(arch_reserve_pio_range);
|
|
|
|
|
2022-05-31 10:04:11 +00:00
|
|
|
static int __init reserve_memblock_reserved_regions(void)
|
|
|
|
{
|
|
|
|
u64 i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < num_standard_resources; ++i) {
|
|
|
|
struct resource *mem = &standard_resources[i];
|
|
|
|
phys_addr_t r_start, r_end, mem_size = resource_size(mem);
|
|
|
|
|
|
|
|
if (!memblock_is_region_reserved(mem->start, mem_size))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for_each_reserved_mem_range(j, &r_start, &r_end) {
|
|
|
|
resource_size_t start, end;
|
|
|
|
|
|
|
|
start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start);
|
|
|
|
end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end);
|
|
|
|
|
|
|
|
if (start > mem->end || end < mem->start)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
reserve_region_with_split(mem, start, end, "Reserved");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
arch_initcall(reserve_memblock_reserved_regions);
|
|
|
|
|
2022-05-31 10:04:12 +00:00
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
static void __init prefill_possible_map(void)
|
|
|
|
{
|
|
|
|
int i, possible;
|
|
|
|
|
|
|
|
possible = num_processors + disabled_cpus;
|
|
|
|
if (possible > nr_cpu_ids)
|
|
|
|
possible = nr_cpu_ids;
|
|
|
|
|
|
|
|
pr_info("SMP: Allowing %d CPUs, %d hotplug CPUs\n",
|
|
|
|
possible, max((possible - num_processors), 0));
|
|
|
|
|
|
|
|
for (i = 0; i < possible; i++)
|
|
|
|
set_cpu_possible(i, true);
|
|
|
|
for (; i < NR_CPUS; i++)
|
|
|
|
set_cpu_possible(i, false);
|
|
|
|
|
2022-09-05 23:08:17 +00:00
|
|
|
set_nr_cpu_ids(possible);
|
2022-05-31 10:04:12 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-05-31 10:04:11 +00:00
|
|
|
void __init setup_arch(char **cmdline_p)
|
|
|
|
{
|
|
|
|
cpu_probe();
|
|
|
|
|
|
|
|
init_environ();
|
efi/loongarch: libstub: remove dependency on flattened DT
LoongArch does not use FDT or DT natively [yet], and the only reason it
currently uses it is so that it can reuse the existing EFI stub code.
Overloading the DT with data passed between the EFI stub and the core
kernel has been a source of problems: there is the overlap between
information provided by EFI which DT can also provide (initrd base/size,
command line, memory descriptions), requiring us to reason about which
is which and what to prioritize. It has also resulted in ABI leaks,
i.e., internal ABI being promoted to external ABI inadvertently because
the bootloader can set the EFI stub's DT properties as well (e.g.,
"kaslr-seed"). This has become especially problematic with boot
environments that want to pretend that EFI boot is being done (to access
ACPI and SMBIOS tables, for instance) but have no ability to execute the
EFI stub, and so the environment that the EFI stub creates is emulated
[poorly, in some cases].
Another downside of treating DT like this is that the DT binary that the
kernel receives is different from the one created by the firmware, which
is undesirable in the context of secure and measured boot.
Given that LoongArch support in Linux is brand new, we can avoid these
pitfalls, and treat the DT strictly as a hardware description, and use a
separate handover method between the EFI stub and the kernel. Now that
initrd loading and passing the EFI memory map have been refactored into
pure EFI routines that use EFI configuration tables, the only thing we
need to pass directly is the kernel command line (even if we could pass
this via a config table as well, it is used extremely early, so passing
it directly is preferred in this case.)
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Huacai Chen <chenhuacai@loongson.cn>
2022-09-16 17:48:53 +00:00
|
|
|
efi_init();
|
2022-12-10 14:40:05 +00:00
|
|
|
fdt_setup();
|
2022-05-31 10:04:11 +00:00
|
|
|
memblock_init();
|
2022-10-12 08:36:14 +00:00
|
|
|
pagetable_init();
|
2022-12-10 14:40:05 +00:00
|
|
|
bootcmdline_init(cmdline_p);
|
2022-05-31 10:04:11 +00:00
|
|
|
parse_early_param();
|
LoongArch: Add kdump support
This patch adds support for kdump. In kdump case the normal kernel will
reserve a region for the crash kernel and jump there on panic.
Arch-specific functions are added to allow for implementing a crash dump
file interface, /proc/vmcore, which can be viewed as a ELF file.
A user-space tool, such as kexec-tools, is responsible for allocating a
separate region for the core's ELF header within the crash kdump kernel
memory and filling it in when executing kexec_load().
Then, its location will be advertised to the crash dump kernel via a
command line argument "elfcorehdr=", and the crash dump kernel will
preserve this region for later use with arch_reserve_vmcore() at boot
time.
At the same time, the crash kdump kernel is also limited within the
"crashkernel" area via a command line argument "mem=", so as not to
destroy the original kernel dump data.
In the crash dump kernel environment, /proc/vmcore is used to access the
primary kernel's memory with copy_oldmem_page().
I tested kdump on LoongArch machines (Loongson-3A5000) and it works as
expected (suggested crashkernel parameter is "crashkernel=512M@2560M"),
you may test it by triggering a crash through /proc/sysrq-trigger:
$ sudo kexec -p /boot/vmlinux-kdump --reuse-cmdline --append="nr_cpus=1"
# echo c > /proc/sysrq-trigger
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-10-12 08:36:19 +00:00
|
|
|
reserve_initrd_mem();
|
2022-05-31 10:04:11 +00:00
|
|
|
|
|
|
|
platform_init();
|
|
|
|
arch_mem_init(cmdline_p);
|
|
|
|
|
|
|
|
resource_init();
|
LoongArch: Fix the !CONFIG_SMP build
1, We assume arch/loongarch/include/asm/smp.h be included in include/
linux/smp.h is valid and the reverse inclusion isn't. So remove the
<linux/smp.h> in arch/loongarch/include/asm/smp.h.
2, arch/loongarch/include/asm/smp.h is only needed when CONFIG_SMP,
and setup.c include it only because it need plat_smp_setup(). So,
reorganize setup.c & smp.h, and then remove <asm/smp.h> in setup.c.
3, Fix cacheinfo.c and percpu.h build error by adding the missing header
files when !CONFIG_SMP.
4, Fix acpi.c build error by adding CONFIG_SMP guards.
5, Move irq_stat definition from smp.c to irq.c and fix its declaration.
6, Select CONFIG_SMP for CONFIG_NUMA, similar as other architectures do.
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-06-05 08:19:53 +00:00
|
|
|
#ifdef CONFIG_SMP
|
2022-05-31 10:04:12 +00:00
|
|
|
plat_smp_setup();
|
|
|
|
prefill_possible_map();
|
LoongArch: Fix the !CONFIG_SMP build
1, We assume arch/loongarch/include/asm/smp.h be included in include/
linux/smp.h is valid and the reverse inclusion isn't. So remove the
<linux/smp.h> in arch/loongarch/include/asm/smp.h.
2, arch/loongarch/include/asm/smp.h is only needed when CONFIG_SMP,
and setup.c include it only because it need plat_smp_setup(). So,
reorganize setup.c & smp.h, and then remove <asm/smp.h> in setup.c.
3, Fix cacheinfo.c and percpu.h build error by adding the missing header
files when !CONFIG_SMP.
4, Fix acpi.c build error by adding CONFIG_SMP guards.
5, Move irq_stat definition from smp.c to irq.c and fix its declaration.
6, Select CONFIG_SMP for CONFIG_NUMA, similar as other architectures do.
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2022-06-05 08:19:53 +00:00
|
|
|
#endif
|
2022-05-31 10:04:11 +00:00
|
|
|
|
|
|
|
paging_init();
|
2023-09-06 14:54:16 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_KASAN
|
|
|
|
kasan_init();
|
|
|
|
#endif
|
2022-05-31 10:04:11 +00:00
|
|
|
}
|