RE: kexec crash on OVMF i386 + x86_64 kernel (Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel)

2019-04-17 Thread Prakhya, Sai Praneeth
> Added efi people.
> 
> I remember previously Sai did some efi32 tests for kexec, but I'm not sure if 
> he
> tested EFI32 + 64bit kernel.
> 
> Kexec status is not certain because I'm not sure anyone tesed and reported
> issues for that.

No.. I didn't test kexec on EFI32 + 64bit kernel and I also haven't tested 
kexec'ing from 
kexec'd kernel.

Regards,
Sai

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-17 Thread Chao Fan
On Wed, Apr 17, 2019 at 10:54:34AM +0200, Borislav Petkov wrote:
>On Wed, Apr 17, 2019 at 03:02:50PM +0800, Dave Young wrote:
>> How about move it after console_init,
>
>Sounds ok to me. That's still before KASLR gets setup and should work
>for Chao's movable regions too.

Yes, when debugging, I also put it after console_init().

Thanks,
Chao Fan

>
>> and at the same time skip efi_get_rsdp_addr in case kexec?
>
>If kexec_get_rsdp_addr() gets a correct address, efi_get_rsdp_addr()
>will be skipped.
>
>-- 
>Regards/Gruss,
>Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>



___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-17 Thread Borislav Petkov
On Wed, Apr 17, 2019 at 10:54:34AM +0200, Borislav Petkov wrote:
> On Wed, Apr 17, 2019 at 03:02:50PM +0800, Dave Young wrote:
> > How about move it after console_init,
> 
> Sounds ok to me. That's still before KASLR gets setup and should work
> for Chao's movable regions too.

