[PATCH] MIPS: Loongson64: Add kexec/kdump support
Jinyang He
hejinyang at loongson.cn
Thu Sep 17 08:41:56 EDT 2020
Hi, Huacai,
On 09/16/2020 01:39 PM, Huacai Chen wrote:
> Hi, Jinyang,
>
> On Tue, Sep 15, 2020 at 10:17 PM Jinyang He <hejinyang at loongson.cn> wrote:
>>
>>
>> On 09/16/2020 09:33 AM, Jiaxun Yang wrote:
>>> 于 2020年9月15日 GMT+08:00 下午9:07:43, Jinyang He <hejinyang at loongson.cn> 写到:
>>>> Add loongson_kexec_prepare(), loongson_kexec_shutdown() and
>>>> loongson_kexec_crashdown() for passing the parameters of kexec_args.
>>>>
>>>> To start loongson64, CPU0 needs 3 parameters:
>>>> fw_arg0: the number of cmd.
>>>> fw_arg1: cmd structure which seems strange, the cmd array[index]'s
>>>> value is cmd string's address, index >= 1.
>>>> fw_arg2: environment.
>>>>
>>>> Secondary CPUs do not need parameter at once. They query their
>>>> mailbox to get PC, SP and GP in a loop before CPU0 brings them up
>>>> and passes these parameters via mailbox.
>>>>
>>>> loongson_kexec_prepare(): Alloc new memory to save cmd for kexec.
>>>> Combine the kexec append option string as cmd structure, and the cmd
>>>> struct will be parsed in fw_init_cmdline() of arch/mips/fw/lib/cmdline.c.
>>>> image->control_code_page need pointing to a safe memory page. In order to
>>>> maintain compatibility for the old firmware the low 2MB is reserverd
>>>> and safe for Loongson. So let it points here.
>>>>
>>>> loongson_kexec_shutdown(): Wake up all present CPUs and let them go
>>>> to reboot_code_buffer. Pass the kexec parameters to kexec_args.
>>>>
>>>> loongson_crash_shutdown(): Pass the kdump parameters to kexec_args.
>>>>
>>>> The assembly part provide a way like BIOS doing to keep secondary
>>>> CPUs in a querying loop.
>>>>
>>>> This patch referenced [1][2][3].
>>>>
>>>> [1] arch/mips/cavium-octeon/setup.c
>>>> [2] https://patchwork.kernel.org/patch/10799217/
>>>> [3] https://gitee.com/loongsonlab/qemu/blob/master/hw/mips/loongson3a_rom.h
>>>>
>>>> Co-developed-by: Youling Tang <tangyouling at loongson.cn>
>>>> Signed-off-by: Youling Tang <tangyouling at loongson.cn>
>>>> Signed-off-by: Jinyang He <hejinyang at loongson.cn>
>>>> ---
>>>> arch/mips/kernel/relocate_kernel.S | 19 ++++++++
>>>> arch/mips/loongson64/reset.c | 88 ++++++++++++++++++++++++++++++++++++++
>>>> 2 files changed, 107 insertions(+)
>>>>
>>>> diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S
>>>> index ac87089..061cbfb 100644
>>>> --- a/arch/mips/kernel/relocate_kernel.S
>>>> +++ b/arch/mips/kernel/relocate_kernel.S
>>>> @@ -133,6 +133,25 @@ LEAF(kexec_smp_wait)
>>>> #else
>>>> sync
>>>> #endif
>>>> +
>>>> +#ifdef CONFIG_CPU_LOONGSON64
>>>> +#define MAILBOX_BASE 0x900000003ff01000
>>> Please avoid hardcoded SMP information. You're breaking Loongson 3B support.
>>>
>> Ok, I see. Since my machine is Loongson 3A. I'll send v2
>> after I test it in 3B.
> 1, My original version can work on both Loongson-3A and Loongson-3B,
> why you modify my patch and hadn't discuss with me?
>
> 2, With this single patch both kexec and kdump cannot work reliably,
> because kexec need this patch:
> https://patchwork.kernel.org/patch/11695929/
>
> and kdump need my first patch in my original version:
> https://patchwork.kernel.org/patch/10799215/
>
> You may argue that you have tested. Yes, I believe that, I'm not
> saying that you haven't test, and I'm not saying that your patch
> cannot work, I'm just saying that your patch is not robust.
>
> 3, I'm the original author and paying attention to kexec/kdump
> continuosly, I will send a new version once the above two patches be
> accepted. But you re-send my patch without any communication with me,
> why you so impatient?
>
> Huacai
>
1, Your original version:
https://patchwork.kernel.org/patch/10799217/
This patch can work on Loongson-3A, I tested it.
But it works wrong after the follow behaviors,
kexec -l vmlinux --append=cmdline_kexec
kexec -p vmlinux --append=cmdline_kdump
kexec -e
It works but cmdline_kdump merged cmdline_kexec.
And this patch memcpy from fw_arg2 to kexec_envp and later memcpy from
kexec_envp to fw_arg2 when fw_arg2 was not changed, it's redundant.
However, I have not Loongson-3B now, and did not test it. For this patch,
does it work well on Loongson-3B3000/Loongson-3B4000?
2, I have known that problem before your patch:
https://patchwork.kernel.org/patch/11695929/
I also did efforts although I had't committed my patch. It's due to the
hardware issues, and I removed pcie_port_device_remove(). Kexec works
normally on GUI. But it works terriblely on CLI. After this discuss:
https://lore.kernel.org/patchwork/patch/1304917/
What Lukas said helped me. I removed
drivers/pci/pci-driver.c: pci_device_shutdown(): pci_clear_master...
Kexec works well on CLI also.
For another patch:
https://patchwork.kernel.org/patch/10799215/
I have not 2way or 4way machine, and I did not test it.
3, I try to fix Loongson64 kexec function since I joined the community.
I fell sorry to not do enough research on Loongson64 kexec. My first patch:
https://patchwork.kernel.org/patch/11684849/
It fixed problem about "Crash kernel" which can be traced back to linux-5.4.
At that time, I thought there is no developer work on Kexec. Thus, I did a
lot on Kexec. Are you really continuosly paying attention to kexec/kdump?
With the exploring and developing deep, I found your patch several days ago
after I did a draft patch witch referenced:
arch/mips/cavium-octeon/setup.c
https://gitee.com/loongsonlab/qemu/blob/master/hw/mips/loongson3a_rom.h
There is no doubt that your patch gives me confidence and suggestion while
it gives me worry. As a newcomer, I do not know if should communicate with
you since your patch was committed one year ago. And now it may be a good
chance to do some communication.
Thanks,
- Jinyang.
>>>> + mfc0 t1, CP0_EBASE
>>>> + andi t1, MIPS_EBASE_CPUNUM
>>>> + dli t0, MAILBOX_BASE
>>>> + andi t3, t1, 0x3
>>>> + sll t3, 8
>>>> + or t0, t0, t3 /* insert core id */
>>>> + andi t2, t1, 0xc
>>>> + dsll t2, 42
>>>> + or t0, t0, t2 /* insert node id */
>>>> +1: ld s1, 0x20(t0) /* get PC via mailbox0 */
>>>> + beqz s1, 1b
>>>> + ld sp, 0x28(t0) /* get SP via mailbox1 */
>>>> + ld gp, 0x30(t0) /* get GP via mailbox2 */
>>>> + ld a1, 0x38(t0)
>>>> + jr s1
>>>> +#endif
>>>> j s1
>>>> END(kexec_smp_wait)
>>>> #endif
>>>> diff --git a/arch/mips/loongson64/reset.c b/arch/mips/loongson64/reset.c
>>>> index 3bb8a1e..322c326 100644
>>>> --- a/arch/mips/loongson64/reset.c
>>>> +++ b/arch/mips/loongson64/reset.c
>>>> @@ -47,12 +47,100 @@ static void loongson_halt(void)
>>>> }
>>>> }
>>>>
>>>> +#ifdef CONFIG_KEXEC
>>>> +#include <linux/cpu.h>
>>>> +#include <linux/kexec.h>
>>>> +
>>>> +#include <asm/bootinfo.h>
>>>> +
>>>> +#define CONTROL_CODE_PAGE 0xFFFFFFFF80000000UL
>>>> +static int kexec_argc;
>>>> +static int kdump_argc;
>>>> +static void *kexec_argv;
>>>> +static void *kdump_argv;
>>>> +
>>>> +static int loongson_kexec_prepare(struct kimage *image)
>>>> +{
>>>> + int i, offt, argc = 0;
>>>> + int *argv;
>>>> + char *str, *ptr, *bootloader = "kexec";
>>>> +
>>>> + argv = kmalloc(COMMAND_LINE_SIZE, GFP_KERNEL);
>>>> + if (!argv)
>>>> + return -ENOMEM;
>>>> +
>>>> + for (i = 0; i < image->nr_segments; i++) {
>>>> + if (!strncmp(bootloader, (char *)image->segment[i].buf,
>>>> + strlen(bootloader))) {
>>>> + argv[argc++] = fw_arg1 + COMMAND_LINE_SIZE/2;
>>>> + str = (char *)argv + COMMAND_LINE_SIZE/2;
>>>> + memcpy(str, image->segment[i].buf, COMMAND_LINE_SIZE/2);
>>>> + ptr = strchr(str, ' ');
>>>> + while (ptr) {
>>>> + *ptr = '\0';
>>>> + if (ptr[1] != ' ') {
>>>> + offt = (int)(ptr - str + 1);
>>>> + argv[argc++] = fw_arg1 + COMMAND_LINE_SIZE/2 + offt;
>>>> + }
>>>> + ptr = strchr(ptr + 1, ' ');
>>>> + }
>>>> + break;
>>>> + }
>>>> + }
>>>> +
>>>> + /* Kexec/kdump needs a safe page to save reboot_code_buffer. */
>>>> + image->control_code_page = virt_to_page((void *)CONTROL_CODE_PAGE);
>>>> +
>>>> + if (image->type == KEXEC_TYPE_CRASH) {
>>>> + kfree(kdump_argv);
>>>> + kdump_argc = argc;
>>>> + kdump_argv = argv;
>>>> + } else {
>>>> + kfree(kexec_argv);
>>>> + kexec_argc = argc;
>>>> + kexec_argv = argv;
>>>> + }
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static void loongson_kexec_shutdown(void)
>>>> +{
>>>> +#ifdef CONFIG_SMP
>>>> + bringup_nonboot_cpus(loongson_sysconf.nr_cpus);
>>>> +#endif
>>>> + fw_arg0 = kexec_argc;
>>>> + memcpy((void *)fw_arg1, kexec_argv, COMMAND_LINE_SIZE);
>>>> +
>>>> + kexec_args[0] = fw_arg0;
>>>> + kexec_args[1] = fw_arg1;
>>>> + kexec_args[2] = fw_arg2;
>>>> +}
>>>> +
>>>> +static void loongson_crash_shutdown(struct pt_regs *regs)
>>>> +{
>>>> + default_machine_crash_shutdown(regs);
>>>> + fw_arg0 = kdump_argc;
>>>> + memcpy((void *)fw_arg1, kdump_argv, COMMAND_LINE_SIZE);
>>>> +
>>>> + kexec_args[0] = fw_arg0;
>>>> + kexec_args[1] = fw_arg1;
>>>> + kexec_args[2] = fw_arg2;
>>>> +}
>>>> +#endif
>>>> +
>>>> static int __init mips_reboot_setup(void)
>>>> {
>>>> _machine_restart = loongson_restart;
>>>> _machine_halt = loongson_halt;
>>>> pm_power_off = loongson_poweroff;
>>>>
>>>> +#ifdef CONFIG_KEXEC
>>>> + _machine_kexec_prepare = loongson_kexec_prepare;
>>>> + _machine_kexec_shutdown = loongson_kexec_shutdown;
>>>> + _machine_crash_shutdown = loongson_crash_shutdown;
>>>> +#endif
>>>> +
>>>> return 0;
>>>> }
>>>>
More information about the kexec
mailing list