From: Borislav Petkov <bp@alien8.de>
To: Dave Young <dyoung@redhat.com>
Cc: mjg59@srcf.ucam.org, linux-efi@vger.kernel.org,
toshi.kani@hp.com, matt@console-pimps.org, greg@kroah.com,
x86@kernel.org, kexec@lists.infradead.org,
linux-kernel@vger.kernel.org,
James.Bottomley@HansenPartnership.com, horms@verge.net.au,
ebiederm@xmission.com, hpa@zytor.com, vgoyal@redhat.com
Subject: Re: [PATCH v4 07/12] efi: passing kexec necessary efi data via setup_data
Date: Wed, 27 Nov 2013 15:07:32 +0100 [thread overview]
Message-ID: <20131127140732.GD32267@pd.tnic> (raw)
In-Reply-To: <1385445477-9665-8-git-send-email-dyoung@redhat.com>
On Tue, Nov 26, 2013 at 01:57:52PM +0800, Dave Young wrote:
> Add a new setup_data type SETUP_EFI for kexec use.
> Passing the saved fw_vendor, runtime, config tables and
> efi runtime mappings.
>
> When entering virtual mode, directly mapping the efi
> runtime ragions which we passed in previously. And skip
> the step to call SetVirtualAddressMap.
>
> Specially for HP z420 workstation it need another variable
> saving,
Why the special handling? Does that mean, this is going to be the case
for other HP UEFI implementations too?
> it's the smbios physical address, the HP bios
> also update the SMBIOS address after entering virtual mode
> besides of the standard fw_vendor,runtime and config table.
>
> Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
> HP z420 workstation.
>
> v2: refresh based on previous patch changes, code cleanup.
> v3: use ioremap instead of phys_to_virt for esdata
>
> Signed-off-by: Dave Young <dyoung@redhat.com>
> ---
> arch/x86/include/asm/efi.h | 12 +++
> arch/x86/include/uapi/asm/bootparam.h | 1 +
> arch/x86/kernel/setup.c | 3 +
> arch/x86/platform/efi/efi.c | 161 ++++++++++++++++++++++++++++++----
> 4 files changed, 160 insertions(+), 17 deletions(-)
>
> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
> index 9fbaeb2..73d5643 100644
> --- a/arch/x86/include/asm/efi.h
> +++ b/arch/x86/include/asm/efi.h
> @@ -133,6 +133,18 @@ extern void efi_sync_low_kernel_mappings(void);
> extern void efi_setup_page_tables(void);
> extern void __init old_map_region(efi_memory_desc_t *md);
>
> +struct efi_setup_data {
> + u64 fw_vendor;
> + u64 runtime;
> + u64 tables;
> + u64 smbios;
> + u64 reserved[8];
What's that for?
> + efi_memory_desc_t map[0];
> +};
> +
> +extern void parse_efi_setup(u64 phys_addr, u32 data_len);
> +extern struct efi_setup_data *esdata;
> +
> #ifdef CONFIG_EFI
>
> static inline bool efi_is_native(void)
[ … ]
> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
> index c3a2aaa..fafeb40 100644
> --- a/arch/x86/platform/efi/efi.c
> +++ b/arch/x86/platform/efi/efi.c
> @@ -504,8 +531,12 @@ static int __init efi_systab_init(void *phys)
> }
>
> efi_systab.hdr = systab64->hdr;
> - efi_systab.fw_vendor = systab64->fw_vendor;
> - tmp |= systab64->fw_vendor;
> +
> + if (esdata)
> + efi_systab.fw_vendor = (unsigned long)esdata->fw_vendor;
> + else
> + efi_systab.fw_vendor = systab64->fw_vendor;
efi_systab.fw_vendor = esdata ? (unsigned long)esdata->fw_vendor
: systab64->fw_vendor;
> + tmp |= efi_systab.fw_vendor;
> efi_systab.fw_revision = systab64->fw_revision;
> efi_systab.con_in_handle = systab64->con_in_handle;
> tmp |= systab64->con_in_handle;
> @@ -519,13 +550,21 @@ static int __init efi_systab_init(void *phys)
> tmp |= systab64->stderr_handle;
> efi_systab.stderr = systab64->stderr;
> tmp |= systab64->stderr;
> - efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
> - tmp |= systab64->runtime;
> + if (esdata)
> + efi_systab.runtime =
> + (void *)(unsigned long)esdata->runtime;
> + else
> + efi_systab.runtime =
> + (void *)(unsigned long)systab64->runtime;
Ditto. Which would take care of these linebreaks which are ugly.
> + tmp |= (unsigned long)efi_systab.runtime;
> efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
> tmp |= systab64->boottime;
> efi_systab.nr_tables = systab64->nr_tables;
> - efi_systab.tables = systab64->tables;
> - tmp |= systab64->tables;
> + if (esdata)
> + efi_systab.tables = (unsigned long)esdata->tables;
> + else
> + efi_systab.tables = systab64->tables;
Ditto.
> + tmp |= efi_systab.tables;
>
> early_iounmap(systab64, sizeof(*systab64));
> #ifdef CONFIG_X86_32
> @@ -631,6 +670,41 @@ static int __init efi_memmap_init(void)
> return 0;
> }
>
> +static int __init efi_reuse_config(u64 tables, int nr_tables)
Static function - no need for "efi_" prefix.
> +{
> + void *p, *tablep;
> + int i, sz;
> +
> + if (!efi_enabled(EFI_64BIT))
> + return 0;
> +
> + sz = sizeof(efi_config_table_64_t);
> +
> + p = tablep = early_memremap(tables, nr_tables * sz);
> + if (!p) {
> + pr_err("Could not map Configuration table!\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < efi.systab->nr_tables; i++) {
> + efi_guid_t guid;
> +
> + guid = ((efi_config_table_64_t *)p)->guid;
> +
> + /*
> + HP z420 workstation smbios will be convert to
> + virtual address after enter virtual mode.
> + Thus in case kexec/kdump the physical address
> + will be passed in setup_data.
Is that what the commit message above says? I'm having a hard time
parsing this text.
> + */
> + if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
> + ((efi_config_table_64_t *)p)->table = esdata->smbios;
...and yet we do this for *every* UEFI box. Why not HP only?
> + p += sz;
> + }
> + early_iounmap(tablep, nr_tables * sz);
> + return 0;
> +}
> +
> void __init efi_init(void)
> {
> efi_char16_t *c16;
> @@ -676,6 +750,9 @@ void __init efi_init(void)
> efi.systab->hdr.revision >> 16,
> efi.systab->hdr.revision & 0xffff, vendor);
>
> + if (esdata && esdata->smbios)
> + efi_reuse_config(efi.systab->tables, efi.systab->nr_tables);
> +
> if (efi_config_init(arch_tables))
> return;
>
> @@ -886,6 +963,43 @@ ret:
> }
>
> /*
> + * map efi regions which was passed via setup_data
> + * the virt_addr is a fixed addr which was used in
> + * 1st kernel of kexec boot.
> + */
Comment to 80 cols pls.
> +static void __init efi_map_regions_fixed(void)
Also no need for "efi_" prefix here.
> +{
> + int i;
> + unsigned long size;
> + efi_memory_desc_t *md;
> + u64 end, systab;
> + void *p;
> +
> + efi_runtime_map = kzalloc(nr_efi_runtime_map * memmap.desc_size,
> + GFP_KERNEL);
Arg alignment.
> + if (!efi_runtime_map)
> + pr_err("Out of memory, EFI runtime on nested kexec non-functional!\n");
> +
> + for (i = 0, p = efi_runtime_map; i < nr_efi_runtime_map; i++) {
> + md = esdata->map + i;
> + efi_map_region_fixed(md);
Gaah, this function should probably have a retval which signalizes
success/failure. For that I should probably teach __map_region to do
that too. On the TODO list.
> + size = md->num_pages << PAGE_SHIFT;
> + end = md->phys_addr + size;
> +
> + systab = (u64) (unsigned long) efi_phys.systab;
> + if (md->phys_addr <= systab && systab < end) {
> + systab += md->virt_addr - md->phys_addr;
> + efi.systab =
> + (efi_system_table_t *) (unsigned long) systab;
CHECK: No space is necessary after a cast
#219: FILE: arch/x86/platform/efi/efi.c:993:
+ efi.systab =
+ (efi_system_table_t *) (unsigned long) systab;
And also, those broken lines are ugly. Just let it stick out over 80 cols.
> + }
> + if (efi_runtime_map) {
> + memcpy(p, md, memmap.desc_size);
> + p += memmap.desc_size;
> + }
> + }
> +}
> +
> +/*
> * This function will switch the EFI runtime services to virtual mode.
> * Essentially, we look through the EFI memmap and map every region that
> * has the runtime attribute bit set in its memory descriptor into the
> @@ -901,6 +1015,10 @@ ret:
> * so that we're in a different address space when calling a runtime
> * function. For function arguments passing we do copy the PGDs of the
> * kernel page table into ->trampoline_pgd prior to each call.
> + *
> + * Specially for kexec boot efi runtime maps in previous kernel should
boot, ...
> + * be passed in via setup_data. In that case runtime ranges will be mapped
case, ...
> + * to fixed virtual addresses exactly same as the ones in previous kernel.
"... to the same virtual addresses as the first kernel."
> */
> void __init efi_enter_virtual_mode(void)
> {
> @@ -919,12 +1037,15 @@ void __init efi_enter_virtual_mode(void)
> return;
> }
>
> - efi_merge_regions();
> -
> - new_memmap = efi_map_regions(&count);
> - if (!new_memmap) {
> - pr_err("Error reallocating memory, EFI runtime non-functional!\n");
> - return;
> + if (esdata)
> + efi_map_regions_fixed();
> + else {
> + efi_merge_regions();
> + new_memmap = efi_map_regions(&count);
> + if (!new_memmap) {
> + pr_err("Error reallocating memory, EFI runtime non-functional!\n");
> + return;
> + }
CHECK: braces {} should be used on all arms of this statement
#253: FILE: arch/x86/platform/efi/efi.c:1040:
+ if (esdata)
[...]
+ else {
[...]
--
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
WARNING: multiple messages have this Message-ID (diff)
From: Borislav Petkov <bp-Gina5bIWoIWzQB+pC5nmwQ@public.gmane.org>
To: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
x86-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
mjg59-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org,
hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org,
James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk@public.gmane.org,
vgoyal-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org,
horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org,
matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org,
toshi.kani-VXdhtT5mjnY@public.gmane.org
Subject: Re: [PATCH v4 07/12] efi: passing kexec necessary efi data via setup_data
Date: Wed, 27 Nov 2013 15:07:32 +0100 [thread overview]
Message-ID: <20131127140732.GD32267@pd.tnic> (raw)
In-Reply-To: <1385445477-9665-8-git-send-email-dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Tue, Nov 26, 2013 at 01:57:52PM +0800, Dave Young wrote:
> Add a new setup_data type SETUP_EFI for kexec use.
> Passing the saved fw_vendor, runtime, config tables and
> efi runtime mappings.
>
> When entering virtual mode, directly mapping the efi
> runtime ragions which we passed in previously. And skip
> the step to call SetVirtualAddressMap.
>
> Specially for HP z420 workstation it need another variable
> saving,
Why the special handling? Does that mean, this is going to be the case
for other HP UEFI implementations too?
> it's the smbios physical address, the HP bios
> also update the SMBIOS address after entering virtual mode
> besides of the standard fw_vendor,runtime and config table.
>
> Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
> HP z420 workstation.
>
> v2: refresh based on previous patch changes, code cleanup.
> v3: use ioremap instead of phys_to_virt for esdata
>
> Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> arch/x86/include/asm/efi.h | 12 +++
> arch/x86/include/uapi/asm/bootparam.h | 1 +
> arch/x86/kernel/setup.c | 3 +
> arch/x86/platform/efi/efi.c | 161 ++++++++++++++++++++++++++++++----
> 4 files changed, 160 insertions(+), 17 deletions(-)
>
> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
> index 9fbaeb2..73d5643 100644
> --- a/arch/x86/include/asm/efi.h
> +++ b/arch/x86/include/asm/efi.h
> @@ -133,6 +133,18 @@ extern void efi_sync_low_kernel_mappings(void);
> extern void efi_setup_page_tables(void);
> extern void __init old_map_region(efi_memory_desc_t *md);
>
> +struct efi_setup_data {
> + u64 fw_vendor;
> + u64 runtime;
> + u64 tables;
> + u64 smbios;
> + u64 reserved[8];
What's that for?
> + efi_memory_desc_t map[0];
> +};
> +
> +extern void parse_efi_setup(u64 phys_addr, u32 data_len);
> +extern struct efi_setup_data *esdata;
> +
> #ifdef CONFIG_EFI
>
> static inline bool efi_is_native(void)
[ … ]
> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
> index c3a2aaa..fafeb40 100644
> --- a/arch/x86/platform/efi/efi.c
> +++ b/arch/x86/platform/efi/efi.c
> @@ -504,8 +531,12 @@ static int __init efi_systab_init(void *phys)
> }
>
> efi_systab.hdr = systab64->hdr;
> - efi_systab.fw_vendor = systab64->fw_vendor;
> - tmp |= systab64->fw_vendor;
> +
> + if (esdata)
> + efi_systab.fw_vendor = (unsigned long)esdata->fw_vendor;
> + else
> + efi_systab.fw_vendor = systab64->fw_vendor;
efi_systab.fw_vendor = esdata ? (unsigned long)esdata->fw_vendor
: systab64->fw_vendor;
> + tmp |= efi_systab.fw_vendor;
> efi_systab.fw_revision = systab64->fw_revision;
> efi_systab.con_in_handle = systab64->con_in_handle;
> tmp |= systab64->con_in_handle;
> @@ -519,13 +550,21 @@ static int __init efi_systab_init(void *phys)
> tmp |= systab64->stderr_handle;
> efi_systab.stderr = systab64->stderr;
> tmp |= systab64->stderr;
> - efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
> - tmp |= systab64->runtime;
> + if (esdata)
> + efi_systab.runtime =
> + (void *)(unsigned long)esdata->runtime;
> + else
> + efi_systab.runtime =
> + (void *)(unsigned long)systab64->runtime;
Ditto. Which would take care of these linebreaks which are ugly.
> + tmp |= (unsigned long)efi_systab.runtime;
> efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
> tmp |= systab64->boottime;
> efi_systab.nr_tables = systab64->nr_tables;
> - efi_systab.tables = systab64->tables;
> - tmp |= systab64->tables;
> + if (esdata)
> + efi_systab.tables = (unsigned long)esdata->tables;
> + else
> + efi_systab.tables = systab64->tables;
Ditto.
> + tmp |= efi_systab.tables;
>
> early_iounmap(systab64, sizeof(*systab64));
> #ifdef CONFIG_X86_32
> @@ -631,6 +670,41 @@ static int __init efi_memmap_init(void)
> return 0;
> }
>
> +static int __init efi_reuse_config(u64 tables, int nr_tables)
Static function - no need for "efi_" prefix.
> +{
> + void *p, *tablep;
> + int i, sz;
> +
> + if (!efi_enabled(EFI_64BIT))
> + return 0;
> +
> + sz = sizeof(efi_config_table_64_t);
> +
> + p = tablep = early_memremap(tables, nr_tables * sz);
> + if (!p) {
> + pr_err("Could not map Configuration table!\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < efi.systab->nr_tables; i++) {
> + efi_guid_t guid;
> +
> + guid = ((efi_config_table_64_t *)p)->guid;
> +
> + /*
> + HP z420 workstation smbios will be convert to
> + virtual address after enter virtual mode.
> + Thus in case kexec/kdump the physical address
> + will be passed in setup_data.
Is that what the commit message above says? I'm having a hard time
parsing this text.
> + */
> + if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
> + ((efi_config_table_64_t *)p)->table = esdata->smbios;
...and yet we do this for *every* UEFI box. Why not HP only?
> + p += sz;
> + }
> + early_iounmap(tablep, nr_tables * sz);
> + return 0;
> +}
> +
> void __init efi_init(void)
> {
> efi_char16_t *c16;
> @@ -676,6 +750,9 @@ void __init efi_init(void)
> efi.systab->hdr.revision >> 16,
> efi.systab->hdr.revision & 0xffff, vendor);
>
> + if (esdata && esdata->smbios)
> + efi_reuse_config(efi.systab->tables, efi.systab->nr_tables);
> +
> if (efi_config_init(arch_tables))
> return;
>
> @@ -886,6 +963,43 @@ ret:
> }
>
> /*
> + * map efi regions which was passed via setup_data
> + * the virt_addr is a fixed addr which was used in
> + * 1st kernel of kexec boot.
> + */
Comment to 80 cols pls.
> +static void __init efi_map_regions_fixed(void)
Also no need for "efi_" prefix here.
> +{
> + int i;
> + unsigned long size;
> + efi_memory_desc_t *md;
> + u64 end, systab;
> + void *p;
> +
> + efi_runtime_map = kzalloc(nr_efi_runtime_map * memmap.desc_size,
> + GFP_KERNEL);
Arg alignment.
> + if (!efi_runtime_map)
> + pr_err("Out of memory, EFI runtime on nested kexec non-functional!\n");
> +
> + for (i = 0, p = efi_runtime_map; i < nr_efi_runtime_map; i++) {
> + md = esdata->map + i;
> + efi_map_region_fixed(md);
Gaah, this function should probably have a retval which signalizes
success/failure. For that I should probably teach __map_region to do
that too. On the TODO list.
> + size = md->num_pages << PAGE_SHIFT;
> + end = md->phys_addr + size;
> +
> + systab = (u64) (unsigned long) efi_phys.systab;
> + if (md->phys_addr <= systab && systab < end) {
> + systab += md->virt_addr - md->phys_addr;
> + efi.systab =
> + (efi_system_table_t *) (unsigned long) systab;
CHECK: No space is necessary after a cast
#219: FILE: arch/x86/platform/efi/efi.c:993:
+ efi.systab =
+ (efi_system_table_t *) (unsigned long) systab;
And also, those broken lines are ugly. Just let it stick out over 80 cols.
> + }
> + if (efi_runtime_map) {
> + memcpy(p, md, memmap.desc_size);
> + p += memmap.desc_size;
> + }
> + }
> +}
> +
> +/*
> * This function will switch the EFI runtime services to virtual mode.
> * Essentially, we look through the EFI memmap and map every region that
> * has the runtime attribute bit set in its memory descriptor into the
> @@ -901,6 +1015,10 @@ ret:
> * so that we're in a different address space when calling a runtime
> * function. For function arguments passing we do copy the PGDs of the
> * kernel page table into ->trampoline_pgd prior to each call.
> + *
> + * Specially for kexec boot efi runtime maps in previous kernel should
boot, ...
> + * be passed in via setup_data. In that case runtime ranges will be mapped
case, ...
> + * to fixed virtual addresses exactly same as the ones in previous kernel.
"... to the same virtual addresses as the first kernel."
> */
> void __init efi_enter_virtual_mode(void)
> {
> @@ -919,12 +1037,15 @@ void __init efi_enter_virtual_mode(void)
> return;
> }
>
> - efi_merge_regions();
> -
> - new_memmap = efi_map_regions(&count);
> - if (!new_memmap) {
> - pr_err("Error reallocating memory, EFI runtime non-functional!\n");
> - return;
> + if (esdata)
> + efi_map_regions_fixed();
> + else {
> + efi_merge_regions();
> + new_memmap = efi_map_regions(&count);
> + if (!new_memmap) {
> + pr_err("Error reallocating memory, EFI runtime non-functional!\n");
> + return;
> + }
CHECK: braces {} should be used on all arms of this statement
#253: FILE: arch/x86/platform/efi/efi.c:1040:
+ if (esdata)
[...]
+ else {
[...]
--
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--
WARNING: multiple messages have this Message-ID (diff)
From: Borislav Petkov <bp@alien8.de>
To: Dave Young <dyoung@redhat.com>
Cc: linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org,
x86@kernel.org, mjg59@srcf.ucam.org, hpa@zytor.com,
James.Bottomley@HansenPartnership.com, vgoyal@redhat.com,
ebiederm@xmission.com, horms@verge.net.au,
kexec@lists.infradead.org, greg@kroah.com,
matt@console-pimps.org, toshi.kani@hp.com
Subject: Re: [PATCH v4 07/12] efi: passing kexec necessary efi data via setup_data
Date: Wed, 27 Nov 2013 15:07:32 +0100 [thread overview]
Message-ID: <20131127140732.GD32267@pd.tnic> (raw)
In-Reply-To: <1385445477-9665-8-git-send-email-dyoung@redhat.com>
On Tue, Nov 26, 2013 at 01:57:52PM +0800, Dave Young wrote:
> Add a new setup_data type SETUP_EFI for kexec use.
> Passing the saved fw_vendor, runtime, config tables and
> efi runtime mappings.
>
> When entering virtual mode, directly mapping the efi
> runtime ragions which we passed in previously. And skip
> the step to call SetVirtualAddressMap.
>
> Specially for HP z420 workstation it need another variable
> saving,
Why the special handling? Does that mean, this is going to be the case
for other HP UEFI implementations too?
> it's the smbios physical address, the HP bios
> also update the SMBIOS address after entering virtual mode
> besides of the standard fw_vendor,runtime and config table.
>
> Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
> HP z420 workstation.
>
> v2: refresh based on previous patch changes, code cleanup.
> v3: use ioremap instead of phys_to_virt for esdata
>
> Signed-off-by: Dave Young <dyoung@redhat.com>
> ---
> arch/x86/include/asm/efi.h | 12 +++
> arch/x86/include/uapi/asm/bootparam.h | 1 +
> arch/x86/kernel/setup.c | 3 +
> arch/x86/platform/efi/efi.c | 161 ++++++++++++++++++++++++++++++----
> 4 files changed, 160 insertions(+), 17 deletions(-)
>
> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
> index 9fbaeb2..73d5643 100644
> --- a/arch/x86/include/asm/efi.h
> +++ b/arch/x86/include/asm/efi.h
> @@ -133,6 +133,18 @@ extern void efi_sync_low_kernel_mappings(void);
> extern void efi_setup_page_tables(void);
> extern void __init old_map_region(efi_memory_desc_t *md);
>
> +struct efi_setup_data {
> + u64 fw_vendor;
> + u64 runtime;
> + u64 tables;
> + u64 smbios;
> + u64 reserved[8];
What's that for?
> + efi_memory_desc_t map[0];
> +};
> +
> +extern void parse_efi_setup(u64 phys_addr, u32 data_len);
> +extern struct efi_setup_data *esdata;
> +
> #ifdef CONFIG_EFI
>
> static inline bool efi_is_native(void)
[ … ]
> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
> index c3a2aaa..fafeb40 100644
> --- a/arch/x86/platform/efi/efi.c
> +++ b/arch/x86/platform/efi/efi.c
> @@ -504,8 +531,12 @@ static int __init efi_systab_init(void *phys)
> }
>
> efi_systab.hdr = systab64->hdr;
> - efi_systab.fw_vendor = systab64->fw_vendor;
> - tmp |= systab64->fw_vendor;
> +
> + if (esdata)
> + efi_systab.fw_vendor = (unsigned long)esdata->fw_vendor;
> + else
> + efi_systab.fw_vendor = systab64->fw_vendor;
efi_systab.fw_vendor = esdata ? (unsigned long)esdata->fw_vendor
: systab64->fw_vendor;
> + tmp |= efi_systab.fw_vendor;
> efi_systab.fw_revision = systab64->fw_revision;
> efi_systab.con_in_handle = systab64->con_in_handle;
> tmp |= systab64->con_in_handle;
> @@ -519,13 +550,21 @@ static int __init efi_systab_init(void *phys)
> tmp |= systab64->stderr_handle;
> efi_systab.stderr = systab64->stderr;
> tmp |= systab64->stderr;
> - efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
> - tmp |= systab64->runtime;
> + if (esdata)
> + efi_systab.runtime =
> + (void *)(unsigned long)esdata->runtime;
> + else
> + efi_systab.runtime =
> + (void *)(unsigned long)systab64->runtime;
Ditto. Which would take care of these linebreaks which are ugly.
> + tmp |= (unsigned long)efi_systab.runtime;
> efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
> tmp |= systab64->boottime;
> efi_systab.nr_tables = systab64->nr_tables;
> - efi_systab.tables = systab64->tables;
> - tmp |= systab64->tables;
> + if (esdata)
> + efi_systab.tables = (unsigned long)esdata->tables;
> + else
> + efi_systab.tables = systab64->tables;
Ditto.
> + tmp |= efi_systab.tables;
>
> early_iounmap(systab64, sizeof(*systab64));
> #ifdef CONFIG_X86_32
> @@ -631,6 +670,41 @@ static int __init efi_memmap_init(void)
> return 0;
> }
>
> +static int __init efi_reuse_config(u64 tables, int nr_tables)
Static function - no need for "efi_" prefix.
> +{
> + void *p, *tablep;
> + int i, sz;
> +
> + if (!efi_enabled(EFI_64BIT))
> + return 0;
> +
> + sz = sizeof(efi_config_table_64_t);
> +
> + p = tablep = early_memremap(tables, nr_tables * sz);
> + if (!p) {
> + pr_err("Could not map Configuration table!\n");
> + return -ENOMEM;
> + }
> +
> + for (i = 0; i < efi.systab->nr_tables; i++) {
> + efi_guid_t guid;
> +
> + guid = ((efi_config_table_64_t *)p)->guid;
> +
> + /*
> + HP z420 workstation smbios will be convert to
> + virtual address after enter virtual mode.
> + Thus in case kexec/kdump the physical address
> + will be passed in setup_data.
Is that what the commit message above says? I'm having a hard time
parsing this text.
> + */
> + if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
> + ((efi_config_table_64_t *)p)->table = esdata->smbios;
...and yet we do this for *every* UEFI box. Why not HP only?
> + p += sz;
> + }
> + early_iounmap(tablep, nr_tables * sz);
> + return 0;
> +}
> +
> void __init efi_init(void)
> {
> efi_char16_t *c16;
> @@ -676,6 +750,9 @@ void __init efi_init(void)
> efi.systab->hdr.revision >> 16,
> efi.systab->hdr.revision & 0xffff, vendor);
>
> + if (esdata && esdata->smbios)
> + efi_reuse_config(efi.systab->tables, efi.systab->nr_tables);
> +
> if (efi_config_init(arch_tables))
> return;
>
> @@ -886,6 +963,43 @@ ret:
> }
>
> /*
> + * map efi regions which was passed via setup_data
> + * the virt_addr is a fixed addr which was used in
> + * 1st kernel of kexec boot.
> + */
Comment to 80 cols pls.
> +static void __init efi_map_regions_fixed(void)
Also no need for "efi_" prefix here.
> +{
> + int i;
> + unsigned long size;
> + efi_memory_desc_t *md;
> + u64 end, systab;
> + void *p;
> +
> + efi_runtime_map = kzalloc(nr_efi_runtime_map * memmap.desc_size,
> + GFP_KERNEL);
Arg alignment.
> + if (!efi_runtime_map)
> + pr_err("Out of memory, EFI runtime on nested kexec non-functional!\n");
> +
> + for (i = 0, p = efi_runtime_map; i < nr_efi_runtime_map; i++) {
> + md = esdata->map + i;
> + efi_map_region_fixed(md);
Gaah, this function should probably have a retval which signalizes
success/failure. For that I should probably teach __map_region to do
that too. On the TODO list.
> + size = md->num_pages << PAGE_SHIFT;
> + end = md->phys_addr + size;
> +
> + systab = (u64) (unsigned long) efi_phys.systab;
> + if (md->phys_addr <= systab && systab < end) {
> + systab += md->virt_addr - md->phys_addr;
> + efi.systab =
> + (efi_system_table_t *) (unsigned long) systab;
CHECK: No space is necessary after a cast
#219: FILE: arch/x86/platform/efi/efi.c:993:
+ efi.systab =
+ (efi_system_table_t *) (unsigned long) systab;
And also, those broken lines are ugly. Just let it stick out over 80 cols.
> + }
> + if (efi_runtime_map) {
> + memcpy(p, md, memmap.desc_size);
> + p += memmap.desc_size;
> + }
> + }
> +}
> +
> +/*
> * This function will switch the EFI runtime services to virtual mode.
> * Essentially, we look through the EFI memmap and map every region that
> * has the runtime attribute bit set in its memory descriptor into the
> @@ -901,6 +1015,10 @@ ret:
> * so that we're in a different address space when calling a runtime
> * function. For function arguments passing we do copy the PGDs of the
> * kernel page table into ->trampoline_pgd prior to each call.
> + *
> + * Specially for kexec boot efi runtime maps in previous kernel should
boot, ...
> + * be passed in via setup_data. In that case runtime ranges will be mapped
case, ...
> + * to fixed virtual addresses exactly same as the ones in previous kernel.
"... to the same virtual addresses as the first kernel."
> */
> void __init efi_enter_virtual_mode(void)
> {
> @@ -919,12 +1037,15 @@ void __init efi_enter_virtual_mode(void)
> return;
> }
>
> - efi_merge_regions();
> -
> - new_memmap = efi_map_regions(&count);
> - if (!new_memmap) {
> - pr_err("Error reallocating memory, EFI runtime non-functional!\n");
> - return;
> + if (esdata)
> + efi_map_regions_fixed();
> + else {
> + efi_merge_regions();
> + new_memmap = efi_map_regions(&count);
> + if (!new_memmap) {
> + pr_err("Error reallocating memory, EFI runtime non-functional!\n");
> + return;
> + }
CHECK: braces {} should be used on all arms of this statement
#253: FILE: arch/x86/platform/efi/efi.c:1040:
+ if (esdata)
[...]
+ else {
[...]
--
Regards/Gruss,
Boris.
Sent from a fat crate under my desk. Formatting is fine.
--
next prev parent reply other threads:[~2013-11-27 14:08 UTC|newest]
Thread overview: 214+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-26 5:57 [PATCH v4 00/12] kexec kernel efi runtime support Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 01/12] efi: remove unused variables in __map_region Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 02/12] efi: add a wrapper function efi_map_region_fixed Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 03/12] efi: reserve boot service fix Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 04/12] efi: cleanup efi_enter_virtual_mode function Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 14:51 ` Matt Fleming
2013-11-26 14:51 ` Matt Fleming
2013-11-26 14:51 ` Matt Fleming
2013-11-26 5:57 ` [PATCH v4 05/12] efi: export more efi table variable to sysfs Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 8:50 ` Borislav Petkov
2013-11-26 8:50 ` Borislav Petkov
2013-11-26 9:13 ` Dave Young
2013-11-26 9:13 ` Dave Young
2013-11-26 9:13 ` Dave Young
2013-11-26 15:57 ` Matt Fleming
2013-11-26 15:57 ` Matt Fleming
2013-11-26 15:57 ` Matt Fleming
2013-11-27 2:53 ` Dave Young
2013-11-27 2:53 ` Dave Young
2013-11-27 2:53 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 06/12] efi: export efi runtime memory mapping " Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 19:30 ` Matt Fleming
2013-11-26 19:30 ` Matt Fleming
2013-11-26 19:30 ` Matt Fleming
2013-11-27 3:07 ` Dave Young
2013-11-27 3:07 ` Dave Young
2013-11-27 3:07 ` Dave Young
2013-11-27 8:17 ` Dave Young
2013-11-27 8:17 ` Dave Young
2013-11-27 8:17 ` Dave Young
2013-11-27 11:44 ` Borislav Petkov
2013-11-27 11:44 ` Borislav Petkov
2013-11-27 11:44 ` Borislav Petkov
2013-11-29 9:40 ` Dave Young
2013-11-29 9:40 ` Dave Young
2013-11-29 9:40 ` Dave Young
2013-11-29 11:50 ` Borislav Petkov
2013-11-29 11:50 ` Borislav Petkov
2013-11-29 11:50 ` Borislav Petkov
2013-11-29 11:59 ` Matt Fleming
2013-11-29 11:59 ` Matt Fleming
2013-11-29 11:59 ` Matt Fleming
2013-12-02 2:51 ` Dave Young
2013-12-02 2:51 ` Dave Young
2013-12-02 2:51 ` Dave Young
2013-12-02 2:59 ` Dave Young
2013-12-02 2:59 ` Dave Young
2013-12-02 2:59 ` Dave Young
2013-12-02 9:40 ` Borislav Petkov
2013-12-02 9:40 ` Borislav Petkov
2013-12-02 9:40 ` Borislav Petkov
2013-12-07 9:01 ` Dave Young
2013-12-07 9:01 ` Dave Young
2013-12-07 9:01 ` Dave Young
2013-12-07 13:30 ` Borislav Petkov
2013-12-07 13:30 ` Borislav Petkov
2013-12-07 13:30 ` Borislav Petkov
2013-12-07 21:46 ` H. Peter Anvin
2013-12-07 21:46 ` H. Peter Anvin
2013-12-07 21:46 ` H. Peter Anvin
2013-12-09 2:23 ` Dave Young
2013-12-09 2:23 ` Dave Young
2013-12-09 2:23 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 07/12] efi: passing kexec necessary efi data via setup_data Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 22:04 ` Matt Fleming
2013-11-26 22:04 ` Matt Fleming
2013-11-26 22:04 ` Matt Fleming
2013-11-27 4:52 ` Dave Young
2013-11-27 4:52 ` Dave Young
2013-11-27 4:52 ` Dave Young
2013-11-27 10:17 ` Matt Fleming
2013-11-27 10:17 ` Matt Fleming
2013-11-27 10:17 ` Matt Fleming
2013-11-29 9:46 ` Dave Young
2013-11-29 9:46 ` Dave Young
2013-11-29 9:46 ` Dave Young
2013-11-27 14:07 ` Borislav Petkov [this message]
2013-11-27 14:07 ` Borislav Petkov
2013-11-27 14:07 ` Borislav Petkov
2013-11-29 9:14 ` Dave Young
2013-11-29 9:14 ` Dave Young
2013-11-29 9:14 ` Dave Young
2013-11-29 16:46 ` Borislav Petkov
2013-11-29 16:46 ` Borislav Petkov
2013-11-29 16:46 ` Borislav Petkov
2013-12-02 2:49 ` Dave Young
2013-12-02 2:49 ` Dave Young
2013-12-02 2:49 ` Dave Young
2013-12-02 9:44 ` Borislav Petkov
2013-12-02 9:44 ` Borislav Petkov
2013-12-02 9:44 ` Borislav Petkov
2013-12-02 22:33 ` Toshi Kani
2013-12-02 22:33 ` Toshi Kani
2013-12-02 22:33 ` Toshi Kani
2013-12-03 1:31 ` Toshi Kani
2013-12-03 1:31 ` Toshi Kani
2013-12-03 1:31 ` Toshi Kani
2013-12-03 1:56 ` Dave Young
2013-12-03 1:56 ` Dave Young
2013-12-03 1:56 ` Dave Young
2013-12-03 15:39 ` Toshi Kani
2013-12-03 15:39 ` Toshi Kani
2013-12-03 15:39 ` Toshi Kani
2013-12-04 2:46 ` Dave Young
2013-12-04 2:46 ` Dave Young
2013-12-04 2:46 ` Dave Young
2013-12-04 16:43 ` Toshi Kani
2013-12-04 16:43 ` Toshi Kani
2013-12-04 16:43 ` Toshi Kani
2013-12-05 1:56 ` Dave Young
2013-12-05 1:56 ` Dave Young
2013-12-05 1:56 ` Dave Young
2013-12-05 11:51 ` Borislav Petkov
2013-12-05 11:51 ` Borislav Petkov
2013-12-05 11:51 ` Borislav Petkov
2013-12-05 15:56 ` Toshi Kani
2013-12-05 15:56 ` Toshi Kani
2013-12-05 15:56 ` Toshi Kani
2013-12-05 20:52 ` Borislav Petkov
2013-12-05 20:52 ` Borislav Petkov
2013-12-05 20:52 ` Borislav Petkov
2013-12-06 1:31 ` Dave Young
2013-12-06 1:31 ` Dave Young
2013-12-06 1:31 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 08/12] efi: only print saved efi runtime maps instead of all memmap ranges for kexec Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-27 10:27 ` Matt Fleming
2013-11-27 10:27 ` Matt Fleming
2013-11-27 14:27 ` Borislav Petkov
2013-11-27 14:27 ` Borislav Petkov
2013-11-27 14:27 ` Borislav Petkov
2013-11-29 8:50 ` Dave Young
2013-11-29 8:50 ` Dave Young
2013-11-29 8:50 ` Dave Young
2013-11-29 16:47 ` Borislav Petkov
2013-11-29 16:47 ` Borislav Petkov
2013-11-29 16:47 ` Borislav Petkov
2013-12-02 2:38 ` Dave Young
2013-12-02 2:38 ` Dave Young
2013-12-02 2:38 ` Dave Young
2013-11-29 8:47 ` Dave Young
2013-11-29 8:47 ` Dave Young
2013-11-29 8:47 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 09/12] x86: add xloadflags bit for efi runtime support on kexec Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-27 14:27 ` Borislav Petkov
2013-11-27 14:27 ` Borislav Petkov
2013-11-27 14:27 ` Borislav Petkov
2013-11-29 8:44 ` Dave Young
2013-11-29 8:44 ` Dave Young
2013-11-29 8:44 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 10/12] x86: export x86 boot_params to sysfs Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-27 11:20 ` Matt Fleming
2013-11-27 11:20 ` Matt Fleming
2013-11-27 11:20 ` Matt Fleming
2013-11-29 9:44 ` Dave Young
2013-11-29 9:44 ` Dave Young
2013-11-29 9:44 ` Dave Young
2013-11-27 14:56 ` Borislav Petkov
2013-11-27 14:56 ` Borislav Petkov
2013-11-27 14:56 ` Borislav Petkov
2013-11-29 8:42 ` Dave Young
2013-11-29 8:42 ` Dave Young
2013-11-29 8:42 ` Dave Young
2013-11-26 5:57 ` [PATCH v4 11/12] x86: reserve setup_data ranges late after parsing memmap cmdline Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-27 15:07 ` Borislav Petkov
2013-11-27 15:07 ` Borislav Petkov
2013-11-29 8:35 ` Dave Young
2013-11-29 8:35 ` Dave Young
2013-11-29 8:35 ` Dave Young
2013-11-29 16:56 ` Borislav Petkov
2013-11-29 16:56 ` Borislav Petkov
2013-11-29 16:56 ` Borislav Petkov
2013-11-26 5:57 ` [PATCH v4 12/12] x86: kdebugfs do not use __va for getting setup_data virt addr Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 5:57 ` Dave Young
2013-11-26 6:04 ` [PATCH v4 00/12] kexec kernel efi runtime support Dave Young
2013-11-26 6:04 ` Dave Young
2013-11-26 6:04 ` Dave Young
2013-11-27 12:50 ` Matt Fleming
2013-11-27 12:50 ` Matt Fleming
2013-11-27 12:50 ` Matt Fleming
2013-11-28 2:08 ` Dave Young
2013-11-28 2:08 ` Dave Young
2013-11-28 2:08 ` Dave Young
2013-11-29 8:28 ` Dave Young
2013-11-29 8:28 ` Dave Young
2013-11-29 8:28 ` Dave Young
2013-11-29 17:02 ` Borislav Petkov
2013-11-29 17:02 ` Borislav Petkov
2013-11-29 17:02 ` Borislav Petkov
2013-12-02 2:32 ` Dave Young
2013-12-02 2:32 ` Dave Young
2013-12-02 2:32 ` Dave Young
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131127140732.GD32267@pd.tnic \
--to=bp@alien8.de \
--cc=James.Bottomley@HansenPartnership.com \
--cc=dyoung@redhat.com \
--cc=ebiederm@xmission.com \
--cc=greg@kroah.com \
--cc=horms@verge.net.au \
--cc=hpa@zytor.com \
--cc=kexec@lists.infradead.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=matt@console-pimps.org \
--cc=mjg59@srcf.ucam.org \
--cc=toshi.kani@hp.com \
--cc=vgoyal@redhat.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.