---
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index c0d6c560df69..24e65a0f756d 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -351,9 +351,6 @@ asmlinkage __visible void *extract_kernel(void *rmode, 
memptr heap,
/* Clear flags intended for solely in-kernel use. */
boot_params->hdr.loadflags &= ~KASLR_FLAG;
 
-   /* Save RSDP address for later use. */
-   boot_params->acpi_rsdp_addr = get_rsdp_addr();
-
sanitize_boot_params(boot_params);
 
if (boot_params->screen_info.orig_video_mode == 7) {
@@ -368,6 +365,14 @@ asmlinkage __visible void *extract_kernel(void *rmode, 
memptr heap,
cols = boot_params->screen_info.orig_video_cols;
 
console_init();
+
+   /*
+* Save RSDP address for later use. Have this after console_init()
+* so that early debugging output from the RSDP parsing code can be
+* collected.
+*/
+   boot_params->acpi_rsdp_addr = get_rsdp_addr();
+
debug_putstr("early console in extract_kernel\n");
 
free_mem_ptr = heap;/* Heap */

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-17 Thread Borislav Petkov
On Wed, Apr 17, 2019 at 03:02:50PM +0800, Dave Young wrote:
> How about move it after console_init,

Sounds ok to me. That's still before KASLR gets setup and should work
for Chao's movable regions too.

> and at the same time skip efi_get_rsdp_addr in case kexec?

If kexec_get_rsdp_addr() gets a correct address, efi_get_rsdp_addr()
will be skipped.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-17 Thread Dave Young
On 04/16/19 at 10:44pm, Junichi Nomura wrote:
> On 4/16/19 6:40 PM, Borislav Petkov wrote:
> > On Mon, Apr 15, 2019 at 11:00:25PM +, Junichi Nomura wrote:
> >> I thought we should hang here instead of return so that we
> >> don't run into efi_get_rsdp_addr() in case of kexec.
> > 
> > Hanging that early without debug output is not very friendly to
> > debuggers, methinks.
> 
> Right. But if we could move get_rsdp_addr() after console_init(),
> you get debug output.
> 

move it after console_init looks better, I finally setup IME as a serial
console, I can see debug msg even for kexec reboot now.

How about move it after console_init, and at the same time skip
efi_get_rsdp_addr in case kexec?

Thanks
Dave

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: kexec crash on OVMF i386 + x86_64 kernel (Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel)

2019-04-16 Thread Dave Young
Added efi people.

I remember previously Sai did some efi32 tests for kexec, but I'm not
sure if he tested EFI32 + 64bit kernel.

Kexec status is not certain because I'm not sure anyone tesed and
reported issues for that.

On 04/16/19 at 11:09pm, Junichi Nomura wrote:
> On 4/16/19 6:45 PM, Borislav Petkov wrote:
> > On Mon, Apr 15, 2019 at 11:14:34PM +, Junichi Nomura wrote:
> >> I see kexec is only supported on 64bit kernel. But are we sure
> >> we don't need to support kexec on EFI32 + 64bit kernel?
> >>
> >> I don't have such an environment and as far as I tried with OVMF i386
> >> and KVM guest, that combination doesn't work reliably even with v5.0.
> > 
> > What does that mean exactly?
> > 
> > If it can be fixed, we can try to.
> 
> When I do kexec on OVMF i386 + x86_64 kernel, 1st kexec seems to work.
> But 2nd kexec (i.e. kexec from kexec-booted system) causes kernel
> crash during boot like this:
> 
> [   69.907176] kexec_core: Starting new kernel
> early console in extract_kernel
> input_data: 0x3e7a73b1
> input_len: 0x004464c8
> output: 0x3d60
> output_len: 0x015c7248
> kernel_total_size: 0x0142c000
> trampoline_32bit: 0x0009d000
> booted via startup_64()
> Physical KASLR using RDRAND RDTSC...
> Virtual KASLR using RDRAND RDTSC...
> 
> Decompressing Linux... Parsing ELF... Performing relocations... done.
> Booting the kernel.
> [0.00] Linux version 5.0.0-dirty (root@vm76) (gcc version 4.8.5 
> 20150623 (Red Hat 4.8.5-28) (GCC)) #2 SMP Mon Apr 8 04:42:45 EDT 2019
> [0.00] Command line: root=UUID=6bea2b7b-e6cc-4dba-ac79-be6530d348f5 
> ro console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 
> crashkernel=auto LANG=en_US.UTF-8 earlyprintk=serial,ttyS0,115200 kexec kexec
> [0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point 
> registers'
> [0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
> [0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
> [0.00] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
> [0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 
> bytes, using 'standard' format.
> [0.00] BIOS-provided physical RAM map:
> [0.00] BIOS-e820: [mem 0x0100-0x0009] usable
> [0.00] BIOS-e820: [mem 0x0010-0x3ed74fff] usable
> [0.00] BIOS-e820: [mem 0x3ed75000-0x3ee86fff] reserved
> [0.00] BIOS-e820: [mem 0x3ee87000-0x3ff06fff] usable
> [0.00] BIOS-e820: [mem 0x3ff07000-0x3ff5efff] reserved
> [0.00] BIOS-e820: [mem 0x3ff5f000-0x3ff66fff] ACPI 
> data
> [0.00] BIOS-e820: [mem 0x3ff67000-0x3ff6afff] ACPI NVS
> [0.00] BIOS-e820: [mem 0x3ff6b000-0x3ffc] usable
> [0.00] BIOS-e820: [mem 0x3ffd-0x3ffe] reserved
> [0.00] BIOS-e820: [mem 0x3fff-0x3fff] usable
> [0.00] BIOS-e820: [mem 0xffe0-0x] reserved
> [0.00] printk: bootconsole [earlyser0] enabled
> [0.00] NX (Execute Disable) protection: active
> [0.00] DMI not present or invalid.
> [0.00] Hypervisor detected: KVM
> [0.00] kvm-clock: Using msrs 4b564d01 and 4b564d00
> [0.00] kvm-clock: cpu 0, msr 2238e001, primary cpu clock
> [0.01] kvm-clock: using sched offset of 100318497884 cycles
> [0.001055] clocksource: kvm-clock: mask: 0x max_cycles: 
> 0x1cd42e4dffb, max_idle_ns: 881590591483 ns
> [0.004086] tsc: Detected 2399.998 MHz processor
> [0.005147] last_pfn = 0x4 max_arch_pfn = 0x4
> [0.006234] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT  
> Memory KASLR using RDRAND RDTSC...
> [0.008079] x2apic: enabled by BIOS, switching to x2apic ops
> [0.020284] RAMDISK: [mem 0x3b8da000-0x3d5f]
> [0.021169] ACPI: Early table checksum verification disabled
> [0.022280] ACPI BIOS Error (bug): A valid RSDP was not found 
> (20181213/tbxfroot-210)
> [0.023755] No NUMA configuration found
> [0.024461] Faking a node at [mem 0x-0x3fff]
> [0.025746] NODE_DATA(0) allocated [mem 0x3ffa6000-0x3ffc]
> [0.027098] crashkernel: memory value expected
> [0.027918] Zone ranges:
> [0.028384]   DMA  [mem 0x1000-0x00ff]
> [0.029553]   DMA32[mem 0x0100-0x3fff]
> [0.030688]   Normal   empty
> [0.031217]   Device   empty
> [0.031741] Movable zone start for each node
> [0.032525] Early memory node ranges
> [0.033212]   node   0: [mem 0x1000-0x0009]
> [0.034377]   node   0: [mem 0x0010-0x3ed74fff]
> [0.035520]   node   0: [mem 0x3ee87000-0x3ff06fff]
> [0.036663] 

kexec crash on OVMF i386 + x86_64 kernel (Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel)

2019-04-16 Thread Junichi Nomura
On 4/16/19 6:45 PM, Borislav Petkov wrote:
> On Mon, Apr 15, 2019 at 11:14:34PM +, Junichi Nomura wrote:
>> I see kexec is only supported on 64bit kernel. But are we sure
>> we don't need to support kexec on EFI32 + 64bit kernel?
>>
>> I don't have such an environment and as far as I tried with OVMF i386
>> and KVM guest, that combination doesn't work reliably even with v5.0.
> 
> What does that mean exactly?
> 
> If it can be fixed, we can try to.

When I do kexec on OVMF i386 + x86_64 kernel, 1st kexec seems to work.
But 2nd kexec (i.e. kexec from kexec-booted system) causes kernel
crash during boot like this:

[   69.907176] kexec_core: Starting new kernel
early console in extract_kernel
input_data: 0x3e7a73b1
input_len: 0x004464c8
output: 0x3d60
output_len: 0x015c7248
kernel_total_size: 0x0142c000
trampoline_32bit: 0x0009d000
booted via startup_64()
Physical KASLR using RDRAND RDTSC...
Virtual KASLR using RDRAND RDTSC...

Decompressing Linux... Parsing ELF... Performing relocations... done.
Booting the kernel.
[0.00] Linux version 5.0.0-dirty (root@vm76) (gcc version 4.8.5 
20150623 (Red Hat 4.8.5-28) (GCC)) #2 SMP Mon Apr 8 04:42:45 EDT 2019
[0.00] Command line: root=UUID=6bea2b7b-e6cc-4dba-ac79-be6530d348f5 ro 
console=tty0 console=ttyS0,115200n8 no_timer_check net.ifnames=0 
crashkernel=auto LANG=en_US.UTF-8 earlyprintk=serial,ttyS0,115200 kexec kexec
[0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point 
registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[0.00] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
[0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, 
using 'standard' format.
[0.00] BIOS-provided physical RAM map:
[0.00] BIOS-e820: [mem 0x0100-0x0009] usable
[0.00] BIOS-e820: [mem 0x0010-0x3ed74fff] usable
[0.00] BIOS-e820: [mem 0x3ed75000-0x3ee86fff] reserved
[0.00] BIOS-e820: [mem 0x3ee87000-0x3ff06fff] usable
[0.00] BIOS-e820: [mem 0x3ff07000-0x3ff5efff] reserved
[0.00] BIOS-e820: [mem 0x3ff5f000-0x3ff66fff] ACPI data
[0.00] BIOS-e820: [mem 0x3ff67000-0x3ff6afff] ACPI NVS
[0.00] BIOS-e820: [mem 0x3ff6b000-0x3ffc] usable
[0.00] BIOS-e820: [mem 0x3ffd-0x3ffe] reserved
[0.00] BIOS-e820: [mem 0x3fff-0x3fff] usable
[0.00] BIOS-e820: [mem 0xffe0-0x] reserved
[0.00] printk: bootconsole [earlyser0] enabled
[0.00] NX (Execute Disable) protection: active
[0.00] DMI not present or invalid.
[0.00] Hypervisor detected: KVM
[0.00] kvm-clock: Using msrs 4b564d01 and 4b564d00
[0.00] kvm-clock: cpu 0, msr 2238e001, primary cpu clock
[0.01] kvm-clock: using sched offset of 100318497884 cycles
[0.001055] clocksource: kvm-clock: mask: 0x max_cycles: 
0x1cd42e4dffb, max_idle_ns: 881590591483 ns
[0.004086] tsc: Detected 2399.998 MHz processor
[0.005147] last_pfn = 0x4 max_arch_pfn = 0x4
[0.006234] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT  
Memory KASLR using RDRAND RDTSC...
[0.008079] x2apic: enabled by BIOS, switching to x2apic ops
[0.020284] RAMDISK: [mem 0x3b8da000-0x3d5f]
[0.021169] ACPI: Early table checksum verification disabled
[0.022280] ACPI BIOS Error (bug): A valid RSDP was not found 
(20181213/tbxfroot-210)
[0.023755] No NUMA configuration found
[0.024461] Faking a node at [mem 0x-0x3fff]
[0.025746] NODE_DATA(0) allocated [mem 0x3ffa6000-0x3ffc]
[0.027098] crashkernel: memory value expected
[0.027918] Zone ranges:
[0.028384]   DMA  [mem 0x1000-0x00ff]
[0.029553]   DMA32[mem 0x0100-0x3fff]
[0.030688]   Normal   empty
[0.031217]   Device   empty
[0.031741] Movable zone start for each node
[0.032525] Early memory node ranges
[0.033212]   node   0: [mem 0x1000-0x0009]
[0.034377]   node   0: [mem 0x0010-0x3ed74fff]
[0.035520]   node   0: [mem 0x3ee87000-0x3ff06fff]
[0.036663]   node   0: [mem 0x3ff6b000-0x3ffc]
[0.037840]   node   0: [mem 0x3fff-0x3fff]
[0.039012] Zeroed struct page in unavailable ranges: 503 pages
[0.039013] Initmem setup node 0 [mem 0x1000-0x3fff]
[0.044319] BUG: unable to handle kernel paging request at ff5fd020
[0.045637] #PF error: [normal kernel read fault]
[0.046501] PGD 2200e067 P4D 

Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-16 Thread Junichi Nomura
On 4/16/19 6:40 PM, Borislav Petkov wrote:
> On Mon, Apr 15, 2019 at 11:00:25PM +, Junichi Nomura wrote:
>> I thought we should hang here instead of return so that we
>> don't run into efi_get_rsdp_addr() in case of kexec.
> 
> Hanging that early without debug output is not very friendly to
> debuggers, methinks.

Right. But if we could move get_rsdp_addr() after console_init(),
you get debug output.

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-16 Thread Borislav Petkov
On Mon, Apr 15, 2019 at 11:14:34PM +, Junichi Nomura wrote:
> I see kexec is only supported on 64bit kernel. But are we sure
> we don't need to support kexec on EFI32 + 64bit kernel?
> 
> I don't have such an environment and as far as I tried with OVMF i386
> and KVM guest, that combination doesn't work reliably even with v5.0.

What does that mean exactly?

If it can be fixed, we can try to.

> So I suppose people don't care.

There's that.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-16 Thread Borislav Petkov
On Mon, Apr 15, 2019 at 11:00:25PM +, Junichi Nomura wrote:
> I thought we should hang here instead of return so that we
> don't run into efi_get_rsdp_addr() in case of kexec.

Hanging that early without debug output is not very friendly to
debuggers, methinks.

> > +   ei = _params->efi_info;
> > +   sig = (char *)>efi_loader_signature;
> > +   if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
> > +   debug_putstr("Wrong kexec EFI loader signature.\n");
> > +   return 0;
> > +   }
> 
> Same here.

Ditto.

You get the idea.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-15 Thread Junichi Nomura
On 4/16/19 8:00 AM, Junichi Nomura wrote:
> On 4/15/19 7:25 PM, Borislav Petkov wrote:
>> On Mon, Apr 15, 2019 at 11:07:17AM +0200, Borislav Petkov wrote:
>>> On Mon, Apr 15, 2019 at 07:01:54AM +, Junichi Nomura wrote:
 OK. Then I'll go back to v3 and make sure to hang when
 something is wrong during kexec boot on EFI system.
>>>
>>> No need - I have it here locally. I'll clean it up and post it for
>>> review.
>>
>> Here it is. Ok, not ok?
> 
> Thank you.  Basically ok.
> I put some comments below about whether to hang or return.
> 
>> +static acpi_physical_address kexec_get_rsdp_addr(void)
>> +{
>> +efi_system_table_64_t *systab;
>> +struct efi_setup_data *esd;
>> +struct efi_info *ei;
>> +char *sig;
>> +
>> +esd = (struct efi_setup_data *)get_kexec_setup_data_addr();
>> +if (!esd)
>> +return 0;
>> +
>> +if (!esd->tables) {
>> +debug_putstr("Wrong kexec SETUP_EFI data.\n");
>> +return 0;
>> +}
> 
> I thought we should hang here instead of return so that we
> don't run into efi_get_rsdp_addr() in case of kexec.
> 
>> +ei = _params->efi_info;
>> +sig = (char *)>efi_loader_signature;
>> +if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
>> +debug_putstr("Wrong kexec EFI loader signature.\n");
>> +return 0;
>> +}
> 
> Same here.

One more question just for clarification.

I see kexec is only supported on 64bit kernel. But are we sure
we don't need to support kexec on EFI32 + 64bit kernel?

I don't have such an environment and as far as I tried with OVMF i386
and KVM guest, that combination doesn't work reliably even with v5.0.
So I suppose people don't care.

>> +/* Get systab from boot params. */
>> +systab = (efi_system_table_64_t *) (ei->efi_systab | 
>> ((__u64)ei->efi_systab_hi << 32));
>> +if (!systab)
>> +error("EFI system table not found in kexec boot_params.");
>> +
>> +return __efi_get_rsdp_addr((unsigned long)esd->tables, 
>> systab->nr_tables, true);
> 
> Same here when __efi_get_rsdp_addr() returns 0.
> 
> I'm fine with either way, though.

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-15 Thread Junichi Nomura
On 4/15/19 7:25 PM, Borislav Petkov wrote:
> On Mon, Apr 15, 2019 at 11:07:17AM +0200, Borislav Petkov wrote:
>> On Mon, Apr 15, 2019 at 07:01:54AM +, Junichi Nomura wrote:
>>> OK. Then I'll go back to v3 and make sure to hang when
>>> something is wrong during kexec boot on EFI system.
>>
>> No need - I have it here locally. I'll clean it up and post it for
>> review.
> 
> Here it is. Ok, not ok?

Thank you.  Basically ok.
I put some comments below about whether to hang or return.

> +static acpi_physical_address kexec_get_rsdp_addr(void)
> +{
> + efi_system_table_64_t *systab;
> + struct efi_setup_data *esd;
> + struct efi_info *ei;
> + char *sig;
> +
> + esd = (struct efi_setup_data *)get_kexec_setup_data_addr();
> + if (!esd)
> + return 0;
> +
> + if (!esd->tables) {
> + debug_putstr("Wrong kexec SETUP_EFI data.\n");
> + return 0;
> + }

I thought we should hang here instead of return so that we
don't run into efi_get_rsdp_addr() in case of kexec.

> + ei = _params->efi_info;
> + sig = (char *)>efi_loader_signature;
> + if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
> + debug_putstr("Wrong kexec EFI loader signature.\n");
> + return 0;
> + }

Same here.

> + /* Get systab from boot params. */
> + systab = (efi_system_table_64_t *) (ei->efi_systab | 
> ((__u64)ei->efi_systab_hi << 32));
> + if (!systab)
> + error("EFI system table not found in kexec boot_params.");
> +
> + return __efi_get_rsdp_addr((unsigned long)esd->tables, 
> systab->nr_tables, true);

Same here when __efi_get_rsdp_addr() returns 0.

I'm fine with either way, though.

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-15 Thread Borislav Petkov
On Mon, Apr 15, 2019 at 11:07:17AM +0200, Borislav Petkov wrote:
> On Mon, Apr 15, 2019 at 07:01:54AM +, Junichi Nomura wrote:
> > OK. Then I'll go back to v3 and make sure to hang when
> > something is wrong during kexec boot on EFI system.
> 
> No need - I have it here locally. I'll clean it up and post it for
> review.

Here it is. Ok, not ok?

---
diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index 0ef4ad55b29b..089639a8a384 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -44,17 +44,109 @@ static acpi_physical_address get_acpi_rsdp(void)
return addr;
 }
 
-/* Search EFI system tables for RSDP. */
-static acpi_physical_address efi_get_rsdp_addr(void)
+/*
+ * Search EFI system tables for RSDP.  If both ACPI_20_TABLE_GUID and
+ * ACPI_TABLE_GUID are found, take the former, which has more features.
+ */
+static acpi_physical_address
+__efi_get_rsdp_addr(unsigned long config_tables, unsigned int nr_tables,
+   bool efi_64)
 {
acpi_physical_address rsdp_addr = 0;
 
 #ifdef CONFIG_EFI
-   unsigned long systab, systab_tables, config_tables;
+   int i;
+
+   /* Get EFI tables from systab. */
+   for (i = 0; i < nr_tables; i++) {
+   acpi_physical_address table;
+   efi_guid_t guid;
+
+   if (efi_64) {
+   efi_config_table_64_t *tbl = (efi_config_table_64_t *) 
config_tables + i;
+
+   guid  = tbl->guid;
+   table = tbl->table;
+
+   if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
+   debug_putstr("Error getting RSDP address: EFI 
config table located above 4GB.\n");
+   return 0;
+   }
+   } else {
+   efi_config_table_32_t *tbl = (efi_config_table_32_t *) 
config_tables + i;
+
+   guid  = tbl->guid;
+   table = tbl->table;
+   }
+
+   if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))
+   rsdp_addr = table;
+   else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID)))
+   return table;
+   }
+#endif
+   return rsdp_addr;
+}
+
+/* EFI/kexec support is 64-bit only. */
+#ifdef CONFIG_X86_64
+static struct efi_setup_data * get_kexec_setup_data_addr(void)
+{
+   struct setup_data *data;
+   u64 pa_data;
+
+   pa_data = boot_params->hdr.setup_data;
+   while (pa_data) {
+   data = (struct setup_data *)pa_data;
+   if (data->type == SETUP_EFI)
+   return (struct efi_setup_data *)(pa_data + 
sizeof(struct setup_data));
+
+   pa_data = data->next;
+   }
+   return NULL;
+}
+
+static acpi_physical_address kexec_get_rsdp_addr(void)
+{
+   efi_system_table_64_t *systab;
+   struct efi_setup_data *esd;
+   struct efi_info *ei;
+   char *sig;
+
+   esd = (struct efi_setup_data *)get_kexec_setup_data_addr();
+   if (!esd)
+   return 0;
+
+   if (!esd->tables) {
+   debug_putstr("Wrong kexec SETUP_EFI data.\n");
+   return 0;
+   }
+
+   ei = _params->efi_info;
+   sig = (char *)>efi_loader_signature;
+   if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
+   debug_putstr("Wrong kexec EFI loader signature.\n");
+   return 0;
+   }
+
+   /* Get systab from boot params. */
+   systab = (efi_system_table_64_t *) (ei->efi_systab | 
((__u64)ei->efi_systab_hi << 32));
+   if (!systab)
+   error("EFI system table not found in kexec boot_params.");
+
+   return __efi_get_rsdp_addr((unsigned long)esd->tables, 
systab->nr_tables, true);
+}
+#else
+static acpi_physical_address kexec_get_rsdp_addr(void) { return 0; }
+#endif /* CONFIG_X86_64 */
+
+static acpi_physical_address efi_get_rsdp_addr(void)
+{
+#ifdef CONFIG_EFI
+   unsigned long systab, config_tables;
unsigned int nr_tables;
struct efi_info *ei;
bool efi_64;
-   int size, i;
char *sig;
 
ei = _params->efi_info;
@@ -88,49 +180,20 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 
config_tables   = stbl->tables;
nr_tables   = stbl->nr_tables;
-   size= sizeof(efi_config_table_64_t);
} else {
efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab;
 
config_tables   = stbl->tables;
nr_tables   = stbl->nr_tables;
-   size= sizeof(efi_config_table_32_t);
}
 
if (!config_tables)
error("EFI config tables not found.");
 
-   /* Get EFI tables from systab. */
-   for (i = 0; i < nr_tables; i++) {
-   acpi_physical_address table;
-   efi_guid_t guid;
-
-  

Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-15 Thread Borislav Petkov
On Mon, Apr 15, 2019 at 07:01:54AM +, Junichi Nomura wrote:
> OK. Then I'll go back to v3 and make sure to hang when
> something is wrong during kexec boot on EFI system.

No need - I have it here locally. I'll clean it up and post it for
review.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-15 Thread Dave Young
On 04/12/19 at 08:23am, Baoquan He wrote:
> On 04/11/19 at 09:14am, Junichi Nomura wrote:
> > On 4/11/19 5:42 PM, Baoquan He wrote:
> > > On 04/11/19 at 08:16am, Junichi Nomura wrote:
> > >> kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
> > >> setup_data was invalid. In such a case, falling back to 
> > >> efi_get_rsdp_addr()
> > >> will hit the problem of accessing invalid table pointer again.
> > > 
> > > Seems you are trying to address Dave Young's comment in 
> > > http://lkml.kernel.org/r/20190404073233.gc5...@dhcp-128-65.nay.redhat.com
> > 
> > Right. His "In case kexec_get_rsdp_addr failed.." comment.
> > 
> > > We may need discuss and make clear if those are doable. E.g the first
> > > comment, if not hang by below line of code, returning 0 for what? Can
> > > kexec still be saved, or just reset to firmware?
> > > 
> > >   error("EFI system table not found in kexec boot_params.")
> > 
> > If we return 0 and also don't hang in the rest of get_rsdp_addr(),
> > it just work as the same way as v5.0 and earlier kernel do.
> > 
> > Failure cases in kexec_get_rsdp_addr() are followings:
> > 1. efi_setup_data is invalid
> > 2. loader signature is invalid
> > 3. EFI systab is not found in boot_params
> > 4. RSDP is not found by parsing tables pointed to by efi_setup_data
> > 
> > I think all of them are critical for EFI boot, so one option could be
> > we never return failure in kexec_get_rsdp_addr() and just hang.
> > But hanging in this very early stage of boot may make the problem
> > harder to investigate once happens. Even earlyprintk is not working yet.
> > So the other option is returning 0 to defer the crash for later stage.
> 
> OK, I got the point, thanks. So it is deferred to the late stage, KASLR
> may not avoid those memory region which is marked as hotpluggable in
> SRAT. Kernel can boot up, but doesn't function well on hotplug stuff.
> In this case, people don't know why it happened. We are still blind.
> 
> Seems early console in efi is the problem, but not kexec or hotplug. I
> am fine to hang, or make it continue booting for now.
> 
> Hi Dave, 
> 
> Is it possible to fix the efi early console issue? I mean the
> feasibility, I believe it won't be easy. Ask this because not only this
> issue encountered, any other issue could be triggered during boot
> decompressing stage. If efi has this problem, we can't debug them
> either.

For normal boot, it maybe doable to use some boot services eg. some
graphic protocols efi firmware provided.

But for kexec, it is different because it become virtual mode, boot
services are not available, and kernel takes over the mode setting etc.
the early framebuffer maybe usable, maybe not, it is not reliable.

Thanks
Dave

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-15 Thread Junichi Nomura
On 4/12/19 10:35 PM, Borislav Petkov wrote:
> On Fri, Apr 12, 2019 at 10:49:56AM +0200, Borislav Petkov wrote:
>> Now I need to go figure out whether there's a reliable way to know in
>> the kexec kernel that it *is* a kexec kernel.
> 
> Actually, thinking about this more, we don't need to know whether the
> kernel was kexeced or not. Why?
> 
> Because if it is kexec'ed, kexec(1) passes the required info in
> setup_data. Now, if for whatever reason the kexec'ed kernel fails to
> parse that EFI info and get the systab to figure out the RDSP, then it
> doesn't have any other choice but fail booting.
> 
> Because there's no way it can figure out where the EFI runtime has been
> mapped and recover by finding the RDSP from there.
> 
> So I think we're perfectly fine with the old approach:
> 
> if (!pa)
> pa = kexec_get_rsdp_addr();
> 
> if (!pa)
> pa = efi_get_rsdp_addr();

OK. Then I'll go back to v3 and make sure to hang when
something is wrong during kexec boot on EFI system.

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-12 Thread Borislav Petkov
On Fri, Apr 12, 2019 at 10:49:56AM +0200, Borislav Petkov wrote:
> Now I need to go figure out whether there's a reliable way to know in
> the kexec kernel that it *is* a kexec kernel.

Actually, thinking about this more, we don't need to know whether the
kernel was kexeced or not. Why?

Because if it is kexec'ed, kexec(1) passes the required info in
setup_data. Now, if for whatever reason the kexec'ed kernel fails to
parse that EFI info and get the systab to figure out the RDSP, then it
doesn't have any other choice but fail booting.

Because there's no way it can figure out where the EFI runtime has been
mapped and recover by finding the RDSP from there.

So I think we're perfectly fine with the old approach:

if (!pa)
pa = kexec_get_rsdp_addr();

if (!pa)
pa = efi_get_rsdp_addr();


-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-12 Thread Borislav Petkov
On Fri, Apr 12, 2019 at 02:54:17AM +, Junichi Nomura wrote:
> Without #ifdef CONFIG_X86_64, I got compiler warnings on 32bit build
> about casting u64 to pointer.

Yah, stupid ifdeffery.

> We need #ifdef CONFIG_EFI to avoid build failure about undefined
> __efi_get_rsdp_addr().

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index c3020e2d8f67..4b1d4a0a4269 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -46,7 +46,6 @@ static acpi_physical_address get_acpi_rsdp(void)
return addr;
 }
 
-#ifdef CONFIG_EFI
 /*
  * Search EFI system tables for RSDP.  If both ACPI_20_TABLE_GUID and
  * ACPI_TABLE_GUID are found, take the former, which has more features.
@@ -56,6 +55,8 @@ __efi_get_rsdp_addr(unsigned long config_tables, unsigned int 
nr_tables,
bool efi_64)
 {
acpi_physical_address rsdp_addr = 0;
+
+#ifdef CONFIG_EFI
int i;
 
/* Get EFI tables from systab. */
@@ -85,10 +86,9 @@ __efi_get_rsdp_addr(unsigned long config_tables, unsigned 
int nr_tables,
else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID)))
return table;
}
-
+#endif
return rsdp_addr;
 }
