On Thu, May 30, 2013 at 10:16:12AM +0800, joeyli wrote:
> 於 四,2013-05-30 於 00:53 +0200,Jiri Kosina 提到:
> > On Wed, 29 May 2013, Russ Anderson wrote:
> > 
> > > > Yes, but this call is clearly happening way before ExitBootServices() 
> > > > -- 
> > > > see the surrounding code, see for example this in efi_main():
> > > > 
> > > > [ ... snip ... ]
> > > >         setup_efi_vars(boot_params);
> > > > 
> > > >         setup_efi_pci(boot_params);
> > > > 
> > > >         status = efi_call_phys3(sys_table->boottime->allocate_pool,
> > > >                                 EFI_LOADER_DATA, sizeof(*gdt),
> > > >                                 (void **)&gdt);
> > > >         if (status != EFI_SUCCESS) {
> > > >                 efi_printk("Failed to alloc mem for gdt structure\n");
> > > >                 goto fail;
> > > >         }
> > > > [ ... snip ... ]
> > > 
> > > Yes.  Note the failing call is sys_table->runtime while all the
> > > other calls are sys_table->boottime and seem to work.  Not sure
> > > why the sys_table->runtime call has a problem but it may be
> > > a clue.  Could something in the runtime path not be set up???
> > 
> > That was my original idea early today as well. My understanding of the 
> > UEFI spec is admittedly limited, but afaics calling runtime method from 
> > boot environment should be a valid thing to do ... ?
> 
> QueryVariableInfo() is a runtime services, all runtime services should
> available bother on boot time and runtime:
> 
> UEFI spec 2.3.1 P.109:
>   Runtime Services
>   Functions that are available before and after any call to  
>   ExitBootServices(). These functions are described in Section 7.

That's a great idea.  This patch moves the QueryVariableInfo()
call from bootime to runtime, in efi_late_init().  The attached
patch is consistent with the UEFI spec and avoids the problem.

Thanks,
-- 
Russ Anderson, OS RAS/Partitioning Project Lead  
SGI - Silicon Graphics Inc          r...@sgi.com
Move query_variable_info call to runtime to avoid bios issues.

Signed-off-by: Russ Anderson <r...@sgi.com>

---
 arch/x86/boot/compressed/eboot.c |   49 ---------------------------------------
 arch/x86/platform/efi/efi.c      |   35 ++++++++++++---------------
 2 files changed, 16 insertions(+), 68 deletions(-)

Index: linux/arch/x86/boot/compressed/eboot.c
===================================================================
--- linux.orig/arch/x86/boot/compressed/eboot.c	2013-05-30 11:02:19.034914824 -0500
+++ linux/arch/x86/boot/compressed/eboot.c	2013-05-30 16:53:50.512636568 -0500
@@ -251,53 +251,6 @@ static void find_bits(unsigned long mask
 	*size = len;
 }
 
-static efi_status_t setup_efi_vars(struct boot_params *params)
-{
-	struct setup_data *data;
-	struct efi_var_bootdata *efidata;
-	u64 store_size, remaining_size, var_size;
-	efi_status_t status;
-
-	if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION)
-		return EFI_UNSUPPORTED;
-
-	data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
-
-	while (data && data->next)
-		data = (struct setup_data *)(unsigned long)data->next;
-
-	status = efi_call_phys4((void *)sys_table->runtime->query_variable_info,
-				EFI_VARIABLE_NON_VOLATILE |
-				EFI_VARIABLE_BOOTSERVICE_ACCESS |
-				EFI_VARIABLE_RUNTIME_ACCESS, &store_size,
-				&remaining_size, &var_size);
-
-	if (status != EFI_SUCCESS) { // RJA
-		efi_printk("RJA: setup_efi_vars FAILED\n");
-		return status;
-	}
-
-	status = efi_call_phys3(sys_table->boottime->allocate_pool,
-				EFI_LOADER_DATA, sizeof(*efidata), &efidata);
-
-	if (status != EFI_SUCCESS)
-		return status;
-
-	efidata->data.type = SETUP_EFI_VARS;
-	efidata->data.len = sizeof(struct efi_var_bootdata) -
-		sizeof(struct setup_data);
-	efidata->data.next = 0;
-	efidata->store_size = store_size;
-	efidata->remaining_size = remaining_size;
-	efidata->max_var_size = var_size;
-
-	if (data)
-		data->next = (unsigned long)efidata;
-	else
-		params->hdr.setup_data = (unsigned long)efidata;
-
-}
-
 static efi_status_t setup_efi_pci(struct boot_params *params)
 {
 	efi_pci_io_protocol *pci;
@@ -1204,8 +1157,6 @@ struct boot_params *efi_main(void *handl
 
 	setup_graphics(boot_params);
 
-	setup_efi_vars(boot_params);
-
 	setup_efi_pci(boot_params);
 
 	status = efi_call_phys3(sys_table->boottime->allocate_pool,
Index: linux/arch/x86/platform/efi/efi.c
===================================================================
--- linux.orig/arch/x86/platform/efi/efi.c	2013-05-30 11:02:19.034914824 -0500
+++ linux/arch/x86/platform/efi/efi.c	2013-05-30 17:05:38.140039879 -0500
@@ -786,9 +786,6 @@ void __init efi_init(void)
 	char vendor[100] = "unknown";
 	int i = 0;
 	void *tmp;
-	struct setup_data *data;
-	struct efi_var_bootdata *efi_var_data;
-	u64 pa_data;
 
 #ifdef CONFIG_X86_32
 	if (boot_params.efi_info.efi_systab_hi ||
@@ -806,22 +803,6 @@ void __init efi_init(void)
 	if (efi_systab_init(efi_phys.systab))
 		return;
 
-	pa_data = boot_params.hdr.setup_data;
-	while (pa_data) {
-		data = early_ioremap(pa_data, sizeof(*efi_var_data));
-		if (data->type == SETUP_EFI_VARS) {
-			efi_var_data = (struct efi_var_bootdata *)data;
-
-			efi_var_store_size = efi_var_data->store_size;
-			efi_var_remaining_size = efi_var_data->remaining_size;
-			efi_var_max_var_size = efi_var_data->max_var_size;
-		}
-		pa_data = data->next;
-		early_iounmap(data, sizeof(*efi_var_data));
-	}
-
-	boot_used_size = efi_var_store_size - efi_var_remaining_size;
-
 	set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
 	/*
@@ -877,7 +858,23 @@ void __init efi_init(void)
 
 void __init efi_late_init(void)
 {
+	efi_status_t status;
+
 	efi_bgrt_init();
+
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return;
+
+	status = efi_call_virt4(query_variable_info,
+				EFI_VARIABLE_NON_VOLATILE |
+				EFI_VARIABLE_BOOTSERVICE_ACCESS |
+				EFI_VARIABLE_RUNTIME_ACCESS,
+				&efi_var_max_var_size, &efi_var_remaining_size,
+				&efi_var_store_size);
+	if (status != EFI_SUCCESS)
+		return;
+
+	boot_used_size = efi_var_store_size - efi_var_remaining_size;
 }
 
 void __init efi_set_executable(efi_memory_desc_t *md, bool executable)

Reply via email to