Re: [patch 6/7 v2] passing kexec necessary efi data via setup_data

2013-11-13 Thread Matt Fleming
On Tue, 05 Nov, at 04:20:13PM, dyo...@redhat.com 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, 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.
 
Does that mean that on some of the platforms you tested the SMBIOS
address isn't updated?

-- 
Matt Fleming, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [patch 6/7 v2] passing kexec necessary efi data via setup_data

2013-11-13 Thread Dave Young
On 11/13/13 at 03:50pm, Matt Fleming wrote:
 On Tue, 05 Nov, at 04:20:13PM, dyo...@redhat.com 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, 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.
  
 Does that mean that on some of the platforms you tested the SMBIOS
 address isn't updated?

Yes, on my three test machines, lenovo, dell and HP, only the HP
machine need this that means the lenovo and dell machine does not
update the SMBIOS address to virt addr.

 
 -- 
 Matt Fleming, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line unsubscribe linux-efi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[patch 6/7 v2] passing kexec necessary efi data via setup_data

2013-11-05 Thread dyoung
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, 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.

Signed-off-by: Dave Young dyo...@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   |  151 ++
 4 files changed, 152 insertions(+), 15 deletions(-)

--- linux-2.6.orig/arch/x86/kernel/setup.c
+++ linux-2.6/arch/x86/kernel/setup.c
@@ -447,6 +447,9 @@ static void __init parse_setup_data(void
case SETUP_DTB:
add_dtb(pa_data);
break;
+   case SETUP_EFI:
+   parse_efi_setup(pa_data, data_len);
+   break;
default:
break;
}
--- linux-2.6.orig/arch/x86/platform/efi/efi.c
+++ linux-2.6/arch/x86/platform/efi/efi.c
@@ -78,6 +78,7 @@ static __initdata efi_config_table_type_
 
 efi_memory_desc_t *efi_runtime_map;
 int nr_efi_runtime_map;
+struct efi_setup_data *esdata;
 
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
@@ -115,6 +116,32 @@ static int __init setup_storage_paranoia
 }
 early_param(efi_no_storage_paranoia, setup_storage_paranoia);
 
+void parse_efi_setup(u64 phys_addr, u32 data_len)
+{
+   int size;
+   struct setup_data *sdata;
+   u64 esdata_phys;
+
+   if (!efi_enabled(EFI_64BIT)) {
+   pr_warn(skipping setup_data on EFI 32BIT!);
+   return;
+   }
+
+   sdata = early_memremap(phys_addr, data_len);
+   if (!sdata)
+   return;
+
+   size = data_len - sizeof(struct setup_data);
+
+   esdata_phys = phys_addr + sizeof(struct setup_data);
+
+   nr_efi_runtime_map = (size - sizeof(struct efi_setup_data)) /
+   sizeof(efi_memory_desc_t);
+   early_iounmap(sdata, data_len);
+
+   /* setup data regions have been reserved by default */
+   esdata = phys_to_virt(esdata_phys);
+}
 
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
@@ -504,8 +531,12 @@ static int __init efi_systab_init(void *
}
 
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;
+   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 *
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;
+   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;
+   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)
+{
+   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);
+