-#endif
 
 /* EFI/kexec support is 64-bit only. */
 #ifdef CONFIG_X86_64
---

> I think that should be the other way around:

No, it shouldn't.

kexec_get_rsdp_addr() must do:

if (!kexec_kernel)
return 0:

esd = (struct efi_setup_data *)get_kexec_setup_data_addr();
if (!esd)
return EFI_SETUP_DATA_INVALID;

...

Now I need to go figure out whether there's a reliable way to know in
the kexec kernel that it *is* a kexec kernel.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Junichi Nomura
On 4/11/19 9:58 PM, Borislav Petkov wrote:
> Something like this based on your v3. I still need to figure out a
> reliable way to check in kexec_get_rsdp_addr() whether we're a kexec-ed
> kernel but other than that, it should look something like this:

Thank you.

> +static struct efi_setup_data *get_kexec_setup_data_addr(void)
> +{
> + struct setup_data *data;
> + u64 pa_data;
> +
> + pa_data = boot_params->hdr.setup_data;
> + while (pa_data) {
> + data = (struct setup_data *) pa_data;
> + if (data->type == SETUP_EFI)
> + return (struct efi_setup_data *)(pa_data + 
> sizeof(struct setup_data));
> +
> + pa_data = data->next;
> + }
> + return NULL;
> +}

Without #ifdef CONFIG_X86_64, I got compiler warnings on 32bit build
about casting u64 to pointer.

> +/* EFI/kexec support is 64-bit only. */
> +static acpi_physical_address kexec_get_rsdp_addr(void)
> +{

We need #ifdef CONFIG_EFI to avoid build failure about undefined
__efi_get_rsdp_addr().

> + efi_system_table_64_t *systab;
> + struct efi_setup_data *esd;
> + struct efi_info *ei;
> + char *sig;
> +
> + if (!IS_ENABLED(CONFIG_X86_64))
> + return 0;
> +
> + esd = get_kexec_setup_data_addr();
> + if (!esd)
> + return EFI_SETUP_DATA_INVALID;
>  
> + if (!esd->tables) {
> + debug_putstr("Wrong kexec SETUP_EFI data.\n");
> + return 0;
> + }

I think that should be the other way around:

esd = get_kexec_setup_data_addr();
if (!esd) // the kernel is not kexec booted
return 0;

if (!esd->tables) {  // kexec booted but data is invalid
debug_putstr("Wrong kexec SETUP_EFI data.\n");
return EFI_SETUP_DATA_INVALID;
}

And other error returns in kexec_get_rsdp_addr() should also be
EFI_SETUP_DATA_INVALID.

> + /* Get systab from boot params. */
> + systab = (efi_system_table_64_t *) (ei->efi_systab | 
> ((__u64)ei->efi_systab_hi << 32));

Though there is !IS_ENABLED(CONFIG_X86_64), compiler still sees this
code and emits warning on 32bit build.

To fix 32bit build warnings, non-EFI build errors and return
values from kexec_get_rsdp_addr(), the patch becomes:

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index 0ef4ad5..715a8b0 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -8,6 +8,8 @@
 #include 
 #include 
 
+#define EFI_SETUP_DATA_INVALID -1ULL
+
 /*
  * Longest parameter of 'acpi=' is 'copy_dsdt', plus an extra '\0'
  * for termination.
@@ -44,17 +46,114 @@ static acpi_physical_address get_acpi_rsdp(void)
return addr;
 }
 
-/* Search EFI system tables for RSDP. */
-static acpi_physical_address efi_get_rsdp_addr(void)
+static struct efi_setup_data *get_kexec_setup_data_addr(void)
+{
+#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
+   struct setup_data *data;
+   u64 pa_data;
+
+   pa_data = boot_params->hdr.setup_data;
+   while (pa_data) {
+   data = (struct setup_data *) pa_data;
+   if (data->type == SETUP_EFI)
+   return (struct efi_setup_data *)(pa_data + 
sizeof(struct setup_data));
+
+   pa_data = data->next;
+   }
+#endif
+   return NULL;
+}
+
+#ifdef CONFIG_EFI
+/*
+ * Search EFI system tables for RSDP.  If both ACPI_20_TABLE_GUID and
+ * ACPI_TABLE_GUID are found, take the former, which has more features.
+ */
+static acpi_physical_address
+__efi_get_rsdp_addr(unsigned long config_tables, unsigned int nr_tables,
+   bool efi_64)
+{
+   acpi_physical_address rsdp_addr = 0;
+   int i;
+
+   /* Get EFI tables from systab. */
+   for (i = 0; i < nr_tables; i++) {
+   acpi_physical_address table;
+   efi_guid_t guid;
+
+   if (efi_64) {
+   efi_config_table_64_t *tbl = (efi_config_table_64_t *) 
config_tables + i;
+
+   guid  = tbl->guid;
+   table = tbl->table;
+
+   if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
+   debug_putstr("Error getting RSDP address: EFI 
config table located above 4GB.\n");
+   return 0;
+   }
+   } else {
+   efi_config_table_32_t *tbl = (efi_config_table_32_t *) 
config_tables + i;
+
+   guid  = tbl->guid;
+   table = tbl->table;
+   }
+
+   if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))
+   rsdp_addr = table;
+   else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID)))
+   return table;
+   }
+
+   return rsdp_addr;
+}
+#endif
+
+/* EFI/kexec support is 64-bit only. */
+static acpi_physical_address kexec_get_rsdp_addr(void)
 {
acpi_physical_address 

Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Baoquan He
On 04/11/19 at 09:14am, Junichi Nomura wrote:
> On 4/11/19 5:42 PM, Baoquan He wrote:
> > On 04/11/19 at 08:16am, Junichi Nomura wrote:
> >> kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
> >> setup_data was invalid. In such a case, falling back to efi_get_rsdp_addr()
> >> will hit the problem of accessing invalid table pointer again.
> > 
> > Seems you are trying to address Dave Young's comment in 
> > http://lkml.kernel.org/r/20190404073233.gc5...@dhcp-128-65.nay.redhat.com
> 
> Right. His "In case kexec_get_rsdp_addr failed.." comment.
> 
> > We may need discuss and make clear if those are doable. E.g the first
> > comment, if not hang by below line of code, returning 0 for what? Can
> > kexec still be saved, or just reset to firmware?
> > 
> > error("EFI system table not found in kexec boot_params.")
> 
> If we return 0 and also don't hang in the rest of get_rsdp_addr(),
> it just work as the same way as v5.0 and earlier kernel do.
> 
> Failure cases in kexec_get_rsdp_addr() are followings:
> 1. efi_setup_data is invalid
> 2. loader signature is invalid
> 3. EFI systab is not found in boot_params
> 4. RSDP is not found by parsing tables pointed to by efi_setup_data
> 
> I think all of them are critical for EFI boot, so one option could be
> we never return failure in kexec_get_rsdp_addr() and just hang.
> But hanging in this very early stage of boot may make the problem
> harder to investigate once happens. Even earlyprintk is not working yet.
> So the other option is returning 0 to defer the crash for later stage.

OK, I got the point, thanks. So it is deferred to the late stage, KASLR
may not avoid those memory region which is marked as hotpluggable in
SRAT. Kernel can boot up, but doesn't function well on hotplug stuff.
In this case, people don't know why it happened. We are still blind.

Seems early console in efi is the problem, but not kexec or hotplug. I
am fine to hang, or make it continue booting for now.

Hi Dave, 

Is it possible to fix the efi early console issue? I mean the
feasibility, I believe it won't be easy. Ask this because not only this
issue encountered, any other issue could be triggered during boot
decompressing stage. If efi has this problem, we can't debug them
either.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Borislav Petkov
Something like this based on your v3. I still need to figure out a
reliable way to check in kexec_get_rsdp_addr() whether we're a kexec-ed
kernel but other than that, it should look something like this:

---
diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index 0ef4ad55b29b..039d91258171 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -8,6 +8,8 @@
 #include 
 #include 
 
+#define EFI_SETUP_DATA_INVALID -1ULL
+
 /*
  * Longest parameter of 'acpi=' is 'copy_dsdt', plus an extra '\0'
  * for termination.
@@ -44,17 +46,108 @@ static acpi_physical_address get_acpi_rsdp(void)
return addr;
 }
 
-/* Search EFI system tables for RSDP. */
-static acpi_physical_address efi_get_rsdp_addr(void)
+static struct efi_setup_data *get_kexec_setup_data_addr(void)
+{
+   struct setup_data *data;
+   u64 pa_data;
+
+   pa_data = boot_params->hdr.setup_data;
+   while (pa_data) {
+   data = (struct setup_data *) pa_data;
+   if (data->type == SETUP_EFI)
+   return (struct efi_setup_data *)(pa_data + 
sizeof(struct setup_data));
+
+   pa_data = data->next;
+   }
+   return NULL;
+}
+
+#ifdef CONFIG_EFI
+/*
+ * Search EFI system tables for RSDP.  If both ACPI_20_TABLE_GUID and
+ * ACPI_TABLE_GUID are found, take the former, which has more features.
+ */
+static acpi_physical_address
+__efi_get_rsdp_addr(unsigned long config_tables, unsigned int nr_tables,
+   bool efi_64)
 {
acpi_physical_address rsdp_addr = 0;
+   int i;
+
+   /* Get EFI tables from systab. */
+   for (i = 0; i < nr_tables; i++) {
+   acpi_physical_address table;
+   efi_guid_t guid;
+
+   if (efi_64) {
+   efi_config_table_64_t *tbl = (efi_config_table_64_t *) 
config_tables + i;
+
+   guid  = tbl->guid;
+   table = tbl->table;
+
+   if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
+   debug_putstr("Error getting RSDP address: EFI 
config table located above 4GB.\n");
+   return 0;
+   }
+   } else {
+   efi_config_table_32_t *tbl = (efi_config_table_32_t *) 
config_tables + i;
+
+   guid  = tbl->guid;
+   table = tbl->table;
+   }
+
+   if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))
+   rsdp_addr = table;
+   else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID)))
+   return table;
+   }
+
+   return rsdp_addr;
+}
+#endif
+
+/* EFI/kexec support is 64-bit only. */
+static acpi_physical_address kexec_get_rsdp_addr(void)
+{
+   efi_system_table_64_t *systab;
+   struct efi_setup_data *esd;
+   struct efi_info *ei;
+   char *sig;
+
+   if (!IS_ENABLED(CONFIG_X86_64))
+   return 0;
+
+   esd = get_kexec_setup_data_addr();
+   if (!esd)
+   return EFI_SETUP_DATA_INVALID;
 
+   if (!esd->tables) {
+   debug_putstr("Wrong kexec SETUP_EFI data.\n");
+   return 0;
+   }
+
+   ei = _params->efi_info;
+   sig = (char *)>efi_loader_signature;
+   if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
+   debug_putstr("Wrong kexec EFI loader signature.\n");
+   return 0;
+   }
+
+   /* Get systab from boot params. */
+   systab = (efi_system_table_64_t *) (ei->efi_systab | 
((__u64)ei->efi_systab_hi << 32));
+   if (!systab)
+   error("EFI system table not found in kexec boot_params.");
+
+   return __efi_get_rsdp_addr((unsigned long)esd->tables, 
systab->nr_tables, true);
+}
+
+static acpi_physical_address efi_get_rsdp_addr(void)
+{
 #ifdef CONFIG_EFI
-   unsigned long systab, systab_tables, config_tables;
+   unsigned long systab, config_tables;
unsigned int nr_tables;
struct efi_info *ei;
bool efi_64;
-   int size, i;
char *sig;
 
ei = _params->efi_info;
@@ -88,49 +181,20 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 
config_tables   = stbl->tables;
nr_tables   = stbl->nr_tables;
-   size= sizeof(efi_config_table_64_t);
} else {
efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab;
 
config_tables   = stbl->tables;
nr_tables   = stbl->nr_tables;
-   size= sizeof(efi_config_table_32_t);
}
 
if (!config_tables)
error("EFI config tables not found.");
 
-   /* Get EFI tables from systab. */
-   for (i = 0; i < nr_tables; i++) {
-   acpi_physical_address table;
-   efi_guid_t guid;
-
-   config_tables += size;
-
- 

Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Boris Petkov
On April 11, 2019 11:32:59 AM GMT+02:00, Junichi Nomura 
 wrote:
>No. But that's why I asked the question. Do you mean putting
>the above code in efi_get_rsdp_addr()?

I'll do what I mean whan I get back later.

-- 
Sent from a small device: formatting sux and brevity is inevitable. 

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Junichi Nomura
On 4/11/19 6:21 PM, Boris Petkov wrote:
> On April 11, 2019 11:13:03 AM GMT+02:00, Junichi Nomura 
>  wrote:
>> On 4/11/19 5:37 PM, Borislav Petkov wrote:
>>> On Thu, Apr 11, 2019 at 08:16:45AM +, Junichi Nomura wrote:
 kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
 setup_data was invalid. In such a case, falling back to
>> efi_get_rsdp_addr()
 will hit the problem of accessing invalid table pointer again.
>>>
>>> Then you need to do this:
>>>
>>> if (kexeced kernel) {
>>> addr = kexec_get_rsdp_addr();
>>> if (!addr) {
>>> /* cannot get address */
>>> return -1;
>>> }
>>>
>>> return addr;
>>> }
>>>
>>> and the calling function get_rsdp_addr() must check the return value
>> and
>>> if it is not 0, return immediately.
>>
>> Do you mean making get_rsdp_addr() like this?
> 
> Does that look like what I've typed above?

No. But that's why I asked the question. Do you mean putting
the above code in efi_get_rsdp_addr()?

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Boris Petkov
On April 11, 2019 11:13:03 AM GMT+02:00, Junichi Nomura 
 wrote:
>On 4/11/19 5:37 PM, Borislav Petkov wrote:
>> On Thu, Apr 11, 2019 at 08:16:45AM +, Junichi Nomura wrote:
>>> kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
>>> setup_data was invalid. In such a case, falling back to
>efi_get_rsdp_addr()
>>> will hit the problem of accessing invalid table pointer again.
>> 
>> Then you need to do this:
>> 
>>  if (kexeced kernel) {
>>  addr = kexec_get_rsdp_addr();
>>  if (!addr) {
>>  /* cannot get address */
>>  return -1;
>>  }
>> 
>>  return addr;
>>  }
>> 
>> and the calling function get_rsdp_addr() must check the return value
>and
>> if it is not 0, return immediately.
>
>Do you mean making get_rsdp_addr() like this?

Does that look like what I've typed above?

-- 
Sent from a small device: formatting sux and brevity is inevitable. 

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Junichi Nomura
On 4/11/19 5:42 PM, Baoquan He wrote:
> On 04/11/19 at 08:16am, Junichi Nomura wrote:
>> kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
>> setup_data was invalid. In such a case, falling back to efi_get_rsdp_addr()
>> will hit the problem of accessing invalid table pointer again.
> 
> Seems you are trying to address Dave Young's comment in 
> http://lkml.kernel.org/r/20190404073233.gc5...@dhcp-128-65.nay.redhat.com

Right. His "In case kexec_get_rsdp_addr failed.." comment.

> We may need discuss and make clear if those are doable. E.g the first
> comment, if not hang by below line of code, returning 0 for what? Can
> kexec still be saved, or just reset to firmware?
> 
>   error("EFI system table not found in kexec boot_params.")

If we return 0 and also don't hang in the rest of get_rsdp_addr(),
it just work as the same way as v5.0 and earlier kernel do.

Failure cases in kexec_get_rsdp_addr() are followings:
1. efi_setup_data is invalid
2. loader signature is invalid
3. EFI systab is not found in boot_params
4. RSDP is not found by parsing tables pointed to by efi_setup_data

I think all of them are critical for EFI boot, so one option could be
we never return failure in kexec_get_rsdp_addr() and just hang.
But hanging in this very early stage of boot may make the problem
harder to investigate once happens. Even earlyprintk is not working yet.
So the other option is returning 0 to defer the crash for later stage.

> It may need be clarified firstly, then go further to rearrange patch.
> That can ease the work, I guess.
> 
> Personal opinion.

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Junichi Nomura
On 4/11/19 5:37 PM, Borislav Petkov wrote:
> On Thu, Apr 11, 2019 at 08:16:45AM +, Junichi Nomura wrote:
>> kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
>> setup_data was invalid. In such a case, falling back to efi_get_rsdp_addr()
>> will hit the problem of accessing invalid table pointer again.
> 
> Then you need to do this:
> 
>   if (kexeced kernel) {
>   addr = kexec_get_rsdp_addr();
>   if (!addr) {
>   /* cannot get address */
>   return -1;
>   }
> 
>   return addr;
>   }
> 
> and the calling function get_rsdp_addr() must check the return value and
> if it is not 0, return immediately.

Do you mean making get_rsdp_addr() like this?

acpi_physical_address get_rsdp_addr(void)
{
acpi_physical_address pa;
+   struct efi_setup_data *esd;

pa = get_acpi_rsdp();

if (!pa)
pa = boot_params->acpi_rsdp_addr;

+   esd = (struct efi_setup_data *) efi_get_kexec_setup_data_addr();
+   if (esd)
+   return kexec_get_rsdp_addr(esd);

if (!pa)
pa = efi_get_rsdp_addr();



-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Baoquan He
On 04/11/19 at 08:16am, Junichi Nomura wrote:
> On 4/11/19 5:09 PM, Borislav Petkov wrote:
> > On Wed, Apr 10, 2019 at 11:34:51PM +, Junichi Nomura wrote:
> >> But efi_get_rsdp_addr() needs to check whether the kernel was
> >> kexec booted to avoid accessing invalid EFI table address.
> >> efi_get_kexec_setup_data_addr() is the only method I know
> >> to check if it was kexec-booted.
> > 
> > Your v3 had the right approach - you first check if you can get the
> > address as a kexec-ed kernel. If you do, you use that one and continue
> > the normal path.
> > 
> > If you don't, you fall back to efi_get_rsdp_addr() and get it directly
> > from EFI.
> > 
> > And then carve out the functionality you need to call multiple times in
> > helper functions like __efi_get_rsdp_addr().
> > 
> > Why doesn't that work anymore?
> 
> kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
> setup_data was invalid. In such a case, falling back to efi_get_rsdp_addr()
> will hit the problem of accessing invalid table pointer again.

Seems you are trying to address Dave Young's comment in 
http://lkml.kernel.org/r/20190404073233.gc5...@dhcp-128-65.nay.redhat.com

We may need discuss and make clear if those are doable. E.g the first
comment, if not hang by below line of code, returning 0 for what? Can
kexec still be saved, or just reset to firmware?

error("EFI system table not found in kexec boot_params.")

It may need be clarified firstly, then go further to rearrange patch.
That can ease the work, I guess.

Personal opinion.

Thanks
Baoquan

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Borislav Petkov
On Thu, Apr 11, 2019 at 08:16:45AM +, Junichi Nomura wrote:
> kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
> setup_data was invalid. In such a case, falling back to efi_get_rsdp_addr()
> will hit the problem of accessing invalid table pointer again.

Then you need to do this:

if (kexeced kernel) {
addr = kexec_get_rsdp_addr();
if (!addr) {
/* cannot get address */
return -1;
}

return addr;
}

and the calling function get_rsdp_addr() must check the return value and
if it is not 0, return immediately.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Junichi Nomura
On 4/11/19 5:09 PM, Borislav Petkov wrote:
> On Wed, Apr 10, 2019 at 11:34:51PM +, Junichi Nomura wrote:
>> But efi_get_rsdp_addr() needs to check whether the kernel was
>> kexec booted to avoid accessing invalid EFI table address.
>> efi_get_kexec_setup_data_addr() is the only method I know
>> to check if it was kexec-booted.
> 
> Your v3 had the right approach - you first check if you can get the
> address as a kexec-ed kernel. If you do, you use that one and continue
> the normal path.
> 
> If you don't, you fall back to efi_get_rsdp_addr() and get it directly
> from EFI.
> 
> And then carve out the functionality you need to call multiple times in
> helper functions like __efi_get_rsdp_addr().
> 
> Why doesn't that work anymore?

kexec_get_rsdp_addr() might fail on kexec-booted kernel, e.g. if the
setup_data was invalid. In such a case, falling back to efi_get_rsdp_addr()
will hit the problem of accessing invalid table pointer again.

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-11 Thread Borislav Petkov
On Wed, Apr 10, 2019 at 11:34:51PM +, Junichi Nomura wrote:
> But efi_get_rsdp_addr() needs to check whether the kernel was
> kexec booted to avoid accessing invalid EFI table address.
> efi_get_kexec_setup_data_addr() is the only method I know
> to check if it was kexec-booted.

Your v3 had the right approach - you first check if you can get the
address as a kexec-ed kernel. If you do, you use that one and continue
the normal path.

If you don't, you fall back to efi_get_rsdp_addr() and get it directly
from EFI.

And then carve out the functionality you need to call multiple times in
helper functions like __efi_get_rsdp_addr().

Why doesn't that work anymore?

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-10 Thread Junichi Nomura
On 4/11/19 2:14 AM, Borislav Petkov wrote:
> On Mon, Apr 08, 2019 at 11:10:17PM +, Junichi Nomura wrote:
>> -#ifdef CONFIG_EFI
>> -unsigned long systab, systab_tables, config_tables;
>> -unsigned int nr_tables;
>> +static void efi_read_boot_params(void)
>> +{
>> +struct efi_setup_data *esd;
>>  struct efi_info *ei;
>> -bool efi_64;
>> -int size, i;
>>  char *sig;
>>  
>> +kexec_efi_setup_data = efi_get_kexec_setup_data_addr();
> 
> Why is that written here and tested in another function?!?

Both efi_get_rsdp_addr() and kexec_get_rsdp_addr() need to check
the result of efi_get_kexec_setup_data_addr(); the former to check
whether to exit early, the latter to use the address of the tables.
I thought it's better to store the result instead of calling twice.

>> +
>>  ei = _params->efi_info;
>>  sig = (char *)>efi_loader_signature;
>>  
>>  if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
>>  efi_64 = true;
>> +efi_booted = true;
> 
> What is that ugliness for? Have you heard of functions returning values?

Same as above. I didn't want to do signature check twice, in
efi_get_rsdp_addr() and kexec_get_rsdp_addr().
Also, the signature check has 2 return values, whether it was 32bit
or 64bit, and whether the signature was valid or not.
I could return one of them via pointer passed parameter but I thought
it's a little bit ugly.  Or I could encode them as something like
EFI_SIGNATURE_64, EFI_SIGNATURE_32, and EFI_SIGNATURE_INVALID.
But I'm not sure it's good to introduce such a thing just for here.

>> +static acpi_physical_address efi_get_rsdp_addr(void)
>> +{
>> +#ifdef CONFIG_EFI
>> +unsigned long config_tables;
>> +unsigned int nr_tables;
>> +
>> +efi_read_boot_params();
> 
> Why do you read boot params here?
> 
> No, no, no.
> 
> First you do
> 
>   efi_get_rsdp_addr()
> 
> if you cannot get an address, you

But efi_get_rsdp_addr() needs to check whether the kernel was
kexec booted to avoid accessing invalid EFI table address.
efi_get_kexec_setup_data_addr() is the only method I know
to check if it was kexec-booted.

>   - parse boot params
>   - then parse EFI tables from the address the kexeced kernel received
> 
> No intermixing of code paths and assigning variables in one function and
> using them in another.

Yeah, I don't like that. But if we are to handle 32bit EFI case,
efi_get_rsdp_addr() and kexec_get_rsdp_addr() become full of
duplication.

> You were on the right track with v3...

-- 
Jun'ichi Nomura, NEC Corporation / NEC Solution Innovators, Ltd.
___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-10 Thread Borislav Petkov
On Mon, Apr 08, 2019 at 11:10:17PM +, Junichi Nomura wrote:
> Commit 3a63f70bf4c3a ("x86/boot: Early parse RSDP and save it in
> boot_params") broke kexec boot on EFI systems.  efi_get_rsdp_addr()
> in the early parsing code tries to search RSDP from EFI table but
> that will crash because the table address is virtual when the kernel
> was booted by kexec.
> 
> In the case of kexec, physical address of EFI tables is provided
> via efi_setup_data in boot_params, which is set up by kexec(1).
> 
> Factor out the table parsing code and use different pointers depending
> on whether the kernel is booted by kexec or not.
> 
> Fixes: 3a63f70bf4c3a ("x86/boot: Early parse RSDP and save it in boot_params")
> Signed-off-by: Jun'ichi Nomura 
> Acked-by: Baoquan He 
> Tested-by: Chao Fan 
> Cc: Borislav Petkov 
> Cc: Dave Young 
> 
> --
> Original post:
>   
> https://lore.kernel.org/lkml/20190322110342.ga16...@jeru.linux.bs1.fc.nec.co.jp/
> 
> v2: Added comments above __efi_get_rsdp_addr() and kexec_get_rsdp_addr() 
> 
> v3: Properly ifdef out 64bit-only kexec code to avoid 32bit build warnings
> 
> v4:
>  - Make sure to avoid efi_get_rsdp_addr() when kexec setup_data exists
>even if the data is invalid.
>  - Return instead of hang if systab is 0 in kexec_get_rsdp_addr().
>  - Check 32bit EFI loader signature in the case of kexec as well.
>  - Factor out EFI-related boot_params handling into efi_read_boot_params() to
>avoid duplication between efi_get_rsdp_addr() and kexec_get_rsdp_addr().
> 
> The patch was tested on 3 different models of EFI-booted physical machines
> for both normal kexec and panic kexec.
> 
> There is a report, that similar problem still happens even with this patch:
>   
> https://lore.kernel.org/lkml/20190404140809.ga7...@dhcp-128-65.nay.redhat.com/
> 
> diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
> index 0ef4ad5..2bc8dca 100644
> --- a/arch/x86/boot/compressed/acpi.c
> +++ b/arch/x86/boot/compressed/acpi.c
> @@ -44,71 +44,80 @@ static acpi_physical_address get_acpi_rsdp(void)
>   return addr;
>  }
>  
> -/* Search EFI system tables for RSDP. */
> -static acpi_physical_address efi_get_rsdp_addr(void)
> +#ifdef CONFIG_EFI
> +static unsigned long kexec_efi_setup_data;
> +static unsigned long efi_systab;
> +static bool efi_booted;
> +static bool efi_64;
> +
> +static unsigned long efi_get_kexec_setup_data_addr(void)
>  {
> - acpi_physical_address rsdp_addr = 0;
> +#if defined(CONFIG_X86_64)
> + struct setup_data *data;
> + u64 pa_data;
> +
> + pa_data = boot_params->hdr.setup_data;
> + while (pa_data) {
> + data = (struct setup_data *) pa_data;
> + if (data->type == SETUP_EFI)
> + return pa_data + sizeof(struct setup_data);
> + pa_data = data->next;
> + }
> +#endif
> + return 0;
> +}
>  
> -#ifdef CONFIG_EFI
> - unsigned long systab, systab_tables, config_tables;
> - unsigned int nr_tables;
> +static void efi_read_boot_params(void)
> +{
> + struct efi_setup_data *esd;
>   struct efi_info *ei;
> - bool efi_64;
> - int size, i;
>   char *sig;
>  
> + kexec_efi_setup_data = efi_get_kexec_setup_data_addr();

Why is that written here and tested in another function?!?

> +
>   ei = _params->efi_info;
>   sig = (char *)>efi_loader_signature;
>  
>   if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
>   efi_64 = true;
> + efi_booted = true;

What is that ugliness for? Have you heard of functions returning values?

This patch has gone all downhill.

> +/*
> + * EFI/kexec support is only added for 64bit. So we don't have to
> + * care 32bit case.
> + */
> +static acpi_physical_address kexec_get_rsdp_addr(void)
> +{
> +#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
> + struct efi_setup_data *esd;
> + unsigned int nr_tables;
> +
> + if (!efi_booted || !kexec_efi_setup_data)
> + return 0;
> +
> + esd = (struct efi_setup_data *) kexec_efi_setup_data;
> +
> + if (!esd->tables) {
> + debug_putstr("Wrong kexec SETUP_EFI data.\n");
> + return 0;
> + }
> +
> + if (!efi_systab) {
> + debug_putstr("EFI system table not found in kexec 
> boot_params.");
> + return 0;
> + }
> +
> + /* Handle EFI bitness properly */
> + if (efi_64) {
> + efi_system_table_64_t *stbl = (efi_system_table_64_t 
> *)efi_systab;
> +
> + nr_tables   = stbl->nr_tables;
> + } else {
> + efi_system_table_32_t *stbl = (efi_system_table_32_t 
> *)efi_systab;
> +
> + nr_tables   = stbl->nr_tables;
> + }
> +
> + return __efi_get_rsdp_addr((unsigned long) esd->tables, nr_tables);
> +#else
> + return 0;
> +#endif
> +}
> +
> +static acpi_physical_address efi_get_rsdp_addr(void)
> +{
> +#ifdef CONFIG_EFI
> + unsigned long config_tables;
> + unsigned int nr_tables;
> +
> + 

[PATCH v4] x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernel

2019-04-08 Thread Junichi Nomura
Commit 3a63f70bf4c3a ("x86/boot: Early parse RSDP and save it in
boot_params") broke kexec boot on EFI systems.  efi_get_rsdp_addr()
in the early parsing code tries to search RSDP from EFI table but
that will crash because the table address is virtual when the kernel
was booted by kexec.

In the case of kexec, physical address of EFI tables is provided
via efi_setup_data in boot_params, which is set up by kexec(1).

Factor out the table parsing code and use different pointers depending
on whether the kernel is booted by kexec or not.

Fixes: 3a63f70bf4c3a ("x86/boot: Early parse RSDP and save it in boot_params")
Signed-off-by: Jun'ichi Nomura 
Acked-by: Baoquan He 
Tested-by: Chao Fan 
Cc: Borislav Petkov 
Cc: Dave Young 

--
Original post:
  
https://lore.kernel.org/lkml/20190322110342.ga16...@jeru.linux.bs1.fc.nec.co.jp/

v2: Added comments above __efi_get_rsdp_addr() and kexec_get_rsdp_addr() 

v3: Properly ifdef out 64bit-only kexec code to avoid 32bit build warnings

v4:
 - Make sure to avoid efi_get_rsdp_addr() when kexec setup_data exists
   even if the data is invalid.
 - Return instead of hang if systab is 0 in kexec_get_rsdp_addr().
 - Check 32bit EFI loader signature in the case of kexec as well.
 - Factor out EFI-related boot_params handling into efi_read_boot_params() to
   avoid duplication between efi_get_rsdp_addr() and kexec_get_rsdp_addr().

The patch was tested on 3 different models of EFI-booted physical machines
for both normal kexec and panic kexec.

There is a report, that similar problem still happens even with this patch:
  https://lore.kernel.org/lkml/20190404140809.ga7...@dhcp-128-65.nay.redhat.com/

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index 0ef4ad5..2bc8dca 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -44,71 +44,80 @@ static acpi_physical_address get_acpi_rsdp(void)
return addr;
 }
 
-/* Search EFI system tables for RSDP. */
-static acpi_physical_address efi_get_rsdp_addr(void)
+#ifdef CONFIG_EFI
+static unsigned long kexec_efi_setup_data;
+static unsigned long efi_systab;
+static bool efi_booted;
+static bool efi_64;
+
+static unsigned long efi_get_kexec_setup_data_addr(void)
 {
-   acpi_physical_address rsdp_addr = 0;
+#if defined(CONFIG_X86_64)
+   struct setup_data *data;
+   u64 pa_data;
+
+   pa_data = boot_params->hdr.setup_data;
+   while (pa_data) {
+   data = (struct setup_data *) pa_data;
+   if (data->type == SETUP_EFI)
+   return pa_data + sizeof(struct setup_data);
+   pa_data = data->next;
+   }
+#endif
+   return 0;
+}
 
-#ifdef CONFIG_EFI
-   unsigned long systab, systab_tables, config_tables;
-   unsigned int nr_tables;
+static void efi_read_boot_params(void)
+{
+   struct efi_setup_data *esd;
struct efi_info *ei;
-   bool efi_64;
-   int size, i;
char *sig;
 
+   kexec_efi_setup_data = efi_get_kexec_setup_data_addr();
+
ei = _params->efi_info;
sig = (char *)>efi_loader_signature;
 
if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
efi_64 = true;
+   efi_booted = true;
} else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4)) {
efi_64 = false;
+   efi_booted = true;
} else {
debug_putstr("Wrong EFI loader signature.\n");
-   return 0;
+   return;
}
 
/* Get systab from boot params. */
 #ifdef CONFIG_X86_64
-   systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
+   efi_systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
 #else
if (ei->efi_systab_hi || ei->efi_memmap_hi) {
debug_putstr("Error getting RSDP address: EFI system table 
located above 4GB.\n");
-   return 0;
+   return;
}
-   systab = ei->efi_systab;
+   efi_systab = ei->efi_systab;
 #endif
-   if (!systab)
-   error("EFI system table not found.");
-
-   /* Handle EFI bitness properly */
-   if (efi_64) {
-   efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab;
-
-   config_tables   = stbl->tables;
-   nr_tables   = stbl->nr_tables;
-   size= sizeof(efi_config_table_64_t);
-   } else {
-   efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab;
-
-   config_tables   = stbl->tables;
-   nr_tables   = stbl->nr_tables;
-   size= sizeof(efi_config_table_32_t);
-   }
+}
 
-   if (!config_tables)
-   error("EFI config tables not found.");
+/*
+ * Search EFI system tables for RSDP.  If both ACPI_20_TABLE_GUID and
+ * ACPI_TABLE_GUID are found, take the former, which has more features.
+ */
+static acpi_physical_address
+__efi_get_rsdp_addr(unsigned long config_tables, unsigned